AdvanceMainTurn¶
This is an action coroutine that runs at the very end of every main turn when both parties no longer can act for this turn.
Procedure¶
commandsuccessis reset to falseblockcooldownis reset to 0.0actionis set to true which changes to an uncontrolled flow- If the following conditions are met, delprojs are processed (see the section below for details):
delprojsisn't empty- There are at least one player party member who has their
hpabove 0 while noteatenby - There are at least one enemy party member who has their
hpabove 0 gameoverisn't in progress
nonphyscalis set to false- Each player party member gets their actor turn advanced (see the section below for details)
- A frame is yielded
availableplayersis set to the amount of player party members whosehpis above 0- If
availableplayersis 0, DeadParty is started followed by an abrupt yield break. This will change to a terminal flow as it is a terminal coroutine. - If there is at least one enemy party member, the enemy party section of the turn advancement is performed alongside some end of main turn process (see the section below for details)
- Otheriwse if
gameoverwas already in progress, a yield break is issued because it means we already changed to a terminal flow and nothing is left to do - Otherwise:
cancelupdateis set to true changing to a terminal flow- A second is yielded
- If
ineventis false (we weren't in an EventDialogue), AddExperience is started changing to a terminal flow. NOTE: the coroutine still continues, but in practice, it can't race against AddExperience
- If
actedthisturnis false,noactionis incremented - If
gameoverisn't in progress whilenoactionis 5 (meaning 5 main turns passed without the ability for the player party to act), the inaction failsafe is done (see the section below for more details) actedthisturnis set to falseforceattackis set to -1playertargetIDis set to -1- If
damagethisturnis higher than flagvar 41 (highest damage in one turn), the flagvar value is set todamagethisturn damagethisturnis set to 0- RefreshAllData is called which sets
alldatato a new list which consists of all theplayerdatafollowed by all theenemydataappended together and it also resets all enemy party member'sblockTimesto 0 - UpdateEntities is called
- UpdateAnim is called
optionis set tolastaction- If there is at least one enemy party member, UpdateAnim is invoked again in 0.75 seconds
- If
charmcooldownis above 0, it is decremented chompyattackedis set to falsehideenemyhpis set to falsemainturnis set to null (which signals the coroutine is no longer in progress as no yield will be done from now on)blockcooldownis set to 0.0 (this resets the GetBlock counter so blocking becomes inactive)- All GameObjects with tag
DestroyTurnhave their tag set toUntaggedfollowed by their destruction in 5.0 seconds
delprojs advance¶
delprojs (or delayed projectiles) are projectiles that an enemy can launch and the projectile will only hit the targetted player party member after a certain amount of main turns passed. This section processes them.
The first thing that happens is nonphyscal is set to true (it will be set to false after this section).
From there, for each delprojs (going from last to start), the delproj's turns gets decremented and if it reached 0, it will land by doing the following:
- instance.
camtargetis set to null - instance.
camtargetposis set to (-4.25, 0.0, 0.0) - instance.
camoffsetis set to (0.0, 4.0, -8.5) enemyis set to trueblockcooldownis set to 0.0commandsuccessis set to false- If the delproj has a
whilesoundset, it is played on loop unless the first character is@in which case, it will play the sound only once where name is the one without the@ - The
argsof the delproj are parsed as explained in the delayed projectile documentation - Unless a
noshadowcommand was parsed, a ShadowLite is added to the delproj'sobj - For delproj's
framestepamount of frames, the projectile is moved (kept track with a local frame counter starting at 0.0 and getting incremented by MainManager.framestepeach iteraction):- The delproj's
objpsotion is set to a lerp from the initial one to thepartyposof the delproj'sposition+ themovecommand offset if it was parsed with a factor of the ratio between the amount of frames spent so far on this loop vs delproj'sframestep - A frame is yielded
- The delproj's
- If the delproj had a
whilesound, it is stopped. NOTE: if this wasn't a looped sound, the call won't work, but the sound will stop on its own - If the delproj has a
deathsound, it is played - If the delproj has
deathparticle, they are played at theobjposition + thepartoffcommand offset if it was parsed - The delproj's
objis destroyed - If the player party member whose index is the
partypointercorresponding to the delproj'spositionhas anhpabove 0 and doesn't have aneatenby, some logic is performed on this player party member:- DoDamage is called targetting the player party memmber without an attacker for delproj's
damagedamageammount with delproj'spropertyas the property andcommandsuccessas the block - If the
hpof the player party member reached 0 or below, theirturnssincedeathis set to -1
- DoDamage is called targetting the player party memmber without an attacker for delproj's
- RemoveDelayedProjectile is called on the delproj which removes it from
delprojs enemyis set to false- 0.6 seconds are yielded
If any delprojs landed:
- SetDefaultCamera is called
checkingdeadis set to a CheckDead action coroutine starting- All frames are yielded while
checkingdeadis in progress actionis set again to true- A frame is yielded
- All actors from both parties with a
cantmovebelow 1 (at least one action available) gets theircantmoveclamped from 1 to 99 (forcing at least one turn needed before an action is available). This in practice doesn't do anything destructive becausemoreturnnextturnis granted later correctly and it's not possible to have a meaningulcantmoveabove 0 by this point (if it happened, it likely means the player party member IsStopped which imply that when the stopping condition gets removed, thecantmovewill reset anyway). currentturnis set to 1 (deselects any previously selected player party member)- 0.5 seconds are yielded
Player party advance¶
This section happens for each player party member.
- The corresponding
receivedrelayof the player party member index is set to false - AdvanceTurnEntity is called on the player party member with hasdelay starting at false
- If the turn advancement resulted in hasdelay becoming true, 0.75 seconds are yielded
- If
eatenkillis true (meaning a player party member died as a result of an eating attack) the game needs to properly kill the player party member that died by doing the following: - battleentity.
shakeiceis set to false
Finally, if the MiracleMatter medal is equipped on the player party member, a revival process will occur, but it can only happen if on top of the medal being equipped, all the following are true:
- This isn't a firststrike from the enemy party
- At least one player party member has its
hpabove 0 without beingeatenby lockmmateris false- The player party member has its
turnssincedeathbe at least (2 - amount ofMiracleMatterequipped - 1) after clamping from 1 to 3 (essentially, at least 2 if only one is equipped, at least 1 if 2, at least 0 if more is equipped, but this case isn't possible under normal gameplay)
If all the conditions are met, the revive occurs as follows:
turnssincedeathis set to 0- RevivePlayer is called on the player party member index with 2 hp and with showcounter
- 0.5 seconds are yielded
- If the player party member's
lockcantmoveis false, theircantmoveis set to 0 (this gives them one action available) - The player party member's
lockcantmoveis set to false
Enemy party advance and end of main turn process¶
This section not only manages enemy turn advance, but it also does some end of main turn process because being in this section means the battle is not going to end.
The first thing that happens is relating to the FavoriteOne medal which is tracked by attackedally. If it's not negative, it means the player party member with the matching trueid was attacked and the other members should receive the medal's benefits. This is only done if there is more than 1 player party member's hp above 0 while not being eatenby.
NOTE: This imply that if the attackedally player party member got hit as well as another player party member on the same main turn, the logic won't happen because the game requires more than 1 player party members alive. This isn't correct: it should require at least 1 player party member alive instead of 2 or more.
The process to apply the medal is as follows:
- For each player party member whose
trueidisn'tattackedallywith anhpabove 0 and without the Eaten condition:- battleentity.
emoticoncooldownis set to 40.0 didnothingis set to false- battleentity.
emoticonidis set to 2 (red ! mark)
- battleentity.
- If at least one player party member had an emote set, the
Wamsound is played - All frames are yielded while the last player party member's battleentity.
emoticoncooldownis above 0.0 - For each player party member whose
trueidisn'tattackedallywith anhpabove 0 with achargeless than 3 and without the Eaten condition:- A StatEffect of type 4 (green up arrow) coroutine is started on the player party member
chargeis incremented
- If at least one player party member gained a
charge, theStatUpsound is played at 1.25 pitch - 0.5 seconds are yielded
attackedallyis reset to -1
From there, each enemy party members gets their turn advanced by having the following logic apply to each of them:
- AdvanceTurnEntity is called on the eneny party member with hasdelay starting at false which advances their actor turn
- If hasdelay got a value of true after the turn advancement, 0.75 seconds are yielded
- battleentity.
shakeiceis set to false - If
cantmoveis 0 (they would have only 1 action available after the actor turn),cantmoveis set to -moves+ 1 (this resets the available actions counter to the base one set from the normal amount being moves) - battleentity.
spinis zeroed out turnsnodamageis incremented (this value is only written to, but never read so it's UNUSED)
Finally, some end of main turn process logic occurs:
- SetLastTurns is called which resets
lastturnselements to be all -1 which resets the player party member selection cycle - A frame is yielded
turnsis incrementedcheckingdeadis set to a EndOfTurnMedals coroutine starting followed by all frames being yielded while the coroutine is in progress. This is what the coroutine does:- Every 2
turns, for each player party member with theHappyHeartmedal equipped and whosehpis above 0:- Heal is called on the player party member with the amount being 2 * the amount of
HappyHeartmedals equipped - 0.5 seconds are yielded
- Heal is called on the player party member with the amount being 2 * the amount of
- Every 2
turns(same cycle as the one above), if theHappyTPmedal is equipped:- HealTP is called which plays a
Heal2sound followed by a heal of instance.tpby 2 * the amount ofHappyTPmedals equipped clamped from 0 to instance.maxtpfollowed by a ShowDamageCounter with type 2 (TP), the amount being the amount of tp healed, the start position beingplayerdata[GetRandomAvaliablePlayer()].battleentityposition + (2.0, 2.0, 2.0) and the end position being (5.0, 5.0, 5.0) - 0.5 seconds are yielded
- HealTP is called which plays a
checkingdeadis set to null which informs the caller the coroutine has ended so it can stop yielding
- Every 2
optionis set to 0currentturnis set to -1 (this unselects any players party members previously selected)enemyis set to false (this resets the controlled flow to be in the player phase)- UpdateConditionIcons is called which calls UpdateConditionBubbles on all battleentity (all
playerdatawith right to false and allenemydatawithhpabove 0 with right to true) actionis set to false changing to a controlled flow- UpdateText is called
Inaction failsafe¶
There is a failsafe in the game where if after 5 main turns, PlayerTurn was never called meaning the player party could in no way perform any actions, the game will forcefully allow the player party to act again. This is tracked by actedthisturn being false reporting no action could be taken and the total amount of main turn is tracked by noaction. This failsafe exists presumably to mitigate a situation where the player party is stopped for too long notably through the results of stopping conditions.
The failsafe is applied by doing the following:
noactionis reset to 0- For each player party member that IsStopped without skipimmobile while their
hpis above 0:MagicUpparticles are played at the battleentity position- ClearStatus is called on the player party member
- Their
cantmoveis set to 0 making them able to act again
- UpdateConditionIcons is called which calls UpdateConditionBubbles on all battleentity (all
playerdatawith right to false and allenemydatawithhpabove 0 with right to true) - UpdateAnim is called
- If at least one player party member had ClearStatus called on them earlier, the
Heal3sound is played followed by a 0.5 seconds yield