Extend the tips page for multiple images per tip

Enable the Tips and Tricks page to show multiple images for each tip.
Add a small GUI panel below the image for switching between them.
Only show it when the current tip has more than one images.

Introduce tipfiles.json to assign images to the text files.
(And stop of relying on file naming)

Add a tip about wonders, and make some slight changes to other texts.
Improve existing tip images and add a bunch of new ones.
This commit is contained in:
Vantha 2024-12-03 21:52:23 +01:00 committed by Nicolas Auvray
parent a949940ff8
commit d7dda097e1
34 changed files with 639 additions and 58 deletions

View file

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

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d8d35bec52b327e6616c3604a0374c6a5421a411ae1f9c9d62bd61078afab2c7
size 413825
oid sha256:2780a4b1d089ea77912798930ef0d183094cc7d348d8787d100e70ce7c085030
size 480924

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cee6ea8fd639ec4628cebb0c5ef6044a451e35ad6e63dc11b2a060d94c3d988a
size 505920
oid sha256:d5fec420dfaa0693dc93187f173e7a53680d564445dcef8375d310389e7b2a74
size 516779

View file

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

View file

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

View file

@ -58,6 +58,7 @@
{ "nick": "Sundiata", "name": "Malcolm Kwadwo Kwarte Quartey" },
{ "nick": "ThorRune" },
{ "name": "Tsaag Valren" },
{ "nick": "Vantha" },
{ "name": "Veronica L. Almy Wright" },
{ "nick": "Victor Rossi", "name": "Victor Rossi" },
{ "nick": "wackyserious", "name": "Arjel Kenneth Abulog" },

View file

@ -297,7 +297,7 @@
{ "nick": "tpearson", "name": "Timothy Pearson" },
{ "nick": "user1", "name": "A. C." },
{ "nick": "usey11" },
{ "nick": "Vantha"},
{ "nick": "Vantha" },
{ "nick": "vincent_c", "name": "Vincent Cheng" },
{ "nick": "vinhig", "name": "Vincent Higginson" },
{ "nick": "vladislavbelov", "name": "Vladislav Belov" },

View file

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

View file

