improve blueprints

efd/v1
Dominik Madarász 2022-10-16 13:00:50 +02:00
parent 71dc349e4e
commit 93612f5462
9 changed files with 78 additions and 150 deletions

View File

@ -6,15 +6,12 @@
typedef enum { typedef enum {
RPKIND_KEY, RPKIND_KEY,
// NOTE(zaklaus): Special actions // NOTE(zaklaus): Special actions
RPKIND_SPAWN_CAR, RPKIND_SPAWN_CAR,
RPKIND_PLACE_ICE_RINK, RPKIND_PLACE_ICE_RINK,
RPKIND_PLACE_ERASE_CHANGES, RPKIND_PLACE_ERASE_CHANGES,
RPKIND_SPAWN_CIRCLING_DRIVER, RPKIND_SPAWN_CIRCLING_DRIVER,
RPKIND_SPAWN_ICEMAKER_ITEM,
RPKIND_SPAWN_CHEST,
RPKIND_SPAWN_BELT,
} replay_kind; } replay_kind;
typedef struct { typedef struct {
@ -45,17 +42,17 @@ static char replaybuf[sizeof(replay_record)*UINT16_MAX + 32];
void debug_replay_store(void) { void debug_replay_store(void) {
ZPL_ASSERT(replay_filename[0]); ZPL_ASSERT(replay_filename[0]);
if (!records) return; if (!records) return;
cw_pack_context pc = {0}; cw_pack_context pc = {0};
cw_pack_context_init(&pc, replaybuf, sizeof(replaybuf), 0); cw_pack_context_init(&pc, replaybuf, sizeof(replaybuf), 0);
cw_pack_unsigned(&pc, REPLAY_MAGIC); cw_pack_unsigned(&pc, REPLAY_MAGIC);
cw_pack_unsigned(&pc, REPLAY_VERSION); cw_pack_unsigned(&pc, REPLAY_VERSION);
cw_pack_array_size(&pc, (uint32_t)zpl_array_count(records)); cw_pack_array_size(&pc, (uint32_t)zpl_array_count(records));
for (int i = 0; i < zpl_array_count(records); i++) { for (int i = 0; i < zpl_array_count(records); i++) {
cw_pack_bin(&pc, &records[i], sizeof(replay_record)); cw_pack_bin(&pc, &records[i], sizeof(replay_record));
} }
zpl_file f = {0}; zpl_file f = {0};
zpl_file_create(&f, replay_filename); zpl_file_create(&f, replay_filename);
zpl_file_write(&f, replaybuf, pc.current - pc.start); zpl_file_write(&f, replaybuf, pc.current - pc.start);
@ -64,44 +61,44 @@ void debug_replay_store(void) {
void debug_replay_load(void) { void debug_replay_load(void) {
ZPL_ASSERT(replay_filename[0]); ZPL_ASSERT(replay_filename[0]);
zpl_file f = {0}; zpl_file f = {0};
zpl_file_error err = zpl_file_open(&f, replay_filename); zpl_file_error err = zpl_file_open(&f, replay_filename);
ZPL_ASSERT(err == ZPL_FILE_ERROR_NONE); ZPL_ASSERT(err == ZPL_FILE_ERROR_NONE);
size_t file_size = zpl_file_size(&f); size_t file_size = zpl_file_size(&f);
zpl_file_read(&f, replaybuf, file_size); zpl_file_read(&f, replaybuf, file_size);
zpl_file_close(&f); zpl_file_close(&f);
cw_unpack_context uc = {0}; cw_unpack_context uc = {0};
cw_unpack_context_init(&uc, replaybuf, (uint32_t)file_size, 0); cw_unpack_context_init(&uc, replaybuf, (uint32_t)file_size, 0);
cw_unpack_next(&uc); cw_unpack_next(&uc);
ZPL_ASSERT(uc.item.type == CWP_ITEM_POSITIVE_INTEGER && uc.item.as.u64 == REPLAY_MAGIC); ZPL_ASSERT(uc.item.type == CWP_ITEM_POSITIVE_INTEGER && uc.item.as.u64 == REPLAY_MAGIC);
cw_unpack_next(&uc); cw_unpack_next(&uc);
ZPL_ASSERT(uc.item.type == CWP_ITEM_POSITIVE_INTEGER); ZPL_ASSERT(uc.item.type == CWP_ITEM_POSITIVE_INTEGER);
uint64_t version = uc.item.as.u64; uint64_t version = uc.item.as.u64;
ZPL_ASSERT(version >= 2); ZPL_ASSERT(version >= 2);
cw_unpack_next(&uc); cw_unpack_next(&uc);
ZPL_ASSERT(uc.item.type == CWP_ITEM_ARRAY); ZPL_ASSERT(uc.item.type == CWP_ITEM_ARRAY);
size_t items = uc.item.as.array.size; size_t items = uc.item.as.array.size;
zpl_array_init_reserve(records, zpl_heap(), sizeof(replay_record)*items); zpl_array_init_reserve(records, zpl_heap(), sizeof(replay_record)*items);
for (size_t i = 0; i < items; i++) { for (size_t i = 0; i < items; i++) {
cw_unpack_next(&uc); cw_unpack_next(&uc);
ZPL_ASSERT(uc.item.type == CWP_ITEM_BIN); ZPL_ASSERT(uc.item.type == CWP_ITEM_BIN);
replay_record rec = {0}; replay_record rec = {0};
switch (version) { switch (version) {
case 2:{ case 2:{
debug_replay_load_record_v2(&rec, uc.item.as.bin.start); debug_replay_load_record_v2(&rec, uc.item.as.bin.start);
}break; }break;
default:{ default:{
zpl_memcopy(&rec, uc.item.as.bin.start, sizeof(replay_record)); zpl_memcopy(&rec, uc.item.as.bin.start, sizeof(replay_record));
}break; }break;
@ -112,10 +109,10 @@ void debug_replay_load(void) {
void debug_replay_start(void) { void debug_replay_start(void) {
is_recording = true; is_recording = true;
if (records) zpl_array_free(records); if (records) zpl_array_free(records);
zpl_array_init_reserve(records, zpl_heap(), UINT16_MAX); zpl_array_init_reserve(records, zpl_heap(), UINT16_MAX);
last_record_time = get_cached_time(); last_record_time = get_cached_time();
SetTargetFPS(60); SetTargetFPS(60);
} }
@ -130,17 +127,17 @@ void debug_replay_clear(void) {
void debug_replay_cleanup_ents(void) { void debug_replay_cleanup_ents(void) {
SetTargetFPS(0); SetTargetFPS(0);
if (!mime) return; if (!mime) return;
entity_despawn(mime); entity_despawn(mime);
mime = 0; mime = 0;
is_playing = false; is_playing = false;
camera_set_follow(plr); camera_set_follow(plr);
for (int i = 0; i < zpl_array_count(temp_actors); i++) { for (int i = 0; i < zpl_array_count(temp_actors); i++) {
entity_despawn(temp_actors[i]); entity_despawn(temp_actors[i]);
} }
zpl_array_free(temp_actors); zpl_array_free(temp_actors);
} }
@ -157,17 +154,17 @@ void debug_replay_run(void) {
record_pos = 0; record_pos = 0;
playback_time = get_cached_time(); playback_time = get_cached_time();
zpl_array_init(temp_actors, zpl_heap()); zpl_array_init(temp_actors, zpl_heap());
plr = camera_get().ent_id; plr = camera_get().ent_id;
Position const *p1 = ecs_get(world_ecs(), plr, Position); Position const *p1 = ecs_get(world_ecs(), plr, Position);
mime = entity_spawn(EKIND_MACRO_BOT); mime = entity_spawn(EKIND_MACRO_BOT);
Position *pos = ecs_get_mut(world_ecs(), mime, Position); Position *pos = ecs_get_mut(world_ecs(), mime, Position);
*pos = *p1; *pos = *p1;
ecs_set(world_ecs(), mime, Input, {0}); ecs_set(world_ecs(), mime, Input, {0});
ecs_set(world_ecs(), mime, Inventory, {0}); ecs_set(world_ecs(), mime, Inventory, {0});
camera_set_follow(mime); camera_set_follow(mime);
SetTargetFPS(60); SetTargetFPS(60);
} }
@ -182,10 +179,10 @@ void ActSpawnBelt(void);
void debug_replay_update(void) { void debug_replay_update(void) {
if (!is_playing) return; if (!is_playing) return;
if (playback_time >= get_cached_time()) return; if (playback_time >= get_cached_time()) return;
replay_record *r = &records[record_pos]; replay_record *r = &records[record_pos];
playback_time = get_cached_time() + r->delay; playback_time = get_cached_time() + r->delay;
switch (r->kind) { switch (r->kind) {
case RPKIND_KEY: { case RPKIND_KEY: {
Input *i = ecs_get_mut(world_ecs(), mime, Input); Input *i = ecs_get_mut(world_ecs(), mime, Input);
@ -209,11 +206,11 @@ void debug_replay_update(void) {
}break; }break;
case RPKIND_SPAWN_CAR: { case RPKIND_SPAWN_CAR: {
ecs_entity_t e = vehicle_spawn(EVEH_CAR); ecs_entity_t e = vehicle_spawn(EVEH_CAR);
Position const *origin = ecs_get(world_ecs(), mime, Position); Position const *origin = ecs_get(world_ecs(), mime, Position);
Position *dest = ecs_get_mut(world_ecs(), e, Position); Position *dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin; *dest = *origin;
zpl_array_append(temp_actors, e); zpl_array_append(temp_actors, e);
}break; }break;
case RPKIND_PLACE_ICE_RINK: { case RPKIND_PLACE_ICE_RINK: {
@ -225,22 +222,13 @@ void debug_replay_update(void) {
case RPKIND_PLACE_ERASE_CHANGES:{ case RPKIND_PLACE_ERASE_CHANGES:{
ActEraseWorldChanges(); ActEraseWorldChanges();
}break; }break;
case RPKIND_SPAWN_ICEMAKER_ITEM:{
ActSpawnCoal();
}break;
case RPKIND_SPAWN_CHEST:{
ActSpawnChest();
}break;
case RPKIND_SPAWN_BELT:{
ActSpawnBelt();
}break;
default: { default: {
ZPL_PANIC("unreachable"); ZPL_PANIC("unreachable");
}break; }break;
} }
record_pos += 1; record_pos += 1;
// NOTE(zaklaus): remove our dummy art exhibist // NOTE(zaklaus): remove our dummy art exhibist
if (mime && record_pos == zpl_array_count(records)) { if (mime && record_pos == zpl_array_count(records)) {
debug_replay_cleanup_ents(); debug_replay_cleanup_ents();
@ -250,13 +238,13 @@ void debug_replay_update(void) {
void debug_replay_record_keystate(pkt_send_keystate state) { void debug_replay_record_keystate(pkt_send_keystate state) {
if (!is_recording) return; if (!is_recording) return;
double record_time = get_cached_time(); double record_time = get_cached_time();
replay_record rec = { replay_record rec = {
.kind = RPKIND_KEY, .kind = RPKIND_KEY,
.pkt = state, .pkt = state,
.delay = (record_time - last_record_time), .delay = (record_time - last_record_time),
}; };
zpl_array_append(records, rec); zpl_array_append(records, rec);
last_record_time = get_cached_time(); last_record_time = get_cached_time();
} }
@ -265,12 +253,12 @@ void debug_replay_special_action(replay_kind kind) {
ZPL_ASSERT(kind != RPKIND_KEY); ZPL_ASSERT(kind != RPKIND_KEY);
if (!is_recording || is_playing) return; if (!is_recording || is_playing) return;
double record_time = get_cached_time(); double record_time = get_cached_time();
replay_record rec = { replay_record rec = {
.kind = kind, .kind = kind,
.delay = (record_time - last_record_time), .delay = (record_time - last_record_time),
}; };
zpl_array_append(records, rec); zpl_array_append(records, rec);
last_record_time = get_cached_time(); last_record_time = get_cached_time();
} }

View File

@ -21,92 +21,6 @@ ActSpawnCar(void) {
debug_replay_special_action(RPKIND_SPAWN_CAR); debug_replay_special_action(RPKIND_SPAWN_CAR);
} }
void
ActSpawnCoal(void) {
ecs_entity_t e = item_spawn(ASSET_COAL, 32);
ecs_entity_t plr = camera_get().ent_id;
Position const* origin = ecs_get(world_ecs(), plr, Position);
Position * dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin;
entity_set_position(e, dest->x, dest->y);
debug_replay_special_action(RPKIND_SPAWN_ICEMAKER_ITEM);
}
void
ActSpawnChest(void) {
ecs_entity_t e = item_spawn(ASSET_CHEST, 32);
ecs_entity_t plr = camera_get().ent_id;
Position const* origin = ecs_get(world_ecs(), plr, Position);
Position * dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin;
entity_set_position(e, dest->x, dest->y);
debug_replay_special_action(RPKIND_SPAWN_CHEST);
}
void
ActSpawnBelt(void) {
ecs_entity_t e = item_spawn(ASSET_BELT, 32);
ecs_entity_t plr = camera_get().ent_id;
Position const* origin = ecs_get(world_ecs(), plr, Position);
Position * dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin;
entity_set_position(e, dest->x, dest->y);
debug_replay_special_action(RPKIND_SPAWN_BELT);
}
void
ActSpawnDurabilityTest(void) {
ecs_entity_t e = item_spawn(ASSET_COAL, 1);
ecs_entity_t plr = camera_get().ent_id;
Position const* origin = ecs_get(world_ecs(), plr, Position);
Position * dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin;
entity_set_position(e, dest->x, dest->y);
Item *it = ecs_get_mut(world_ecs(), e, Item);
it->durability = (float)(rand() % 100) / 100.0f;
}
void
ActSpawnFurnace(void) {
ecs_entity_t e = item_spawn(ASSET_FURNACE, 32);
ecs_entity_t plr = camera_get().ent_id;
Position const* origin = ecs_get(world_ecs(), plr, Position);
Position * dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin;
entity_set_position(e, dest->x, dest->y);
}
void
ActSpawnTallTest(void) {
ecs_entity_t e = item_spawn(ASSET_TEST_TALL, 32);
ecs_entity_t plr = camera_get().ent_id;
Position const* origin = ecs_get(world_ecs(), plr, Position);
Position * dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin;
entity_set_position(e, dest->x, dest->y);
}
void
ActSpawnDemoHouseItem(void) {
ecs_entity_t e = item_spawn(ASSET_BLUEPRINT, 1);
ecs_entity_t plr = camera_get().ent_id;
Position const* origin = ecs_get(world_ecs(), plr, Position);
Position * dest = ecs_get_mut(world_ecs(), e, Position);
*dest = *origin;
entity_set_position(e, dest->x, dest->y);
}
void void
ActSpawnItemPrev(void) { ActSpawnItemPrev(void) {
while (true) { while (true) {

View File

@ -17,6 +17,11 @@ Texture2D texgen_build_anim_fallback(asset_id id, int64_t counter) {
} }
Texture2D texgen_build_sprite_fallback(asset_id id) { Texture2D texgen_build_sprite_fallback(asset_id id) {
if (id > ASSET_BLUEPRINT_BEGIN && id < ASSET_BLUEPRINT_END) {
return LoadTexEco("blueprint");
}
switch (id) { switch (id) {
case ASSET_BLANK: return GenColorEco(WHITE); break; case ASSET_BLANK: return GenColorEco(WHITE); break;
case ASSET_BUILDMODE_HIGHLIGHT: return GenColorEco(WHITE); break; case ASSET_BUILDMODE_HIGHLIGHT: return GenColorEco(WHITE); break;
@ -24,7 +29,6 @@ Texture2D texgen_build_sprite_fallback(asset_id id) {
// NOTE(zaklaus): items // NOTE(zaklaus): items
case ASSET_COAL: return LoadTexEco("coal"); case ASSET_COAL: return LoadTexEco("coal");
case ASSET_BLUEPRINT: return LoadTexEco("blueprint");
// NOTE(zaklaus): blocks // NOTE(zaklaus): blocks
case ASSET_FENCE: return LoadTexEco("fence"); case ASSET_FENCE: return LoadTexEco("fence");

View File

@ -11,7 +11,10 @@
X(ASSET_THING)\ X(ASSET_THING)\
X(ASSET_CHEST)\ X(ASSET_CHEST)\
X(ASSET_FURNACE)\ X(ASSET_FURNACE)\
X(ASSET_BLUEPRINT_BEGIN)\
X(ASSET_BLUEPRINT)\ X(ASSET_BLUEPRINT)\
X(ASSET_BLUEPRINT_DEMO_HOUSE)\
X(ASSET_BLUEPRINT_END)\
X(ASSET_FENCE)\ X(ASSET_FENCE)\
X(ASSET_DEV)\ X(ASSET_DEV)\
X(ASSET_GROUND)\ X(ASSET_GROUND)\
@ -38,7 +41,7 @@ typedef enum {
#define X(id) id, #define X(id) id,
_ASSETS _ASSETS
#undef X #undef X
MAX_ASSETS = 1024, MAX_ASSETS,
} asset_id; } asset_id;
extern const char *asset_names[]; extern const char *asset_names[];

View File

@ -19,6 +19,7 @@ static asset assets[] = {
ASSET_TEX(ASSET_CHEST), ASSET_TEX(ASSET_CHEST),
ASSET_TEX(ASSET_FURNACE), ASSET_TEX(ASSET_FURNACE),
ASSET_TEX(ASSET_BLUEPRINT), ASSET_TEX(ASSET_BLUEPRINT),
ASSET_TEX(ASSET_BLUEPRINT_DEMO_HOUSE),
// NOTE(zaklaus): blocks // NOTE(zaklaus): blocks
ASSET_TEX(ASSET_FENCE), ASSET_TEX(ASSET_FENCE),

View File

@ -11,7 +11,7 @@ static item_desc items[] = {
ITEM_SELF(ASSET_TEST_TALL, 64), ITEM_SELF(ASSET_TEST_TALL, 64),
// ITEM_BLUEPRINT(ASSET_BLUEPRINT, 1, 4, 4, "]]]]]CF] ]]]]]"), // ITEM_BLUEPRINT(ASSET_BLUEPRINT, 1, 4, 4, "]]]]]CF] ]]]]]"),
ITEM_BLUEPRINT(ASSET_BLUEPRINT, 1, 4, 4, PROT({ ASSET_WOOD,ASSET_WOOD,ASSET_WOOD,ASSET_WOOD, ITEM_BLUEPRINT_PROXY(ASSET_BLUEPRINT_DEMO_HOUSE, ASSET_BLUEPRINT, 1, 4, 4, PROT({ ASSET_WOOD,ASSET_WOOD,ASSET_WOOD,ASSET_WOOD,
ASSET_WOOD,ASSET_FURNACE,ASSET_CHEST,ASSET_WOOD, ASSET_WOOD,ASSET_FURNACE,ASSET_CHEST,ASSET_WOOD,
ASSET_FENCE,ASSET_EMPTY,ASSET_EMPTY,ASSET_WOOD, ASSET_FENCE,ASSET_EMPTY,ASSET_EMPTY,ASSET_WOOD,
ASSET_WALL,ASSET_EMPTY,ASSET_EMPTY,ASSET_WOOD})), ASSET_WALL,ASSET_EMPTY,ASSET_EMPTY,ASSET_WOOD})),

View File

@ -39,6 +39,23 @@ __VA_ARGS__\
__VA_ARGS__\ __VA_ARGS__\
} }
#define ITEM_BLUEPRINT_PROXY(asset, place_asset, qty, w_, h_, plan_, ...)\
{\
.kind = asset,\
.usage = UKIND_PLACE_ITEM_DATA,\
.attachment = UDATA_NONE,\
.max_quantity = qty,\
.blueprint = {\
.w = w_,\
.h = h_,\
.plan = (const asset_id[])plan_\
},\
.place_item = {\
.id = place_asset\
},\
__VA_ARGS__\
}
#define ITEM_INGREDIENT(asset, qty, _producer, _product, _additional, ...)\ #define ITEM_INGREDIENT(asset, qty, _producer, _product, _additional, ...)\
{\ {\
.kind = asset,\ .kind = asset,\

View File

@ -7,12 +7,12 @@
typedef struct { typedef struct {
asset_id id; asset_id id;
asset_kind kind; asset_kind kind;
union { union {
Texture2D tex; Texture2D tex;
Sound snd; Sound snd;
}; };
// NOTE(zaklaus): metadata // NOTE(zaklaus): metadata
} asset; } asset;
@ -28,20 +28,20 @@ static double assets_frame_next_draw = 0.0;
int32_t assets_setup(void) { int32_t assets_setup(void) {
for (uint32_t i=0; i<ASSETS_COUNT; i++) { for (uint32_t i=0; i<ASSETS_COUNT; i++) {
asset *b = &assets[i]; asset *b = &assets[i];
switch (b->kind) { switch (b->kind) {
case AKIND_TEXTURE: { case AKIND_TEXTURE: {
b->tex = texgen_build_sprite(b->id); b->tex = texgen_build_sprite(b->id);
}break; }break;
case AKIND_ANIM: { case AKIND_ANIM: {
b->tex = texgen_build_anim(b->id, 0); b->tex = texgen_build_anim(b->id, 0);
}break; }break;
case AKIND_SOUND: { case AKIND_SOUND: {
// TODO(zaklaus): soundgen // TODO(zaklaus): soundgen
}break; }break;
default: break; default: break;
} }
} }
@ -53,21 +53,21 @@ int32_t assets_frame(void) {
if (assets_frame_next_draw < get_cached_time()) { if (assets_frame_next_draw < get_cached_time()) {
for (uint32_t i=0; i<ASSETS_COUNT; i++) { for (uint32_t i=0; i<ASSETS_COUNT; i++) {
asset *b = &assets[i]; asset *b = &assets[i];
switch (b->kind) { switch (b->kind) {
case AKIND_ANIM: { case AKIND_ANIM: {
UnloadTexture(b->tex); UnloadTexture(b->tex);
b->tex = texgen_build_anim(b->id, assets_frame_counter); b->tex = texgen_build_anim(b->id, assets_frame_counter);
}break; }break;
default: break; default: break;
} }
} }
assets_frame_next_draw = get_cached_time() + ASSET_FRAME_RENDER_MS; assets_frame_next_draw = get_cached_time() + ASSET_FRAME_RENDER_MS;
assets_frame_counter += ASSET_FRAME_SKIP; assets_frame_counter += ASSET_FRAME_SKIP;
} }
return 0; return 0;
} }
@ -78,11 +78,11 @@ void assets_destroy(void) {
case AKIND_TEXTURE: { case AKIND_TEXTURE: {
UnloadTexture(assets[i].tex); UnloadTexture(assets[i].tex);
}break; }break;
case AKIND_SOUND: { case AKIND_SOUND: {
// TODO(zaklaus): soundgen // TODO(zaklaus): soundgen
}break; }break;
default: break; default: break;
} }
} }
@ -93,7 +93,7 @@ uint16_t assets_find(asset_id id) {
if (assets[i].id == id) if (assets[i].id == id)
return i; return i;
} }
ZPL_PANIC("Unknown asset id: %d\n", id); ZPL_PANIC("Unknown asset id: %d\n", id);
return ASSET_INVALID; return ASSET_INVALID;
} }

View File

@ -20,6 +20,7 @@ uint16_t assets_find(asset_id id);
asset_kind assets_get_kind(uint16_t id); asset_kind assets_get_kind(uint16_t id);
void *assets_get_snd(uint16_t id); void *assets_get_snd(uint16_t id);
void *assets_get_tex(uint16_t id); void *assets_get_tex(uint16_t id);
uint16_t assets_resolve_proxy(uint16_t id);
// NOTE(zaklaus): client only // NOTE(zaklaus): client only
#define ASSET_SRC_RECT() ((Rectangle){0, 0, 64, 64}) #define ASSET_SRC_RECT() ((Rectangle){0, 0, 64, 64})