ZombieRoach¶
data usage¶
At the start of the action, if data is null or empty, it's initialised to be 4 element with a starting value of 0 for each element except data[1] where the starting value is 2.
data[0]: This tells the "mode" this enemy is on which drastically changes the move selection process because it changes the sets of move they can use. The value can only be 0 or 1 and it is toggled between the 2 whendata[1]is 0 at the end of the action which will cause them to switch the current mode in the post move logic and havedata[1]set back to 2 (meaning the current mode won't change until 2 main turns). Here are the details of the 2 modes:- 0: Sand mode. Here are the moveset changes:
- The energy spheres throw move is accessible, but not the single target ice attack move
- The moving sand attack move is accessible, but not the party wide icicle throw move
- When summoning an enemy, it will always be a SandWall
- After using a magic boost or heal, the energy spheres throw move will always be used
- 1: Ice mode. Here are the moveset changes:
- The single target ice attack move is accessible, but not the energy spheres throw move
- The party wide icicle throw move is accessible, but not the moving sand attack move
- When summoning an enemy, it will always be an IceWall
- After using a magic boost or heal, the single target ice attack move will always be used
- 0: Sand mode. Here are the moveset changes:
data[1]: This is the main turn cooldown beforedata[0]is toggled which causes a mode switch. Its starting value is 2 and it decreases at the end of their last actor turn of the main turn in the post move logic. When it reaches 0 after the decrement,data[0]is toggled between 0 and 1 which causes a mode changedata[2]: This is an actor turn cooldown that restricts the usage of the moving sand move and party wide icicle throw move. When the former is used, the value is set to 2 and when the latter is used, the value is set to 3. At the start of every actor turn in the pre move logic, the value decrements when it is above 0. For either moves to be selectable (whichever one is appropriate for the current mode), the value needs to be 0 after the decrement. However, this doesn't apply if this enemy's position isUndergroundas the moving sand move is always used in that case. It also doesn't completely prevent either move to be used if the enemy selects the wall enemy summon move while there is already one inenemydata. See the move selection section below for detailsdata[3]: Effectively UNUSED because while it is written to when this enemy heals themselves and it is decremented in the post move logic if it's higher than 0, it is never read meaning this value effectively doesn't do anything
HardMode changes¶
HardMode being true does the following changes:
- The HPPercent threshold changes for getting a moves of 2 and a decremented
cantmove(2 actor turns per main turns including the current one). It changes to be when it reaches lower than 0.5 from 0.33 - In the energy spheres throw move, the amount of projectiles to throw changes to be random between 2 and 3 inclusive instead of always being 2
- In the energy spheres throw move, the base damage dealt per each projectile changes to 2 from 3
- In the energy spheres throw move, the yield time before each Projectile calls changes to 0.5 seconds from 0.65 seconds
- In the energy spheres throw move, the speed of each projectile changes to 40.0 from 50.0
- In the single target ice attack move, the amount of frames the ice pillar takes to reach its target and appear changes to 71.0 frames from 81.0 frames
- In the moving sand attack move, the DoCommand call (which is a TappingKey) has
barfilldecrease 25% faster each frame. However, this change doesn't affect anything ifmashcommandaltis true making the command a SequentialKeys - In the moving sand attack move, the damageammount of each DoDamage calls changes to 0 from 1 (this doesn't mean the call no longer does damages because it is meant for the
hardatkeffect to apply which could deal a non zero amount of damages and the call also has AtLeast1Pierce which guarantees a non zero amount of damages) - In the enemy summon move,
cantmovegets decremented which grants an additonal actor turn to this enemy
Move selection¶
6 moves are possible:
- A multiple targets energy spheres throw
- A single target ice attack
- A single target moving sand attack that may hit multiple times and drain
hp - A party wide icicle throw
- Summons a new SandWall or IceWall enemy
- Uses magic to boost or heal themselves, then performs move 1 or 2
The move selection process is complex because it involves the current mode (see the data[0] explanation above), odds (which can change depending on data[2]) as well as some special cases.
For the mode, it changes which pair of moves is usable amongst move 1 through 4 and it also decides the enemy to summon in move 5. The other pair is innacessible and will never be used until the mode toggles. Here is a table that summarises each mode (the starting mode is the sand mode):
| Mode | Moves accessible | Enemy summoned on move 5 |
|---|---|---|
| Sand |
|
SandWall |
| Ice |
|
IceWall |
What's important is that move 1 and 2 as well as move 3 and 4 are viewed as the same during the move selection process. The actual move to use from each of these pairs is determined by the mode, but they still feature completely different logic which is why they are also documented as separate moves. For the sake of simplicity, each pair will be refered to as "move 1-2" and "move 3-4" since they are viewed the same way during the selection process.
Next, the odds to use a move. Here are the base odds to use each move:
| Move or pair | Odds |
|---|---|
| 1-2 | 2/7 |
| 3-4 | 2/7 |
| 5 | 1/7 |
| 6 | 2/7 |
However, there are 2 special cases to this:
- If position is
Underground, move 3-4 is always used (this should only and always be the case after using move 3 and in such case, move 3 will be used again) - If move 3-4 was selected and
data[2]is above 0 (after the decrement), the move can't be selected because the actor turn cooldown on it hasn't expired yet
In that second case, the entire move selection is rerolled with different odds that don't include move 3/4. Here are those special odds:
| Move or pair | Odds |
|---|---|
| 1-2 | 2/5 |
| 5 | 1/5 |
| 6 | 2/5 |
Finally, move 5 may cause another move to be used instead once selected if there are more than 1 enemydata including this enemy (which means move 5 was used and the summoned enemy is still present). When this happens, move 1-2 or move 3-4 will be used which is determined by an RNG check with uniform probabilities (1/2 chance each).
Pre move logic¶
The following logic always happen at the start of the action:
- If
data[2]is above 0, it is decremented (this is the move 3-4 cooldown tracking)
Next is a phase transition that happens if all of the following conditions are fufilled:
- BattlePosition isn't
Underground - HPPercent is less than 0.33 (0.5 instead if hardmode is true)
- This enemy's moves is 1 (meaning this transition didn't happen yet)
Here is what happens in the phase transition:
Magicsound playsMagicUpparticles plays at this enemy position- animstate set to 100
- y
spinset to 15.0 - Yield for 0.75 seconds
spinzeroed outStatUpsound plays- StatEffect called on this enemy with type 5 (yellow up arrow)
movesset to 2 andcantmovedecremented (gives 2 actor turns per main turn including the current main turn)- Yield for 0.5 seconds
Post move logic¶
The following logic always happen after using a move:
- If
cantmoveis 0 (meaning this is the end of the last actor turn of this enemy which acts as a pseudo main turn ending check),data[1]is decremented. If after this decrement, it became 0 or below (meaning the main turn cooldown for toggling the mode just expired):- If position is
Underground, it is changed toGroundwith the following logic (it is assumed that the moving sand attack move was used):- MoveTowards startp with a 2.0 multiplier
- Yield all frames until
forcemoveis done diggingset to falseflipset to false- FlipAngle called with setangle
checkingdeadset to a new ChangePosition call to change this enemy'spositiontoGround- Over the course of 31.0 frames,
extra[1](aPrefabs/Objects/MovingSandfrom the moving sand attack move) scale changes from 0.5x to 0.0x via a lerp extra[1]gets destroyed- Yield all frames until
checkingdeadis null (the coroutine completed)
initialheightset to 0.3data[0]toggled (becomes 1 if it was 0 or becomes 0 if it was 1)- y
spinset to 15.0 Clothsound plays- If
data[0]is 1 (ice mode):- The local startstate is set to 13 (
BattleIdle) minheightandheightset to 0.0- animstate set to 102
- The local startstate is set to 13 (
- Otherwise (sand mode):
- The local startstate is set to 0 (
Idle) heightandminheightset toinitialheight- animstate set to 103
bobspeedandbobrangeset tostartbsandstartbfrespectively
- The local startstate is set to 0 (
data[1]set to 2 (reset the main turn cooldown before toggling modes again)- Yield for 0.5 seconds
spinzeroed out- FlipAngle called with setangle
basestateand animstate set to the local startstate
- If position is
- If
data[3]is above 0, it is decremented (this doesn't do anything since thisdataslot is effectively UNUSED)
Move 1 - Energy spheres throw¶
A multiple targets energy spheres 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.
Projectile calls¶
| # | Conditions | damage | property | attacker | playertarget | obj | speed | height | extraargs | destroyparticle | audioonhit | audiomoving | spin | nosound |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Always happen from 2 times (random between 2 and 3 times instead if hardmode is true), but each call requires that at least 1 player party member is alive (hp above 0 and not eatenby) |
3 (2 instead if hardmode is true) | null | This enemy | playertargetID after GetSingleTarget (target changes for each call) |
A new Prefabs/Objects/EnergySphere GameObject rooted positioned at this enemy position + (-2.0, 4.0, 0.0) + a random vector between (-1.5, -1.0, 0.0) and (1.5, 1.0, 0.0) with a NoMapColor tag |
50.0 (40.0 instead if hardmode is true) | 1.0 (-0.5 instead if it's the second hit) | SepPart@3@1,keepcolor |
Stars |
PingShot |
null | Vector3.zero | false |
Logic sequence¶
- animstate set to 100
- Yield for 0.5 seconds
- The amount of hits is determined which is 2 (random between 2 and 3 instead if hardmode is true)
checkingdeadset to an EnergySpheres coroutine with the amount of hits to do (checkingdeadis set to null when completed)- Yield all frames until
checkingdeadis null
This is what the EnergySpheres coroutine ends up doing:
- A GameObject array is created to hold each projectile objects
- For each hits to do:
- If at least one player party member is alive (
hpabove 0 and not eatenby):- GetSingleTarget
Charge7sound plays- A new
Prefabs/Particles/ChargingGameObject is created rooted positioned at this enemy position + (-2.0, 4.0, 0.0) + a random vector between (-1.5, -1.0, 0.0) and (1.5, 1.0, 0.0) - Yield for 0.65 seconds (0.5 seconds instead if hardmode is true)
- The projectile element is set to a new
Prefabs/Objects/EnergySphereGameObject rooted positioned at thePrefabs/Particles/Chargingposition with aNoMapColortag Lazer2sound plays- Projectile 1 call happens
Prefabs/Particles/Chargingmoves offscreen at 999.0 in yPrefabs/Particles/Charginggets destroyed in 3.0 seconds- Yield all frames until the projectile element is null (the Projectile call completed)
- If at least one player party member is alive (
- Yield for 0.5 seconds
checkingdeadset to null which signals the caller that the coroutine completed
Move 2 - Single target ice attack¶
A single target ice attack.
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 | This enemy | playertargetID after GetSingleTarget |
3 | Freeze | null | commandsuccess |
Logic sequence¶
This is done by yield returning the EnemyIceAttackBasic coroutine with the battleentity:
- GetSingleTarget
- animstate set to 101
IceMothThrowsound plays- A new
Prefabs/Objects/SingleSphereGameObject is created childed to a newPrefabs/AnimSpecific/mothbattlesphereGameObject - Over the course of 31.0 frames, the
Prefabs/AnimSpecific/mothbattlespheremoves from this enemy position + (1.1, 1.85, -0.1) to this enemy position + (-2.0, -0.5, 5.0) via a BeizierCurve3 with a ymax of 5.0 - The
Prefabs/Objects/SingleSpheregets rooted - If
hologramis true, thePrefabs/Objects/SingleSphereRenderer's color is set to 8080FF (mostly blue) with half opacity Prefabs/AnimSpecific/mothbattlespheregets destroyedWatcherIcesound plays- Over the course of 81.0 frames (71.0 instead if hardmode is true),
Prefabs/Objects/SingleSpheremoves from its position with the y component at 0.0 toplayertargetentityposition via a SmoothLerp Prefabs/Objects/SingleSpheregets destroyed- animstate set to 104
IceMothHitsound plays- A new
Prefabs/Particles/mothicenormalGameObject is created rooted atplayertargetentityposition + 0.5 in y then destroyed in 2.0 seconds - A new
Prefabs/Objects/icepillaris created rooted atplayertargetentityposition with a DialogueAnim that has atargetscaleof (0.5, 0.5, 1.0) - DoDamage 1 call happens
- Yield for 0.65 seconds
- The
Prefabs/Objects/icepillar's DialogueAnim has itsshrinkset to true with ashrinkspeedof 0.025 - The
Prefabs/Objects/icepillargets destroyed in 5.0 seconds - Yield for 0.5 seconds
Move 3 - Moving sand attack¶
A single target moving sand attack that may hit multiple times and drain hp.
DoCommand calls¶
| # | Conditions | timer | commandtype | data |
|---|---|---|---|---|
| 1 | None | -1.0 (infinite) | TappingKey |
|
1: Due to the clamping logic related to this value, it means that the decrease value per frame is 0.005 * the game's frametime when hardmode is false and 0.00625 * the game's frametime when hardmode is true. Effectively, it means that hardmode being true makes barfil decrease 25% more per frame
DoDamage calls¶
| # | Conditions | attacker | target | damageammount | property | overrides | block |
|---|---|---|---|---|---|---|---|
| 1 | Called once if barfill is less than 1.0 (not full) during DoCommand 1 once 0.5 seconds passed and then continously called again every 1.25 seconds until either barfill reaches 1.0 (checked 0.75 seconds after each call) or that playerdata[playertargetID]'s hp becomes 0 |
This enemy | playertargetID after GetSingleTarget (target is the same for each calls) |
1 (0 instead if hardmode is true1) | Atleast1pierce2 | null | false |
1: This doesn't mean the call won't deal any damage because not only Atleast1pierce guarantees 1 damage is dealt, but also because it is meant to function with hardatk in mind which takes effect when hardmode is true
2: Enemy piercing damages are disabled, see the CalculateBaseDamage documentation to learn more
Logic sequence¶
data[2]set to 3 (this is the actor turn cooldown to use this move or the party wide icicle throw, it will effectively be 2 actor turns since the decrement happens before)WatcherSandLoopsound plays on loop usingsounds[9]- If this enemy position isn't already
Underground, it is changed to it with the following:diggingset to truecheckingdeadset to a new ChangePosition call to change this enemy'spositiontoUndergroundextra[1]initialised to a newPrefabs/Objects/MovingSandGameObject childed to this enemy with a Renderer's color of pure gray- Over the course of 61.0 frames,
extra[1]scale changes from 0.0x to 0.5x via a lerp - Yield all frames until
checkingdeadis null (the coroutine completed)
- GetSingleTarget called
- MoveTowards
playertargetentity - Yield all frames until
forcemoveis done - Camera moves to look near
playerdata[playertargetID] - y
spinset to 13.0 playertargetentityanimstate set to 11 (Hurt)- Over the course of 30.0 frames,
playertargetentitymoves to -0.5 in y via a lerp infinitecommandeset to true which will prevent DoCommand 1 to end when MainManager.mashcommandaltis true until the action command is succeeded- CreateHelpBox called with 4 (the TappingKey command's help)
- DoCommand 1 call happens
- As long as
playerdata[playertargetID]'shpis above 0 andactionroutineisn't null (meaning DoCommand 1 hasn't ended yet):- Yield for 0.5 seconds
- If
barfillis less than 1.0 (it isn't full yet):- DoDamage 1 call happens
- If
lastdamageis above 0, Heal is called to heal this enemy bylastdamageamount ofhp
- Yield for 0.75 seconds
Barfillsound stops- DestroyHelpBox is called which sets
helpboxidto -1 and destroyshelpboxif it existed in 0.5 seconds with shrink before setting it to null - FinishAction is called manually to end DoCommand 1 if it wasn't already (but it should be by then)
- MoveTowards + 3.0 in x
playertargetentity's yspinset to 20.0- Over the course of 30.0 frames,
playertargetentitymoves from its position - 0.5 to its position before this action via a BeizierCurve3 with a ymax of 2.0 - SetDefaultCamera called
playertargetentity'sspinzeroed outsounds[9]stopped- If
playertargetentity'shpis above 0, its animstate is set to the value they had before this action - Yield all frames until
forcemoveis done
Move 4 - Party wide icicle throw¶
A party wide icicle 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.
PartyDamage¶
| # | Conditions | caller | damage | property | block | jumpheight | spinammount | jumpevenonblock | overrides |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Always happen | This enemy | 4 | Freeze | commandsuccess |
0.0 | Vector3.zero | false | null |
Logic sequence¶
This is done by yield returning the EnemyIceFall coroutine with the battleentity:
- animstate set to 100
- A new
Prefabs/Objects/icecleGameObject is created rooted positioned at this enemy position + (-2.0, 4.5, 0.0) with a scale of 0.0x and its BoxCollider destroyed Spinsound plays on loop usingsounds[8]- Over the course of 60.0 frames,
Prefabs/Objects/iceclescale changes to 1.25x via a lerp, the y angle goes towards 10.0 and thesounds[8]pitch changes from 0.0 to 1.0 - A new UI object is created named
tchilded to theGUICamerausing theguisprites[41]sprite (a crosshair) on layer 15 (3DUI) - animstate set to 101
Crosshairsound plays on loop usingsounds[9]with 0.9 pitch and 0.35 volume- Over the course of 81.0 frames,
tmoves from (0.0, 3.0, 0.0) to (-4.5, 1.0, 0.0) via a SmoothLerp + a number in the y component that goes from Sin(Time.time * 2.0) * -3.0 to 0.0. Before each yield,tz angle increases by 5x the game's frametime andPrefabs/Objects/icecley angles increases by 10.0 sounds[8]andsounds[9]stoppedIceMothThrowsound playstgets destroyedPrefabs/Objects/icecleangles set to (0.0, 0.0, -45.0)- Over the course of 26.0 frames,
Prefabs/Objects/iceclemoves to (-4.5, 1.0, 0.0) via a lerp IceMothHitsound playsmothicenormalparticles plays at thePrefabs/Objects/icecleposition with a scale of 2.0xPrefabs/Objects/iceclegets destroyed- PartyDamage 1 call happens
- Yield for 0.5 seconds
Move 5 - Wall enemy summon¶
Summons a new SandWall or IceWall enemy. No damages are dealt.
Logic sequence¶
Charge12sound plays- animstate set to 100
- Yield for 0.5 seconds
- ShakeScreen called with 0.2 ammount and 0.75 time
- Yield for 0.75 seconds
- animstate set to 104
Charge15sound playsimpactsmokeparticles plays at this enemy position - 3.0 in xcheckingdeadset to a new SummonEnemy call to summon a SandWall enemy (in sand mode) or IceWall enemy (in ice mode) at this enemy position - 3.0 in x- Yield all frames until
checkingdeadis null (the coroutine completed) - If hardmode is true,
cantmoveis decremented which grants an additional actor turn to this enemy enemydata[1](which should always be the wall that was just summoned) has itsdiebyitselfset to true which mean if they are the only enemy party member alive, CheckDead will kill them
Move 6 - Magic boost or heal followed by move 1 or 2¶
Uses magic to boost or heal themselves, then performs move 1 (Energy spheres / Single target ice). No damages are dealt for this move, but move 1 will causes damages to be dealt.
Logic sequence¶
Magicsound playsMagicUpparticles plays at this enemy position- animstate set to 100
- y
spinset to 15.0 - Yield for 0.75 seconds
spinzeroed out
From there, 3 effects can occur: a heal, AttackUp condition or DefenseUp condition. The one that will be done depends on 2 checks:
locktriis false and a 2.5/10.0 RNG check passes- HPPercent is less than 0.4 and a 5/10 RNG check passes
Here is a table that summarises which one will be done when according to these 2 checks (note that check 2 is only tested if check 1 was true):
| Check 1 | Check 2 | Effect |
|---|---|---|
| false | N/A | DefenseUp |
| true | false | AttackUp condition |
| true | true | Heal |
The locktri requirement for the AttackUp and heal is set to true when the heal effect happens. This means that healing will prevent this enemy from ever healing or getting the AttackUp condition again by the usage of this move.
Here is what happens in the DefenseUp condition effect:
StatUpsound plays- StatEffect called on this enemy with type 1 (blue up arrow)
- SetCondition called to inflict the DefenseUp condition on this enemy for 2 main turns
Here is what happens for the AttackUp condition effect:
- StatEffect called on this enemy with type 0 (red up arrow)
- SetCondition called to inflict the AttackUp condition on this enemy for 2 main turns
StatUpsound plays
And here's what happens in the healing effect:
- Heal is called to heal this enemy by its
maxhp* 0.1 floored locktriis set to true (this will prevent this enemy to heal or get an AttackUp condition by using this move again)data[3]set to 3 (this doesn't do anything because thisdataslot is UNUSED)
Finally, after the effect is done, the following happens:
- Yield for 0.5 seconds
- Move 1 or 2 (whichever is appropriate based on the current mode) is used immediately without ending this actor turn