From 3b9e3afd449facf5c98ffee50247c80e293f8545 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Sat, 16 Dec 2017 16:45:46 +0100 Subject: Start adding decorations. --- src/common.hpp | 10 +++---- src/game/assets.cpp | 4 +++ src/game/decos.cpp | 56 ++++++++++++++++++++++++++++++++++++ src/game/game.cpp | 1 + src/game/game.hpp | 27 ++++++++++++++++-- src/game/worldgen.cpp | 78 ++++++++++++++++++++++++++++++++++++++------------- src/render.cpp | 9 ++---- src/world.cpp | 9 +----- 8 files changed, 152 insertions(+), 42 deletions(-) create mode 100644 src/game/decos.cpp (limited to 'src') diff --git a/src/common.hpp b/src/common.hpp index 1ae3595..f543ca5 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -95,7 +95,6 @@ namespace world { class world_t { procgen::prng_t prng; - procgen::perlin_noise_t perlin; std::map sectors; @@ -106,7 +105,10 @@ namespace world { friend render::state_t; public: - void (*generator)(tile_t*, tile_index_t, procgen::perlin_noise_t*) = 0; + procgen::perlin_noise_t perlin; + + void (*generator)(world_t *world, sector_index_t index, sector_t *sector, void *data) = 0; + void *generator_data = 0; world_t(void); @@ -311,10 +313,8 @@ namespace render { class state_t { sf::RenderWindow *window; - procgen::prng_t prng; - procgen::perlin_noise_t perlin; - void render_sector(world::sector_t *sector); + void render_sector(world::world_t *world, world::sector_t *sector); void drender_text(rectf_t rect, std::string str); void drender_entity(world::entity_t *ent); public: diff --git a/src/game/assets.cpp b/src/game/assets.cpp index 2f913ba..a908962 100644 --- a/src/game/assets.cpp +++ b/src/game/assets.cpp @@ -5,6 +5,7 @@ namespace game::assets { human_assets_t human; alien_assets_t alien; fx_assets_t fx; +deco_assets_t deco; void load(void) { @@ -22,6 +23,9 @@ void load(void) fx.blood.load("assets/units/blood_", 4); + deco.stone.load("assets/deco/stone_", 1); + deco.eyething.load("assets/deco/eyething_", 2); + world::register_tile(TILE_DIRT, 0); render::register_tile(TILE_DIRT, "assets/tiles/dirt.png"); world::register_tile(TILE_STONE, CF_SOLID); diff --git a/src/game/decos.cpp b/src/game/decos.cpp new file mode 100644 index 0000000..2307762 --- /dev/null +++ b/src/game/decos.cpp @@ -0,0 +1,56 @@ +#include "game.hpp" + +namespace game { + +static const struct { + render::animated_texture_t *texture; + v2f_t mins, maxs; + world::cflags_t cflags; + v2f_t render_mins, render_maxs; + double fps; +} decos[ ] = { + { + &assets::deco.stone, + {-0.4f, +0.1f}, {+0.4f, +0.4f}, CF_SOLID, + {-0.4f, -0.4f}, {+0.4f, +0.4f}, 0.0 + }, + { + &assets::deco.stone, + {-0.2f, +0.1f}, {+0.2f, +0.2f}, CF_SOLID, + {-0.2f, -0.2f}, {+0.2f, +0.2f}, 0.0 + }, + { + &assets::deco.eyething, + {-0.4f, +0.1f}, {+0.4f, +0.4f}, CF_SOLID, + {-0.4f, -1.2f}, {+0.4f, +0.4f}, 0.3 + } +}; + +deco_t::deco_t(game::state_t *game_, deco_type_t type_) : entity_t(ET_DECO) +{ + game = game_; + type = type_; +} + +void deco_t::spawn(world::world_t *world, v2f_t x) +{ + v2f_t center, offset; + + offset[0] = world->perlin.get(x, 0.17331f); + offset[1] = world->perlin.get(x, 0.19571f); + center = x + v2f_t(0.5f, 0.5f) + offset.norm() * 0.1; + + cmodel.bounds[0] = center + decos[type].mins; + cmodel.bounds[1] = center + decos[type].maxs; + cmodel.cflags = decos[type].cflags; + render_bounds[0] = center + decos[type].render_mins; + render_bounds[1] = center + decos[type].render_maxs; + link(world); +} +void deco_t::render_to(render::state_t *render) +{ + render->render(game->now * decos[type].fps + phase_shift, + decos[type].texture, render_bounds, sf::Color::White); +} + +} // namespace game diff --git a/src/game/game.cpp b/src/game/game.cpp index 3005bd5..993f450 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -10,6 +10,7 @@ void state_t::start(void) alien_t *alien; world.generator = worldgen; + world.generator_data = (void*)this; human = new human_t(this); human->place(&world, v2f_t(0.5, 0.5)); diff --git a/src/game/game.hpp b/src/game/game.hpp index 58892ff..e1eca84 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -3,7 +3,8 @@ namespace game { enum { ET_UNIT, - ET_EFFECT + ET_EFFECT, + ET_DECO }; enum { @@ -23,8 +24,7 @@ namespace game { extern size_t selection_cookie; - void worldgen(world::tile_t *tile, world::tile_index_t x, - procgen::perlin_noise_t *perlin); + void worldgen(world::world_t *world, world::sector_index_t index, world::sector_t *sector, void *data); namespace assets { typedef struct { @@ -43,9 +43,14 @@ namespace game { render::animated_texture_t blood; } fx_assets_t; + typedef struct { + render::animated_texture_t stone, eyething; + } deco_assets_t; + extern human_assets_t human; extern alien_assets_t alien; extern fx_assets_t fx; + extern deco_assets_t deco; void load(void); } @@ -176,4 +181,20 @@ namespace game { ~fx_blood_t(void) = default; void render_to(render::state_t *render); }; + + typedef enum { + DECO_STONE, + DECO_STONE_SMALL, + DECO_EYETHING + } deco_type_t; + + class deco_t : public world::entity_t { + game::state_t *game; + deco_type_t type; + public: + double phase_shift; + deco_t(game::state_t *game, deco_type_t type_); + void spawn(world::world_t *world, v2f_t x); + void render_to(render::state_t *render); + }; }; diff --git a/src/game/worldgen.cpp b/src/game/worldgen.cpp index 62c8a5e..74a07c7 100644 --- a/src/game/worldgen.cpp +++ b/src/game/worldgen.cpp @@ -2,28 +2,66 @@ namespace game { -void worldgen(world::tile_t *tile, world::tile_index_t x, - procgen::perlin_noise_t *perlin) +using namespace world; + +void add_decoration(world_t *world, state_t *game, v2f_t x, float noise) { - float waterlevel, height; - - waterlevel = perlin->get(x, 1000.0f) * 0.3f + - perlin->get(x, 500.0f) * 0.1f; - - height = perlin->get(x, 40.0f) * 0.6f + - perlin->get(x, 20.0f) * 0.25f + - perlin->get(x, 10.0f) * 0.2f + - perlin->get(x, 4.0f) * 0.1f + - perlin->get(x, 1.0f) * 0.05f; - - if (height < waterlevel) - tile->type = TILE_WATER; - else if (height < waterlevel + 0.1) - tile->type = TILE_DIRT; - else if (perlin->get(x, 3.0f) > 0.0f) - tile->type = TILE_STONE; + deco_t *deco; + deco_type_t type; + + if (noise < 0.3) + return; + + if (noise > 0.45) + type = DECO_EYETHING; + else if (noise > 0.35) + type = DECO_STONE; else - tile->type = TILE_DIRT; + type = DECO_STONE_SMALL; + + deco = new deco_t(game, type); + deco->spawn(world, x); + deco->phase_shift = noise * 500.0; +} + +void worldgen(world_t *world, sector_index_t index, sector_t *sector, void *data) +{ + state_t *game = (game::state_t*)data; + + for (coord_t ly = 0; ly < SECTOR_SIZE; ly++) + for (coord_t lx = 0; lx < SECTOR_SIZE; lx++) { + tile_t *tile = sector->tiles + ly * SECTOR_SIZE + lx; + tile_index_t tile_index(index[0] * SECTOR_SIZE + lx, + index[1] * SECTOR_SIZE + ly); + v2f_t x; + float waterlevel, height; + float deco_noise; + + x = v2f_t(index) * SECTOR_SIZE + v2f_t(lx, ly); + + waterlevel = world->perlin.get(x, 1000.0f) * 0.3f + + world->perlin.get(x, 500.0f) * 0.1f; + + height = world->perlin.get(x, 40.0f) * 0.6f + + world->perlin.get(x, 20.0f) * 0.25f + + world->perlin.get(x, 10.0f) * 0.2f + + world->perlin.get(x, 4.0f) * 0.1f + + world->perlin.get(x, 1.0f) * 0.05f; + + if (height < waterlevel) + tile->type = TILE_WATER; + else if (height < waterlevel + 0.1) + tile->type = TILE_DIRT; + else if (world->perlin.get(x, 3.0f) > 0.0f) + tile->type = TILE_STONE; + else + tile->type = TILE_DIRT; + + deco_noise = world->perlin.get(x, 0.125559f); + + if (tile->type == TILE_DIRT) + add_decoration(world, game, x, deco_noise); + } } } diff --git a/src/render.cpp b/src/render.cpp index 2e8447b..9dfa12b 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -10,9 +10,6 @@ state_t::state_t(sf::RenderWindow *window_) window = window_; font.loadFromFile("assets/FanwoodText.otf"); - - prng.seed(396); - perlin.generate(&prng, 16); } // FIXME: rename @@ -95,7 +92,7 @@ static void generate_tile_verts(sf::Vertex *verts, v2f_t tx, procgen::perlin_noi } } -void state_t::render_sector(world::sector_t *sector) +void state_t::render_sector(world::world_t *world, world::sector_t *sector) { for (ssize_t y = 0; y < SECTOR_SIZE; y++) for (ssize_t x = 0; x < SECTOR_SIZE; x++) { @@ -114,7 +111,7 @@ void state_t::render_sector(world::sector_t *sector) } sf::RenderStates states(texture); - generate_tile_verts(verts, tx, &perlin); + generate_tile_verts(verts, tx, &world->perlin); window->draw(verts, 8, sf::TrianglesFan, states); if (debug_draw_tile_coords) { @@ -156,7 +153,7 @@ void state_t::render(game::state_t *game) bbox[1] += margin; for (world::sector_t *sector : game->world.get_sectors(bbox)) - render_sector(sector); + render_sector(&game->world, sector); ents = game->world.get_render_entities(bbox); ents.sort( diff --git a/src/world.cpp b/src/world.cpp index 46dcde5..1975b4e 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -34,15 +34,8 @@ void world_t::generate(sector_t *sector, sector_index_t index, bool partial) sector->bounds.v[0] = (v2f_t)index * SECTOR_SIZE; sector->bounds.v[1] = sector->bounds.v[0] + v2f_t(SECTOR_SIZE, SECTOR_SIZE); - for (coord_t ly = 0; ly < SECTOR_SIZE; ly++) - for (coord_t lx = 0; lx < SECTOR_SIZE; lx++) { - tile_t *tile = sector->tiles + ly * SECTOR_SIZE + lx; - tile_index_t tile_index(index[0] * SECTOR_SIZE + lx, - index[1] * SECTOR_SIZE + ly); - generator(tile, tile_index, &perlin); - } - sector->empty = false; + generator(this, index, sector, generator_data); if (partial) return; -- cgit