mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-08-15 14:43:32 -07:00
Create designated tutorial class in the GUI
This keeps messags.js shorter, prevents unnecessary GetGUIObjectByName calls and, most importantly, makes it a lot more extensible for the future.
This commit is contained in:
parent
0e6e0280fc
commit
663f5c5ff6
6 changed files with 79 additions and 76 deletions
|
|
@ -9,7 +9,7 @@
|
||||||
</object>
|
</object>
|
||||||
|
|
||||||
<object hotkey="session.gui.tutorial.toggle">
|
<object hotkey="session.gui.tutorial.toggle">
|
||||||
<action on="Press">toggleTutorial();</action>
|
<action on="Press">g_Tutorial?.toggle();</action>
|
||||||
</object>
|
</object>
|
||||||
|
|
||||||
<object hotkey="silhouettes">
|
<object hotkey="silhouettes">
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,3 @@
|
||||||
/**
|
|
||||||
* All tutorial messages received so far.
|
|
||||||
*/
|
|
||||||
var g_TutorialMessages = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GUI tags applied to the most recent tutorial message.
|
|
||||||
*/
|
|
||||||
var g_TutorialNewMessageTags = { "color": "255 226 149" };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of seconds we monitor to rate limit flares.
|
* The number of seconds we monitor to rate limit flares.
|
||||||
*/
|
*/
|
||||||
|
|
@ -174,7 +164,7 @@ var g_NotificationsTypes =
|
||||||
},
|
},
|
||||||
"tutorial": function(notification, player)
|
"tutorial": function(notification, player)
|
||||||
{
|
{
|
||||||
updateTutorial(notification);
|
g_Tutorial.update(notification);
|
||||||
},
|
},
|
||||||
"tribute": function(notification, player)
|
"tribute": function(notification, player)
|
||||||
{
|
{
|
||||||
|
|
@ -335,7 +325,7 @@ function findGuidForPlayerID(playerID)
|
||||||
/**
|
/**
|
||||||
* Processes all pending notifications sent from the GUIInterface simulation component.
|
* Processes all pending notifications sent from the GUIInterface simulation component.
|
||||||
*/
|
*/
|
||||||
function handleNotifications(closePageCallback)
|
function handleNotifications()
|
||||||
{
|
{
|
||||||
for (const notification of Engine.GuiInterfaceCall("GetNotifications"))
|
for (const notification of Engine.GuiInterfaceCall("GetNotifications"))
|
||||||
{
|
{
|
||||||
|
|
@ -346,7 +336,7 @@ function handleNotifications(closePageCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const player of notification.players)
|
for (const player of notification.players)
|
||||||
g_NotificationsTypes[notification.type](notification, player, closePageCallback);
|
g_NotificationsTypes[notification.type](notification, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,57 +355,6 @@ function focusAttack(attack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTutorial()
|
|
||||||
{
|
|
||||||
const tutorialPanel = Engine.GetGUIObjectByName("tutorialPanel");
|
|
||||||
tutorialPanel.hidden = !tutorialPanel.hidden || !Engine.GetGUIObjectByName("tutorialText").caption;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the tutorial panel when a new goal.
|
|
||||||
*/
|
|
||||||
function updateTutorial(notification, closePageCallback)
|
|
||||||
{
|
|
||||||
// Show the tutorial panel if not yet done
|
|
||||||
Engine.GetGUIObjectByName("tutorialPanel").hidden = false;
|
|
||||||
|
|
||||||
if (notification.warning)
|
|
||||||
{
|
|
||||||
Engine.GetGUIObjectByName("tutorialWarning").caption = coloredText(translate(notification.warning), "orange");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const notificationText =
|
|
||||||
notification.instructions.reduce((instructions, item) =>
|
|
||||||
instructions + (typeof item === "string" ? translate(item) : colorizeHotkey(translate(item.text), item.hotkey)),
|
|
||||||
"");
|
|
||||||
|
|
||||||
Engine.GetGUIObjectByName("tutorialText").caption = g_TutorialMessages.concat(setStringTags(notificationText, g_TutorialNewMessageTags)).join("\n");
|
|
||||||
g_TutorialMessages.push(notificationText);
|
|
||||||
|
|
||||||
if (notification.readyButton)
|
|
||||||
{
|
|
||||||
Engine.GetGUIObjectByName("tutorialReady").hidden = false;
|
|
||||||
if (notification.leave)
|
|
||||||
{
|
|
||||||
Engine.GetGUIObjectByName("tutorialWarning").caption = translate("Click to quit this tutorial.");
|
|
||||||
Engine.GetGUIObjectByName("tutorialReady").caption = translate("Quit");
|
|
||||||
|
|
||||||
Engine.GetGUIObjectByName("tutorialReady").onPress = () =>
|
|
||||||
{
|
|
||||||
closePageCallback({ [Engine.openRequest]: endGame(true) });
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Engine.GetGUIObjectByName("tutorialWarning").caption = translate("Click when ready.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Engine.GetGUIObjectByName("tutorialWarning").caption = translate("Follow the instructions.");
|
|
||||||
Engine.GetGUIObjectByName("tutorialReady").hidden = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process every CNetMessage (see NetMessage.h, NetMessages.h) sent by the CNetServer.
|
* Process every CNetMessage (see NetMessage.h, NetMessages.h) sent by the CNetServer.
|
||||||
* Saves the received object to mainlog.html.
|
* Saves the received object to mainlog.html.
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ var g_ResearchProgress;
|
||||||
var g_TimeNotificationOverlay;
|
var g_TimeNotificationOverlay;
|
||||||
var g_TopPanel;
|
var g_TopPanel;
|
||||||
var g_TradeDialog;
|
var g_TradeDialog;
|
||||||
|
var g_Tutorial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map, player and match settings set in game setup.
|
* Map, player and match settings set in game setup.
|
||||||
|
|
@ -284,6 +285,7 @@ async function init(initData, hotloadData)
|
||||||
g_DiplomacyColors = new DiplomacyColors();
|
g_DiplomacyColors = new DiplomacyColors();
|
||||||
g_PlayerViewControl = new PlayerViewControl();
|
g_PlayerViewControl = new PlayerViewControl();
|
||||||
g_PlayerViewControl.registerViewedPlayerChangeHandler(g_DiplomacyColors.updateDisplayedPlayerColors.bind(g_DiplomacyColors));
|
g_PlayerViewControl.registerViewedPlayerChangeHandler(g_DiplomacyColors.updateDisplayedPlayerColors.bind(g_DiplomacyColors));
|
||||||
|
g_PlayerViewControl.registerViewedPlayerChangeHandler(resetTemplates);
|
||||||
g_DiplomacyColors.registerDiplomacyColorsChangeHandler(g_PlayerViewControl.rebuild.bind(g_PlayerViewControl));
|
g_DiplomacyColors.registerDiplomacyColorsChangeHandler(g_PlayerViewControl.rebuild.bind(g_PlayerViewControl));
|
||||||
g_DiplomacyColors.registerDiplomacyColorsChangeHandler(updateGUIObjects);
|
g_DiplomacyColors.registerDiplomacyColorsChangeHandler(updateGUIObjects);
|
||||||
g_PauseControl = new PauseControl();
|
g_PauseControl = new PauseControl();
|
||||||
|
|
@ -339,18 +341,17 @@ async function init(initData, hotloadData)
|
||||||
handleNetMessages().catch(reject);
|
handleNetMessages().catch(reject);
|
||||||
}), new Promise(closePageCallback =>
|
}), new Promise(closePageCallback =>
|
||||||
{
|
{
|
||||||
g_PlayerViewControl.registerViewedPlayerChangeHandler(resetTemplates.bind(undefined,
|
|
||||||
closePageCallback));
|
|
||||||
g_Menu = new Menu(g_PauseControl, g_PlayerViewControl, g_Chat, closePageCallback);
|
g_Menu = new Menu(g_PauseControl, g_PlayerViewControl, g_Chat, closePageCallback);
|
||||||
g_NetworkStatusOverlay = new NetworkStatusOverlay(closePageCallback);
|
g_NetworkStatusOverlay = new NetworkStatusOverlay(closePageCallback);
|
||||||
g_QuitConfirmationDefeat = new QuitConfirmationDefeat(closePageCallback);
|
g_QuitConfirmationDefeat = new QuitConfirmationDefeat(closePageCallback);
|
||||||
g_QuitConfirmationReplay = new QuitConfirmationReplay(closePageCallback);
|
g_QuitConfirmationReplay = new QuitConfirmationReplay(closePageCallback);
|
||||||
// TODO: use event instead
|
g_Tutorial = new Tutorial(closePageCallback);
|
||||||
onSimulationUpdate(closePageCallback);
|
|
||||||
Engine.GetGUIObjectByName("session").onSimulationUpdate =
|
|
||||||
onSimulationUpdate.bind(undefined, closePageCallback);
|
|
||||||
})]);
|
})]);
|
||||||
|
|
||||||
|
// TODO: use event instead
|
||||||
|
onSimulationUpdate();
|
||||||
|
Engine.GetGUIObjectByName("session").onSimulationUpdate = onSimulationUpdate;
|
||||||
|
|
||||||
for (const handler of g_PlayersInitHandlers)
|
for (const handler of g_PlayersInitHandlers)
|
||||||
handler();
|
handler();
|
||||||
|
|
||||||
|
|
@ -472,14 +473,14 @@ function initializeMusic()
|
||||||
global.music.setState(global.music.states.PEACE);
|
global.music.setState(global.music.states.PEACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetTemplates(closePageCallback)
|
function resetTemplates()
|
||||||
{
|
{
|
||||||
// Update GUI and clear player-dependent cache
|
// Update GUI and clear player-dependent cache
|
||||||
g_TemplateData = {};
|
g_TemplateData = {};
|
||||||
Engine.GuiInterfaceCall("ResetTemplateModified");
|
Engine.GuiInterfaceCall("ResetTemplateModified");
|
||||||
|
|
||||||
// TODO: do this more selectively
|
// TODO: do this more selectively
|
||||||
onSimulationUpdate(closePageCallback);
|
onSimulationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -677,7 +678,7 @@ function onTick()
|
||||||
Engine.GuiInterfaceCall("ClearRenamedEntities");
|
Engine.GuiInterfaceCall("ClearRenamedEntities");
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSimulationUpdate(closePageCallback)
|
function onSimulationUpdate()
|
||||||
{
|
{
|
||||||
// Templates change depending on technologies and auras, so they have to be reloaded after such a change.
|
// Templates change depending on technologies and auras, so they have to be reloaded after such a change.
|
||||||
// g_TechnologyData data never changes, so it shouldn't be deleted.
|
// g_TechnologyData data never changes, so it shouldn't be deleted.
|
||||||
|
|
@ -705,7 +706,7 @@ function onSimulationUpdate(closePageCallback)
|
||||||
handler();
|
handler();
|
||||||
|
|
||||||
// TODO: Move to handlers
|
// TODO: Move to handlers
|
||||||
handleNotifications(closePageCallback);
|
handleNotifications();
|
||||||
updateGUIObjects();
|
updateGUIObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
<script directory="gui/session/top_panel/"/>
|
<script directory="gui/session/top_panel/"/>
|
||||||
<script directory="gui/session/top_panel/IconButtons/"/>
|
<script directory="gui/session/top_panel/IconButtons/"/>
|
||||||
<script directory="gui/session/trade/"/>
|
<script directory="gui/session/trade/"/>
|
||||||
|
<script directory="gui/session/tutorial/"/>
|
||||||
|
|
||||||
<object name="session">
|
<object name="session">
|
||||||
|
|
||||||
|
|
@ -52,7 +53,7 @@
|
||||||
<include file="gui/session/TimeNotificationOverlay.xml"/>
|
<include file="gui/session/TimeNotificationOverlay.xml"/>
|
||||||
<include file="gui/session/TopPanel.xml"/>
|
<include file="gui/session/TopPanel.xml"/>
|
||||||
<include file="gui/session/trade/TradeDialog.xml"/>
|
<include file="gui/session/trade/TradeDialog.xml"/>
|
||||||
<include file="gui/session/tutorial_panel.xml"/>
|
<include file="gui/session/tutorial/Tutorial.xml"/>
|
||||||
<include file="gui/session/Menu.xml"/>
|
<include file="gui/session/Menu.xml"/>
|
||||||
|
|
||||||
<!-- Contains miscellanious objects s.a.: the technology research -->
|
<!-- Contains miscellanious objects s.a.: the technology research -->
|
||||||
|
|
|
||||||
62
binaries/data/mods/public/gui/session/tutorial/Tutorial.js
Normal file
62
binaries/data/mods/public/gui/session/tutorial/Tutorial.js
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
class Tutorial
|
||||||
|
{
|
||||||
|
panel = Engine.GetGUIObjectByName("tutorialPanel");
|
||||||
|
text = Engine.GetGUIObjectByName("tutorialText");
|
||||||
|
warning = Engine.GetGUIObjectByName("tutorialWarning");
|
||||||
|
readyButton = Engine.GetGUIObjectByName("tutorialReady");
|
||||||
|
instructions = [];
|
||||||
|
closePageCallback;
|
||||||
|
|
||||||
|
constructor(closePageCallback)
|
||||||
|
{
|
||||||
|
this.closePageCallback = closePageCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle()
|
||||||
|
{
|
||||||
|
this.panel.hidden = !this.panel.hidden || !this.text.caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(notification)
|
||||||
|
{
|
||||||
|
this.panel.hidden = false;
|
||||||
|
|
||||||
|
if (notification.warning)
|
||||||
|
{
|
||||||
|
this.warning.caption = coloredText(translate(notification.warning), "orange");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const notificationText =
|
||||||
|
notification.instructions.reduce((instructions, item) =>
|
||||||
|
instructions + (typeof item === "string" ? translate(item) : colorizeHotkey(translate(item.text), item.hotkey)),
|
||||||
|
"");
|
||||||
|
|
||||||
|
this.text.caption = this.instructions.concat(setStringTags(notificationText, this.NewInstructionTags)).join("\n");
|
||||||
|
this.instructions.push(notificationText);
|
||||||
|
|
||||||
|
if (notification.readyButton)
|
||||||
|
{
|
||||||
|
this.readyButton.hidden = false;
|
||||||
|
if (notification.leave)
|
||||||
|
{
|
||||||
|
this.warning.caption = translate("Click to quit this tutorial.");
|
||||||
|
this.readyButton.caption = translate("Quit");
|
||||||
|
this.readyButton.onPress = () => { this.closePageCallback({ [Engine.openRequest]: endGame(true) }); };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.warning.caption = translate("Click when ready.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.warning.caption = translate("Follow the instructions.");
|
||||||
|
this.readyButton.hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GUI tags applied to the most recent instruction.
|
||||||
|
*/
|
||||||
|
Tutorial.prototype.NewInstructionTags = { "color": "255 226 149" };
|
||||||
|
|
||||||
Loading…
Reference in a new issue