Make stairs work

This commit is contained in:
2025-11-11 22:12:08 -06:00
parent 4f8f6a47cb
commit 9f23533069
10 changed files with 103 additions and 48 deletions

View File

@@ -76,20 +76,43 @@ void entityWalk(entity_t *entity, const entitydir_t direction) {
}
// Get tile under foot
tile_t tile = mapGetTile(newPos);
if(tile == TILE_NULL && newPos.z > 0) {
// Check one level down for walkable tile (stairs down)
tile_t tileCurrent = mapGetTile(entity->position);
tile_t tileNew = mapGetTile(newPos);
bool_t fall = false;
bool_t raise = false;
// Are we walking up stairs?
if(
tileIsStairs(tileCurrent) &&
(direction+TILE_STAIRS_SOUTH) == tileCurrent &&
newPos.z < (MAP_CHUNK_DEPTH - 1)
) {
tileNew = TILE_NULL;// Force check for stairs above.
worldpos_t abovePos = newPos;
abovePos.z += 1;
tile_t tileAbove = mapGetTile(abovePos);
if(tileAbove != TILE_NULL && tileIsWalkable(tileAbove)) {
// We can go up the stairs.
raise = true;
}
} else if(tileNew == TILE_NULL && newPos.z > 0) {
// Falling down?
worldpos_t belowPos = newPos;
belowPos.z -= 1;
tile_t belowTile = mapGetTile(belowPos);
if(belowTile == TILE_STAIRS_UP) {
tile = TILE_STAIRS_DOWN;// Mark current as stairs down
tile_t tileBelow = mapGetTile(belowPos);
if(
tileBelow != TILE_NULL &&
tileIsStairs(tileBelow) &&
(entityDirGetOpposite(direction)+TILE_STAIRS_SOUTH) == tileBelow
) {
// We will fall to this tile.
fall = true;
}
}
// Tile walkable?
if(!tileIsWalkable(tile)) return;
// Can we walk here?
if(!raise && !fall && !tileIsWalkable(tileNew)) return;// Blocked
// Entity in way?
entity_t *other = ENTITIES;
@@ -105,13 +128,10 @@ void entityWalk(entity_t *entity, const entitydir_t direction) {
entity->animation = ENTITY_ANIM_WALK;
entity->animTime = ENTITY_ANIM_WALK_DURATION;// TODO: Running vs walking
// We are comitting, we can run effects here.
if(tile == TILE_STAIRS_DOWN) {
// Moving down a level
entity->position.z -= 1;
} else if(tile == TILE_STAIRS_UP) {
// Moving up a level
if(raise) {
entity->position.z += 1;
} else if(fall) {
entity->position.z -= 1;
}
}

View File

@@ -8,6 +8,16 @@
#include "entitydir.h"
#include "assert/assert.h"
entitydir_t entityDirGetOpposite(const entitydir_t dir) {
switch(dir) {
case ENTITY_DIR_NORTH: return ENTITY_DIR_SOUTH;
case ENTITY_DIR_SOUTH: return ENTITY_DIR_NORTH;
case ENTITY_DIR_EAST: return ENTITY_DIR_WEST;
case ENTITY_DIR_WEST: return ENTITY_DIR_EAST;
default: return dir;
}
}
void entityDirGetRelative(
const entitydir_t from,
worldunits_t *outX,

View File

@@ -20,6 +20,14 @@ typedef enum {
ENTITY_DIR_RIGHT = ENTITY_DIR_EAST,
} entitydir_t;
/**
* Gets the opposite direction of a given direction.
*
* @param dir The direction to get the opposite of.
* @return entitydir_t The opposite direction.
*/
entitydir_t entityDirGetOpposite(const entitydir_t dir);
/**
* Asserts a given direction is valid.
*

View File

@@ -8,10 +8,10 @@
#pragma once
#include "rpg/world/tile.h"
#include "worldpos.h"
#include "display/mesh/mesh.h"
#include "display/mesh/quad.h"
#define CHUNK_VERTEX_COUNT_MAX (6 * CHUNK_TILE_COUNT * 2)
#define CHUNK_MESH_COUNT_MAX 12
#define CHUNK_VERTEX_COUNT_MAX (QUAD_VERTEX_COUNT * CHUNK_TILE_COUNT * 2)
#define CHUNK_MESH_COUNT_MAX 14
typedef struct chunk_s {
chunkpos_t position;

View File

@@ -1,14 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct {
vec2 min;
vec2 max;
} region_t;

View File

@@ -8,9 +8,28 @@
#include "tile.h"
bool_t tileIsWalkable(const tile_t tile) {
return (
tile == TILE_WALKABLE ||
tile == TILE_STAIRS_UP ||
tile == TILE_STAIRS_DOWN
);
switch(tile) {
case TILE_WALKABLE:
case TILE_STAIRS_NORTH:
case TILE_STAIRS_SOUTH:
case TILE_STAIRS_EAST:
case TILE_STAIRS_WEST:
return true;
default:
return false;
}
}
bool_t tileIsStairs(const tile_t tile) {
switch(tile) {
case TILE_STAIRS_NORTH:
case TILE_STAIRS_SOUTH:
case TILE_STAIRS_EAST:
case TILE_STAIRS_WEST:
return true;
default:
return false;
}
}

View File

@@ -6,15 +6,18 @@
*/
#pragma once
#include "dusk.h"
#include "rpg/entity/entitydir.h"
typedef uint8_t tile_t;
#define TILE_NULL 0
#define TILE_WALKABLE 1
#define TILE_STAIRS_UP 2
#define TILE_STAIRS_DOWN 3
#define TILE_STAIRS_SOUTH (2 + ENTITY_DIR_SOUTH)
#define TILE_STAIRS_EAST (2 + ENTITY_DIR_EAST)
#define TILE_STAIRS_WEST (2 + ENTITY_DIR_WEST)
#define TILE_STAIRS_NORTH (2 + ENTITY_DIR_NORTH)
#define TILE_TEST 6
/**
* Returns whether or not the given tile is walkable.
@@ -22,4 +25,12 @@ typedef uint8_t tile_t;
* @param tile The tile to check.
* @return bool_t True if walkable, false if not.
*/
bool_t tileIsWalkable(const tile_t tile);
bool_t tileIsWalkable(const tile_t tile);
/**
* Returns whether or not the given tile is a stairs tile.
*
* @param tile The tile to check.
* @return bool_t True if stairs, false if not.
*/
bool_t tileIsStairs(const tile_t tile);

View File

@@ -10,7 +10,7 @@
#define CHUNK_WIDTH 16
#define CHUNK_HEIGHT 16
#define CHUNK_DEPTH 8
#define CHUNK_DEPTH 4
#define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH)
#define MAP_CHUNK_WIDTH 3