-
Notifications
You must be signed in to change notification settings - Fork 927
Allow tall grass in forests
Internally, Generation 2 treats Ilex Forest as a cave, meaning that the player will encounter wild Pokémon just by walking around. However, this means that you can't just add tall grass there, or in any other forest map one may wish to implement.
- Understanding environment types
- Rename the environment constant
- Finalize map permissions
- Update field move blocks
In the Generation 2 games, each map is assigned an "environment type", which are defined in data/maps/maps.asm. Each type handles what the player can or can't do in a certain map. For example, one can't use Fly or ride a bike in an INDOOR map, but the bike can be used in a GATE. Meanwhile, an Escape Rope can only be used in either a CAVE or a DUNGEON.
For the sake of this tutorial, we'll be repurposing the unused ENVIRONMENT_5 into a new type, which we'll call FOREST.
Edit constants/map_data_constants.asm:
const CAVE
- const ENVIRONMENT_5
+ const FORESTEdit data/maps/maps.asm:
;\2: tileset: a TILESET_* constant
-;\3: environment: TOWN, ROUTE, INDOOR, CAVE, ENVIRONMENT_5, GATE, or DUNGEON
+;\3: environment: TOWN, ROUTE, INDOOR, CAVE, FOREST, GATE, or DUNGEONEdit data/maps/environment_colors.asm:
dw .DungeonColors ; CAVE
- dw .Env5Colors ; ENVIRONMENT_5
+ dw .ForestColors ; FOREST
...
-.Env5Colors:
+.ForestColors:
db $00, $01, $02, $03, $04, $05, $06, $07 ; morn
db $08, $09, $0a, $0b, $0c, $0d, $0e, $0f ; day
db $10, $11, $12, $13, $14, $15, $16, $17 ; nite
db $18, $19, $1a, $1b, $1c, $1d, $1e, $1f ; darkEdit engine/battle/battle_transition.asm:
StartTrainerBattle_DetermineWhichAnimation:
...
- cp ENVIRONMENT_5
+ cp FOREST
jr z, .caveEdit engine/gfx/sgb_layouts.asm:
cp DUNGEON
jr z, .cave
- cp ENVIRONMENT_5
- jr z, .env5
+ cp FOREST
+ jr z, .forest
...
-.env5
+.forest
ld a, PREDEFPAL_VERMILION
retWe'll be going back to the next two files later on this tutorial.
Edit home/map.asm:
CheckUnknownMap:: ; unreferenced
cp INDOOR
ret z
cp GATE
ret z
- cp ENVIRONMENT_5
+ cp FOREST
retEdit engine/overworld/map_setup.asm:
(Note: older versions of pokecrystal call this function .CheckSurfing2)
.ResetSurfingOrBikingState:
...
call GetMapEnvironment
cp INDOOR
jr z, .no_biking
- cp ENVIRONMENT_5
+ cp FOREST
jr z, .no_bikingNow we're done renaming the FOREST constant, but we still have some things left to do.
As is, the player won't be able to ride the bike in a FOREST map, and Dig/Escapes Ropes won't work either. To fix that, some files need to be updated.
Edit home/map.asm:
CheckIndoorMap::
cp INDOOR
ret z
cp CAVE
ret z
cp DUNGEON
ret z
cp GATE
+ ret z
+ cp FOREST
retEdit engine/overworld/map_setup.asm:
.ResetSurfingOrBikingState:
...
call GetMapEnvironment
cp INDOOR
jr z, .no_biking
- cp FOREST
- jr z, .no_bikingEdit engine/events/overworld.asm:
.CheckCanDig:
call GetMapEnvironment
cp CAVE
jr z, .incave
cp DUNGEON
jr z, .incave
+ cp FOREST
+ jr z, .incave
.fail
ld a, $2
ret
...
.CheckEnvironment:
call GetMapEnvironment
call CheckOutdoorMap
jr z, .ok
cp CAVE
jr z, .ok
cp GATE
jr z, .ok
+ cp FOREST
+ jr z, .ok
jr .nopeWe only have one thing left to take care of, which is allow tall grass to be hacked away using Cut.
To do so, we'll have to edit the table which handles block replacements related to overworld field moves. Here, we'll assume you added the new tall grass block at ID $28. That's the target block, which is followed by the one it will be replaced with (in this case, the regular grassy floor block).
Edit data/collision/field_move_blocks.asm:
.forest:
; facing block, replacement block, animation
db $0f, $17, 0
+ db $28, $01, 1
db -1 ; endAnd there we go! Now you can have maps use the FOREST type, which lets the player use the bike, Dig, and Escape Ropes, but restricts the use of Fly.
