1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
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](#1-create-a-new-puzzle)
2. [Create a new word wall](#2-create-a-new-word-wall)
3. [Create a condition to open the wall](#3-create-a-condition-to-open-the-wall)
## 1. Create a new puzzle
Create **gfx/unown_puzzle/relicanth.png**:

(This image was drawn by [Neslug](https://www.deviantart.com/neslug/art/GSC-Hoenn-Puzzle-Panels-192327829).)
Then edit [constants/script_constants.asm](../blob/master/constants/script_constants.asm):
```diff
; 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](../blob/master/engine/games/unown_puzzle.asm):
```diff
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](../blob/master/constants/script_constants.asm) again:
```diff
; 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](../blob/master/data/events/unown_walls.asm):
```diff
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](../blob/master/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](../tree/master/maps/); `SpecialAerodactylChamber` `SpecialKabutoChamber` are called by the `OWFlash` and `EscapeRopeFunction` routines in [engine/events/overworld.asm](../blob/master/engine/events/overworld.asm), respectively.
The word "WHIRL" implies that you should use Whirlpool. So, edit [engine/events/unown_walls.asm](../blob/master/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](../blob/master/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](../blob/master/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.
|