Add a Tips and Tricks page containing the loading screen tips

- Small popup page accessible from the main menu via Learn to Play.
- Lets the player read through the tips with 'Previous' and 'Next' buttons.
- Tips continue to be shown on the loading screen.
-> but there without the scrolling ability.

- Added two new hotkeys for quicker tip changing (item.prev and item.next)
-> set to the left and right arrows respectively by default.

- Responsible scripts are placed in gui/reference/tips/.
- The tip text files have been moved to gui/reference/tips/texts/.
- Tip image files have been moved to art/textures/ui/tips/.

- Added a series of new sprites (textures in art/textures/ui/tipdisplay/)
-> comprises a title decoration, a bullet point sprite, and a new button
style.
This commit is contained in:
Vantha 2024-09-20 12:00:58 +02:00 committed by Ralph Sennhauser
parent 1c12ada278
commit 38b71c1bac
149 changed files with 535 additions and 158 deletions

View file

@ -418,6 +418,10 @@ rewind = "Shift+Backspace" ; If timewarp mode enabled, go back to earlier
next = "Tab", "Alt+S" ; Show the next tab
prev = "Shift+Tab", "Alt+W" ; Show the previous tab
[hotkey.item]
next = "RightArrow" ; Show the next item of a list
prev = "LeftArrow" ; Show the previous item of a list
[hotkey.text] ; > GUI TEXTBOX HOTKEYS
delete.left = "Ctrl+Backspace" ; Delete word to the left of cursor
delete.right = "Ctrl+Del" ; Delete word to the right of cursor

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eea1fcf91b908608b324d3cbc338f910e6bad9be3a61e8d2c13cacad2c9e5df3
size 314

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a793864d24ddc596dce3c5de6e94d4e6bf19bbc7b954f6488890daae9f737c24
size 594

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:edd1ab1182a46fad152667c4333c03f87d286536b3428d48858b2069cb2b78bd
size 366

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5ef224f97dca446a41f1e1acf7c364f899d6b86b1a8a62bbd4a9312beb2be7bb
size 10377

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3c63813b9c16756aa1c24419c8bb3a8ee6f5095af94101805f2c073651f60745
size 5823

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d1ddec0078002e7aff588914ef9c18ee9b08a618ba74120964a45f5c92b79345
size 8278

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8963642a740556a2438742dd17dd71eb2576d3e6afa3a38bebd185b6a9257a79
size 8167

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:040ba034064c326ecdecd5b04ba78bc83f54c8559134ca83cc8742286582e896
size 1728

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:df06f74a12049d725be4fe46e45cce0bb3f68c3acc151a967865df28248968ef
size 1351

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dff510f39d80d4b23497c8f1f59b443fd0bc3ce636d12719014e90a94960b78e
size 321

View file

