summaryrefslogtreecommitdiff
path: root/Allow-more-than-15-object_events-per-map.md
blob: c6880891f07174caf1a8a268f512901730065201 (plain)
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
Map scripts in [maps/\*.asm](../tree/master/maps/) declare new objects—NPCs, item balls, Berry trees, etc—with the `object_event` macro. But you can't have more than 15 `object_event`s in one map. ([GoldenrodCity.asm](../blob/master/maps/GoldenrodCity.asm) reaches this limit, and four other maps nearly do with 14 `object_event`s.) Turns out this is an easy limit to increase.

Edit [constants/wram_constants.asm](../blob/master/constants/wram_constants.asm):

```diff
 ; wMapObjects:: ; d71e
 PLAYER_OBJECT EQU 0
-NUM_OBJECTS   EQU 16
+NUM_OBJECTS   EQU 18
```

And edit [wram.asm](../blob/master/wram.asm):

```diff
-	ds 40
+	ds 6
 
 wMapObjects:: ; d71e
 wPlayerObject:: map_object wPlayer
 wMap1Object::   map_object wMap1
 wMap2Object::   map_object wMap2
 wMap3Object::   map_object wMap3
 wMap4Object::   map_object wMap4
 wMap5Object::   map_object wMap5
 wMap6Object::   map_object wMap6
 wMap7Object::   map_object wMap7
 wMap8Object::   map_object wMap8
 wMap9Object::   map_object wMap9
 wMap10Object::  map_object wMap10
 wMap11Object::  map_object wMap11
 wMap12Object::  map_object wMap12
 wMap13Object::  map_object wMap13
 wMap14Object::  map_object wMap14
 wMap15Object::  map_object wMap15
+wMap16Object::  map_object wMap16
+wMap17Object::  map_object wMap17
 wMapObjectsEnd::
 
 wObjectMasks:: ds NUM_OBJECTS ; d81e
```

That's it! We just added space for maps to define 17 total `object_event`s. (Plus the player object, making 18 total.) So you could, for example, add two more NPCs to make Goldenrod City feel busier.

Let's look at how it works. `wMapObjects` is an array of `map_object` structs, one for each possible object (including the player). You can see what data is stored for each `map_object` in the macro definition in [macros/wram.asm](../blob/master/macros/wram.asm):

```asm
map_object: MACRO
\1ObjectStructID::  db
\1ObjectSprite::    db
\1ObjectYCoord::    db
\1ObjectXCoord::    db
\1ObjectMovement::  db
\1ObjectRadius::    db
\1ObjectHour::      db
\1ObjectTimeOfDay:: db
\1ObjectColor::     db
\1ObjectRange::     db
\1ObjectScript::    dw
\1ObjectEventFlag:: dw
	ds 2
ENDM
```

This is all the same data that gets declared by the `object_event` macro, defined in [macros/scripts/maps.asm](../blob/master/macros/scripts/maps.asm):

```asm
object_event: MACRO
;\1: x: left to right, starts at 0
;\2: y: top to bottom, starts at 0
;\3: sprite: a SPRITE_* constant
;\4: movement function: a SPRITEMOVEDATA_* constant
;\5, \6: movement radius: x, y
;\7, \8: hour limits: h1, h2 (0-23)
;  * if h1 < h2, the object_event will only appear from h1 to h2
;  * if h1 > h2, the object_event will not appear from h2 to h1
;  * if h1 == h2, the object_event will always appear
;  * if h1 == -1, h2 is treated as a time-of-day value:
;    a combo of MORN, DAY, and/or NITE, or -1 to always appear
;\9: color: a PAL_NPC_* constant, or 0 for sprite default
;\10: function: a OBJECTTYPE_* constant
;\11: sight range: applies to OBJECTTYPE_TRAINER
;\12: script pointer
;\13: event flag: an EVENT_* constant, or -1 to always appear
	db \3, \2 + 4, \1 + 4, \4
	dn \6, \5
	db \7, \8
	shift
	dn \8, \9
	shift
	db \9
	shift
	dw \9
	shift
	dw \9
ENDM
```

`wObjectMasks` is likewise an array of mask bytes, one for each possible object. If the mask is −1, the object is hidden.

Basically, the `object_event` structs in the ROM get copied into the `map_object` structs in RAM, so there needs to be enough space in RAM for all of them. And each new object needs 17 bytes—16 for its `map_object` (count them), and one for its mask—so we had to use 34 of the unused bytes in that `ds 40`.

If you wanted to allow an 18th object, you would have to find 17 bytes of unused space here and there in the same `SECTION` as `wMapObjects` and `wObjectMasks`. Which is not difficult; if you scroll down to the "`map scene ids`" and "`fight counts`", they both have large chunks of unused space afterwards (`ds 49` and `ds 100`).