[Disclaimer: I know I'm using ES6 and it's problematic, for now it's easier because it's similar to the Java I'm familiar with]
In my RPG, I have a widget for handling the decay of status effects at the end of each round:
<<widget "endofround">>
<<run console.log("End of round start")>>
<<for _actor range $args[0]>>
<<run console.log(_actor.name)>>
<<for _k, _effect range _actor.effects>>
<<run console.log("Index #"+_k)>>
<<run console.log(_effect.name)>>
<<run console.log("Time = "+_effect.duration)>>
/* DoT check */
<<if _effect.dot is true>>
<<set _message to true>>
<<set $dmg = _effect.damage(_actor)>>
<<print _effect.msg(_actor)>>
<br/>
<<run _actor.setHP(-$dmg)>>
<<set $target[0] = _actor>>
<<deathcheck>>
<</if>>
/* decrementor */
<<if !_effect.topDec>>
<<if _effect.duration >= 1 and !(_actor.stasis is true and _effect.name != "Stasis")>>
<<set _effect.duration -= 1>>
<</if>>
<<run console.log("Time = "+_effect.duration)>>
<<if _effect.duration == 0>>
<<set _m = _actor.removeEffect(_k,'pierce')>>
<<set _k -= 1>>
<<if _m.length > 0>>
<<print _m>>
<<set _message to true>>
<</if>>
<</if>>
<</if>>
<</for>>
<</for>>
<</widget>>
...where $args[0] is the party (enemies or allies).
removeEffect is a method function I define in the battling character class:
window.Actor = class Actor {
(...)
removeEffect (id,mod) {
if (!this.stasis || mod == 'pierce'){
var effect = this.effects[id];
this.effects.deleteAt(id);
effect.onRemove(this);
return effect.removeText(this.name)+"\n";
} else {
return `${this.name}'s Stasis held the effect in place!<br/>`;
}
}
...where onRemove is a method function for status effects. It works fine when it's successfully called, so I don't think it's a problem.
This is creating an issue: If multiple effects expire on the same turn, the index pointer in the reaper loop is thrown off, because I used deleteAt(), which adjusts the array length to compensate for the deletion. So for instance, if effect #0 and effect #1 both expire simultaneously, the reaper deletes effect #0, which causes effect #1 to become effect #0; but _k is now 1, and the next iteration of the reaper therefore tries to apply removeEffect() to the effect at index 1, which no longer exists.
I'm not entirely sure how to fix this. I attempted to decrement _k after the removal, but that appears to be overridden by the loop logic. Is a simple patch possible, or will I have to scrap this widget and create a new algorithm entirely?