map: expand tile system with doors
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I5704e8f954f6f935954c46ef8af40b836a6a6964
This commit is contained in:
parent
ceb657add8
commit
2f5c959500
3 changed files with 176 additions and 11 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#include "rng/rng.h"
|
||||
#include "settings.h"
|
||||
#include "utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -20,7 +21,8 @@ void map_init(Map *map) {
|
|||
int is_floor(const Map *map, int x, int y) {
|
||||
if (!in_bounds(x, y, MAP_WIDTH, MAP_HEIGHT))
|
||||
return 0;
|
||||
return map->tiles[y][x] == TILE_FLOOR || map->tiles[y][x] == TILE_STAIRS;
|
||||
return map->tiles[y][x] == TILE_FLOOR || map->tiles[y][x] == TILE_STAIRS || map->tiles[y][x] == TILE_DOOR_OPEN ||
|
||||
map->tiles[y][x] == TILE_DOOR_RUINED;
|
||||
}
|
||||
|
||||
void get_room_center(Room *room, int *cx, int *cy) {
|
||||
|
|
@ -109,6 +111,32 @@ static int generate_rooms(Map *map, Room *rooms, int floor) {
|
|||
return room_count;
|
||||
}
|
||||
|
||||
// Check if a tile is at a room boundary (adjacent to wall but inside room)
|
||||
static int is_room_boundary(Map *map, int x, int y) {
|
||||
// Must be floor
|
||||
if (map->tiles[y][x] != TILE_FLOOR)
|
||||
return 0;
|
||||
// Must have at least one adjacent wall
|
||||
if (in_bounds(x - 1, y, MAP_WIDTH, MAP_HEIGHT) && map->tiles[y][x - 1] == TILE_WALL)
|
||||
return 1;
|
||||
if (in_bounds(x + 1, y, MAP_WIDTH, MAP_HEIGHT) && map->tiles[y][x + 1] == TILE_WALL)
|
||||
return 1;
|
||||
if (in_bounds(x, y - 1, MAP_WIDTH, MAP_HEIGHT) && map->tiles[y - 1][x] == TILE_WALL)
|
||||
return 1;
|
||||
if (in_bounds(x, y + 1, MAP_WIDTH, MAP_HEIGHT) && map->tiles[y + 1][x] == TILE_WALL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Place doors at corridor-room junctions
|
||||
// DISABLED: Door placement removed per user request
|
||||
static void place_doors(Map *map, Room *rooms, int room_count) {
|
||||
(void)map;
|
||||
(void)rooms;
|
||||
(void)room_count;
|
||||
// No-op: doors disabled
|
||||
}
|
||||
|
||||
// Connect all rooms with corridors
|
||||
static void connect_rooms(Map *map, Room *rooms, int room_count) {
|
||||
for (int i = 0; i < room_count - 1; i++) {
|
||||
|
|
@ -125,6 +153,9 @@ static void connect_rooms(Map *map, Room *rooms, int room_count) {
|
|||
carve_h_corridor(map, cx1, cx2, cy2);
|
||||
}
|
||||
}
|
||||
|
||||
// Place doors after all corridors are carved
|
||||
place_doors(map, rooms, room_count);
|
||||
}
|
||||
|
||||
// Place stairs in the last room (furthest from start)
|
||||
|
|
@ -134,8 +165,43 @@ static void place_stairs(Map *map, Room *rooms, int room_count) {
|
|||
int cx, cy;
|
||||
get_room_center(last_room, &cx, &cy);
|
||||
|
||||
// Place stairs at center of last room
|
||||
// Ensure stairs are placed on a floor tile, not a wall
|
||||
if (in_bounds(cx, cy, MAP_WIDTH, MAP_HEIGHT) && map->tiles[cy][cx] == TILE_FLOOR) {
|
||||
map->tiles[cy][cx] = TILE_STAIRS;
|
||||
return;
|
||||
}
|
||||
|
||||
// 3x3 fallback
|
||||
for (int dy = -1; dy <= 1; dy++) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
int nx = cx + dx;
|
||||
int ny = cy + dy;
|
||||
if (in_bounds(nx, ny, MAP_WIDTH, MAP_HEIGHT) && map->tiles[ny][nx] == TILE_FLOOR) {
|
||||
map->tiles[ny][nx] = TILE_STAIRS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expanded fallback: scan the room for any floor tile
|
||||
for (int dy = 0; dy < last_room->h; dy++) {
|
||||
for (int dx = 0; dx < last_room->w; dx++) {
|
||||
int nx = last_room->x + dx;
|
||||
int ny = last_room->y + dy;
|
||||
if (in_bounds(nx, ny, MAP_WIDTH, MAP_HEIGHT) && map->tiles[ny][nx] == TILE_FLOOR) {
|
||||
map->tiles[ny][nx] = TILE_STAIRS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Final fallback: force the center tile to stairs regardless of type
|
||||
fprintf(stderr, "Warning: No floor tile found for stairs at room center (%d, %d). Forcing stairs placement.\n", cx,
|
||||
cy);
|
||||
if (in_bounds(cx, cy, MAP_WIDTH, MAP_HEIGHT)) {
|
||||
if (map->tiles[cy][cx] == TILE_WALL) {
|
||||
map->tiles[cy][cx] = TILE_FLOOR;
|
||||
}
|
||||
map->tiles[cy][cx] = TILE_STAIRS;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
114
src/common.h
114
src/common.h
|
|
@ -9,7 +9,7 @@ typedef struct {
|
|||
} Vec2;
|
||||
|
||||
// Tile types
|
||||
typedef enum { TILE_WALL, TILE_FLOOR, TILE_STAIRS } TileType;
|
||||
typedef enum { TILE_WALL, TILE_FLOOR, TILE_STAIRS, TILE_DOOR_CLOSED, TILE_DOOR_OPEN, TILE_DOOR_RUINED } TileType;
|
||||
|
||||
// Status effect types
|
||||
typedef enum { EFFECT_NONE, EFFECT_POISON, EFFECT_STUN, EFFECT_BLEED, EFFECT_WEAKEN, EFFECT_BURN } StatusEffectType;
|
||||
|
|
@ -49,69 +49,165 @@ typedef struct {
|
|||
typedef enum { ITEM_POTION, ITEM_WEAPON, ITEM_ARMOR } ItemType;
|
||||
|
||||
// Item
|
||||
|
||||
typedef struct {
|
||||
int x, y;
|
||||
|
||||
ItemType type;
|
||||
|
||||
int power;
|
||||
|
||||
int floor;
|
||||
|
||||
int picked_up;
|
||||
|
||||
DamageClass dmg_class;
|
||||
|
||||
int crit_chance;
|
||||
|
||||
int crit_multiplier;
|
||||
|
||||
int status_chance;
|
||||
|
||||
// rendering
|
||||
|
||||
int sprite_tile_id; // tile ID for rendering
|
||||
|
||||
} Item;
|
||||
|
||||
// Player animation states
|
||||
typedef enum { PLAYER_ANIM_IDLE, PLAYER_ANIM_WALK, PLAYER_ANIM_ATTACK } PlayerAnimState;
|
||||
|
||||
// Player
|
||||
|
||||
typedef struct {
|
||||
Vec2 position;
|
||||
|
||||
int hp, max_hp;
|
||||
|
||||
int attack;
|
||||
|
||||
int defense;
|
||||
|
||||
int floor;
|
||||
|
||||
int step_count;
|
||||
int speed; // actions per 100 ticks (100 = 1 action per turn)
|
||||
|
||||
int speed; // actions per 100 ticks (100 = 1 action per turn)
|
||||
|
||||
int cooldown; // countdown to next action (0 = can act)
|
||||
int dodge; // dodge chance percentage
|
||||
int block; // flat damage reduction on successful block roll
|
||||
|
||||
int dodge; // dodge chance percentage
|
||||
|
||||
int block; // flat damage reduction on successful block roll
|
||||
|
||||
Item equipped_weapon;
|
||||
|
||||
int has_weapon;
|
||||
|
||||
Item equipped_armor;
|
||||
|
||||
int has_armor;
|
||||
|
||||
Item inventory[MAX_INVENTORY];
|
||||
|
||||
int inventory_count;
|
||||
|
||||
// status effects
|
||||
|
||||
StatusEffect effects[MAX_EFFECTS];
|
||||
|
||||
int effect_count;
|
||||
|
||||
// animation
|
||||
|
||||
PlayerAnimState anim_state;
|
||||
|
||||
int anim_frame; // current animation frame
|
||||
|
||||
int anim_timer; // frames until next frame
|
||||
|
||||
int facing_right; // 1 = facing right, 0 = facing left
|
||||
|
||||
// rendering
|
||||
|
||||
int sprite_tile_id; // tile ID for rendering
|
||||
|
||||
// visual effects
|
||||
|
||||
int flash_timer; // damage flash frames remaining
|
||||
|
||||
} Player;
|
||||
|
||||
// Enemy types
|
||||
typedef enum { ENEMY_GOBLIN, ENEMY_SKELETON, ENEMY_ORC } EnemyType;
|
||||
|
||||
// Enemy animation states
|
||||
typedef enum { ENEMY_ANIM_IDLE, ENEMY_ANIM_WALK, ENEMY_ANIM_ATTACK } EnemyAnimState;
|
||||
|
||||
// Enemy
|
||||
|
||||
typedef struct {
|
||||
Vec2 position;
|
||||
|
||||
int hp;
|
||||
|
||||
int max_hp;
|
||||
|
||||
int attack;
|
||||
|
||||
int alive;
|
||||
|
||||
EnemyType type;
|
||||
int speed; // actions per 100 ticks
|
||||
|
||||
int speed; // actions per 100 ticks
|
||||
|
||||
int cooldown; // countdown to next action
|
||||
int dodge; // dodge chance percentage
|
||||
int block; // flat damage reduction
|
||||
|
||||
int dodge; // dodge chance percentage
|
||||
|
||||
int block; // flat damage reduction
|
||||
|
||||
int resistance[NUM_DMG_CLASSES];
|
||||
|
||||
DamageClass dmg_class;
|
||||
|
||||
int status_chance;
|
||||
|
||||
int crit_chance; // crit chance percentage (0-100)
|
||||
int crit_mult; // crit damage multiplier percentage (e.g. 150 = 1.5x)
|
||||
|
||||
int crit_mult; // crit damage multiplier percentage (e.g. 150 = 1.5x)
|
||||
|
||||
// vision
|
||||
|
||||
int vision_range;
|
||||
int alert; // 1 = aware of player, searching
|
||||
|
||||
int alert; // 1 = aware of player, searching
|
||||
|
||||
int last_known_x; // last position where enemy saw player
|
||||
|
||||
int last_known_y;
|
||||
|
||||
// status effects
|
||||
|
||||
StatusEffect effects[MAX_EFFECTS];
|
||||
|
||||
int effect_count;
|
||||
|
||||
// animation
|
||||
|
||||
EnemyAnimState anim_state;
|
||||
|
||||
int anim_frame; // current animation frame
|
||||
|
||||
int anim_timer; // frames until next frame
|
||||
|
||||
int facing_right; // 1 = facing right, 0 = facing left
|
||||
|
||||
// rendering
|
||||
|
||||
int sprite_tile_id; // tile ID for rendering
|
||||
|
||||
} Enemy;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -83,4 +83,7 @@
|
|||
#define ENEMY_VIEW_RANGE 6
|
||||
#define ENEMY_PATROL_MOVE_CHANCE 30
|
||||
|
||||
// Visual polish
|
||||
#define DRAW_GRID_LINES 1
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue