HoloKabbu
¶
Assumptions¶
This enemy is assumed to be fought with HoloVi and HoloLeif for certain moves to be usable and for the move selection process to work correctly.
It is also assume that this enemy's chargeonotherenemy contains HoloVi and HoloLeif because of specific logic that involves their hitaction
logic expecting it to be triggered by hitting this enemy (more specifically, an enemy with an animid of Beetle
).
By the same token, it is assumed that this enemy's animid
is Beetle
.
data
usage¶
At the start of the action, if data
is null or empty, it's initialised to be 5 element with a starting value of 0.
data[0]
: This reperesents the amount of time some specific moves were used in the battle by incrementing the value on each usage. If the value reaches 5, this enemy will no longer be able to use any moves in the list. Here are the implicated moves:- Revives HoloVi and HoloLeif from
reservedata
- Revives another enemy party member from
reservedata
leaving them at 7hp
- Inflict the Poison condition on HoloVi bypassing the
poisonres
check for 3 main turns. NOTE: For this move specifically,data[0]
will NOT increment, but the move still won't be used ifdata[0]
reaches 5
- Revives HoloVi and HoloLeif from
data[1]
: An actor turn cooldown on the usage of the any moves managed bydata[0]
. On usage of 2 of the 3 moves, the value is set to 3. The value is always decremented in the pre move logic when above 0 and the value must be 0 for any of the 3 moves managed bydata[0]
to be usable. Effectively, it's a 2 actor turns cooldown before any of the 3 moves become usable again. NOTE: The Poison infliction on HoloVi move exceptionally does NOT change the value ofdata[1]
upon usage, but the usage of the move is still forbidden ifdata[1]
is above 0data[2]
: An actor turn cooldown on the usage of the turn relay simulation move. On every usage of the move, the value is set to 3 and it is always decremented in the pre move logic when above 0. For the move to be usable, the value needs to be 0. Effectively, it's a 2 actor turn cooldown on the move before it becomes usable again. NOTE: If HoloVi uses their turn relay simulation move to this enemy, this enemy'sdata[2]
is set to 2 which is a 1 actor turn cooldown on the usage of this enemy's turn relay simulation movedata[3]
: This enforces a 1 time usage constraint of the move that revives HoloVi and HoloLeif fromreservedata
. On usage of the move, the value is set to 1 while the move requires a value of 0. This means that once the move is used once in the battle, it is not usable again for the remainder of the battle. In these circumstances, the singular 7hp
revive move will be used instead when applicabledata[4]
: An actor turn cooldown on the usage of the move with a Taunted infliction on all player party members for 2 main turns. When the move is used, the value is set to 3 and it is always decremented in the pre move logic if it is above 0. For the move to be usable, the value needs to be 0. Effectively, this is a 2 actor turns cooldown before the move becomes usable again
Move selection¶
10 moves are possible:
- A single target horn slash
- Revives HoloVi and HoloLeif from
reservedata
leaving their at 6hp
with canmove (so they can take an actor turn immediately on the same main turn) - Revives another enemy party member from
reservedata
leaving them at 7hp
with canmove (so they can take an actor turn immediately on the same main turn) - Inflict the Poison condition on HoloVi bypassing the
poisonres
check for 3 main turns (effectively 2 main turns since the current main turn ends soon) - Inflicts the Taunted condition on all player party members for 2 main turns (effectively 1 main turn since the current main turn ends soon)
- Revives another enemy party member from
reservedata
leaving them at 4hp
with canmove (so they can take an actor turn immediately on the same main turn) - A party wide dash attack
- A single target rock throw
- Simulate a turn relay by decrementing the
cantmove
of HoloVi or HoloLeif which grants them an additional actor turn on this main turn - A single target underground strike
Move 5 is always used if turns
is 0 (the first main turn).
Otherwise, the decision of which move to use is based on the weigthed odds. However, these weighted odds have 3 possible distribution sets which will be numbered as follows (the first one that applies is used):
- All of the following conditions are fufilled:
- Both HoloVi and HoloLeif are present, but this enemy either has at least 1
charge
or it has the AttackUp condition - Either HoloVi or HoloLeif isn't present (assumed to be dead)
In all sets, move 2 and 3 belong together as one unit used in the move selection process. To simplify this fact, it will be refered to as move 2-3 when refering to the move selection.
Also, each moves have additional requirements that if they aren't fufilled, the move won't be used and instead cause a reroll of the move selection process. However the amount of attempts to a move selection is tracked and after 5 failures to select a move, move 1 is always used.
There is a special case for move 2-3 because when selected, the decision if either move can be used and which one to use is nested inside the main move selection. This means that when move 2-3 is selected, the following decision logic happens to handle this:
- If both HoloVi and HoloLeif aren't present (assumed to be dead) and
data[3]
is 0 (move 2 wasn't used before), move 2 is always used. Due todata[3]
, this can only happen once per battle - If the above conditions aren't fufilled, but the
reservedata
isn't empty still (meaning it's assumed either HoloVi or HoloLeif is dead), move 3 is used - If none of the conditions above are fufilled, the move selection process is rerolled
Here are the odds for all distributions sets, their usage requirements and the step to take if those requirements aren't fufilled.
Move | Odds set 1 | Odds set 2 | Odds set 3 | Requirements |
---|---|---|---|---|
1 | 6/42 | 6/39 | 0/11 | None, the move is always used when selected |
2-3 | 4/42 | 2/39 | 2/11 |
|
4 | 2/42 | 1/39 | 1/11 | |
5 | 3/42 | 0/39 | 1/11 | data[4] is 0 or less (this move wasn't used in the last 2 actor turns of this enemy) |
6 | 3/42 | 3/39 | 3/11 | reservedata isn't empty (there is someone available to be revived) |
7 | 9/42 | 15/39 | 1/11 | None, the move is always used when selected |
8 | 6/42 | 0/39 | 1/11 | None, the move is always used when selected |
9 | 3/42 | 3/39 | 1/11 |
|
10 | 6/42 | 6/39 | 1/11 | None, the move is always used when selected |
As a sidenote, the entire move selection process occurs in the HoloKabbu coroutine who is yield returned by DoAction.
Pre move logic¶
The following logic always happens before the usage of a move (this happens in DoAction, the rest happens in HoloKabbu):
- entity.
sprite
.material.renderQueue set to 2500 - CreateShield called on the entity which initialises their
bubbleshield
if it didn't exist yet
Move 1 - Horn slash¶
A single target horn slash.
DoDamage calls¶
# | Conditions | attacker | target | damageammount | property | overrides | block |
---|---|---|---|---|---|---|---|
1 | Always happen | enemydata[actionid] 1 |
playertargetID after GetSingleTarget |
3 | Flip2 | null | commandsuccess |
1: This is incorrect because actionid
is unused so it's always 0 and under normal gameplay, this enemy should always be enemydata[1]
. The overall affect is the attacker is incorrectly set to be HoloVi while HoloKabbu
should have been the attacker here.
2: This property gets overriden to null in CalculateBaseDamage as the target is a player party member so it does nothing.
Logic sequence¶
This is done by yield returning the EnemyHeavyStrike coroutine with the battleentity:
- GetSingleTarget called
- Camera moves to look near
playerdata[playertargetID]
- MoveTowards
playertargetentity
position + (1.5, 0.0, -0.1) with 2.0 multiplier - Yield all frames until
forcemove
is done - animstate set to 103
Charge3
sound plays usingsounds[9]
with 1.2 pitch- ShakeSprite called with intensity (0.25, 0.0, 0.0) and 45.0 frametimer
- Yield for 0.75 seconds
sounds[9]
stopped- animstate set to 104
HugeHit
sound plays- ShakeScreen called with 0.2 ammount for 0.75 time with dontreset
- DoDamage 1 call happens
playertargetentity
's yspin
set to 35.0playertargetentity
has Jump called on them with an h of 15.0- Yield for 0.5 seconds
- Yield all frames until
playertargetentity
isonground
playertargetentity
'sspin
zeroed out- Yield for 0.5 seconds
Move 2 - Revives HoloVi and HoloLeif¶
Revives HoloVi and HoloLeif from reservedata
leaving their at 6 hp
with canmove (so they can take an actor turn immediately on the same main turn). No damages are dealt.
dontusecharge
set to true¶
This move always sets dontusecharge
to true which means charges
will not get zeroed out in post action.
Logic sequence¶
- Yield return ItemAnim with the battleentity with the
MiracleShake
item:- animstate set to 4 (
ItemGet
) ItemHold
sound plays- A new sprite object gets created rooted at this enemy + its
itemoffset
using the item's icon as sprite - Yield for 1.0 second
- The sprite gets destroyed
- animstate set to 4 (
data[3]
is set to 1 which prevents this move from being used again in the battle (move 3 will be used instead if applicable, see the move selection section above for details)data[0]
is incremented. If it reaches 5, this move, move 3 and move 4 can't be used anymoredata[1]
is set to 3 so this move, move 3 and move 4 can't be used for the next 2 actor turns- For each
reservedata
:- ReviveEnemy called to revive the enemy party member with an hppercent of 6.0 (leaves them at 6
hp
) with canmove and showcounter
- ReviveEnemy called to revive the enemy party member with an hppercent of 6.0 (leaves them at 6
- Yield for 1.0 second
Move 3 - Revives another enemy party member with 7 hp
¶
Revives another enemy party member from reservedata
leaving them at 7 hp
with canmove (so they can take an actor turn immediately on the same main turn). No damages are dealt.
dontusecharge
set to true¶
This move always sets dontusecharge
to true which means charges
will not get zeroed out in post action.
Logic sequence¶
- Yield return ItemAnim with the battleentity with the
MagicDrops
item:- animstate set to 4 (
ItemGet
) ItemHold
sound plays- A new sprite object gets created rooted at this enemy + its
itemoffset
using the item's icon as sprite - Yield for 1.0 second
- The sprite gets destroyed
- animstate set to 4 (
data[0]
is incremented. If it reaches 5, this move, move 2 and move 4 can't be used anymoredata[1]
is set to 3 so this move, move 2 and move 4 can't be used for the next 2 actor turns- ReviveEnemy called to revive a random
reservedata
with an hppercent of 7.0 (leaves them at 7hp
) with canmove and showcounter - Yield for 1.0 second
Move 4 - Poison infliction on HoloVi¶
Inflict the Poison condition on HoloVi bypassing the poisonres
check for 3 main turns (effectively 2 main turns since the current main turn ends soon). No damages are dealt.
dontusecharge
set to true¶
This move always sets dontusecharge
to true which means charges
will not get zeroed out in post action.
Logic sequence¶
- Yield return ItemAnim with the battleentity with the
DangerShroom
item:- animstate set to 4 (
ItemGet
) ItemHold
sound plays- A new sprite object gets created rooted at this enemy + its
itemoffset
using the item's icon as sprite - Yield for 1.0 second
- The sprite gets destroyed
- animstate set to 4 (
- StatusEffect called on HoloVi to inflict them the Poison condition for 3 main turns without effect with force (effectively for 2 main turns since the current main turn ends soon). This will bypass
poisonres
check Poison
sound playsPoisonEffect
particles plays at HoloVi position- Yield return ItemSpinAnim with a pos of HoloVi position + 1.0 in y and a sprite of the
PoisonAttacker
medal icon
Move 5 - Party wide Taunted infliction¶
Inflicts the Taunted condition on all player party members for 2 main turns (effectively 1 main turn since the current main turn ends soon). No damages are dealt.
dontusecharge
set to true¶
This move always sets dontusecharge
to true which means charges
will not get zeroed out in post action.
Logic sequence¶
This is done by yield returning the EnemyTaunt coroutine with the battleentity with all:
dontusecharge
is set to true- animstate set to 109
- Camera moves to look near this enemy
Taunt2
sound plays on loop usingsounds[9]
- Yield for 0.5 seconds
- Yield for 0.25 seconds
- SetDefaultCamera called
- For each player party members whose
hp
is above 0:- SetCondition called to inflict the Taunted condition on the player party member for 2 main turns (effectively 1 since the main turn advances soon after)
Taunt
sound plays- animstate of the player party member set depending on
playertargetID
(NOTE: This is incorrect because this move isn't single target so the value depends on whatever it happened to be assigned before):- 0 (
Bee
): 10 (Flustered
) - 1 (
Beetle
): 5 (Angry
) - 2 (
Moth
): 102
- 0 (
Prefabs/Particles/AngryParticle
instantiated childed to the player party member with local position being Vector3.up- Yield for 0.5 seconds
- Yield for 0.25 seconds
sounds[9]
stoppedPrefabs/Particles/AngryParticle
destroyed- the player party member animstate restored to its value before this action
Finally, data[4]
is set to 3 so this move isn't usable for the next 2 actor turns.
Move 6 - Revives another enemy party member with 4 hp
¶
Revives another enemy party member from reservedata
leaving them at 4 hp
with canmove (so they can take an actor turn immediately on the same main turn). No damages are dealt.
dontusecharge
set to true¶
This move always sets dontusecharge
to true which means charges
will not get zeroed out in post action.
Logic sequence¶
This is done by yield returning the EnemyPepTalk coroutine with the battleentity and targetting a random reservedata
enemy party member:
dontusecharge
is set to true- SetCamera called to move the camera without target at the selected
reservedata
with a speed of 0.05 and an offset of (0.0, 2.0, -6.0) which basically zooms in on the target - MoveTowards the selected
reservedata
+ (-1.25, 0.0, -0.1) - Yield all frames until
forcemove
is done flip
set to trueTaunt2
sound plays on loop- animstate set to 5 (
Angry
) - Yield for 0.75 seconds
Taunt2
sound stops- Yield return a ShakeSprite call on the selected
reservedata
with an intensity of 0.1 in x for 40.0 framtimer - ReviveEnemy called to revive the target with an hppercent of 4.0 (leaves them at 4
hp
) with canmove and showcounter - Yield for 0.5 seconds
Move 7 - Party wide dash attack¶
A party wide dash attack.
PartyDamage¶
# | Conditions | caller | damage | property | block | jumpheight | spinammount | jumpevenonblock | overrides |
---|---|---|---|---|---|---|---|---|---|
1 | Always happen | This enemy | 3 | Flip1 | commandsuccess |
0.0 | Vector3.zero | false | null |
1: This property gets overriden to null in CalculateBaseDamage as the target is a player party member so it does nothing.
Logic sequence¶
This is done by yield returning the BeetleDash coroutine with the following parameters:
- enemyid: This enemy
- damage: 3
- animprepare: 116
- animdash: 117
- startp: This enemy's position
- speed: 29.0
This is what the coroutine effectively ends up doing:
playertargetID
set to -1- Camera moves slightly to the left
- MoveTowards (-0.5, 0.0, 0.0) at 2.0 multiplier
- Yield all frames until
forcemove
is done Charge3
sound plays usingsounds[9]
with 1.2 pitch- animstate set to 116
- ShakeSprite called with (0.25, 0.0, 0.0) intensity and 60.0 frametimer
- Over the course of 41.0 frames, this enemy moves 2.0 to the left via a lerp
- ShakeSprite called with 0.1 intensity and 40.0 frametimer
- Yield for 41.0 frames counted by framestep
sounds[9]
stopped- animstate set to 117
trail
set to trueFastWoosh
sound plays- Over the course of 29.0 frames, this enemy moves to (-15.0, 0.0, 0.0) via a lerp. On the first frame that the x position is less than -4.5, the following happens only once:
- ShakeScreen called with an ammount of (0.25, 0.0, 0.0) for 0.65 time with dontreset
HugeHit
sound plays- PartyDamage 1 call happens
- position set to (15.0, 0.0, 0.0)
trail
set to false- SetDefaultCamera called
- animstate set to 1 (
Walk
) - Over the course of 61.0 frames, this enemy moves to startp via a lerp while having its animstate set to 1 (
Walk
) sprite
local position reset to Vector3.zerocheckingdead
set to null which signals the caller that this coroutine completed
Move 8 - Rock throw¶
A single target rock throw.
nonphyscal
set to true¶
This move always sets nonphyscal
to true which affects the effects of the FrostBite
, SpikeBod
and PoisonTouch
medal if equipped on the target
DoDamage calls¶
# | Conditions | attacker | target | damageammount | property | overrides | block |
---|---|---|---|---|---|---|---|
1 | Always happen | null | playertargetID after GetSingleTarget |
3 | null | null | commandsuccess |
Logic sequence¶
This is done by yield returning the EnemyPebbleToss coroutine with the battleentity:
- GetSingleTarget called
- animstate set to 28 (
TossItem
) Toss
sound plays- A new sprite object is created rooted at this enemy postion + (0.5, 2.0, -0.1) using the
MightyPeeble
medal sprite - Over the course of 48.0 frames, the
MightyPeeble
sprite moves toplayertargetentity
position + (0.0, 2.0, -0.1) via a BeizierCurve3 with a ymax of 3.5. Before each frame yield,MightyPeeble
's z angle increses by 15.0 * framestep - DoDamage 1 call happens
MightyPeeble
object is destroyed- Yield for 0.5 seconds
Move 9 - Decrements the cantmove
of HoloVi or HoloLeif¶
Simulate a turn relay by decrementing the cantmove
of HoloVi or HoloLeif which grants them an additional actor turn on this main turn. No damages are dealt.
dontusecharge
set to true¶
This move always sets dontusecharge
to true which means charges
will not get zeroed out in post action.
Logic sequence¶
The target is selected randomly between HoloVi and HoloLeif. As explained in the move selection above, the target must be present and not be IsStoppedLite (same as IsStopped, but Flipped doesn't count as stopped). This will assume this is the case:
- Yield return on EnemyRelay with the battleentity to the target:
dontusecharge
set to true- This enemy animstate set to 4 (
ItemGet
) - The target animstate set to 2 (
Jump
) - This enemy's y
spin
set to 15.0 - The target's y
spin
set to 15.0 - The target's
cantmove
is decremented which grants them an additional actor turn on this main turn Relay
sound plays- Yield for 0.5 seconds
- This enemy
spin
zeroed out - The target
spin
zeroed out - The target animstate reset to its
basestate
- This enemy animstate reset to its
basestate
data[2]
set to 3 so this move isn't usable for the next 2 actor turns- If the target of the move's
data
isn't yet initialised, it is initialised to 10 blank slots (even if not all of them will be used) - The target's
data[2]
is set to 2 which prevents them from using their version of this move on the current main turn
Move 10 - Underground strike¶
A single target underground strike.
DoDamage calls¶
# | Conditions | attacker | target | damageammount | property | overrides | block |
---|---|---|---|---|---|---|---|
1 | Always happen | enemydata[actionid] 1 |
playertargetID after GetSingleTarget |
4 | Pierce2 | null | commandsuccess |
1: This is incorrect because actionid
is unused so it's always 0 and under normal gameplay, this enemy should always be enemydata[1]
. The overall affect is the attacker is incorrectly set to be HoloVi while HoloKabbu
should have been the attacker here.
2: Enemy piercing damages are disabled so this property does nothing, see the CalculateBaseDamage documentation to learn more
Logic sequence¶
This is done by yield returning the EnemyKabbuDig coroutine with the battleentity:
- GetSingleTarget called
Dig
sound plays- animstate set to 101
digging
set to true- Yield for 0.65 seconds
- Camera moves to look near
playerdata[playertargetID]
- MoveTowards
playertargetentity
position with 2.0 multiplier Digging
sound plays on loop usingsounds[9]
- Yield all frames until
forcemove
is done - Yield for 0.25 seconds
- ShakeScreen called with 0.1 ammount for 0.75 time with dontreset
sounds[9]
stopped- DoDamage 1 call happens
- SetDefaultCamera called
digging
set to falsesprite
angles reset to Vector3.zero- y
spin
set to 20.0 - animstate set to 119
sprite
scale set tostartscale
DigPop
sound playsDirtExplode
particles plays atplayertargetentity
position- Over the course of 46.0 frames, this enemy moves to the value before this coroutine + Vector3.up via a BeizierCurve3 with a ymax of 0.0
- position set to the value before this coroutine
- animstate set to 13 (
BattleIdle
) - SetAnimForce called
spin
zeroed out