-Subproject commit 8fed55072b5b2d5baa06e2ab045df3161f86fdb2
+Subproject commit 38f6d1d15a6d1469a080d77e9fcdafe5c545abf0
exploration
biomes seem too small, maybe that will become easier to tune when
there's a little more diversity between them
+ chunk generation takes too long, it's incredibly annoying
+ should look into speeding it up and executing on a different thread
spawning
throw std::runtime_error("failed to open block type file " + full);
}
TokenStreamReader in(file);
- string name;
+ string proto;
while (in.HasMore()) {
- in.ReadIdentifier(name);
- in.Skip(Token::EQUALS);
BlockType type;
+ in.ReadIdentifier(type.name);
+ in.Skip(Token::EQUALS);
+ if (in.Peek().type == Token::IDENTIFIER) {
+ // prototype
+ in.ReadIdentifier(proto);
+ type.Copy(reg.Get(proto));
+ }
type.Read(in, snd_index, tex_index, shapes);
in.Skip(Token::SEMICOLON);
reg.Add(std::move(type));
/// gravity configuration or null if not emitting gravity
std::unique_ptr<BlockGravity> gravity;
+ /// a string identifying in contexts where numbers just won't do
+ /// must be unique within any given set
+ std::string name;
/// a string to display to the user
std::string label;
BlockType() noexcept;
+ /// clone values of given type
+ /// this copies everything except for ID, name, label, and gravity
+ void Copy(const BlockType &) noexcept;
+
void Read(
TokenStreamReader &in,
ResourceIndex &snd_index,
#include "BlockType.hpp"
+#include <map>
+#include <string>
#include <vector>
public:
BlockTypeRegistry();
+ /// register a new block type
+ /// this may throw if the name is already taken (names must be unique)
Block::Type Add(BlockType &&);
size_t size() const noexcept { return types.size(); }
iterator end() noexcept { return types.end(); }
const_iterator end() const noexcept { return types.end(); }
- BlockType &operator [](Block::Type id) { return types[id]; }
- const BlockType &operator [](Block::Type id) const { return types[id]; }
+ /// lookup by ID
+ BlockType &operator [](Block::Type id) noexcept { return types[id]; }
+ const BlockType &operator [](Block::Type id) const noexcept { return types[id]; }
- BlockType &Get(Block::Type id) { return types[id]; }
- const BlockType &Get(Block::Type id) const { return types[id]; }
+ BlockType &Get(Block::Type id) noexcept { return types[id]; }
+ const BlockType &Get(Block::Type id) const noexcept { return types[id]; }
+
+ /// lookup by name
+ BlockType &Get(const std::string &name);
+ const BlockType &Get(const std::string &name) const;
private:
std::vector<BlockType> types;
+ std::map<std::string, Block::Type> names;
};
return Block(0);
}
float random = GetValue(random_noise, pos, config.randomness);
+ // as weird as it sounds, but this is faster tham glm::fract and generates a
+ // better distribution than (transformed variants of) erf, erfc, atan, and smoothstep
if (random < 0.0f) random += 1.0f;
float value = random * total;
// TODO: change to binary search
#include "../shared/ResourceIndex.hpp"
#include <iostream>
+#include <stdexcept>
#include <glm/gtx/euler_angles.hpp>
#include <glm/gtx/norm.hpp>
#include <glm/gtx/transform.hpp>
, rgb_mod(1.0f, 1.0f, 1.0f)
, outline_color(-1, -1, -1)
, gravity()
+, name("anonymous")
, label("some block")
, place_sound(-1)
, remove_sound(-1)
}
+void BlockType::Copy(const BlockType &other) noexcept {
+ shape = other.shape;
+ textures = other.textures;
+ hsl_mod = other.hsl_mod;
+ rgb_mod = other.rgb_mod;
+ outline_color = other.outline_color;
+ place_sound = other.place_sound;
+ remove_sound = other.remove_sound;
+ luminosity = other.luminosity;
+ visible = other.visible;
+ block_light = other.block_light;
+ collision = other.collision;
+ collide_block = collide_block;
+ generate = other.generate;
+ min_solidity = other.min_solidity;
+ mid_solidity = other.mid_solidity;
+ max_solidity = other.max_solidity;
+ min_humidity = other.min_humidity;
+ mid_humidity = other.mid_humidity;
+ max_humidity = other.max_humidity;
+ min_temperature = other.min_temperature;
+ mid_temperature = other.mid_temperature;
+ max_temperature = other.max_temperature;
+ min_richness = other.min_richness;
+ mid_richness = other.mid_richness;
+ max_richness = other.max_richness;
+ commonness = other.commonness;
+}
+
void BlockType::Read(
TokenStreamReader &in,
ResourceIndex &snd_index,
BlockTypeRegistry::BlockTypeRegistry() {
BlockType air;
+ air.name = "air";
+ air.label = "Air";
air.visible = false;
air.block_light = false;
air.collision = false;
Block::Type BlockTypeRegistry::Add(BlockType &&t) {
int id = types.size();
+ if (!names.emplace(t.name, id).second) {
+ throw std::runtime_error("duplicate block type name " + t.name);
+ }
types.push_back(std::move(t));
types.back().id = id;
return id;
}
+BlockType &BlockTypeRegistry::Get(const std::string &name) {
+ auto entry = names.find(name);
+ if (entry != names.end()) {
+ return Get(entry->second);
+ } else {
+ throw std::runtime_error("unknown block type " + name);
+ }
+}
+
+const BlockType &BlockTypeRegistry::Get(const std::string &name) const {
+ auto entry = names.find(name);
+ if (entry != names.end()) {
+ return Get(entry->second);
+ } else {
+ throw std::runtime_error("unknown block type " + name);
+ }
+}
+
namespace {
types = BlockTypeRegistry();
BlockType obstacle;
+ obstacle.name = "obstacle";
obstacle.visible = true;
obstacle.block_light = true;
types.Add(std::move(obstacle));
BlockType source;
+ source.name = "source";
source.visible = true;
source.luminosity = 5;
source.block_light = true;