Add a new Unown puzzle chamber - pret/pokecrystal GitHub Wiki
This tutorial is for how to add a new Unown puzzle chamber, including a new sliding panel puzzle, a word on the back wall, and a trigger condition for the back wall to open. As an example, we'll add a chamber for Relicanth.
Contents
1. Create a new puzzle
Create gfx/unown_puzzle/relicanth.png:
(This image was drawn by Neslug.)
Then edit constants/script_constants.asm:
; UnownPuzzle setval arguments
; LoadUnownPuzzlePiecesGFX.LZPointers indexes (see engine/games/unown_puzzle.asm)
const_def
const UNOWNPUZZLE_KABUTO ; 0
const UNOWNPUZZLE_OMANYTE ; 1
const UNOWNPUZZLE_AERODACTYL ; 2
const UNOWNPUZZLE_HO_OH ; 3
+ const UNOWNPUZZLE_RELICANTH
NUM_UNOWN_PUZZLES EQU const_value
And edit engine/games/unown_puzzle.asm:
LoadUnownPuzzlePiecesGFX:
...
.LZPointers:
; entries correspond to UNOWNPUZZLE_* constants
dw KabutoPuzzleLZ
dw OmanytePuzzleLZ
dw AerodactylPuzzleLZ
dw HoOhPuzzleLZ
+ dw RelicanthPuzzleLZ
UnownPuzzleCursorGFX:
INCBIN "gfx/unown_puzzle/cursor.2bpp"
UnownPuzzleStartCancelLZ:
INCBIN "gfx/unown_puzzle/start_cancel.2bpp.lz"
HoOhPuzzleLZ:
INCBIN "gfx/unown_puzzle/hooh.2bpp.lz"
AerodactylPuzzleLZ:
INCBIN "gfx/unown_puzzle/aerodactyl.2bpp.lz"
KabutoPuzzleLZ:
INCBIN "gfx/unown_puzzle/kabuto.2bpp.lz"
OmanytePuzzleLZ:
INCBIN "gfx/unown_puzzle/omanyte.2bpp.lz"
+
+RelicanthPuzzleLZ:
+INCBIN "gfx/unown_puzzle/relicanth.2bpp.lz"
Now you can create a map with a script like this:
RuinsOfAlphRelicanthChamberPuzzle:
refreshscreen
setval UNOWNPUZZLE_RELICANTH
special UnownPuzzle
closetext
iftrue .PuzzleComplete
end
.PuzzleComplete
...
And it will work the way you expect.
2. Create a new word wall
Edit constants/script_constants.asm again:
; DisplayUnownWords setval arguments
; UnownWalls and MenuHeaders_UnownWalls indexes (see data/events/unown_walls.asm)
const_def
const UNOWNWORDS_ESCAPE ; 0
const UNOWNWORDS_LIGHT ; 1
const UNOWNWORDS_WATER ; 2
const UNOWNWORDS_HO_OH ; 3
+ const UNOWNWORDS_WHIRL
Then edit data/events/unown_walls.asm:
UnownWalls:
; UNOWNWORDS_ESCAPE
; db $08, $44, $04, $00, $2e, $08, -1
unownwall "E", "S", "C", "A", "P", "E"
; UNOWNWORDS_LIGHT
; db $26, $20, $0c, $0e, $46, -1
unownwall "L", "I", "G", "H", "T"
; UNOWNWORDS_WATER
; db $4c, $00, $46, $08, $42, -1
unownwall "W", "A", "T", "E", "R"
; UNOWNWORDS_HO_OH
; db $0e, $2c, $64, $2c, $0e, -1
unownwall "H", "O", "-", "O", "H"
+; UNOWNWORDS_WHIRL
+ unownwall "W", "H", "I", "R", "L"
MenuHeaders_UnownWalls:
; UNOWNWORDS_ESCAPE
db MENU_BACKUP_TILES ; flags
menu_coords 3, 4, 16, 9
; UNOWNWORDS_LIGHT
db MENU_BACKUP_TILES ; flags
menu_coords 4, 4, 15, 9
; UNOWNWORDS_WATER
db MENU_BACKUP_TILES ; flags
menu_coords 4, 4, 15, 9
; UNOWNWORDS_HO_OH
db MENU_BACKUP_TILES ; flags
menu_coords 4, 4, 15, 9
+; UNOWNWORDS_WHIRL
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 4, 4, 15, 9
The unownwall
macro turns capital letters and hyphens into their corresponding Unown letters. The menu_coords
macro is used here to define the textbox surrounding the word when it appears; note that the word "ESCAPE" has a wider box to fit its six letters.
Now you can create a map with a script like this:
RuinsOfAlphRelicanthChamberWallPatternLeft:
opentext
writetext RuinsOfAlphRelicanthChamberWallPatternLeftText
setval UNOWNWORDS_WHIRL
special DisplayUnownWords
closetext
end
And it will work the way you expect.
3. Create a condition to open the wall
The wall-opening routines are defined in engine/events/unown_walls.asm. Each wall has a routine that sets the corresponding WALL_OPENED
event if certain conditions are met:
HoOhChamber
: Called when you enter the chamber. Checks if Ho-Oh is the first Pokémon in the party.OmanyteChamber
: Called when you enter the chamber. Checks if a Water Stone is in the Pack or held by a Pokémon in the party.SpecialAerodactylChamber
: Called when you use Flash. Checks if you are in the Aerodactyl chamber.SpecialKabutoChamber
: Called when you use an Escape Rope. Checks if you are in the Kabuto chamber.
HoOhChamber
and OmanyteChamber
are called by scene_script
s in their respective chamber scripts in maps/*.asm; SpecialAerodactylChamber
SpecialKabutoChamber
are called by the OWFlash
and EscapeRopeFunction
routines in engine/events/overworld.asm, respectively.
The word "WHIRL" implies that you should use Whirlpool. So, edit engine/events/unown_walls.asm to define a new SpecialRelicanthChamber
routine that checks if you are in the Relicanth chamber map, and sets EVENT_WALL_OPENED_IN_RELICANTH_CHAMBER
if so. Then edit engine/events/overworld.asm so that WhirlpoolFunction
calls SpecialRelicanthChamber
the way that EscapeRopeFunction
calls SpecialKabutoChamber
. (You will, of course, also need to edit constants/event_flags.asm to define EVENT_WALL_OPENED_IN_RELICANTH_CHAMBER
, not to mention creating the Relicanth chamber map in the first place.) I won't go into the details of how to do this, since you probably don't want exactly this condition, and the existing four routines are sufficient to show the general pattern.
Anyway, once that's done, you can use Whirlpool in the Relicanth chamber to open the wall.