lots of changes
parent
b8e3decc96
commit
0be5d87ede
|
@ -4,7 +4,7 @@ game_rulesdef game_rules = (game_rulesdef){
|
||||||
.phy_walk_drag = 4.23f,
|
.phy_walk_drag = 4.23f,
|
||||||
.demo_npc_move_speed = 500,
|
.demo_npc_move_speed = 500,
|
||||||
.demo_npc_steer_speed = 300,
|
.demo_npc_steer_speed = 300,
|
||||||
.furnace_cook_time = 5.0f,
|
.furnace_cook_time = 1.f,
|
||||||
.item_pick_radius = 25.0f,
|
.item_pick_radius = 25.0f,
|
||||||
.item_merger_radius = 75.0f,
|
.item_merger_radius = 75.0f,
|
||||||
.item_attract_radius = 75.0f,
|
.item_attract_radius = 75.0f,
|
||||||
|
|
|
@ -49,7 +49,7 @@ ActSpawnChest(void) {
|
||||||
|
|
||||||
void
|
void
|
||||||
ActSpawnBelt(void) {
|
ActSpawnBelt(void) {
|
||||||
ecs_entity_t e = item_spawn(ASSET_BELT, 999);
|
ecs_entity_t e = item_spawn(ASSET_BELT, 32);
|
||||||
ecs_entity_t plr = camera_get().ent_id;
|
ecs_entity_t plr = camera_get().ent_id;
|
||||||
|
|
||||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||||
|
|
|
@ -12,9 +12,12 @@ ECS_COMPONENT_DECLARE(Classify);
|
||||||
ECS_COMPONENT_DECLARE(Vehicle);
|
ECS_COMPONENT_DECLARE(Vehicle);
|
||||||
ECS_COMPONENT_DECLARE(IsInVehicle);
|
ECS_COMPONENT_DECLARE(IsInVehicle);
|
||||||
ECS_COMPONENT_DECLARE(Item);
|
ECS_COMPONENT_DECLARE(Item);
|
||||||
|
ECS_COMPONENT_DECLARE(ItemAlreadyEdited);
|
||||||
ECS_COMPONENT_DECLARE(Inventory);
|
ECS_COMPONENT_DECLARE(Inventory);
|
||||||
ECS_COMPONENT_DECLARE(ItemContainer);
|
ECS_COMPONENT_DECLARE(ItemContainer);
|
||||||
ECS_COMPONENT_DECLARE(Furnace);
|
ECS_COMPONENT_DECLARE(Furnace);
|
||||||
|
ECS_COMPONENT_DECLARE(Fuel);
|
||||||
|
ECS_COMPONENT_DECLARE(Ingredient);
|
||||||
ECS_COMPONENT_DECLARE(Device);
|
ECS_COMPONENT_DECLARE(Device);
|
||||||
ECS_COMPONENT_DECLARE(DemoNPC);
|
ECS_COMPONENT_DECLARE(DemoNPC);
|
||||||
ECS_COMPONENT_DECLARE(StreamInfo);
|
ECS_COMPONENT_DECLARE(StreamInfo);
|
||||||
|
@ -34,9 +37,12 @@ void ComponentsImport(ecs_world_t *ecs) {
|
||||||
ECS_COMPONENT_DEFINE(ecs, Vehicle);
|
ECS_COMPONENT_DEFINE(ecs, Vehicle);
|
||||||
ECS_COMPONENT_DEFINE(ecs, IsInVehicle);
|
ECS_COMPONENT_DEFINE(ecs, IsInVehicle);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Item);
|
ECS_COMPONENT_DEFINE(ecs, Item);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, ItemAlreadyEdited);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Inventory);
|
ECS_COMPONENT_DEFINE(ecs, Inventory);
|
||||||
ECS_COMPONENT_DEFINE(ecs, ItemContainer);
|
ECS_COMPONENT_DEFINE(ecs, ItemContainer);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Furnace);
|
ECS_COMPONENT_DEFINE(ecs, Furnace);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, Fuel);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, Ingredient);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Device);
|
ECS_COMPONENT_DEFINE(ecs, Device);
|
||||||
ECS_COMPONENT_DEFINE(ecs, DemoNPC);
|
ECS_COMPONENT_DEFINE(ecs, DemoNPC);
|
||||||
ECS_COMPONENT_DEFINE(ecs, StreamInfo);
|
ECS_COMPONENT_DEFINE(ecs, StreamInfo);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "flecs/flecs.h"
|
#include "flecs/flecs.h"
|
||||||
|
#include "gen/assets.h"
|
||||||
|
|
||||||
#ifndef ecs_get_mut_if
|
#ifndef ecs_get_mut_if
|
||||||
#define ecs_get_mut_if(world, entity, component)\
|
#define ecs_get_mut_if(world, entity, component)\
|
||||||
|
@ -100,12 +101,17 @@ typedef struct {
|
||||||
uint16_t kind;
|
uint16_t kind;
|
||||||
uint32_t quantity;
|
uint32_t quantity;
|
||||||
float merger_time;
|
float merger_time;
|
||||||
|
float durability; // 1.0 - 0.0 (0.0 = broken), we can only ever merge items of the same durability
|
||||||
} Item;
|
} Item;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char _unused;
|
||||||
|
} ItemAlreadyEdited;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// TODO: we now hold a ref to an item, instead of representing an item slot,
|
// TODO: we now hold a ref to an item, instead of representing an item slot,
|
||||||
// so that we can let the item entity keep its own components and also handle merging ops on its own.
|
// so that we can let the item entity keep its own components and also handle merging ops on its own.
|
||||||
ecs_entity_t items[ITEMS_CONTAINER_SIZE];
|
ecs_entity_t items[ITEMS_INVENTORY_SIZE];
|
||||||
float pickup_time;
|
float pickup_time;
|
||||||
} Inventory;
|
} Inventory;
|
||||||
|
|
||||||
|
@ -114,18 +120,21 @@ typedef struct {
|
||||||
} ItemContainer;
|
} ItemContainer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ecs_entity_t processed_item;
|
asset_id processed_item;
|
||||||
float cook_time;
|
float cook_time;
|
||||||
float burn_time;
|
float burn_time;
|
||||||
} Furnace;
|
} Furnace;
|
||||||
|
|
||||||
// typedef struct {
|
typedef struct {
|
||||||
// float burn_time;
|
asset_id kind;
|
||||||
// } Fuel;
|
float burn_time;
|
||||||
|
} Fuel;
|
||||||
|
|
||||||
// typedef struct {
|
typedef struct {
|
||||||
// asset_id converted_kind;
|
asset_id producer;
|
||||||
// } FuelTank;
|
asset_id additional_ingredient; // optional - can specify additional item we need in the container to craft this item
|
||||||
|
asset_id product;
|
||||||
|
} Ingredient;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t asset;
|
uint16_t asset;
|
||||||
|
@ -150,9 +159,12 @@ extern ECS_COMPONENT_DECLARE(Classify);
|
||||||
extern ECS_COMPONENT_DECLARE(Vehicle);
|
extern ECS_COMPONENT_DECLARE(Vehicle);
|
||||||
extern ECS_COMPONENT_DECLARE(IsInVehicle);
|
extern ECS_COMPONENT_DECLARE(IsInVehicle);
|
||||||
extern ECS_COMPONENT_DECLARE(Item);
|
extern ECS_COMPONENT_DECLARE(Item);
|
||||||
|
extern ECS_COMPONENT_DECLARE(ItemAlreadyEdited);
|
||||||
extern ECS_COMPONENT_DECLARE(Inventory);
|
extern ECS_COMPONENT_DECLARE(Inventory);
|
||||||
extern ECS_COMPONENT_DECLARE(ItemContainer);
|
extern ECS_COMPONENT_DECLARE(ItemContainer);
|
||||||
extern ECS_COMPONENT_DECLARE(Furnace);
|
extern ECS_COMPONENT_DECLARE(Furnace);
|
||||||
|
extern ECS_COMPONENT_DECLARE(Fuel);
|
||||||
|
extern ECS_COMPONENT_DECLARE(Ingredient);
|
||||||
extern ECS_COMPONENT_DECLARE(Device);
|
extern ECS_COMPONENT_DECLARE(Device);
|
||||||
extern ECS_COMPONENT_DECLARE(DemoNPC);
|
extern ECS_COMPONENT_DECLARE(DemoNPC);
|
||||||
extern ECS_COMPONENT_DECLARE(StreamInfo);
|
extern ECS_COMPONENT_DECLARE(StreamInfo);
|
||||||
|
|
|
@ -2,33 +2,42 @@ void FurnaceCook(ecs_iter_t *it) {
|
||||||
ItemContainer *storage = ecs_field(it, ItemContainer, 1);
|
ItemContainer *storage = ecs_field(it, ItemContainer, 1);
|
||||||
Furnace *furnace = ecs_field(it, Furnace, 2);
|
Furnace *furnace = ecs_field(it, Furnace, 2);
|
||||||
Position *p = ecs_field(it, Position, 3);
|
Position *p = ecs_field(it, Position, 3);
|
||||||
|
Device *d = ecs_field(it, Device, 4);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
for (int j = 0; j < ITEMS_CONTAINER_SIZE; j++) {
|
for (int j = 0; j < ITEMS_CONTAINER_SIZE; j++) {
|
||||||
if (storage[i].items[j].kind == ASSET_COAL) {
|
ecs_entity_t item_slot_ent = storage[i].items[j];
|
||||||
// furnace[i].fuel_level += itemdb_get(storage[i].items[j].uuid, ITEMDB_FUEL_LEVEL);
|
Item *item = item_get_data(item_slot_ent);
|
||||||
// furnace[i].fuel_level = zpl_clamp(furnace[i].fuel_level + 0.8f, 0.0f, 1.0f);
|
|
||||||
storage[i].items[j].quantity--;
|
const Fuel *fuel = 0;
|
||||||
if (storage[i].items[j].quantity == 0) {
|
if ((fuel = ecs_get(it->world, item_slot_ent, Fuel))) {
|
||||||
storage[i].items[j] = (ItemSlot){0};
|
if (fuel->kind == d->asset) {
|
||||||
|
furnace[i].burn_time += fuel->kind;
|
||||||
|
item_despawn(item_slot_ent);
|
||||||
|
storage[i].items[j] = 0;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (furnace[i].fuel_level <= 0.0f) continue;
|
// if (furnace[i].burn_time <= 0.0f) continue; TODO
|
||||||
if (furnace[i].cook_time < game_time()) {
|
if (furnace[i].cook_time < game_time()) {
|
||||||
if (furnace[i].processed_item.kind > 0) {
|
if (furnace[i].processed_item > 0) {
|
||||||
uint64_t e = item_spawn(furnace[i].processed_item.kind, 1);
|
uint64_t e = item_spawn(furnace[i].processed_item, 1);
|
||||||
entity_set_position(e, p[i].x, p[i].y);
|
entity_set_position(e, p[i].x, p[i].y);
|
||||||
furnace[i].processed_item.kind = 0;
|
furnace[i].processed_item = 0;
|
||||||
} else {
|
} else {
|
||||||
if (storage[i].items[j].kind == ASSET_DEMO_ICEMAKER) {
|
const Ingredient *ing = 0;
|
||||||
furnace[i].processed_item.kind = ASSET_BELT;
|
if ((ing = ecs_get(it->world, item_slot_ent, Ingredient))) {
|
||||||
storage[i].items[j].quantity--;
|
if (ing->producer == d->asset) {
|
||||||
if (storage[i].items[j].quantity == 0) {
|
furnace[i].processed_item = ing->product;
|
||||||
storage[i].items[j] = (ItemSlot){0};
|
furnace[i].cook_time = game_time() + game_rules.furnace_cook_time;
|
||||||
|
zpl_printf("e_id %llu, qty: %d\n", item_slot_ent, item->quantity);
|
||||||
|
item->quantity--;
|
||||||
|
if (item->quantity <= 0) {
|
||||||
|
item_despawn(item_slot_ent);
|
||||||
|
storage[i].items[j] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
furnace[i].cook_time = game_time() + game_rules.furnace_cook_time;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,14 @@ void PickItem(ecs_iter_t *it) {
|
||||||
if (inv[i].pickup_time > game_time()) continue;
|
if (inv[i].pickup_time > game_time()) continue;
|
||||||
size_t ents_count;
|
size_t ents_count;
|
||||||
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2);
|
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2);
|
||||||
|
bool picked = false;
|
||||||
|
|
||||||
for (size_t j = 0; j < ents_count; j++) {
|
for (size_t j = 0; j < ents_count; j++) {
|
||||||
Item *drop = 0;
|
Item *drop = 0;
|
||||||
if ((drop = ecs_get_mut_if(it->world, ents[j], Item))) {
|
uint64_t ent_id = ents[j];
|
||||||
Position *p2 = ecs_get_mut(it->world, ents[j], Position);
|
if ((drop = ecs_get_mut_if(it->world, ent_id, Item))) {
|
||||||
Velocity *v2 = ecs_get_mut(it->world, ents[j], Velocity);
|
Position *p2 = ecs_get_mut(it->world, ent_id, Position);
|
||||||
|
Velocity *v2 = ecs_get_mut(it->world, ent_id, Velocity);
|
||||||
|
|
||||||
float dx = p2->x - p[i].x;
|
float dx = p2->x - p[i].x;
|
||||||
float dy = p2->y - p[i].y;
|
float dy = p2->y - p[i].y;
|
||||||
|
@ -21,23 +23,25 @@ void PickItem(ecs_iter_t *it) {
|
||||||
if (range <= game_rules.item_pick_radius) {
|
if (range <= game_rules.item_pick_radius) {
|
||||||
uint16_t drop_id = item_find(drop->kind);
|
uint16_t drop_id = item_find(drop->kind);
|
||||||
for (size_t k = 0; k < ITEMS_INVENTORY_SIZE; k += 1) {
|
for (size_t k = 0; k < ITEMS_INVENTORY_SIZE; k += 1) {
|
||||||
ItemSlot *item_slot = &inv[i].items[k];
|
ecs_entity_t item_slot_ent = inv[i].items[k];
|
||||||
Item *item = item_get_data(item_slot->ent);
|
Item *item = item_get_data(item_slot_ent);
|
||||||
uint16_t item_id = item_find(item->kind);
|
uint16_t item_id = item ? item_find(item->kind) : 0;
|
||||||
if (item_id != ASSET_INVALID && (item->quantity == 0 || (item->quantity != 0 && item->kind == drop->kind)) && item->quantity < item_max_quantity(drop_id)
|
if (!item || (item_id != ASSET_INVALID && (item->kind == drop->kind && item->durability == drop->durability) && item->quantity < item_max_quantity(drop_id))) {
|
||||||
&& (item_slot->ent == 0 || item_slot->ent == ents[j])) {
|
if (item) {
|
||||||
uint32_t picked_count = zpl_max(0, drop->quantity);
|
uint32_t picked_count = zpl_max(0, drop->quantity);
|
||||||
picked_count = zpl_clamp(picked_count, 0, item_max_quantity(drop_id) - item->quantity);
|
picked_count = zpl_clamp(picked_count, 0, item_max_quantity(drop_id) - item->quantity);
|
||||||
item_slot->ent = ents[j];
|
item->quantity += picked_count;
|
||||||
item->quantity += picked_count;
|
drop->quantity -= picked_count;
|
||||||
drop->quantity -= picked_count;
|
item->kind = drop->kind;
|
||||||
item->kind = drop->kind;
|
|
||||||
entity_wake(ents[j]);
|
|
||||||
|
|
||||||
if (drop->quantity == 0)
|
if (drop->quantity == 0)
|
||||||
item_show(ents[j], false);
|
item_despawn(ent_id);
|
||||||
|
} else if (!world_entity_valid(item_slot_ent)) {
|
||||||
item_slot->ent = ents[j];
|
entity_wake(ent_id);
|
||||||
|
item_show(ent_id, false);
|
||||||
|
inv[i].items[k] = ent_id;
|
||||||
|
}
|
||||||
|
picked = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +50,8 @@ void PickItem(ecs_iter_t *it) {
|
||||||
v2->y = (p[i].y - p2->y) * game_rules.item_attract_force;
|
v2->y = (p[i].y - p2->y) * game_rules.item_attract_force;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (picked) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +64,7 @@ void DropItem(ecs_iter_t *it) {
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (!in[i].drop) continue;
|
if (!in[i].drop) continue;
|
||||||
|
|
||||||
ItemSlot *items = inv[i].items;
|
ecs_entity_t *items = inv[i].items;
|
||||||
|
|
||||||
if (in[i].storage_action){
|
if (in[i].storage_action){
|
||||||
if (world_entity_valid(in[i].storage_ent)){
|
if (world_entity_valid(in[i].storage_ent)){
|
||||||
|
@ -73,8 +79,9 @@ void DropItem(ecs_iter_t *it) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemSlot *item_slot = &items[in[i].storage_action ? in[i].storage_selected_item : in[i].selected_item];
|
uint8_t slot_id = in[i].storage_action ? in[i].storage_selected_item : in[i].selected_item;
|
||||||
Item *item = item_get_data(item_slot->ent);
|
ecs_entity_t item_slot_ent = items[slot_id];
|
||||||
|
Item *item = item_get_data(item_slot_ent);
|
||||||
|
|
||||||
if (!item || item->quantity <= 0)
|
if (!item || item->quantity <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -83,72 +90,67 @@ void DropItem(ecs_iter_t *it) {
|
||||||
if (in[i].sprint) {
|
if (in[i].sprint) {
|
||||||
dropped_count /= 2;
|
dropped_count /= 2;
|
||||||
} else if (in[i].ctrl) {
|
} else if (in[i].ctrl) {
|
||||||
dropped_count = dropped_count > 0 ? 1 : 0;
|
dropped_count = item->quantity-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dropped_count == 0)
|
if (dropped_count == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ecs_entity_t te = item_slot->ent;
|
item_show(item_slot_ent, true);
|
||||||
item_show(item_slot->ent, true);
|
|
||||||
item->quantity -= dropped_count;
|
|
||||||
|
|
||||||
ItemDrop *d = ecs_get_mut(world_ecs(), te, ItemDrop);
|
Position *ipos = ecs_get_mut(it->world, item_slot_ent, Position);
|
||||||
*d = (ItemDrop){
|
entity_set_position(item_slot_ent, p[i].x, p[i].y);
|
||||||
.kind = item->kind,
|
|
||||||
.quantity = dropped_count,
|
|
||||||
.merger_time = game_time() + game_rules.item_drop_merger_time,
|
|
||||||
};
|
|
||||||
|
|
||||||
Position *ipos = ecs_get_mut(it->world, te, Position);
|
Velocity *v = ecs_get_mut(it->world, item_slot_ent, Velocity);
|
||||||
*ipos = p[i];
|
|
||||||
|
|
||||||
Velocity *v = ecs_get_mut(it->world, te, Velocity);
|
|
||||||
v->x = in[i].mx * 800.0f;
|
v->x = in[i].mx * 800.0f;
|
||||||
v->y = in[i].my * 800.0f;
|
v->y = in[i].my * 800.0f;
|
||||||
|
|
||||||
inv[i].pickup_time = game_time() + game_rules.item_drop_pickup_time;
|
inv[i].pickup_time = game_time() + game_rules.item_drop_pickup_time;
|
||||||
in[i].drop = false;
|
in[i].drop = false;
|
||||||
|
items[slot_id] = 0;
|
||||||
|
|
||||||
if (item->quantity == 0) {
|
if (item->quantity - dropped_count > 0) {
|
||||||
item->kind = 0;
|
item->quantity -= dropped_count;
|
||||||
|
ecs_entity_t te = item_spawn(item->kind, dropped_count);
|
||||||
|
item_show(te, false);
|
||||||
|
items[slot_id] = te;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergeItems(ecs_iter_t *it) {
|
// void MergeItems(ecs_iter_t *it) {
|
||||||
Position *p = ecs_field(it, Position, 1);
|
// Position *p = ecs_field(it, Position, 1);
|
||||||
ItemDrop *id = ecs_field(it, ItemDrop, 2);
|
// ItemDrop *id = ecs_field(it, ItemDrop, 2);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i += 1) {
|
// for (int i = 0; i < it->count; i += 1) {
|
||||||
ItemDrop *item = &id[i];
|
// ItemDrop *item = &id[i];
|
||||||
|
|
||||||
if (item->merger_time < game_time())
|
// if (item->merger_time < game_time())
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
size_t ents_count;
|
// size_t ents_count;
|
||||||
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 1);
|
// int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 1);
|
||||||
|
|
||||||
for (size_t j = 0; j < ents_count; j++) {
|
// for (size_t j = 0; j < ents_count; j++) {
|
||||||
ItemDrop *drop = 0;
|
// ItemDrop *drop = 0;
|
||||||
if ((drop = ecs_get_mut_if(it->world, ents[j], ItemDrop))) {
|
// if ((drop = ecs_get_mut_if(it->world, ents[j], ItemDrop))) {
|
||||||
if (drop->kind != item->kind || (ecs_entity_t)ents[j] == it->entities[i] || drop->quantity == 0 || item->quantity == 0)
|
// if (drop->kind != item->kind || (ecs_entity_t)ents[j] == it->entities[i] || drop->quantity == 0 || item->quantity == 0)
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
Position const* p2 = ecs_get(it->world, ents[j], Position);
|
// Position const* p2 = ecs_get(it->world, ents[j], Position);
|
||||||
|
|
||||||
float dx = p2->x - (p[i].x);
|
// float dx = p2->x - (p[i].x);
|
||||||
float dy = p2->y - (p[i].y);
|
// float dy = p2->y - (p[i].y);
|
||||||
float range = zpl_sqrt(dx*dx + dy*dy);
|
// float range = zpl_sqrt(dx*dx + dy*dy);
|
||||||
if (range <= game_rules.item_merger_radius) {
|
// if (range <= game_rules.item_merger_radius) {
|
||||||
drop->quantity += item->quantity;
|
// drop->quantity += item->quantity;
|
||||||
item_despawn(it->entities[i]);
|
// item_despawn(it->entities[i]);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void SwapItems(ecs_iter_t *it) {
|
void SwapItems(ecs_iter_t *it) {
|
||||||
Input *in = ecs_field(it, Input, 1);
|
Input *in = ecs_field(it, Input, 1);
|
||||||
|
@ -157,7 +159,7 @@ void SwapItems(ecs_iter_t *it) {
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (!in[i].swap) continue;
|
if (!in[i].swap) continue;
|
||||||
|
|
||||||
ItemDrop *items = inv[i].items;
|
ecs_entity_t *items = inv[i].items;
|
||||||
|
|
||||||
if (in[i].storage_action){
|
if (in[i].storage_action){
|
||||||
if (world_entity_valid(in[i].storage_ent)){
|
if (world_entity_valid(in[i].storage_ent)){
|
||||||
|
@ -172,40 +174,49 @@ void SwapItems(ecs_iter_t *it) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemDrop *to = 0;
|
ecs_entity_t *from_ent = 0;
|
||||||
ItemDrop *from = 0;
|
ecs_entity_t *to_ent = 0;
|
||||||
|
Item *to = 0;
|
||||||
|
Item *from = 0;
|
||||||
|
|
||||||
if (in[i].swap_storage){
|
if (in[i].swap_storage){
|
||||||
in[i].swap_storage = false;
|
in[i].swap_storage = false;
|
||||||
|
|
||||||
if (in[i].storage_action){
|
if (in[i].storage_action){
|
||||||
from = &inv[i].items[in[i].swap_from];
|
from_ent = &inv[i].items[in[i].swap_from];
|
||||||
to = &items[in[i].swap_to];
|
to_ent = &items[in[i].swap_to];
|
||||||
|
from = item_get_data(*from_ent);
|
||||||
|
to = item_get_data(*to_ent);
|
||||||
}else{
|
}else{
|
||||||
if (world_entity_valid(in[i].storage_ent)){
|
if (world_entity_valid(in[i].storage_ent)){
|
||||||
ItemContainer *ic = 0;
|
ItemContainer *ic = 0;
|
||||||
if ((ic = ecs_get_mut_if(it->world, in[i].storage_ent, ItemContainer))){
|
if ((ic = ecs_get_mut_if(it->world, in[i].storage_ent, ItemContainer))){
|
||||||
from = &ic->items[in[i].swap_from];
|
from_ent = &ic->items[in[i].swap_from];
|
||||||
|
from = item_get_data(*from_ent);
|
||||||
}else{
|
}else{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
to = &items[in[i].swap_to];
|
to_ent = &items[in[i].swap_to];
|
||||||
|
to = item_get_data(*to_ent);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
from = &items[in[i].swap_from];
|
from_ent = &items[in[i].swap_from];
|
||||||
to = &items[in[i].swap_to];
|
to_ent = &items[in[i].swap_to];
|
||||||
|
from = item_get_data(*from_ent);
|
||||||
|
to = item_get_data(*to_ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZPL_ASSERT(from && to);
|
if (!from) continue;
|
||||||
|
|
||||||
uint16_t to_id = item_find(to->kind);
|
uint16_t to_id = to ? item_find(to->kind) : ASSET_EMPTY;
|
||||||
|
asset_id to_kind = to ? to->kind : ASSET_EMPTY;
|
||||||
|
|
||||||
if (to == from) {
|
if (to_ent == from_ent) {
|
||||||
// NOTE(zaklaus): do nothing
|
// NOTE(zaklaus): do nothing
|
||||||
} else if (to->kind == from->kind && to->quantity > 0) {
|
} else if (to_kind == from->kind && to->quantity > 0) {
|
||||||
uint32_t swapped_count = from->quantity;
|
uint32_t swapped_count = from->quantity;
|
||||||
if (in[i].sprint) {
|
if (in[i].sprint) {
|
||||||
swapped_count /= 2;
|
swapped_count /= 2;
|
||||||
|
@ -216,24 +227,28 @@ void SwapItems(ecs_iter_t *it) {
|
||||||
to->quantity += swapped_count;
|
to->quantity += swapped_count;
|
||||||
from->quantity -= swapped_count;
|
from->quantity -= swapped_count;
|
||||||
|
|
||||||
if (swapped_count == 0) {
|
if (from->quantity == 0) {
|
||||||
ItemDrop tmp = *to;
|
item_despawn(*from_ent);
|
||||||
*to = *from;
|
*from_ent = 0;
|
||||||
*from = tmp;
|
|
||||||
}
|
}
|
||||||
} else if ((in[i].ctrl || in[i].sprint) && to->quantity == 0 && from->quantity > 0) {
|
} else if ((in[i].ctrl || in[i].sprint) && to == 0 && from->quantity > 0) {
|
||||||
// NOTE(zaklaus): item split
|
// NOTE(zaklaus): item split
|
||||||
uint32_t split_count = from->quantity / 2;
|
uint32_t split_count = from->quantity / 2;
|
||||||
if (in[i].ctrl) {
|
if (in[i].ctrl) {
|
||||||
split_count = 1;
|
split_count = 1;
|
||||||
}
|
}
|
||||||
to->quantity = split_count;
|
if (from->quantity - split_count == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ecs_entity_t te = item_spawn(from->kind, split_count);
|
||||||
|
item_show(te, false);
|
||||||
|
*to_ent = te;
|
||||||
|
|
||||||
from->quantity -= split_count;
|
from->quantity -= split_count;
|
||||||
to->kind = from->kind;
|
|
||||||
} else {
|
} else {
|
||||||
ItemDrop tmp = *to;
|
ecs_entity_t tmp = *to_ent;
|
||||||
*to = *from;
|
*to_ent = *from_ent;
|
||||||
*from = tmp;
|
*from_ent = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
in[i].swap = false;
|
in[i].swap = false;
|
||||||
|
@ -252,12 +267,13 @@ void UseItem(ecs_iter_t *it) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemDrop *item = &inv[i].items[in[i].selected_item];
|
ecs_entity_t item_ent = inv[i].items[in[i].selected_item];
|
||||||
|
Item *item = item_get_data(item_ent);
|
||||||
uint16_t item_id = 0;
|
uint16_t item_id = 0;
|
||||||
item_usage usage = UKIND_DELETE;
|
item_usage usage = UKIND_DELETE;
|
||||||
|
|
||||||
if (!in[i].deletion_mode){
|
if (!in[i].deletion_mode){
|
||||||
item_id = item_find(item->kind);
|
item_id = item ? item_find(item->kind) : ASSET_EMPTY;
|
||||||
usage = item_get_usage(item_id);
|
usage = item_get_usage(item_id);
|
||||||
if (!item || item->quantity <= 0) continue;
|
if (!item || item->quantity <= 0) continue;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +284,7 @@ void UseItem(ecs_iter_t *it) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (in[i].use && usage > UKIND_END_PLACE)
|
else if (in[i].use && usage > UKIND_END_PLACE)
|
||||||
item_use(it->world, item, p[i], 0);
|
item_use(it->world, item_ent, 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;
|
asset_id ofs = 0;
|
||||||
if (item_get_place_directional(item_id) && in[i].num_placements >= 2) {
|
if (item_get_place_directional(item_id) && in[i].num_placements >= 2) {
|
||||||
|
@ -289,13 +305,18 @@ void UseItem(ecs_iter_t *it) {
|
||||||
|
|
||||||
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, ofs);
|
item_use(it->world, item_ent, item, pos, ofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
in[i].num_placements = 0;
|
in[i].num_placements = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_wake(it->entities[i]);
|
entity_wake(it->entities[i]);
|
||||||
|
|
||||||
|
if (item->quantity == 0) {
|
||||||
|
item_despawn(item_ent);
|
||||||
|
inv[i].items[in[i].selected_item] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,11 +339,13 @@ void HarvestIntoContainers(ecs_iter_t *it) {
|
||||||
// NOTE(zaklaus): find any item
|
// NOTE(zaklaus): find any item
|
||||||
size_t ents_count;
|
size_t ents_count;
|
||||||
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 0);
|
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 0);
|
||||||
|
bool picked = false;
|
||||||
|
|
||||||
for (size_t j = 0; j < ents_count; j++) {
|
for (size_t j = 0; j < ents_count; j++) {
|
||||||
ItemDrop *drop = 0;
|
Item *drop = 0;
|
||||||
if ((drop = ecs_get_mut_if(it->world, ents[j], ItemDrop))) {
|
if ((drop = ecs_get_mut_if(it->world, ents[j], Item))) {
|
||||||
const Position *p2 = ecs_get(it->world, ents[j], Position);
|
Position *p2 = ecs_get_mut(it->world, ents[j], Position);
|
||||||
|
uint64_t ent_id = ents[j];
|
||||||
|
|
||||||
float dx = p2->x - p[i].x;
|
float dx = p2->x - p[i].x;
|
||||||
float dy = p2->y - p[i].y;
|
float dy = p2->y - p[i].y;
|
||||||
|
@ -330,23 +353,32 @@ void HarvestIntoContainers(ecs_iter_t *it) {
|
||||||
if (range <= game_rules.item_pick_radius) {
|
if (range <= game_rules.item_pick_radius) {
|
||||||
uint16_t drop_id = item_find(drop->kind);
|
uint16_t drop_id = item_find(drop->kind);
|
||||||
for (size_t k = 0; k < ITEMS_CONTAINER_SIZE; k += 1) {
|
for (size_t k = 0; k < ITEMS_CONTAINER_SIZE; k += 1) {
|
||||||
ItemDrop *item = &in->items[k];
|
uint64_t item_slot_ent = in[i].items[k];
|
||||||
uint16_t item_id = item_find(item->kind);
|
Item *item = item_get_data(item_slot_ent);
|
||||||
if (item_id != ASSET_INVALID && (item->quantity == 0 || (item->quantity != 0 && item->kind == drop->kind)) && item->quantity < item_max_quantity(drop_id)) {
|
uint16_t item_id = item ? item_find(item->kind) : 0;
|
||||||
uint32_t picked_count = zpl_max(0, drop->quantity);
|
if (!item || (item_id != ASSET_INVALID && (item->kind == drop->kind && item->durability == drop->durability) && item->quantity < item_max_quantity(drop_id))) {
|
||||||
picked_count = zpl_clamp(picked_count, 0, item_max_quantity(drop_id) - item->quantity);
|
if (item) {
|
||||||
item->quantity += picked_count;
|
uint32_t picked_count = zpl_max(0, drop->quantity);
|
||||||
drop->quantity -= picked_count;
|
picked_count = zpl_clamp(picked_count, 0, item_max_quantity(drop_id) - item->quantity);
|
||||||
item->kind = drop->kind;
|
item->quantity += picked_count;
|
||||||
entity_wake(ents[j]);
|
drop->quantity -= picked_count;
|
||||||
entity_wake(it->entities[i]);
|
|
||||||
|
|
||||||
if (drop->quantity == 0)
|
if (drop->quantity == 0) {
|
||||||
item_despawn(ents[j]);
|
item_despawn(ent_id);
|
||||||
|
}
|
||||||
|
} else if (!world_entity_valid(item_slot_ent)) {
|
||||||
|
entity_wake(ent_id);
|
||||||
|
item_show(ent_id, false);
|
||||||
|
in[i].items[k] = ent_id;
|
||||||
|
}
|
||||||
|
entity_wake(it->entities[i]);
|
||||||
|
picked = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (picked) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,7 @@ void SystemsImport(ecs_world_t *ecs) {
|
||||||
ECS_SYSTEM(ecs, UseItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, UseItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
||||||
ECS_SYSTEM(ecs, InspectContainers, EcsPostUpdate, components.Input, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, InspectContainers, EcsPostUpdate, components.Input, !components.IsInVehicle);
|
||||||
ECS_SYSTEM(ecs, HarvestIntoContainers, EcsPostUpdate, components.ItemContainer, components.Position);
|
ECS_SYSTEM(ecs, HarvestIntoContainers, EcsPostUpdate, components.ItemContainer, components.Position);
|
||||||
ECS_SYSTEM(ecs, FurnaceCook, EcsPostUpdate, components.ItemContainer, components.Furnace, components.Position);
|
ECS_SYSTEM(ecs, FurnaceCook, EcsPostUpdate, components.ItemContainer, components.Furnace, components.Position, components.Device);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, ResetActivators, EcsPostUpdate, components.Input);
|
ECS_SYSTEM(ecs, ResetActivators, EcsPostUpdate, components.Input);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ static inline asset_id item_fix_kind(asset_id id) {
|
||||||
|
|
||||||
void item_show(uint64_t ent, bool show) {
|
void item_show(uint64_t ent, bool show) {
|
||||||
Classify *c = ecs_get_mut(world_ecs(), ent, Classify);
|
Classify *c = ecs_get_mut(world_ecs(), ent, Classify);
|
||||||
|
librg_entity_visibility_global_set(world_tracker(), ent, show ? LIBRG_VISIBLITY_DEFAULT : LIBRG_VISIBLITY_NEVER);
|
||||||
c->id = show ? EKIND_ITEM : EKIND_SERVER;
|
c->id = show ? EKIND_ITEM : EKIND_SERVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +38,25 @@ uint64_t item_spawn(asset_id kind, uint32_t qty) {
|
||||||
.kind = item_fix_kind(kind),
|
.kind = item_fix_kind(kind),
|
||||||
.quantity = qty,
|
.quantity = qty,
|
||||||
.merger_time = 0,
|
.merger_time = 0,
|
||||||
|
.durability = 1.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
item_desc *it = &items[item_find(kind)];
|
||||||
|
|
||||||
|
switch (it->attachment) {
|
||||||
|
case UDATA_FUEL: {
|
||||||
|
Fuel *f = ecs_get_mut(world_ecs(), e, Fuel);
|
||||||
|
f->burn_time = it->fuel.burn_time;
|
||||||
|
} break;
|
||||||
|
case UDATA_INGREDIENT: {
|
||||||
|
Ingredient *i = ecs_get_mut(world_ecs(), e, Ingredient);
|
||||||
|
i->producer = it->ingredient.producer;
|
||||||
|
i->product = it->ingredient.product;
|
||||||
|
i->additional_ingredient = it->ingredient.additional_ingredient;
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
return (uint64_t)e;
|
return (uint64_t)e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,15 +69,22 @@ item_id item_find(asset_id kind) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *item_get_data(uint64_t ent) {
|
Item *item_get_data(uint64_t ent) {
|
||||||
return ecs_get_mut(world_ecs(), ent, Item);
|
if (!world_entity_valid(ent)) return NULL;
|
||||||
|
// if (ecs_get(world_ecs(), ent, ItemAlreadyEdited)) return NULL;
|
||||||
|
// ecs_add(world_ecs(), ent, ItemAlreadyEdited);
|
||||||
|
return ecs_get_mut_if(world_ecs(), ent, Item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void item_use(ecs_world_t *ecs, ItemSlot *it, Position p, uint64_t udata) {
|
const Item *item_get_data_const(uint64_t ent) {
|
||||||
|
if (!world_entity_valid(ent)) return NULL;
|
||||||
|
return ecs_get(world_ecs(), ent, Item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void item_use(ecs_world_t *ecs, ecs_entity_t e, Item *it, Position p, uint64_t udata) {
|
||||||
(void)ecs;
|
(void)ecs;
|
||||||
Item *d = item_get_data(it->ent);
|
if (e == 0) return;
|
||||||
uint16_t it_id = d->kind;
|
uint16_t it_id = item_find(it->kind);
|
||||||
item_desc *desc = &items[it_id];
|
item_desc *desc = &items[it_id];
|
||||||
if (it->ent == 0) return;
|
|
||||||
switch (item_get_usage(it_id)) {
|
switch (item_get_usage(it_id)) {
|
||||||
case UKIND_HOLD: /* NOOP */ break;
|
case UKIND_HOLD: /* NOOP */ break;
|
||||||
case UKIND_PLACE:{
|
case UKIND_PLACE:{
|
||||||
|
@ -71,7 +96,7 @@ void item_use(ecs_world_t *ecs, ItemSlot *it, Position p, uint64_t udata) {
|
||||||
|
|
||||||
// NOTE(zaklaus): If we replace the same item, refund 1 qty and let it replace it
|
// NOTE(zaklaus): If we replace the same item, refund 1 qty and let it replace it
|
||||||
if (item_asset_id == it_id) {
|
if (item_asset_id == it_id) {
|
||||||
d->quantity++;
|
it->quantity++;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +106,7 @@ void item_use(ecs_world_t *ecs, ItemSlot *it, Position p, uint64_t udata) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
world_chunk_replace_block(l.chunk_id, l.id, blocks_find(desc->place.kind + (asset_id)udata));
|
world_chunk_replace_block(l.chunk_id, l.id, blocks_find(desc->place.kind + (asset_id)udata));
|
||||||
d->quantity--;
|
it->quantity--;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case UKIND_PLACE_ITEM:{
|
case UKIND_PLACE_ITEM:{
|
||||||
|
@ -98,7 +123,7 @@ void item_use(ecs_world_t *ecs, ItemSlot *it, Position p, uint64_t udata) {
|
||||||
ZPL_ASSERT(world_entity_valid(e));
|
ZPL_ASSERT(world_entity_valid(e));
|
||||||
entity_set_position(e, p.x, p.y);
|
entity_set_position(e, p.x, p.y);
|
||||||
|
|
||||||
d->quantity--;
|
it->quantity--;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,33 +11,51 @@ typedef enum {
|
||||||
UKIND_PLACE,
|
UKIND_PLACE,
|
||||||
UKIND_PLACE_ITEM,
|
UKIND_PLACE_ITEM,
|
||||||
UKIND_END_PLACE,
|
UKIND_END_PLACE,
|
||||||
|
|
||||||
// NOTE(zaklaus): the rest of possible actions
|
// NOTE(zaklaus): the rest of possible actions
|
||||||
UKIND_HOLD,
|
UKIND_HOLD,
|
||||||
UKIND_PROXY,
|
UKIND_PROXY,
|
||||||
} item_usage;
|
} item_usage;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UDATA_NONE,
|
||||||
|
UDATA_FUEL,
|
||||||
|
UDATA_INGREDIENT,
|
||||||
|
} item_attachment;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
asset_id kind;
|
asset_id kind;
|
||||||
item_usage usage;
|
item_usage usage;
|
||||||
|
item_attachment attachment;
|
||||||
uint32_t max_quantity;
|
uint32_t max_quantity;
|
||||||
bool unique;
|
|
||||||
|
|
||||||
// NOTE(zaklaus): usage data
|
// NOTE(zaklaus): usage data
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
asset_id kind;
|
asset_id kind;
|
||||||
bool directional; // NOTE(zaklaus): expects next 4 asset entries to be direction assets
|
bool directional; // NOTE(zaklaus): expects next 4 asset entries to be direction assets
|
||||||
} place;
|
} place;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
asset_id id;
|
asset_id id;
|
||||||
} proxy;
|
} proxy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
asset_id id;
|
asset_id id;
|
||||||
} place_item;
|
} place_item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
float burn_time;
|
||||||
|
} fuel;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
asset_id producer;
|
||||||
|
asset_id product;
|
||||||
|
asset_id additional_ingredient;
|
||||||
|
} ingredient;
|
||||||
|
};
|
||||||
} item_desc;
|
} item_desc;
|
||||||
|
|
||||||
typedef uint16_t item_id;
|
typedef uint16_t item_id;
|
||||||
|
@ -48,15 +66,11 @@ void item_show(uint64_t ent, bool show);
|
||||||
uint64_t item_spawn(asset_id kind, uint32_t qty);
|
uint64_t item_spawn(asset_id kind, uint32_t qty);
|
||||||
void item_despawn(uint64_t id);
|
void item_despawn(uint64_t id);
|
||||||
|
|
||||||
// NOTE: item ops
|
|
||||||
void item_pickup(uint64_t ent, uint64_t item);
|
|
||||||
void item_drop(uint64_t ent, uint64_t item);
|
|
||||||
void item_merge(uint64_t item1, uint64_t item2);
|
|
||||||
|
|
||||||
// NOTE(zaklaus): items
|
// NOTE(zaklaus): items
|
||||||
item_id item_find(asset_id kind);
|
item_id item_find(asset_id kind);
|
||||||
void item_use(ecs_world_t *ecs, ItemSlot *it, Position p, uint64_t udata);
|
void item_use(ecs_world_t *ecs, ecs_entity_t e, Item *it, Position p, uint64_t udata);
|
||||||
Item *item_get_data(uint64_t ent);
|
Item *item_get_data(uint64_t ent);
|
||||||
|
const Item *item_get_data_const(uint64_t ent);
|
||||||
|
|
||||||
uint32_t item_max_quantity(item_id id);
|
uint32_t item_max_quantity(item_id id);
|
||||||
item_usage item_get_usage(item_id id);
|
item_usage item_get_usage(item_id id);
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
static item_desc items[] = {
|
static item_desc items[] = {
|
||||||
{ .kind = 0, .max_quantity = 0, },
|
{ .kind = 0, .max_quantity = 0, },
|
||||||
ITEM_BLOCK(ASSET_DEMO_ICEMAKER, 64, ASSET_WATER),
|
ITEM_INGREDIENT(ASSET_DEMO_ICEMAKER, 64, ASSET_FURNACE, ASSET_BELT, 0),
|
||||||
ITEM_SELF(ASSET_FENCE, 64),
|
ITEM_SELF(ASSET_FENCE, 64),
|
||||||
ITEM_SELF(ASSET_WOOD, 64),
|
ITEM_FUEL(ASSET_WOOD, 64, 15.0f),
|
||||||
ITEM_HOLD(ASSET_TREE, 64),
|
ITEM_HOLD(ASSET_TREE, 64),
|
||||||
|
|
||||||
ITEM_SELF_DIR(ASSET_BELT, 999),
|
ITEM_SELF_DIR(ASSET_BELT, 999),
|
||||||
|
|
|
@ -4,13 +4,39 @@
|
||||||
{\
|
{\
|
||||||
.kind = asset,\
|
.kind = asset,\
|
||||||
.usage = UKIND_HOLD,\
|
.usage = UKIND_HOLD,\
|
||||||
|
.attachment = UDATA_NONE,\
|
||||||
.max_quantity = qty,\
|
.max_quantity = qty,\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ITEM_FUEL(asset, qty, fuel_value)\
|
||||||
|
{\
|
||||||
|
.kind = asset,\
|
||||||
|
.usage = UKIND_HOLD,\
|
||||||
|
.attachment = UDATA_FUEL,\
|
||||||
|
.max_quantity = qty,\
|
||||||
|
.fuel = {\
|
||||||
|
.burn_time = fuel_value\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ITEM_INGREDIENT(asset, qty, _producer, _product, _additional)\
|
||||||
|
{\
|
||||||
|
.kind = asset,\
|
||||||
|
.usage = UKIND_HOLD,\
|
||||||
|
.attachment = UDATA_INGREDIENT,\
|
||||||
|
.max_quantity = qty,\
|
||||||
|
.ingredient = {\
|
||||||
|
.producer = _producer,\
|
||||||
|
.product = _product,\
|
||||||
|
.additional_ingredient = _additional,\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
#define ITEM_BLOCK(asset, qty, build_asset)\
|
#define ITEM_BLOCK(asset, qty, build_asset)\
|
||||||
{\
|
{\
|
||||||
.kind = asset,\
|
.kind = asset,\
|
||||||
.usage = UKIND_PLACE,\
|
.usage = UKIND_PLACE,\
|
||||||
|
.attachment = UDATA_NONE,\
|
||||||
.max_quantity = qty,\
|
.max_quantity = qty,\
|
||||||
.place = {\
|
.place = {\
|
||||||
.kind = build_asset,\
|
.kind = build_asset,\
|
||||||
|
@ -21,6 +47,7 @@
|
||||||
{\
|
{\
|
||||||
.kind = asset,\
|
.kind = asset,\
|
||||||
.usage = UKIND_PLACE,\
|
.usage = UKIND_PLACE,\
|
||||||
|
.attachment = UDATA_NONE,\
|
||||||
.max_quantity = qty,\
|
.max_quantity = qty,\
|
||||||
.place = {\
|
.place = {\
|
||||||
.kind = build_asset,\
|
.kind = build_asset,\
|
||||||
|
@ -32,6 +59,7 @@
|
||||||
{\
|
{\
|
||||||
.kind = asset,\
|
.kind = asset,\
|
||||||
.usage = UKIND_PROXY,\
|
.usage = UKIND_PROXY,\
|
||||||
|
.attachment = UDATA_NONE,\
|
||||||
.proxy = {\
|
.proxy = {\
|
||||||
.id = proxy_id,\
|
.id = proxy_id,\
|
||||||
}\
|
}\
|
||||||
|
@ -41,6 +69,7 @@
|
||||||
{\
|
{\
|
||||||
.kind = asset,\
|
.kind = asset,\
|
||||||
.usage = UKIND_PLACE_ITEM,\
|
.usage = UKIND_PLACE_ITEM,\
|
||||||
|
.attachment = UDATA_NONE,\
|
||||||
.max_quantity = qty,\
|
.max_quantity = qty,\
|
||||||
.place_item = {\
|
.place_item = {\
|
||||||
.id = eid\
|
.id = eid\
|
||||||
|
|
|
@ -43,7 +43,7 @@ void buildmode_draw(void) {
|
||||||
build_is_deletion_mode = !build_is_deletion_mode;
|
build_is_deletion_mode = !build_is_deletion_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemDrop *item = &e->items[e->selected_item];
|
Item *item = &e->items[e->selected_item];
|
||||||
|
|
||||||
if (e->has_items && !e->inside_vehicle && item->quantity > 0 && (!is_outside_range || build_is_deletion_mode)) {
|
if (e->has_items && !e->inside_vehicle && item->quantity > 0 && (!is_outside_range || build_is_deletion_mode)) {
|
||||||
item_usage usage = 0;
|
item_usage usage = 0;
|
||||||
|
|
|
@ -4,7 +4,7 @@ typedef struct {
|
||||||
|
|
||||||
bool item_is_held;
|
bool item_is_held;
|
||||||
uint8_t held_item_idx;
|
uint8_t held_item_idx;
|
||||||
ItemDrop held_item;
|
Item held_item;
|
||||||
|
|
||||||
bool is_inside;
|
bool is_inside;
|
||||||
bool storage_action;
|
bool storage_action;
|
||||||
|
@ -44,7 +44,7 @@ void inventory_draw_panel(entity_view *e, bool is_player, float sx, float sy){
|
||||||
{
|
{
|
||||||
debug_area_status area = check_mouse_area(x, y, 64, 64);
|
debug_area_status area = check_mouse_area(x, y, 64, 64);
|
||||||
Color color = RAYWHITE;
|
Color color = RAYWHITE;
|
||||||
ItemDrop *item = (is_player) ? &e->items[i] : &e->storage_items[i];
|
Item *item = (is_player) ? &e->items[i] : &e->storage_items[i];
|
||||||
|
|
||||||
if (area == DAREA_HOVER) {
|
if (area == DAREA_HOVER) {
|
||||||
color = YELLOW;
|
color = YELLOW;
|
||||||
|
|
|
@ -64,12 +64,12 @@ typedef struct entity_view {
|
||||||
|
|
||||||
// NOTE(zaklaus): inventory
|
// NOTE(zaklaus): inventory
|
||||||
uint8_t has_items;
|
uint8_t has_items;
|
||||||
ItemDrop items[ITEMS_INVENTORY_SIZE];
|
Item items[ITEMS_INVENTORY_SIZE];
|
||||||
uint8_t selected_item;
|
uint8_t selected_item;
|
||||||
|
|
||||||
// NOTE(zaklaus): storage interface
|
// NOTE(zaklaus): storage interface
|
||||||
uint8_t has_storage_items;
|
uint8_t has_storage_items;
|
||||||
ItemDrop storage_items[ITEMS_CONTAINER_SIZE];
|
Item storage_items[ITEMS_CONTAINER_SIZE];
|
||||||
uint8_t storage_selected_item;
|
uint8_t storage_selected_item;
|
||||||
|
|
||||||
// NOTE(zaklaus): entity picking
|
// NOTE(zaklaus): entity picking
|
||||||
|
|
|
@ -62,7 +62,7 @@ void predict_receive_update(entity_view *d, entity_view *data) {
|
||||||
data->tran_time = d->tran_time;
|
data->tran_time = d->tran_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ENTITY_DO_LERP_SP 1
|
#define ENTITY_DO_LERP_SP 0
|
||||||
|
|
||||||
void lerp_entity_positions(uint64_t key, entity_view *data) {
|
void lerp_entity_positions(uint64_t key, entity_view *data) {
|
||||||
(void)key;
|
(void)key;
|
||||||
|
|
|
@ -56,8 +56,8 @@ entity_view *world_build_entity_view(int64_t e) {
|
||||||
view.heading = veh->heading;
|
view.heading = veh->heading;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ecs_get(world_ecs(), e, ItemDrop)) {
|
if (ecs_get(world_ecs(), e, Item)) {
|
||||||
ItemDrop const* dr = ecs_get(world_ecs(), e, ItemDrop);
|
Item const* dr = ecs_get(world_ecs(), e, Item);
|
||||||
view.asset = dr->kind;
|
view.asset = dr->kind;
|
||||||
view.quantity = dr->quantity;
|
view.quantity = dr->quantity;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,8 @@ entity_view *world_build_entity_view(int64_t e) {
|
||||||
view.has_items = true;
|
view.has_items = true;
|
||||||
|
|
||||||
for (int i = 0; i < ITEMS_INVENTORY_SIZE; i += 1) {
|
for (int i = 0; i < ITEMS_INVENTORY_SIZE; i += 1) {
|
||||||
view.items[i] = inv->items[i];
|
const Item *it = ecs_get(world_ecs(), inv->items[i], Item);
|
||||||
|
view.items[i] = it ? *it : (Item){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
const Input *in = ecs_get(world_ecs(), e, Input);
|
const Input *in = ecs_get(world_ecs(), e, Input);
|
||||||
|
@ -89,7 +90,8 @@ entity_view *world_build_entity_view(int64_t e) {
|
||||||
view.has_storage_items = true;
|
view.has_storage_items = true;
|
||||||
|
|
||||||
for (int i = 0; i < ITEMS_CONTAINER_SIZE; i += 1) {
|
for (int i = 0; i < ITEMS_CONTAINER_SIZE; i += 1) {
|
||||||
view.storage_items[i] = ic->items[i];
|
const Item *it = ecs_get(world_ecs(), ic->items[i], Item);
|
||||||
|
view.storage_items[i] = it ? *it : (Item){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
view.storage_selected_item = in->storage_selected_item;
|
view.storage_selected_item = in->storage_selected_item;
|
||||||
|
@ -590,7 +592,6 @@ int64_t *world_chunk_query_entities(int64_t e, size_t *ents_len, int8_t radius)
|
||||||
ZPL_ASSERT_NOT_NULL(ents_len);
|
ZPL_ASSERT_NOT_NULL(ents_len);
|
||||||
static int64_t ents[UINT16_MAX];
|
static int64_t ents[UINT16_MAX];
|
||||||
*ents_len = UINT16_MAX;
|
*ents_len = UINT16_MAX;
|
||||||
librg_entity_radius_set(world.tracker, e, radius);
|
|
||||||
librg_world_query(world.tracker, e, radius, ents, ents_len);
|
librg_world_query(world.tracker, e, radius, ents, ents_len);
|
||||||
return ents;
|
return ents;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue