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¶
commandsuccess
is reset to falseblockcooldown
is reset to 0.0action
is set to true which changes to an uncontrolled flow- If the following conditions are met, delprojs are processed (see the section below for details):
delprojs
isn't empty- There are at least one player party member who has their
hp
above 0 while noteatenby
- There are at least one enemy party member who has their
hp
above 0 gameover
isn't in progress
nonphyscal
is set to false- Each player party member gets their actor turn advanced (see the section below for details)
- A frame is yielded
availableplayers
is set to the amount of player party members whosehp
is above 0- If
availableplayers
is 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
gameover
was 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:
cancelupdate
is set to true changing to a terminal flow- A second is yielded
- If
inevent
is 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
actedthisturn
is false,noaction
is incremented - If
gameover
isn't in progress whilenoaction
is 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) actedthisturn
is set to falseforceattack
is set to -1playertargetID
is set to -1- If
damagethisturn
is higher than flagvar 41 (highest damage in one turn), the flagvar value is set todamagethisturn
damagethisturn
is set to 0- RefreshAllData is called which sets
alldata
to a new list which consists of all theplayerdata
followed by all theenemydata
appended together and it also resets all enemy party member'sblockTimes
to 0 - UpdateEntities is called
- UpdateAnim is called
option
is set tolastaction
- If there is at least one enemy party member, UpdateAnim is invoked again in 0.75 seconds
- If
charmcooldown
is above 0, it is decremented chompyattacked
is set to falsehideenemyhp
is set to falsemainturn
is set to null (which signals the coroutine is no longer in progress as no yield will be done from now on)blockcooldown
is set to 0.0 (this resets the GetBlock counter so blocking becomes inactive)- All GameObjects with tag
DestroyTurn
have their tag set toUntagged
followed 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.
camtarget
is set to null - instance.
camtargetpos
is set to (-4.25, 0.0, 0.0) - instance.
camoffset
is set to (0.0, 4.0, -8.5) enemy
is set to trueblockcooldown
is set to 0.0commandsuccess
is set to false- If the delproj has a
whilesound
set, 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
args
of the delproj are parsed as explained in the delayed projectile documentation - Unless a
noshadow
command was parsed, a ShadowLite is added to the delproj'sobj
- For delproj's
framestep
amount of frames, the projectile is moved (kept track with a local frame counter starting at 0.0 and getting incremented by MainManager.framestep
each iteraction):- The delproj's
obj
psotion is set to a lerp from the initial one to thepartypos
of the delproj'sposition
+ themove
command 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 theobj
position + thepartoff
command offset if it was parsed - The delproj's
obj
is destroyed - If the player party member whose index is the
partypointer
corresponding to the delproj'sposition
has anhp
above 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
damage
damageammount with delproj'sproperty
as the property andcommandsuccess
as the block - If the
hp
of the player party member reached 0 or below, theirturnssincedeath
is 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
enemy
is set to false- 0.6 seconds are yielded
If any delprojs
landed:
- SetDefaultCamera is called
checkingdead
is set to a CheckDead action coroutine starting- All frames are yielded while
checkingdead
is in progress action
is set again to true- A frame is yielded
- All actors from both parties with a
cantmove
below 1 (at least one action available) gets theircantmove
clamped from 1 to 99 (forcing at least one turn needed before an action is available). This in practice doesn't do anything destructive becausemoreturnnextturn
is granted later correctly and it's not possible to have a meaningulcantmove
above 0 by this point (if it happened, it likely means the player party member IsStopped which imply that when the stopping condition gets removed, thecantmove
will reset anyway). currentturn
is 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
receivedrelay
of 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
eatenkill
is 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.
shakeice
is 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
hp
above 0 without beingeatenby
lockmmater
is false- The player party member has its
turnssincedeath
be at least (2 - amount ofMiracleMatter
equipped - 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:
turnssincedeath
is 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
lockcantmove
is false, theircantmove
is set to 0 (this gives them one action available) - The player party member's
lockcantmove
is 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
trueid
isn'tattackedally
with anhp
above 0 and without the Eaten condition:- battleentity.
emoticoncooldown
is set to 40.0 didnothing
is set to false- battleentity.
emoticonid
is set to 2 (red ! mark)
- battleentity.
- If at least one player party member had an emote set, the
Wam
sound is played - All frames are yielded while the last player party member's battleentity.
emoticoncooldown
is above 0.0 - For each player party member whose
trueid
isn'tattackedally
with anhp
above 0 with acharge
less than 3 and without the Eaten condition:- A StatEffect of type 4 (green up arrow) coroutine is started on the player party member
charge
is incremented
- If at least one player party member gained a
charge
, theStatUp
sound is played at 1.25 pitch - 0.5 seconds are yielded
attackedally
is 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.
shakeice
is set to false - If
cantmove
is 0 (they would have only 1 action available after the actor turn),cantmove
is set to -moves
+ 1 (this resets the available actions counter to the base one set from the normal amount being moves) - battleentity.
spin
is zeroed out turnsnodamage
is 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
lastturns
elements to be all -1 which resets the player party member selection cycle - A frame is yielded
turns
is incrementedcheckingdead
is 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 theHappyHeart
medal equipped and whosehp
is above 0:- Heal is called on the player party member with the amount being 2 * the amount of
HappyHeart
medals 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 theHappyTP
medal is equipped:- HealTP is called which plays a
Heal2
sound followed by a heal of instance.tp
by 2 * the amount ofHappyTP
medals equipped clamped from 0 to instance.maxtp
followed by a ShowDamageCounter with type 2 (TP), the amount being the amount of tp healed, the start position beingplayerdata[
GetRandomAvaliablePlayer()].battleentity
position + (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
checkingdead
is set to null which informs the caller the coroutine has ended so it can stop yielding
- Every 2
option
is set to 0currentturn
is set to -1 (this unselects any players party members previously selected)enemy
is set to false (this resets the controlled flow to be in the player phase)- UpdateConditionIcons is called which calls UpdateConditionBubbles on all battleentity (all
playerdata
with right to false and allenemydata
withhp
above 0 with right to true) action
is 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:
noaction
is reset to 0- For each player party member that IsStopped without skipimmobile while their
hp
is above 0:MagicUp
particles are played at the battleentity position- ClearStatus is called on the player party member
- Their
cantmove
is set to 0 making them able to act again
- UpdateConditionIcons is called which calls UpdateConditionBubbles on all battleentity (all
playerdata
with right to false and allenemydata
withhp
above 0 with right to true) - UpdateAnim is called
- If at least one player party member had ClearStatus called on them earlier, the
Heal3
sound is played followed by a 0.5 seconds yield