streamline assets=

master
Dominik Madarász 2024-05-29 10:45:43 +02:00
parent a9ea1e9335
commit b348400c1a
12 changed files with 277 additions and 210 deletions

View File

@ -134,11 +134,12 @@ float game_time() {
return (float)get_cached_time();
}
void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled) {
void game_setup(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled) {
game_mode = play_mode;
game_should_close = false;
db_init();
entity_default_spawnlist();
game_init(db_init());
#ifndef _DEBUG
const char *host_ip = "lab.zakto.pw";
@ -181,6 +182,8 @@ void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_
//ecs_set_target_fps(world_ecs(), 60);
}
}
game_init_ecs();
if (game_mode == GAMEKIND_SINGLE) {
for (uint32_t i = 0; i < num_viewers; i++) {

View File

@ -11,7 +11,7 @@ typedef enum {
FORCE_GAMEKIND_UINT8 = UINT8_MAX
} game_kind;
void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled);
void game_setup(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled);
void game_shutdown();
void game_request_close();
uint8_t game_is_running();
@ -21,6 +21,8 @@ game_kind game_get_kind(void);
//~ NOTE(zaklaus): game events
// Implemented by games
void game_init(bool new_db);
void game_init_ecs(); // called once the world is initialised
void game_input();
void game_update();
void game_render();

View File

@ -28,7 +28,7 @@ void sql_asset(sqlite3_context *ctx, int argc, sqlite3_value **argv) {
sqlite3_result_null(ctx);
}
void db_init() {
bool db_init() {
bool new_db = !zpl_fs_exists(ECO2D_DB);
sqlite3_open(ECO2D_DB, &db);
assert(db && "Failed to open database.");
@ -37,7 +37,7 @@ void db_init() {
sqlite3_create_function(db, "asset", 1, SQLITE_UTF8, NULL, sql_asset, NULL, NULL);
if (new_db) {
zpl_printf("[INFO] Creating new database.\n");
zpl_printf("[INFO] Creating new database...\n");
db_exec_file("art/queries/tables.sql");
assets_db_init();
@ -48,10 +48,12 @@ void db_init() {
}
// initialise models db
assets_db();
blocks_db();
craft_db();
item_db();
zpl_printf("[INFO] Loading models from database...\n");
assets_db(); zpl_printf("[INFO] Assets loaded.\n");
blocks_db(); zpl_printf("[INFO] Blocks loaded.\n");
craft_db(); zpl_printf("[INFO] Recipes loaded.\n");
item_db(); zpl_printf("[INFO] Items loaded.\n");
return new_db;
}
void db_shutdown() {

View File

@ -2,7 +2,7 @@
#include "platform/system.h"
#include "zpl.h"
void db_init();
bool db_init();
void db_shutdown();
// raw query data getters

View File

@ -8,8 +8,45 @@
#include "systems/systems.h"
#include "zpl.h"
typedef struct {
asset_id id;
uint64_t (*proc)();
uint64_t (*proc_udata)(void*);
} spawndef;
static spawndef *entity_spawnlist;
void entity_add_spawndef(uint16_t id, uint64_t (*proc)()) {
spawndef def={0};
def.id = id;
def.proc = proc;
zpl_array_append(entity_spawnlist, def);
}
void entity_add_spawndef_data(uint16_t id, uint64_t (*proc)(void*)) {
spawndef def={0};
def.id = id;
def.proc_udata = proc;
zpl_array_append(entity_spawnlist, def);
}
// NOTE(zaklaus): bring in entity spawnlist
#include "lists/entity_spawnlist.c"
// #include "lists/entity_spawnlist.c"
#include "models/prefabs/prefabs_list.c"
#define MAX_ENTITY_SPAWNDEFS ((size_t)zpl_array_count(entity_spawnlist))
void entity_default_spawnlist(void) {
zpl_array_init(entity_spawnlist, zpl_heap());
entity_add_spawndef(ASSET_CHEST, storage_spawn);
entity_add_spawndef(ASSET_FURNACE, furnace_spawn);
entity_add_spawndef(ASSET_CRAFTBENCH, craftbench_spawn);
entity_add_spawndef(ASSET_SPLITTER, splitter_spawn);
entity_add_spawndef(ASSET_ASSEMBLER, assembler_spawn);
entity_add_spawndef(ASSET_CREATURE, creature_spawn);
entity_add_spawndef(ASSET_MOB, mob_spawn);
entity_add_spawndef_data(ASSET_BLUEPRINT, blueprint_spawn_udata);
}
uint64_t entity_spawn(uint16_t class_id) {
ecs_entity_t e = ecs_new(world_ecs(), 0);

View File

@ -11,6 +11,11 @@ void entity_batch_despawn(uint64_t *ids, size_t num_ids);
void entity_despawn(uint64_t ent_id);
void entity_set_position(uint64_t ent_id, float x, float y);
// NOTE(zaklaus): spawndef manager
void entity_add_spawndef(uint16_t id, uint64_t (*proc)());
void entity_add_spawndef_data(uint16_t id, uint64_t (*proc)(void*));
void entity_default_spawnlist(void);
// NOTE(zaklaus): action-based entity stream throttling
void entity_wake(uint64_t ent_id);

View File

@ -1,30 +1,38 @@
#include "core/game.h"
void game_input() {
game_core_input();
}
void game_update() {
game_core_update();
}
void game_render() {
game_core_render();
}
void game_player_joined(uint64_t ent) {
}
void game_player_departed(uint64_t ent) {
}
void game_player_died(uint64_t ent) {
}
void game_client_receive_code(pkt_send_code data) {
}
#include "core/game.h"
void game_init(bool new_db) {
}
void game_init_ecs() {
}
void game_input() {
game_core_input();
}
void game_update() {
game_core_update();
}
void game_render() {
game_core_render();
}
void game_player_joined(uint64_t ent) {
}
void game_player_departed(uint64_t ent) {
}
void game_player_died(uint64_t ent) {
}
void game_client_receive_code(pkt_send_code data) {
}

View File

@ -69,7 +69,7 @@ int main(int argc, char** argv) {
}
sighandler_register();
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
game_setup(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
game_run();

View File

@ -1,31 +1,38 @@
#include "core/game.h"
void game_input() {
game_core_input();
}
void game_update() {
game_core_update();
}
void game_render() {
game_core_render();
}
void game_player_joined(uint64_t ent) {
ecs_set(world_ecs(), ent, Inventory, {0});
ecs_set(world_ecs(), ent, HealthRegen, {15.f});
}
void game_player_departed(uint64_t ent) {
}
void game_player_died(uint64_t ent) {
}
void game_client_receive_code(pkt_send_code data) {
}
#include "core/game.h"
void game_init(bool new_db) {
}
void game_init_ecs() {
}
void game_input() {
game_core_input();
}
void game_update() {
game_core_update();
}
void game_render() {
game_core_render();
}
void game_player_joined(uint64_t ent) {
ecs_set(world_ecs(), ent, Inventory, {0});
ecs_set(world_ecs(), ent, HealthRegen, {15.f});
}
void game_player_departed(uint64_t ent) {
}
void game_player_died(uint64_t ent) {
}
void game_client_receive_code(pkt_send_code data) {
}

View File

@ -73,7 +73,7 @@ int main(int argc, char** argv) {
}
sighandler_register();
game_init(host, port, play_mode, num_viewers, seed, chunk_size, world_size, is_dash_enabled);
game_setup(host, port, play_mode, num_viewers, seed, chunk_size, world_size, is_dash_enabled);
game_run();

View File

@ -1,134 +1,138 @@
#include "core/game.h"
#include "game.h"
#include "world/world.h"
#include "models/components.h"
#include "systems/systems.h"
#include "models/entity.h"
#include "world/entity_view.h"
#include "gui/notifications.h"
float get_rand_between(float min, float max) {
return ((float)rand() / (float)RAND_MAX) * (max - min) + min;
}
static ecs_query_t *ecs_mobpos_query = NULL;
static ecs_query_t *ecs_pawn_query = NULL;
// custom systems
#include "system_mob.c"
#include "system_weapon.c"
#define PLAYER_RESPAWN_BLAST_FORCE 1200.0f
void PlayerRespawn(ecs_iter_t *it) {
Respawn *r = ecs_field(it, Respawn, 1);
Input *in = ecs_field(it, Input, 2);
Sprite *s = ecs_field(it, Sprite, 3);
Position *p = ecs_field(it, Position, 4);
Health *h = ecs_field(it, Health, 5);
for (int i = 0; i < it->count; i++) {
if (r[i].timer > 0) {
TICK_VAR(r[i].timer);
continue;
}
ecs_remove(it->world, it->entities[i], Respawn);
ecs_remove(it->world, it->entities[i], Dead);
in[i].is_blocked = 0;
s[i].spritesheet = 0;
h[i].hp = h[i].max_hp;
size_t ents_count;
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2);
for (size_t j = 0; j < ents_count; j++) {
uint64_t ent_id = ents[j];
if (!ecs_get(it->world, ent_id, Mob) || ecs_get(it->world, ent_id, Dead)) {
continue;
}
const Position *p2 = ecs_get(it->world, ent_id, Position);
Velocity *v = ecs_get_mut(it->world, ent_id, Velocity);
float dx = p2->x - p[i].x;
float dy = p2->y - p[i].y;
float range = zpl_sqrt(dx*dx + dy*dy);
if (range <= 5*WORLD_BLOCK_SIZE) {
Health *hp = ecs_get_mut(it->world, ent_id, Health);
hp->dmg += hp->max_hp/2.0f;
v->x += (dx/range)*PLAYER_RESPAWN_BLAST_FORCE;
v->y += (dy/range)*PLAYER_RESPAWN_BLAST_FORCE;
}
}
}
}
void mob_systems(ecs_world_t *ecs) {
ECS_SYSTEM_TICKED_EX(ecs, MobDetectPlayers, EcsPostUpdate, 100.0f, components.Position, components.Mob, !components.Dead);
ECS_SYSTEM(ecs, MobMovement, EcsPostUpdate, components.Velocity, components.Position, components.MobHuntPlayer, !components.Dead);
ECS_SYSTEM_TICKED(ecs, MobMeleeAtk, EcsPostUpdate, components.Position, components.Mob, components.MobHuntPlayer, components.MobMelee, !components.Dead);
ECS_SYSTEM_TICKED(ecs, MobDespawnDead, EcsPostUpdate, components.Mob, components.Dead);
ECS_SYSTEM_TICKED(ecs, MobSpawner, EcsPostUpdate, components.Input, components.Position, !components.Dead);
ECS_SYSTEM_TICKED(ecs, PlayerRespawn, EcsPostUpdate, components.Respawn, components.Input, components.Sprite, components.Position, components.Health);
//NOTE(DavoSK): weapons
ecs_mobpos_query = ecs_query_new(world_ecs(), "components.Mob, components.Position, components.Health, components.Velocity, !components.Dead");
ecs_pawn_query = ecs_query_new(world_ecs(), "components.Position, components.Health, components.Velocity, !components.Dead");
ECS_SYSTEM_TICKED(ecs, WeaponKnifeMechanic, EcsPostUpdate, components.WeaponKnife, components.Position, components.Input, !components.Dead);
ECS_SYSTEM_TICKED(ecs, WeaponProjectileHit, EcsPostUpdate, components.WeaponProjectile, components.Position, components.Rotation);
ECS_SYSTEM_TICKED(ecs, WeaponProjectileExpire, EcsPostUpdate, components.WeaponProjectile, components.Position);
ECS_OBSERVER(ecs, MobOnDead, EcsOnAdd, components.Mob, components.Sprite, components.Velocity, components.Dead);
}
void game_input() {
game_core_input();
}
void game_update() {
game_core_update();
}
void game_render() {
game_core_render();
}
void game_setup_ecs() {
mob_systems(world_ecs());
}
void game_player_departed(uint64_t ent) {
}
void game_player_joined(uint64_t ent) {
notification_push("test1", "Hello World!");
//NOTE(DavoSK): add weapon component for testing
ecs_world_t* world = world_ecs();
ecs_set(world, (ecs_entity_t)ent, WeaponKnife, {
.projectile_count = 10,
.damage = 10,
.spawn_delay = WEAPON_KNIFE_SPAWN_DELAY
});
}
void game_player_died(uint64_t ent) {
Sprite *spr = ecs_get_mut(world_ecs(), ent, Sprite);
Velocity *v = ecs_get_mut(world_ecs(), ent, Velocity);
spr->frame = 3 + (rand()%5);
spr->spritesheet = 69; /*special code*/
*v = (Velocity){0.0f, 0.0f};
ecs_remove(world_ecs(), ent, PhysicsBody);
ecs_set(world_ecs(), ent, Respawn, { 100 });
}
void game_client_receive_code(pkt_send_code data) {
switch (data.code) {
case SURV_CODE_SHOW_NOTIF: {
notification_push("TEST", data.data);
} break;
}
}
#include "core/game.h"
#include "game.h"
#include "world/world.h"
#include "models/components.h"
#include "systems/systems.h"
#include "models/entity.h"
#include "world/entity_view.h"
#include "gui/notifications.h"
float get_rand_between(float min, float max) {
return ((float)rand() / (float)RAND_MAX) * (max - min) + min;
}
static ecs_query_t *ecs_mobpos_query = NULL;
static ecs_query_t *ecs_pawn_query = NULL;
// custom systems
#include "system_mob.c"
#include "system_weapon.c"
#define PLAYER_RESPAWN_BLAST_FORCE 1200.0f
void PlayerRespawn(ecs_iter_t *it) {
Respawn *r = ecs_field(it, Respawn, 1);
Input *in = ecs_field(it, Input, 2);
Sprite *s = ecs_field(it, Sprite, 3);
Position *p = ecs_field(it, Position, 4);
Health *h = ecs_field(it, Health, 5);
for (int i = 0; i < it->count; i++) {
if (r[i].timer > 0) {
TICK_VAR(r[i].timer);
continue;
}
ecs_remove(it->world, it->entities[i], Respawn);
ecs_remove(it->world, it->entities[i], Dead);
in[i].is_blocked = 0;
s[i].spritesheet = 0;
h[i].hp = h[i].max_hp;
size_t ents_count;
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2);
for (size_t j = 0; j < ents_count; j++) {
uint64_t ent_id = ents[j];
if (!ecs_get(it->world, ent_id, Mob) || ecs_get(it->world, ent_id, Dead)) {
continue;
}
const Position *p2 = ecs_get(it->world, ent_id, Position);
Velocity *v = ecs_get_mut(it->world, ent_id, Velocity);
float dx = p2->x - p[i].x;
float dy = p2->y - p[i].y;
float range = zpl_sqrt(dx*dx + dy*dy);
if (range <= 5*WORLD_BLOCK_SIZE) {
Health *hp = ecs_get_mut(it->world, ent_id, Health);
hp->dmg += hp->max_hp/2.0f;
v->x += (dx/range)*PLAYER_RESPAWN_BLAST_FORCE;
v->y += (dy/range)*PLAYER_RESPAWN_BLAST_FORCE;
}
}
}
}
void mob_systems(ecs_world_t *ecs) {
ECS_SYSTEM_TICKED_EX(ecs, MobDetectPlayers, EcsPostUpdate, 100.0f, components.Position, components.Mob, !components.Dead);
ECS_SYSTEM(ecs, MobMovement, EcsPostUpdate, components.Velocity, components.Position, components.MobHuntPlayer, !components.Dead);
ECS_SYSTEM_TICKED(ecs, MobMeleeAtk, EcsPostUpdate, components.Position, components.Mob, components.MobHuntPlayer, components.MobMelee, !components.Dead);
ECS_SYSTEM_TICKED(ecs, MobDespawnDead, EcsPostUpdate, components.Mob, components.Dead);
ECS_SYSTEM_TICKED(ecs, MobSpawner, EcsPostUpdate, components.Input, components.Position, !components.Dead);
ECS_SYSTEM_TICKED(ecs, PlayerRespawn, EcsPostUpdate, components.Respawn, components.Input, components.Sprite, components.Position, components.Health);
//NOTE(DavoSK): weapons
ecs_mobpos_query = ecs_query_new(world_ecs(), "components.Mob, components.Position, components.Health, components.Velocity, !components.Dead");
ecs_pawn_query = ecs_query_new(world_ecs(), "components.Position, components.Health, components.Velocity, !components.Dead");
ECS_SYSTEM_TICKED(ecs, WeaponKnifeMechanic, EcsPostUpdate, components.WeaponKnife, components.Position, components.Input, !components.Dead);
ECS_SYSTEM_TICKED(ecs, WeaponProjectileHit, EcsPostUpdate, components.WeaponProjectile, components.Position, components.Rotation);
ECS_SYSTEM_TICKED(ecs, WeaponProjectileExpire, EcsPostUpdate, components.WeaponProjectile, components.Position);
ECS_OBSERVER(ecs, MobOnDead, EcsOnAdd, components.Mob, components.Sprite, components.Velocity, components.Dead);
}
void game_init(bool new_db) {
}
void game_input() {
game_core_input();
}
void game_update() {
game_core_update();
}
void game_render() {
game_core_render();
}
void game_init_ecs() {
mob_systems(world_ecs());
}
void game_player_departed(uint64_t ent) {
}
void game_player_joined(uint64_t ent) {
notification_push("test1", "Hello World!");
//NOTE(DavoSK): add weapon component for testing
ecs_world_t* world = world_ecs();
ecs_set(world, (ecs_entity_t)ent, WeaponKnife, {
.projectile_count = 10,
.damage = 10,
.spawn_delay = WEAPON_KNIFE_SPAWN_DELAY
});
}
void game_player_died(uint64_t ent) {
Sprite *spr = ecs_get_mut(world_ecs(), ent, Sprite);
Velocity *v = ecs_get_mut(world_ecs(), ent, Velocity);
spr->frame = 3 + (rand()%5);
spr->spritesheet = 69; /*special code*/
*v = (Velocity){0.0f, 0.0f};
ecs_remove(world_ecs(), ent, PhysicsBody);
ecs_set(world_ecs(), ent, Respawn, { 100 });
}
void game_client_receive_code(pkt_send_code data) {
switch (data.code) {
case SURV_CODE_SHOW_NOTIF: {
notification_push("TEST", data.data);
} break;
}
}

View File

@ -90,8 +90,7 @@ int main(int argc, char** argv) {
}
sighandler_register();
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, is_dash_enabled);
game_setup_ecs();
game_setup(host, port, play_mode, 1, seed, chunk_size, world_size, is_dash_enabled);
game_run();
game_shutdown();