mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-08-15 14:43:32 -07:00
Revise tutorial step handling
- Remove the delay functionality from the tutorial. It was unused and that for a reason. Switching to the next step after a fixed amount of time is never wanted. It was only used to force-show the ready button in one case, but a designated bool communicates the purpose better. - Rename the "ready" button to "continue" as it fits better. - Rename "leave" to "isLast" as it's more descriptive. - Rename the "warning" object of the instruction panel to "hint" as it's not always display warnings, and move its captions to the class prototype like the coding conventions state. - Simplify the logic in NextStep a bit to make it more readable.
This commit is contained in:
parent
f3b71a1fbf
commit
702e3f1113
4 changed files with 41 additions and 45 deletions
|
|
@ -6,17 +6,17 @@ class InstructionPanel
|
|||
{
|
||||
panel = Engine.GetGUIObjectByName("instructionPanel");
|
||||
text = Engine.GetGUIObjectByName("instructionPanelText");
|
||||
warning = Engine.GetGUIObjectByName("instructionPanelWarning");
|
||||
readyButton = Engine.GetGUIObjectByName("instructionPanelReady");
|
||||
hint = Engine.GetGUIObjectByName("instructionPanelHint");
|
||||
continueButton = Engine.GetGUIObjectByName("instructionPanelContinueButton");
|
||||
instructions = [];
|
||||
closePage;
|
||||
|
||||
constructor(closePage)
|
||||
{
|
||||
this.closePage = closePage;
|
||||
this.readyButton.onPress = () =>
|
||||
this.continueButton.onPress = () =>
|
||||
{
|
||||
Engine.PostNetworkCommand({ "type": "dialog-answer", "tutorial": "ready" });
|
||||
Engine.PostNetworkCommand({ "type": "dialog-answer", "tutorial": "continue" });
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ class InstructionPanel
|
|||
|
||||
displayWarning(warning)
|
||||
{
|
||||
this.warning.caption = setStringTags(warning, this.WarningTags);
|
||||
this.hint.caption = setStringTags(warning, this.WarningTags);
|
||||
}
|
||||
|
||||
displayStep(panelData)
|
||||
|
|
@ -35,22 +35,22 @@ class InstructionPanel
|
|||
this.text.caption = this.instructions.concat(setStringTags(panelData.text, this.NewInstructionTags)).join("\n");
|
||||
this.instructions.push(panelData.text);
|
||||
|
||||
if (panelData.readyButton)
|
||||
if (panelData.showContinueButton)
|
||||
{
|
||||
this.readyButton.hidden = false;
|
||||
if (panelData.leave)
|
||||
this.continueButton.hidden = false;
|
||||
if (panelData.isLast)
|
||||
{
|
||||
this.warning.caption = translate("Click to quit this tutorial.");
|
||||
this.readyButton.caption = translate("Quit");
|
||||
this.readyButton.onPress = this.closePage;
|
||||
this.hint.caption = translate("Click to quit this tutorial.");
|
||||
this.continueButton.caption = translate("Quit");
|
||||
this.continueButton.onPress = this.closePage;
|
||||
}
|
||||
else
|
||||
this.warning.caption = translate("Click when ready.");
|
||||
this.hint.caption = this.HintCaptions.Continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.warning.caption = translate("Follow the instructions.");
|
||||
this.readyButton.hidden = true;
|
||||
this.hint.caption = this.HintCaptions.Instruction;
|
||||
this.continueButton.hidden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -64,3 +64,9 @@ InstructionPanel.prototype.NewInstructionTags = { "color": "255 226 149" };
|
|||
* Tags applied to warning messages.
|
||||
*/
|
||||
InstructionPanel.prototype.WarningTags = { "color": "orange" };
|
||||
|
||||
InstructionPanel.prototype.HintCaptions = {
|
||||
"Continue": translate("Click when continue."),
|
||||
"Instruction": translate("Follow the instructions."),
|
||||
"Quit": translate("Click to quit this tutorial.")
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
<object size="10 10 100%-20 100%-48">
|
||||
<object name="instructionPanelText" type="text" style="TutorialPanel"/>
|
||||
</object>
|
||||
<object name="instructionPanelWarning" type="text" style="ModernLeftLabelText" size="10 100%-42 100%-20 100%-12"/>
|
||||
<object name="instructionPanelReady" type="button" style="ModernButtonRed" size="100%-160 100%-42 100%-20 100%-12">
|
||||
<translatableAttribute id="caption">Ready</translatableAttribute>
|
||||
<object name="instructionPanelHint" type="text" style="ModernLeftLabelText" size="10 100%-42 100%-20 100%-12"/>
|
||||
<object name="instructionPanelContinueButton" type="button" style="ModernButtonRed" size="100%-160 100%-42 100%-20 100%-12">
|
||||
<translatableAttribute id="caption">Continue</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
|
|
|||
|
|
@ -39,16 +39,11 @@ Trigger.prototype.NextStep = function(deserializing = false)
|
|||
if (this.index > this.tutorialSteps.length)
|
||||
return;
|
||||
const step = this.tutorialSteps[this.index];
|
||||
let needDelay = true;
|
||||
let readyButton = false;
|
||||
|
||||
Trigger.prototype.Init = step.Init || null;
|
||||
if (!deserializing && this.Init)
|
||||
this.Init();
|
||||
|
||||
Trigger.prototype.IsDone = step.IsDone || (() => false);
|
||||
const stepAlreadyDone = this.IsDone();
|
||||
|
||||
for (const event of this.tutorialEvents)
|
||||
{
|
||||
const action = event + "Trigger";
|
||||
|
|
@ -56,36 +51,31 @@ Trigger.prototype.NextStep = function(deserializing = false)
|
|||
{
|
||||
Trigger.prototype[action] = step[event];
|
||||
this.EnableTrigger(event, action);
|
||||
if (!stepAlreadyDone)
|
||||
needDelay = false;
|
||||
}
|
||||
else
|
||||
this.DisableTrigger(event, action);
|
||||
}
|
||||
|
||||
// Steps without actions to be performed by the player must have
|
||||
// - either the property delay (a value > 0 to wait for a given time, and -1 to display the Ready button)
|
||||
// - or no trigger functions (needDelay will be set automatically to true and the Ready button displayed)
|
||||
if (step.delay || needDelay)
|
||||
Trigger.prototype.IsDone = step.IsDone || (() => false);
|
||||
const showContinueButton =
|
||||
step.panelData.showContinueButton === undefined ?
|
||||
this.IsDone() || this.tutorialEvents.every(event => !step[event]) :
|
||||
step.panelData.showContinueButton;
|
||||
|
||||
if (showContinueButton)
|
||||
{
|
||||
if (step.delay && step.delay > 0)
|
||||
this.DoAfterDelay(+step.delay, "NextStep", {});
|
||||
else
|
||||
this.EnableTrigger("OnPlayerCommand", "OnPlayerCommandTrigger");
|
||||
Trigger.prototype.OnPlayerCommandTrigger = function(msg)
|
||||
{
|
||||
this.EnableTrigger("OnPlayerCommand", "OnPlayerCommandTrigger");
|
||||
Trigger.prototype.OnPlayerCommandTrigger = function(msg)
|
||||
{
|
||||
if (msg.cmd.type == "dialog-answer" && msg.cmd.tutorial && msg.cmd.tutorial == "ready")
|
||||
this.NextStep();
|
||||
};
|
||||
readyButton = true;
|
||||
}
|
||||
if (msg.cmd.type == "dialog-answer" && msg.cmd.tutorial && msg.cmd.tutorial == "continue")
|
||||
this.NextStep();
|
||||
};
|
||||
}
|
||||
|
||||
this.DisplayStep(step, readyButton, ++this.index == this.tutorialSteps.length);
|
||||
this.DisplayStep(step, showContinueButton, ++this.index == this.tutorialSteps.length);
|
||||
};
|
||||
|
||||
Trigger.prototype.DisplayStep = function(step, readyButton = false, leave = false)
|
||||
Trigger.prototype.DisplayStep = function(step, showContinueButton = false, isLast = false)
|
||||
{
|
||||
const cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
cmpGUIInterface.PushNotification({
|
||||
|
|
@ -95,8 +85,8 @@ Trigger.prototype.DisplayStep = function(step, readyButton = false, leave = fals
|
|||
"type": step.type,
|
||||
"panelData": {
|
||||
...step.panelData,
|
||||
"readyButton": readyButton,
|
||||
"leave": leave
|
||||
"showContinueButton": showContinueButton,
|
||||
"isLast": isLast
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -274,9 +274,9 @@ Trigger.prototype.tutorialSteps = [
|
|||
"panelData": {
|
||||
"text":
|
||||
markForTranslation("You may notice that berries are a finite supply of food. We will need a more lasting food source. Fields produce an unlimited food resource, but are slower to gather than forageable fruits.\n") +
|
||||
markForTranslation("But to minimize the distance between a farm and its corresponding food dropsite, we will first build a Farmstead.")
|
||||
markForTranslation("But to minimize the distance between a farm and its corresponding food dropsite, we will first build a Farmstead."),
|
||||
"showContinueButton": true
|
||||
},
|
||||
"delay": -1,
|
||||
"OnOwnershipChanged": function(msg)
|
||||
{
|
||||
if (this.houseGoal.has(+msg.entity))
|
||||
|
|
|
|||
Loading…
Reference in a new issue