Changeset View
Standalone View
binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js
function StatusEffectsReceiver() {} | function StatusEffectsReceiver() {} | ||||
StatusEffectsReceiver.prototype.Init = function() | StatusEffectsReceiver.prototype.Init = function() | ||||
Freagarach: Some GlobalScript perhaps? | |||||
Done Inline ActionsTemplates.js ? Stan: Templates.js ? | |||||
Done Inline ActionsThis is intrasically tied to the schema we use to specify modifiers in JSON and in XML, which are sadly already different. iirc only simulation code uses the tech/aura equivalent of this, so I would put it in a helper next to the schema definition. wraitii: This is intrasically tied to the schema we use to specify modifiers in JSON and in XML, which… | |||||
{ | { | ||||
this.activeStatusEffects = {}; | this.activeStatusEffects = {}; | ||||
}; | }; | ||||
StatusEffectsReceiver.prototype.GetActiveStatuses = function() | StatusEffectsReceiver.prototype.GetActiveStatuses = function() | ||||
{ | { | ||||
Done Inline Actions\n Freagarach: `\n`
Further down the file as well. | |||||
return this.activeStatusEffects; | return this.activeStatusEffects; | ||||
}; | }; | ||||
Done Inline ActionsString to bool conversion ? Stan: String to bool conversion ? | |||||
Done Inline ActionsWhat do you mean here exactly? Freagarach: What do you mean here exactly? | |||||
// Called by attacking effects. | // Called by attacking effects. | ||||
Done Inline ActionsTernary ? Stan: Ternary ? | |||||
Done Inline ActionsI think yes here. wraitii: I think yes here. | |||||
Done Inline ActionsShould we default to ["Unit", "Structure"]? Freagarach: Should we default to `["Unit", "Structure"]`? | |||||
StatusEffectsReceiver.prototype.GiveStatus = function(effectData, attacker, attackerOwner, bonusMultiplier) | StatusEffectsReceiver.prototype.GiveStatus = function(effectData, attacker, attackerOwner, bonusMultiplier) | ||||
{ | { | ||||
for (let effect in effectData) | for (let effect in effectData) | ||||
this.AddStatus(effect, effectData[effect]); | this.AddStatus(effect, effectData[effect]); | ||||
Done Inline ActionsShould be a variable defined earlier to prevent unnecessary object creation. Freagarach: Should be a variable defined earlier to prevent unnecessary object creation. | |||||
// TODO: implement loot / resistance. | // TODO: implement loot / resistance. | ||||
return { "inflictedStatuses": Object.keys(effectData) }; | return { "inflictedStatuses": Object.keys(effectData) }; | ||||
}; | }; | ||||
StatusEffectsReceiver.prototype.AddStatus = function(statusName, data) | StatusEffectsReceiver.prototype.AddStatus = function(statusName, data) | ||||
{ | { | ||||
if (this.activeStatusEffects[statusName]) | if (this.activeStatusEffects[statusName]) | ||||
{ | |||||
// TODO: implement different behaviour when receiving the same status multiple times. | |||||
// For now, these are ignored. | |||||
return; | return; | ||||
} | |||||
Done Inline ActionsThis should go in a separate patch.
But this is more complex to do correctly and should come later. wraitii: This should go in a separate patch.
I see 4 ways to handle being hit with the same status… | |||||
this.activeStatusEffects[statusName] = {}; | this.activeStatusEffects[statusName] = {}; | ||||
let status = this.activeStatusEffects[statusName]; | let status = this.activeStatusEffects[statusName]; | ||||
Done Inline ActionsIs the arbitrary number 10 enough? I would say not. Freagarach: Is the arbitrary number 10 enough? I would say not. | |||||
Done Inline ActionsTBH I wouldn't handle stackability in this diff. There are tricky issues associated with it. Slow and steady wins the race. wraitii: TBH I wouldn't handle stackability in this diff. There are tricky issues associated with it. | |||||
Done Inline ActionsWhy 10 ? Stan: Why 10 ? | |||||
Object.assign(status, data); | Object.assign(status, data); | ||||
status.Interval = +data.Interval; | |||||
status.TimeElapsed = 0; | |||||
status.FirstTime = true; | |||||
Done Inline ActionsPretty sure it's missing some spaces, I guess the linter will complain :D Stan: Pretty sure it's missing some spaces, I guess the linter will complain :D | |||||
Done Inline Actionslooks like long line, maybe you should format it and make multiple lines of it :) Silier: looks like long line, maybe you should format it and make multiple lines of it :) | |||||
Done Inline ActionsBoth correct, waiting for the discussion how to unify and properly pass things. Thanks for noticing :) Freagarach: Both correct, waiting for the discussion how to unify and properly pass things. Thanks for… | |||||
Done Inline ActionsMissing space. Stan: Missing space. | |||||
if (status.Modifiers) | |||||
{ | |||||
let modifications = DeriveModificationsFromXMLTemplate(status.Modifiers); | |||||
warn(uneval(modifications)); | |||||
StanUnsubmitted Done Inline Actionsoversight :) Stan: oversight :) | |||||
let cmpModifiersManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ModifiersManager); | |||||
cmpModifiersManager.AddModifiers(statusName, modifications, this.entity); | |||||
Done Inline ActionsDon't we have a function to do that ? Stan: Don't we have a function to do that ? | |||||
} | |||||
// We want an interval to update the GUI to show how much time of the status effect | |||||
// is left even if the status effect itself has no interval. | |||||
if (status.Duration && !status.Interval) | |||||
status.Interval = 1000; | |||||
Done Inline ActionsWhat if 0 ? Stan: What if 0 ? | |||||
Done Inline Actionsinterval = 0 does not work for timer if (typeof repeattime != "number" || !(repeattime > 0)) error("Invalid repeattime to SetInterval of "+funcname); Silier: interval = 0 does not work for timer
```
if (typeof repeattime != "number" || !(repeattime >… | |||||
Done Inline ActionsAh yeah that famous warning :D Stan: Ah yeah that famous warning :D | |||||
if (status.Interval) | |||||
Done Inline Actions(StatusEffectsReceiver.prototype.Interval = 1000) elexis: (StatusEffectsReceiver.prototype.Interval = 1000) | |||||
{ | |||||
if (status.Duration) | |||||
{ | |||||
status._timeElapsed = 0; | |||||
status._firstTime = true; | |||||
} | |||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | ||||
status.Timer = cmpTimer.SetInterval(this.entity, IID_StatusEffectsReceiver, "ExecuteEffect", 0, +status.Interval, statusName); | status._timer = cmpTimer.SetInterval(this.entity, IID_StatusEffectsReceiver, "ExecuteEffect", 0, +status.Interval, statusName); | ||||
} | |||||
}; | }; | ||||
Done Inline ActionsI realise I did the capitalisation here, but I would downgrade this to lower-case as it doesn't come from the template. In fact, I might write it _timer to make the difference more explicit. Same for 'timeelapsed' and 'firstTime' wraitii: I realise I did the capitalisation here, but I would downgrade this to lower-case as it doesn't… | |||||
StatusEffectsReceiver.prototype.RemoveStatus = function(statusName) | StatusEffectsReceiver.prototype.RemoveStatus = function(statusName) | ||||
{ | { | ||||
if (!this.activeStatusEffects[statusName]) | let statusEffect = this.activeStatusEffects[statusName]; | ||||
if (!statusEffect) | |||||
return; | return; | ||||
if (statusEffect.Modifiers) | |||||
{ | |||||
let cmpModifiersManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ModifiersManager); | |||||
cmpModifiersManager.RemoveAllModifiers(statusName, this.entity); | |||||
} | |||||
if (statusEffect._timer) | |||||
{ | |||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | ||||
cmpTimer.CancelTimer(this.activeStatusEffects[statusName].Timer); | cmpTimer.CancelTimer(statusEffect._timer); | ||||
} | |||||
delete this.activeStatusEffects[statusName]; | delete this.activeStatusEffects[statusName]; | ||||
}; | }; | ||||
StatusEffectsReceiver.prototype.ExecuteEffect = function(statusName, lateness) | StatusEffectsReceiver.prototype.ExecuteEffect = function(statusName, lateness) | ||||
{ | { | ||||
let status = this.activeStatusEffects[statusName]; | let status = this.activeStatusEffects[statusName]; | ||||
if (!status) | if (!status) | ||||
return; | return; | ||||
if (status.FirstTime) | if (status.Duration) | ||||
{ | |||||
if (status._firstTime) | |||||
{ | { | ||||
status.FirstTime = false; | status._firstTime = false; | ||||
status.TimeElapsed += lateness; | status._timeElapsed += lateness; | ||||
} | } | ||||
else | else | ||||
status.TimeElapsed += status.Interval + lateness; | status._timeElapsed += +status.Interval + lateness; | ||||
} | |||||
Attacking.HandleAttackEffects(statusName, status, this.entity, -1, -1); | if (status.Damage || status.Capture) | ||||
Attacking.HandleAttackEffects(statusName, status, this.entity, INVALID_ENTITY, INVALID_PLAYER); | |||||
if (status.Duration && status.TimeElapsed >= +status.Duration) | if (status.Duration && status._timeElapsed >= +status.Duration) | ||||
Done Inline ActionsINVALID_ENTITY, INVALID_PLAYER Silier: INVALID_ENTITY, INVALID_PLAYER | |||||
this.RemoveStatus(statusName); | this.RemoveStatus(statusName); | ||||
}; | }; | ||||
Engine.RegisterComponentType(IID_StatusEffectsReceiver, "StatusEffectsReceiver", StatusEffectsReceiver); | Engine.RegisterComponentType(IID_StatusEffectsReceiver, "StatusEffectsReceiver", StatusEffectsReceiver); |
Some GlobalScript perhaps?