diff options
author | YamaArashi <shadow962@live.com> | 2012-01-24 10:13:58 -0800 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2012-01-24 10:13:58 -0800 |
commit | 9c3684535a646d47e3173e0d2291338d03bdb94e (patch) | |
tree | fdb1eaf85b80596be7eac9caee7775e741850bd2 | |
parent | 187642e9051b000e5ad3d6de84697410c7022869 (diff) |
more battle code disassembled
hg-commit-id: b7c80c2263e2
-rw-r--r-- | common.asm | 311 | ||||
-rw-r--r-- | constants.asm | 13 |
2 files changed, 315 insertions, 9 deletions
@@ -25241,21 +25241,314 @@ SubstituteBrokeText: ; 0x3e2b1 db $50 ; 0x3e2b1 + 5 bytes -INCBIN "baserom.gbc",$3e2b6,$3e2f8 - $3e2b6 +; this function raises the attack modifier of a pokemon using Rage when that pokemon is attacked +HandleBuildingRage: ; 62B6 +; values for the player turn + ld hl,W_ENEMYBATTSTATUS2 + ld de,W_ENEMYMONATTACKMOD + ld bc,W_ENEMYMOVENUM + ld a,[H_WHOSETURN] + and a + jr z,.next\@ +; values for the enemy turn + ld hl,W_PLAYERBATTSTATUS2 + ld de,W_PLAYERMONATTACKMOD + ld bc,W_PLAYERMOVENUM +.next\@ + bit 6,[hl] ; is the pokemon being attacked under the effect of Rage? + ret z ; return if not + ld a,[de] + cp a,$0d ; maximum stat modifier value + ret z ; return if attack modifier is already maxed + ld a,[H_WHOSETURN] + xor a,$01 ; flip turn for the stat modifier raising function + ld [H_WHOSETURN],a +; change the target pokemon's move to $00 and the effect to the one +; that causes the attack modifier to go up one stage + ld h,b + ld l,c + ld [hl],$00 ; null move number + inc hl + ld [hl],ATTACK_UP1_EFFECT + push hl + ld hl,BuildingRageText + call PrintText + call $7428 ; stat modifier raising function + pop hl + xor a + ldd [hl],a ; null move effect + ld a,RAGE + ld [hl],a ; restore the target pokemon's move number to Rage + ld a,[H_WHOSETURN] + xor a,$01 ; flip turn back to the way it was + ld [H_WHOSETURN],a + ret -UnnamedText_3e2f8: ; 0x3e2f8 - TX_FAR _UnnamedText_3e2f8 +BuildingRageText: ; 0x3e2f8 + TX_FAR _BuildingRageText db $50 ; 0x3e2f8 + 5 bytes -INCBIN "baserom.gbc",$3e2fd,$3e324 - $3e2fd +; copy last move for Mirror Move +; sets zero flag on failure and unsets zero flag on success +MirrorMoveCopyMove: ; 62FD + ld a,[H_WHOSETURN] + and a +; values for player turn + ld a,[$ccf2] + ld hl,W_PLAYERSELECTEDMOVE + ld de,W_PLAYERMOVENUM + jr z,.next\@ +; values for enemy turn + ld a,[$ccf1] + ld de,W_ENEMYMOVENUM + ld hl,W_ENEMYSELECTEDMOVE +.next\@ + ld [hl],a + cp a,MIRROR_MOVE ; did the target pokemon also use Mirror Move? + jr z,.mirrorMoveFailed\@ + and a ; null move? + jr nz,ReloadMoveData +.mirrorMoveFailed\@ +; Mirror Move fails on itself and null moves + ld hl,MirrorMoveFailedText + call PrintText + xor a + ret -UnnamedText_3e324: ; 0x3e324 - TX_FAR _UnnamedText_3e324 +MirrorMoveFailedText: ; 0x3e324 + TX_FAR _MirrorMoveFailedText db $50 ; 0x3e324 + 5 bytes -INCBIN "baserom.gbc",$3e329,$14b +; function used to reload move data for moves like Mirror Move and Metronome +ReloadMoveData: ; 6329 + ld [$d11e],a + dec a + ld hl,Moves + ld bc,$0006 + call AddNTimes + ld a,BANK(Moves) + call FarCopyData ; copy the move's stats + call IncrementMovePP +; the follow two function calls are used to reload the move name + call $3058 + call $3826 + ld a,$01 + and a + ret + +; function that picks a random move for metronome +MetronomePickMove: ; 6348 + xor a + ld [$cc5b],a + ld a,METRONOME + call PlayMoveAnimation ; play Metronome's animation +; values for player turn + ld de,W_PLAYERMOVENUM + ld hl,W_PLAYERSELECTEDMOVE + ld a,[H_WHOSETURN] + and a + jr z,.pickMoveLoop\@ +; values for enemy turn + ld de,W_ENEMYMOVENUM + ld hl,W_ENEMYSELECTEDMOVE +; loop to pick a random number in the range [1, $a5) to be the move used by Metronome +.pickMoveLoop\@ + call $6e9b ; random number + and a + jr z,.pickMoveLoop\@ + cp a,$a5 ; max normal move number + 1 (this is Struggle's move number) + jr nc,.pickMoveLoop\@ + cp a,METRONOME + jr z,.pickMoveLoop\@ + ld [hl],a + jr ReloadMoveData + +; this function increments the current move's PP +; it's used to prevent moves that run another move within the same turn +; (like Mirror Move and Metronome) from losing 2 PP +IncrementMovePP: ; 6373 + ld a,[H_WHOSETURN] + and a +; values for player turn + ld hl,W_PLAYERMONPP + ld de,W_PARTYMON1_MOVE1PP + ld a,[W_PLAYERMOVELISTINDEX] + jr z,.next\@ +; values for enemy turn + ld hl,W_ENEMYMONPP + ld de,$d8c1 ; enemy party pokemon 1 PP + ld a,[W_ENEMYMOVELISTINDEX] +.next\@ + ld b,$00 + ld c,a + add hl,bc + inc [hl] ; increment PP in the currently battling pokemon memory location + ld h,d + ld l,e + add hl,bc + ld a,[H_WHOSETURN] + and a + ld a,[W_PLAYERMONNUMBER] ; value for player turn + jr z,.next2\@ + ld a,[W_ENEMYMONNUMBER] ; value for enemy turn +.next2\@ + ld bc,$002c + call AddNTimes + inc [hl] ; increment PP in the party memory location + ret + +; function to adjust the base damage of an attack to account for type effectiveness +AdjustDamageForMoveType: ; 63A5 +; values for player turn + ld hl,W_PLAYERMONTYPES + ld a,[hli] + ld b,a ; b = type 1 of attacker + ld c,[hl] ; c = type 2 of attacker + ld hl,W_ENEMYMONTYPES + ld a,[hli] + ld d,a ; d = type 1 of defender + ld e,[hl] ; e = type 2 of defender + ld a,[W_PLAYERMOVETYPE] + ld [$d11e],a + ld a,[H_WHOSETURN] + and a + jr z,.next\@ +; values for enemy turn + ld hl,W_ENEMYMONTYPES + ld a,[hli] + ld b,a ; b = type 1 of attacker + ld c,[hl] ; c = type 2 of attacker + ld hl,W_PLAYERMONTYPES + ld a,[hli] + ld d,a ; d = type 1 of defender + ld e,[hl] ; e = type 2 of defender + ld a,[W_ENEMYMOVETYPE] + ld [$d11e],a +.next\@ + ld a,[$d11e] ; move type + cp b ; does the move type match type 1 of the attacker? + jr z,.sameTypeAttackBonus\@ + cp c ; does the move type match type 2 of the attacker? + jr z,.sameTypeAttackBonus\@ + jr .skipSameTypeAttackBonus\@ +.sameTypeAttackBonus\@ +; if the move type matches one of the attacker's types + ld hl,W_DAMAGE + 1 + ld a,[hld] + ld h,[hl] + ld l,a ; hl = damage + ld b,h + ld c,l ; bc = damage + srl b + rr c ; bc = floor(0.5 * damage) + add hl,bc ; hl = floor(1.5 * damage) +; store damage + ld a,h + ld [W_DAMAGE],a + ld a,l + ld [W_DAMAGE + 1],a + ld hl,$d05b + set 7,[hl] +.skipSameTypeAttackBonus\@ + ld a,[$d11e] + ld b,a ; b = move type + ld hl,TypeEffects +.loop\@ + ld a,[hli] ; a = "attacking type" of the current type pair + cp a,$ff + jr z,.done\@ + cp b ; does move type match "attacking type"? + jr nz,.nextTypePair\@ + ld a,[hl] ; a = "defending type" of the current type pair + cp d ; does type 1 of defender match "defending type"? + jr z,.matchingPairFound\@ + cp e ; does type 2 of defender match "defending type"? + jr z,.matchingPairFound\@ + jr .nextTypePair\@ +.matchingPairFound\@ +; if the move type matches the "attacking type" and one of the defender's types matches the "defending type" + push hl + push bc + inc hl + ld a,[$d05b] + and a,$80 + ld b,a + ld a,[hl] ; a = damage multiplier + ld [$ff99],a + add b + ld [$d05b],a + xor a + ld [$ff96],a + ld hl,W_DAMAGE + ld a,[hli] + ld [$ff97],a + ld a,[hld] + ld [$ff98],a + call $38ac ; multiply + ld a,10 + ld [$ff99],a + ld b,$04 + call $38b9 ; divide + ld a,[$ff97] + ld [hli],a + ld b,a + ld a,[$ff98] + ld [hl],a + or b ; is damage 0? + jr nz,.skipTypeImmunity\@ +.typeImmunity\@ +; if damage is 0, make the move miss + inc a + ld [W_MOVEMISSED],a +.skipTypeImmunity\@ + pop bc + pop hl +.nextTypePair\@ + inc hl + inc hl + jp .loop\@ +.done\@ + ret + +; function to tell how effective the type of an enemy attack is on the player's current pokemon +; this doesn't take into account the effects that dual types can have +; (e.g. 4x weakness / resistance, weaknesses and resistances canceling) +; the result is stored in [$D11E] +; ($05 is not very effective, $10 is neutral, $14 is super effective) +; as far is can tell, this is only used once in some AI code to help decide which move to use +AIGetTypeEffectiveness: ; 6449 + ld a,[W_ENEMYMOVETYPE] + ld d,a ; d = type of enemy move + ld hl,W_PLAYERMONTYPES + ld b,[hl] ; b = type 1 of player's pokemon + inc hl + ld c,[hl] ; c = type 2 of player's pokemon + ld a,$10 + ld [$d11e],a ; initialize [$D11E] to neutral effectiveness + ld hl,TypeEffects +.loop\@ + ld a,[hli] + cp a,$ff + ret z + cp d ; match the type of the move + jr nz,.nextTypePair1\@ + ld a,[hli] + cp b ; match with type 1 of pokemon + jr z,.done\@ + cp c ; or match with type 2 of pokemon + jr z,.done\@ + jr .nextTypePair2\@ +.nextTypePair1\@ + inc hl +.nextTypePair2\@ + inc hl + jr .loop\@ +.done\@ + ld a,[hl] + ld [$d11e],a ; store damage multiplier + ret TypeEffects: ; 6474 ; format: attacking type, defending type, damage multiplier @@ -57070,12 +57363,12 @@ _SubstituteBrokeText: ; 0x89b6a db "SUBSTITUTE broke!", $58 ; 0x89b6a + 22 bytes -_UnnamedText_3e2f8: ; 0x89b80 +_BuildingRageText: ; 0x89b80 db $0, $5a, "'s", $4f db "RAGE is building!", $58 ; 0x89b80 + 22 bytes -_UnnamedText_3e324: ; 0x89b96 +_MirrorMoveFailedText: ; 0x89b96 db $0, "The MIRROR MOVE", $4e, "failed!", $58 ; 0x89b96 + 25 bytes diff --git a/constants.asm b/constants.asm index e743c934..4a76c2ae 100644 --- a/constants.asm +++ b/constants.asm @@ -89,6 +89,9 @@ TX_RAM: MACRO ; wram locations +W_PLAYERMOVELISTINDEX EQU $CC2E +W_PLAYERMONNUMBER EQU $CC2F + ; current HP of player and enemy substitutes W_PLAYERSUBSITUTEHP EQU $CCD7 W_ENEMYSUBSITUTEHP EQU $CCD8 @@ -96,6 +99,8 @@ W_ENEMYSUBSITUTEHP EQU $CCD8 W_PLAYERSELECTEDMOVE EQU $CCDC W_ENEMYSELECTEDMOVE EQU $CCDD +W_ENEMYMOVELISTINDEX EQU $CCE2 + W_AICOUNT EQU $CCDF ; number of times remaining that AI action can occur ; stat modifiers for the player's current pokemon @@ -150,8 +155,12 @@ W_ENEMYMONSTATUS EQU $CFE9 ; active opponent's status condition ; bit 5 frz ; bit 6 par ; unused? (XXX confirm) +W_ENEMYMONTYPES EQU $CFEA +W_ENEMYMONTYPE1 EQU $CFEA +W_ENEMYMONTYPE2 EQU $CFEB W_ENEMYMONLEVEL EQU $CFF3 W_ENEMYMONMAXHP EQU $CFF4 ; (16 bits) +W_ENEMYMONPP EQU $CFFE W_PLAYERMONCURHP EQU $D015 ; active opponent's hp (16 bits) W_PLAYERMONSTATUS EQU $D018 ; the status of the player’s current monster @@ -163,8 +172,12 @@ W_PLAYERMONSTATUS EQU $D018 ; the status of the player’s current monster ; bit 5 frz ; bit 6 par ; unused? (XXX confirm) +W_PLAYERMONTYPES EQU $D019 +W_PLAYERMONTYPE1 EQU $D019 +W_PLAYERMONTYPE2 EQU $D01A W_PLAYERMONLEVEL EQU $D022 W_PLAYERMONMAXHP EQU $D023 ; (16 bits) +W_PLAYERMONPP EQU $D02D W_TRAINERCLASS EQU $D031 |