mirror of
https://github.com/pret/pokegold-spaceworld.git
synced 2026-08-08 19:25:24 -05:00
6083 lines
96 KiB
NASM
6083 lines
96 KiB
NASM
DoPlayerTurn:
|
|
xor a
|
|
ldh [hBattleTurn], a
|
|
|
|
ld a, [wBattlePlayerAction]
|
|
and a
|
|
ret nz
|
|
|
|
xor a
|
|
ld [wTurnEnded], a
|
|
call CheckTurn
|
|
|
|
ld a, [wTurnEnded]
|
|
and a
|
|
ret nz
|
|
|
|
call UpdateMoveData
|
|
ld a, [wPlayerMoveStructEffect]
|
|
jr DoMove
|
|
|
|
DoEnemyTurn:
|
|
ld a, 1
|
|
ldh [hBattleTurn], a
|
|
ld a, [wLinkMode]
|
|
and a
|
|
jr z, .do_it
|
|
|
|
ld a, [wOtherPlayerLinkAction]
|
|
cp BATTLEACTION_STRUGGLE
|
|
jr z, .do_it
|
|
cp BATTLEACTION_SWITCH1
|
|
ret nc
|
|
|
|
.do_it:
|
|
xor a
|
|
ld [wTurnEnded], a
|
|
call CheckTurn
|
|
|
|
ld a, [wTurnEnded]
|
|
and a
|
|
ret nz
|
|
|
|
ld hl, wEnemyTurnsTaken
|
|
inc [hl]
|
|
|
|
call UpdateMoveData
|
|
ld a, [wEnemyMoveStructEffect]
|
|
; fallthrough
|
|
|
|
DoMove:
|
|
; Get the user's move effect.
|
|
ld b, 0
|
|
ld c, a
|
|
ld hl, MoveEffectsPointers
|
|
add hl, bc
|
|
add hl, bc
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
|
|
ld de, wBattleScriptBuffer
|
|
|
|
.GetMoveEffect:
|
|
ld a, [hli]
|
|
ld [de], a
|
|
inc de
|
|
cp endmove_command
|
|
jr nz, .GetMoveEffect
|
|
|
|
; Start at the first command.
|
|
ld hl, wBattleScriptBuffer
|
|
ld a, l
|
|
ld [wBattleScriptBufferAddress], a
|
|
ld a, h
|
|
ld [wBattleScriptBufferAddress + 1], a
|
|
|
|
.ReadMoveEffectCommand:
|
|
push bc
|
|
ld a, [wBattleScriptBufferAddress]
|
|
ld l, a
|
|
ld a, [wBattleScriptBufferAddress + 1]
|
|
ld h, a
|
|
|
|
ld a, [hli]
|
|
|
|
ld c, a
|
|
cp endmove_command
|
|
ld a, l
|
|
ld [wBattleScriptBufferAddress], a
|
|
ld a, h
|
|
ld [wBattleScriptBufferAddress + 1], a
|
|
jr z, .end
|
|
|
|
; The rest of the commands (01-af) are read from BattleCommandPointers.
|
|
dec c
|
|
ld b, 0
|
|
ld hl, BattleCommandPointers
|
|
add hl, bc
|
|
add hl, bc
|
|
ld a, [hli]
|
|
ld [wPredefBC + 1], a
|
|
ld a, [hl]
|
|
ld [wPredefBC], a
|
|
pop bc
|
|
|
|
ld hl, .ReadMoveEffectCommand
|
|
push hl
|
|
ld a, [wPredefBC + 1]
|
|
ld l, a
|
|
ld a, [wPredefBC]
|
|
ld h, a
|
|
jp hl
|
|
|
|
.end:
|
|
pop bc
|
|
ret
|
|
|
|
INCLUDE "data/moves/effects.asm"
|
|
|
|
INCLUDE "data/battle/ai/effect_command_pointers.asm"
|
|
|
|
CheckTurn:
|
|
BattleCommand_CheckTurn:
|
|
; Repurposed as hardcoded turn handling. Useless as a command.
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wCurPlayerMove]
|
|
jr z, .go
|
|
ld a, [wCurEnemyMove]
|
|
|
|
.go
|
|
inc a
|
|
jp z, EndTurn
|
|
|
|
xor a
|
|
ld [wAttackMissed], a
|
|
ld [wBattleAnimParam], a
|
|
ld [wAlreadyDisobeyed], a
|
|
ld [wAlreadyFailed], a
|
|
|
|
ld a, EFFECTIVE
|
|
ld [wTypeModifier], a
|
|
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp nz, CheckEnemyTurn
|
|
|
|
ld hl, wBattleMonStatus
|
|
ld a, [hl]
|
|
and SLP
|
|
jr z, .not_asleep
|
|
|
|
dec a
|
|
ld [wBattleMonStatus], a
|
|
and SLP
|
|
jr z, .woke_up
|
|
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld de, ANIM_SLP
|
|
call PlayFXAnimID
|
|
jr .fast_asleep
|
|
|
|
.woke_up
|
|
ld hl, WokeUpText
|
|
call PrintText
|
|
ld hl, UpdatePlayerHUD
|
|
call CallFromBank0F
|
|
ld hl, wPlayerSubStatus1
|
|
res SUBSTATUS_NIGHTMARE, [hl]
|
|
jr .not_asleep
|
|
|
|
.fast_asleep
|
|
ld hl, FastAsleepText
|
|
call PrintText
|
|
|
|
; Snore and Sleep Talk bypass sleep.
|
|
ld a, [wCurPlayerMove]
|
|
cp MOVE_SNORE
|
|
jr z, .not_asleep
|
|
cp MOVE_SLEEP_TALK
|
|
jr z, .not_asleep
|
|
|
|
xor a
|
|
ld [wLastPlayerCounterMove], a
|
|
jp EndTurn
|
|
|
|
.not_asleep
|
|
ld hl, wBattleMonStatus
|
|
bit FRZ, [hl]
|
|
jr z, .not_frozen
|
|
|
|
; Flame Wheel and Sacred Fire thaw the user.
|
|
ld a, [wCurPlayerMove]
|
|
cp MOVE_FLAME_WHEEL
|
|
jr z, .not_frozen
|
|
cp MOVE_SACRED_FIRE
|
|
jr z, .not_frozen
|
|
|
|
ld hl, FrozenSolidText
|
|
call PrintText
|
|
xor a
|
|
ld [wLastPlayerCounterMove], a
|
|
jp EndTurn
|
|
|
|
.not_frozen
|
|
ld a, [wEnemySubStatus3]
|
|
bit SUBSTATUS_USING_TRAPPING_MOVE, a
|
|
jp z, .not_trapped
|
|
|
|
; Rapid Spin breaks the player free of trapping moves
|
|
ld a, [wCurPlayerMove]
|
|
cp MOVE_RAPID_SPIN
|
|
jp z, .not_trapped
|
|
ld hl, CantMoveText
|
|
call PrintText
|
|
jp EndTurn
|
|
|
|
.not_trapped
|
|
ld hl, wPlayerSubStatus3
|
|
bit SUBSTATUS_FLINCHED, [hl]
|
|
jp z, .not_flinched
|
|
|
|
res SUBSTATUS_FLINCHED, [hl]
|
|
ld hl, FlinchedText
|
|
call PrintText
|
|
jp EndTurn
|
|
|
|
.not_flinched
|
|
ld hl, wPlayerSubStatus4
|
|
bit SUBSTATUS_RECHARGE, [hl]
|
|
jr z, .no_recharge
|
|
|
|
res SUBSTATUS_RECHARGE, [hl]
|
|
ld hl, MustRechargeText
|
|
call PrintText
|
|
jp EndTurn
|
|
|
|
.no_recharge
|
|
ld hl, wPlayerDisableCount
|
|
ld a, [hl]
|
|
and a
|
|
jr z, .not_disabled
|
|
|
|
dec a
|
|
ld [hl], a
|
|
and $f
|
|
jr nz, .not_disabled
|
|
|
|
ld [hl], a
|
|
ld [wDisabledMove], a
|
|
ld hl, DisabledNoMoreText
|
|
call PrintText
|
|
|
|
.not_disabled
|
|
ld a, [wPlayerSubStatus3]
|
|
add a ; bit SUBSTATUS_CONFUSED
|
|
jr nc, .not_confused
|
|
|
|
ld hl, wPlayerConfuseCount
|
|
dec [hl]
|
|
jr nz, .confused
|
|
|
|
ld hl, wPlayerSubStatus3
|
|
res SUBSTATUS_CONFUSED, [hl]
|
|
ld hl, ConfusedNoMoreText
|
|
call PrintText
|
|
jr .not_confused
|
|
|
|
.confused
|
|
ld hl, IsConfusedText
|
|
call PrintText
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld de, ANIM_CONFUSED
|
|
call PlayFXAnimID
|
|
|
|
; 50% chance of hitting itself
|
|
call BattleRandom
|
|
cp 50 percent + 1
|
|
jp c, .not_confused
|
|
|
|
; clear confusion-dependent substatus
|
|
ld hl, wPlayerSubStatus3
|
|
ld a, [hl]
|
|
and 1 << SUBSTATUS_CONFUSED
|
|
ld [hl], a
|
|
|
|
call HitConfusion
|
|
jr .cant_move
|
|
|
|
.not_confused
|
|
ld a, [wPlayerSubStatus1]
|
|
add a ; bit SUBSTATUS_ATTRACT
|
|
jr nc, .not_infatuated
|
|
|
|
ld hl, InLoveWithText
|
|
call PrintText
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld de, ANIM_IN_LOVE
|
|
call PlayFXAnimID
|
|
|
|
; 50% chance of infatuation
|
|
call BattleRandom
|
|
cp 50 percent + 1
|
|
jp c, .not_infatuated
|
|
ld hl, InfatuationText
|
|
call PrintText
|
|
jr .cant_move
|
|
|
|
.not_infatuated
|
|
ld a, [wDisabledMove]
|
|
and a
|
|
jr z, .no_disabled_move
|
|
|
|
ld hl, wCurPlayerMove
|
|
cp [hl]
|
|
jr nz, .no_disabled_move
|
|
|
|
call MoveDisabled
|
|
jp EndTurn
|
|
|
|
.no_disabled_move
|
|
ld hl, wBattleMonStatus
|
|
bit PAR, [hl]
|
|
jr z, .not_paralyzed
|
|
|
|
call BattleRandom
|
|
cp 25 percent
|
|
jr nc, .not_paralyzed
|
|
ld hl, FullyParalyzedText
|
|
call PrintText
|
|
|
|
.cant_move
|
|
ld hl, wPlayerSubStatus3
|
|
ld a, [hl]
|
|
and ((1 << SUBSTATUS_CONFUSED) | (1 << SUBSTATUS_INVULNERABLE) | (1 << SUBSTATUS_FLINCHED) | (1 << SUBSTATUS_IN_LOOP))
|
|
ld [hl], a
|
|
|
|
ld hl, wPlayerSubStatus1
|
|
res SUBSTATUS_ROLLOUT, [hl]
|
|
|
|
ld a, [wPlayerMoveStruct]
|
|
cp MOVE_FLY
|
|
jr z, .fly_dig
|
|
cp MOVE_DIG
|
|
jr z, .fly_dig
|
|
jr .end_turn
|
|
|
|
.fly_dig
|
|
res SUBSTATUS_INVULNERABLE, [hl]
|
|
ld a, 2
|
|
ld [wBattleAnimParam], a
|
|
call LoadMoveAnim
|
|
|
|
.end_turn
|
|
jp EndTurn
|
|
|
|
.not_paralyzed
|
|
ret
|
|
|
|
CheckEnemyTurn:
|
|
ld hl, wEnemyMonStatus
|
|
ld a, [hl]
|
|
and SLP
|
|
jr z, .not_asleep
|
|
|
|
dec a
|
|
ld [wEnemyMonStatus], a
|
|
and a
|
|
jr z, .woke_up
|
|
|
|
ld hl, FastAsleepText
|
|
call PrintText
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld de, ANIM_SLP
|
|
call PlayFXAnimID
|
|
jr .fast_asleep
|
|
|
|
.woke_up
|
|
ld hl, WokeUpText
|
|
call PrintText
|
|
ld hl, UpdateEnemyHUD
|
|
call CallFromBank0F
|
|
ld hl, wEnemySubStatus1
|
|
res SUBSTATUS_NIGHTMARE, [hl]
|
|
jr .not_asleep
|
|
|
|
.fast_asleep
|
|
; Snore and Sleep Talk bypass sleep.
|
|
ld a, [wCurPlayerMove]
|
|
cp MOVE_SNORE
|
|
jr z, .not_asleep
|
|
cp MOVE_SLEEP_TALK
|
|
jr z, .not_asleep
|
|
|
|
xor a
|
|
ld [wLastEnemyCounterMove], a
|
|
jp EndTurn
|
|
|
|
.not_asleep
|
|
ld hl, wEnemyMonStatus
|
|
bit FRZ, [hl]
|
|
jr z, .not_frozen
|
|
|
|
; Flame Wheel and Sacred Fire thaw the user.
|
|
ld a, [wCurEnemyMove]
|
|
cp MOVE_FLAME_WHEEL
|
|
jr z, .not_frozen
|
|
cp MOVE_SACRED_FIRE
|
|
jr z, .not_frozen
|
|
|
|
ld hl, FrozenSolidText
|
|
call PrintText
|
|
xor a
|
|
ld [wLastEnemyCounterMove], a
|
|
jp EndTurn
|
|
|
|
.not_frozen
|
|
ld a, [wPlayerSubStatus3]
|
|
bit SUBSTATUS_USING_TRAPPING_MOVE, a
|
|
jp z, .not_trapped
|
|
|
|
; Rapid Spin breaks the player free of trapping moves
|
|
ld a, [wCurEnemyMove]
|
|
cp MOVE_RAPID_SPIN
|
|
jp z, .not_trapped
|
|
ld hl, CantMoveText
|
|
call PrintText
|
|
jp EndTurn
|
|
|
|
.not_trapped
|
|
ld hl, wEnemySubStatus3
|
|
bit SUBSTATUS_FLINCHED, [hl]
|
|
jp z, .not_flinched
|
|
|
|
res SUBSTATUS_FLINCHED, [hl]
|
|
ld hl, FlinchedText
|
|
call PrintText
|
|
jp EndTurn
|
|
|
|
.not_flinched
|
|
ld hl, wEnemySubStatus4
|
|
bit SUBSTATUS_RECHARGE, [hl]
|
|
jr z, .no_recharge
|
|
|
|
res SUBSTATUS_RECHARGE, [hl]
|
|
ld hl, MustRechargeText
|
|
call PrintText
|
|
jp EndTurn
|
|
|
|
.no_recharge
|
|
ld hl, wEnemyDisableCount
|
|
ld a, [hl]
|
|
and a
|
|
jr z, .not_disabled
|
|
|
|
dec a
|
|
ld [hl], a
|
|
and $f
|
|
jr nz, .not_disabled
|
|
|
|
ld [hl], a
|
|
ld [wEnemyDisabledMove], a
|
|
ld hl, DisabledNoMoreText
|
|
call PrintText
|
|
|
|
.not_disabled
|
|
ld a, [wEnemySubStatus3]
|
|
add a ; bit SUBSTATUS_CONFUSED
|
|
jp nc, .not_confused
|
|
|
|
ld hl, wEnemyConfuseCount
|
|
dec [hl]
|
|
jr nz, .confused
|
|
|
|
ld hl, wEnemySubStatus3
|
|
res SUBSTATUS_CONFUSED, [hl]
|
|
ld hl, ConfusedNoMoreText
|
|
call PrintText
|
|
jp .not_confused
|
|
|
|
.confused
|
|
ld hl, IsConfusedText
|
|
call PrintText
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld de, ANIM_CONFUSED
|
|
call PlayFXAnimID
|
|
|
|
; 50% chance of hitting itself
|
|
call BattleRandom
|
|
cp 50 percent + 1
|
|
jr c, .not_confused
|
|
|
|
; clear confusion-dependent substatus
|
|
ld hl, wEnemySubStatus3
|
|
ld a, [hl]
|
|
and 1 << SUBSTATUS_CONFUSED
|
|
ld [hl], a
|
|
|
|
; Player's turn zeroes out wCriticalHit here, but not the enemy.
|
|
; Damage doesn't appear to be affected by this in any way.
|
|
ld hl, HurtItselfText
|
|
call PrintText
|
|
call HitSelfInConfusion
|
|
call BattleCommand_DamageCalc
|
|
|
|
xor a
|
|
ld [wNumHits], a
|
|
ldh [hBattleTurn], a
|
|
ld de, MOVE_POUND
|
|
call PlayFXAnimID
|
|
ld a, 1
|
|
ldh [hBattleTurn], a
|
|
call DoEnemyDamage
|
|
jr .cant_move
|
|
|
|
.not_confused
|
|
ld a, [wEnemySubStatus1]
|
|
add a
|
|
jr nc, .not_infatuated
|
|
|
|
ld hl, InLoveWithText
|
|
call PrintText
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld de, ANIM_IN_LOVE
|
|
call PlayFXAnimID
|
|
|
|
; 50% chance of infatuation
|
|
call BattleRandom
|
|
cp 50 percent + 1
|
|
jp c, .not_infatuated
|
|
ld hl, InfatuationText
|
|
call PrintText
|
|
jr .cant_move
|
|
|
|
.not_infatuated
|
|
ld a, [wEnemyDisabledMove]
|
|
and a
|
|
jr z, .no_disabled_move
|
|
|
|
ld hl, wCurEnemyMove
|
|
cp [hl]
|
|
jr nz, .no_disabled_move
|
|
|
|
call MoveDisabled
|
|
jp EndTurn
|
|
|
|
.no_disabled_move
|
|
ld hl, wEnemyMonStatus
|
|
bit PAR, [hl]
|
|
jr z, .not_paralyzed
|
|
|
|
call BattleRandom
|
|
cp 25 percent
|
|
jr nc, .not_paralyzed
|
|
ld hl, FullyParalyzedText
|
|
call PrintText
|
|
|
|
.cant_move
|
|
ld hl, wEnemySubStatus3
|
|
ld a, [hl]
|
|
and ((1 << SUBSTATUS_CONFUSED) | (1 << SUBSTATUS_INVULNERABLE) | (1 << SUBSTATUS_FLINCHED) | (1 << SUBSTATUS_IN_LOOP))
|
|
ld [hl], a
|
|
|
|
ld hl, wEnemySubStatus1
|
|
res SUBSTATUS_ROLLOUT, [hl]
|
|
|
|
ld a, [wEnemyMoveStruct]
|
|
cp MOVE_FLY
|
|
jr z, .fly_dig
|
|
cp MOVE_DIG
|
|
jr z, .fly_dig
|
|
jr .end_turn
|
|
|
|
.fly_dig
|
|
res SUBSTATUS_INVULNERABLE, [hl]
|
|
ld a, 2
|
|
ld [wBattleAnimParam], a
|
|
call LoadMoveAnim
|
|
|
|
.end_turn
|
|
jp EndTurn
|
|
|
|
.not_paralyzed
|
|
ret
|
|
; Redundant extra ret
|
|
ret
|
|
|
|
EndTurn:
|
|
ld a, 1
|
|
ld [wTurnEnded], a
|
|
ret
|
|
|
|
FastAsleepText:
|
|
text "<USER>は"
|
|
line "ぐうぐう ねむっている"
|
|
prompt
|
|
|
|
WokeUpText:
|
|
text "<USER>は めをさました!"
|
|
prompt
|
|
|
|
FrozenSolidText:
|
|
text "<USER>は"
|
|
line "こおって しまって うごかない!"
|
|
prompt
|
|
|
|
FullyParalyzedText:
|
|
text "<USER>は"
|
|
line "からだが しびれて うごけない"
|
|
prompt
|
|
|
|
FlinchedText:
|
|
text "<USER>は ひるんだ!"
|
|
prompt
|
|
|
|
MustRechargeText:
|
|
text "こうげきの はんどうで"
|
|
line "<USER>は うごけない!"
|
|
prompt
|
|
|
|
DisabledNoMoreText:
|
|
text "<USER>の"
|
|
line "かなしばりが とけた!"
|
|
prompt
|
|
|
|
IsConfusedText:
|
|
text "<USER>は"
|
|
line "こんらんしている!"
|
|
prompt
|
|
|
|
HurtItselfText:
|
|
text "わけも わからず"
|
|
line "じぶんを こうげきした!"
|
|
prompt
|
|
|
|
ConfusedNoMoreText:
|
|
text "<USER>の"
|
|
line "こんらんが とけた!"
|
|
prompt
|
|
|
|
AttackContinuesText:
|
|
text "<USER>の こうげきは"
|
|
line "まだ つづいている"
|
|
done
|
|
|
|
CantMoveText:
|
|
text "<USER>は"
|
|
line "みうごきが とれない!"
|
|
prompt
|
|
|
|
StoringEnergyText:
|
|
text "<USER>は がまんしている"
|
|
prompt
|
|
|
|
UnleashedEnergyText:
|
|
text "<USER>の"
|
|
line "がまんが とかれた!"
|
|
prompt
|
|
|
|
HungOnText:
|
|
text "<TARGET>は"
|
|
line "@"
|
|
text_from_ram wStringBuffer1
|
|
text "で もちこたえた!"
|
|
prompt
|
|
|
|
EnduredText:
|
|
text "<TARGET>は あいての"
|
|
line "こうげきを こらえた!"
|
|
prompt
|
|
|
|
InLoveWithText:
|
|
text "<USER>は"
|
|
line "<TARGET>に メロメロだ!"
|
|
prompt
|
|
|
|
InfatuationText:
|
|
text "<USER>は メロメロで"
|
|
line "わざが だせなかった!"
|
|
prompt
|
|
|
|
MoveDisabled:
|
|
ld hl, wCurPlayerMove
|
|
ld de, wPlayerSubStatus3
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .ok
|
|
inc hl ; wCurEnemyMove
|
|
ld de, wEnemySubStatus3
|
|
|
|
.ok
|
|
ld a, [de]
|
|
res SUBSTATUS_CHARGED, a
|
|
ld [de], a
|
|
|
|
ld a, [hl]
|
|
ld [wNamedObjectIndexBuffer], a
|
|
call GetMoveName
|
|
ld hl, DisabledMoveText
|
|
jp PrintText
|
|
|
|
DisabledMoveText:
|
|
text "<USER>は かなしばりで"
|
|
line "@"
|
|
text_from_ram wStringBuffer1
|
|
text "がだせない!"
|
|
prompt
|
|
|
|
HitConfusion:
|
|
ld hl, HurtItselfText
|
|
call PrintText
|
|
|
|
xor a
|
|
ld [wCriticalHit], a
|
|
call HitSelfInConfusion
|
|
call BattleCommand_DamageCalc
|
|
|
|
xor a
|
|
ld [wNumHits], a
|
|
inc a
|
|
ldh [hBattleTurn], a
|
|
|
|
ld de, MOVE_POUND
|
|
call PlayFXAnimID
|
|
ld hl, UpdatePlayerHUD
|
|
call CallFromBank0F
|
|
xor a
|
|
ldh [hBattleTurn], a
|
|
jp DoPlayerDamage
|
|
|
|
BattleCommand_CheckObedience:
|
|
; Enemy can't disobey
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ret nz
|
|
|
|
xor a
|
|
ld [wAlreadyDisobeyed], a
|
|
|
|
; No obedience in link battles
|
|
; (since no handling exists for enemy)
|
|
ld a, [wLinkMode]
|
|
and a
|
|
ret nz
|
|
|
|
; If the monster's id doesn't match the player's,
|
|
; some conditions need to be met.
|
|
ld hl, wPartyMon1ID
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
ld a, [wCurBattleMon]
|
|
call AddNTimes
|
|
ld a, [wPlayerID]
|
|
cp [hl]
|
|
jr nz, .obeylevel
|
|
inc hl
|
|
ld a, [wPlayerID + 1]
|
|
cp [hl]
|
|
ret z
|
|
|
|
.obeylevel
|
|
; The maximum obedience level is constrained by owned badges:
|
|
ld hl, wBadges
|
|
|
|
; eighth badge
|
|
bit 7, [hl]
|
|
ld a, MAX_LEVEL + 1
|
|
jr nz, .getlevel
|
|
|
|
; sixth badge
|
|
bit 5, [hl]
|
|
ld a, 70
|
|
jr nz, .getlevel
|
|
|
|
; fourth badge
|
|
bit 3, [hl]
|
|
ld a, 50
|
|
jr nz, .getlevel
|
|
|
|
; second badge
|
|
bit 1, [hl]
|
|
ld a, 30
|
|
jr nz, .getlevel
|
|
|
|
; no badges
|
|
ld a, 10
|
|
|
|
.getlevel
|
|
; c = obedience level
|
|
; d = monster level
|
|
; b = c + d
|
|
ld b, a
|
|
ld c, a
|
|
|
|
ld a, [wBattleMonLevel]
|
|
ld d, a
|
|
|
|
add b
|
|
ld b, a
|
|
|
|
; No overflow (this should never happen)
|
|
jr nc, .checklevel
|
|
ld b, $ff
|
|
|
|
.checklevel
|
|
; If the monster's level is lower than the obedience level, it will obey.
|
|
ld a, c
|
|
cp d
|
|
ret nc
|
|
|
|
; Random number from 0 to obedience level + monster level
|
|
.rand1:
|
|
call BattleRandom
|
|
swap a
|
|
cp b
|
|
jr nc, .rand1
|
|
|
|
; The higher above the obedience level the monster is,
|
|
; the more likely it is to disobey.
|
|
cp c
|
|
ret c
|
|
|
|
; Another random number from 0 to obedience level + monster level
|
|
.rand2
|
|
call BattleRandom
|
|
cp b
|
|
jr nc, .rand2
|
|
|
|
; A second chance.
|
|
cp c
|
|
jr c, .UseInstead
|
|
|
|
; No hope of using a move now.
|
|
|
|
; b = number of levels the monster is above the obedience level
|
|
ld a, d
|
|
sub c
|
|
ld b, a
|
|
|
|
; The chance of napping is the difference out of 256.
|
|
call BattleRandom
|
|
swap a
|
|
sub b
|
|
jr c, .Nap
|
|
|
|
; The chance of not hitting itself is the same.
|
|
cp b
|
|
jr nc, .DoNothing
|
|
|
|
ld hl, WontObeyText
|
|
call PrintText
|
|
call HitConfusion
|
|
jp .EndDisobedience
|
|
|
|
.Nap
|
|
call BattleRandom
|
|
add a
|
|
swap a
|
|
and SLP
|
|
jr z, .Nap
|
|
ld [wBattleMonStatus], a
|
|
ld hl, BeganToNapText
|
|
jr .Print
|
|
|
|
.DoNothing
|
|
call BattleRandom
|
|
and %11
|
|
|
|
ld hl, LoafingAroundText
|
|
and a ; 0
|
|
jr z, .Print
|
|
|
|
ld hl, WontObeyText
|
|
dec a ; 1
|
|
jr z, .Print
|
|
|
|
ld hl, TurnedAwayText
|
|
dec a ; 2
|
|
jr z, .Print
|
|
|
|
ld hl, IgnoredOrdersText
|
|
|
|
.Print
|
|
call PrintText
|
|
jr .EndDisobedience
|
|
|
|
.UseInstead
|
|
; Can't use another move if the monster only has one!
|
|
ld a, [wBattleMonMoves + 1]
|
|
and a
|
|
jr z, .DoNothing
|
|
|
|
; Notably, disobedience skips over checks for Disable entirely, unlike pokered and final pokegold.
|
|
|
|
; If total PP across all moves is equal to the selected moves PP, then that move is the only option.
|
|
; In that case, disobedience is forced by doing nothing.
|
|
|
|
; BUG: The calculation does not take max PP increases into account at any point.
|
|
; Therefore, this will never trigger if any moves other than the selected one had PP Ups used on them.
|
|
; This results in a potential move PP underflow, as seen below.
|
|
ld hl, wBattleMonPP
|
|
push hl
|
|
ld a, [hli] ; first move PP
|
|
ld b, [hl] ; second move PP
|
|
inc hl
|
|
add b
|
|
ld b, [hl] ; third move PP
|
|
inc hl
|
|
add b
|
|
ld b, [hl] ; fourth move PP
|
|
add b
|
|
pop hl
|
|
push af
|
|
|
|
; Force disobedience if move is the only option
|
|
ld a, [wCurMoveNum]
|
|
ld c, a
|
|
ld b, 0
|
|
add hl, bc
|
|
ld b, [hl]
|
|
pop af
|
|
|
|
cp b
|
|
jr z, .DoNothing
|
|
|
|
; Make sure we can actually use the move once we get there.
|
|
ld a, 1
|
|
ld [wAlreadyDisobeyed], a
|
|
|
|
ld a, [w2DMenuNumRows]
|
|
dec a
|
|
ld b, a
|
|
|
|
; Save the move we originally picked for afterward.
|
|
ld a, [wCurMoveNum]
|
|
ld c, a
|
|
|
|
.RandomMove
|
|
call BattleRandom
|
|
maskbits NUM_MOVES
|
|
cp b
|
|
jr nc, .RandomMove
|
|
|
|
; Not the move we were trying to use.
|
|
cp c
|
|
jr z, .RandomMove
|
|
|
|
; Make sure it has PP.
|
|
ld [wCurMoveNum], a
|
|
ld hl, wBattleMonPP
|
|
ld e, a
|
|
ld d, 0
|
|
add hl, de
|
|
ld a, [hl]
|
|
; BUG: This line clearly wasn't designed to handle moves with extra max PP, so it lets those slide no matter what.
|
|
; As a result, if max PP-increased moves are used at zero PP, they will underflow. However...
|
|
and a
|
|
jr z, .RandomMove
|
|
|
|
; ...the code that would've used the move is missing the part that actually USES the move.
|
|
; This causes it to fall through to .EndDisobedience, skipping the player's turn with no text.
|
|
ld a, [wCurMoveNum]
|
|
ld c, a
|
|
ld b, 0
|
|
ld hl, wBattleMonMoves
|
|
add hl, bc
|
|
ld a, [hl]
|
|
ld [wCurPlayerMove], a
|
|
call UpdateMoveData
|
|
|
|
.EndDisobedience
|
|
jp EndMoveEffect
|
|
|
|
LoafingAroundText:
|
|
text_from_ram wBattleMonNickname
|
|
text "は なまけている"
|
|
prompt
|
|
|
|
BeganToNapText:
|
|
text_from_ram wBattleMonNickname
|
|
text "は ひるねをはじめた!"
|
|
prompt
|
|
|
|
WontObeyText:
|
|
text_from_ram wBattleMonNickname
|
|
text "は いうことを きかない"
|
|
prompt
|
|
|
|
TurnedAwayText:
|
|
text_from_ram wBattleMonNickname
|
|
text "は そっぽを むいた"
|
|
prompt
|
|
|
|
IgnoredOrdersText:
|
|
text_from_ram wBattleMonNickname
|
|
text "は しらんぷりをした"
|
|
prompt
|
|
|
|
INCLUDE "engine/battle/used_move_text.asm"
|
|
|
|
BattleCommand_DoTurn:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wCurPlayerMove]
|
|
ld hl, wBattleMonPP
|
|
ld de, wPlayerSubStatus3
|
|
jr z, .proceed
|
|
|
|
ld a, [wCurEnemyMove]
|
|
ld hl, wEnemyMonPP
|
|
ld de, wEnemySubStatus3
|
|
|
|
.proceed
|
|
; If move is struggle, return
|
|
cp MOVE_STRUGGLE
|
|
ret z
|
|
|
|
; If forced to use the same move repeatedly, return
|
|
ld a, [de]
|
|
and ((1 << SUBSTATUS_BIDE) | (1 << SUBSTATUS_RAMPAGE) | (1 << SUBSTATUS_IN_LOOP))
|
|
ret nz
|
|
|
|
inc de
|
|
ld a, [de]
|
|
bit SUBSTATUS_RAGE, a
|
|
ret nz
|
|
|
|
call .consume_pp
|
|
ld a, b
|
|
and a
|
|
jp nz, EndMoveEffect
|
|
|
|
; Don't update party mon's PP to match when transformed.
|
|
inc de
|
|
ld a, [de]
|
|
bit SUBSTATUS_TRANSFORMED, a
|
|
ret nz
|
|
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld hl, wPartyMon1PP
|
|
ld a, [wCurBattleMon]
|
|
jr z, .player
|
|
|
|
; Wild Pokémon don't use PP
|
|
ld a, [wBattleMode]
|
|
dec a
|
|
ret z
|
|
|
|
ld hl, wOTPartyMon1PP
|
|
ld a, [wCurOTMon]
|
|
|
|
.player
|
|
ld bc, (wPartyMon2 - wPartyMon1)
|
|
call AddNTimes
|
|
|
|
.consume_pp
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wCurMoveNum]
|
|
jr z, .okay
|
|
ld a, [wCurEnemyMoveNum]
|
|
|
|
.okay
|
|
; BUG: If the Pokémon had PP Ups applied to the move it's using, then it can use it even with 0 PP.
|
|
; While not normally an issue, as the move is prevented from even being selected if it has 0 PP,
|
|
; this becomes a problem when the opponent uses Spite to lower the move's PP before the move is used.
|
|
|
|
; The move's PP will underflow, and lose one PP Up boost in the process.
|
|
ld c, a
|
|
ld b, 0
|
|
add hl, bc
|
|
ld a, [hl]
|
|
and a ; should be 'and PP_MASK'
|
|
jr z, .out_of_pp
|
|
|
|
dec [hl]
|
|
ld b, 0
|
|
ret
|
|
|
|
.out_of_pp
|
|
call BattleCommand_MoveDelay
|
|
ld hl, NoPPLeftText
|
|
call PrintText
|
|
ld b, 1
|
|
ret
|
|
|
|
NoPPLeftText:
|
|
text "しかし わざの ポイントが"
|
|
line "なかった!"
|
|
prompt
|
|
|
|
BattleCommand_Critical:
|
|
xor a
|
|
ld [wCriticalHit], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wEnemyMonSpecies]
|
|
jr nz, .go
|
|
ld a, [wBattleMonSpecies]
|
|
|
|
.go:
|
|
ld [wCurSpecies], a
|
|
call GetBaseData
|
|
ld c, 6
|
|
ld hl, wPlayerMoveStructPower
|
|
ld de, wPlayerSubStatus4
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .player
|
|
ld hl, wEnemyMoveStructPower
|
|
ld de, wEnemySubStatus4
|
|
|
|
.player:
|
|
ld a, [hld]
|
|
and a
|
|
ret z
|
|
|
|
ld a, [de]
|
|
bit SUBSTATUS_FOCUS_ENERGY, a
|
|
jr z, .not_focus_energy
|
|
dec c
|
|
dec c
|
|
dec c
|
|
|
|
.not_focus_energy:
|
|
dec hl
|
|
ld b, [hl]
|
|
ld hl, HighCriticalMoves
|
|
|
|
.CheckCritical:
|
|
ld a, [hli]
|
|
cp b
|
|
jr z, .critical_hit_move
|
|
inc a
|
|
jr nz, .CheckCritical
|
|
jr .CalcCritChance
|
|
|
|
.critical_hit_move:
|
|
dec c
|
|
dec c
|
|
|
|
; de = Base Speed * 4
|
|
.CalcCritChance:
|
|
ld a, [wMonHBaseSpeed]
|
|
ld e, a
|
|
ld d, 0
|
|
sla e
|
|
rl d
|
|
sla e
|
|
rl d
|
|
|
|
.half_crit_chance:
|
|
dec c
|
|
jr z, .CheckForCritGuarantee
|
|
srl d
|
|
rr e
|
|
jr .half_crit_chance
|
|
|
|
.CheckForCritGuarantee:
|
|
ld b, e
|
|
ld a, d
|
|
and a
|
|
jr z, .SharpScythe
|
|
ld b, $ff
|
|
|
|
.SharpScythe:
|
|
push bc
|
|
call GetUserItem
|
|
ld a, b
|
|
cp HELD_CRITICAL_UP
|
|
|
|
ld a, c
|
|
pop bc
|
|
jr nz, .Tally
|
|
|
|
; Old crit chance + held item parameter = New crit chance
|
|
add b
|
|
ld b, a
|
|
jr nc, .Tally
|
|
ld b, $ff
|
|
|
|
; Roll random number, return if less than or equal to b.
|
|
.Tally:
|
|
; Bug: 1/256 chance to not get a crit even when b is the max possible value.
|
|
call BattleRandom
|
|
rlc a
|
|
rlc a
|
|
rlc a
|
|
cp b
|
|
ret nc
|
|
|
|
ld a, 1
|
|
ld [wCriticalHit], a
|
|
ret
|
|
|
|
HighCriticalMoves:
|
|
INCLUDE "data/moves/critical_hit_moves.asm"
|
|
|
|
BattleCommand_DamageStats:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr nz, .enemy
|
|
|
|
call PlayerAttackDamage
|
|
jr .return
|
|
|
|
.enemy:
|
|
call EnemyAttackDamage
|
|
|
|
.return:
|
|
ret
|
|
|
|
INCLUDE "engine/battle/move_effects/triple_kick.asm"
|
|
|
|
BattleCommand_Stab:
|
|
; STAB = Same Type Attack Bonus
|
|
ld hl, wBattleMonType
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
ld hl, wEnemyMonType
|
|
ld a, [hli]
|
|
ld d, a
|
|
ld e, [hl]
|
|
ld a, [wPlayerMoveStructType]
|
|
ld [wNumSetBits], a
|
|
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .go
|
|
|
|
ld hl, wEnemyMonType
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
ld hl, wBattleMonType
|
|
ld a, [hli]
|
|
ld d, a
|
|
ld e, [hl]
|
|
ld a, [wEnemyMoveStructType]
|
|
ld [wCurType], a
|
|
|
|
.go:
|
|
call DoWeatherModifiers
|
|
|
|
ld a, [wCurType]
|
|
cp b
|
|
jr z, .stab
|
|
cp c
|
|
jr z, .stab
|
|
|
|
jr .SkipStab
|
|
|
|
.stab:
|
|
ld hl, wCurDamage + 1
|
|
ld a, [hld]
|
|
ld h, [hl]
|
|
ld l, a
|
|
|
|
ld b, h
|
|
ld c, l
|
|
srl b
|
|
rr c
|
|
add hl, bc
|
|
|
|
ld a, h
|
|
ld [wCurDamage], a
|
|
ld a, l
|
|
ld [wCurDamage + 1], a
|
|
ld hl, wTypeModifier
|
|
set STAB_DAMAGE_F, [hl]
|
|
|
|
.SkipStab:
|
|
ld a, [wCurType]
|
|
ld b, a
|
|
ld hl, TypeMatchups
|
|
|
|
.TypesLoop:
|
|
ld a, [hli]
|
|
cp -1
|
|
jr z, .end
|
|
|
|
; foresight
|
|
cp -2
|
|
jr nz, .SkipForesightCheck
|
|
|
|
push hl
|
|
ld hl, wEnemySubStatus1
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .foresight_check
|
|
ld hl, wPlayerSubStatus1
|
|
|
|
.foresight_check:
|
|
bit SUBSTATUS_IDENTIFIED, [hl]
|
|
pop hl
|
|
jr nz, .end
|
|
jr .TypesLoop
|
|
|
|
.SkipForesightCheck:
|
|
cp b
|
|
jr nz, .SkipType
|
|
ld a, [hl]
|
|
cp d
|
|
jr z, .GotMatchup
|
|
cp e
|
|
jr z, .GotMatchup
|
|
jr .SkipType
|
|
|
|
.GotMatchup:
|
|
push hl
|
|
push bc
|
|
inc hl
|
|
ld a, [wTypeModifier]
|
|
and STAB_DAMAGE
|
|
ld b, a
|
|
ld a, [hl]
|
|
and a
|
|
jr nz, .NotImmune
|
|
inc a
|
|
ld [wAttackMissed], a
|
|
xor a
|
|
|
|
.NotImmune:
|
|
ldh [hMultiplier], a
|
|
add b
|
|
ld [wTypeModifier], a
|
|
|
|
xor a
|
|
ldh [hMultiplicand], a
|
|
|
|
ld hl, wCurDamage
|
|
ld a, [hli]
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, [hld]
|
|
ldh [hMultiplicand + 2], a
|
|
|
|
call Multiply
|
|
|
|
ld a, 10
|
|
ldh [hDivisor], a
|
|
ld b, 4
|
|
|
|
call Divide
|
|
|
|
ldh a, [hQuotient + 2]
|
|
ld [hli], a
|
|
ldh a, [hQuotient + 3]
|
|
ld [hl], a
|
|
pop bc
|
|
pop hl
|
|
|
|
.SkipType:
|
|
inc hl
|
|
inc hl
|
|
jp .TypesLoop
|
|
|
|
.end:
|
|
call BattleCheckTypeMatchup
|
|
ld a, [wNumSetBits]
|
|
ld b, a
|
|
ld a, [wTypeModifier]
|
|
and STAB_DAMAGE
|
|
or b
|
|
ld [wTypeModifier], a
|
|
ret
|
|
|
|
DoWeatherModifiers:
|
|
push hl
|
|
push de
|
|
push bc
|
|
ld hl, WeatherTypeModifiers
|
|
ld a, [wBattleWeather]
|
|
ld b, a
|
|
ld a, [wCurType]
|
|
ld c, a
|
|
|
|
.CheckWeatherType:
|
|
ld a, [hli]
|
|
cp -1
|
|
jr z, .done
|
|
|
|
cp b
|
|
jr nz, .NextWeatherType
|
|
ld a, [hl]
|
|
cp c
|
|
jr z, .ApplyModifier
|
|
|
|
.NextWeatherType:
|
|
inc hl
|
|
inc hl
|
|
jr .CheckWeatherType
|
|
|
|
.ApplyModifier:
|
|
xor a
|
|
ldh [hMultiplicand], a
|
|
ld a, [wCurDamage]
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, [wCurDamage + 1]
|
|
ldh [hMultiplicand + 2], a
|
|
|
|
inc hl
|
|
ld a, [hl]
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
|
|
ld a, 10
|
|
ldh [hDivisor], a
|
|
ld b, 4
|
|
call Divide
|
|
|
|
ldh a, [hQuotient + 1]
|
|
and a
|
|
ld bc, $ffff
|
|
jr nz, .Update
|
|
|
|
ldh a, [hQuotient + 2]
|
|
ld b, a
|
|
ldh a, [hQuotient + 3]
|
|
ld c, a
|
|
or b
|
|
jr nz, .Update
|
|
|
|
ld bc, 1
|
|
|
|
.Update:
|
|
ld a, b
|
|
ld [wCurDamage], a
|
|
ld a, c
|
|
ld [wCurDamage + 1], a
|
|
|
|
.done:
|
|
pop bc
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
WeatherTypeModifiers:
|
|
db WEATHER_RAIN, TYPE_WATER, SUPER_EFFECTIVE
|
|
db WEATHER_RAIN, TYPE_FIRE, NOT_VERY_EFFECTIVE
|
|
db WEATHER_SUN, TYPE_FIRE, SUPER_EFFECTIVE
|
|
db WEATHER_SUN, TYPE_WATER, NOT_VERY_EFFECTIVE
|
|
db -1 ; end
|
|
|
|
BattleCheckTypeMatchup:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
|
|
ld hl, wEnemyMonType
|
|
ld a, [wPlayerMoveStructType]
|
|
jr z, CheckTypeMatchup
|
|
|
|
ld hl, wBattleMonType
|
|
ld a, [wEnemyMoveStructType]
|
|
|
|
CheckTypeMatchup:
|
|
ld d, a
|
|
ld b, [hl]
|
|
inc hl
|
|
ld c, [hl]
|
|
ld a, EFFECTIVE
|
|
ld [wTypeMatchup], a
|
|
ld hl, TypeMatchups
|
|
.TypesLoop:
|
|
ld a, [hli]
|
|
cp -1
|
|
jr z, .End
|
|
cp -2
|
|
jr nz, .Next
|
|
push hl
|
|
ld hl, wEnemySubStatus1
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .do_foresight_check
|
|
ld hl, wPlayerSubStatus1
|
|
|
|
.do_foresight_check:
|
|
bit SUBSTATUS_IDENTIFIED, [hl]
|
|
pop hl
|
|
jr nz, .End
|
|
jr .TypesLoop
|
|
|
|
.Next:
|
|
cp d
|
|
jr nz, .Nope
|
|
ld a, [hli]
|
|
cp b
|
|
jr z, .Yup
|
|
cp c
|
|
jr z, .Yup
|
|
jr .Nope2
|
|
|
|
.Nope:
|
|
inc hl
|
|
.Nope2:
|
|
inc hl
|
|
jr .TypesLoop
|
|
|
|
.Yup:
|
|
xor a
|
|
ldh [hProduct], a
|
|
ldh [hMultiplicand], a
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, [hli]
|
|
ldh [hMultiplicand + 2], a
|
|
ld a, [wTypeMatchup]
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
ld a, 10
|
|
ldh [hDivisor], a
|
|
push bc
|
|
ld b, 4
|
|
call Divide
|
|
pop bc
|
|
ldh a, [hQuotient + 3]
|
|
ld [wTypeMatchup], a
|
|
jr .TypesLoop
|
|
|
|
.End:
|
|
ret
|
|
|
|
INCLUDE "data/types/type_matchups.asm"
|
|
|
|
BattleCommand_DamageVariation:
|
|
; Modify the damage spread between 85% and 100%.
|
|
|
|
; Because of the method of division the probability distribution
|
|
; is not consistent. This makes the highest damage multipliers
|
|
; rarer than normal.
|
|
|
|
; No point in reducing 1 or 0 damage.
|
|
ld hl, wCurDamage
|
|
ld a, [hli]
|
|
and a
|
|
jr nz, .go
|
|
ld a, [hl]
|
|
cp 2
|
|
ret c
|
|
|
|
.go:
|
|
; Start with the maximum damage.
|
|
xor a
|
|
ldh [hMultiplicand], a
|
|
dec hl
|
|
ld a, [hli]
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, [hl]
|
|
ldh [hMultiplicand + 2], a
|
|
|
|
; Multiply by 85-100%...
|
|
.loop:
|
|
call BattleRandom
|
|
rrca
|
|
cp $d9
|
|
jr c, .loop
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
|
|
; ...divide by 100%...
|
|
ld a, 100 percent
|
|
ldh [hDivisor], a
|
|
ld b, 4
|
|
call Divide
|
|
|
|
; ...to get .85-1.00x damage.
|
|
ldh a, [hQuotient + 2]
|
|
ld hl, wCurDamage
|
|
ld [hli], a
|
|
ldh a, [hQuotient + 3]
|
|
ld [hl], a
|
|
ret
|
|
|
|
BattleCommand_CheckHit:
|
|
ld hl, wEnemySubStatus1
|
|
ld de, wPlayerMoveStructEffect
|
|
ld bc, wEnemyMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .DreamEater
|
|
ld hl, wPlayerSubStatus1
|
|
ld de, wEnemyMoveStructEffect
|
|
ld bc, wBattleMonStatus
|
|
|
|
.DreamEater:
|
|
; Return z if we're trying to eat the dream of
|
|
; a monster that isn't sleeping.
|
|
ld a, [de]
|
|
cp EFFECT_DREAM_EATER
|
|
jr nz, .Protect
|
|
ld a, [bc]
|
|
and SLP
|
|
jp z, .Miss
|
|
|
|
.Protect:
|
|
bit SUBSTATUS_PROTECT, [hl]
|
|
jp nz, .Miss
|
|
ld a, [de]
|
|
cp EFFECT_SWIFT
|
|
ret z
|
|
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
bit SUBSTATUS_LOCK_ON, [hl]
|
|
res SUBSTATUS_LOCK_ON, [hl]
|
|
ret nz
|
|
|
|
; Bug: Supposed to return z if using an HP drain move on a substitute.
|
|
; Register a is expected to contain the move struct effect.
|
|
; However, it is overwritten to either 0 or 1 by calling CheckSubstituteOpp.
|
|
call CheckSubstituteOpp
|
|
|
|
jr z, .FlyDigMoves
|
|
cp EFFECT_LEECH_HIT
|
|
jp z, .Miss
|
|
cp EFFECT_DREAM_EATER
|
|
jp z, .Miss
|
|
|
|
.FlyDigMoves:
|
|
; Check for moves that can hit underground/flying opponents.
|
|
; Return z if the current move can hit the opponent.
|
|
dec hl
|
|
dec hl
|
|
bit SUBSTATUS_INVULNERABLE, [hl]
|
|
jp z, .EnemyMonMist
|
|
|
|
ld hl, wLastEnemyCounterMove
|
|
ld de, wPlayerMoveStruct
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .fly_moves
|
|
ld hl, wLastPlayerCounterMove
|
|
ld de, wEnemyMoveStruct
|
|
|
|
.fly_moves:
|
|
ld a, [hl]
|
|
cp MOVE_FLY
|
|
jr nz, .dig_moves
|
|
|
|
; Final game adds Gust to this list
|
|
ld a, [de]
|
|
cp MOVE_WHIRLWIND
|
|
jr z, .EnemyMonMist
|
|
cp MOVE_THUNDER
|
|
jr z, .EnemyMonMist
|
|
jp .Miss
|
|
|
|
.dig_moves:
|
|
cp MOVE_DIG
|
|
jp nz, .Miss
|
|
|
|
; Final game adds Magnitude to this list
|
|
ld a, [de]
|
|
cp MOVE_EARTHQUAKE
|
|
jr z, .EnemyMonMist
|
|
cp MOVE_FISSURE
|
|
jr z, .EnemyMonMist
|
|
jp .Miss
|
|
|
|
.EnemyMonMist:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr nz, .PlayerMonMist
|
|
ld a, [wPlayerMoveStructEffect]
|
|
cp EFFECT_ATTACK_DOWN
|
|
jr c, .skip_enemy_mist_check
|
|
cp EFFECT_RESET_STATS + 1
|
|
jr c, .enemy_mist_check
|
|
cp EFFECT_ATTACK_DOWN_2
|
|
jr c, .skip_enemy_mist_check
|
|
cp EFFECT_REFLECT + 1
|
|
jr c, .enemy_mist_check
|
|
jr .skip_enemy_mist_check
|
|
|
|
.enemy_mist_check:
|
|
ld a, [wEnemySubStatus4]
|
|
bit SUBSTATUS_MIST, a
|
|
jp nz, .Miss
|
|
|
|
.skip_enemy_mist_check:
|
|
ld a, [wPlayerSubStatus4]
|
|
bit SUBSTATUS_X_ACCURACY, a
|
|
ret nz
|
|
jr .calc_hit_chance
|
|
|
|
.PlayerMonMist:
|
|
ld a, [wEnemyMoveStructEffect]
|
|
cp EFFECT_ATTACK_DOWN
|
|
jr c, .skip_player_mist_check
|
|
cp EFFECT_RESET_STATS + 1
|
|
jr c, .player_mist_check
|
|
cp EFFECT_ATTACK_DOWN_2
|
|
jr c, .skip_player_mist_check
|
|
cp EFFECT_REFLECT + 1
|
|
jr c, .player_mist_check
|
|
jr .skip_player_mist_check
|
|
|
|
.player_mist_check:
|
|
ld a, [wPlayerSubStatus4]
|
|
bit SUBSTATUS_MIST, a
|
|
jp nz, .Miss
|
|
|
|
.skip_player_mist_check:
|
|
ld a, [wEnemySubStatus4]
|
|
bit SUBSTATUS_X_ACCURACY, a
|
|
ret nz
|
|
|
|
.calc_hit_chance:
|
|
call .StatModifiers
|
|
ld a, [wPlayerMoveStructAccuracy]
|
|
ld b, a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .StrangeThread
|
|
ld a, [wEnemyMoveStructAccuracy]
|
|
ld b, a
|
|
|
|
.StrangeThread:
|
|
push bc
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_STRANGE_THREAD
|
|
ld a, c
|
|
pop bc
|
|
jr nz, .skip_strange_thread
|
|
|
|
ld c, a
|
|
ld a, b
|
|
sub c
|
|
ld b, a
|
|
jr nc, .skip_strange_thread
|
|
ld b, 0
|
|
|
|
.skip_strange_thread:
|
|
call BattleRandom
|
|
cp b
|
|
jr nc, .Miss
|
|
ret
|
|
|
|
.Miss:
|
|
xor a
|
|
ld hl, wCurDamage
|
|
ld [hli], a
|
|
ld [hl], a
|
|
inc a
|
|
ld [wAttackMissed], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .player_wrapping
|
|
ld hl, wEnemySubStatus3
|
|
res SUBSTATUS_USING_TRAPPING_MOVE, [hl]
|
|
ret
|
|
|
|
.player_wrapping:
|
|
ld hl, wPlayerSubStatus3
|
|
res SUBSTATUS_USING_TRAPPING_MOVE, [hl]
|
|
ret
|
|
|
|
.StatModifiers:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
|
|
ld hl, wPlayerMoveStructAccuracy
|
|
ld a, [wPlayerAccLevel]
|
|
ld b, a
|
|
ld a, [wEnemyEvaLevel]
|
|
ld c, a
|
|
jr z, .got_acc_eva
|
|
|
|
ld hl, wEnemyMoveStructAccuracy
|
|
ld a, [wEnemyAccLevel]
|
|
ld b, a
|
|
ld a, [wPlayerEvaLevel]
|
|
ld c, a
|
|
|
|
.got_acc_eva:
|
|
; c = 14 - Evasion Level
|
|
ld a, $e
|
|
sub c
|
|
ld c, a
|
|
|
|
xor a
|
|
ldh [hMultiplicand], a
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, [hl]
|
|
ldh [hMultiplicand + 2], a
|
|
push hl
|
|
ld d, 2
|
|
|
|
.accuracy_loop:
|
|
; look up the multiplier from the table
|
|
push bc
|
|
ld hl, AccuracyLevelMultipliers
|
|
dec b
|
|
sla b
|
|
ld c, b
|
|
ld b, 0
|
|
add hl, bc
|
|
pop bc
|
|
; multiply by the first byte in that row...
|
|
ld a, [hli]
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
; ... and divide by the second byte
|
|
ld a, [hl]
|
|
ldh [hPrintNumDivisor], a
|
|
ld b, 4
|
|
call Divide
|
|
; minimum accuracy is 1 (nonzero)
|
|
ldh a, [hQuotient + 3]
|
|
ld b, a
|
|
ldh a, [hQuotient + 2]
|
|
or b
|
|
jp nz, .min_accuracy
|
|
|
|
ldh [hQuotient + 2], a
|
|
ld a, 1
|
|
ldh [hQuotient + 3], a
|
|
|
|
.min_accuracy:
|
|
; do the same thing to the target's evasion
|
|
ld b, c
|
|
dec d
|
|
jr nz, .accuracy_loop
|
|
|
|
; if the result is more than 2 bytes, max out at 100%
|
|
ldh a, [hQuotient + 2]
|
|
and a
|
|
ldh a, [hQuotient + 3]
|
|
jr z, .finish_accuracy
|
|
ld a, $ff
|
|
|
|
.finish_accuracy:
|
|
pop hl
|
|
ld [hl], a
|
|
ret
|
|
|
|
; Identical to StatLevelMultipliers.
|
|
; Given this is a separate table (unlike RBY), seems like they were already in the process of being split.
|
|
AccuracyLevelMultipliers:
|
|
INCLUDE "data/battle/stat_multipliers.asm"
|
|
|
|
BattleCommand_EffectChance:
|
|
; final game clears out wEffectFailed here
|
|
call CheckSubstituteOpp
|
|
jr nz, .failed
|
|
push hl
|
|
ld hl, wPlayerMoveStructEffectChance
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_move_chance
|
|
ld hl, wEnemyMoveStructEffectChance
|
|
|
|
.got_move_chance
|
|
call BattleRandom
|
|
cp [hl]
|
|
pop hl
|
|
ret
|
|
|
|
.failed:
|
|
and a
|
|
ret
|
|
|
|
BattleCommand_LowerSub:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerSubStatus4]
|
|
jr z, .go
|
|
ld a, [wEnemySubStatus4]
|
|
|
|
.go:
|
|
bit SUBSTATUS_SUBSTITUTE, a
|
|
ret z
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld [wFXAnimID + 1], a
|
|
inc a
|
|
ld [wBattleAnimParam], a
|
|
ld a, MOVE_SUBSTITUTE
|
|
jp LoadBattleAnim
|
|
|
|
BattleCommand_MoveAnim:
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
jp nz, BattleCommand_MoveDelay
|
|
|
|
assert BATTLEANIM_NONE + 1 == BATTLEANIM_DAMAGE
|
|
inc a
|
|
ld [wNumHits], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStruct]
|
|
ld c, a
|
|
ld de, wPlayerRolloutCount
|
|
ld a, [wPlayerMoveStructEffect]
|
|
jr z, .got_rollout_count
|
|
|
|
ld a, [wEnemyMoveStruct]
|
|
ld c, a
|
|
ld de, wEnemyRolloutCount
|
|
ld a, [wEnemyMoveStructEffect]
|
|
|
|
.got_rollout_count:
|
|
cp EFFECT_MULTI_HIT
|
|
jr z, .alternate_anim
|
|
cp EFFECT_CONVERSION
|
|
jr z, .alternate_anim
|
|
cp EFFECT_DOUBLE_HIT
|
|
jr z, .alternate_anim
|
|
cp EFFECT_POISON_MULTI_HIT
|
|
jr z, .alternate_anim
|
|
cp EFFECT_TRIPLE_KICK
|
|
jr z, .triplekick
|
|
xor a
|
|
ld [wBattleAnimParam], a
|
|
|
|
.triplekick:
|
|
ld e, c
|
|
ld d, 0
|
|
jp PlayFXAnimID
|
|
|
|
.alternate_anim:
|
|
ld a, [wBattleAnimParam]
|
|
and 1
|
|
xor 1
|
|
ld [wBattleAnimParam], a
|
|
ld a, [de]
|
|
cp 1
|
|
ld e, c
|
|
ld d, 0
|
|
jp z, PlayFXAnimID
|
|
xor a
|
|
ld [wNumHits], a
|
|
jp PlayFXAnimID
|
|
|
|
BattleCommand_RaiseSub:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerSubStatus4]
|
|
jr z, .got_substatus
|
|
ld a, [wEnemySubStatus4]
|
|
|
|
.got_substatus:
|
|
bit SUBSTATUS_SUBSTITUTE, a
|
|
ret z
|
|
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld [wFXAnimID + 1], a
|
|
ld a, 2
|
|
ld [wBattleAnimParam], a
|
|
ld a, MOVE_SUBSTITUTE
|
|
jp LoadBattleAnim
|
|
|
|
BattleCommand_FailureText:
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
ret z
|
|
call GetFailureResultText
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStruct]
|
|
ld hl, wPlayerSubStatus3
|
|
jr z, .check_fly_dig
|
|
|
|
ld a, [wEnemyMoveStruct]
|
|
ld hl, wEnemySubStatus3
|
|
|
|
.check_fly_dig:
|
|
cp MOVE_FLY
|
|
jr z, .fly_dig
|
|
cp MOVE_DIG
|
|
jr z, .fly_dig
|
|
jp EndMoveEffect
|
|
|
|
.fly_dig:
|
|
res SUBSTATUS_INVULNERABLE, [hl]
|
|
ld a, 2
|
|
ld [wBattleAnimParam], a
|
|
call LoadMoveAnim
|
|
jp EndMoveEffect
|
|
|
|
BattleCommand_ApplyDamage:
|
|
ld hl, wEnemySubStatus1
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_substatus_1
|
|
ld hl, wPlayerSubStatus1
|
|
|
|
.got_substatus_1:
|
|
bit SUBSTATUS_ENDURE, [hl]
|
|
jr z, .focus_orb
|
|
call BattleCommand_FalseSwipe
|
|
ld b, 0
|
|
jr nc, .damage
|
|
ld b, 1
|
|
jr .damage
|
|
|
|
.focus_orb:
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_FOCUS_ORB
|
|
ld b, 0
|
|
jr nz, .damage
|
|
|
|
call BattleRandom
|
|
cp c
|
|
jr nc, .damage
|
|
call BattleCommand_FalseSwipe
|
|
ld b, 0
|
|
jr nc, .damage
|
|
ld b, 2
|
|
|
|
.damage:
|
|
push bc
|
|
call .update_damage_taken
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr nz, .damage_player
|
|
call DoEnemyDamage
|
|
jr .done_damage
|
|
|
|
.damage_player:
|
|
call DoPlayerDamage
|
|
|
|
.done_damage:
|
|
pop bc
|
|
ld a, b
|
|
and a
|
|
ret z
|
|
|
|
dec a
|
|
jr nz, .focus_orb_text
|
|
ld hl, EnduredText
|
|
jp PrintText
|
|
|
|
.focus_orb_text:
|
|
call GetOpponentItem
|
|
ld a, [hl]
|
|
ld [wNumSetBits], a
|
|
call GetItemName
|
|
ld hl, HungOnText
|
|
jp PrintText
|
|
|
|
.update_damage_taken:
|
|
ld de, wPlayerDamageTaken + 1
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr nz, .got_damage_taken
|
|
ld de, wEnemyDamageTaken + 1
|
|
|
|
.got_damage_taken:
|
|
ld a, [wCurDamage + 1]
|
|
ld b, a
|
|
ld a, [de]
|
|
add b
|
|
ld [de], a
|
|
dec de
|
|
ld a, [wCurDamage]
|
|
ld b, a
|
|
ld a, [de]
|
|
adc b
|
|
ld [de], a
|
|
ret nc
|
|
ld a, $ff
|
|
ld [de], a
|
|
inc de
|
|
ld [de], a
|
|
ret
|
|
|
|
INCLUDE "engine/battle/move_effects/gen1_heal.asm"
|
|
|
|
GetFailureResultText:
|
|
ld de, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .go
|
|
ld de, wEnemyMoveStructEffect
|
|
|
|
.go:
|
|
ld hl, DoesntAffectText
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
jr z, .got_text
|
|
ld hl, AttackMissedText
|
|
ld a, [wCriticalHit]
|
|
cp -1
|
|
jr nz, .got_text
|
|
ld hl, UnaffectedText
|
|
|
|
.got_text:
|
|
push de
|
|
call PrintText
|
|
xor a
|
|
ld [wCriticalHit], a
|
|
|
|
; Take 1/4 of wCurDamage if using Jump Kick/High Jump Kick
|
|
pop de
|
|
ld a, [de]
|
|
cp EFFECT_JUMP_KICK
|
|
ret nz
|
|
ld hl, wCurDamage
|
|
ld a, [hli]
|
|
ld b, [hl]
|
|
rept 3
|
|
srl a
|
|
rr b
|
|
endr
|
|
ld [hl], b
|
|
dec hl
|
|
ld [hli], a
|
|
or b
|
|
jr nz, .do_at_least_one_damage
|
|
inc a
|
|
ld [hl], a
|
|
|
|
.do_at_least_one_damage:
|
|
ld hl, CrashedText
|
|
call PrintText
|
|
ld a, 1
|
|
ld [wBattleAnimParam], a
|
|
call LoadMoveAnim
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp nz, DoEnemyDamage
|
|
jp DoPlayerDamage
|
|
|
|
AttackMissedText:
|
|
text "しかし <USER>の"
|
|
line "こうげきは はずれた!"
|
|
prompt
|
|
|
|
CrashedText:
|
|
text "いきおい あまって"
|
|
line "<USER>は"
|
|
cont "じめんに ぶつかった!"
|
|
prompt
|
|
|
|
UnaffectedText:
|
|
text "<TARGET>には"
|
|
line "ぜんぜんきいてない!"
|
|
prompt
|
|
|
|
PrintDoesntAffect:
|
|
ld hl, DoesntAffectText
|
|
jp PrintText
|
|
|
|
DoesntAffectText:
|
|
text "<TARGET>には"
|
|
line "こうかが ない みたいだ<⋯⋯>"
|
|
prompt
|
|
|
|
; Prints the message for critical hits or one-hit KOs.
|
|
|
|
; If there is no message to be printed, wait 20 frames.
|
|
BattleCommand_CriticalText:
|
|
ld a, [wCriticalHit]
|
|
and a
|
|
jr z, .wait
|
|
|
|
dec a
|
|
add a
|
|
ld hl, .texts
|
|
ld b, 0
|
|
ld c, a
|
|
add hl, bc
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
call PrintText
|
|
|
|
xor a
|
|
ld [wCriticalHit], a
|
|
|
|
.wait:
|
|
ld c, 20
|
|
jp DelayFrames
|
|
|
|
.texts:
|
|
dw CriticalHitText
|
|
dw OneHitKOText
|
|
|
|
CriticalHitText:
|
|
text "きゅうしょに あたった!"
|
|
prompt
|
|
|
|
OneHitKOText:
|
|
text "いちげき ひっさつ!"
|
|
prompt
|
|
|
|
BattleCommand_SuperEffectiveText:
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
ret z
|
|
ld hl, SuperEffectiveText
|
|
jr nc, .print
|
|
ld hl, NotVeryEffectiveText
|
|
.print:
|
|
jp PrintText
|
|
|
|
SuperEffectiveText:
|
|
text "こうかは ばつぐんだ!"
|
|
prompt
|
|
|
|
NotVeryEffectiveText:
|
|
text "こうかは いまひとつの ようだ"
|
|
prompt
|
|
|
|
BattleCommand_CheckFaint:
|
|
ld hl, wEnemyMonHP
|
|
ld de, wEnemySubStatus5
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_hp
|
|
ld hl, wBattleMonHP
|
|
ld de, wPlayerSubStatus5
|
|
|
|
.got_hp:
|
|
ld a, [hli]
|
|
or [hl]
|
|
ret nz
|
|
|
|
ld a, [de]
|
|
bit SUBSTATUS_DESTINY_BOND, a
|
|
jr z, .no_dbond
|
|
|
|
ld hl, TookDownWithItText
|
|
call PrintText
|
|
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld hl, wEnemyMonMaxHP + 1
|
|
bccoord 2, 2
|
|
ld a, 0
|
|
jr nz, .got_max_hp
|
|
ld hl, wBattleMonMaxHP + 1
|
|
bccoord 10, 9
|
|
ld a, 1
|
|
|
|
.got_max_hp:
|
|
ld [wWhichHPBar], a
|
|
ld a, [hld]
|
|
ld [wHPBarMaxHP], a
|
|
ld a, [hld]
|
|
ld [wHPBarMaxHP + 1], a
|
|
; Back up current HP and set it to 0
|
|
ld a, [hl]
|
|
ld [wHPBarOldHP], a
|
|
xor a
|
|
ld [hld], a
|
|
ld a, [hl]
|
|
ld [wHPBarOldHP + 1], a
|
|
xor a
|
|
ld [hl], a
|
|
|
|
ld [wHPBarNewHP], a
|
|
ld [wHPBarNewHP + 1], a
|
|
ld h, b
|
|
ld l, c
|
|
predef UpdateHPBar
|
|
|
|
ldh a, [hBattleTurn]
|
|
push af
|
|
xor 1
|
|
ldh [hBattleTurn], a
|
|
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld [wFXAnimID + 1], a
|
|
inc a
|
|
ld [wBattleAnimParam], a
|
|
ld a, MOVE_DESTINY_BOND
|
|
call LoadBattleAnim
|
|
pop af
|
|
ldh [hBattleTurn], a
|
|
|
|
.no_dbond:
|
|
jp EndMoveEffect
|
|
|
|
TookDownWithItText:
|
|
text "<TARGET>は <USER>を"
|
|
line "みちずれに した!"
|
|
prompt
|
|
|
|
; Used to handle hitting the opponent when they have SUBSTATUS_RAGE.
|
|
; However, Rage itself doesn't actually initiate the effect in this build, so this interaction is unseen.
|
|
BattleCommand_BuildOpponentRage:
|
|
; This jump really wasn't necessary.
|
|
jp .start
|
|
|
|
.start:
|
|
ld hl, wEnemySubStatus4
|
|
ld de, wEnemyAtkLevel
|
|
ld bc, wEnemyMoveStruct
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .player
|
|
ld hl, wPlayerSubStatus4
|
|
ld de, wPlayerAtkLevel
|
|
ld bc, wPlayerMoveStruct
|
|
|
|
.player:
|
|
bit SUBSTATUS_RAGE, [hl]
|
|
ret z
|
|
|
|
ld a, [de]
|
|
cp $d
|
|
ret z
|
|
|
|
ldh a, [hBattleTurn]
|
|
xor 1
|
|
ldh [hBattleTurn], a
|
|
; Temporarily replaces target's current move with NULL that raises attack.
|
|
ld h, b
|
|
ld l, c
|
|
ld [hl], 0
|
|
inc hl
|
|
ld [hl], EFFECT_ATTACK_UP
|
|
push hl
|
|
ld hl, RageBuildingText
|
|
call PrintText
|
|
; This is where the line that actually raises the target's attack stat WAS... in Gen I.
|
|
; In this prototype, the stat-raising call is strangely absent, meaning the prior setup was all for nothing!
|
|
|
|
; This also means the "rage building" effect is purely visual in this build and doesn't indicate anything.
|
|
|
|
pop hl
|
|
xor a
|
|
ld [hld], a
|
|
ld a, MOVE_RAGE
|
|
ld [hl], a
|
|
|
|
ldh a, [hBattleTurn]
|
|
xor 1
|
|
ldh [hBattleTurn], a
|
|
ret
|
|
|
|
RageBuildingText:
|
|
text "<USER>の いかりの"
|
|
line "ボルテージが あがっていく!"
|
|
prompt
|
|
|
|
EndMoveEffect:
|
|
ld a, [wBattleScriptBufferAddress]
|
|
ld l, a
|
|
ld a, [wBattleScriptBufferAddress + 1]
|
|
ld h, a
|
|
ld a, endmove_command
|
|
ld [hli], a
|
|
ld [hli], a
|
|
ld [hl], a
|
|
ret
|
|
|
|
PlayerAttackDamage:
|
|
xor a
|
|
ld hl, wCurDamage
|
|
ld [hli], a
|
|
ld [hl], a
|
|
|
|
ld hl, wPlayerMoveStructPower
|
|
ld a, [hli]
|
|
and a
|
|
ld d, a
|
|
ret z
|
|
|
|
ld a, [hl]
|
|
cp SPECIAL_TYPES
|
|
jr nc, .special
|
|
|
|
; physical
|
|
ld hl, wEnemyMonDefense
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
ld a, [wEnemySubStatus5]
|
|
bit 2, a
|
|
jr z, .physicalcrit
|
|
|
|
sla c
|
|
rl b
|
|
|
|
.physicalcrit:
|
|
ld hl, wBattleMonAttack
|
|
ld a, [wCriticalHit]
|
|
and a
|
|
jr z, .TruncateHL_BC
|
|
|
|
ld c, STAT_DEF
|
|
call GetEnemyMonStat
|
|
|
|
ldh a, [hQuotient + 2]
|
|
ld b, a
|
|
ldh a, [hQuotient + 3]
|
|
ld c, a
|
|
push bc
|
|
ld hl, wPartyMon1Attack
|
|
ld a, [wCurBattleMon]
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
pop bc
|
|
jr .TruncateHL_BC
|
|
|
|
.special:
|
|
ld hl, wEnemyMonSpclDef
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
ld a, [wEnemySubStatus5]
|
|
bit 1, a
|
|
jr z, .specialcrit
|
|
sla c
|
|
rl b
|
|
|
|
.specialcrit:
|
|
ld hl, wBattleMonSpclAtk
|
|
ld a, [wCriticalHit]
|
|
and a
|
|
jr z, .TruncateHL_BC
|
|
|
|
ld c, STAT_SDEF
|
|
call GetEnemyMonStat
|
|
|
|
ldh a, [hQuotient + 2]
|
|
ld b, a
|
|
ldh a, [hQuotient + 3]
|
|
ld c, a
|
|
push bc
|
|
ld hl, wPartyMon1SpclAtk
|
|
ld a, [wCurBattleMon]
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
pop bc
|
|
|
|
.TruncateHL_BC:
|
|
ld a, [hli]
|
|
ld l, [hl]
|
|
ld h, a
|
|
or b
|
|
jr z, .done
|
|
|
|
srl b
|
|
rr c
|
|
srl b
|
|
rr c
|
|
srl h
|
|
rr l
|
|
srl h
|
|
rr l
|
|
|
|
ld a, l
|
|
or h
|
|
jr nz, .done
|
|
|
|
inc l
|
|
|
|
.done:
|
|
ld b, l
|
|
ld a, [wBattleMonLevel]
|
|
ld e, a
|
|
ld a, [wCriticalHit]
|
|
and a
|
|
jr z, .return
|
|
|
|
sla e
|
|
|
|
.return:
|
|
ld a, 1
|
|
and a
|
|
ret
|
|
|
|
EnemyAttackDamage:
|
|
ld hl, wCurDamage
|
|
xor a
|
|
ld [hli], a
|
|
ld [hl], a
|
|
ld hl, wEnemyMoveStructPower
|
|
ld a, [hli]
|
|
ld d, a
|
|
and a
|
|
ret z
|
|
ld a, [hl]
|
|
cp SPECIAL_TYPES
|
|
jr nc, .special
|
|
|
|
ld hl, wBattleMonDefense
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
ld a, [wPlayerSubStatus5]
|
|
bit 2, a
|
|
jr z, .physicalcrit
|
|
sla c
|
|
rl b
|
|
|
|
.physicalcrit:
|
|
ld hl, wEnemyMonAttack
|
|
ld a, [wCriticalHit]
|
|
and a
|
|
jr z, .TruncateHL_BC
|
|
ld hl, wPartyMon1Defense
|
|
ld a, [wCurBattleMon]
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
push bc
|
|
ld c, STAT_ATK
|
|
call GetEnemyMonStat
|
|
ld hl, hQuotient + 2
|
|
pop bc
|
|
jr .TruncateHL_BC
|
|
|
|
.special:
|
|
ld hl, wBattleMonSpclDef
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
ld a, [wPlayerSubStatus5]
|
|
bit 1, a
|
|
jr z, .specialcrit
|
|
sla c
|
|
rl b
|
|
|
|
.specialcrit:
|
|
ld hl, wEnemyMonSpclAtk
|
|
ld a, [wCriticalHit]
|
|
and a
|
|
jr z, .TruncateHL_BC
|
|
ld hl, wPartyMon1SpclDef
|
|
ld a, [wCurBattleMon]
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
push bc
|
|
ld c, STAT_SATK
|
|
call GetEnemyMonStat
|
|
ld hl, hQuotient + 2
|
|
pop bc
|
|
|
|
.TruncateHL_BC:
|
|
ld a, [hli]
|
|
ld l, [hl]
|
|
ld h, a
|
|
or b
|
|
jr z, .done
|
|
|
|
srl b
|
|
rr c
|
|
srl b
|
|
rr c
|
|
srl h
|
|
rr l
|
|
srl h
|
|
rr l
|
|
|
|
ld a, l
|
|
or h
|
|
jr nz, .done
|
|
inc l
|
|
|
|
.done:
|
|
ld b, l
|
|
ld a, [wEnemyMonLevel]
|
|
ld e, a
|
|
ld a, [wCriticalHit]
|
|
and a
|
|
jr z, .return
|
|
|
|
sla e
|
|
|
|
.return:
|
|
ld a, 1
|
|
and a
|
|
and a
|
|
ret
|
|
|
|
HitSelfInConfusion:
|
|
xor a
|
|
ld hl, wCurDamage
|
|
ld [hli], a
|
|
ld [hl], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld hl, wBattleMonDefense
|
|
ld de, wPlayerSubStatus5
|
|
ld a, [wBattleMonLevel]
|
|
jr z, .got_it
|
|
|
|
ld hl, wEnemyMonDefense
|
|
ld de, wEnemySubStatus5
|
|
ld a, [wEnemyMonLevel]
|
|
|
|
.got_it
|
|
push af
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld c, [hl]
|
|
ld a, [de]
|
|
bit SUBSTATUS_REFLECT, a
|
|
jr z, .mimic_screen
|
|
sla c
|
|
rl b
|
|
|
|
.mimic_screen
|
|
dec hl
|
|
dec hl
|
|
dec hl
|
|
ld a, [hli]
|
|
ld l, [hl]
|
|
ld h, a
|
|
|
|
or b
|
|
jr z, .done
|
|
srl b
|
|
rr c
|
|
srl b
|
|
rr c
|
|
srl h
|
|
rr l
|
|
srl h
|
|
rr l
|
|
ld a, l
|
|
or h
|
|
jr nz, .done
|
|
inc l
|
|
|
|
.done:
|
|
ld b, l
|
|
ld d, 40
|
|
pop af
|
|
ld e, a
|
|
ret
|
|
|
|
GetEnemyMonStat:
|
|
push de
|
|
push bc
|
|
ld a, [wLinkMode]
|
|
cp LINK_COLOSSEUM
|
|
jr nz, .notLinkBattle
|
|
|
|
ld hl, wOTPartyMon1MaxHP
|
|
dec c
|
|
sla c
|
|
ld b, 0
|
|
add hl, bc
|
|
ld a, [wCurOTMon]
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
|
|
ld a, [hli]
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, [hl]
|
|
ldh [hMultiplicand + 2], a
|
|
pop bc
|
|
pop de
|
|
ret
|
|
|
|
.notLinkBattle:
|
|
ld a, [wEnemyMonLevel]
|
|
ld [wCurPartyLevel], a
|
|
ld a, [wEnemyMonSpecies]
|
|
ld [wCurSpecies], a
|
|
call GetBaseData
|
|
ld hl, wEnemyMonDVs
|
|
ld de, wTempMonDVs
|
|
ld a, [hli]
|
|
ld [de], a
|
|
inc de
|
|
ld a, [hl]
|
|
ld [de], a
|
|
pop bc
|
|
ld b, 0
|
|
ld hl, wTempMonSpcExp - $9
|
|
predef CalcMonStatC
|
|
pop de
|
|
ret
|
|
|
|
; Return a damage value for move power d, player level e, enemy defense c and player attack b.
|
|
; Return 1 if successful, else 0.
|
|
BattleCommand_DamageCalc:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStructEffect]
|
|
jr z, .player
|
|
ld a, [wEnemyMoveStructEffect]
|
|
|
|
.player:
|
|
; Selfdestruct and Explosion halve defense.
|
|
cp EFFECT_SELFDESTRUCT
|
|
jr nz, .dont_selfdestruct
|
|
srl c
|
|
jr nz, .dont_selfdestruct
|
|
inc c
|
|
|
|
.dont_selfdestruct:
|
|
; Variable-hit moves and Conversion can have a power of 0.
|
|
cp EFFECT_MULTI_HIT
|
|
jr z, .skip_zero_damage_check
|
|
cp $1e
|
|
jr z, .skip_zero_damage_check
|
|
|
|
; No damage if move power is 0.
|
|
ld a, d
|
|
and a
|
|
ret z
|
|
|
|
.skip_zero_damage_check:
|
|
; No checks for a defense value of 0, unlike in the final game.
|
|
xor a
|
|
ld hl, hDividend
|
|
ld [hli], a
|
|
ld [hli], a
|
|
ld [hl], a
|
|
|
|
; Level * 2
|
|
ld a, e
|
|
add a
|
|
jr nc, .level_not_overflowing
|
|
push af
|
|
ld a, 1
|
|
ld [hl], a
|
|
pop af
|
|
|
|
.level_not_overflowing:
|
|
inc hl
|
|
ld [hli], a
|
|
|
|
; / 5
|
|
ld a, 5
|
|
ld [hld], a
|
|
push bc
|
|
ld b, 4
|
|
call Divide
|
|
pop bc
|
|
|
|
; + 2
|
|
inc [hl]
|
|
inc [hl]
|
|
|
|
; * bp
|
|
inc hl
|
|
ld [hl], d
|
|
call Multiply
|
|
|
|
; * Attack
|
|
ld [hl], b
|
|
call Multiply
|
|
|
|
; / Defense
|
|
ld [hl], c
|
|
ld b, 4
|
|
call Divide
|
|
|
|
; / 50
|
|
ld [hl], 50
|
|
ld b, 4
|
|
call Divide
|
|
|
|
; Item boosts
|
|
call GetUserItem
|
|
ld hl, TypeBoostItems
|
|
|
|
.NextItem:
|
|
ld a, [hli]
|
|
cp -1
|
|
jr z, .DoneItem
|
|
|
|
; Item effect
|
|
cp b
|
|
ld a, [hli]
|
|
jr nz, .NextItem
|
|
|
|
; Type
|
|
ld b, a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStructType]
|
|
jr z, .player_move_type
|
|
ld a, [wEnemyMoveStructType]
|
|
.player_move_type:
|
|
cp b
|
|
jr nz, .DoneItem
|
|
|
|
; * 100 + item effect amount
|
|
ld a, c
|
|
add 100
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
|
|
; / 100
|
|
ld a, 100
|
|
ldh [hDivisor], a
|
|
ld b, 4
|
|
call Divide
|
|
|
|
.DoneItem:
|
|
; Update wCurDamage. Max 999 (capped at 997, then add 2).
|
|
DEF MAX_DAMAGE EQU 999
|
|
DEF MIN_DAMAGE EQU 2
|
|
DEF DAMAGE_CAP EQU MAX_DAMAGE - MIN_DAMAGE
|
|
|
|
ld hl, wCurDamage
|
|
ld b, [hl]
|
|
ldh a, [hQuotient + 3]
|
|
add b
|
|
ldh [hQuotient + 3], a
|
|
jr nc, .dont_cap_1
|
|
|
|
ldh a, [hQuotient + 2]
|
|
inc a
|
|
ldh [hQuotient + 2], a
|
|
and a
|
|
jr z, .Cap
|
|
|
|
.dont_cap_1:
|
|
ldh a, [hQuotient]
|
|
ld b, a
|
|
ldh a, [hQuotient + 1]
|
|
or a
|
|
jr nz, .Cap
|
|
|
|
ldh a, [hQuotient + 2]
|
|
cp HIGH(DAMAGE_CAP + 1)
|
|
jr c, .dont_cap_2
|
|
|
|
cp HIGH(DAMAGE_CAP + 1) + 1
|
|
jr nc, .Cap
|
|
|
|
ldh a, [hQuotient + 3]
|
|
cp LOW(DAMAGE_CAP + 1)
|
|
jr nc, .Cap
|
|
|
|
.dont_cap_2:
|
|
inc hl
|
|
|
|
ldh a, [hQuotient + 3]
|
|
ld b, [hl]
|
|
add b
|
|
ld [hld], a
|
|
|
|
ldh a, [hQuotient + 2]
|
|
ld b, [hl]
|
|
adc b
|
|
ld [hl], a
|
|
jr c, .Cap
|
|
|
|
ld a, [hl]
|
|
cp HIGH(DAMAGE_CAP + 1)
|
|
jr c, .dont_cap_3
|
|
|
|
cp HIGH(DAMAGE_CAP + 1) + 1
|
|
jr nc, .Cap
|
|
|
|
inc hl
|
|
ld a, [hld]
|
|
cp LOW(DAMAGE_CAP + 1)
|
|
jr c, .dont_cap_3
|
|
|
|
.Cap:
|
|
ld a, HIGH(DAMAGE_CAP)
|
|
ld [hli], a
|
|
ld a, LOW(DAMAGE_CAP)
|
|
ld [hld], a
|
|
|
|
.dont_cap_3:
|
|
; Add back MIN_DAMAGE (capping at 999).
|
|
inc hl
|
|
ld a, [hl]
|
|
add MIN_DAMAGE
|
|
ld [hld], a
|
|
jr nc, .dont_floor
|
|
inc [hl]
|
|
.dont_floor:
|
|
|
|
; Returns nz and nc.
|
|
ld a, 1
|
|
and a
|
|
ret
|
|
|
|
Unused_HighCriticalMoves:
|
|
INCLUDE "data/moves/critical_hit_moves.asm"
|
|
|
|
INCLUDE "data/types/type_boost_items.asm"
|
|
|
|
BattleCommand_ConstantDamage:
|
|
ld hl, wBattleMonLevel
|
|
ld de, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_turn
|
|
ld hl, wEnemyMonLevel
|
|
ld de, wEnemyMoveStructEffect
|
|
|
|
.got_turn
|
|
ld a, [de]
|
|
cp EFFECT_LEVEL_DAMAGE
|
|
ld b, [hl]
|
|
ld a, 0
|
|
jr z, .got_power
|
|
|
|
ld a, [de]
|
|
cp EFFECT_PSYWAVE
|
|
jr z, .psywave
|
|
|
|
cp EFFECT_SUPER_FANG
|
|
jr z, .super_fang
|
|
|
|
cp EFFECT_REVERSAL
|
|
jr z, .reversal
|
|
|
|
inc de
|
|
ld a, [de]
|
|
ld b, a
|
|
ld a, 0
|
|
jr .got_power
|
|
|
|
.psywave
|
|
ld a, b
|
|
srl a
|
|
add b
|
|
ld b, a
|
|
.psywave_loop
|
|
call BattleRandom
|
|
and a
|
|
jr z, .psywave_loop
|
|
cp b
|
|
jr nc, .psywave_loop
|
|
ld b, a
|
|
ld a, 0
|
|
jr .got_power
|
|
|
|
.super_fang
|
|
ld hl, wEnemyMonHP
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_hp
|
|
ld hl, wBattleMonHP
|
|
|
|
.got_hp
|
|
ld a, [hli]
|
|
srl a
|
|
ld b, a
|
|
ld a, [hl]
|
|
rr a
|
|
push af
|
|
ld a, b
|
|
pop bc
|
|
and a
|
|
jr nz, .got_power
|
|
|
|
or b
|
|
ld a, 0
|
|
jr nz, .got_power
|
|
ld b, 1
|
|
jr .got_power
|
|
|
|
.got_power
|
|
ld hl, wCurDamage
|
|
ld [hli], a
|
|
ld [hl], b
|
|
ret
|
|
|
|
.reversal
|
|
ld hl, wBattleMonHP
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .reversal_got_hp
|
|
ld hl, wEnemyMonHP
|
|
|
|
.reversal_got_hp
|
|
xor a
|
|
ldh [hDividend], a
|
|
ldh [hMultiplicand], a
|
|
ld a, [hli]
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, [hli]
|
|
ldh [hMultiplicand + 2], a
|
|
ld a, 48
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld a, [hl]
|
|
ldh [hDivisor], a
|
|
ld a, b
|
|
and a
|
|
jr z, .skip_to_divide
|
|
|
|
ldh a, [hDivisor]
|
|
srl b
|
|
rr a
|
|
srl b
|
|
rr a
|
|
ldh [hDivisor], a
|
|
|
|
ldh a, [hProduct + 2]
|
|
ld b, a
|
|
srl b
|
|
ldh a, [hProduct + 3]
|
|
rr a
|
|
srl b
|
|
rr a
|
|
ldh [hDividend + 3], a
|
|
ld a, b
|
|
ldh [hDividend + 2], a
|
|
|
|
.skip_to_divide
|
|
ld b, 4
|
|
call Divide
|
|
ldh a, [hQuotient + 3]
|
|
ld b, a
|
|
ld hl, FlailReversalPower
|
|
|
|
.reversal_loop
|
|
ld a, [hli]
|
|
cp b
|
|
jr nc, .break_loop
|
|
inc hl
|
|
jr .reversal_loop
|
|
|
|
.break_loop
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [hl]
|
|
jr nz, .notPlayersTurn
|
|
ld hl, wPlayerMoveStructPower
|
|
ld [hl], a
|
|
push hl
|
|
call PlayerAttackDamage
|
|
jr .notEnemysTurn
|
|
|
|
.notPlayersTurn
|
|
ld hl, wEnemyMoveStructPower
|
|
ld [hl], a
|
|
push hl
|
|
call EnemyAttackDamage
|
|
|
|
.notEnemysTurn
|
|
call BattleCommand_DamageCalc
|
|
pop hl
|
|
ld [hl], 1
|
|
ret
|
|
|
|
INCLUDE "data/moves/flail_reversal_power.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/counter.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/encore.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/pain_split.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/snore.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/conversion2.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/lock_on.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/sketch.asm"
|
|
|
|
; Thaw the opponent if frozen, and
|
|
; raise the user's Attack one stage.
|
|
BattleCommand_DefrostOpponent:
|
|
call LoadMoveAnim
|
|
ld hl, wPlayerMoveStructEffect
|
|
ld de, wEnemyMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .go
|
|
ld hl, wEnemyMoveStructEffect
|
|
ld de, wBattleMonStatus
|
|
|
|
.go
|
|
push hl
|
|
call Defrost
|
|
pop hl
|
|
|
|
ld a, [hl]
|
|
push hl
|
|
push af
|
|
|
|
ld a, EFFECT_ATTACK_UP
|
|
ld [hl], a
|
|
call BattleCommand_StatUp
|
|
|
|
pop af
|
|
pop hl
|
|
ld [hl], a
|
|
ret
|
|
|
|
INCLUDE "engine/battle/move_effects/sleep_talk.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/destiny_bond.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/spite.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/false_swipe.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/bell_chime.asm"
|
|
|
|
PlayFXAnimID:
|
|
ld a, e
|
|
ld [wFXAnimID], a
|
|
ld a, d
|
|
ld [wFXAnimID + 1], a
|
|
|
|
ld c, 3
|
|
call DelayFrames
|
|
jpfar PlayBattleAnim
|
|
|
|
DoEnemyDamage:
|
|
ld hl, wCurDamage
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld a, [hl]
|
|
or b
|
|
jr z, .did_no_damage
|
|
|
|
ld a, [wEnemySubStatus4]
|
|
bit SUBSTATUS_SUBSTITUTE, a
|
|
jp nz, DoSubstituteDamage
|
|
|
|
ld a, [hld]
|
|
ld b, a
|
|
ld a, [wEnemyMonHP + 1]
|
|
ld [wHPBarOldHP], a
|
|
sub b
|
|
ld [wEnemyMonHP + 1], a
|
|
ld a, [hl]
|
|
ld b, a
|
|
ld a, [wEnemyMonHP]
|
|
ld [wHPBarOldHP + 1], a
|
|
sbc b
|
|
ld [wEnemyMonHP], a
|
|
jr nc, .no_underflow
|
|
|
|
ld a, [wHPBarOldHP + 1]
|
|
ld [hli], a
|
|
ld a, [wHPBarOldHP]
|
|
ld [hl], a
|
|
xor a
|
|
ld hl, wEnemyMonHP
|
|
ld [hli], a
|
|
ld [hl], a
|
|
|
|
.no_underflow:
|
|
ld hl, wEnemyMonMaxHP
|
|
ld a, [hli]
|
|
ld [wHPBarMaxHP + 1], a
|
|
ld a, [hl]
|
|
ld [wHPBarMaxHP], a
|
|
ld hl, wEnemyMonHP
|
|
ld a, [hli]
|
|
ld [wHPBarNewHP + 1], a
|
|
ld a, [hl]
|
|
ld [wHPBarNewHP], a
|
|
|
|
hlcoord 2, 2
|
|
xor a
|
|
ld [wWhichHPBar], a
|
|
predef UpdateHPBar
|
|
.did_no_damage:
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
DoPlayerDamage:
|
|
ld hl, wCurDamage
|
|
ld a, [hli]
|
|
ld b, a
|
|
ld a, [hl]
|
|
or b
|
|
jr z, .did_no_damage
|
|
|
|
ld a, [wPlayerSubStatus4]
|
|
bit SUBSTATUS_SUBSTITUTE, a
|
|
jp nz, DoSubstituteDamage
|
|
|
|
ld a, [hld]
|
|
ld b, a
|
|
ld a, [wBattleMonHP + 1]
|
|
ld [wHPBarOldHP], a
|
|
sub b
|
|
ld [wBattleMonHP + 1], a
|
|
ld [wHPBarNewHP], a
|
|
ld b, [hl]
|
|
ld a, [wBattleMonHP]
|
|
ld [wHPBarOldHP + 1], a
|
|
sbc b
|
|
ld [wBattleMonHP], a
|
|
ld [wHPBarNewHP + 1], a
|
|
jr nc, .no_underflow
|
|
|
|
ld a, [wHPBarOldHP + 1]
|
|
ld [hli], a
|
|
ld a, [wHPBarOldHP]
|
|
ld [hl], a
|
|
xor a
|
|
ld hl, wBattleMonHP
|
|
ld [hli], a
|
|
ld [hl], a
|
|
ld hl, wHPBarNewHP
|
|
ld [hli], a
|
|
ld [hl], a
|
|
|
|
.no_underflow:
|
|
ld hl, wBattleMonMaxHP
|
|
ld a, [hli]
|
|
ld [wHPBarMaxHP + 1], a
|
|
ld a, [hl]
|
|
ld [wHPBarMaxHP], a
|
|
|
|
hlcoord 10, 9
|
|
ld a, 1
|
|
ld [wWhichHPBar], a
|
|
predef UpdateHPBar
|
|
|
|
.did_no_damage:
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
DoSubstituteDamage:
|
|
ld hl, SubTookDamageText
|
|
call PrintText
|
|
ld de, wEnemySubstituteHP
|
|
ld bc, wEnemySubStatus4
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_hp
|
|
ld de, wPlayerSubstituteHP
|
|
ld bc, wPlayerSubStatus4
|
|
|
|
.got_hp:
|
|
ld hl, wCurDamage
|
|
ld a, [hli]
|
|
and a
|
|
jr nz, .broke
|
|
ld a, [de]
|
|
sub [hl]
|
|
ld [de], a
|
|
ret nc
|
|
|
|
.broke:
|
|
ld h, b
|
|
ld l, c
|
|
res SUBSTATUS_SUBSTITUTE, [hl]
|
|
ld hl, SubFadedText
|
|
call PrintText
|
|
|
|
ldh a, [hBattleTurn]
|
|
push af
|
|
xor 1
|
|
ldh [hBattleTurn], a
|
|
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld [wFXAnimID + 1], a
|
|
|
|
ld a, 3
|
|
ld [wBattleAnimParam], a
|
|
ld a, MOVE_SUBSTITUTE
|
|
call LoadBattleAnim
|
|
pop af
|
|
ldh [hBattleTurn], a
|
|
ldh a, [hBattleTurn]
|
|
ld hl, wPlayerMoveStructEffect
|
|
and a
|
|
jr z, .got_move_effect
|
|
ld hl, wEnemyMoveStructEffect
|
|
|
|
; Cancel move effect
|
|
.got_move_effect:
|
|
xor a
|
|
ld [hl], a
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
SubTookDamageText:
|
|
text "<TARGET>に かわって"
|
|
line "ぶんしんが こうげきを うけた!"
|
|
prompt
|
|
|
|
SubFadedText:
|
|
text "<TARGET>の ぶんしんは"
|
|
line "きえてしまった<⋯⋯>"
|
|
prompt
|
|
|
|
UpdateMoveData:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp z, .player
|
|
|
|
ld hl, wEnemySubStatus5
|
|
ld de, wEnemyMoveStruct
|
|
ld bc, wLastEnemyCounterMove
|
|
push bc
|
|
ld a, [wCurEnemyMove]
|
|
ld b, a
|
|
jr .get_move_data
|
|
|
|
.player:
|
|
ld hl, wPlayerSubStatus5
|
|
ld de, wPlayerMoveStruct
|
|
ld bc, wLastPlayerCounterMove
|
|
push bc
|
|
ld a, [wCurPlayerMove]
|
|
ld b, a
|
|
ld a, [wPlayerDebugSelectedMove]
|
|
and a
|
|
jr z, .get_move_data
|
|
ld b, a
|
|
|
|
.get_move_data:
|
|
ld a, b
|
|
pop bc
|
|
and a
|
|
bit SUBSTATUS_ENCORED, [hl]
|
|
jr nz, .encored
|
|
|
|
ld [wCurSpecies], a
|
|
ld [wNamedObjectIndexBuffer], a
|
|
dec a
|
|
ld hl, Moves
|
|
ld bc, MOVE_LENGTH
|
|
call AddNTimes
|
|
ld a, BANK(Moves)
|
|
call FarCopyBytes
|
|
jr .get_move_name
|
|
|
|
.encored:
|
|
ld a, [bc]
|
|
ld [wCurSpecies], a
|
|
ld [wNamedObjectIndexBuffer], a
|
|
|
|
.get_move_name:
|
|
call GetMoveName
|
|
jp CopyStringToStringBuffer2
|
|
|
|
; Unreferenced. Seems to be early sleep code leftover from Gen 1.
|
|
; It was used at SOME point, seeing as compatibility with held items was added.
|
|
Unreferenced_OldSleepTarget:
|
|
ld de, wEnemyMonStatus
|
|
ld bc, wEnemySubStatus4
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp z, .player
|
|
ld de, wBattleMonStatus
|
|
ld bc, wPlayerSubStatus4
|
|
|
|
.player:
|
|
ld a, [bc]
|
|
bit SUBSTATUS_RECHARGE, a
|
|
res SUBSTATUS_RECHARGE, a
|
|
ld [bc], a
|
|
jr nz, .set_sleep_counter
|
|
; Return if it already has a status effect
|
|
ld a, [de]
|
|
and a
|
|
ret nz
|
|
; Return if the move would be not very effective
|
|
ld a, [wTypeModifier]
|
|
and $7f
|
|
cp EFFECTIVE
|
|
ret c
|
|
; Check held item effect and return if it prevents sleep
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_SLEEP
|
|
ret z
|
|
; Return if effect chance isn't met
|
|
call BattleCommand_EffectChance
|
|
ret nc
|
|
; Return if Safeguard is protecting the target
|
|
call SafeCheckSafeguard
|
|
ret nz
|
|
|
|
.set_sleep_counter:
|
|
; Set sleep counter to between 1 and 7
|
|
call BattleRandom
|
|
and 7
|
|
jr z, .set_sleep_counter
|
|
|
|
ld [de], a
|
|
call PlayDamageAnim
|
|
push de
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
|
|
ld hl, FellAsleepText
|
|
call PrintText
|
|
pop de
|
|
|
|
; Check for held items. If it has one of the below effects, the item is used.
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_HEAL_SLEEP
|
|
jr z, .cure_sleep
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .cure_sleep
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .cure_sleep
|
|
ret
|
|
|
|
.cure_sleep:
|
|
ld a, [de]
|
|
and ~SLP
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
FellAsleepText:
|
|
text "<TARGET>は"
|
|
line "ねむってしまった!"
|
|
prompt
|
|
|
|
BattleCommand_SleepTarget:
|
|
ld de, wEnemyMonStatus
|
|
ld bc, wEnemySubStatus4
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp z, .player
|
|
ld de, wBattleMonStatus
|
|
ld bc, wPlayerSubStatus4
|
|
|
|
.player:
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
ld hl, DoesntAffectText
|
|
jr c, .fail
|
|
|
|
push bc
|
|
call GetOpponentItem
|
|
ld a, b
|
|
pop bc
|
|
cp HELD_PREVENT_SLEEP
|
|
jr nz, .not_protected_by_item
|
|
|
|
ld a, [hl]
|
|
ld [wNamedObjectIndexBuffer], a
|
|
call GetItemName
|
|
ld hl, ProtectedByText
|
|
jr .fail
|
|
|
|
.not_protected_by_item:
|
|
ld a, [de]
|
|
and SLP
|
|
ld hl, AlreadyAsleepText
|
|
jr nz, .fail
|
|
|
|
ld hl, DidntAffectText
|
|
ld a, [de]
|
|
and a
|
|
jr nz, .fail
|
|
|
|
call CheckSubstituteOpp
|
|
jr nz, .fail
|
|
|
|
ld a, [bc]
|
|
bit SUBSTATUS_RECHARGE, a
|
|
res SUBSTATUS_RECHARGE, a
|
|
ld [bc], a
|
|
jr nz, .random_loop
|
|
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
jr nz, .fail
|
|
|
|
.random_loop:
|
|
call BattleRandom
|
|
and 7
|
|
jr z, .random_loop
|
|
|
|
ld [de], a
|
|
call PlayDamageAnim
|
|
push de
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
|
|
ld hl, FellAsleepText
|
|
call PrintText
|
|
|
|
pop de
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_HEAL_SLEEP
|
|
jr z, .use_item
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .use_item
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .use_item
|
|
ret
|
|
|
|
.use_item:
|
|
ld a, [de]
|
|
and ~SLP
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
.fail:
|
|
call BattleCommand_MoveDelay
|
|
jp PrintText
|
|
|
|
AlreadyAsleepText:
|
|
text "<TARGET>は すでに"
|
|
line "ねむっている"
|
|
prompt
|
|
|
|
BattleCommand_PoisonTarget:
|
|
ld de, wEnemyMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_status
|
|
ld de, wBattleMonStatus
|
|
|
|
.got_status
|
|
call CheckSubstituteOpp
|
|
ret nz
|
|
ld a, [de]
|
|
and a
|
|
ret nz
|
|
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
ret c
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_POISON
|
|
ret z
|
|
|
|
call BattleCommand_EffectChance
|
|
ret nc
|
|
call SafeCheckSafeguard
|
|
ret nz
|
|
|
|
ld a, [de]
|
|
set PSN, a
|
|
ld [de], a
|
|
|
|
push de
|
|
ld de, ANIM_PSN
|
|
call PlayOpponentBattleAnim
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
ld hl, WasPoisonedText
|
|
call PrintText
|
|
|
|
pop de
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_HEAL_POISON
|
|
jr z, .use_item
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .use_item
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .use_item
|
|
ret
|
|
|
|
.use_item
|
|
ld a, [de]
|
|
res PSN, a
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
WasPoisonedText:
|
|
text "<TARGET>は どくをあびた!"
|
|
prompt
|
|
|
|
BattleCommand_Poison:
|
|
ld de, wEnemyMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_status
|
|
ld de, wBattleMonStatus
|
|
|
|
.got_status
|
|
ld hl, DoesntAffectText
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
jp c, .failed
|
|
|
|
; BUG: Checks for the Poison bit, but not any other statuses.
|
|
; I'm sure this won't come up later...
|
|
ld hl, AlreadyPoisonedText
|
|
ld a, [de]
|
|
bit PSN, a
|
|
jp nz, .failed
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_POISON
|
|
jr nz, .do_poison
|
|
|
|
ld a, [hl]
|
|
ld [wNamedObjectIndexBuffer], a
|
|
call GetItemName
|
|
ld hl, ProtectedByText
|
|
jr .failed
|
|
|
|
.do_poison
|
|
; BUG: the comparison from "cp HELD_PREVENT_POISON" is still loaded in flags.
|
|
; Therefore it will never fail here, and poison can stack on top of other status conditions.
|
|
; Fixed in the final version by loading and properly comparing mon's status here.
|
|
ld hl, DidntAffectText
|
|
and a
|
|
jr nz, .failed
|
|
|
|
call CheckSubstituteOpp
|
|
jr nz, .failed
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
jr nz, .failed
|
|
|
|
ld a, [de]
|
|
set PSN, a
|
|
ld [de], a
|
|
|
|
push de
|
|
call .check_toxic
|
|
jr z, .toxic
|
|
|
|
call PlayDamageAnim
|
|
ld hl, WasPoisonedText
|
|
call PrintText
|
|
jr .finished
|
|
|
|
.toxic
|
|
set SUBSTATUS_TOXIC, [hl]
|
|
xor a
|
|
ld [de], a
|
|
call PlayDamageAnim
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
|
|
ld hl, BadlyPoisonedText
|
|
call PrintText
|
|
|
|
.finished
|
|
pop de
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_HEAL_POISON
|
|
jr z, .use_item
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .use_item
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .use_item
|
|
ret
|
|
|
|
.use_item
|
|
ld a, [de]
|
|
res PSN, a
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
call .check_toxic
|
|
ret nz
|
|
res SUBSTATUS_TOXIC, [hl]
|
|
ret
|
|
|
|
.check_toxic
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStructEffect]
|
|
ld hl, wEnemySubStatus5
|
|
ld de, wEnemyToxicCount
|
|
jr z, .ok
|
|
ld a, [wEnemyMoveStructEffect]
|
|
ld hl, wPlayerSubStatus5
|
|
ld de, wPlayerToxicCount
|
|
|
|
.ok
|
|
cp EFFECT_TOXIC
|
|
ret
|
|
|
|
.failed
|
|
call BattleCommand_MoveDelay
|
|
jp PrintText
|
|
|
|
AlreadyPoisonedText:
|
|
text "<TARGET>は すでに"
|
|
line "どくを あびている"
|
|
prompt
|
|
|
|
BadlyPoisonedText:
|
|
text "<TARGET>は"
|
|
line "もうどくをあびた!"
|
|
prompt
|
|
|
|
BattleCommand_DrainTarget:
|
|
call SapHealth
|
|
ld hl, SuckedHealthText
|
|
jp PrintText
|
|
|
|
SuckedHealthText:
|
|
text "<TARGET>から"
|
|
line "たいりょくを すいとった!"
|
|
prompt
|
|
|
|
BattleCommand_EatDream:
|
|
call SapHealth
|
|
ld hl, DreamEatenText
|
|
jp PrintText
|
|
|
|
DreamEatenText:
|
|
text "<TARGET>の"
|
|
line "ゆめを くった!"
|
|
prompt
|
|
|
|
SapHealth:
|
|
; Divide damage by two
|
|
ld hl, wCurDamage
|
|
ld a, [hl]
|
|
srl a
|
|
ld [hli], a
|
|
ld a, [hl]
|
|
rr a
|
|
ld [hld], a
|
|
or [hl]
|
|
jr nz, .at_least_one
|
|
inc hl
|
|
inc [hl]
|
|
|
|
.at_least_one:
|
|
ld hl, wBattleMonHP
|
|
ld de, wBattleMonMaxHP
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp z, .battlemonhp
|
|
ld hl, wEnemyMonHP
|
|
ld de, wEnemyMonMaxHP
|
|
|
|
.battlemonhp:
|
|
; Store current HP in little endian wHPBarOldHP
|
|
ld bc, wHPBarOldHP + 1
|
|
ld a, [hli]
|
|
ld [bc], a
|
|
ld a, [hl]
|
|
dec bc
|
|
ld [bc], a
|
|
|
|
; Store max HP in little endian wHPBarMaxHP
|
|
ld a, [de]
|
|
dec bc
|
|
ld [bc], a
|
|
inc de
|
|
ld a, [de]
|
|
dec bc
|
|
ld [bc], a
|
|
|
|
; Add wCurDamage to current HP and copy it to little endian wHPBarNewHP
|
|
ld a, [wCurDamage + 1]
|
|
ld b, [hl]
|
|
add b
|
|
ld [hld], a
|
|
ld [wHPBarNewHP], a
|
|
ld a, [wCurDamage]
|
|
ld b, [hl]
|
|
adc b
|
|
ld [hli], a
|
|
ld [wHPBarNewHP + 1], a
|
|
jr c, .max_hp
|
|
|
|
; Subtract current HP from max HP (to see if we have more than 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, .finish
|
|
|
|
.max_hp:
|
|
ld a, [de]
|
|
ld [hld], a
|
|
ld [wHPBarNewHP], a
|
|
dec de
|
|
ld a, [de]
|
|
ld [hli], a
|
|
ld [wHPBarNewHP + 1], a
|
|
inc de
|
|
|
|
.finish:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
hlcoord 10, 9
|
|
ld a, 1
|
|
jr z, .hp_bar
|
|
hlcoord 2, 2
|
|
xor a
|
|
|
|
.hp_bar:
|
|
ld [wWhichHPBar], a
|
|
predef UpdateHPBar
|
|
predef UpdatePlayerHUD
|
|
predef UpdateEnemyHUD
|
|
ld hl, UpdateBattleMonInParty
|
|
jp CallFromBank0F
|
|
|
|
BattleCommand_BurnTarget:
|
|
xor a
|
|
ld [wNumHits], a
|
|
call CheckSubstituteOpp
|
|
ret nz
|
|
ld de, wEnemyMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_status
|
|
ld de, wBattleMonStatus
|
|
|
|
.got_status
|
|
ld a, [de]
|
|
and a
|
|
jp nz, Defrost
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
ret c
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_BURN
|
|
ret z
|
|
call BattleCommand_EffectChance
|
|
ret nc
|
|
call SafeCheckSafeguard
|
|
ret nz
|
|
|
|
ld a, [de]
|
|
set BRN, a
|
|
ld [de], a
|
|
push de
|
|
|
|
ld hl, ApplyBrnEffectOnAttack
|
|
call CallFromBank0F
|
|
ld de, ANIM_BRN
|
|
call PlayOpponentBattleAnim
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
ld hl, WasBurnedText
|
|
call PrintText
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
pop de
|
|
cp HELD_HEAL_BURN
|
|
jr z, .use_item
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .use_item
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .use_item
|
|
ret
|
|
|
|
.use_item
|
|
ld a, [de]
|
|
res BRN, a
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
WasBurnedText:
|
|
text "<TARGET>は"
|
|
line "やけどをおった!"
|
|
prompt
|
|
|
|
Defrost:
|
|
ld a, [de]
|
|
and 1 << FRZ
|
|
ret z
|
|
xor a
|
|
ld [de], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wCurOTMon]
|
|
ld hl, wOTPartyMon1Status
|
|
jr z, .ok
|
|
ld hl, wPartyMon1Status
|
|
ld a, [wCurBattleMon]
|
|
|
|
.ok
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
xor a
|
|
ld [hl], a
|
|
ld hl, DefrostedOpponentText
|
|
jp PrintText
|
|
|
|
DefrostedOpponentText:
|
|
text "ほのおをあびて<TARGET>の"
|
|
line "こおりが とけた!"
|
|
prompt
|
|
|
|
BattleCommand_FreezeTarget:
|
|
xor a
|
|
ld [wNumHits], a
|
|
call CheckSubstituteOpp
|
|
ret nz
|
|
ld de, wEnemyMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_status
|
|
ld de, wBattleMonStatus
|
|
|
|
.got_status
|
|
ld a, [de]
|
|
and a
|
|
ret nz
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
ret c
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_FREEZE
|
|
ret z
|
|
call BattleCommand_EffectChance
|
|
ret nc
|
|
call SafeCheckSafeguard
|
|
ret nz
|
|
|
|
ld a, [de]
|
|
set FRZ, a
|
|
ld [de], a
|
|
push de
|
|
call EndRechargeOpp
|
|
|
|
ld de, ANIM_FRZ
|
|
call PlayOpponentBattleAnim
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
ld hl, WasFrozenText
|
|
call PrintText
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
pop de
|
|
cp HELD_HEAL_FREEZE
|
|
jr z, .use_item
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .use_item
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .use_item
|
|
ret
|
|
|
|
.use_item
|
|
ld a, [de]
|
|
res FRZ, a
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
WasFrozenText:
|
|
text "<TARGET>は"
|
|
line "こおりづけになった!"
|
|
prompt
|
|
|
|
BattleCommand_ParalyzeTarget:
|
|
xor a
|
|
ld [wNumHits], a
|
|
call CheckSubstituteOpp
|
|
ret nz
|
|
ld de, wEnemyMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_status
|
|
ld de, wBattleMonStatus
|
|
|
|
.got_status
|
|
ld a, [de]
|
|
and a
|
|
ret nz
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
ret c
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_PARALYZE
|
|
ret z
|
|
call BattleCommand_EffectChance
|
|
ret nc
|
|
call SafeCheckSafeguard
|
|
ret nz
|
|
|
|
ld a, [de]
|
|
set PAR, a
|
|
ld [de], a
|
|
push de
|
|
ld hl, ApplyPrzEffectOnSpeed
|
|
call CallFromBank0F
|
|
ld de, ANIM_PAR
|
|
call PlayOpponentBattleAnim
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
call PrintParalyze
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
pop de
|
|
cp HELD_HEAL_PARALYZE
|
|
jr z, .use_item
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .use_item
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .use_item
|
|
ret
|
|
|
|
.use_item:
|
|
ld a, [de]
|
|
res PAR, a
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
BattleCommand_StatUp:
|
|
ld hl, wPlayerStatLevels
|
|
ld de, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_stat_levels
|
|
ld hl, wEnemyStatLevels
|
|
ld de, wEnemyMoveStructEffect
|
|
|
|
.got_stat_levels
|
|
ld a, [de]
|
|
sub EFFECT_ATTACK_UP
|
|
cp NUM_LEVEL_STATS
|
|
jr c, .increment_stat_level
|
|
|
|
; Map +2 effects to corresponding +1 effects
|
|
sub (EFFECT_ATTACK_UP_2 - EFFECT_ATTACK_UP)
|
|
|
|
.increment_stat_level
|
|
; Try to increase stat, and fail if already at maximum stat level
|
|
ld c, a
|
|
ld b, 0
|
|
add hl, bc
|
|
ld b, [hl]
|
|
inc b
|
|
ld a, MAX_STAT_LEVEL
|
|
cp b
|
|
jp c, .cant_raise_stat
|
|
|
|
; Increase stat again if move has an UP_2 effect
|
|
ld a, [de]
|
|
cp EFFECT_ATTACK_UP + NUM_LEVEL_STATS
|
|
jr c, .got_num_stages
|
|
|
|
inc b
|
|
ld a, MAX_STAT_LEVEL
|
|
cp b
|
|
jr nc, .got_num_stages
|
|
ld b, a
|
|
|
|
.got_num_stages
|
|
; Store increased stat
|
|
ld [hl], b
|
|
ld a, c
|
|
; BUG: This code is supposed to check for ACCURACY or greater, but this code predates
|
|
; the addition of the Special Defense stat, so it uses an old stat index.
|
|
; This means that Special Defense generally is not affected by stat boosts in this build.
|
|
; (The rare exceptions being when ApplyStatLevelMultiplierOnAllStats is called, i.e. Baton Pass)
|
|
cp SP_DEFENSE
|
|
jr nc, .done_calcing_stats
|
|
push hl
|
|
ld hl, wBattleMonStats + 1
|
|
ld de, wPlayerStats
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_stats_pointer
|
|
ld hl, wEnemyMonStats + 1
|
|
ld de, wEnemyStats
|
|
|
|
.got_stats_pointer
|
|
push bc
|
|
sla c
|
|
ld b, 0
|
|
add hl, bc
|
|
ld a, c
|
|
add e
|
|
ld e, a
|
|
jr nc, .no_carry
|
|
inc d
|
|
|
|
.no_carry
|
|
pop bc
|
|
ld a, [hld]
|
|
sub LOW(MAX_STAT_VALUE)
|
|
jr nz, .not_already_max
|
|
ld a, [hl]
|
|
sbc HIGH(MAX_STAT_VALUE)
|
|
jp z, .stats_already_max
|
|
|
|
.not_already_max
|
|
push hl
|
|
push bc
|
|
|
|
ld hl, StatLevelMultipliers
|
|
dec b
|
|
sla b
|
|
ld c, b
|
|
ld b, 0
|
|
add hl, bc
|
|
pop bc
|
|
|
|
xor a
|
|
ldh [hMultiplicand], a
|
|
ld a, [de]
|
|
ldh [hMultiplicand + 1], a
|
|
inc de
|
|
ld a, [de]
|
|
ldh [hMultiplicand + 2], a
|
|
|
|
ld a, [hli]
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
|
|
ld a, [hl]
|
|
ldh [hDivisor], a
|
|
ld b, 4
|
|
call Divide
|
|
|
|
pop hl
|
|
ldh a, [hQuotient + 3]
|
|
sub LOW(MAX_STAT_VALUE)
|
|
ldh a, [hQuotient + 2]
|
|
sbc HIGH(MAX_STAT_VALUE)
|
|
jp c, .not_maxed_out
|
|
|
|
ld a, HIGH(MAX_STAT_VALUE)
|
|
ldh [hQuotient + 2], a
|
|
ld a, LOW(MAX_STAT_VALUE)
|
|
ldh [hQuotient + 3], a
|
|
|
|
.not_maxed_out
|
|
ldh a, [hQuotient + 2]
|
|
ld [hli], a
|
|
ldh a, [hQuotient + 3]
|
|
ld [hl], a
|
|
pop hl
|
|
|
|
.done_calcing_stats
|
|
ld b, c
|
|
inc b
|
|
call GetStatName
|
|
|
|
; Checks for if Minimize is used, and if so set w[user]Minimized
|
|
; Seems to be set up to check either Mist or Substitute as well, but the SubStatus4 is never actually read
|
|
ld hl, wPlayerSubStatus4
|
|
ld de, wPlayerMoveStruct
|
|
ld bc, wPlayerMinimized
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .player_turn
|
|
ld hl, wEnemySubStatus4
|
|
ld de, wEnemyMoveStruct
|
|
ld bc, wEnemyMinimized
|
|
|
|
.player_turn
|
|
call BattleCommand_LowerSub
|
|
call LoadMoveAnim
|
|
call BattleCommand_RaiseSub
|
|
ld a, [de]
|
|
cp MOVE_MINIMIZE
|
|
jr nz, .not_minimize
|
|
pop bc
|
|
ld a, 1
|
|
ld [bc], a
|
|
|
|
.not_minimize
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
; BUG: All stats except for the currently raised stat are badge-boosted again.
|
|
ld hl, BadgeStatBoosts
|
|
call z, CallFromBank0F
|
|
|
|
ld hl, Text_BattleEffectActivate
|
|
call PrintText
|
|
|
|
; BUG: Incorrectly checks the opponents' Pokémon for burn and
|
|
; paralysis penalties, while leaving the player untouched.
|
|
|
|
; Additionally, the same penalty will keep stacking each time it triggers.
|
|
; Final game fixes this by recalculating the stats each time.
|
|
ld hl, ApplyPrzEffectOnSpeed
|
|
call CallFromBank0F
|
|
ld hl, ApplyBrnEffectOnAttack
|
|
jp CallFromBank0F
|
|
|
|
.stats_already_max
|
|
pop hl
|
|
dec [hl]
|
|
|
|
.cant_raise_stat
|
|
call BattleCommand_MoveDelay
|
|
jp PrintNoChangesText
|
|
|
|
Text_BattleEffectActivate:
|
|
text "<USER>の"
|
|
line "@"
|
|
text_from_ram wStringBuffer2
|
|
text "が@"
|
|
start_asm
|
|
|
|
ld hl, .BattleStatWentWayUpText
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStructEffect]
|
|
jr z, .got_effect
|
|
ld a, [wEnemyMoveStructEffect]
|
|
|
|
.got_effect
|
|
cp EFFECT_ATTACK_UP + NUM_LEVEL_STATS
|
|
ret nc
|
|
ld hl, .BattleStatWentUpText
|
|
ret
|
|
|
|
.BattleStatWentWayUpText
|
|
text_exit
|
|
text "<SCROLL>ぐーんと@"
|
|
; Fallthrough. These strings are connected in Japanese, but separate in English.
|
|
|
|
.BattleStatWentUpText
|
|
text " あがった!"
|
|
prompt
|
|
|
|
BattleCommand_StatDown:
|
|
ld hl, wEnemyStatLevels
|
|
ld de, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_stat_levels
|
|
|
|
ld hl, wPlayerStatLevels
|
|
ld de, wEnemyMoveStructEffect
|
|
ld a, [wLinkMode]
|
|
cp LINK_COLOSSEUM
|
|
jr z, .got_stat_levels
|
|
; 25% chance for enemy monsters' stat-lowering moves to fail
|
|
call BattleRandom
|
|
cp 25 percent + 1
|
|
jp c, .missed
|
|
|
|
.got_stat_levels
|
|
call CheckSubstituteOpp
|
|
jp nz, .missed
|
|
ld a, [de]
|
|
cp EFFECT_ATTACK_DOWN_HIT
|
|
jr c, .is_damaging_move
|
|
|
|
call BattleCommand_EffectChance
|
|
jp nc, .failed
|
|
|
|
ld a, [de]
|
|
sub EFFECT_ATTACK_DOWN_HIT
|
|
jr .decrease_stat_level
|
|
|
|
.is_damaging_move
|
|
push hl
|
|
push de
|
|
call BattleCommand_CheckHit
|
|
pop de
|
|
pop hl
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
jp nz, .missed
|
|
|
|
call CheckHiddenOpponent
|
|
jp nz, .missed
|
|
|
|
ld a, [de]
|
|
sub EFFECT_ATTACK_DOWN
|
|
cp NUM_LEVEL_STATS
|
|
jr c, .decrease_stat_level
|
|
sub (EFFECT_ATTACK_DOWN_2 - EFFECT_ATTACK_DOWN)
|
|
|
|
.decrease_stat_level
|
|
ld c, a
|
|
ld b, 0
|
|
add hl, bc
|
|
ld b, [hl]
|
|
dec b
|
|
jp z, .failed
|
|
|
|
ld a, [de]
|
|
cp EFFECT_ATTACK_DOWN_2 - $16 ; $24. EFFECT_24 is seemingly not used
|
|
jr c, .got_num_stages
|
|
cp EFFECT_ATTACK_DOWN_HIT
|
|
jr nc, .got_num_stages
|
|
dec b
|
|
jr nz, .got_num_stages
|
|
inc b
|
|
|
|
.got_num_stages
|
|
; Store decreased stat level
|
|
ld [hl], b
|
|
ld a, c
|
|
; BUG: Same issue as BattleCommand_StatUp. Special Defense is not recalculated.
|
|
cp SP_DEFENSE
|
|
jr nc, .done_calcing_stats
|
|
push hl
|
|
push de
|
|
ld hl, wEnemyMonStats + 1
|
|
ld de, wEnemyStats
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_stats_pointer
|
|
ld hl, wBattleMonStats + 1
|
|
ld de, wPlayerStats
|
|
|
|
.got_stats_pointer
|
|
push bc
|
|
sla c
|
|
ld b, 0
|
|
add hl, bc
|
|
ld a, c
|
|
add e
|
|
ld e, a
|
|
jr nc, .no_carry
|
|
inc d
|
|
|
|
.no_carry
|
|
pop bc
|
|
ld a, [hld]
|
|
sub 1
|
|
jr nz, .not_already_min
|
|
ld a, [hl]
|
|
and a
|
|
jp z, .stats_already_min
|
|
|
|
.not_already_min
|
|
push hl
|
|
push bc
|
|
|
|
ld hl, StatLevelMultipliers
|
|
dec b
|
|
sla b
|
|
ld c, b
|
|
ld b, 0
|
|
add hl, bc
|
|
pop bc
|
|
|
|
xor a
|
|
ldh [hMultiplicand], a
|
|
ld a, [de]
|
|
ldh [hMultiplicand + 1], a
|
|
inc de
|
|
ld a, [de]
|
|
ldh [hMultiplicand + 2], a
|
|
|
|
ld a, [hli]
|
|
ldh [hMultiplier], a
|
|
call Multiply
|
|
|
|
ld a, [hl]
|
|
ldh [hDivisor], a
|
|
ld b, 4
|
|
call Divide
|
|
|
|
pop hl
|
|
ldh a, [hQuotient + 3]
|
|
ld b, a
|
|
ldh a, [hQuotient + 2]
|
|
or b
|
|
jp nz, .not_zero
|
|
|
|
ldh [hQuotient + 2], a
|
|
ld a, 1
|
|
ldh [hQuotient + 3], a
|
|
|
|
.not_zero
|
|
ldh a, [hQuotient + 2]
|
|
ld [hli], a
|
|
ldh a, [hQuotient + 3]
|
|
ld [hl], a
|
|
pop de
|
|
pop hl
|
|
|
|
.done_calcing_stats
|
|
ld b, c
|
|
inc b
|
|
push de
|
|
call GetStatName
|
|
|
|
pop de
|
|
ld a, [de]
|
|
cp EFFECT_ATTACK_DOWN_HIT
|
|
jr nc, .non_damaging
|
|
call PlayDamageAnim
|
|
|
|
.non_damaging
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
; Badge Boosts applied again on the player.
|
|
; See BattleCommand_StatUp for what goes wrong here.
|
|
ld hl, BadgeStatBoosts
|
|
call nz, CallFromBank0F
|
|
ld hl, Text_BattleFoeEffectActivate
|
|
call PrintText
|
|
|
|
; Same problem as with BattleCommand_StatUp: the stat decreases can stack.
|
|
ld hl, ApplyPrzEffectOnSpeed
|
|
; For some reason, this was "fixed" here so that it happens to the player,
|
|
; but not the opponent, and only for the paralysis speed drop...
|
|
; This sounds like a Link Battle desync waiting to happen.
|
|
call nz, CallFromBank0F
|
|
ld hl, ApplyBrnEffectOnAttack
|
|
jp CallFromBank0F
|
|
|
|
.stats_already_min
|
|
pop de
|
|
pop hl
|
|
inc [hl]
|
|
|
|
.failed
|
|
ld a, [de]
|
|
cp EFFECT_ATTACK_DOWN_HIT
|
|
ret nc
|
|
call BattleCommand_MoveDelay
|
|
jp PrintNoChangesText
|
|
|
|
.missed
|
|
ld a, [de]
|
|
cp EFFECT_ATTACK_DOWN_HIT
|
|
ret nc
|
|
call BattleCommand_MoveDelay
|
|
jp TryPrintButItFailed
|
|
|
|
Text_BattleFoeEffectActivate:
|
|
text "<TARGET>の"
|
|
line "@"
|
|
text_from_ram wStringBuffer2
|
|
text "が@"
|
|
start_asm
|
|
ld hl, .BattleStatFellText
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStructEffect]
|
|
jr z, .got_effect
|
|
ld a, [wEnemyMoveStructEffect]
|
|
|
|
.got_effect
|
|
cp EFFECT_ATTACK_DOWN + NUM_LEVEL_STATS
|
|
ret c
|
|
cp EFFECT_ATTACK_DOWN_HIT
|
|
ret nc
|
|
ld hl, .BattleStatSharplyFellText
|
|
ret
|
|
|
|
.BattleStatSharplyFellText:
|
|
text_exit
|
|
text "<SCROLL>がくっと@"
|
|
; Fallthrough. These strings are connected in Japanese, but separate in English.
|
|
|
|
.BattleStatFellText:
|
|
text " さがった!"
|
|
prompt
|
|
|
|
GetStatName:
|
|
ld hl, StatNames
|
|
ld c, '@'
|
|
|
|
.CheckName
|
|
dec b
|
|
jr z, .Copy
|
|
|
|
.GetName
|
|
ld a, [hli]
|
|
cp c
|
|
jr z, .CheckName
|
|
jr .GetName
|
|
|
|
.Copy
|
|
ld de, wStringBuffer2
|
|
ld bc, NAME_LENGTH - 1
|
|
jp CopyBytes
|
|
|
|
INCLUDE "data/battle/stat_names.asm"
|
|
StatLevelMultipliers:
|
|
INCLUDE "data/battle/stat_multipliers.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/bide.asm"
|
|
|
|
BattleCommand_CheckRampage:
|
|
ld hl, wPlayerSubStatus3
|
|
ld de, wPlayerRolloutCount
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .player
|
|
ld hl, wEnemySubStatus3
|
|
ld de, wEnemyRolloutCount
|
|
|
|
.player
|
|
bit SUBSTATUS_RAMPAGE, [hl]
|
|
ret z
|
|
|
|
ld a, [de]
|
|
dec a
|
|
ld [de], a
|
|
jr nz, .continue_rampage
|
|
|
|
res SUBSTATUS_RAMPAGE, [hl]
|
|
; The final game prevents confusion here if the player is under Safeguard.
|
|
set SUBSTATUS_CONFUSED, [hl]
|
|
call BattleRandom
|
|
and %00000001
|
|
inc a
|
|
inc a
|
|
inc de
|
|
ld [de], a
|
|
|
|
.continue_rampage
|
|
ld b, rampage_command
|
|
jp SkipToBattleCommand
|
|
|
|
BattleCommand_Rampage:
|
|
ld hl, wPlayerSubStatus3
|
|
ld de, wPlayerRolloutCount
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .ok
|
|
ld hl, wEnemySubStatus3
|
|
ld de, wEnemyRolloutCount
|
|
|
|
.ok
|
|
set SUBSTATUS_RAMPAGE, [hl]
|
|
; Rampage for 1 or 2 more turns
|
|
call BattleRandom
|
|
and %00000001
|
|
inc a
|
|
inc a
|
|
ld [de], a
|
|
ret
|
|
|
|
INCLUDE "engine/battle/move_effects/teleport.asm"
|
|
|
|
; Loop back to 'critical'.
|
|
BattleCommand_EndLoop:
|
|
|
|
ld hl, wPlayerSubStatus3
|
|
ld de, wPlayerRolloutCount
|
|
ld bc, wPlayerDamageTaken
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_addrs
|
|
ld hl, wEnemySubStatus3
|
|
ld de, wEnemyRolloutCount
|
|
ld bc, wEnemyDamageTaken
|
|
|
|
.got_addrs
|
|
bit SUBSTATUS_IN_LOOP, [hl]
|
|
jp nz, .in_loop
|
|
|
|
set SUBSTATUS_IN_LOOP, [hl]
|
|
ld hl, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_effect
|
|
ld hl, wEnemyMoveStructEffect
|
|
|
|
.got_effect
|
|
ld a, [hl]
|
|
cp EFFECT_POISON_MULTI_HIT
|
|
jr z, .twineedle
|
|
cp EFFECT_DOUBLE_HIT
|
|
ld a, 1
|
|
jr z, .double_hit
|
|
ld a, [hl]
|
|
cp EFFECT_TRIPLE_KICK
|
|
jr nz, .not_triple_kick
|
|
|
|
.reject_triple_kick_sample
|
|
call BattleRandom
|
|
and 3
|
|
jr z, .reject_triple_kick_sample
|
|
dec a
|
|
jr nz, .double_hit
|
|
ld a, 1
|
|
ld [bc], a
|
|
jr .done_loop
|
|
|
|
.not_triple_kick
|
|
call BattleRandom
|
|
cp 2
|
|
jr c, .got_number_hits
|
|
call BattleRandom
|
|
and 3
|
|
|
|
.got_number_hits
|
|
inc a
|
|
|
|
.double_hit
|
|
ld [de], a
|
|
inc a
|
|
ld [bc], a
|
|
jr .loop_back_to_critical
|
|
|
|
.twineedle
|
|
ld a, EFFECT_POISON_HIT
|
|
ld [hl], a
|
|
dec a
|
|
jr .double_hit
|
|
|
|
.in_loop:
|
|
ld a, [de]
|
|
dec a
|
|
ld [de], a
|
|
jr nz, .loop_back_to_critical
|
|
.done_loop
|
|
ld hl, PlayerHitTimesText
|
|
ld de, wPlayerSubStatus3
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_hit_n_times_text
|
|
ld hl, EnemyHitTimesText
|
|
ld de, wEnemySubStatus3
|
|
|
|
.got_hit_n_times_text
|
|
ld a, [de]
|
|
res SUBSTATUS_IN_LOOP, a
|
|
ld [de], a
|
|
push bc
|
|
call PrintText
|
|
pop bc
|
|
xor a
|
|
ld [bc], a
|
|
ret
|
|
|
|
.loop_back_to_critical
|
|
ld a, [wBattleScriptBufferAddress + 1]
|
|
ld h, a
|
|
ld a, [wBattleScriptBufferAddress]
|
|
ld l, a
|
|
|
|
.not_critical
|
|
ld a, [hld]
|
|
cp critical_command
|
|
jr nz, .not_critical
|
|
inc hl
|
|
ld a, h
|
|
ld [wBattleScriptBufferAddress + 1], a
|
|
ld a, l
|
|
ld [wBattleScriptBufferAddress], a
|
|
ret
|
|
|
|
PlayerHitTimesText:
|
|
text "あいてに @"
|
|
deciram wPlayerDamageTaken, 1, 1
|
|
text "かい あたった!"
|
|
prompt
|
|
|
|
EnemyHitTimesText:
|
|
text "あいてに @"
|
|
deciram wEnemyDamageTaken, 1, 1
|
|
text "かい あたった!"
|
|
prompt
|
|
|
|
BattleCommand_FlinchTarget:
|
|
call CheckSubstituteOpp
|
|
ret nz
|
|
ld hl, wEnemySubStatus3
|
|
ld de, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .go
|
|
ld hl, wPlayerSubStatus3
|
|
ld de, wEnemyMoveStructEffect
|
|
|
|
.go
|
|
call EndRechargeOpp
|
|
call BattleCommand_EffectChance
|
|
ret nc
|
|
set SUBSTATUS_FLINCHED, [hl]
|
|
ret
|
|
|
|
BattleCommand_HeldFlinch:
|
|
; No handling for move missing... can flinches still happen after a miss?
|
|
call GetUserItem
|
|
ld a, b
|
|
cp HELD_FLINCH
|
|
ret nz
|
|
|
|
call CheckSubstituteOpp
|
|
ret nz
|
|
|
|
ld hl, wEnemySubStatus3
|
|
ld de, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .go
|
|
ld hl, wPlayerSubStatus3
|
|
ld de, wEnemyMoveStructEffect
|
|
|
|
.go
|
|
push hl
|
|
call EndRechargeOpp
|
|
call GetUserItem
|
|
pop hl
|
|
call BattleRandom
|
|
cp c
|
|
ret nc
|
|
set SUBSTATUS_FLINCHED, [hl]
|
|
ret
|
|
|
|
BattleCommand_OHKO:
|
|
ld hl, wCurDamage
|
|
xor a
|
|
ld [hli], a
|
|
ld [hl], a
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
jr c, .no_effect
|
|
ld hl, wBattleMonSpeed + 1
|
|
ld de, wEnemyMonSpeed + 1
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .compare_speed
|
|
ld hl, wEnemyMonSpeed + 1
|
|
ld de, wBattleMonSpeed + 1
|
|
|
|
.compare_speed
|
|
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, .no_effect
|
|
|
|
call BattleCommand_CheckHit
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
ret nz
|
|
|
|
ld hl, wCurDamage
|
|
ld a, $ff
|
|
ld [hli], a
|
|
ld [hl], a
|
|
ld a, 2
|
|
ld [wCriticalHit], a
|
|
ret
|
|
|
|
.no_effect
|
|
ld a, $ff
|
|
ld [wCriticalHit], a
|
|
ld a, 1
|
|
ld [wAttackMissed], a
|
|
ret
|
|
|
|
BattleCommand_CheckCharge:
|
|
ld hl, wPlayerSubStatus3
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_substatus
|
|
ld hl, wEnemySubStatus3
|
|
|
|
.got_substatus
|
|
bit SUBSTATUS_CHARGED, [hl]
|
|
ret z
|
|
res SUBSTATUS_CHARGED, [hl]
|
|
res SUBSTATUS_INVULNERABLE, [hl]
|
|
ld b, charge_command
|
|
jp SkipToBattleCommand
|
|
|
|
BattleCommand_Charge:
|
|
xor a
|
|
ld [wNumHits], a
|
|
inc a
|
|
ld [wBattleAnimParam], a
|
|
call LoadMoveAnim
|
|
|
|
ld hl, wPlayerSubStatus3
|
|
ld de, wPlayerMoveStruct
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .ok
|
|
ld hl, wEnemySubStatus3
|
|
ld de, wEnemyMoveStruct
|
|
|
|
.ok
|
|
set SUBSTATUS_CHARGED, [hl]
|
|
ld a, [de]
|
|
cp MOVE_FLY
|
|
jr nz, .dont_set_flying
|
|
set SUBSTATUS_INVULNERABLE, [hl]
|
|
|
|
.dont_set_flying
|
|
ld a, [de]
|
|
cp MOVE_DIG
|
|
jr nz, .dont_set_digging
|
|
set SUBSTATUS_INVULNERABLE, [hl]
|
|
|
|
.dont_set_digging
|
|
ld a, [de]
|
|
ld [wChargeMoveNum], a
|
|
ld hl, .UsedText
|
|
call PrintText
|
|
jp EndMoveEffect
|
|
|
|
.UsedText
|
|
text "<USER>@"
|
|
start_asm
|
|
ld a, [wChargeMoveNum]
|
|
cp MOVE_RAZOR_WIND
|
|
ld hl, BattleMadeWhirlwindText
|
|
jr z, .done
|
|
|
|
cp MOVE_SOLARBEAM
|
|
ld hl, BattleTookSunlightText
|
|
jr z, .done
|
|
|
|
cp MOVE_SKULL_BASH
|
|
ld hl, BattleLoweredHeadText
|
|
jr z, .done
|
|
|
|
cp MOVE_SKY_ATTACK
|
|
ld hl, BattleGlowingText
|
|
jr z, .done
|
|
|
|
cp MOVE_FLY
|
|
ld hl, BattleFlewText
|
|
jr z, .done
|
|
|
|
cp MOVE_DIG
|
|
ld hl, BattleDugText
|
|
|
|
.done
|
|
ret
|
|
|
|
BattleMadeWhirlwindText:
|
|
text "の まわりで"
|
|
line "くうきが うずを まく!"
|
|
prompt
|
|
|
|
BattleTookSunlightText:
|
|
text "は"
|
|
line "ひかりを きゅうしゅうした!"
|
|
prompt
|
|
|
|
BattleLoweredHeadText:
|
|
text "は"
|
|
line "くびを ひっこめた!"
|
|
prompt
|
|
|
|
BattleGlowingText:
|
|
text "を"
|
|
line "はげしい ひかりが つつむ!"
|
|
prompt
|
|
|
|
BattleFlewText:
|
|
text "は"
|
|
line "そらたかく とびあがった!"
|
|
prompt
|
|
|
|
BattleDugText:
|
|
text "は"
|
|
line "あなをほって ちちゅうに もぐった!"
|
|
prompt
|
|
|
|
; Skips to the traptarget command in the move's battle script buffer.
|
|
; This command was dummied out in the final game, most likely due to
|
|
; the changes made to trapping moves.
|
|
BattleCommand_SkipToTrapTarget:
|
|
ld hl, wPlayerSubStatus3
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .ok
|
|
ld hl, wEnemySubStatus3
|
|
|
|
.ok
|
|
bit SUBSTATUS_USING_TRAPPING_MOVE, [hl]
|
|
ret z
|
|
|
|
ld a, [wBattleScriptBufferAddress + 1]
|
|
ld h, a
|
|
ld a, [wBattleScriptBufferAddress]
|
|
ld l, a
|
|
|
|
.find_traptarget
|
|
ld a, [hli]
|
|
cp traptarget_command
|
|
|
|
jr nz, .find_traptarget
|
|
dec hl
|
|
ld a, h
|
|
ld [wBattleScriptBufferAddress + 1], a
|
|
ld a, l
|
|
ld [wBattleScriptBufferAddress], a
|
|
ret
|
|
|
|
BattleCommand_TrapTarget:
|
|
ld hl, wPlayerSubStatus3
|
|
ld de, wPlayerRolloutCount
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_substatus
|
|
ld hl, wEnemySubStatus3
|
|
ld de, wEnemyRolloutCount
|
|
|
|
.got_substatus
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
ret nz
|
|
bit SUBSTATUS_USING_TRAPPING_MOVE, [hl]
|
|
jr nz, .attack_continues
|
|
|
|
call EndRechargeOpp
|
|
set SUBSTATUS_USING_TRAPPING_MOVE, [hl]
|
|
|
|
; 3/8 chance for 2 and 3 attacks, and 1/8 chance for 4 and 5 attacks.
|
|
call BattleRandom
|
|
and %11
|
|
cp 2
|
|
jr c, .trap
|
|
call BattleRandom
|
|
and %11
|
|
|
|
.trap
|
|
inc a
|
|
ld [de], a
|
|
ret
|
|
|
|
.attack_continues
|
|
push hl
|
|
push de
|
|
ld hl, AttackContinuesText
|
|
call PrintText
|
|
|
|
pop hl
|
|
dec [hl]
|
|
|
|
pop hl
|
|
ret nz
|
|
res SUBSTATUS_USING_TRAPPING_MOVE, [hl]
|
|
ret
|
|
|
|
INCLUDE "engine/battle/move_effects/mist.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/focus_energy.asm"
|
|
|
|
BattleCommand_Recoil:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStruct]
|
|
ld hl, wBattleMonMaxHP
|
|
jr z, .got_max_hp
|
|
ld a, [wEnemyMoveStruct]
|
|
ld hl, wEnemyMonMaxHP
|
|
|
|
; get 1/4 damage or 1 HP, whichever is higher
|
|
.got_max_hp
|
|
ld d, a
|
|
ld a, [wCurDamage]
|
|
ld b, a
|
|
ld a, [wCurDamage + 1]
|
|
ld c, a
|
|
srl b
|
|
rr c
|
|
ld a, d
|
|
; get 1/2 damage instead if move is Struggle
|
|
cp MOVE_STRUGGLE
|
|
jr z, .struggle
|
|
srl b
|
|
rr c
|
|
|
|
.struggle
|
|
ld a, b
|
|
or c
|
|
jr nz, .min_damage
|
|
inc c
|
|
|
|
.min_damage
|
|
ld a, [hli]
|
|
ld [wHPBarMaxHP + 1], a
|
|
ld a, [hl]
|
|
ld [wHPBarMaxHP], a
|
|
dec hl
|
|
dec hl
|
|
|
|
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, .dont_ko
|
|
xor a
|
|
ld [hli], a
|
|
ld [hl], a
|
|
ld hl, wHPBarNewHP
|
|
ld [hli], a
|
|
ld [hl], a
|
|
|
|
.dont_ko
|
|
hlcoord 10, 9
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, 1
|
|
jr z, .animate_hp_bar
|
|
hlcoord 2, 2
|
|
xor a
|
|
|
|
.animate_hp_bar
|
|
ld [wWhichHPBar], a
|
|
predef UpdateHPBar
|
|
ld hl, RecoilText
|
|
jp PrintText
|
|
|
|
RecoilText:
|
|
text "<USER>は こうげきの"
|
|
line "はんどうを うけた!"
|
|
prompt
|
|
|
|
BattleCommand_ConfuseTarget:
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_CONFUSE
|
|
ret z
|
|
call BattleCommand_EffectChance
|
|
ret nc
|
|
jr BattleCommand_FinishConfusingTarget
|
|
|
|
BattleCommand_Confuse:
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_CONFUSE
|
|
jr nz, .no_item_protection
|
|
ld a, [hl]
|
|
ld [wNamedObjectIndexBuffer], a
|
|
call GetItemName
|
|
call BattleCommand_MoveDelay
|
|
ld hl, ProtectedByText
|
|
jp PrintText
|
|
|
|
.no_item_protection
|
|
call CheckSubstituteOpp
|
|
jr nz, BattleCommand_Confuse_CheckSnore_Swagger_ConfuseHit
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
jr nz, BattleCommand_Confuse_CheckSnore_Swagger_ConfuseHit
|
|
|
|
BattleCommand_FinishConfusingTarget:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld hl, wEnemySubStatus3
|
|
ld bc, wEnemyConfuseCount
|
|
ld a, [wPlayerMoveStructEffect]
|
|
jr z, .got_confuse_count
|
|
ld hl, wPlayerSubStatus3
|
|
ld bc, wPlayerConfuseCount
|
|
ld a, [wEnemyMoveStructEffect]
|
|
|
|
.got_confuse_count
|
|
bit SUBSTATUS_CONFUSED, [hl]
|
|
jr nz, BattleCommand_Confuse_CheckSnore_Swagger_ConfuseHit
|
|
set SUBSTATUS_CONFUSED, [hl]
|
|
; confused for 2-5 turns
|
|
push af
|
|
call BattleRandom
|
|
and 3
|
|
inc a
|
|
inc a
|
|
ld [bc], a
|
|
|
|
pop af
|
|
cp EFFECT_CONFUSE_HIT
|
|
jr z, .got_effect
|
|
cp EFFECT_SNORE
|
|
jr z, .got_effect
|
|
cp EFFECT_SWAGGER
|
|
jr z, .got_effect
|
|
call LoadMoveAnim
|
|
jr .became_confused_text
|
|
|
|
.got_effect
|
|
ld de, ANIM_CONFUSED
|
|
call PlayOpponentBattleAnim
|
|
|
|
.became_confused_text
|
|
ld hl, BecameConfusedText
|
|
jp PrintText
|
|
|
|
BecameConfusedText:
|
|
text "<TARGET>は"
|
|
line "こんらんした!"
|
|
prompt
|
|
|
|
BattleCommand_Confuse_CheckSnore_Swagger_ConfuseHit:
|
|
cp EFFECT_CONFUSE_HIT
|
|
ret z
|
|
cp EFFECT_SNORE
|
|
ret z
|
|
cp EFFECT_SWAGGER
|
|
ret z
|
|
call BattleCommand_MoveDelay
|
|
jp TryPrintButItFailed
|
|
|
|
BattleCommand_Paralyze:
|
|
ld hl, wEnemyMonStatus
|
|
ld de, wPlayerMoveStructType
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp z, .got_status
|
|
ld hl, wBattleMonStatus
|
|
ld de, wEnemyMoveStructType
|
|
|
|
.got_status
|
|
ld a, [wTypeModifier]
|
|
and EFFECTIVENESS_MASK
|
|
cp EFFECTIVE
|
|
jr c, .didnt_affect
|
|
|
|
ld a, [hl]
|
|
and a
|
|
jr nz, .paralyzed
|
|
|
|
push hl
|
|
call GetOpponentItem
|
|
ld a, b
|
|
cp HELD_PREVENT_PARALYZE
|
|
ld a, [hl]
|
|
pop hl
|
|
jr nz, .paralyze
|
|
|
|
ld [wNamedObjectIndexBuffer], a
|
|
call GetItemName
|
|
call BattleCommand_MoveDelay
|
|
ld hl, ProtectedByText
|
|
jp PrintText
|
|
|
|
.paralyze
|
|
ld a, [wAttackMissed]
|
|
and a
|
|
jr nz, .paralyzed
|
|
set PAR, [hl]
|
|
push hl
|
|
ld hl, ApplyPrzEffectOnSpeed
|
|
call CallFromBank0F
|
|
|
|
ld c, 30
|
|
call DelayFrames
|
|
call LoadMoveAnim
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
call PrintParalyze
|
|
|
|
call GetOpponentItem
|
|
ld a, b
|
|
pop de
|
|
cp HELD_HEAL_PARALYZE
|
|
jr z, .use_item
|
|
cp HELD_HEAL_STATUS
|
|
jr z, .use_item
|
|
cp HELD_FULL_RESTORE
|
|
jr z, .use_item
|
|
ret
|
|
|
|
.use_item
|
|
ld a, [de]
|
|
res PAR, a
|
|
ld [de], a
|
|
ld a, [hl]
|
|
call PrintUsersItemActivated
|
|
call ConsumeHeldItem
|
|
ld hl, UpdateBattleHuds
|
|
jp CallFromBank0F
|
|
|
|
.paralyzed
|
|
call BattleCommand_MoveDelay
|
|
jp PrintDidntAffectText
|
|
|
|
.didnt_affect
|
|
call BattleCommand_MoveDelay
|
|
jp PrintDoesntAffect
|
|
|
|
INCLUDE "engine/battle/move_effects/substitute.asm"
|
|
|
|
BattleCommand_RechargeNextTurn:
|
|
ld hl, wPlayerSubStatus4
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .ok
|
|
ld hl, wEnemySubStatus4
|
|
|
|
.ok:
|
|
set SUBSTATUS_RECHARGE, [hl]
|
|
ret
|
|
|
|
EndRechargeOpp:
|
|
push hl
|
|
ld hl, wEnemySubStatus4
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .ok
|
|
ld hl, wPlayerSubStatus4
|
|
|
|
.ok
|
|
res SUBSTATUS_RECHARGE, [hl]
|
|
pop hl
|
|
ret
|
|
|
|
INCLUDE "engine/battle/move_effects/rage.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/mimic.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/leech_seed.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/splash.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/disable.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/pay_day.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/conversion.asm"
|
|
|
|
; Effect identical to Gen I
|
|
BattleCommand_ResetStats:
|
|
ld a, BASE_STAT_LEVEL
|
|
ld hl, wPlayerStatLevels
|
|
call .Fill
|
|
ld hl, wEnemyStatLevels
|
|
call .Fill
|
|
|
|
ld hl, wPlayerStats
|
|
ld de, wBattleMonStats
|
|
call .CopyStats
|
|
ld hl, wEnemyStats
|
|
ld de, wEnemyMonStats
|
|
call .CopyStats
|
|
|
|
ld hl, wEnemyMonStatus
|
|
ld de, wCurEnemyMove
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .cure_status
|
|
ld hl, wBattleMonStatus
|
|
dec de
|
|
|
|
.cure_status
|
|
ld a, [hl]
|
|
ld [hl], 0
|
|
and (1 << FRZ) | SLP
|
|
jr z, .not_immobile
|
|
; prevent the Pokemon from executing a move if it was asleep or frozen
|
|
ld a, $ff
|
|
ld [de], a
|
|
|
|
.not_immobile
|
|
; Cure Disable
|
|
xor a
|
|
ld [wPlayerDisableCount], a
|
|
ld [wEnemyDisableCount], a
|
|
ld hl, wDisabledMove
|
|
ld [hli], a
|
|
ld [hl], a
|
|
; Cure Confusion
|
|
ld hl, wPlayerSubStatus3
|
|
res SUBSTATUS_CONFUSED, [hl]
|
|
|
|
; Clear X Accuracy, Mist, Focus Energy, and Leech Seed
|
|
inc hl
|
|
ld a, [hl]
|
|
and ~((1 << SUBSTATUS_X_ACCURACY) | (1 << SUBSTATUS_MIST) | (1 << SUBSTATUS_FOCUS_ENERGY) | (1 << SUBSTATUS_LEECH_SEED))
|
|
|
|
; Clear Toxic, Reflect, and Light Screen
|
|
ld [hli], a
|
|
ld a, [hl]
|
|
and %11110000 | (1 << SUBSTATUS_TRANSFORMED)
|
|
ld [hl], a
|
|
|
|
; Now do likewise for the enemy
|
|
ld hl, wEnemySubStatus3
|
|
res SUBSTATUS_CONFUSED, [hl]
|
|
|
|
inc hl
|
|
ld a, [hl]
|
|
and ~((1 << SUBSTATUS_X_ACCURACY) | (1 << SUBSTATUS_MIST) | (1 << SUBSTATUS_FOCUS_ENERGY) | (1 << SUBSTATUS_LEECH_SEED))
|
|
|
|
ld [hli], a
|
|
ld a, [hl]
|
|
and %11110000 | (1 << SUBSTATUS_TRANSFORMED)
|
|
ld [hl], a
|
|
|
|
call LoadMoveAnim
|
|
ld hl, EliminatedStatsText
|
|
jp PrintText
|
|
|
|
.Fill
|
|
ld b, 8
|
|
|
|
.fill_loop
|
|
ld [hli], a
|
|
dec b
|
|
jr nz, .fill_loop
|
|
ret
|
|
|
|
.CopyStats:
|
|
ld b, 8
|
|
|
|
.copy_stats_loop
|
|
ld a, [hli]
|
|
ld [de], a
|
|
inc de
|
|
dec b
|
|
jr nz, .copy_stats_loop
|
|
ret
|
|
|
|
EliminatedStatsText:
|
|
text "すべての ステータスが"
|
|
line "もとに もどった!"
|
|
prompt
|
|
|
|
BattleCommand_Heal:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld de, wBattleMonHP
|
|
ld hl, wBattleMonMaxHP
|
|
ld a, [wPlayerMoveStruct]
|
|
jr z, .got_hp
|
|
ld de, wEnemyMonHP
|
|
ld hl, wEnemyMonMaxHP
|
|
ld a, [wEnemyMoveStruct]
|
|
|
|
.got_hp
|
|
ld b, a
|
|
ld a, [de]
|
|
cp [hl]
|
|
inc de
|
|
inc hl
|
|
ld a, [de]
|
|
sbc [hl]
|
|
jp z, .hp_full
|
|
ld a, b
|
|
cp MOVE_REST
|
|
jr nz, .not_rest
|
|
|
|
push hl
|
|
push de
|
|
push af
|
|
call BattleCommand_MoveDelay
|
|
ld hl, wBattleMonStatus
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_status
|
|
ld hl, wEnemyMonStatus
|
|
|
|
.got_status
|
|
ld a, [hl]
|
|
and a
|
|
ld [hl], REST_SLEEP_TURNS
|
|
ld hl, WentToSleepText
|
|
jr z, .no_status_to_heal
|
|
ld hl, RestedText
|
|
.no_status_to_heal
|
|
call PrintText
|
|
pop af
|
|
pop de
|
|
pop hl
|
|
|
|
.not_rest
|
|
jr z, .restore_full_hp
|
|
callfar GetHalfMaxHP
|
|
jr .finish
|
|
|
|
.restore_full_hp
|
|
callfar GetMaxHP
|
|
|
|
.finish
|
|
call LoadMoveAnim
|
|
ldh a, [hBattleTurn]
|
|
push af
|
|
xor 1
|
|
ldh [hBattleTurn], a
|
|
callfar RestoreHP
|
|
pop af
|
|
ldh [hBattleTurn], a
|
|
ld hl, UpdateBattleHuds
|
|
call CallFromBank0F
|
|
ld hl, RegainedHealthText
|
|
jp PrintText
|
|
|
|
.hp_full
|
|
call BattleCommand_MoveDelay
|
|
jp PrintButItFailed
|
|
|
|
WentToSleepText:
|
|
text "<USER>は"
|
|
line "ねむりはじめた!"
|
|
done
|
|
|
|
RestedText:
|
|
text "<USER>は けんこうになって"
|
|
line "ねむりはじめた!"
|
|
done
|
|
|
|
RegainedHealthText:
|
|
text "<USER>は たいりょくを"
|
|
line "かいふくした!"
|
|
prompt
|
|
|
|
INCLUDE "engine/battle/move_effects/transform.asm"
|
|
|
|
BattleCommand_Screen:
|
|
ld hl, wPlayerSubStatus5
|
|
ld de, wPlayerMoveStructEffect
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_substatus
|
|
ld hl, wEnemySubStatus5
|
|
ld de, wEnemyMoveStructEffect
|
|
|
|
.got_substatus
|
|
ld a, [de]
|
|
; BUG: Uses the old Gen 1 index for EFFECT_LIGHT_SCREEN.
|
|
; This causes Light Screen to have the same effect as Reflect in this build.
|
|
cp EFFECT_REFLECT - 1
|
|
jr nz, .Reflect
|
|
|
|
bit SUBSTATUS_LIGHT_SCREEN, [hl]
|
|
jr nz, .failed
|
|
set SUBSTATUS_LIGHT_SCREEN, [hl]
|
|
ld hl, LightScreenEffectText
|
|
jr .good
|
|
|
|
.Reflect
|
|
bit SUBSTATUS_REFLECT, [hl]
|
|
jr nz, .failed
|
|
set SUBSTATUS_REFLECT, [hl]
|
|
ld hl, ReflectEffectText
|
|
|
|
.good
|
|
push hl
|
|
call LoadMoveAnim
|
|
pop hl
|
|
jp PrintText
|
|
|
|
.failed
|
|
call BattleCommand_MoveDelay
|
|
jp PrintButItFailed
|
|
|
|
LightScreenEffectText:
|
|
text "<USER>は"
|
|
line "とくしゅこうげきに つよくなった!"
|
|
prompt
|
|
|
|
ReflectEffectText:
|
|
text "<USER>は"
|
|
line "だげきこうげきに つよくなった!"
|
|
prompt
|
|
|
|
; Hasn't been split into "can't go any higher/lower!" yet
|
|
PrintNoChangesText:
|
|
ld hl, NoChangesText
|
|
jp PrintText
|
|
|
|
NoChangesText:
|
|
text "しかし こうかが なかった!"
|
|
prompt
|
|
|
|
PrintNothingHappenedText:
|
|
ld hl, NothingHappenedText
|
|
jp PrintText
|
|
|
|
NothingHappenedText:
|
|
text "しかし なにもおこらない"
|
|
prompt
|
|
|
|
TryPrintButItFailed:
|
|
ld a, [wAlreadyFailed]
|
|
and a
|
|
ret nz
|
|
|
|
PrintButItFailed:
|
|
ld hl, ButItFailedText
|
|
jp PrintText
|
|
|
|
ButItFailedText:
|
|
text "しかし うまく きまらなかった!"
|
|
prompt
|
|
|
|
PrintDidntAffectText:
|
|
ld hl, DidntAffectText
|
|
jp PrintText
|
|
|
|
DidntAffectText:
|
|
text "しかし <TARGET>には"
|
|
line "きかなかった!"
|
|
prompt
|
|
|
|
IsUnaffectedText:
|
|
text "<TARGET>は"
|
|
line "へいきな かおを している!"
|
|
prompt
|
|
|
|
PrintParalyze:
|
|
ld hl, ParalyzedText
|
|
jp PrintText
|
|
|
|
ParalyzedText:
|
|
text "<TARGET>は まひして"
|
|
line "わざが でにくくなった!"
|
|
prompt
|
|
|
|
ProtectedByText:
|
|
text "<TARGET>は "
|
|
line "@"
|
|
text_from_ram wStringBuffer1
|
|
text "で まもられてる!"
|
|
prompt
|
|
|
|
CheckSubstituteOpp:
|
|
push hl
|
|
ld hl, wEnemySubStatus4
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .player_turn
|
|
ld hl, wPlayerSubStatus4
|
|
|
|
.player_turn:
|
|
bit SUBSTATUS_SUBSTITUTE, [hl]
|
|
pop hl
|
|
ret
|
|
|
|
INCLUDE "engine/battle/move_effects/selfdestruct.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/mirror_move.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/metronome.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/thief.asm"
|
|
|
|
BattleCommand_ArenaTrap:
|
|
ld hl, wEnemySubStatus5
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_substatus
|
|
ld hl, wPlayerSubStatus5
|
|
|
|
.got_substatus
|
|
; Doesn't work on an absent opponent.
|
|
call CheckHiddenOpponent
|
|
jr nz, .failed
|
|
|
|
; Don't trap if the opponent is already trapped.
|
|
bit SUBSTATUS_CANT_RUN, [hl]
|
|
jr nz, .failed
|
|
|
|
; Otherwise trap the opponent.
|
|
set SUBSTATUS_CANT_RUN, [hl]
|
|
call LoadMoveAnim
|
|
ld hl, .CantEscapeNowText
|
|
jp PrintText
|
|
|
|
.CantEscapeNowText:
|
|
text "<TARGET>は"
|
|
line "もう にげられない!"
|
|
prompt
|
|
|
|
.failed
|
|
call BattleCommand_MoveDelay
|
|
jp PrintButItFailed
|
|
|
|
INCLUDE "engine/battle/move_effects/nightmare.asm"
|
|
|
|
; Thaw the user.
|
|
BattleCommand_Defrost:
|
|
ld hl, wPartyMon1Status
|
|
ld a, [wCurBattleMon]
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
ld d, h
|
|
ld e, l
|
|
ld hl, wBattleMonStatus
|
|
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_battle_vars
|
|
|
|
ld hl, wOTPartyMon1Status
|
|
ld a, [wCurOTMon]
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
ld d, h
|
|
ld e, l
|
|
ld hl, wEnemyMonStatus
|
|
|
|
.got_battle_vars
|
|
bit FRZ, [hl]
|
|
ret z
|
|
|
|
res FRZ, [hl]
|
|
ld a, [de]
|
|
res FRZ, a
|
|
ld [de], a
|
|
|
|
ld hl, WasDefrostedText
|
|
call PrintText
|
|
ret
|
|
|
|
WasDefrostedText:
|
|
text "<USER>の"
|
|
line "こおりが とけた!"
|
|
prompt
|
|
|
|
INCLUDE "engine/battle/move_effects/nail_down.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/protect.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/spikes.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/foresight.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/perish_song.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/sandstorm.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/endure.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/rollout.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/swagger.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/fury_cutter.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/attract.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/return.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/present.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/frustration.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/safeguard.asm"
|
|
|
|
SafeCheckSafeguard:
|
|
ld hl, wEnemyScreens
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_turn
|
|
ld hl, wPlayerScreens
|
|
|
|
.got_turn
|
|
bit SCREENS_SAFEGUARD, [hl]
|
|
ret
|
|
|
|
BattleCommand_CheckSafeguard:
|
|
ld hl, wEnemyScreens
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .got_turn
|
|
ld hl, wPlayerScreens
|
|
|
|
.got_turn
|
|
bit SCREENS_SAFEGUARD, [hl]
|
|
ret z
|
|
|
|
ld a, 1
|
|
ld [wAttackMissed], a
|
|
call BattleCommand_MoveDelay
|
|
ld hl, SafeguardProtectText
|
|
jp PrintText
|
|
|
|
SafeguardProtectText:
|
|
text "<TARGET>は"
|
|
line "しんぴのベールに まもられている!"
|
|
prompt
|
|
|
|
INCLUDE "engine/battle/move_effects/magnitude.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/baton_pass.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/pursuit.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/rapid_spin.asm"
|
|
|
|
BattleCommand_HealMorn:
|
|
lb de, MORN_F, MORN_F
|
|
jr BattleCommand_TimeBasedHealContinue
|
|
|
|
BattleCommand_HealDay:
|
|
lb de, DAY_F, DAY_F
|
|
jr BattleCommand_TimeBasedHealContinue
|
|
|
|
BattleCommand_HealNite:
|
|
lb de, NITE_F, DARKNESS_F
|
|
; fallthrough
|
|
|
|
; Restores random amount between 1/2 max HP to full max HP during certain times.
|
|
; Simply heals 1/2 HP otherwise.
|
|
BattleCommand_TimeBasedHealContinue:
|
|
push de
|
|
callfar GetMaxHP
|
|
pop de
|
|
|
|
ld a, [wTimeOfDay]
|
|
cp d
|
|
jr z, .start
|
|
|
|
ld a, [wTimeOfDay]
|
|
cp e
|
|
jr z, .start
|
|
callfar GetHalfMaxHP
|
|
|
|
.start
|
|
call BattleRandom
|
|
set 7, a
|
|
ldh [hMultiplier], a
|
|
xor a
|
|
ldh [hMultiplicand], a
|
|
ld a, b
|
|
ldh [hMultiplicand + 1], a
|
|
ld a, c
|
|
ldh [hMultiplicand + 2], a
|
|
call Multiply
|
|
|
|
ld a, $ff
|
|
ldh [hDivisor], a
|
|
ld b, 4
|
|
call Divide
|
|
|
|
ldh a, [hQuotient + 2]
|
|
ld b, a
|
|
ldh a, [hQuotient + 3]
|
|
ld c, a
|
|
call LoadMoveAnim
|
|
|
|
ldh a, [hBattleTurn]
|
|
push af
|
|
xor 1
|
|
ldh [hBattleTurn], a
|
|
callfar RestoreHP
|
|
pop af
|
|
ldh [hBattleTurn], a
|
|
|
|
ld hl, .RegainedHealthText
|
|
call PrintText
|
|
ret
|
|
|
|
.RegainedHealthText
|
|
text "<USER>は たいりょくを"
|
|
line "かいふくした!"
|
|
prompt
|
|
|
|
INCLUDE "engine/battle/move_effects/hidden_power.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/rain_dance.asm"
|
|
|
|
INCLUDE "engine/battle/move_effects/sunny_day.asm"
|
|
|
|
; This function increments the current move's PP.
|
|
; It's used to prevent moves that run another move within the same turn
|
|
; (like Mirror Move and Metronome) from losing 2 PP.
|
|
IncrementMovePP:
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld hl, wBattleMonPP
|
|
ld de, wPartyMon1PP
|
|
ld a, [wCurMoveNum]
|
|
jr z, .ok
|
|
ld hl, wEnemyMonPP
|
|
ld de, wOTPartyMon1PP
|
|
ld a, [wCurEnemyMoveNum]
|
|
|
|
.ok
|
|
ld b, 0
|
|
ld c, a
|
|
add hl, bc
|
|
inc [hl]
|
|
ld h, d
|
|
ld l, e
|
|
add hl, bc
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wCurBattleMon]
|
|
jr z, .update_pp
|
|
ld a, [wEnemyMonStatus]
|
|
|
|
.update_pp
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
inc [hl]
|
|
ret
|
|
|
|
CheckHiddenOpponent:
|
|
push hl
|
|
ld hl, wEnemySubStatus3
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr z, .player_turn
|
|
ld hl, wPlayerSubStatus3
|
|
.player_turn
|
|
bit SUBSTATUS_INVULNERABLE, [hl]
|
|
pop hl
|
|
ret
|
|
|
|
GetUserItem:
|
|
ld hl, wBattleMonItem
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp z, .go
|
|
ld hl, wEnemyMonItem
|
|
|
|
.go
|
|
ld b, [hl]
|
|
jp GetItemHeldEffect
|
|
|
|
GetOpponentItem:
|
|
ld hl, wEnemyMonItem
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jp z, .go
|
|
ld hl, wBattleMonItem
|
|
|
|
.go
|
|
ld b, [hl]
|
|
jp GetItemHeldEffect
|
|
|
|
GetItemHeldEffect:
|
|
ld a, b
|
|
and a
|
|
ret z
|
|
|
|
push hl
|
|
push bc
|
|
ld hl, ItemAttributes + ITEMATTR_PARAM
|
|
|
|
dec a
|
|
ld c, a
|
|
ld b, 0
|
|
add hl, bc
|
|
add hl, bc
|
|
add hl, bc
|
|
add hl, bc
|
|
add hl, bc
|
|
add hl, bc
|
|
add hl, bc
|
|
|
|
ld a, BANK(ItemAttributes)
|
|
call GetFarByte
|
|
|
|
pop bc
|
|
ld c, a
|
|
dec hl
|
|
ld a, BANK(ItemAttributes)
|
|
call GetFarByte
|
|
|
|
ld b, a
|
|
pop hl
|
|
ret
|
|
|
|
ConsumeHeldItem:
|
|
push hl
|
|
push de
|
|
push bc
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld hl, wOTPartyMon1Item
|
|
ld de, wEnemyMonItem
|
|
ld a, [wCurOTMon]
|
|
jr z, .their_turn
|
|
ld hl, wPartyMon1Item
|
|
ld de, wBattleMonItem
|
|
ld a, [wCurBattleMon]
|
|
|
|
.their_turn
|
|
push hl
|
|
push af
|
|
ld a, [de]
|
|
ld b, a
|
|
call GetItemHeldEffect
|
|
ld hl, ConsumableEffects
|
|
.loop
|
|
ld a, [hli]
|
|
cp b
|
|
jr z, .ok
|
|
inc a
|
|
jr nz, .loop
|
|
pop af
|
|
pop hl
|
|
pop bc
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
.ok
|
|
xor a
|
|
ld [de], a
|
|
pop af
|
|
pop hl
|
|
ld bc, PARTYMON_STRUCT_LENGTH
|
|
call AddNTimes
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
jr nz, .ourturn
|
|
ld a, [wBattleMode]
|
|
dec a
|
|
jr z, .done
|
|
|
|
.ourturn
|
|
ld [hl], 0
|
|
|
|
.done
|
|
pop bc
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
INCLUDE "data/battle/held_consumables.asm"
|
|
|
|
PrintUsersItemActivated:
|
|
push hl
|
|
push de
|
|
push bc
|
|
ld [wNamedObjectIndexBuffer], a
|
|
call GetItemName
|
|
ld hl, BattleText_UsersStringBuffer1Activated
|
|
call PrintText
|
|
pop bc
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
BattleText_UsersStringBuffer1Activated:
|
|
text "そうびしていた"
|
|
line "@"
|
|
text_from_ram wStringBuffer1
|
|
text "が さどうした!"
|
|
prompt
|
|
|
|
PlayDamageAnim:
|
|
xor a
|
|
ld [wFXAnimID + 1], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStructAnimation]
|
|
jr z, .player
|
|
ld a, [wEnemyMoveStructAnimation]
|
|
|
|
.player:
|
|
and a
|
|
ret z
|
|
ld [wFXAnimID], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, 6 ; BATTLEANIM_ENEMY_DAMAGE
|
|
jr z, .player_damage
|
|
ld a, 3 ; BATTLEANIM_PLAYER_DAMAGE
|
|
|
|
.player_damage:
|
|
ld [wNumHits], a
|
|
jp PlayUserBattleAnim
|
|
|
|
LoadMoveAnim:
|
|
xor a
|
|
ld [wNumHits], a
|
|
ld [wFXAnimID + 1], a
|
|
ldh a, [hBattleTurn]
|
|
and a
|
|
ld a, [wPlayerMoveStructAnimation]
|
|
jr z, .not_enemy_turn
|
|
ld a, [wEnemyMoveStructAnimation]
|
|
.not_enemy_turn
|
|
and a
|
|
ret z
|
|
; Fallthrough
|
|
LoadBattleAnim:
|
|
ld [wFXAnimID], a
|
|
; Fallthrough
|
|
PlayUserBattleAnim:
|
|
push hl
|
|
push de
|
|
push bc
|
|
callfar PlayBattleAnim
|
|
pop bc
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
PlayOpponentBattleAnim:
|
|
ld a, e
|
|
ld [wFXAnimID], a
|
|
ld a, d
|
|
ld [wFXAnimID + 1], a
|
|
xor a
|
|
ld [wNumHits], a
|
|
|
|
push hl
|
|
push de
|
|
push bc
|
|
ldh a, [hBattleTurn]
|
|
push af
|
|
xor 1
|
|
ldh [hBattleTurn], a
|
|
callfar PlayBattleAnim
|
|
|
|
pop af
|
|
ldh [hBattleTurn], a
|
|
pop bc
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
CallFromBank0F:
|
|
ld a, $f
|
|
jp FarCall_hl
|
|
|
|
BattleCommand_MoveDelay:
|
|
ld c, 50
|
|
jp DelayFrames
|
|
|
|
BattleCommand_ClearText:
|
|
ld hl, .text
|
|
jp PrintText
|
|
|
|
.text:
|
|
text_end
|
|
|
|
SkipToBattleCommand:
|
|
ld a, [wBattleScriptBufferAddress + 1]
|
|
ld h, a
|
|
ld a, [wBattleScriptBufferAddress]
|
|
ld l, a
|
|
.loop
|
|
ld a, [hli]
|
|
cp b
|
|
jr nz, .loop
|
|
ld a, h
|
|
ld [wBattleScriptBufferAddress + 1], a
|
|
ld a, l
|
|
ld [wBattleScriptBufferAddress], a
|
|
ret
|