summaryrefslogtreecommitdiff
path: root/engine/battle/core.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/battle/core.asm')
-rwxr-xr-xengine/battle/core.asm1732
1 files changed, 8 insertions, 1724 deletions
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
index 90033b53..96ec8e2f 100755
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -1,100 +1,10 @@
BattleCore:
-; These are move effects (second value from the Moves table in bank $E).
-ResidualEffects1:
-; most non-side effects
- db CONVERSION_EFFECT
- db HAZE_EFFECT
- db SWITCH_AND_TELEPORT_EFFECT
- db MIST_EFFECT
- db FOCUS_ENERGY_EFFECT
- db CONFUSION_EFFECT
- db HEAL_EFFECT
- db TRANSFORM_EFFECT
- db LIGHT_SCREEN_EFFECT
- db REFLECT_EFFECT
- db POISON_EFFECT
- db PARALYZE_EFFECT
- db SUBSTITUTE_EFFECT
- db MIMIC_EFFECT
- db LEECH_SEED_EFFECT
- db SPLASH_EFFECT
- db -1
-SetDamageEffects:
-; moves that do damage but not through normal calculations
-; e.g., Super Fang, Psywave
- db SUPER_FANG_EFFECT
- db SPECIAL_DAMAGE_EFFECT
- db -1
-ResidualEffects2:
-; non-side effects not included in ResidualEffects1
-; stat-affecting moves, sleep-inflicting moves, and Bide
-; e.g., Meditate, Bide, Hypnosis
- db $01
- db ATTACK_UP1_EFFECT
- db DEFENSE_UP1_EFFECT
- db SPEED_UP1_EFFECT
- db SPECIAL_UP1_EFFECT
- db ACCURACY_UP1_EFFECT
- db EVASION_UP1_EFFECT
- db ATTACK_DOWN1_EFFECT
- db DEFENSE_DOWN1_EFFECT
- db SPEED_DOWN1_EFFECT
- db SPECIAL_DOWN1_EFFECT
- db ACCURACY_DOWN1_EFFECT
- db EVASION_DOWN1_EFFECT
- db BIDE_EFFECT
- db SLEEP_EFFECT
- db ATTACK_UP2_EFFECT
- db DEFENSE_UP2_EFFECT
- db SPEED_UP2_EFFECT
- db SPECIAL_UP2_EFFECT
- db ACCURACY_UP2_EFFECT
- db EVASION_UP2_EFFECT
- db ATTACK_DOWN2_EFFECT
- db DEFENSE_DOWN2_EFFECT
- db SPEED_DOWN2_EFFECT
- db SPECIAL_DOWN2_EFFECT
- db ACCURACY_DOWN2_EFFECT
- db EVASION_DOWN2_EFFECT
- db -1
-AlwaysHappenSideEffects:
-; Attacks that aren't finished after they faint the opponent.
- db DRAIN_HP_EFFECT
- db EXPLODE_EFFECT
- db DREAM_EATER_EFFECT
- db PAY_DAY_EFFECT
- db TWO_TO_FIVE_ATTACKS_EFFECT
- db $1E
- db ATTACK_TWICE_EFFECT
- db RECOIL_EFFECT
- db TWINEEDLE_EFFECT
- db RAGE_EFFECT
- db -1
-SpecialEffects:
-; Effects from arrays 2, 4, and 5B, minus Twineedle and Rage.
-; Includes all effects that do not need to be called at the end of
-; ExecutePlayerMove (or ExecuteEnemyMove), because they have already been handled
- db DRAIN_HP_EFFECT
- db EXPLODE_EFFECT
- db DREAM_EATER_EFFECT
- db PAY_DAY_EFFECT
- db SWIFT_EFFECT
- db TWO_TO_FIVE_ATTACKS_EFFECT
- db $1E
- db CHARGE_EFFECT
- db SUPER_FANG_EFFECT
- db SPECIAL_DAMAGE_EFFECT
- db FLY_EFFECT
- db ATTACK_TWICE_EFFECT
- db JUMP_KICK_EFFECT
- db RECOIL_EFFECT
- ; fallthrough to Next EffectsArray
-SpecialEffectsCont:
-; damaging moves whose effect is executed prior to damage calculation
- db THRASH_PETAL_DANCE_EFFECT
- db TRAPPING_EFFECT
- db -1
+INCLUDE "data/battle/residual_effects_1.asm"
+INCLUDE "data/battle/set_damage_effects.asm"
+INCLUDE "data/battle/residual_effects_2.asm"
+INCLUDE "data/battle/always_happen_effects.asm"
+INCLUDE "data/battle/special_effects.asm"
SlidePlayerAndEnemySilhouettesOnScreen:
call LoadPlayerBackPic
@@ -3904,20 +3814,7 @@ DetermineExclamationPointTextNum:
pop bc
ret
-ExclamationPointMoveSets:
- db SWORDS_DANCE, GROWTH
- db $00
- db RECOVER, BIDE, SELFDESTRUCT, AMNESIA
- db $00
- db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BARRAGE
- db $00
- db POUND, SCRATCH, VICEGRIP, WING_ATTACK, FLY, BIND, SLAM, HORN_ATTACK, BODY_SLAM
- db WRAP, THRASH, TAIL_WHIP, LEER, BITE, GROWL, ROAR, SING, PECK, COUNTER
- db STRENGTH, ABSORB, STRING_SHOT, EARTHQUAKE, FISSURE, DIG, TOXIC, SCREECH, HARDEN
- db MINIMIZE, WITHDRAW, DEFENSE_CURL, METRONOME, LICK, CLAMP, CONSTRICT, POISON_GAS
- db LEECH_LIFE, BUBBLE, FLASH, SPLASH, ACID_ARMOR, FURY_SWIPES, REST, SHARPEN, SLASH, SUBSTITUTE
- db $00
- db $FF ; terminator
+INCLUDE "data/move_grammar.asm"
PrintMoveFailureText:
ld de, wPlayerMoveEffect
@@ -4668,13 +4565,7 @@ JumpToOHKOMoveEffect:
dec a
ret
-
-UnusedHighCriticalMoves:
- db KARATE_CHOP
- db RAZOR_LEAF
- db CRABHAMMER
- db SLASH
- db $FF
+INCLUDE "data/battle/unused_critical_hit_moves.asm"
; determines if attack is a critical hit
; azure heights claims "the fastest pokémon (who are,not coincidentally,
@@ -4745,14 +4636,7 @@ CriticalHitTest:
ld [wCriticalHitOrOHKO], a ; set critical hit flag
ret
-; high critical hit moves
-HighCriticalMoves:
- db KARATE_CHOP
- db RAZOR_LEAF
- db CRABHAMMER
- db SLASH
- db $FF
-
+INCLUDE "data/battle/critical_hit_moves.asm"
; function to determine if Counter hits and if so, how much damage it does
HandleCounterMove:
@@ -7117,1603 +7001,3 @@ LoadMonBackPic:
ld a, [H_LOADEDROMBANK]
ld b, a
jp CopyVideoData
-
-JumpMoveEffect:
- call _JumpMoveEffect
- ld b, $1
- ret
-
-_JumpMoveEffect:
- ld a, [H_WHOSETURN]
- and a
- ld a, [wPlayerMoveEffect]
- jr z, .next1
- ld a, [wEnemyMoveEffect]
-.next1
- dec a ; subtract 1, there is no special effect for 00
- add a ; x2, 16bit pointers
- ld hl, MoveEffectPointerTable
- ld b, 0
- ld c, a
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- jp hl ; jump to special effect handler
-
-MoveEffectPointerTable:
- dw SleepEffect ; unused effect
- dw PoisonEffect ; POISON_SIDE_EFFECT1
- dw DrainHPEffect ; DRAIN_HP_EFFECT
- dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT1
- dw FreezeBurnParalyzeEffect ; FREEZE_SIDE_EFFECT
- dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT1
- dw ExplodeEffect ; EXPLODE_EFFECT
- dw DrainHPEffect ; DREAM_EATER_EFFECT
- dw $0000 ; MIRROR_MOVE_EFFECT
- dw StatModifierUpEffect ; ATTACK_UP1_EFFECT
- dw StatModifierUpEffect ; DEFENSE_UP1_EFFECT
- dw StatModifierUpEffect ; SPEED_UP1_EFFECT
- dw StatModifierUpEffect ; SPECIAL_UP1_EFFECT
- dw StatModifierUpEffect ; ACCURACY_UP1_EFFECT
- dw StatModifierUpEffect ; EVASION_UP1_EFFECT
- dw PayDayEffect ; PAY_DAY_EFFECT
- dw $0000 ; SWIFT_EFFECT
- dw StatModifierDownEffect ; ATTACK_DOWN1_EFFECT
- dw StatModifierDownEffect ; DEFENSE_DOWN1_EFFECT
- dw StatModifierDownEffect ; SPEED_DOWN1_EFFECT
- dw StatModifierDownEffect ; SPECIAL_DOWN1_EFFECT
- dw StatModifierDownEffect ; ACCURACY_DOWN1_EFFECT
- dw StatModifierDownEffect ; EVASION_DOWN1_EFFECT
- dw ConversionEffect ; CONVERSION_EFFECT
- dw HazeEffect ; HAZE_EFFECT
- dw BideEffect ; BIDE_EFFECT
- dw ThrashPetalDanceEffect ; THRASH_PETAL_DANCE_EFFECT
- dw SwitchAndTeleportEffect ; SWITCH_AND_TELEPORT_EFFECT
- dw TwoToFiveAttacksEffect ; TWO_TO_FIVE_ATTACKS_EFFECT
- dw TwoToFiveAttacksEffect ; unused effect
- dw FlinchSideEffect ; FLINCH_SIDE_EFFECT1
- dw SleepEffect ; SLEEP_EFFECT
- dw PoisonEffect ; POISON_SIDE_EFFECT2
- dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT2
- dw FreezeBurnParalyzeEffect ; unused effect
- dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT2
- dw FlinchSideEffect ; FLINCH_SIDE_EFFECT2
- dw OneHitKOEffect ; OHKO_EFFECT
- dw ChargeEffect ; CHARGE_EFFECT
- dw $0000 ; SUPER_FANG_EFFECT
- dw $0000 ; SPECIAL_DAMAGE_EFFECT
- dw TrappingEffect ; TRAPPING_EFFECT
- dw ChargeEffect ; FLY_EFFECT
- dw TwoToFiveAttacksEffect ; ATTACK_TWICE_EFFECT
- dw $0000 ; JUMP_KICK_EFFECT
- dw MistEffect ; MIST_EFFECT
- dw FocusEnergyEffect ; FOCUS_ENERGY_EFFECT
- dw RecoilEffect ; RECOIL_EFFECT
- dw ConfusionEffect ; CONFUSION_EFFECT
- dw StatModifierUpEffect ; ATTACK_UP2_EFFECT
- dw StatModifierUpEffect ; DEFENSE_UP2_EFFECT
- dw StatModifierUpEffect ; SPEED_UP2_EFFECT
- dw StatModifierUpEffect ; SPECIAL_UP2_EFFECT
- dw StatModifierUpEffect ; ACCURACY_UP2_EFFECT
- dw StatModifierUpEffect ; EVASION_UP2_EFFECT
- dw HealEffect ; HEAL_EFFECT
- dw TransformEffect ; TRANSFORM_EFFECT
- dw StatModifierDownEffect ; ATTACK_DOWN2_EFFECT
- dw StatModifierDownEffect ; DEFENSE_DOWN2_EFFECT
- dw StatModifierDownEffect ; SPEED_DOWN2_EFFECT
- dw StatModifierDownEffect ; SPECIAL_DOWN2_EFFECT
- dw StatModifierDownEffect ; ACCURACY_DOWN2_EFFECT
- dw StatModifierDownEffect ; EVASION_DOWN2_EFFECT
- dw ReflectLightScreenEffect ; LIGHT_SCREEN_EFFECT
- dw ReflectLightScreenEffect ; REFLECT_EFFECT
- dw PoisonEffect ; POISON_EFFECT
- dw ParalyzeEffect ; PARALYZE_EFFECT
- dw StatModifierDownEffect ; ATTACK_DOWN_SIDE_EFFECT
- dw StatModifierDownEffect ; DEFENSE_DOWN_SIDE_EFFECT
- dw StatModifierDownEffect ; SPEED_DOWN_SIDE_EFFECT
- dw StatModifierDownEffect ; SPECIAL_DOWN_SIDE_EFFECT
- dw StatModifierDownEffect ; unused effect
- dw StatModifierDownEffect ; unused effect
- dw StatModifierDownEffect ; unused effect
- dw StatModifierDownEffect ; unused effect
- dw ConfusionSideEffect ; CONFUSION_SIDE_EFFECT
- dw TwoToFiveAttacksEffect ; TWINEEDLE_EFFECT
- dw $0000 ; unused effect
- dw SubstituteEffect ; SUBSTITUTE_EFFECT
- dw HyperBeamEffect ; HYPER_BEAM_EFFECT
- dw RageEffect ; RAGE_EFFECT
- dw MimicEffect ; MIMIC_EFFECT
- dw $0000 ; METRONOME_EFFECT
- dw LeechSeedEffect ; LEECH_SEED_EFFECT
- dw SplashEffect ; SPLASH_EFFECT
- dw DisableEffect ; DISABLE_EFFECT
-
-SleepEffect:
- ld de, wEnemyMonStatus
- ld bc, wEnemyBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jp z, .sleepEffect
- ld de, wBattleMonStatus
- ld bc, wPlayerBattleStatus2
-
-.sleepEffect
- ld a, [bc]
- bit NEEDS_TO_RECHARGE, a ; does the target need to recharge? (hyper beam)
- res NEEDS_TO_RECHARGE, a ; target no longer needs to recharge
- ld [bc], a
- jr nz, .setSleepCounter ; if the target had to recharge, all hit tests will be skipped
- ; including the event where the target already has another status
- ld a, [de]
- ld b, a
- and $7
- jr z, .notAlreadySleeping ; can't affect a mon that is already asleep
- ld hl, AlreadyAsleepText
- jp PrintText
-.notAlreadySleeping
- ld a, b
- and a
- jr nz, .didntAffect ; can't affect a mon that is already statused
- push de
- call MoveHitTest ; apply accuracy tests
- pop de
- ld a, [wMoveMissed]
- and a
- jr nz, .didntAffect
-.setSleepCounter
-; set target's sleep counter to a random number between 1 and 7
- call BattleRandom
- and $7
- jr z, .setSleepCounter
- ld [de], a
- call PlayCurrentMoveAnimation2
- ld hl, FellAsleepText
- jp PrintText
-.didntAffect
- jp PrintDidntAffectText
-
-FellAsleepText:
- TX_FAR _FellAsleepText
- db "@"
-
-AlreadyAsleepText:
- TX_FAR _AlreadyAsleepText
- db "@"
-
-PoisonEffect:
- ld hl, wEnemyMonStatus
- ld de, wPlayerMoveEffect
- ld a, [H_WHOSETURN]
- and a
- jr z, .poisonEffect
- ld hl, wBattleMonStatus
- ld de, wEnemyMoveEffect
-.poisonEffect
- call CheckTargetSubstitute
- jr nz, .noEffect ; can't poison a substitute target
- ld a, [hli]
- ld b, a
- and a
- jr nz, .noEffect ; miss if target is already statused
- ld a, [hli]
- cp POISON ; can't poison a poison-type target
- jr z, .noEffect
- ld a, [hld]
- cp POISON ; can't poison a poison-type target
- jr z, .noEffect
- ld a, [de]
- cp POISON_SIDE_EFFECT1
- ld b, $34 ; ~20% chance of poisoning
- jr z, .sideEffectTest
- cp POISON_SIDE_EFFECT2
- ld b, $67 ; ~40% chance of poisoning
- jr z, .sideEffectTest
- push hl
- push de
- call MoveHitTest ; apply accuracy tests
- pop de
- pop hl
- ld a, [wMoveMissed]
- and a
- jr nz, .didntAffect
- jr .inflictPoison
-.sideEffectTest
- call BattleRandom
- cp b ; was side effect successful?
- ret nc
-.inflictPoison
- dec hl
- set 3, [hl] ; mon is now poisoned
- push de
- dec de
- ld a, [H_WHOSETURN]
- and a
- ld b, ANIM_C7
- ld hl, wPlayerBattleStatus3
- ld a, [de]
- ld de, wPlayerToxicCounter
- jr nz, .ok
- ld b, ANIM_A9
- ld hl, wEnemyBattleStatus3
- ld de, wEnemyToxicCounter
-.ok
- cp TOXIC
- jr nz, .normalPoison ; done if move is not Toxic
- set BADLY_POISONED, [hl] ; else set Toxic battstatus
- xor a
- ld [de], a
- ld hl, BadlyPoisonedText
- jr .continue
-.normalPoison
- ld hl, PoisonedText
-.continue
- pop de
- ld a, [de]
- cp POISON_EFFECT
- jr z, .regularPoisonEffect
- ld a, b
- call PlayBattleAnimation2
- jp PrintText
-.regularPoisonEffect
- call PlayCurrentMoveAnimation2
- jp PrintText
-.noEffect
- ld a, [de]
- cp POISON_EFFECT
- ret nz
-.didntAffect
- ld c, 50
- call DelayFrames
- jp PrintDidntAffectText
-
-PoisonedText:
- TX_FAR _PoisonedText
- db "@"
-
-BadlyPoisonedText:
- TX_FAR _BadlyPoisonedText
- db "@"
-
-DrainHPEffect:
- jpab DrainHPEffect_
-
-ExplodeEffect:
- ld hl, wBattleMonHP
- ld de, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .faintUser
- ld hl, wEnemyMonHP
- ld de, wEnemyBattleStatus2
-.faintUser
- xor a
- ld [hli], a ; set the mon's HP to 0
- ld [hli], a
- inc hl
- ld [hl], a ; set mon's status to 0
- ld a, [de]
- res SEEDED, a ; clear mon's leech seed status
- ld [de], a
- ret
-
-FreezeBurnParalyzeEffect:
- xor a
- ld [wAnimationType], a
- call CheckTargetSubstitute ; test bit 4 of d063/d068 flags [target has substitute flag]
- ret nz ; return if they have a substitute, can't effect them
- ld a, [H_WHOSETURN]
- and a
- jp nz, opponentAttacker
- ld a, [wEnemyMonStatus]
- and a
- jp nz, CheckDefrost ; can't inflict status if opponent is already statused
- ld a, [wPlayerMoveType]
- ld b, a
- ld a, [wEnemyMonType1]
- cp b ; do target type 1 and move type match?
- ret z ; return if they match (an ice move can't freeze an ice-type, body slam can't paralyze a normal-type, etc.)
- ld a, [wEnemyMonType2]
- cp b ; do target type 2 and move type match?
- ret z ; return if they match
- ld a, [wPlayerMoveEffect]
- cp PARALYZE_SIDE_EFFECT1 + 1 ; 10% status effects are 04, 05, 06 so 07 will set carry for those
- ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
- jr c, .next1 ; branch ahead if this is a 10% chance effect..
- ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
- sub $1e ; subtract $1E to map to equivalent 10% chance effects
-.next1
- push af
- call BattleRandom ; get random 8bit value for probability test
- cp b
- pop bc
- ret nc ; do nothing if random value is >= 1A or 4D [no status applied]
- ld a, b ; what type of effect is this?
- cp BURN_SIDE_EFFECT1
- jr z, .burn
- cp FREEZE_SIDE_EFFECT
- jr z, .freeze
-; .paralyze
- ld a, 1 << PAR
- ld [wEnemyMonStatus], a
- call QuarterSpeedDueToParalysis ; quarter speed of affected mon
- ld a, ANIM_A9
- call PlayBattleAnimation
- jp PrintMayNotAttackText ; print paralysis text
-.burn
- ld a, 1 << BRN
- ld [wEnemyMonStatus], a
- call HalveAttackDueToBurn ; halve attack of affected mon
- ld a, ANIM_A9
- call PlayBattleAnimation
- ld hl, BurnedText
- jp PrintText
-.freeze
- call ClearHyperBeam ; resets hyper beam (recharge) condition from target
- ld a, 1 << FRZ
- ld [wEnemyMonStatus], a
- ld a, ANIM_A9
- call PlayBattleAnimation
- ld hl, FrozenText
- jp PrintText
-opponentAttacker:
- ld a, [wBattleMonStatus] ; mostly same as above with addresses swapped for opponent
- and a
- jp nz, CheckDefrost
- ld a, [wEnemyMoveType]
- ld b, a
- ld a, [wBattleMonType1]
- cp b
- ret z
- ld a, [wBattleMonType2]
- cp b
- ret z
- ld a, [wEnemyMoveEffect]
- cp PARALYZE_SIDE_EFFECT1 + 1
- ld b, $1a
- jr c, .next1
- ld b, $4d
- sub $1e
-.next1
- push af
- call BattleRandom
- cp b
- pop bc
- ret nc
- ld a, b
- cp BURN_SIDE_EFFECT1
- jr z, .burn
- cp FREEZE_SIDE_EFFECT
- jr z, .freeze
- ld a, 1 << PAR
- ld [wBattleMonStatus], a
- call QuarterSpeedDueToParalysis
- jp PrintMayNotAttackText
-.burn
- ld a, 1 << BRN
- ld [wBattleMonStatus], a
- call HalveAttackDueToBurn
- ld hl, BurnedText
- jp PrintText
-.freeze
-; hyper beam bits aren't reseted for opponent's side
- ld a, 1 << FRZ
- ld [wBattleMonStatus], a
- ld hl, FrozenText
- jp PrintText
-
-BurnedText:
- TX_FAR _BurnedText
- db "@"
-
-FrozenText:
- TX_FAR _FrozenText
- db "@"
-
-CheckDefrost:
-; any fire-type move that has a chance inflict burn (all but Fire Spin) will defrost a frozen target
- and 1 << FRZ ; are they frozen?
- ret z ; return if so
- ld a, [H_WHOSETURN]
- and a
- jr nz, .opponent
- ;player [attacker]
- ld a, [wPlayerMoveType]
- sub FIRE
- ret nz ; return if type of move used isn't fire
- ld [wEnemyMonStatus], a ; set opponent status to 00 ["defrost" a frozen monster]
- ld hl, wEnemyMon1Status
- ld a, [wEnemyMonPartyPos]
- ld bc, wEnemyMon2 - wEnemyMon1
- call AddNTimes
- xor a
- ld [hl], a ; clear status in roster
- ld hl, FireDefrostedText
- jr .common
-.opponent
- ld a, [wEnemyMoveType] ; same as above with addresses swapped
- sub FIRE
- ret nz
- ld [wBattleMonStatus], a
- ld hl, wPartyMon1Status
- ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
- xor a
- ld [hl], a
- ld hl, FireDefrostedText
-.common
- jp PrintText
-
-FireDefrostedText:
- TX_FAR _FireDefrostedText
- db "@"
-
-StatModifierUpEffect:
- ld hl, wPlayerMonStatMods
- ld de, wPlayerMoveEffect
- ld a, [H_WHOSETURN]
- and a
- jr z, .statModifierUpEffect
- ld hl, wEnemyMonStatMods
- ld de, wEnemyMoveEffect
-.statModifierUpEffect
- ld a, [de]
- sub ATTACK_UP1_EFFECT
- cp EVASION_UP1_EFFECT + $3 - ATTACK_UP1_EFFECT ; covers all +1 effects
- jr c, .incrementStatMod
- sub ATTACK_UP2_EFFECT - ATTACK_UP1_EFFECT ; map +2 effects to equivalent +1 effect
-.incrementStatMod
- ld c, a
- ld b, $0
- add hl, bc
- ld b, [hl]
- inc b ; increment corresponding stat mod
- ld a, $d
- cp b ; can't raise stat past +6 ($d or 13)
- jp c, PrintNothingHappenedText
- ld a, [de]
- cp ATTACK_UP1_EFFECT + $8 ; is it a +2 effect?
- jr c, .ok
- inc b ; if so, increment stat mod again
- ld a, $d
- cp b ; unless it's already +6
- jr nc, .ok
- ld b, a
-.ok
- ld [hl], b
- ld a, c
- cp $4
- jr nc, UpdateStatDone ; jump if mod affected is evasion/accuracy
- push hl
- ld hl, wBattleMonAttack + 1
- ld de, wPlayerMonUnmodifiedAttack
- ld a, [H_WHOSETURN]
- and a
- jr z, .pointToStats
- ld hl, wEnemyMonAttack + 1
- ld de, wEnemyMonUnmodifiedAttack
-.pointToStats
- push bc
- sla c
- ld b, $0
- add hl, bc ; hl = modified stat
- ld a, c
- add e
- ld e, a
- jr nc, .checkIf999
- inc d ; de = unmodified (original) stat
-.checkIf999
- pop bc
- ld a, [hld]
- sub 999 % $100 ; check if stat is already 999
- jr nz, .recalculateStat
- ld a, [hl]
- sbc 999 / $100
- jp z, RestoreOriginalStatModifier
-.recalculateStat ; recalculate affected stat
- ; paralysis and burn penalties, as well as badge boosts are ignored
- push hl
- push bc
- ld hl, StatModifierRatios
- dec b
- sla b
- ld c, b
- ld b, $0
- add hl, bc
- pop bc
- xor a
- ld [H_MULTIPLICAND], a
- ld a, [de]
- ld [H_MULTIPLICAND + 1], a
- inc de
- ld a, [de]
- ld [H_MULTIPLICAND + 2], a
- ld a, [hli]
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, [hl]
- ld [H_DIVISOR], a
- ld b, $4
- call Divide
- pop hl
-; cap at 999
- ld a, [H_PRODUCT + 3]
- sub 999 % $100
- ld a, [H_PRODUCT + 2]
- sbc 999 / $100
- jp c, UpdateStat
- ld a, 999 / $100
- ld [H_MULTIPLICAND + 1], a
- ld a, 999 % $100
- ld [H_MULTIPLICAND + 2], a
-
-UpdateStat:
- ld a, [H_PRODUCT + 2]
- ld [hli], a
- ld a, [H_PRODUCT + 3]
- ld [hl], a
- pop hl
-UpdateStatDone:
- ld b, c
- inc b
- call PrintStatText
- ld hl, wPlayerBattleStatus2
- ld de, wPlayerMoveNum
- ld bc, wPlayerMonMinimized
- ld a, [H_WHOSETURN]
- and a
- jr z, .asm_3f4e6
- ld hl, wEnemyBattleStatus2
- ld de, wEnemyMoveNum
- ld bc, wEnemyMonMinimized
-.asm_3f4e6
- ld a, [de]
- cp MINIMIZE
- jr nz, .asm_3f4f9
- ; if a substitute is up, slide off the substitute and show the mon pic before
- ; playing the minimize animation
- bit HAS_SUBSTITUTE_UP, [hl]
- push af
- push bc
- ld hl, HideSubstituteShowMonAnim
- ld b, BANK(HideSubstituteShowMonAnim)
- push de
- call nz, Bankswitch
- pop de
-.asm_3f4f9
- call PlayCurrentMoveAnimation
- ld a, [de]
- cp MINIMIZE
- jr nz, .applyBadgeBoostsAndStatusPenalties
- pop bc
- ld a, $1
- ld [bc], a
- ld hl, ReshowSubstituteAnim
- ld b, BANK(ReshowSubstituteAnim)
- pop af
- call nz, Bankswitch
-.applyBadgeBoostsAndStatusPenalties
- ld a, [H_WHOSETURN]
- and a
- call z, ApplyBadgeStatBoosts ; whenever the player uses a stat-up move, badge boosts get reapplied again to every stat,
- ; even to those not affected by the stat-up move (will be boosted further)
- ld hl, MonsStatsRoseText
- call PrintText
-
-; these shouldn't be here
- call QuarterSpeedDueToParalysis ; apply speed penalty to the player whose turn is not, if it's paralyzed
- jp HalveAttackDueToBurn ; apply attack penalty to the player whose turn is not, if it's burned
-
-RestoreOriginalStatModifier:
- pop hl
- dec [hl]
-
-PrintNothingHappenedText:
- ld hl, NothingHappenedText
- jp PrintText
-
-MonsStatsRoseText:
- TX_FAR _MonsStatsRoseText
- TX_ASM
- ld hl, GreatlyRoseText
- ld a, [H_WHOSETURN]
- and a
- ld a, [wPlayerMoveEffect]
- jr z, .playerTurn
- ld a, [wEnemyMoveEffect]
-.playerTurn
- cp ATTACK_DOWN1_EFFECT
- ret nc
- ld hl, RoseText
- ret
-
-GreatlyRoseText:
- TX_DELAY
- TX_FAR _GreatlyRoseText
-; fallthrough
-RoseText:
- TX_FAR _RoseText
- db "@"
-
-StatModifierDownEffect:
- ld hl, wEnemyMonStatMods
- ld de, wPlayerMoveEffect
- ld bc, wEnemyBattleStatus1
- ld a, [H_WHOSETURN]
- and a
- jr z, .statModifierDownEffect
- ld hl, wPlayerMonStatMods
- ld de, wEnemyMoveEffect
- ld bc, wPlayerBattleStatus1
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- jr z, .statModifierDownEffect
- call BattleRandom
- cp $40 ; 1/4 chance to miss by in regular battle
- jp c, MoveMissed
-.statModifierDownEffect
- call CheckTargetSubstitute ; can't hit through substitute
- jp nz, MoveMissed
- ld a, [de]
- cp ATTACK_DOWN_SIDE_EFFECT
- jr c, .nonSideEffect
- call BattleRandom
- cp $55 ; 85/256 chance for side effects
- jp nc, CantLowerAnymore
- ld a, [de]
- sub ATTACK_DOWN_SIDE_EFFECT ; map each stat to 0-3
- jr .decrementStatMod
-.nonSideEffect ; non-side effects only
- push hl
- push de
- push bc
- call MoveHitTest ; apply accuracy tests
- pop bc
- pop de
- pop hl
- ld a, [wMoveMissed]
- and a
- jp nz, MoveMissed
- ld a, [bc]
- bit INVULNERABLE, a ; fly/dig
- jp nz, MoveMissed
- ld a, [de]
- sub ATTACK_DOWN1_EFFECT
- cp EVASION_DOWN1_EFFECT + $3 - ATTACK_DOWN1_EFFECT ; covers all -1 effects
- jr c, .decrementStatMod
- sub ATTACK_DOWN2_EFFECT - ATTACK_DOWN1_EFFECT ; map -2 effects to corresponding -1 effect
-.decrementStatMod
- ld c, a
- ld b, $0
- add hl, bc
- ld b, [hl]
- dec b ; dec corresponding stat mod
- jp z, CantLowerAnymore ; if stat mod is 1 (-6), can't lower anymore
- ld a, [de]
- cp ATTACK_DOWN2_EFFECT - $16 ; $24
- jr c, .ok
- cp EVASION_DOWN2_EFFECT + $5 ; $44
- jr nc, .ok
- dec b ; stat down 2 effects only (dec mod again)
- jr nz, .ok
- inc b ; increment mod to 1 (-6) if it would become 0 (-7)
-.ok
- ld [hl], b ; save modified mod
- ld a, c
- cp $4
- jr nc, UpdateLoweredStatDone ; jump for evasion/accuracy
- push hl
- push de
- ld hl, wEnemyMonAttack + 1
- ld de, wEnemyMonUnmodifiedAttack
- ld a, [H_WHOSETURN]
- and a
- jr z, .pointToStat
- ld hl, wBattleMonAttack + 1
- ld de, wPlayerMonUnmodifiedAttack
-.pointToStat
- push bc
- sla c
- ld b, $0
- add hl, bc ; hl = modified stat
- ld a, c
- add e
- ld e, a
- jr nc, .noCarry
- inc d ; de = unmodified stat
-.noCarry
- pop bc
- ld a, [hld]
- sub $1 ; can't lower stat below 1 (-6)
- jr nz, .recalculateStat
- ld a, [hl]
- and a
- jp z, CantLowerAnymore_Pop
-.recalculateStat
-; recalculate affected stat
-; paralysis and burn penalties, as well as badge boosts are ignored
- push hl
- push bc
- ld hl, StatModifierRatios
- dec b
- sla b
- ld c, b
- ld b, $0
- add hl, bc
- pop bc
- xor a
- ld [H_MULTIPLICAND], a
- ld a, [de]
- ld [H_MULTIPLICAND + 1], a
- inc de
- ld a, [de]
- ld [H_MULTIPLICAND + 2], a
- ld a, [hli]
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, [hl]
- ld [H_DIVISOR], a
- ld b, $4
- call Divide
- pop hl
- ld a, [H_PRODUCT + 3]
- ld b, a
- ld a, [H_PRODUCT + 2]
- or b
- jp nz, UpdateLoweredStat
- ld [H_MULTIPLICAND + 1], a
- ld a, $1
- ld [H_MULTIPLICAND + 2], a
-
-UpdateLoweredStat:
- ld a, [H_PRODUCT + 2]
- ld [hli], a
- ld a, [H_PRODUCT + 3]
- ld [hl], a
- pop de
- pop hl
-UpdateLoweredStatDone:
- ld b, c
- inc b
- push de
- call PrintStatText
- pop de
- ld a, [de]
- cp $44
- jr nc, .ApplyBadgeBoostsAndStatusPenalties
- call PlayCurrentMoveAnimation2
-.ApplyBadgeBoostsAndStatusPenalties
- ld a, [H_WHOSETURN]
- and a
- call nz, ApplyBadgeStatBoosts ; whenever the player uses a stat-down move, badge boosts get reapplied again to every stat,
- ; even to those not affected by the stat-up move (will be boosted further)
- ld hl, MonsStatsFellText
- call PrintText
-
-; These where probably added given that a stat-down move affecting speed or attack will override
-; the stat penalties from paralysis and burn respectively.
-; But they are always called regardless of the stat affected by the stat-down move.
- call QuarterSpeedDueToParalysis
- jp HalveAttackDueToBurn
-
-CantLowerAnymore_Pop:
- pop de
- pop hl
- inc [hl]
-
-CantLowerAnymore:
- ld a, [de]
- cp ATTACK_DOWN_SIDE_EFFECT
- ret nc
- ld hl, NothingHappenedText
- jp PrintText
-
-MoveMissed:
- ld a, [de]
- cp $44
- ret nc
- jp ConditionalPrintButItFailed
-
-MonsStatsFellText:
- TX_FAR _MonsStatsFellText
- TX_ASM
- ld hl, FellText
- ld a, [H_WHOSETURN]
- and a
- ld a, [wPlayerMoveEffect]
- jr z, .playerTurn
- ld a, [wEnemyMoveEffect]
-.playerTurn
-; check if the move's effect decreases a stat by 2
- cp BIDE_EFFECT
- ret c
- cp ATTACK_DOWN_SIDE_EFFECT
- ret nc
- ld hl, GreatlyFellText
- ret
-
-GreatlyFellText:
- TX_DELAY
- TX_FAR _GreatlyFellText
-; fallthrough
-FellText:
- TX_FAR _FellText
- db "@"
-
-PrintStatText:
- ld hl, StatsTextStrings
- ld c, "@"
-.findStatName_outer
- dec b
- jr z, .foundStatName
-.findStatName_inner
- ld a, [hli]
- cp c
- jr z, .findStatName_outer
- jr .findStatName_inner
-.foundStatName
- ld de, wcf4b
- ld bc, $a
- jp CopyData
-
-StatsTextStrings:
- db "ATTACK@"
- db "DEFENSE@"
- db "SPEED@"
- db "SPECIAL@"
- db "ACCURACY@"
- db "EVADE@"
-
-StatModifierRatios:
-; first byte is numerator, second byte is denominator
- db 25, 100 ; 0.25
- db 28, 100 ; 0.28
- db 33, 100 ; 0.33
- db 40, 100 ; 0.40
- db 50, 100 ; 0.50
- db 66, 100 ; 0.66
- db 1, 1 ; 1.00
- db 15, 10 ; 1.50
- db 2, 1 ; 2.00
- db 25, 10 ; 2.50
- db 3, 1 ; 3.00
- db 35, 10 ; 3.50
- db 4, 1 ; 4.00
-
-BideEffect:
- ld hl, wPlayerBattleStatus1
- ld de, wPlayerBideAccumulatedDamage
- ld bc, wPlayerNumAttacksLeft
- ld a, [H_WHOSETURN]
- and a
- jr z, .bideEffect
- ld hl, wEnemyBattleStatus1
- ld de, wEnemyBideAccumulatedDamage
- ld bc, wEnemyNumAttacksLeft
-.bideEffect
- set STORING_ENERGY, [hl] ; mon is now using bide
- xor a
- ld [de], a
- inc de
- ld [de], a
- ld [wPlayerMoveEffect], a
- ld [wEnemyMoveEffect], a
- call BattleRandom
- and $1
- inc a
- inc a
- ld [bc], a ; set Bide counter to 2 or 3 at random
- ld a, [H_WHOSETURN]
- add XSTATITEM_ANIM
- jp PlayBattleAnimation2
-
-ThrashPetalDanceEffect:
- ld hl, wPlayerBattleStatus1
- ld de, wPlayerNumAttacksLeft
- ld a, [H_WHOSETURN]
- and a
- jr z, .thrashPetalDanceEffect
- ld hl, wEnemyBattleStatus1
- ld de, wEnemyNumAttacksLeft
-.thrashPetalDanceEffect
- set THRASHING_ABOUT, [hl] ; mon is now using thrash/petal dance
- call BattleRandom
- and $1
- inc a
- inc a
- ld [de], a ; set thrash/petal dance counter to 2 or 3 at random
- ld a, [H_WHOSETURN]
- add ANIM_B0
- jp PlayBattleAnimation2
-
-SwitchAndTeleportEffect:
- ld a, [H_WHOSETURN]
- and a
- jr nz, .handleEnemy
- ld a, [wIsInBattle]
- dec a
- jr nz, .notWildBattle1
- ld a, [wCurEnemyLVL]
- ld b, a
- ld a, [wBattleMonLevel]
- cp b ; is the player's level greater than the enemy's level?
- jr nc, .playerMoveWasSuccessful ; if so, teleport will always succeed
- add b
- ld c, a
- inc c ; c = sum of player level and enemy level
-.rejectionSampleLoop1
- call BattleRandom
- cp c ; get a random number between 0 and c
- jr nc, .rejectionSampleLoop1
- srl b
- srl b ; b = enemyLevel / 4
- cp b ; is rand[0, playerLevel + enemyLevel) >= (enemyLevel / 4)?
- jr nc, .playerMoveWasSuccessful ; if so, allow teleporting
- ld c, 50
- call DelayFrames
- ld a, [wPlayerMoveNum]
- cp TELEPORT
- jp nz, PrintDidntAffectText
- jp PrintButItFailedText_
-.playerMoveWasSuccessful
- call ReadPlayerMonCurHPAndStatus
- xor a
- ld [wAnimationType], a
- inc a
- ld [wEscapedFromBattle], a
- ld a, [wPlayerMoveNum]
- jr .playAnimAndPrintText
-.notWildBattle1
- ld c, 50
- call DelayFrames
- ld hl, IsUnaffectedText
- ld a, [wPlayerMoveNum]
- cp TELEPORT
- jp nz, PrintText
- jp PrintButItFailedText_
-.handleEnemy
- ld a, [wIsInBattle]
- dec a
- jr nz, .notWildBattle2
- ld a, [wBattleMonLevel]
- ld b, a
- ld a, [wCurEnemyLVL]
- cp b
- jr nc, .enemyMoveWasSuccessful
- add b
- ld c, a
- inc c
-.rejectionSampleLoop2
- call BattleRandom
- cp c
- jr nc, .rejectionSampleLoop2
- srl b
- srl b
- cp b
- jr nc, .enemyMoveWasSuccessful
- ld c, 50
- call DelayFrames
- ld a, [wEnemyMoveNum]
- cp TELEPORT
- jp nz, PrintDidntAffectText
- jp PrintButItFailedText_
-.enemyMoveWasSuccessful
- call ReadPlayerMonCurHPAndStatus
- xor a
- ld [wAnimationType], a
- inc a
- ld [wEscapedFromBattle], a
- ld a, [wEnemyMoveNum]
- jr .playAnimAndPrintText
-.notWildBattle2
- ld c, 50
- call DelayFrames
- ld hl, IsUnaffectedText
- ld a, [wEnemyMoveNum]
- cp TELEPORT
- jp nz, PrintText
- jp ConditionalPrintButItFailed
-.playAnimAndPrintText
- push af
- call PlayBattleAnimation
- ld c, 20
- call DelayFrames
- pop af
- ld hl, RanFromBattleText
- cp TELEPORT
- jr z, .printText
- ld hl, RanAwayScaredText
- cp ROAR
- jr z, .printText
- ld hl, WasBlownAwayText
-.printText
- jp PrintText
-
-RanFromBattleText:
- TX_FAR _RanFromBattleText
- db "@"
-
-RanAwayScaredText:
- TX_FAR _RanAwayScaredText
- db "@"
-
-WasBlownAwayText:
- TX_FAR _WasBlownAwayText
- db "@"
-
-TwoToFiveAttacksEffect:
- ld hl, wPlayerBattleStatus1
- ld de, wPlayerNumAttacksLeft
- ld bc, wPlayerNumHits
- ld a, [H_WHOSETURN]
- and a
- jr z, .twoToFiveAttacksEffect
- ld hl, wEnemyBattleStatus1
- ld de, wEnemyNumAttacksLeft
- ld bc, wEnemyNumHits
-.twoToFiveAttacksEffect
- bit ATTACKING_MULTIPLE_TIMES, [hl] ; is mon attacking multiple times?
- ret nz
- set ATTACKING_MULTIPLE_TIMES, [hl] ; mon is now attacking multiple times
- ld hl, wPlayerMoveEffect
- ld a, [H_WHOSETURN]
- and a
- jr z, .setNumberOfHits
- ld hl, wEnemyMoveEffect
-.setNumberOfHits
- ld a, [hl]
- cp TWINEEDLE_EFFECT
- jr z, .twineedle
- cp ATTACK_TWICE_EFFECT
- ld a, $2 ; number of hits it's always 2 for ATTACK_TWICE_EFFECT
- jr z, .saveNumberOfHits
-; for TWO_TO_FIVE_ATTACKS_EFFECT 3/8 chance for 2 and 3 hits, and 1/8 chance for 4 and 5 hits
- call BattleRandom
- and $3
- cp $2
- jr c, .gotNumHits
-; if the number of hits was greater than 2, re-roll again for a lower chance
- call BattleRandom
- and $3
-.gotNumHits
- inc a
- inc a
-.saveNumberOfHits
- ld [de], a
- ld [bc], a
- ret
-.twineedle
- ld a, POISON_SIDE_EFFECT1
- ld [hl], a ; set Twineedle's effect to poison effect
- jr .saveNumberOfHits
-
-FlinchSideEffect:
- call CheckTargetSubstitute
- ret nz
- ld hl, wEnemyBattleStatus1
- ld de, wPlayerMoveEffect
- ld a, [H_WHOSETURN]
- and a
- jr z, .flinchSideEffect
- ld hl, wPlayerBattleStatus1
- ld de, wEnemyMoveEffect
-.flinchSideEffect
- ld a, [de]
- cp FLINCH_SIDE_EFFECT1
- ld b, $1a ; ~10% chance of flinch
- jr z, .gotEffectChance
- ld b, $4d ; ~30% chance of flinch
-.gotEffectChance
- call BattleRandom
- cp b
- ret nc
- set FLINCHED, [hl] ; set mon's status to flinching
- call ClearHyperBeam
- ret
-
-OneHitKOEffect:
- jpab OneHitKOEffect_
-
-ChargeEffect:
- ld hl, wPlayerBattleStatus1
- ld de, wPlayerMoveEffect
- ld a, [H_WHOSETURN]
- and a
- ld b, XSTATITEM_ANIM
- jr z, .chargeEffect
- ld hl, wEnemyBattleStatus1
- ld de, wEnemyMoveEffect
- ld b, ANIM_AF
-.chargeEffect
- set CHARGING_UP, [hl]
- ld a, [de]
- dec de ; de contains enemy or player MOVENUM
- cp FLY_EFFECT
- jr nz, .notFly
- set INVULNERABLE, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
- ld b, TELEPORT ; load Teleport's animation
-.notFly
- ld a, [de]
- cp DIG
- jr nz, .notDigOrFly
- set INVULNERABLE, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
- ld b, ANIM_C0
-.notDigOrFly
- xor a
- ld [wAnimationType], a
- ld a, b
- call PlayBattleAnimation
- ld a, [de]
- ld [wChargeMoveNum], a
- ld hl, ChargeMoveEffectText
- jp PrintText
-
-ChargeMoveEffectText:
- TX_FAR _ChargeMoveEffectText
- TX_ASM
- ld a, [wChargeMoveNum]
- cp RAZOR_WIND
- ld hl, MadeWhirlwindText
- jr z, .gotText
- cp SOLARBEAM
- ld hl, TookInSunlightText
- jr z, .gotText
- cp SKULL_BASH
- ld hl, LoweredItsHeadText
- jr z, .gotText
- cp SKY_ATTACK
- ld hl, SkyAttackGlowingText
- jr z, .gotText
- cp FLY
- ld hl, FlewUpHighText
- jr z, .gotText
- cp DIG
- ld hl, DugAHoleText
-.gotText
- ret
-
-MadeWhirlwindText:
- TX_FAR _MadeWhirlwindText
- db "@"
-
-TookInSunlightText:
- TX_FAR _TookInSunlightText
- db "@"
-
-LoweredItsHeadText:
- TX_FAR _LoweredItsHeadText
- db "@"
-
-SkyAttackGlowingText:
- TX_FAR _SkyAttackGlowingText
- db "@"
-
-FlewUpHighText:
- TX_FAR _FlewUpHighText
- db "@"
-
-DugAHoleText:
- TX_FAR _DugAHoleText
- db "@"
-
-TrappingEffect:
- ld hl, wPlayerBattleStatus1
- ld de, wPlayerNumAttacksLeft
- ld a, [H_WHOSETURN]
- and a
- jr z, .trappingEffect
- ld hl, wEnemyBattleStatus1
- ld de, wEnemyNumAttacksLeft
-.trappingEffect
- bit USING_TRAPPING_MOVE, [hl]
- ret nz
- call ClearHyperBeam ; since this effect is called before testing whether the move will hit,
- ; the target won't need to recharge even if the trapping move missed
- set USING_TRAPPING_MOVE, [hl] ; mon is now using a trapping move
- call BattleRandom ; 3/8 chance for 2 and 3 attacks, and 1/8 chance for 4 and 5 attacks
- and $3
- cp $2
- jr c, .setTrappingCounter
- call BattleRandom
- and $3
-.setTrappingCounter
- inc a
- ld [de], a
- ret
-
-MistEffect:
- jpab MistEffect_
-
-FocusEnergyEffect:
- jpab FocusEnergyEffect_
-
-RecoilEffect:
- jpab RecoilEffect_
-
-ConfusionSideEffect:
- call BattleRandom
- cp $19 ; ~10% chance
- ret nc
- jr ConfusionSideEffectSuccess
-
-ConfusionEffect:
- call CheckTargetSubstitute
- jr nz, ConfusionEffectFailed
- call MoveHitTest
- ld a, [wMoveMissed]
- and a
- jr nz, ConfusionEffectFailed
-
-ConfusionSideEffectSuccess:
- ld a, [H_WHOSETURN]
- and a
- ld hl, wEnemyBattleStatus1
- ld bc, wEnemyConfusedCounter
- ld a, [wPlayerMoveEffect]
- jr z, .confuseTarget
- ld hl, wPlayerBattleStatus1
- ld bc, wPlayerConfusedCounter
- ld a, [wEnemyMoveEffect]
-.confuseTarget
- bit CONFUSED, [hl] ; is mon confused?
- jr nz, ConfusionEffectFailed
- set CONFUSED, [hl] ; mon is now confused
- push af
- call BattleRandom
- and $3
- inc a
- inc a
- ld [bc], a ; confusion status will last 2-5 turns
- pop af
- cp CONFUSION_SIDE_EFFECT
- call nz, PlayCurrentMoveAnimation2
- ld hl, BecameConfusedText
- jp PrintText
-
-BecameConfusedText:
- TX_FAR _BecameConfusedText
- db "@"
-
-ConfusionEffectFailed:
- cp CONFUSION_SIDE_EFFECT
- ret z
- ld c, 50
- call DelayFrames
- jp ConditionalPrintButItFailed
-
-ParalyzeEffect:
- jpab ParalyzeEffect_
-
-SubstituteEffect:
- jpab SubstituteEffect_
-
-HyperBeamEffect:
- ld hl, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .hyperBeamEffect
- ld hl, wEnemyBattleStatus2
-.hyperBeamEffect
- set NEEDS_TO_RECHARGE, [hl] ; mon now needs to recharge
- ret
-
-ClearHyperBeam:
- push hl
- ld hl, wEnemyBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .playerTurn
- ld hl, wPlayerBattleStatus2
-.playerTurn
- res NEEDS_TO_RECHARGE, [hl] ; mon no longer needs to recharge
- pop hl
- ret
-
-RageEffect:
- ld hl, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .player
- ld hl, wEnemyBattleStatus2
-.player
- set USING_RAGE, [hl] ; mon is now in "rage" mode
- ret
-
-MimicEffect:
- ld c, 50
- call DelayFrames
- call MoveHitTest
- ld a, [wMoveMissed]
- and a
- jr nz, .mimicMissed
- ld a, [H_WHOSETURN]
- and a
- ld hl, wBattleMonMoves
- ld a, [wPlayerBattleStatus1]
- jr nz, .enemyTurn
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- jr nz, .letPlayerChooseMove
- ld hl, wEnemyMonMoves
- ld a, [wEnemyBattleStatus1]
-.enemyTurn
- bit INVULNERABLE, a
- jr nz, .mimicMissed
-.getRandomMove
- push hl
- call BattleRandom
- and $3
- ld c, a
- ld b, $0
- add hl, bc
- ld a, [hl]
- pop hl
- and a
- jr z, .getRandomMove
- ld d, a
- ld a, [H_WHOSETURN]
- and a
- ld hl, wBattleMonMoves
- ld a, [wPlayerMoveListIndex]
- jr z, .playerTurn
- ld hl, wEnemyMonMoves
- ld a, [wEnemyMoveListIndex]
- jr .playerTurn
-.letPlayerChooseMove
- ld a, [wEnemyBattleStatus1]
- bit INVULNERABLE, a
- jr nz, .mimicMissed
- ld a, [wCurrentMenuItem]
- push af
- ld a, $1
- ld [wMoveMenuType], a
- call MoveSelectionMenu
- call LoadScreenTilesFromBuffer1
- ld hl, wEnemyMonMoves
- ld a, [wCurrentMenuItem]
- ld c, a
- ld b, $0
- add hl, bc
- ld d, [hl]
- pop af
- ld hl, wBattleMonMoves
-.playerTurn
- ld c, a
- ld b, $0
- add hl, bc
- ld a, d
- ld [hl], a
- ld [wd11e], a
- call GetMoveName
- call PlayCurrentMoveAnimation
- ld hl, MimicLearnedMoveText
- jp PrintText
-.mimicMissed
- jp PrintButItFailedText_
-
-MimicLearnedMoveText:
- TX_FAR _MimicLearnedMoveText
- db "@"
-
-LeechSeedEffect:
- jpab LeechSeedEffect_
-
-SplashEffect:
- call PlayCurrentMoveAnimation
- jp PrintNoEffectText
-
-DisableEffect:
- call MoveHitTest
- ld a, [wMoveMissed]
- and a
- jr nz, .moveMissed
- ld de, wEnemyDisabledMove
- ld hl, wEnemyMonMoves
- ld a, [H_WHOSETURN]
- and a
- jr z, .disableEffect
- ld de, wPlayerDisabledMove
- ld hl, wBattleMonMoves
-.disableEffect
-; no effect if target already has a move disabled
- ld a, [de]
- and a
- jr nz, .moveMissed
-.pickMoveToDisable
- push hl
- call BattleRandom
- and $3
- ld c, a
- ld b, $0
- add hl, bc
- ld a, [hl]
- pop hl
- and a
- jr z, .pickMoveToDisable ; loop until a non-00 move slot is found
- ld [wd11e], a ; store move number
- push hl
- ld a, [H_WHOSETURN]
- and a
- ld hl, wBattleMonPP
- jr nz, .enemyTurn
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- pop hl ; wEnemyMonMoves
- jr nz, .playerTurnNotLinkBattle
-; .playerTurnLinkBattle
- push hl
- ld hl, wEnemyMonPP
-.enemyTurn
- push hl
- ld a, [hli]
- or [hl]
- inc hl
- or [hl]
- inc hl
- or [hl]
- and $3f
- pop hl ; wBattleMonPP or wEnemyMonPP
- jr z, .moveMissedPopHL ; nothing to do if all moves have no PP left
- add hl, bc
- ld a, [hl]
- pop hl
- and a
- jr z, .pickMoveToDisable ; pick another move if this one had 0 PP
-.playerTurnNotLinkBattle
-; non-link battle enemies have unlimited PP so the previous checks aren't needed
- call BattleRandom
- and $7
- inc a ; 1-8 turns disabled
- inc c ; move 1-4 will be disabled
- swap c
- add c ; map disabled move to high nibble of wEnemyDisabledMove / wPlayerDisabledMove
- ld [de], a
- call PlayCurrentMoveAnimation2
- ld hl, wPlayerDisabledMoveNumber
- ld a, [H_WHOSETURN]
- and a
- jr nz, .printDisableText
- inc hl ; wEnemyDisabledMoveNumber
-.printDisableText
- ld a, [wd11e] ; move number
- ld [hl], a
- call GetMoveName
- ld hl, MoveWasDisabledText
- jp PrintText
-.moveMissedPopHL
- pop hl
-.moveMissed
- jp PrintButItFailedText_
-
-MoveWasDisabledText:
- TX_FAR _MoveWasDisabledText
- db "@"
-
-PayDayEffect:
- jpab PayDayEffect_
-
-ConversionEffect:
- jpab ConversionEffect_
-
-HazeEffect:
- jpab HazeEffect_
-
-HealEffect:
- jpab HealEffect_
-
-TransformEffect:
- jpab TransformEffect_
-
-ReflectLightScreenEffect:
- jpab ReflectLightScreenEffect_
-
-NothingHappenedText:
- TX_FAR _NothingHappenedText
- db "@"
-
-PrintNoEffectText:
- ld hl, NoEffectText
- jp PrintText
-
-NoEffectText:
- TX_FAR _NoEffectText
- db "@"
-
-ConditionalPrintButItFailed:
- ld a, [wMoveDidntMiss]
- and a
- ret nz ; return if the side effect failed, yet the attack was successful
-
-PrintButItFailedText_:
- ld hl, ButItFailedText
- jp PrintText
-
-ButItFailedText:
- TX_FAR _ButItFailedText
- db "@"
-
-PrintDidntAffectText:
- ld hl, DidntAffectText
- jp PrintText
-
-DidntAffectText:
- TX_FAR _DidntAffectText
- db "@"
-
-IsUnaffectedText:
- TX_FAR _IsUnaffectedText
- db "@"
-
-PrintMayNotAttackText:
- ld hl, ParalyzedMayNotAttackText
- jp PrintText
-
-ParalyzedMayNotAttackText:
- TX_FAR _ParalyzedMayNotAttackText
- db "@"
-
-CheckTargetSubstitute:
- push hl
- ld hl, wEnemyBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .next1
- ld hl, wPlayerBattleStatus2
-.next1
- bit HAS_SUBSTITUTE_UP, [hl]
- pop hl
- ret
-
-PlayCurrentMoveAnimation2:
-; animation at MOVENUM will be played unless MOVENUM is 0
-; plays wAnimationType 3 or 6
- ld a, [H_WHOSETURN]
- and a
- ld a, [wPlayerMoveNum]
- jr z, .notEnemyTurn
- ld a, [wEnemyMoveNum]
-.notEnemyTurn
- and a
- ret z
-
-PlayBattleAnimation2:
-; play animation ID at a and animation type 6 or 3
- ld [wAnimationID], a
- ld a, [H_WHOSETURN]
- and a
- ld a, $6
- jr z, .storeAnimationType
- ld a, $3
-.storeAnimationType
- ld [wAnimationType], a
- jp PlayBattleAnimationGotID
-
-PlayCurrentMoveAnimation:
-; animation at MOVENUM will be played unless MOVENUM is 0
-; resets wAnimationType
- xor a
- ld [wAnimationType], a
- ld a, [H_WHOSETURN]
- and a
- ld a, [wPlayerMoveNum]
- jr z, .notEnemyTurn
- ld a, [wEnemyMoveNum]
-.notEnemyTurn
- and a
- ret z
-
-PlayBattleAnimation:
-; play animation ID at a and predefined animation type
- ld [wAnimationID], a
-
-PlayBattleAnimationGotID:
-; play animation at wAnimationID
- push hl
- push de
- push bc
- predef MoveAnimation
- pop bc
- pop de
- pop hl
- ret