diff options
| author | YamaArashi <shadow962@live.com> | 2012-01-24 04:49:20 -0800 | 
|---|---|---|
| committer | YamaArashi <shadow962@live.com> | 2012-01-24 04:49:20 -0800 | 
| commit | 3eda472a22bc0ca68e56884d7a63020b68b7bcad (patch) | |
| tree | fc504143bdf0e5f01b257c635a6ebda24822014f | |
| parent | 9a3a6c1b53deaae0236aa8ee85d384f2d29032bb (diff) | |
disasm more battle code
hg-commit-id: 6f008f9e5c9d
| -rw-r--r-- | common.asm | 250 | ||||
| -rw-r--r-- | constants.asm | 92 | 
2 files changed, 340 insertions, 2 deletions
| @@ -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 diff --git a/constants.asm b/constants.asm index 8cb95bcd..32a2ebf4 100644 --- a/constants.asm +++ b/constants.asm @@ -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 | 
