diff options
author | Rangi <remy.oukaour+rangi42@gmail.com> | 2019-02-10 15:39:13 -0500 |
---|---|---|
committer | Rangi <remy.oukaour+rangi42@gmail.com> | 2019-02-10 15:39:13 -0500 |
commit | 6ebb633ad9f881c428d3d2563251498b121094a5 (patch) | |
tree | 79b444db2323637c2783cfc69f2f61f6699cabb4 | |
parent | 55147b4f9b95da615efe67b94016618bed315a58 (diff) |
Diffs
-rw-r--r-- | Sideways-stairs-with-diagonal-movement.md | 418 | ||||
-rw-r--r-- | screenshots/sideways-stair-tiles.png | bin | 0 -> 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. - +## 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: + + + +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! + + + +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 Binary files differnew file mode 100644 index 0000000..f84b057 --- /dev/null +++ b/screenshots/sideways-stair-tiles.png |