summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2019-02-10 15:39:13 -0500
committerRangi <remy.oukaour+rangi42@gmail.com>2019-02-10 15:39:13 -0500
commit6ebb633ad9f881c428d3d2563251498b121094a5 (patch)
tree79b444db2323637c2783cfc69f2f61f6699cabb4
parent55147b4f9b95da615efe67b94016618bed315a58 (diff)
Diffs
-rw-r--r--Sideways-stairs-with-diagonal-movement.md418
-rw-r--r--screenshots/sideways-stair-tiles.pngbin0 -> 341 bytes
2 files changed, 402 insertions, 16 deletions
diff --git a/Sideways-stairs-with-diagonal-movement.md b/Sideways-stairs-with-diagonal-movement.md
index b809f45..fc6484b 100644
--- a/Sideways-stairs-with-diagonal-movement.md
+++ b/Sideways-stairs-with-diagonal-movement.md
@@ -4,13 +4,17 @@ All the stairs in Gen 1 and 2 only go upwards. Gen 3 had a few that go downwards
[Here](https://github.com/Rangi42/pokecrystal/commit/8095894b01b1b95d1cb6ab325ac84a825f5f9a90) are all the changes needed to implement diagonal stairs, applied to a copy of pokecrystal. You can `clone` [Rangi42/pokecrystal](https://github.com/Rangi42/pokecrystal/tree/diagonal-stairs) and `checkout` the `diagonal-stairs` branch to test it for yourself.
-![Screenshot](screenshots/sideways-stairs.png)
+## Contents
-## TOC
+1. [Define collision types for sideways stairs](#1-define-collision-types-for-sideways-stairs)
+2. [Add a step type for sideways stairs](#2-add-a-step-type-for-sideways-stairs)
+3. [Add movement commands for diagonal steps](#3-add-movement-commands-for-diagonal-steps)
+4. [Use the diagonal step movement for the sideways stair collision type](#4-use-the-diagonal-step-movement-for-the-sideways-stair-collision-type)
+5. [Add sideways stairs to a map](#5-add-sideways-stairs-to-a-map)
-## 1. Define the constants
+## 1. Define collision types for sideways stairs
Edit [constants/collision_constants.asm](../blob/master/constants/collision_constants.asm):
@@ -26,40 +30,422 @@ Edit [constants/collision_constants.asm](../blob/master/constants/collision_cons
; collision data type nybbles
LO_NYBBLE_GRASS EQU $07
- HI_NYBBLE_TALL_GRASS EQU $10
...
- HI_NYBBLE_SIDE_WALLS EQU $b0
HI_NYBBLE_UNUSED_C0 EQU $c0
+HI_NYBBLE_DIAGONAL_STAIRS EQU $d0
```
-The collision constants will let us apply the diagonal step to the player once it is programmed.
+And edit [data/collision_permissions.asm](../blob/master/data/collision_permissions.asm):
+
+```diff
+ TileCollisionTable::
+ ; entries correspond to COLL_* constants
+ ...
+- NONTALKABLE LANDTILE ; d0
+- NONTALKABLE LANDTILE ; d1
++ NONTALKABLE LANDTILE ; COLL_DIAGONAL_STAIRS_RIGHT
++ NONTALKABLE LANDTILE ; COLL_DIAGONAL_STAIRS_LEFT
+ ...
+```
+
+
+## 2. Add a step type for sideways stairs
-Now edit [constants/map_object_constants.asm](../blob/master/constants/map_object_constants.asm):
+Edit [constants/map_object_constants.asm](../blob/master/constants/map_object_constants.asm):
```diff
; StepTypesJumptable indexes (see engine/overworld/map_objects.asm)
const_def
const STEP_TYPE_00 ; 00
- const STEP_TYPE_SLEEP ; 01
...
- const STEP_TYPE_17 ; 17
- const STEP_TYPE_18 ; 18
const STEP_TYPE_SKYFALL_TOP ; 19
+ const STEP_TYPE_NPC_DIAGONAL_STAIRS
+ const STEP_TYPE_PLAYER_DIAGONAL_STAIRS
+```
+
+Then edit [engine/overworld/map_objects.asm](../blob/master/engine/overworld/map_objects.asm):
+
+```diff
+ StepTypesJumptable:
+ ; entries correspond to STEP_TYPE_* constants
+ dw ObjectMovementReset ; 00
+ ...
+ dw SkyfallTop ; 19
++ dw NPCDiagonalStairs
++ dw PlayerDiagonalStairs
+```
+
+```diff
++NPCDiagonalStairs:
++ ret
++
++PlayerDiagonalStairs:
++ call Field1cAnonymousJumptable
++; anonymous dw
++ dw .InitHorizontal1
++ dw .StepHorizontal
++ dw .InitHorizontal2
++ dw .StepHorizontal
++ dw .InitVertical
++ dw .StepVertical
++
++.InitHorizontal2:
++ call GetNextTile
++.InitHorizontal1:
++ ld hl, wPlayerStepFlags
++ set 7, [hl]
++ call IncrementObjectStructField1c
++.StepHorizontal:
++ call UpdateDiagonalStairsPosition
++ call UpdatePlayerStep
++ ld hl, OBJECT_STEP_DURATION
++ add hl, bc
++ dec [hl]
++ ret nz
++ call CopyNextCoordsTileToStandingCoordsTile
++ ld hl, OBJECT_FLAGS2
++ add hl, bc
++ res 3, [hl]
++ ld hl, wPlayerStepFlags
++ set 6, [hl]
++ set 4, [hl]
++ jp IncrementObjectStructField1c
++
++.InitVertical:
++ ld hl, OBJECT_ACTION
++ add hl, bc
++ ld [hl], OBJECT_ACTION_STAND
++
++; If you start on the bottom half of a block, you go up;
++; if you start on the top half, you go down.
++ ld a, [wMetatileStandingY]
++ and a
++ ld a, DOWN
++ jr z, .got_dir
++ ld a, UP
++.got_dir
++ ld hl, OBJECT_DIRECTION_WALKING
++ add hl, bc
++ ld [hl], a
++
++ call GetNextTile
++ ld hl, wPlayerStepFlags
++ set 7, [hl]
++ call IncrementObjectStructField1c
++.StepVertical:
++ call UpdateDiagonalStairsPosition
++ call UpdatePlayerStep
++ ld hl, OBJECT_STEP_DURATION
++ add hl, bc
++ dec [hl]
++ ret nz
++ ld hl, wPlayerStepFlags
++ set 6, [hl]
++ call CopyNextCoordsTileToStandingCoordsTile
++ ld hl, OBJECT_STEP_TYPE
++ add hl, bc
++ ld [hl], STEP_TYPE_SLEEP
++ ret
++
++UpdateDiagonalStairsPosition:
++ ld a, [wMetatileStandingY]
++ and a
++ ld e, 1
++ jr z, .goingdown
++ ld e, -1
++.goingdown
++ ld hl, OBJECT_SPRITE_Y_OFFSET
++ add hl, bc
++ ld a, [hl]
++ add e
++ ld [hl], a
++ ret
+```
+
+TODO: Explain changes.
+
+
+## 3. Add movement commands for diagonal steps
+
+Edit [macros/scripts/movement.asm](../blob/master/macros/scripts/movement.asm):
+
+```diff
+ ; MovementPointers indexes (see engine/overworld/movement.asm)
+ enum_start 0, +4
+
+ ; Directional movements
+
+ enum movement_turn_head ; $00
+ turn_head: MACRO
+ db movement_turn_head | \1
+ ENDM
...
+ enum movement_fast_jump_step ; $34
+ fast_jump_step: MACRO
+ db movement_fast_jump_step | \1
+ ENDM
++
++ enum movement_stairs_step
++stairs_step: MACRO
++ db movement_stairs_step | \1
++ENDM
+
+ __enumdir__ = +1
+```
+
+Then edit [engine/overworld/movement.asm](../blob/master/engine/overworld/movement.asm):
+
+```diff
+ MovementPointers:
+ ; entries correspond to macros/scripts/movement.asm enumeration
+ dw Movement_turn_head_down ; 00
+ ...
+ dw Movement_fast_jump_step_right ; 37
++ dw Movement_stairs_step_down
++ dw Movement_stairs_step_up
++ dw Movement_stairs_step_left
++ dw Movement_stairs_step_right
+ dw Movement_remove_sliding ; 38
+ ...
+```
+
+```diff
++Movement_stairs_step_down:
++ ld a, STEP_WALK << 2 | DOWN
++ jp DiagonalStairsStep
++
++Movement_stairs_step_up:
++ ld a, STEP_WALK << 2 | UP
++ jp DiagonalStairsStep
++
++Movement_stairs_step_left:
++ ld a, STEP_WALK << 2 | LEFT
++ jp DiagonalStairsStep
++
++Movement_stairs_step_right:
++ ld a, STEP_WALK << 2 | RIGHT
++ jp DiagonalStairsStep
++
++DiagonalStairsStep:
++ call InitStep
++ ld hl, OBJECT_1F
++ add hl, bc
++ ld [hl], $0
++
++ ld hl, OBJECT_ACTION
++ add hl, bc
++ ld [hl], OBJECT_ACTION_STEP
++
++ ld hl, wCenteredObject
++ ldh a, [hMapObjectIndexBuffer]
++ cp [hl]
++ jr z, .player
++
++ ld hl, OBJECT_STEP_TYPE
++ add hl, bc
++ ld [hl], STEP_TYPE_NPC_DIAGONAL_STAIRS
++ ret
++
++.player
++ ld hl, OBJECT_STEP_TYPE
++ add hl, bc
++ ld [hl], STEP_TYPE_PLAYER_DIAGONAL_STAIRS
++ ret
+```
+
+TODO: Explain changes.
+
+
+## 4. Use the diagonal step movement for the sideways stair collision type
+
+Edit [constants/map_object_constants.asm](../blob/master/constants/map_object_constants.asm) again:
+
+```diff
; DoPlayerMovement.DoStep arguments (see engine/overworld/player_movement.asm)
const_def
const STEP_SLOW ; 0
- const STEP_WALK ; 1
- const STEP_BIKE ; 2
- const STEP_LEDGE ; 3
- const STEP_ICE ; 4
- const STEP_TURN ; 5
- const STEP_BACK_LEDGE ; 6
+ ...
const STEP_WALK_IN_PLACE ; 7
+ const STEP_DIAGONAL_STAIRS
```
+
+Then edit [engine/overworld/player_movement.asm](../blob/master/engine/overworld/player_movement.asm):
+
+```diff
+ DoPlayerMovement::
+
+ ...
+
+ .Normal:
+ call .CheckForced
+ call .GetAction
+ call .CheckTile
+ ret c
+ call .CheckTurning
+ ret c
+ call .TryStep
+ ret c
+ call .TryJump
+ ret c
++ call .TryDiagonalStairs
++ ret c
+ call .CheckWarp
+ ret c
+ jr .NotMoving
+
+ ...
+
+ .Ice:
+ call .CheckForced
+ call .GetAction
+ call .CheckTile
+ ret c
+ call .CheckTurning
+ ret c
+ call .TryStep
+ ret c
+ call .TryJump
+ ret c
++ call .TryDiagonalStairs
++ ret c
+ call .CheckWarp
+ ret c
+ ld a, [wWalkingDirection]
+ cp STANDING
+ jr z, .HitWall
+ call .BumpSound
+ .HitWall:
+ call .StandInPlace
+ xor a
+ ret
+```
+
+```diff
+ .TryJump:
+ ld a, [wPlayerStandingTile]
+ ld e, a
+ and $f0
+ cp HI_NYBBLE_LEDGES
+ jr nz, .DontJump
+
+ ld a, e
+ and 7
+ ld e, a
+ ld d, 0
+ ld hl, .data_8021e
+ add hl, de
+ ld a, [wFacingDirection]
+ and [hl]
+ jr z, .DontJump
+
+ ld de, SFX_JUMP_OVER_LEDGE
+ call PlaySFX
+ ld a, STEP_LEDGE
+ call .DoStep
+ ld a, 7
+ scf
+ ret
+
+ .DontJump:
+ xor a
+ ret
+
+ .data_8021e
+ db FACE_RIGHT ; COLL_HOP_RIGHT
+ db FACE_LEFT ; COLL_HOP_LEFT
+ db FACE_UP ; COLL_HOP_UP
+ db FACE_DOWN ; COLL_HOP_DOWN
+ db FACE_RIGHT | FACE_DOWN ; COLL_HOP_DOWN_RIGHT
+ db FACE_DOWN | FACE_LEFT ; COLL_HOP_DOWN_LEFT
+ db FACE_UP | FACE_RIGHT ; COLL_HOP_UP_RIGHT
+ db FACE_UP | FACE_LEFT ; COLL_HOP_UP_LEFT
++
++.TryDiagonalStairs:
++ ld a, [wPlayerStandingTile]
++ ld e, a
++ and $f0
++ cp HI_NYBBLE_DIAGONAL_STAIRS
++ jr nz, .DontDiagonalStairs
++
++ ld a, e
++ and 7
++ ld e, a
++ ld d, 0
++ ld hl, .FacingStairsTable
++ add hl, de
++ ld a, [wFacingDirection]
++ and [hl]
++ jr z, .DontDiagonalStairs
++
++ ld a, STEP_DIAGONAL_STAIRS
++ call .DoStep
++ ld a, 7
++ scf
++ ret
++
++.FacingStairsTable:
++ db FACE_RIGHT
++ db FACE_LEFT
++
++.DontDiagonalStairs:
++ xor a
++ ret
+```
+
+```diff
+ .Steps:
+ ; entries correspond to STEP_* constants
+ dw .SlowStep
+ dw .NormalStep
+ dw .FastStep
+ dw .JumpStep
+ dw .SlideStep
+ dw .TurningStep
+ dw .BackJumpStep
+ dw .FinishFacing
++ dw .DiagonalStairsStep
+
+ .SlowStep:
+ slow_step DOWN
+ slow_step UP
+ slow_step LEFT
+ slow_step RIGHT
+ ...
+ .FinishFacing:
+ db $80 | DOWN
+ db $80 | UP
+ db $80 | LEFT
+ db $80 | RIGHT
++.DiagonalStairsStep:
++ stairs_step DOWN
++ stairs_step UP
++ stairs_step LEFT
++ stairs_step RIGHT
+```
+
+TODO: Explain changes.
+
+
+## 5. Add sideways stairs to a map
+
+Here are some sideways stair tiles:
+
+![Screenshot](screenshots/sideways-stair-tiles.png)
+
+Let's say you want to add some sideways stairs to the cliffs on Route 45. Since [maps/Route45.blk](../blob/master/maps/Route45.blk) uses the `johto` tileset, here's what that would involve:
+
+1. Add the stair tiles to [gfx/tilesets/johto.png](../blob/master/gfx/tilesets/johto.png)
+2. Assign the `GRAY` color to those tiles in [gfx/tilesets/johto_palette_map.asm](../blob/master/gfx/tilesets/johto_palette_map.asm)
+3. Design sideways stair blocks in [data/tilesets/johto_metatiles.bin](../blob/master/data/tilesets/johto_metatiles.bin)
+4. Assign the `DIAGONAL_STAIRS_LEFT` and `DIAGONAL_STAIRS_RIGHT` collision types to those blocks in [data/tilesets/johto_collision.asm](../blob/master/data/tilesets/johto_collision.asm)
+5. Redesign [maps/Route45.blk](../blob/master/maps/Route45.blk) to use the sideways stair blocks
+
+You can use [Polished Map](https://github.com/Rangi42/polished-map) to edit maps and tilesets; refer to the [new map](Add-a-new-map-and-landmark) and [new tileset](Add-a-new-tileset) tutorials for more information.
+
+Now test it out!
+
+![Screenshot](screenshots/sideways-stairs.png)
+
+TODO: Explain how to use `COLL_DIAGONAL_STAIRS_RIGHT` and `COLL_DIAGONAL_STAIRS_LEFT`.
diff --git a/screenshots/sideways-stair-tiles.png b/screenshots/sideways-stair-tiles.png
new file mode 100644
index 0000000..f84b057
--- /dev/null
+++ b/screenshots/sideways-stair-tiles.png
Binary files differ