Rename tutorial "goals" to "steps"

While it's currently the case everywhere, tutorial "steps" don't
necessarily have to be goals, they could be stuff like tips or info too
in general, if different types of "steps" are added in the future.
This commit is contained in:
Vantha
2026-02-24 17:09:07 +01:00
committed by Vantha
parent dd396f19b6
commit ab4a9d6def
4 changed files with 95 additions and 95 deletions
@@ -19,8 +19,8 @@ class Tutorial
handleNotification(notification)
{
if (notification.goal)
this.displayGoal(notification.goal);
if (notification.step)
this.displayStep(notification.step);
if (notification.warning)
this.displayWarning(notification.warning);
}
@@ -30,22 +30,22 @@ class Tutorial
this.warning.caption = coloredText(translate(warning), "orange");
}
displayGoal(goal)
displayStep(step)
{
this.panel.hidden = false;
const notificationText =
goal.instructions.reduce((instructions, item) =>
step.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 (goal.readyButton)
if (step.readyButton)
{
this.readyButton.hidden = false;
if (goal.leave)
if (step.leave)
{
this.warning.caption = translate("Click to quit this tutorial.");
this.readyButton.caption = translate("Quit");
@@ -9,11 +9,11 @@ Trigger.prototype.InitTutorial = function(data)
this.RegisterTrigger("OnPlayerCommand", "OnPlayerCommandTrigger", { "enabled": false });
this.tutorialEvents.push("OnPlayerCommand");
for (const goal of this.tutorialGoals)
for (const step of this.tutorialSteps)
{
for (const key in goal)
for (const key in step)
{
if (typeof goal[key] !== "function" || this.tutorialEvents.indexOf(key) != -1)
if (typeof step[key] !== "function" || this.tutorialEvents.indexOf(key) != -1)
continue;
if (key == "Init")
continue;
@@ -25,67 +25,67 @@ Trigger.prototype.InitTutorial = function(data)
}
}
this.NextGoal();
this.NextStep();
};
Trigger.prototype.NextGoal = function(deserializing = false)
Trigger.prototype.NextStep = function(deserializing = false)
{
if (this.index > this.tutorialGoals.length)
if (this.index > this.tutorialSteps.length)
return;
const goal = this.tutorialGoals[this.index];
const step = this.tutorialSteps[this.index];
let needDelay = true;
let readyButton = false;
Trigger.prototype.Init = goal.Init || null;
Trigger.prototype.Init = step.Init || null;
if (!deserializing && this.Init)
this.Init();
Trigger.prototype.IsDone = goal.IsDone || (() => false);
const goalAlreadyDone = this.IsDone();
Trigger.prototype.IsDone = step.IsDone || (() => false);
const stepAlreadyDone = this.IsDone();
for (const event of this.tutorialEvents)
{
const action = event + "Trigger";
if (goal[event])
if (step[event])
{
Trigger.prototype[action] = goal[event];
Trigger.prototype[action] = step[event];
this.EnableTrigger(event, action);
if (!goalAlreadyDone)
if (!stepAlreadyDone)
needDelay = false;
}
else
this.DisableTrigger(event, action);
}
// Goals without actions to be performed by the player must have
// 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 (goal.delay || needDelay)
if (step.delay || needDelay)
{
if (goal.delay && goal.delay > 0)
this.DoAfterDelay(+goal.delay, "NextGoal", {});
if (step.delay && step.delay > 0)
this.DoAfterDelay(+step.delay, "NextStep", {});
else
{
this.EnableTrigger("OnPlayerCommand", "OnPlayerCommandTrigger");
Trigger.prototype.OnPlayerCommandTrigger = function(msg)
{
if (msg.cmd.type == "dialog-answer" && msg.cmd.tutorial && msg.cmd.tutorial == "ready")
this.NextGoal();
this.NextStep();
};
readyButton = true;
}
}
this.GoalMessage(goal.instructions, readyButton, ++this.index == this.tutorialGoals.length);
this.DisplayStep(step.instructions, readyButton, ++this.index == this.tutorialSteps.length);
};
Trigger.prototype.GoalMessage = function(instructions, readyButton=false, leave=false)
Trigger.prototype.DisplayStep = function(instructions, readyButton=false, leave=false)
{
const cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGUIInterface.PushNotification({
"type": "tutorial",
"players": [1],
"goal": {
"step": {
"instructions": typeof instructions === "string" ? [instructions] : instructions,
"readyButton": readyButton,
"leave": leave
@@ -93,7 +93,7 @@ Trigger.prototype.GoalMessage = function(instructions, readyButton=false, leave=
});
};
Trigger.prototype.WarningMessage = function(warning)
Trigger.prototype.DisplayWarning = function(warning)
{
const cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGUIInterface.PushNotification({
@@ -107,9 +107,9 @@ Trigger.prototype.OnDeserializedTrigger = function()
{
this.index = Math.max(0, this.index - 1);
// Display messages from already processed goals
// Display messages from already processed steps
for (let i = 0; i < this.index; ++i)
this.GoalMessage(this.tutorialGoals[i].instructions, false, false);
this.DisplayStep(this.tutorialSteps[i].instructions, false, false);
this.NextGoal(true);
this.NextStep(true);
};
@@ -1,4 +1,4 @@
Trigger.prototype.tutorialGoals = [
Trigger.prototype.tutorialSteps = [
{
"instructions": markForTranslation("Welcome to the 0\xa0A.D. tutorial."),
},
@@ -8,7 +8,7 @@ Trigger.prototype.tutorialGoals = [
{
if (msg.cmd.type == "gather" && msg.cmd.target &&
TriggerHelper.GetResourceType(msg.cmd.target).specific == "fruit")
this.NextGoal();
this.NextStep();
}
},
{
@@ -17,7 +17,7 @@ Trigger.prototype.tutorialGoals = [
{
if (msg.cmd.type == "gather" && msg.cmd.target &&
TriggerHelper.GetResourceType(msg.cmd.target).specific == "tree")
this.NextGoal();
this.NextStep();
}
},
{
@@ -36,10 +36,10 @@ Trigger.prototype.tutorialGoals = [
const txt = +msg.count == 1 ?
markForTranslation("Do not forget to press the batch training hotkey while clicking to produce multiple units.") :
markForTranslation("Click on the Hoplite icon.");
this.WarningMessage(txt);
this.DisplayWarning(txt);
return;
}
this.NextGoal();
this.NextStep();
}
},
{
@@ -47,7 +47,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "House"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -55,7 +55,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Storehouse"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -78,10 +78,10 @@ Trigger.prototype.tutorialGoals = [
const txt = +msg.count == 1 ?
markForTranslation("Do not forget to press the batch training hotkey while clicking to produce multiple units.") :
markForTranslation("Click on the Skirmisher icon.");
this.WarningMessage(txt);
this.DisplayWarning(txt);
return;
}
this.NextGoal();
this.NextStep();
}
},
{
@@ -89,7 +89,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Farmstead"))
this.NextGoal();
this.NextStep();
},
"OnTrainingFinished": function(msg)
{
@@ -105,7 +105,7 @@ Trigger.prototype.tutorialGoals = [
"OnStructureBuilt": function(msg)
{
if (TriggerHelper.EntityMatchesClassList(msg.building, "Farmstead"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -123,13 +123,13 @@ Trigger.prototype.tutorialGoals = [
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Field"))
this.farmStarted = true;
if (this.IsDone())
this.NextGoal();
this.NextStep();
},
"OnTrainingFinished": function(msg)
{
this.trainingDone = true;
if (this.IsDone())
this.NextGoal();
this.NextStep();
}
},
{
@@ -137,7 +137,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "House"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -160,12 +160,12 @@ Trigger.prototype.tutorialGoals = [
const txt = +msg.count == 1 ?
markForTranslation("Do not forget to press the batch training hotkey while clicking to produce multiple units.") :
markForTranslation("Click on the Hoplite icon.");
this.WarningMessage(txt);
this.DisplayWarning(txt);
return;
}
this.trainingStarted = true;
if (this.IsDone())
this.NextGoal();
this.NextStep();
},
"OnPlayerCommand": function(msg)
{
@@ -173,12 +173,12 @@ Trigger.prototype.tutorialGoals = [
!msg.cmd.data.command || msg.cmd.data.command != "gather" ||
!msg.cmd.data.resourceType || msg.cmd.data.resourceType.specific != "tree")
{
this.WarningMessage(markForTranslation("Select the Civic Center, then hover the cursor over the tree and right-click when you see your cursor change into a wood icon."));
this.DisplayWarning(markForTranslation("Select the Civic Center, then hover the cursor over the tree and right-click when you see your cursor change into a wood icon."));
return;
}
this.rallyPointSet = true;
if (this.IsDone())
this.NextGoal();
this.NextStep();
}
},
{
@@ -186,7 +186,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Barracks"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -198,7 +198,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchQueued": function(msg)
{
if (msg.technologyTemplate && TriggerHelper.EntityMatchesClassList(msg.researcherEntity, "CivilCentre"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -213,7 +213,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchFinished": function(msg)
{
if (msg.tech == "phase_town_generic")
this.NextGoal();
this.NextStep();
}
},
{
@@ -221,7 +221,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Outpost"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -244,12 +244,12 @@ Trigger.prototype.tutorialGoals = [
const txt = +msg.count == 1 ?
markForTranslation("Do not forget to press the batch training hotkey while clicking to produce multiple units.") :
markForTranslation("Click on the Civilian icon.");
this.WarningMessage(txt);
this.DisplayWarning(txt);
return;
}
this.trainingStarted = true;
if (this.IsDone())
this.NextGoal();
this.NextStep();
},
"OnPlayerCommand": function(msg)
{
@@ -259,7 +259,7 @@ Trigger.prototype.tutorialGoals = [
return;
this.rallyPointSet = true;
if (this.IsDone())
this.NextGoal();
this.NextStep();
}
},
{
@@ -267,7 +267,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "repair" && TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Tower"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -275,7 +275,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchQueued": function(msg)
{
if (msg.technologyTemplate && TriggerHelper.EntityMatchesClassList(msg.researcherEntity, "Forge"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -283,7 +283,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchFinished": function(msg)
{
this.LaunchAttack();
this.NextGoal();
this.NextStep();
}
},
{
@@ -293,7 +293,7 @@ Trigger.prototype.tutorialGoals = [
if (msg.to != INVALID_PLAYER)
return;
if (this.IsAttackRepelled())
this.NextGoal();
this.NextStep();
}
},
{
@@ -314,7 +314,7 @@ Trigger.prototype.tutorialGoals = [
this.marketStarted = this.marketStarted || TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Market");
this.templeStarted = this.templeStarted || TriggerHelper.EntityMatchesClassList(msg.cmd.target, "Temple");
if (this.IsDone())
this.NextGoal();
this.NextStep();
}
},
{
@@ -326,7 +326,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchQueued": function(msg)
{
if (msg.technologyTemplate && TriggerHelper.EntityMatchesClassList(msg.researcherEntity, "CivilCentre"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -338,7 +338,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchFinished": function(msg)
{
if (msg.tech == "phase_city_generic")
this.NextGoal();
this.NextStep();
}
},
{
@@ -358,7 +358,7 @@ Trigger.prototype.tutorialGoals = [
if (this.IsDone())
{
this.RemoveChampions();
this.NextGoal();
this.NextStep();
}
}
},
@@ -372,7 +372,7 @@ Trigger.prototype.tutorialGoals = [
if (msg.from != this.enemyID)
return;
if (TriggerHelper.EntityMatchesClassList(msg.entity, "CivilCentre"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -1,4 +1,4 @@
Trigger.prototype.tutorialGoals = [
Trigger.prototype.tutorialSteps = [
{
"instructions": [
markForTranslation("This tutorial will teach the basics of developing your economy. Typically, you will start with a Civic Center and a couple units in Village Phase and ultimately, your goal will be to develop and expand your empire, often by evolving to Town Phase and City Phase afterward.\n"),
@@ -54,7 +54,7 @@ Trigger.prototype.tutorialGoals = [
{
if (msg.cmd.type == "gather" && msg.cmd.target &&
TriggerHelper.GetResourceType(msg.cmd.target).specific == "fruit")
this.NextGoal();
this.NextStep();
}
},
{
@@ -65,7 +65,7 @@ Trigger.prototype.tutorialGoals = [
{
if (msg.cmd.type == "gather" && msg.cmd.target &&
TriggerHelper.GetResourceType(msg.cmd.target).specific == "tree")
this.NextGoal();
this.NextStep();
}
},
{
@@ -76,7 +76,7 @@ Trigger.prototype.tutorialGoals = [
{
if (msg.cmd.type == "gather" && msg.cmd.target &&
TriggerHelper.GetResourceType(msg.cmd.target).specific == "meat")
this.NextGoal();
this.NextStep();
}
},
{
@@ -91,10 +91,10 @@ Trigger.prototype.tutorialGoals = [
!msg.cmd.data.command || msg.cmd.data.command != "gather" ||
!msg.cmd.data.resourceType || msg.cmd.data.resourceType.specific != "tree")
{
this.WarningMessage(markForTranslation("Select the Civic Center, then hover the cursor over a tree and right-click when you see the cursor change into a wood icon."));
this.DisplayWarning(markForTranslation("Select the Civic Center, then hover the cursor over a tree and right-click when you see the cursor change into a wood icon."));
return;
}
this.NextGoal();
this.NextStep();
}
},
@@ -116,10 +116,10 @@ Trigger.prototype.tutorialGoals = [
const txt = +msg.count == 1 ?
markForTranslation("Do not forget to hold the hotkey while clicking to train several units.") :
markForTranslation("The second icon represents the Hoplites.");
this.WarningMessage(txt);
this.DisplayWarning(txt);
return;
}
this.NextGoal();
this.NextStep();
}
},
{
@@ -130,7 +130,7 @@ Trigger.prototype.tutorialGoals = [
],
"OnTrainingFinished": function(msg)
{
this.NextGoal();
this.NextStep();
}
},
{
@@ -142,7 +142,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "construct" && msg.cmd.template == "structures/athen/storehouse")
this.NextGoal();
this.NextStep();
}
},
{
@@ -153,7 +153,7 @@ Trigger.prototype.tutorialGoals = [
{
const cmpResourceDropsite = Engine.QueryInterface(msg.building, IID_ResourceDropsite);
if (cmpResourceDropsite && cmpResourceDropsite.AcceptsType("wood"))
this.NextGoal();
this.NextStep();
},
},
{
@@ -164,7 +164,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "unset-rallypoint")
this.NextGoal();
this.NextStep();
},
"OnTrainingFinished": function(msg)
{
@@ -192,10 +192,10 @@ Trigger.prototype.tutorialGoals = [
const txt = +msg.count == 1 ?
markForTranslation("Do not forget to hold the hotkey and click to train several units.") :
markForTranslation("The first icon represents the Civilians.");
this.WarningMessage(txt);
this.DisplayWarning(txt);
return;
}
this.NextGoal();
this.NextStep();
}
},
{
@@ -209,7 +209,7 @@ Trigger.prototype.tutorialGoals = [
},
"OnTrainingFinished": function(msg)
{
this.NextGoal();
this.NextStep();
}
},
{
@@ -254,7 +254,7 @@ Trigger.prototype.tutorialGoals = [
this.houseGoal.add(+msg.entity);
++this.houseCount;
if (this.IsDone())
this.NextGoal();
this.NextStep();
}
}
},
@@ -282,7 +282,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "construct" && msg.cmd.template == "structures/athen/farmstead")
this.NextGoal();
this.NextStep();
},
"OnOwnershipChanged": function(msg)
{
@@ -304,7 +304,7 @@ Trigger.prototype.tutorialGoals = [
if (this.houseGoal.has(+msg.entity))
this.houseGoal.delete(+msg.entity);
if (this.IsDone())
this.NextGoal();
this.NextStep();
}
},
{
@@ -314,7 +314,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "construct" && msg.cmd.template == "structures/athen/field")
this.NextGoal();
this.NextStep();
}
},
{
@@ -326,7 +326,7 @@ Trigger.prototype.tutorialGoals = [
{
if (msg.cmd.type == "gather" && msg.cmd.target &&
TriggerHelper.GetResourceType(msg.cmd.target).specific == "meat")
this.NextGoal();
this.NextStep();
}
},
{
@@ -339,10 +339,10 @@ Trigger.prototype.tutorialGoals = [
(msg.cmd.data.command != "build" || !msg.cmd.data.target || !TriggerHelper.EntityMatchesClassList(msg.cmd.data.target, "Field")) &&
(msg.cmd.data.command != "gather" || !msg.cmd.data.resourceType || msg.cmd.data.resourceType.specific != "grain"))
{
this.WarningMessage(markForTranslation("Select the Civic Center and right-click on the Field."));
this.DisplayWarning(markForTranslation("Select the Civic Center and right-click on the Field."));
return;
}
this.NextGoal();
this.NextStep();
}
},
{
@@ -363,11 +363,11 @@ Trigger.prototype.tutorialGoals = [
const txt = +msg.count != 1 ?
markForTranslation("Click without holding a hotkey to train a single unit.") :
markForTranslation("Click on the Civilian icon.");
this.WarningMessage(txt);
this.DisplayWarning(txt);
return;
}
if (++this.femaleCount == 3)
this.NextGoal();
this.NextStep();
}
},
{
@@ -383,7 +383,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchQueued": function(msg)
{
if (msg.technologyTemplate && TriggerHelper.EntityMatchesClassList(msg.researcherEntity, "Farmstead"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -395,7 +395,7 @@ Trigger.prototype.tutorialGoals = [
"OnPlayerCommand": function(msg)
{
if (msg.cmd.type == "construct" && msg.cmd.template == "structures/athen/barracks")
this.NextGoal();
this.NextStep();
}
},
@@ -406,7 +406,7 @@ Trigger.prototype.tutorialGoals = [
"OnStructureBuilt": function(msg)
{
if (TriggerHelper.EntityMatchesClassList(msg.building, "Barracks"))
this.NextGoal();
this.NextStep();
},
},
{
@@ -421,7 +421,7 @@ Trigger.prototype.tutorialGoals = [
"OnResearchQueued": function(msg)
{
if (msg.technologyTemplate && TriggerHelper.EntityMatchesClassList(msg.researcherEntity, "CivilCentre"))
this.NextGoal();
this.NextStep();
}
},
{
@@ -460,12 +460,12 @@ Trigger.prototype.tutorialGoals = [
this.metal = true;
}
if (this.IsDone())
this.NextGoal();
this.NextStep();
},
"OnResearchFinished": function(msg)
{
if (this.IsDone())
this.NextGoal();
this.NextStep();
}
},
{