From: Daniel Karbach Date: Tue, 6 Oct 2015 15:21:52 +0000 (+0200) Subject: random stuff X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=825f479edf9867938b6789215ad7ae6303596cba;p=blank.git random stuff pun intended --- diff --git a/Makefile b/Makefile index c23e9ac..00230db 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ LDXXFLAGS ?= LDXXFLAGS += $(PKGLIBS) DEBUG_FLAGS = -g3 -O0 -PROFILE_FLAGS = -DNDEBUG -O1 -g3 +PROFILE_FLAGS = -DNDEBUG -O1 -g3 -DBLANK_PROFILING RELEASE_FLAGS = -DNDEBUG -O2 -g1 TEST_FLAGS = -g -O2 -I./src $(TESTFLAGS) diff --git a/src/ai/Spawner.cpp b/src/ai/Spawner.cpp index 946e351..4f28cfb 100644 --- a/src/ai/Spawner.cpp +++ b/src/ai/Spawner.cpp @@ -4,6 +4,7 @@ #include "RandomWalk.hpp" #include "../model/CompositeModel.hpp" #include "../model/Skeletons.hpp" +#include "../rand/GaloisLFSR.hpp" #include "../world/BlockLookup.hpp" #include "../world/BlockType.hpp" #include "../world/ChunkIndex.hpp" @@ -17,18 +18,18 @@ using namespace std; namespace blank { -Spawner::Spawner(World &world, Skeletons &skeletons, uint64_t seed) +Spawner::Spawner(World &world, Skeletons &skeletons, GaloisLFSR &rand) : world(world) , skeletons(skeletons) , controllers() -, random(seed) +, random(rand) , timer(64) , despawn_range(128 * 128) , spawn_distance(16 * 16) , max_entities(16) , chunk_range(4) , skeletons_offset(0) -, skeletons_length(skeletons.Size()) { +, skeletons_length(skeletons.size()) { timer.Start(); } @@ -40,7 +41,7 @@ Spawner::~Spawner() { void Spawner::LimitSkeletons(size_t begin, size_t end) { - if (begin >= skeletons.Size() || end > skeletons.Size() || begin >= end) { + if (begin >= skeletons.size() || end > skeletons.size() || begin >= end) { cout << "warning, skeleton limit out of bounds or invalid range given" << endl; } else { skeletons_offset = begin; @@ -101,15 +102,7 @@ void Spawner::TrySpawn() { } const Player &player = *i; - int index = random.Next() % player.GetChunks().TotalChunks(); - - glm::ivec3 chunk(player.GetChunks().PositionOf(index)); - - glm::ivec3 pos( - random.Next() % Chunk::width, - random.Next() % Chunk::height, - random.Next() % Chunk::depth - ); + BlockLookup spawn_block(player.GetChunks().RandomBlock(random)); // distance check //glm::vec3 diff(glm::vec3(chunk * Chunk::Extent() - pos) + player.entity->Position()); @@ -119,7 +112,6 @@ void Spawner::TrySpawn() { //} // check if the spawn block and the one above it are loaded and inhabitable - BlockLookup spawn_block(player.GetChunks()[index], pos); if (!spawn_block || spawn_block.GetType().collide_block) { return; } @@ -129,7 +121,7 @@ void Spawner::TrySpawn() { return; } - Spawn(player.GetEntity(), chunk, glm::vec3(pos) + glm::vec3(0.5f)); + Spawn(player.GetEntity(), spawn_block.GetChunk().Position(), spawn_block.GetBlockCoords()); } void Spawner::Spawn(Entity &reference, const glm::ivec3 &chunk, const glm::vec3 &pos) { diff --git a/src/ai/Spawner.hpp b/src/ai/Spawner.hpp index d0c6f97..e460bbc 100644 --- a/src/ai/Spawner.hpp +++ b/src/ai/Spawner.hpp @@ -2,7 +2,6 @@ #define BLANK_AI_SPAWNER_HPP_ #include "../app/IntervalTimer.hpp" -#include "../rand/GaloisLFSR.hpp" #include #include @@ -13,13 +12,14 @@ namespace blank { class CompositeModel; class Controller; class Entity; +class GaloisLFSR; class Skeletons; class World; class Spawner { public: - Spawner(World &, Skeletons &, std::uint64_t seed); + Spawner(World &, Skeletons &, GaloisLFSR &); ~Spawner(); void LimitSkeletons(std::size_t begin, std::size_t end); @@ -38,7 +38,7 @@ private: Skeletons &skeletons; std::vector controllers; - GaloisLFSR random; + GaloisLFSR &random; IntervalTimer timer; float despawn_range; diff --git a/src/app/Environment.hpp b/src/app/Environment.hpp index f3aa4b5..724db70 100644 --- a/src/app/Environment.hpp +++ b/src/app/Environment.hpp @@ -7,6 +7,7 @@ #include "StateControl.hpp" #include "../audio/Audio.hpp" #include "../graphics/Viewport.hpp" +#include "../rand/GaloisLFSR.hpp" #include "../ui/Keymap.hpp" #include @@ -37,6 +38,8 @@ struct HeadlessEnvironment { StateControl state; + GaloisLFSR rng; + explicit HeadlessEnvironment(const Config &); diff --git a/src/app/runtime.cpp b/src/app/runtime.cpp index 22ca920..c80fa76 100644 --- a/src/app/runtime.cpp +++ b/src/app/runtime.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -117,8 +118,17 @@ HeadlessEnvironment::HeadlessEnvironment(const Config &config) : config(config) , loader(config.asset_path) , counter() -, state() { - +, state() +, rng( +#ifdef BLANK_PROFILING +0 +#else +std::time(nullptr) +#endif +){ + for (int i = 0; i < 4; ++i) { + rng.Next(); + } } string HeadlessEnvironment::Config::GetWorldPath(const string &world_name) const { diff --git a/src/model/Skeletons.hpp b/src/model/Skeletons.hpp index e49352c..131bf0c 100644 --- a/src/model/Skeletons.hpp +++ b/src/model/Skeletons.hpp @@ -13,6 +13,11 @@ class EntityModel; class Skeletons { +public: + using size_type = std::size_t; + using reference = CompositeModel &; + using const_reference = const CompositeModel &; + public: Skeletons(); ~Skeletons(); @@ -20,10 +25,10 @@ public: void LoadHeadless(); void Load(); - std::size_t Size() const noexcept { return skeletons.size(); } + size_type size() const noexcept { return skeletons.size(); } - CompositeModel &operator[](std::size_t i) noexcept { return *skeletons[i]; } - const CompositeModel &operator[](std::size_t i) const noexcept { return *skeletons[i]; } + reference operator[](size_type i) noexcept { return *skeletons[i]; } + const_reference operator[](size_type i) const noexcept { return *skeletons[i]; } CompositeModel *ByID(std::uint16_t) noexcept; const CompositeModel *ByID(std::uint16_t) const noexcept; diff --git a/src/rand/GaloisLFSR.hpp b/src/rand/GaloisLFSR.hpp index b071443..2ee476b 100644 --- a/src/rand/GaloisLFSR.hpp +++ b/src/rand/GaloisLFSR.hpp @@ -48,6 +48,15 @@ public: return (*this)(next); } + template + typename Container::reference From(Container &c) { + return c[Next() % c.size()]; + } + template + typename Container::const_reference From(const Container &c) { + return c[Next() % c.size()]; + } + private: std::uint64_t state; // bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi) diff --git a/src/server/ServerState.cpp b/src/server/ServerState.cpp index 8c3f7e6..e6c031f 100644 --- a/src/server/ServerState.cpp +++ b/src/server/ServerState.cpp @@ -24,14 +24,14 @@ ServerState::ServerState( , generator(gc, block_types) , chunk_loader(world.Chunks(), generator, ws) , skeletons() -, spawner(world, skeletons, gc.seed) +, spawner(world, skeletons, env.rng) , server(config.net, world, ws) , loop_timer(16) { TextureIndex tex_index; env.loader.LoadBlockTypes("default", block_types, tex_index); generator.Scan(); skeletons.LoadHeadless(); - spawner.LimitSkeletons(1, skeletons.Size()); + spawner.LimitSkeletons(1, skeletons.size()); server.SetPlayerModel(skeletons[0]); loop_timer.Start(); diff --git a/src/standalone/MasterState.cpp b/src/standalone/MasterState.cpp index 6ead299..dedb4ce 100644 --- a/src/standalone/MasterState.cpp +++ b/src/standalone/MasterState.cpp @@ -34,7 +34,7 @@ MasterState::MasterState( , chunk_loader(world.Chunks(), generator, save) , chunk_renderer(player.GetChunks()) , skeletons() -, spawner(world, skeletons, gc.seed) +, spawner(world, skeletons, env.rng) , sky(env.loader.LoadCubeMap("skybox")) , preload(env, chunk_loader, chunk_renderer) , unload(env, world.Chunks(), save) { @@ -45,7 +45,7 @@ MasterState::MasterState( chunk_renderer.LoadTextures(env.loader, tex_index); chunk_renderer.FogDensity(wc.fog_density); skeletons.Load(); - spawner.LimitSkeletons(0, skeletons.Size()); + spawner.LimitSkeletons(0, skeletons.size()); if (save.Exists(player)) { save.Read(player); } else { diff --git a/src/world/ChunkIndex.hpp b/src/world/ChunkIndex.hpp index 17b9dd6..91fc704 100644 --- a/src/world/ChunkIndex.hpp +++ b/src/world/ChunkIndex.hpp @@ -1,7 +1,9 @@ #ifndef BLANK_WORLD_CHUNKINDEX_HPP_ #define BLANK_WORLD_CHUNKINDEX_HPP_ +#include "BlockLookup.hpp" #include "Chunk.hpp" +#include "../rand/GaloisLFSR.hpp" #include @@ -30,6 +32,13 @@ public: Chunk *operator [](int i) noexcept { return chunks[i]; } const Chunk *operator [](int i) const noexcept { return chunks[i]; } + Chunk *RandomChunk(GaloisLFSR &rand) { + return rand.From(chunks); + } + BlockLookup RandomBlock(GaloisLFSR &rand) { + return BlockLookup(RandomChunk(rand), Chunk::ToPos(rand.Next() % Chunk::size)); + } + int Extent() const noexcept { return extent; } Chunk::Pos CoordsBegin() const noexcept { return base - Chunk::Pos(extent); }