new crafting system
parent
70bb456a43
commit
9e368527a3
Binary file not shown.
After Width: | Height: | Size: 424 B |
|
@ -13,6 +13,7 @@ add_library(eco2d-foundation STATIC
|
||||||
src/models/items.c
|
src/models/items.c
|
||||||
src/models/entity.c
|
src/models/entity.c
|
||||||
src/models/device.c
|
src/models/device.c
|
||||||
|
src/models/crafting.c
|
||||||
|
|
||||||
src/models/prefabs/player.c
|
src/models/prefabs/player.c
|
||||||
src/models/prefabs/vehicle.c
|
src/models/prefabs/vehicle.c
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include "models/crafting.h"
|
||||||
|
|
||||||
|
#define R(id1,qty1)\
|
||||||
|
{\
|
||||||
|
.id = id1,\
|
||||||
|
.qty = qty1\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RECIPE(id,prod,qty,...)\
|
||||||
|
{\
|
||||||
|
.product = id,\
|
||||||
|
.product_qty = qty,\
|
||||||
|
.producer = prod,\
|
||||||
|
.reagents = (reagent[]){\
|
||||||
|
__VA_ARGS__\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
|
static recipe recipes[] = {
|
||||||
|
RECIPE(ASSET_BELT, ASSET_FURNACE, 4, R(ASSET_FENCE, 8), R(ASSET_WOOD, 2), {0}),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_RECIPES (sizeof(recipes)/sizeof(recipes[0]))
|
||||||
|
|
||||||
|
#undef R
|
||||||
|
#undef RECIPE
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
static item_desc items[] = {
|
static item_desc items[] = {
|
||||||
{ .kind = 0, .max_quantity = 0, },
|
{ .kind = 0, .max_quantity = 0, },
|
||||||
ITEM_INGREDIENT(ASSET_FENCE, 64, ASSET_FURNACE, ASSET_BELT, 0),
|
ITEM_HOLD(ASSET_FENCE, 64),
|
||||||
ITEM_ENERGY(ASSET_COAL, ASSET_FURNACE, 64, 15.0f),
|
ITEM_ENERGY(ASSET_COAL, ASSET_FURNACE, 64, 15.0f),
|
||||||
ITEM_SELF(ASSET_WOOD, 64),
|
ITEM_SELF(ASSET_WOOD, 64),
|
||||||
ITEM_SELF(ASSET_TREE, 64),
|
ITEM_SELF(ASSET_TREE, 64),
|
||||||
|
|
|
@ -17,7 +17,6 @@ ECS_COMPONENT_DECLARE(Inventory);
|
||||||
ECS_COMPONENT_DECLARE(ItemContainer);
|
ECS_COMPONENT_DECLARE(ItemContainer);
|
||||||
ECS_COMPONENT_DECLARE(Producer);
|
ECS_COMPONENT_DECLARE(Producer);
|
||||||
ECS_COMPONENT_DECLARE(EnergySource);
|
ECS_COMPONENT_DECLARE(EnergySource);
|
||||||
ECS_COMPONENT_DECLARE(Ingredient);
|
|
||||||
ECS_COMPONENT_DECLARE(ItemRouter);
|
ECS_COMPONENT_DECLARE(ItemRouter);
|
||||||
ECS_COMPONENT_DECLARE(Device);
|
ECS_COMPONENT_DECLARE(Device);
|
||||||
ECS_COMPONENT_DECLARE(Blueprint);
|
ECS_COMPONENT_DECLARE(Blueprint);
|
||||||
|
@ -44,7 +43,6 @@ void ComponentsImport(ecs_world_t *ecs) {
|
||||||
ECS_COMPONENT_DEFINE(ecs, ItemContainer);
|
ECS_COMPONENT_DEFINE(ecs, ItemContainer);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Producer);
|
ECS_COMPONENT_DEFINE(ecs, Producer);
|
||||||
ECS_COMPONENT_DEFINE(ecs, EnergySource);
|
ECS_COMPONENT_DEFINE(ecs, EnergySource);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Ingredient);
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, ItemRouter);
|
ECS_COMPONENT_DEFINE(ecs, ItemRouter);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Device);
|
ECS_COMPONENT_DEFINE(ecs, Device);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Blueprint);
|
ECS_COMPONENT_DEFINE(ecs, Blueprint);
|
||||||
|
|
|
@ -131,12 +131,13 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
asset_id processed_item;
|
asset_id processed_item;
|
||||||
|
uint32_t processed_item_qty;
|
||||||
float process_time;
|
float process_time;
|
||||||
float energy_level;
|
float energy_level;
|
||||||
} Producer;
|
} Producer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char _unused;
|
uint32_t push_qty;
|
||||||
} ItemRouter;
|
} ItemRouter;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -144,12 +145,6 @@ typedef struct {
|
||||||
float energy_level;
|
float energy_level;
|
||||||
} EnergySource;
|
} EnergySource;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
asset_id producer;
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -188,7 +183,6 @@ extern ECS_COMPONENT_DECLARE(Inventory);
|
||||||
extern ECS_COMPONENT_DECLARE(ItemContainer);
|
extern ECS_COMPONENT_DECLARE(ItemContainer);
|
||||||
extern ECS_COMPONENT_DECLARE(Producer);
|
extern ECS_COMPONENT_DECLARE(Producer);
|
||||||
extern ECS_COMPONENT_DECLARE(EnergySource);
|
extern ECS_COMPONENT_DECLARE(EnergySource);
|
||||||
extern ECS_COMPONENT_DECLARE(Ingredient);
|
|
||||||
extern ECS_COMPONENT_DECLARE(ItemRouter);
|
extern ECS_COMPONENT_DECLARE(ItemRouter);
|
||||||
extern ECS_COMPONENT_DECLARE(Device);
|
extern ECS_COMPONENT_DECLARE(Device);
|
||||||
extern ECS_COMPONENT_DECLARE(Blueprint);
|
extern ECS_COMPONENT_DECLARE(Blueprint);
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
#include "crafting.h"
|
||||||
|
#include "models/items.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
asset_id id;
|
||||||
|
uint32_t qty;
|
||||||
|
} reagent;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
asset_id product;
|
||||||
|
uint32_t product_qty;
|
||||||
|
asset_id producer;
|
||||||
|
reagent *reagents;
|
||||||
|
} recipe;
|
||||||
|
|
||||||
|
#include "lists/crafting_list.c"
|
||||||
|
|
||||||
|
uint32_t craft__find_num_recipes_by_reagent(asset_id producer, asset_id id) {
|
||||||
|
uint32_t num_recipes=0;
|
||||||
|
for (int i = 0; i < MAX_RECIPES; ++i) {
|
||||||
|
if (recipes[i].producer == producer) {
|
||||||
|
for (int j = 0; recipes[i].reagents[j].id; ++j) {
|
||||||
|
if (recipes[i].reagents[j].id == id) {
|
||||||
|
++num_recipes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num_recipes;
|
||||||
|
}
|
||||||
|
|
||||||
|
recipe *craft__find_recipe_by_reagent(asset_id producer, asset_id id, uint32_t slot_id) {
|
||||||
|
for (int i = 0; i < MAX_RECIPES; ++i) {
|
||||||
|
if (recipes[i].producer == producer) {
|
||||||
|
for (int j = 0; recipes[i].reagents[j].id; ++j) {
|
||||||
|
if (recipes[i].reagents[j].id == id) {
|
||||||
|
if (slot_id > 0) {
|
||||||
|
--slot_id;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return &recipes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool craft_is_reagent_used_in_producer(asset_id reagent, asset_id producer) {
|
||||||
|
return craft__find_num_recipes_by_reagent(producer, reagent) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset_id craft_perform_recipe(ecs_entity_t *items, asset_id producer, uint32_t *quantity) {
|
||||||
|
ZPL_ASSERT_NOT_NULL(items);
|
||||||
|
|
||||||
|
for (int i = 0; i < ITEMS_CONTAINER_SIZE; i++) {
|
||||||
|
ecs_entity_t item_slot_ent = items[i];
|
||||||
|
if (item_slot_ent == 0) continue;
|
||||||
|
Item *item = item_get_data(item_slot_ent);
|
||||||
|
if (!item) continue;
|
||||||
|
|
||||||
|
uint32_t num_recipes = craft__find_num_recipes_by_reagent(producer, item->kind);
|
||||||
|
for (uint32_t rec_i = 0; rec_i < num_recipes; ++rec_i) {
|
||||||
|
// TODO(zaklaus): slow, find a better way to retrieve known recipes
|
||||||
|
recipe *rec = craft__find_recipe_by_reagent(producer, item->kind, rec_i);
|
||||||
|
if (!rec) {
|
||||||
|
// NOTE(zaklaus): this item is not used as a reagent, skip it.
|
||||||
|
// TODO(zaklaus): is this a bug? should we assert?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t skip_slot=0;
|
||||||
|
|
||||||
|
// NOTE(zaklaus): analyse if all the reagents are present
|
||||||
|
for (int j = 0; rec->reagents[j].id; ++j) {
|
||||||
|
reagent *rea = &rec->reagents[j];
|
||||||
|
uint32_t pending_qty = rea->qty;
|
||||||
|
|
||||||
|
for (int k = 0; k < ITEMS_CONTAINER_SIZE; k++) {
|
||||||
|
ecs_entity_t rea_item_slot_ent = items[k];
|
||||||
|
if (rea_item_slot_ent == 0) continue;
|
||||||
|
Item *rea_item = item_get_data(rea_item_slot_ent);
|
||||||
|
if (!rea_item) continue;
|
||||||
|
|
||||||
|
if (rea->id == rea_item->kind && rea_item->quantity > 0) {
|
||||||
|
pending_qty -= zpl_min(pending_qty, rea_item->quantity);
|
||||||
|
|
||||||
|
if (pending_qty == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending_qty > 0) {
|
||||||
|
// NOTE(zaklaus): reagent not found, bail
|
||||||
|
skip_slot=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(zaklaus): demand not met, bye!
|
||||||
|
if (skip_slot)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// NOTE(zaklaus): deplete used reagents
|
||||||
|
for (int j = 0; rec->reagents[j].id; ++j) {
|
||||||
|
reagent *rea = &rec->reagents[j];
|
||||||
|
uint32_t pending_qty = rea->qty;
|
||||||
|
|
||||||
|
for (int k = 0; k < ITEMS_CONTAINER_SIZE; k++) {
|
||||||
|
ecs_entity_t rea_item_slot_ent = items[k];
|
||||||
|
if (rea_item_slot_ent == 0) continue;
|
||||||
|
Item *rea_item = item_get_data(rea_item_slot_ent);
|
||||||
|
if (!rea_item) continue;
|
||||||
|
|
||||||
|
if (rea->id == rea_item->kind && rea_item->quantity > 0) {
|
||||||
|
rea_item->quantity -= zpl_min(pending_qty, rea_item->quantity);
|
||||||
|
pending_qty -= zpl_min(pending_qty, rea_item->quantity);
|
||||||
|
if (rea_item->quantity == 0) {
|
||||||
|
item_despawn(rea_item_slot_ent);
|
||||||
|
items[k] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending_qty == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(zaklaus): all done, return the product and its qty
|
||||||
|
*quantity = rec->product_qty;
|
||||||
|
return rec->product;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(zaklaus):
|
||||||
|
asset_id craft_has_byproducts(asset_id product) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(zaklaus):
|
||||||
|
uint32_t craft_resolve_graph(asset_id product, uint16_t *hops, uint8_t direct_cost) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
#include "platform/system.h"
|
||||||
|
#include "models/assets.h"
|
||||||
|
|
||||||
|
#include "models/components.h"
|
||||||
|
|
||||||
|
// NOTE(zaklaus): resolves recipe dependencies and consumes reagents
|
||||||
|
// to enqueue a production of a new item.
|
||||||
|
// TODO(zaklaus): "items" is assumed to come from ItemContainer component.
|
||||||
|
asset_id craft_perform_recipe(ecs_entity_t *items, asset_id producer, uint32_t *quantity);
|
||||||
|
|
||||||
|
// NOTE(zaklaus): informs us on whether this product has any byproducts desired.
|
||||||
|
asset_id craft_has_byproducts(asset_id product);
|
||||||
|
|
||||||
|
// NOTE(zaklaus): mostly used by item router so we don't push reagents out
|
||||||
|
bool craft_is_reagent_used_in_producer(asset_id reagent, asset_id producer);
|
||||||
|
|
||||||
|
// NOTE(zaklaus): resolves the production chain and analyses the amount of items required
|
||||||
|
// and a number of hops (production layers) needed to produce the item.
|
||||||
|
// optionally, it allows to calculate "direct_cost" of the product.
|
||||||
|
uint32_t craft_resolve_graph(asset_id product, uint16_t *hops, uint8_t direct_cost);
|
|
@ -57,12 +57,6 @@ uint64_t item_spawn(asset_id kind, uint32_t qty) {
|
||||||
.energy_level = it->energy_source.energy_level,
|
.energy_level = it->energy_source.energy_level,
|
||||||
};
|
};
|
||||||
} break;
|
} 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;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UDATA_NONE,
|
UDATA_NONE,
|
||||||
UDATA_ENERGY_SOURCE,
|
UDATA_ENERGY_SOURCE,
|
||||||
UDATA_INGREDIENT,
|
|
||||||
} item_attachment;
|
} item_attachment;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -52,12 +51,6 @@ typedef struct {
|
||||||
asset_id producer;
|
asset_id producer;
|
||||||
float energy_level;
|
float energy_level;
|
||||||
} energy_source;
|
} energy_source;
|
||||||
|
|
||||||
struct {
|
|
||||||
asset_id producer;
|
|
||||||
asset_id product;
|
|
||||||
asset_id additional_ingredient;
|
|
||||||
} ingredient;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: item data
|
// NOTE: item data
|
||||||
|
|
|
@ -15,7 +15,7 @@ uint64_t furnace_spawn(void) {
|
||||||
*producer = (Producer){0};
|
*producer = (Producer){0};
|
||||||
producer->energy_level = 69.0f;
|
producer->energy_level = 69.0f;
|
||||||
|
|
||||||
ecs_add(world_ecs(), e, ItemRouter);
|
ecs_set(world_ecs(), e, ItemRouter, {1});
|
||||||
return (uint64_t)e;
|
return (uint64_t)e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "models/crafting.h"
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
asset_id FetchAssetAtPos(float x, float y) {
|
asset_id FetchAssetAtPos(float x, float y) {
|
||||||
world_block_lookup lookup = world_block_from_realpos(x, y);
|
world_block_lookup lookup = world_block_from_realpos(x, y);
|
||||||
|
@ -63,6 +65,7 @@ void PushItemsOnNodes(ecs_iter_t *it) {
|
||||||
// We need a way to refer to specific blocks in the world so we can do easy block ID checks
|
// We need a way to refer to specific blocks in the world so we can do easy block ID checks
|
||||||
// and re-build the cache when a change is detected.
|
// and re-build the cache when a change is detected.
|
||||||
|
|
||||||
|
|
||||||
float push_dx[4], push_dy[4];
|
float push_dx[4], push_dy[4];
|
||||||
uint8_t nodes = CheckForNearbyBelts(&p[i], push_dx, push_dy);
|
uint8_t nodes = CheckForNearbyBelts(&p[i], push_dx, push_dy);
|
||||||
uint8_t num_nodes = (uint8_t)zpl_count_set_bits(nodes);
|
uint8_t num_nodes = (uint8_t)zpl_count_set_bits(nodes);
|
||||||
|
@ -77,14 +80,12 @@ void PushItemsOnNodes(ecs_iter_t *it) {
|
||||||
ecs_entity_t item_slot_ent = storage[i].items[j];
|
ecs_entity_t item_slot_ent = storage[i].items[j];
|
||||||
if (item_slot_ent == 0) continue;
|
if (item_slot_ent == 0) continue;
|
||||||
Item *item = item_get_data(item_slot_ent);
|
Item *item = item_get_data(item_slot_ent);
|
||||||
|
if (!item) continue;
|
||||||
|
|
||||||
const Ingredient *ing = 0;
|
if (craft_is_reagent_used_in_producer(item->kind, d->asset)) {
|
||||||
// NOTE(zaklaus): Make sure we don't push out items from input node
|
// NOTE(zaklaus): this is an input reagent, keep it
|
||||||
if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) {
|
|
||||||
if (ing->producer == d->asset) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while (item->quantity > 0 && num_nodes > 0) {
|
while (item->quantity > 0 && num_nodes > 0) {
|
||||||
// NOTE(zaklaus): Use a rolling counter to select an output node.
|
// NOTE(zaklaus): Use a rolling counter to select an output node.
|
||||||
|
@ -94,14 +95,14 @@ void PushItemsOnNodes(ecs_iter_t *it) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t e = item_spawn(item->kind, 1);
|
uint64_t e = item_spawn(item->kind, zpl_min(r->push_qty, item->quantity));
|
||||||
entity_set_position(e, p[i].x + push_dx[counter], p[i].y + push_dy[counter]);
|
entity_set_position(e, p[i].x + push_dx[counter], p[i].y + push_dy[counter]);
|
||||||
|
|
||||||
Velocity *e_vel = ecs_get_mut_ex(it->world, e, Velocity);
|
Velocity *e_vel = ecs_get_mut_ex(it->world, e, Velocity);
|
||||||
e_vel->x = push_dx[counter];
|
e_vel->x = push_dx[counter];
|
||||||
e_vel->y = push_dy[counter];
|
e_vel->y = push_dy[counter];
|
||||||
|
|
||||||
--item->quantity;
|
item->quantity -= zpl_min(r->push_qty, item->quantity);
|
||||||
--num_nodes;
|
--num_nodes;
|
||||||
++counter;
|
++counter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "models/crafting.h"
|
||||||
|
|
||||||
void ProduceItems(ecs_iter_t *it) {
|
void ProduceItems(ecs_iter_t *it) {
|
||||||
ItemContainer *storage = ecs_field(it, ItemContainer, 1);
|
ItemContainer *storage = ecs_field(it, ItemContainer, 1);
|
||||||
Producer *producer = ecs_field(it, Producer, 2);
|
Producer *producer = ecs_field(it, Producer, 2);
|
||||||
|
@ -7,6 +9,7 @@ void ProduceItems(ecs_iter_t *it) {
|
||||||
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++) {
|
||||||
ecs_entity_t item_slot_ent = storage[i].items[j];
|
ecs_entity_t item_slot_ent = storage[i].items[j];
|
||||||
|
if (item_slot_ent == 0) continue;
|
||||||
Item *item = item_get_data(item_slot_ent);
|
Item *item = item_get_data(item_slot_ent);
|
||||||
|
|
||||||
const EnergySource *energy_source = 0;
|
const EnergySource *energy_source = 0;
|
||||||
|
@ -19,27 +22,19 @@ void ProduceItems(ecs_iter_t *it) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(zaklaus): handle fuel
|
||||||
// if (producer[i].energy_level <= 0.0f) continue;
|
// if (producer[i].energy_level <= 0.0f) continue;
|
||||||
|
|
||||||
|
// TODO(zaklaus): use ticks
|
||||||
if (producer[i].process_time < game_time()) {
|
if (producer[i].process_time < game_time()) {
|
||||||
if (producer[i].processed_item > 0) {
|
if (producer[i].processed_item > 0) {
|
||||||
uint64_t e = item_spawn(producer[i].processed_item, 1);
|
uint64_t e = item_spawn(producer[i].processed_item, producer[i].processed_item_qty);
|
||||||
entity_set_position(e, p[i].x, p[i].y);
|
entity_set_position(e, p[i].x, p[i].y);
|
||||||
producer[i].processed_item = 0;
|
producer[i].processed_item = 0;
|
||||||
} else {
|
} else {
|
||||||
const Ingredient *ing = 0;
|
producer[i].processed_item = craft_perform_recipe(storage[i].items, d->asset, &producer[i].processed_item_qty);
|
||||||
if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) {
|
|
||||||
if (ing->producer == d->asset) {
|
|
||||||
if (item->quantity <= 0) {
|
|
||||||
item_despawn(item_slot_ent);
|
|
||||||
storage[i].items[j] = 0;
|
|
||||||
} else {
|
|
||||||
producer[i].processed_item = ing->product;
|
|
||||||
producer[i].process_time = game_time() + game_rules.furnace_cook_time;
|
producer[i].process_time = game_time() + game_rules.furnace_cook_time;
|
||||||
}
|
}
|
||||||
item->quantity--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue