diff options
-rw-r--r-- | constants/predef_constants.asm | 2 | ||||
-rwxr-xr-x | engine/battle/core.asm | 66 | ||||
-rw-r--r-- | engine/battle/core_.asm | 1255 | ||||
-rw-r--r-- | engine/battle/moveEffects/drain_hp_effect.asm | 2 | ||||
-rw-r--r-- | engine/battle/moveEffects/reflect_light_screen_effect.asm | 2 | ||||
-rwxr-xr-x | engine/items/items.asm | 4 | ||||
-rwxr-xr-x | wram.asm | 2 |
7 files changed, 1282 insertions, 51 deletions
diff --git a/constants/predef_constants.asm b/constants/predef_constants.asm index 2f1834d5..6c64962b 100644 --- a/constants/predef_constants.asm +++ b/constants/predef_constants.asm @@ -36,7 +36,7 @@ const_value = 0 predef_const Func_480ff predef_const CalcPositionOfPlayerRelativeToNPC predef_const ConvertNPCMovementDirectionsToJoypadMasks - predef_const Func_48125 + predef_const PredefShakeScreenHorizontally predef_const UpdateHPBar predef_const HPBarLength predef_const Diploma_TextBoxBorder diff --git a/engine/battle/core.asm b/engine/battle/core.asm index b6d6ace0..0efb7ac2 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -3308,7 +3308,7 @@ ExecutePlayerMove: ; 3d65e (f:565e) jp z, ExecutePlayerMoveDone CheckIfPlayerNeedsToChargeUp: ; 3d69a (f:569a) - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] cp CHARGE_EFFECT jp z, JumpMoveEffect cp FLY_EFFECT @@ -3328,19 +3328,19 @@ PlayerCanExecuteMove: ; 3d6b0 (f:56b0) ld de,wPlayerSelectedMove ; pointer to the move just used ld b,BANK(DecrementPP) call Bankswitch - ld a,[W_PLAYERMOVEEFFECT] ; effect of the move just used + ld a,[wPlayerMoveEffect] ; effect of the move just used ld hl,ResidualEffects1 ld de,1 call IsInArray jp c,JumpMoveEffect ; ResidualEffects1 moves skip damage calculation and accuracy tests ; unless executed as part of their exclusive effect functions - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] ld hl,SpecialEffectsCont ld de,1 call IsInArray call c,JumpMoveEffect ; execute the effects of SpecialEffectsCont moves (e.g. Wrap, Thrash) but don't skip anything PlayerCalcMoveDamage: ; 3d6dc (f:56dc) - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] ld hl,SetDamageEffects ld de,1 call IsInArray @@ -3360,12 +3360,12 @@ handleIfPlayerMoveMissed ld a,[wMoveMissed] and a jr z,getPlayerAnimationType - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] sub a,EXPLODE_EFFECT jr z,playPlayerMoveAnimation ; don't play any animation if the move missed, unless it was EXPLODE_EFFECT jr playerCheckIfFlyOrChargeEffect getPlayerAnimationType - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] and a ld a,4 ; move has no effect other than dealing damage jr z,playPlayerMoveAnimation @@ -3392,7 +3392,7 @@ playPlayerMoveAnimation playerCheckIfFlyOrChargeEffect ld c,30 call DelayFrames - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] cp a,FLY_EFFECT jr z,.playAnim cp a,CHARGE_EFFECT @@ -3404,7 +3404,7 @@ playerCheckIfFlyOrChargeEffect ld a,STATUS_AFFECTED_ANIM call PlayMoveAnimation MirrorMoveCheck - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] cp a,MIRROR_MOVE_EFFECT jr nz,.metronomeCheck call MirrorMoveCopyMove @@ -3418,7 +3418,7 @@ MirrorMoveCheck call MetronomePickMove jp CheckIfPlayerNeedsToChargeUp ; Go back to damage calculation for the move picked by Metronome .next - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] ld hl,ResidualEffects2 ld de,1 call IsInArray @@ -3427,7 +3427,7 @@ MirrorMoveCheck and a jr z,.moveDidNotMiss call PrintMoveFailureText - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] cp a,EXPLODE_EFFECT ; even if Explosion or Selfdestruct missed, its effect still needs to be activated jr z,.notDone jp ExecutePlayerMoveDone ; otherwise, we're done if the move missed @@ -3438,7 +3438,7 @@ MirrorMoveCheck ld a,1 ld [wMoveDidntMiss],a .notDone - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] ld hl,AlwaysHappenSideEffects ld de,1 call IsInArray @@ -3464,7 +3464,7 @@ MirrorMoveCheck xor a ld [wPlayerNumHits],a .executeOtherEffects - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] and a jp z,ExecutePlayerMoveDone ld hl,SpecialEffects @@ -3670,7 +3670,7 @@ CheckPlayerStatusConditions: ; 3d854 (f:5854) ; clear bide, thrashing, charging up, and trapping moves such as warp (already cleared for confusion damage) and $ff ^ ((1 << StoringEnergy) | (1 << ThrashingAbout) | (1 << ChargingUp) | (1 << UsingTrappingMove)) ld [hl],a - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] cp a,FLY_EFFECT jr z,.FlyOrChargeEffect cp a,CHARGE_EFFECT @@ -3781,7 +3781,7 @@ CheckPlayerStatusConditions: ; 3d854 (f:5854) call GetMoveName call CopyStringToCF4B xor a - ld [W_PLAYERMOVEEFFECT], a + ld [wPlayerMoveEffect], a ld hl, PlayerCanExecuteMove jp .returnToHL @@ -3888,7 +3888,7 @@ HandleSelfConfusionDamage: ; 3daad (f:5aad) ld [hli], a ld a, [wBattleMonDefense + 1] ld [hl], a - ld hl, W_PLAYERMOVEEFFECT + ld hl, wPlayerMoveEffect push hl ld a, [hl] push af @@ -4068,7 +4068,7 @@ ExclamationPointMoveSets: ; 3dba3 (f:5ba3) db $FF ; terminator PrintMoveFailureText: ; 3dbe2 (f:5be2) - ld de, W_PLAYERMOVEEFFECT + ld de, wPlayerMoveEffect ld a, [H_WHOSETURN] and a jr z, .playersTurn @@ -4657,7 +4657,7 @@ CalculateDamage: ; 3df65 (f:5f65) ld a, [H_WHOSETURN] ; whose turn? and a - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] jr z, .effect ld a, [wEnemyMoveEffect] .effect @@ -4970,7 +4970,7 @@ HandleCounterMove: ; 3e093 (f:6093) ret ApplyAttackToEnemyPokemon: ; 3e0df (f:60df) - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] cp a,OHKO_EFFECT jr z,ApplyDamageToEnemyPokemon cp a,SUPER_FANG_EFFECT @@ -5252,7 +5252,7 @@ AttackSubstitute: ; 3e25e (f:625e) ld a,[H_WHOSETURN] xor a,$01 ld [H_WHOSETURN],a - ld hl,W_PLAYERMOVEEFFECT ; value for player's turn + ld hl,wPlayerMoveEffect ; value for player's turn and a jr z,.nullifyEffect ld hl,wEnemyMoveEffect ; value for enemy's turn @@ -5588,7 +5588,7 @@ INCLUDE "data/type_effects.asm" MoveHitTest: ; 3e56b (f:656b) ; player's turn ld hl,wEnemyBattleStatus1 - ld de,W_PLAYERMOVEEFFECT + ld de,wPlayerMoveEffect ld bc,wEnemyMonStatus ld a,[H_WHOSETURN] and a @@ -5624,7 +5624,7 @@ MoveHitTest: ; 3e56b (f:656b) jr nz,.enemyTurn .playerTurn ; this checks if the move effect is disallowed by mist - ld a,[W_PLAYERMOVEEFFECT] + ld a,[wPlayerMoveEffect] cp a,ATTACK_DOWN1_EFFECT jr c,.skipEnemyMistCheck cp a,HAZE_EFFECT + 1 @@ -6998,7 +6998,7 @@ JumpMoveEffect: ; 3f132 (f:7132) _JumpMoveEffect: ; 3f138 (f:7138) ld a, [H_WHOSETURN] and a - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] jr z, .next1 ld a, [wEnemyMoveEffect] .next1 @@ -7155,7 +7155,7 @@ AlreadyAsleepText: ; 3f24a (f:724a) PoisonEffect: ; 3f24f (f:724f) ld hl, wEnemyMonStatus - ld de, W_PLAYERMOVEEFFECT + ld de, wPlayerMoveEffect ld a, [H_WHOSETURN] and a jr z, .poisonEffect @@ -7288,7 +7288,7 @@ FreezeBurnParalyzeEffect: ; 3f30c (f:730c) ld a, [wEnemyMonType2] cp b ; do target type 2 and move type match? ret z ; return if they match - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] cp a, PARALYZE_SIDE_EFFECT1 + 1 ; 10% status effects are 04, 05, 06 so 07 will set carry for those ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance jr c, .next1 ; branch ahead if this is a 10% chance effect.. @@ -7423,7 +7423,7 @@ FireDefrostedText: ; 3f423 (f:7423) StatModifierUpEffect: ; 3f428 (f:7428) ld hl, wPlayerMonStatMods - ld de, W_PLAYERMOVEEFFECT + ld de, wPlayerMoveEffect ld a, [H_WHOSETURN] and a jr z, .statModifierUpEffect @@ -7591,7 +7591,7 @@ MonsStatsRoseText: ; 3f528 (f:7528) ld hl, GreatlyRoseText ld a, [H_WHOSETURN] and a - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] jr z, .asm_3f53b ld a, [wEnemyMoveEffect] .asm_3f53b @@ -7610,7 +7610,7 @@ RoseText: ; 3f547 (f:7547) StatModifierDownEffect: ; 3f54c (f:754c) ld hl, wEnemyMonStatMods - ld de, W_PLAYERMOVEEFFECT + ld de, wPlayerMoveEffect ld bc, wEnemyBattleStatus1 ld a, [H_WHOSETURN] and a @@ -7793,7 +7793,7 @@ MonsStatsFellText: ; 3f661 (f:7661) ld hl, FellText ld a, [H_WHOSETURN] and a - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] jr z, .asm_3f674 ld a, [wEnemyMoveEffect] .asm_3f674 @@ -7868,7 +7868,7 @@ BideEffect: ; 3f6e5 (f:76e5) ld [de], a inc de ld [de], a - ld [W_PLAYERMOVEEFFECT], a + ld [wPlayerMoveEffect], a ld [wEnemyMoveEffect], a call BattleRandom and $1 @@ -8027,7 +8027,7 @@ TwoToFiveAttacksEffect: ; 3f811 (f:7811) bit AttackingMultipleTimes, [hl] ; is mon attacking multiple times? ret nz set AttackingMultipleTimes, [hl] ; mon is now attacking multiple times - ld hl, W_PLAYERMOVEEFFECT + ld hl, wPlayerMoveEffect ld a, [H_WHOSETURN] and a jr z, .setNumberOfHits @@ -8062,7 +8062,7 @@ FlinchSideEffect: ; 3f85b (f:785b) call CheckTargetSubstitute ret nz ld hl, wEnemyBattleStatus1 - ld de, W_PLAYERMOVEEFFECT + ld de, wPlayerMoveEffect ld a, [H_WHOSETURN] and a jr z, .flinchSideEffect @@ -8087,7 +8087,7 @@ OneHitKOEffect: ; 3f884 (f:7884) ChargeEffect: ; 3f88c (f:788c) ld hl, wPlayerBattleStatus1 - ld de, W_PLAYERMOVEEFFECT + ld de, wPlayerMoveEffect ld a, [H_WHOSETURN] and a ld b, XSTATITEM_ANIM @@ -8220,7 +8220,7 @@ ConfusionSideEffectSuccess: ; 3f96f (f:796f) and a ld hl, wEnemyBattleStatus1 ld bc, W_ENEMYCONFUSEDCOUNTER - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] jr z, .confuseTarget ld hl, wPlayerBattleStatus1 ld bc, W_PLAYERCONFUSEDCOUNTER diff --git a/engine/battle/core_.asm b/engine/battle/core_.asm index fecfad07..997a1c0c 100644 --- a/engine/battle/core_.asm +++ b/engine/battle/core_.asm @@ -2943,22 +2943,1245 @@ Func_3d536: ; 3d536 (f:5536) jp PlaceString AnyMoveToSelect: ; 3d55f (f:555f) - dr $3d55f,$3d5a0 +; return z and Struggle as the selected move if all moves have 0 PP and/or are disabled + ld a, STRUGGLE + ld [wPlayerSelectedMove], a + ld a, [wPlayerDisabledMove] + and a + ld hl, wBattleMonPP + jr nz, .handleDisabledMove + ld a, [hli] + or [hl] + inc hl + or [hl] + inc hl + or [hl] + and $3f + ret nz + jr .noMovesLeft +.handleDisabledMove + swap a + and $f ; get move disabled + ld b, a + ld d, NUM_MOVES + 1 + xor a +.handleDisabledMovePPLoop + dec d + jr z, .allMovesChecked + ld c, [hl] ; get move PP + inc hl + dec b ; is this the disabled move? + jr z, .handleDisabledMovePPLoop ; if so, ignore its PP value + or c + jr .handleDisabledMovePPLoop +.allMovesChecked +; bugfix: only check PP value and not PP up bits +; in case all other moves have no PP left and a move has a PP up used on it +; and a non-PP up move is disabled + and $3f ; any PP left? + ret nz ; return if a move has PP left +.noMovesLeft + ld hl, NoMovesLeftText + call PrintText + ld c, 60 + call DelayFrames + xor a + ret + +NoMovesLeftText: ; 3d59b (f:559b) + TX_FAR _NoMovesLeftText + db "@" + SwapMovesInMenu: ; 3d5a0 (f:55a0) - dr $3d5a0,$3d629 + ld a, [wPlayerBattleStatus3] + bit Transformed, a + jp nz, MoveSelectionMenu + ld a, [wMenuItemToSwap] + and a + jr z, .noMenuItemSelected + ld hl, wBattleMonMoves + call .swapBytes ; swap moves + ld hl, wBattleMonPP + call .swapBytes ; swap move PP +; update the index of the disabled move if necessary + ld hl, wPlayerDisabledMove + ld a, [hl] + swap a + and $f + ld b, a + ld a, [wCurrentMenuItem] + cp b + jr nz, .next + ld a, [hl] + and $f + ld b, a + ld a, [wMenuItemToSwap] + swap a + add b + ld [hl], a + jr .swapMovesInPartyMon +.next + ld a, [wMenuItemToSwap] + cp b + jr nz, .swapMovesInPartyMon + ld a, [hl] + and $f + ld b, a + ld a, [wCurrentMenuItem] + swap a + add b + ld [hl], a +.swapMovesInPartyMon + ld hl, wPartyMon1Moves + ld a, [wPlayerMonNumber] + ld bc, wPartyMon2 - wPartyMon1 + call AddNTimes + push hl + call .swapBytes ; swap moves + pop hl + ld bc, wPartyMon1PP - wPartyMon1Moves + add hl, bc + call .swapBytes ; swap move PP + xor a + ld [wMenuItemToSwap], a ; deselect the item + jp MoveSelectionMenu +.swapBytes + push hl + ld a, [wMenuItemToSwap] + dec a + ld c, a + ld b, 0 + add hl, bc + ld d, h + ld e, l + pop hl + ld a, [wCurrentMenuItem] + dec a + ld c, a + ld b, 0 + add hl, bc + ld a, [de] + ld b, [hl] + ld [hl], a + ld a, b + ld [de], a + ret +.noMenuItemSelected + ld a, [wCurrentMenuItem] + ld [wMenuItemToSwap], a ; select the current menu item for swapping + jp MoveSelectionMenu + PrintMenuItem: ; 3d629 (f:5629) - dr $3d629,$3d6d6 + xor a + ld [H_AUTOBGTRANSFERENABLED], a + coord hl, 0, 8 + lb bc, 3, 9 + call TextBoxBorder + ld a, [wPlayerDisabledMove] + and a + jr z, .notDisabled + swap a + and $f + ld b, a + ld a, [wCurrentMenuItem] + cp b + jr nz, .notDisabled + coord hl, 1, 10 + ld de, DisabledText + call PlaceString + jr .moveDisabled +.notDisabled + ld hl, wCurrentMenuItem + dec [hl] + xor a + ld [H_WHOSETURN], a + ld hl, wBattleMonMoves + ld a, [wCurrentMenuItem] + ld c, a + ld b, $0 ; which item in the menu is the cursor pointing to? (0-3) + add hl, bc ; point to the item (move) in memory + ld a, [hl] + ld [wPlayerSelectedMove], a ; update wPlayerSelectedMove even if the move + ; isn't actually selected (just pointed to by the cursor) + ld a, [wPlayerMonNumber] + ld [wWhichPokemon], a + ld a, BATTLE_MON_DATA + ld [wMonDataLocation], a + callab GetMaxPP + ld hl, wCurrentMenuItem + ld c, [hl] + inc [hl] + ld b, $0 + ld hl, wBattleMonPP + add hl, bc + ld a, [hl] + and $3f + ld [wcd6d], a +; print TYPE/<type> and <curPP>/<maxPP> + coord hl, 1, 9 + ld de, TypeText + call PlaceString + coord hl, 7, 11 + ld [hl], "/" + coord hl, 5, 9 + ld [hl], "/" + coord hl, 5, 11 + ld de, wcd6d + lb bc, 1, 2 + call PrintNumber + coord hl, 8, 11 + ld de, wMaxPP + lb bc, 1, 2 + call PrintNumber + call GetCurrentMove + coord hl, 2, 10 + predef PrintMoveType +.moveDisabled + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a + jp Delay3 + +DisabledText: ; 3d6c7 (f:56c7) + db "Disabled!@" + +TypeText: ; 3d6d1 (f:56d1) + db "TYPE@" + SelectEnemyMove: ; 3d6d6 (f:56d6) - dr $3d6d6,$3d777 + ld a, [wLinkState] + sub LINK_STATE_BATTLING + jr nz, .noLinkBattle +; link battle + call SaveScreenTilesToBuffer1 + call LinkBattleExchangeData + call LoadScreenTilesFromBuffer1 + ld a, [wSerialExchangeNybbleReceiveData] + cp $e + jp z, .linkedOpponentUsedStruggle + cp $d + jr z, .unableToSelectMove + cp $4 + ret nc + ld [wEnemyMoveListIndex], a + ld c, a + ld hl, wEnemyMonMoves + ld b, $0 + add hl, bc + ld a, [hl] + jr .done +.noLinkBattle + ld a, [wEnemyBattleStatus2] + and (1 << NeedsToRecharge) | (1 << UsingRage) ; need to recharge or using rage + ret nz + ld hl, wEnemyBattleStatus1 + ld a, [hl] + and (1 << ChargingUp) | (1 << ThrashingAbout) ; using a charging move or thrash/petal dance + ret nz + ld a, [wEnemyMonStatus] + and SLP | 1 << FRZ ; sleeping or frozen + ret nz + ld a, [wEnemyBattleStatus1] + and (1 << UsingTrappingMove) | (1 << StoringEnergy) ; using a trapping move like wrap or bide + ret nz + ld a, [wPlayerBattleStatus1] + bit UsingTrappingMove, a ; caught in player's trapping move (e.g. wrap) + jr z, .canSelectMove +.unableToSelectMove + ld a, $ff + jr .done +.canSelectMove + ld hl, wEnemyMonMoves+1 ; 2nd enemy move + ld a, [hld] + and a + jr nz, .atLeastTwoMovesAvailable + ld a, [wEnemyDisabledMove] + and a + ld a, STRUGGLE ; struggle if the only move is disabled + jr nz, .done +.atLeastTwoMovesAvailable + ld a, [wIsInBattle] + dec a + jr z, .chooseRandomMove ; wild encounter + callab AIEnemyTrainerChooseMoves +.chooseRandomMove + push hl + call BattleRandom + ld b, $1 + cp $3f ; select move 1, [0,3e] (63/256 chance) + jr c, .moveChosen + inc hl + inc b + cp $7f ; select move 2, [3f,7e] (64/256 chance) + jr c, .moveChosen + inc hl + inc b + cp $be ; select move 3, [7f,bd] (63/256 chance) + jr c, .moveChosen + inc hl + inc b ; select move 4, [be,ff] (66/256 chance) +.moveChosen + ld a, b + dec a + ld [wEnemyMoveListIndex], a + ld a, [wEnemyDisabledMove] + swap a + and $f + cp b + ld a, [hl] + pop hl + jr z, .chooseRandomMove ; move disabled, try again + and a + jr z, .chooseRandomMove ; move non-existant, try again +.done + ld [wEnemySelectedMove], a + ret +.linkedOpponentUsedStruggle + ld a, STRUGGLE + jr .done + +; this appears to exchange data with the other gameboy during link battles LinkBattleExchangeData: ; 3d777 (f:5777) - dr $3d777,$3d7d0 + ld a, $ff + ld [wSerialExchangeNybbleReceiveData], a + ld a, [wPlayerMoveListIndex] + cp $f ; is the player running from battle? + jr z, .doExchange + ld a, [wActionResultOrTookBattleTurn] + and a ; is the player switching in another mon? + jr nz, .switching +; the player used a move + ld a, [wPlayerSelectedMove] + cp STRUGGLE + ld b, $e + jr z, .next + dec b + inc a + jr z, .next + ld a, [wPlayerMoveListIndex] + jr .doExchange +.switching + ld a, [wWhichPokemon] + add 4 + ld b, a +.next + ld a, b +.doExchange + ld [wSerialExchangeNybbleSendData], a + callab PrintWaitingText +.syncLoop1 + call Serial_ExchangeNybble + call DelayFrame + ld a, [wSerialExchangeNybbleReceiveData] + inc a + jr z, .syncLoop1 + ld b, 10 +.syncLoop2 + call DelayFrame + call Serial_ExchangeNybble + dec b + jr nz, .syncLoop2 + ld b, 10 +.syncLoop3 + call DelayFrame + call Serial_SendZeroByte + dec b + jr nz, .syncLoop3 + ret + ExecutePlayerMove: ; 3d7d0 (f:57d0) - dr $3d7d0,$3d9ac + xor a + ld [H_WHOSETURN], a ; set player's turn + ld a, [wPlayerSelectedMove] + inc a + jp z, ExecutePlayerMoveDone ; for selected move = FF, skip most of player's turn + xor a + ld [wMoveMissed], a + ld [wMonIsDisobedient], a + ld [wMoveDidntMiss], a + ld a, $a + ld [wDamageMultipliers], a + ld a, [wActionResultOrTookBattleTurn] + and a ; has the player already used the turn (e.g. by using an item, trying to run or switching pokemon) + jp nz, ExecutePlayerMoveDone + call PrintGhostText + jp z, ExecutePlayerMoveDone + call CheckPlayerStatusConditions + jr nz, .playerHasNoSpecialCondition + jp [hl] +.playerHasNoSpecialCondition + call GetCurrentMove + ld hl, wPlayerBattleStatus1 + bit ChargingUp, [hl] ; charging up for attack + jr nz, PlayerCanExecuteChargingMove + call CheckForDisobedience + jp z, ExecutePlayerMoveDone + +CheckIfPlayerNeedsToChargeUp: ; 3d80c (f:580c) + ld a, [wPlayerMoveEffect] + cp CHARGE_EFFECT + jp z, JumpMoveEffect + cp FLY_EFFECT + jp z, JumpMoveEffect + jr PlayerCanExecuteMove + +; in-battle stuff +PlayerCanExecuteChargingMove: ; 3d81b (f:581b) + ld hl,wPlayerBattleStatus1 + res ChargingUp,[hl] ; reset charging up and invulnerability statuses if mon was charging up for an attack + ; being fully paralyzed or hurting oneself in confusion removes charging up status + ; resulting in the Pokemon being invulnerable for the whole battle + res Invulnerable,[hl] +PlayerCanExecuteMove: ; 3d822 (f:5822) + call PrintMonName1Text + ld hl,DecrementPP + ld de,wPlayerSelectedMove ; pointer to the move just used + ld b,BANK(DecrementPP) + call Bankswitch + ld a,[wPlayerMoveEffect] ; effect of the move just used + ld hl,ResidualEffects1 + ld de,1 + call IsInArray + jp c,JumpMoveEffect ; ResidualEffects1 moves skip damage calculation and accuracy tests + ; unless executed as part of their exclusive effect functions + ld a,[wPlayerMoveEffect] + ld hl,SpecialEffectsCont + ld de,1 + call IsInArray + call c,JumpMoveEffect ; execute the effects of SpecialEffectsCont moves (e.g. Wrap, Thrash) but don't skip anything +PlayerCalcMoveDamage: ; 3d84e (f:584e) + ld a,[wPlayerMoveEffect] + ld hl,SetDamageEffects + ld de,1 + call IsInArray + jp c,.moveHitTest ; SetDamageEffects moves (e.g. Seismic Toss and Super Fang) skip damage calculation + call CriticalHitTest + call HandleCounterMove + jr z,handleIfPlayerMoveMissed + call GetDamageVarsForPlayerAttack + call CalculateDamage + jp z,playerCheckIfFlyOrChargeEffect ; for moves with 0 BP, skip any further damage calculation and, for now, skip MoveHitTest + ; for these moves, accuracy tests will only occur if they are called as part of the effect itself + call AdjustDamageForMoveType + call RandomizeDamage +.moveHitTest + call MoveHitTest +handleIfPlayerMoveMissed: ; 3d877 (f:5877) + ld a,[wMoveMissed] + and a + jr z,getPlayerAnimationType + ld a,[wPlayerMoveEffect] + sub a,EXPLODE_EFFECT + jr z,playPlayerMoveAnimation ; don't play any animation if the move missed, unless it was EXPLODE_EFFECT + jr playerCheckIfFlyOrChargeEffect +getPlayerAnimationType: ; 3d87b (f:587b) + ld a,[wPlayerMoveEffect] + and a + ld a,4 ; move has no effect other than dealing damage + jr z,playPlayerMoveAnimation + ld a,5 ; move has effect +playPlayerMoveAnimation ; 3d890 (f:5890) + push af + ld a,[wPlayerBattleStatus2] + bit HasSubstituteUp,a + ld hl,HideSubstituteShowMonAnim + ld b,BANK(HideSubstituteShowMonAnim) + call nz,Bankswitch + pop af + ld [wAnimationType],a + ld a,[W_PLAYERMOVENUM] + call PlayMoveAnimation + call HandleExplodingAnimation + call DrawPlayerHUDAndHPBar + ld a,[wPlayerBattleStatus2] + bit HasSubstituteUp,a + ld hl,ReshowSubstituteAnim + ld b,BANK(ReshowSubstituteAnim) + call nz,Bankswitch + jr MirrorMoveCheck +playerCheckIfFlyOrChargeEffect ; 3d8bd (f:58bd) + ld c,30 + call DelayFrames + ld a,[wPlayerMoveEffect] + cp a,FLY_EFFECT + jr z,.playAnim + cp a,CHARGE_EFFECT + jr z,.playAnim + jr MirrorMoveCheck +.playAnim + xor a + ld [wAnimationType],a + ld a,STATUS_AFFECTED_ANIM + call PlayMoveAnimation +MirrorMoveCheck: ; 3d8d8 (f:58d8) + ld a,[wPlayerMoveEffect] + cp a,MIRROR_MOVE_EFFECT + jr nz,.metronomeCheck + call MirrorMoveCopyMove + jp z,ExecutePlayerMoveDone + xor a + ld [wMonIsDisobedient],a + jp CheckIfPlayerNeedsToChargeUp ; if Mirror Move was successful go back to damage calculation for copied move +.metronomeCheck + cp a,METRONOME_EFFECT + jr nz,.next + call MetronomePickMove + jp CheckIfPlayerNeedsToChargeUp ; Go back to damage calculation for the move picked by Metronome +.next + ld a,[wPlayerMoveEffect] + ld hl,ResidualEffects2 + ld de,1 + call IsInArray + jp c,JumpMoveEffect ; done here after executing effects of ResidualEffects2 + ld a,[wMoveMissed] + and a + jr z,.moveDidNotMiss + call PrintMoveFailureText + ld a,[wPlayerMoveEffect] + cp a,EXPLODE_EFFECT ; even if Explosion or Selfdestruct missed, its effect still needs to be activated + jr z,.notDone + jp ExecutePlayerMoveDone ; otherwise, we're done if the move missed +.moveDidNotMiss + call ApplyAttackToEnemyPokemon + call PrintCriticalOHKOText + callab DisplayEffectiveness + ld a,1 + ld [wMoveDidntMiss],a +.notDone + ld a,[wPlayerMoveEffect] + ld hl,AlwaysHappenSideEffects + ld de,1 + call IsInArray + call c,JumpMoveEffect ; not done after executing effects of AlwaysHappenSideEffects + ld hl,wEnemyMonHP + ld a,[hli] + ld b,[hl] + or b + ret z ; don't do anything else if the enemy fainted + call HandleBuildingRage + + ld hl,wPlayerBattleStatus1 + bit AttackingMultipleTimes,[hl] + jr z,.executeOtherEffects + ld a,[wPlayerNumAttacksLeft] + dec a + ld [wPlayerNumAttacksLeft],a + jp nz,getPlayerAnimationType ; for multi-hit moves, apply attack until PlayerNumAttacksLeft hits 0 or the enemy faints. + ; damage calculation and accuracy tests only happen for the first hit + res AttackingMultipleTimes,[hl] ; clear attacking multiple times status when all attacks are over + ld hl,MultiHitText + call PrintText + xor a + ld [wPlayerNumHits],a +.executeOtherEffects + ld a,[wPlayerMoveEffect] + and a + jp z,ExecutePlayerMoveDone + ld hl,SpecialEffects + ld de,1 + call IsInArray + call nc,JumpMoveEffect ; move effects not included in SpecialEffects or in either of the ResidualEffect arrays, + ; which are the effects not covered yet. Rage effect will be executed for a second time (though it's irrelevant). + ; Includes side effects that only need to be called if the target didn't faint. + ; Responsible for executing Twineedle's second side effect (poison). + jp ExecutePlayerMoveDone + +MultiHitText: ; 3d977 (f:5977) + TX_FAR _MultiHitText + db "@" + +ExecutePlayerMoveDone: ; 3d97c (f:597c) + xor a + ld [wActionResultOrTookBattleTurn],a + ld b,1 + ret + +PrintGhostText: ; 3d983 (f:5983) +; print the ghost battle messages + call IsGhostBattle + ret nz + ld a,[H_WHOSETURN] + and a + jr nz,.Ghost + ld a,[wBattleMonStatus] ; player’s turn + and a,SLP | (1 << FRZ) + ret nz + ld hl,ScaredText + call PrintText + xor a + ret +.Ghost ; ghost’s turn + ld hl,GetOutText + call PrintText + xor a + ret + +ScaredText: ; 3d9a2 (f:59a2) + TX_FAR _ScaredText + db "@" + +GetOutText: ; 3d9a7 (f:59a7) + TX_FAR _GetOutText + db "@" + IsGhostBattle: ; 3d9ac (f:59ac) - dr $3d9ac,$3ddc3 + ld a,[wIsInBattle] + dec a + ret nz + ld a,[wCurMap] + cp a,POKEMONTOWER_1 + jr c,.next + cp a,LAVENDER_HOUSE_1 + jr nc,.next + ld b,SILPH_SCOPE + call IsItemInBag + ret z +.next + ld a,1 + and a + ret + +; checks for various status conditions affecting the player mon +; stores whether the mon cannot use a move this turn in Z flag +CheckPlayerStatusConditions: ; 3d9c6 (f:59c6) + ld hl,wBattleMonStatus + ld a,[hl] + and a,SLP ; sleep mask + jr z,.FrozenCheck +; sleeping + dec a + ld [wBattleMonStatus],a ; decrement number of turns left + and a + jr z,.WakeUp ; if the number of turns hit 0, wake up +; fast asleep + xor a + ld [wAnimationType],a + ld a,SLP_ANIM - 1 + call PlayMoveAnimation + ld hl,FastAsleepText + call PrintText + jr .sleepDone +.WakeUp + ld hl,WokeUpText + call PrintText +.sleepDone + xor a + ld [wPlayerUsedMove],a + ld hl,ExecutePlayerMoveDone ; player can't move this turn + jp .returnToHL + +.FrozenCheck + bit FRZ,[hl] ; frozen? + jr z,.HeldInPlaceCheck + ld hl,IsFrozenText + call PrintText + xor a + ld [wPlayerUsedMove],a + ld hl,ExecutePlayerMoveDone ; player can't move this turn + jp .returnToHL + +.HeldInPlaceCheck + ld a,[wEnemyBattleStatus1] + bit UsingTrappingMove,a ; is enemy using a mult-turn move like wrap? + jp z,.FlinchedCheck + ld hl,CantMoveText + call PrintText + ld hl,ExecutePlayerMoveDone ; player can't move this turn + jp .returnToHL + +.FlinchedCheck + ld hl,wPlayerBattleStatus1 + bit Flinched,[hl] + jp z,.HyperBeamCheck + res Flinched,[hl] ; reset player's flinch status + ld hl,FlinchedText + call PrintText + ld hl,ExecutePlayerMoveDone ; player can't move this turn + jp .returnToHL + +.HyperBeamCheck + ld hl,wPlayerBattleStatus2 + bit NeedsToRecharge,[hl] + jr z,.AnyMoveDisabledCheck + res NeedsToRecharge,[hl] ; reset player's recharge status + ld hl,MustRechargeText + call PrintText + ld hl,ExecutePlayerMoveDone ; player can't move this turn + jp .returnToHL + +.AnyMoveDisabledCheck + ld hl,wPlayerDisabledMove + ld a,[hl] + and a + jr z,.ConfusedCheck + dec a + ld [hl],a + and $f ; did Disable counter hit 0? + jr nz,.ConfusedCheck + ld [hl],a + ld [wPlayerDisabledMoveNumber],a + ld hl,DisabledNoMoreText + call PrintText + +.ConfusedCheck + ld a,[wPlayerBattleStatus1] + add a ; is player confused? + jr nc,.TriedToUseDisabledMoveCheck + ld hl,W_PLAYERCONFUSEDCOUNTER + dec [hl] + jr nz,.IsConfused + ld hl,wPlayerBattleStatus1 + res Confused,[hl] ; if confused counter hit 0, reset confusion status + ld hl,ConfusedNoMoreText + call PrintText + jr .TriedToUseDisabledMoveCheck +.IsConfused + ld hl,IsConfusedText + call PrintText + xor a + ld [wAnimationType],a + ld a,CONF_ANIM - 1 + call PlayMoveAnimation + call BattleRandom + cp a,$80 ; 50% chance to hurt itself + jr c,.TriedToUseDisabledMoveCheck + ld hl,wPlayerBattleStatus1 + ld a,[hl] + and a, 1 << Confused ; if mon hurts itself, clear every other status from wPlayerBattleStatus1 + ld [hl],a + call HandleSelfConfusionDamage + jr .MonHurtItselfOrFullyParalysed + +.TriedToUseDisabledMoveCheck +; prevents a disabled move that was selected before being disabled from being used + ld a,[wPlayerDisabledMoveNumber] + and a + jr z,.ParalysisCheck + ld hl,wPlayerSelectedMove + cp [hl] + jr nz,.ParalysisCheck + call PrintMoveIsDisabledText + ld hl,ExecutePlayerMoveDone ; if a disabled move was somehow selected, player can't move this turn + jp .returnToHL + +.ParalysisCheck + ld hl,wBattleMonStatus + bit PAR,[hl] + jr z,.BideCheck + call BattleRandom + cp a,$3F ; 25% to be fully paralyzed + jr nc,.BideCheck + ld hl,FullyParalyzedText + call PrintText + +.MonHurtItselfOrFullyParalysed + ld hl,wPlayerBattleStatus1 + ld a,[hl] + ; clear bide, thrashing, charging up, and trapping moves such as warp (already cleared for confusion damage) + and $ff ^ ((1 << StoringEnergy) | (1 << ThrashingAbout) | (1 << ChargingUp) | (1 << UsingTrappingMove)) + ld [hl],a + ld a,[wPlayerMoveEffect] + cp a,FLY_EFFECT + jr z,.FlyOrChargeEffect + cp a,CHARGE_EFFECT + jr z,.FlyOrChargeEffect + jr .NotFlyOrChargeEffect + +.FlyOrChargeEffect + xor a + ld [wAnimationType],a + ld a,STATUS_AFFECTED_ANIM + call PlayMoveAnimation +.NotFlyOrChargeEffect + ld hl,ExecutePlayerMoveDone + jp .returnToHL ; if using a two-turn move, we need to recharge the first turn + +.BideCheck + ld hl,wPlayerBattleStatus1 + bit StoringEnergy,[hl] ; is mon using bide? + jr z,.ThrashingAboutCheck + xor a + ld [W_PLAYERMOVENUM],a + ld hl,wDamage + ld a,[hli] + ld b,a + ld c,[hl] + ld hl,wPlayerBideAccumulatedDamage + 1 + ld a,[hl] + add c ; acumulate damage taken + ld [hld],a + ld a,[hl] + adc b + ld [hl],a + ld hl,wPlayerNumAttacksLeft + dec [hl] ; did Bide counter hit 0? + jr z,.UnleashEnergy + ld hl,ExecutePlayerMoveDone + jp .returnToHL ; unless mon unleashes energy, can't move this turn +.UnleashEnergy + ld hl,wPlayerBattleStatus1 + res StoringEnergy,[hl] ; not using bide any more + ld hl,UnleashedEnergyText + call PrintText + ld a,1 + ld [W_PLAYERMOVEPOWER],a + ld hl,wPlayerBideAccumulatedDamage + 1 + ld a,[hld] + add a + ld b,a + ld [wDamage + 1],a + ld a,[hl] + rl a ; double the damage + ld [wDamage],a + or b + jr nz,.next + ld a,1 + ld [wMoveMissed],a +.next + xor a + ld [hli],a + ld [hl],a + ld a,BIDE + ld [W_PLAYERMOVENUM],a + ld hl,handleIfPlayerMoveMissed ; skip damage calculation, DecrementPP and MoveHitTest + jp .returnToHL + +.ThrashingAboutCheck + bit ThrashingAbout,[hl] ; is mon using thrash or petal dance? + jr z,.MultiturnMoveCheck + ld a,THRASH + ld [W_PLAYERMOVENUM],a + ld hl,ThrashingAboutText + call PrintText + ld hl,wPlayerNumAttacksLeft + dec [hl] ; did Thrashing About counter hit 0? + ld hl,PlayerCalcMoveDamage ; skip DecrementPP + jp nz,.returnToHL + push hl + ld hl,wPlayerBattleStatus1 + res ThrashingAbout,[hl] ; no longer thrashing about + set Confused,[hl] ; confused + call BattleRandom + and a,3 + inc a + inc a ; confused for 2-5 turns + ld [W_PLAYERCONFUSEDCOUNTER],a + pop hl ; skip DecrementPP + jp .returnToHL + +.MultiturnMoveCheck + bit UsingTrappingMove,[hl] ; is mon using multi-turn move? + jp z,.RageCheck + ld hl,AttackContinuesText + call PrintText + ld a,[wPlayerNumAttacksLeft] + dec a ; did multi-turn move end? + 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 + jp .returnToHL + +.RageCheck + ld a, [wPlayerBattleStatus2] + bit UsingRage, a ; is mon using rage? + jp z, .checkPlayerStatusConditionsDone ; if we made it this far, mon can move normally this turn + ld a, RAGE + ld [wd11e], a + call GetMoveName + call CopyStringToCF4B + xor a + ld [wPlayerMoveEffect], a + ld hl, PlayerCanExecuteMove + jp .returnToHL + +.returnToHL + xor a + ret + +.checkPlayerStatusConditionsDone + ld a, $1 + and a + ret + +FastAsleepText: ; 3dbaf (f:5baf) + TX_FAR _FastAsleepText + db "@" + +WokeUpText: ; 3dbb4 (f:5bb4) + TX_FAR _WokeUpText + db "@" + +IsFrozenText: ; 3dbb9 (f:5bb9) + TX_FAR _IsFrozenText + db "@" + +FullyParalyzedText: ; 3dbbe (f:5bbe) + TX_FAR _FullyParalyzedText + db "@" + +FlinchedText: ; 3dbc3 (f:5bc3) + TX_FAR _FlinchedText + db "@" + +MustRechargeText: ; 3dbc8 (f:5bc8) + TX_FAR _MustRechargeText + db "@" + +DisabledNoMoreText: ; 3dbcd (f:5bcd) + TX_FAR _DisabledNoMoreText + db "@" + +IsConfusedText: ; 3dbd2 (f:5bd2) + TX_FAR _IsConfusedText + db "@" + +HurtItselfText: ; 3dbd7 (f:5bd7) + TX_FAR _HurtItselfText + db "@" + +ConfusedNoMoreText: ; 3dbdc (f:5bdc) + TX_FAR _ConfusedNoMoreText + db "@" + +SavingEnergyText: ; 3dbe1 (f:5be1) + TX_FAR _SavingEnergyText + db "@" + +UnleashedEnergyText: ; 3dbe6 (f:5be6) + TX_FAR _UnleashedEnergyText + db "@" + +ThrashingAboutText: ; 3dbeb (f:5beb) + TX_FAR _ThrashingAboutText + db "@" + +AttackContinuesText: ; 3dbf0 (f:5bf0) + TX_FAR _AttackContinuesText + db "@" + +CantMoveText: ; 3dbf5 (f:5bf5) + TX_FAR _CantMoveText + db "@" + +PrintMoveIsDisabledText: ; 3dbfa (f:5bfa) + ld hl, wPlayerSelectedMove + ld de, wPlayerBattleStatus1 + ld a, [H_WHOSETURN] + and a + jr z, .removeChargingUp + inc hl + ld de, wEnemyBattleStatus1 +.removeChargingUp + ld a, [de] + res ChargingUp, a ; end the pokemon's + ld [de], a + ld a, [hl] + ld [wd11e], a + call GetMoveName + ld hl, MoveIsDisabledText + jp PrintText + +MoveIsDisabledText: ; 3dc1a (f:5c1a) + TX_FAR _MoveIsDisabledText + db "@" + +HandleSelfConfusionDamage: ; 3dc1f (f:5c1f) + ld hl, HurtItselfText + call PrintText + ld hl, wEnemyMonDefense + ld a, [hli] + push af + ld a, [hld] + push af + ld a, [wBattleMonDefense] + ld [hli], a + ld a, [wBattleMonDefense + 1] + ld [hl], a + ld hl, wPlayerMoveEffect + push hl + ld a, [hl] + push af + xor a + ld [hli], a + ld [wCriticalHitOrOHKO], a ; self-inflicted confusion damage can't be a Critical Hit + ld a, 40 ; 40 base power + ld [hli], a + xor a + ld [hl], a + call GetDamageVarsForPlayerAttack + call CalculateDamage ; ignores AdjustDamageForMoveType (type-less damage), RandomizeDamage, + ; and MoveHitTest (always hits) + pop af + pop hl + ld [hl], a + ld hl, wEnemyMonDefense + 1 + pop af + ld [hld], a + pop af + ld [hl], a + xor a + ld [wAnimationType], a + inc a + ld [H_WHOSETURN], a + call PlayMoveAnimation + call DrawPlayerHUDAndHPBar + xor a + ld [H_WHOSETURN], a + jp ApplyDamageToPlayerPokemon + +PrintMonName1Text: ; 3dc67 (f:5c67) + 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: ; 3dc6d (f:5c6d) + TX_FAR _MonName1Text + TX_ASM + ld a, [H_WHOSETURN] + and a + ld a, [W_PLAYERMOVENUM] + ld hl, wPlayerUsedMove + jr z, .playerTurn + ld a, [wEnemyMoveNum] + ld hl, wEnemyUsedMove +.playerTurn + ld [hl], a + ld [wd11e], a + call DetermineExclamationPointTextNum + ld a, [wMonIsDisobedient] + and a + ld hl, Used2Text + ret nz + ld a, [wd11e] + cp 3 + ld hl, Used2Text + ret c + ld hl, Used1Text + ret + +Used1Text: ; 3dc9f (f:5c9f) + TX_FAR _Used1Text + TX_ASM + jr PrintInsteadText + +Used2Text: ; 3dca6 (f:5ca6) + TX_FAR _Used2Text + TX_ASM + ; fall through + +PrintInsteadText: ; 3dcab (f:5cab) + ld a, [wMonIsDisobedient] + and a + jr z, PrintMoveName + ld hl, InsteadText + ret + +InsteadText: ; 3dcb5 (f:5cb5) + TX_FAR _InsteadText + TX_ASM + ; fall through + +PrintMoveName: ; 3dcba (f:5cba) + ld hl, _PrintMoveName + ret + +_PrintMoveName: ; 3dcbe (f:5cbe) + TX_FAR _CF4BText + TX_ASM + ld hl, ExclamationPointPointerTable + ld a, [wd11e] ; exclamation point num + 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: ; 3dcd4 (f:5cd4) + dw ExclamationPoint1Text + dw ExclamationPoint2Text + dw ExclamationPoint3Text + dw ExclamationPoint4Text + dw ExclamationPoint5Text + +ExclamationPoint1Text: ; 3dcde (f:5cde) + TX_FAR _ExclamationPoint1Text + db "@" + +ExclamationPoint2Text: ; 3dce3 (f:5ce3) + TX_FAR _ExclamationPoint2Text + db "@" + +ExclamationPoint3Text: ; 3dce8 (f:5ce8) + TX_FAR _ExclamationPoint3Text + db "@" + +ExclamationPoint4Text: ; 3dced (f:5ced) + TX_FAR _ExclamationPoint4Text + db "@" + +ExclamationPoint5Text: ; 3dcf2 (f:5cf2) + TX_FAR _ExclamationPoint5Text + db "@" + +; 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: ; 3dcf7 (f:5cf7) + push bc + ld a, [wd11e] ; 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 [wd11e], a ; exclamation point num + pop bc + ret + +ExclamationPointMoveSets: ; 3dd15 (f:5d15) +; a grammar mistake was fixed (only concerning japanese) +; BIDE is in category 3, moved from category 2 + db SWORDS_DANCE, GROWTH + db $00 + db RECOVER, SELFDESTRUCT, AMNESIA + db $00 + db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BIDE, BARRAGE + db $00 + db POUND, SCRATCH, VICEGRIP, WING_ATTACK, FLY, BIND, SLAM, HORN_ATTACK, BODY_SLAM + db WRAP, THRASH, TAIL_WHIP, LEER, BITE, GROWL, ROAR, SING, PECK, COUNTER + db STRENGTH, ABSORB, STRING_SHOT, EARTHQUAKE, FISSURE, DIG, TOXIC, SCREECH, HARDEN + db MINIMIZE, WITHDRAW, DEFENSE_CURL, METRONOME, LICK, CLAMP, CONSTRICT, POISON_GAS + db LEECH_LIFE, BUBBLE, FLASH, SPLASH, ACID_ARMOR, FURY_SWIPES, REST, SHARPEN, SLASH, SUBSTITUTE + db $00 + db $FF ; terminator + +PrintMoveFailureText: ; 3dd54 (f:5d54) + ld de, wPlayerMoveEffect + ld a, [H_WHOSETURN] + and a + jr z, .playersTurn + ld de, wEnemyMoveEffect +.playersTurn + ld hl, DoesntAffectMonText + ld a, [wDamageMultipliers] + and $7f + jr z, .gotTextToPrint + ld hl, AttackMissedText + ld a, [wCriticalHitOrOHKO] + cp $ff + jr nz, .gotTextToPrint + ld hl, UnaffectedText +.gotTextToPrint + push de + call PrintText + xor a + ld [wCriticalHitOrOHKO], a + pop de + ld a, [de] + cp JUMP_KICK_EFFECT + ret nz + + ; if you get here, the mon used jump kick or hi jump kick and missed + ld hl, wDamage ; since the move missed, W_DAMAGE will always contain 0 at this point. + ; Thus, recoil damage will always be equal to 1 + ; even if it was intended to be potential damage/8. + ld a, [hli] + ld b, [hl] + srl a + rr b + srl a + rr b + srl a + rr b + ld [hl], b + dec hl + ld [hli], a + or b + jr nz, .applyRecoil + inc a + ld [hl], a +.applyRecoil + ld hl, KeptGoingAndCrashedText + call PrintText + ld b, $4 + predef PredefShakeScreenHorizontally + ld a, [H_WHOSETURN] + and a + jr nz, .enemyTurn + jp ApplyDamageToPlayerPokemon +.enemyTurn + jp ApplyDamageToEnemyPokemon + +AttackMissedText: ; 3ddb4 (f:5db4) + TX_FAR _AttackMissedText + db "@" + +KeptGoingAndCrashedText: ; 3ddb9 (f:5db9) + TX_FAR _KeptGoingAndCrashedText + db "@" + +UnaffectedText: ; 3ddbe (f:5dbe) + TX_FAR _UnaffectedText + db "@" + PrintDoesntAffectText: ; 3ddc3 (f:5dc3) - dr $3ddc3,$3e5bb + ld hl, DoesntAffectMonText + jp PrintText + +DoesntAffectMonText: ; 3ddc9 (f:5dc9) + TX_FAR _DoesntAffectMonText + db "@" +PrintCriticalOHKOText: ; 3ddce (f:5dce) + dr $3ddce,$3ddfa +CheckForDisobedience: ; 3ddfa (f:5dfa) + dr $3ddfa,$3df41 +GetDamageVarsForPlayerAttack: ; 3df41 (f:5f41) + dr $3df41,$3e0d7 +CalculateDamage: ; 3e0d7 (f:60d7) + dr $3e0d7,$3e195 +CriticalHitTest: ; 3e195 (f:6195) + dr $3e195,$3e205 +HandleCounterMove: ; 3e205 (f:6205) + dr $3e205,$3e251 +ApplyAttackToEnemyPokemon: ; 3e251 (f:6251) + dr $3e251,$3e2b4 +ApplyDamageToEnemyPokemon: ; 3e2b4 (f:62b4) + dr $3e2b4,$3e372 +ApplyDamageToPlayerPokemon: ; 3e372 (f:6372) + dr $3e372,$3e428 +HandleBuildingRage: ; 3e428 (f:6428) + dr $3e428,$3e46f +MirrorMoveCopyMove: ; 3e46f (f:646f) + dr $3e46f,$3e4ba +MetronomePickMove: ; 3e4ba (f:64ba) + dr $3e4ba,$3e517 +AdjustDamageForMoveType: ; 3e517 (f:6517) + dr $3e517,$3e5bb + AIGetTypeEffectiveness: ; 3e5bb (f:65bb) ld a,[wEnemyMoveType] ld d,a ; d = type of enemy move @@ -3006,9 +4229,13 @@ AIGetTypeEffectiveness: ; 3e5bb (f:65bb) INCLUDE "data/type_effects.asm" MoveHitTest: ; 3e6f1 (f:66f1) - dr $3e6f1,$3e842 + dr $3e6f1,$3e80d +RandomizeDamage: ; 3e80d (f:680d) + dr $3e80d,$3e842 ExecuteEnemyMove: ; 3e842 (f:6842) - dr $3e842,$3ec87 + dr $3e842,$3ec44 +GetCurrentMove: ; 3ec44 (f:6c44) + dr $3ec44,$3ec87 LoadEnemyMonData: ; 3ec87 (f:6c87) dr $3ec87,$3edb8 DoBattleTransitionAndInitBattleVariables: ; 3edb8 (f:6db8) @@ -3032,9 +4259,13 @@ LoadHudTilePatterns: ; 3efe7 (f:6fe7) PrintEmptyString: ; 3f020 (f:7020) dr $3f020,$3f027 BattleRandom: ; 3f027 (f:7027) - dr $3f027,$3f093 + dr $3f027,$3f05f +HandleExplodingAnimation: ; 3f05f (f:705f) + dr $3f05f,$3f093 PlayMoveAnimation: ; 3f093 (f:7093) - dr $3f093,$3f3de + dr $3f093,$3f0a7 +JumpMoveEffect: ; 3f0a7 (f:70a7) + dr $3f0a7,$3f3de StatModifierUpEffect: ; 3f3de (f:73de) dr $3f3de,$3fb2e PrintButItFailedText_: ; 3fb2e (f:7b2e) diff --git a/engine/battle/moveEffects/drain_hp_effect.asm b/engine/battle/moveEffects/drain_hp_effect.asm index 46d61196..2af286a8 100644 --- a/engine/battle/moveEffects/drain_hp_effect.asm +++ b/engine/battle/moveEffects/drain_hp_effect.asm @@ -85,7 +85,7 @@ DrainHPEffect_: ; 76e7 (1:76e7) ld hl, SuckedHealthText ld a, [H_WHOSETURN] and a - ld a, [W_PLAYERMOVEEFFECT] + ld a, [wPlayerMoveEffect] jr z, .next3 ld a, [wEnemyMoveEffect] .next3 diff --git a/engine/battle/moveEffects/reflect_light_screen_effect.asm b/engine/battle/moveEffects/reflect_light_screen_effect.asm index c3f4de7f..c9e43715 100644 --- a/engine/battle/moveEffects/reflect_light_screen_effect.asm +++ b/engine/battle/moveEffects/reflect_light_screen_effect.asm @@ -1,6 +1,6 @@ ReflectLightScreenEffect_: ; f645d (3d:645d) ld hl, wPlayerBattleStatus3 - ld de, W_PLAYERMOVEEFFECT + ld de, wPlayerMoveEffect ld a, [H_WHOSETURN] and a jr z, .reflectLightScreenEffect diff --git a/engine/items/items.asm b/engine/items/items.asm index e0cccf01..8a21de7c 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -1697,7 +1697,7 @@ ItemUseXStat: ; df69 (3:df69) ld a,[hli] push af ; save [W_PLAYERMOVENUM] ld a,[hl] - push af ; save [W_PLAYERMOVEEFFECT] + push af ; save [wPlayerMoveEffect] push hl ld a,[wcf91] sub a,X_ATTACK - ATTACK_UP1_EFFECT @@ -1721,7 +1721,7 @@ ItemUseXStat: ; df69 (3:df69) pop hl pop af - ld [hld],a ; restore [W_PLAYERMOVEEFFECT] + ld [hld],a ; restore [wPlayerMoveEffect] pop af ld [hl],a ; restore [W_PLAYERMOVENUM] ret @@ -1500,7 +1500,7 @@ W_ENEMYMOVEMAXPP:: ; cfd1 ds 1 W_PLAYERMOVENUM:: ; cfd2 ds 1 -W_PLAYERMOVEEFFECT:: ; cfd3 +wPlayerMoveEffect:: ; cfd3 ds 1 W_PLAYERMOVEPOWER:: ; cfd4 ds 1 |