#ifndef GENESIS_BLOBBER_CELL3D_H
#define GENESIS_BLOBBER_CELL3D_H

#include <stdint.h>

#define BL_DCOLS 79
#define BL_DROWS 29

/* Floor types are prefixed FT_ to avoid colliding with the legacy
   gen/grid.h cell_flag_t values (F_IN_ROOM, F_BRIDGE flag, ...). */
typedef enum {
    FT_VOID      = 0,  /* fully solid \u2014 no cell you can stand in */
    FT_STONE     = 1,
    FT_WATER     = 2,
    FT_LAVA      = 3,
    FT_CHASM     = 4,  /* no floor; fall through to cell below */
    FT_STAIR_UP  = 5,
    FT_STAIR_DOWN= 6,
    FT_BRIDGE    = 7,
    FT_DOOR_SILL = 8,
} b_floor_t;

typedef enum {
    C_OPEN  = 0,  /* open to cell above (chasm ceiling / sky shaft) */
    C_STONE = 1,
    C_SKY   = 2,
} b_ceiling_t;

typedef enum {
    W_NONE   = 0,  /* open \u2014 party can pass */
    W_SOLID  = 1,
    W_DOOR   = 2,
    W_SECRET = 3,
    W_ARCH   = 4,  /* visible opening, decorative frame */
} b_wall_t;

typedef enum {
    FACE_N = 0,  /* \u2212y */
    FACE_E = 1,  /* +x */
    FACE_S = 2,  /* +y */
    FACE_W = 3,  /* \u2212x */
} b_face_t;

typedef enum {
    S_VOID      = 0,
    S_ROOM      = 1,
    S_CORRIDOR  = 2,
    S_DOOR      = 3,
    S_CAVE      = 4,  /* rougher material; still blocky geometry */
    S_MACHINE   = 5,
} b_style_t;

typedef enum {
    BF_IN_LOOP           = 1u << 0,
    BF_CHOKEPT           = 1u << 1,
    BF_IN_MACHINE        = 1u << 2,
    BF_MACHINE_GATE      = 1u << 3,
    BF_MACHINE_IMPREG    = 1u << 4,
    BF_WREATH            = 1u << 5,
} b_flag_t;

typedef struct {                /* 10 bytes */
    uint8_t  floor;             /* b_floor_t */
    uint8_t  ceiling;           /* b_ceiling_t */
    uint8_t  walls[4];          /* b_wall_t per b_face_t (N,E,S,W) */
    uint8_t  marker;            /* MK_* from src/gen/grid.h (reused enum) */
    uint8_t  style;             /* b_style_t */
    uint16_t room_id;           /* 0 = not in a room */
    uint8_t  machine_id;
    uint8_t  flags;             /* b_flag_t bitfield */
} cell3d_t;

static inline int b_in_bounds(int x, int y) {
    return x >= 0 && x < BL_DCOLS && y >= 0 && y < BL_DROWS;
}

static inline int b_floor_is_standable(uint8_t f) {
    return f == FT_STONE || f == FT_BRIDGE || f == FT_DOOR_SILL
        || f == FT_STAIR_UP || f == FT_STAIR_DOWN;
}

#endif
