code: removed minimal 3d

isolation
Vladyslav Hrytsenko 2022-09-28 23:03:21 +03:00
parent 645111b53c
commit 8a12661689
8 changed files with 0 additions and 835 deletions

View File

@ -1,3 +1,2 @@
add_subdirectory(sandbox) add_subdirectory(sandbox)
add_subdirectory(minimal) add_subdirectory(minimal)
add_subdirectory(minimal_3d)

View File

@ -1,14 +0,0 @@
add_executable(minimal-3d
src/main.c
src/platform.c
src/worldgen.c
src/texgen.c
src/rules.c
)
target_compile_definitions(minimal-3d PRIVATE CLIENT)
include_directories(src ../../foundation/src ../../../art/gen)
target_link_libraries(minimal-3d eco2d-foundation)
target_compile_options(minimal-3d PRIVATE -Werror -Wall -Wextra -Wno-unused-function -Wno-unknown-pragmas -Wno-unused-variable -Wno-unused-parameter)
link_system_libs(minimal-3d)

View File

@ -1,120 +0,0 @@
#define ZPL_IMPL
#include "zpl.h"
#include "platform/system.h"
#include "core/game.h"
#include "ents/entity.h"
#include "world/entity_view.h"
#include "utils/options.h"
#include "platform/signal_handling.h"
#include "platform/profiler.h"
#include "flecs/flecs.h"
#include "flecs/flecs_os_api_stdcpp.h"
#include "ecs/components.h"
#include "ecs/systems.h"
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
void UpdateDrawFrame(void);
#endif
#define DEFAULT_WORLD_SEED 302097
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
#define DEFAULT_WORLD_SIZE 32 /* 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);
#if !defined(PLATFORM_WEB)
while (game_is_running()) {
reset_cached_time();
profile (PROF_MAIN_LOOP) {
game_input();
game_update();
game_render();
}
profiler_collate();
}
#else
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#endif
game_shutdown();
sighandler_unregister();
zpl_string_free(host);
zpl_opts_free(&opts);
return 0;
}
#if defined(PLATFORM_WEB)
void UpdateDrawFrame(void) {
reset_cached_time();
profile (PROF_MAIN_LOOP) {
game_input();
game_update();
game_render();
}
profiler_collate();
}
#endif
static float temp_time = 0.0f;
float get_cached_time(void) {
return temp_time;
}
void reset_cached_time(void) {
temp_time = zpl_time_rel();
}

View File

