disasm more battle code

hg-commit-id: 6f008f9e5c9d
This commit is contained in:
YamaArashi 2012-01-24 04:49:20 -08:00
parent 9a3a6c1b53
commit 3eda472a22
2 changed files with 340 additions and 2 deletions

View file

@ -24844,7 +24844,63 @@ HighCriticalMoves: ; 0x3e08e
db $FF
; 0x3e093
INCBIN "baserom.gbc",$3e093,$3e0df - $3e093
; function to determine if Counter hits and if so, how much damage it does
HandleCounterMove: ; 6093
ld a,[H_WHOSETURN] ; whose turn
and a
; player's turn
ld hl,W_ENEMYSELECTEDMOVE
ld de,W_ENEMYMOVEPOWER
ld a,[W_PLAYERSELECTEDMOVE]
jr z,.next\@
; enemy's turn
ld hl,W_PLAYERSELECTEDMOVE
ld de,W_PLAYERMOVEPOWER
ld a,[W_ENEMYSELECTEDMOVE]
.next\@
cp a,COUNTER
ret nz ; return if not using Counter
ld a,$01
ld [W_MOVEMISSED],a ; initialize the move missed variable to true (it is set to false below if the move hits)
ld a,[hl]
cp a,COUNTER
ret z ; if the target also used Counter, miss
ld a,[de]
and a
ret z ; if the move the target used has 0 power, miss
; check if the move the target used was Normal or Fighting type
inc de
ld a,[de]
and a ; normal type
jr z,.counterableType\@
cp a,FIGHTING
jr z,.counterableType\@
; if the move wasn't Normal or Fighting type, miss
xor a
ret
.counterableType\@
ld hl,W_DAMAGE
ld a,[hli]
or [hl]
ret z ; Counter misses if the target did no damage to the Counter user
; double the damage that the target did to the Counter user
ld a,[hl]
add a
ldd [hl],a
ld a,[hl]
adc a
ld [hl],a
jr nc,.noCarry\@
; damage is capped at 0xFFFF
ld a,$ff
ld [hli],a
ld [hl],a
.noCarry\@
xor a
ld [W_MOVEMISSED],a
call MoveHitTest ; do the normal move hit test in addition to Counter's special rules
xor a
ret
ApplyDamageToEnemyPokemon: ; 60DF
ld a,[W_PLAYERMOVEEFFECT]
@ -25083,7 +25139,197 @@ TypeEffects: ; 6474
db DRAGON,DRAGON,20
db $FF
INCBIN "baserom.gbc",$3e56b,$3e887 - $3e56b
; some tests that need to pass for a move to hit
MoveHitTest: ; 656B
; player's turn
ld hl,W_ENEMYBATTSTATUS1
ld de,W_PLAYERMOVEEFFECT
ld bc,W_ENEMYMONSTATUS
ld a,[H_WHOSETURN]
and a
jr z,.dreamEaterCheck\@
; enemy's turn
ld hl,W_PLAYERBATTSTATUS1
ld de,W_ENEMYMOVEEFFECT
ld bc,W_PLAYERMONSTATUS
.dreamEaterCheck\@
ld a,[de]
cp a,DREAM_EATER_EFFECT
jr nz,.swiftCheck\@
ld a,[bc]
and a,$07 ; is the target pokemon sleeping?
jp z,.moveMissed\@
.swiftCheck\@
ld a,[de]
cp a,SWIFT_EFFECT
ret z ; Swift never misses (interestingly, Azure Heights lists this is a myth, but it is appears to be true)
call $7b79 ; substitute check (note that this overwrites a)
jr z,.checkForDigOrFlyStatus\@
; this code is buggy. it's supposed to prevent HP draining moves from working on substitutes.
; since $7b79 overwrites a with either $00 or $01, it never works.
cp a,DRAIN_HP_EFFECT ; $03
jp z,.moveMissed\@
cp a,DREAM_EATER_EFFECT ; $08
jp z,.moveMissed\@
.checkForDigOrFlyStatus\@
bit 6,[hl]
jp nz,.moveMissed\@
ld a,[H_WHOSETURN]
and a
jr nz,.enemyTurn\@
.playerTurn\@
; this checks if the move effect is disallowed by mist
ld a,[W_PLAYERMOVEEFFECT]
cp a,$12
jr c,.skipEnemyMistCheck\@
cp a,$1a
jr c,.enemyMistCheck\@
cp a,$3a
jr c,.skipEnemyMistCheck\@
cp a,$42
jr c,.enemyMistCheck\@
jr .skipEnemyMistCheck\@
.enemyMistCheck\@
; if move effect is from $12 to $19 inclusive or $3a to $41 inclusive
; i.e. the following moves
; GROWL, TAIL WHIP, LEER, STRING SHOT, SAND-ATTACK, SMOKESCREEN, KINESIS,
; FLASH, CONVERSION, HAZE*, SCREECH, LIGHT SCREEN*, REFLECT*
; the moves that are marked with an asterisk are not affected since this
; function is not called when those moves are used
; XXX are there are any others like those three?
ld a,[W_ENEMYBATTSTATUS2]
bit 1,a
jp nz,.moveMissed\@
.skipEnemyMistCheck\@
ld a,[W_PLAYERBATTSTATUS2]
bit 0,a ; is the player using X Accuracy?
ret nz ; if so, always hit regardless of accuracy/evasion
jr .calcHitChance\@
.enemyTurn\@
ld a,[W_ENEMYMOVEEFFECT]
cp a,$12
jr c,.skipPlayerMistCheck\@
cp a,$1a
jr c,.playerMistCheck\@
cp a,$3a
jr c,.skipPlayerMistCheck\@
cp a,$42
jr c,.playerMistCheck\@
jr .skipPlayerMistCheck\@
.playerMistCheck\@
; similar to enemy mist check
ld a,[W_PLAYERBATTSTATUS2]
bit 1,a
jp nz,.moveMissed\@
.skipPlayerMistCheck\@
ld a,[W_ENEMYBATTSTATUS2]
bit 0,a ; is the enemy using X Accuracy?
ret nz ; if so, always hit regardless of accuracy/evasion
.calcHitChance\@
call CalcHitChance ; scale the move accuracy according to attacker's accuracy and target's evasion
ld a,[W_PLAYERMOVEACCURACY]
ld b,a
ld a,[H_WHOSETURN]
and a
jr z,.doAccuracyCheck\@
ld a,[W_ENEMYMOVEACCURACY]
ld b,a
.doAccuracyCheck\@
; if the random number generated is greater than or equal to the scaled accuracy, the move misses
; note that this means that even the highest accuracy is still just a 255/256 chance, not 100%
call $6e9b ; random number
cp b
jr nc,.moveMissed\@
ret
.moveMissed\@
xor a
ld hl,W_DAMAGE ; zero the damage
ld [hli],a
ld [hl],a
inc a
ld [W_MOVEMISSED],a
ld a,[H_WHOSETURN]
and a
jr z,.playerTurn2\@
.enemyTurn2\@
ld hl,W_ENEMYBATTSTATUS1
res 5,[hl] ; end multi-turn attack e.g. wrap
ret
.playerTurn2\@
ld hl,W_PLAYERBATTSTATUS1
res 5,[hl] ; end multi-turn attack e.g. wrap
ret
; values for player turn
CalcHitChance: ; 6624
ld hl,W_PLAYERMOVEACCURACY
ld a,[H_WHOSETURN]
and a
ld a,[W_PLAYERMONACCURACYMOD]
ld b,a
ld a,[W_ENEMYMONEVASIONMOD]
ld c,a
jr z,.next\@
; values for enemy turn
ld hl,W_ENEMYMOVEACCURACY
ld a,[W_ENEMYMONACCURACYMOD]
ld b,a
ld a,[W_PLAYERMONEVASIONMOD]
ld c,a
.next\@
ld a,$0e
sub c
ld c,a ; c = 14 - EVASIONMOD (this "reflects" the value over 7, so that an increase in the target's evasion decreases the hit chance instead of increasing the hit chance)
; zero the high bytes of the multiplicand
xor a
ld [$ff96],a
ld [$ff97],a
ld a,[hl]
ld [$ff98],a ; set multiplicand to move accuracy
push hl
ld d,$02 ; loop has two iterations
; loop to do the calculations, the first iteration multiplies by the accuracy ratio and the second iteration multiplies by the evasion ratio
.loop\@
push bc
ld hl,$76cb ; stat modifier ratios
dec b
sla b
ld c,b
ld b,$00
add hl,bc ; hl = address of stat modifier ratio
pop bc
ld a,[hli]
ld [$ff99],a ; set multiplier to the numerator of the ratio
call $38ac ; multiply
ld a,[hl]
ld [$ff99],a ; set divisor to the the denominator of the ratio (the dividend is the product of the previous multiplication)
ld b,$04 ; number of significant bytes in the dividend
call $38b9 ; divide
ld a,[$ff98]
ld b,a
ld a,[$ff97]
or b
jp nz,.nextCalculation\@
; make sure the result is always at least one
ld [$ff97],a
ld a,$01
ld [$ff98],a
.nextCalculation\@
ld b,c
dec d
jr nz,.loop\@
ld a,[$ff97]
and a ; is the calculated hit chance over 0xFF?
ld a,[$ff98]
jr z,.storeAccuracy\@
; if calculated hit chance over 0xFF
ld a,$ff ; set the hit chance to 0xFF
.storeAccuracy\@
pop hl
ld [hl],a ; store the hit chance in the move accuracy variable
ret
INCBIN "baserom.gbc",$3e687,$3e887 - $3e687
UnnamedText_3e887: ; 0x3e887
TX_FAR _UnnamedText_3e887

View file

@ -94,6 +94,27 @@ W_ENEMYSELECTEDMOVE EQU $CCDD
W_AICOUNT EQU $CCDF ; number of times remaining that AI action can occur
; stat modifiers for the player's current pokemon
; value can range from 1 - 13 ($1 to $D)
; 7 is normal
W_PLAYERMONATTACKMOD EQU $CD1A
W_PLAYERMONDEFENSEMOD EQU $CD1B
W_PLAYERMONSPEEDMOD EQU $CD1C
W_PLAYERMONSPECIALMOD EQU $CD1D
W_PLAYERMONACCURACYMOD EQU $CD1E
W_PLAYERMONEVASIONMOD EQU $CD1F
; stat modifiers for the enemy's current pokemon
; value can range from 1 - 13 ($1 to $D)
; 7 is normal
W_ENEMYMONATTACKMOD EQU $CD2E
W_ENEMYMONDEFENSEMOD EQU $CD2F
W_ENEMYMONSPEEDMOD EQU $CD30
W_ENEMYMONSPECIALMOD EQU $CD31
W_ENEMYMONACCURACYMOD EQU $CD32
W_ENEMYMONEVASIONMOD EQU $CD33
W_WHICHTRADE EQU $CD3D ; which entry from TradeMons to select
W_WHICHPOKEMON EQU $CF92 ; which pokemon you selected
@ -1172,6 +1193,77 @@ TM_48 EQU $F8
TM_49 EQU $F9
TM_50 EQU $FA
; tentative move effect constants
; {stat}_(UP|DOWN)(1|2) means that the move raises the user's (or lowers the target's) corresponding stat modifier by 1 (or 2) stages
; {status condition}_side_effect means that the move has a side chance of causing that condition
; {status condition}_effect means that the move causes the status condition every time it hits the target
POISON_SIDE_EFFECT1 EQU $02
DRAIN_HP_EFFECT EQU $03
BURN_SIDE_EFFECT1 EQU $04
FREEZE_SIDE_EFFECT EQU $05
PARALYZE_SIDE_EFFECT1 EQU $06
EXPLODE_EFFECT EQU $07 ; Explosion, Self Destruct
DREAM_EATER_EFFECT EQU $08
MIRROR_MOVE_EFFECT EQU $09
ATTACK_UP1_EFFECT EQU $0A
DEFENSE_UP1_EFFECT EQU $0B
SPECIAL_UP1_EFFECT EQU $0D
EVASION_UP1_EFFECT EQU $0F
PAY_DAY_EFFECT EQU $10
SWIFT_EFFECT EQU $11
ATTACK_DOWN1_EFFECT EQU $12
DEFENSE_DOWN1_EFFECT EQU $13
SPEED_DOWN1_EFFECT EQU $14
ACCURACY_DOWN1_EFFECT EQU $16
CONVERSION_EFFECT EQU $18
HAZE_EFFECT EQU $19
BIDE_EFFECT EQU $1A
THRASH_PETAL_DANCE_EFFECT EQU $1B
SWITCH_AND_TELEPORT_EFFECT EQU $1C
TWO_TO_FIVE_ATTACKS_EFFECT EQU $1D
FLINCH_SIDE_EFFECT1 EQU $1F
SLEEP_EFFECT EQU $20
POISON_SIDE_EFFECT2 EQU $21
BURN_SIDE_EFFECT2 EQU $22
PARALYZE_SIDE_EFFECT2 EQU $24
FLINCH_SIDE_EFFECT2 EQU $25
OHKO_EFFECT EQU $26 ; moves like Horn Drill
CHARGE_EFFECT EQU $27 ; moves like Solar Beam
SUPER_FANG_EFFECT EQU $28
SPECIAL_DAMAGE_EFFECT EQU $29 ; Seismic Toss, Night Shade, Sonic Boom, Dragon Rage, Psywave
TRAPPING_EFFECT EQU $2A ; moves like Wrap
FLY_EFFECT EQU $2B
ATTACK_TWICE_EFFECT EQU $2C
JUMP_KICK_EFFECT EQU $2D ; Jump Kick and Hi Jump Kick effect
MIST_EFFECT EQU $2E
FOCUS_ENERGY_EFFECT EQU $2F
RECOIL_EFFECT EQU $30 ; moves like Double Edge
CONFUSION_EFFECT EQU $31 ; Confuse Ray, Supersonic (not the move Confusion)
ATTACK_UP2_EFFECT EQU $32
DEFENSE_UP2_EFFECT EQU $33
SPEED_UP2_EFFECT EQU $34
SPECIAL_UP2_EFFECT EQU $35
HEAL_EFFECT EQU $38 ; Recover, Softboiled, Rest
TRANSFORM_EFFECT EQU $39
DEFENSE_DOWN2_EFFECT EQU $3B
LIGHT_SCREEN_EFFECT EQU $40
REFLECT_EFFECT EQU $41
POISON_EFFECT EQU $42
PARALYZE_EFFECT EQU $43
ATTACK_DOWN_SIDE_EFFECT EQU $44
DEFENSE_DOWN_SIDE_EFFECT EQU $45
SPEED_DOWN_SIDE_EFFECT EQU $46
SPECIAL_DOWN_SIDE_EFFECT EQU $47
CONFUSION_SIDE_EFFECT EQU $4C
TWINEEDLE_EFFECT EQU $4D
SUBSTITUTE_EFFECT EQU $4F
HYPER_BEAM_EFFECT EQU $50
RAGE_EFFECT EQU $51
MIMIC_EFFECT EQU $52
METRONOME_EFFECT EQU $53
LEECH_SEED_EFFECT EQU $54
SPLASH_EFFECT EQU $55
DISABLE_EFFECT EQU $56
; move name constants
POUND EQU $01