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)
#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"
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();
}
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;
}
const Player &player = *i;
- int index = random.Next<unsigned int>() % player.GetChunks().TotalChunks();
-
- glm::ivec3 chunk(player.GetChunks().PositionOf(index));
-
- glm::ivec3 pos(
- random.Next<unsigned char>() % Chunk::width,
- random.Next<unsigned char>() % Chunk::height,
- random.Next<unsigned char>() % Chunk::depth
- );
+ BlockLookup spawn_block(player.GetChunks().RandomBlock(random));
// distance check
//glm::vec3 diff(glm::vec3(chunk * Chunk::Extent() - pos) + player.entity->Position());
//}
// 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;
}
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) {
#define BLANK_AI_SPAWNER_HPP_
#include "../app/IntervalTimer.hpp"
-#include "../rand/GaloisLFSR.hpp"
#include <vector>
#include <glm/glm.hpp>
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);
Skeletons &skeletons;
std::vector<Controller *> controllers;
- GaloisLFSR random;
+ GaloisLFSR &random;
IntervalTimer timer;
float despawn_range;
#include "StateControl.hpp"
#include "../audio/Audio.hpp"
#include "../graphics/Viewport.hpp"
+#include "../rand/GaloisLFSR.hpp"
#include "../ui/Keymap.hpp"
#include <string>
StateControl state;
+ GaloisLFSR rng;
+
explicit HeadlessEnvironment(const Config &);
#include <cctype>
#include <cstdlib>
+#include <ctime>
#include <fstream>
#include <iostream>
#include <SDL.h>
: 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<int>();
+ }
}
string HeadlessEnvironment::Config::GetWorldPath(const string &world_name) const {
class Skeletons {
+public:
+ using size_type = std::size_t;
+ using reference = CompositeModel &;
+ using const_reference = const CompositeModel &;
+
public:
Skeletons();
~Skeletons();
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;
return (*this)(next);
}
+ template<class Container>
+ typename Container::reference From(Container &c) {
+ return c[Next<typename Container::size_type>() % c.size()];
+ }
+ template<class Container>
+ typename Container::const_reference From(const Container &c) {
+ return c[Next<typename Container::size_type>() % c.size()];
+ }
+
private:
std::uint64_t state;
// bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi)
, 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();
, 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) {
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 {
#ifndef BLANK_WORLD_CHUNKINDEX_HPP_
#define BLANK_WORLD_CHUNKINDEX_HPP_
+#include "BlockLookup.hpp"
#include "Chunk.hpp"
+#include "../rand/GaloisLFSR.hpp"
#include <vector>
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<unsigned int>() % Chunk::size));
+ }
+
int Extent() const noexcept { return extent; }
Chunk::Pos CoordsBegin() const noexcept { return base - Chunk::Pos(extent); }