@ -1,190 +0,0 @@
#include "platform/platform.h"
#include "raylib.h"
#include "raymath.h"
#include "net/network.h"
#include "core/game.h"
#include "world/entity_view.h"
#include "world/prediction.h"
#include "core/camera.h"
#include "math.h"
#include "world/blocks.h"
#include "gen/assets.h"
#include "platform/profiler.h"
#include "debug/debug_ui.h"
#include "utils/raylib_helpers.h"
#if defined(PLATFORM_WEB)
#include <emscripten.h>
EM_JS(int, canvas_get_width, (), {
return canvas.width;
});
EM_JS(int, canvas_get_height, (), {
return canvas.height;
});
#endif
static uint16_t screenWidth = 1024;
static uint16_t screenHeight = 768;
static float target_zoom = 0.6f;
static bool request_shutdown;
#include "renderer.c"
bool inv_is_open = false;
void platform_init() {
SetTraceLogLevel(LOG_ERROR);
#if defined(PLATFORM_WEB)
screenWidth = (uint16_t)canvas_get_width();
screenHeight = (uint16_t)canvas_get_height();
#endif
InitWindow(screenWidth, screenHeight, "eco2d");
SetWindowState(/*FLAG_WINDOW_UNDECORATED|*/FLAG_WINDOW_MAXIMIZED|FLAG_WINDOW_RESIZABLE|FLAG_MSAA_4X_HINT);
#if !defined(PLATFORM_WEB)
screenWidth = (uint16_t)GetScreenWidth();
screenHeight = (uint16_t)GetScreenHeight();
#endif
renderer_init();
}
void platform_shutdown() {
renderer_shutdown();
CloseWindow();
}
uint8_t platform_is_running() {
return !WindowShouldClose();
}
static game_keystate_data last_input_data = {0};
inline static
void platform_input_update_input_frame(game_keystate_data data) {
// NOTE(zaklaus): Test if there are any changes
if (data.x != last_input_data.x) goto send_data;
if (data.y != last_input_data.y) goto send_data;
if (data.use != last_input_data.use) goto send_data;
if (data.sprint != last_input_data.sprint) goto send_data;
if (data.ctrl != last_input_data.ctrl) goto send_data;
return;
send_data:
last_input_data = data;
game_action_send_keystate(&data);
}
void platform_input() {
float mouse_z = (GetMouseWheelMove()*0.5f);
float mouse_modified = target_zoom < 4 ? mouse_z / (zpl_exp(4 - (target_zoom))) : mouse_z;
if (mouse_z != 0.0f) {
target_zoom = zpl_clamp(target_zoom + mouse_modified, 0.1f, 11.0f);
}
// NOTE(zaklaus): keystate handling
{
float x=0.0f, y=0.0f;
uint8_t use, sprint, drop, ctrl, pick;
if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) x += 1.0f;
if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) x -= 1.0f;
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) y += 1.0f;
if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) y -= 1.0f;
use = IsKeyPressed(KEY_SPACE);
sprint = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
ctrl = IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL);
// NOTE(zaklaus): NEW! mouse movement
Vector2 mouse_pos = GetMousePosition();
mouse_pos.x /= screenWidth;
mouse_pos.y /= screenHeight;
mouse_pos.x -= 0.5f;
mouse_pos.y -= 0.5f;
mouse_pos = Vector2Normalize(mouse_pos);
if (game_get_kind() == GAMEKIND_SINGLE && IsMouseButtonDown(MOUSE_MIDDLE_BUTTON)) {
x = mouse_pos.x;
y = -mouse_pos.y;
}
game_keystate_data in_data = {
.x = x,
.y = y,
.mx = mouse_pos.x,
.my = mouse_pos.y,
.use = use,
.sprint = sprint,
.ctrl = ctrl,
};
platform_input_update_input_frame(in_data);
}
}
void platform_render() {
#if !defined(PLATFORM_WEB)
screenWidth = (uint16_t)GetScreenWidth();
screenHeight = (uint16_t)GetScreenHeight();
#else
uint16_t newScreenWidth = (uint16_t)canvas_get_width();
uint16_t newScreenHeight = (uint16_t)canvas_get_height();
if (newScreenWidth != screenWidth || newScreenHeight != screenHeight) {
screenWidth = newScreenWidth;
screenHeight = newScreenHeight;
SetWindowSize(screenWidth, screenHeight);
}
#endif
profile(PROF_ENTITY_LERP) {
game_world_view_active_entity_map(lerp_entity_positions);
game_world_view_active_entity_map(do_entity_fadeinout);
}
assets_frame();
BeginDrawing();
{
profile (PROF_RENDER) {
renderer_draw();
}
}
EndDrawing();
if (request_shutdown) {
CloseWindow();
}
}
float platform_frametime() {
return GetFrameTime();
}
float platform_zoom_get(void) {
return target_zoom;
}
void platform_request_close(void) {
request_shutdown = true;
}
void platform_get_block_realpos(float *x, float *y){
camera cam = camera_get();
Vector2 mpos = GetMousePosition();
entity_view *e = game_world_view_active_get_entity(cam.ent_id);
if (!e) return;
float zoom = renderer_zoom_get();
mpos.x -= screenWidth/2.0f;
mpos.y -= screenHeight/2.0f;
cam.x += mpos.x*(1.0f/zoom);
cam.y += mpos.y*(1.0f/zoom);
cam.x = ((int32_t)cam.x / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE;
cam.y = ((int32_t)cam.y / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE;
cam.x += WORLD_BLOCK_SIZE/2.0f;
cam.y += WORLD_BLOCK_SIZE/2.0f;
if (x) *x = (float)cam.x;
if (y) *y = (float)cam.y;
}

View File

@ -1,153 +0,0 @@
static Camera3D render_camera;
static float cam_zoom = 1.5f;
float zpl_lerp(float,float,float);
float zpl_to_degrees(float);
void DEBUG_draw_ground(uint64_t key, entity_view * data) {
switch (data->kind) {
case EKIND_CHUNK: {
world_view *view = game_world_view_get_active();
float size = (float)(view->chunk_size * WORLD_BLOCK_SIZE);
float half_size = size / 2.0f;
float half_block_size = (float)(WORLD_BLOCK_SIZE >> 1);
int16_t offset = 0;
float x = data->x * size + offset;
float y = data->y * size + offset;
RenderTexture2D tex = GetChunkTexture(key);
DrawCubeTexture(tex.texture, (Vector3){x+half_size, 0.0f, y+half_size}, size, 0.01f, size, WHITE);
for (size_t ty = 0; ty < view->chunk_size; ty++) {
for (size_t tx = 0; tx < view->chunk_size; tx++) {
block_id blk_id = data->outer_blocks[(ty*view->chunk_size)+tx];
if (blk_id != 0) {
DrawCubeTexture(GetBlockImage(blk_id), (Vector3){x + tx*WORLD_BLOCK_SIZE+half_block_size, 32.0f, y + ty*WORLD_BLOCK_SIZE+half_block_size}, 64, 0.01f, 64, WHITE);
}
}
}
for (int by = 0; by < 16; by++) {
for (int bx = 0; bx < 16; bx++) {
switch (blocks_get_flags(data->blocks[by*16+bx])) {
case BLOCK_FLAG_COLLISION:{
DrawCubeWires((Vector3){x + bx*WORLD_BLOCK_SIZE+half_block_size, 34.f, y + by*WORLD_BLOCK_SIZE+half_block_size}, 64, 66, 64, BLUE);
}break;
case BLOCK_FLAG_HAZARD:{
DrawCubeWires((Vector3){x + bx*WORLD_BLOCK_SIZE+half_block_size, 16.667f, y + by*WORLD_BLOCK_SIZE+half_block_size}, 64, 33, 64, RED);
}break;
}
}
}
}break;
default:break;
}
}
void DEBUG_draw_entities(uint64_t key, entity_view * data) {
(void)key;
uint16_t size = 16;
uint16_t ground_offset = 30;
switch (data->kind) {
case EKIND_DEMO_NPC: {
float x = data->x;
float y = data->y;
DrawSphere((Vector3){x,ground_offset,y}, size, ColorAlpha(BLUE, data->tran_time));
}break;
case EKIND_PLAYER: {
float x = data->x;
float y = data->y;
DrawSphere((Vector3){x,ground_offset,y}, size, ColorAlpha(YELLOW, data->tran_time));
}break;
case EKIND_MACRO_BOT: {
float x = data->x;
float y = data->y;
DrawSphere((Vector3){x,ground_offset,y}, size, ColorAlpha(PURPLE, data->tran_time));
}break;
case EKIND_VEHICLE: {
float x = data->x;
float y = data->y;
float const w = 280;
float const h = 150;
EcoDrawCube((Vector3){x,15.0f,y}, w/2.0f, 10.f, h/2.0f, -zpl_to_degrees(data->heading), ColorAlpha(RED, data->tran_time));
}break;
case EKIND_CHUNK:break;
default:{
float x = data->x;
float y = data->y;
EcoDrawCube((Vector3){x, 15.0f, y}, 16, 16, 16, 0.0f, ColorAlpha(PINK, data->tran_time));
}break;
}
}
void renderer_draw(void) {
cam_zoom = zpl_min(zpl_lerp(cam_zoom, target_zoom, GetFrameTime()*2.18f), 9.98f);
camera_update();
camera game_camera = camera_get();
#if 1
render_camera.position = (Vector3){(float)game_camera.x, 260.0f*(10.0f-cam_zoom), (float)game_camera.y+50.0f*(10.0f-cam_zoom/2.0f)};
render_camera.target = (Vector3){(float)game_camera.x, 0.0f, (float)game_camera.y};
#else
UpdateCamera(&render_camera);
#endif
ClearBackground(GetColor(0x222034));
BeginMode3D(render_camera);
game_world_view_active_entity_map(DEBUG_draw_ground);
game_world_view_active_entity_map(DEBUG_draw_entities);
EndMode3D();
}
void renderer_init(void) {
render_camera.up = (Vector3){0.0f,0.0f,-1.0f};
render_camera.fovy = 45.f;
render_camera.projection = CAMERA_PERSPECTIVE;
#if 0
SetCameraMode(render_camera, CAMERA_ORBITAL);
render_camera.position = (Vector3){10,10,10};
render_camera.target = (Vector3){0};
#endif
// NOTE(zaklaus): Paint the screen before we load the game
// TODO(zaklaus): Render a cool loading screen background maybe? :wink: :wink:
BeginDrawing();
ClearBackground(GetColor(0x222034));
char const *loading_text = "zpl.eco2d (in 3d) is loading...";
int text_w = MeasureText(loading_text, 120);
DrawText(loading_text, GetScreenWidth()-text_w-15, GetScreenHeight()-135, 120, RAYWHITE);
EndDrawing();
blocks_setup();
assets_setup();
}
void renderer_shutdown(void) {
blocks_destroy();
assets_destroy();
}
void renderer_debug_draw(void) {
}
float renderer_zoom_get(void) {
return cam_zoom;
}
void renderer_draw_single(float x, float y, asset_id id, Color color) {
(void)color;
BeginMode3D(render_camera);
EcoDrawCube((Vector3){x, 15.0f, y}, 16, 16, 16, 0.0f, PINK);
EndMode3D();
}

View File

@ -1,5 +0,0 @@
#include "core/rules.h"
void rules_setup() {
}

View File

@ -1,76 +0,0 @@
#include "gen/texgen.h"
#include "world/world.h"
#include "zpl.h"
static inline
Texture2D LoadTexEco(const char *name) {
static char filename[128];
zpl_snprintf(filename, 128, "art/gen/%s.png", name);
return LoadTexture(filename);
}
static inline
Image LoadImageEco(const char *name) {
static char filename[128];
zpl_snprintf(filename, 128, "art/gen/%s.png", name);
return LoadImage(filename);
}
static inline
Texture2D Image2TexEco(Image image) {
Texture2D tex = LoadTextureFromImage(image);
UnloadImage(image);
return tex;
}
static inline
Texture2D GenColorEco(Color color) {
Image img = GenImageColor(1, 1, color);
return Image2TexEco(img);
}
Texture2D texgen_build_anim(asset_id id, int64_t counter) {
(void)counter;
switch (id) {
case ASSET_WATER: {
Image img = LoadImageEco("water");
ImageColorBrightness(&img, zpl_abs((counter % 64 - 32)*2));
return Image2TexEco(img);
}break;
default: return GenColorEco(PINK); break;
}
}
Texture2D texgen_build_sprite(asset_id id) {
switch (id) {
case ASSET_BLANK: return GenColorEco(WHITE); break;
case ASSET_BUILDMODE_HIGHLIGHT: return GenColorEco(WHITE); break;
// NOTE(zaklaus): items
case ASSET_DEMO_ICEMAKER: return LoadTexEco("demo_icemaker");
// NOTE(zaklaus): blocks
case ASSET_FENCE: return LoadTexEco("fence");
case ASSET_GROUND: return LoadTexEco("grass");
case ASSET_DIRT: return LoadTexEco("dirt");
case ASSET_WALL: return LoadTexEco("asphalt");
case ASSET_HILL_SNOW:
case ASSET_HILL: return LoadTexEco("rock");
case ASSET_LAVA: return LoadTexEco("lava");
case ASSET_WOOD: return LoadTexEco("wood");
case ASSET_TREE: return LoadTexEco("tree");
// case ASSET_WATER: return LoadTexEco("water");
case ASSET_BELT:
case ASSET_BELT_RIGHT: return LoadTexEco("belt_right");
case ASSET_BELT_LEFT: return LoadTexEco("belt_left");
case ASSET_BELT_UP: return LoadTexEco("belt_up");
case ASSET_BELT_DOWN: return LoadTexEco("belt_down");
// NOTE(zaklaus): devices
case ASSET_CHEST: return LoadTexEco("chest");
default: return GenColorEco(PINK); break;
}
}

View File

@ -1,276 +0,0 @@
#include "zpl.h"
#include <math.h>
#include <stdlib.h>
#include "world/world.h"
#include "world/blocks.h"
#include "world/perlin.h"
#include "ecs/components.h"
#include "ents/entity.h"
#include "ents/vehicle.h"
#include "ents/items.h"
#include "world/blocks_info.h"
#define WORLD_BLOCK_OBSERVER(name) block_id name(block_id *data, block_id id, uint32_t block_idx)
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
#define WORLD_PERLIN_FREQ 100
#define WORLD_PERLIN_OCTAVES 1
#define BLOCK_INVALID 0xF
block_id worldgen_biome_find(uint32_t biome, uint32_t kind) {
asset_id asset = ASSET_INVALID;
switch (biome) {
case BLOCK_BIOME_DEV: {
switch (kind) {
case BLOCK_KIND_GROUND: asset = ASSET_GROUND; break;
case BLOCK_KIND_DIRT: asset = ASSET_DIRT; break;
case BLOCK_KIND_WALL: asset = ASSET_WALL; break;
case BLOCK_KIND_HILL_SNOW:
case BLOCK_KIND_HILL: asset = ASSET_HILL; break;
case BLOCK_KIND_WATER: asset = ASSET_WATER; break;
case BLOCK_KIND_LAVA: asset = ASSET_LAVA; break;
}
}
}
return blocks_find(asset);
}
static world_data *world;
static void world_fill_rect(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
for (uint32_t cy=y; cy<y+h; cy++) {
for (uint32_t cx=x; cx<x+w; cx++) {
if (cx < 0 || cx >= world->dim) continue;
if (cy < 0 || cy >= world->dim) continue;
uint32_t i = (cy*world->dim) + cx;
if (proc) {
block_id new_id = (*proc)(data, id, i);
if (new_id != BLOCK_INVALID) {
id = new_id;
}
else continue;
}
data[i] = id;
}
}
}
static void world_fill_circle(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
for (uint32_t cy=y; cy<y+h; cy++) {
for (uint32_t cx=x; cx<x+w; cx++) {
if (cx < 0 || cx >= world->dim) continue;
if (cy < 0 || cy >= world->dim) continue;
uint32_t i = (cy*world->dim) + cx;
if (proc) {
block_id new_id = (*proc)(data, id, i);
if (new_id != BLOCK_INVALID) {
id = new_id;
}
else continue;
}
data[i] = id;
}
}
}
static void world_fill_rect_anchor(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) {
uint32_t w2 = (uint32_t)floorf(w*ax);
uint32_t h2 = (uint32_t)floorf(h*ay);
world_fill_rect(data, id, x-w2, y-h2, w, h, proc);
}
static WORLD_BLOCK_OBSERVER(shaper) {
uint32_t kind = id;
uint32_t old_kind = data[block_idx];
if (kind == BLOCK_KIND_WALL && kind == old_kind) {
return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL);
}
if (kind == BLOCK_KIND_HILL && kind == old_kind) {
return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL_SNOW);
}
return id;
}
static block_id world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) {
uint32_t x = block_idx % world->dim + ofx;
uint32_t y = block_idx / world->dim + ofy;
return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
}
static block_id world_perlin_cond(uint32_t block_idx, double chance) {
return world_perlin_cond_offset(block_idx, chance, 0, 0);
}
#if 1
static WORLD_BLOCK_OBSERVER(shaper_noise80) {
return world_perlin_cond(block_idx, 0.80) ? shaper(data, id, block_idx) : BLOCK_INVALID;
}
static WORLD_BLOCK_OBSERVER(shaper_noise50) {
return world_perlin_cond(block_idx, 0.50) ? shaper(data, id, block_idx) : BLOCK_INVALID;
}
static WORLD_BLOCK_OBSERVER(shaper_noise33) {
return world_perlin_cond(block_idx, 0.33) ? shaper(data, id, block_idx) : BLOCK_INVALID;
}
static WORLD_BLOCK_OBSERVER(shaper_noise05) {
return world_perlin_cond(block_idx, 0.05) ? shaper(data, id, block_idx) : BLOCK_INVALID;
}
static WORLD_BLOCK_OBSERVER(shaper_noise05b) {
return world_perlin_cond_offset(block_idx, 0.05, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID;
}
static WORLD_BLOCK_OBSERVER(shaper_noise01b) {
return world_perlin_cond_offset(block_idx, 0.01, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID;
}
#else
static WORLD_BLOCK_OBSERVER(shaper_noise80) {
return rand()%10 < 8 ? shaper(id, block_idx) : BLOCK_INVALID;
}
static WORLD_BLOCK_OBSERVER(shaper_noise50) {
return rand()%10 < 5 ? shaper(id, block_idx) : BLOCK_INVALID;
}
static WORLD_BLOCK_OBSERVER(shaper_noise33) {
return rand()%10 < 3 ? shaper(id, block_idx) : BLOCK_INVALID;
}
#endif
#if 0
static void world_fill_mountain(uint32_t x, uint32_t y) {
}
#endif
#define RAND_RANGE(x,y) (x + (int)rand()%(y-(x)))
#define RAND_RANGEF(x,y) ((float)RAND_RANGE(x,y))
int32_t worldgen_build(world_data *wld) {
// TODO(zaklaus): pass world as an arg instead
world = wld;
// TODO: perform world gen
// atm, we will fill the world with ground and surround it by walls
block_id wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
block_id grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
block_id dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT);
block_id watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
block_id lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA);
block_id tree_id = blocks_find(ASSET_TREE);
srand(world->seed);
// walls
world_fill_rect(world->data, wall_id, 0, 0, world->dim, world->dim, NULL);
// ground
world_fill_rect(world->data, grnd_id, 1, 1, world->dim-2, world->dim-2, NULL);
world_fill_rect(world->data, dirt_id, 1, 1, world->dim-2, world->dim-2, shaper_noise05);
world_fill_rect(world->outer_data, tree_id, 1, 1, world->dim-2, world->dim-2, shaper_noise01b);
// water
#if 1
for (int i=0; i<RAND_RANGE(58, 92); i++) {
world_fill_rect_anchor(world->data, watr_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), 4+RAND_RANGE(0,3), 4+RAND_RANGE(0,3), 0.5f, 0.5f, shaper_noise80);
}
#endif
// ice rink
#if 0
world_fill_rect_anchor(world->data, watr_id, 450, 125, 10, 10, 0.0f, 0.0f, NULL);
#endif
// lava
#if 1
for (int i=0; i<RAND_RANGE(48, 62); i++) {
world_fill_rect_anchor(world->data, lava_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), 4+RAND_RANGE(0,3), 4+RAND_RANGE(0,3), 0.5f, 0.5f, shaper_noise80);
}
#endif
// hills
#if 1
const uint32_t HILLS_SIZE = 21;
for (int i=0; i<RAND_RANGE(8, 124); i++) {
world_fill_rect_anchor(world->data, wall_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), RAND_RANGE(0,HILLS_SIZE), RAND_RANGE(0,HILLS_SIZE), 0.5f, 0.5f, shaper_noise50);
}
#endif
// vehicles
#if 1
for (int i=0; i<RAND_RANGE(258, 1124); i++) {
uint64_t e = vehicle_spawn();
Position *dest = ecs_get_mut(world_ecs(), e, Position);
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
entity_set_position(e, dest->x, dest->y);
}
#endif
// items
#if 1
for (int i=0; i<RAND_RANGE(328, 164); i++) {
uint64_t e = item_spawn(ASSET_DEMO_ICEMAKER, 32);
Position *dest = ecs_get_mut(world_ecs(), e, Position);
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
entity_set_position(e, dest->x, dest->y);
}
for (int i=0; i<RAND_RANGE(328, 164); i++) {
uint64_t e = item_spawn(ASSET_FENCE, 64);
Position *dest = ecs_get_mut(world_ecs(), e, Position);
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
entity_set_position(e, dest->x, dest->y);
}
for (int i=0; i<RAND_RANGE(328, 164); i++) {
uint64_t e = item_spawn(ASSET_WOOD, 64);
Position *dest = ecs_get_mut(world_ecs(), e, Position);
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
entity_set_position(e, dest->x, dest->y);
}
for (int i=0; i<RAND_RANGE(128, 564); i++) {
uint64_t e = item_spawn(ASSET_BELT, 999);
Position *dest = ecs_get_mut(world_ecs(), e, Position);
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
entity_set_position(e, dest->x, dest->y);
}
for (int i=0; i<RAND_RANGE(128, 964); i++) {
uint64_t e = item_spawn(ASSET_CHEST, 4);
Position *dest = ecs_get_mut(world_ecs(), e, Position);
dest->x = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE);
entity_set_position(e, dest->x, dest->y);
}
#endif
return WORLD_ERROR_NONE;
}