mirror of
https://github.com/thornAvery/jep-hack.git
synced 2026-02-07 00:25:24 +13:00
First Commit
Upload literally everything from the pokecrystal16 expand-move-ID branch
This commit is contained in:
commit
2f8a41f833
4618 changed files with 480386 additions and 0 deletions
845
engine/battle/ai/items.asm
Normal file
845
engine/battle/ai/items.asm
Normal file
|
|
@ -0,0 +1,845 @@
|
|||
AI_SwitchOrTryItem:
|
||||
and a
|
||||
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
ret z
|
||||
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
farcall CheckEnemyLockedIn
|
||||
ret nz
|
||||
|
||||
ld a, [wPlayerSubStatus5]
|
||||
bit SUBSTATUS_CANT_RUN, a
|
||||
jr nz, DontSwitch
|
||||
|
||||
ld a, [wEnemyWrapCount]
|
||||
and a
|
||||
jr nz, DontSwitch
|
||||
|
||||
; always load the first trainer class in wTrainerClass for Battle Tower trainers
|
||||
ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH
|
||||
ld a, [wInBattleTowerBattle]
|
||||
and a
|
||||
jr nz, .ok
|
||||
|
||||
ld a, [wTrainerClass]
|
||||
dec a
|
||||
ld bc, NUM_TRAINER_ATTRIBUTES
|
||||
call AddNTimes
|
||||
|
||||
.ok
|
||||
bit SWITCH_OFTEN_F, [hl]
|
||||
jp nz, SwitchOften
|
||||
bit SWITCH_RARELY_F, [hl]
|
||||
jp nz, SwitchRarely
|
||||
bit SWITCH_SOMETIMES_F, [hl]
|
||||
jp nz, SwitchSometimes
|
||||
; fallthrough
|
||||
|
||||
DontSwitch:
|
||||
call AI_TryItem
|
||||
ret
|
||||
|
||||
SwitchOften:
|
||||
callfar CheckAbleToSwitch
|
||||
ld a, [wEnemySwitchMonParam]
|
||||
and $f0
|
||||
jp z, DontSwitch
|
||||
|
||||
cp $10
|
||||
jr nz, .not_10
|
||||
call Random
|
||||
cp 50 percent + 1
|
||||
jr c, .switch
|
||||
jp DontSwitch
|
||||
.not_10
|
||||
|
||||
cp $20
|
||||
jr nz, .not_20
|
||||
call Random
|
||||
cp 79 percent - 1
|
||||
jr c, .switch
|
||||
jp DontSwitch
|
||||
.not_20
|
||||
|
||||
; $30
|
||||
call Random
|
||||
cp 4 percent
|
||||
jp c, DontSwitch
|
||||
|
||||
.switch
|
||||
ld a, [wEnemySwitchMonParam]
|
||||
and $f
|
||||
inc a
|
||||
; In register 'a' is the number (1-6) of the mon to switch to
|
||||
ld [wEnemySwitchMonIndex], a
|
||||
jp AI_TrySwitch
|
||||
|
||||
SwitchRarely:
|
||||
callfar CheckAbleToSwitch
|
||||
ld a, [wEnemySwitchMonParam]
|
||||
and $f0
|
||||
jp z, DontSwitch
|
||||
|
||||
cp $10
|
||||
jr nz, .not_10
|
||||
call Random
|
||||
cp 8 percent
|
||||
jr c, .switch
|
||||
jp DontSwitch
|
||||
.not_10
|
||||
|
||||
cp $20
|
||||
jr nz, .not_20
|
||||
call Random
|
||||
cp 12 percent
|
||||
jr c, .switch
|
||||
jp DontSwitch
|
||||
.not_20
|
||||
|
||||
; $30
|
||||
call Random
|
||||
cp 79 percent - 1
|
||||
jp c, DontSwitch
|
||||
|
||||
.switch
|
||||
ld a, [wEnemySwitchMonParam]
|
||||
and $f
|
||||
inc a
|
||||
ld [wEnemySwitchMonIndex], a
|
||||
jp AI_TrySwitch
|
||||
|
||||
SwitchSometimes:
|
||||
callfar CheckAbleToSwitch
|
||||
ld a, [wEnemySwitchMonParam]
|
||||
and $f0
|
||||
jp z, DontSwitch
|
||||
|
||||
cp $10
|
||||
jr nz, .not_10
|
||||
call Random
|
||||
cp 20 percent - 1
|
||||
jr c, .switch
|
||||
jp DontSwitch
|
||||
.not_10
|
||||
|
||||
cp $20
|
||||
jr nz, .not_20
|
||||
call Random
|
||||
cp 50 percent + 1
|
||||
jr c, .switch
|
||||
jp DontSwitch
|
||||
.not_20
|
||||
|
||||
; $30
|
||||
call Random
|
||||
cp 20 percent - 1
|
||||
jp c, DontSwitch
|
||||
|
||||
.switch
|
||||
ld a, [wEnemySwitchMonParam]
|
||||
and $f
|
||||
inc a
|
||||
ld [wEnemySwitchMonIndex], a
|
||||
jp AI_TrySwitch
|
||||
|
||||
CheckSubstatusCantRun: ; unreferenced
|
||||
ld a, [wEnemySubStatus5]
|
||||
bit SUBSTATUS_CANT_RUN, a
|
||||
ret
|
||||
|
||||
AI_TryItem:
|
||||
; items are not allowed in the Battle Tower
|
||||
ld a, [wInBattleTowerBattle]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
ld a, [wEnemyTrainerItem1]
|
||||
ld b, a
|
||||
ld a, [wEnemyTrainerItem2]
|
||||
or b
|
||||
ret z
|
||||
|
||||
call .IsHighestLevel
|
||||
ret nc
|
||||
|
||||
ld a, [wTrainerClass]
|
||||
dec a
|
||||
ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH
|
||||
ld bc, NUM_TRAINER_ATTRIBUTES
|
||||
call AddNTimes
|
||||
ld b, h
|
||||
ld c, l
|
||||
ld hl, AI_Items
|
||||
ld de, wEnemyTrainerItem1
|
||||
.loop
|
||||
ld a, [hl]
|
||||
and a
|
||||
inc a
|
||||
ret z
|
||||
|
||||
ld a, [de]
|
||||
cp [hl]
|
||||
jr z, .has_item
|
||||
inc de
|
||||
ld a, [de]
|
||||
cp [hl]
|
||||
jr z, .has_item
|
||||
|
||||
dec de
|
||||
inc hl
|
||||
inc hl
|
||||
inc hl
|
||||
jr .loop
|
||||
|
||||
.has_item
|
||||
inc hl
|
||||
|
||||
push hl
|
||||
push de
|
||||
ld de, .callback
|
||||
push de
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
jp hl
|
||||
.callback
|
||||
pop de
|
||||
pop hl
|
||||
|
||||
inc hl
|
||||
inc hl
|
||||
jr c, .loop
|
||||
|
||||
; used item
|
||||
xor a
|
||||
ld [de], a
|
||||
inc a
|
||||
ld [wEnemyGoesFirst], a
|
||||
|
||||
ld hl, wEnemySubStatus3
|
||||
res SUBSTATUS_BIDE, [hl]
|
||||
|
||||
xor a
|
||||
ld [wEnemyFuryCutterCount], a
|
||||
ld [wEnemyProtectCount], a
|
||||
ld [wEnemyRageCounter], a
|
||||
|
||||
ld hl, wEnemySubStatus4
|
||||
res SUBSTATUS_RAGE, [hl]
|
||||
|
||||
xor a
|
||||
ld [wLastEnemyCounterMove], a
|
||||
|
||||
scf
|
||||
ret
|
||||
|
||||
.IsHighestLevel:
|
||||
ld a, [wOTPartyCount]
|
||||
ld d, a
|
||||
ld e, 0
|
||||
ld hl, wOTPartyMon1Level
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
.next
|
||||
ld a, [hl]
|
||||
cp e
|
||||
jr c, .ok
|
||||
ld e, a
|
||||
.ok
|
||||
add hl, bc
|
||||
dec d
|
||||
jr nz, .next
|
||||
|
||||
ld a, [wCurOTMon]
|
||||
ld hl, wOTPartyMon1Level
|
||||
call AddNTimes
|
||||
ld a, [hl]
|
||||
cp e
|
||||
jr nc, .yes
|
||||
|
||||
.no ; unreferenced
|
||||
and a
|
||||
ret
|
||||
|
||||
.yes
|
||||
scf
|
||||
ret
|
||||
|
||||
AI_Items:
|
||||
dbw FULL_RESTORE, .FullRestore
|
||||
dbw MAX_POTION, .MaxPotion
|
||||
dbw HYPER_POTION, .HyperPotion
|
||||
dbw SUPER_POTION, .SuperPotion
|
||||
dbw POTION, .Potion
|
||||
dbw X_ACCURACY, .XAccuracy
|
||||
dbw FULL_HEAL, .FullHeal
|
||||
dbw GUARD_SPEC, .GuardSpec
|
||||
dbw DIRE_HIT, .DireHit
|
||||
dbw X_ATTACK, .XAttack
|
||||
dbw X_DEFEND, .XDefend
|
||||
dbw X_SPEED, .XSpeed
|
||||
dbw X_SPECIAL, .XSpecial
|
||||
db -1 ; end
|
||||
|
||||
.FullHeal:
|
||||
call .Status
|
||||
jp c, .DontUse
|
||||
call EnemyUsedFullHeal
|
||||
jp .Use
|
||||
|
||||
.Status:
|
||||
ld a, [wEnemyMonStatus]
|
||||
and a
|
||||
jp z, .DontUse
|
||||
|
||||
ld a, [bc]
|
||||
bit CONTEXT_USE_F, a
|
||||
jr nz, .StatusCheckContext
|
||||
ld a, [bc]
|
||||
bit ALWAYS_USE_F, a
|
||||
jp nz, .Use
|
||||
call Random
|
||||
cp 20 percent - 1
|
||||
jp c, .Use
|
||||
jp .DontUse
|
||||
|
||||
.StatusCheckContext:
|
||||
ld a, [wEnemySubStatus5]
|
||||
bit SUBSTATUS_TOXIC, a
|
||||
jr z, .FailToxicCheck
|
||||
ld a, [wEnemyToxicCount]
|
||||
cp 4
|
||||
jr c, .FailToxicCheck
|
||||
call Random
|
||||
cp 50 percent + 1
|
||||
jp c, .Use
|
||||
.FailToxicCheck:
|
||||
ld a, [wEnemyMonStatus]
|
||||
and 1 << FRZ | SLP_MASK
|
||||
jp z, .DontUse
|
||||
jp .Use
|
||||
|
||||
.FullRestore:
|
||||
call .HealItem
|
||||
jp nc, .UseFullRestore
|
||||
ld a, [bc]
|
||||
bit CONTEXT_USE_F, a
|
||||
jp z, .DontUse
|
||||
call .Status
|
||||
jp c, .DontUse
|
||||
|
||||
.UseFullRestore:
|
||||
call EnemyUsedFullRestore
|
||||
jp .Use
|
||||
|
||||
.MaxPotion:
|
||||
call .HealItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedMaxPotion
|
||||
jp .Use
|
||||
|
||||
.HealItem:
|
||||
ld a, [bc]
|
||||
bit CONTEXT_USE_F, a
|
||||
jr nz, .CheckHalfOrQuarterHP
|
||||
callfar AICheckEnemyHalfHP
|
||||
jp c, .DontUse
|
||||
ld a, [bc]
|
||||
bit UNKNOWN_USE_F, a
|
||||
jp nz, .CheckQuarterHP
|
||||
callfar AICheckEnemyQuarterHP
|
||||
jp nc, .UseHealItem
|
||||
call Random
|
||||
cp 50 percent + 1
|
||||
jp c, .UseHealItem
|
||||
jp .DontUse
|
||||
|
||||
.CheckQuarterHP:
|
||||
callfar AICheckEnemyQuarterHP
|
||||
jp c, .DontUse
|
||||
call Random
|
||||
cp 20 percent - 1
|
||||
jp c, .DontUse
|
||||
jr .UseHealItem
|
||||
|
||||
.CheckHalfOrQuarterHP:
|
||||
callfar AICheckEnemyHalfHP
|
||||
jp c, .DontUse
|
||||
callfar AICheckEnemyQuarterHP
|
||||
jp nc, .UseHealItem
|
||||
call Random
|
||||
cp 20 percent - 1
|
||||
jp nc, .DontUse
|
||||
|
||||
.UseHealItem:
|
||||
jp .Use
|
||||
|
||||
.HyperPotion:
|
||||
call .HealItem
|
||||
jp c, .DontUse
|
||||
ld b, 200
|
||||
call EnemyUsedHyperPotion
|
||||
jp .Use
|
||||
|
||||
.SuperPotion:
|
||||
call .HealItem
|
||||
jp c, .DontUse
|
||||
ld b, 50
|
||||
call EnemyUsedSuperPotion
|
||||
jp .Use
|
||||
|
||||
.Potion:
|
||||
call .HealItem
|
||||
jp c, .DontUse
|
||||
ld b, 20
|
||||
call EnemyUsedPotion
|
||||
jp .Use
|
||||
|
||||
; Everything up to "End unused" is unused
|
||||
|
||||
.UnusedHealItem: ; unreferenced
|
||||
; This has similar conditions to .HealItem
|
||||
callfar AICheckEnemyMaxHP
|
||||
jr c, .dont_use
|
||||
push bc
|
||||
ld de, wEnemyMonMaxHP + 1
|
||||
ld hl, wEnemyMonHP + 1
|
||||
ld a, [de]
|
||||
sub [hl]
|
||||
jr z, .check_40_percent
|
||||
dec hl
|
||||
dec de
|
||||
ld c, a
|
||||
sbc [hl]
|
||||
and a
|
||||
jr nz, .check_40_percent
|
||||
ld a, c
|
||||
cp b
|
||||
jp c, .check_50_percent
|
||||
callfar AICheckEnemyQuarterHP
|
||||
jr c, .check_40_percent
|
||||
|
||||
.check_50_percent
|
||||
pop bc
|
||||
ld a, [bc]
|
||||
bit UNKNOWN_USE_F, a
|
||||
jp z, .Use
|
||||
call Random
|
||||
cp 50 percent + 1
|
||||
jp c, .Use
|
||||
|
||||
.dont_use
|
||||
jp .DontUse
|
||||
|
||||
.check_40_percent
|
||||
pop bc
|
||||
ld a, [bc]
|
||||
bit UNKNOWN_USE_F, a
|
||||
jp z, .DontUse
|
||||
call Random
|
||||
cp 39 percent + 1
|
||||
jp c, .Use
|
||||
jp .DontUse
|
||||
|
||||
; End unused
|
||||
|
||||
.XAccuracy:
|
||||
call .XItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedXAccuracy
|
||||
jp .Use
|
||||
|
||||
.GuardSpec:
|
||||
call .XItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedGuardSpec
|
||||
jp .Use
|
||||
|
||||
.DireHit:
|
||||
call .XItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedDireHit
|
||||
jp .Use
|
||||
|
||||
.XAttack:
|
||||
call .XItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedXAttack
|
||||
jp .Use
|
||||
|
||||
.XDefend:
|
||||
call .XItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedXDefend
|
||||
jp .Use
|
||||
|
||||
.XSpeed:
|
||||
call .XItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedXSpeed
|
||||
jp .Use
|
||||
|
||||
.XSpecial:
|
||||
call .XItem
|
||||
jp c, .DontUse
|
||||
call EnemyUsedXSpecial
|
||||
jp .Use
|
||||
|
||||
.XItem:
|
||||
ld a, [wEnemyTurnsTaken]
|
||||
and a
|
||||
jr nz, .notfirstturnout
|
||||
ld a, [bc]
|
||||
bit ALWAYS_USE_F, a
|
||||
jp nz, .Use
|
||||
call Random
|
||||
cp 50 percent + 1
|
||||
jp c, .DontUse
|
||||
ld a, [bc]
|
||||
bit CONTEXT_USE_F, a
|
||||
jp nz, .Use
|
||||
call Random
|
||||
cp 50 percent + 1
|
||||
jp c, .DontUse
|
||||
jp .Use
|
||||
.notfirstturnout
|
||||
ld a, [bc]
|
||||
bit ALWAYS_USE_F, a
|
||||
jp z, .DontUse
|
||||
call Random
|
||||
cp 20 percent - 1
|
||||
jp nc, .DontUse
|
||||
jp .Use
|
||||
|
||||
.DontUse:
|
||||
scf
|
||||
ret
|
||||
|
||||
.Use:
|
||||
and a
|
||||
ret
|
||||
|
||||
AIUpdateHUD:
|
||||
call UpdateEnemyMonInParty
|
||||
farcall UpdateEnemyHUD
|
||||
ld a, $1
|
||||
ldh [hBGMapMode], a
|
||||
ld hl, wEnemyItemState
|
||||
dec [hl]
|
||||
scf
|
||||
ret
|
||||
|
||||
AIUsedItemSound:
|
||||
push de
|
||||
ld de, SFX_FULL_HEAL
|
||||
call PlaySFX
|
||||
pop de
|
||||
ret
|
||||
|
||||
EnemyUsedFullHeal:
|
||||
call AIUsedItemSound
|
||||
call AI_HealStatus
|
||||
ld a, FULL_HEAL
|
||||
jp PrintText_UsedItemOn_AND_AIUpdateHUD
|
||||
|
||||
EnemyUsedMaxPotion:
|
||||
ld a, MAX_POTION
|
||||
ld [wCurEnemyItem], a
|
||||
jr FullRestoreContinue
|
||||
|
||||
EnemyUsedFullRestore:
|
||||
; BUG: AI use of Full Heal does not cure confusion status (see docs/bugs_and_glitches.md)
|
||||
call AI_HealStatus
|
||||
ld a, FULL_RESTORE
|
||||
ld [wCurEnemyItem], a
|
||||
ld hl, wEnemySubStatus3
|
||||
res SUBSTATUS_CONFUSED, [hl]
|
||||
xor a
|
||||
ld [wEnemyConfuseCount], a
|
||||
; fallthrough
|
||||
|
||||
FullRestoreContinue:
|
||||
ld de, wCurHPAnimOldHP
|
||||
ld hl, wEnemyMonHP + 1
|
||||
ld a, [hld]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld a, [hl]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld hl, wEnemyMonMaxHP + 1
|
||||
ld a, [hld]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld [wCurHPAnimMaxHP], a
|
||||
ld [wEnemyMonHP + 1], a
|
||||
ld a, [hl]
|
||||
ld [de], a
|
||||
ld [wCurHPAnimMaxHP + 1], a
|
||||
ld [wEnemyMonHP], a
|
||||
jr EnemyPotionFinish
|
||||
|
||||
EnemyUsedPotion:
|
||||
ld a, POTION
|
||||
ld b, 20
|
||||
jr EnemyPotionContinue
|
||||
|
||||
EnemyUsedSuperPotion:
|
||||
ld a, SUPER_POTION
|
||||
ld b, 50
|
||||
jr EnemyPotionContinue
|
||||
|
||||
EnemyUsedHyperPotion:
|
||||
ld a, HYPER_POTION
|
||||
ld b, 200
|
||||
|
||||
EnemyPotionContinue:
|
||||
ld [wCurEnemyItem], a
|
||||
ld hl, wEnemyMonHP + 1
|
||||
ld a, [hl]
|
||||
ld [wCurHPAnimOldHP], a
|
||||
add b
|
||||
ld [hld], a
|
||||
ld [wCurHPAnimNewHP], a
|
||||
ld a, [hl]
|
||||
ld [wCurHPAnimOldHP + 1], a
|
||||
ld [wCurHPAnimNewHP + 1], a
|
||||
jr nc, .ok
|
||||
inc a
|
||||
ld [hl], a
|
||||
ld [wCurHPAnimNewHP + 1], a
|
||||
.ok
|
||||
inc hl
|
||||
ld a, [hld]
|
||||
ld b, a
|
||||
ld de, wEnemyMonMaxHP + 1
|
||||
ld a, [de]
|
||||
dec de
|
||||
ld [wCurHPAnimMaxHP], a
|
||||
sub b
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [de]
|
||||
ld [wCurHPAnimMaxHP + 1], a
|
||||
sbc b
|
||||
jr nc, EnemyPotionFinish
|
||||
inc de
|
||||
ld a, [de]
|
||||
dec de
|
||||
ld [hld], a
|
||||
ld [wCurHPAnimNewHP], a
|
||||
ld a, [de]
|
||||
ld [hl], a
|
||||
ld [wCurHPAnimNewHP + 1], a
|
||||
|
||||
EnemyPotionFinish:
|
||||
call PrintText_UsedItemOn
|
||||
hlcoord 2, 2
|
||||
xor a
|
||||
ld [wWhichHPBar], a
|
||||
call AIUsedItemSound
|
||||
predef AnimateHPBar
|
||||
jp AIUpdateHUD
|
||||
|
||||
AI_TrySwitch:
|
||||
; Determine whether the AI can switch based on how many Pokemon are still alive.
|
||||
; If it can switch, it will.
|
||||
ld a, [wOTPartyCount]
|
||||
ld c, a
|
||||
ld hl, wOTPartyMon1HP
|
||||
ld d, 0
|
||||
.SwitchLoop:
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hld]
|
||||
or b
|
||||
jr z, .fainted
|
||||
inc d
|
||||
.fainted
|
||||
push bc
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
dec c
|
||||
jr nz, .SwitchLoop
|
||||
|
||||
ld a, d
|
||||
cp 2
|
||||
jp nc, AI_Switch
|
||||
and a
|
||||
ret
|
||||
|
||||
AI_Switch:
|
||||
ld a, $1
|
||||
ld [wEnemyIsSwitching], a
|
||||
ld [wEnemyGoesFirst], a
|
||||
ld hl, wEnemySubStatus4
|
||||
res SUBSTATUS_RAGE, [hl]
|
||||
xor a
|
||||
ldh [hBattleTurn], a
|
||||
callfar PursuitSwitch
|
||||
|
||||
push af
|
||||
ld a, [wCurOTMon]
|
||||
ld hl, wOTPartyMon1Status
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
call AddNTimes
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld hl, wEnemyMonStatus
|
||||
ld bc, MON_MAXHP - MON_STATUS
|
||||
call CopyBytes
|
||||
pop af
|
||||
|
||||
jr c, .skiptext
|
||||
ld hl, EnemyWithdrewText
|
||||
call PrintText
|
||||
|
||||
.skiptext
|
||||
ld a, 1
|
||||
ld [wBattleHasJustStarted], a
|
||||
callfar NewEnemyMonStatus
|
||||
callfar ResetEnemyStatLevels
|
||||
ld hl, wPlayerSubStatus1
|
||||
res SUBSTATUS_IN_LOVE, [hl]
|
||||
farcall EnemySwitch
|
||||
farcall ResetBattleParticipants
|
||||
xor a
|
||||
ld [wBattleHasJustStarted], a
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret nz
|
||||
scf
|
||||
ret
|
||||
|
||||
EnemyWithdrewText:
|
||||
text_far _EnemyWithdrewText
|
||||
text_end
|
||||
|
||||
EnemyUsedFullHealRed: ; unreferenced
|
||||
call AIUsedItemSound
|
||||
call AI_HealStatus
|
||||
ld a, FULL_HEAL_RED ; X_SPEED
|
||||
jp PrintText_UsedItemOn_AND_AIUpdateHUD
|
||||
|
||||
AI_HealStatus:
|
||||
; BUG: AI use of Full Heal or Full Restore does not cure Nightmare status (see docs/bugs_and_glitches.md)
|
||||
ld a, [wCurOTMon]
|
||||
ld hl, wOTPartyMon1Status
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
call AddNTimes
|
||||
xor a
|
||||
ld [hl], a
|
||||
ld [wEnemyMonStatus], a
|
||||
ld hl, wEnemySubStatus5
|
||||
res SUBSTATUS_TOXIC, [hl]
|
||||
ret
|
||||
|
||||
EnemyUsedXAccuracy:
|
||||
call AIUsedItemSound
|
||||
ld hl, wEnemySubStatus4
|
||||
set SUBSTATUS_X_ACCURACY, [hl]
|
||||
ld a, X_ACCURACY
|
||||
jp PrintText_UsedItemOn_AND_AIUpdateHUD
|
||||
|
||||
EnemyUsedGuardSpec:
|
||||
call AIUsedItemSound
|
||||
ld hl, wEnemySubStatus4
|
||||
set SUBSTATUS_MIST, [hl]
|
||||
ld a, GUARD_SPEC
|
||||
jp PrintText_UsedItemOn_AND_AIUpdateHUD
|
||||
|
||||
EnemyUsedDireHit:
|
||||
call AIUsedItemSound
|
||||
ld hl, wEnemySubStatus4
|
||||
set SUBSTATUS_FOCUS_ENERGY, [hl]
|
||||
ld a, DIRE_HIT
|
||||
jp PrintText_UsedItemOn_AND_AIUpdateHUD
|
||||
|
||||
AICheckEnemyFractionMaxHP: ; unreferenced
|
||||
; Input: a = divisor
|
||||
; Work: bc = [wEnemyMonMaxHP] / a
|
||||
; Work: de = [wEnemyMonHP]
|
||||
; Output:
|
||||
; - c, nz if [wEnemyMonHP] > [wEnemyMonMaxHP] / a
|
||||
; - nc, z if [wEnemyMonHP] = [wEnemyMonMaxHP] / a
|
||||
; - nc, nz if [wEnemyMonHP] < [wEnemyMonMaxHP] / a
|
||||
ldh [hDivisor], a
|
||||
ld hl, wEnemyMonMaxHP
|
||||
ld a, [hli]
|
||||
ldh [hDividend], a
|
||||
ld a, [hl]
|
||||
ldh [hDividend + 1], a
|
||||
ld b, 2
|
||||
call Divide
|
||||
ldh a, [hQuotient + 3]
|
||||
ld c, a
|
||||
ldh a, [hQuotient + 2]
|
||||
ld b, a
|
||||
ld hl, wEnemyMonHP + 1
|
||||
ld a, [hld]
|
||||
ld e, a
|
||||
ld a, [hl]
|
||||
ld d, a
|
||||
ld a, d
|
||||
sub b
|
||||
ret nz
|
||||
ld a, e
|
||||
sub c
|
||||
ret
|
||||
|
||||
EnemyUsedXAttack:
|
||||
ld b, ATTACK
|
||||
ld a, X_ATTACK
|
||||
jr EnemyUsedXItem
|
||||
|
||||
EnemyUsedXDefend:
|
||||
ld b, DEFENSE
|
||||
ld a, X_DEFEND
|
||||
jr EnemyUsedXItem
|
||||
|
||||
EnemyUsedXSpeed:
|
||||
ld b, SPEED
|
||||
ld a, X_SPEED
|
||||
jr EnemyUsedXItem
|
||||
|
||||
EnemyUsedXSpecial:
|
||||
ld b, SP_ATTACK
|
||||
ld a, X_SPECIAL
|
||||
|
||||
; Parameter
|
||||
; a = ITEM_CONSTANT
|
||||
; b = BATTLE_CONSTANT (ATTACK, DEFENSE, SPEED, SP_ATTACK, SP_DEFENSE, ACCURACY, EVASION)
|
||||
EnemyUsedXItem:
|
||||
ld [wCurEnemyItem], a
|
||||
push bc
|
||||
call PrintText_UsedItemOn
|
||||
pop bc
|
||||
farcall RaiseStat
|
||||
jp AIUpdateHUD
|
||||
|
||||
; Parameter
|
||||
; a = ITEM_CONSTANT
|
||||
PrintText_UsedItemOn_AND_AIUpdateHUD:
|
||||
ld [wCurEnemyItem], a
|
||||
call PrintText_UsedItemOn
|
||||
jp AIUpdateHUD
|
||||
|
||||
PrintText_UsedItemOn:
|
||||
ld a, [wCurEnemyItem]
|
||||
ld [wNamedObjectIndex], a
|
||||
call GetItemName
|
||||
ld hl, wStringBuffer1
|
||||
ld de, wMonOrItemNameBuffer
|
||||
ld bc, ITEM_NAME_LENGTH
|
||||
call CopyBytes
|
||||
ld hl, EnemyUsedOnText
|
||||
jp PrintText
|
||||
|
||||
EnemyUsedOnText:
|
||||
text_far _EnemyUsedOnText
|
||||
text_end
|
||||
217
engine/battle/ai/move.asm
Normal file
217
engine/battle/ai/move.asm
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
AIChooseMove:
|
||||
; Score each move of wEnemyMonMoves in wEnemyAIMoveScores. Lower is better.
|
||||
; Pick the move with the lowest score.
|
||||
|
||||
; Wildmons attack at random.
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
ret z
|
||||
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; No use picking a move if there's no choice.
|
||||
farcall CheckEnemyLockedIn
|
||||
ret nz
|
||||
|
||||
; The default score is 20. Unusable moves are given a score of 80.
|
||||
ld a, 20
|
||||
ld hl, wEnemyAIMoveScores
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
|
||||
; Don't pick disabled moves.
|
||||
ld a, [wEnemyDisabledMove]
|
||||
and a
|
||||
jr z, .CheckPP
|
||||
|
||||
ld hl, wEnemyMonMoves
|
||||
ld c, 0
|
||||
.CheckDisabledMove:
|
||||
cp [hl]
|
||||
jr z, .ScoreDisabledMove
|
||||
inc c
|
||||
inc hl
|
||||
jr .CheckDisabledMove
|
||||
.ScoreDisabledMove:
|
||||
ld hl, wEnemyAIMoveScores
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld [hl], 80
|
||||
|
||||
; Don't pick moves with 0 PP.
|
||||
.CheckPP:
|
||||
ld hl, wEnemyAIMoveScores - 1
|
||||
ld de, wEnemyMonPP
|
||||
ld b, 0
|
||||
.CheckMovePP:
|
||||
inc b
|
||||
ld a, b
|
||||
cp NUM_MOVES + 1
|
||||
jr z, .ApplyLayers
|
||||
inc hl
|
||||
ld a, [de]
|
||||
inc de
|
||||
and PP_MASK
|
||||
jr nz, .CheckMovePP
|
||||
ld [hl], 80
|
||||
jr .CheckMovePP
|
||||
|
||||
; Apply AI scoring layers depending on the trainer class.
|
||||
.ApplyLayers:
|
||||
ld hl, TrainerClassAttributes + TRNATTR_AI_MOVE_WEIGHTS
|
||||
|
||||
; If we have a battle in BattleTower just load the Attributes of the first trainer class in wTrainerClass (Falkner)
|
||||
; so we have always the same AI, regardless of the loaded class of trainer
|
||||
ld a, [wInBattleTowerBattle]
|
||||
bit 0, a
|
||||
jr nz, .battle_tower_skip
|
||||
|
||||
ld a, [wTrainerClass]
|
||||
dec a
|
||||
ld bc, 7 ; Trainer2AI - Trainer1AI
|
||||
call AddNTimes
|
||||
|
||||
.battle_tower_skip
|
||||
lb bc, CHECK_FLAG, 0
|
||||
push bc
|
||||
push hl
|
||||
|
||||
.CheckLayer:
|
||||
pop hl
|
||||
pop bc
|
||||
|
||||
ld a, c
|
||||
cp 16 ; up to 16 scoring layers
|
||||
jr z, .DecrementScores
|
||||
|
||||
push bc
|
||||
ld d, BANK(TrainerClassAttributes)
|
||||
predef SmallFarFlagAction
|
||||
ld d, c
|
||||
pop bc
|
||||
|
||||
inc c
|
||||
push bc
|
||||
push hl
|
||||
|
||||
ld a, d
|
||||
and a
|
||||
jr z, .CheckLayer
|
||||
|
||||
ld hl, AIScoringPointers
|
||||
dec c
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld a, BANK(AIScoring)
|
||||
call FarCall_hl
|
||||
|
||||
jr .CheckLayer
|
||||
|
||||
; Decrement the scores of all moves one by one until one reaches 0.
|
||||
.DecrementScores:
|
||||
ld hl, wEnemyAIMoveScores
|
||||
ld de, wEnemyMonMoves
|
||||
ld c, NUM_MOVES
|
||||
|
||||
.DecrementNextScore:
|
||||
; If the enemy has no moves, this will infinite.
|
||||
ld a, [de]
|
||||
inc de
|
||||
and a
|
||||
jr z, .DecrementScores
|
||||
|
||||
; We are done whenever a score reaches 0
|
||||
dec [hl]
|
||||
jr z, .PickLowestScoreMoves
|
||||
|
||||
; If we just decremented the fourth move's score, go back to the first move
|
||||
inc hl
|
||||
dec c
|
||||
jr z, .DecrementScores
|
||||
|
||||
jr .DecrementNextScore
|
||||
|
||||
; In order to avoid bias towards the moves located first in memory, increment the scores
|
||||
; that were decremented one more time than the rest (in case there was a tie).
|
||||
; This means that the minimum score will be 1.
|
||||
.PickLowestScoreMoves:
|
||||
ld a, c
|
||||
|
||||
.move_loop
|
||||
inc [hl]
|
||||
dec hl
|
||||
inc a
|
||||
cp NUM_MOVES + 1
|
||||
jr nz, .move_loop
|
||||
|
||||
ld hl, wEnemyAIMoveScores
|
||||
ld de, wEnemyMonMoves
|
||||
ld c, NUM_MOVES
|
||||
|
||||
; Give a score of 0 to a blank move
|
||||
.loop2
|
||||
ld a, [de]
|
||||
and a
|
||||
jr nz, .skip_load
|
||||
ld [hl], a
|
||||
|
||||
; Disregard the move if its score is not 1
|
||||
.skip_load
|
||||
ld a, [hl]
|
||||
dec a
|
||||
jr z, .keep
|
||||
xor a
|
||||
ld [hli], a
|
||||
jr .after_toss
|
||||
|
||||
.keep
|
||||
ld a, [de]
|
||||
ld [hli], a
|
||||
.after_toss
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .loop2
|
||||
|
||||
; Randomly choose one of the moves with a score of 1
|
||||
.ChooseMove:
|
||||
ld hl, wEnemyAIMoveScores
|
||||
call Random
|
||||
maskbits NUM_MOVES
|
||||
ld c, a
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .ChooseMove
|
||||
|
||||
ld [wCurEnemyMove], a
|
||||
ld a, c
|
||||
ld [wCurEnemyMoveNum], a
|
||||
ret
|
||||
|
||||
AIScoringPointers:
|
||||
; entries correspond to AI_* constants
|
||||
dw AI_Basic
|
||||
dw AI_Setup
|
||||
dw AI_Types
|
||||
dw AI_Offensive
|
||||
dw AI_Smart
|
||||
dw AI_Opportunist
|
||||
dw AI_Aggressive
|
||||
dw AI_Cautious
|
||||
dw AI_Status
|
||||
dw AI_Risky
|
||||
dw AI_None
|
||||
dw AI_None
|
||||
dw AI_None
|
||||
dw AI_None
|
||||
dw AI_None
|
||||
dw AI_None
|
||||
199
engine/battle/ai/redundant.asm
Normal file
199
engine/battle/ai/redundant.asm
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
AI_Redundant:
|
||||
; Check if move effect c will fail because it's already been used.
|
||||
; Return z if the move is a good choice.
|
||||
; Return nz if the move is a bad choice.
|
||||
ld a, c
|
||||
ld de, 3
|
||||
ld hl, .Moves
|
||||
call IsInArray
|
||||
jp nc, .NotRedundant
|
||||
inc hl
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
jp hl
|
||||
|
||||
.Moves:
|
||||
dbw EFFECT_DREAM_EATER, .DreamEater
|
||||
dbw EFFECT_HEAL, .Heal
|
||||
dbw EFFECT_LIGHT_SCREEN, .LightScreen
|
||||
dbw EFFECT_MIST, .Mist
|
||||
dbw EFFECT_FOCUS_ENERGY, .FocusEnergy
|
||||
dbw EFFECT_CONFUSE, .Confuse
|
||||
dbw EFFECT_TRANSFORM, .Transform
|
||||
dbw EFFECT_REFLECT, .Reflect
|
||||
dbw EFFECT_SUBSTITUTE, .Substitute
|
||||
dbw EFFECT_LEECH_SEED, .LeechSeed
|
||||
dbw EFFECT_DISABLE, .Disable
|
||||
dbw EFFECT_ENCORE, .Encore
|
||||
dbw EFFECT_SNORE, .Snore
|
||||
dbw EFFECT_SLEEP_TALK, .SleepTalk
|
||||
dbw EFFECT_MEAN_LOOK, .MeanLook
|
||||
dbw EFFECT_NIGHTMARE, .Nightmare
|
||||
dbw EFFECT_SPIKES, .Spikes
|
||||
dbw EFFECT_FORESIGHT, .Foresight
|
||||
dbw EFFECT_PERISH_SONG, .PerishSong
|
||||
dbw EFFECT_SANDSTORM, .Sandstorm
|
||||
dbw EFFECT_ATTRACT, .Attract
|
||||
dbw EFFECT_SAFEGUARD, .Safeguard
|
||||
dbw EFFECT_RAIN_DANCE, .RainDance
|
||||
dbw EFFECT_SUNNY_DAY, .SunnyDay
|
||||
dbw EFFECT_TELEPORT, .Teleport
|
||||
dbw EFFECT_MORNING_SUN, .MorningSun
|
||||
dbw EFFECT_SYNTHESIS, .Synthesis
|
||||
dbw EFFECT_MOONLIGHT, .Moonlight
|
||||
dbw EFFECT_SWAGGER, .Swagger
|
||||
dbw EFFECT_FUTURE_SIGHT, .FutureSight
|
||||
db -1
|
||||
|
||||
.LightScreen:
|
||||
ld a, [wEnemyScreens]
|
||||
bit SCREENS_LIGHT_SCREEN, a
|
||||
ret
|
||||
|
||||
.Mist:
|
||||
ld a, [wEnemySubStatus4]
|
||||
bit SUBSTATUS_MIST, a
|
||||
ret
|
||||
|
||||
.FocusEnergy:
|
||||
ld a, [wEnemySubStatus4]
|
||||
bit SUBSTATUS_FOCUS_ENERGY, a
|
||||
ret
|
||||
|
||||
.Confuse:
|
||||
ld a, [wPlayerSubStatus3]
|
||||
bit SUBSTATUS_CONFUSED, a
|
||||
ret nz
|
||||
ld a, [wPlayerScreens]
|
||||
bit SCREENS_SAFEGUARD, a
|
||||
ret
|
||||
|
||||
.Transform:
|
||||
ld a, [wEnemySubStatus5]
|
||||
bit SUBSTATUS_TRANSFORMED, a
|
||||
ret
|
||||
|
||||
.Reflect:
|
||||
ld a, [wEnemyScreens]
|
||||
bit SCREENS_REFLECT, a
|
||||
ret
|
||||
|
||||
.Substitute:
|
||||
ld a, [wEnemySubStatus4]
|
||||
bit SUBSTATUS_SUBSTITUTE, a
|
||||
ret
|
||||
|
||||
.LeechSeed:
|
||||
ld a, [wPlayerSubStatus4]
|
||||
bit SUBSTATUS_LEECH_SEED, a
|
||||
ret
|
||||
|
||||
.Disable:
|
||||
ld a, [wPlayerDisableCount]
|
||||
and a
|
||||
ret
|
||||
|
||||
.Encore:
|
||||
ld a, [wPlayerSubStatus5]
|
||||
bit SUBSTATUS_ENCORED, a
|
||||
ret
|
||||
|
||||
.Snore:
|
||||
.SleepTalk:
|
||||
ld a, [wEnemyMonStatus]
|
||||
and SLP_MASK
|
||||
jr z, .Redundant
|
||||
jr .NotRedundant
|
||||
|
||||
.MeanLook:
|
||||
ld a, [wEnemySubStatus5]
|
||||
bit SUBSTATUS_CANT_RUN, a
|
||||
ret
|
||||
|
||||
.Nightmare:
|
||||
ld a, [wBattleMonStatus]
|
||||
and a
|
||||
jr z, .Redundant
|
||||
ld a, [wPlayerSubStatus1]
|
||||
bit SUBSTATUS_NIGHTMARE, a
|
||||
ret
|
||||
|
||||
.Spikes:
|
||||
ld a, [wPlayerScreens]
|
||||
bit SCREENS_SPIKES, a
|
||||
ret
|
||||
|
||||
.Foresight:
|
||||
ld a, [wPlayerSubStatus1]
|
||||
bit SUBSTATUS_IDENTIFIED, a
|
||||
ret
|
||||
|
||||
.PerishSong:
|
||||
ld a, [wPlayerSubStatus1]
|
||||
bit SUBSTATUS_PERISH, a
|
||||
ret
|
||||
|
||||
.Sandstorm:
|
||||
ld a, [wBattleWeather]
|
||||
cp WEATHER_SANDSTORM
|
||||
jr z, .Redundant
|
||||
jr .NotRedundant
|
||||
|
||||
.Attract:
|
||||
farcall CheckOppositeGender
|
||||
jr c, .Redundant
|
||||
ld a, [wPlayerSubStatus1]
|
||||
bit SUBSTATUS_IN_LOVE, a
|
||||
ret
|
||||
|
||||
.Safeguard:
|
||||
ld a, [wEnemyScreens]
|
||||
bit SCREENS_SAFEGUARD, a
|
||||
ret
|
||||
|
||||
.RainDance:
|
||||
ld a, [wBattleWeather]
|
||||
cp WEATHER_RAIN
|
||||
jr z, .Redundant
|
||||
jr .NotRedundant
|
||||
|
||||
.SunnyDay:
|
||||
ld a, [wBattleWeather]
|
||||
cp WEATHER_SUN
|
||||
jr z, .Redundant
|
||||
jr .NotRedundant
|
||||
|
||||
.DreamEater:
|
||||
ld a, [wBattleMonStatus]
|
||||
and SLP_MASK
|
||||
jr z, .Redundant
|
||||
jr .NotRedundant
|
||||
|
||||
.Swagger:
|
||||
ld a, [wPlayerSubStatus3]
|
||||
bit SUBSTATUS_CONFUSED, a
|
||||
ret
|
||||
|
||||
.FutureSight:
|
||||
; BUG: AI does not discourage Future Sight when it's already been used (see docs/bugs_and_glitches.md)
|
||||
ld a, [wEnemyScreens]
|
||||
bit 5, a
|
||||
ret
|
||||
|
||||
.Heal:
|
||||
.MorningSun:
|
||||
.Synthesis:
|
||||
.Moonlight:
|
||||
farcall AICheckEnemyMaxHP
|
||||
jr nc, .NotRedundant
|
||||
|
||||
.Teleport:
|
||||
.Redundant:
|
||||
ld a, 1
|
||||
and a
|
||||
ret
|
||||
|
||||
.NotRedundant:
|
||||
xor a
|
||||
ret
|
||||
3293
engine/battle/ai/scoring.asm
Normal file
3293
engine/battle/ai/scoring.asm
Normal file
File diff suppressed because it is too large
Load diff
650
engine/battle/ai/switch.asm
Normal file
650
engine/battle/ai/switch.asm
Normal file
|
|
@ -0,0 +1,650 @@
|
|||
CheckPlayerMoveTypeMatchups:
|
||||
; Check how well the moves you've already used
|
||||
; fare against the enemy's Pokemon. Used to
|
||||
; score a potential switch.
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ld a, BASE_AI_SWITCH_SCORE
|
||||
ld [wEnemyAISwitchScore], a
|
||||
ld hl, wPlayerUsedMoves
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .unknown_moves
|
||||
|
||||
ld d, NUM_MOVES
|
||||
ld e, 0
|
||||
.loop
|
||||
ld a, [hli]
|
||||
and a
|
||||
jr z, .exit
|
||||
push hl
|
||||
call GetMoveTypeIfDamaging
|
||||
jr z, .next
|
||||
|
||||
ld hl, wEnemyMonType
|
||||
call CheckTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
cp EFFECTIVE + 1 ; 1.0 + 0.1
|
||||
jr nc, .super_effective
|
||||
and a
|
||||
jr z, .next
|
||||
cp EFFECTIVE ; 1.0
|
||||
jr nc, .neutral
|
||||
|
||||
; not very effective
|
||||
ld a, e
|
||||
cp 1 ; 0.1
|
||||
jr nc, .next
|
||||
ld e, 1
|
||||
jr .next
|
||||
|
||||
.neutral
|
||||
ld e, 2
|
||||
jr .next
|
||||
|
||||
.super_effective
|
||||
call .DecreaseScore
|
||||
pop hl
|
||||
jr .done
|
||||
|
||||
.next
|
||||
pop hl
|
||||
dec d
|
||||
jr nz, .loop
|
||||
|
||||
.exit
|
||||
ld a, e
|
||||
cp 2
|
||||
jr z, .done
|
||||
call .IncreaseScore
|
||||
ld a, e
|
||||
and a
|
||||
jr nz, .done
|
||||
call .IncreaseScore
|
||||
jr .done
|
||||
|
||||
.unknown_moves
|
||||
ld a, [wBattleMonType1]
|
||||
ld b, a
|
||||
ld hl, wEnemyMonType1
|
||||
call CheckTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
cp EFFECTIVE + 1 ; 1.0 + 0.1
|
||||
jr c, .ok
|
||||
call .DecreaseScore
|
||||
.ok
|
||||
ld a, [wBattleMonType2]
|
||||
cp b
|
||||
jr z, .ok2
|
||||
call CheckTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
cp EFFECTIVE + 1 ; 1.0 + 0.1
|
||||
jr c, .ok2
|
||||
call .DecreaseScore
|
||||
.ok2
|
||||
|
||||
.done
|
||||
call .CheckEnemyMoveMatchups
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.CheckEnemyMoveMatchups:
|
||||
ld de, wEnemyMonMoves
|
||||
ld b, NUM_MOVES + 1
|
||||
ld c, 0
|
||||
|
||||
ld a, [wTypeMatchup]
|
||||
push af
|
||||
.loop2
|
||||
dec b
|
||||
jr z, .exit2
|
||||
|
||||
ld a, [de]
|
||||
and a
|
||||
jr z, .exit2
|
||||
|
||||
inc de
|
||||
call GetMoveTypeIfDamaging
|
||||
jr z, .loop2
|
||||
|
||||
ld hl, wBattleMonType1
|
||||
call CheckTypeMatchup
|
||||
|
||||
ld a, [wTypeMatchup]
|
||||
; immune
|
||||
and a
|
||||
jr z, .loop2
|
||||
|
||||
; not very effective
|
||||
inc c
|
||||
cp EFFECTIVE
|
||||
jr c, .loop2
|
||||
|
||||
; neutral
|
||||
inc c
|
||||
inc c
|
||||
inc c
|
||||
inc c
|
||||
inc c
|
||||
cp EFFECTIVE
|
||||
jr z, .loop2
|
||||
|
||||
; super effective
|
||||
ld c, 100
|
||||
jr .loop2
|
||||
|
||||
.exit2
|
||||
pop af
|
||||
ld [wTypeMatchup], a
|
||||
|
||||
ld a, c
|
||||
and a
|
||||
jr z, .doubledown ; double down
|
||||
cp 5
|
||||
jr c, .DecreaseScore ; down
|
||||
cp 100
|
||||
ret c
|
||||
jr .IncreaseScore ; up
|
||||
|
||||
.doubledown
|
||||
call .DecreaseScore
|
||||
.DecreaseScore:
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
dec a
|
||||
ld [wEnemyAISwitchScore], a
|
||||
ret
|
||||
|
||||
.IncreaseScore:
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
inc a
|
||||
ld [wEnemyAISwitchScore], a
|
||||
ret
|
||||
|
||||
CheckAbleToSwitch:
|
||||
xor a
|
||||
ld [wEnemySwitchMonParam], a
|
||||
call FindAliveEnemyMons
|
||||
ret c
|
||||
|
||||
ld a, [wEnemySubStatus1]
|
||||
bit SUBSTATUS_PERISH, a
|
||||
jr z, .no_perish
|
||||
|
||||
ld a, [wEnemyPerishCount]
|
||||
cp 1
|
||||
jr nz, .no_perish
|
||||
|
||||
; Perish count is 1
|
||||
|
||||
call FindAliveEnemyMons
|
||||
call FindEnemyMonsWithAtLeastQuarterMaxHP
|
||||
call FindEnemyMonsThatResistPlayer
|
||||
call FindAliveEnemyMonsWithASuperEffectiveMove
|
||||
|
||||
ld a, e
|
||||
cp 2
|
||||
jr nz, .not_2
|
||||
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
add $30 ; maximum chance
|
||||
ld [wEnemySwitchMonParam], a
|
||||
ret
|
||||
|
||||
.not_2
|
||||
call FindAliveEnemyMons
|
||||
sla c
|
||||
sla c
|
||||
ld b, $ff
|
||||
|
||||
.loop1
|
||||
inc b
|
||||
sla c
|
||||
jr nc, .loop1
|
||||
|
||||
ld a, b
|
||||
add $30 ; maximum chance
|
||||
ld [wEnemySwitchMonParam], a
|
||||
ret
|
||||
|
||||
.no_perish
|
||||
call CheckPlayerMoveTypeMatchups
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
cp 11
|
||||
ret nc
|
||||
|
||||
ld a, [wLastPlayerCounterMove]
|
||||
and a
|
||||
jr z, .no_last_counter_move
|
||||
|
||||
call FindEnemyMonsImmuneToLastCounterMove
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
and a
|
||||
jr z, .no_last_counter_move
|
||||
|
||||
ld c, a
|
||||
call FindEnemyMonsWithASuperEffectiveMove
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
cp $ff
|
||||
ret z
|
||||
|
||||
ld b, a
|
||||
ld a, e
|
||||
cp 2
|
||||
jr z, .not_2_again
|
||||
|
||||
call CheckPlayerMoveTypeMatchups
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
cp 10
|
||||
ret nc
|
||||
|
||||
ld a, b
|
||||
add $10
|
||||
ld [wEnemySwitchMonParam], a
|
||||
ret
|
||||
|
||||
.not_2_again
|
||||
ld c, $10
|
||||
call CheckPlayerMoveTypeMatchups
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
cp 10
|
||||
jr nc, .okay
|
||||
ld c, $20
|
||||
|
||||
.okay
|
||||
ld a, b
|
||||
add c
|
||||
ld [wEnemySwitchMonParam], a
|
||||
ret
|
||||
|
||||
.no_last_counter_move
|
||||
call CheckPlayerMoveTypeMatchups
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
cp 10
|
||||
ret nc
|
||||
|
||||
call FindAliveEnemyMons
|
||||
call FindEnemyMonsWithAtLeastQuarterMaxHP
|
||||
call FindEnemyMonsThatResistPlayer
|
||||
call FindAliveEnemyMonsWithASuperEffectiveMove
|
||||
|
||||
ld a, e
|
||||
cp $2
|
||||
ret nz
|
||||
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
add $10
|
||||
ld [wEnemySwitchMonParam], a
|
||||
ret
|
||||
|
||||
FindAliveEnemyMons:
|
||||
ld a, [wOTPartyCount]
|
||||
cp 2
|
||||
jr c, .only_one
|
||||
|
||||
ld d, a
|
||||
ld e, 0
|
||||
ld b, 1 << (PARTY_LENGTH - 1)
|
||||
ld c, 0
|
||||
ld hl, wOTPartyMon1HP
|
||||
|
||||
.loop
|
||||
ld a, [wCurOTMon]
|
||||
cp e
|
||||
jr z, .next
|
||||
|
||||
push bc
|
||||
ld b, [hl]
|
||||
inc hl
|
||||
ld a, [hld]
|
||||
or b
|
||||
pop bc
|
||||
jr z, .next
|
||||
|
||||
ld a, c
|
||||
or b
|
||||
ld c, a
|
||||
|
||||
.next
|
||||
srl b
|
||||
push bc
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
inc e
|
||||
dec d
|
||||
jr nz, .loop
|
||||
|
||||
ld a, c
|
||||
and a
|
||||
jr nz, .more_than_one
|
||||
|
||||
.only_one
|
||||
scf
|
||||
ret
|
||||
|
||||
.more_than_one
|
||||
and a
|
||||
ret
|
||||
|
||||
FindEnemyMonsImmuneToLastCounterMove:
|
||||
ld hl, wOTPartyMon1
|
||||
ld a, [wOTPartyCount]
|
||||
ld b, a
|
||||
ld c, 1 << (PARTY_LENGTH - 1)
|
||||
ld d, 0
|
||||
xor a
|
||||
ld [wEnemyAISwitchScore], a
|
||||
|
||||
.loop
|
||||
ld a, [wCurOTMon]
|
||||
cp d
|
||||
push hl
|
||||
jr z, .next
|
||||
|
||||
push hl
|
||||
push bc
|
||||
|
||||
; If the Pokemon has at least 1 HP...
|
||||
ld bc, MON_HP
|
||||
add hl, bc
|
||||
pop bc
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
pop hl
|
||||
jr z, .next
|
||||
|
||||
ld a, [hl]
|
||||
ld [wCurSpecies], a
|
||||
call GetBaseData
|
||||
|
||||
; the player's last move is damaging...
|
||||
ld a, [wLastPlayerCounterMove]
|
||||
call GetMoveTypeIfDamaging
|
||||
jr z, .next
|
||||
|
||||
; and the Pokemon is immune to it...
|
||||
ld hl, wBaseType
|
||||
call CheckTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
and a
|
||||
jr nz, .next
|
||||
|
||||
; ... encourage that Pokemon.
|
||||
ld a, [wEnemyAISwitchScore]
|
||||
or c
|
||||
ld [wEnemyAISwitchScore], a
|
||||
.next
|
||||
pop hl
|
||||
dec b
|
||||
ret z
|
||||
|
||||
push bc
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
|
||||
inc d
|
||||
srl c
|
||||
jr .loop
|
||||
|
||||
FindAliveEnemyMonsWithASuperEffectiveMove:
|
||||
push bc
|
||||
ld a, [wOTPartyCount]
|
||||
ld e, a
|
||||
ld hl, wOTPartyMon1HP
|
||||
ld b, 1 << (PARTY_LENGTH - 1)
|
||||
ld c, 0
|
||||
.loop
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
jr z, .next
|
||||
|
||||
ld a, b
|
||||
or c
|
||||
ld c, a
|
||||
|
||||
.next
|
||||
srl b
|
||||
push bc
|
||||
ld bc, wPartyMon2HP - (wPartyMon1HP + 1)
|
||||
add hl, bc
|
||||
pop bc
|
||||
dec e
|
||||
jr nz, .loop
|
||||
|
||||
ld a, c
|
||||
pop bc
|
||||
|
||||
and c
|
||||
ld c, a
|
||||
; fallthrough
|
||||
|
||||
FindEnemyMonsWithASuperEffectiveMove:
|
||||
ld a, -1
|
||||
ld [wEnemyAISwitchScore], a
|
||||
ld hl, wOTPartyMon1Moves
|
||||
ld b, 1 << (PARTY_LENGTH - 1)
|
||||
ld d, 0
|
||||
ld e, 0
|
||||
.loop
|
||||
ld a, b
|
||||
and c
|
||||
jr z, .next
|
||||
|
||||
push hl
|
||||
push bc
|
||||
; for move on mon:
|
||||
ld b, NUM_MOVES
|
||||
ld c, 0
|
||||
.loop3
|
||||
; if move is None: break
|
||||
ld a, [hli]
|
||||
and a
|
||||
push hl
|
||||
jr z, .break3
|
||||
|
||||
; if move has no power: continue
|
||||
call GetMoveTypeIfDamaging
|
||||
jr z, .nope
|
||||
|
||||
; check type matchups
|
||||
ld hl, wBattleMonType1
|
||||
call CheckTypeMatchup
|
||||
|
||||
; if immune or not very effective: continue
|
||||
ld a, [wTypeMatchup]
|
||||
cp 10
|
||||
jr c, .nope
|
||||
|
||||
; if neutral: load 1 and continue
|
||||
ld e, 1
|
||||
cp EFFECTIVE + 1
|
||||
jr c, .nope
|
||||
|
||||
; if super-effective: load 2 and break
|
||||
ld e, 2
|
||||
jr .break3
|
||||
|
||||
.nope
|
||||
pop hl
|
||||
dec b
|
||||
jr nz, .loop3
|
||||
|
||||
jr .done
|
||||
|
||||
.break3
|
||||
pop hl
|
||||
.done
|
||||
ld a, e
|
||||
pop bc
|
||||
pop hl
|
||||
cp 2
|
||||
jr z, .done2 ; at least one move is super-effective
|
||||
cp 1
|
||||
jr nz, .next ; no move does more than half damage
|
||||
|
||||
; encourage this pokemon
|
||||
ld a, d
|
||||
or b
|
||||
ld d, a
|
||||
jr .next ; such a long jump
|
||||
|
||||
.next
|
||||
; next pokemon?
|
||||
push bc
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
srl b
|
||||
jr nc, .loop
|
||||
|
||||
; if no pokemon has a super-effective move: return
|
||||
ld a, d
|
||||
ld b, a
|
||||
and a
|
||||
ret z
|
||||
|
||||
.done2
|
||||
; convert the bit flag to an int and return
|
||||
push bc
|
||||
sla b
|
||||
sla b
|
||||
ld c, $ff
|
||||
.loop2
|
||||
inc c
|
||||
sla b
|
||||
jr nc, .loop2
|
||||
|
||||
ld a, c
|
||||
ld [wEnemyAISwitchScore], a
|
||||
pop bc
|
||||
ret
|
||||
|
||||
FindEnemyMonsThatResistPlayer:
|
||||
push bc
|
||||
ld hl, wOTPartySpecies
|
||||
ld b, 1 << (PARTY_LENGTH - 1)
|
||||
ld c, 0
|
||||
|
||||
.loop
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
jr z, .done
|
||||
|
||||
push hl
|
||||
ld [wCurSpecies], a
|
||||
call GetBaseData
|
||||
ld a, [wLastPlayerCounterMove]
|
||||
and a
|
||||
jr z, .skip_move
|
||||
|
||||
call GetMoveTypeIfDamaging
|
||||
jr nz, .check_type
|
||||
|
||||
.skip_move
|
||||
ld a, [wBattleMonType1]
|
||||
ld hl, wBaseType
|
||||
call CheckTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
cp 10 + 1
|
||||
jr nc, .dont_choose_mon
|
||||
ld a, [wBattleMonType2]
|
||||
|
||||
.check_type
|
||||
ld hl, wBaseType
|
||||
call CheckTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
cp EFFECTIVE + 1
|
||||
jr nc, .dont_choose_mon
|
||||
|
||||
ld a, b
|
||||
or c
|
||||
ld c, a
|
||||
|
||||
.dont_choose_mon
|
||||
srl b
|
||||
pop hl
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
ld a, c
|
||||
pop bc
|
||||
and c
|
||||
ld c, a
|
||||
ret
|
||||
|
||||
FindEnemyMonsWithAtLeastQuarterMaxHP:
|
||||
push bc
|
||||
ld de, wOTPartySpecies
|
||||
ld b, 1 << (PARTY_LENGTH - 1)
|
||||
ld c, 0
|
||||
ld hl, wOTPartyMon1HP
|
||||
|
||||
.loop
|
||||
ld a, [de]
|
||||
inc de
|
||||
cp $ff
|
||||
jr z, .done
|
||||
|
||||
push hl
|
||||
push bc
|
||||
ld b, [hl]
|
||||
inc hl
|
||||
ld c, [hl]
|
||||
inc hl
|
||||
inc hl
|
||||
; hl = MaxHP + 1
|
||||
; bc = [CurHP] * 4
|
||||
srl c
|
||||
rl b
|
||||
srl c
|
||||
rl b
|
||||
; if bc >= [hl], encourage
|
||||
ld a, [hld]
|
||||
cp c
|
||||
ld a, [hl]
|
||||
sbc b
|
||||
pop bc
|
||||
jr nc, .next
|
||||
|
||||
ld a, b
|
||||
or c
|
||||
ld c, a
|
||||
|
||||
.next
|
||||
srl b
|
||||
pop hl
|
||||
push bc
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
ld a, c
|
||||
pop bc
|
||||
and c
|
||||
ld c, a
|
||||
ret
|
||||
|
||||
GetMoveTypeIfDamaging:
|
||||
; returns the type of move a in a, and sets the zero flag depending on whether the move causes damage
|
||||
; clobbers hl
|
||||
push bc
|
||||
call GetMoveAddress
|
||||
ld b, a
|
||||
rept MOVE_POWER - 1
|
||||
inc hl
|
||||
endr
|
||||
call GetFarByte
|
||||
ld c, a
|
||||
ld a, b
|
||||
inc hl
|
||||
call GetFarByte
|
||||
inc c
|
||||
dec c
|
||||
pop bc
|
||||
ret
|
||||
417
engine/battle/anim_hp_bar.asm
Normal file
417
engine/battle/anim_hp_bar.asm
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
_AnimateHPBar:
|
||||
call .IsMaximumMoreThan48Pixels
|
||||
jr c, .MoreThan48Pixels
|
||||
call .ComputePixels
|
||||
.ShortAnimLoop:
|
||||
push bc
|
||||
push hl
|
||||
call ShortAnim_UpdateVariables
|
||||
pop hl
|
||||
pop bc
|
||||
push af
|
||||
push bc
|
||||
push hl
|
||||
call ShortHPBarAnim_UpdateTiles
|
||||
call HPBarAnim_BGMapUpdate
|
||||
pop hl
|
||||
pop bc
|
||||
pop af
|
||||
jr nc, .ShortAnimLoop
|
||||
ret
|
||||
|
||||
.MoreThan48Pixels:
|
||||
call .ComputePixels
|
||||
.LongAnimLoop:
|
||||
push bc
|
||||
push hl
|
||||
call LongAnim_UpdateVariables
|
||||
pop hl
|
||||
pop bc
|
||||
ret c
|
||||
push af
|
||||
push bc
|
||||
push hl
|
||||
call LongHPBarAnim_UpdateTiles
|
||||
call HPBarAnim_BGMapUpdate
|
||||
pop hl
|
||||
pop bc
|
||||
pop af
|
||||
jr nc, .LongAnimLoop
|
||||
ret
|
||||
|
||||
.IsMaximumMoreThan48Pixels:
|
||||
ld a, [wCurHPAnimMaxHP + 1]
|
||||
and a
|
||||
jr nz, .player
|
||||
ld a, [wCurHPAnimMaxHP]
|
||||
cp HP_BAR_LENGTH_PX
|
||||
jr nc, .player
|
||||
and a
|
||||
ret
|
||||
|
||||
.player
|
||||
scf
|
||||
ret
|
||||
|
||||
.ComputePixels:
|
||||
push hl
|
||||
ld hl, wCurHPAnimMaxHP
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
pop hl
|
||||
call ComputeHPBarPixels
|
||||
ld a, e
|
||||
ld [wCurHPBarPixels], a
|
||||
|
||||
ld a, [wCurHPAnimNewHP]
|
||||
ld c, a
|
||||
ld a, [wCurHPAnimNewHP + 1]
|
||||
ld b, a
|
||||
ld a, [wCurHPAnimMaxHP]
|
||||
ld e, a
|
||||
ld a, [wCurHPAnimMaxHP + 1]
|
||||
ld d, a
|
||||
call ComputeHPBarPixels
|
||||
ld a, e
|
||||
ld [wNewHPBarPixels], a
|
||||
|
||||
push hl
|
||||
ld hl, wCurHPAnimOldHP
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
pop hl
|
||||
ld a, e
|
||||
sub c
|
||||
ld e, a
|
||||
ld a, d
|
||||
sbc b
|
||||
ld d, a
|
||||
jr c, .negative
|
||||
ld a, [wCurHPAnimOldHP]
|
||||
ld [wCurHPAnimLowHP], a
|
||||
ld a, [wCurHPAnimNewHP]
|
||||
ld [wCurHPAnimHighHP], a
|
||||
ld bc, 1
|
||||
jr .got_direction
|
||||
|
||||
.negative
|
||||
ld a, [wCurHPAnimOldHP]
|
||||
ld [wCurHPAnimHighHP], a
|
||||
ld a, [wCurHPAnimNewHP]
|
||||
ld [wCurHPAnimLowHP], a
|
||||
ld a, e
|
||||
xor $ff
|
||||
inc a
|
||||
ld e, a
|
||||
ld a, d
|
||||
xor $ff
|
||||
ld d, a
|
||||
ld bc, -1
|
||||
.got_direction
|
||||
ld a, d
|
||||
ld [wCurHPAnimDeltaHP], a
|
||||
ld a, e
|
||||
ld [wCurHPAnimDeltaHP + 1], a
|
||||
ret
|
||||
|
||||
ShortAnim_UpdateVariables:
|
||||
ld hl, wCurHPBarPixels
|
||||
ld a, [wNewHPBarPixels]
|
||||
cp [hl]
|
||||
jr nz, .not_finished
|
||||
scf
|
||||
ret
|
||||
|
||||
.not_finished
|
||||
ld a, c
|
||||
add [hl]
|
||||
ld [hl], a
|
||||
call ShortHPBar_CalcPixelFrame
|
||||
and a
|
||||
ret
|
||||
|
||||
LongAnim_UpdateVariables:
|
||||
.loop
|
||||
ld hl, wCurHPAnimOldHP
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, e
|
||||
cp [hl]
|
||||
jr nz, .next
|
||||
inc hl
|
||||
ld a, d
|
||||
cp [hl]
|
||||
jr nz, .next
|
||||
scf
|
||||
ret
|
||||
|
||||
.next
|
||||
ld l, e
|
||||
ld h, d
|
||||
add hl, bc
|
||||
ld a, l
|
||||
ld [wCurHPAnimOldHP], a
|
||||
ld a, h
|
||||
ld [wCurHPAnimOldHP + 1], a
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ld hl, wCurHPAnimMaxHP
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
; BUG: HP bar animation is slow for high HP (see docs/bugs_and_glitches.md)
|
||||
call ComputeHPBarPixels
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ld a, e
|
||||
ld hl, wCurHPBarPixels
|
||||
cp [hl]
|
||||
jr z, .loop
|
||||
ld [hl], a
|
||||
and a
|
||||
ret
|
||||
|
||||
ShortHPBarAnim_UpdateTiles:
|
||||
call HPBarAnim_UpdateHPRemaining
|
||||
ld d, HP_BAR_LENGTH
|
||||
ld a, [wWhichHPBar]
|
||||
and $1
|
||||
ld b, a
|
||||
ld a, [wCurHPBarPixels]
|
||||
ld e, a
|
||||
ld c, a
|
||||
push de
|
||||
call HPBarAnim_RedrawHPBar
|
||||
pop de
|
||||
call HPBarAnim_PaletteUpdate
|
||||
ret
|
||||
|
||||
LongHPBarAnim_UpdateTiles:
|
||||
call HPBarAnim_UpdateHPRemaining
|
||||
ld a, [wCurHPAnimOldHP]
|
||||
ld c, a
|
||||
ld a, [wCurHPAnimOldHP + 1]
|
||||
ld b, a
|
||||
ld a, [wCurHPAnimMaxHP]
|
||||
ld e, a
|
||||
ld a, [wCurHPAnimMaxHP + 1]
|
||||
ld d, a
|
||||
call ComputeHPBarPixels
|
||||
ld c, e
|
||||
ld d, HP_BAR_LENGTH
|
||||
ld a, [wWhichHPBar]
|
||||
and $1
|
||||
ld b, a
|
||||
push de
|
||||
call HPBarAnim_RedrawHPBar
|
||||
pop de
|
||||
call HPBarAnim_PaletteUpdate
|
||||
ret
|
||||
|
||||
HPBarAnim_RedrawHPBar:
|
||||
ld a, [wWhichHPBar]
|
||||
cp $2
|
||||
jr nz, .skip
|
||||
ld a, 2 * SCREEN_WIDTH
|
||||
add l
|
||||
ld l, a
|
||||
ld a, 0
|
||||
adc h
|
||||
ld h, a
|
||||
.skip
|
||||
call DrawBattleHPBar
|
||||
ret
|
||||
|
||||
HPBarAnim_UpdateHPRemaining:
|
||||
ld a, [wWhichHPBar]
|
||||
and a
|
||||
ret z
|
||||
cp $1
|
||||
jr z, .load_15
|
||||
ld de, SCREEN_WIDTH + 2
|
||||
jr .loaded_de
|
||||
|
||||
.load_15
|
||||
ld de, SCREEN_WIDTH + 1
|
||||
.loaded_de
|
||||
push hl
|
||||
add hl, de
|
||||
ld a, " "
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hld], a
|
||||
dec hl
|
||||
ld a, [wCurHPAnimOldHP]
|
||||
ld [wStringBuffer2 + 1], a
|
||||
ld a, [wCurHPAnimOldHP + 1]
|
||||
ld [wStringBuffer2], a
|
||||
ld de, wStringBuffer2
|
||||
lb bc, 2, 3
|
||||
call PrintNum
|
||||
pop hl
|
||||
ret
|
||||
|
||||
HPBarAnim_PaletteUpdate:
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
ret z
|
||||
ld hl, wCurHPAnimPal
|
||||
call SetHPPal
|
||||
ld a, [wCurHPAnimPal]
|
||||
ld c, a
|
||||
farcall ApplyHPBarPals
|
||||
ret
|
||||
|
||||
HPBarAnim_BGMapUpdate:
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr nz, .cgb
|
||||
call DelayFrame
|
||||
call DelayFrame
|
||||
ret
|
||||
|
||||
.cgb
|
||||
ld a, [wWhichHPBar]
|
||||
and a
|
||||
jr z, .load_0
|
||||
cp $1
|
||||
jr z, .load_1
|
||||
ld a, [wCurPartyMon]
|
||||
cp $3
|
||||
jr nc, .bottom_half_of_screen
|
||||
ld c, $0
|
||||
jr .got_third
|
||||
|
||||
.bottom_half_of_screen
|
||||
ld c, $1
|
||||
.got_third
|
||||
push af
|
||||
cp $2
|
||||
jr z, .skip_delay
|
||||
cp $5
|
||||
jr z, .skip_delay
|
||||
ld a, $2
|
||||
ldh [hBGMapMode], a
|
||||
ld a, c
|
||||
ldh [hBGMapThird], a
|
||||
call DelayFrame
|
||||
.skip_delay
|
||||
ld a, $1
|
||||
ldh [hBGMapMode], a
|
||||
ld a, c
|
||||
ldh [hBGMapThird], a
|
||||
call DelayFrame
|
||||
pop af
|
||||
cp $2
|
||||
jr z, .two_frames
|
||||
cp $5
|
||||
jr z, .two_frames
|
||||
ret
|
||||
|
||||
.two_frames
|
||||
inc c
|
||||
ld a, $2
|
||||
ldh [hBGMapMode], a
|
||||
ld a, c
|
||||
ldh [hBGMapThird], a
|
||||
call DelayFrame
|
||||
ld a, $1
|
||||
ldh [hBGMapMode], a
|
||||
ld a, c
|
||||
ldh [hBGMapThird], a
|
||||
call DelayFrame
|
||||
ret
|
||||
|
||||
.load_0
|
||||
ld c, $0
|
||||
jr .finish
|
||||
|
||||
.load_1
|
||||
ld c, $1
|
||||
.finish
|
||||
call DelayFrame
|
||||
ld a, c
|
||||
ldh [hBGMapThird], a
|
||||
call DelayFrame
|
||||
ret
|
||||
|
||||
ShortHPBar_CalcPixelFrame:
|
||||
ld a, [wCurHPAnimMaxHP]
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ld hl, 0
|
||||
ld a, [wCurHPBarPixels]
|
||||
cp HP_BAR_LENGTH_PX
|
||||
jr nc, .return_max
|
||||
and a
|
||||
jr z, .return_zero
|
||||
call AddNTimes
|
||||
|
||||
ld b, 0
|
||||
.loop
|
||||
; BUG: HP bar animation off-by-one error for low HP (see docs/bugs_and_glitches.md)
|
||||
ld a, l
|
||||
sub HP_BAR_LENGTH_PX
|
||||
ld l, a
|
||||
ld a, h
|
||||
sbc $0
|
||||
ld h, a
|
||||
jr c, .done
|
||||
inc b
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
push bc
|
||||
ld bc, $80
|
||||
add hl, bc
|
||||
pop bc
|
||||
ld a, l
|
||||
sub HP_BAR_LENGTH_PX
|
||||
ld l, a
|
||||
ld a, h
|
||||
sbc $0
|
||||
ld h, a
|
||||
jr c, .no_carry
|
||||
inc b
|
||||
.no_carry
|
||||
ld a, [wCurHPAnimLowHP]
|
||||
cp b
|
||||
jr nc, .finish
|
||||
ld a, [wCurHPAnimHighHP]
|
||||
cp b
|
||||
jr c, .finish
|
||||
ld a, b
|
||||
.finish
|
||||
ld [wCurHPAnimOldHP], a
|
||||
ret
|
||||
|
||||
.return_zero
|
||||
xor a
|
||||
ld [wCurHPAnimOldHP], a
|
||||
ret
|
||||
|
||||
.return_max
|
||||
ld a, [wCurHPAnimMaxHP]
|
||||
ld [wCurHPAnimOldHP], a
|
||||
ret
|
||||
840
engine/battle/battle_transition.asm
Normal file
840
engine/battle/battle_transition.asm
Normal file
|
|
@ -0,0 +1,840 @@
|
|||
; BattleTransitionJumptable.Jumptable indexes
|
||||
DEF BATTLETRANSITION_CAVE EQU $01
|
||||
DEF BATTLETRANSITION_CAVE_STRONGER EQU $09
|
||||
DEF BATTLETRANSITION_NO_CAVE EQU $10
|
||||
DEF BATTLETRANSITION_NO_CAVE_STRONGER EQU $18
|
||||
DEF BATTLETRANSITION_FINISH EQU $20
|
||||
DEF BATTLETRANSITION_END EQU $80
|
||||
|
||||
DEF BATTLETRANSITION_SQUARE EQU "8" ; $fe
|
||||
DEF BATTLETRANSITION_BLACK EQU "9" ; $ff
|
||||
|
||||
DoBattleTransition:
|
||||
call .InitGFX
|
||||
ldh a, [rBGP]
|
||||
ld [wBGP], a
|
||||
ldh a, [rOBP0]
|
||||
ld [wOBP0], a
|
||||
ldh a, [rOBP1]
|
||||
ld [wOBP1], a
|
||||
call DelayFrame
|
||||
ld hl, hVBlank
|
||||
ld a, [hl]
|
||||
push af
|
||||
vc_hook Reduce_battle_transition_flashing
|
||||
ld [hl], $1
|
||||
|
||||
.loop
|
||||
ld a, [wJumptableIndex]
|
||||
bit 7, a ; BATTLETRANSITION_END?
|
||||
jr nz, .done
|
||||
call BattleTransitionJumptable
|
||||
call DelayFrame
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wBGPals1)
|
||||
ldh [rSVBK], a
|
||||
|
||||
ld hl, wBGPals1
|
||||
ld bc, 8 palettes
|
||||
xor a
|
||||
call ByteFill
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
|
||||
ld a, %11111111
|
||||
ld [wBGP], a
|
||||
call DmgToCgbBGPals
|
||||
call DelayFrame
|
||||
xor a
|
||||
ldh [hLCDCPointer], a
|
||||
ldh [hLYOverrideStart], a
|
||||
ldh [hLYOverrideEnd], a
|
||||
ldh [hSCY], a
|
||||
|
||||
ld a, $1 ; unnecessary bankswitch?
|
||||
ldh [rSVBK], a
|
||||
pop af
|
||||
vc_hook Stop_reducing_battle_transition_flashing
|
||||
ldh [hVBlank], a
|
||||
call DelayFrame
|
||||
ret
|
||||
|
||||
.InitGFX:
|
||||
ld a, [wLinkMode]
|
||||
cp LINK_MOBILE
|
||||
jr z, .mobile
|
||||
farcall ReanchorBGMap_NoOAMUpdate
|
||||
call UpdateSprites
|
||||
call DelayFrame
|
||||
call .NonMobile_LoadPokeballTiles
|
||||
call BattleStart_CopyTilemapAtOnce
|
||||
jr .resume
|
||||
|
||||
.mobile
|
||||
call LoadTrainerBattlePokeballTiles
|
||||
|
||||
.resume
|
||||
ld a, SCREEN_HEIGHT_PX
|
||||
ldh [hWY], a
|
||||
call DelayFrame
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ld hl, wJumptableIndex
|
||||
xor a
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
call WipeLYOverrides
|
||||
ret
|
||||
|
||||
.NonMobile_LoadPokeballTiles:
|
||||
call LoadTrainerBattlePokeballTiles
|
||||
hlbgcoord 0, 0
|
||||
call ConvertTrainerBattlePokeballTilesTo2bpp
|
||||
ret
|
||||
|
||||
LoadTrainerBattlePokeballTiles:
|
||||
; Load the tiles used in the Pokeball Graphic that fills the screen
|
||||
; at the start of every Trainer battle.
|
||||
ld de, TrainerBattlePokeballTiles
|
||||
ld hl, vTiles0 tile BATTLETRANSITION_SQUARE
|
||||
ld b, BANK(TrainerBattlePokeballTiles)
|
||||
ld c, 2
|
||||
call Request2bpp
|
||||
|
||||
ldh a, [rVBK]
|
||||
push af
|
||||
ld a, $1
|
||||
ldh [rVBK], a
|
||||
|
||||
ld de, TrainerBattlePokeballTiles
|
||||
ld hl, vTiles3 tile BATTLETRANSITION_SQUARE
|
||||
ld b, BANK(TrainerBattlePokeballTiles)
|
||||
ld c, 2
|
||||
call Request2bpp
|
||||
|
||||
pop af
|
||||
ldh [rVBK], a
|
||||
ret
|
||||
|
||||
ConvertTrainerBattlePokeballTilesTo2bpp:
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wDecompressScratch)
|
||||
ldh [rSVBK], a
|
||||
push hl
|
||||
ld hl, wDecompressScratch
|
||||
ld bc, $28 tiles
|
||||
|
||||
.loop
|
||||
ld [hl], -1
|
||||
inc hl
|
||||
dec bc
|
||||
ld a, c
|
||||
or b
|
||||
jr nz, .loop
|
||||
|
||||
pop hl
|
||||
ld de, wDecompressScratch
|
||||
ld b, BANK(@)
|
||||
ld c, $28
|
||||
call Request2bpp
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
|
||||
TrainerBattlePokeballTiles:
|
||||
INCBIN "gfx/overworld/trainer_battle_pokeball_tiles.2bpp"
|
||||
|
||||
BattleTransitionJumptable:
|
||||
jumptable .Jumptable, wJumptableIndex
|
||||
|
||||
.Jumptable:
|
||||
dw StartTrainerBattle_DetermineWhichAnimation ; 00
|
||||
|
||||
; BATTLETRANSITION_CAVE
|
||||
dw StartTrainerBattle_LoadPokeBallGraphics ; 01
|
||||
dw StartTrainerBattle_SetUpBGMap ; 02
|
||||
dw StartTrainerBattle_Flash ; 03
|
||||
dw StartTrainerBattle_Flash ; 04
|
||||
dw StartTrainerBattle_Flash ; 05
|
||||
dw StartTrainerBattle_NextScene ; 06
|
||||
dw StartTrainerBattle_SetUpForWavyOutro ; 07
|
||||
dw StartTrainerBattle_SineWave ; 08
|
||||
|
||||
; BATTLETRANSITION_CAVE_STRONGER
|
||||
dw StartTrainerBattle_LoadPokeBallGraphics ; 09
|
||||
dw StartTrainerBattle_SetUpBGMap ; 0a
|
||||
dw StartTrainerBattle_Flash ; 0b
|
||||
dw StartTrainerBattle_Flash ; 0c
|
||||
dw StartTrainerBattle_Flash ; 0d
|
||||
dw StartTrainerBattle_NextScene ; 0e
|
||||
; There is no setup for this one
|
||||
dw StartTrainerBattle_ZoomToBlack ; 0f
|
||||
|
||||
; BATTLETRANSITION_NO_CAVE
|
||||
dw StartTrainerBattle_LoadPokeBallGraphics ; 10
|
||||
dw StartTrainerBattle_SetUpBGMap ; 11
|
||||
dw StartTrainerBattle_Flash ; 12
|
||||
dw StartTrainerBattle_Flash ; 13
|
||||
dw StartTrainerBattle_Flash ; 14
|
||||
dw StartTrainerBattle_NextScene ; 15
|
||||
dw StartTrainerBattle_SetUpForSpinOutro ; 16
|
||||
dw StartTrainerBattle_SpinToBlack ; 17
|
||||
|
||||
; BATTLETRANSITION_NO_CAVE_STRONGER
|
||||
dw StartTrainerBattle_LoadPokeBallGraphics ; 18
|
||||
dw StartTrainerBattle_SetUpBGMap ; 19
|
||||
dw StartTrainerBattle_Flash ; 1a
|
||||
dw StartTrainerBattle_Flash ; 1b
|
||||
dw StartTrainerBattle_Flash ; 1c
|
||||
dw StartTrainerBattle_NextScene ; 1d
|
||||
dw StartTrainerBattle_SetUpForRandomScatterOutro ; 1e
|
||||
dw StartTrainerBattle_SpeckleToBlack ; 1f
|
||||
|
||||
; BATTLETRANSITION_FINISH
|
||||
dw StartTrainerBattle_Finish ; 20
|
||||
|
||||
; transition animations
|
||||
const_def
|
||||
const TRANS_CAVE
|
||||
const TRANS_CAVE_STRONGER
|
||||
const TRANS_NO_CAVE
|
||||
const TRANS_NO_CAVE_STRONGER
|
||||
|
||||
; transition animation bits
|
||||
DEF TRANS_STRONGER_F EQU 0 ; bit set in TRANS_CAVE_STRONGER and TRANS_NO_CAVE_STRONGER
|
||||
DEF TRANS_NO_CAVE_F EQU 1 ; bit set in TRANS_NO_CAVE and TRANS_NO_CAVE_STRONGER
|
||||
|
||||
StartTrainerBattle_DetermineWhichAnimation:
|
||||
; The screen flashes a different number of times depending on the level of
|
||||
; your lead Pokemon relative to the opponent's.
|
||||
; BUG: Battle transitions fail to account for enemy's level (see docs/bugs_and_glitches.md)
|
||||
ld de, 0
|
||||
ld a, [wBattleMonLevel]
|
||||
add 3
|
||||
ld hl, wEnemyMonLevel
|
||||
cp [hl]
|
||||
jr nc, .not_stronger
|
||||
set TRANS_STRONGER_F, e
|
||||
.not_stronger
|
||||
ld a, [wEnvironment]
|
||||
cp CAVE
|
||||
jr z, .cave
|
||||
cp ENVIRONMENT_5
|
||||
jr z, .cave
|
||||
cp DUNGEON
|
||||
jr z, .cave
|
||||
set TRANS_NO_CAVE_F, e
|
||||
.cave
|
||||
ld hl, .StartingPoints
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
ld [wJumptableIndex], a
|
||||
ret
|
||||
|
||||
.StartingPoints:
|
||||
; entries correspond to TRANS_* constants
|
||||
db BATTLETRANSITION_CAVE
|
||||
db BATTLETRANSITION_CAVE_STRONGER
|
||||
db BATTLETRANSITION_NO_CAVE
|
||||
db BATTLETRANSITION_NO_CAVE_STRONGER
|
||||
|
||||
StartTrainerBattle_Finish:
|
||||
call ClearSprites
|
||||
ld a, BATTLETRANSITION_END
|
||||
ld [wJumptableIndex], a
|
||||
ret
|
||||
|
||||
StartTrainerBattle_NextScene:
|
||||
ld hl, wJumptableIndex
|
||||
inc [hl]
|
||||
ret
|
||||
|
||||
StartTrainerBattle_SetUpBGMap:
|
||||
call StartTrainerBattle_NextScene
|
||||
xor a
|
||||
ld [wBattleTransitionCounter], a
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
StartTrainerBattle_Flash:
|
||||
call .DoFlashAnimation
|
||||
ret nc
|
||||
call StartTrainerBattle_NextScene
|
||||
ret
|
||||
|
||||
.DoFlashAnimation:
|
||||
ld a, [wTimeOfDayPalset]
|
||||
cp DARKNESS_PALSET
|
||||
jr z, .done
|
||||
ld hl, wBattleTransitionCounter
|
||||
ld a, [hl]
|
||||
inc [hl]
|
||||
srl a
|
||||
ld e, a
|
||||
ld d, 0
|
||||
ld hl, .pals
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
cp %00000001
|
||||
jr z, .done
|
||||
ld [wBGP], a
|
||||
call DmgToCgbBGPals
|
||||
and a
|
||||
ret
|
||||
|
||||
.done
|
||||
xor a
|
||||
ld [wBattleTransitionCounter], a
|
||||
scf
|
||||
ret
|
||||
|
||||
.pals:
|
||||
dc 3, 3, 2, 1
|
||||
dc 3, 3, 3, 2
|
||||
dc 3, 3, 3, 3
|
||||
dc 3, 3, 3, 2
|
||||
dc 3, 3, 2, 1
|
||||
dc 3, 2, 1, 0
|
||||
dc 2, 1, 0, 0
|
||||
dc 1, 0, 0, 0
|
||||
dc 0, 0, 0, 0
|
||||
dc 1, 0, 0, 0
|
||||
dc 2, 1, 0, 0
|
||||
dc 3, 2, 1, 0
|
||||
dc 0, 0, 0, 1
|
||||
|
||||
StartTrainerBattle_SetUpForWavyOutro:
|
||||
vc_hook Stop_reducing_battle_transition_flashing_WavyOutro
|
||||
farcall RespawnPlayerAndOpponent
|
||||
ld a, BANK(wLYOverrides)
|
||||
ldh [rSVBK], a
|
||||
call StartTrainerBattle_NextScene
|
||||
|
||||
ld a, LOW(rSCX)
|
||||
ldh [hLCDCPointer], a
|
||||
xor a
|
||||
ldh [hLYOverrideStart], a
|
||||
ld a, $90
|
||||
ldh [hLYOverrideEnd], a
|
||||
xor a
|
||||
ld [wBattleTransitionCounter], a
|
||||
ld [wBattleTransitionSineWaveOffset], a
|
||||
ret
|
||||
|
||||
StartTrainerBattle_SineWave:
|
||||
ld a, [wBattleTransitionCounter]
|
||||
cp $60
|
||||
jr nc, .end
|
||||
call .DoSineWave
|
||||
ret
|
||||
|
||||
.end
|
||||
ld a, BATTLETRANSITION_FINISH
|
||||
ld [wJumptableIndex], a
|
||||
ret
|
||||
|
||||
.DoSineWave:
|
||||
ld hl, wBattleTransitionSineWaveOffset
|
||||
ld a, [hl]
|
||||
inc [hl]
|
||||
ld hl, wBattleTransitionCounter
|
||||
ld d, [hl]
|
||||
add [hl]
|
||||
ld [hl], a
|
||||
ld a, wLYOverridesEnd - wLYOverrides
|
||||
ld bc, wLYOverrides
|
||||
ld e, 0
|
||||
|
||||
.loop
|
||||
push af
|
||||
push de
|
||||
ld a, e
|
||||
call StartTrainerBattle_DrawSineWave
|
||||
ld [bc], a
|
||||
inc bc
|
||||
pop de
|
||||
ld a, e
|
||||
add 2
|
||||
ld e, a
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
StartTrainerBattle_SetUpForSpinOutro:
|
||||
vc_hook Stop_reducing_battle_transition_flashing_SpinOutro
|
||||
farcall RespawnPlayerAndOpponent
|
||||
ld a, BANK(wLYOverrides)
|
||||
ldh [rSVBK], a
|
||||
call StartTrainerBattle_NextScene
|
||||
xor a
|
||||
ld [wBattleTransitionCounter], a
|
||||
ret
|
||||
|
||||
StartTrainerBattle_SpinToBlack:
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ld a, [wBattleTransitionCounter]
|
||||
ld e, a
|
||||
ld d, 0
|
||||
ld hl, .spin_quadrants
|
||||
rept 5
|
||||
add hl, de
|
||||
endr
|
||||
ld a, [hli]
|
||||
cp -1
|
||||
jr z, .end
|
||||
ld [wBattleTransitionSineWaveOffset], a
|
||||
call .load
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
call DelayFrame
|
||||
call DelayFrame
|
||||
ld hl, wBattleTransitionCounter
|
||||
inc [hl]
|
||||
ret
|
||||
|
||||
.end
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
call DelayFrame
|
||||
call DelayFrame
|
||||
call DelayFrame
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ld a, BATTLETRANSITION_FINISH
|
||||
ld [wJumptableIndex], a
|
||||
ret
|
||||
|
||||
; quadrants
|
||||
const_def
|
||||
const UPPER_LEFT
|
||||
const UPPER_RIGHT
|
||||
const LOWER_LEFT
|
||||
const LOWER_RIGHT
|
||||
|
||||
; quadrant bits
|
||||
DEF RIGHT_QUADRANT_F EQU 0 ; bit set in UPPER_RIGHT and LOWER_RIGHT
|
||||
DEF LOWER_QUADRANT_F EQU 1 ; bit set in LOWER_LEFT and LOWER_RIGHT
|
||||
|
||||
.spin_quadrants:
|
||||
MACRO spin_quadrant
|
||||
db \1
|
||||
dw \2
|
||||
dwcoord \3, \4
|
||||
ENDM
|
||||
spin_quadrant UPPER_LEFT, .wedge1, 1, 6
|
||||
spin_quadrant UPPER_LEFT, .wedge2, 0, 3
|
||||
spin_quadrant UPPER_LEFT, .wedge3, 1, 0
|
||||
spin_quadrant UPPER_LEFT, .wedge4, 5, 0
|
||||
spin_quadrant UPPER_LEFT, .wedge5, 9, 0
|
||||
spin_quadrant UPPER_RIGHT, .wedge5, 10, 0
|
||||
spin_quadrant UPPER_RIGHT, .wedge4, 14, 0
|
||||
spin_quadrant UPPER_RIGHT, .wedge3, 18, 0
|
||||
spin_quadrant UPPER_RIGHT, .wedge2, 19, 3
|
||||
spin_quadrant UPPER_RIGHT, .wedge1, 18, 6
|
||||
spin_quadrant LOWER_RIGHT, .wedge1, 18, 11
|
||||
spin_quadrant LOWER_RIGHT, .wedge2, 19, 14
|
||||
spin_quadrant LOWER_RIGHT, .wedge3, 18, 17
|
||||
spin_quadrant LOWER_RIGHT, .wedge4, 14, 17
|
||||
spin_quadrant LOWER_RIGHT, .wedge5, 10, 17
|
||||
spin_quadrant LOWER_LEFT, .wedge5, 9, 17
|
||||
spin_quadrant LOWER_LEFT, .wedge4, 5, 17
|
||||
spin_quadrant LOWER_LEFT, .wedge3, 1, 17
|
||||
spin_quadrant LOWER_LEFT, .wedge2, 0, 14
|
||||
spin_quadrant LOWER_LEFT, .wedge1, 1, 11
|
||||
db -1
|
||||
|
||||
.load:
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
.loop
|
||||
push hl
|
||||
ld a, [de]
|
||||
ld c, a
|
||||
inc de
|
||||
.loop1
|
||||
ld [hl], BATTLETRANSITION_BLACK
|
||||
ld a, [wBattleTransitionSineWaveOffset]
|
||||
bit RIGHT_QUADRANT_F, a
|
||||
jr z, .leftside
|
||||
inc hl
|
||||
jr .okay1
|
||||
.leftside
|
||||
dec hl
|
||||
.okay1
|
||||
dec c
|
||||
jr nz, .loop1
|
||||
pop hl
|
||||
ld a, [wBattleTransitionSineWaveOffset]
|
||||
bit LOWER_QUADRANT_F, a
|
||||
ld bc, SCREEN_WIDTH
|
||||
jr z, .upper
|
||||
ld bc, -SCREEN_WIDTH
|
||||
.upper
|
||||
add hl, bc
|
||||
ld a, [de]
|
||||
inc de
|
||||
cp -1
|
||||
ret z
|
||||
and a
|
||||
jr z, .loop
|
||||
ld c, a
|
||||
.loop2
|
||||
ld a, [wBattleTransitionSineWaveOffset]
|
||||
bit RIGHT_QUADRANT_F, a
|
||||
jr z, .leftside2
|
||||
dec hl
|
||||
jr .okay2
|
||||
.leftside2
|
||||
inc hl
|
||||
.okay2
|
||||
dec c
|
||||
jr nz, .loop2
|
||||
jr .loop
|
||||
|
||||
.wedge1: db 2, 3, 5, 4, 9, -1
|
||||
.wedge2: db 1, 1, 2, 2, 4, 2, 4, 2, 3, -1
|
||||
.wedge3: db 2, 1, 3, 1, 4, 1, 4, 1, 4, 1, 3, 1, 2, 1, 1, 1, 1, -1
|
||||
.wedge4: db 4, 1, 4, 0, 3, 1, 3, 0, 2, 1, 2, 0, 1, -1
|
||||
.wedge5: db 4, 0, 3, 0, 3, 0, 2, 0, 2, 0, 1, 0, 1, 0, 1, -1
|
||||
|
||||
StartTrainerBattle_SetUpForRandomScatterOutro:
|
||||
vc_hook Stop_reducing_battle_transition_flashing_ScatterOutro
|
||||
farcall RespawnPlayerAndOpponent
|
||||
ld a, BANK(wLYOverrides)
|
||||
ldh [rSVBK], a
|
||||
call StartTrainerBattle_NextScene
|
||||
ld a, $10
|
||||
ld [wBattleTransitionCounter], a
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
StartTrainerBattle_SpeckleToBlack:
|
||||
ld hl, wBattleTransitionCounter
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .done
|
||||
dec [hl]
|
||||
ld c, $c
|
||||
.loop
|
||||
push bc
|
||||
call .BlackOutRandomTile
|
||||
pop bc
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
.done
|
||||
ld a, $1
|
||||
ldh [hBGMapMode], a
|
||||
call DelayFrame
|
||||
call DelayFrame
|
||||
call DelayFrame
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ld a, BATTLETRANSITION_FINISH
|
||||
ld [wJumptableIndex], a
|
||||
ret
|
||||
|
||||
.BlackOutRandomTile:
|
||||
.y_loop
|
||||
call Random
|
||||
cp SCREEN_HEIGHT
|
||||
jr nc, .y_loop
|
||||
ld b, a
|
||||
|
||||
.x_loop
|
||||
call Random
|
||||
cp SCREEN_WIDTH
|
||||
jr nc, .x_loop
|
||||
ld c, a
|
||||
|
||||
hlcoord 0, -1
|
||||
ld de, SCREEN_WIDTH
|
||||
inc b
|
||||
|
||||
.row_loop
|
||||
add hl, de
|
||||
dec b
|
||||
jr nz, .row_loop
|
||||
add hl, bc
|
||||
|
||||
; If the tile has already been blacked out,
|
||||
; sample a new tile
|
||||
ld a, [hl]
|
||||
cp BATTLETRANSITION_BLACK
|
||||
jr z, .y_loop
|
||||
ld [hl], BATTLETRANSITION_BLACK
|
||||
ret
|
||||
|
||||
StartTrainerBattle_LoadPokeBallGraphics:
|
||||
ld a, [wOtherTrainerClass]
|
||||
and a
|
||||
jp z, .nextscene ; don't need to be here if wild
|
||||
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
|
||||
hlcoord 0, 0, wAttrmap
|
||||
ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
|
||||
inc b
|
||||
inc c
|
||||
jr .enter_loop_midway
|
||||
|
||||
.pal_loop
|
||||
; set all pals to 7
|
||||
ld a, [hl]
|
||||
or PAL_BG_TEXT
|
||||
ld [hli], a
|
||||
.enter_loop_midway
|
||||
dec c
|
||||
jr nz, .pal_loop
|
||||
dec b
|
||||
jr nz, .pal_loop
|
||||
|
||||
call .loadpokeballgfx
|
||||
hlcoord 2, 1
|
||||
|
||||
ld b, SCREEN_WIDTH - 4
|
||||
.tile_loop
|
||||
push hl
|
||||
ld c, 2
|
||||
.row_loop
|
||||
push hl
|
||||
ld a, [de]
|
||||
inc de
|
||||
.col_loop
|
||||
; Loading is done bit by bit
|
||||
and a
|
||||
jr z, .done
|
||||
sla a
|
||||
jr nc, .no_load
|
||||
ld [hl], BATTLETRANSITION_SQUARE
|
||||
.no_load
|
||||
inc hl
|
||||
jr .col_loop
|
||||
|
||||
.done
|
||||
pop hl
|
||||
push bc
|
||||
ld bc, (SCREEN_WIDTH - 4) / 2
|
||||
add hl, bc
|
||||
pop bc
|
||||
dec c
|
||||
jr nz, .row_loop
|
||||
|
||||
pop hl
|
||||
push bc
|
||||
ld bc, SCREEN_WIDTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
dec b
|
||||
jr nz, .tile_loop
|
||||
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr nz, .cgb
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
call DelayFrame
|
||||
call DelayFrame
|
||||
jr .nextscene
|
||||
|
||||
.cgb
|
||||
ld hl, .pals
|
||||
ld a, [wTimeOfDayPal]
|
||||
maskbits NUM_DAYTIMES
|
||||
cp DARKNESS_F
|
||||
jr nz, .not_dark
|
||||
ld hl, .darkpals
|
||||
.not_dark
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wBGPals1)
|
||||
ldh [rSVBK], a
|
||||
call .copypals
|
||||
push hl
|
||||
ld de, wBGPals1 palette PAL_BG_TEXT
|
||||
ld bc, 1 palettes
|
||||
call CopyBytes
|
||||
pop hl
|
||||
ld de, wBGPals2 palette PAL_BG_TEXT
|
||||
ld bc, 1 palettes
|
||||
call CopyBytes
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ld a, TRUE
|
||||
ldh [hCGBPalUpdate], a
|
||||
call DelayFrame
|
||||
call BattleStart_CopyTilemapAtOnce
|
||||
|
||||
.nextscene
|
||||
call StartTrainerBattle_NextScene
|
||||
ret
|
||||
|
||||
.copypals
|
||||
ld de, wBGPals1 palette PAL_BG_TEXT
|
||||
call .copy
|
||||
ld de, wBGPals2 palette PAL_BG_TEXT
|
||||
call .copy
|
||||
ld de, wOBPals1 palette PAL_OW_TREE
|
||||
call .copy
|
||||
ld de, wOBPals2 palette PAL_OW_TREE
|
||||
call .copy
|
||||
ld de, wOBPals1 palette PAL_OW_ROCK
|
||||
call .copy
|
||||
ld de, wOBPals2 palette PAL_OW_ROCK
|
||||
|
||||
.copy
|
||||
push hl
|
||||
ld bc, 1 palettes
|
||||
call CopyBytes
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.pals:
|
||||
INCLUDE "gfx/overworld/trainer_battle.pal"
|
||||
|
||||
.darkpals:
|
||||
INCLUDE "gfx/overworld/trainer_battle_dark.pal"
|
||||
|
||||
.loadpokeballgfx:
|
||||
ld a, [wOtherTrainerClass]
|
||||
ld de, PokeBallTransition
|
||||
ret
|
||||
|
||||
PokeBallTransition:
|
||||
; 16x16 overlay of a Poke Ball
|
||||
pusho
|
||||
opt b.X ; . = 0, X = 1
|
||||
bigdw %......XXXX......
|
||||
bigdw %....XXXXXXXX....
|
||||
bigdw %..XXXX....XXXX..
|
||||
bigdw %..XX........XX..
|
||||
bigdw %.XX..........XX.
|
||||
bigdw %.XX...XXXX...XX.
|
||||
bigdw %XX...XX..XX...XX
|
||||
bigdw %XXXXXX....XXXXXX
|
||||
bigdw %XXXXXX....XXXXXX
|
||||
bigdw %XX...XX..XX...XX
|
||||
bigdw %.XX...XXXX...XX.
|
||||
bigdw %.XX..........XX.
|
||||
bigdw %..XX........XX..
|
||||
bigdw %..XXXX....XXXX..
|
||||
bigdw %....XXXXXXXX....
|
||||
bigdw %......XXXX......
|
||||
popo
|
||||
|
||||
WipeLYOverrides:
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wLYOverrides)
|
||||
ldh [rSVBK], a
|
||||
|
||||
ld hl, wLYOverrides
|
||||
call .wipe
|
||||
ld hl, wLYOverridesBackup
|
||||
call .wipe
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
|
||||
.wipe
|
||||
xor a
|
||||
ld c, SCREEN_HEIGHT_PX
|
||||
.loop
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
StartTrainerBattle_DrawSineWave:
|
||||
calc_sine_wave
|
||||
|
||||
StartTrainerBattle_ZoomToBlack:
|
||||
vc_hook Stop_reducing_battle_transition_flashing_ZoomToBlack
|
||||
farcall RespawnPlayerAndOpponent
|
||||
ld de, .boxes
|
||||
|
||||
.loop
|
||||
ld a, [de]
|
||||
cp -1
|
||||
jr z, .done
|
||||
inc de
|
||||
ld c, a
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld b, a
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld l, a
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld h, a
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
call .Copy
|
||||
call WaitBGMap
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
ld a, BATTLETRANSITION_FINISH
|
||||
ld [wJumptableIndex], a
|
||||
ret
|
||||
|
||||
.boxes
|
||||
MACRO zoombox
|
||||
; width, height, start y, start x
|
||||
db \1, \2
|
||||
dwcoord \3, \4
|
||||
ENDM
|
||||
zoombox 4, 2, 8, 8
|
||||
zoombox 6, 4, 7, 7
|
||||
zoombox 8, 6, 6, 6
|
||||
zoombox 10, 8, 5, 5
|
||||
zoombox 12, 10, 4, 4
|
||||
zoombox 14, 12, 3, 3
|
||||
zoombox 16, 14, 2, 2
|
||||
zoombox 18, 16, 1, 1
|
||||
zoombox 20, 18, 0, 0
|
||||
db -1
|
||||
|
||||
.Copy:
|
||||
ld a, BATTLETRANSITION_BLACK
|
||||
.row
|
||||
push bc
|
||||
push hl
|
||||
.col
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .col
|
||||
pop hl
|
||||
ld bc, SCREEN_WIDTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
dec b
|
||||
jr nz, .row
|
||||
ret
|
||||
|
||||
UnusedWaitBGMapOnce: ; unreferenced
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a ; redundant
|
||||
call WaitBGMap
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
3
engine/battle/battlestart_copytilemapatonce.asm
Normal file
3
engine/battle/battlestart_copytilemapatonce.asm
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
BattleStart_CopyTilemapAtOnce:
|
||||
call CGBOnly_CopyTilemapAtOnce
|
||||
ret
|
||||
47
engine/battle/check_battle_scene.asm
Normal file
47
engine/battle/check_battle_scene.asm
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
CheckBattleScene:
|
||||
; Return carry if battle scene is turned off.
|
||||
|
||||
ld a, BANK(wLinkMode)
|
||||
ld hl, wLinkMode
|
||||
call GetFarWRAMByte
|
||||
cp LINK_MOBILE
|
||||
jr z, .mobile
|
||||
|
||||
ld a, [wOptions]
|
||||
bit BATTLE_SCENE, a
|
||||
jr nz, .off
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
.mobile
|
||||
ld a, [wcd2f]
|
||||
and a
|
||||
jr nz, .from_wram
|
||||
|
||||
ld a, BANK(s4_a60c) ; MBC30 bank used by JP Crystal; inaccessible by MBC3
|
||||
call OpenSRAM
|
||||
ld a, [s4_a60c]
|
||||
ld c, a
|
||||
call CloseSRAM
|
||||
|
||||
ld a, c
|
||||
bit 0, c
|
||||
jr z, .off
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
.from_wram
|
||||
ld a, BANK(w5_dc00)
|
||||
ld hl, w5_dc00
|
||||
call GetFarWRAMByte
|
||||
bit 0, a
|
||||
jr z, .off
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
.off
|
||||
scf
|
||||
ret
|
||||
57
engine/battle/consume_held_item.asm
Normal file
57
engine/battle/consume_held_item.asm
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
ConsumeHeldItem:
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ld hl, wOTPartyMon1Item
|
||||
ld de, wEnemyMonItem
|
||||
ld a, [wCurOTMon]
|
||||
jr z, .theirturn
|
||||
ld hl, wPartyMon1Item
|
||||
ld de, wBattleMonItem
|
||||
ld a, [wCurBattleMon]
|
||||
|
||||
.theirturn
|
||||
push hl
|
||||
push af
|
||||
ld a, [de]
|
||||
ld b, a
|
||||
farcall 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
|
||||
call GetPartyLocation
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .ourturn
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
jr z, .done
|
||||
|
||||
.ourturn
|
||||
ld [hl], NO_ITEM
|
||||
|
||||
.done
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
INCLUDE "data/battle/held_consumables.asm"
|
||||
9236
engine/battle/core.asm
Normal file
9236
engine/battle/core.asm
Normal file
File diff suppressed because it is too large
Load diff
6878
engine/battle/effect_commands.asm
Normal file
6878
engine/battle/effect_commands.asm
Normal file
File diff suppressed because it is too large
Load diff
108
engine/battle/hidden_power.asm
Normal file
108
engine/battle/hidden_power.asm
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
HiddenPowerDamage:
|
||||
; Override Hidden Power's type and power based on the user's DVs.
|
||||
|
||||
ld hl, wBattleMonDVs
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_dvs
|
||||
ld hl, wEnemyMonDVs
|
||||
.got_dvs
|
||||
|
||||
; Power:
|
||||
|
||||
; Take the top bit from each stat
|
||||
|
||||
; Attack
|
||||
ld a, [hl]
|
||||
swap a
|
||||
and %1000
|
||||
|
||||
; Defense
|
||||
ld b, a
|
||||
ld a, [hli]
|
||||
and %1000
|
||||
srl a
|
||||
or b
|
||||
|
||||
; Speed
|
||||
ld b, a
|
||||
ld a, [hl]
|
||||
swap a
|
||||
and %1000
|
||||
srl a
|
||||
srl a
|
||||
or b
|
||||
|
||||
; Special
|
||||
ld b, a
|
||||
ld a, [hl]
|
||||
and %1000
|
||||
srl a
|
||||
srl a
|
||||
srl a
|
||||
or b
|
||||
|
||||
; Multiply by 5
|
||||
ld b, a
|
||||
add a
|
||||
add a
|
||||
add b
|
||||
|
||||
; Add Special & 3
|
||||
ld b, a
|
||||
ld a, [hld]
|
||||
and %0011
|
||||
add b
|
||||
|
||||
; Divide by 2 and add 30 + 1
|
||||
srl a
|
||||
add 30
|
||||
inc a
|
||||
|
||||
ld d, a
|
||||
|
||||
; Type:
|
||||
|
||||
; Def & 3
|
||||
ld a, [hl]
|
||||
and %0011
|
||||
ld b, a
|
||||
|
||||
; + (Atk & 3) << 2
|
||||
ld a, [hl]
|
||||
and %0011 << 4
|
||||
swap a
|
||||
add a
|
||||
add a
|
||||
or b
|
||||
|
||||
; Skip Normal
|
||||
inc a
|
||||
|
||||
; Skip Bird
|
||||
cp BIRD
|
||||
jr c, .done
|
||||
inc a
|
||||
|
||||
; Skip unused types
|
||||
cp UNUSED_TYPES
|
||||
jr c, .done
|
||||
add UNUSED_TYPES_END - UNUSED_TYPES
|
||||
|
||||
.done
|
||||
|
||||
; Overwrite the current move type.
|
||||
push af
|
||||
ld a, BATTLE_VARS_MOVE_TYPE
|
||||
call GetBattleVarAddr
|
||||
pop af
|
||||
ld [hl], a
|
||||
|
||||
; Get the rest of the damage formula variables
|
||||
; based on the new type, but keep base power.
|
||||
ld a, d
|
||||
push af
|
||||
farcall BattleCommand_DamageStats ; damagestats
|
||||
pop af
|
||||
ld d, a
|
||||
ret
|
||||
162
engine/battle/link_result.asm
Normal file
162
engine/battle/link_result.asm
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
DetermineLinkBattleResult:
|
||||
farcall UpdateEnemyMonInParty
|
||||
ld hl, wPartyMon1HP
|
||||
call .CountMonsRemaining
|
||||
push bc
|
||||
ld hl, wOTPartyMon1HP
|
||||
call .CountMonsRemaining
|
||||
ld a, c
|
||||
pop bc
|
||||
cp c
|
||||
jr z, .even_number_of_mons_remaining
|
||||
jr c, .defeat
|
||||
jr .victory
|
||||
|
||||
.even_number_of_mons_remaining
|
||||
call .BothSides_CheckNumberMonsAtFullHealth
|
||||
jr z, .drawn
|
||||
ld a, e
|
||||
cp $1
|
||||
jr z, .victory
|
||||
cp $2
|
||||
jr z, .defeat
|
||||
ld hl, wPartyMon1HP
|
||||
call .CalcPercentHPRemaining
|
||||
push de
|
||||
ld hl, wOTPartyMon1HP
|
||||
call .CalcPercentHPRemaining
|
||||
pop hl
|
||||
ld a, d
|
||||
cp h
|
||||
jr c, .victory
|
||||
jr z, .compare_lo
|
||||
jr .defeat
|
||||
|
||||
.compare_lo
|
||||
ld a, e
|
||||
cp l
|
||||
jr z, .drawn
|
||||
jr nc, .defeat
|
||||
|
||||
.victory
|
||||
ld a, [wBattleResult]
|
||||
and $f0
|
||||
ld [wBattleResult], a ; WIN
|
||||
ret
|
||||
|
||||
.defeat
|
||||
ld a, [wBattleResult]
|
||||
and $f0
|
||||
add LOSE
|
||||
ld [wBattleResult], a
|
||||
ret
|
||||
|
||||
.drawn
|
||||
ld a, [wBattleResult]
|
||||
and $f0
|
||||
add DRAW
|
||||
ld [wBattleResult], a
|
||||
ret
|
||||
|
||||
.CountMonsRemaining:
|
||||
ld c, 0
|
||||
ld b, 3
|
||||
ld de, PARTYMON_STRUCT_LENGTH - 1
|
||||
.loop
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
jr nz, .not_fainted
|
||||
inc c
|
||||
|
||||
.not_fainted
|
||||
add hl, de
|
||||
dec b
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
.CalcPercentHPRemaining:
|
||||
ld de, 0
|
||||
ld c, $3
|
||||
.loop2
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
jr z, .next
|
||||
dec hl
|
||||
xor a
|
||||
ldh [hDividend + 0], a
|
||||
ld a, [hli]
|
||||
ldh [hDividend + 1], a
|
||||
ld a, [hli]
|
||||
ldh [hDividend + 2], a
|
||||
xor a
|
||||
ldh [hDividend + 3], a
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hld]
|
||||
srl b
|
||||
rr a
|
||||
srl b
|
||||
rr a
|
||||
ldh [hDivisor], a
|
||||
ld b, $4
|
||||
call Divide
|
||||
ldh a, [hQuotient + 3]
|
||||
add e
|
||||
ld e, a
|
||||
ldh a, [hQuotient + 2]
|
||||
adc d
|
||||
ld d, a
|
||||
dec hl
|
||||
|
||||
.next
|
||||
push de
|
||||
ld de, $2f
|
||||
add hl, de
|
||||
pop de
|
||||
dec c
|
||||
jr nz, .loop2
|
||||
ret
|
||||
|
||||
.BothSides_CheckNumberMonsAtFullHealth:
|
||||
ld hl, wPartyMon1HP
|
||||
call .CheckFaintedOrFullHealth
|
||||
jr nz, .finish ; we have a pokemon that's neither fainted nor at full health
|
||||
ld hl, wOTPartyMon1HP
|
||||
call .CheckFaintedOrFullHealth
|
||||
ld e, $1 ; victory
|
||||
ret
|
||||
|
||||
.finish
|
||||
ld hl, wOTPartyMon1HP
|
||||
call .CheckFaintedOrFullHealth
|
||||
ld e, $0 ; drawn
|
||||
ret nz ; we both have pokemon that are neither fainted nor at full health
|
||||
ld e, $2 ; defeat
|
||||
ld a, $1 ; not drawn
|
||||
and a
|
||||
ret
|
||||
|
||||
.CheckFaintedOrFullHealth:
|
||||
ld d, 3
|
||||
.loop3
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
or b
|
||||
jr z, .fainted_or_full_health
|
||||
ld a, [hli]
|
||||
cp b
|
||||
ret nz
|
||||
ld a, [hld]
|
||||
cp c
|
||||
ret nz
|
||||
|
||||
.fainted_or_full_health
|
||||
push de
|
||||
ld de, PARTYMON_STRUCT_LENGTH - 2
|
||||
add hl, de
|
||||
pop de
|
||||
dec d
|
||||
jr nz, .loop3
|
||||
ret
|
||||
100
engine/battle/menu.asm
Normal file
100
engine/battle/menu.asm
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
LoadBattleMenu:
|
||||
ld hl, BattleMenuHeader
|
||||
call LoadMenuHeader
|
||||
ld a, [wBattleMenuCursorPosition]
|
||||
ld [wMenuCursorPosition], a
|
||||
call InterpretBattleMenu
|
||||
ld a, [wMenuCursorPosition]
|
||||
ld [wBattleMenuCursorPosition], a
|
||||
call ExitMenu
|
||||
ret
|
||||
|
||||
SafariBattleMenu: ; unreferenced
|
||||
ld hl, SafariBattleMenuHeader
|
||||
call LoadMenuHeader
|
||||
jr CommonBattleMenu
|
||||
|
||||
ContestBattleMenu:
|
||||
ld hl, ContestBattleMenuHeader
|
||||
call LoadMenuHeader
|
||||
; fallthrough
|
||||
|
||||
CommonBattleMenu:
|
||||
ld a, [wBattleMenuCursorPosition]
|
||||
ld [wMenuCursorPosition], a
|
||||
call _2DMenu
|
||||
ld a, [wMenuCursorPosition]
|
||||
ld [wBattleMenuCursorPosition], a
|
||||
call ExitMenu
|
||||
ret
|
||||
|
||||
BattleMenuHeader:
|
||||
db MENU_BACKUP_TILES ; flags
|
||||
menu_coords 8, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
|
||||
dw .MenuData
|
||||
db 1 ; default option
|
||||
|
||||
.MenuData:
|
||||
db STATICMENU_CURSOR | STATICMENU_DISABLE_B ; flags
|
||||
dn 2, 2 ; rows, columns
|
||||
db 6 ; spacing
|
||||
dba .Text
|
||||
dbw BANK(@), NULL
|
||||
|
||||
.Text:
|
||||
db "FIGHT@"
|
||||
db "<PKMN>@"
|
||||
db "PACK@"
|
||||
db "RUN@"
|
||||
|
||||
SafariBattleMenuHeader:
|
||||
db MENU_BACKUP_TILES ; flags
|
||||
menu_coords 0, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
|
||||
dw .MenuData
|
||||
db 1 ; default option
|
||||
|
||||
.MenuData:
|
||||
db STATICMENU_CURSOR | STATICMENU_DISABLE_B ; flags
|
||||
dn 2, 2 ; rows, columns
|
||||
db 11 ; spacing
|
||||
dba .Text
|
||||
dba .PrintSafariBallsRemaining
|
||||
|
||||
.Text:
|
||||
db "サファりボール× @" ; "SAFARI BALL× @"
|
||||
db "エサをなげる@" ; "THROW BAIT"
|
||||
db "いしをなげる@" ; "THROW ROCK"
|
||||
db "にげる@" ; "RUN"
|
||||
|
||||
.PrintSafariBallsRemaining:
|
||||
hlcoord 17, 13
|
||||
ld de, wSafariBallsRemaining
|
||||
lb bc, PRINTNUM_LEADINGZEROS | 1, 2
|
||||
call PrintNum
|
||||
ret
|
||||
|
||||
ContestBattleMenuHeader:
|
||||
db MENU_BACKUP_TILES ; flags
|
||||
menu_coords 2, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
|
||||
dw .MenuData
|
||||
db 1 ; default option
|
||||
|
||||
.MenuData:
|
||||
db STATICMENU_CURSOR | STATICMENU_DISABLE_B ; flags
|
||||
dn 2, 2 ; rows, columns
|
||||
db 12 ; spacing
|
||||
dba .Text
|
||||
dba .PrintParkBallsRemaining
|
||||
|
||||
.Text:
|
||||
db "FIGHT@"
|
||||
db "<PKMN>@"
|
||||
db "PARKBALL× @"
|
||||
db "RUN@"
|
||||
|
||||
.PrintParkBallsRemaining:
|
||||
hlcoord 13, 16
|
||||
ld de, wParkBallsRemaining
|
||||
lb bc, PRINTNUM_LEADINGZEROS | 1, 2
|
||||
call PrintNum
|
||||
ret
|
||||
224
engine/battle/misc.asm
Normal file
224
engine/battle/misc.asm
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
_DisappearUser:
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .player
|
||||
call GetEnemyFrontpicCoords
|
||||
jr .okay
|
||||
.player
|
||||
call GetPlayerBackpicCoords
|
||||
.okay
|
||||
call ClearBox
|
||||
jr FinishAppearDisappearUser
|
||||
|
||||
_AppearUserRaiseSub:
|
||||
farcall BattleCommand_RaiseSubNoAnim
|
||||
jr AppearUser
|
||||
|
||||
_AppearUserLowerSub:
|
||||
farcall BattleCommand_LowerSubNoAnim
|
||||
|
||||
AppearUser:
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .player
|
||||
call GetEnemyFrontpicCoords
|
||||
xor a
|
||||
jr .okay
|
||||
.player
|
||||
call GetPlayerBackpicCoords
|
||||
ld a, $31
|
||||
.okay
|
||||
ldh [hGraphicStartTile], a
|
||||
predef PlaceGraphic
|
||||
FinishAppearDisappearUser:
|
||||
ld a, $1
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
GetEnemyFrontpicCoords:
|
||||
hlcoord 12, 0
|
||||
lb bc, 7, 7
|
||||
ret
|
||||
|
||||
GetPlayerBackpicCoords:
|
||||
hlcoord 2, 6
|
||||
lb bc, 6, 6
|
||||
ret
|
||||
|
||||
DoWeatherModifiers:
|
||||
ld de, WeatherTypeModifiers
|
||||
ld a, [wBattleWeather]
|
||||
ld b, a
|
||||
ld a, [wCurType]
|
||||
ld c, a
|
||||
|
||||
.CheckWeatherType:
|
||||
ld a, [de]
|
||||
inc de
|
||||
cp -1
|
||||
jr z, .done_weather_types
|
||||
|
||||
cp b
|
||||
jr nz, .NextWeatherType
|
||||
|
||||
ld a, [de]
|
||||
cp c
|
||||
jr z, .ApplyModifier
|
||||
|
||||
.NextWeatherType:
|
||||
inc de
|
||||
inc de
|
||||
jr .CheckWeatherType
|
||||
|
||||
.done_weather_types
|
||||
ld de, WeatherMoveModifiers
|
||||
|
||||
ld a, BATTLE_VARS_MOVE_EFFECT
|
||||
call GetBattleVar
|
||||
ld c, a
|
||||
|
||||
.CheckWeatherMove:
|
||||
ld a, [de]
|
||||
inc de
|
||||
cp -1
|
||||
jr z, .done
|
||||
|
||||
cp b
|
||||
jr nz, .NextWeatherMove
|
||||
|
||||
ld a, [de]
|
||||
cp c
|
||||
jr z, .ApplyModifier
|
||||
|
||||
.NextWeatherMove:
|
||||
inc de
|
||||
inc de
|
||||
jr .CheckWeatherMove
|
||||
|
||||
.ApplyModifier:
|
||||
xor a
|
||||
ldh [hMultiplicand + 0], a
|
||||
ld hl, wCurDamage
|
||||
ld a, [hli]
|
||||
ldh [hMultiplicand + 1], a
|
||||
ld a, [hl]
|
||||
ldh [hMultiplicand + 2], a
|
||||
|
||||
inc de
|
||||
ld a, [de]
|
||||
ldh [hMultiplier], a
|
||||
|
||||
call Multiply
|
||||
|
||||
ld a, 10
|
||||
ldh [hDivisor], a
|
||||
ld b, 4
|
||||
call Divide
|
||||
|
||||
ldh a, [hQuotient + 1]
|
||||
and a
|
||||
ld bc, -1
|
||||
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
|
||||
ret
|
||||
|
||||
INCLUDE "data/battle/weather_modifiers.asm"
|
||||
|
||||
DoBadgeTypeBoosts:
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
ld a, [wInBattleTowerBattle]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
push de
|
||||
push bc
|
||||
|
||||
ld hl, BadgeTypeBoosts
|
||||
|
||||
ld a, [wKantoBadges]
|
||||
ld b, a
|
||||
ld a, [wJohtoBadges]
|
||||
ld c, a
|
||||
|
||||
.CheckBadge:
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .done
|
||||
|
||||
srl b
|
||||
rr c
|
||||
jr nc, .NextBadge
|
||||
|
||||
ld a, [wCurType]
|
||||
cp [hl]
|
||||
jr z, .ApplyBoost
|
||||
|
||||
.NextBadge:
|
||||
inc hl
|
||||
jr .CheckBadge
|
||||
|
||||
.ApplyBoost:
|
||||
ld a, [wCurDamage]
|
||||
ld h, a
|
||||
ld d, a
|
||||
ld a, [wCurDamage + 1]
|
||||
ld l, a
|
||||
ld e, a
|
||||
|
||||
srl d
|
||||
rr e
|
||||
srl d
|
||||
rr e
|
||||
srl d
|
||||
rr e
|
||||
|
||||
ld a, e
|
||||
or d
|
||||
jr nz, .done_min
|
||||
ld e, 1
|
||||
|
||||
.done_min
|
||||
add hl, de
|
||||
jr nc, .Update
|
||||
|
||||
ld hl, $ffff
|
||||
|
||||
.Update:
|
||||
ld a, h
|
||||
ld [wCurDamage], a
|
||||
ld a, l
|
||||
ld [wCurDamage + 1], a
|
||||
|
||||
.done
|
||||
pop bc
|
||||
pop de
|
||||
ret
|
||||
|
||||
INCLUDE "data/types/badge_type_boosts.asm"
|
||||
75
engine/battle/move_effects/attract.asm
Normal file
75
engine/battle/move_effects/attract.asm
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
BattleCommand_Attract:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .failed
|
||||
call CheckOppositeGender
|
||||
jr c, .failed
|
||||
call CheckHiddenOpponent
|
||||
jr nz, .failed
|
||||
ld a, BATTLE_VARS_SUBSTATUS1_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_IN_LOVE, [hl]
|
||||
jr nz, .failed
|
||||
|
||||
set SUBSTATUS_IN_LOVE, [hl]
|
||||
call AnimateCurrentMove
|
||||
|
||||
; 'fell in love!'
|
||||
ld hl, FellInLoveText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
jp FailMove
|
||||
|
||||
CheckOppositeGender:
|
||||
ld a, MON_SPECIES
|
||||
call BattlePartyAttr
|
||||
ld a, [hl]
|
||||
ld [wCurPartySpecies], a
|
||||
|
||||
ld a, [wCurBattleMon]
|
||||
ld [wCurPartyMon], a
|
||||
xor a
|
||||
ld [wMonType], a
|
||||
|
||||
farcall GetGender
|
||||
jr c, .genderless_samegender
|
||||
|
||||
ld b, 1
|
||||
jr nz, .got_gender
|
||||
dec b
|
||||
|
||||
.got_gender
|
||||
push bc
|
||||
ld a, [wTempEnemyMonSpecies]
|
||||
ld [wCurPartySpecies], a
|
||||
ld hl, wEnemyMonDVs
|
||||
ld a, [wEnemySubStatus5]
|
||||
bit SUBSTATUS_TRANSFORMED, a
|
||||
jr z, .not_transformed
|
||||
ld hl, wEnemyBackupDVs
|
||||
.not_transformed
|
||||
ld a, [hli]
|
||||
ld [wTempMonDVs], a
|
||||
ld a, [hl]
|
||||
ld [wTempMonDVs + 1], a
|
||||
ld a, TEMPMON
|
||||
ld [wMonType], a
|
||||
farcall GetGender
|
||||
pop bc
|
||||
jr c, .genderless_samegender
|
||||
|
||||
ld a, 1
|
||||
jr nz, .got_enemy_gender
|
||||
dec a
|
||||
|
||||
.got_enemy_gender
|
||||
xor b
|
||||
jr z, .genderless_samegender
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
.genderless_samegender
|
||||
scf
|
||||
ret
|
||||
215
engine/battle/move_effects/baton_pass.asm
Normal file
215
engine/battle/move_effects/baton_pass.asm
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
BattleCommand_BatonPass:
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jp nz, .Enemy
|
||||
|
||||
; Need something to switch to
|
||||
call CheckAnyOtherAlivePartyMons
|
||||
jp z, FailedBatonPass
|
||||
|
||||
call UpdateBattleMonInParty
|
||||
call AnimateCurrentMove
|
||||
|
||||
ld c, 50
|
||||
call DelayFrames
|
||||
|
||||
; Transition into switchmon menu
|
||||
call LoadStandardMenuHeader
|
||||
farcall SetUpBattlePartyMenu
|
||||
|
||||
farcall ForcePickSwitchMonInBattle
|
||||
|
||||
; Return to battle scene
|
||||
call ClearPalettes
|
||||
farcall _LoadBattleFontsHPBar
|
||||
call CloseWindow
|
||||
call ClearSprites
|
||||
hlcoord 1, 0
|
||||
lb bc, 4, 10
|
||||
call ClearBox
|
||||
ld b, SCGB_BATTLE_COLORS
|
||||
call GetSGBLayout
|
||||
call SetPalettes
|
||||
call BatonPass_LinkPlayerSwitch
|
||||
|
||||
; Mobile link battles handle entrances differently
|
||||
farcall CheckMobileBattleError
|
||||
jp c, EndMoveEffect
|
||||
|
||||
ld hl, PassedBattleMonEntrance
|
||||
call CallBattleCore
|
||||
|
||||
call ResetBatonPassStatus
|
||||
ret
|
||||
|
||||
.Enemy:
|
||||
; Wildmons don't have anything to switch to
|
||||
ld a, [wBattleMode]
|
||||
dec a ; WILDMON
|
||||
jp z, FailedBatonPass
|
||||
|
||||
call CheckAnyOtherAliveEnemyMons
|
||||
jp z, FailedBatonPass
|
||||
|
||||
call UpdateEnemyMonInParty
|
||||
call AnimateCurrentMove
|
||||
call BatonPass_LinkEnemySwitch
|
||||
|
||||
; Mobile link battles handle entrances differently
|
||||
farcall CheckMobileBattleError
|
||||
jp c, EndMoveEffect
|
||||
|
||||
; Passed enemy PartyMon entrance
|
||||
xor a
|
||||
ld [wEnemySwitchMonIndex], a
|
||||
ld hl, EnemySwitch_SetMode
|
||||
call CallBattleCore
|
||||
ld hl, ResetBattleParticipants
|
||||
call CallBattleCore
|
||||
ld a, TRUE
|
||||
ld [wApplyStatLevelMultipliersToEnemy], a
|
||||
ld hl, ApplyStatLevelMultiplierOnAllStats
|
||||
call CallBattleCore
|
||||
|
||||
ld hl, SpikesDamage
|
||||
call CallBattleCore
|
||||
|
||||
jr ResetBatonPassStatus
|
||||
|
||||
BatonPass_LinkPlayerSwitch:
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld a, BATTLEPLAYERACTION_USEITEM
|
||||
ld [wBattlePlayerAction], a
|
||||
|
||||
call LoadStandardMenuHeader
|
||||
ld hl, LinkBattleSendReceiveAction
|
||||
call CallBattleCore
|
||||
call CloseWindow
|
||||
|
||||
xor a ; BATTLEPLAYERACTION_USEMOVE
|
||||
ld [wBattlePlayerAction], a
|
||||
ret
|
||||
|
||||
BatonPass_LinkEnemySwitch:
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret z
|
||||
|
||||
call LoadStandardMenuHeader
|
||||
ld hl, LinkBattleSendReceiveAction
|
||||
call CallBattleCore
|
||||
|
||||
ld a, [wOTPartyCount]
|
||||
add BATTLEACTION_SWITCH1
|
||||
ld b, a
|
||||
ld a, [wBattleAction]
|
||||
cp BATTLEACTION_SWITCH1
|
||||
jr c, .baton_pass
|
||||
cp b
|
||||
jr c, .switch
|
||||
|
||||
.baton_pass
|
||||
ld a, [wCurOTMon]
|
||||
add BATTLEACTION_SWITCH1
|
||||
ld [wBattleAction], a
|
||||
.switch
|
||||
jp CloseWindow
|
||||
|
||||
FailedBatonPass:
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
|
||||
ResetBatonPassStatus:
|
||||
; Reset status changes that aren't passed by Baton Pass.
|
||||
|
||||
; Nightmare isn't passed.
|
||||
ld a, BATTLE_VARS_STATUS
|
||||
call GetBattleVar
|
||||
and SLP_MASK
|
||||
jr nz, .ok
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVarAddr
|
||||
res SUBSTATUS_NIGHTMARE, [hl]
|
||||
.ok
|
||||
|
||||
; Disable isn't passed.
|
||||
call ResetActorDisable
|
||||
|
||||
; Attraction isn't passed.
|
||||
ld hl, wPlayerSubStatus1
|
||||
res SUBSTATUS_IN_LOVE, [hl]
|
||||
ld hl, wEnemySubStatus1
|
||||
res SUBSTATUS_IN_LOVE, [hl]
|
||||
ld hl, wPlayerSubStatus5
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS5
|
||||
call GetBattleVarAddr
|
||||
res SUBSTATUS_TRANSFORMED, [hl]
|
||||
res SUBSTATUS_ENCORED, [hl]
|
||||
|
||||
; New mon hasn't used a move yet.
|
||||
ld a, BATTLE_VARS_LAST_MOVE
|
||||
call GetBattleVarAddr
|
||||
ld [hl], 0
|
||||
|
||||
xor a
|
||||
ld [wPlayerWrapCount], a
|
||||
ld [wEnemyWrapCount], a
|
||||
ret
|
||||
|
||||
CheckAnyOtherAlivePartyMons:
|
||||
ld hl, wPartyMon1HP
|
||||
ld a, [wPartyCount]
|
||||
ld d, a
|
||||
ld a, [wCurBattleMon]
|
||||
ld e, a
|
||||
jr CheckAnyOtherAliveMons
|
||||
|
||||
CheckAnyOtherAliveEnemyMons:
|
||||
ld hl, wOTPartyMon1HP
|
||||
ld a, [wOTPartyCount]
|
||||
ld d, a
|
||||
ld a, [wCurOTMon]
|
||||
ld e, a
|
||||
|
||||
; fallthrough
|
||||
|
||||
CheckAnyOtherAliveMons:
|
||||
; Check for nonzero HP starting from partymon
|
||||
; HP at hl for d partymons, besides current mon e.
|
||||
|
||||
; Return nz if any are alive.
|
||||
|
||||
xor a
|
||||
ld b, a
|
||||
ld c, a
|
||||
.loop
|
||||
ld a, c
|
||||
cp d
|
||||
jr z, .done
|
||||
cp e
|
||||
jr z, .next
|
||||
|
||||
ld a, [hli]
|
||||
or b
|
||||
ld b, a
|
||||
ld a, [hld]
|
||||
or b
|
||||
ld b, a
|
||||
|
||||
.next
|
||||
push bc
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
inc c
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
ld a, b
|
||||
and a
|
||||
ret
|
||||
220
engine/battle/move_effects/beat_up.asm
Normal file
220
engine/battle/move_effects/beat_up.asm
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
BattleCommand_BeatUp:
|
||||
call ResetDamage
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jp nz, .enemy_beats_up
|
||||
|
||||
ld a, [wPlayerSubStatus3]
|
||||
bit SUBSTATUS_IN_LOOP, a
|
||||
jr nz, .next_mon
|
||||
|
||||
ld c, 20
|
||||
call DelayFrames
|
||||
xor a
|
||||
ld [wPlayerRolloutCount], a
|
||||
ld [wCurBeatUpPartyMon], a
|
||||
ld [wBeatUpHitAtLeastOnce], a
|
||||
jr .got_mon
|
||||
|
||||
.next_mon
|
||||
ld a, [wPlayerRolloutCount]
|
||||
ld b, a
|
||||
ld a, [wPartyCount]
|
||||
sub b
|
||||
ld [wCurBeatUpPartyMon], a
|
||||
|
||||
.got_mon
|
||||
; BUG: Beat Up can desynchronize link battles (see docs/bugs_and_glitches.md)
|
||||
ld a, [wCurBeatUpPartyMon]
|
||||
ld hl, wPartyMonNicknames
|
||||
call GetNickname
|
||||
ld a, MON_HP
|
||||
call GetBeatupMonLocation
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
jp z, .beatup_fail ; fainted
|
||||
ld a, [wCurBeatUpPartyMon]
|
||||
ld c, a
|
||||
ld a, [wCurBattleMon]
|
||||
cp [hl]
|
||||
ld hl, wBattleMonStatus
|
||||
jr z, .active_mon
|
||||
ld a, MON_STATUS
|
||||
call GetBeatupMonLocation
|
||||
.active_mon
|
||||
ld a, [hl]
|
||||
and a
|
||||
jp nz, .beatup_fail
|
||||
|
||||
ld a, $1
|
||||
ld [wBeatUpHitAtLeastOnce], a
|
||||
ld hl, BeatUpAttackText
|
||||
call StdBattleTextbox
|
||||
|
||||
ld a, [wEnemyMonSpecies]
|
||||
ld [wCurSpecies], a
|
||||
call GetBaseData
|
||||
ld a, [wBaseDefense]
|
||||
ld c, a
|
||||
|
||||
push bc
|
||||
ld a, MON_SPECIES
|
||||
call GetBeatupMonLocation
|
||||
ld a, [hl]
|
||||
ld [wCurSpecies], a
|
||||
call GetBaseData
|
||||
ld a, [wBaseAttack]
|
||||
pop bc
|
||||
ld b, a
|
||||
|
||||
push bc
|
||||
ld a, MON_LEVEL
|
||||
call GetBeatupMonLocation
|
||||
ld a, [hl]
|
||||
ld e, a
|
||||
pop bc
|
||||
|
||||
ld a, [wPlayerMoveStructPower]
|
||||
ld d, a
|
||||
ret
|
||||
|
||||
.enemy_beats_up
|
||||
ld a, [wEnemySubStatus3]
|
||||
bit SUBSTATUS_IN_LOOP, a
|
||||
jr nz, .enemy_next_mon
|
||||
|
||||
xor a
|
||||
ld [wEnemyRolloutCount], a
|
||||
ld [wCurBeatUpPartyMon], a
|
||||
ld [wBeatUpHitAtLeastOnce], a
|
||||
jr .enemy_got_mon
|
||||
|
||||
.enemy_next_mon
|
||||
ld a, [wEnemyRolloutCount]
|
||||
ld b, a
|
||||
ld a, [wOTPartyCount]
|
||||
sub b
|
||||
ld [wCurBeatUpPartyMon], a
|
||||
|
||||
.enemy_got_mon
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
jr z, .wild
|
||||
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
jr nz, .link_or_tower
|
||||
|
||||
ld a, [wInBattleTowerBattle]
|
||||
and a
|
||||
jr nz, .link_or_tower
|
||||
|
||||
ld a, [wCurBeatUpPartyMon]
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ld hl, wOTPartySpecies
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
ld [wNamedObjectIndex], a
|
||||
call GetPokemonName
|
||||
jr .got_enemy_nick
|
||||
|
||||
.link_or_tower
|
||||
ld a, [wCurBeatUpPartyMon]
|
||||
ld hl, wOTPartyMonNicknames
|
||||
ld bc, NAME_LENGTH
|
||||
call AddNTimes
|
||||
ld de, wStringBuffer1
|
||||
call CopyBytes
|
||||
|
||||
.got_enemy_nick
|
||||
ld a, MON_HP
|
||||
call GetBeatupMonLocation
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
jp z, .beatup_fail
|
||||
|
||||
ld a, [wCurBeatUpPartyMon]
|
||||
ld b, a
|
||||
ld a, [wCurOTMon]
|
||||
cp b
|
||||
ld hl, wEnemyMonStatus
|
||||
jr z, .active_enemy
|
||||
ld a, MON_STATUS
|
||||
call GetBeatupMonLocation
|
||||
.active_enemy
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr nz, .beatup_fail
|
||||
|
||||
ld a, $1
|
||||
ld [wBeatUpHitAtLeastOnce], a
|
||||
jr .finish_beatup
|
||||
|
||||
.wild
|
||||
ld a, [wEnemyMonSpecies]
|
||||
ld [wNamedObjectIndex], a
|
||||
call GetPokemonName
|
||||
ld hl, BeatUpAttackText
|
||||
call StdBattleTextbox
|
||||
jp EnemyAttackDamage
|
||||
|
||||
.finish_beatup
|
||||
ld hl, BeatUpAttackText
|
||||
call StdBattleTextbox
|
||||
|
||||
ld a, [wBattleMonSpecies]
|
||||
ld [wCurSpecies], a
|
||||
call GetBaseData
|
||||
ld a, [wBaseDefense]
|
||||
ld c, a
|
||||
|
||||
push bc
|
||||
ld a, MON_SPECIES
|
||||
call GetBeatupMonLocation
|
||||
ld a, [hl]
|
||||
ld [wCurSpecies], a
|
||||
call GetBaseData
|
||||
ld a, [wBaseAttack]
|
||||
pop bc
|
||||
ld b, a
|
||||
|
||||
push bc
|
||||
ld a, MON_LEVEL
|
||||
call GetBeatupMonLocation
|
||||
ld a, [hl]
|
||||
ld e, a
|
||||
pop bc
|
||||
|
||||
ld a, [wEnemyMoveStructPower]
|
||||
ld d, a
|
||||
ret
|
||||
|
||||
.beatup_fail
|
||||
ld b, buildopponentrage_command
|
||||
jp SkipToBattleCommand
|
||||
|
||||
BattleCommand_BeatUpFailText:
|
||||
; BUG: Beat Up may trigger King's Rock even if it failed (see docs/bugs_and_glitches.md)
|
||||
ld a, [wBeatUpHitAtLeastOnce]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
jp PrintButItFailed
|
||||
|
||||
GetBeatupMonLocation:
|
||||
push bc
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ld hl, wPartyMon1Species
|
||||
jr z, .got_species
|
||||
ld hl, wOTPartyMon1Species
|
||||
|
||||
.got_species
|
||||
ld a, [wCurBeatUpPartyMon]
|
||||
add hl, bc
|
||||
call GetPartyLocation
|
||||
pop bc
|
||||
ret
|
||||
31
engine/battle/move_effects/belly_drum.asm
Normal file
31
engine/battle/move_effects/belly_drum.asm
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
BattleCommand_BellyDrum:
|
||||
; BUG: Belly Drum sharply boosts Attack even with under 50% HP (see docs/bugs_and_glitches.md)
|
||||
call BattleCommand_AttackUp2
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .failed
|
||||
|
||||
callfar GetHalfMaxHP
|
||||
callfar CheckUserHasEnoughHP
|
||||
jr nc, .failed
|
||||
|
||||
push bc
|
||||
call AnimateCurrentMove
|
||||
pop bc
|
||||
callfar SubtractHPFromUser
|
||||
call UpdateUserInParty
|
||||
ld a, MAX_STAT_LEVEL - BASE_STAT_LEVEL - 1
|
||||
|
||||
.max_attack_loop
|
||||
push af
|
||||
call BattleCommand_AttackUp2
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .max_attack_loop
|
||||
|
||||
ld hl, BellyDrumText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
99
engine/battle/move_effects/bide.asm
Normal file
99
engine/battle/move_effects/bide.asm
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
BattleCommand_StoreEnergy:
|
||||
ld a, BATTLE_VARS_SUBSTATUS3
|
||||
call GetBattleVar
|
||||
bit SUBSTATUS_BIDE, a
|
||||
ret z
|
||||
|
||||
ld hl, wPlayerRolloutCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .check_still_storing_energy
|
||||
ld hl, wEnemyRolloutCount
|
||||
.check_still_storing_energy
|
||||
dec [hl]
|
||||
jr nz, .still_storing
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS3
|
||||
call GetBattleVarAddr
|
||||
res SUBSTATUS_BIDE, [hl]
|
||||
|
||||
ld hl, UnleashedEnergyText
|
||||
call StdBattleTextbox
|
||||
|
||||
ld a, BATTLE_VARS_MOVE_POWER
|
||||
call GetBattleVarAddr
|
||||
ld a, 1
|
||||
ld [hl], a
|
||||
ld hl, wPlayerDamageTaken + 1
|
||||
ld de, wPlayerCharging ; player
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .player
|
||||
ld hl, wEnemyDamageTaken + 1
|
||||
ld de, wEnemyCharging ; enemy
|
||||
.player
|
||||
ld a, [hld]
|
||||
add a
|
||||
ld b, a
|
||||
ld [wCurDamage + 1], a
|
||||
ld a, [hl]
|
||||
rl a
|
||||
ld [wCurDamage], a
|
||||
jr nc, .not_maxed
|
||||
ld a, $ff
|
||||
ld [wCurDamage], a
|
||||
ld [wCurDamage + 1], a
|
||||
.not_maxed
|
||||
or b
|
||||
jr nz, .built_up_something
|
||||
ld a, 1
|
||||
ld [wAttackMissed], a
|
||||
.built_up_something
|
||||
xor a
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
ld [de], a
|
||||
|
||||
ld a, BATTLE_VARS_MOVE_ANIM
|
||||
call GetBattleVarAddr
|
||||
push hl
|
||||
ld hl, BIDE
|
||||
call GetMoveIDFromIndex
|
||||
pop hl
|
||||
ld [hl], a
|
||||
|
||||
ld b, unleashenergy_command
|
||||
jp SkipToBattleCommand
|
||||
|
||||
.still_storing
|
||||
ld hl, StoringEnergyText
|
||||
call StdBattleTextbox
|
||||
jp EndMoveEffect
|
||||
|
||||
BattleCommand_UnleashEnergy:
|
||||
ld de, wPlayerDamageTaken
|
||||
ld bc, wPlayerRolloutCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_damage
|
||||
ld de, wEnemyDamageTaken
|
||||
ld bc, wEnemyRolloutCount
|
||||
.got_damage
|
||||
ld a, BATTLE_VARS_SUBSTATUS3
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_BIDE, [hl]
|
||||
xor a
|
||||
ld [de], a
|
||||
inc de
|
||||
ld [de], a
|
||||
ld [wPlayerMoveStructEffect], a
|
||||
ld [wEnemyMoveStructEffect], a
|
||||
call BattleRandom
|
||||
and 1
|
||||
inc a
|
||||
inc a
|
||||
ld [bc], a
|
||||
ld a, 1
|
||||
ld [wBattleAnimParam], a
|
||||
call AnimateCurrentMove
|
||||
jp EndMoveEffect
|
||||
94
engine/battle/move_effects/conversion.asm
Normal file
94
engine/battle/move_effects/conversion.asm
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
BattleCommand_Conversion:
|
||||
ld hl, wBattleMonMoves
|
||||
ld de, wBattleMonType1
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_moves
|
||||
ld hl, wEnemyMonMoves
|
||||
ld de, wEnemyMonType1
|
||||
.got_moves
|
||||
push de
|
||||
ld c, 0
|
||||
ld de, wStringBuffer1
|
||||
.loop
|
||||
push hl
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
pop hl
|
||||
and a
|
||||
jr z, .okay
|
||||
push hl
|
||||
push bc
|
||||
ld l, a
|
||||
ld a, MOVE_TYPE
|
||||
call GetMoveAttribute
|
||||
ld [de], a
|
||||
inc de
|
||||
pop bc
|
||||
pop hl
|
||||
inc c
|
||||
ld a, c
|
||||
cp NUM_MOVES
|
||||
jr c, .loop
|
||||
.okay
|
||||
ld a, $ff
|
||||
ld [de], a
|
||||
inc de
|
||||
ld [de], a
|
||||
inc de
|
||||
ld [de], a
|
||||
pop de
|
||||
ld hl, wStringBuffer1
|
||||
.loop2
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .fail
|
||||
cp CURSE_TYPE
|
||||
jr z, .next
|
||||
ld a, [de]
|
||||
cp [hl]
|
||||
jr z, .next
|
||||
inc de
|
||||
ld a, [de]
|
||||
dec de
|
||||
cp [hl]
|
||||
jr nz, .done
|
||||
.next
|
||||
inc hl
|
||||
jr .loop2
|
||||
|
||||
.fail
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
|
||||
.done
|
||||
.loop3
|
||||
call BattleRandom
|
||||
maskbits NUM_MOVES
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ld hl, wStringBuffer1
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .loop3
|
||||
cp CURSE_TYPE
|
||||
jr z, .loop3
|
||||
ld a, [de]
|
||||
cp [hl]
|
||||
jr z, .loop3
|
||||
inc de
|
||||
ld a, [de]
|
||||
dec de
|
||||
cp [hl]
|
||||
jr z, .loop3
|
||||
ld a, [hl]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld [de], a
|
||||
ld [wNamedObjectIndex], a
|
||||
farcall GetTypeName
|
||||
call AnimateCurrentMove
|
||||
ld hl, TransformedTypeText
|
||||
jp StdBattleTextbox
|
||||
62
engine/battle/move_effects/conversion2.asm
Normal file
62
engine/battle/move_effects/conversion2.asm
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
BattleCommand_Conversion2:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .failed
|
||||
ld hl, wBattleMonType1
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_type
|
||||
ld hl, wEnemyMonType1
|
||||
.got_type
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
and a
|
||||
jr z, .failed
|
||||
push hl
|
||||
ld l, a
|
||||
ld a, MOVE_TYPE
|
||||
call GetMoveAttribute
|
||||
ld d, a
|
||||
pop hl
|
||||
cp CURSE_TYPE
|
||||
jr z, .failed
|
||||
call AnimateCurrentMove
|
||||
call BattleCommand_SwitchTurn
|
||||
|
||||
.loop
|
||||
call BattleRandom
|
||||
maskbits TYPES_END
|
||||
cp UNUSED_TYPES
|
||||
jr c, .okay
|
||||
cp UNUSED_TYPES_END
|
||||
jr c, .loop
|
||||
cp TYPES_END
|
||||
jr nc, .loop
|
||||
.okay
|
||||
ld [hli], a
|
||||
ld [hld], a
|
||||
push hl
|
||||
ld a, BATTLE_VARS_MOVE_TYPE
|
||||
call GetBattleVarAddr
|
||||
push af
|
||||
push hl
|
||||
ld a, d
|
||||
ld [hl], a
|
||||
call BattleCheckTypeMatchup
|
||||
pop hl
|
||||
pop af
|
||||
ld [hl], a
|
||||
pop hl
|
||||
ld a, [wTypeMatchup]
|
||||
cp EFFECTIVE
|
||||
jr nc, .loop
|
||||
call BattleCommand_SwitchTurn
|
||||
|
||||
ld a, [hl]
|
||||
ld [wNamedObjectIndex], a
|
||||
predef GetTypeName
|
||||
ld hl, TransformedTypeText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
jp FailMove
|
||||
56
engine/battle/move_effects/counter.asm
Normal file
56
engine/battle/move_effects/counter.asm
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
BattleCommand_Counter:
|
||||
ld a, 1
|
||||
ld [wAttackMissed], a
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld b, a
|
||||
callfar GetMoveEffect
|
||||
ld a, b
|
||||
cp EFFECT_COUNTER
|
||||
ret z
|
||||
|
||||
call BattleCommand_ResetTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
and a
|
||||
ret z
|
||||
|
||||
call CheckOpponentWentFirst
|
||||
ret z
|
||||
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
ld de, wStringBuffer1
|
||||
call GetMoveData
|
||||
|
||||
ld a, [wStringBuffer1 + MOVE_POWER]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld a, [wStringBuffer1 + MOVE_TYPE]
|
||||
cp SPECIAL
|
||||
ret nc
|
||||
|
||||
; BUG: Counter and Mirror Coat still work if the opponent uses an item (see docs/bugs_and_glitches.md)
|
||||
ld hl, wCurDamage
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
ret z
|
||||
|
||||
ld a, [hl]
|
||||
add a
|
||||
ld [hld], a
|
||||
ld a, [hl]
|
||||
adc a
|
||||
ld [hl], a
|
||||
jr nc, .capped
|
||||
ld a, $ff
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
.capped
|
||||
|
||||
xor a
|
||||
ld [wAttackMissed], a
|
||||
ret
|
||||
91
engine/battle/move_effects/curse.asm
Normal file
91
engine/battle/move_effects/curse.asm
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
BattleCommand_Curse:
|
||||
ld de, wBattleMonType1
|
||||
ld bc, wPlayerStatLevels
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .go
|
||||
ld de, wEnemyMonType1
|
||||
ld bc, wEnemyStatLevels
|
||||
|
||||
.go
|
||||
|
||||
; Curse is different for Ghost-types.
|
||||
|
||||
ld a, [de]
|
||||
cp GHOST
|
||||
jr z, .ghost
|
||||
inc de
|
||||
ld a, [de]
|
||||
cp GHOST
|
||||
jr z, .ghost
|
||||
|
||||
; If no stats can be increased, don't.
|
||||
|
||||
; Attack
|
||||
ld a, [bc]
|
||||
cp MAX_STAT_LEVEL
|
||||
jr c, .raise
|
||||
|
||||
; Defense
|
||||
inc bc
|
||||
ld a, [bc]
|
||||
cp MAX_STAT_LEVEL
|
||||
jr nc, .cantraise
|
||||
|
||||
.raise
|
||||
|
||||
; Raise Attack and Defense, and lower Speed.
|
||||
|
||||
ld a, $1
|
||||
ld [wBattleAnimParam], a
|
||||
call AnimateCurrentMove
|
||||
ld a, SPEED
|
||||
call LowerStat
|
||||
call BattleCommand_SwitchTurn
|
||||
call BattleCommand_StatDownMessage
|
||||
call ResetMiss
|
||||
call BattleCommand_SwitchTurn
|
||||
call BattleCommand_AttackUp
|
||||
call BattleCommand_StatUpMessage
|
||||
call ResetMiss
|
||||
call BattleCommand_DefenseUp
|
||||
jp BattleCommand_StatUpMessage
|
||||
|
||||
.ghost
|
||||
|
||||
; Cut HP in half and put a curse on the opponent.
|
||||
|
||||
call CheckHiddenOpponent
|
||||
jr nz, .failed
|
||||
|
||||
call CheckSubstituteOpp
|
||||
jr nz, .failed
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_CURSE, [hl]
|
||||
jr nz, .failed
|
||||
|
||||
set SUBSTATUS_CURSE, [hl]
|
||||
call AnimateCurrentMove
|
||||
ld hl, GetHalfMaxHP
|
||||
call CallBattleCore
|
||||
ld hl, SubtractHPFromUser
|
||||
call CallBattleCore
|
||||
call UpdateUserInParty
|
||||
ld hl, PutACurseText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
|
||||
.cantraise
|
||||
|
||||
; Can't raise either stat.
|
||||
|
||||
ld b, ABILITY + 1
|
||||
call GetStatName
|
||||
call AnimateFailedMove
|
||||
ld hl, WontRiseAnymoreText
|
||||
jp StdBattleTextbox
|
||||
7
engine/battle/move_effects/destiny_bond.asm
Normal file
7
engine/battle/move_effects/destiny_bond.asm
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
BattleCommand_DestinyBond:
|
||||
ld a, BATTLE_VARS_SUBSTATUS5
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_DESTINY_BOND, [hl]
|
||||
call AnimateCurrentMove
|
||||
ld hl, DestinyBondEffectText
|
||||
jp StdBattleTextbox
|
||||
73
engine/battle/move_effects/disable.asm
Normal file
73
engine/battle/move_effects/disable.asm
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
BattleCommand_Disable:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .failed
|
||||
|
||||
ld de, wEnemyDisableCount
|
||||
ld hl, wEnemyMonMoves
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_moves
|
||||
ld de, wPlayerDisableCount
|
||||
ld hl, wBattleMonMoves
|
||||
.got_moves
|
||||
|
||||
ld a, [de]
|
||||
and a
|
||||
jr nz, .failed
|
||||
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
and a
|
||||
jr z, .failed
|
||||
ld b, a
|
||||
push bc
|
||||
ld bc, STRUGGLE
|
||||
call CompareMove
|
||||
pop bc
|
||||
jr z, .failed
|
||||
|
||||
ld c, $ff
|
||||
.loop
|
||||
inc c
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr nz, .loop
|
||||
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ld hl, wEnemyMonPP
|
||||
jr z, .got_pp
|
||||
ld hl, wBattleMonPP
|
||||
.got_pp
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .failed
|
||||
.loop2
|
||||
call BattleRandom
|
||||
and 7
|
||||
jr z, .loop2
|
||||
inc a
|
||||
inc c
|
||||
swap c
|
||||
add c
|
||||
ld [de], a
|
||||
call AnimateCurrentMove
|
||||
ld hl, wDisabledMove
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .got_disabled_move_pointer
|
||||
inc hl
|
||||
.got_disabled_move_pointer
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
ld [hl], a
|
||||
ld [wNamedObjectIndex], a
|
||||
call GetMoveName
|
||||
ld hl, WasDisabledText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
jp FailMove
|
||||
120
engine/battle/move_effects/encore.asm
Normal file
120
engine/battle/move_effects/encore.asm
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
BattleCommand_Encore:
|
||||
ld hl, wEnemyMonMoves
|
||||
ld de, wEnemyEncoreCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld hl, wBattleMonMoves
|
||||
ld de, wPlayerEncoreCount
|
||||
.ok
|
||||
ld a, BATTLE_VARS_LAST_MOVE_OPP
|
||||
call GetBattleVar
|
||||
ld b, a
|
||||
push hl
|
||||
ld hl, .invalid_moves
|
||||
call CheckMoveInList
|
||||
pop hl
|
||||
jp c, .failed
|
||||
|
||||
.got_move
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr nz, .got_move
|
||||
|
||||
ld bc, wBattleMonPP - wBattleMonMoves - 1
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
and PP_MASK
|
||||
jp z, .failed
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jp nz, .failed
|
||||
ld a, BATTLE_VARS_SUBSTATUS5_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_ENCORED, [hl]
|
||||
jp nz, .failed
|
||||
set SUBSTATUS_ENCORED, [hl]
|
||||
call BattleRandom
|
||||
and $3
|
||||
inc a
|
||||
inc a
|
||||
inc a
|
||||
ld [de], a
|
||||
call CheckOpponentWentFirst
|
||||
jr nz, .finish_move
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .force_last_enemy_move
|
||||
|
||||
push hl
|
||||
ld a, [wLastPlayerMove]
|
||||
ld b, a
|
||||
ld c, 0
|
||||
ld hl, wBattleMonMoves
|
||||
.find_player_move
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr z, .got_player_move
|
||||
inc c
|
||||
ld a, c
|
||||
cp NUM_MOVES
|
||||
jr c, .find_player_move
|
||||
pop hl
|
||||
res SUBSTATUS_ENCORED, [hl]
|
||||
xor a
|
||||
ld [de], a
|
||||
jr .failed
|
||||
|
||||
.got_player_move
|
||||
pop hl
|
||||
ld a, c
|
||||
ld [wCurMoveNum], a
|
||||
ld a, b
|
||||
ld [wCurPlayerMove], a
|
||||
ld de, wPlayerMoveStruct
|
||||
call GetMoveData
|
||||
jr .finish_move
|
||||
|
||||
.force_last_enemy_move
|
||||
push hl
|
||||
ld a, [wLastEnemyMove]
|
||||
ld b, a
|
||||
ld c, 0
|
||||
ld hl, wEnemyMonMoves
|
||||
.find_enemy_move
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr z, .got_enemy_move
|
||||
inc c
|
||||
ld a, c
|
||||
cp NUM_MOVES
|
||||
jr c, .find_enemy_move
|
||||
pop hl
|
||||
res SUBSTATUS_ENCORED, [hl]
|
||||
xor a
|
||||
ld [de], a
|
||||
jr .failed
|
||||
|
||||
.got_enemy_move
|
||||
pop hl
|
||||
ld a, c
|
||||
ld [wCurEnemyMoveNum], a
|
||||
ld a, b
|
||||
ld [wCurEnemyMove], a
|
||||
ld de, wEnemyMoveStruct
|
||||
call GetMoveData
|
||||
|
||||
.finish_move
|
||||
call AnimateCurrentMove
|
||||
ld hl, GotAnEncoreText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
jp PrintDidntAffect2
|
||||
|
||||
.invalid_moves
|
||||
dw NO_MOVE
|
||||
dw STRUGGLE
|
||||
dw ENCORE
|
||||
dw MIRROR_MOVE
|
||||
dw -1
|
||||
14
engine/battle/move_effects/endure.asm
Normal file
14
engine/battle/move_effects/endure.asm
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
BattleCommand_Endure:
|
||||
; Endure shares code with Protect. See protect.asm.
|
||||
|
||||
call ProtectChance
|
||||
ret c
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_ENDURE, [hl]
|
||||
|
||||
call AnimateCurrentMove
|
||||
|
||||
ld hl, BracedItselfText
|
||||
jp StdBattleTextbox
|
||||
46
engine/battle/move_effects/false_swipe.asm
Normal file
46
engine/battle/move_effects/false_swipe.asm
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
BattleCommand_FalseSwipe:
|
||||
; Makes sure wCurDamage < MonHP
|
||||
|
||||
ld hl, wEnemyMonHP
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_hp
|
||||
ld hl, wBattleMonHP
|
||||
.got_hp
|
||||
ld de, wCurDamage
|
||||
ld c, 2
|
||||
push hl
|
||||
push de
|
||||
call CompareBytes
|
||||
pop de
|
||||
pop hl
|
||||
jr c, .done
|
||||
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld a, [hl]
|
||||
dec a
|
||||
ld [de], a
|
||||
|
||||
inc a
|
||||
jr nz, .okay
|
||||
dec de
|
||||
ld a, [de]
|
||||
dec a
|
||||
ld [de], a
|
||||
.okay
|
||||
|
||||
ld a, [wCriticalHit]
|
||||
cp 2
|
||||
jr nz, .carry
|
||||
xor a
|
||||
ld [wCriticalHit], a
|
||||
|
||||
.carry
|
||||
scf
|
||||
ret
|
||||
|
||||
.done
|
||||
and a
|
||||
ret
|
||||
13
engine/battle/move_effects/focus_energy.asm
Normal file
13
engine/battle/move_effects/focus_energy.asm
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
BattleCommand_FocusEnergy:
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_FOCUS_ENERGY, [hl]
|
||||
jr nz, .already_pumped
|
||||
set SUBSTATUS_FOCUS_ENERGY, [hl]
|
||||
call AnimateCurrentMove
|
||||
ld hl, GettingPumpedText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.already_pumped
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
20
engine/battle/move_effects/foresight.asm
Normal file
20
engine/battle/move_effects/foresight.asm
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
BattleCommand_Foresight:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .failed
|
||||
|
||||
call CheckHiddenOpponent
|
||||
jr nz, .failed
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_IDENTIFIED, [hl]
|
||||
jr nz, .failed
|
||||
|
||||
set SUBSTATUS_IDENTIFIED, [hl]
|
||||
call AnimateCurrentMove
|
||||
ld hl, IdentifiedText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
jp FailMove
|
||||
26
engine/battle/move_effects/frustration.asm
Normal file
26
engine/battle/move_effects/frustration.asm
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
BattleCommand_FrustrationPower:
|
||||
; BUG: Return and Frustration deal no damage when the user's happiness is low or high, respectively (see docs/bugs_and_glitches.md)
|
||||
push bc
|
||||
ld hl, wBattleMonHappiness
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld hl, wEnemyMonHappiness
|
||||
.ok
|
||||
ld a, $ff
|
||||
sub [hl]
|
||||
ldh [hMultiplicand + 2], a
|
||||
xor a
|
||||
ldh [hMultiplicand + 0], a
|
||||
ldh [hMultiplicand + 1], a
|
||||
ld a, 10
|
||||
ldh [hMultiplier], a
|
||||
call Multiply
|
||||
ld a, 25
|
||||
ldh [hDivisor], a
|
||||
ld b, 4
|
||||
call Divide
|
||||
ldh a, [hQuotient + 3]
|
||||
ld d, a
|
||||
pop bc
|
||||
ret
|
||||
53
engine/battle/move_effects/fury_cutter.asm
Normal file
53
engine/battle/move_effects/fury_cutter.asm
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
BattleCommand_FuryCutter:
|
||||
ld hl, wPlayerFuryCutterCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .go
|
||||
ld hl, wEnemyFuryCutterCount
|
||||
|
||||
.go
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jp nz, ResetFuryCutterCount
|
||||
|
||||
inc [hl]
|
||||
|
||||
; Damage capped at 5 turns' worth (16x).
|
||||
ld a, [hl]
|
||||
ld b, a
|
||||
cp 6
|
||||
jr c, .checkdouble
|
||||
ld b, 5
|
||||
|
||||
.checkdouble
|
||||
dec b
|
||||
ret z
|
||||
|
||||
; Double the damage
|
||||
ld hl, wCurDamage + 1
|
||||
sla [hl]
|
||||
dec hl
|
||||
rl [hl]
|
||||
jr nc, .checkdouble
|
||||
|
||||
; No overflow
|
||||
ld a, $ff
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
ResetFuryCutterCount:
|
||||
push hl
|
||||
|
||||
ld hl, wPlayerFuryCutterCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .reset
|
||||
ld hl, wEnemyFuryCutterCount
|
||||
|
||||
.reset
|
||||
xor a
|
||||
ld [hl], a
|
||||
|
||||
pop hl
|
||||
ret
|
||||
77
engine/battle/move_effects/future_sight.asm
Normal file
77
engine/battle/move_effects/future_sight.asm
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
BattleCommand_CheckFutureSight:
|
||||
ld hl, wPlayerFutureSightCount
|
||||
ld de, wPlayerFutureSightDamage
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld hl, wEnemyFutureSightCount
|
||||
ld de, wEnemyFutureSightDamage
|
||||
.ok
|
||||
|
||||
ld a, [hl]
|
||||
and a
|
||||
ret z
|
||||
cp 1
|
||||
ret nz
|
||||
|
||||
ld [hl], 0
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld [wCurDamage], a
|
||||
ld a, [de]
|
||||
ld [wCurDamage + 1], a
|
||||
ld b, futuresight_command
|
||||
jp SkipToBattleCommand
|
||||
|
||||
BattleCommand_FutureSight:
|
||||
call CheckUserIsCharging
|
||||
jr nz, .AlreadyChargingFutureSight
|
||||
ld a, BATTLE_VARS_MOVE_ANIM
|
||||
call GetBattleVar
|
||||
ld b, a
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE
|
||||
call GetBattleVarAddr
|
||||
ld [hl], b
|
||||
ld a, BATTLE_VARS_LAST_MOVE
|
||||
call GetBattleVarAddr
|
||||
ld [hl], b
|
||||
.AlreadyChargingFutureSight:
|
||||
ld hl, wPlayerFutureSightCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .GotFutureSightCount
|
||||
ld hl, wEnemyFutureSightCount
|
||||
.GotFutureSightCount:
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr nz, .failed
|
||||
ld a, 4
|
||||
ld [hl], a
|
||||
call BattleCommand_LowerSub
|
||||
call BattleCommand_MoveDelay
|
||||
ld hl, ForesawAttackText
|
||||
call StdBattleTextbox
|
||||
call BattleCommand_RaiseSub
|
||||
ld de, wPlayerFutureSightDamage
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .StoreDamage
|
||||
ld de, wEnemyFutureSightDamage
|
||||
.StoreDamage:
|
||||
ld hl, wCurDamage
|
||||
ld a, [hl]
|
||||
ld [de], a
|
||||
ld [hl], 0
|
||||
inc hl
|
||||
inc de
|
||||
ld a, [hl]
|
||||
ld [de], a
|
||||
ld [hl], 0
|
||||
jp EndMoveEffect
|
||||
|
||||
.failed
|
||||
pop bc
|
||||
call ResetDamage
|
||||
call AnimateFailedMove
|
||||
call PrintButItFailed
|
||||
jp EndMoveEffect
|
||||
32
engine/battle/move_effects/heal_bell.asm
Normal file
32
engine/battle/move_effects/heal_bell.asm
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
BattleCommand_HealBell:
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVarAddr
|
||||
res SUBSTATUS_NIGHTMARE, [hl]
|
||||
ld de, wPartyMon1Status
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_status
|
||||
ld de, wOTPartyMon1Status
|
||||
.got_status
|
||||
ld a, BATTLE_VARS_STATUS
|
||||
call GetBattleVarAddr
|
||||
xor a
|
||||
ld [hl], a
|
||||
ld h, d
|
||||
ld l, e
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
ld d, PARTY_LENGTH
|
||||
.loop
|
||||
ld [hl], a
|
||||
add hl, bc
|
||||
dec d
|
||||
jr nz, .loop
|
||||
call AnimateCurrentMove
|
||||
|
||||
ld hl, BellChimedText
|
||||
call StdBattleTextbox
|
||||
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jp z, CalcPlayerStats
|
||||
jp CalcEnemyStats
|
||||
6
engine/battle/move_effects/hidden_power.asm
Normal file
6
engine/battle/move_effects/hidden_power.asm
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
BattleCommand_HiddenPower:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
ret nz
|
||||
farcall HiddenPowerDamage
|
||||
ret
|
||||
39
engine/battle/move_effects/leech_seed.asm
Normal file
39
engine/battle/move_effects/leech_seed.asm
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
BattleCommand_LeechSeed:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .evaded
|
||||
call CheckSubstituteOpp
|
||||
jr nz, .evaded
|
||||
|
||||
ld de, wEnemyMonType1
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld de, wBattleMonType1
|
||||
.ok
|
||||
|
||||
ld a, [de]
|
||||
cp GRASS
|
||||
jr z, .grass
|
||||
inc de
|
||||
ld a, [de]
|
||||
cp GRASS
|
||||
jr z, .grass
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS4_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_LEECH_SEED, [hl]
|
||||
jr nz, .evaded
|
||||
set SUBSTATUS_LEECH_SEED, [hl]
|
||||
call AnimateCurrentMove
|
||||
ld hl, WasSeededText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.grass
|
||||
call AnimateFailedMove
|
||||
jp PrintDoesntAffect
|
||||
|
||||
.evaded
|
||||
call AnimateFailedMove
|
||||
ld hl, EvadedText
|
||||
jp StdBattleTextbox
|
||||
19
engine/battle/move_effects/lock_on.asm
Normal file
19
engine/battle/move_effects/lock_on.asm
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
BattleCommand_LockOn:
|
||||
call CheckSubstituteOpp
|
||||
jr nz, .fail
|
||||
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .fail
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS5_OPP
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_LOCK_ON, [hl]
|
||||
call AnimateCurrentMove
|
||||
|
||||
ld hl, TookAimText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.fail
|
||||
call AnimateFailedMove
|
||||
jp PrintDidntAffect
|
||||
27
engine/battle/move_effects/magnitude.asm
Normal file
27
engine/battle/move_effects/magnitude.asm
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
BattleCommand_GetMagnitude:
|
||||
push bc
|
||||
call BattleRandom
|
||||
ld b, a
|
||||
ld hl, MagnitudePower
|
||||
.loop
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr nc, .ok
|
||||
inc hl
|
||||
inc hl
|
||||
jr .loop
|
||||
|
||||
.ok
|
||||
ld d, [hl]
|
||||
push de
|
||||
inc hl
|
||||
ld a, [hl]
|
||||
ld [wTextDecimalByte], a
|
||||
call BattleCommand_MoveDelay
|
||||
ld hl, MagnitudeText
|
||||
call StdBattleTextbox
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
|
||||
INCLUDE "data/moves/magnitude_power.asm"
|
||||
70
engine/battle/move_effects/metronome.asm
Normal file
70
engine/battle/move_effects/metronome.asm
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
BattleCommand_Metronome:
|
||||
call ClearLastMove
|
||||
call CheckUserIsCharging
|
||||
jr nz, .charging
|
||||
|
||||
ld a, [wBattleAnimParam]
|
||||
push af
|
||||
call BattleCommand_LowerSub
|
||||
pop af
|
||||
ld [wBattleAnimParam], a
|
||||
|
||||
.charging
|
||||
call LoadMoveAnim
|
||||
|
||||
.GetMove:
|
||||
call ChooseRandomMove
|
||||
|
||||
; None of the moves in MetronomeExcepts.
|
||||
ld de, 2
|
||||
ld hl, MetronomeExcepts
|
||||
call IsInWordArray
|
||||
jr c, .GetMove
|
||||
ld h, b
|
||||
ld l, c
|
||||
call GetMoveIDFromIndex
|
||||
|
||||
; No moves the user already has.
|
||||
ld b, a
|
||||
call CheckUserMove
|
||||
jr z, .GetMove
|
||||
|
||||
ld a, BATTLE_VARS_MOVE
|
||||
call GetBattleVarAddr
|
||||
ld [hl], b
|
||||
call UpdateMoveData
|
||||
jp ResetTurn
|
||||
|
||||
ChooseRandomMove:
|
||||
; chooses a random valid move and returns it in bc
|
||||
call BattleRandom
|
||||
if HIGH(NUM_ATTACKS)
|
||||
maskbits HIGH(NUM_ATTACKS) + 1
|
||||
if HIGH(NUM_ATTACKS) & (HIGH(NUM_ATTACKS) + 1)
|
||||
; if HIGH(NUM_ATTACKS) is not one less than a power of two
|
||||
cp HIGH(NUM_ATTACKS) + 1
|
||||
jr nc, ChooseRandomMove
|
||||
endc
|
||||
ld b, a
|
||||
call BattleRandom
|
||||
ld c, a
|
||||
or b
|
||||
jr z, ChooseRandomMove
|
||||
if LOW(NUM_ATTACKS) != $ff
|
||||
ld a, b
|
||||
cp HIGH(NUM_ATTACKS)
|
||||
ret nz
|
||||
ld a, c
|
||||
cp LOW(NUM_ATTACKS) + 1
|
||||
jr nc, ChooseRandomMove
|
||||
endc
|
||||
else
|
||||
cp NUM_ATTACKS
|
||||
jr nc, ChooseRandomMove
|
||||
inc a
|
||||
ld c, a
|
||||
ld b, 0
|
||||
endc
|
||||
ret
|
||||
|
||||
INCLUDE "data/moves/metronome_exception_moves.asm"
|
||||
53
engine/battle/move_effects/mimic.asm
Normal file
53
engine/battle/move_effects/mimic.asm
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
BattleCommand_Mimic:
|
||||
call ClearLastMove
|
||||
call BattleCommand_MoveDelay
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .fail
|
||||
ld hl, wBattleMonMoves
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .player_turn
|
||||
ld hl, wEnemyMonMoves
|
||||
.player_turn
|
||||
call CheckHiddenOpponent
|
||||
jr nz, .fail
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
and a
|
||||
jr z, .fail
|
||||
ld b, a
|
||||
push bc
|
||||
ld bc, STRUGGLE
|
||||
call CompareMove
|
||||
pop bc
|
||||
jr z, .fail
|
||||
ld c, NUM_MOVES
|
||||
.check_already_knows_move
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr z, .fail
|
||||
dec c
|
||||
jr nz, .check_already_knows_move
|
||||
push hl
|
||||
ld hl, MIMIC
|
||||
call GetMoveIDFromIndex
|
||||
pop hl
|
||||
.find_mimic
|
||||
dec hl
|
||||
cp [hl]
|
||||
jr nz, .find_mimic
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
ld [hl], a
|
||||
ld [wNamedObjectIndex], a
|
||||
ld bc, wBattleMonPP - wBattleMonMoves
|
||||
add hl, bc
|
||||
ld [hl], 5
|
||||
call GetMoveName
|
||||
call AnimateCurrentMove
|
||||
ld hl, MimicLearnedMoveText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.fail
|
||||
jp FailMimic
|
||||
57
engine/battle/move_effects/mirror_coat.asm
Normal file
57
engine/battle/move_effects/mirror_coat.asm
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
BattleCommand_MirrorCoat:
|
||||
ld a, 1
|
||||
ld [wAttackMissed], a
|
||||
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld b, a
|
||||
callfar GetMoveEffect
|
||||
ld a, b
|
||||
cp EFFECT_MIRROR_COAT
|
||||
ret z
|
||||
|
||||
call BattleCommand_ResetTypeMatchup
|
||||
ld a, [wTypeMatchup]
|
||||
and a
|
||||
ret z
|
||||
|
||||
call CheckOpponentWentFirst
|
||||
ret z
|
||||
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
ld de, wStringBuffer1
|
||||
call GetMoveData
|
||||
|
||||
ld a, [wStringBuffer1 + MOVE_POWER]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld a, [wStringBuffer1 + MOVE_TYPE]
|
||||
cp SPECIAL
|
||||
ret c
|
||||
|
||||
; BUG: Counter and Mirror Coat still work if the opponent uses an item (see docs/bugs_and_glitches.md)
|
||||
ld hl, wCurDamage
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
ret z
|
||||
|
||||
ld a, [hl]
|
||||
add a
|
||||
ld [hld], a
|
||||
ld a, [hl]
|
||||
adc a
|
||||
ld [hl], a
|
||||
jr nc, .capped
|
||||
ld a, $ff
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
.capped
|
||||
|
||||
xor a
|
||||
ld [wAttackMissed], a
|
||||
ret
|
||||
48
engine/battle/move_effects/mirror_move.asm
Normal file
48
engine/battle/move_effects/mirror_move.asm
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
BattleCommand_MirrorMove:
|
||||
call ClearLastMove
|
||||
|
||||
ld a, BATTLE_VARS_MOVE
|
||||
call GetBattleVarAddr
|
||||
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
and a
|
||||
jr z, .failed
|
||||
|
||||
call CheckUserMove
|
||||
jr nz, .use
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
|
||||
ld hl, MirrorMoveFailedText
|
||||
call StdBattleTextbox
|
||||
jp EndMoveEffect
|
||||
|
||||
.use
|
||||
ld a, b
|
||||
ld [hl], a
|
||||
ld [wNamedObjectIndex], a
|
||||
|
||||
push af
|
||||
ld a, BATTLE_VARS_MOVE_ANIM
|
||||
call GetBattleVarAddr
|
||||
ld d, h
|
||||
ld e, l
|
||||
pop af
|
||||
|
||||
call GetMoveData
|
||||
call GetMoveName
|
||||
call CopyName1
|
||||
call CheckUserIsCharging
|
||||
jr nz, .done
|
||||
|
||||
ld a, [wBattleAnimParam]
|
||||
push af
|
||||
call BattleCommand_LowerSub
|
||||
pop af
|
||||
ld [wBattleAnimParam], a
|
||||
|
||||
.done
|
||||
call BattleCommand_MoveDelay
|
||||
jp ResetTurn
|
||||
13
engine/battle/move_effects/mist.asm
Normal file
13
engine/battle/move_effects/mist.asm
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
BattleCommand_Mist:
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_MIST, [hl]
|
||||
jr nz, .already_mist
|
||||
set SUBSTATUS_MIST, [hl]
|
||||
call AnimateCurrentMove
|
||||
ld hl, MistText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.already_mist
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
35
engine/battle/move_effects/nightmare.asm
Normal file
35
engine/battle/move_effects/nightmare.asm
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
BattleCommand_Nightmare:
|
||||
; Can't hit an absent opponent.
|
||||
|
||||
call CheckHiddenOpponent
|
||||
jr nz, .failed
|
||||
|
||||
; Can't hit a substitute.
|
||||
|
||||
call CheckSubstituteOpp
|
||||
jr nz, .failed
|
||||
|
||||
; Only works on a sleeping opponent.
|
||||
|
||||
ld a, BATTLE_VARS_STATUS_OPP
|
||||
call GetBattleVarAddr
|
||||
and SLP_MASK
|
||||
jr z, .failed
|
||||
|
||||
; Bail if the opponent is already having a nightmare.
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_NIGHTMARE, [hl]
|
||||
jr nz, .failed
|
||||
|
||||
; Otherwise give the opponent a nightmare.
|
||||
|
||||
set SUBSTATUS_NIGHTMARE, [hl]
|
||||
call AnimateCurrentMove
|
||||
ld hl, StartedNightmareText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
91
engine/battle/move_effects/pain_split.asm
Normal file
91
engine/battle/move_effects/pain_split.asm
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
BattleCommand_PainSplit:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jp nz, .ButItFailed
|
||||
call CheckSubstituteOpp
|
||||
jp nz, .ButItFailed
|
||||
call AnimateCurrentMove
|
||||
ld hl, wBattleMonMaxHP + 1
|
||||
ld de, wEnemyMonMaxHP + 1
|
||||
call .PlayerShareHP
|
||||
ld a, $1
|
||||
ld [wWhichHPBar], a
|
||||
hlcoord 10, 9
|
||||
predef AnimateHPBar
|
||||
ld hl, wEnemyMonHP
|
||||
ld a, [hli]
|
||||
ld [wHPBuffer2 + 1], a
|
||||
ld a, [hli]
|
||||
ld [wHPBuffer2], a
|
||||
ld a, [hli]
|
||||
ld [wHPBuffer1 + 1], a
|
||||
ld a, [hl]
|
||||
ld [wHPBuffer1], a
|
||||
call .EnemyShareHP
|
||||
xor a
|
||||
ld [wWhichHPBar], a
|
||||
call ResetDamage
|
||||
hlcoord 2, 2
|
||||
predef AnimateHPBar
|
||||
farcall _UpdateBattleHUDs
|
||||
|
||||
ld hl, SharedPainText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.PlayerShareHP:
|
||||
ld a, [hld]
|
||||
ld [wHPBuffer1], a
|
||||
ld a, [hld]
|
||||
ld [wHPBuffer1 + 1], a
|
||||
ld a, [hld]
|
||||
ld b, a
|
||||
ld [wHPBuffer2], a
|
||||
ld a, [hl]
|
||||
ld [wHPBuffer2 + 1], a
|
||||
dec de
|
||||
dec de
|
||||
ld a, [de]
|
||||
dec de
|
||||
add b
|
||||
ld [wCurDamage + 1], a
|
||||
ld b, [hl]
|
||||
ld a, [de]
|
||||
adc b
|
||||
srl a
|
||||
ld [wCurDamage], a
|
||||
ld a, [wCurDamage + 1]
|
||||
rr a
|
||||
ld [wCurDamage + 1], a
|
||||
inc hl
|
||||
inc hl
|
||||
inc hl
|
||||
inc de
|
||||
inc de
|
||||
inc de
|
||||
|
||||
.EnemyShareHP:
|
||||
ld c, [hl]
|
||||
dec hl
|
||||
ld a, [wCurDamage + 1]
|
||||
sub c
|
||||
ld b, [hl]
|
||||
dec hl
|
||||
ld a, [wCurDamage]
|
||||
sbc b
|
||||
jr nc, .skip
|
||||
|
||||
ld a, [wCurDamage]
|
||||
ld b, a
|
||||
ld a, [wCurDamage + 1]
|
||||
ld c, a
|
||||
.skip
|
||||
ld a, c
|
||||
ld [hld], a
|
||||
ld [wHPBuffer3], a
|
||||
ld a, b
|
||||
ld [hli], a
|
||||
ld [wHPBuffer3 + 1], a
|
||||
ret
|
||||
|
||||
.ButItFailed:
|
||||
jp PrintDidntAffect2
|
||||
24
engine/battle/move_effects/pay_day.asm
Normal file
24
engine/battle/move_effects/pay_day.asm
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
BattleCommand_PayDay:
|
||||
xor a
|
||||
ld hl, wStringBuffer1
|
||||
ld [hli], a
|
||||
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ld a, [wBattleMonLevel]
|
||||
jr z, .ok
|
||||
ld a, [wEnemyMonLevel]
|
||||
.ok
|
||||
|
||||
add a
|
||||
ld hl, wPayDayMoney + 2
|
||||
add [hl]
|
||||
ld [hld], a
|
||||
jr nc, .done
|
||||
inc [hl]
|
||||
dec hl
|
||||
jr nz, .done
|
||||
inc [hl]
|
||||
.done
|
||||
ld hl, CoinsScatteredText
|
||||
jp StdBattleTextbox
|
||||
36
engine/battle/move_effects/perish_song.asm
Normal file
36
engine/battle/move_effects/perish_song.asm
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
BattleCommand_PerishSong:
|
||||
ld hl, wPlayerSubStatus1
|
||||
ld de, wEnemySubStatus1
|
||||
bit SUBSTATUS_PERISH, [hl]
|
||||
jr z, .ok
|
||||
|
||||
ld a, [de]
|
||||
bit SUBSTATUS_PERISH, a
|
||||
jr nz, .failed
|
||||
|
||||
.ok
|
||||
bit SUBSTATUS_PERISH, [hl]
|
||||
jr nz, .enemy
|
||||
|
||||
set SUBSTATUS_PERISH, [hl]
|
||||
ld a, 4
|
||||
ld [wPlayerPerishCount], a
|
||||
|
||||
.enemy
|
||||
ld a, [de]
|
||||
bit SUBSTATUS_PERISH, a
|
||||
jr nz, .done
|
||||
|
||||
set SUBSTATUS_PERISH, a
|
||||
ld [de], a
|
||||
ld a, 4
|
||||
ld [wEnemyPerishCount], a
|
||||
|
||||
.done
|
||||
call AnimateCurrentMove
|
||||
ld hl, StartPerishText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
87
engine/battle/move_effects/present.asm
Normal file
87
engine/battle/move_effects/present.asm
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
BattleCommand_Present:
|
||||
; BUG: Present damage is incorrect in link battles (see docs/bugs_and_glitches.md)
|
||||
ld a, [wLinkMode]
|
||||
cp LINK_COLOSSEUM
|
||||
jr z, .colosseum_skippush
|
||||
push bc
|
||||
push de
|
||||
.colosseum_skippush
|
||||
|
||||
call BattleCommand_Stab
|
||||
|
||||
ld a, [wLinkMode]
|
||||
cp LINK_COLOSSEUM
|
||||
jr z, .colosseum_skippop
|
||||
pop de
|
||||
pop bc
|
||||
.colosseum_skippop
|
||||
|
||||
ld a, [wTypeMatchup]
|
||||
and a
|
||||
jp z, AnimateFailedMove
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jp nz, AnimateFailedMove
|
||||
|
||||
push bc
|
||||
call BattleRandom
|
||||
ld b, a
|
||||
ld hl, PresentPower
|
||||
ld c, 0
|
||||
.next
|
||||
ld a, [hli]
|
||||
cp -1
|
||||
jr z, .heal_effect
|
||||
cp b
|
||||
jr nc, .got_power
|
||||
inc c
|
||||
inc hl
|
||||
jr .next
|
||||
|
||||
.got_power
|
||||
ld a, c
|
||||
ld [wBattleAnimParam], a
|
||||
call AnimateCurrentMoveEitherSide
|
||||
ld d, [hl]
|
||||
pop bc
|
||||
ret
|
||||
|
||||
.heal_effect
|
||||
pop bc
|
||||
ld a, $3 ; heal animation
|
||||
ld [wBattleAnimParam], a
|
||||
call AnimateCurrentMove
|
||||
call BattleCommand_SwitchTurn
|
||||
ld hl, AICheckPlayerMaxHP
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_hp_fn_pointer
|
||||
ld hl, AICheckEnemyMaxHP
|
||||
.got_hp_fn_pointer
|
||||
ld a, BANK(AICheckPlayerMaxHP) ; aka BANK(AICheckEnemyMaxHP)
|
||||
rst FarCall
|
||||
jr c, .already_fully_healed
|
||||
|
||||
ld hl, GetQuarterMaxHP
|
||||
call CallBattleCore
|
||||
call BattleCommand_SwitchTurn
|
||||
ld hl, RestoreHP
|
||||
call CallBattleCore
|
||||
call BattleCommand_SwitchTurn
|
||||
ld hl, RegainedHealthText
|
||||
call StdBattleTextbox
|
||||
call BattleCommand_SwitchTurn
|
||||
call UpdateOpponentInParty
|
||||
jr .do_animation
|
||||
|
||||
.already_fully_healed
|
||||
call BattleCommand_SwitchTurn
|
||||
call _CheckBattleScene
|
||||
jr nc, .do_animation
|
||||
call AnimateFailedMove
|
||||
ld hl, PresentFailedText
|
||||
call StdBattleTextbox
|
||||
.do_animation
|
||||
jp EndMoveEffect
|
||||
|
||||
INCLUDE "data/moves/present_power.asm"
|
||||
74
engine/battle/move_effects/protect.asm
Normal file
74
engine/battle/move_effects/protect.asm
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
BattleCommand_Protect:
|
||||
call ProtectChance
|
||||
ret c
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_PROTECT, [hl]
|
||||
|
||||
call AnimateCurrentMove
|
||||
|
||||
ld hl, ProtectedItselfText
|
||||
jp StdBattleTextbox
|
||||
|
||||
ProtectChance:
|
||||
ld de, wPlayerProtectCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_count
|
||||
ld de, wEnemyProtectCount
|
||||
.got_count
|
||||
|
||||
call CheckOpponentWentFirst
|
||||
jr nz, .failed
|
||||
|
||||
; Can't have a substitute.
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVar
|
||||
bit SUBSTATUS_SUBSTITUTE, a
|
||||
jr nz, .failed
|
||||
|
||||
; Halve the chance of a successful Protect for each consecutive use.
|
||||
|
||||
ld b, $ff
|
||||
ld a, [de]
|
||||
ld c, a
|
||||
.loop
|
||||
ld a, c
|
||||
and a
|
||||
jr z, .done
|
||||
dec c
|
||||
|
||||
srl b
|
||||
ld a, b
|
||||
and a
|
||||
jr nz, .loop
|
||||
jr .failed
|
||||
.done
|
||||
|
||||
.rand
|
||||
call BattleRandom
|
||||
and a
|
||||
jr z, .rand
|
||||
|
||||
dec a
|
||||
cp b
|
||||
jr nc, .failed
|
||||
|
||||
; Another consecutive Protect use.
|
||||
|
||||
ld a, [de]
|
||||
inc a
|
||||
ld [de], a
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
.failed
|
||||
xor a
|
||||
ld [de], a
|
||||
call AnimateFailedMove
|
||||
call PrintButItFailed
|
||||
scf
|
||||
ret
|
||||
47
engine/battle/move_effects/psych_up.asm
Normal file
47
engine/battle/move_effects/psych_up.asm
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
BattleCommand_PsychUp:
|
||||
ld hl, wEnemyStatLevels
|
||||
ld de, wPlayerStatLevels
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .pointers_correct
|
||||
; It's the enemy's turn, so swap the pointers.
|
||||
push hl
|
||||
ld h, d
|
||||
ld l, e
|
||||
pop de
|
||||
.pointers_correct
|
||||
push hl
|
||||
ld b, NUM_LEVEL_STATS
|
||||
; If any of the enemy's stats is modified from its base level,
|
||||
; the move succeeds. Otherwise, it fails.
|
||||
.loop
|
||||
ld a, [hli]
|
||||
cp BASE_STAT_LEVEL
|
||||
jr nz, .break
|
||||
dec b
|
||||
jr nz, .loop
|
||||
pop hl
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
|
||||
.break
|
||||
pop hl
|
||||
ld b, NUM_LEVEL_STATS
|
||||
.loop2
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
dec b
|
||||
jr nz, .loop2
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .calc_enemy_stats
|
||||
call CalcPlayerStats
|
||||
jr .merge
|
||||
|
||||
.calc_enemy_stats
|
||||
call CalcEnemyStats
|
||||
.merge
|
||||
call AnimateCurrentMove
|
||||
ld hl, CopiedStatsText
|
||||
jp StdBattleTextbox
|
||||
23
engine/battle/move_effects/pursuit.asm
Normal file
23
engine/battle/move_effects/pursuit.asm
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
BattleCommand_Pursuit:
|
||||
; Double damage if the opponent is switching.
|
||||
|
||||
ld hl, wEnemyIsSwitching
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld hl, wPlayerIsSwitching
|
||||
.ok
|
||||
ld a, [hl]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld hl, wCurDamage + 1
|
||||
sla [hl]
|
||||
dec hl
|
||||
rl [hl]
|
||||
ret nc
|
||||
|
||||
ld a, $ff
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
ret
|
||||
5
engine/battle/move_effects/rage.asm
Normal file
5
engine/battle/move_effects/rage.asm
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
BattleCommand_Rage:
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_RAGE, [hl]
|
||||
ret
|
||||
8
engine/battle/move_effects/rain_dance.asm
Normal file
8
engine/battle/move_effects/rain_dance.asm
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
BattleCommand_StartRain:
|
||||
ld a, WEATHER_RAIN
|
||||
ld [wBattleWeather], a
|
||||
ld a, 5
|
||||
ld [wWeatherCount], a
|
||||
call AnimateCurrentMove
|
||||
ld hl, DownpourText
|
||||
jp StdBattleTextbox
|
||||
34
engine/battle/move_effects/rapid_spin.asm
Normal file
34
engine/battle/move_effects/rapid_spin.asm
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
BattleCommand_ClearHazards:
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_LEECH_SEED, [hl]
|
||||
jr z, .not_leeched
|
||||
res SUBSTATUS_LEECH_SEED, [hl]
|
||||
ld hl, ShedLeechSeedText
|
||||
call StdBattleTextbox
|
||||
.not_leeched
|
||||
|
||||
ld hl, wPlayerScreens
|
||||
ld de, wPlayerWrapCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_screens_wrap
|
||||
ld hl, wEnemyScreens
|
||||
ld de, wEnemyWrapCount
|
||||
.got_screens_wrap
|
||||
bit SCREENS_SPIKES, [hl]
|
||||
jr z, .no_spikes
|
||||
res SCREENS_SPIKES, [hl]
|
||||
ld hl, BlewSpikesText
|
||||
push de
|
||||
call StdBattleTextbox
|
||||
pop de
|
||||
.no_spikes
|
||||
|
||||
ld a, [de]
|
||||
and a
|
||||
ret z
|
||||
xor a
|
||||
ld [de], a
|
||||
ld hl, ReleasedByText
|
||||
jp StdBattleTextbox
|
||||
25
engine/battle/move_effects/return.asm
Normal file
25
engine/battle/move_effects/return.asm
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
BattleCommand_HappinessPower:
|
||||
; BUG: Return and Frustration deal no damage when the user's happiness is low or high, respectively (see docs/bugs_and_glitches.md)
|
||||
push bc
|
||||
ld hl, wBattleMonHappiness
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld hl, wEnemyMonHappiness
|
||||
.ok
|
||||
xor a
|
||||
ldh [hMultiplicand + 0], a
|
||||
ldh [hMultiplicand + 1], a
|
||||
ld a, [hl]
|
||||
ldh [hMultiplicand + 2], a
|
||||
ld a, 10
|
||||
ldh [hMultiplier], a
|
||||
call Multiply
|
||||
ld a, 25
|
||||
ldh [hDivisor], a
|
||||
ld b, 4
|
||||
call Divide
|
||||
ldh a, [hQuotient + 3]
|
||||
ld d, a
|
||||
pop bc
|
||||
ret
|
||||
91
engine/battle/move_effects/rollout.asm
Normal file
91
engine/battle/move_effects/rollout.asm
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
DEF MAX_ROLLOUT_COUNT EQU 5
|
||||
|
||||
BattleCommand_CheckCurl:
|
||||
ld de, wPlayerRolloutCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld de, wEnemyRolloutCount
|
||||
.ok
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVar
|
||||
bit SUBSTATUS_ROLLOUT, a
|
||||
jr z, .reset
|
||||
|
||||
ld b, doturn_command
|
||||
jp SkipToBattleCommand
|
||||
|
||||
.reset
|
||||
xor a
|
||||
ld [de], a
|
||||
ret
|
||||
|
||||
BattleCommand_RolloutPower:
|
||||
ld a, BATTLE_VARS_STATUS
|
||||
call GetBattleVar
|
||||
and SLP_MASK
|
||||
ret nz
|
||||
|
||||
ld hl, wPlayerRolloutCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_rollout_count
|
||||
ld hl, wEnemyRolloutCount
|
||||
|
||||
.got_rollout_count
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr nz, .skip_set_rampage
|
||||
ld a, 1
|
||||
ld [wSomeoneIsRampaging], a
|
||||
|
||||
.skip_set_rampage
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr z, .hit
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVarAddr
|
||||
res 6, [hl]
|
||||
ret
|
||||
|
||||
.hit
|
||||
inc [hl]
|
||||
ld a, [hl]
|
||||
ld b, a
|
||||
cp MAX_ROLLOUT_COUNT
|
||||
jr c, .not_done_with_rollout
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVarAddr
|
||||
res SUBSTATUS_ROLLOUT, [hl]
|
||||
jr .done_with_substatus_flag
|
||||
|
||||
.not_done_with_rollout
|
||||
ld a, BATTLE_VARS_SUBSTATUS1
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_ROLLOUT, [hl]
|
||||
|
||||
.done_with_substatus_flag
|
||||
ld a, BATTLE_VARS_SUBSTATUS2
|
||||
call GetBattleVar
|
||||
bit SUBSTATUS_CURLED, a
|
||||
jr z, .not_curled
|
||||
inc b
|
||||
.not_curled
|
||||
.loop
|
||||
dec b
|
||||
jr z, .done_damage
|
||||
|
||||
ld hl, wCurDamage + 1
|
||||
sla [hl]
|
||||
dec hl
|
||||
rl [hl]
|
||||
jr nc, .loop
|
||||
|
||||
ld a, $ff
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
|
||||
.done_damage
|
||||
ret
|
||||
21
engine/battle/move_effects/safeguard.asm
Normal file
21
engine/battle/move_effects/safeguard.asm
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
BattleCommand_Safeguard:
|
||||
ld hl, wPlayerScreens
|
||||
ld de, wPlayerSafeguardCount
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ok
|
||||
ld hl, wEnemyScreens
|
||||
ld de, wEnemySafeguardCount
|
||||
.ok
|
||||
bit SCREENS_SAFEGUARD, [hl]
|
||||
jr nz, .failed
|
||||
set SCREENS_SAFEGUARD, [hl]
|
||||
ld a, 5
|
||||
ld [de], a
|
||||
call AnimateCurrentMove
|
||||
ld hl, CoveredByVeilText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
16
engine/battle/move_effects/sandstorm.asm
Normal file
16
engine/battle/move_effects/sandstorm.asm
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
BattleCommand_StartSandstorm:
|
||||
ld a, [wBattleWeather]
|
||||
cp WEATHER_SANDSTORM
|
||||
jr z, .failed
|
||||
|
||||
ld a, WEATHER_SANDSTORM
|
||||
ld [wBattleWeather], a
|
||||
ld a, 5
|
||||
ld [wWeatherCount], a
|
||||
call AnimateCurrentMove
|
||||
ld hl, SandstormBrewedText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
29
engine/battle/move_effects/selfdestruct.asm
Normal file
29
engine/battle/move_effects/selfdestruct.asm
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
BattleCommand_Selfdestruct:
|
||||
farcall StubbedTrainerRankings_Selfdestruct
|
||||
ld a, BATTLEANIM_PLAYER_DAMAGE
|
||||
ld [wNumHits], a
|
||||
ld c, 3
|
||||
call DelayFrames
|
||||
ld a, BATTLE_VARS_STATUS
|
||||
call GetBattleVarAddr
|
||||
xor a
|
||||
ld [hli], a
|
||||
inc hl
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
ld a, $1
|
||||
ld [wBattleAnimParam], a
|
||||
call BattleCommand_LowerSub
|
||||
call LoadMoveAnim
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVarAddr
|
||||
res SUBSTATUS_LEECH_SEED, [hl]
|
||||
ld a, BATTLE_VARS_SUBSTATUS5_OPP
|
||||
call GetBattleVarAddr
|
||||
res SUBSTATUS_DESTINY_BOND, [hl]
|
||||
call _CheckBattleScene
|
||||
ret nc
|
||||
farcall DrawPlayerHUD
|
||||
farcall DrawEnemyHUD
|
||||
call WaitBGMap
|
||||
jp RefreshBattleHuds
|
||||
121
engine/battle/move_effects/sketch.asm
Normal file
121
engine/battle/move_effects/sketch.asm
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
BattleCommand_Sketch:
|
||||
call ClearLastMove
|
||||
; Don't sketch during a link battle
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
jr z, .not_linked
|
||||
call AnimateFailedMove
|
||||
jp PrintNothingHappened
|
||||
|
||||
.not_linked
|
||||
; If the opponent has a substitute up, fail.
|
||||
call CheckSubstituteOpp
|
||||
jp nz, .fail
|
||||
; If the opponent is transformed, fail.
|
||||
; BUG: A Transformed Pokémon can use Sketch and learn otherwise unobtainable moves (see docs/bugs_and_glitches.md)
|
||||
ld a, BATTLE_VARS_SUBSTATUS5_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_TRANSFORMED, [hl]
|
||||
jp nz, .fail
|
||||
; Get the user's moveset in its party struct.
|
||||
; This move replacement shall be permanent.
|
||||
; Pointer will be in de.
|
||||
ld a, MON_MOVES
|
||||
call UserPartyAttr
|
||||
ld d, h
|
||||
ld e, l
|
||||
; Get the battle move structs.
|
||||
ld hl, wBattleMonMoves
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .get_last_move
|
||||
ld hl, wEnemyMonMoves
|
||||
.get_last_move
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
ld [wNamedObjectIndex], a
|
||||
ld b, a
|
||||
; Fail if move is invalid or is Struggle.
|
||||
and a
|
||||
jr z, .fail
|
||||
push bc
|
||||
ld bc, STRUGGLE
|
||||
call CompareMove
|
||||
pop bc
|
||||
jr z, .fail
|
||||
; Fail if user already knows that move
|
||||
ld c, NUM_MOVES
|
||||
.does_user_already_know_move
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr z, .fail
|
||||
dec c
|
||||
jr nz, .does_user_already_know_move
|
||||
; Find Sketch in the user's moveset.
|
||||
; Pointer in hl, and index in c.
|
||||
push hl
|
||||
ld hl, SKETCH
|
||||
call GetMoveIDFromIndex
|
||||
pop hl
|
||||
ld c, NUM_MOVES
|
||||
.find_sketch
|
||||
dec c
|
||||
dec hl
|
||||
cp [hl]
|
||||
jr nz, .find_sketch
|
||||
; The Sketched move is loaded to that slot.
|
||||
ld a, b
|
||||
ld [hl], a
|
||||
; Copy the base PP from that move.
|
||||
push bc
|
||||
push hl
|
||||
ld l, a
|
||||
ld a, MOVE_PP
|
||||
call GetMoveAttribute
|
||||
pop hl
|
||||
ld bc, wBattleMonPP - wBattleMonMoves
|
||||
add hl, bc
|
||||
ld [hl], a
|
||||
pop bc
|
||||
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .user_trainer
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
jr nz, .user_trainer
|
||||
; wildmon
|
||||
ld a, [hl]
|
||||
push bc
|
||||
ld hl, wWildMonPP
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld [hl], a
|
||||
ld hl, wWildMonMoves
|
||||
add hl, bc
|
||||
pop bc
|
||||
ld [hl], b
|
||||
jr .done_copy
|
||||
|
||||
.user_trainer
|
||||
ld a, [hl]
|
||||
push af
|
||||
ld l, c
|
||||
ld h, 0
|
||||
add hl, de
|
||||
ld a, b
|
||||
ld [hl], a
|
||||
pop af
|
||||
ld de, MON_PP - MON_MOVES
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
.done_copy
|
||||
call GetMoveName
|
||||
call AnimateCurrentMove
|
||||
|
||||
ld hl, SketchedText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.fail
|
||||
call AnimateFailedMove
|
||||
jp PrintDidntAffect
|
||||
141
engine/battle/move_effects/sleep_talk.asm
Normal file
141
engine/battle/move_effects/sleep_talk.asm
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
BattleCommand_SleepTalk:
|
||||
call ClearLastMove
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jr nz, .fail
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ld hl, wBattleMonMoves + 1
|
||||
ld a, [wDisabledMove]
|
||||
ld d, a
|
||||
jr z, .got_moves
|
||||
ld hl, wEnemyMonMoves + 1
|
||||
ld a, [wEnemyDisabledMove]
|
||||
ld d, a
|
||||
.got_moves
|
||||
ld a, BATTLE_VARS_STATUS
|
||||
call GetBattleVar
|
||||
and SLP_MASK
|
||||
jr z, .fail
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .fail
|
||||
call .safely_check_has_usable_move
|
||||
jr c, .fail
|
||||
dec hl
|
||||
.sample_move
|
||||
push hl
|
||||
call BattleRandom
|
||||
maskbits NUM_MOVES
|
||||
ld c, a
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
pop hl
|
||||
and a
|
||||
jr z, .sample_move
|
||||
ld e, a
|
||||
ld a, BATTLE_VARS_MOVE_ANIM
|
||||
call GetBattleVar
|
||||
cp e
|
||||
jr z, .sample_move
|
||||
ld a, e
|
||||
cp d
|
||||
jr z, .sample_move
|
||||
call .check_two_turn_move
|
||||
jr z, .sample_move
|
||||
ld a, BATTLE_VARS_MOVE
|
||||
call GetBattleVarAddr
|
||||
ld a, e
|
||||
ld [hl], a
|
||||
call CheckUserIsCharging
|
||||
jr nz, .charging
|
||||
ld a, [wBattleAnimParam]
|
||||
push af
|
||||
call BattleCommand_LowerSub
|
||||
pop af
|
||||
ld [wBattleAnimParam], a
|
||||
.charging
|
||||
call LoadMoveAnim
|
||||
call UpdateMoveData
|
||||
jp ResetTurn
|
||||
|
||||
.fail
|
||||
call AnimateFailedMove
|
||||
jp TryPrintButItFailed
|
||||
|
||||
.safely_check_has_usable_move
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
call .check_has_usable_move
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.check_has_usable_move
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ld a, [wDisabledMove]
|
||||
jr z, .got_move_2
|
||||
|
||||
ld a, [wEnemyDisabledMove]
|
||||
.got_move_2
|
||||
ld b, a
|
||||
ld a, BATTLE_VARS_MOVE
|
||||
call GetBattleVar
|
||||
ld c, a
|
||||
dec hl
|
||||
ld d, NUM_MOVES
|
||||
.loop2
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .carry
|
||||
|
||||
cp c
|
||||
jr z, .nope
|
||||
cp b
|
||||
jr z, .nope
|
||||
|
||||
call .check_two_turn_move
|
||||
jr nz, .no_carry
|
||||
|
||||
.nope
|
||||
inc hl
|
||||
dec d
|
||||
jr nz, .loop2
|
||||
|
||||
.carry
|
||||
scf
|
||||
ret
|
||||
|
||||
.no_carry
|
||||
and a
|
||||
ret
|
||||
|
||||
.check_two_turn_move
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
ld b, a
|
||||
callfar GetMoveEffect
|
||||
ld a, b
|
||||
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
|
||||
cp EFFECT_SKULL_BASH
|
||||
ret z
|
||||
cp EFFECT_RAZOR_WIND
|
||||
ret z
|
||||
cp EFFECT_SKY_ATTACK
|
||||
ret z
|
||||
cp EFFECT_SOLARBEAM
|
||||
ret z
|
||||
cp EFFECT_FLY
|
||||
ret z
|
||||
cp EFFECT_BIDE
|
||||
ret
|
||||
10
engine/battle/move_effects/snore.asm
Normal file
10
engine/battle/move_effects/snore.asm
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
BattleCommand_Snore:
|
||||
ld a, BATTLE_VARS_STATUS
|
||||
call GetBattleVar
|
||||
and SLP_MASK
|
||||
ret nz
|
||||
call ResetDamage
|
||||
ld a, $1
|
||||
ld [wAttackMissed], a
|
||||
call FailMove
|
||||
jp EndMoveEffect
|
||||
24
engine/battle/move_effects/spikes.asm
Normal file
24
engine/battle/move_effects/spikes.asm
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
BattleCommand_Spikes:
|
||||
ld hl, wEnemyScreens
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_screens
|
||||
ld hl, wPlayerScreens
|
||||
.got_screens
|
||||
|
||||
; Fails if spikes are already down!
|
||||
|
||||
bit SCREENS_SPIKES, [hl]
|
||||
jr nz, .failed
|
||||
|
||||
; Nothing else stops it from working.
|
||||
|
||||
set SCREENS_SPIKES, [hl]
|
||||
|
||||
call AnimateCurrentMove
|
||||
|
||||
ld hl, SpikesText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
jp FailMove
|
||||
87
engine/battle/move_effects/spite.asm
Normal file
87
engine/battle/move_effects/spite.asm
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
BattleCommand_Spite:
|
||||
ld a, [wAttackMissed]
|
||||
and a
|
||||
jp nz, .failed
|
||||
ld bc, PARTYMON_STRUCT_LENGTH ; unused
|
||||
ld hl, wEnemyMonMoves
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_moves
|
||||
ld hl, wBattleMonMoves
|
||||
.got_moves
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP
|
||||
call GetBattleVar
|
||||
and a
|
||||
jr z, .failed
|
||||
ld b, a
|
||||
push bc
|
||||
ld bc, STRUGGLE
|
||||
call CompareMove
|
||||
pop bc
|
||||
jr z, .failed
|
||||
ld c, -1
|
||||
.loop
|
||||
inc c
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr nz, .loop
|
||||
ld [wNamedObjectIndex], a
|
||||
dec hl
|
||||
ld b, 0
|
||||
push bc
|
||||
ld c, wBattleMonPP - wBattleMonMoves
|
||||
add hl, bc
|
||||
pop bc
|
||||
ld a, [hl]
|
||||
and PP_MASK
|
||||
jr z, .failed
|
||||
push bc
|
||||
call GetMoveName
|
||||
; lose 2-5 PP
|
||||
call BattleRandom
|
||||
and %11
|
||||
inc a
|
||||
inc a
|
||||
ld b, a
|
||||
ld a, [hl]
|
||||
and PP_MASK
|
||||
cp b
|
||||
jr nc, .deplete_pp
|
||||
ld b, a
|
||||
.deplete_pp
|
||||
ld a, [hl]
|
||||
sub b
|
||||
ld [hl], a
|
||||
push af
|
||||
ld a, MON_PP
|
||||
call OpponentPartyAttr
|
||||
ld d, b
|
||||
pop af
|
||||
pop bc
|
||||
add hl, bc
|
||||
ld e, a
|
||||
ld a, BATTLE_VARS_SUBSTATUS5_OPP
|
||||
call GetBattleVar
|
||||
bit SUBSTATUS_TRANSFORMED, a
|
||||
jr nz, .transformed
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .not_wildmon
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
jr nz, .not_wildmon
|
||||
ld hl, wWildMonPP
|
||||
add hl, bc
|
||||
.not_wildmon
|
||||
ld [hl], e
|
||||
.transformed
|
||||
push de
|
||||
call AnimateCurrentMove
|
||||
pop de
|
||||
ld a, d
|
||||
ld [wTextDecimalByte], a
|
||||
ld hl, SpiteEffectText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.failed
|
||||
jp PrintDidntAffect2
|
||||
4
engine/battle/move_effects/splash.asm
Normal file
4
engine/battle/move_effects/splash.asm
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
BattleCommand_Splash:
|
||||
call AnimateCurrentMove
|
||||
farcall StubbedTrainerRankings_Splash
|
||||
jp PrintNothingHappened
|
||||
86
engine/battle/move_effects/substitute.asm
Normal file
86
engine/battle/move_effects/substitute.asm
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
BattleCommand_Substitute:
|
||||
call BattleCommand_MoveDelay
|
||||
ld hl, wBattleMonMaxHP
|
||||
ld de, wPlayerSubstituteHP
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .got_hp
|
||||
ld hl, wEnemyMonMaxHP
|
||||
ld de, wEnemySubstituteHP
|
||||
.got_hp
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVar
|
||||
bit SUBSTATUS_SUBSTITUTE, a
|
||||
jr nz, .already_has_sub
|
||||
|
||||
ld a, [hli]
|
||||
ld b, [hl]
|
||||
srl a
|
||||
rr b
|
||||
srl a
|
||||
rr b
|
||||
dec hl
|
||||
dec hl
|
||||
ld a, b
|
||||
ld [de], a
|
||||
ld a, [hld]
|
||||
sub b
|
||||
ld e, a
|
||||
ld a, [hl]
|
||||
sbc 0
|
||||
ld d, a
|
||||
jr c, .too_weak_to_sub
|
||||
ld a, d
|
||||
or e
|
||||
jr z, .too_weak_to_sub
|
||||
ld [hl], d
|
||||
inc hl
|
||||
ld [hl], e
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_SUBSTITUTE, [hl]
|
||||
|
||||
ld hl, wPlayerWrapCount
|
||||
ld de, wPlayerTrappingMove
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .player
|
||||
ld hl, wEnemyWrapCount
|
||||
ld de, wEnemyTrappingMove
|
||||
.player
|
||||
|
||||
xor a
|
||||
ld [hl], a
|
||||
ld [de], a
|
||||
call _CheckBattleScene
|
||||
jr c, .no_anim
|
||||
|
||||
xor a
|
||||
ld [wNumHits], a
|
||||
ld [wBattleAnimParam], a
|
||||
ld hl, SUBSTITUTE
|
||||
call GetMoveIDFromIndex
|
||||
call LoadAnim
|
||||
jr .finish
|
||||
|
||||
.no_anim
|
||||
call BattleCommand_RaiseSubNoAnim
|
||||
.finish
|
||||
ld hl, MadeSubstituteText
|
||||
call StdBattleTextbox
|
||||
jp RefreshBattleHuds
|
||||
|
||||
.already_has_sub
|
||||
call CheckUserIsCharging
|
||||
call nz, BattleCommand_RaiseSub
|
||||
ld hl, HasSubstituteText
|
||||
jr .jp_stdbattletextbox
|
||||
|
||||
.too_weak_to_sub
|
||||
call CheckUserIsCharging
|
||||
call nz, BattleCommand_RaiseSub
|
||||
ld hl, TooWeakSubText
|
||||
.jp_stdbattletextbox
|
||||
jp StdBattleTextbox
|
||||
8
engine/battle/move_effects/sunny_day.asm
Normal file
8
engine/battle/move_effects/sunny_day.asm
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
BattleCommand_StartSun:
|
||||
ld a, WEATHER_SUN
|
||||
ld [wBattleWeather], a
|
||||
ld a, 5
|
||||
ld [wWeatherCount], a
|
||||
call AnimateCurrentMove
|
||||
ld hl, SunGotBrightText
|
||||
jp StdBattleTextbox
|
||||
94
engine/battle/move_effects/teleport.asm
Normal file
94
engine/battle/move_effects/teleport.asm
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
BattleCommand_Teleport:
|
||||
ld a, [wBattleType]
|
||||
cp BATTLETYPE_SHINY
|
||||
jr z, .failed
|
||||
cp BATTLETYPE_TRAP
|
||||
jr z, .failed
|
||||
cp BATTLETYPE_CELEBI
|
||||
jr z, .failed
|
||||
cp BATTLETYPE_SUICUNE
|
||||
jr z, .failed
|
||||
|
||||
ld a, BATTLE_VARS_SUBSTATUS5_OPP
|
||||
call GetBattleVar
|
||||
bit SUBSTATUS_CANT_RUN, a
|
||||
jr nz, .failed
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .enemy_turn
|
||||
|
||||
; Can't teleport from a trainer battle
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
jr nz, .failed
|
||||
; b = player level
|
||||
ld a, [wCurPartyLevel]
|
||||
ld b, a
|
||||
; If player level >= enemy level, Teleport will succeed
|
||||
ld a, [wBattleMonLevel]
|
||||
cp b
|
||||
jr nc, .run_away
|
||||
; c = player level + enemy level + 1
|
||||
add b
|
||||
ld c, a
|
||||
inc c
|
||||
; Generate a number less than c
|
||||
.loop_player
|
||||
call BattleRandom
|
||||
cp c
|
||||
jr nc, .loop_player
|
||||
; b = enemy level / 4
|
||||
srl b
|
||||
srl b
|
||||
; If the random number >= enemy level / 4, Teleport will succeed
|
||||
cp b
|
||||
jr nc, .run_away
|
||||
|
||||
.failed
|
||||
call AnimateFailedMove
|
||||
jp PrintButItFailed
|
||||
|
||||
.enemy_turn
|
||||
; Can't teleport from a trainer battle
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
jr nz, .failed
|
||||
; b = enemy level
|
||||
ld a, [wBattleMonLevel]
|
||||
ld b, a
|
||||
; If enemy level >= player level, Teleport will succeed
|
||||
ld a, [wCurPartyLevel]
|
||||
cp b
|
||||
jr nc, .run_away
|
||||
; c = enemy level + player level + 1
|
||||
add b
|
||||
ld c, a
|
||||
inc c
|
||||
; Generate a number less than c
|
||||
.loop_enemy
|
||||
; BUG: Wild Pokémon can always Teleport regardless of level difference (see docs/bugs_and_glitches.md)
|
||||
call BattleRandom
|
||||
cp c
|
||||
jr nc, .loop_enemy
|
||||
; b = player level / 4
|
||||
srl b
|
||||
srl b
|
||||
cp b
|
||||
jr nc, .run_away
|
||||
|
||||
.run_away
|
||||
call UpdateBattleMonInParty
|
||||
xor a
|
||||
ld [wNumHits], a
|
||||
inc a
|
||||
ld [wForcedSwitch], a
|
||||
ld [wBattleAnimParam], a
|
||||
call SetBattleDraw
|
||||
call BattleCommand_LowerSub
|
||||
call LoadMoveAnim
|
||||
ld c, 20
|
||||
call DelayFrames
|
||||
call SetBattleDraw
|
||||
|
||||
ld hl, FledFromBattleText
|
||||
jp StdBattleTextbox
|
||||
110
engine/battle/move_effects/thief.asm
Normal file
110
engine/battle/move_effects/thief.asm
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
BattleCommand_Thief:
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .enemy
|
||||
|
||||
; The player needs to be able to steal an item.
|
||||
|
||||
call .playeritem
|
||||
ld a, [hl]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; The enemy needs to have an item to steal.
|
||||
|
||||
call .enemyitem
|
||||
ld a, [hl]
|
||||
and a
|
||||
ret z
|
||||
|
||||
; Can't steal mail.
|
||||
|
||||
ld [wNamedObjectIndex], a
|
||||
ld d, a
|
||||
farcall ItemIsMail
|
||||
ret c
|
||||
|
||||
ld a, [wEffectFailed]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
jr z, .stealenemyitem
|
||||
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
ret z
|
||||
|
||||
.stealenemyitem
|
||||
call .enemyitem
|
||||
xor a
|
||||
ld [hl], a
|
||||
ld [de], a
|
||||
|
||||
call .playeritem
|
||||
ld a, [wNamedObjectIndex]
|
||||
ld [hl], a
|
||||
ld [de], a
|
||||
jr .stole
|
||||
|
||||
.enemy
|
||||
|
||||
; The enemy can't already have an item.
|
||||
|
||||
call .enemyitem
|
||||
ld a, [hl]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; The player must have an item to steal.
|
||||
|
||||
call .playeritem
|
||||
ld a, [hl]
|
||||
and a
|
||||
ret z
|
||||
|
||||
; Can't steal mail!
|
||||
|
||||
ld [wNamedObjectIndex], a
|
||||
ld d, a
|
||||
farcall ItemIsMail
|
||||
ret c
|
||||
|
||||
ld a, [wEffectFailed]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; If the enemy steals your item,
|
||||
; it's gone for good if you don't get it back.
|
||||
|
||||
call .playeritem
|
||||
xor a
|
||||
ld [hl], a
|
||||
ld [de], a
|
||||
|
||||
call .enemyitem
|
||||
ld a, [wNamedObjectIndex]
|
||||
ld [hl], a
|
||||
ld [de], a
|
||||
|
||||
.stole
|
||||
call GetItemName
|
||||
ld hl, StoleText
|
||||
jp StdBattleTextbox
|
||||
|
||||
.playeritem
|
||||
ld a, MON_ITEM
|
||||
call BattlePartyAttr
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld hl, wBattleMonItem
|
||||
ret
|
||||
|
||||
.enemyitem
|
||||
ld a, MON_ITEM
|
||||
call OTPartyAttr
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld hl, wEnemyMonItem
|
||||
ret
|
||||
16
engine/battle/move_effects/thunder.asm
Normal file
16
engine/battle/move_effects/thunder.asm
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
BattleCommand_ThunderAccuracy:
|
||||
ld a, BATTLE_VARS_MOVE_TYPE
|
||||
call GetBattleVarAddr
|
||||
inc hl
|
||||
ld a, [wBattleWeather]
|
||||
cp WEATHER_RAIN
|
||||
jr z, .rain
|
||||
cp WEATHER_SUN
|
||||
ret nz
|
||||
ld [hl], 50 percent + 1
|
||||
ret
|
||||
|
||||
.rain
|
||||
; Redundant with CheckHit guranteeing hit
|
||||
ld [hl], 100 percent
|
||||
ret
|
||||
156
engine/battle/move_effects/transform.asm
Normal file
156
engine/battle/move_effects/transform.asm
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
BattleCommand_Transform:
|
||||
call ClearLastMove
|
||||
ld a, BATTLE_VARS_SUBSTATUS5_OPP
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_TRANSFORMED, [hl]
|
||||
jp nz, BattleEffect_ButItFailed
|
||||
call CheckHiddenOpponent
|
||||
jp nz, BattleEffect_ButItFailed
|
||||
xor a
|
||||
ld [wNumHits], a
|
||||
ld a, $1
|
||||
ld [wBattleAnimParam], a
|
||||
ld a, BATTLE_VARS_SUBSTATUS4
|
||||
call GetBattleVarAddr
|
||||
bit SUBSTATUS_SUBSTITUTE, [hl]
|
||||
push af
|
||||
jr z, .mimic_substitute
|
||||
call CheckUserIsCharging
|
||||
jr nz, .mimic_substitute
|
||||
ld hl, SUBSTITUTE
|
||||
call GetMoveIDFromIndex
|
||||
call LoadAnim
|
||||
.mimic_substitute
|
||||
ld a, BATTLE_VARS_SUBSTATUS5
|
||||
call GetBattleVarAddr
|
||||
set SUBSTATUS_TRANSFORMED, [hl]
|
||||
call ResetActorDisable
|
||||
ld hl, wBattleMonSpecies
|
||||
ld de, wEnemyMonSpecies
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .got_mon_species
|
||||
ld hl, wEnemyMonSpecies
|
||||
ld de, wBattleMonSpecies
|
||||
xor a
|
||||
ld [wCurMoveNum], a
|
||||
.got_mon_species
|
||||
push hl
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc hl
|
||||
inc de
|
||||
inc de
|
||||
ld bc, NUM_MOVES
|
||||
call CopyBytes
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .mimic_enemy_backup
|
||||
ld a, [de]
|
||||
ld [wEnemyBackupDVs], a
|
||||
inc de
|
||||
ld a, [de]
|
||||
ld [wEnemyBackupDVs + 1], a
|
||||
dec de
|
||||
.mimic_enemy_backup
|
||||
; copy DVs
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
; move pointer to stats
|
||||
ld bc, wBattleMonStats - wBattleMonPP
|
||||
add hl, bc
|
||||
push hl
|
||||
ld h, d
|
||||
ld l, e
|
||||
add hl, bc
|
||||
ld d, h
|
||||
ld e, l
|
||||
pop hl
|
||||
ld bc, wBattleMonStructEnd - wBattleMonStats
|
||||
call CopyBytes
|
||||
; init the power points
|
||||
ld bc, wBattleMonMoves - wBattleMonStructEnd
|
||||
add hl, bc
|
||||
push de
|
||||
ld d, h
|
||||
ld e, l
|
||||
pop hl
|
||||
ld bc, wBattleMonPP - wBattleMonStructEnd
|
||||
add hl, bc
|
||||
ld b, NUM_MOVES
|
||||
.pp_loop
|
||||
ld a, [de]
|
||||
inc de
|
||||
and a
|
||||
jr z, .done_move
|
||||
push bc
|
||||
ld bc, SKETCH
|
||||
call CompareMove
|
||||
pop bc
|
||||
ld a, 1
|
||||
jr z, .done_move
|
||||
ld a, 5
|
||||
.done_move
|
||||
ld [hli], a
|
||||
dec b
|
||||
jr nz, .pp_loop
|
||||
pop hl
|
||||
ld a, [hl]
|
||||
ld [wNamedObjectIndex], a
|
||||
call GetPokemonName
|
||||
ld hl, wEnemyStats
|
||||
ld de, wPlayerStats
|
||||
ld bc, 2 * 5
|
||||
call BattleSideCopy
|
||||
ld hl, wEnemyStatLevels
|
||||
ld de, wPlayerStatLevels
|
||||
ld bc, 8
|
||||
call BattleSideCopy
|
||||
call _CheckBattleScene
|
||||
jr c, .mimic_anims
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
ld a, [wPlayerMinimized]
|
||||
jr z, .got_byte
|
||||
ld a, [wEnemyMinimized]
|
||||
.got_byte
|
||||
and a
|
||||
jr nz, .mimic_anims
|
||||
call LoadMoveAnim
|
||||
jr .after_anim
|
||||
|
||||
.mimic_anims
|
||||
call BattleCommand_MoveDelay
|
||||
call BattleCommand_RaiseSubNoAnim
|
||||
.after_anim
|
||||
xor a
|
||||
ld [wNumHits], a
|
||||
ld a, $2
|
||||
ld [wBattleAnimParam], a
|
||||
pop af
|
||||
jr z, .no_substitute
|
||||
ld hl, SUBSTITUTE
|
||||
call GetMoveIDFromIndex
|
||||
call LoadAnim
|
||||
.no_substitute
|
||||
ld hl, TransformedText
|
||||
jp StdBattleTextbox
|
||||
|
||||
BattleSideCopy:
|
||||
; Copy bc bytes from hl to de if it's the player's turn.
|
||||
; Copy bc bytes from de to hl if it's the enemy's turn.
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .copy
|
||||
|
||||
; Swap hl and de
|
||||
push hl
|
||||
ld h, d
|
||||
ld l, e
|
||||
pop de
|
||||
.copy
|
||||
jp CopyBytes
|
||||
30
engine/battle/move_effects/triple_kick.asm
Normal file
30
engine/battle/move_effects/triple_kick.asm
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
BattleCommand_TripleKick:
|
||||
ld a, [wBattleAnimParam]
|
||||
ld b, a
|
||||
inc b
|
||||
ld hl, wCurDamage + 1
|
||||
ld a, [hld]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
.next_kick
|
||||
dec b
|
||||
ret z
|
||||
ld a, [hl]
|
||||
add e
|
||||
ld [hld], a
|
||||
ld a, [hl]
|
||||
adc d
|
||||
ld [hli], a
|
||||
|
||||
; No overflow.
|
||||
jr nc, .next_kick
|
||||
ld a, $ff
|
||||
ld [hld], a
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
BattleCommand_KickCounter:
|
||||
ld hl, wBattleAnimParam
|
||||
inc [hl]
|
||||
ret
|
||||
66
engine/battle/read_trainer_attributes.asm
Normal file
66
engine/battle/read_trainer_attributes.asm
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
GetTrainerClassName:
|
||||
ld hl, wRivalName
|
||||
ld a, c
|
||||
cp RIVAL1
|
||||
jr z, .rival
|
||||
|
||||
ld [wCurSpecies], a
|
||||
ld a, TRAINER_NAME
|
||||
ld [wNamedObjectType], a
|
||||
call GetName
|
||||
ld de, wStringBuffer1
|
||||
ret
|
||||
|
||||
.rival
|
||||
ld de, wStringBuffer1
|
||||
push de
|
||||
ld bc, NAME_LENGTH
|
||||
call CopyBytes
|
||||
pop de
|
||||
ret
|
||||
|
||||
GetOTName:
|
||||
ld hl, wOTPlayerName
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
jr nz, .ok
|
||||
|
||||
ld hl, wRivalName
|
||||
ld a, c
|
||||
cp RIVAL1
|
||||
jr z, .ok
|
||||
|
||||
ld [wCurSpecies], a
|
||||
ld a, TRAINER_NAME
|
||||
ld [wNamedObjectType], a
|
||||
call GetName
|
||||
ld hl, wStringBuffer1
|
||||
|
||||
.ok
|
||||
ld bc, TRAINER_CLASS_NAME_LENGTH
|
||||
ld de, wOTClassName
|
||||
push de
|
||||
call CopyBytes
|
||||
pop de
|
||||
ret
|
||||
|
||||
GetTrainerAttributes:
|
||||
ld a, [wTrainerClass]
|
||||
ld c, a
|
||||
call GetOTName
|
||||
ld a, [wTrainerClass]
|
||||
dec a
|
||||
ld hl, TrainerClassAttributes + TRNATTR_ITEM1
|
||||
ld bc, NUM_TRAINER_ATTRIBUTES
|
||||
call AddNTimes
|
||||
ld de, wEnemyTrainerItem1
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
ld a, [hl]
|
||||
ld [wEnemyTrainerBaseReward], a
|
||||
ret
|
||||
|
||||
INCLUDE "data/trainers/attributes.asm"
|
||||
21
engine/battle/read_trainer_dvs.asm
Normal file
21
engine/battle/read_trainer_dvs.asm
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
GetTrainerDVs:
|
||||
; Return the DVs of wOtherTrainerClass in bc
|
||||
|
||||
push hl
|
||||
ld a, [wOtherTrainerClass]
|
||||
dec a
|
||||
ld c, a
|
||||
ld b, 0
|
||||
|
||||
ld hl, TrainerClassDVs
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld c, [hl]
|
||||
|
||||
pop hl
|
||||
ret
|
||||
|
||||
INCLUDE "data/trainers/dvs.asm"
|
||||
298
engine/battle/read_trainer_party.asm
Normal file
298
engine/battle/read_trainer_party.asm
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
ReadTrainerParty:
|
||||
ld a, [wInBattleTowerBattle]
|
||||
bit 0, a
|
||||
ret nz
|
||||
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
ld hl, wOTPartyCount
|
||||
xor a
|
||||
ld [hli], a
|
||||
dec a
|
||||
ld [hl], a
|
||||
|
||||
ld hl, wOTPartyMons
|
||||
ld bc, PARTYMON_STRUCT_LENGTH * PARTY_LENGTH
|
||||
xor a
|
||||
call ByteFill
|
||||
|
||||
ld a, [wOtherTrainerClass]
|
||||
cp CAL
|
||||
jr nz, .not_cal2
|
||||
ld a, [wOtherTrainerID]
|
||||
cp CAL2
|
||||
jr z, .cal2
|
||||
ld a, [wOtherTrainerClass]
|
||||
.not_cal2
|
||||
|
||||
dec a
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ld hl, TrainerGroups
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld [wTrainerGroupBank], a
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
ld a, [wOtherTrainerID]
|
||||
ld b, a
|
||||
.skip_trainer
|
||||
dec b
|
||||
jr z, .got_trainer
|
||||
.loop
|
||||
ld a, [wTrainerGroupBank]
|
||||
call GetFarByte
|
||||
add a, l
|
||||
ld l, a
|
||||
jr nc, .skip_trainer
|
||||
inc h
|
||||
jr .skip_trainer
|
||||
.got_trainer
|
||||
inc hl
|
||||
|
||||
.skip_name
|
||||
call GetNextTrainerDataByte
|
||||
cp "@"
|
||||
jr nz, .skip_name
|
||||
|
||||
call GetNextTrainerDataByte
|
||||
ld [wOtherTrainerType], a
|
||||
ld d, h
|
||||
ld e, l
|
||||
call ReadTrainerPartyPieces
|
||||
|
||||
.done
|
||||
jp ComputeTrainerReward
|
||||
|
||||
.cal2
|
||||
ld a, BANK(sMysteryGiftTrainer)
|
||||
call OpenSRAM
|
||||
ld a, TRAINERTYPE_MOVES
|
||||
ld [wOtherTrainerType], a
|
||||
ld de, sMysteryGiftTrainer
|
||||
call ReadTrainerPartyPieces
|
||||
call CloseSRAM
|
||||
jr .done
|
||||
|
||||
ReadTrainerPartyPieces:
|
||||
ld h, d
|
||||
ld l, e
|
||||
|
||||
.loop
|
||||
call GetNextTrainerDataByte
|
||||
cp $ff
|
||||
ret z
|
||||
|
||||
ld [wCurPartyLevel], a
|
||||
call GetNextTrainerDataByte
|
||||
push hl
|
||||
push af
|
||||
call GetNextTrainerDataByte
|
||||
ld h, a
|
||||
pop af
|
||||
ld l, a
|
||||
call GetPokemonIDFromIndex
|
||||
ld [wCurPartySpecies], a
|
||||
|
||||
ld a, OTPARTYMON
|
||||
ld [wMonType], a
|
||||
predef TryAddMonToParty
|
||||
pop hl
|
||||
inc hl ;because hl was pushed before the last call to GetNextTrainerDataByte
|
||||
|
||||
ld a, [wOtherTrainerType]
|
||||
and TRAINERTYPE_ITEM
|
||||
jr z, .no_item
|
||||
push hl
|
||||
ld a, [wOTPartyCount]
|
||||
dec a
|
||||
ld hl, wOTPartyMon1Item
|
||||
call GetPartyLocation
|
||||
ld d, h
|
||||
ld e, l
|
||||
pop hl
|
||||
call GetNextTrainerDataByte
|
||||
ld [de], a
|
||||
.no_item
|
||||
|
||||
ld a, [wOtherTrainerType]
|
||||
rra ; TRAINERTYPE_MOVES_F == 0
|
||||
jr nc, .no_moves
|
||||
push hl
|
||||
ld a, [wOTPartyCount]
|
||||
dec a
|
||||
ld hl, wOTPartyMon1Moves
|
||||
call GetPartyLocation
|
||||
ld d, h
|
||||
ld e, l
|
||||
pop hl
|
||||
|
||||
ld b, NUM_MOVES
|
||||
.copy_moves
|
||||
call GetNextTrainerDataByte
|
||||
push hl
|
||||
push af
|
||||
call GetNextTrainerDataByte
|
||||
ld h, a
|
||||
pop af
|
||||
ld l, a
|
||||
call GetMoveIDFromIndex
|
||||
pop hl
|
||||
inc hl
|
||||
ld [de], a
|
||||
inc de
|
||||
dec b
|
||||
jr nz, .copy_moves
|
||||
|
||||
push hl
|
||||
|
||||
ld a, [wOTPartyCount]
|
||||
dec a
|
||||
ld hl, wOTPartyMon1
|
||||
call GetPartyLocation
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld hl, MON_PP
|
||||
add hl, de
|
||||
|
||||
push hl
|
||||
ld hl, MON_MOVES
|
||||
add hl, de
|
||||
pop de
|
||||
|
||||
ld b, NUM_MOVES
|
||||
.copy_pp
|
||||
ld a, [hli]
|
||||
and a
|
||||
jr z, .copied_pp
|
||||
|
||||
push hl
|
||||
ld l, a
|
||||
ld a, MOVE_PP
|
||||
call GetMoveAttribute
|
||||
pop hl
|
||||
|
||||
ld [de], a
|
||||
inc de
|
||||
dec b
|
||||
jr nz, .copy_pp
|
||||
.copied_pp
|
||||
|
||||
pop hl
|
||||
.no_moves
|
||||
|
||||
jp .loop
|
||||
|
||||
ComputeTrainerReward:
|
||||
ld hl, hProduct
|
||||
xor a
|
||||
ld [hli], a
|
||||
ld [hli], a ; hMultiplicand + 0
|
||||
ld [hli], a ; hMultiplicand + 1
|
||||
ld a, [wEnemyTrainerBaseReward]
|
||||
ld [hli], a ; hMultiplicand + 2
|
||||
ld a, [wCurPartyLevel]
|
||||
ld [hl], a ; hMultiplier
|
||||
call Multiply
|
||||
ld hl, wBattleReward
|
||||
xor a
|
||||
ld [hli], a
|
||||
ldh a, [hProduct + 2]
|
||||
ld [hli], a
|
||||
ldh a, [hProduct + 3]
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
Battle_GetTrainerName::
|
||||
ld a, [wInBattleTowerBattle]
|
||||
bit 0, a
|
||||
ld hl, wOTPlayerName
|
||||
ld a, BANK(@)
|
||||
ld [wTrainerGroupBank], a
|
||||
jp nz, CopyTrainerName
|
||||
|
||||
ld a, [wOtherTrainerID]
|
||||
ld b, a
|
||||
ld a, [wOtherTrainerClass]
|
||||
ld c, a
|
||||
; fallthrough
|
||||
|
||||
GetTrainerName::
|
||||
ld a, c
|
||||
cp CAL
|
||||
jr nz, .not_cal2
|
||||
|
||||
ld a, BANK(sMysteryGiftTrainerHouseFlag)
|
||||
call OpenSRAM
|
||||
ld a, [sMysteryGiftTrainerHouseFlag]
|
||||
and a
|
||||
call CloseSRAM
|
||||
jr z, .not_cal2
|
||||
|
||||
ld a, BANK(sMysteryGiftPartnerName)
|
||||
call OpenSRAM
|
||||
ld hl, sMysteryGiftPartnerName
|
||||
call CopyTrainerName
|
||||
jp CloseSRAM
|
||||
|
||||
.not_cal2
|
||||
dec c
|
||||
push bc
|
||||
ld b, 0
|
||||
ld hl, TrainerGroups
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld [wTrainerGroupBank], a
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
pop bc
|
||||
|
||||
.loop
|
||||
dec b
|
||||
jr z, .done
|
||||
|
||||
ld a, [wTrainerGroupBank]
|
||||
call GetFarByte
|
||||
add a, l
|
||||
ld l, a
|
||||
jr nc, .loop
|
||||
inc h
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
inc hl
|
||||
; fallthrough
|
||||
|
||||
CopyTrainerName:
|
||||
ld de, wStringBuffer1
|
||||
push de
|
||||
ld bc, NAME_LENGTH
|
||||
ld a, [wTrainerGroupBank]
|
||||
call FarCopyBytes
|
||||
pop de
|
||||
ret
|
||||
|
||||
IncompleteCopyNameFunction: ; unreferenced
|
||||
; Copy of CopyTrainerName but without "call CopyBytes"
|
||||
ld de, wStringBuffer1
|
||||
push de
|
||||
ld bc, NAME_LENGTH
|
||||
pop de
|
||||
ret
|
||||
|
||||
GetNextTrainerDataByte:
|
||||
ld a, [wTrainerGroupBank]
|
||||
call GetFarByte
|
||||
inc hl
|
||||
ret
|
||||
|
||||
INCLUDE "data/trainers/party_pointers.asm"
|
||||
19
engine/battle/returntobattle_useball.asm
Normal file
19
engine/battle/returntobattle_useball.asm
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
_ReturnToBattle_UseBall:
|
||||
call ClearBGPalettes
|
||||
call ClearTilemap
|
||||
ld a, [wBattleType]
|
||||
cp BATTLETYPE_TUTORIAL
|
||||
jr z, .gettutorialbackpic
|
||||
farcall GetBattleMonBackpic
|
||||
jr .continue
|
||||
|
||||
.gettutorialbackpic
|
||||
farcall GetTrainerBackpic
|
||||
.continue
|
||||
farcall GetEnemyMonFrontpic
|
||||
farcall _LoadBattleFontsHPBar
|
||||
call GetMemSGBLayout
|
||||
call CloseWindow
|
||||
call LoadStandardMenuHeader
|
||||
call WaitBGMap
|
||||
jp SetPalettes
|
||||
98
engine/battle/sliding_intro.asm
Normal file
98
engine/battle/sliding_intro.asm
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
BattleIntroSlidingPics:
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wLYOverrides)
|
||||
ldh [rSVBK], a
|
||||
call .subfunction1
|
||||
ld a, LOW(rSCX)
|
||||
ldh [hLCDCPointer], a
|
||||
call .subfunction2
|
||||
xor a
|
||||
ldh [hLCDCPointer], a
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
|
||||
.subfunction1
|
||||
call .subfunction4
|
||||
ld a, $90
|
||||
ldh [hSCX], a
|
||||
ld a, %11100100
|
||||
call DmgToCgbBGPals
|
||||
lb de, %11100100, %11100100
|
||||
call DmgToCgbObjPals
|
||||
ret
|
||||
|
||||
.subfunction2
|
||||
ld d, $90
|
||||
ld e, $72
|
||||
ld a, $48
|
||||
inc a
|
||||
.loop1
|
||||
push af
|
||||
.loop2
|
||||
ldh a, [rLY]
|
||||
cp $60
|
||||
jr c, .loop2
|
||||
ld a, d
|
||||
ldh [hSCX], a
|
||||
call .subfunction5
|
||||
inc e
|
||||
inc e
|
||||
dec d
|
||||
dec d
|
||||
pop af
|
||||
push af
|
||||
cp $1
|
||||
jr z, .skip1
|
||||
push de
|
||||
call .subfunction3
|
||||
pop de
|
||||
|
||||
.skip1
|
||||
call DelayFrame
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .loop1
|
||||
ret
|
||||
|
||||
.subfunction3
|
||||
ld hl, wShadowOAMSprite00XCoord
|
||||
ld c, $12 ; 18
|
||||
ld de, SPRITEOAMSTRUCT_LENGTH
|
||||
.loop3
|
||||
dec [hl]
|
||||
dec [hl]
|
||||
add hl, de
|
||||
dec c
|
||||
jr nz, .loop3
|
||||
ret
|
||||
|
||||
.subfunction4
|
||||
ld hl, wLYOverrides
|
||||
ld a, $90
|
||||
ld bc, SCREEN_HEIGHT_PX
|
||||
call ByteFill
|
||||
ret
|
||||
|
||||
.subfunction5
|
||||
ld hl, wLYOverrides
|
||||
ld a, d
|
||||
ld c, $3e ; 62
|
||||
.loop4
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .loop4
|
||||
ld a, e
|
||||
ld c, $22 ; 34
|
||||
.loop5
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .loop5
|
||||
xor a
|
||||
ld c, $30 ; 48
|
||||
.loop6
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .loop6
|
||||
ret
|
||||
199
engine/battle/start_battle.asm
Normal file
199
engine/battle/start_battle.asm
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
ShowLinkBattleParticipants:
|
||||
; If we're not in a communications room,
|
||||
; we don't need to be here.
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
ret z
|
||||
|
||||
farcall _ShowLinkBattleParticipants
|
||||
ld c, 150
|
||||
call DelayFrames
|
||||
call ClearTilemap
|
||||
call ClearSprites
|
||||
ret
|
||||
|
||||
FindFirstAliveMonAndStartBattle:
|
||||
xor a
|
||||
ldh [hMapAnims], a
|
||||
call DelayFrame
|
||||
ld b, PARTY_LENGTH
|
||||
ld hl, wPartyMon1HP
|
||||
ld de, PARTYMON_STRUCT_LENGTH - 1
|
||||
|
||||
.loop
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
jr nz, .okay
|
||||
add hl, de
|
||||
dec b
|
||||
jr nz, .loop
|
||||
|
||||
.okay
|
||||
ld de, MON_LEVEL - MON_HP
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
ld [wBattleMonLevel], a
|
||||
predef DoBattleTransition
|
||||
farcall _LoadBattleFontsHPBar
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
call ClearSprites
|
||||
call ClearTilemap
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ldh [hWY], a
|
||||
ldh [rWY], a
|
||||
ldh [hMapAnims], a
|
||||
ret
|
||||
|
||||
PlayBattleMusic:
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
xor a
|
||||
ld [wMusicFade], a
|
||||
ld de, MUSIC_NONE
|
||||
call PlayMusic
|
||||
call DelayFrame
|
||||
call MaxVolume
|
||||
|
||||
ld a, [wBattleType]
|
||||
cp BATTLETYPE_SUICUNE
|
||||
ld de, MUSIC_SUICUNE_BATTLE
|
||||
jp z, .done
|
||||
cp BATTLETYPE_ROAMING
|
||||
jp z, .done
|
||||
|
||||
; Are we fighting a trainer?
|
||||
ld a, [wOtherTrainerClass]
|
||||
and a
|
||||
jr nz, .trainermusic
|
||||
|
||||
farcall RegionCheck
|
||||
ld a, e
|
||||
and a
|
||||
jr nz, .kantowild
|
||||
|
||||
ld de, MUSIC_JOHTO_WILD_BATTLE
|
||||
ld a, [wTimeOfDay]
|
||||
cp NITE_F
|
||||
jr nz, .done
|
||||
ld de, MUSIC_JOHTO_WILD_BATTLE_NIGHT
|
||||
jr .done
|
||||
|
||||
.kantowild
|
||||
ld de, MUSIC_KANTO_WILD_BATTLE
|
||||
jr .done
|
||||
|
||||
.trainermusic
|
||||
ld de, MUSIC_CHAMPION_BATTLE
|
||||
cp CHAMPION
|
||||
jr z, .done
|
||||
cp RED
|
||||
jr z, .done
|
||||
|
||||
; BUG: Team Rocket battle music is not used for Executives or Scientists (see docs/bugs_and_glitches.md)
|
||||
ld de, MUSIC_ROCKET_BATTLE
|
||||
cp GRUNTM
|
||||
jr z, .done
|
||||
cp GRUNTF
|
||||
jr z, .done
|
||||
|
||||
ld de, MUSIC_KANTO_GYM_LEADER_BATTLE
|
||||
farcall IsKantoGymLeader
|
||||
jr c, .done
|
||||
|
||||
; IsGymLeader also counts CHAMPION, RED, and the Kanto gym leaders
|
||||
; but they have been taken care of before this
|
||||
ld de, MUSIC_JOHTO_GYM_LEADER_BATTLE
|
||||
farcall IsGymLeader
|
||||
jr c, .done
|
||||
|
||||
ld de, MUSIC_RIVAL_BATTLE
|
||||
ld a, [wOtherTrainerClass]
|
||||
cp RIVAL1
|
||||
jr z, .done
|
||||
cp RIVAL2
|
||||
jr nz, .othertrainer
|
||||
|
||||
ld a, [wOtherTrainerID]
|
||||
cp RIVAL2_2_CHIKORITA ; Rival in Indigo Plateau
|
||||
jr c, .done
|
||||
ld de, MUSIC_CHAMPION_BATTLE
|
||||
jr .done
|
||||
|
||||
.othertrainer
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
jr nz, .johtotrainer
|
||||
|
||||
farcall RegionCheck
|
||||
ld a, e
|
||||
and a
|
||||
jr nz, .kantotrainer
|
||||
|
||||
.johtotrainer
|
||||
ld de, MUSIC_JOHTO_TRAINER_BATTLE
|
||||
jr .done
|
||||
|
||||
.kantotrainer
|
||||
ld de, MUSIC_KANTO_TRAINER_BATTLE
|
||||
|
||||
.done
|
||||
call PlayMusic
|
||||
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
ClearBattleRAM:
|
||||
xor a
|
||||
ld [wBattlePlayerAction], a
|
||||
ld [wBattleResult], a
|
||||
|
||||
ld hl, wPartyMenuCursor
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
|
||||
ld [wMenuScrollPosition], a
|
||||
ld [wCriticalHit], a
|
||||
ld [wBattleMonSpecies], a
|
||||
ld [wBattleParticipantsNotFainted], a
|
||||
ld [wCurBattleMon], a
|
||||
ld [wForcedSwitch], a
|
||||
ld [wTimeOfDayPal], a
|
||||
ld [wPlayerTurnsTaken], a
|
||||
ld [wEnemyTurnsTaken], a
|
||||
ld [wEvolvableFlags], a
|
||||
|
||||
ld hl, wPlayerHPPal
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
|
||||
ld hl, wBattleMonDVs
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
|
||||
ld hl, wEnemyMonDVs
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
|
||||
; Clear the entire BattleMons area
|
||||
ld hl, wBattle
|
||||
ld bc, wBattleEnd - wBattle
|
||||
xor a
|
||||
call ByteFill
|
||||
|
||||
callfar ResetEnemyStatLevels
|
||||
|
||||
call ClearWindowData
|
||||
|
||||
ld hl, hBGMapAddress
|
||||
xor a ; LOW(vBGMap0)
|
||||
ld [hli], a
|
||||
ld [hl], HIGH(vBGMap0)
|
||||
ret
|
||||
257
engine/battle/trainer_huds.asm
Normal file
257
engine/battle/trainer_huds.asm
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
BattleStart_TrainerHuds:
|
||||
ld a, $e4
|
||||
ldh [rOBP0], a
|
||||
call LoadBallIconGFX
|
||||
call ShowPlayerMonsRemaining
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
ret z
|
||||
jp ShowOTTrainerMonsRemaining
|
||||
|
||||
EnemySwitch_TrainerHud:
|
||||
ld a, $e4
|
||||
ldh [rOBP0], a
|
||||
call LoadBallIconGFX
|
||||
jp ShowOTTrainerMonsRemaining
|
||||
|
||||
ShowPlayerMonsRemaining:
|
||||
call DrawPlayerPartyIconHUDBorder
|
||||
ld hl, wPartyMon1HP
|
||||
ld de, wPartyCount
|
||||
call StageBallTilesData
|
||||
; ldpixel wPlaceBallsX, 12, 12
|
||||
ld a, 12 * 8
|
||||
ld hl, wPlaceBallsX
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
ld a, 8
|
||||
ld [wPlaceBallsDirection], a
|
||||
ld hl, wShadowOAMSprite00
|
||||
jp LoadTrainerHudOAM
|
||||
|
||||
ShowOTTrainerMonsRemaining:
|
||||
call DrawEnemyHUDBorder
|
||||
ld hl, wOTPartyMon1HP
|
||||
ld de, wOTPartyCount
|
||||
call StageBallTilesData
|
||||
; ldpixel wPlaceBallsX, 9, 4
|
||||
ld hl, wPlaceBallsX
|
||||
ld a, 9 * 8
|
||||
ld [hli], a
|
||||
ld [hl], 4 * 8
|
||||
ld a, -8
|
||||
ld [wPlaceBallsDirection], a
|
||||
ld hl, wShadowOAMSprite00 + PARTY_LENGTH * SPRITEOAMSTRUCT_LENGTH
|
||||
jp LoadTrainerHudOAM
|
||||
|
||||
StageBallTilesData:
|
||||
ld a, [de]
|
||||
push af
|
||||
ld de, wBattleHUDTiles
|
||||
ld c, PARTY_LENGTH
|
||||
ld a, $34 ; empty slot
|
||||
.loop1
|
||||
ld [de], a
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .loop1
|
||||
pop af
|
||||
|
||||
ld de, wBattleHUDTiles
|
||||
.loop2
|
||||
push af
|
||||
call .GetHUDTile
|
||||
inc de
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .loop2
|
||||
ret
|
||||
|
||||
.GetHUDTile:
|
||||
ld a, [hli]
|
||||
and a
|
||||
jr nz, .got_hp
|
||||
ld a, [hl]
|
||||
and a
|
||||
ld b, $33 ; fainted
|
||||
jr z, .fainted
|
||||
|
||||
.got_hp
|
||||
dec hl
|
||||
dec hl
|
||||
dec hl
|
||||
ld a, [hl]
|
||||
and a
|
||||
ld b, $32 ; statused
|
||||
jr nz, .load
|
||||
dec b ; normal
|
||||
jr .load
|
||||
|
||||
.fainted
|
||||
dec hl
|
||||
dec hl
|
||||
dec hl
|
||||
|
||||
.load
|
||||
ld a, b
|
||||
ld [de], a
|
||||
ld bc, PARTYMON_STRUCT_LENGTH + MON_HP - MON_STATUS
|
||||
add hl, bc
|
||||
ret
|
||||
|
||||
DrawPlayerHUDBorder:
|
||||
ld hl, .tiles
|
||||
ld de, wTrainerHUDTiles
|
||||
ld bc, .tiles_end - .tiles
|
||||
call CopyBytes
|
||||
hlcoord 18, 10
|
||||
ld de, -1 ; start on right
|
||||
jr PlaceHUDBorderTiles
|
||||
|
||||
.tiles
|
||||
db $73 ; right side
|
||||
db $77 ; bottom right
|
||||
db $6f ; bottom left
|
||||
db $76 ; bottom side
|
||||
.tiles_end
|
||||
|
||||
DrawPlayerPartyIconHUDBorder:
|
||||
ld hl, .tiles
|
||||
ld de, wTrainerHUDTiles
|
||||
ld bc, .tiles_end - .tiles
|
||||
call CopyBytes
|
||||
hlcoord 18, 10
|
||||
ld de, -1 ; start on right
|
||||
jr PlaceHUDBorderTiles
|
||||
|
||||
.tiles
|
||||
db $73 ; right side
|
||||
db $5c ; bottom right
|
||||
db $6f ; bottom left
|
||||
db $76 ; bottom side
|
||||
.tiles_end
|
||||
|
||||
DrawEnemyHUDBorder:
|
||||
ld hl, .tiles
|
||||
ld de, wTrainerHUDTiles
|
||||
ld bc, .tiles_end - .tiles
|
||||
call CopyBytes
|
||||
hlcoord 1, 2
|
||||
ld de, 1 ; start on left
|
||||
call PlaceHUDBorderTiles
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
ret nz
|
||||
ld a, [wTempEnemyMonSpecies]
|
||||
call CheckCaughtMon
|
||||
ret z
|
||||
hlcoord 1, 1
|
||||
ld [hl], $5d
|
||||
ret
|
||||
|
||||
.tiles
|
||||
db $6d ; left side
|
||||
db $74 ; bottom left
|
||||
db $78 ; bottom right
|
||||
db $76 ; bottom side
|
||||
.tiles_end
|
||||
|
||||
PlaceHUDBorderTiles:
|
||||
ld a, [wTrainerHUDTiles + 0]
|
||||
ld [hl], a
|
||||
ld bc, SCREEN_WIDTH
|
||||
add hl, bc
|
||||
ld a, [wTrainerHUDTiles + 1]
|
||||
ld [hl], a
|
||||
ld b, 8
|
||||
.loop
|
||||
add hl, de
|
||||
ld a, [wTrainerHUDTiles + 3]
|
||||
ld [hl], a
|
||||
dec b
|
||||
jr nz, .loop
|
||||
add hl, de
|
||||
ld a, [wTrainerHUDTiles + 2]
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
LinkBattle_TrainerHuds:
|
||||
call LoadBallIconGFX
|
||||
ld hl, wPartyMon1HP
|
||||
ld de, wPartyCount
|
||||
call StageBallTilesData
|
||||
ld hl, wPlaceBallsX
|
||||
ld a, 10 * 8
|
||||
ld [hli], a
|
||||
ld [hl], 8 * 8
|
||||
ld a, 8
|
||||
ld [wPlaceBallsDirection], a
|
||||
ld hl, wShadowOAMSprite00
|
||||
call LoadTrainerHudOAM
|
||||
|
||||
ld hl, wOTPartyMon1HP
|
||||
ld de, wOTPartyCount
|
||||
call StageBallTilesData
|
||||
ld hl, wPlaceBallsX
|
||||
ld a, 10 * 8
|
||||
ld [hli], a
|
||||
ld [hl], 13 * 8
|
||||
ld hl, wShadowOAMSprite00 + PARTY_LENGTH * SPRITEOAMSTRUCT_LENGTH
|
||||
jp LoadTrainerHudOAM
|
||||
|
||||
LoadTrainerHudOAM:
|
||||
ld de, wBattleHUDTiles
|
||||
ld c, PARTY_LENGTH
|
||||
.loop
|
||||
ld a, [wPlaceBallsY]
|
||||
ld [hli], a ; y
|
||||
ld a, [wPlaceBallsX]
|
||||
ld [hli], a ; x
|
||||
ld a, [de]
|
||||
ld [hli], a ; tile id
|
||||
ld a, PAL_BATTLE_OB_YELLOW
|
||||
ld [hli], a ; attributes
|
||||
ld a, [wPlaceBallsX]
|
||||
ld b, a
|
||||
ld a, [wPlaceBallsDirection]
|
||||
add b
|
||||
ld [wPlaceBallsX], a
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
LoadBallIconGFX:
|
||||
ld de, .gfx
|
||||
ld hl, vTiles0 tile $31
|
||||
lb bc, BANK(LoadBallIconGFX), 4
|
||||
call Get2bppViaHDMA
|
||||
ret
|
||||
|
||||
.gfx
|
||||
INCBIN "gfx/battle/balls.2bpp"
|
||||
|
||||
_ShowLinkBattleParticipants:
|
||||
call ClearBGPalettes
|
||||
call LoadFontsExtra
|
||||
hlcoord 2, 3
|
||||
ld b, 9
|
||||
ld c, 14
|
||||
call Textbox
|
||||
hlcoord 4, 5
|
||||
ld de, wPlayerName
|
||||
call PlaceString
|
||||
hlcoord 4, 10
|
||||
ld de, wOTPlayerName
|
||||
call PlaceString
|
||||
hlcoord 9, 8
|
||||
ld a, "<BOLD_V>"
|
||||
ld [hli], a
|
||||
ld [hl], "<BOLD_S>"
|
||||
farcall LinkBattle_TrainerHuds ; no need to farcall
|
||||
ld b, SCGB_DIPLOMA
|
||||
call GetSGBLayout
|
||||
call SetPalettes
|
||||
ld a, $e4
|
||||
ldh [rOBP0], a
|
||||
ret
|
||||
9
engine/battle/update_battle_huds.asm
Normal file
9
engine/battle/update_battle_huds.asm
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
_UpdateBattleHUDs:
|
||||
farcall DrawPlayerHUD
|
||||
ld hl, wPlayerHPPal
|
||||
call SetHPPal
|
||||
farcall DrawEnemyHUD
|
||||
ld hl, wEnemyHPPal
|
||||
call SetHPPal
|
||||
farcall FinishBattleAnim
|
||||
ret
|
||||
119
engine/battle/used_move_text.asm
Normal file
119
engine/battle/used_move_text.asm
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
DisplayUsedMoveText:
|
||||
ld hl, UsedMoveText
|
||||
call BattleTextbox
|
||||
jp WaitBGMap
|
||||
|
||||
UsedMoveText:
|
||||
text_far _ActorNameText
|
||||
text_asm
|
||||
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .start
|
||||
|
||||
ld a, [wPlayerMoveStruct + MOVE_ANIM]
|
||||
call UpdateUsedMoves
|
||||
|
||||
.start
|
||||
ld a, BATTLE_VARS_LAST_MOVE
|
||||
call GetBattleVarAddr
|
||||
ld d, h
|
||||
ld e, l
|
||||
|
||||
ld a, BATTLE_VARS_LAST_COUNTER_MOVE
|
||||
call GetBattleVarAddr
|
||||
|
||||
ld a, BATTLE_VARS_MOVE_ANIM
|
||||
call GetBattleVar
|
||||
ld [wTempByteValue], a
|
||||
|
||||
push hl
|
||||
farcall CheckUserIsCharging
|
||||
pop hl
|
||||
jr nz, .ok
|
||||
|
||||
; update last move
|
||||
ld a, [wTempByteValue]
|
||||
ld [hl], a
|
||||
ld [de], a
|
||||
|
||||
.ok
|
||||
ld hl, UsedMoveInsteadText
|
||||
ret
|
||||
|
||||
UsedMoveInsteadText:
|
||||
text_far _UsedMoveText
|
||||
text_asm
|
||||
; check obedience
|
||||
ld a, [wAlreadyDisobeyed]
|
||||
and a
|
||||
jr z, .GetMoveNameText
|
||||
; print "instead,"
|
||||
ld hl, .UsedInsteadText
|
||||
ret
|
||||
|
||||
.UsedInsteadText:
|
||||
text_far _UsedInsteadText
|
||||
text_asm
|
||||
.GetMoveNameText:
|
||||
ld hl, MoveNameText
|
||||
ret
|
||||
|
||||
MoveNameText:
|
||||
text_far _MoveNameText
|
||||
text_end
|
||||
|
||||
UpdateUsedMoves:
|
||||
; append move a to wPlayerUsedMoves unless it has already been used
|
||||
|
||||
push bc
|
||||
; start of list
|
||||
ld hl, wPlayerUsedMoves
|
||||
; get move id
|
||||
ld b, a
|
||||
; next count
|
||||
ld c, NUM_MOVES
|
||||
|
||||
.loop
|
||||
; get move from the list
|
||||
ld a, [hli]
|
||||
; not used yet?
|
||||
and a
|
||||
jr z, .add
|
||||
; already used?
|
||||
cp b
|
||||
jr z, .quit
|
||||
; next byte
|
||||
dec c
|
||||
jr nz, .loop
|
||||
|
||||
; if the list is full and the move hasn't already been used
|
||||
; shift the list back one byte, deleting the first move used
|
||||
; this can occur with struggle or a new learned move
|
||||
ld hl, wPlayerUsedMoves + 1
|
||||
; 1 = 2
|
||||
ld a, [hld]
|
||||
ld [hli], a
|
||||
; 2 = 3
|
||||
inc hl
|
||||
ld a, [hld]
|
||||
ld [hli], a
|
||||
; 3 = 4
|
||||
inc hl
|
||||
ld a, [hld]
|
||||
ld [hl], a
|
||||
; 4 = new move
|
||||
ld a, b
|
||||
ld [wPlayerUsedMoves + 3], a
|
||||
jr .quit
|
||||
|
||||
.add
|
||||
; go back to the byte we just inced from
|
||||
dec hl
|
||||
; add the new move
|
||||
ld [hl], b
|
||||
|
||||
.quit
|
||||
; list updated
|
||||
pop bc
|
||||
ret
|
||||
Loading…
Add table
Add a link
Reference in a new issue