aboutsummaryrefslogtreecommitdiffstats
path: root/engine/battle
diff options
context:
space:
mode:
authordannye <33dannye@gmail.com>2026-01-17 22:38:33 -0600
committerdannye <33dannye@gmail.com>2026-01-17 22:38:33 -0600
commitbc2354dd6626ce28bb9561547ed2107cfa56c18e (patch)
tree5902d4c3389253c76b7c3351e0d7dfecb551c28d /engine/battle
parentIdentify characters in `_OakSpeechText2B` and `Printer_GetMonStats.IDNo` (#144) (diff)
parentUse macros for `WildMonEncounterSlotChances` (#562) (diff)
downloadpokeyellow-bc2354dd6626ce28bb9561547ed2107cfa56c18e.tar.gz
pokeyellow-bc2354dd6626ce28bb9561547ed2107cfa56c18e.tar.xz
pokeyellow-bc2354dd6626ce28bb9561547ed2107cfa56c18e.zip
Merge branch 'master' of https://github.com/pret/pokered
Diffstat (limited to 'engine/battle')
-rw-r--r--engine/battle/animations.asm52
-rw-r--r--engine/battle/battle_transitions.asm10
-rw-r--r--engine/battle/core.asm258
-rw-r--r--engine/battle/decrement_pp.asm2
-rw-r--r--engine/battle/draw_hud_pokeball_gfx.asm14
-rw-r--r--engine/battle/effects.asm24
-rw-r--r--engine/battle/end_of_battle.asm6
-rw-r--r--engine/battle/experience.asm28
-rw-r--r--engine/battle/get_trainer_name.asm2
-rw-r--r--engine/battle/ghost_marowak_anim.asm4
-rw-r--r--engine/battle/init_battle.asm12
-rw-r--r--engine/battle/link_battle_versus_text.asm4
-rw-r--r--engine/battle/move_effects/haze.asm4
-rw-r--r--engine/battle/move_effects/substitute.asm4
-rw-r--r--engine/battle/move_effects/transform.asm14
-rw-r--r--engine/battle/read_trainer_party.asm2
-rw-r--r--engine/battle/trainer_ai.asm10
-rw-r--r--engine/battle/used_move_text.asm139
18 files changed, 298 insertions, 291 deletions
diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm
index 5adecbd7..aafb966e 100644
--- a/engine/battle/animations.asm
+++ b/engine/battle/animations.asm
@@ -24,7 +24,7 @@ DrawFrameBlock:
jp z, .flipHorizontalTranslateDown ; SUBANIMTYPE_HFLIP
dec a
jr z, .flipBaseCoords ; SUBANIMTYPE_COORDFLIP
-.noTransformation
+; no transformation
ld a, [wBaseCoordY]
add [hl]
ld [de], a ; store Y
@@ -157,7 +157,7 @@ DrawFrameBlock:
ld a, [wNumFBTiles]
cp c
jp nz, .loop ; go back up if there are more tiles to draw
-.afterDrawingTiles
+; after drawing tiles
ld a, [wFBMode]
cp FRAMEBLOCKMODE_02
jr z, .advanceFrameBlockDestAddr ; skip delay and don't clean OAM buffer
@@ -210,7 +210,7 @@ PlayAnimation:
jr z, .AnimationOver
cp FIRST_SE_ID ; is this subanimation or a special effect?
jr c, .playSubanimation
-.doSpecialEffect
+; do Special Effect
ld c, a
ld de, SpecialEffectPointers
.searchSpecialEffectTableLoop
@@ -315,11 +315,11 @@ LoadSubanimation:
and %11100000
cp SUBANIMTYPE_ENEMY << 5
vc_hook Reduce_move_anim_flashing_Reflect
- jr nz, .isNotType5
-.isType5
+ jr nz, .isNotTypeEnemy
+; subanim type enemy
call GetSubanimationTransform2
jr .saveTransformation
-.isNotType5
+.isNotTypeEnemy
vc_hook Reduce_move_anim_flashing_Self_Destruct
call GetSubanimationTransform1
.saveTransformation
@@ -440,11 +440,11 @@ MoveAnimation:
jr nz, .animationsDisabled
call ShareMoveAnimations
call PlayAnimation
- jr .next4
+ jr .next
.animationsDisabled
ld c, 30
call DelayFrames
-.next4
+.next
vc_hook Stop_reducing_move_anim_flashing_Reflect
call PlayApplyingAttackAnimation ; shake the screen or flash the pic in and out (to show damage)
.animationFinished
@@ -968,7 +968,7 @@ BallMoveDistances2:
DoGrowlSpecialEffects:
ld hl, wShadowOAM
ld de, wShadowOAMSprite04
- ld bc, $10
+ ld bc, OBJ_SIZE * 4
call CopyData ; copy the musical note graphic
ld a, [wSubAnimCounter]
dec a
@@ -1141,6 +1141,8 @@ SetAnimationBGPalette:
call UpdateCGBPal_BGP
ret
+AnimationUnusedShakeScreen: ; unreferenced
+; Shakes the screen for a while.
ld b, $5
AnimationShakeScreenVertically:
@@ -1272,12 +1274,12 @@ _AnimationSlideMonUp:
push bc
; In each iteration, slide up all rows but the top one (which is overwritten).
- ld b, 6
+ ld b, PIC_HEIGHT - 1
.slideLoop
push bc
push de
push hl
- ld bc, 7
+ ld bc, PIC_WIDTH
call CopyData
; Note that de and hl are popped in the same order they are pushed, swapping
; their values. When CopyData is called, hl points to a tile 1 row below
@@ -1301,10 +1303,10 @@ _AnimationSlideMonUp:
ld a, [wSlideMonUpBottomRowLeftTile]
inc a
ld [wSlideMonUpBottomRowLeftTile], a
- ld c, 7
+ ld c, PIC_WIDTH
.fillBottomRowLoop
ld [hli], a
- add 7
+ add PIC_WIDTH
dec c
jr nz, .fillBottomRowLoop
@@ -1381,7 +1383,7 @@ AdjustOAMBlockXPos:
ld h, d
AdjustOAMBlockXPos2:
- ld de, 4
+ ld de, OBJ_SIZE
.loop
ld a, [wCoordAdjustmentAmount]
ld b, a
@@ -1391,7 +1393,7 @@ AdjustOAMBlockXPos2:
jr c, .skipPuttingEntryOffScreen
; put off-screen if X >= 168
dec hl
- ld a, 160
+ ld a, SCREEN_HEIGHT_PX + OAM_Y_OFS
ld [hli], a
.skipPuttingEntryOffScreen
ld [hl], a
@@ -1405,7 +1407,7 @@ AdjustOAMBlockYPos:
ld h, d
AdjustOAMBlockYPos2:
- ld de, 4
+ ld de, OBJ_SIZE
.loop
ld a, [wCoordAdjustmentAmount]
ld b, a
@@ -1756,7 +1758,7 @@ _AnimationShootBallsUpward:
dec a
ld [wNumShootingBalls], a
.next
- ld de, 4
+ ld de, OBJ_SIZE
add hl, de ; next OAM entry
dec b
jr nz, .innerLoop
@@ -1809,10 +1811,10 @@ AnimationMinimizeMon:
ld hl, wTempPic
push hl
xor a
- ld bc, 7 * 7 * $10
+ ld bc, PIC_SIZE tiles
call FillMemory
pop hl
- ld de, 7 * 3 * $10 + 4 * $10 + 4
+ ld de, (PIC_WIDTH * 3 + 4) tiles + TILE_SIZE / 4
add hl, de
ld de, MinimizedMonSprite
ld c, MinimizedMonSpriteEnd - MinimizedMonSprite
@@ -1860,7 +1862,7 @@ AnimationSlideMonDownAndHide:
jr nz, .loop
call AnimationHideMonPic
ld hl, wTempPic
- ld bc, 7 * 7 tiles
+ ld bc, PIC_SIZE tiles
xor a
call FillMemory
jp CopyTempPicToMonPic
@@ -1951,7 +1953,7 @@ CopyTempPicToMonPic:
ld hl, vFrontPic ; enemy turn
.next
ld de, wTempPic
- ld bc, 7 * 7
+ ld bc, PIC_SIZE
jp CopyVideoData
AnimationWavyScreen:
@@ -2019,7 +2021,7 @@ AnimationSubstitute:
; Changes the pokemon's sprite to the mini sprite
ld hl, wTempPic
xor a
- ld bc, 7 * 7 tiles
+ ld bc, PIC_SIZE tiles
call FillMemory
ldh a, [hWhoseTurn]
and a
@@ -2055,7 +2057,7 @@ AnimationSubstitute:
jp AnimationShowMonPic
CopyMonsterSpriteData:
- ld bc, 1 tiles
+ ld bc, TILE_SIZE
ld a, BANK(MonsterSprite)
jp FarCopyData
@@ -2538,7 +2540,7 @@ FallingObjects_UpdateOAMEntry:
inc a
cp 112
jr c, .next
- ld a, 160 ; if Y >= 112, put it off-screen
+ ld a, SCREEN_HEIGHT_PX + OAM_Y_OFS ; if Y >= 112, put it off-screen
.next
ld [hli], a ; Y
cp 40
@@ -2655,7 +2657,7 @@ AnimationShakeEnemyHUD:
; Make a copy of the back pic's tile patterns in sprite tile pattern VRAM.
ld de, vBackPic
ld hl, vSprites
- ld bc, 7 * 7
+ ld bc, PIC_SIZE
call CopyVideoData
xor a
diff --git a/engine/battle/battle_transitions.asm b/engine/battle/battle_transitions.asm
index 8a340bf7..cd0af180 100644
--- a/engine/battle/battle_transitions.asm
+++ b/engine/battle/battle_transitions.asm
@@ -14,7 +14,7 @@ BattleTransition:
ldh a, [hSpriteIndex] ; enemy trainer sprite index (0 if wild battle)
ld c, a
ld b, 0
- ld de, $10
+ ld de, SPRITESTATEDATA1_LENGTH
.loop1
ld a, [hl]
cp $ff
@@ -35,13 +35,13 @@ BattleTransition:
jr z, .skip2 ; skip clearing the block if the enemy trainer is using it
push hl
push bc
- ld bc, $10
+ ld bc, OBJ_SIZE * 4
xor a
call FillMemory
pop bc
pop hl
.skip2
- ld de, $10
+ ld de, OBJ_SIZE * 4
add hl, de
dec c
jr nz, .loop2
@@ -104,11 +104,11 @@ GetBattleTransitionID_CompareLevels:
ld a, [hli]
or [hl]
jr nz, .notFainted
- ld de, wPartyMon2 - (wPartyMon1 + 1)
+ ld de, PARTYMON_STRUCT_LENGTH - 1
add hl, de
jr .faintedLoop
.notFainted
- ld de, wPartyMon1Level - (wPartyMon1HP + 1)
+ ld de, MON_LEVEL - (MON_HP + 1)
add hl, de
ld a, [hl]
add $3
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
index a1a989e4..33301e58 100644
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -109,8 +109,8 @@ SlidePlayerAndEnemySilhouettesOnScreen:
SlidePlayerHeadLeft:
push bc
ld hl, wShadowOAMSprite00XCoord
- ld c, $15 ; number of OAM entries
- ld de, $4 ; size of OAM entry
+ ld c, 7 * 3 ; number of OAM entries
+ ld de, OBJ_SIZE
.loop
dec [hl] ; decrement X
dec [hl] ; decrement X
@@ -140,7 +140,7 @@ StartBattle:
inc a
ld [wFirstMonsNotOutYet], a
ld hl, wEnemyMon1HP
- ld bc, wEnemyMon2 - wEnemyMon1 - 1
+ ld bc, PARTYMON_STRUCT_LENGTH - 1
ld d, $3
.findFirstAliveEnemyMonLoop
inc d
@@ -745,7 +745,7 @@ FaintEnemyPokemon:
jr z, .wild
ld a, [wEnemyMonPartyPos]
ld hl, wEnemyMon1HP
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
xor a
ld [hli], a
@@ -885,7 +885,7 @@ AnyEnemyPokemonAliveCheck:
ld b, a
xor a
ld hl, wEnemyMon1HP
- ld de, wEnemyMon2 - wEnemyMon1
+ ld de, PARTYMON_STRUCT_LENGTH
.nextPokemon
or [hl]
inc hl
@@ -1222,17 +1222,17 @@ SlideDownFaintedMonPic:
push af
set BIT_NO_TEXT_DELAY, a
ld [wStatusFlags5], a
- ld b, 7 ; number of times to slide
+ ld b, PIC_HEIGHT ; number of times to slide
.slideStepLoop ; each iteration, the mon is slid down one row
push bc
push de
push hl
- ld b, 6 ; number of rows
+ ld b, PIC_HEIGHT - 1 ; number of rows
.rowLoop
push bc
push hl
push de
- ld bc, $7
+ ld bc, PIC_WIDTH
call CopyData
pop de
pop hl
@@ -1264,7 +1264,8 @@ SlideDownFaintedMonPic:
ret
SevenSpacesText:
- db " @"
+ ds PIC_WIDTH, ' '
+ db "@"
; slides the player or enemy trainer off screen
; a is the number of tiles to slide it horizontally (always 9 for the player trainer or 8 for the enemy trainer)
@@ -1276,7 +1277,7 @@ SlideTrainerPicOffScreen:
.slideStepLoop ; each iteration, the trainer pic is slid one tile left/right
push bc
push hl
- ld b, 7 ; number of rows
+ ld b, PIC_HEIGHT ; number of rows
.rowLoop
push hl
ldh a, [hSlideAmount]
@@ -1285,7 +1286,7 @@ SlideTrainerPicOffScreen:
ldh a, [hSlideAmount]
cp 8
jr z, .slideRight
-.slideLeft ; slide player sprite off screen
+; slide player sprite left off screen
ld a, [hld]
ld [hli], a
inc hl
@@ -1368,7 +1369,7 @@ EnemySendOutFirstMon:
ld a, b
ld [wWhichPokemon], a
push bc
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
pop bc
inc hl
@@ -1380,7 +1381,7 @@ EnemySendOutFirstMon:
.next3
ld a, [wWhichPokemon]
ld hl, wEnemyMon1Level
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [hl]
ld [wCurEnemyLevel], a
@@ -1495,7 +1496,7 @@ AnyPartyAlive::
ld e, a
xor a
ld hl, wPartyMon1HP
- ld bc, wPartyMon2 - wPartyMon1 - 1
+ ld bc, PARTYMON_STRUCT_LENGTH - 1
.partyMonsLoop
or [hl]
inc hl
@@ -1511,7 +1512,7 @@ AnyPartyAlive::
HasMonFainted:
ld a, [wWhichPokemon]
ld hl, wPartyMon1HP
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [hli]
or [hl]
@@ -1665,16 +1666,16 @@ GotAwayText:
; copies from party data to battle mon data when sending out a new player mon
LoadBattleMonFromParty:
ld a, [wWhichPokemon]
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
ld hl, wPartyMon1Species
call AddNTimes
ld de, wBattleMonSpecies
ld bc, wBattleMonDVs - wBattleMonSpecies
call CopyData
- ld bc, wPartyMon1DVs - wPartyMon1OTID
+ ld bc, MON_DVS - MON_OTID
add hl, bc
ld de, wBattleMonDVs
- ld bc, wPartyMon1PP - wPartyMon1DVs
+ ld bc, MON_PP - MON_DVS
call CopyData
ld de, wBattleMonPP
ld bc, NUM_MOVES
@@ -1709,16 +1710,16 @@ LoadBattleMonFromParty:
; copies from enemy party data to current enemy mon data when sending out a new enemy mon
LoadEnemyMonFromParty:
ld a, [wWhichPokemon]
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
ld hl, wEnemyMons
call AddNTimes
ld de, wEnemyMonSpecies
ld bc, wEnemyMonDVs - wEnemyMonSpecies
call CopyData
- ld bc, wEnemyMon1DVs - wEnemyMon1OTID
+ ld bc, MON_DVS - MON_OTID
add hl, bc
ld de, wEnemyMonDVs
- ld bc, wEnemyMon1PP - wEnemyMon1DVs
+ ld bc, MON_PP - MON_DVS
call CopyData
ld de, wEnemyMonPP
ld bc, NUM_MOVES
@@ -1869,17 +1870,17 @@ AnimateRetreatingPlayerMon:
call ClearScreenArea
ret
-; Copies player's current pokemon's current HP and status into the party
+; Copies player's current pokemon's current HP, party pos, and status into the party
; struct data so it stays after battle or switching
ReadPlayerMonCurHPAndStatus:
ld a, [wPlayerMonNumber]
ld hl, wPartyMon1HP
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld d, h
ld e, l
ld hl, wBattleMonHP
- ld bc, $4 ; 2 bytes HP, 1 byte unknown (unused?), 1 byte status
+ ld bc, MON_STATUS + 1 - MON_HP ; also copies party pos in-between HP and status
jp CopyData
DrawHUDsAndHPBars:
@@ -2623,7 +2624,7 @@ MoveSelectionMenu:
.relearnmenu
ld a, [wWhichPokemon]
ld hl, wPartyMon1Moves
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
call .loadmoves
hlcoord 4, 7
@@ -2969,12 +2970,12 @@ ENDC
.swapMovesInPartyMon
ld hl, wPartyMon1Moves
ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
push hl
call .swapBytes ; swap moves
pop hl
- ld bc, wPartyMon1PP - wPartyMon1Moves
+ ld bc, MON_PP - MON_MOVES
add hl, bc
call .swapBytes ; swap move PP
xor a
@@ -3285,7 +3286,7 @@ PlayerCanExecuteChargingMove:
; resulting in the Pokemon being invulnerable for the whole battle
res INVULNERABLE, [hl]
PlayerCanExecuteMove:
- call PrintMonName1Text
+ call DisplayUsedMoveText
ld hl, DecrementPP
ld de, wPlayerSelectedMove ; pointer to the move just used
ld b, BANK(DecrementPP)
@@ -3621,7 +3622,7 @@ CheckPlayerStatusConditions:
bit PAR, [hl]
jr z, .BideCheck
call BattleRandom
- cp $3F ; 25% to be fully paralyzed
+ cp 25 percent ; chance to be fully paralyzed
jr nc, .BideCheck
ld hl, FullyParalyzedText
call PrintText
@@ -3727,11 +3728,12 @@ CheckPlayerStatusConditions:
ld hl, AttackContinuesText
call PrintText
ld a, [wPlayerNumAttacksLeft]
- dec a ; did multi-turn move end?
+ dec a
ld [wPlayerNumAttacksLeft], a
- ld hl, GetPlayerAnimationType ; if it didn't, skip damage calculation (deal damage equal to last hit),
- ; DecrementPP and MoveHitTest
- jp nz, .returnToHL
+ ld hl, GetPlayerAnimationType ; skip damage calculation (deal damage equal to last hit),
+ ; DecrementPP and MoveHitTest
+ jp nz, .returnToHL ; redundant leftover code, the case wEnemyNumAttacksLeft == 0
+ ; is handled within CheckNumAttacksLeft
jp .returnToHL
.RageCheck
@@ -3796,7 +3798,7 @@ ConfusedNoMoreText:
text_far _ConfusedNoMoreText
text_end
-SavingEnergyText:
+SavingEnergyText: ; unreferenced
text_far _SavingEnergyText
text_end
@@ -3882,139 +3884,7 @@ HandleSelfConfusionDamage:
ldh [hWhoseTurn], a
jp ApplyDamageToPlayerPokemon
-PrintMonName1Text:
- ld hl, MonName1Text
- jp PrintText
-
-; this function wastes time calling DetermineExclamationPointTextNum
-; and choosing between Used1Text and Used2Text, even though
-; those text strings are identical and both continue at PrintInsteadText
-; this likely had to do with Japanese grammar that got translated,
-; but the functionality didn't get removed
-MonName1Text:
- text_far _MonName1Text
- text_asm
- ldh a, [hWhoseTurn]
- and a
- ld a, [wPlayerMoveNum]
- ld hl, wPlayerUsedMove
- jr z, .playerTurn
- ld a, [wEnemyMoveNum]
- ld hl, wEnemyUsedMove
-.playerTurn
- ld [hl], a
- ld [wMoveGrammar], a
- call DetermineExclamationPointTextNum
- ld a, [wMonIsDisobedient]
- and a
- ld hl, Used2Text
- ret nz
- ld a, [wMoveGrammar]
- cp 3
- ld hl, Used2Text
- ret c
- ld hl, Used1Text
- ret
-
-Used1Text:
- text_far _Used1Text
- text_asm
- jr PrintInsteadText
-
-Used2Text:
- text_far _Used2Text
- text_asm
- ; fall through
-
-PrintInsteadText:
- ld a, [wMonIsDisobedient]
- and a
- jr z, PrintMoveName
- ld hl, InsteadText
- ret
-
-InsteadText:
- text_far _InsteadText
- text_asm
- ; fall through
-
-PrintMoveName:
- ld hl, _PrintMoveName
- ret
-
-_PrintMoveName:
- text_far _MoveNameText
- text_asm
- ld hl, ExclamationPointPointerTable
- ld a, [wMoveGrammar]
- add a
- push bc
- ld b, $0
- ld c, a
- add hl, bc
- pop bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ret
-
-ExclamationPointPointerTable:
- dw ExclamationPoint1Text
- dw ExclamationPoint2Text
- dw ExclamationPoint3Text
- dw ExclamationPoint4Text
- dw ExclamationPoint5Text
-
-ExclamationPoint1Text:
- text_far _ExclamationPoint1Text
- text_end
-
-ExclamationPoint2Text:
- text_far _ExclamationPoint2Text
- text_end
-
-ExclamationPoint3Text:
- text_far _ExclamationPoint3Text
- text_end
-
-ExclamationPoint4Text:
- text_far _ExclamationPoint4Text
- text_end
-
-ExclamationPoint5Text:
- text_far _ExclamationPoint5Text
- text_end
-
-; this function does nothing useful
-; if the move being used is in set [1-4] from ExclamationPointMoveSets,
-; use ExclamationPoint[1-4]Text
-; otherwise, use ExclamationPoint5Text
-; but all five text strings are identical
-; this likely had to do with Japanese grammar that got translated,
-; but the functionality didn't get removed
-DetermineExclamationPointTextNum:
- push bc
- ld a, [wMoveGrammar] ; move ID
- ld c, a
- ld b, $0
- ld hl, ExclamationPointMoveSets
-.loop
- ld a, [hli]
- cp $ff
- jr z, .done
- cp c
- jr z, .done
- and a
- jr nz, .loop
- inc b
- jr .loop
-.done
- ld a, b
- ld [wMoveGrammar], a
- pop bc
- ret
-
-INCLUDE "data/moves/grammar.asm"
+INCLUDE "engine/battle/used_move_text.asm"
PrintMoveFailureText:
ld de, wPlayerMoveEffect
@@ -4140,7 +4010,7 @@ CheckForDisobedience:
; compare the mon's original trainer ID with the player's ID to see if it was traded
.checkIfMonIsTraded
ld hl, wPartyMon1OTID
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
ld a, [wPlayerMonNumber]
call AddNTimes
ld a, [wPlayerID]
@@ -4341,7 +4211,7 @@ GetDamageVarsForPlayerAttack:
ld a, [hl] ; a = [wPlayerMoveType]
cp SPECIAL ; types >= SPECIAL are all special
jr nc, .specialAttack
-.physicalAttack
+; physical attack
ld hl, wEnemyMonDefense
ld a, [hli]
ld b, a
@@ -4367,7 +4237,7 @@ GetDamageVarsForPlayerAttack:
push bc
ld hl, wPartyMon1Attack
ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
pop bc
jr .scaleStats
@@ -4399,7 +4269,7 @@ GetDamageVarsForPlayerAttack:
push bc
ld hl, wPartyMon1Special
ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
pop bc
; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
@@ -4454,7 +4324,7 @@ GetDamageVarsForEnemyAttack:
ld a, [hl] ; a = [wEnemyMoveType]
cp SPECIAL ; types >= SPECIAL are all special
jr nc, .specialAttack
-.physicalAttack
+; physical attack
ld hl, wBattleMonDefense
ld a, [hli]
ld b, a
@@ -4473,7 +4343,7 @@ GetDamageVarsForEnemyAttack:
; in the case of a critical hit, reset the player's defense and the enemy's attack to their base values
ld hl, wPartyMon1Defense
ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [hli]
ld b, a
@@ -4505,7 +4375,7 @@ GetDamageVarsForEnemyAttack:
; in the case of a critical hit, reset the player's and enemy's specials to their base values
ld hl, wPartyMon1Special
ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [hli]
ld b, a
@@ -4568,7 +4438,7 @@ GetEnemyMonStat:
ld b, $0
add hl, bc
ld a, [wEnemyMonPartyPos]
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [hli]
ldh [hMultiplicand + 1], a
@@ -5367,7 +5237,7 @@ IncrementMovePP:
jr z, .updatePP
ld a, [wEnemyMonPartyPos] ; value for enemy turn
.updatePP
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
inc [hl] ; increment PP in the party memory location
ret
@@ -5471,7 +5341,6 @@ AdjustDamageForMoveType:
ld [hl], a
or b ; is damage 0?
jr nz, .skipTypeImmunity
-.typeImmunity
; if damage is 0, make the move miss
; this only occurs if a move that would do 2 or 3 damage is 0.25x effective against the target
inc a
@@ -5575,7 +5444,7 @@ MoveHitTest:
ldh a, [hWhoseTurn]
and a
jr nz, .enemyTurn
-.playerTurn
+; player's turn
; this checks if the move effect is disallowed by mist
ld a, [wPlayerMoveEffect]
cp ATTACK_DOWN1_EFFECT
@@ -5647,12 +5516,12 @@ MoveHitTest:
ld [wMoveMissed], a
ldh a, [hWhoseTurn]
and a
- jr z, .playerTurn2
-.enemyTurn2
+ jr z, .playerTurn
+; enemy's turn
ld hl, wEnemyBattleStatus1
res USING_TRAPPING_MOVE, [hl] ; end multi-turn attack e.g. wrap
ret
-.playerTurn2
+.playerTurn
ld hl, wPlayerBattleStatus1
res USING_TRAPPING_MOVE, [hl] ; end multi-turn attack e.g. wrap
ret
@@ -5823,7 +5692,7 @@ EnemyCanExecuteChargingMove:
EnemyCanExecuteMove:
xor a
ld [wMonIsDisobedient], a
- call PrintMonName1Text
+ call DisplayUsedMoveText
ld a, [wEnemyMoveEffect]
ld hl, ResidualEffects1
ld de, $1
@@ -6244,10 +6113,11 @@ CheckEnemyStatusConditions:
ld hl, AttackContinuesText
call PrintText
ld hl, wEnemyNumAttacksLeft
- dec [hl] ; did multi-turn move end?
- ld hl, GetEnemyAnimationType ; if it didn't, skip damage calculation (deal damage equal to last hit),
+ dec [hl]
+ ld hl, GetEnemyAnimationType ; skip damage calculation (deal damage equal to last hit),
; DecrementPP and MoveHitTest
- jp nz, .enemyReturnToHL
+ jp nz, .enemyReturnToHL ; redundant leftover code, the case wEnemyNumAttacksLeft == 0
+ ; is handled within CheckNumAttacksLeft
jp .enemyReturnToHL
.checkIfUsingRage
ld a, [wEnemyBattleStatus2]
@@ -6387,7 +6257,7 @@ LoadEnemyMonData:
; if it's a trainer battle, copy moves from enemy party data
ld hl, wEnemyMon1Moves
ld a, [wWhichPokemon]
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld bc, NUM_MOVES
call CopyData
@@ -6538,7 +6408,7 @@ LoadPlayerBackPic:
ld [hl], d ; OAM Y
inc hl
ld [hl], e ; OAM X
- ld a, $8 ; height of tile
+ ld a, TILE_HEIGHT
add d ; increase Y by height of tile
ld d, a
inc hl
@@ -6554,7 +6424,7 @@ LoadPlayerBackPic:
ldh a, [hOAMTile]
add $4 ; increase tile number by 4
ldh [hOAMTile], a
- ld a, $8 ; width of tile
+ ld a, TILE_WIDTH
add e ; increase X by width of tile
ld e, a
dec b
@@ -6567,7 +6437,7 @@ LoadPlayerBackPic:
ld de, sSpriteBuffer1
ldh a, [hLoadedROMBank]
ld b, a
- ld c, 7 * 7
+ ld c, PIC_SIZE
call CopyVideoData
call CloseSRAM
ld a, $31
@@ -6599,7 +6469,7 @@ QuarterSpeedDueToParalysis:
ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
-.enemyTurn ; quarter the player's speed
+; enemy's turn, quarter the player's speed
ld a, [wBattleMonStatus]
and 1 << PAR
ret z ; return if player not paralysed
@@ -6642,7 +6512,7 @@ HalveAttackDueToBurn:
ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
-.enemyTurn ; halve the player's attack
+; enemy's turn, halve the player's attack
ld a, [wBattleMonStatus]
and 1 << BRN
ret z ; return if player not burnt
@@ -6826,7 +6696,7 @@ LoadHudTilePatterns:
ldh a, [rLCDC]
add a ; is LCD disabled?
jr c, .lcdEnabled
-.lcdDisabled
+; LCD disabled
ld hl, BattleHudTiles1
ld de, vChars2 tile $6d
ld bc, BattleHudTiles1End - BattleHudTiles1
@@ -6840,11 +6710,11 @@ LoadHudTilePatterns:
.lcdEnabled
ld de, BattleHudTiles1
ld hl, vChars2 tile $6d
- lb bc, BANK(BattleHudTiles1), (BattleHudTiles1End - BattleHudTiles1) / $8
+ lb bc, BANK(BattleHudTiles1), (BattleHudTiles1End - BattleHudTiles1) / TILE_1BPP_SIZE
call CopyVideoDataDouble
ld de, BattleHudTiles2
ld hl, vChars2 tile $73
- lb bc, BANK(BattleHudTiles2), (BattleHudTiles3End - BattleHudTiles2) / $8
+ lb bc, BANK(BattleHudTiles2), (BattleHudTiles3End - BattleHudTiles2) / TILE_1BPP_SIZE
jp CopyVideoDataDouble
PrintEmptyString:
diff --git a/engine/battle/decrement_pp.asm b/engine/battle/decrement_pp.asm
index 441bbb81..93515224 100644
--- a/engine/battle/decrement_pp.asm
+++ b/engine/battle/decrement_pp.asm
@@ -31,7 +31,7 @@ DecrementPP:
ld hl, wPartyMon1PP ; PP of first move (in party)
ld a, [wPlayerMonNumber] ; which mon in party is active
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes ; calculate address of the mon to modify
.DecrementPP:
ld a, [wPlayerMoveListIndex] ; which move (0, 1, 2, 3) did we use?
diff --git a/engine/battle/draw_hud_pokeball_gfx.asm b/engine/battle/draw_hud_pokeball_gfx.asm
index 0b0aac7d..bf955040 100644
--- a/engine/battle/draw_hud_pokeball_gfx.asm
+++ b/engine/battle/draw_hud_pokeball_gfx.asm
@@ -13,12 +13,12 @@ DrawEnemyPokeballs:
LoadPartyPokeballGfx:
ld de, PokeballTileGraphics
ld hl, vSprites tile $31
- lb bc, BANK(PokeballTileGraphics), (PokeballTileGraphicsEnd - PokeballTileGraphics) / $10
+ lb bc, BANK(PokeballTileGraphics), (PokeballTileGraphicsEnd - PokeballTileGraphics) / TILE_SIZE
jp CopyVideoData
SetupOwnPartyPokeballs:
call PlacePlayerHUDTiles
- ld hl, wPartyMon1
+ ld hl, wPartyMons
ld de, wPartyCount
call SetupPokeballs
ld a, $60
@@ -94,7 +94,7 @@ PickPokeball:
.done
ld a, b
ld [de], a
- ld bc, wPartyMon2 - wPartyMon1Status
+ ld bc, PARTYMON_STRUCT_LENGTH - MON_STATUS
add hl, bc ; next mon struct
ret
@@ -123,7 +123,7 @@ WritePokeballOAMData:
PlacePlayerHUDTiles:
ld hl, PlayerBattleHUDGraphicsTiles
ld de, wHUDGraphicsTiles
- ld bc, $3
+ ld bc, wHUDGraphicsTilesEnd - wHUDGraphicsTiles
call CopyData
hlcoord 18, 10
ld de, -1
@@ -138,7 +138,7 @@ PlayerBattleHUDGraphicsTiles:
PlaceEnemyHUDTiles:
ld hl, EnemyBattleHUDGraphicsTiles
ld de, wHUDGraphicsTiles
- ld bc, $3
+ ld bc, wHUDGraphicsTilesEnd - wHUDGraphicsTiles
call CopyData
hlcoord 1, 2
ld de, $1
@@ -154,7 +154,7 @@ PlaceHUDTiles:
ld [hl], $73
ld bc, SCREEN_WIDTH
add hl, bc
- ld a, [wHUDGraphicsTiles + 1] ; leftmost tile
+ ld a, [wHUDCornerTile] ; leftmost tile
ld [hl], a
ld a, 8
.loop
@@ -163,7 +163,7 @@ PlaceHUDTiles:
dec a
jr nz, .loop
add hl, de
- ld a, [wHUDGraphicsTiles + 2] ; rightmost tile
+ ld a, [wHUDTriangleTile] ; rightmost tile
ld [hl], a
ret
diff --git a/engine/battle/effects.asm b/engine/battle/effects.asm
index 2babf7f1..185b7dad 100644
--- a/engine/battle/effects.asm
+++ b/engine/battle/effects.asm
@@ -41,7 +41,7 @@ SleepEffect:
; including the event where the target already has another status
ld a, [de]
ld b, a
- and $7
+ and SLP_MASK
jr z, .notAlreadySleeping ; can't affect a mon that is already asleep
ld hl, AlreadyAsleepText
jp PrintText
@@ -58,7 +58,7 @@ SleepEffect:
.setSleepCounter
; set target's sleep counter to a random number between 1 and 7
call BattleRandom
- and $7
+ and SLP_MASK
jr z, .setSleepCounter
ld b, a
ld a, [wUnknownSerialFlag_d499]
@@ -250,7 +250,7 @@ FreezeBurnParalyzeEffect:
jr z, .burn1
cp FREEZE_SIDE_EFFECT1
jr z, .freeze1
-; .paralyze1
+; paralyze1
ld a, 1 << PAR
ld [wEnemyMonStatus], a
call QuarterSpeedDueToParalysis ; quarter speed of affected mon
@@ -313,7 +313,7 @@ FreezeBurnParalyzeEffect:
jr z, .burn2
cp FREEZE_SIDE_EFFECT1
jr z, .freeze2
-; .paralyze2
+; paralyze2
ld a, 1 << PAR
ld [wBattleMonStatus], a
call QuarterSpeedDueToParalysis
@@ -359,7 +359,7 @@ CheckDefrost:
ld [wEnemyMonStatus], a ; set opponent status to 00 ["defrost" a frozen monster]
ld hl, wEnemyMon1Status
ld a, [wEnemyMonPartyPos]
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
xor a
ld [hl], a ; clear status in roster
@@ -372,7 +372,7 @@ CheckDefrost:
ld [wBattleMonStatus], a
ld hl, wPartyMon1Status
ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
xor a
ld [hl], a
@@ -629,7 +629,7 @@ StatModifierDownEffect:
ld a, [de]
cp ATTACK_DOWN2_EFFECT - $16 ; $24
jr c, .ok
- cp EVASION_DOWN2_EFFECT + $5 ; $44
+ cp ATTACK_DOWN_SIDE_EFFECT ; move side effects, stat mod decrease is always 1
jr nc, .ok
dec b ; stat down 2 effects only (dec mod again)
jr nz, .ok
@@ -722,7 +722,7 @@ UpdateLoweredStatDone:
.ApplyBadgeBoostsAndStatusPenalties
ldh a, [hWhoseTurn]
and a
- call nz, ApplyBadgeStatBoosts ; whenever the player uses a stat-down move, badge boosts get reapplied again to every stat,
+ call nz, ApplyBadgeStatBoosts ; whenever the opponent uses a stat-down move, badge boosts get reapplied again to every stat,
; even to those not affected by the stat-down move (will be boosted further)
ld hl, MonsStatsFellText
call PrintText
@@ -747,7 +747,7 @@ CantLowerAnymore:
MoveMissed:
ld a, [de]
- cp $44
+ cp ATTACK_DOWN_SIDE_EFFECT
ret nc
jp ConditionalPrintButItFailed
@@ -790,7 +790,7 @@ PrintStatText:
jr .findStatName_inner
.foundStatName
ld de, wStringBuffer
- ld bc, $a
+ ld bc, STAT_NAME_LENGTH
jp CopyData
INCLUDE "data/battle/stat_mod_names.asm"
@@ -1377,7 +1377,7 @@ DisableEffect:
cp LINK_STATE_BATTLING
pop hl ; wEnemyMonMoves
jr nz, .playerTurnNotLinkBattle
-; .playerTurnLinkBattle
+; player's turn, Link Battle
push hl
ld hl, wEnemyMonPP
.enemyTurn
@@ -1512,6 +1512,7 @@ PlayCurrentMoveAnimation2:
.notEnemyTurn
and a
ret z
+; fallthrough
PlayBattleAnimation2:
; play animation ID at a and animation type 6 or 3
@@ -1538,6 +1539,7 @@ PlayCurrentMoveAnimation:
.notEnemyTurn
and a
ret z
+; fallthrough
PlayBattleAnimation:
; play animation ID at a and predefined animation type
diff --git a/engine/battle/end_of_battle.asm b/engine/battle/end_of_battle.asm
index 53946250..2ae3f71f 100644
--- a/engine/battle/end_of_battle.asm
+++ b/engine/battle/end_of_battle.asm
@@ -5,7 +5,7 @@ EndOfBattle:
; link battle
ld a, [wEnemyMonPartyPos]
ld hl, wEnemyMon1Status
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [wEnemyMonStatus]
ld [hl], a
@@ -64,8 +64,8 @@ EndOfBattle:
ld [hli], a
ld [hl], a
ld [wListScrollOffset], a
- ld hl, wPlayerStatsToDouble
- ld b, $18
+ ld hl, wBattleStatusData
+ ld b, wBattleStatusDataEnd - wBattleStatusData
.loop
ld [hli], a
dec b
diff --git a/engine/battle/experience.asm b/engine/battle/experience.asm
index 32afc017..55d8d782 100644
--- a/engine/battle/experience.asm
+++ b/engine/battle/experience.asm
@@ -21,7 +21,7 @@ GainExperience:
and a ; is mon's gain exp flag set?
pop hl
jp z, .nextMon ; if mon's gain exp flag not set, go to next mon
- ld de, (wPartyMon1HPExp + 1) - (wPartyMon1HP + 1)
+ ld de, (MON_HP_EXP + 1) - (MON_HP + 1)
add hl, de
ld d, h
ld e, l
@@ -66,9 +66,9 @@ GainExperience:
ldh [hDivisor], a
ld b, 4
call Divide
- ld hl, wPartyMon1OTID - (wPartyMon1DVs - 1)
+ ld hl, MON_OTID - (MON_DVS - 1)
add hl, de
- ld b, [hl] ; party mon OTID
+ ld b, [hl] ; wPartyMon*OTID
inc hl
ld a, [wPlayerID]
cp b
@@ -152,7 +152,7 @@ GainExperience:
ld [wMonDataLocation], a
call LoadMonData
pop hl
- ld bc, wPartyMon1Level - wPartyMon1Exp
+ ld bc, MON_LEVEL - MON_EXP
add hl, bc
push hl
farcall CalcLevelFromExperience
@@ -166,13 +166,13 @@ GainExperience:
ld a, d
ld [wCurEnemyLevel], a
ld [hl], a
- ld bc, wPartyMon1Species - wPartyMon1Level
+ ld bc, MON_SPECIES - MON_LEVEL
add hl, bc
ld a, [hl]
ld [wCurSpecies], a
ld [wPokedexNum], a
call GetMonHeader
- ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1Species
+ ld bc, (MON_MAXHP + 1) - MON_SPECIES
add hl, bc
push hl
ld a, [hld]
@@ -181,7 +181,7 @@ GainExperience:
push bc ; push max HP (from before levelling up)
ld d, h
ld e, l
- ld bc, (wPartyMon1HPExp - 1) - wPartyMon1MaxHP
+ ld bc, (MON_HP_EXP - 1) - MON_MAXHP
add hl, bc
ld b, $1 ; consider stat exp when calculating stats
call CalcStats
@@ -193,15 +193,15 @@ GainExperience:
ld a, [hl]
sbc b
ld b, a ; bc = difference between old max HP and new max HP after levelling
- ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
+ ld de, (MON_HP + 1) - MON_MAXHP
add hl, de
; add to the current HP the amount of max HP gained when levelling
- ld a, [hl] ; wPartyMon1HP + 1
+ ld a, [hl] ; wPartyMon*HP + 1
add c
ld [hld], a
- ld a, [hl] ; wPartyMon1HP + 1
+ ld a, [hl] ; wPartyMon*HP + 1
adc b
- ld [hl], a ; wPartyMon1HP
+ ld [hl], a ; wPartyMon*HP
ld a, [wPlayerMonNumber]
ld b, a
ld a, [wWhichPokemon]
@@ -216,7 +216,7 @@ GainExperience:
ld a, [hl]
ld [de], a
; copy other stats from party mon to battle mon
- ld bc, wPartyMon1Level - (wPartyMon1HP + 1)
+ ld bc, MON_LEVEL - (MON_HP + 1)
add hl, bc
push hl
ld de, wBattleMonLevel
@@ -251,7 +251,7 @@ GainExperience:
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
call LoadMonData
- ld d, $1
+ ld d, LEVEL_UP_STATS_BOX
callfar PrintStatsBox
call WaitForTextScrollButtonPress
call LoadScreenTilesFromBuffer1
@@ -277,7 +277,7 @@ GainExperience:
cp b
jr z, .done
ld [wWhichPokemon], a
- ld bc, wPartyMon2 - wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
ld hl, wPartyMon1
call AddNTimes
jp .partyMonLoop
diff --git a/engine/battle/get_trainer_name.asm b/engine/battle/get_trainer_name.asm
index a0e869fc..1983b08a 100644
--- a/engine/battle/get_trainer_name.asm
+++ b/engine/battle/get_trainer_name.asm
@@ -20,5 +20,5 @@ GetTrainerName_::
ld hl, wNameBuffer
.foundName
ld de, wTrainerName
- ld bc, ITEM_NAME_LENGTH
+ ld bc, TRAINER_NAME_LENGTH
jp CopyData
diff --git a/engine/battle/ghost_marowak_anim.asm b/engine/battle/ghost_marowak_anim.asm
index 6514ccaa..ab5f9017 100644
--- a/engine/battle/ghost_marowak_anim.asm
+++ b/engine/battle/ghost_marowak_anim.asm
@@ -51,11 +51,11 @@ MarowakAnim:
call Delay3
jp ClearSprites
-; copies a mon pic's from background VRAM to sprite VRAM and sets up OAM
+; copies a mon pic's from background VRAM to sprite VRAM and sets up OAM
CopyMonPicFromBGToSpriteVRAM:
ld de, vFrontPic
ld hl, vSprites
- ld bc, 7 * 7
+ ld bc, PIC_SIZE
call CopyVideoData
ld a, $10
ld [wBaseCoordY], a
diff --git a/engine/battle/init_battle.asm b/engine/battle/init_battle.asm
index a291880c..15dbb3d1 100644
--- a/engine/battle/init_battle.asm
+++ b/engine/battle/init_battle.asm
@@ -76,17 +76,7 @@ InitWildBattle:
ld [hli], a ; write front sprite pointer
ld [hl], b
ld hl, wEnemyMonNick ; set name to "GHOST"
- ld a, 'G'
- ld [hli], a
- ld a, 'H'
- ld [hli], a
- ld a, 'O'
- ld [hli], a
- ld a, 'S'
- ld [hli], a
- ld a, 'T'
- ld [hli], a
- ld [hl], '@'
+ ld_hli_a_string "GHOST@"
ld a, [wCurPartySpecies]
push af
ld a, MON_GHOST
diff --git a/engine/battle/link_battle_versus_text.asm b/engine/battle/link_battle_versus_text.asm
index e5dd42ea..40c1aad9 100644
--- a/engine/battle/link_battle_versus_text.asm
+++ b/engine/battle/link_battle_versus_text.asm
@@ -12,9 +12,7 @@ DisplayLinkBattleVersusTextBox:
call PlaceString
; place bold "VS" tiles between the names
hlcoord 9, 8
- ld a, '<BOLD_V>'
- ld [hli], a
- ld [hl], '<BOLD_S>'
+ ld_hli_a_string "<BOLD_V><BOLD_S>"
xor a
ld [wUpdateSpritesEnabled], a
callfar SetupPlayerAndEnemyPokeballs
diff --git a/engine/battle/move_effects/haze.asm b/engine/battle/move_effects/haze.asm
index 76722d0e..0f89ad19 100644
--- a/engine/battle/move_effects/haze.asm
+++ b/engine/battle/move_effects/haze.asm
@@ -59,7 +59,7 @@ CureVolatileStatuses:
ret
ResetStatMods:
- ld b, $8
+ ld b, NUM_STAT_MODS
.loop
ld [hli], a
dec b
@@ -67,7 +67,7 @@ ResetStatMods:
ret
ResetStats:
- ld b, $8
+ ld b, (NUM_STATS - 1) * 2 ; doesn't reset STAT_HEALTH
.loop
ld a, [hli]
ld [de], a
diff --git a/engine/battle/move_effects/substitute.asm b/engine/battle/move_effects/substitute.asm
index e4311209..01d5a8a3 100644
--- a/engine/battle/move_effects/substitute.asm
+++ b/engine/battle/move_effects/substitute.asm
@@ -37,8 +37,8 @@ SubstituteEffect_:
sbc 0
pop bc
jr c, .notEnoughHP ; underflow means user would be left with negative health
- ; bug: since it only branches on carry, it will possibly leave user with 0 HP
-.userHasZeroOrMoreHP
+ ; bug: since it only branches on carry, it will possibly leave user with 0 HP
+; user has 0 or more HP
ld [hli], a ; save resulting HP after subtraction into current HP
ld [hl], d
ld h, b
diff --git a/engine/battle/move_effects/transform.asm b/engine/battle/move_effects/transform.asm
index 775816c7..e8bafe04 100644
--- a/engine/battle/move_effects/transform.asm
+++ b/engine/battle/move_effects/transform.asm
@@ -2,17 +2,22 @@ TransformEffect_:
ld hl, wBattleMonSpecies
ld de, wEnemyMonSpecies
ld bc, wEnemyBattleStatus3
+ ; bug: on enemy's turn, a is overloaded with hWhoseTurn,
+ ; before the check for INVULNERABLE
ld a, [wEnemyBattleStatus1]
ldh a, [hWhoseTurn]
and a
jr nz, .hitTest
+; player's turn
ld hl, wEnemyMonSpecies
ld de, wBattleMonSpecies
ld bc, wPlayerBattleStatus3
ld [wPlayerMoveListIndex], a
+ ; bug: this should be target's BattleStatus1 (i.e. wEnemyBattleStatus1)
ld a, [wPlayerBattleStatus1]
.hitTest
bit INVULNERABLE, a ; is mon invulnerable to typical attacks? (fly/dig)
+ ; this check doesn't work due to above bugs
jp nz, .failed
push hl
push de
@@ -82,14 +87,15 @@ TransformEffect_:
ld a, [hli]
ld [de], a
inc de
-; Attack, Defense, Speed, and Special stats
+; Skip level and max HP
inc hl
inc hl
inc hl
inc de
inc de
inc de
- ld bc, $8
+; Attack, Defense, Speed, and Special stats
+ ld bc, (NUM_STATS - 1) * 2
call CopyData
ld bc, wBattleMonMoves - wBattleMonPP
add hl, bc ; ld hl, wBattleMonMoves
@@ -99,7 +105,7 @@ TransformEffect_:
ld a, [hli]
and a
jr z, .lessThanFourMoves
- ld a, $5
+ ld a, 5
.lessThanFourMoves
ld [de], a
inc de
@@ -129,7 +135,7 @@ TransformEffect_:
ld l, e
pop de
.gotStatsOrModsToCopy
- ld bc, $8
+ ld bc, (NUM_STATS - 1) * 2
jp CopyData
.failed
diff --git a/engine/battle/read_trainer_party.asm b/engine/battle/read_trainer_party.asm
index c8ee8fda..f4a2bef9 100644
--- a/engine/battle/read_trainer_party.asm
+++ b/engine/battle/read_trainer_party.asm
@@ -103,7 +103,7 @@ ReadTrainer:
jp z, .FinishUp
dec a
ld hl, wEnemyMon1Moves
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [de]
inc de
diff --git a/engine/battle/trainer_ai.asm b/engine/battle/trainer_ai.asm
index 7081fdfd..d97ee076 100644
--- a/engine/battle/trainer_ai.asm
+++ b/engine/battle/trainer_ai.asm
@@ -578,7 +578,7 @@ AISwitchIfEnoughMons:
inc d
.Fainted
push bc
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
add hl, bc
pop bc
dec c
@@ -592,16 +592,16 @@ AISwitchIfEnoughMons:
SwitchEnemyMon:
-; prepare to withdraw the active monster: copy hp, number, and status to roster
+; prepare to withdraw the active monster: copy HP, party pos, and status to roster
ld a, [wEnemyMonPartyPos]
ld hl, wEnemyMon1HP
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld d, h
ld e, l
ld hl, wEnemyMonHP
- ld bc, 4
+ ld bc, MON_STATUS + 1 - MON_HP ; also copies party pos in-between HP and status
call CopyData
ld hl, AIBattleWithdrawText
@@ -635,7 +635,7 @@ AICureStatus:
; cures the status of enemy's active pokemon
ld a, [wEnemyMonPartyPos]
ld hl, wEnemyMon1Status
- ld bc, wEnemyMon2 - wEnemyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
xor a
ld [hl], a ; clear status in enemy team roster
diff --git a/engine/battle/used_move_text.asm b/engine/battle/used_move_text.asm
new file mode 100644
index 00000000..abb35e67
--- /dev/null
+++ b/engine/battle/used_move_text.asm
@@ -0,0 +1,139 @@
+DisplayUsedMoveText:
+ ld hl, UsedMoveText
+ jp PrintText
+
+UsedMoveText:
+ text_far _ActorNameText
+ text_asm
+
+ ldh a, [hWhoseTurn]
+ and a
+ ld a, [wPlayerMoveNum]
+ ld hl, wPlayerUsedMove
+ jr z, .playerTurn
+
+ ld a, [wEnemyMoveNum]
+ ld hl, wEnemyUsedMove
+
+.playerTurn
+ ld [hl], a
+ ld [wMoveGrammar], a
+ call GetMoveGrammar
+ ld a, [wMonIsDisobedient]
+ and a
+ ld hl, UsedMove2Text
+ ret nz
+
+ ; check move grammar
+ ld a, [wMoveGrammar]
+ cp $3
+ ld hl, UsedMove2Text
+ ret c
+ ld hl, UsedMove1Text
+ ret
+
+UsedMove1Text:
+ text_far _UsedMove1Text
+ text_asm
+ jr UsedMoveText_CheckObedience
+
+UsedMove2Text:
+ text_far _UsedMove2Text
+ text_asm
+ ; fall through
+
+UsedMoveText_CheckObedience:
+; check obedience
+ ld a, [wMonIsDisobedient]
+ and a
+ jr z, .GetMoveNameText
+; print "instead,"
+ ld hl, .UsedInsteadText
+ ret
+
+.UsedInsteadText:
+ text_far _UsedInsteadText
+ text_asm
+ ; fall through
+
+.GetMoveNameText:
+ ld hl, MoveNameText
+ ret
+
+MoveNameText:
+ text_far _MoveNameText
+ text_asm
+ ld hl, .endusedmovetexts
+ ld a, [wMoveGrammar]
+ add a
+ push bc
+ ld b, $0
+ ld c, a
+ add hl, bc
+ pop bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+.endusedmovetexts:
+; entries correspond to MoveGrammar sets
+ dw EndUsedMove1Text
+ dw EndUsedMove2Text
+ dw EndUsedMove3Text
+ dw EndUsedMove4Text
+ dw EndUsedMove5Text
+
+EndUsedMove1Text:
+ text_far _EndUsedMove1Text
+ text_end
+
+EndUsedMove2Text:
+ text_far _EndUsedMove2Text
+ text_end
+
+EndUsedMove3Text:
+ text_far _EndUsedMove3Text
+ text_end
+
+EndUsedMove4Text:
+ text_far _EndUsedMove4Text
+ text_end
+
+EndUsedMove5Text:
+ text_far _EndUsedMove5Text
+ text_end
+
+; This function is redundant in the English localization.
+; In Japanese, it selects one of 5 distinct sentence structures.
+; In English, all of these sentences have the exact same structure,
+; so this serves no purpose.
+GetMoveGrammar:
+ push bc
+ ld a, [wMoveGrammar] ; move ID
+ ld c, a
+ ld b, $0
+ ld hl, MoveGrammar
+.loop
+ ld a, [hli]
+; end of table?
+ cp -1
+ jr z, .end
+; match?
+ cp c
+ jr z, .end
+; advance grammar type at 0
+ and a
+ jr nz, .loop
+; next grammar type
+ inc b
+ jr .loop
+
+.end
+; wMoveGrammar now contains move grammar
+ ld a, b
+ ld [wMoveGrammar], a
+ pop bc
+ ret
+
+INCLUDE "data/moves/grammar.asm"