Changeset View
Standalone View
binaries/data/mods/public/maps/scripts/Tutorial.js
- This file was added.
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
Trigger.prototype.events = []; | |||||
elexis: This will break once another map, victory condition or other trigger script adds a events… | |||||
mimoAuthorUnsubmitted Not Done Inline ActionsI don't see why you would need any victory conditions in such a tutorial which is just to learn the basic commands, but ok. I will change to tutorialXXX mimo: I don't see why you would need any victory conditions in such a tutorial which is just to learn… | |||||
Not Done Inline ActionsDo these survive being serialized? I think only non-prototype properties do. leper: Do these survive being serialized? I think only non-prototype properties do. | |||||
Not Done Inline ActionsI don't know if we want to serialize the tutorials? i rather see it as a serie of short parts (this one is only the first and should be 10 to 15 mn), with only serializing which ones have been done by the player. mimo: I don't know if we want to serialize the tutorials? i rather see it as a serie of short parts… | |||||
Not Done Inline ActionsWe should be able to. Also adding code that has inherent serialization issues and shipping that will not help with making modders do the right thing. leper: We should be able to. Also adding code that has inherent serialization issues and shipping that… | |||||
Not Done Inline ActionsNot supporting serialization should break savegames. Storing variables and initializing them can be done as in the survival of the fittest or gallic fields trigger script if not sure. Having it consistent in all trigger scripts is also an incentive. See also rP18912 and rP18909 (when rejoining an MP game or loading a savegame, first the file was loaded and kept a reference to the Trigger component after init, then deserialized and created a new Trigger component while the variable still contained a reference to the old trigger component. Not the same issue as suspected here, but doing it the way we have past those commits should be supported) elexis: Not supporting serialization should break savegames. Storing variables and initializing them… | |||||
/** call when deserializing a saved tutorial */ | |||||
elexisUnsubmitted Not Done Inline Actions/** \n elexis: /** \n
Capital letter, call->called?, potentially period | |||||
mimoAuthorUnsubmitted Not Done Inline Actionsok mimo: ok | |||||
Trigger.prototype.Deserialize = function(data) | |||||
elexisUnsubmitted Not Done Inline ActionsThis actually sounds like it would break serialization, since the other Trigger scripts also extend the Trigger prototype, so all of those properties will be lost. Why implement custom serialize/deserialize functions? It is sufficient to omit these functions and let the default serialization serialize all properties as far as I know (could be tested by starting an MP game and rejoining that and observing whether we get an OOS error, or pyrogenesis -replay="/path/to/replay/commands.txt" -mod=public -rejointest=someNumber doing the same) elexis: This actually sounds like it would break serialization, since the other Trigger scripts also… | |||||
mimoAuthorUnsubmitted Not Done Inline ActionsBetter test it before saying so. It was tested and does not break anything because you don't (and should never) need to load other trigger scripts. mimo: Better test it before saying so. It was tested and does not break anything because you don't… | |||||
leperUnsubmitted Not Done Inline ActionsIsn't the call to StartTutorial only needed because events isn't serialized, which is caused by it being in the prototype as opposed to a normal member? leper: Isn't the call to `StartTutorial` only needed because `events` isn't serialized, which is… | |||||
{ | |||||
this.Init(); | |||||
this.count = data.count; | |||||
this.index = data.index - 1; | |||||
this.fullText = data.fullText; | |||||
this.StartTutorial(); | |||||
}; | |||||
/** called when starting a new tutorial */ | |||||
Trigger.prototype.InitTutorial = function(data) | |||||
{ | |||||
this.count = 0; | |||||
this.index = 0; | |||||
this.fullText = ""; | |||||
this.StartTutorial(); | |||||
}; | |||||
Trigger.prototype.StartTutorial = function() | |||||
{ | |||||
// First register needed triggers | |||||
this.RegisterTrigger("OnPlayerCommand", "OnPlayerCommandTrigger", { "enabled": false }); | |||||
this.events.push("OnPlayerCommand"); | |||||
for (let goal of this.goals) | |||||
{ | |||||
elexisUnsubmitted Not Done Inline Actions(potentially unneeded braces) elexis: (potentially unneeded braces) | |||||
mimoAuthorUnsubmitted Not Done Inline ActionsI prefer having such brace as otherwise, the code may break in the future when people add one line. mimo: I prefer having such brace as otherwise, the code may break in the future when people add one… | |||||
for (let key in goal) | |||||
{ | |||||
if (typeof goal[key] !== "function" || this.events.indexOf(key) != -1) | |||||
continue; | |||||
let action = key + "Trigger"; | |||||
this.RegisterTrigger(key, action, { "enabled": false }); | |||||
this.events.push(key); | |||||
} | |||||
} | |||||
for (let i = 0; i < this.index; ++i) | |||||
this.GoalMessage(this.goals[i].instructions, false, false); | |||||
this.NextGoal(); | |||||
}; | |||||
Trigger.prototype.NextGoal = function() | |||||
{ | |||||
if (this.index > this.goals.length) | |||||
return; | |||||
let goal = this.goals[this.index]; | |||||
let needDelay = true; | |||||
let readyButton = false; | |||||
for (let event of this.events) | |||||
{ | |||||
let action = event + "Trigger"; | |||||
if (goal[event]) | |||||
{ | |||||
Not Done Inline ActionsShould this be this.OnPlayerCommandTrigger? elexis: Should this be `this.OnPlayerCommandTrigger`? | |||||
Not Done Inline Actionsno as we can't serialize it mimo: no as we can't serialize it | |||||
Trigger.prototype[action] = goal[event]; | |||||
this.EnableTrigger(event, action); | |||||
needDelay = false; | |||||
this.count = 0; | |||||
} | |||||
else | |||||
this.DisableTrigger(event, action); | |||||
} | |||||
if (needDelay) // no actions for the next goal | |||||
{ | |||||
if (goal.delay) | |||||
this.DoAfterDelay(+goal.delay, "NextGoal", {}); | |||||
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(); | |||||
}; | |||||
readyButton = true; | |||||
} | |||||
} | |||||
this.GoalMessage(goal.instructions, readyButton, ++this.index == this.goals.length); | |||||
}; | |||||
Trigger.prototype.GoalMessage = function(text, readyButton=false, leave=false) | |||||
{ | |||||
let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); | |||||
cmpGUIInterface.PushNotification({ | |||||
"type": "tutorial", | |||||
"players": [1], | |||||
"message": text, | |||||
"translateMessage": true, | |||||
"readyButton": readyButton, | |||||
"leave": leave | |||||
}); | |||||
}; | |||||
Trigger.prototype.WarningMessage = function(txt) | |||||
{ | |||||
let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); | |||||
cmpGUIInterface.PushNotification({ | |||||
"type": "tutorial", | |||||
"players": [1], | |||||
"message": txt, | |||||
"translateMessage": true, | |||||
"warning": true | |||||
}); | |||||
}; | |||||
Trigger.prototype.OnPlayerCommandTrigger = function() {}; | |||||
Trigger.prototype.OnResearchQueuedTrigger = function() {}; | |||||
Trigger.prototype.OnResearchFinishedTrigger = function() {}; | |||||
Trigger.prototype.OnStructureBuiltTrigger = function() {}; | |||||
Trigger.prototype.OnTrainingQueuedTrigger = function() {}; | |||||
Trigger.prototype.OnTrainingFinishedTrigger = function() {}; |
This will break once another map, victory condition or other trigger script adds a events property. Not the fault of this patch but perhaps tutorialEvents, tutorialIndex, tutorialCount works too for the time being.
We will have to do something about this sometime ( https://wildfiregames.com/forum/index.php?/topic/22179-trigger-prototype-naming-conflicts/ )
Why isn't tutorialEvents serialized?