summaryrefslogtreecommitdiff
path: root/engine/battle
diff options
context:
space:
mode:
Diffstat (limited to 'engine/battle')
-rwxr-xr-xengine/battle/animations.asm766
-rw-r--r--engine/battle/bank3d_battle.asm291
-rwxr-xr-xengine/battle/bank_e_misc.asm19
-rw-r--r--engine/battle/battle_transitions.asm8
-rw-r--r--engine/battle/common_text.asm16
-rwxr-xr-xengine/battle/core.asm710
-rw-r--r--engine/battle/draw_hud_pokeball_gfx.asm10
-rwxr-xr-xengine/battle/end_of_battle.asm4
-rw-r--r--engine/battle/experience.asm22
-rw-r--r--engine/battle/ghost_marowak_anim.asm5
-rw-r--r--engine/battle/link_battle_versus_text.asm3
-rw-r--r--engine/battle/moveEffects/heal_effect.asm6
-rw-r--r--engine/battle/moveEffects/reflect_light_screen_effect.asm6
-rw-r--r--engine/battle/moveEffects/transform_effect.asm11
-rwxr-xr-xengine/battle/read_trainer_party.asm103
-rwxr-xr-xengine/battle/safari_zone.asm10
-rw-r--r--engine/battle/scale_sprites.asm7
-rw-r--r--engine/battle/trainer_ai.asm37
-rw-r--r--engine/battle/wild_encounters.asm7
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