@ -36,7 +36,7 @@ var g_MainMenuItems = [
"caption": translate("Tips and Tricks"),
"tooltip": translate("Discover simple tips, tricks, and game mechanics."),
"onPress": () => {
Engine.PushGuiPage("page_tips.xml");
Engine.PushGuiPage("page_tips.xml", { "tipScrolling": true });
}
},
{

View file

@ -1,8 +1,8 @@
class TipsPage
{
constructor()
constructor(initData, hotloadData)
{
this.tipDisplay = new TipDisplay();
this.tipDisplay = new TipDisplay(initData, hotloadData);
this.closeButton = new CloseButton(this);
}

View file

@ -1,65 +1,96 @@
/**
* This class is concerned with chosing and displaying tips about how to play the game.
* This includes a text and an image.
* This includes a text and one or more images.
*/
class TipDisplay
{
/**
* @param {boolean} tipScrolling - Whether or not to enable the player to scroll through the tips.
* @param {boolean} initData.tipScrolling - Whether or not to enable the player to scroll through the tips and the tip images.
* @param {Array|undefined} hotloadData.tipFilesData - Hotloaded value storing last time's tipFilesData.
* @param {number|undefined} hotloadData.tipIndex - Hotloaded value pointing to a specific tip.
* @param {number|undefined} hotloadData.tipImageIndex - Hotloaded value pointing to a specific tip image.
*/
constructor(tipScrolling = true)
constructor(initData, hotloadData)
{
this.tipImage = Engine.GetGUIObjectByName("tipImage");
this.tipTitle = Engine.GetGUIObjectByName("tipTitle");
this.tipTitleDecoration = Engine.GetGUIObjectByName("tipTitleDecoration");
this.tipText = Engine.GetGUIObjectByName("tipText");
this.tipImageText = Engine.GetGUIObjectByName("tipImageText");
this.previousTipButton = Engine.GetGUIObjectByName("previousTipButton");
this.imageControlPanel = Engine.GetGUIObjectByName("imageControlPanel");
this.nextTipButton = Engine.GetGUIObjectByName("nextTipButton");
this.previousImageButton = Engine.GetGUIObjectByName("previousImageButton");
this.nextImageButton = Engine.GetGUIObjectByName("nextImageButton");
this.previousTipButton.caption = this.CaptionPreviousTip;
this.previousTipButton.tooltip = colorizeHotkey("%(hotkey)s: ", "item.prev") + this.TooltipPreviousTip;
this.nextTipButton.caption = this.CaptionNextTip;
this.previousTipButton.tooltip = colorizeHotkey("%(hotkey)s: ", "item.prev") + this.TooltipPreviousTip;
this.nextTipButton.tooltip = colorizeHotkey("%(hotkey)s: ", "item.next") + this.TooltipNextTip;
this.previousImageButton.tooltip = this.TooltipPreviousImage;
this.nextImageButton.tooltip = this.TooltipNextImage;
this.tipFiles = shuffleArray(listFiles(this.TextPath, ".txt", false));
if (this.tipFiles.length === 0)
{
warn("Failed to find any tips to display.");
return;
}
this.tipFilesData =
hotloadData?.tipFilesData ||
shuffleArray(
Engine.ReadJSONFile(this.TipFilesDataFile)
).map(tip => {
tip.imageFiles = shuffleArray(tip.imageFiles);
return tip;
});
const hideButtons = !tipScrolling || this.tipFiles.length < 2;
this.currentTip = {};
this.tipIndex = -1;
this.tipImageIndex = -1;
this.enableTipScrolling = initData.tipScrolling;
const hideButtons = !initData.tipScrolling || this.tipFilesData.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);
this.previousTipButton.onPress = () => this.onTipIndexChange(-1);
this.nextTipButton.onPress = () => this.onTipIndexChange(1);
this.previousImageButton.onPress = () => this.onTipImageIndexChange(-1);
this.nextImageButton.onPress = () => this.onTipImageIndexChange(1);
this.onTipIndexChange(hotloadData?.tipIndex ? hotloadData.tipIndex + 1 : 1);
if (hotloadData?.tipImageIndex)
this.onTipImageIndexChange(hotloadData.tipImageIndex + 1);
}
onIndexChange(number)
getHotloadData()
{
this.tipFilesIndex += number;
this.tipFilesIndex = Math.max(0, Math.min(this.tipFilesIndex, this.tipFiles.length - 1));
this.displayTip(this.tipFiles[this.tipFilesIndex]);
this.rebuildButtons();
return {
"tipFilesData": this.tipFilesData,
"tipIndex": this.tipIndex,
"tipImageIndex": this.tipImageIndex
};
}
rebuildButtons()
onTipIndexChange(number)
{
this.previousTipButton.enabled = this.tipFilesIndex !== 0 && !this.previousTipButton.hidden;
this.nextTipButton.enabled = this.tipFilesIndex < this.tipFiles.length - 1 && !this.nextTipButton.hidden;
this.tipIndex += number;
this.tipIndex = Math.max(0, Math.min(this.tipIndex, this.tipFilesData.length - 1));
this.currentTip = this.tipFilesData[this.tipIndex];
this.updateTipText();
this.rebuildTipButtons();
this.onTipImageIndexChange(-this.tipImageIndex);
}
displayTip(tipFile)
onTipImageIndexChange(number)
{
this.tipImage.sprite = "stretched:" + this.ImagePath + tipFile + ".png";
this.tipImageIndex += number;
this.tipImageIndex = Math.max(0, Math.min(this.tipImageIndex, this.currentTip.imageFiles.length - 1));
const tipText = Engine.TranslateLines(Engine.ReadFile(
this.TextPath + tipFile + ".txt")).split("\n");
this.updateTipImage();
this.rebuildTipImageButtons();
}
updateTipText()
{
const tipText = Engine.TranslateLines(Engine.ReadFile(this.TextPath + this.currentTip.textFile)).split("\n");
this.tipTitle.caption = tipText.shift();
this.scaleGuiElementsToFit();
@ -67,6 +98,27 @@ class TipDisplay
text && "[icon=\"BulletPoint\"] " + text).join("\n\n");
}
updateTipImage()
{
this.tipImage.sprite = "stretched:" + this.ImagePath + this.currentTip.imageFiles[this.tipImageIndex];
this.imageControlPanel.hidden = !this.enableTipScrolling || this.currentTip.imageFiles.length === 1;
if (!this.imageControlPanel.hidden)
this.tipImageText.caption = (this.tipImageIndex + 1) + " / " + this.currentTip.imageFiles.length;
}
rebuildTipButtons()
{
this.previousTipButton.enabled = !this.previousTipButton.hidden && this.tipIndex !== 0;
this.nextTipButton.enabled = !this.nextTipButton.hidden && this.tipIndex < this.tipFilesData.length - 1;
}
rebuildTipImageButtons()
{
this.previousImageButton.enabled = this.tipImageIndex > 0;
this.nextImageButton.enabled = this.tipImageIndex < this.currentTip.imageFiles.length - 1;
}
scaleGuiElementsToFit()
{
const titleSize = this.tipTitle.size;
@ -92,12 +144,20 @@ TipDisplay.prototype.TooltipPreviousTip = translate("Switch to the previous tip.
TipDisplay.prototype.CaptionNextTip = translateWithContext("button", "Next");
TipDisplay.prototype.TooltipNextTip = translate("Switch to the next tip.");
TipDisplay.prototype.TooltipPreviousImage = translate("Switch to the previous image.");
TipDisplay.prototype.TooltipNextImage = translate("Switch to the next image.");
/**
* JSON file assigning one or more tip image files (.png) to each tip text file (.txt).
*/
TipDisplay.prototype.TipFilesDataFile = "gui/reference/tips/tipfiles.json";
/**
* 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.
* Subdirectory of art/textures/ui storing the .png images illustrating the tips.
*/
TipDisplay.prototype.ImagePath = "tips/";

View file

@ -1,11 +1,15 @@
<?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 type="image" name="imageControlPanel" sprite="ModernFade" size="80 398 440 430">
<object type="image" sprite="TipImageFrame"/>
<object type="text" name="tipImageText" style="TipImageText"/>
<object type="button" name="previousImageButton" style="PreviousImageButton" size="43 9 57 23"/>
<object type="button" name="nextImageButton" style="NextImageButton" size="303 9 317 23"/>
</object>
<object type="image" sprite="TipImageFrame" size="0 0 520 392" ghost="true">
<object name="tipImage" size="4 4 516 516" type="image">
<object type="image" sprite="stretched:tipdisplay/tip-image-gradient.png"/>
</object>
</object>

View file

@ -227,6 +227,77 @@
</sprite>
<!-- PREVIOUS IMAGE BUTTON -->
<sprite name="PreviousImageButton">
<effect add_color="255 255 255"/>
<image
texture="tipdisplay/arrow.png"
/>
</sprite>
<sprite name="PreviousImageButtonOver">
<effect add_color="152 133 43"/>
<image
texture="tipdisplay/arrow.png"
/>
</sprite>
<sprite name="PreviousImageButtonPressed">
<effect add_color="204 180 57"/>
<image
texture="tipdisplay/arrow.png"
/>
</sprite>
<sprite name="PreviousImageButtonDisabled">
<effect add_color="90 90 90"/>
<image
texture="tipdisplay/arrow.png"
/>
</sprite>
<!-- NEXT IMAGE BUTTON
Note that the textures are mirrored horizontally (by setting the texure_size) -->
<sprite name="NextImageButton">
<effect add_color="255 255 255"/>
<image
texture="tipdisplay/arrow.png"
texture_size="100% 0 0 100%"
real_texture_placement="-16 0 16 32"
/>
</sprite>
<sprite name="NextImageButtonOver">
<effect add_color="152 133 43"/>
<image
texture="tipdisplay/arrow.png"
texture_size="100% 0 0 100%"
real_texture_placement="-16 0 16 32"
/>
</sprite>
<sprite name="NextImageButtonPressed">
<effect add_color="204 180 57"/>
<image
texture="tipdisplay/arrow.png"
texture_size="100% 0 0 100%"
real_texture_placement="-16 0 16 32"
/>
</sprite>
<sprite name="NextImageButtonDisabled">
<effect add_color="90 90 90"/>
<image
texture="tipdisplay/arrow.png"
texture_size="100% 0 0 100%"
real_texture_placement="-16 0 16 32"
/>
</sprite>
<!-- TITLE DECO -->
<sprite name="TipTitleDecoration">
<image

View file

@ -15,6 +15,13 @@
text_valign="top"
/>
<style name="TipImageText"
font="sans-bold-16"
textcolor="white"
text_align="center"
text_valign="center"
/>
<style name="PreviousTipButton"
font="sans-bold-16"
textcolor="black"
@ -43,4 +50,20 @@
mouse_event_mask="texture:tipdisplay/button_mask_right.png"
/>
<style name="PreviousImageButton"
sprite="PreviousImageButton"
sprite_over="PreviousImageButtonOver"
sprite_pressed="PreviousImageButtonPressed"
sprite_disabled="PreviousImageButtonDisabled"
sound_pressed="audio/interface/ui/ui_button_click.ogg"
/>
<style name="NextImageButton"
sprite="NextImageButton"
sprite_over="NextImageButtonOver"
sprite_pressed="NextImageButtonPressed"
sprite_disabled="NextImageButtonDisabled"
sound_pressed="audio/interface/ui/ui_button_click.ogg"
/>
</styles>

View file

@ -1,3 +1,3 @@
TREASURES
Collectible chests, bare resources on land, and shipwrecks on the shore.
Collectible chests, bare resources on land, and shipwrecks in the sea.
Provide you with an instant resource boost, so keep an eye out for them as you explore.

View file

@ -0,0 +1,5 @@
WONDER
A powerful and expensive late-game structure available to all civilizations.
Represents an actual monumental structure built by that culture in antiquity.
Provides the technology “Glorious Expansion” which increases your maximum population capacity by 20%.
Enable the victory condition “Wonder” in the game setup and race to see who can build one first (and control it for a certain amount of time)!

View file

@ -0,0 +1,364 @@
[
{
"textFile": "army_camp.txt",
"imageFiles": [
"army_camp.png"
]
},
{
"textFile": "arrow_ship.txt",
"imageFiles": [
"arrow_ship.png"
]
},
{
"textFile": "autoqueue.txt",
"imageFiles": [
"autoqueue.png"
]
},
{
"textFile": "barracks.txt",
"imageFiles": [
"barracks.png"
]
},
{
"textFile": "barter.txt",
"imageFiles": [
"barter.png"
]
},
{
"textFile": "biomes.txt",
"imageFiles": [
"biomes.png"
]
},
{
"textFile": "briton_war_dog.txt",
"imageFiles": [
"briton_war_dog.png"
]
},
{
"textFile": "carth_sacred_band.txt",
"imageFiles": [
"carth_sacred_band.png"
]
},
{
"textFile": "carth_shipyard.txt",
"imageFiles": [
"carth_shipyard.png"
]
},
{
"textFile": "catapults.txt",
"imageFiles": [
"catapults.png"
]
},
{
"textFile": "cavalry_stable.txt",
"imageFiles": [
"cavalry_stable.png"
]
},
{
"textFile": "celtic_war_barge.txt",
"imageFiles": [
"celtic_war_barge.png"
]
},
{
"textFile": "city_walls.txt",
"imageFiles": [
"city_walls.png"
]
},
{
"textFile": "civic_center.txt",
"imageFiles": [
"civic_center.png"
]
},
{
"textFile": "control_groups.txt",
"imageFiles": [
"control_groups.png"
]
},
{
"textFile": "default_formation.txt",
"imageFiles": [
"default_formation.png"
]
},
{
"textFile": "defense_tower.txt",
"imageFiles": [
"defense_tower.png"
]
},
{
"textFile": "dock.txt",
"imageFiles": [
"dock.png"
]
},
{
"textFile": "elephant_stable.txt",
"imageFiles": [
"elephant_stable.png"
]
},
{
"textFile": "embassies.txt",
"imageFiles": [
"embassies.png"
]
},
{
"textFile": "fire_ship.txt",
"imageFiles": [
"fire_ship.png"
]
},
{
"textFile": "fishing.txt",
"imageFiles": [
"fishing.png"
]
},
{
"textFile": "forge.txt",
"imageFiles": [
"forge_iber.png",
"forge_maur.png",
"forge_rome.png"
]
},
{
"textFile": "formations.txt",
"imageFiles": [
"formations.png"
]
},
{
"textFile": "fortress.txt",
"imageFiles": [
"fortress_han.png",
"fortress_iber.png",
"fortress_maur.png"
]
},
{
"textFile": "freehand_position.txt",
"imageFiles": [
"freehand_position.png"
]
},
{
"textFile": "gathering.txt",
"imageFiles": [
"gathering.png"
]
},
{
"textFile": "heroes.txt",
"imageFiles": [
"heroes.png"
]
},
{
"textFile": "lighthouse.txt",
"imageFiles": [
"lighthouse.png"
]
},
{
"textFile": "loot.txt",
"imageFiles": [
"loot.png"
]
},
{
"textFile": "map_flare.txt",
"imageFiles": [
"map_flare.png"
]
},
{
"textFile": "mauryan_worker_elephant.txt",
"imageFiles": [
"mauryan_worker_elephant.png"
]
},
{
"textFile": "meroe_pyramids.txt",
"imageFiles": [
"meroe_pyramids.png"
]
},
{
"textFile": "nomad_mode.txt",
"imageFiles": [
"nomad_mode.png"
]
},
{
"textFile": "order_one_unit.txt",
"imageFiles": [
"order_one_unit.png"
]
},
{
"textFile": "outposts.txt",
"imageFiles": [
"outposts.png"
]
},
{
"textFile": "palisades.txt",
"imageFiles": [
"palisades.png"
]
},
{
"textFile": "persian_architecture.txt",
"imageFiles": [
"persian_architecture.png"
]
},
{
"textFile": "pikemen.txt",
"imageFiles": [
"pikemen.png"
]
},
{
"textFile": "queue_orders.txt",
"imageFiles": [
"queue_orders.png"
]
},
{
"textFile": "ramming_ship.txt",
"imageFiles": [
"ramming_ship.png"
]
},
{
"textFile": "resource_counter.txt",
"imageFiles": [
"resource_counter.png"
]
},
{
"textFile": "savanna_biome.txt",
"imageFiles": [
"savanna_biome.png"
]
},
{
"textFile": "select_wounded_units.txt",
"imageFiles": [
"select_wounded_units.png"
]
},
{
"textFile": "shrine.txt",
"imageFiles": [
"shrine.png"
]
},
{
"textFile": "siege_ship.txt",
"imageFiles": [
"siege_ship.png"
]
},
{
"textFile": "snapping.txt",
"imageFiles": [
"snapping.png"
]
},
{
"textFile": "spartan_hoplites.txt",
"imageFiles": [
"spartan_hoplites.png"
]
},
{
"textFile": "spearmen.txt",
"imageFiles": [
"spearmen.png"
]
},
{
"textFile": "storehouse.txt",
"imageFiles": [
"storehouse_1.png",
"storehouse_2.png"
]
},
{
"textFile": "syntagma.txt",
"imageFiles": [
"syntagma.png"
]
},
{
"textFile": "temple.txt",
"imageFiles": [
"temple_gaul.png",
"temple_greek.png",
"temple_pers.png"
]
},
{
"textFile": "territory_decay.txt",
"imageFiles": [
"territory_decay.png"
]
},
{
"textFile": "theater.txt",
"imageFiles": [
"theater.png"
]
},
{
"textFile": "trading.txt",
"imageFiles": [
"trading.png"
]
},
{
"textFile": "treasure.txt",
"imageFiles": [
"treasure.png"
]
},
{
"textFile": "war_elephants.txt",
"imageFiles": [
"war_elephants.png"
]
},
{
"textFile": "whales.txt",
"imageFiles": [
"whales.png"
]
},
{
"textFile": "wonder.txt",
"imageFiles": [
"wonder_gaul.png",
"wonder_han.png"
]
}
]

View file

@ -1,4 +1,11 @@
function init()
var g_TipsPage;
function init(initData, hotloadData)
{
var g_TipsPage = new TipsPage();
g_TipsPage = new TipsPage(initData, hotloadData);
}
function getHotloadData()
{
return g_TipsPage?.tipDisplay.getHotloadData();
}

View file

@ -4,7 +4,7 @@
<script directory="gui/reference/tips/"/>
<script directory="gui/reference/common/Buttons/"/>
<object type="image" sprite="BackgroundTranslucent"/>
<object type="image" size="50%-502 50%-246 50%+502 50%+246" sprite="ModernDialog">
<object type="image" size="50%-502 50%-250 50%+502 50%+250" sprite="ModernDialog">
<object style="TitleText" type="text" size="50%-128 -18 50%+128 14">
<translatableAttribute id="caption">Tips and Tricks</translatableAttribute>
</object>

View file

@ -714,10 +714,24 @@ class CheckRefs:
def add_tips(self):
self.logger.info("Loading tips...")
for fp, _ffp in sorted(self.find_files("gui/reference/tips/texts/", "txt")):
self.files.extend([fp for (fp, _ffp) in self.find_files("gui/reference/tips/", ("txt"))])
ffp = None
fp = Path("gui/reference/tips/tipfiles.json")
for mod in self.mods:
json_path = self.vfs_root / mod / fp
if json_path.exists():
ffp = json_path
if ffp is None:
self.logger.error("Failed to load tips. File tipfiles.json missing.")
else:
self.files.append(fp)
self.roots.append(fp)
self.deps.append((fp, Path(f"art/textures/ui/tips/{fp.stem}.png")))
with open(ffp, encoding="utf-8") as f:
tips = load(f)
for tip in tips:
self.deps.append((fp, Path(f"gui/reference/tips/texts/{tip['textFile']}")))
for image in tip.get("imageFiles", []):
self.deps.append((fp, Path(f"art/textures/ui/tips/{image}")))
def add_rms(self):
self.logger.info("Loading random maps...")