diff options
author | Rangi <remy.oukaour+rangi42@gmail.com> | 2018-07-28 13:49:10 -0400 |
---|---|---|
committer | Rangi <remy.oukaour+rangi42@gmail.com> | 2018-07-28 13:49:10 -0400 |
commit | 25103d65e37c07f9e629feaf9c6e9be3bf1f743d (patch) | |
tree | 186623fb0db6e2bf8d9e66cbf868f42fc970a4a6 | |
parent | 571f1554dad9482c11c86dfb3dff7e6735dfeabd (diff) |
Allow more than 15 object_events per map
-rw-r--r-- | Allow-more-than-15-object_events-per-map.md | 145 | ||||
-rw-r--r-- | Tutorials.md | 2 | ||||
-rw-r--r-- | screenshots/17-object_events.png | bin | 0 -> 1839 bytes |
3 files changed, 146 insertions, 1 deletions
diff --git a/Allow-more-than-15-object_events-per-map.md b/Allow-more-than-15-object_events-per-map.md new file mode 100644 index 0000000..2f67d9f --- /dev/null +++ b/Allow-more-than-15-object_events-per-map.md @@ -0,0 +1,145 @@ +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 $10 ++NUM_OBJECTS EQU $12 +``` + +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 two more `object_event`s. + +We can demonstrate this by editing [maps/GoldenrodCity.asm](../blob/master/maps/GoldenrodCity.asm): + +```diff +- db 15 ; object events ++ db 17 ; object events + object_event 7, 18, SPRITE_POKEFAN_M, SPRITEMOVEDATA_STANDING_UP, 0, 0, -1, -1, 0, OBJECTTYPE_SCRIPT, 0, GoldenrodCityPokefanMScript, EVENT_GOLDENROD_CITY_CIVILIANS + ... + object_event 12, 22, SPRITE_POKEFAN_M, SPRITEMOVEDATA_SPINRANDOM_SLOW, 0, 0, -1, -1, PAL_NPC_RED, OBJECTTYPE_SCRIPT, 0, MoveTutorScript, EVENT_GOLDENROD_CITY_MOVE_TUTOR ++ object_event 17, 12, SPRITE_YOUNGSTER, SPRITEMOVEDATA_STANDING_LEFT, 0, 0, -1, -1, PAL_NPC_RED, OBJECTTYPE_SCRIPT, 0, GoldenrodCityTrainSpotter1Script, EVENT_RESTORED_POWER_TO_KANTO ++ object_event 22, 13, SPRITE_YOUNGSTER, SPRITEMOVEDATA_SPINRANDOM_SLOW, 0, 0, -1, -1, PAL_NPC_BLUE, OBJECTTYPE_SCRIPT, 0, GoldenrodCityTrainSpotter2Script, EVENT_RESTORED_POWER_TO_KANTO ++ ++GoldenrodCityTrainSpotter1Script: ++ jumptextfaceplayer .Text ++ ++.Text: ++ text "The MAGNET TRAIN" ++ line "isn't here, so" ++ cont "we're safe on the" ++ cont "tracks." ++ ++ para "I'm disappointed" ++ line "though… I wanted" ++ cont "to photograph it!" ++ done ++ ++GoldenrodCityTrainSpotter2Script: ++ jumptextfaceplayer .Text ++ ++.Text: ++ text "Trainspotting is" ++ line "a hobby anyone" ++ cont "can get into!" ++ ++ para "I collect train" ++ line "tickets and" ++ cont "timetables!" ++ done +``` + +The new 16th and 17th NPCs will appear: + + + +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`). diff --git a/Tutorials.md b/Tutorials.md index 2259341..2265c4d 100644 --- a/Tutorials.md +++ b/Tutorials.md @@ -40,6 +40,7 @@ Tutorials may use diff syntax to show edits: - [Expand tilesets from 192 to 255 tiles](Expand-tilesets-from-192-to-255-tiles) - [Allow map tiles to appear above sprites (so NPCs can walk behind tiles) with `PRIORITY` colors](Allow-map-tiles-to-appear-above-sprites-\(so-NPCs-can-walk-behind-tiles\)-with-PRIORITY-colors) - [Allow tiles to have different attributes in different blocks (including X and Y flip)](Allow-tiles-to-have-different-attributes-in-different-blocks-\(including-X-and-Y-flip\)) +- [Allow more than 15 `object_event`s per map](Allow-more-than-15-object_events-per-map) - [Increase Pokémon sprite animation size](Increase-Pokémon-sprite-animation-size) - [Allow more trainer parties, with individual DVs, stat experience, and nicknames](Allow-more-trainer-parties,-with-individual-DVs,-stat-experience,-and-nicknames) - [Colored trainer card badges](Colored-trainer-card-badges) @@ -80,7 +81,6 @@ Tutorials may use diff syntax to show edits: - Dive (exists in [Orange](https://github.com/PiaCarrot/pokeorange)) - Evolution methods (location, held item, move, [etc](https://gitgud.io/pfero/axyllagame/commit/81914d43eb89195734caee724c0a40d4686a0bab)) - More daily and weekly events -- More than 15 `object_event`s per map - Third trainer card page for Kanto badges - Fourth stats page for caught data - Colored party menu icons diff --git a/screenshots/17-object_events.png b/screenshots/17-object_events.png Binary files differnew file mode 100644 index 0000000..26d2c07 --- /dev/null +++ b/screenshots/17-object_events.png |