Skip to content
Rangi edited this page Jan 28, 2018 · 24 revisions

Much of the game logic can be changed via the files in data/, but some things are hard-coded and can be tricky to find. This page lists things that may trip you up when hacking.

Contents

Tilesets that have per-mapgroup roofs

This is caused by LoadTilesetGFX in home/map.asm:

; These tilesets support dynamic per-mapgroup roof tiles.
	ld a, [wTileset]
	cp TILESET_JOHTO
	jr z, .load_roof
	cp TILESET_JOHTO_MODERN
	jr z, .load_roof
	cp TILESET_BATTLE_TOWER_OUTSIDE
	jr z, .load_roof
	jr .skip_roof

.load_roof
	farcall LoadMapGroupRoof

.skip_roof

Maps that don't display a location sign

This is caused by ReturnFromMapSetupScript.CheckSpecialMap in engine/events/map_name_sign.asm:

.CheckSpecialMap: ; b8070
; These landmarks do not get pop-up signs.
	cp -1
	ret z
	cp SPECIAL_MAP
	ret z
	cp RADIO_TOWER
	ret z
	cp LAV_RADIO_TOWER
	ret z
	cp UNDERGROUND_PATH
	ret z
	cp INDIGO_PLATEAU
	ret z
	cp POWER_PLANT
	ret z
	ld a, $1
	and a
	ret
; b8089

Outdoor maps within indoor maps don't confuse Dig or Escape Rope

Dig and Escape Rope take you out of a dungeon and back to the entrance you used. However, some dungeons are designed with an enclosed outdoor portion, and it would be bad if visiting those portions made Dig or Escape Rope take you back to them instead of properly outside the dungeon.

There's no "outdoor-within-indoor" map environment, so the few maps in this situation have to be hard-coded. It's caused by LoadWarpData.SaveDigWarp in engine/warp_connection.asm:

; MOUNT_MOON_SQUARE and TIN_TOWER_ROOF are outdoor maps within indoor maps.
; Dig and Escape Rope should not take you to them.
	ld a, [wPrevMapGroup]
	cp GROUP_MOUNT_MOON_SQUARE ; GROUP_TIN_TOWER_ROOF
	jr nz, .not_mt_moon_or_tin_tower
	ld a, [wPrevMapNumber]
	cp MAP_MOUNT_MOON_SQUARE
	ret z
	cp MAP_TIN_TOWER_ROOF
	ret z
.not_mt_moon_or_tin_tower

RIVAL1's first Pokémon has no held item

This is caused by InitEnemyTrainer in engine/battle/core.asm:

	; RIVAL1's first mon has no held item
	ld a, [TrainerClass]
	cp RIVAL1
	jr nz, .ok
	xor a
	ld [OTPartyMon1Item], a
.ok

Trainer classes with different battle music

This is caused by PlayBattleMusic in engine/battle/start_battle.asm. The routine's logic is:

  1. If [BattleType] is BATTLETYPE_SUICUNE or BATTLETYPE_ROAMING, play MUSIC_SUICUNE_BATTLE.
  2. If it's a wild battle, play MUSIC_KANTO_WILD_BATTLE if we're in Kanto, MUSIC_JOHTO_WILD_BATTLE_NIGHT in Johto at night, or MUSIC_JOHTO_WILD_BATTLE during morning and day.
  3. If [OtherTrainerClass] is CHAMPION or RED, play MUSIC_CHAMPION_BATTLE.
  4. If [OtherTrainerClass] is GRUNTM or GRUNTF, play MUSIC_ROCKET_BATTLE. (They should have included EXECUTIVEM, EXECUTIVEF, and SCIENTIST too…)
  5. If [OtherTrainerClass] is listed under KantoGymLeaders in data/trainers/leaders.asm, play MUSIC_KANTO_GYM_LEADER_BATTLE.
  6. If [OtherTrainerClass] is listed under GymLeaders in data/trainers/leaders.asm, play MUSIC_JOHTO_GYM_LEADER_BATTLE. (CHAMPION, RED, and the Kanto Gym leaders are listed but have already been accounted for at this point.)
  7. If [OtherTrainerClass] is RIVAL2 and [OtherTrainerID] is at least RIVAL2_2_CHIKORITA (i.e. we're battling our rival in Indigo Plateau), play MUSIC_CHAMPION_BATTLE.
  8. If [OtherTrainerClass] is RIVAL1 or RIVAL2, play MUSIC_RIVAL_BATTLE.
  9. If it's a link battle, play MUSIC_JOHTO_TRAINER_BATTLE.
  10. Play MUSIC_KANTO_TRAINER_BATTLE if we're in Kanto or MUSIC_JOHTO_TRAINER_BATTLE if we're in Johto.

RIVAL1 and RIVAL2 don't print their trainer class in battle

Both of these classes are named "RIVAL", but battles just print "SILVER wants to battle!", not "RIVAL SILVER wants to battle!"

This is caused by PlaceEnemysName in home/text.asm:

	ld a, [TrainerClass]
	cp RIVAL1
	jr z, .rival
	cp RIVAL2
	jr z, .rival
Clone this wiki locally