diff --git a/code/game/src/assets.h b/code/game/src/assets.h index b494374..0b3606b 100644 --- a/code/game/src/assets.h +++ b/code/game/src/assets.h @@ -28,6 +28,7 @@ typedef enum { ASSET_WOOD, ASSET_TREE, + ASSET_BELT, ASSET_BELT_LEFT, ASSET_BELT_RIGHT, ASSET_BELT_UP, diff --git a/code/game/src/assets_list.c b/code/game/src/assets_list.c index bc514f2..2a053c5 100644 --- a/code/game/src/assets_list.c +++ b/code/game/src/assets_list.c @@ -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), diff --git a/code/game/src/gen/texgen.c b/code/game/src/gen/texgen.c index 3dfff0b..b4683d1 100644 --- a/code/game/src/gen/texgen.c +++ b/code/game/src/gen/texgen.c @@ -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"); diff --git a/code/game/src/items.c b/code/game/src/items.c index 941decb..157a9cd 100644 --- a/code/game/src/items.c +++ b/code/game/src/items.c @@ -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; ikind); 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; } @@ -59,4 +68,9 @@ uint32_t item_max_quantity(uint16_t id) { 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; } \ No newline at end of file diff --git a/code/game/src/items.h b/code/game/src/items.h index 44d3157..36f608b 100644 --- a/code/game/src/items.h +++ b/code/game/src/items.h @@ -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); diff --git a/code/game/src/items_list.c b/code/game/src/items_list.c index 16edde4..de1e917 100644 --- a/code/game/src/items_list.c +++ b/code/game/src/items_list.c @@ -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), }; diff --git a/code/game/src/world/worldgen/worldgen_test.c b/code/game/src/world/worldgen/worldgen_test.c index fa0c9f5..65b642e 100644 --- a/code/game/src/world/worldgen/worldgen_test.c +++ b/code/game/src/world/worldgen/worldgen_test.c @@ -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; ix = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); diff --git a/code/modules/source/system_items.c b/code/modules/source/system_items.c index e14b7bf..05eb634 100644 --- a/code/modules/source/system_items.c +++ b/code/modules/source/system_items.c @@ -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); @@ -192,16 +196,34 @@ void UseItem(ecs_iter_t *it) { ItemDrop *item = &inv[i].items[in[i].selected_item]; 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); 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; } }