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

  1. Understanding environment types
  2. Rename the environment constant
  3. Finalize map permissions
  4. 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.

image image