@ -79,6 +79,14 @@
"name": "Previous tab",
"desc": "Show the previous tab."
},
"item.next": {
"name": "Next item",
"desc": "Show the next item."
},
"item.prev": {
"name": "Previous item",
"desc": "Show the previous item."
},
"text.delete.left": {
"name": "Delete before cursor",
"desc": "Delete word to the left of cursor."

View file

@ -1,62 +0,0 @@
/**
* This class is concerned with chosing and displaying hints about how to play the game.
* This includes a text and an image.
*/
class TipDisplay
{
constructor()
{
this.tipImage = Engine.GetGUIObjectByName("tipImage");
this.tipTitle = Engine.GetGUIObjectByName("tipTitle");
this.tipText = Engine.GetGUIObjectByName("tipText");
this.tipFiles = listFiles(this.TextPath, ".txt", false);
this.displayRandomTip();
}
displayRandomTip()
{
let tipFile = pickRandom(this.tipFiles);
if (tipFile)
this.displayTip(tipFile);
else
error("Failed to find any matching tips for the loading screen.");
}
displayTip(tipFile)
{
this.tipImage.sprite =
"stretched:" + this.ImagePath + tipFile + ".png";
let tipText = Engine.TranslateLines(Engine.ReadFile(
this.TextPath + tipFile + ".txt")).split("\n");
this.tipTitle.caption = tipText.shift();
// Change the height of the title and the text to fit the full title.
const margin = 10;
const titleSize = this.tipTitle.size;
titleSize.bottom = titleSize.top + this.tipTitle.getTextSize().height + margin;
this.tipTitle.size = titleSize;
const textSize = this.tipText.size;
textSize.top = titleSize.bottom;
this.tipText.size = textSize;
this.tipText.caption = tipText.map(text =>
text && sprintf(this.BulletFormat, { "tiptext": text })).join("\n\n");
}
}
/**
* Directory storing txt files containing the gameplay tips.
*/
TipDisplay.prototype.TextPath = "gui/text/tips/";
/**
* Directory storing the PNG images with filenames corresponding to the tip text files.
*/
TipDisplay.prototype.ImagePath = "loading/tips/";
// Translation: A bullet point used before every item of list of tips displayed on loading screen
TipDisplay.prototype.BulletFormat = translate("• %(tiptext)s");

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<object size="0 0 520 392">
<object type="image" sprite="LoadingTipImage">
<object name="tipImage" size="4 4 516 516" type="image">
<object name="tipImageCover" type="image" sprite="LoadingTipImageCover"/>
</object>
</object>
</object>
<object size="570 0 910 400" type="image" sprite="LoadingTipText">
<object name="tipTitle" size="30 30 100%-30 50" type="text" style="LoadingTipTitleText"/>
<object name="tipText" size="30 50 100%-30 100%" type="text" style="LoadingTipText"/>
</object>
</object>

View file

@ -6,7 +6,8 @@ function init(data)
"initData": data,
"progressBar": new ProgressBar(),
"quoteDisplay": new QuoteDisplay(),
"tipDisplay": new TipDisplay(),
// Note that the construction parameter is set to false to disable tip scrolling.
"tipDisplay": new TipDisplay(false),
"titleDisplay": new TitleDisplay(data)
};

View file

@ -15,7 +15,7 @@
</object>
<object size="50%-452 50%-196 50%+452 50%+196">
<include file="gui/loading/TipDisplay.xml"/>
<include file="gui/reference/tips/sections/TipDisplay.xml"/>
</object>
<object size="50%-448 50%+230 50%+448 100%-16">

View file

@ -40,68 +40,4 @@
/>
</sprite>
<!-- TIP IMAGE-->
<sprite name="LoadingTipImage">
<!-- sides -->
<image
texture="global/border/line_horiz.png"
texture_size="0 0 64 4"
size="4 0 100%-4 4"
/>
<image
texture="global/border/line_vert.png"
texture_size="0 0 4 64"
size="100%-4 4 100% 100%-4"
/>
<image
texture="global/border/line_horiz.png"
texture_size="0 0 64 4"
size="4 100%-4 100%-4 100%"
/>
<image
texture="global/border/line_vert.png"
texture_size="0 0 4 64"
size="0 4 4 100%-4"
/>
<!-- corners -->
<image
texture="global/border/line_corner_top_right.png"
texture_size="0 0 4 4"
size="100%-4 0 100% 4"
/>
<image
texture="global/border/line_corner_bottom_right.png"
texture_size="0 0 4 4"
size="100%-4 100%-4 100% 100%"
/>
<image
texture="global/border/line_corner_bottom_left.png"
texture_size="0 0 4 4"
size="0 100%-4 4 100%"
/>
<image
texture="global/border/line_corner_top_left.png"
texture_size="0 0 4 4"
size="0 0 4 4"
/>
</sprite>
<!-- TIP IMAGE GRADIENT -->
<sprite name="LoadingTipImageCover">
<image
texture="loading/gradient_tips.png"
texture_size="0 0 100% 100%"
size="0 0 100% 100%"
/>
</sprite>
<!-- TIP TEXT -->
<sprite name="LoadingTipText">
<image
texture="loading/parchment.png"
real_texture_placement="0 0 322 386"
/>
</sprite>
</sprites>

View file

@ -30,19 +30,6 @@
text_valign="top"
/>
<style name="LoadingTipTitleText"
font="sans-bold-16"
textcolor="black"
text_align="left"
text_valign="top"
/>
<style name="LoadingTipText"
font="sans-bold-14"
textcolor="black"
text_align="left"
text_valign="top"
/>
<style name="LoadingProgressbar"
sprite_bar="LoadingProgressBarMiddle"

View file

@ -50,6 +50,8 @@ You may change hotkeys in [font="sans-bold-14"]Options > Hotkeys[font="sans-14"]
hotkey.bigscreenshot Take huge screenshot (6400×4800 pixels, in .bmp format, location is displayed in the top left of the GUI after the file has been saved, and can also be seen in the console/logs if you miss it there)
hotkey.tab.next Switch to the next tab
hotkey.tab.prev Switch to the previous tab
hotkey.item.next Switch to the next item of a list
hotkey.item.prev Switch to the previous item of a list
[font="sans-bold-14"]In Game[font="sans-14"]
Double Left Click \[on unit] Select all of your units of the same kind on the screen (even if they're different ranks)

View file

@ -9,6 +9,10 @@
<include>common/sprites.xml</include>
<include>common/styles.xml</include>
<include>reference/tips/setup.xml</include>
<include>reference/tips/sprites.xml</include>
<include>reference/tips/styles.xml</include>
<include>loading/styles.xml</include>
<include>loading/sprites.xml</include>
<include>loading/loading.xml</include>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<page>
<include>common/modern/setup.xml</include>
<include>common/modern/styles.xml</include>
<include>common/modern/sprites.xml</include>
<include>common/sprites.xml</include>
<include>common/styles.xml</include>
<include>reference/tips/setup.xml</include>
<include>reference/tips/sprites.xml</include>
<include>reference/tips/styles.xml</include>
<include>reference/tips/tips.xml</include>
</page>

View file

@ -32,6 +32,13 @@ var g_MainMenuItems = [
});
}
},
{
"caption": translate("Tips and Tricks"),
"tooltip": translate("Discover simple tips, tricks, and game mechanics."),
"onPress": () => {
Engine.PushGuiPage("page_tips.xml");
}
},
{
"caption": translate("Structure Tree"),
"tooltip": colorizeHotkey(translate("%(hotkey)s: View the structure tree of civilizations featured in 0 A.D."), "structree"),

View file

@ -0,0 +1,15 @@
class TipsPage
{
constructor()
{
this.tipDisplay = new TipDisplay();
this.closeButton = new CloseButton(this);
}
closePage()
{
Engine.PopGuiPage("page_tips.xml");
}
}
TipsPage.prototype.CloseButtonTooltip = translate("%(hotkey)s: Close Tips and Tricks.");

View file

@ -0,0 +1,103 @@
/**
* This class is concerned with chosing and displaying tips about how to play the game.
* This includes a text and an image.
*/
class TipDisplay
{
/**
* @param {boolean} tipScrolling - Whether or not to enable the player to scroll through the tips.
*/
constructor(tipScrolling = true)
{
this.tipImage = Engine.GetGUIObjectByName("tipImage");
this.tipTitle = Engine.GetGUIObjectByName("tipTitle");
this.tipTitleDecoration = Engine.GetGUIObjectByName("tipTitleDecoration");
this.tipText = Engine.GetGUIObjectByName("tipText");
this.previousTipButton = Engine.GetGUIObjectByName("previousTipButton");
this.nextTipButton = Engine.GetGUIObjectByName("nextTipButton");
this.previousTipButton.caption = this.CaptionPreviousTip;
this.previousTipButton.tooltip = colorizeHotkey("%(hotkey)s: ", "item.prev") + this.TooltipPreviousTip;
this.nextTipButton.caption = this.CaptionNextTip;
this.nextTipButton.tooltip = colorizeHotkey("%(hotkey)s: ", "item.next") + this.TooltipNextTip;
this.tipFiles = shuffleArray(listFiles(this.TextPath, ".txt", false));
if (this.tipFiles.length === 0)
{
warn("Failed to find any tips to display.");
return;
}
const hideButtons = !tipScrolling || this.tipFiles.length < 2;
this.previousTipButton.hidden = hideButtons;
this.nextTipButton.hidden = hideButtons;
this.tipFilesIndex = -1;
this.nextTipButton.onPress = () => this.onIndexChange(1);
this.previousTipButton.onPress = () => this.onIndexChange(-1);
this.onIndexChange(1);
}
onIndexChange(number)
{
this.tipFilesIndex += number;
this.tipFilesIndex = Math.max(0, Math.min(this.tipFilesIndex, this.tipFiles.length - 1));
this.displayTip(this.tipFiles[this.tipFilesIndex]);
this.rebuildButtons();
}
rebuildButtons()
{
this.previousTipButton.enabled = this.tipFilesIndex !== 0 && !this.previousTipButton.hidden;
this.nextTipButton.enabled = this.tipFilesIndex < this.tipFiles.length - 1 && !this.nextTipButton.hidden;
}
displayTip(tipFile)
{
this.tipImage.sprite = "stretched:" + this.ImagePath + tipFile + ".png";
const tipText = Engine.TranslateLines(Engine.ReadFile(
this.TextPath + tipFile + ".txt")).split("\n");
this.tipTitle.caption = tipText.shift();
this.scaleGuiElementsToFit();
this.tipText.caption = tipText.map(text =>
text && "[icon=\"BulletPoint\"] " + text).join("\n\n");
}
scaleGuiElementsToFit()
{
const titleSize = this.tipTitle.size;
const titleTextSize = this.tipTitle.getTextSize();
titleSize.bottom = titleSize.top + titleTextSize.height;
this.tipTitle.size = titleSize;
this.tipTitleDecoration.size = new GUISize(
-(titleTextSize.width / 2 + 12), this.tipTitle.size.bottom - 4, titleTextSize.width / 2 + 12, this.tipTitle.size.bottom + 12,
50, 0, 50, 0
);
const textSize = this.tipText.size;
textSize.top = this.tipTitleDecoration.size.bottom + 10;
this.tipText.size = textSize;
}
}
TipDisplay.prototype.CaptionPreviousTip = translateWithContext("button", "Previous");
TipDisplay.prototype.TooltipPreviousTip = translate("Switch to the previous tip.");
TipDisplay.prototype.CaptionNextTip = translateWithContext("button", "Next");
TipDisplay.prototype.TooltipNextTip = translate("Switch to the next tip.");
/**
* Directory storing .txt files containing the gameplay tips.
*/
TipDisplay.prototype.TextPath = "gui/reference/tips/texts/";
/**
* Directory storing the .png images with filenames corresponding to the tip text files.
*/
TipDisplay.prototype.ImagePath = "tips/";

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<script directory="gui/reference/tips/sections/"/>
<object size="0 0 520 392">
<object type="image" sprite="TipImageFrame">
<object name="tipImage" size="4 4 516 516" type="image">
<object type="image" sprite="stretched:tipdisplay/tip-image-gradient.png"/>
</object>
</object>
</object>
<object size="570 0 910 400">
<object type="image" sprite="TipTextBackground"/>
<object name="previousTipButton" type="button" style="PreviousTipButton" hotkey="item.prev" size="30 348 155 372"/>
<object name="nextTipButton" type="button" style="NextTipButton" hotkey="item.next" size="185 348 310 372"/>
<object name="tipTitle" size="30 30 100%-30 50" type="text" text_align="center" style="TipTitleText"/>
<object name="tipTitleDecoration" type="image" sprite="TipTitleDecoration"/>
<object name="tipText" size="30 50 100%-20 100%" type="text" style="TipText" ghost="true"/>
</object>
</object>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<setup>
<icon name="BulletPoint"
sprite="stretched:tipdisplay/bullet-point.png"
size="8 8"
/>
</setup>

View file

@ -0,0 +1,246 @@
<?xml version="1.0" encoding="utf-8"?>
<sprites>
<!-- TIP IMAGE FRAME-->
<sprite name="TipImageFrame">
<!-- sides -->
<image
texture="global/border/line_horiz.png"
texture_size="0 0 64 4"
size="4 0 100%-4 4"
/>
<image
texture="global/border/line_vert.png"
texture_size="0 0 4 64"
size="100%-4 4 100% 100%-4"
/>
<image
texture="global/border/line_horiz.png"
texture_size="0 0 64 4"
size="4 100%-4 100%-4 100%"
/>
<image
texture="global/border/line_vert.png"
texture_size="0 0 4 64"
size="0 4 4 100%-4"
/>
<!-- corners -->
<image
texture="global/border/line_corner_top_right.png"
texture_size="0 0 4 4"
size="100%-4 0 100% 4"
/>
<image
texture="global/border/line_corner_bottom_right.png"
texture_size="0 0 4 4"
size="100%-4 100%-4 100% 100%"
/>
<image
texture="global/border/line_corner_bottom_left.png"
texture_size="0 0 4 4"
size="0 100%-4 4 100%"
/>
<image
texture="global/border/line_corner_top_left.png"
texture_size="0 0 4 4"
size="0 0 4 4"
/>
</sprite>
<!-- TIP TEXT BACKGROUND-->
<sprite name="TipTextBackground">
<image
texture="tipdisplay/parchment.png"
size="0 0 100% 100%"
real_texture_placement="-4 0 317 386"
/>
</sprite>
<!-- PREVIOUS TIP BUTTON
Note that the textures are mirrored horizontally (by setting the texure_size) -->
<sprite name="PreviousTipButton">
<image
texture="tipdisplay/button-highlight_base.png"
texture_size="100% 0 0 100%"
size="-10 -10 100%+10 100%+10"
real_texture_placement="16 0 80 64"
/>
<image
texture="tipdisplay/button-decoration_front.png"
texture_size="100% 0 0 100%"
size="0 0 24 100%"
real_texture_placement="-8 0 24 32"
/>
<image
texture="tipdisplay/button-decoration_back.png"
texture_size="100% 0 0 100%"
size="100%-24 0 100%-12 100%"
real_texture_placement="12 0 28 32"
/>
</sprite>
<sprite name="PreviousTipButtonOver">
<image
texture="tipdisplay/button-highlight_over.png"
texture_size="100% 0 0 100%"
size="-10 -10 100%+10 100%+10"
real_texture_placement="16 0 80 64"
/>
<image
texture="tipdisplay/button-decoration_front.png"
texture_size="100% 0 0 100%"
size="0 0 24 100%"
real_texture_placement="-8 0 24 32"
/>
<image
texture="tipdisplay/button-decoration_back.png"
texture_size="100% 0 0 100%"
size="100%-24 0 100%-12 100%"
real_texture_placement="12 0 28 32"
/>
</sprite>
<sprite name="PreviousTipButtonPressed">
<image
texture="tipdisplay/button-highlight_pressed.png"
texture_size="100% 0 0 100%"
size="-10 -10 100%+10 100%+10"
real_texture_placement="16 0 80 64"
/>
<image
texture="tipdisplay/button-decoration_front.png"
texture_size="100% 0 0 100%"
size="0 0 24 100%"
real_texture_placement="-8 0 24 32"
/>
<image
texture="tipdisplay/button-decoration_back.png"
texture_size="100% 0 0 100%"
size="100%-24 0 100%-12 100%"
real_texture_placement="12 0 28 32"
/>
</sprite>
<sprite name="PreviousTipButtonDisabled">
<effect add_color="70 65 50"/>
<image
texture="tipdisplay/button-highlight_disabled.png"
texture_size="100% 0 0 100%"
size="-10 -10 100%+10 100%+10"
real_texture_placement="16 0 80 64"
/>
<image
texture="tipdisplay/button-decoration_front.png"
texture_size="100% 0 0 100%"
size="0 0 24 100%"
real_texture_placement="-8 0 24 32"
/>
<image
texture="tipdisplay/button-decoration_back.png"
texture_size="100% 0 0 100%"
size="100%-24 0 100%-12 100%"
real_texture_placement="12 0 28 32"
/>
</sprite>
<sprite name="PreviousTipButtonMask">
<image backcolor="0 0 0"/>
<image
backcolor="255 255 255"
size="0 0 100%-12 100%"
/>
</sprite>
<!-- NEXT TIP BUTTON -->
<sprite name="NextTipButton">
<image
texture="tipdisplay/button-highlight_base.png"
size="-10 -10 100%+10 100%+10"
/>
<image
texture="tipdisplay/button-decoration_back.png"
size="12 0 24 100%"
/>
<image
texture="tipdisplay/button-decoration_front.png"
size="100%-24 -2 100% 100%+2"
/>
</sprite>
<sprite name="NextTipButtonOver">
<image
texture="tipdisplay/button-highlight_over.png"
size="-10 -10 100%+10 100%+10"
/>
<image
texture="tipdisplay/button-decoration_back.png"
size="12 0 24 100%"
/>
<image
texture="tipdisplay/button-decoration_front.png"
size="100%-24 -2 100% 100%+2"
/>
</sprite>
<sprite name="NextTipButtonPressed">
<image
texture="tipdisplay/button-highlight_pressed.png"
size="-10 -10 100%+10 100%+10"
/>
<image
texture="tipdisplay/button-decoration_back.png"
size="12 0 24 100%"
/>
<image
texture="tipdisplay/button-decoration_front.png"
size="100%-24 -2 100% 100%+2"
/>
</sprite>
<sprite name="NextTipButtonDisabled">
<effect add_color="70 65 50"/>
<image
texture="tipdisplay/button-highlight_disabled.png"
size="-10 -10 100%+10 100%+10"
/>
<image
texture="tipdisplay/button-decoration_back.png"
size="12 0 24 100%"
/>
<image
texture="tipdisplay/button-decoration_front.png"
size="100%-24 -2 100% 100%+2"
/>
</sprite>
<!-- TITLE DECO -->
<sprite name="TipTitleDecoration">
<image
texture="tipdisplay/title-ornament.png"
size="0 0 16 100%"
/>
<image
texture="tipdisplay/title-ornament.png"
texture_size="100% 0 0 100%"
size="100%-16 0 100% 100%"
/>
<image
backcolor="black"
size="11 9 100%-11 11"
/>
</sprite>
</sprites>

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<styles>
<style name="TipTitleText"
font="sans-bold-16"
textcolor="black"
text_align="left"
text_valign="top"
/>
<style name="TipText"
font="sans-bold-14"
textcolor="black"
text_align="left"
text_valign="top"
/>
<style name="PreviousTipButton"
font="sans-bold-16"
textcolor="black"
textcolor_disabled="70 65 50"
text_align="center"
text_valign="center"
sprite="PreviousTipButton"
sprite_disabled="PreviousTipButtonDisabled"
sprite_over="PreviousTipButtonOver"
sprite_pressed="PreviousTipButtonPressed"
sound_pressed="audio/interface/ui/ui_button_click.ogg"
mouse_event_mask="texture:tipdisplay/button_mask_left.png"
/>
<style name="NextTipButton"
font="sans-bold-16"
textcolor="black"
textcolor_disabled="70 65 50"
text_align="center"
text_valign="center"
sprite="NextTipButton"
sprite_disabled="NextTipButtonDisabled"
sprite_over="NextTipButtonOver"
sprite_pressed="NextTipButtonPressed"
sound_pressed="audio/interface/ui/ui_button_click.ogg"
mouse_event_mask="texture:tipdisplay/button_mask_right.png"
/>
</styles>

Some files were not shown because too many files have changed in this diff Show more