diff --git a/src/rpg/entity/entity.c b/src/rpg/entity/entity.c index 168c264..be46056 100644 --- a/src/rpg/entity/entity.c +++ b/src/rpg/entity/entity.c @@ -76,17 +76,19 @@ void entityWalk(entity_t *entity, const entitydir_t direction) { } // Get tile under foot - chunkpos_t chunkPos; - worldPosToChunkPos(&newPos, &chunkPos); - chunkindex_t chunkIndex = mapGetChunkIndexAt(chunkPos); - tile_t tile = TILE_NULL; - if(chunkIndex != -1) { - chunk_t *chunk = mapGetChunk(chunkIndex); - assertNotNull(chunk, "Chunk pointer cannot be NULL"); - chunktileindex_t tileIndex = woprldPosToChunkTileIndex(&newPos); - tile = chunk->tiles[tileIndex]; + tile_t tile = mapGetTile(newPos); + if(tile == TILE_NULL && newPos.z > 0) { + // Check one level down for walkable tile (stairs down) + worldpos_t belowPos = newPos; + belowPos.z -= 1; + tile = mapGetTile(belowPos); + + if(tile != TILE_NULL) newPos.z -= 1; } + // Tile walkable? + if(!tileIsWalkable(tile)) return; + // Entity in way? entity_t *other = ENTITIES; do { @@ -99,6 +101,8 @@ void entityWalk(entity_t *entity, const entitydir_t direction) { entity->position = newPos; entity->animation = ENTITY_ANIM_WALK; entity->animTime = ENTITY_ANIM_WALK_DURATION;// TODO: Running vs walking + + // We are comitting, we can run effects here. } entity_t * entityGetAt(const worldpos_t position) { diff --git a/src/rpg/world/CMakeLists.txt b/src/rpg/world/CMakeLists.txt index cec1f00..b2284d7 100644 --- a/src/rpg/world/CMakeLists.txt +++ b/src/rpg/world/CMakeLists.txt @@ -9,4 +9,5 @@ target_sources(${DUSK_TARGET_NAME} chunk.c map.c worldpos.c + tile.c ) \ No newline at end of file diff --git a/src/rpg/world/map.c b/src/rpg/world/map.c index 2883c89..125c139 100644 --- a/src/rpg/world/map.c +++ b/src/rpg/world/map.c @@ -7,6 +7,7 @@ #include "map.h" #include "util/memory.h" +#include "assert/assert.h" map_t MAP; @@ -126,16 +127,13 @@ void mapChunkLoad(chunk_t* chunk) { ); memoryZero(chunk->tiles, sizeof(tile_t) * CHUNK_TILE_COUNT); - uint8_t x, y, z; - x = 1; - y = 2; - z = 0; - - chunk->tiles[ - (z * CHUNK_WIDTH * CHUNK_HEIGHT) + - (y * CHUNK_WIDTH) + - x - ] = (tile_t){ .id = 1 }; + // 3x3 test walkable area + for(int y = 0; y <= 3; y++) { + for(int x = 0; x <= 3; x++) { + chunktileindex_t tileIndex = (y * CHUNK_WIDTH) + x; + chunk->tiles[tileIndex] = TILE_WALKABLE; + } + } } chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) { @@ -160,4 +158,16 @@ chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) { chunk_t* mapGetChunk(const uint8_t index) { if(index >= MAP_CHUNK_COUNT) return NULL; return &MAP.chunks[index]; +} + +tile_t mapGetTile(const worldpos_t position) { + chunkpos_t chunkPos; + worldPosToChunkPos(&position, &chunkPos); + chunkindex_t chunkIndex = mapGetChunkIndexAt(chunkPos); + if(chunkIndex == -1) return TILE_NULL; + + chunk_t *chunk = mapGetChunk(chunkIndex); + assertNotNull(chunk, "Chunk pointer cannot be NULL"); + chunktileindex_t tileIndex = woprldPosToChunkTileIndex(&position); + return chunk->tiles[tileIndex]; } \ No newline at end of file diff --git a/src/rpg/world/map.h b/src/rpg/world/map.h index 82fd8f1..6e1f33a 100644 --- a/src/rpg/world/map.h +++ b/src/rpg/world/map.h @@ -61,4 +61,12 @@ chunkindex_t mapGetChunkIndexAt(const chunkpos_t position); * @param chunkIndex The index of the chunk. * @return A pointer to the chunk. */ -chunk_t * mapGetChunk(const uint8_t chunkIndex); \ No newline at end of file +chunk_t * mapGetChunk(const uint8_t chunkIndex); + +/** + * Gets the tile at the given world position. + * + * @param position The world position. + * @return The tile at that position, or TILE_NULL if the chunk is unloaded. + */ +tile_t mapGetTile(const worldpos_t position); \ No newline at end of file diff --git a/src/rpg/world/tile.c b/src/rpg/world/tile.c new file mode 100644 index 0000000..09fe756 --- /dev/null +++ b/src/rpg/world/tile.c @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "tile.h" + +bool_t tileIsWalkable(const tile_t tile) { + return tile == TILE_WALKABLE; +} \ No newline at end of file diff --git a/src/rpg/world/tile.h b/src/rpg/world/tile.h index dbc923a..bbabcf9 100644 --- a/src/rpg/world/tile.h +++ b/src/rpg/world/tile.h @@ -9,8 +9,15 @@ #include "dusk.h" -typedef struct tile_s { - uint8_t id; -} tile_t; +typedef uint8_t tile_t; -#define TILE_NULL ((tile_t){ .id = 0 }) \ No newline at end of file +#define TILE_NULL 0 +#define TILE_WALKABLE 1 + +/** + * Returns whether or not the given tile is walkable. + * + * @param tile The tile to check. + * @return bool_t True if walkable, false if not. + */ +bool_t tileIsWalkable(const tile_t tile); \ No newline at end of file