-
Notifications
You must be signed in to change notification settings - Fork 946
Quick Field Debug New Game
This ports some of the features from the Field Debug option that is present on the Japanese G/S debug ROMs. It allows you to skip the whole intro sequence, warping directly to the player's room. It also includes a fast walk option that ignores all collisions and events by holding down B.
- Adding the main menu option
- Adding Debug New Game functions
- Fixing overworld movement
- (Optional) Add comments
- Adding more features
First edit engine/menus/main_menu.asm, replacing NEW GAME with NEW GAME DEBUG in the debug build.
.Strings:
; entries correspond to MAINMENUITEM_* constants
db "CONTINUE@"
+ if DEF(_DEBUG)
+ db "NEW GAME DEBUG@"
+ else
db "NEW GAME@"
+ endc
db "OPTION@"
db "MYSTERY GIFT@"
db "MOBILE@"
db "MOBILE STUDIUM@"
if DEF(_DEBUG)
db "DEBUG ROOM@"
endc
.Jumptable:
; entries correspond to MAINMENUITEM_* constants
dw MainMenu_Continue
+ if DEF(_DEBUG)
+ dw MainMenu_NewGameDebug
+ else
dw MainMenu_NewGame
+ endc
dw MainMenu_Option
dw MainMenu_MysteryGift
dw MainMenu_Mobile
dw MainMenu_MobileStudiumMainMenu_NewGame:
farcall NewGame
ret
+ if DEF(_DEBUG)
+ MainMenu_NewGameDebug:
+ farcall NewGameDebug
+ ret
+ endc
MainMenu_Option:
farcall Option
retAdd this code at the end of engine/menus/intro_menu.asm:
+ if DEF(_DEBUG)
+ NewGameDebug:
+ ld hl, wDebugFlags
+ set DEBUG_FIELD_F, [hl]
+ call ResetWRAM
+ farcall InitNewGameDebug
+ call ClearTilemapEtc
+ call InitializeWorld
+
+ ld a, SPAWN_HOME
+ ld [wDefaultSpawnpoint], a
+
+ ld a, MAPSETUP_WARP
+ ldh [hMapEntryMethod], a
+ jp FinishContinueFunction
+ endcCreate a new file engine/debug/new_game_debug.asm and paste the following code:
InitNewGameDebug:
call InitRandomDebugName
; give yourself max money & coins
ld a, HIGH(MAX_MONEY >> 8)
ld [wMoney], a
ld a, HIGH(MAX_MONEY) ; mid
ld [wMoney + 1], a
ld a, LOW(MAX_MONEY)
ld [wMoney + 2], a
ld a, HIGH(MAX_COINS)
ld [wCoins], a
ld a, LOW(MAX_COINS)
ld [wCoins + 1], a
call InitDebugStarter
ld de, DebugItems
call GetDebugItems
; pokedex
ld hl, wPokedexCaught
call SetDexFlags
ld hl, wPokedexSeen
call SetDexFlags
ld hl, wUnownDex
ld [hl], 1
ld hl, wFirstUnownSeen
ld [hl], 7
call SetPokegearFlags
; disable Mom's Pokegear speech
ld a, SCENE_PLAYERSHOUSE1F_NOOP
ld [wPlayersHouse1FSceneID], a
; setting this event enables trade and link battles
ld de, EVENT_GAVE_MYSTERY_EGG_TO_ELM
ld b, SET_FLAG
jp EventFlagAction
farcall SetAllDecorationFlags
farcall InitRoamMons
ld a, $0c
ld [wStringBuffer2 + 1], a
ld a, $22
ld [wStringBuffer2 + 2], a
call InitTimeOfDay
call Random
ld [wLuckyIDNumber], a
call Random
ld [wLuckyIDNumber + 1], a
ret
InitRandomDebugName:
; pick a random name from the trainer list
call Random
cp NUM_TRAINER_CLASSES
jr nc, InitRandomDebugName
ld c, a
ld b, 0
ld hl, TrainerGroups
add hl, bc
add hl, bc
ld a, BANK(TrainerGroups)
call GetFarWord
ld de, wPlayerName
ld bc, NAME_LENGTH
ld a, BANK(Trainers)
call FarCopyBytes
ld hl, .RivalName
ld de, wRivalName
ld bc, NAME_LENGTH
call CopyBytes
ret
.RivalName:
db "RED@"
InitDebugStarter:
; add a random evolved starter at Lvl 80
call Random
and %11
jr z, InitDebugStarter
dec a
ld b, a
add a
add b
add MEGANIUM
ld b, 80
call .AddToParty
ret
.AddToParty:
ld [wCurPartySpecies], a
ld a, b
ld [wCurPartyLevel], a
predef TryAddMonToParty
ret
GetDebugItems:
ld hl, wNumItems
.loop
ld a, [de]
cp -1
ret z
ld [wCurItem], a
inc de
ld a, [de]
inc de
ld [wItemQuantityChange], a
call ReceiveItem
jr .loop
DebugItems:
db BICYCLE, 1
db OLD_ROD, 1
db GOOD_ROD, 1
db SUPER_ROD, 1
db COIN_CASE, 1
db ITEMFINDER, 1
db FLOWER_MAIL, 6
db MASTER_BALL, 99
db ULTRA_BALL, 99
db POKE_BALL, 99
db HEAVY_BALL, 99
db LEVEL_BALL, 99
db LURE_BALL, 99
db FAST_BALL, 99
db POTION, 30
db RARE_CANDY, 20
db FULL_HEAL, 99
db -1
SetDexFlags:
IF NUM_POKEMON > 7
ld b, NUM_POKEMON / 8 ; 251 / 8 == 31
ld a, %11111111
.loop
ld [hli], a
dec b
jr nz, .loop
ENDC
IF NUM_POKEMON % 8
ld [hl], (1 << (NUM_POKEMON % 8)) - 1 ; (1 << 251 % 8)) - 1 == %00000111
ENDC
ret
SetPokegearFlags:
ld hl, wStatusFlags
set STATUSFLAGS_POKEDEX_F, [hl]
ld hl, wPokegearFlags
set POKEGEAR_OBTAINED_F, [hl]
ld hl, wPokegearFlags
set POKEGEAR_RADIO_CARD_F, [hl]
ld hl, wPokegearFlags
set POKEGEAR_PHONE_CARD_F, [hl]
ld hl, wPokegearFlags
set POKEGEAR_MAP_CARD_F, [hl]
ret
Edit main.asm and include the new file:
SECTION "Debug Room", ROMX
if DEF(_DEBUG)
INCLUDE "engine/debug/debug_room.asm"
endc
+ SECTION "New Game Debug", ROMX
+
+ if DEF(_DEBUG)
+ INCLUDE "engine/debug/new_game_debug.asm"
+ endc
SECTION "Battle Tower Text", ROMX
INCLUDE "data/battle_tower/trainer_text.asm"Edit the following files:
CheckEngineFlag:
; Check engine flag de
; Return carry if flag is not set
+ if DEF(_DEBUG)
+ call CheckFieldDebug
+ jr nz, .isset
+ endc
ld b, CHECK_FLAG
farcall EngineFlagAction
ld a, c
and a
jr nz, .issetCheckTrainerEvent:
nop
nop
+ if DEF(_DEBUG)
+ call CheckBPressedDebug
+ jr nz, .nope
+ endc
call CheckTrainerBattle
jr nc, .nope
ld a, PLAYEREVENT_SEENBYTRAINER
scf
ret
.nope
xor a
ret
CheckTileEvent:
; Check for warps, coord events, or wild battles.
call CheckWarpConnectionsEnabled
jr z, .connections_disabled
farcall CheckMovingOffEdgeOfMap
jr c, .map_connection
call CheckWarpTile
jr c, .warp_tile
.connections_disabled
+ if DEF(_DEBUG)
+ call CheckBPressedDebug
+ jr nz, .ok
+ endc
call CheckCoordEventsEnabled
jr z, .coord_events_disabled
call CheckCurrentMapCoordEvents
jr c, .coord_eventengine/overworld/player_movement.asm:
.Normal:
+ if DEF(_DEBUG)
+ call .DebugMovement
+ ret c
+ endc
call .CheckForced
call .GetAction
call .CheckTile
ret c
call .CheckTurning
ret c
call .TryStep
ret c
call .TryJump
ret c
call .CheckWarp
ret c
jr .NotMoving
.Surf:
+ if DEF(_DEBUG)
+ call .DebugMovement
+ ret c
+ endc
call .CheckForced
call .GetAction
call .CheckTile
ret c
call .CheckTurning
ret c
call .TrySurf
ret c
jr .NotMoving
.Ice:
+ if DEF(_DEBUG)
+ call .DebugMovement
+ ret c
+ endc
call .CheckForced
call .GetAction
call .CheckTile.Standing:
call .StandInPlace
xor a
ret
+ if DEF(_DEBUG)
+ .DebugMovement:
+ call CheckBPressedDebug
+ jr z, .Regular
+ call .GetAction
+ ld a, [wWalkingDirection]
+ cp STANDING
+ jr z, .DebugStanding
+ ld a, [wWalkingTileCollision]
+ cp COLL_FF
+ jr z, .DebugStanding
+ ld a, STEP_BIKE
+ call .DoStep
+ scf
+ ret
+
+ .DebugStanding:
+ call .DebugStandInPlace
+ scf
+ ret
+
+ .Regular:
+ xor a
+ ret
+ endc
.CheckTile:.FinishFacing:
db $80 | DOWN
db $80 | UP
db $80 | LEFT
db $80 | RIGHT
.StandInPlace:
ld a, 0
ld [wPlayerTurningDirection], a
+ if DEF(_DEBUG)
+ .DebugStandInPlace:
+ endc
ld a, movement_step_sleep
ld [wMovementAnimation], a
xor a
retAt this point it's done, you can build and test! Keep reading if you want to add optional contents.
Enabling debug features uses previously unreferenced functions. You may want to include a warning for your future self, in case you're running short on space some day and decide to trim unused contents. Alternatively, you can wrap the functions with if DEF(_DEBUG) code.
engine/overworld/decorations.asm:
SetAllDecorationFlags: ; unreferenced except in _DEBUG builds
CheckBPressedDebug:: ; unreferenced except in _DEBUG builds
CheckFieldDebug:: ; unreferenced except in _DEBUG builds
Essential Debug Tools adds some more functions at game start, by using the Radio as a script hub.