Allow tall grass in forests - pret/pokecrystal GitHub Wiki
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.
Contents
- Understanding environment types
- Rename the environment constant
- Finalize map permissions
- Update field move blocks
1. Understanding environment types
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
.
2. Rename the environment constant
Edit constants/map_data_constants.asm:
const CAVE
- const ENVIRONMENT_5
+ const FOREST
Edit 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 DUNGEON
Edit 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 ; dark
Edit engine/battle/battle_transition.asm:
StartTrainerBattle_DetermineWhichAnimation:
...
- cp ENVIRONMENT_5
+ cp FOREST
jr z, .cave
Edit 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
ret
We'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
ret
Edit engine/overworld/map_setup.asm: Note: in older versions of pokecrystal this is called .CheckSurfing2:
.ResetSurfingOrBikingState:
...
call GetMapEnvironment
cp INDOOR
jr z, .no_biking
- cp ENVIRONMENT_5
+ cp FOREST
jr z, .no_biking
Now we're done renaming the FOREST
constant, but we still have some things left to do.
3. Finalize map permissions
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
ret
Edit engine/overworld/map_setup.asm:
.ResetSurfingOrBikingState:
...
call GetMapEnvironment
cp INDOOR
jr z, .no_biking
- cp FOREST
- jr z, .no_biking
Edit 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 .nope
4. Update field move blocks
We 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 ; end
And 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.