diff options
author | Rangi <35663410+Rangi42@users.noreply.github.com> | 2020-07-03 09:38:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-03 09:38:52 -0400 |
commit | c85050497c1bd062e9cd40bf5b32fa3beca366cc (patch) | |
tree | 9593ddd3ab820223ab580d5fc0ae133b485b8315 /engine/battle/move_effects | |
parent | 5559d51c863b6fb529ea0494d857950a36fe85b7 (diff) | |
parent | 87ef75c173b5d5f227912860487600b6f53d1d1f (diff) |
Merge pull request #256 from Rangi42/master
Add subdirectories to engine/ similar to pokecrystal
Diffstat (limited to 'engine/battle/move_effects')
-rw-r--r-- | engine/battle/move_effects/conversion.asm | 35 | ||||
-rw-r--r-- | engine/battle/move_effects/drain_hp.asm | 104 | ||||
-rw-r--r-- | engine/battle/move_effects/focus_energy.asm | 22 | ||||
-rw-r--r-- | engine/battle/move_effects/haze.asm | 81 | ||||
-rw-r--r-- | engine/battle/move_effects/heal.asm | 120 | ||||
-rw-r--r-- | engine/battle/move_effects/leech_seed.asm | 40 | ||||
-rw-r--r-- | engine/battle/move_effects/mist.asm | 19 | ||||
-rw-r--r-- | engine/battle/move_effects/one_hit_ko.asm | 38 | ||||
-rw-r--r-- | engine/battle/move_effects/paralyze.asm | 47 | ||||
-rw-r--r-- | engine/battle/move_effects/pay_day.asm | 45 | ||||
-rw-r--r-- | engine/battle/move_effects/recoil.asm | 70 | ||||
-rw-r--r-- | engine/battle/move_effects/reflect_light_screen.asm | 45 | ||||
-rw-r--r-- | engine/battle/move_effects/substitute.asm | 77 | ||||
-rw-r--r-- | engine/battle/move_effects/transform.asm | 148 |
14 files changed, 891 insertions, 0 deletions
diff --git a/engine/battle/move_effects/conversion.asm b/engine/battle/move_effects/conversion.asm new file mode 100644 index 00000000..f23c3d70 --- /dev/null +++ b/engine/battle/move_effects/conversion.asm @@ -0,0 +1,35 @@ +ConversionEffect_: + ld hl, wEnemyMonType1 + ld de, wBattleMonType1 + ld a, [H_WHOSETURN] + and a + ld a, [wEnemyBattleStatus1] + jr z, .conversionEffect + push hl + ld h, d + ld l, e + pop de + ld a, [wPlayerBattleStatus1] +.conversionEffect + bit INVULNERABLE, a ; is mon immune to typical attacks (dig/fly) + jr nz, PrintButItFailedText +; copy target's types to user + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + ld hl, PlayCurrentMoveAnimation + call CallBankF + ld hl, ConvertedTypeText + jp PrintText + +ConvertedTypeText: + TX_FAR _ConvertedTypeText + db "@" + +PrintButItFailedText: + ld hl, PrintButItFailedText_ +CallBankF: + ld b, BANK(PrintButItFailedText_) + jp Bankswitch diff --git a/engine/battle/move_effects/drain_hp.asm b/engine/battle/move_effects/drain_hp.asm new file mode 100644 index 00000000..e5f4681a --- /dev/null +++ b/engine/battle/move_effects/drain_hp.asm @@ -0,0 +1,104 @@ +DrainHPEffect_: + ld hl, wDamage + ld a, [hl] + srl a ; divide damage by 2 + ld [hli], a + ld a, [hl] + rr a + ld [hld], a + or [hl] ; is damage 0? + jr nz, .getAttackerHP +; if damage is 0, increase to 1 so that the attacker gains at least 1 HP + inc hl + inc [hl] +.getAttackerHP + ld hl, wBattleMonHP + ld de, wBattleMonMaxHP + ld a, [H_WHOSETURN] + and a + jp z, .addDamageToAttackerHP + ld hl, wEnemyMonHP + ld de, wEnemyMonMaxHP +.addDamageToAttackerHP + ld bc, wHPBarOldHP+1 +; copy current HP to wHPBarOldHP + ld a, [hli] + ld [bc], a + ld a, [hl] + dec bc + ld [bc], a +; copy max HP to wHPBarMaxHP + ld a, [de] + dec bc + ld [bc], a + inc de + ld a, [de] + dec bc + ld [bc], a +; add damage to attacker's HP and copy new HP to wHPBarNewHP + ld a, [wDamage + 1] + ld b, [hl] + add b + ld [hld], a + ld [wHPBarNewHP], a + ld a, [wDamage] + ld b, [hl] + adc b + ld [hli], a + ld [wHPBarNewHP+1], a + jr c, .capToMaxHP ; if HP > 65,535, cap to max HP +; compare HP with max HP + ld a, [hld] + ld b, a + ld a, [de] + dec de + sub b + ld a, [hli] + ld b, a + ld a, [de] + inc de + sbc b + jr nc, .next +.capToMaxHP + ld a, [de] + ld [hld], a + ld [wHPBarNewHP], a + dec de + ld a, [de] + ld [hli], a + ld [wHPBarNewHP+1], a + inc de +.next + ld a, [H_WHOSETURN] + and a + coord hl, 10, 9 + ld a, $1 + jr z, .next2 + coord hl, 2, 2 + xor a +.next2 + ld [wHPBarType], a + predef UpdateHPBar2 + predef DrawPlayerHUDAndHPBar + predef DrawEnemyHUDAndHPBar + callab ReadPlayerMonCurHPAndStatus + ld hl, SuckedHealthText + ld a, [H_WHOSETURN] + and a + ld a, [wPlayerMoveEffect] + jr z, .next3 + ld a, [wEnemyMoveEffect] +.next3 + cp DREAM_EATER_EFFECT + jr nz, .printText + ld hl, DreamWasEatenText +.printText + jp PrintText + +SuckedHealthText: + TX_FAR _SuckedHealthText + db "@" + +DreamWasEatenText: + TX_FAR _DreamWasEatenText + db "@" diff --git a/engine/battle/move_effects/focus_energy.asm b/engine/battle/move_effects/focus_energy.asm new file mode 100644 index 00000000..16dad7bb --- /dev/null +++ b/engine/battle/move_effects/focus_energy.asm @@ -0,0 +1,22 @@ +FocusEnergyEffect_: + ld hl, wPlayerBattleStatus2 + ld a, [H_WHOSETURN] + and a + jr z, .notEnemy + ld hl, wEnemyBattleStatus2 +.notEnemy + bit GETTING_PUMPED, [hl] ; is mon already using focus energy? + jr nz, .alreadyUsing + set GETTING_PUMPED, [hl] ; mon is now using focus energy + callab PlayCurrentMoveAnimation + ld hl, GettingPumpedText + jp PrintText +.alreadyUsing + ld c, 50 + call DelayFrames + jpab PrintButItFailedText_ + +GettingPumpedText: + TX_DELAY + TX_FAR _GettingPumpedText + db "@" diff --git a/engine/battle/move_effects/haze.asm b/engine/battle/move_effects/haze.asm new file mode 100644 index 00000000..47723ba2 --- /dev/null +++ b/engine/battle/move_effects/haze.asm @@ -0,0 +1,81 @@ +HazeEffect_: + ld a, $7 +; store 7 on every stat mod + ld hl, wPlayerMonAttackMod + call ResetStatMods + ld hl, wEnemyMonAttackMod + call ResetStatMods +; copy unmodified stats to battle stats + ld hl, wPlayerMonUnmodifiedAttack + ld de, wBattleMonAttack + call ResetStats + ld hl, wEnemyMonUnmodifiedAttack + ld de, wEnemyMonAttack + call ResetStats +; cure non-volatile status, but only for the target + ld hl, wEnemyMonStatus + ld de, wEnemySelectedMove + ld a, [H_WHOSETURN] + and a + jr z, .cureStatuses + ld hl, wBattleMonStatus + dec de ; wPlayerSelectedMove + +.cureStatuses + ld a, [hl] + ld [hl], $0 + and SLP | (1 << FRZ) + jr z, .cureVolatileStatuses +; prevent the Pokemon from executing a move if it was asleep or frozen + ld a, $ff + ld [de], a + +.cureVolatileStatuses + xor a + ld [wPlayerDisabledMove], a + ld [wEnemyDisabledMove], a + ld hl, wPlayerDisabledMoveNumber + ld [hli], a + ld [hl], a + ld hl, wPlayerBattleStatus1 + call CureVolatileStatuses + ld hl, wEnemyBattleStatus1 + call CureVolatileStatuses + ld hl, PlayCurrentMoveAnimation + call CallBankF + ld hl, StatusChangesEliminatedText + jp PrintText + +CureVolatileStatuses: + res CONFUSED, [hl] + inc hl ; BATTSTATUS2 + ld a, [hl] + ; clear USING_X_ACCURACY, PROTECTED_BY_MIST, GETTING_PUMPED, and SEEDED statuses + and $ff ^((1 << USING_X_ACCURACY) | (1 << PROTECTED_BY_MIST) | (1 << GETTING_PUMPED) | (1 << SEEDED)) + ld [hli], a ; BATTSTATUS3 + ld a, [hl] + and %11110000 | (1 << TRANSFORMED) ; clear Bad Poison, Reflect and Light Screen statuses + ld [hl], a + ret + +ResetStatMods: + ld b, $8 +.loop + ld [hli], a + dec b + jr nz, .loop + ret + +ResetStats: + ld b, $8 +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + ret + +StatusChangesEliminatedText: + TX_FAR _StatusChangesEliminatedText + db "@" diff --git a/engine/battle/move_effects/heal.asm b/engine/battle/move_effects/heal.asm new file mode 100644 index 00000000..2e68acc0 --- /dev/null +++ b/engine/battle/move_effects/heal.asm @@ -0,0 +1,120 @@ +HealEffect_: + ld a, [H_WHOSETURN] + and a + ld de, wBattleMonHP + ld hl, wBattleMonMaxHP + ld a, [wPlayerMoveNum] + jr z, .healEffect + ld de, wEnemyMonHP + ld hl, wEnemyMonMaxHP + ld a, [wEnemyMoveNum] +.healEffect + ld b, a + ld a, [de] + cp [hl] ; most significant bytes comparison is ignored + ; causes the move to miss if max HP is 255 or 511 points higher than the current HP + inc de + inc hl + ld a, [de] + sbc [hl] + jp z, .failed ; no effect if user's HP is already at its maximum + ld a, b + cp REST + jr nz, .healHP + push hl + push de + push af + ld c, 50 + call DelayFrames + ld hl, wBattleMonStatus + ld a, [H_WHOSETURN] + and a + jr z, .restEffect + ld hl, wEnemyMonStatus +.restEffect + ld a, [hl] + and a + ld [hl], 2 ; clear status and set number of turns asleep to 2 + ld hl, StartedSleepingEffect ; if mon didn't have an status + jr z, .printRestText + ld hl, FellAsleepBecameHealthyText ; if mon had an status +.printRestText + call PrintText + pop af + pop de + pop hl +.healHP + ld a, [hld] + ld [wHPBarMaxHP], a + ld c, a + ld a, [hl] + ld [wHPBarMaxHP+1], a + ld b, a + jr z, .gotHPAmountToHeal +; Recover and Softboiled only heal for half the mon's max HP + srl b + rr c +.gotHPAmountToHeal +; update HP + ld a, [de] + ld [wHPBarOldHP], a + add c + ld [de], a + ld [wHPBarNewHP], a + dec de + ld a, [de] + ld [wHPBarOldHP+1], a + adc b + ld [de], a + ld [wHPBarNewHP+1], a + inc hl + inc de + ld a, [de] + dec de + sub [hl] + dec hl + ld a, [de] + sbc [hl] + jr c, .playAnim +; copy max HP to current HP if an overflow occurred + ld a, [hli] + ld [de], a + ld [wHPBarNewHP+1], a + inc de + ld a, [hl] + ld [de], a + ld [wHPBarNewHP], a +.playAnim + ld hl, PlayCurrentMoveAnimation + call BankswitchEtoF + ld a, [H_WHOSETURN] + and a + coord hl, 10, 9 + ld a, $1 + jr z, .updateHPBar + coord hl, 2, 2 + xor a +.updateHPBar + ld [wHPBarType], a + predef UpdateHPBar2 + ld hl, DrawHUDsAndHPBars + call BankswitchEtoF + ld hl, RegainedHealthText + jp PrintText +.failed + ld c, 50 + call DelayFrames + ld hl, PrintButItFailedText_ + jp BankswitchEtoF + +StartedSleepingEffect: + TX_FAR _StartedSleepingEffect + db "@" + +FellAsleepBecameHealthyText: + TX_FAR _FellAsleepBecameHealthyText + db "@" + +RegainedHealthText: + TX_FAR _RegainedHealthText + db "@" diff --git a/engine/battle/move_effects/leech_seed.asm b/engine/battle/move_effects/leech_seed.asm new file mode 100644 index 00000000..f4d3ee9c --- /dev/null +++ b/engine/battle/move_effects/leech_seed.asm @@ -0,0 +1,40 @@ +LeechSeedEffect_: + callab MoveHitTest + ld a, [wMoveMissed] + and a + jr nz, .moveMissed + ld hl, wEnemyBattleStatus2 + ld de, wEnemyMonType1 + ld a, [H_WHOSETURN] + and a + jr z, .leechSeedEffect + ld hl, wPlayerBattleStatus2 + ld de, wBattleMonType1 +.leechSeedEffect +; miss if the target is grass-type or already seeded + ld a, [de] + cp GRASS + jr z, .moveMissed + inc de + ld a, [de] + cp GRASS + jr z, .moveMissed + bit SEEDED, [hl] + jr nz, .moveMissed + set SEEDED, [hl] + callab PlayCurrentMoveAnimation + ld hl, WasSeededText + jp PrintText +.moveMissed + ld c, 50 + call DelayFrames + ld hl, EvadedAttackText + jp PrintText + +WasSeededText: + TX_FAR _WasSeededText + db "@" + +EvadedAttackText: + TX_FAR _EvadedAttackText + db "@" diff --git a/engine/battle/move_effects/mist.asm b/engine/battle/move_effects/mist.asm new file mode 100644 index 00000000..65070a3e --- /dev/null +++ b/engine/battle/move_effects/mist.asm @@ -0,0 +1,19 @@ +MistEffect_: + ld hl, wPlayerBattleStatus2 + ld a, [H_WHOSETURN] + and a + jr z, .mistEffect + ld hl, wEnemyBattleStatus2 +.mistEffect + bit PROTECTED_BY_MIST, [hl] ; is mon protected by mist? + jr nz, .mistAlreadyInUse + set PROTECTED_BY_MIST, [hl] ; mon is now protected by mist + callab PlayCurrentMoveAnimation + ld hl, ShroudedInMistText + jp PrintText +.mistAlreadyInUse + jpab PrintButItFailedText_ + +ShroudedInMistText: + TX_FAR _ShroudedInMistText + db "@" diff --git a/engine/battle/move_effects/one_hit_ko.asm b/engine/battle/move_effects/one_hit_ko.asm new file mode 100644 index 00000000..827e2197 --- /dev/null +++ b/engine/battle/move_effects/one_hit_ko.asm @@ -0,0 +1,38 @@ +OneHitKOEffect_: + ld hl, wDamage + xor a + ld [hli], a + ld [hl], a ; set the damage output to zero + dec a + ld [wCriticalHitOrOHKO], a + ld hl, wBattleMonSpeed + 1 + ld de, wEnemyMonSpeed + 1 + ld a, [H_WHOSETURN] + and a + jr z, .compareSpeed + ld hl, wEnemyMonSpeed + 1 + ld de, wBattleMonSpeed + 1 +.compareSpeed +; set damage to 65535 and OHKO flag is the user's current speed is higher than the target's + ld a, [de] + dec de + ld b, a + ld a, [hld] + sub b + ld a, [de] + ld b, a + ld a, [hl] + sbc b + jr c, .userIsSlower + ld hl, wDamage + ld a, $ff + ld [hli], a + ld [hl], a + ld a, $2 + ld [wCriticalHitOrOHKO], a + ret +.userIsSlower +; keep damage at 0 and set move missed flag if target's current speed is higher instead + ld a, $1 + ld [wMoveMissed], a + ret diff --git a/engine/battle/move_effects/paralyze.asm b/engine/battle/move_effects/paralyze.asm new file mode 100644 index 00000000..95979ae6 --- /dev/null +++ b/engine/battle/move_effects/paralyze.asm @@ -0,0 +1,47 @@ +ParalyzeEffect_: + ld hl, wEnemyMonStatus + ld de, wPlayerMoveType + ld a, [H_WHOSETURN] + and a + jp z, .next + ld hl, wBattleMonStatus + ld de, wEnemyMoveType +.next + ld a, [hl] + and a ; does the target already have a status ailment? + jr nz, .didntAffect +; check if the target is immune due to types + ld a, [de] + cp ELECTRIC + jr nz, .hitTest + ld b, h + ld c, l + inc bc + ld a, [bc] + cp GROUND + jr z, .doesntAffect + inc bc + ld a, [bc] + cp GROUND + jr z, .doesntAffect +.hitTest + push hl + callab MoveHitTest + pop hl + ld a, [wMoveMissed] + and a + jr nz, .didntAffect + set PAR, [hl] + callab QuarterSpeedDueToParalysis + ld c, 30 + call DelayFrames + callab PlayCurrentMoveAnimation + jpab PrintMayNotAttackText +.didntAffect + ld c, 50 + call DelayFrames + jpab PrintDidntAffectText +.doesntAffect + ld c, 50 + call DelayFrames + jpab PrintDoesntAffectText diff --git a/engine/battle/move_effects/pay_day.asm b/engine/battle/move_effects/pay_day.asm new file mode 100644 index 00000000..e5daf014 --- /dev/null +++ b/engine/battle/move_effects/pay_day.asm @@ -0,0 +1,45 @@ +PayDayEffect_: + xor a + ld hl, wcd6d + ld [hli], a + ld a, [H_WHOSETURN] + and a + ld a, [wBattleMonLevel] + jr z, .payDayEffect + ld a, [wEnemyMonLevel] +.payDayEffect +; level * 2 + add a + ld [H_DIVIDEND + 3], a + xor a + ld [H_DIVIDEND], a + ld [H_DIVIDEND + 1], a + ld [H_DIVIDEND + 2], a +; convert to BCD + ld a, 100 + ld [H_DIVISOR], a + ld b, $4 + call Divide + ld a, [H_QUOTIENT + 3] + ld [hli], a + ld a, [H_REMAINDER] + ld [H_DIVIDEND + 3], a + ld a, 10 + ld [H_DIVISOR], a + ld b, $4 + call Divide + ld a, [H_QUOTIENT + 3] + swap a + ld b, a + ld a, [H_REMAINDER] + add b + ld [hl], a + ld de, wTotalPayDayMoney + 2 + ld c, $3 + predef AddBCDPredef + ld hl, CoinsScatteredText + jp PrintText + +CoinsScatteredText: + TX_FAR _CoinsScatteredText + db "@" diff --git a/engine/battle/move_effects/recoil.asm b/engine/battle/move_effects/recoil.asm new file mode 100644 index 00000000..0f2f087b --- /dev/null +++ b/engine/battle/move_effects/recoil.asm @@ -0,0 +1,70 @@ +RecoilEffect_: + ld a, [H_WHOSETURN] + and a + ld a, [wPlayerMoveNum] + ld hl, wBattleMonMaxHP + jr z, .recoilEffect + ld a, [wEnemyMoveNum] + ld hl, wEnemyMonMaxHP +.recoilEffect + ld d, a + ld a, [wDamage] + ld b, a + ld a, [wDamage + 1] + ld c, a + srl b + rr c + ld a, d + cp STRUGGLE ; struggle deals 50% recoil damage + jr z, .gotRecoilDamage + srl b + rr c +.gotRecoilDamage + ld a, b + or c + jr nz, .updateHP + inc c ; minimum recoil damage is 1 +.updateHP +; subtract HP from user due to the recoil damage + ld a, [hli] + ld [wHPBarMaxHP+1], a + ld a, [hl] + ld [wHPBarMaxHP], a + push bc + ld bc, wBattleMonHP - wBattleMonMaxHP + add hl, bc + pop bc + ld a, [hl] + ld [wHPBarOldHP], a + sub c + ld [hld], a + ld [wHPBarNewHP], a + ld a, [hl] + ld [wHPBarOldHP+1], a + sbc b + ld [hl], a + ld [wHPBarNewHP+1], a + jr nc, .getHPBarCoords +; if recoil damage is higher than the Pokemon's HP, set its HP to 0 + xor a + ld [hli], a + ld [hl], a + ld hl, wHPBarNewHP + ld [hli], a + ld [hl], a +.getHPBarCoords + coord hl, 10, 9 + ld a, [H_WHOSETURN] + and a + ld a, $1 + jr z, .updateHPBar + coord hl, 2, 2 + xor a +.updateHPBar + ld [wHPBarType], a + predef UpdateHPBar2 + ld hl, HitWithRecoilText + jp PrintText +HitWithRecoilText: + TX_FAR _HitWithRecoilText + db "@" diff --git a/engine/battle/move_effects/reflect_light_screen.asm b/engine/battle/move_effects/reflect_light_screen.asm new file mode 100644 index 00000000..2805a969 --- /dev/null +++ b/engine/battle/move_effects/reflect_light_screen.asm @@ -0,0 +1,45 @@ +ReflectLightScreenEffect_: + ld hl, wPlayerBattleStatus3 + ld de, wPlayerMoveEffect + ld a, [H_WHOSETURN] + and a + jr z, .reflectLightScreenEffect + ld hl, wEnemyBattleStatus3 + ld de, wEnemyMoveEffect +.reflectLightScreenEffect + ld a, [de] + cp LIGHT_SCREEN_EFFECT + jr nz, .reflect + bit HAS_LIGHT_SCREEN_UP, [hl] ; is mon already protected by light screen? + jr nz, .moveFailed + set HAS_LIGHT_SCREEN_UP, [hl] ; mon is now protected by light screen + ld hl, LightScreenProtectedText + jr .playAnim +.reflect + bit HAS_REFLECT_UP, [hl] ; is mon already protected by reflect? + jr nz, .moveFailed + set HAS_REFLECT_UP, [hl] ; mon is now protected by reflect + ld hl, ReflectGainedArmorText +.playAnim + push hl + ld hl, PlayCurrentMoveAnimation + call BankswitchEtoF + pop hl + jp PrintText +.moveFailed + ld c, 50 + call DelayFrames + ld hl, PrintButItFailedText_ + jp BankswitchEtoF + +LightScreenProtectedText: + TX_FAR _LightScreenProtectedText + db "@" + +ReflectGainedArmorText: + TX_FAR _ReflectGainedArmorText + db "@" + +BankswitchEtoF: + ld b, BANK(BattleCore) + jp Bankswitch diff --git a/engine/battle/move_effects/substitute.asm b/engine/battle/move_effects/substitute.asm new file mode 100644 index 00000000..1bb6c887 --- /dev/null +++ b/engine/battle/move_effects/substitute.asm @@ -0,0 +1,77 @@ +SubstituteEffect_: + ld c, 50 + call DelayFrames + ld hl, wBattleMonMaxHP + ld de, wPlayerSubstituteHP + ld bc, wPlayerBattleStatus2 + ld a, [H_WHOSETURN] + and a + jr z, .notEnemy + ld hl, wEnemyMonMaxHP + ld de, wEnemySubstituteHP + ld bc, wEnemyBattleStatus2 +.notEnemy + ld a, [bc] + bit HAS_SUBSTITUTE_UP, a ; user already has substitute? + jr nz, .alreadyHasSubstitute +; quarter health to remove from user +; assumes max HP is 1023 or lower + push bc + ld a, [hli] + ld b, [hl] + srl a + rr b + srl a + rr b ; max hp / 4 + push de + ld de, wBattleMonHP - wBattleMonMaxHP + add hl, de ; point hl to current HP low byte + pop de + ld a, b + ld [de], a ; save copy of HP to subtract in wPlayerSubstituteHP/wEnemySubstituteHP + ld a, [hld] +; subtract [max hp / 4] to current HP + sub b + ld d, a + ld a, [hl] + sbc 0 + pop bc + jr c, .notEnoughHP ; underflow means user would be left with negative health + ; bug: since it only branches on carry, it will possibly leave user with 0 HP +.userHasZeroOrMoreHP + ldi [hl], a ; save resulting HP after subtraction into current HP + ld [hl], d + ld h, b + ld l, c + set HAS_SUBSTITUTE_UP, [hl] + ld a, [wOptions] + bit 7, a ; battle animation is enabled? + ld hl, PlayCurrentMoveAnimation + ld b, BANK(PlayCurrentMoveAnimation) + jr z, .animationEnabled + ld hl, AnimationSubstitute + ld b, BANK(AnimationSubstitute) +.animationEnabled + call Bankswitch ; jump to routine depending on animation setting + ld hl, SubstituteText + call PrintText + jpab DrawHUDsAndHPBars +.alreadyHasSubstitute + ld hl, HasSubstituteText + jr .printText +.notEnoughHP + ld hl, TooWeakSubstituteText +.printText + jp PrintText + +SubstituteText: + TX_FAR _SubstituteText + db "@" + +HasSubstituteText: + TX_FAR _HasSubstituteText + db "@" + +TooWeakSubstituteText: + TX_FAR _TooWeakSubstituteText + db "@" diff --git a/engine/battle/move_effects/transform.asm b/engine/battle/move_effects/transform.asm new file mode 100644 index 00000000..9a5de9cc --- /dev/null +++ b/engine/battle/move_effects/transform.asm @@ -0,0 +1,148 @@ +TransformEffect_: + ld hl, wBattleMonSpecies + ld de, wEnemyMonSpecies + ld bc, wEnemyBattleStatus3 + ld a, [wEnemyBattleStatus1] + ld a, [H_WHOSETURN] + and a + jr nz, .hitTest + ld hl, wEnemyMonSpecies + ld de, wBattleMonSpecies + ld bc, wPlayerBattleStatus3 + ld [wPlayerMoveListIndex], a + ld a, [wPlayerBattleStatus1] +.hitTest + bit INVULNERABLE, a ; is mon invulnerable to typical attacks? (fly/dig) + jp nz, .failed + push hl + push de + push bc + ld hl, wPlayerBattleStatus2 + ld a, [H_WHOSETURN] + and a + jr z, .transformEffect + ld hl, wEnemyBattleStatus2 +.transformEffect +; animation(s) played are different if target has Substitute up + bit HAS_SUBSTITUTE_UP, [hl] + push af + ld hl, HideSubstituteShowMonAnim + ld b, BANK(HideSubstituteShowMonAnim) + call nz, Bankswitch + ld a, [wOptions] + add a + ld hl, PlayCurrentMoveAnimation + ld b, BANK(PlayCurrentMoveAnimation) + jr nc, .gotAnimToPlay + ld hl, AnimationTransformMon + ld b, BANK(AnimationTransformMon) +.gotAnimToPlay + call Bankswitch + ld hl, ReshowSubstituteAnim + ld b, BANK(ReshowSubstituteAnim) + pop af + call nz, Bankswitch + pop bc + ld a, [bc] + set TRANSFORMED, a ; mon is now transformed + ld [bc], a + pop de + pop hl + push hl +; transform user into opposing Pokemon +; species + ld a, [hl] + ld [de], a +; type 1, type 2, catch rate, and moves + ld bc, $5 + add hl, bc + inc de + inc de + inc de + inc de + inc de + inc bc + inc bc + call CopyData + ld a, [H_WHOSETURN] + and a + jr z, .next +; save enemy mon DVs at wTransformedEnemyMonOriginalDVs + ld a, [de] + ld [wTransformedEnemyMonOriginalDVs], a + inc de + ld a, [de] + ld [wTransformedEnemyMonOriginalDVs + 1], a + dec de +.next +; DVs + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + inc de +; Attack, Defense, Speed, and Special stats + inc hl + inc hl + inc hl + inc de + inc de + inc de + ld bc, $8 + call CopyData + ld bc, wBattleMonMoves - wBattleMonPP + add hl, bc ; ld hl, wBattleMonMoves + ld b, NUM_MOVES +.copyPPLoop +; 5 PP for all moves + ld a, [hli] + and a + jr z, .lessThanFourMoves + ld a, $5 + ld [de], a + inc de + dec b + jr nz, .copyPPLoop + jr .copyStats +.lessThanFourMoves +; 0 PP for blank moves + xor a + ld [de], a + inc de + dec b + jr nz, .lessThanFourMoves +.copyStats +; original (unmodified) stats and stat mods + pop hl + ld a, [hl] + ld [wd11e], a + call GetMonName + ld hl, wEnemyMonUnmodifiedAttack + ld de, wPlayerMonUnmodifiedAttack + call .copyBasedOnTurn ; original (unmodified) stats + ld hl, wEnemyMonStatMods + ld de, wPlayerMonStatMods + call .copyBasedOnTurn ; stat mods + ld hl, TransformedText + jp PrintText + +.copyBasedOnTurn + ld a, [H_WHOSETURN] + and a + jr z, .gotStatsOrModsToCopy + push hl + ld h, d + ld l, e + pop de +.gotStatsOrModsToCopy + ld bc, $8 + jp CopyData + +.failed + ld hl, PrintButItFailedText_ + jp BankswitchEtoF + +TransformedText: + TX_FAR _TransformedText + db "@" |