directional build mode
parent
1a5a550512
commit
42a58ef5fb
|
@ -28,6 +28,7 @@ typedef enum {
|
|||
ASSET_WOOD,
|
||||
ASSET_TREE,
|
||||
|
||||
ASSET_BELT,
|
||||
ASSET_BELT_LEFT,
|
||||
ASSET_BELT_RIGHT,
|
||||
ASSET_BELT_UP,
|
||||
|
|
|
@ -23,6 +23,8 @@ static asset assets[] = {
|
|||
ASSET_TEX(ASSET_HOLE),
|
||||
ASSET_TEX(ASSET_WOOD),
|
||||
ASSET_TEX(ASSET_TREE),
|
||||
|
||||
ASSET_TEX(ASSET_BELT),
|
||||
ASSET_TEX(ASSET_BELT_LEFT),
|
||||
ASSET_TEX(ASSET_BELT_RIGHT),
|
||||
ASSET_TEX(ASSET_BELT_UP),
|
||||
|
|
|
@ -27,8 +27,10 @@ Texture2D texgen_build_sprite(asset_id id) {
|
|||
case ASSET_LAVA: return LoadImageEco("lava");
|
||||
case ASSET_WOOD: return LoadImageEco("wood");
|
||||
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_LEFT: return LoadImageEco("belt_left");
|
||||
case ASSET_BELT_UP: return LoadImageEco("belt_up");
|
||||
case ASSET_BELT_DOWN: return LoadImageEco("belt_down");
|
||||
|
||||
|
|
|
@ -24,15 +24,24 @@ uint64_t item_spawn(asset_id kind, uint32_t qty) {
|
|||
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) {
|
||||
for (uint16_t i=0; i<ITEMS_COUNT; i++) {
|
||||
if (items[i].kind == kind)
|
||||
return i;
|
||||
return item_resolve_proxy(i);
|
||||
}
|
||||
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;
|
||||
uint16_t item_id = item_find(it->kind);
|
||||
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_PLACE:{
|
||||
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--;
|
||||
}break;
|
||||
}
|
||||
|
@ -60,3 +69,8 @@ item_usage item_get_usage(uint16_t id) {
|
|||
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
|
||||
return items[id].usage;
|
||||
}
|
||||
|
||||
bool item_get_place_directional(uint16_t id) {
|
||||
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
|
||||
return items[id].place.directional;
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
typedef enum {
|
||||
UKIND_HOLD,
|
||||
UKIND_PROXY,
|
||||
UKIND_PLACE,
|
||||
UKIND_PLACE_ITEM,
|
||||
UKIND_END_PLACE,
|
||||
|
@ -21,7 +22,12 @@ typedef struct {
|
|||
union {
|
||||
struct {
|
||||
asset_id kind;
|
||||
bool directional; // NOTE(zaklaus): expects next 4 asset entries to be direction assets
|
||||
} place;
|
||||
|
||||
struct {
|
||||
asset_id id;
|
||||
} proxy;
|
||||
};
|
||||
} item_desc;
|
||||
|
||||
|
@ -31,7 +37,8 @@ void item_despawn(uint64_t id);
|
|||
|
||||
// NOTE(zaklaus): items
|
||||
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);
|
||||
item_usage item_get_usage(uint16_t id);
|
||||
bool item_get_place_directional(uint16_t id);
|
||||
|
|
|
@ -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_DIR(asset, qty) ITEM_BLOCK_DIR(asset, qty, asset)
|
||||
|
||||
static item_desc items[] = {
|
||||
{
|
||||
|
@ -29,8 +50,9 @@ static item_desc items[] = {
|
|||
ITEM_SELF(ASSET_WOOD, 64),
|
||||
ITEM_HOLD(ASSET_TREE, 64),
|
||||
|
||||
ITEM_SELF(ASSET_BELT_LEFT, 999),
|
||||
ITEM_SELF(ASSET_BELT_RIGHT, 999),
|
||||
ITEM_SELF(ASSET_BELT_UP, 999),
|
||||
ITEM_SELF(ASSET_BELT_DOWN, 999),
|
||||
ITEM_SELF_DIR(ASSET_BELT, 999),
|
||||
ITEM_PROXY(ASSET_BELT_LEFT, ASSET_BELT),
|
||||
ITEM_PROXY(ASSET_BELT_RIGHT, ASSET_BELT),
|
||||
ITEM_PROXY(ASSET_BELT_UP, ASSET_BELT),
|
||||
ITEM_PROXY(ASSET_BELT_DOWN, ASSET_BELT),
|
||||
};
|
||||
|
|
|
@ -244,8 +244,8 @@ int32_t worldgen_test(world_data *wld) {
|
|||
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
for (int i=0; i<RAND_RANGE(328, 164); i++) {
|
||||
uint64_t e = item_spawn(ASSET_BELT_LEFT, 999);
|
||||
for (int i=0; i<RAND_RANGE(128, 564); i++) {
|
||||
uint64_t e = item_spawn(ASSET_BELT, 999);
|
||||
|
||||
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
|
||||
|
|
|
@ -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) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Position *p = ecs_column(it, Position, 2);
|
||||
|
@ -196,12 +200,30 @@ void UseItem(ecs_iter_t *it) {
|
|||
item_usage usage = item_get_usage(item_id);
|
||||
|
||||
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) {
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue