diff options
Diffstat (limited to 'engine/battle')
-rwxr-xr-x | engine/battle/animations.asm | 766 | ||||
-rw-r--r-- | engine/battle/bank3d_battle.asm | 291 | ||||
-rwxr-xr-x | engine/battle/bank_e_misc.asm | 19 | ||||
-rw-r--r-- | engine/battle/battle_transitions.asm | 8 | ||||
-rw-r--r-- | engine/battle/common_text.asm | 16 | ||||
-rwxr-xr-x | engine/battle/core.asm | 710 | ||||
-rw-r--r-- | engine/battle/draw_hud_pokeball_gfx.asm | 10 | ||||
-rwxr-xr-x | engine/battle/end_of_battle.asm | 4 | ||||
-rw-r--r-- | engine/battle/experience.asm | 22 | ||||
-rw-r--r-- | engine/battle/ghost_marowak_anim.asm | 5 | ||||
-rw-r--r-- | engine/battle/link_battle_versus_text.asm | 3 | ||||
-rw-r--r-- | engine/battle/moveEffects/heal_effect.asm | 6 | ||||
-rw-r--r-- | engine/battle/moveEffects/reflect_light_screen_effect.asm | 6 | ||||
-rw-r--r-- | engine/battle/moveEffects/transform_effect.asm | 11 | ||||
-rwxr-xr-x | engine/battle/read_trainer_party.asm | 103 | ||||
-rwxr-xr-x | engine/battle/safari_zone.asm | 10 | ||||
-rw-r--r-- | engine/battle/scale_sprites.asm | 7 | ||||
-rw-r--r-- | engine/battle/trainer_ai.asm | 37 | ||||
-rw-r--r-- | engine/battle/wild_encounters.asm | 7 |
19 files changed, 1246 insertions, 795 deletions
diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm index 74e48535..de1e67b9 100755 --- a/engine/battle/animations.asm +++ b/engine/battle/animations.asm @@ -15,6 +15,8 @@ DrawFrameBlock: ld a, [wFBTileCounter] inc a ld [wFBTileCounter], a + ld a, $2 + ld [wdef5], a ld a, [wSubAnimTransform] dec a jr z, .flipHorizontalAndVertical ; 1 @@ -46,13 +48,22 @@ DrawFrameBlock: .finishCopying ; finish copying values to OAM (when [wSubAnimTransform] not 1 or 2) add [hl] ; X offset ld [de], a ; store X + cp 88 + jr c, .asm_78056 + ld a, [wdef5] + inc a + ld [wdef5], a +.asm_78056 inc hl inc de ld a, [hli] - add $31 ; base tile ID for battle animations + add a, $31 ; base tile ID for battle animations ld [de], a ; store tile ID inc de ld a, [hli] + ld b, a + ld a, [wdef5] + or b ld [de], a ; store flags inc de jp .nextTile @@ -71,10 +82,16 @@ DrawFrameBlock: ld a, 168 sub b ; flip X coordinate ld [de], a ; store X + cp 88 + jr c, .asm_78087 + ld a, [wdef5] + inc a + ld [wdef5], a +.asm_78087 inc hl inc de ld a, [hli] - add $31 ; base tile ID for battle animations + add a, $31 ; base tile ID for battle animations ld [de], a ; store tile ID inc de ; toggle horizontal and vertical flip @@ -82,15 +99,16 @@ DrawFrameBlock: and a ld b, OAM_VFLIP | OAM_HFLIP jr z, .storeFlags1 - cp OAM_HFLIP + cp a, OAM_HFLIP ld b, OAM_VFLIP jr z, .storeFlags1 - cp OAM_VFLIP + cp a, OAM_VFLIP ld b, OAM_HFLIP jr z, .storeFlags1 ld b, 0 .storeFlags1 - ld a, b + ld a, [wdef5] + or b ld [de], a inc de jp .nextTile @@ -107,6 +125,12 @@ DrawFrameBlock: ld a, 168 sub b ; flip X coordinate ld [de], a ; store X + cp 88 + jr c, .asm_780c8 + ld a, [wdef5] + inc a + ld [wdef5], a +.asm_780c8 inc hl inc de ld a, [hli] @@ -122,6 +146,9 @@ DrawFrameBlock: .disableHorizontalFlip res 5, a .storeFlags2 + ld b, a + ld a, [wdef5] + or b ld [de], a inc de .nextTile @@ -245,11 +272,13 @@ PlayAnimation: push af ld a, [wAnimPalette] ld [rOBP0], a + call UpdateGBCPal_OBP0 call LoadAnimationTileset call LoadSubanimation call PlaySubanimation pop af ld [rOBP0], a + call UpdateGBCPal_OBP0 .nextAnimationCommand pop hl jr .animationLoop @@ -367,12 +396,7 @@ AnimationTileset2: INCBIN "gfx/attack_anim_2.2bpp" SlotMachineTiles2: -IF DEF(_RED) - INCBIN "gfx/red/slotmachine2.2bpp" -ENDC -IF DEF(_BLUE) - INCBIN "gfx/blue/slotmachine2.2bpp" -ENDC + INCBIN "gfx/slotmachine2.2bpp" MoveAnimation: push hl @@ -537,6 +561,8 @@ SetAnimationPalette: ld [rOBP0], a ld a, $6c ld [rOBP1], a + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ret .notSGB ld a, $e4 @@ -544,6 +570,28 @@ SetAnimationPalette: ld [rOBP0], a ld a, $6c ld [rOBP1], a + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 + ret + +Func_78e98: + call SaveScreenTilesToBuffer2 + xor a + ld [H_AUTOBGTRANSFERENABLED], a + call ClearScreen + ld h, vBGMap0 / $100 + call WriteLowerByteOfBGMapAndEnableBGTransfer + call Delay3 + xor a + ld [H_AUTOBGTRANSFERENABLED], a + call LoadScreenTilesFromBuffer2 + ld h, vBGMap1 / $100 + +WriteLowerByteOfBGMapAndEnableBGTransfer: + ld l, vBGMap0 & $ff + call BattleAnimCopyTileMapToVRAM + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a ret PlaySubanimation: @@ -691,7 +739,7 @@ AnimationIdSpecialEffects: dw DoExplodeSpecialEffects db SPORE - dw AnimationFlashScreen + dw FlashScreenEveryFourFrameBlocks db EXPLOSION dw DoExplodeSpecialEffects @@ -733,6 +781,7 @@ DoBallTossSpecialEffects: ld a, [rOBP0] xor %00111100 ; complement colors 1 and 2 ld [rOBP0], a + call UpdateGBCPal_OBP0 .skipFlashingEffect ld a, [wSubAnimCounter] cp 11 ; is it the beginning of the subanimation? @@ -922,7 +971,7 @@ TradeShakePokeball: jp PlaySound BallMoveDistances1: - db -12,-12,-8 + db -12, -12, -8 db $ff ; terminator ; function to make the pokeball jump up @@ -963,7 +1012,7 @@ TradeJumpPokeball: jr .loop BallMoveDistances2: - db 11,12,-12,-7,7,12,-8,8 + db 11, 12, -12, -7, 7, 12, -8, 8 db $ff ; terminator ; this function copies the current musical note graphic @@ -1102,6 +1151,7 @@ AnimationFlashScreenLong: cp $01 ; is it the end of the palettes? jr z, .endOfPalettes ld [rBGP], a + call UpdateGBCPal_BGP call FlashScreenLongDelay jr .innerLoop .endOfPalettes @@ -1164,14 +1214,17 @@ AnimationFlashScreen: push af ; save initial palette ld a, %00011011 ; 0, 1, 2, 3 (inverted colors) ld [rBGP], a + call UpdateGBCPal_BGP ld c, 2 call DelayFrames xor a ; white out background ld [rBGP], a + call UpdateGBCPal_BGP ld c, 2 call DelayFrames pop af ld [rBGP], a ; restore initial palette + call UpdateGBCPal_BGP ret AnimationDarkScreenPalette: @@ -1217,6 +1270,7 @@ SetAnimationBGPalette: ld a, c .next ld [rBGP], a + call UpdateGBCPal_BGP ret ld b, $5 @@ -1261,15 +1315,30 @@ AnimationWaterDropletsEverywhere: _AnimationWaterDroplets: ld hl, wOAMBuffer .loop + ld a, $1 + ld [wdef5], a ld a, [wBaseCoordY] ld [hli], a ; Y + cp 40 + jr c, .asm_792d7 + ld a, [wdef5] + inc a + ld [wdef5], a +.asm_792d7 ld a, [wBaseCoordX] add 27 ld [wBaseCoordX], a ld [hli], a ; X + cp 88 + jr c, .asm_792ee + ld a, [wdef5] + add $2 + and $3 + ld [wdef5], a +.asm_792ee ld a, [wDropletTile] ld [hli], a ; tile - xor a + ld a, [wdef5] ld [hli], a ; attribute ld a, [wBaseCoordX] cp 144 @@ -1412,16 +1481,30 @@ BattleAnimWriteOAMEntry: ; Y coordinate = e (increased by 8 each call, before the write to OAM) ; X coordinate = [wBaseCoordX] ; tile = d -; attributes = 0 +; attributes = variable (dependant on coords) + ld a, $1 + ld [wdef5], a ld a, e add 8 ld e, a ld [hli], a + cp 40 + jr c, .asm_793d8 + ld a, [wdef5] + inc a + ld [wdef5], a +.asm_793d8 ld a, [wBaseCoordX] ld [hli], a + cp 88 + jr c, .asm_793e8 + ld a, [wdef5] + add $2 + ld [wdef5], a +.asm_793e8 ld a, d ld [hli], a - xor a + ld a, [wdef5] ld [hli], a ret @@ -1473,7 +1556,7 @@ AdjustOAMBlockYPos2: ret AnimationBlinkEnemyMon: -; Make the enemy mon's sprite blink on and off for a second or two + ; Make the enemy mon's sprite blink on and off for a second or two ld hl, AnimationBlinkMon jp CallWithTurnFlipped @@ -1626,6 +1709,8 @@ AnimationSpiralBallsInward: ld a, [hl] cp $ff jr z, .done + ld a, $2 + ld [wdef5], a ld a, [wSpiralBallsBaseY] add [hl] ld [de], a ; Y @@ -1634,9 +1719,20 @@ AnimationSpiralBallsInward: ld a, [wSpiralBallsBaseX] add [hl] ld [de], a ; X + cp 88 + jr c, .asm_79524 + ld a, $3 + ld [wdef5], a +.asm_79524 inc hl inc de inc de + ld a, [de] + and $f0 + ld b, a + ld a, [wdef5] + or b + ld [de], a inc de dec c jr nz, .innerLoop @@ -1938,7 +2034,7 @@ _AnimationSlideMonOff: jr nz, .slideLoop ret -; Since mon pic tile numbers go from top to bottom, left to right in order, +; Since mon pic tile numbers go from top to bottom, left to right in order, ; adding the height of the mon pic in tiles to a tile number gives the tile ; number of the tile one column to the right (and thus subtracting the height ; gives the reverse). If the next tile would be past the edge of the pic, the 2 @@ -1948,10 +2044,8 @@ _AnimationSlideMonOff: .PlayerNextTile ld a, [hl] add 7 -; This is a bug. The lower right corner tile of the mon back pic is blanked -; while the mon is sliding off the screen. It should compare with the max tile -; plus one instead. - cp $61 +; bugfix: compares against the max tile + 1 as opposed to the max tile + cp $62 ret c ld a, " " ret @@ -2088,18 +2182,24 @@ AnimationSubstitute: CopySlowbroSpriteData: ld bc, $0010 ld a, BANK(SlowbroSprite) - jp FarCopyData2 + jp FarCopyData HideSubstituteShowMonAnim: ld a, [H_WHOSETURN] and a ld hl, wPlayerMonMinimized + ld de, wPlayerBattleStatus1 + ld bc, wPlayerMoveNum ld a, [wPlayerBattleStatus2] jr z, .next1 ld hl, wEnemyMonMinimized + ld de, wEnemyBattleStatus1 + ld bc, wEnemyMoveNum ld a, [wEnemyBattleStatus2] .next1 push hl + push de + push bc ; if the substitute broke, slide it down, else slide it offscreen horizontally bit HAS_SUBSTITUTE_UP, a jr nz, .substituteStillUp @@ -2108,12 +2208,65 @@ HideSubstituteShowMonAnim: .substituteStillUp call AnimationSlideMonOff .next2 + pop bc + pop de + ld a, [de] + bit INVULNERABLE, a pop hl + jr nz, .invulnerable + ld a, [bc] + cp FLY + jr z, .flyOrDig + cp DIG + jr z, .flyOrDig +.invulnerable ld a, [hl] and a jp nz, AnimationMinimizeMon call AnimationFlashMonPic jp AnimationShowMonPic +.flyOrDig + ld a, [H_WHOSETURN] + and a + jr nz, .enemy + ld a, [wPlayerMonMinimized] + and a + jr nz, .monIsMinimized + ld a, [wBattleMonSpecies] + ld [wcf91], a + ld [wd0b5], a + call GetMonHeader + predef LoadMonBackPic + ret +.enemy + ld a, [wEnemyMonMinimized] + and a + jr nz, .monIsMinimized + ld a, [wEnemyMonSpecies] + ld [wcf91], a + ld [wd0b5], a + call GetMonHeader + ld de, vFrontPic + jp LoadMonFrontSprite +.monIsMinimized + ld hl, wTempPic + push hl + xor a + ld bc, 7 * 7 * $10 + call FillMemory + pop hl + ld de, $194 + add hl, de + ld de, MinimizedMonSprite + ld c, MinimizedMonSpriteEnd - MinimizedMonSprite +.loop + ld a, [de] + ld [hli], a + ld [hli], a + inc de + dec c + jr nz, .loop + jp CopyTempPicToMonPic ReshowSubstituteAnim: call AnimationSlideMonOff @@ -2181,6 +2334,23 @@ AnimationHideEnemyMonPic: ld [H_AUTOBGTRANSFERENABLED], a jp Delay3 +Func_79929: + ld hl, wPlayerMonMinimized + ld a, [H_WHOSETURN] + and a + jr z, .playerTurn + ld hl, wEnemyMonMinimized +.playerTurn + ld a, [hl] + and a + jr z, .notMinimized + call AnimationMinimizeMon + ret +.notMinimized + call AnimationFlashMonPic + call AnimationShowMonPic + ret + InitMultipleObjectsOAM: ; Writes c OAM entries with tile d. ; Sets their Y coordinates to sequential multiples of 8, starting from 0. @@ -2202,6 +2372,8 @@ InitMultipleObjectsOAM: jr nz, .loop ret + ret ; unreferenced + AnimationHideMonPic: ; Hides the mon's sprite. ld a, [H_WHOSETURN] @@ -2228,7 +2400,7 @@ ClearMonPicFromTileMap: ret ; puts the tile map destination address of a mon sprite in hl, given the row count in b -; The usual row count is 7, but it may be smaller when sliding a mon sprite in/out, +; The usual row count is 7, but it may be smaller when sliding a mon sprite in/out, ; in order to show only a portion of the mon sprite. GetMonSpriteTileMapPointerFromRowCount: push de @@ -2364,172 +2536,172 @@ IsCryMove: MoveSoundTable: ; ID, pitch mod, tempo mod - db SFX_POUND, $00,$80 ; POUND - db SFX_BATTLE_0C, $10,$80 ; KARATE_CHOP - db SFX_DOUBLESLAP, $00,$80 ; DOUBLESLAP - db SFX_BATTLE_0B, $01,$80 ; COMET_PUNCH - db SFX_BATTLE_0D, $00,$40 ; MEGA_PUNCH - db SFX_SILPH_SCOPE, $00,$ff ; PAY_DAY - db SFX_BATTLE_0D, $10,$60 ; FIRE_PUNCH - db SFX_BATTLE_0D, $20,$80 ; ICE_PUNCH - db SFX_BATTLE_0D, $00,$a0 ; THUNDERPUNCH - db SFX_DAMAGE, $00,$80 ; SCRATCH - db SFX_BATTLE_0F, $20,$40 ; VICEGRIP - db SFX_BATTLE_0F, $00,$80 ; GUILLOTINE - db SFX_BATTLE_0E, $00,$a0 ; RAZOR_WIND - db SFX_NOT_VERY_EFFECTIVE,$10,$c0 ; SWORDS_DANCE - db SFX_NOT_VERY_EFFECTIVE,$00,$a0 ; CUT - db SFX_BATTLE_12, $00,$c0 ; GUST - db SFX_BATTLE_12, $10,$a0 ; WING_ATTACK - db SFX_BATTLE_13, $00,$e0 ; WHIRLWIND - db SFX_NOT_VERY_EFFECTIVE,$20,$c0 ; FLY - db SFX_BATTLE_14, $00,$80 ; BIND - db SFX_BATTLE_22, $00,$80 ; SLAM - db SFX_VINE_WHIP, $01,$80 ; VINE_WHIP - db SFX_BATTLE_20, $00,$80 ; STOMP - db SFX_BATTLE_17, $f0,$40 ; DOUBLE_KICK - db SFX_SUPER_EFFECTIVE, $00,$80 ; MEGA_KICK - db SFX_BATTLE_17, $00,$80 ; JUMP_KICK - db SFX_BATTLE_21, $10,$80 ; ROLLING_KICK - db SFX_BATTLE_1B, $01,$a0 ; SAND_ATTACK - db SFX_BATTLE_18, $00,$80 ; HEADBUTT - db SFX_BATTLE_1E, $00,$60 ; HORN_ATTACK - db SFX_BATTLE_1E, $01,$40 ; FURY_ATTACK - db SFX_HORN_DRILL, $00,$a0 ; HORN_DRILL - db SFX_SUPER_EFFECTIVE, $10,$a0 ; TACKLE - db SFX_BATTLE_20, $00,$c0 ; BODY_SLAM - db SFX_BATTLE_14, $10,$60 ; WRAP - db SFX_SUPER_EFFECTIVE, $00,$a0 ; TAKE_DOWN - db SFX_BATTLE_22, $11,$c0 ; THRASH - db SFX_SUPER_EFFECTIVE, $20,$c0 ; DOUBLE_EDGE - db SFX_BATTLE_21, $00,$80 ; TAIL_WHIP - db SFX_BATTLE_1B, $00,$80 ; POISON_STING - db SFX_BATTLE_1B, $20,$c0 ; TWINEEDLE - db SFX_BATTLE_19, $00,$80 ; PIN_MISSILE - db SFX_BATTLE_31, $ff,$40 ; LEER - db SFX_BATTLE_1E, $00,$80 ; BITE - db SFX_BATTLE_0B, $00,$c0 ; GROWL - db SFX_BATTLE_0B, $00,$40 ; ROAR - db SFX_BATTLE_35, $00,$80 ; SING - db SFX_BATTLE_27, $40,$60 ; SUPERSONIC - db SFX_BATTLE_27, $00,$80 ; SONICBOOM - db SFX_BATTLE_27, $ff,$40 ; DISABLE - db SFX_BATTLE_2A, $80,$c0 ; ACID - db SFX_BATTLE_19, $10,$a0 ; EMBER - db SFX_BATTLE_19, $21,$e0 ; FLAMETHROWER - db SFX_BATTLE_29, $00,$80 ; MIST - db SFX_BATTLE_24, $20,$60 ; WATER_GUN - db SFX_BATTLE_2A, $00,$80 ; HYDRO_PUMP - db SFX_BATTLE_2C, $00,$80 ; SURF - db SFX_BATTLE_28, $40,$80 ; ICE_BEAM - db SFX_BATTLE_29, $f0,$e0 ; BLIZZARD - db SFX_PSYBEAM, $00,$80 ; PSYBEAM - db SFX_BATTLE_2A, $f0,$60 ; BUBBLEBEAM - db SFX_BATTLE_28, $00,$80 ; AURORA_BEAM - db SFX_BATTLE_36, $00,$80 ; HYPER_BEAM - db SFX_PECK,$01, $a0 ; PECK - db SFX_BATTLE_13, $f0,$20 ; DRILL_PECK - db SFX_BATTLE_23, $01,$c0 ; SUBMISSION - db SFX_BATTLE_23, $00,$80 ; LOW_KICK - db SFX_SUPER_EFFECTIVE, $00,$e0 ; COUNTER - db SFX_BATTLE_26, $01,$60 ; SEISMIC_TOSS - db SFX_BATTLE_26, $20,$40 ; STRENGTH - db SFX_BATTLE_24, $00,$80 ; ABSORB - db SFX_BATTLE_24, $40,$c0 ; MEGA_DRAIN - db SFX_BATTLE_1B, $03,$60 ; LEECH_SEED - db SFX_BATTLE_25, $11,$e0 ; GROWTH - db SFX_BATTLE_12, $20,$e0 ; RAZOR_LEAF - db SFX_BATTLE_2E, $00,$80 ; SOLARBEAM - db SFX_BATTLE_1C, $00,$80 ; POISONPOWDER - db SFX_BATTLE_1C, $11,$a0 ; STUN_SPORE - db SFX_BATTLE_1C, $01,$c0 ; SLEEP_POWDER - db SFX_BATTLE_13, $14,$c0 ; PETAL_DANCE - db SFX_BATTLE_1B, $02,$a0 ; STRING_SHOT - db SFX_BATTLE_29, $f0,$80 ; DRAGON_RAGE - db SFX_BATTLE_29, $20,$c0 ; FIRE_SPIN - db SFX_BATTLE_2F, $00,$20 ; THUNDERSHOCK - db SFX_BATTLE_2F, $20,$80 ; THUNDERBOLT - db SFX_BATTLE_2E, $12,$60 ; THUNDER_WAVE - db SFX_BATTLE_26, $00,$80 ; THUNDER - db SFX_BATTLE_14, $01,$e0 ; ROCK_THROW - db SFX_BATTLE_29, $0f,$e0 ; EARTHQUAKE - db SFX_BATTLE_29, $11,$20 ; FISSURE - db SFX_DAMAGE, $10,$40 ; DIG - db SFX_BATTLE_0F, $10,$c0 ; TOXIC - db SFX_BATTLE_14, $00,$20 ; CONFUSION - db SFX_PSYCHIC_M, $00,$80 ; PSYCHIC_M - db SFX_BATTLE_35, $11,$18 ; HYPNOSIS - db SFX_BATTLE_09, $20,$c0 ; MEDITATE - db SFX_FAINT_FALL, $20,$c0 ; AGILITY - db SFX_BATTLE_25, $00,$10 ; QUICK_ATTACK - db SFX_BATTLE_26, $f0,$20 ; RAGE - db SFX_BATTLE_33, $f0,$c0 ; TELEPORT - db SFX_NOT_VERY_EFFECTIVE,$f0,$e0 ; NIGHT_SHADE - db SFX_BATTLE_09, $f0,$40 ; MIMIC - db SFX_BATTLE_31, $00,$80 ; SCREECH - db SFX_BATTLE_33, $80,$40 ; DOUBLE_TEAM - db SFX_BATTLE_33, $00,$80 ; RECOVER - db SFX_BATTLE_14, $11,$20 ; HARDEN - db SFX_BATTLE_14, $22,$10 ; MINIMIZE - db SFX_BATTLE_1B, $f1,$ff ; SMOKESCREEN - db SFX_BATTLE_13, $f1,$ff ; CONFUSE_RAY - db SFX_BATTLE_14, $33,$30 ; WITHDRAW - db SFX_BATTLE_32, $40,$c0 ; DEFENSE_CURL - db SFX_BATTLE_0E, $20,$20 ; BARRIER - db SFX_BATTLE_0E, $f0,$10 ; LIGHT_SCREEN - db SFX_BATTLE_0F, $f8,$10 ; HAZE - db SFX_NOT_VERY_EFFECTIVE,$f0,$10 ; REFLECT - db SFX_BATTLE_25, $00,$80 ; FOCUS_ENERGY - db SFX_BATTLE_18, $00,$c0 ; BIDE - db SFX_BATTLE_32, $c0,$ff ; METRONOME - db SFX_BATTLE_09, $f2,$20 ; MIRROR_MOVE - db SFX_BATTLE_34, $00,$80 ; SELFDESTRUCT - db SFX_BATTLE_34, $00,$40 ; EGG_BOMB - db SFX_BATTLE_09, $00,$40 ; LICK - db SFX_NOT_VERY_EFFECTIVE,$10,$ff ; SMOG - db SFX_BATTLE_2A, $20,$20 ; SLUDGE - db SFX_BATTLE_32, $00,$80 ; BONE_CLUB - db SFX_BATTLE_29, $1f,$20 ; FIRE_BLAST - db SFX_BATTLE_25, $2f,$80 ; WATERFALL - db SFX_BATTLE_0F, $1f,$ff ; CLAMP - db SFX_BATTLE_2B, $1f,$60 ; SWIFT - db SFX_BATTLE_26, $1e,$20 ; SKULL_BASH - db SFX_BATTLE_26, $1f,$18 ; SPIKE_CANNON - db SFX_BATTLE_14, $0f,$80 ; CONSTRICT - db SFX_BATTLE_09, $f8,$10 ; AMNESIA - db SFX_FAINT_FALL, $18,$20 ; KINESIS - db SFX_BATTLE_32, $08,$40 ; SOFTBOILED - db SFX_BATTLE_17, $01,$e0 ; HI_JUMP_KICK - db SFX_NOT_VERY_EFFECTIVE,$09,$ff ; GLARE - db SFX_BATTLE_35, $42,$01 ; DREAM_EATER - db SFX_BATTLE_1C, $00,$ff ; POISON_GAS - db SFX_BATTLE_32, $08,$e0 ; BARRAGE - db SFX_BATTLE_24, $00,$80 ; LEECH_LIFE - db SFX_BATTLE_09, $88,$10 ; LOVELY_KISS - db SFX_BATTLE_25, $48,$ff ; SKY_ATTACK - db SFX_FAINT_FALL, $ff,$ff ; TRANSFORM - db SFX_BATTLE_24, $ff,$10 ; BUBBLE - db SFX_FAINT_FALL, $ff,$04 ; DIZZY_PUNCH - db SFX_BATTLE_1C, $01,$ff ; SPORE - db SFX_BATTLE_13, $f8,$ff ; FLASH - db SFX_BATTLE_0C, $f0,$f0 ; PSYWAVE - db SFX_BATTLE_0F, $08,$10 ; SPLASH - db SFX_BATTLE_0D, $f0,$ff ; ACID_ARMOR - db SFX_SUPER_EFFECTIVE, $f0,$ff ; CRABHAMMER - db SFX_BATTLE_34, $10,$ff ; EXPLOSION - db SFX_BATTLE_0E, $f0,$20 ; FURY_SWIPES - db SFX_BATTLE_2B, $f0,$60 ; BONEMERANG - db SFX_BATTLE_21, $12,$10 ; REST - db SFX_BATTLE_36, $f0,$20 ; ROCK_SLIDE - db SFX_BATTLE_1E, $12,$ff ; HYPER_FANG - db SFX_BATTLE_31, $80,$04 ; SHARPEN - db SFX_BATTLE_33, $f0,$10 ; CONVERSION - db SFX_BATTLE_29, $f8,$ff ; TRI_ATTACK - db SFX_BATTLE_26, $f0,$ff ; SUPER_FANG - db SFX_NOT_VERY_EFFECTIVE,$01,$ff ; SLASH - db SFX_BATTLE_2C, $d8,$04 ; SUBSTITUTE - db SFX_BATTLE_0B, $00,$80 ; STRUGGLE - db SFX_BATTLE_0B, $00,$80 + db SFX_POUND, $00, $80 ; POUND + db SFX_BATTLE_0C, $10, $80 ; KARATE_CHOP + db SFX_DOUBLESLAP, $00, $80 ; DOUBLESLAP + db SFX_BATTLE_0B, $01, $80 ; COMET_PUNCH + db SFX_BATTLE_0D, $00, $40 ; MEGA_PUNCH + db SFX_SILPH_SCOPE, $00, $ff ; PAY_DAY + db SFX_BATTLE_0D, $10, $60 ; FIRE_PUNCH + db SFX_BATTLE_0D, $20, $80 ; ICE_PUNCH + db SFX_BATTLE_0D, $00, $a0 ; THUNDERPUNCH + db SFX_DAMAGE, $00, $80 ; SCRATCH + db SFX_BATTLE_0F, $20, $40 ; VICEGRIP + db SFX_BATTLE_0F, $00, $80 ; GUILLOTINE + db SFX_BATTLE_0E, $00, $a0 ; RAZOR_WIND + db SFX_NOT_VERY_EFFECTIVE, $10, $c0 ; SWORDS_DANCE + db SFX_NOT_VERY_EFFECTIVE, $00, $a0 ; CUT + db SFX_BATTLE_12, $00, $c0 ; GUST + db SFX_BATTLE_12, $10, $a0 ; WING_ATTACK + db SFX_BATTLE_13, $00, $e0 ; WHIRLWIND + db SFX_NOT_VERY_EFFECTIVE, $20, $c0 ; FLY + db SFX_BATTLE_14, $00, $80 ; BIND + db SFX_BATTLE_22, $00, $80 ; SLAM + db SFX_VINE_WHIP, $01, $80 ; VINE_WHIP + db SFX_BATTLE_20, $00, $80 ; STOMP + db SFX_BATTLE_17, $f0, $40 ; DOUBLE_KICK + db SFX_SUPER_EFFECTIVE, $00, $80 ; MEGA_KICK + db SFX_BATTLE_17, $00, $80 ; JUMP_KICK + db SFX_BATTLE_21, $10, $80 ; ROLLING_KICK + db SFX_BATTLE_1B, $01, $a0 ; SAND_ATTACK + db SFX_BATTLE_18, $00, $80 ; HEADBUTT + db SFX_BATTLE_1E, $00, $60 ; HORN_ATTACK + db SFX_BATTLE_1E, $01, $40 ; FURY_ATTACK + db SFX_HORN_DRILL, $00, $a0 ; HORN_DRILL + db SFX_SUPER_EFFECTIVE, $10, $a0 ; TACKLE + db SFX_BATTLE_20, $00, $c0 ; BODY_SLAM + db SFX_BATTLE_14, $10, $60 ; WRAP + db SFX_SUPER_EFFECTIVE, $00, $a0 ; TAKE_DOWN + db SFX_BATTLE_22, $11, $c0 ; THRASH + db SFX_SUPER_EFFECTIVE, $20, $c0 ; DOUBLE_EDGE + db SFX_BATTLE_21, $00, $80 ; TAIL_WHIP + db SFX_BATTLE_1B, $00, $80 ; POISON_STING + db SFX_BATTLE_1B, $20, $c0 ; TWINEEDLE + db SFX_BATTLE_19, $00, $80 ; PIN_MISSILE + db SFX_BATTLE_31, $ff, $40 ; LEER + db SFX_BATTLE_1E, $00, $80 ; BITE + db SFX_BATTLE_0B, $00, $c0 ; GROWL + db SFX_BATTLE_0B, $00, $40 ; ROAR + db SFX_BATTLE_35, $00, $80 ; SING + db SFX_BATTLE_27, $40, $60 ; SUPERSONIC + db SFX_BATTLE_27, $00, $80 ; SONICBOOM + db SFX_BATTLE_27, $ff, $40 ; DISABLE + db SFX_BATTLE_2A, $80, $c0 ; ACID + db SFX_BATTLE_19, $10, $a0 ; EMBER + db SFX_BATTLE_19, $21, $e0 ; FLAMETHROWER + db SFX_BATTLE_29, $00, $80 ; MIST + db SFX_BATTLE_24, $20, $60 ; WATER_GUN + db SFX_BATTLE_2A, $00, $80 ; HYDRO_PUMP + db SFX_BATTLE_2C, $00, $80 ; SURF + db SFX_BATTLE_28, $40, $80 ; ICE_BEAM + db SFX_BATTLE_29, $f0, $e0 ; BLIZZARD + db SFX_PSYBEAM, $00, $80 ; PSYBEAM + db SFX_BATTLE_2A, $f0, $60 ; BUBBLEBEAM + db SFX_BATTLE_28, $00, $80 ; AURORA_BEAM + db SFX_BATTLE_36, $00, $80 ; HYPER_BEAM + db SFX_PECK, $01, $a0 ; PECK + db SFX_BATTLE_13, $f0, $20 ; DRILL_PECK + db SFX_BATTLE_23, $01, $c0 ; SUBMISSION + db SFX_BATTLE_23, $00, $80 ; LOW_KICK + db SFX_SUPER_EFFECTIVE, $00, $e0 ; COUNTER + db SFX_BATTLE_26, $01, $60 ; SEISMIC_TOSS + db SFX_BATTLE_26, $20, $40 ; STRENGTH + db SFX_BATTLE_24, $00, $80 ; ABSORB + db SFX_BATTLE_24, $40, $c0 ; MEGA_DRAIN + db SFX_BATTLE_1B, $03, $60 ; LEECH_SEED + db SFX_BATTLE_25, $11, $e0 ; GROWTH + db SFX_BATTLE_12, $20, $e0 ; RAZOR_LEAF + db SFX_BATTLE_2E, $00, $80 ; SOLARBEAM + db SFX_BATTLE_1C, $00, $80 ; POISONPOWDER + db SFX_BATTLE_1C, $11, $a0 ; STUN_SPORE + db SFX_BATTLE_1C, $01, $c0 ; SLEEP_POWDER + db SFX_BATTLE_13, $14, $c0 ; PETAL_DANCE + db SFX_BATTLE_1B, $02, $a0 ; STRING_SHOT + db SFX_BATTLE_29, $f0, $80 ; DRAGON_RAGE + db SFX_BATTLE_29, $20, $c0 ; FIRE_SPIN + db SFX_BATTLE_2F, $00, $20 ; THUNDERSHOCK + db SFX_BATTLE_2F, $20, $80 ; THUNDERBOLT + db SFX_BATTLE_2E, $12, $60 ; THUNDER_WAVE + db SFX_BATTLE_26, $00, $80 ; THUNDER + db SFX_BATTLE_14, $01, $e0 ; ROCK_THROW + db SFX_BATTLE_29, $0f, $e0 ; EARTHQUAKE + db SFX_BATTLE_29, $11, $20 ; FISSURE + db SFX_DAMAGE, $10, $40 ; DIG + db SFX_BATTLE_0F, $10, $c0 ; TOXIC + db SFX_BATTLE_14, $00, $20 ; CONFUSION + db SFX_PSYCHIC_M, $00, $80 ; PSYCHIC_M + db SFX_BATTLE_35, $11, $18 ; HYPNOSIS + db SFX_BATTLE_09, $20, $c0 ; MEDITATE + db SFX_FAINT_FALL, $20, $c0 ; AGILITY + db SFX_BATTLE_25, $00, $10 ; QUICK_ATTACK + db SFX_BATTLE_26, $f0, $20 ; RAGE + db SFX_BATTLE_33, $f0, $c0 ; TELEPORT + db SFX_NOT_VERY_EFFECTIVE, $f0, $e0 ; NIGHT_SHADE + db SFX_BATTLE_09, $f0, $40 ; MIMIC + db SFX_BATTLE_31, $00, $80 ; SCREECH + db SFX_BATTLE_33, $80, $40 ; DOUBLE_TEAM + db SFX_BATTLE_33, $00, $80 ; RECOVER + db SFX_BATTLE_14, $11, $20 ; HARDEN + db SFX_BATTLE_14, $22, $10 ; MINIMIZE + db SFX_BATTLE_1B, $f1, $ff ; SMOKESCREEN + db SFX_BATTLE_13, $f1, $ff ; CONFUSE_RAY + db SFX_BATTLE_14, $33, $30 ; WITHDRAW + db SFX_BATTLE_32, $40, $c0 ; DEFENSE_CURL + db SFX_BATTLE_0E, $20, $20 ; BARRIER + db SFX_BATTLE_0E, $f0, $10 ; LIGHT_SCREEN + db SFX_BATTLE_0F, $f8, $10 ; HAZE + db SFX_NOT_VERY_EFFECTIVE, $f0, $10 ; REFLECT + db SFX_BATTLE_25, $00, $80 ; FOCUS_ENERGY + db SFX_BATTLE_18, $00, $c0 ; BIDE + db SFX_BATTLE_32, $c0, $ff ; METRONOME + db SFX_BATTLE_09, $f2, $20 ; MIRROR_MOVE + db SFX_BATTLE_34, $00, $80 ; SELFDESTRUCT + db SFX_BATTLE_34, $00, $40 ; EGG_BOMB + db SFX_BATTLE_09, $00, $40 ; LICK + db SFX_NOT_VERY_EFFECTIVE, $10, $ff ; SMOG + db SFX_BATTLE_2A, $20, $20 ; SLUDGE + db SFX_BATTLE_32, $00, $80 ; BONE_CLUB + db SFX_BATTLE_29, $1f, $20 ; FIRE_BLAST + db SFX_BATTLE_25, $2f, $80 ; WATERFALL + db SFX_BATTLE_0F, $1f, $ff ; CLAMP + db SFX_BATTLE_2B, $1f, $60 ; SWIFT + db SFX_BATTLE_26, $1e, $20 ; SKULL_BASH + db SFX_BATTLE_26, $1f, $18 ; SPIKE_CANNON + db SFX_BATTLE_14, $0f, $80 ; CONSTRICT + db SFX_BATTLE_09, $f8, $10 ; AMNESIA + db SFX_FAINT_FALL, $18, $20 ; KINESIS + db SFX_BATTLE_32, $08, $40 ; SOFTBOILED + db SFX_BATTLE_17, $01, $e0 ; HI_JUMP_KICK + db SFX_NOT_VERY_EFFECTIVE, $09, $ff ; GLARE + db SFX_BATTLE_35, $42, $01 ; DREAM_EATER + db SFX_BATTLE_1C, $00, $ff ; POISON_GAS + db SFX_BATTLE_32, $08, $e0 ; BARRAGE + db SFX_BATTLE_24, $00, $80 ; LEECH_LIFE + db SFX_BATTLE_09, $88, $10 ; LOVELY_KISS + db SFX_BATTLE_25, $48, $ff ; SKY_ATTACK + db SFX_FAINT_FALL, $ff, $ff ; TRANSFORM + db SFX_BATTLE_24, $ff, $10 ; BUBBLE + db SFX_FAINT_FALL, $ff, $04 ; DIZZY_PUNCH + db SFX_BATTLE_1C, $01, $ff ; SPORE + db SFX_BATTLE_13, $f8, $ff ; FLASH + db SFX_BATTLE_0C, $f0, $f0 ; PSYWAVE + db SFX_BATTLE_0F, $08, $10 ; SPLASH + db SFX_BATTLE_0D, $f0, $ff ; ACID_ARMOR + db SFX_SUPER_EFFECTIVE, $f0, $ff ; CRABHAMMER + db SFX_BATTLE_34, $10, $ff ; EXPLOSION + db SFX_BATTLE_0E, $f0, $20 ; FURY_SWIPES + db SFX_BATTLE_2B, $f0, $60 ; BONEMERANG + db SFX_BATTLE_21, $12, $10 ; REST + db SFX_BATTLE_36, $f0, $20 ; ROCK_SLIDE + db SFX_BATTLE_1E, $12, $ff ; HYPER_FANG + db SFX_BATTLE_31, $80, $04 ; SHARPEN + db SFX_BATTLE_33, $f0, $10 ; CONVERSION + db SFX_BATTLE_29, $f8, $ff ; TRI_ATTACK + db SFX_BATTLE_26, $f0, $ff ; SUPER_FANG + db SFX_NOT_VERY_EFFECTIVE, $01, $ff ; SLASH + db SFX_BATTLE_2C, $d8, $04 ; SUBSTITUTE + db SFX_BATTLE_0B, $00, $80 ; STRUGGLE + db SFX_BATTLE_0B, $00, $80 CopyPicTiles: ld a, [H_WHOSETURN] @@ -2587,112 +2759,108 @@ CopyTileIDs: ret TileIDListPointerTable: - dw Unknown_79b24 - dn 7, 7 - dw Unknown_79b55 - dn 5, 7 - dw Unknown_79b78 - dn 3, 7 + dw DownscaledMonTiles_7x7 + dn 7, 7 + dw DownscaledMonTiles_5x7 + dn 5, 7 + dw DownscaledMonTiles_3x7 + dn 3, 7 dw GengarIntroTiles1 - dn 7, 7 + dn 7, 7 dw GengarIntroTiles2 - dn 7, 7 + dn 7, 7 dw GengarIntroTiles3 - dn 7, 7 - dw Unknown_79c20 - dn 8, 6 - dw Unknown_79c50 - dn 3, 12 + dn 7, 7 + dw DownscaledMonTiles_79d7c + dn 8, 6 + dw DownscaledMonTiles_79dac + dn 3, 12 DownscaledMonTiles_5x5: - db $31,$38,$46,$54,$5B - db $32,$39,$47,$55,$5C - db $34,$3B,$49,$57,$5E - db $36,$3D,$4B,$59,$60 - db $37,$3E,$4C,$5A,$61 + db $31, $38, $46, $54, $5B + db $32, $39, $47, $55, $5C + db $34, $3B, $49, $57, $5E + db $36, $3D, $4B, $59, $60 + db $37, $3E, $4C, $5A, $61 DownscaledMonTiles_3x3: - db $31,$46,$5B - db $34,$49,$5E - db $37,$4C,$61 - -Unknown_79b24: - db $00,$07,$0E,$15,$1C,$23,$2A - db $01,$08,$0F,$16,$1D,$24,$2B - db $02,$09,$10,$17,$1E,$25,$2C - db $03,$0A,$11,$18,$1F,$26,$2D - db $04,$0B,$12,$19,$20,$27,$2E - db $05,$0C,$13,$1A,$21,$28,$2F - db $06,$0D,$14,$1B,$22,$29,$30 - -Unknown_79b55: - db $00,$07,$0E,$15,$1C,$23,$2A - db $01,$08,$0F,$16,$1D,$24,$2B - db $03,$0A,$11,$18,$1F,$26,$2D - db $04,$0B,$12,$19,$20,$27,$2E - db $05,$0C,$13,$1A,$21,$28,$2F - -Unknown_79b78: - db $00,$07,$0E,$15,$1C,$23,$2A - db $02,$09,$10,$17,$1E,$25,$2C - db $04,$0B,$12,$19,$20,$27,$2E + db $31, $46, $5B + db $34, $49, $5E + db $37, $4C, $61 + +DownscaledMonTiles_7x7: + db $00, $07, $0E, $15, $1C, $23, $2A + db $01, $08, $0F, $16, $1D, $24, $2B + db $02, $09, $10, $17, $1E, $25, $2C + db $03, $0A, $11, $18, $1F, $26, $2D + db $04, $0B, $12, $19, $20, $27, $2E + db $05, $0C, $13, $1A, $21, $28, $2F + db $06, $0D, $14, $1B, $22, $29, $30 + +DownscaledMonTiles_5x7: + db $00, $07, $0E, $15, $1C, $23, $2A + db $01, $08, $0F, $16, $1D, $24, $2B + db $03, $0A, $11, $18, $1F, $26, $2D + db $04, $0B, $12, $19, $20, $27, $2E + db $05, $0C, $13, $1A, $21, $28, $2F + +DownscaledMonTiles_3x7: + db $00, $07, $0E, $15, $1C, $23, $2A + db $02, $09, $10, $17, $1E, $25, $2C + db $04, $0B, $12, $19, $20, $27, $2E GengarIntroTiles1: - db $00,$00,$00,$00,$00,$00,$00 - db $00,$00,$00,$00,$00,$19,$00 - db $02,$06,$0B,$10,$14,$1A,$00 - db $00,$07,$0C,$11,$15,$1B,$00 - db $03,$08,$0D,$12,$16,$1C,$00 - db $04,$09,$0E,$13,$17,$1D,$1F - db $05,$0A,$0F,$01,$18,$1E,$20 + db $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $19, $00 + db $02, $06, $0B, $10, $14, $1A, $00 + db $00, $07, $0C, $11, $15, $1B, $00 + db $03, $08, $0D, $12, $16, $1C, $00 + db $04, $09, $0E, $13, $17, $1D, $1F + db $05, $0A, $0F, $01, $18, $1E, $20 GengarIntroTiles2: - db $00,$00,$00,$30,$00,$37,$00 - db $00,$00,$2B,$31,$34,$38,$3D - db $21,$26,$2C,$01,$35,$39,$3E - db $22,$27,$2D,$32,$36,$01,$00 - db $23,$28,$2E,$33,$01,$3A,$00 - db $24,$29,$2F,$01,$01,$3B,$00 - db $25,$2A,$01,$01,$01,$3C,$00 + db $00, $00, $00, $30, $00, $37, $00 + db $00, $00, $2B, $31, $34, $38, $3D + db $21, $26, $2C, $01, $35, $39, $3E + db $22, $27, $2D, $32, $36, $01, $00 + db $23, $28, $2E, $33, $01, $3A, $00 + db $24, $29, $2F, $01, $01, $3B, $00 + db $25, $2A, $01, $01, $01, $3C, $00 GengarIntroTiles3: - db $00,$00,$00,$00,$00,$00,$00 - db $00,$00,$47,$4D,$00,$00,$00 - db $00,$00,$48,$4E,$52,$56,$5B - db $3F,$43,$49,$4F,$53,$57,$5C - db $40,$44,$4A,$50,$54,$58,$00 - db $41,$45,$4B,$51,$4C,$59,$5D - db $42,$46,$4C,$4C,$55,$5A,$5E - -Unknown_79c20: - db $31,$32,$32,$32,$32,$33 - db $34,$35,$36,$36,$37,$38 - db $34,$39,$3A,$3A,$3B,$38 - db $3C,$3D,$3E,$3E,$3F,$40 - db $41,$42,$43,$43,$44,$45 - db $46,$47,$43,$48,$49,$4A - db $41,$43,$4B,$4C,$4D,$4E - db $4F,$50,$50,$50,$51,$52 - -Unknown_79c50: - db $43,$55,$56,$53,$53,$53,$53,$53,$53,$53,$53,$53 - db $43,$57,$58,$54,$54,$54,$54,$54,$54,$54,$54,$54 - db $43,$59,$5A,$43,$43,$43,$43,$43,$43,$43,$43,$43 + db $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $47, $4D, $00, $00, $00 + db $00, $00, $48, $4E, $52, $56, $5B + db $3F, $43, $49, $4F, $53, $57, $5C + db $40, $44, $4A, $50, $54, $58, $00 + db $41, $45, $4B, $51, $4C, $59, $5D + db $42, $46, $4C, $4C, $55, $5A, $5E + +DownscaledMonTiles_79d7c: + db $31, $32, $32, $32, $32, $33 + db $34, $35, $36, $36, $37, $38 + db $34, $39, $3A, $3A, $3B, $38 + db $3C, $3D, $3E, $3E, $3F, $40 + db $41, $42, $43, $43, $44, $45 + db $46, $47, $43, $48, $49, $4A + db $41, $43, $4B, $4C, $4D, $4E + db $4F, $50, $50, $50, $51, $52 + +DownscaledMonTiles_79dac: + db $43, $55, $56, $53, $53, $53, $53, $53, $53, $53, $53, $53 + db $43, $57, $58, $54, $54, $54, $54, $54, $54, $54, $54, $54 + db $43, $59, $5A, $43, $43, $43, $43, $43, $43, $43, $43, $43 AnimationLeavesFalling: ; Makes leaves float down from the top of the screen. This is used ; in Razor Leaf's animation. - ld a, [rOBP0] - push af ld a, [wAnimPalette] ld [rOBP0], a + call UpdateGBCPal_OBP0 ld d, $37 ; leaf tile ld a, 3 ; number of leaves ld [wNumFallingObjects], a - call AnimationFallingObjects - pop af - ld [rOBP0], a - ret + jp AnimationFallingObjects AnimationPetalsFalling: ; Makes lots of petals fall down from the top of the screen. It's used in @@ -2747,6 +2915,8 @@ FallingObjects_UpdateOAMEntry: ; movement byte. ld hl, wOAMBuffer add hl, de + ld a, $1 + ld [wdef5], a ld a, [hl] inc a inc a @@ -2755,6 +2925,12 @@ FallingObjects_UpdateOAMEntry: ld a, 160 ; if Y >= 112, put it off-screen .next ld [hli], a ; Y + cp 40 + jr c, .asm_79e51 + ld a, [wdef5] + inc a + ld [wdef5], a +.asm_79e51 ld a, [wFallingObjectMovementByte] ld b, a ld de, FallingObjects_DeltaXs @@ -2771,6 +2947,13 @@ FallingObjects_UpdateOAMEntry: ld a, [de] add [hl] ld [hli], a ; X + cp 88 + jr c, .asm_79e75 + ld a, [wdef5] + add $2 + and $3 + ld [wdef5], a +.asm_79e75 inc hl xor a ; no horizontal flip jr .next2 @@ -2780,9 +2963,19 @@ FallingObjects_UpdateOAMEntry: ld a, [hl] sub b ld [hli], a ; X + cp 88 + jr c, .asm_79e5c + ld a, [wdef5] + add $2 + and $3 + ld [wdef5], a +.asm_79e5c inc hl ld a, (1 << OAM_X_FLIP) .next2 + ld b, a + ld a, [wdef5] + or b ld [hl], a ; attribute ret @@ -2822,7 +3015,7 @@ FallingObjects_InitXCoords: ret FallingObjects_InitialXCoords: - db $38,$40,$50,$60,$70,$88,$90,$56,$67,$4A,$77,$84,$98,$32,$22,$5C,$6C,$7D,$8E,$99 + db $38, $40, $50, $60, $70, $88, $90, $56, $67, $4A, $77, $84, $98, $32, $22, $5C, $6C, $7D, $8E, $99 FallingObjects_InitMovementData: ld hl, wFallingObjectsMovementData @@ -2838,7 +3031,7 @@ FallingObjects_InitMovementData: ret FallingObjects_InitialMovementData: - db $00,$84,$06,$81,$02,$88,$01,$83,$05,$89,$09,$80,$07,$87,$03,$82,$04,$85,$08,$86 + db $00, $84, $06, $81, $02, $88, $01, $83, $05, $89, $09, $80, $07, $87, $03, $82, $04, $85, $08, $86 AnimationShakeEnemyHUD: ; Shakes the enemy HUD. @@ -2867,6 +3060,14 @@ AnimationShakeEnemyHUD: ld hl, vBGMap1 - $20 * 7 call BattleAnimCopyTileMapToVRAM +; update BGMap attributes + ld a, [hGBC] + and a + jr z, .notGBC + ld c, 13 + callba LoadBGMapAttributes +.notGBC + ; Move the window so that the row below the enemy HUD (in BG map 0) lines up ; with the top row of the window on the screen. This makes it so that the window ; covers everything below the enemy HD with a copy that looks just like what @@ -2900,13 +3101,18 @@ AnimationShakeEnemyHUD: ld [hWY], a ld hl, vBGMap1 call BattleAnimCopyTileMapToVRAM +; update BGMap attributes + ld a, [hGBC] + and a + jr z, .notGBC2 + ld c, 11 + callba LoadBGMapAttributes +.notGBC2 xor a ld [hWY], a call SaveScreenTilesToBuffer1 ld hl, vBGMap0 call BattleAnimCopyTileMapToVRAM - call ClearScreen - call Delay3 call LoadScreenTilesFromBuffer1 ld hl, vBGMap1 jp BattleAnimCopyTileMapToVRAM @@ -2995,7 +3201,7 @@ TossBallAnimation: .PokeBallAnimations: ; sequence of animations that make up the Poké Ball toss - db POOF_ANIM,HIDEPIC_ANIM,SHAKE_ANIM,POOF_ANIM,SHOWPIC_ANIM + db POOF_ANIM, HIDEPIC_ANIM, SHAKE_ANIM, POOF_ANIM, SHOWPIC_ANIM .BlockBall ld a, TOSS_ANIM diff --git a/engine/battle/bank3d_battle.asm b/engine/battle/bank3d_battle.asm new file mode 100644 index 00000000..0cf24fe1 --- /dev/null +++ b/engine/battle/bank3d_battle.asm @@ -0,0 +1,291 @@ +InitBattle: + ld a, [wCurOpponent] + and a + jr z, asm_f6003 + +InitOpponent: + ld a, [wCurOpponent] + ld [wcf91], a + ld [wEnemyMonSpecies2], a + jr asm_f601d +asm_f6003: + ld a, [wd732] + bit 1, a + jr z, .asm_f600f + ld a, [hJoyHeld] + bit 1, a ; B button pressed? + ret nz +.asm_f600f + ld a, [wNumberOfNoRandomBattleStepsLeft] + and a + ret nz + callab TryDoWildEncounter + ret nz +asm_f601d: + ld a, [wMapPalOffset] + push af + ld hl, wLetterPrintingDelayFlags + ld a, [hl] + push af + res 1, [hl] + call InitBattleVariables + ld a, [wEnemyMonSpecies2] + sub OPP_ID_OFFSET + jp c, InitWildBattle + ld [wTrainerClass], a + call GetTrainerInformation + callab ReadTrainer + callab DoBattleTransitionAndInitBattleVariables + call _LoadTrainerPic + xor a + ld [wEnemyMonSpecies2], a + ld [$ffe1], a + dec a + ld [wAICount], a + coord hl, 12, 0 + predef CopyUncompressedPicToTilemap + ld a, $ff + ld [wEnemyMonPartyPos], a + ld a, $2 + ld [wIsInBattle], a + + ; Is this a major story battle? + ld a,[wLoneAttackNo] + and a + jp z,InitBattle_Common + callabd_ModifyPikachuHappiness PIKAHAPPY_GYMLEADER ; useless since already in bank3d + jp InitBattle_Common + +InitWildBattle: + ld a, $1 + ld [wIsInBattle], a + callab LoadEnemyMonData + callab DoBattleTransitionAndInitBattleVariables + ld a, [wCurOpponent] + cp MAROWAK + jr z, .isGhost + callab IsGhostBattle + jr nz, .isNoGhost +.isGhost + ld hl, wMonHSpriteDim + ld a, $66 + ld [hli], a ; write sprite dimensions + ld bc, GhostPic + ld a, c + 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 a, [wcf91] + push af + ld a, MON_GHOST + ld [wcf91], a + ld de, vFrontPic + call LoadMonFrontSprite ; load ghost sprite + pop af + ld [wcf91], a + jr .spriteLoaded +.isNoGhost + ld de, vFrontPic + call LoadMonFrontSprite ; load mon sprite +.spriteLoaded + xor a + ld [wTrainerClass], a + ld [$ffe1], a + coord hl, 12, 0 + predef CopyUncompressedPicToTilemap + +; common code that executes after init battle code specific to trainer or wild battles +InitBattle_Common: + ld b, $0 + call RunPaletteCommand + callab SlidePlayerAndEnemySilhouettesOnScreen + xor a + ld [H_AUTOBGTRANSFERENABLED], a + ld hl, .emptyString + call PrintText + call SaveScreenTilesToBuffer1 + call ClearScreen + ld a, $98 + ld [$ffbd], a + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a + call Delay3 + ld a, $9c + ld [$ffbd], a + call LoadScreenTilesFromBuffer1 + coord hl, 9, 7 + ld bc, $50a + call ClearScreenArea + coord hl, 1, 0 + ld bc, $40a + call ClearScreenArea + call ClearSprites + ld a, [wIsInBattle] + dec a ; is it a wild battle? + ld hl, DrawEnemyHUDAndHPBar + ld b,BANK(DrawEnemyHUDAndHPBar) + call z, Bankswitch ; draw enemy HUD and HP bar if it's a wild battle + callab StartBattle + callab EndOfBattle + pop af + ld [wLetterPrintingDelayFlags], a + pop af + ld [wMapPalOffset], a + ld a, [wSavedTilesetType] + ld [hTilesetType], a + scf + ret +.emptyString + db "@" + +_LoadTrainerPic: +; wd033-wd034 contain pointer to pic + ld a, [wTrainerPicPointer] + ld e, a + ld a, [wTrainerPicPointer + 1] + ld d, a ; de contains pointer to trainer pic + ld a, [wLinkState] + and a + ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's) + jr z, .loadSprite + ld a, Bank(RedPicFront) +.loadSprite + call UncompressSpriteFromDE + ld de, vFrontPic + ld a, $77 + ld c, a + jp LoadUncompressedSpriteData + +LoadMonBackPic: +; Assumes the monster's attributes have +; been loaded with GetMonHeader. + ld a, [wBattleMonSpecies2] + ld [wcf91], a + coord hl, 1, 5 + ld bc,$708 + call ClearScreenArea + ld hl, wMonHBackSprite - wMonHeader + call UncompressMonSprite + predef ScaleSpriteByTwo + ld de, vBackPic + call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite + ld hl, vSprites + ld de, vBackPic + ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied + ld a, [H_LOADEDROMBANK] + ld b, a + jp CopyVideoData + +AnimateSendingOutMon: + ld a, [wPredefRegisters] + ld h, a + ld a, [wPredefRegisters + 1] + ld l, a + ld a, [$ffe1] + ld [H_DOWNARROWBLINKCNT1], a + ld b, $4c + ld a, [wIsInBattle] + and a + jr z, .asm_f61ef + add b + ld [hl], a + call Delay3 + ld bc, -41 + add hl, bc + ld a, $1 + ld [wNumMovesMinusOne], a + ld bc, $303 + predef CopyDownscaledMonTiles + ld c, $4 + call DelayFrames + ld bc, -41 + add hl, bc + xor a + ld [wNumMovesMinusOne], a + ld bc, $505 + predef CopyDownscaledMonTiles + ld c, $5 + call DelayFrames + ld bc, -41 + jr .asm_f61f2 +.asm_f61ef + ld bc, -123 +.asm_f61f2 + add hl, bc + ld a, [H_DOWNARROWBLINKCNT1] + add $31 + jr CopyUncompressedPicToHL + +CopyUncompressedPicToTilemap: + ld a, [wPredefRegisters] + ld h, a + ld a, [wPredefRegisters + 1] + ld l, a + ld a, [$ffe1] +CopyUncompressedPicToHL: + ld bc, $707 + ld de, $14 + push af + ld a, [wSpriteFlipped] + and a + jr nz, .asm_f6220 + pop af +.asm_f6211 + push bc + push hl +.asm_f6213 + ld [hl], a + add hl, de + inc a + dec c + jr nz, .asm_f6213 + pop hl + inc hl + pop bc + dec b + jr nz, .asm_f6211 + ret + +.asm_f6220 + push bc + ld b, $0 + dec c + add hl, bc + pop bc + pop af +.asm_f6227 + push bc + push hl +.asm_f6229 + ld [hl], a + add hl, de + inc a + dec c + jr nz, .asm_f6229 + pop hl + dec hl + pop bc + dec b + jr nz, .asm_f6227 + ret + +INCLUDE "engine/battle/init_battle_variables.asm" +INCLUDE "engine/battle/moveEffects/focus_energy_effect.asm" +INCLUDE "engine/battle/moveEffects/heal_effect.asm" +INCLUDE "engine/battle/moveEffects/transform_effect.asm" +INCLUDE "engine/battle/moveEffects/reflect_light_screen_effect.asm" +INCLUDE "engine/battle/moveEffects/mist_effect.asm" +INCLUDE "engine/battle/moveEffects/one_hit_ko_effect.asm" +INCLUDE "engine/battle/moveEffects/pay_day_effect.asm" +INCLUDE "engine/battle/moveEffects/paralyze_effect.asm" diff --git a/engine/battle/bank_e_misc.asm b/engine/battle/bank_e_misc.asm index 33af6f6f..df9145f2 100755 --- a/engine/battle/bank_e_misc.asm +++ b/engine/battle/bank_e_misc.asm @@ -101,22 +101,3 @@ InitList: ld a, b ld [wItemPrices + 1], a ret - -; get species of mon e in list [wMonDataLocation] for LoadMonData -GetMonSpecies: - ld hl, wPartySpecies - ld a, [wMonDataLocation] - and a - jr z, .getSpecies - dec a - jr z, .enemyParty - ld hl, wBoxSpecies - jr .getSpecies -.enemyParty - ld hl, wEnemyPartyMons -.getSpecies - ld d, 0 - add hl, de - ld a, [hl] - ld [wcf91], a - ret diff --git a/engine/battle/battle_transitions.asm b/engine/battle/battle_transitions.asm index 436e38b5..e4392a01 100644 --- a/engine/battle/battle_transitions.asm +++ b/engine/battle/battle_transitions.asm @@ -196,6 +196,9 @@ BattleTransition_BlackScreen: ld [rBGP], a ld [rOBP0], a ld [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ret ; for non-dungeon trainer battles @@ -359,6 +362,7 @@ BattleTransition_FlashScreen_: cp $1 jr z, .done ld [rBGP], a + call UpdateGBCPal_BGP ld c, 2 call DelayFrames jr .loop @@ -373,7 +377,7 @@ BattleTransition_FlashScreenPalettes: ; used for low level trainer dungeon battles BattleTransition_Shrink: - ld c, SCREEN_HEIGHT / 2 + ld c, 9 .loop push bc xor a @@ -407,7 +411,7 @@ BattleTransition_Shrink: ; used for high level trainer dungeon battles BattleTransition_Split: - ld c, SCREEN_HEIGHT / 2 + ld c, 9 xor a ld [H_AUTOBGTRANSFERENABLED], a .loop diff --git a/engine/battle/common_text.asm b/engine/battle/common_text.asm index 4a138048..e8f4f002 100644 --- a/engine/battle/common_text.asm +++ b/engine/battle/common_text.asm @@ -8,8 +8,20 @@ PrintBeginningBattleText: cp MR_FUJIS_HOUSE jr c, .pokemonTower .notPokemonTower + ld a,[wBattleType] + cp BATTLE_TYPE_PIKACHU + jr nz,.notPikachuBattle + callab IsPlayerPikachuAsleepInParty + ld e,$24 + jr c,.asm_f4026 + ld e,$a +.asm_f4026 + callab PlayPikachuSoundClip + jr .continue +.notPikachuBattle ld a, [wEnemyMonSpecies2] call PlayCry +.continue ld hl, WildMonAppearedText ld a, [wMoveMissed] and a @@ -23,9 +35,13 @@ PrintBeginningBattleText: call DelayFrames ld hl, TrainerWantsToFightText .wildBattle + ld a, [wBattleType] + and a + jr nz, .doNotDrawPokeballs push hl callab DrawAllPokeballs pop hl +.doNotDrawPokeballs call PrintText jr .done .pokemonTower diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 2b00a812..60146902 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -157,6 +157,9 @@ SlidePlayerAndEnemySilhouettesOnScreen: ld [rBGP], a ld [rOBP0], a ld [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 .slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen ld h, b ld l, $40 @@ -246,10 +249,16 @@ StartBattle: call DelayFrames call SaveScreenTilesToBuffer1 .checkAnyPartyAlive + ld a, [wBattleType] + cp BATTLE_TYPE_RUN + jp z, .specialBattle + cp BATTLE_TYPE_PIKACHU + jp z, .specialBattle call AnyPartyAlive ld a, d and a jp z, HandlePlayerBlackOut ; jump if no mon is alive +.specialBattle call LoadScreenTilesFromBuffer1 ld a, [wBattleType] and a ; is it a normal battle? @@ -983,6 +992,11 @@ ReplaceFaintedEnemyMon: ld hl, wEnemyHPBarColor ld e, $30 call GetBattleHealthBarColor + setpal SHADE_BLACK, SHADE_DARK, SHADE_LIGHT, SHADE_WHITE + ld [rOBP0], a + ld [rOBP1], a + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 callab DrawEnemyPokeballs ld a, [wLinkState] cp LINK_STATE_BATTLING @@ -1048,9 +1062,7 @@ TrainerDefeatedText: PlayBattleVictoryMusic: push af - ld a, $ff - ld [wNewSoundID], a - call PlaySoundWaitForCurrent + call StopAllMusic ld c, BANK(Music_DefeatedTrainer) pop af call PlayMusic @@ -1104,6 +1116,7 @@ RemoveFaintedPlayerMon: ld a, $ff ld [wLowHealthAlarm], a ;disable low health alarm call WaitForSoundToFinish + xor a .skipWaitForSound ; a is 0, so this zeroes the enemy's accumulated damage. ld hl, wEnemyBideAccumulatedDamage @@ -1128,10 +1141,36 @@ RemoveFaintedPlayerMon: and a ; was this called by HandleEnemyMonFainted? ret z ; if so, return + ld a, [wPlayerMonNumber] + ld [wWhichPokemon], a + callab IsThisPartymonStarterPikachu_Party + jr nc, .notPlayerPikachu + ld e, $3 + callab PlayPikachuSoundClip + jr .printText +.notPlayerPikachu ld a, [wBattleMonSpecies] call PlayCry +.printText ld hl, PlayerMonFaintedText - jp PrintText + call PrintText + ld a, [wPlayerMonNumber] + ld [wWhichPokemon], a + ld a, [wBattleMonLevel] + ld b, a + ld a, [wEnemyMonLevel] + sub b ; enemylevel - playerlevel + ; are we stronger than the opposing pokemon? + jr c, .regularFaint ; if so, deduct happiness regularly + + cp 30 ; is the enemy 30 levels greater than us? + jr nc, .carelessTrainer ; if so, punish the player for being careless, as they shouldn't be fighting a very high leveled trainer with such a level difference +.regularFaint + callabd_ModifyPikachuHappiness PIKAHAPPY_FAINTED + ret +.carelessTrainer + callabd_ModifyPikachuHappiness PIKAHAPPY_CARELESSTRAINER + ret PlayerMonFaintedText: TX_FAR _PlayerMonFaintedText @@ -1188,7 +1227,7 @@ ChooseNextMon: ld a, [wLinkState] cp LINK_STATE_BATTLING jr nz, .notLinkBattle - inc a + ld a, 1 ld [wActionResultOrTookBattleTurn], a call LinkBattleExchangeData .notLinkBattle @@ -1588,6 +1627,8 @@ TryRunningFromBattle: ld a, [wBattleType] cp BATTLE_TYPE_SAFARI jp z, .canEscape ; jump if it's a safari battle + cp BATTLE_TYPE_RUN + jp z, .canEscape ; hurry, get away? ld a, [wLinkState] cp LINK_STATE_BATTLING jp z, .canEscape @@ -1843,19 +1884,46 @@ SendOutMon: call RunPaletteCommand ld hl, wEnemyBattleStatus1 res USING_TRAPPING_MOVE, [hl] + callab IsThisPartymonStarterPikachu + jr c, .starterPikachu ld a, $1 ld [H_WHOSETURN], a ld a, POOF_ANIM call PlayMoveAnimation coord hl, 4, 11 predef AnimateSendingOutMon + jr .playRegularCry +.starterPikachu + xor a + ld [H_WHOSETURN], a + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a + callab StarterPikachuBattleEntranceAnimation + callab IsPlayerPikachuAsleepInParty + ld e, $24 + jr c, .asm_3cd81 + ld e, $a +.asm_3cd81 + callab PlayPikachuSoundClip + jr .done +.playRegularCry ld a, [wcf91] call PlayCry +.done call PrintEmptyString jp SaveScreenTilesToBuffer1 ; show 2 stages of the player mon getting smaller before disappearing AnimateRetreatingPlayerMon: + ld a, [wWhichPokemon] + push af + ld a, [wPlayerMonNumber] + ld [wWhichPokemon], a + callab IsThisPartymonStarterPikachu + pop bc + ld a, b + ld [wWhichPokemon], a + jr c, .starterPikachu coord hl, 1, 5 lb bc, 7, 7 call ClearScreenArea @@ -1879,10 +1947,17 @@ AnimateRetreatingPlayerMon: call .clearScreenArea ld a, $4c Coorda 5, 11 + jr .clearScreenArea +.starterPikachu + xor a + ld [H_WHOSETURN], a + callab AnimationSlideMonOff + ret .clearScreenArea coord hl, 1, 5 lb bc, 7, 7 - jp ClearScreenArea + call ClearScreenArea + ret ; reads player's current mon's HP into wBattleMonHP ReadPlayerMonCurHPAndStatus: @@ -2104,36 +2179,49 @@ DisplayBattleMenu: ld [wTextBoxID], a call DisplayTextBoxID ld a, [wBattleType] - dec a - jp nz, .handleBattleMenuInput ; handle menu input if it's not the old man tutorial -; the following happens for the old man tutorial + cp BATTLE_TYPE_OLD_MAN + jr z, .doSimulatedMenuInput ; simulate menu input if it's the old man or prof. oak pikachu battle + cp BATTLE_TYPE_PIKACHU + jr z, .doSimulatedMenuInput + jp .handleBattleMenuInput +; the following happens for the old man tutorial and prof. oak pikachu battle +.doSimulatedMenuInput ld hl, wPlayerName ld de, wGrassRate ld bc, NAME_LENGTH call CopyData ; temporarily save the player name in unused space, ; which is supposed to get overwritten when entering a - ; map with wild Pokémon. Due to an oversight, the data + ; map with wild Pokémon. + ; In Red/Blue, due to an oversight, the data ; may not get overwritten (cinnabar) and the infamous - ; Missingno. glitch can show up. + ; Missingno. glitch can show up. However, + ; this has been fixed in yellow ld hl, .oldManName + ld a, [wBattleType] + dec a + jr z, .useOldManName + ld hl, .profOakName +.useOldManName ld de, wPlayerName ld bc, NAME_LENGTH call CopyData ; the following simulates the keystrokes by drawing menus on screen coord hl, 9, 14 ld [hl], "▶" - ld c, 80 + ld c, 20 call DelayFrames ld [hl], " " coord hl, 9, 16 ld [hl], "▶" - ld c, 50 + ld c, 20 call DelayFrames ld [hl], "▷" ld a, $2 ; select the "ITEM" menu jp .upperLeftMenuItemWasNotSelected .oldManName db "OLD MAN@" +.profOakName + db "PROF.OAK@" .handleBattleMenuInput ld a, [wBattleAndStartSavedMenuItem] ld [wCurrentMenuItem], a @@ -2216,6 +2304,9 @@ DisplayBattleMenu: .AButtonPressed call PlaceUnfilledArrowMenuCursor ld a, [wBattleType] + cp BATTLE_TYPE_RUN + jr z, .handleUnusedBattle + ld a, [wBattleType] cp BATTLE_TYPE_SAFARI ld a, [wCurrentMenuItem] ld [wBattleAndStartSavedMenuItem], a @@ -2247,7 +2338,18 @@ DisplayBattleMenu: .throwSafariBallWasSelected ld a, SAFARI_BALL ld [wcf91], a - jr UseBagItem + jp UseBagItem +.handleUnusedBattle + ld a, [wCurrentMenuItem] + cp $3 + jp z, BattleMenu_RunWasSelected + ld hl, .RunAwayText + call PrintText + jp DisplayBattleMenu + +.RunAwayText + TX_FAR _RunAwayText + db "@" .upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected cp $2 @@ -2284,19 +2386,23 @@ BagWasSelected: call DrawHUDsAndHPBars .next ld a, [wBattleType] - dec a ; is it the old man tutorial? - jr nz, DisplayPlayerBag ; no, it is a normal battle - ld hl, OldManItemList + cp BATTLE_TYPE_OLD_MAN ; is it the old man tutorial? + jr z, .simulatedInputBattle + cp BATTLE_TYPE_PIKACHU ; is it the prof oak battle with pikachu? + jr z, .simulatedInputBattle + jr DisplayPlayerBag +.simulatedInputBattle + ld hl, SimulatedInputBattleItemList ld a, l ld [wListPointer], a ld a, h ld [wListPointer + 1], a jr DisplayBagMenu -OldManItemList: - db 1 ; # items - db POKE_BALL, 50 - db -1 +SimulatedInputBattleItemList: + db 1 ; # of items + db POKE_BALL, 1 + db $ff DisplayPlayerBag: ; get the pointer to player's bag when in a normal battle @@ -2455,6 +2561,8 @@ PartyMenuOrRockOrRun: predef StatusScreen predef StatusScreen2 ; now we need to reload the enemy mon pic + ld a, 1 + ld [H_WHOSETURN], a ld a, [wEnemyBattleStatus2] bit HAS_SUBSTITUTE_UP, a ; does the enemy mon have a substitute? ld hl, AnimationSubstitute @@ -2559,13 +2667,13 @@ MoveSelectionMenu: .writemoves ld de, wMovesString - ld a, [hFlags_0xFFF6] + ld a, [hFlags_0xFFFA] set 2, a - ld [hFlags_0xFFF6], a + ld [hFlags_0xFFFA], a call PlaceString - ld a, [hFlags_0xFFF6] + ld a, [hFlags_0xFFFA] res 2, a - ld [hFlags_0xFFF6], a + ld [hFlags_0xFFFA], a ret .regularmenu @@ -2574,9 +2682,8 @@ MoveSelectionMenu: ld hl, wBattleMonMoves call .loadmoves coord hl, 4, 12 - ld b, 4 - ld c, 14 - di ; out of pure coincidence, it is possible for vblank to occur between the di and ei + lb bc, 4, 14 + di ; out of pure coincidence, it is possible for vblank to occur between the di and ei ; so it is necessary to put the di ei block to not cause tearing call TextBoxBorder coord hl, 4, 12 @@ -2593,8 +2700,7 @@ MoveSelectionMenu: ld hl, wEnemyMonMoves call .loadmoves coord hl, 0, 7 - ld b, 4 - ld c, 14 + lb bc, 4, 14 call TextBoxBorder coord hl, 2, 8 call .writemoves @@ -2608,8 +2714,7 @@ MoveSelectionMenu: call AddNTimes call .loadmoves coord hl, 4, 7 - ld b, 4 - ld c, 14 + lb bc, 4, 14 call TextBoxBorder coord hl, 6, 8 call .writemoves @@ -2623,8 +2728,6 @@ MoveSelectionMenu: ld a, [wMoveMenuType] cp $1 jr z, .selectedmoveknown - ld a, $1 - jr nc, .selectedmoveknown ld a, [wPlayerMoveListIndex] inc a .selectedmoveknown @@ -2685,10 +2788,10 @@ SelectMenuItem: call AddNTimes ld [hl], "▷" .select - ld hl, hFlags_0xFFF6 + ld hl, hFlags_0xFFFA set 1, [hl] call HandleMenuInput - ld hl, hFlags_0xFFF6 + ld hl, hFlags_0xFFFA res 1, [hl] bit 6, a jp nz, SelectMenuItem_CursorUp ; up @@ -2790,6 +2893,55 @@ SelectMenuItem_CursorDown: ld [wCurrentMenuItem], a jp SelectMenuItem +Func_3d4f5: + bit 3, a + ld a, $0 + jr nz, .asm_3d4fd + ld a, $1 +.asm_3d4fd + ld [H_WHOSETURN], a + call LoadScreenTilesFromBuffer1 + call Func_3d536 + ld a, [wTestBattlePlayerSelectedMove] + and a + jp z, MoveSelectionMenu + ld [wAnimationID], a + xor a + ld [wAnimationType], a + predef MoveAnimation + callab Func_78e98 + jp MoveSelectionMenu + +Func_3d523: + ld a, [wTestBattlePlayerSelectedMove] + dec a + jr asm_3d52d +Func_3d529: + ld a, [wTestBattlePlayerSelectedMove] + inc a +asm_3d52d: + ld [wTestBattlePlayerSelectedMove], a + call Func_3d536 + jp MoveSelectionMenu + +Func_3d536: + coord hl, 10, 16 + lb bc, 2, 10 + call ClearScreenArea + coord hl, 10, 17 + ld de, wTestBattlePlayerSelectedMove + lb bc, LEADING_ZEROES | 1, 3 + call PrintNumber + ld a, [wTestBattlePlayerSelectedMove] + and a + ret z + cp STRUGGLE + ret nc + ld [wd11e], a + call GetMoveName + coord hl, 13, 17 + jp PlaceString + AnyMoveToSelect: ; return z and Struggle as the selected move if all moves have 0 PP and/or are disabled ld a, STRUGGLE @@ -2823,7 +2975,10 @@ AnyMoveToSelect: or c jr .handleDisabledMovePPLoop .allMovesChecked - and a ; any PP left? +; 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 @@ -2838,6 +2993,9 @@ NoMovesLeftText: db "@" SwapMovesInMenu: + ld a, [wPlayerBattleStatus3] + bit TRANSFORMED, a + jp nz, MoveSelectionMenu ld a, [wMenuItemToSwap] and a jr z, .noMenuItemSelected @@ -2917,8 +3075,7 @@ PrintMenuItem: xor a ld [H_AUTOBGTRANSFERENABLED], a coord hl, 0, 8 - ld b, 3 - ld c, 9 + lb bc, 3, 9 call TextBoxBorder ld a, [wPlayerDisabledMove] and a @@ -2985,7 +3142,7 @@ PrintMenuItem: jp Delay3 DisabledText: - db "disabled!@" + db "Disabled!@" TypeText: db "TYPE@" @@ -3905,11 +4062,13 @@ DetermineExclamationPointTextNum: ret ExclamationPointMoveSets: +; 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, BIDE, SELFDESTRUCT, AMNESIA + db RECOVER, SELFDESTRUCT, AMNESIA db $00 - db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BARRAGE + 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 @@ -4593,31 +4752,31 @@ CalculateDamage: ld a, [H_QUOTIENT + 3] add b ld [H_QUOTIENT + 3], a - jr nc, .asm_3dfd0 + jr nc, .asm_3e142 ld a, [H_QUOTIENT + 2] inc a ld [H_QUOTIENT + 2], a and a - jr z, .asm_3e004 + jr z, .asm_3e176 -.asm_3dfd0 +.asm_3e142 ld a, [H_QUOTIENT] ld b, a ld a, [H_QUOTIENT + 1] or a - jr nz, .asm_3e004 + jr nz, .asm_3e176 ld a, [H_QUOTIENT + 2] cp 998 / $100 - jr c, .asm_3dfe8 + jr c, .asm_3e15a cp 998 / $100 + 1 - jr nc, .asm_3e004 + jr nc, .asm_3e176 ld a, [H_QUOTIENT + 3] cp 998 % $100 - jr nc, .asm_3e004 + jr nc, .asm_3e176 -.asm_3dfe8 +.asm_3e15a inc hl ld a, [H_QUOTIENT + 3] ld b, [hl] @@ -4628,26 +4787,26 @@ CalculateDamage: ld b, [hl] adc b ld [hl], a - jr c, .asm_3e004 + jr c, .asm_3e176 ld a, [hl] cp 998 / $100 - jr c, .asm_3e00a + jr c, .asm_3e17c cp 998 / $100 + 1 - jr nc, .asm_3e004 + jr nc, .asm_3e176 inc hl ld a, [hld] cp 998 % $100 - jr c, .asm_3e00a + jr c, .asm_3e17c -.asm_3e004 +.asm_3e176 ; cap at 997 ld a, 997 / $100 ld [hli], a ld a, 997 % $100 ld [hld], a -.asm_3e00a +.asm_3e17c ; add 2 inc hl ld a, [hl] @@ -4677,7 +4836,7 @@ UnusedHighCriticalMoves: db $FF ; determines if attack is a critical hit -; azure heights claims "the fastest pokémon (who are,not coincidentally, +; azure heights claims "the fastest pokémon (who are, not coincidentally, ; among the most popular) tend to CH about 20 to 25% of the time." CriticalHitTest: xor a @@ -5098,7 +5257,7 @@ AttackSubstitute: ld a, [H_WHOSETURN] xor $01 ld [H_WHOSETURN], a - callab HideSubstituteShowMonAnim ; animate the substitute breaking + callab Func_79929 ; animate the substitute breaking ; flip the turn back to the way it was ld a, [H_WHOSETURN] xor $01 @@ -5395,32 +5554,26 @@ AdjustDamageForMoveType: .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 [wTypeEffectiveness] -; ($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: ld a, [wEnemyMoveType] - ld d, a ; d = type of enemy move + ld d, a ; d = type of enemy move ld hl, wBattleMonType - ld b, [hl] ; b = type 1 of player's pokemon + ld b, [hl] ; b = type 1 of player's pokemon inc hl - ld c, [hl] ; c = type 2 of player's pokemon + ld c, [hl] ; c = type 2 of player's pokemon ld a, $10 - ld [wTypeEffectiveness], a ; initialize to neutral effectiveness + ld [wd11e], a ; initialize [wd11e] to neutral effectiveness ld hl, TypeEffects .loop ld a, [hli] cp $ff ret z - cp d ; match the type of the move + cp d ; match the type of the move jr nz, .nextTypePair1 ld a, [hli] - cp b ; match with type 1 of pokemon + cp b ; match with type 1 of pokemon jr z, .done - cp c ; or match with type 2 of pokemon + cp c ; or match with type 2 of pokemon jr z, .done jr .nextTypePair2 .nextTypePair1 @@ -5428,9 +5581,21 @@ AIGetTypeEffectiveness: .nextTypePair2 inc hl jr .loop + .done + ld a, [wTrainerClass] + cp LORELEI + jr nz, .ok + ld a, [wEnemyMonSpecies] + cp DEWGONG + jr nz, .ok + call BattleRandom + cp $66 ; 40 percent + ret c +.ok + ld a, [hl] - ld [wTypeEffectiveness], a ; store damage multiplier + ld [wd11e], a ; store damage multiplier ret INCLUDE "data/type_effects.asm" @@ -6409,10 +6574,13 @@ SwapPlayerAndEnemyLevels: ; (for use when scrolling the player sprite and enemy's silhouettes on screen) LoadPlayerBackPic: ld a, [wBattleType] - dec a ; is it the old man tutorial? - ld de, RedPicBack - jr nz, .next ld de, OldManPic + cp BATTLE_TYPE_OLD_MAN ; is it the old man tutorial? + jr z, .next + ld de, ProfOakPicBack + cp BATTLE_TYPE_PIKACHU ; is it the pikachu battle at the beginning of the game? + jr z, .next + ld de, RedPicBack .next ld a, BANK(RedPicBack) call UncompressSpriteFromDE @@ -6437,6 +6605,8 @@ LoadPlayerBackPic: ld [hli], a ; OAM tile number inc a ; increment tile number ld [hOAMTile], a + ld a, $2 + ld [hl], a inc hl dec c jr nz, .innerLoop @@ -6450,18 +6620,15 @@ LoadPlayerBackPic: jr nz, .loop ld de, vBackPic call InterlaceMergeSpriteBuffers - ld a, $a - ld [$0], a - xor a - ld [$4000], a + ld a, $0 + call SwitchSRAMBankAndLatchClockData ld hl, vSprites ld de, sSpriteBuffer1 ld a, [H_LOADEDROMBANK] ld b, a ld c, 7 * 7 call CopyVideoData - xor a - ld [$0], a + call PrepareRTCDataAndDisableSRAM ld a, $31 ld [hStartTileID], a coord hl, 1, 5 @@ -6832,292 +6999,10 @@ HandleExplodingAnimation: PlayMoveAnimation: ld [wAnimationID], a call Delay3 - predef_jump MoveAnimation - -InitBattle: - ld a, [wCurOpponent] - and a - jr z, DetermineWildOpponent - -InitOpponent: - ld a, [wCurOpponent] - ld [wcf91], a - ld [wEnemyMonSpecies2], a - jr InitBattleCommon - -DetermineWildOpponent: - ld a, [wd732] - bit 1, a - jr z, .asm_3ef2f - ld a, [hJoyHeld] - bit 1, a ; B button pressed? - ret nz -.asm_3ef2f - ld a, [wNumberOfNoRandomBattleStepsLeft] - and a - ret nz - callab TryDoWildEncounter - ret nz -InitBattleCommon: - ld a, [wMapPalOffset] - push af - ld hl, wLetterPrintingDelayFlags - ld a, [hl] - push af - res 1, [hl] - callab InitBattleVariables - ld a, [wEnemyMonSpecies2] - sub OPP_ID_OFFSET - jp c, InitWildBattle - ld [wTrainerClass], a - call GetTrainerInformation - callab ReadTrainer - call DoBattleTransitionAndInitBattleVariables - call _LoadTrainerPic - xor a - ld [wEnemyMonSpecies2], a - ld [hStartTileID], a - dec a - ld [wAICount], a - coord hl, 12, 0 - predef CopyUncompressedPicToTilemap - ld a, $ff - ld [wEnemyMonPartyPos], a - ld a, $2 - ld [wIsInBattle], a - jp _InitBattleCommon - -InitWildBattle: - ld a, $1 - ld [wIsInBattle], a - call LoadEnemyMonData - call DoBattleTransitionAndInitBattleVariables - ld a, [wCurOpponent] - cp MAROWAK - jr z, .isGhost - call IsGhostBattle - jr nz, .isNoGhost -.isGhost - ld hl, wMonHSpriteDim - ld a, $66 - ld [hli], a ; write sprite dimensions - ld bc, GhostPic - ld a, c - 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 a, [wcf91] - push af - ld a, MON_GHOST - ld [wcf91], a - ld de, vFrontPic - call LoadMonFrontSprite ; load ghost sprite - pop af - ld [wcf91], a - jr .spriteLoaded -.isNoGhost - ld de, vFrontPic - call LoadMonFrontSprite ; load mon sprite -.spriteLoaded - xor a - ld [wTrainerClass], a - ld [hStartTileID], a - coord hl, 12, 0 - predef CopyUncompressedPicToTilemap - -; common code that executes after init battle code specific to trainer or wild battles -_InitBattleCommon: - ld b, SET_PAL_BATTLE_BLACK - call RunPaletteCommand - call SlidePlayerAndEnemySilhouettesOnScreen - xor a - ld [H_AUTOBGTRANSFERENABLED], a - ld hl, .emptyString - call PrintText - call SaveScreenTilesToBuffer1 - call ClearScreen - ld a, $98 - ld [H_AUTOBGTRANSFERDEST + 1], a - ld a, $1 - ld [H_AUTOBGTRANSFERENABLED], a - call Delay3 - ld a, $9c - ld [H_AUTOBGTRANSFERDEST + 1], a - call LoadScreenTilesFromBuffer1 - coord hl, 9, 7 - lb bc, 5, 10 - call ClearScreenArea - coord hl, 1, 0 - lb bc, 4, 10 - call ClearScreenArea - call ClearSprites - ld a, [wIsInBattle] - dec a ; is it a wild battle? - call z, DrawEnemyHUDAndHPBar ; draw enemy HUD and HP bar if it's a wild battle - call StartBattle - callab EndOfBattle - pop af - ld [wLetterPrintingDelayFlags], a - pop af - ld [wMapPalOffset], a - ld a, [wSavedTilesetType] - ld [hTilesetType], a - scf - ret -.emptyString - db "@" - -_LoadTrainerPic: -; wd033-wd034 contain pointer to pic - ld a, [wTrainerPicPointer] - ld e, a - ld a, [wTrainerPicPointer + 1] - ld d, a ; de contains pointer to trainer pic - ld a, [wLinkState] - and a - ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's) - jr z, .loadSprite - ld a, Bank(RedPicFront) -.loadSprite - call UncompressSpriteFromDE - ld de, vFrontPic - ld a, $77 - ld c, a - jp LoadUncompressedSpriteData - -; unreferenced -ResetCryModifiers: - xor a - ld [wFrequencyModifier], a - ld [wTempoModifier], a - jp PlaySound - -; animates the mon "growing" out of the pokeball -AnimateSendingOutMon: - ld a, [wPredefRegisters] - ld h, a - ld a, [wPredefRegisters + 1] - ld l, a - ld a, [hStartTileID] - ld [hBaseTileID], a - ld b, $4c - ld a, [wIsInBattle] - and a - jr z, .notInBattle - add b - ld [hl], a - call Delay3 - ld bc, -(SCREEN_WIDTH * 2 + 1) - add hl, bc - ld a, 1 - ld [wDownscaledMonSize], a - lb bc, 3, 3 - predef CopyDownscaledMonTiles - ld c, 4 - call DelayFrames - ld bc, -(SCREEN_WIDTH * 2 + 1) - add hl, bc - xor a - ld [wDownscaledMonSize], a - lb bc, 5, 5 - predef CopyDownscaledMonTiles - ld c, 5 - call DelayFrames - ld bc, -(SCREEN_WIDTH * 2 + 1) - jr .next -.notInBattle - ld bc, -(SCREEN_WIDTH * 6 + 3) -.next - add hl, bc - ld a, [hBaseTileID] - add $31 - jr CopyUncompressedPicToHL - -CopyUncompressedPicToTilemap: - ld a, [wPredefRegisters] - ld h, a - ld a, [wPredefRegisters + 1] - ld l, a - ld a, [hStartTileID] -CopyUncompressedPicToHL: - lb bc, 7, 7 - ld de, SCREEN_WIDTH - push af - ld a, [wSpriteFlipped] - and a - jr nz, .flipped - pop af -.loop - push bc - push hl -.innerLoop - ld [hl], a - add hl, de - inc a - dec c - jr nz, .innerLoop - pop hl - inc hl - pop bc - dec b - jr nz, .loop - ret - -.flipped - push bc - ld b, 0 - dec c - add hl, bc - pop bc - pop af -.flippedLoop - push bc - push hl -.flippedInnerLoop - ld [hl], a - add hl, de - inc a - dec c - jr nz, .flippedInnerLoop - pop hl - dec hl - pop bc - dec b - jr nz, .flippedLoop + predef MoveAnimation + callab Func_78e98 ret -LoadMonBackPic: -; Assumes the monster's attributes have -; been loaded with GetMonHeader. - ld a, [wBattleMonSpecies2] - ld [wcf91], a - coord hl, 1, 5 - ld b, 7 - ld c, 8 - call ClearScreenArea - ld hl, wMonHBackSprite - wMonHeader - call UncompressMonSprite - predef ScaleSpriteByTwo - ld de, vBackPic - call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite - ld hl, vSprites - ld de, vBackPic - ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied - ld a, [H_LOADEDROMBANK] - ld b, a - jp CopyVideoData - JumpMoveEffect: call _JumpMoveEffect ld b, $1 @@ -7266,6 +7151,16 @@ SleepEffect: call BattleRandom and $7 jr z, .setSleepCounter + ld b, a + ld a, [wUnknownSerialFlag_d499] + and a + jr z, .asm_3f1ba ; XXX stadium stuff? + ld a, b + and $3 + jr z, .setSleepCounter + ld b, a +.asm_3f1ba + ld a, b ld [de], a call PlayCurrentMoveAnimation2 ld hl, FellAsleepText @@ -7404,7 +7299,7 @@ FreezeBurnParalyzeEffect: ret nz ; return if they have a substitute, can't effect them ld a, [H_WHOSETURN] and a - jp nz, opponentAttacker + jp nz, .opponentAttacker ld a, [wEnemyMonStatus] and a jp nz, CheckDefrost ; can't inflict status if opponent is already statused @@ -7417,7 +7312,17 @@ FreezeBurnParalyzeEffect: cp b ; do target type 2 and move type match? ret z ; return if they match ld a, [wPlayerMoveEffect] - cp PARALYZE_SIDE_EFFECT1 + 1 ; 10% status effects are 04, 05, 06 so 07 will set carry for those + cp UNUSED_EFFECT_23 ; more stadium stuff + jr nz, .asm_3f2c7 + ld a, [wUnknownSerialFlag_d499] + and a + ld a, FREEZE_SIDE_EFFECT + ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance + jr z, .next1 + ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance + jr .next1 +.asm_3f2c7 + 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.. ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance @@ -7430,9 +7335,9 @@ FreezeBurnParalyzeEffect: ret nc ; do nothing if random value is >= 1A or 4D [no status applied] ld a, b ; what type of effect is this? cp BURN_SIDE_EFFECT1 - jr z, .burn + jr z, .burn1 cp FREEZE_SIDE_EFFECT - jr z, .freeze + jr z, .freeze1 ; .paralyze ld a, 1 << PAR ld [wEnemyMonStatus], a @@ -7440,7 +7345,7 @@ FreezeBurnParalyzeEffect: ld a, ANIM_A9 call PlayBattleAnimation jp PrintMayNotAttackText ; print paralysis text -.burn +.burn1 ld a, 1 << BRN ld [wEnemyMonStatus], a call HalveAttackDueToBurn ; halve attack of affected mon @@ -7448,7 +7353,7 @@ FreezeBurnParalyzeEffect: call PlayBattleAnimation ld hl, BurnedText jp PrintText -.freeze +.freeze1 call ClearHyperBeam ; resets hyper beam (recharge) condition from target ld a, 1 << FRZ ld [wEnemyMonStatus], a @@ -7456,7 +7361,7 @@ FreezeBurnParalyzeEffect: call PlayBattleAnimation ld hl, FrozenText jp PrintText -opponentAttacker: +.opponentAttacker ld a, [wBattleMonStatus] ; mostly same as above with addresses swapped for opponent and a jp nz, CheckDefrost @@ -7469,12 +7374,22 @@ opponentAttacker: cp b ret z ld a, [wEnemyMoveEffect] - cp PARALYZE_SIDE_EFFECT1 + 1 + cp UNUSED_EFFECT_23 ; more stadium stuff + jr nz, .asm_3f341 + ld a, [wUnknownSerialFlag_d499] + and a + ld a, FREEZE_SIDE_EFFECT + ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance + jr z, .next2 + ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance + jr .next2 +.asm_3f341 + cp a, PARALYZE_SIDE_EFFECT1 + 1 ld b, $1a - jr c, .next1 + jr c, .next2 ld b, $4d sub $1e -.next1 +.next2 push af call BattleRandom cp b @@ -7482,23 +7397,29 @@ opponentAttacker: ret nc ld a, b cp BURN_SIDE_EFFECT1 - jr z, .burn + jr z, .burn2 cp FREEZE_SIDE_EFFECT - jr z, .freeze + jr z, .freeze2 ld a, 1 << PAR ld [wBattleMonStatus], a call QuarterSpeedDueToParalysis + ld a, ANIM_C7 + call PlayBattleAnimation2 jp PrintMayNotAttackText -.burn +.burn2 ld a, 1 << BRN ld [wBattleMonStatus], a call HalveAttackDueToBurn + ld a, ANIM_C7 + call PlayBattleAnimation2 ld hl, BurnedText jp PrintText -.freeze +.freeze2 ; hyper beam bits aren't reseted for opponent's side ld a, 1 << FRZ ld [wBattleMonStatus], a + ld a, ANIM_C7 + call PlayBattleAnimation2 ld hl, FrozenText jp PrintText @@ -7663,25 +7584,25 @@ UpdateStatDone: ld bc, wPlayerMonMinimized ld a, [H_WHOSETURN] and a - jr z, .asm_3f4e6 + jr z, .playerTurn ld hl, wEnemyBattleStatus2 ld de, wEnemyMoveNum ld bc, wEnemyMonMinimized -.asm_3f4e6 +.playerTurn ld a, [de] cp MINIMIZE - jr nz, .asm_3f4f9 + jr nz, .notMinimize ; if a substitute is up, slide off the substitute and show the mon pic before ; playing the minimize animation bit HAS_SUBSTITUTE_UP, [hl] push af push bc + push de ld hl, HideSubstituteShowMonAnim ld b, BANK(HideSubstituteShowMonAnim) - push de call nz, Bankswitch pop de -.asm_3f4f9 +.notMinimize call PlayCurrentMoveAnimation ld a, [de] cp MINIMIZE @@ -8199,6 +8120,9 @@ FlinchSideEffect: ld hl, wPlayerBattleStatus1 ld de, wEnemyMoveEffect .flinchSideEffect + ld a, [wLinkState] + cp LINK_STATE_BATTLING + call z, ClearHyperBeam ld a, [de] cp FLINCH_SIDE_EFFECT1 ld b, $1a ; ~10% chance of flinch @@ -8240,10 +8164,27 @@ ChargeEffect: set INVULNERABLE, [hl] ; mon is now invulnerable to typical attacks (fly/dig) ld b, ANIM_C0 .notDigOrFly + push de + push bc + inc hl ; battle status 2 + push hl + ld a, [hl] + bit HAS_SUBSTITUTE_UP, a + ld hl, HideSubstituteShowMonAnim + ld b, BANK(HideSubstituteShowMonAnim) + call nz, Bankswitch + pop hl + pop bc xor a ld [wAnimationType], a ld a, b call PlayBattleAnimation + ld a, [hl] + bit HAS_SUBSTITUTE_UP, a + ld hl, ReshowSubstituteAnim + ld b, BANK(ReshowSubstituteAnim) + call nz, Bankswitch + pop de ld a, [de] ld [wChargeMoveNum], a ld hl, ChargeMoveEffectText @@ -8713,6 +8654,7 @@ PlayBattleAnimationGotID: push de push bc predef MoveAnimation + callab Func_78e98 pop bc pop de pop hl diff --git a/engine/battle/draw_hud_pokeball_gfx.asm b/engine/battle/draw_hud_pokeball_gfx.asm index 323dd167..96294774 100644 --- a/engine/battle/draw_hud_pokeball_gfx.asm +++ b/engine/battle/draw_hud_pokeball_gfx.asm @@ -27,6 +27,8 @@ SetupOwnPartyPokeballs: ld [hl], a ld a, 8 ld [wHUDPokeballGfxOffsetX], a + xor a + ld [wdef5], a ld hl, wOAMBuffer jp WritePokeballOAMData @@ -41,6 +43,8 @@ SetupEnemyPartyPokeballs: ld [hl], $20 ld a, -8 ld [wHUDPokeballGfxOffsetX], a + ld a, $1 + ld [wdef5], a ld hl, wOAMBuffer + PARTY_LENGTH * 4 jp WritePokeballOAMData @@ -104,7 +108,7 @@ WritePokeballOAMData: ld [hli], a ld a, [de] ld [hli], a - xor a + ld a, [wdef5] ld [hli], a ld a, [wBaseCoordX] ld b, a @@ -174,6 +178,8 @@ SetupPlayerAndEnemyPokeballs: ld [hl], $40 ld a, 8 ld [wHUDPokeballGfxOffsetX], a + xor a + ld [wdef5], a ld hl, wOAMBuffer call WritePokeballOAMData ld hl, wEnemyMons @@ -183,6 +189,8 @@ SetupPlayerAndEnemyPokeballs: ld a, $50 ld [hli], a ld [hl], $68 + ld a, $1 + ld [wdef5], a ld hl, wOAMBuffer + $18 jp WritePokeballOAMData diff --git a/engine/battle/end_of_battle.asm b/engine/battle/end_of_battle.asm index 830a23a1..5c0c3991 100755 --- a/engine/battle/end_of_battle.asm +++ b/engine/battle/end_of_battle.asm @@ -10,6 +10,8 @@ EndOfBattle: ld a, [wEnemyMonStatus] ld [hl], a call ClearScreen + ld b, SET_PAL_OVERWORLD + call RunPaletteCommand callab DisplayLinkBattleVersusTextBox ld a, [wBattleResult] cp $1 @@ -43,6 +45,8 @@ EndOfBattle: xor a ld [wForceEvolution], a predef EvolutionAfterBattle + ld d, $82 + callab UpdatePikachuMoodAfterBattle .resetVariables xor a ld [wLowHealthAlarm], a ;disable low health alarm diff --git a/engine/battle/experience.asm b/engine/battle/experience.asm index 24748338..722685c2 100644 --- a/engine/battle/experience.asm +++ b/engine/battle/experience.asm @@ -43,7 +43,7 @@ GainExperience: inc de jr .nextBaseStat .maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp - ld a, $ff + dec a ; a is 0 from previous check ld [de], a inc de ld [de], a @@ -233,13 +233,19 @@ GainExperience: .recalcStatChanges xor a ; battle mon ld [wCalculateWhoseStats], a - callab CalculateModifiedStats - callab ApplyBurnAndParalysisPenaltiesToPlayer - callab ApplyBadgeStatBoosts - callab DrawPlayerHUDAndHPBar - callab PrintEmptyString + ld hl, CalculateModifiedStats + call Bankswitch15ToF + ld hl, ApplyBurnAndParalysisPenaltiesToPlayer + call Bankswitch15ToF + ld hl, ApplyBadgeStatBoosts + call Bankswitch15ToF + ld hl, DrawPlayerHUDAndHPBar + call Bankswitch15ToF + ld hl, PrintEmptyString + call Bankswitch15ToF call SaveScreenTilesToBuffer1 .printGrewLevelText + callabd_ModifyPikachuHappiness PIKAHAPPY_LEVELUP ld hl, GrewLevelText call PrintText xor a ; PLAYER_PARTY_DATA @@ -339,6 +345,10 @@ BoostExp: ld [H_QUOTIENT + 2], a ret +Bankswitch15ToF: + ld b, BANK(BattleCore) + jp Bankswitch + GainedText: TX_FAR _GainedText TX_ASM diff --git a/engine/battle/ghost_marowak_anim.asm b/engine/battle/ghost_marowak_anim.asm index 7adb20d8..5bb3e308 100644 --- a/engine/battle/ghost_marowak_anim.asm +++ b/engine/battle/ghost_marowak_anim.asm @@ -2,6 +2,7 @@ MarowakAnim: ; animate the ghost being unveiled as a Marowak ld a, $e4 ld [rOBP1], a + call UpdateGBCPal_OBP1 call CopyMonPicFromBGToSpriteVRAM ; cover the BG ghost pic with a sprite ghost pic that looks the same ; now that the ghost pic is being displayed using sprites, clear the ghost pic from the BG tilemap coord hl, 12, 0 @@ -27,6 +28,7 @@ MarowakAnim: sla a sla a ld [rOBP1], a + call UpdateGBCPal_OBP1 jr nz, .fadeOutGhostLoop call ClearSprites call CopyMonPicFromBGToSpriteVRAM ; copy Marowak pic from BG to sprite VRAM @@ -40,6 +42,7 @@ MarowakAnim: srl b rra ld [rOBP1], a + call UpdateGBCPal_OBP1 ld a, b and a jr nz, .fadeInMarowakLoop @@ -74,7 +77,7 @@ CopyMonPicFromBGToSpriteVRAM: ld [hli], a ld a, d ld [hli], a - ld a, $10 ; use OBP1 + ld a, $14 ; use OBP1 ld [hli], a inc d dec c diff --git a/engine/battle/link_battle_versus_text.asm b/engine/battle/link_battle_versus_text.asm index 76559117..63142ba6 100644 --- a/engine/battle/link_battle_versus_text.asm +++ b/engine/battle/link_battle_versus_text.asm @@ -2,8 +2,7 @@ DisplayLinkBattleVersusTextBox: call LoadTextBoxTilePatterns coord hl, 3, 4 - ld b, 7 - ld c, 12 + lb bc, 7, 12 call TextBoxBorder coord hl, 4, 5 ld de, wPlayerName diff --git a/engine/battle/moveEffects/heal_effect.asm b/engine/battle/moveEffects/heal_effect.asm index 2e68acc0..97afa394 100644 --- a/engine/battle/moveEffects/heal_effect.asm +++ b/engine/battle/moveEffects/heal_effect.asm @@ -86,7 +86,7 @@ HealEffect_: ld [wHPBarNewHP], a .playAnim ld hl, PlayCurrentMoveAnimation - call BankswitchEtoF + call Bankswitch3DtoF ld a, [H_WHOSETURN] and a coord hl, 10, 9 @@ -98,14 +98,14 @@ HealEffect_: ld [wHPBarType], a predef UpdateHPBar2 ld hl, DrawHUDsAndHPBars - call BankswitchEtoF + call Bankswitch3DtoF ld hl, RegainedHealthText jp PrintText .failed ld c, 50 call DelayFrames ld hl, PrintButItFailedText_ - jp BankswitchEtoF + jp Bankswitch3DtoF StartedSleepingEffect: TX_FAR _StartedSleepingEffect diff --git a/engine/battle/moveEffects/reflect_light_screen_effect.asm b/engine/battle/moveEffects/reflect_light_screen_effect.asm index 2805a969..e5748b19 100644 --- a/engine/battle/moveEffects/reflect_light_screen_effect.asm +++ b/engine/battle/moveEffects/reflect_light_screen_effect.asm @@ -23,14 +23,14 @@ ReflectLightScreenEffect_: .playAnim push hl ld hl, PlayCurrentMoveAnimation - call BankswitchEtoF + call Bankswitch3DtoF pop hl jp PrintText .moveFailed ld c, 50 call DelayFrames ld hl, PrintButItFailedText_ - jp BankswitchEtoF + jp Bankswitch3DtoF LightScreenProtectedText: TX_FAR _LightScreenProtectedText @@ -40,6 +40,6 @@ ReflectGainedArmorText: TX_FAR _ReflectGainedArmorText db "@" -BankswitchEtoF: +Bankswitch3DtoF: ld b, BANK(BattleCore) jp Bankswitch diff --git a/engine/battle/moveEffects/transform_effect.asm b/engine/battle/moveEffects/transform_effect.asm index 9a5de9cc..ec07b303 100644 --- a/engine/battle/moveEffects/transform_effect.asm +++ b/engine/battle/moveEffects/transform_effect.asm @@ -100,18 +100,11 @@ TransformEffect_: and a jr z, .lessThanFourMoves ld a, $5 - ld [de], a - inc de - dec b - jr nz, .copyPPLoop - jr .copyStats .lessThanFourMoves -; 0 PP for blank moves - xor a ld [de], a inc de dec b - jr nz, .lessThanFourMoves + jr nz, .copyPPLoop .copyStats ; original (unmodified) stats and stat mods pop hl @@ -141,7 +134,7 @@ TransformEffect_: .failed ld hl, PrintButItFailedText_ - jp BankswitchEtoF + jp Bankswitch3DtoF TransformedText: TX_FAR _TransformedText diff --git a/engine/battle/read_trainer_party.asm b/engine/battle/read_trainer_party.asm index ba4f6f8e..b4ee46a0 100755 --- a/engine/battle/read_trainer_party.asm +++ b/engine/battle/read_trainer_party.asm @@ -15,8 +15,8 @@ ReadTrainer: ld [hl], a ; get the pointer to trainer data for this class - ld a, [wCurOpponent] - sub $C9 ; convert value from pokemon to trainer + ld a, [wTrainerClass] ; get trainer class + dec a add a ld hl, TrainerDataPointers ld c, a @@ -53,7 +53,7 @@ ReadTrainer: .LoopTrainerData ld a, [hli] and a ; have we reached the end of the trainer data? - jr z, .FinishUp + jp z, .AddAdditionalMoveData ld [wcf91], a ; write species somewhere (XXX why?) ld a, ENEMY_PARTY_DATA ld [wMonDataLocation], a @@ -68,7 +68,7 @@ ReadTrainer: ; - if [wLoneAttackNo] != 0, one pokemon on the team has a special move ld a, [hli] and a ; have we reached the end of the trainer data? - jr z, .AddLoneMove + jr z, .AddAdditionalMoveData ld [wCurEnemyLVL], a ld a, [hli] ld [wcf91], a @@ -78,69 +78,48 @@ ReadTrainer: call AddPartyMon pop hl jr .SpecialTrainer -.AddLoneMove -; does the trainer have a single monster with a different move - ld a, [wLoneAttackNo] ; Brock is 01, Misty is 02, Erika is 04, etc - and a - jr z, .AddTeamMove - dec a - add a +.AddAdditionalMoveData +; does the trainer have additional move data? + ld a, [wTrainerClass] + ld b, a + ld a, [wTrainerNo] ld c, a - ld b, 0 - ld hl, LoneMoves - add hl, bc + ld hl, SpecialTrainerMoves +.loopAdditionalMoveData + ld a, [hli] + cp $ff + jr z, .FinishUp + cp b + jr nz, .asm_39c46 ld a, [hli] - ld d, [hl] - ld hl, wEnemyMon1Moves + 2 + cp c + jr nz, .asm_39c46 + ld d, h + ld e, l +.writeAdditionalMoveDataLoop + ld a, [de] + inc de + and a + jp z, .FinishUp + dec a + ld hl, wEnemyMon1Moves ld bc, wEnemyMon2 - wEnemyMon1 call AddNTimes - ld [hl], d - jr .FinishUp -.AddTeamMove -; check if our trainer's team has special moves - -; get trainer class number - ld a, [wCurOpponent] - sub OPP_ID_OFFSET - ld b, a - ld hl, TeamMoves - -; iterate through entries in TeamMoves, checking each for our trainer class -.IterateTeamMoves + ld a, [de] + inc de + dec a + ld c, a + ld b, 0 + add hl,bc + ld a, [de] + inc de + ld [hl], a + jr .writeAdditionalMoveDataLoop +.asm_39c46 ld a, [hli] - cp b - jr z, .GiveTeamMoves ; is there a match? - inc hl ; if not, go to the next entry - inc a - jr nz, .IterateTeamMoves - -; no matches found. is this trainer champion rival? - ld a, b - cp SONY3 - jr z, .ChampionRival - jr .FinishUp ; nope -.GiveTeamMoves - ld a, [hl] - ld [wEnemyMon5Moves + 2], a - jr .FinishUp -.ChampionRival ; give moves to his team - -; pidgeot - ld a, SKY_ATTACK - ld [wEnemyMon1Moves + 2], a - -; starter - ld a, [wRivalStarter] - cp STARTER3 - ld b, MEGA_DRAIN - jr z, .GiveStarterMove - cp STARTER1 - ld b, FIRE_BLAST - jr z, .GiveStarterMove - ld b, BLIZZARD ; must be squirtle -.GiveStarterMove - ld a, b - ld [wEnemyMon6Moves + 2], a + and a + jr nz, .asm_39c46 + jr .loopAdditionalMoveData .FinishUp ; clear wAmountMoneyWon addresses xor a diff --git a/engine/battle/safari_zone.asm b/engine/battle/safari_zone.asm index 4672892d..88064f9a 100755 --- a/engine/battle/safari_zone.asm +++ b/engine/battle/safari_zone.asm @@ -2,18 +2,18 @@ PrintSafariZoneBattleText: ld hl, wSafariBaitFactor ld a, [hl] and a - jr z, .asm_4284 + jr z, .asm_411e dec [hl] ld hl, SafariZoneEatingText - jr .asm_429f -.asm_4284 + jr .asm_4138 +.asm_411e dec hl ld a, [hl] and a ret z dec [hl] ld hl, SafariZoneAngryText - jr nz, .asm_429f + jr nz, .asm_4138 push hl ld a, [wEnemyMonSpecies] ld [wd0b5], a @@ -21,7 +21,7 @@ PrintSafariZoneBattleText: ld a, [wMonHCatchRate] ld [wEnemyMonActualCatchRate], a pop hl -.asm_429f +.asm_4138 push hl call LoadScreenTilesFromBuffer1 pop hl diff --git a/engine/battle/scale_sprites.asm b/engine/battle/scale_sprites.asm index 98521528..c614d638 100644 --- a/engine/battle/scale_sprites.asm +++ b/engine/battle/scale_sprites.asm @@ -2,6 +2,13 @@ ; assumes that input sprite chunks are 4x4 tiles, and the rightmost and bottommost 4 pixels will be ignored ; resulting in a 7*7 tile output sprite chunk ScaleSpriteByTwo: + ld a, $0 + call SwitchSRAMBankAndLatchClockData + call ScaleSpriteByTwo_ + call PrepareRTCDataAndDisableSRAM + ret + +ScaleSpriteByTwo_: ld de, sSpriteBuffer1 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped ld hl, sSpriteBuffer0 + SPRITEBUFFERSIZE - 1 ; end of destination buffer call ScaleLastSpriteColumnByTwo ; last tile column is special case diff --git a/engine/battle/trainer_ai.asm b/engine/battle/trainer_ai.asm index ac6c1a72..c8fdfb29 100644 --- a/engine/battle/trainer_ai.asm +++ b/engine/battle/trainer_ai.asm @@ -295,7 +295,7 @@ TrainerClassMoveChoiceModifications: db 1,0 ; GAMBLER db 1,3,0 ; BEAUTY db 1,2,0 ; PSYCHIC_TR - db 1,3,0 ; ROCKER + db 1,0 ; ROCKER db 1,0 ; JUGGLER db 1,0 ; TAMER db 1,0 ; BIRD_KEEPER @@ -311,11 +311,11 @@ TrainerClassMoveChoiceModifications: db 1,0 ; BRUNO db 1,0 ; BROCK db 1,3,0 ; MISTY - db 1,3,0 ; LT_SURGE + db 1,0 ; LT_SURGE db 1,3,0 ; ERIKA db 1,3,0 ; KOGA - db 1,3,0 ; BLAINE - db 1,3,0 ; SABRINA + db 1,0 ; BLAINE + db 1,0 ; SABRINA db 1,2,0 ; GENTLEMAN db 1,3,0 ; SONY2 db 1,3,0 ; SONY3 @@ -337,14 +337,20 @@ INCLUDE "data/trainer_moves.asm" INCLUDE "data/trainer_parties.asm" TrainerAI: - and a ld a, [wIsInBattle] dec a - ret z ; if not a trainer, we're done here + jr z, .done ; if not a trainer, we're done here ld a, [wLinkState] cp LINK_STATE_BATTLING - ret z - ld a, [wTrainerClass] ; what trainer class is this? + jr z, .done ; if in a link battle, we're done as well + ld a, [wEnemyBattleStatus1] + and 1 << CHARGING_UP | 1 << THRASHING_ABOUT | 1 << STORING_ENERGY ; %10011 + jr nz, .done ; don't follow trainer ai if opponent is in a locked state + ld a, [wEnemyBattleStatus2] + and 1 << USING_RAGE ; %1000000 + jr nz, .done ; don't follow trainer ai if opponent is locked in rage + ; note that this doesn't check for hyper beam recharge which can cause problems + ld a,[wTrainerClass] ; what trainer class is this? dec a ld c, a ld b, 0 @@ -354,7 +360,7 @@ TrainerAI: add hl, bc ld a, [wAICount] and a - ret z ; if no AI uses left, we're done here + jr z, .done; if no AI uses left, we're done here inc hl inc a jr nz, .getpointer @@ -367,6 +373,9 @@ TrainerAI: ld l, a call Random jp hl +.done + and a + ret TrainerAIPointers: ; one entry per trainer class @@ -476,22 +485,22 @@ ErikaAI: jp AIUseSuperPotion KogaAI: - cp 25 percent + 1 + cp 13 percent - 1 ret nc jp AIUseXAttack BlaineAI: cp 25 percent + 1 ret nc + ld a, 10 + call AICheckIfHPBelowFraction + ret nc jp AIUseSuperPotion SabrinaAI: cp 25 percent + 1 ret nc - ld a, 10 - call AICheckIfHPBelowFraction - ret nc - jp AIUseHyperPotion + jp AIUseXDefend Sony2AI: cp 13 percent - 1 diff --git a/engine/battle/wild_encounters.asm b/engine/battle/wild_encounters.asm index 231c46e7..0285346e 100644 --- a/engine/battle/wild_encounters.asm +++ b/engine/battle/wild_encounters.asm @@ -24,8 +24,9 @@ TryDoWildEncounter: ld [wRepelRemainingSteps], a .next ; determine if wild pokemon can appear in the half-block we're standing in -; is the bottom right tile (9,9) of the half-block we're standing in a grass/water tile? - coord hl, 9, 9 +; is the bottom left tile (8,9) of the half-block we're standing in a grass/water tile? +; note that by using the bottom left tile, this prevents the "left-shore" tiles from generating grass encounters + coord hl, 8, 9 ld c, [hl] ld a, [wGrassTile] cp c @@ -68,8 +69,6 @@ TryDoWildEncounter: cp $14 ; is the bottom left tile (8,9) of the half-block we're standing in a water tile? jr nz, .gotWildEncounterType ; else, it's treated as a grass tile by default ld hl, wWaterMons -; since the bottom right tile of a "left shore" half-block is $14 but the bottom left tile is not, -; "left shore" half-blocks (such as the one in the east coast of Cinnabar) load grass encounters. .gotWildEncounterType ld b, 0 add hl, bc |