Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
Vladyslav Hrytsenko | b032db0acd | |
Vladyslav Hrytsenko | ac6b44eb0a | |
Vladyslav Hrytsenko | 74f0956b66 | |
Vladyslav Hrytsenko | 17951f329f | |
Vladyslav Hrytsenko | 1a5ef9e8fc |
|
@ -1,5 +1,5 @@
|
|||
add_executable(minimal
|
||||
src/main.c
|
||||
src/oldmain.c
|
||||
src/platform.c
|
||||
src/worldgen.c
|
||||
src/texgen.c
|
||||
|
|
|
@ -1,82 +1,5 @@
|
|||
#define ZPL_IMPL
|
||||
#include "zpl.h"
|
||||
#include "platform/system.h"
|
||||
#include "core/game.h"
|
||||
#include "models/entity.h"
|
||||
#include "world/entity_view.h"
|
||||
#include "utils/options.h"
|
||||
#include "platform/signal_handling.h"
|
||||
#include "platform/profiler.h"
|
||||
typedef int efd_main;
|
||||
|
||||
#include "flecs.h"
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
|
||||
#include "models/components.h"
|
||||
#include "systems/systems.h"
|
||||
|
||||
#include "platform/arch.h"
|
||||
|
||||
#define DEFAULT_WORLD_SEED 302097
|
||||
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
|
||||
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
zpl_opts opts={0};
|
||||
zpl_opts_init(&opts, zpl_heap(), argv[0]);
|
||||
|
||||
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
|
||||
//zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
|
||||
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
|
||||
|
||||
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
|
||||
|
||||
if (!ok) {
|
||||
zpl_opts_print_errors(&opts);
|
||||
zpl_opts_print_help(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
|
||||
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
|
||||
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
|
||||
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
|
||||
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
|
||||
zpl_string host = zpl_opts_string(&opts, "host", NULL);
|
||||
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
|
||||
|
||||
game_kind play_mode = GAMEKIND_SINGLE;
|
||||
|
||||
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
|
||||
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "random-seed")) {
|
||||
zpl_random rnd={0};
|
||||
zpl_random_init(&rnd);
|
||||
seed = zpl_random_gen_u32(&rnd);
|
||||
zpl_printf("Seed: %u\n", seed);
|
||||
}
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "preview-map")) {
|
||||
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sighandler_register();
|
||||
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
|
||||
|
||||
game_run();
|
||||
|
||||
game_shutdown();
|
||||
sighandler_unregister();
|
||||
|
||||
zpl_string_free(host);
|
||||
zpl_opts_free(&opts);
|
||||
efd_main start() {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
#define ZPL_IMPL
|
||||
#include "zpl.h"
|
||||
#include "platform/system.h"
|
||||
#include "core/game.h"
|
||||
#include "models/entity.h"
|
||||
#include "world/entity_view.h"
|
||||
#include "utils/options.h"
|
||||
#include "platform/signal_handling.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
#include "flecs.h"
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
|
||||
#include "models/components.h"
|
||||
#include "systems/systems.h"
|
||||
|
||||
#include "platform/arch.h"
|
||||
|
||||
#define DEFAULT_WORLD_SEED 302097
|
||||
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
|
||||
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
zpl_opts opts={0};
|
||||
zpl_opts_init(&opts, zpl_heap(), argv[0]);
|
||||
|
||||
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
|
||||
//zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
|
||||
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
|
||||
|
||||
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
|
||||
|
||||
if (!ok) {
|
||||
zpl_opts_print_errors(&opts);
|
||||
zpl_opts_print_help(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
|
||||
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
|
||||
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
|
||||
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
|
||||
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
|
||||
zpl_string host = zpl_opts_string(&opts, "host", NULL);
|
||||
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
|
||||
|
||||
game_kind play_mode = GAMEKIND_SINGLE;
|
||||
|
||||
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
|
||||
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "random-seed")) {
|
||||
zpl_random rnd={0};
|
||||
zpl_random_init(&rnd);
|
||||
seed = zpl_random_gen_u32(&rnd);
|
||||
zpl_printf("Seed: %u\n", seed);
|
||||
}
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "preview-map")) {
|
||||
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sighandler_register();
|
||||
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
|
||||
|
||||
game_run();
|
||||
|
||||
game_shutdown();
|
||||
sighandler_unregister();
|
||||
|
||||
zpl_string_free(host);
|
||||
zpl_opts_free(&opts);
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
add_executable(survival
|
||||
src/main.c
|
||||
src/oldmain.c
|
||||
src/platform.c
|
||||
src/worldgen.c
|
||||
src/texgen.c
|
||||
|
|
|
@ -1,101 +1,462 @@
|
|||
#define ZPL_IMPL
|
||||
#include "zpl.h"
|
||||
#include "platform/system.h"
|
||||
#include "core/game.h"
|
||||
#include "game.h"
|
||||
#include "models/entity.h"
|
||||
#include "world/entity_view.h"
|
||||
#include "utils/options.h"
|
||||
#include "platform/signal_handling.h"
|
||||
#include "platform/profiler.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "flecs.h"
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
/// lib.c
|
||||
|
||||
#include "models/components.h"
|
||||
#include "systems/systems.h"
|
||||
// core
|
||||
|
||||
#include "platform/arch.h"
|
||||
typedef int efd_app;
|
||||
typedef uint16_t efd_entity_type;
|
||||
typedef int32_t efd_result;
|
||||
typedef void * efd_world;
|
||||
typedef int efd_entid;
|
||||
|
||||
ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0)
|
||||
#include "tinyc2.h"
|
||||
ZPL_DIAGNOSTIC_POP
|
||||
// define amount of memeory reserved for???
|
||||
// custom data within COMMAND (cli->ser) and SNAPSHOT (ser->cli)
|
||||
#define EFD_COMMAND_SIZE 64 * 1024
|
||||
#define EFD_SNAPSHOT_SIZE 128 * 1024
|
||||
|
||||
#define DEFAULT_WORLD_SEED 302097
|
||||
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
|
||||
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
|
||||
#define EFD_TYPE_SHIFT 16
|
||||
#define EFD_ID(type) (((type) << EFD_TYPE_SHIFT) + 1)
|
||||
#define EFD_TYPE(id) ((id - 1) >> EFD_TYPE_SHIFT)
|
||||
#define EFD_END 0
|
||||
|
||||
/*
|
||||
TODO
|
||||
- monster spawner
|
||||
- the longer we survive, the more and stronger enemies we spawn
|
||||
- player grows HP by leveling up
|
||||
- XP increases by killing mobs
|
||||
- player can pick an "ability" upon reaching level milestones
|
||||
- abilities: armor/shield, TODO ...
|
||||
- enemies damage player when close to him in ticks (damage effects, ...)
|
||||
- basic projectile pooling (flecs)
|
||||
- somewhat believable world gen, small hamlets with cols, etc
|
||||
*/
|
||||
typedef enum efd_instance_type {
|
||||
EFD_TYPE_NONE = 0,
|
||||
|
||||
/* chunk */
|
||||
EFD_TYPE_TILE,
|
||||
EFD_TYPE_BLOCK,
|
||||
EFD_TYPE_CHUNK,
|
||||
|
||||
/* entities */
|
||||
EFD_TYPE_ITEM,
|
||||
EFD_TYPE_OBJECT,
|
||||
EFD_TYPE_DEVICE,
|
||||
EFD_TYPE_VEHICLE,
|
||||
EFD_TYPE_MOB,
|
||||
EFD_TYPE_PLAYER,
|
||||
|
||||
/* other */
|
||||
EFD_TYPE_OTHER,
|
||||
|
||||
/* utils */
|
||||
EFD_TYPE_LAST,
|
||||
EFD_TYPE_MAX = 0xFFFF,
|
||||
} efd_instance_type;
|
||||
|
||||
typedef enum efd_flags {
|
||||
EFD_FLAG_COLLISION = (1 << 1),
|
||||
EFD_FLAG_HAZARD = (1 << 2),
|
||||
EFD_FLAG_ESSENTIAL = (1 << 3),
|
||||
EFD_FLAG_DESTROY_ON_COLLISION = (1 << 4),
|
||||
} efd_flags;
|
||||
|
||||
|
||||
// assets
|
||||
|
||||
typedef enum efd_asset_type {
|
||||
EFD_NONE = 0,
|
||||
EFD_TEXTURE,
|
||||
EFD_ANIMATION,
|
||||
EFD_SOUND,
|
||||
EFD_FONT,
|
||||
EFD_SHADER,
|
||||
} efd_asset_type;
|
||||
|
||||
typedef enum efd_asset_flags {
|
||||
EFD_FLAG_ATLAS = (1 << 1), // texture is an atlas and has multiple frames
|
||||
EFD_FLAG_LOOPED = (1 << 2), // frames are looped sequentially (requrires EFD_FLAG_ATLAS, can be combined with EFD_FLAG_RANDOM)
|
||||
EFD_FLAG_RANDOM = (1 << 3), // one of the frames is randomly chosen (requrires EFD_FLAG_ATLAS, can be combined with EFD_FLAG_LOOPED)
|
||||
EFD_FLAG_COMPLEX = (1 << 4), // frames have a complex state system and require a separate asset with EFD_ANIMATION type
|
||||
} efd_asset_flags;
|
||||
|
||||
typedef struct efd_asset {
|
||||
efd_asset_type type;
|
||||
int id;
|
||||
const char *path;
|
||||
int32_t flags;
|
||||
struct {
|
||||
int size_x;
|
||||
int size_y;
|
||||
} atlas;
|
||||
void *data;
|
||||
} efd_asset;
|
||||
|
||||
// objects
|
||||
|
||||
typedef struct efd_tile {
|
||||
int id;
|
||||
int flags;
|
||||
float drag;
|
||||
float friction;
|
||||
} efd_tile;
|
||||
|
||||
typedef struct efd_block {
|
||||
int id;
|
||||
int flags;
|
||||
float bounce;
|
||||
int velx;
|
||||
int vely;
|
||||
} efd_block;
|
||||
|
||||
typedef struct efd_item_list {
|
||||
int id;
|
||||
int qty;
|
||||
} efd_item_list;
|
||||
|
||||
typedef struct efd_craft {
|
||||
int producer;
|
||||
int ticks;
|
||||
efd_item_list *input;
|
||||
efd_item_list *output;
|
||||
} efd_craft;
|
||||
|
||||
typedef struct efd_tooltip {
|
||||
const char *title;
|
||||
const char *description;
|
||||
} efd_tooltip;
|
||||
|
||||
typedef struct efd_entity {
|
||||
int id;
|
||||
int flags;
|
||||
int stack;
|
||||
union {
|
||||
int durability;
|
||||
int health;
|
||||
};
|
||||
efd_result (*spawn_cb)(efd_entid);
|
||||
efd_item_list *drop;
|
||||
} efd_entity;
|
||||
|
||||
|
||||
typedef struct efd_app_desc {
|
||||
const char *name;
|
||||
int debug_ui;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int fullscreen;
|
||||
int vsync;
|
||||
|
||||
int server_only;
|
||||
int viewer_only;
|
||||
int viewer_amount;
|
||||
int world_seed;
|
||||
int world_seed_random;
|
||||
|
||||
efd_result (*init_cb)();
|
||||
efd_result (*system_cb)();
|
||||
efd_result (*update_cb)();
|
||||
efd_result (*render_cb)(efd_entity_type type);
|
||||
efd_result (*player_join_cb)(efd_entid player_id);
|
||||
efd_result (*player_leave_cb)(efd_entid player_id);
|
||||
efd_result (*cleanup_cb)();
|
||||
|
||||
struct {
|
||||
float item_pickup_radius;
|
||||
float item_merge_radius;
|
||||
float item_drop_radius;
|
||||
float item_attract_radius;
|
||||
float item_attract_force;
|
||||
} rules;
|
||||
|
||||
efd_asset *assets;
|
||||
efd_tile *tiles;
|
||||
efd_block *blocks;
|
||||
efd_entity *entities;
|
||||
efd_craft *crafting;
|
||||
efd_tooltip *tooltips;
|
||||
} efd_app_desc;
|
||||
|
||||
/// app.c
|
||||
|
||||
enum {
|
||||
/* textures */
|
||||
TILE_AIR = EFD_ID(EFD_TYPE_TILE),
|
||||
TILE_DIRT,
|
||||
TILE_GRASS,
|
||||
TILE_STONE,
|
||||
TILE_WATER,
|
||||
TILE_LAVA,
|
||||
|
||||
BLOCK_AIR = EFD_ID(EFD_TYPE_BLOCK),
|
||||
BLOCK_WOOD,
|
||||
BLOCK_HILL,
|
||||
BLOCK_HILL_SNOW,
|
||||
BLOCK_FENCE_LEFT,
|
||||
BLOCK_FENCE_RIGHT,
|
||||
BLOCK_FENCE_UP,
|
||||
BLOCK_FENCE_DOWN,
|
||||
BLOCK_WALL_LEFT,
|
||||
BLOCK_WALL_RIGHT,
|
||||
BLOCK_WALL_UP,
|
||||
BLOCK_WALL_DOWN,
|
||||
BLOCK_BELT_LEFT,
|
||||
BLOCK_BELT_RIGHT,
|
||||
BLOCK_BELT_UP,
|
||||
BLOCK_BELT_DOWN,
|
||||
|
||||
ENTITY_IRON_ORE = EFD_ID(EFD_TYPE_ITEM),
|
||||
ENTITY_IRON_INGOT,
|
||||
ENTITY_IRON_PLATE,
|
||||
ENTITY_SCREW,
|
||||
ENTITY_BELT,
|
||||
|
||||
ENTITY_FIR_TREE = EFD_ID(EFD_TYPE_OBJECT),
|
||||
ENTITY_OAK_TREE,
|
||||
|
||||
ENTITY_CHEST = EFD_ID(EFD_TYPE_DEVICE),
|
||||
ENTITY_FURNACE,
|
||||
ENTITY_CRAFTBENCH,
|
||||
ENTITY_ASSEMBLER,
|
||||
|
||||
ENTITY_MONSTER = EFD_ID(EFD_TYPE_MOB),
|
||||
ENTITY_RABBIT,
|
||||
ENTITY_BOAR,
|
||||
ENTITY_BIZON,
|
||||
ENTITY_BEAR,
|
||||
|
||||
ENTITY_TRUCK = EFD_ID(EFD_TYPE_VEHICLE),
|
||||
ENTITY_CAR,
|
||||
|
||||
ENTITY_PLAYER = EFD_ID(EFD_TYPE_PLAYER),
|
||||
};
|
||||
|
||||
efd_result init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result systems(efd_world *w) {
|
||||
// ECS_SYSTEM(w, Move, EcsOnUpdate, Position, [in] Velocity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result update() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result render(efd_entity_type type) {
|
||||
// switch (type) {
|
||||
// case ENTITY_PLAYER:
|
||||
// /* additional/replacable rendering code on top of what EFD provides for built-in types */
|
||||
// efd_render_texture(ENTITY_PLAYER, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
// return 1; /* we handled the rendering, don't render with the default renderer */
|
||||
// break;
|
||||
|
||||
// case ENTITY_MONSTER:
|
||||
// /* our custom rendering code for monster */
|
||||
// efd_render_texture(ENTITY_MONSTER, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
// break;
|
||||
|
||||
// case ENTITY_WEAPON:
|
||||
// /* our custom rendering code for weapon */
|
||||
// break;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result player_join(efd_entid player) {
|
||||
// efd_notify_push(player, "Test", "Welcome to the game!", 5.0f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result player_leave(efd_entid player) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result cleanup() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result chest_spawn(efd_entid id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_result furnace_spawn(efd_entid id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
efd_app_desc efd_main() {
|
||||
return (efd_app_desc){
|
||||
.name = "Survival",
|
||||
.debug_ui = true,
|
||||
|
||||
/* these are defaults, with zpl_option/config files overrides */
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.fullscreen = 0,
|
||||
.vsync = 1,
|
||||
|
||||
/* these are code overrides for zpl_option flags (not defaults) */
|
||||
.server_only = false,
|
||||
.viewer_only = false,
|
||||
.viewer_amount = 1,
|
||||
.world_seed = 0,
|
||||
.world_seed_random = true,
|
||||
|
||||
/* primary callbacks */
|
||||
.init_cb = init,
|
||||
.system_cb = systems,
|
||||
.update_cb = update,
|
||||
.render_cb = render,
|
||||
.player_join_cb = player_join,
|
||||
.player_leave_cb = player_leave,
|
||||
.cleanup_cb = cleanup,
|
||||
|
||||
.rules = {
|
||||
.item_pickup_radius = 25.0f,
|
||||
.item_merge_radius = 75.0f,
|
||||
.item_drop_radius = 15.0f,
|
||||
.item_attract_radius = 75.0f,
|
||||
.item_attract_force = 0.1f,
|
||||
},
|
||||
|
||||
.assets = (efd_asset[]){
|
||||
{EFD_TEXTURE, TILE_GRASS, "assets/grass.png", EFD_FLAG_ATLAS | EFD_FLAG_RANDOM, .atlas = {4, 1}},
|
||||
{EFD_TEXTURE, TILE_DIRT, "assets/dirt.png", EFD_FLAG_ATLAS | EFD_FLAG_RANDOM, .atlas = {4, 1}},
|
||||
{EFD_TEXTURE, TILE_LAVA, "assets/lava.png", EFD_FLAG_ATLAS | EFD_FLAG_LOOPED, .atlas = {4, 1}},
|
||||
{EFD_TEXTURE, TILE_WATER, "assets/water.png", EFD_FLAG_ATLAS | EFD_FLAG_RANDOM | EFD_FLAG_LOOPED, .atlas = {4, 1}},
|
||||
|
||||
{EFD_TEXTURE, ENTITY_OAK_TREE, "assets/tree.png"},
|
||||
{EFD_TEXTURE, ENTITY_CHEST, "assets/chest.png"},
|
||||
{EFD_TEXTURE, ENTITY_FURNACE, "assets/furnace.png"},
|
||||
|
||||
{EFD_TEXTURE, ENTITY_PLAYER, "assets/player.png", EFD_FLAG_ATLAS | EFD_FLAG_COMPLEX},
|
||||
{EFD_TEXTURE, ENTITY_MONSTER, "assets/monster.png"},
|
||||
|
||||
/* animations */
|
||||
{EFD_ANIMATION, ENTITY_PLAYER, "assets/player.anim"},
|
||||
|
||||
/* sounds */
|
||||
{EFD_SOUND, ENTITY_PLAYER, "assets/player.wav"},
|
||||
|
||||
{EFD_END},
|
||||
},
|
||||
|
||||
.tiles = (efd_tile[]){
|
||||
{TILE_AIR},
|
||||
{TILE_DIRT, .drag = 1.0f, .friction = 1.0f},
|
||||
{TILE_GRASS, .drag = 1.0f, .friction = 1.0f},
|
||||
{TILE_WATER, .drag = 0.11f , .friction = 10.0f},
|
||||
{TILE_LAVA, EFD_FLAG_HAZARD, .drag = 6.2f , .friction = 40.0f},
|
||||
|
||||
{EFD_END},
|
||||
},
|
||||
|
||||
.blocks = (efd_block[]){
|
||||
{BLOCK_AIR},
|
||||
{BLOCK_HILL, EFD_FLAG_COLLISION},
|
||||
{BLOCK_HILL_SNOW, EFD_FLAG_COLLISION},
|
||||
{BLOCK_WOOD, EFD_FLAG_COLLISION, .bounce = 0.0f},
|
||||
|
||||
{BLOCK_WALL_LEFT, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
{BLOCK_WALL_RIGHT, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
{BLOCK_WALL_UP, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
{BLOCK_WALL_DOWN, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
|
||||
{BLOCK_FENCE_LEFT, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
{BLOCK_FENCE_RIGHT, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
{BLOCK_FENCE_UP, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
{BLOCK_FENCE_DOWN, EFD_FLAG_COLLISION, .bounce = 1.0f},
|
||||
|
||||
{BLOCK_BELT_LEFT, .velx = -150.0f},
|
||||
{BLOCK_BELT_RIGHT, .velx = 150.0f},
|
||||
{BLOCK_BELT_UP, .vely = -150.0f},
|
||||
{BLOCK_BELT_DOWN, .vely = 150.0f},
|
||||
|
||||
{EFD_END},
|
||||
},
|
||||
|
||||
.entities = (efd_entity[]){
|
||||
{ENTITY_IRON_ORE, .stack = 32},
|
||||
{ENTITY_IRON_PLATE, .stack = 32},
|
||||
{ENTITY_SCREW, .stack = 256},
|
||||
|
||||
{ENTITY_OAK_TREE, EFD_FLAG_DESTROY_ON_COLLISION, .drop = (efd_item_list[]){
|
||||
{ENTITY_SCREW, 1},
|
||||
{EFD_END},
|
||||
}},
|
||||
|
||||
{ENTITY_CHEST, .spawn_cb = chest_spawn},
|
||||
{ENTITY_FURNACE, .spawn_cb = furnace_spawn},
|
||||
|
||||
{ENTITY_MONSTER, .health = 256},
|
||||
{ENTITY_TRUCK},
|
||||
{ENTITY_PLAYER},
|
||||
|
||||
{EFD_END},
|
||||
},
|
||||
|
||||
.crafting = (efd_craft[]){
|
||||
{
|
||||
.producer = ENTITY_FURNACE,
|
||||
.ticks = 20,
|
||||
.input = (efd_item_list[]){
|
||||
{ENTITY_IRON_ORE, 1},
|
||||
{EFD_END},
|
||||
},
|
||||
.output = (efd_item_list[]){
|
||||
{ENTITY_IRON_PLATE, 4},
|
||||
{EFD_END},
|
||||
},
|
||||
},
|
||||
{
|
||||
.producer = ENTITY_CRAFTBENCH,
|
||||
.ticks = 40,
|
||||
.input = (efd_item_list[]){
|
||||
{ENTITY_IRON_PLATE, 1},
|
||||
{EFD_END},
|
||||
},
|
||||
.output = (efd_item_list[]){
|
||||
{ENTITY_SCREW, 8},
|
||||
{EFD_END},
|
||||
},
|
||||
},
|
||||
{
|
||||
.producer = ENTITY_ASSEMBLER,
|
||||
.ticks = 120,
|
||||
.input = (efd_item_list[]){
|
||||
{ENTITY_SCREW, 4},
|
||||
{ENTITY_IRON_PLATE, 2},
|
||||
{EFD_END},
|
||||
},
|
||||
.output = (efd_item_list[]){
|
||||
{ENTITY_BELT, 1},
|
||||
{EFD_END},
|
||||
},
|
||||
},
|
||||
|
||||
{EFD_END},
|
||||
},
|
||||
|
||||
.tooltips = (efd_tooltip[]){
|
||||
{"BLOCK_STONE", "It's a block of stone, what did you expect?"},
|
||||
{"BLOCK_BRICK", "It's a block of brick, what did you expect?"},
|
||||
{EFD_END},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// test.c
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void test(efd_entity_type type) { printf("type: %d\n", type); }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
zpl_opts opts={0};
|
||||
zpl_opts_init(&opts, zpl_heap(), argv[0]);
|
||||
efd_app_desc desc = efd_main();
|
||||
printf("value: %f\n", desc.rules.item_pickup_radius);
|
||||
printf("TILE_DIRT: %d\n", TILE_DIRT);
|
||||
printf("TILE_GRASS: %d\n", TILE_GRASS);
|
||||
printf("ENTITY_PLAYER: %d, is_valid type: %d\n", ENTITY_PLAYER, EFD_TYPE(ENTITY_PLAYER) == EFD_TYPE_PLAYER);
|
||||
printf("ENTITY_CHEST: %d, is_valid type: %d\n", ENTITY_CHEST, EFD_TYPE(ENTITY_CHEST) == EFD_TYPE_DEVICE);
|
||||
|
||||
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
|
||||
//zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
|
||||
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
|
||||
desc.init_cb();
|
||||
|
||||
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
|
||||
|
||||
if (!ok) {
|
||||
zpl_opts_print_errors(&opts);
|
||||
zpl_opts_print_help(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
|
||||
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
|
||||
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
|
||||
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
|
||||
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
|
||||
zpl_string host = zpl_opts_string(&opts, "host", NULL);
|
||||
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
|
||||
|
||||
game_kind play_mode = GAMEKIND_SINGLE;
|
||||
|
||||
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
|
||||
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "random-seed")) {
|
||||
zpl_random rnd={0};
|
||||
zpl_random_init(&rnd);
|
||||
seed = zpl_random_gen_u32(&rnd);
|
||||
zpl_printf("Seed: %u\n", seed);
|
||||
}
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "preview-map")) {
|
||||
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sighandler_register();
|
||||
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
|
||||
game_setup_ecs();
|
||||
game_run();
|
||||
|
||||
game_shutdown();
|
||||
sighandler_unregister();
|
||||
|
||||
zpl_string_free(host);
|
||||
zpl_opts_free(&opts);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
#define ZPL_IMPL
|
||||
#include "zpl.h"
|
||||
#include "platform/system.h"
|
||||
#include "core/game.h"
|
||||
#include "game.h"
|
||||
#include "models/entity.h"
|
||||
#include "world/entity_view.h"
|
||||
#include "utils/options.h"
|
||||
#include "platform/signal_handling.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
#include "flecs.h"
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
|
||||
#include "models/components.h"
|
||||
#include "systems/systems.h"
|
||||
|
||||
#include "platform/arch.h"
|
||||
|
||||
ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0)
|
||||
#include "tinyc2.h"
|
||||
ZPL_DIAGNOSTIC_POP
|
||||
|
||||
#define DEFAULT_WORLD_SEED 302097
|
||||
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
|
||||
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
|
||||
|
||||
/*
|
||||
TODO
|
||||
- monster spawner
|
||||
- the longer we survive, the more and stronger enemies we spawn
|
||||
- player grows HP by leveling up
|
||||
- XP increases by killing mobs
|
||||
- player can pick an "ability" upon reaching level milestones
|
||||
- abilities: armor/shield, TODO ...
|
||||
- enemies damage player when close to him in ticks (damage effects, ...)
|
||||
- basic projectile pooling (flecs)
|
||||
- somewhat believable world gen, small hamlets with cols, etc
|
||||
*/
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
zpl_opts opts={0};
|
||||
zpl_opts_init(&opts, zpl_heap(), argv[0]);
|
||||
|
||||
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
|
||||
//zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
|
||||
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
|
||||
|
||||
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
|
||||
|
||||
if (!ok) {
|
||||
zpl_opts_print_errors(&opts);
|
||||
zpl_opts_print_help(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
|
||||
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
|
||||
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
|
||||
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
|
||||
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
|
||||
zpl_string host = zpl_opts_string(&opts, "host", NULL);
|
||||
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
|
||||
|
||||
game_kind play_mode = GAMEKIND_SINGLE;
|
||||
|
||||
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
|
||||
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "random-seed")) {
|
||||
zpl_random rnd={0};
|
||||
zpl_random_init(&rnd);
|
||||
seed = zpl_random_gen_u32(&rnd);
|
||||
zpl_printf("Seed: %u\n", seed);
|
||||
}
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "preview-map")) {
|
||||
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sighandler_register();
|
||||
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
|
||||
game_setup_ecs();
|
||||
game_run();
|
||||
|
||||
game_shutdown();
|
||||
sighandler_unregister();
|
||||
|
||||
zpl_string_free(host);
|
||||
zpl_opts_free(&opts);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
## Foundation:
|
||||
* platform
|
||||
* viewer system ??
|
||||
* camera
|
||||
* game
|
||||
* debug ui
|
||||
* packet utils
|
||||
* arch
|
||||
* input
|
||||
* profiler
|
||||
* renderer
|
||||
* signal handling
|
||||
* zpl options
|
||||
* gen/textgen -> assets
|
||||
* items
|
||||
* inventory
|
||||
* crafting
|
||||
* notifications
|
||||
* tooltips
|
||||
* chunk
|
||||
* blocks
|
||||
* tiles (and chunk baker)
|
||||
* systems (core systems)
|
||||
* components
|
||||
* net
|
||||
* packets (but add custom messaging, and security)
|
||||
* compression
|
||||
* world
|
||||
* wrold_view
|
||||
* entity_view
|
||||
|
||||
|
||||
## Components
|
||||
-------
|
||||
* app - thing that runs game
|
||||
* game - the game stuff, includes client and server
|
||||
* packet - structure that has data written/read by client/server
|
||||
* asset - structure that describes tile/block/object/entity, something that can be visualized
|
||||
* module - a thing that uses a set of ecs components and systems to create a self-contained ecs module
|
||||
------------
|
||||
* world - a map of chunks within the game world
|
||||
* world-view - a representation of the world recreated by the client
|
||||
----------
|
||||
* chunk - entity that contains set of tiles and blocks
|
||||
* tile - basic thing that makes up the chunks
|
||||
* block - 2nd level of things that make up the chunk
|
||||
* entity - an grid-independant static or dynamic entity that can exist in the world and has some systems controlling it
|
||||
primary archetypes:
|
||||
* item - an entity in the world, that can have a different state when its picked up
|
||||
* object - an item that can be placed in the world
|
||||
* device - an object that can be interacted with
|
||||
* mob - an entity that can be controlled by ai
|
||||
* player - an entity that can be controlled by a player
|
||||
* vehicle - an entity that can be used to transport other entities
|
||||
* craft - a recipe that can be used to craft an item
|
||||
|
||||
|
||||
## Naming
|
||||
|
||||
* zpl.eco
|
||||
* foundation
|
||||
* sandbox
|
||||
* survival
|
||||
* prefix: efd_
|
||||
|
||||
## Concepts
|
||||
* tile
|
||||
* block
|
||||
* entity
|
||||
* item
|
||||
* object
|
||||
* device
|
||||
* mob
|
||||
* player
|
||||
* vehicle
|
||||
* craft
|
||||
|
||||
## Transitions
|
||||
* item -> tile (item destroyed, tile replaced)
|
||||
* item -> block (item destroyed, block created)
|
||||
* item -> entity (item hidden and untracked, entity component added) // item becomes entity, just changes state
|
||||
* item -> item (crafting) (item destroyed, item created)
|
||||
* tile -> item (tile replaced, item created)
|
||||
* block -> item (block destroyed, item created)
|
||||
* block -> block (crafting) (block destroyed, block created)
|
||||
* entity -> item (entity component removed, item shown and tracked) // entity becomes item, just changes state
|
||||
|
||||
## Features
|
||||
* In-memory lists
|
||||
* assets
|
||||
* items
|
||||
* crafting recepies
|
||||
* prafabs for entities (pipeline for entities)
|
||||
* built in server->client RPC
|
||||
*
|
||||
|
||||
|
||||
|
||||
// // register game specific input bindings
|
||||
// // pre-defined bindings and controlsets
|
||||
// efd_controlset_apply(EFD_ACTION_MOVE, EFD_CONTROLSET_WASD | EFD_CONTROLSET_ARROWS | EFD_CONTROLSET_GAMEPAD_LEFT);
|
||||
// efd_controlset_apply(EFD_ACTION_POINT, EFD_CONTROLSET_MOUSE | EFD_CONTROLSET_GAMEPAD_RIGHT);
|
||||
|
||||
// // custom bindings and controlsets
|
||||
// efd_controlset_keyboard(CONTROLSET_ACCELERATE, EFD_KEY_DOWN, EFD_KEY_SHIFT_LEFT | EFD_KEY_SHIFT_RIGHT);
|
||||
// efd_controlset_gamepad(CONTROLSET_ACCELERATE, EFD_GAMEPAD_LEFT_TRIGGER, 0.5f);
|
||||
// efd_controlset_apply(EFD_ACTION_SPRINT, CONTROLSET_ACCERLATE);
|
||||
|
||||
// // custom input bindings for custom actions
|
||||
// efd_controlset_register(ACTION_USE);
|
||||
// efd_controlset_keyboard(CONTROLSET_USE, EFD_KEY_DOWN, EFD_KEY_E);
|
||||
// efd_controlset_gamepad(CONTROLSET_USE, EFD_GAMEPAD_BUTTON_A, 0.5f);
|
||||
// efd_controlset_apply(ACTION_USE, CONTROLSET_USE);
|
Loading…
Reference in New Issue