directional build mode

isolation_bkp/dynres
Dominik Madarász 2021-11-02 18:58:55 +01:00
parent 1a5a550512
commit 42a58ef5fb
8 changed files with 84 additions and 14 deletions

View File

@ -28,6 +28,7 @@ typedef enum {
ASSET_WOOD, ASSET_WOOD,
ASSET_TREE, ASSET_TREE,
ASSET_BELT,
ASSET_BELT_LEFT, ASSET_BELT_LEFT,
ASSET_BELT_RIGHT, ASSET_BELT_RIGHT,
ASSET_BELT_UP, ASSET_BELT_UP,

View File

@ -23,6 +23,8 @@ static asset assets[] = {
ASSET_TEX(ASSET_HOLE), ASSET_TEX(ASSET_HOLE),
ASSET_TEX(ASSET_WOOD), ASSET_TEX(ASSET_WOOD),
ASSET_TEX(ASSET_TREE), ASSET_TEX(ASSET_TREE),
ASSET_TEX(ASSET_BELT),
ASSET_TEX(ASSET_BELT_LEFT), ASSET_TEX(ASSET_BELT_LEFT),
ASSET_TEX(ASSET_BELT_RIGHT), ASSET_TEX(ASSET_BELT_RIGHT),
ASSET_TEX(ASSET_BELT_UP), ASSET_TEX(ASSET_BELT_UP),

View File

@ -27,8 +27,10 @@ Texture2D texgen_build_sprite(asset_id id) {
case ASSET_LAVA: return LoadImageEco("lava"); case ASSET_LAVA: return LoadImageEco("lava");
case ASSET_WOOD: return LoadImageEco("wood"); case ASSET_WOOD: return LoadImageEco("wood");
case ASSET_TREE: return LoadImageEco("tree"); case ASSET_TREE: return LoadImageEco("tree");
case ASSET_BELT_LEFT: return LoadImageEco("belt_left");
case ASSET_BELT:
case ASSET_BELT_RIGHT: return LoadImageEco("belt_right"); case ASSET_BELT_RIGHT: return LoadImageEco("belt_right");
case ASSET_BELT_LEFT: return LoadImageEco("belt_left");
case ASSET_BELT_UP: return LoadImageEco("belt_up"); case ASSET_BELT_UP: return LoadImageEco("belt_up");
case ASSET_BELT_DOWN: return LoadImageEco("belt_down"); case ASSET_BELT_DOWN: return LoadImageEco("belt_down");

View File

@ -24,15 +24,24 @@ uint64_t item_spawn(asset_id kind, uint32_t qty) {
return (uint64_t)e; return (uint64_t)e;
} }
static inline uint16_t item_resolve_proxy(uint16_t id) {
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
item_usage usage = items[id].usage;
if (usage == UKIND_PROXY) {
return item_find(items[id].proxy.id);
}
return id;
}
uint16_t item_find(asset_id kind) { uint16_t item_find(asset_id kind) {
for (uint16_t i=0; i<ITEMS_COUNT; i++) { for (uint16_t i=0; i<ITEMS_COUNT; i++) {
if (items[i].kind == kind) if (items[i].kind == kind)
return i; return item_resolve_proxy(i);
} }
return ASSET_INVALID; return ASSET_INVALID;
} }
void item_use(ecs_world_t *ecs, ItemDrop *it, Position p) { void item_use(ecs_world_t *ecs, ItemDrop *it, Position p, uint64_t udata) {
(void)ecs; (void)ecs;
uint16_t item_id = item_find(it->kind); uint16_t item_id = item_find(it->kind);
item_desc *desc = &items[item_id]; item_desc *desc = &items[item_id];
@ -41,7 +50,7 @@ void item_use(ecs_world_t *ecs, ItemDrop *it, Position p) {
case UKIND_HOLD: /* NOOP */ break; case UKIND_HOLD: /* NOOP */ break;
case UKIND_PLACE:{ case UKIND_PLACE:{
world_block_lookup l = world_block_from_realpos(p.x, p.y); world_block_lookup l = world_block_from_realpos(p.x, p.y);
if (world_chunk_place_block(l.chunk_id, l.id, blocks_find(desc->place.kind)) ) if (world_chunk_place_block(l.chunk_id, l.id, blocks_find(desc->place.kind + (asset_id)udata)) )
it->quantity--; it->quantity--;
}break; }break;
} }
@ -60,3 +69,8 @@ item_usage item_get_usage(uint16_t id) {
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT); ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
return items[id].usage; return items[id].usage;
} }
bool item_get_place_directional(uint16_t id) {
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
return items[id].place.directional;
}

View File

@ -7,6 +7,7 @@
typedef enum { typedef enum {
UKIND_HOLD, UKIND_HOLD,
UKIND_PROXY,
UKIND_PLACE, UKIND_PLACE,
UKIND_PLACE_ITEM, UKIND_PLACE_ITEM,
UKIND_END_PLACE, UKIND_END_PLACE,
@ -21,7 +22,12 @@ typedef struct {
union { union {
struct { struct {
asset_id kind; asset_id kind;
bool directional; // NOTE(zaklaus): expects next 4 asset entries to be direction assets
} place; } place;
struct {
asset_id id;
} proxy;
}; };
} item_desc; } item_desc;
@ -31,7 +37,8 @@ void item_despawn(uint64_t id);
// NOTE(zaklaus): items // NOTE(zaklaus): items
uint16_t item_find(asset_id kind); uint16_t item_find(asset_id kind);
void item_use(ecs_world_t *ecs, ItemDrop *it, Position p); void item_use(ecs_world_t *ecs, ItemDrop *it, Position p, uint64_t udata);
uint32_t item_max_quantity(uint16_t id); uint32_t item_max_quantity(uint16_t id);
item_usage item_get_usage(uint16_t id); item_usage item_get_usage(uint16_t id);
bool item_get_place_directional(uint16_t id);

View File

@ -17,7 +17,28 @@
}\ }\
} }
#define ITEM_BLOCK_DIR(asset, qty, build_asset)\
{\
.kind = asset,\
.usage = UKIND_PLACE,\
.max_quantity = qty,\
.place = {\
.kind = build_asset,\
.directional = true,\
}\
}
#define ITEM_PROXY(asset, proxy_id)\
{\
.kind = asset,\
.usage = UKIND_PROXY,\
.proxy = {\
.id = proxy_id,\
}\
}
#define ITEM_SELF(asset, qty) ITEM_BLOCK(asset, qty, asset) #define ITEM_SELF(asset, qty) ITEM_BLOCK(asset, qty, asset)
#define ITEM_SELF_DIR(asset, qty) ITEM_BLOCK_DIR(asset, qty, asset)
static item_desc items[] = { static item_desc items[] = {
{ {
@ -29,8 +50,9 @@ static item_desc items[] = {
ITEM_SELF(ASSET_WOOD, 64), ITEM_SELF(ASSET_WOOD, 64),
ITEM_HOLD(ASSET_TREE, 64), ITEM_HOLD(ASSET_TREE, 64),
ITEM_SELF(ASSET_BELT_LEFT, 999), ITEM_SELF_DIR(ASSET_BELT, 999),
ITEM_SELF(ASSET_BELT_RIGHT, 999), ITEM_PROXY(ASSET_BELT_LEFT, ASSET_BELT),
ITEM_SELF(ASSET_BELT_UP, 999), ITEM_PROXY(ASSET_BELT_RIGHT, ASSET_BELT),
ITEM_SELF(ASSET_BELT_DOWN, 999), ITEM_PROXY(ASSET_BELT_UP, ASSET_BELT),
ITEM_PROXY(ASSET_BELT_DOWN, ASSET_BELT),
}; };

View File

@ -244,8 +244,8 @@ int32_t worldgen_test(world_data *wld) {
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
} }
for (int i=0; i<RAND_RANGE(328, 164); i++) { for (int i=0; i<RAND_RANGE(128, 564); i++) {
uint64_t e = item_spawn(ASSET_BELT_LEFT, 999); uint64_t e = item_spawn(ASSET_BELT, 999);
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL); Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);

View File

@ -182,6 +182,10 @@ void SwapItems(ecs_iter_t *it) {
} }
} }
#ifndef zpl_sign0
#define zpl_sign0(x) (x == 0.0f) ? 0 : ((x) >= 0 ? 1 : -1)
#endif
void UseItem(ecs_iter_t *it) { void UseItem(ecs_iter_t *it) {
Input *in = ecs_column(it, Input, 1); Input *in = ecs_column(it, Input, 1);
Position *p = ecs_column(it, Position, 2); Position *p = ecs_column(it, Position, 2);
@ -192,16 +196,34 @@ void UseItem(ecs_iter_t *it) {
ItemDrop *item = &inv[i].items[in[i].selected_item]; ItemDrop *item = &inv[i].items[in[i].selected_item];
if (!item || item->quantity <= 0) continue; if (!item || item->quantity <= 0) continue;
uint16_t item_id = item_find(item ->kind); uint16_t item_id = item_find(item->kind);
item_usage usage = item_get_usage(item_id); item_usage usage = item_get_usage(item_id);
if (in[i].use && usage > UKIND_END_PLACE) if (in[i].use && usage > UKIND_END_PLACE)
item_use(it->world, item, p[i]); item_use(it->world, item, p[i], 0);
else if (in[i].num_placements > 0 && usage < UKIND_END_PLACE) { else if (in[i].num_placements > 0 && usage < UKIND_END_PLACE) {
asset_id ofs = 0;
if (item_get_place_directional(item_id) && in[i].num_placements >= 2) {
float p1x = in[i].placements_x[0];
float p1y = in[i].placements_y[0];
float p2x = in[i].placements_x[1];
float p2y = in[i].placements_y[1];
float sx = zpl_sign0(p2x-p1x);
float sy = zpl_sign0(p2y-p1y);
ofs = (sx < 0.0f) ? 1 : 2;
if (sx == 0.0f) {
ofs = (sy < 0.0f) ? 3 : 4;
}
} else if(item_get_place_directional(item_id)) {
// NOTE(zaklaus): ensure we pick the first variant
ofs = 1;
}
for (size_t j = 0; j < in[i].num_placements; j++) { for (size_t j = 0; j < in[i].num_placements; j++) {
Position pos = {.x = in[i].placements_x[j], .y = in[i].placements_y[j]}; Position pos = {.x = in[i].placements_x[j], .y = in[i].placements_y[j]};
item_use(it->world, item, pos); item_use(it->world, item, pos, ofs);
} }
in[i].num_placements = 0; in[i].num_placements = 0;
} }
} }