]> git.localhorst.tv Git - blobs.git/commitdiff
fun with resources
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 16 Nov 2017 22:47:17 +0000 (23:47 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 16 Nov 2017 22:47:17 +0000 (23:47 +0100)
src/app/Assets.hpp
src/app/app.cpp
src/blobs.cpp
src/world/Planet.hpp
src/world/Resource.hpp [new file with mode: 0644]
src/world/Resources.hpp [new file with mode: 0644]
src/world/Set.hpp [new file with mode: 0644]
src/world/TileSet.hpp [deleted file]
src/world/TileType.hpp
src/world/world.cpp

index 4ea7f57458f1f8c2435114eb561f40688c364bbc..05a45ac82abe211a9425b4fa7aa0bf5e194c29f6 100644 (file)
@@ -5,6 +5,9 @@
 #include "../graphics/CreatureSkin.hpp"
 #include "../graphics/PlanetSurface.hpp"
 #include "../graphics/SunSurface.hpp"
+#include "../world/Resource.hpp"
+#include "../world/Set.hpp"
+#include "../world/TileType.hpp"
 
 #include <string>
 
@@ -18,6 +21,11 @@ struct Assets {
        std::string tile_path;
        std::string skin_path;
 
+       struct {
+               world::Set<world::Resource> resources;
+               world::Set<world::TileType> tiles;
+       } data;
+
        struct {
                graphics::ArrayTexture tiles;
                graphics::ArrayTexture skins;
index 62de9abab0320ca56ae20fbb130e42c6ec7a4d60..cfdbf8070355b1d2ec55364445baa61913ef1829 100644 (file)
@@ -169,6 +169,55 @@ Assets::Assets()
 : path("assets/")
 , tile_path(path + "tiles/")
 , skin_path(path + "skins/") {
+       data.resources.Add({ "air", "Air", 0 });
+       data.resources.Add({ "biomass", "Biomass", 0 });
+       data.resources.Add({ "dirt", "Dirt", 0 });
+       data.resources.Add({ "ice", "Ice", 0 });
+       data.resources.Add({ "rock", "Rock", 0 });
+       data.resources.Add({ "sand", "Sand", 0 });
+       data.resources.Add({ "water", "Water", 0 });
+       data.resources.Add({ "wood", "Wood", 0 });
+
+       data.tiles.Add({ "algae",    "Algae",    0,  0 });
+       data.tiles.Add({ "desert",   "Desert",   0,  1 });
+       data.tiles.Add({ "forest",   "Forest",   0,  2 });
+       data.tiles.Add({ "grass",    "Grass",    0,  3 });
+       data.tiles.Add({ "ice",      "Ice",      0,  4 });
+       data.tiles.Add({ "jungle",   "Jungle",   0,  5 });
+       data.tiles.Add({ "mountain", "Mountain", 0,  6 });
+       data.tiles.Add({ "ocean",    "Ocean",    0,  7 });
+       data.tiles.Add({ "rock",     "Rock",     0,  8 });
+       data.tiles.Add({ "sand",     "Sand",     0,  9 });
+       data.tiles.Add({ "taiga",    "Taiga",    0, 10 });
+       data.tiles.Add({ "tundra",   "Tundra",   0, 11 });
+       data.tiles.Add({ "water",    "Water",    0, 12 });
+       data.tiles.Add({ "wheat",    "Wheat",    0, 13 });
+
+       data.tiles["algae"]   .resources.push_back({ data.resources["water"].id,   1.0  });
+       data.tiles["algae"]   .resources.push_back({ data.resources["biomass"].id, 0.5  });
+       data.tiles["desert"]  .resources.push_back({ data.resources["sand"].id,    1.0  });
+       data.tiles["forest"]  .resources.push_back({ data.resources["wood"].id,    1.0  });
+       data.tiles["forest"]  .resources.push_back({ data.resources["dirt"].id,    0.5  });
+       data.tiles["grass"]   .resources.push_back({ data.resources["dirt"].id,    0.5  });
+       data.tiles["grass"]   .resources.push_back({ data.resources["biomass"].id, 0.25 });
+       data.tiles["grass"]   .resources.push_back({ data.resources["water"].id,   0.25 });
+       data.tiles["ice"]     .resources.push_back({ data.resources["ice"].id,     1.0  });
+       data.tiles["ice"]     .resources.push_back({ data.resources["water"].id,   0.25 });
+       data.tiles["jungle"]  .resources.push_back({ data.resources["wood"].id,    0.5  });
+       data.tiles["jungle"]  .resources.push_back({ data.resources["biomass"].id, 0.5  });
+       data.tiles["mountain"].resources.push_back({ data.resources["rock"].id,    1.0  });
+       data.tiles["ocean"]   .resources.push_back({ data.resources["water"].id,   1.0  });
+       data.tiles["rock"]    .resources.push_back({ data.resources["rock"].id,    1.0  });
+       data.tiles["sand"]    .resources.push_back({ data.resources["sand"].id,    1.0  });
+       data.tiles["taiga"]   .resources.push_back({ data.resources["wood"].id,    1.0  });
+       data.tiles["taiga"]   .resources.push_back({ data.resources["water"].id,   0.5  });
+       data.tiles["tundra"]  .resources.push_back({ data.resources["rock"].id,    1.0  });
+       data.tiles["tundra"]  .resources.push_back({ data.resources["ice"].id,     0.5  });
+       data.tiles["water"]   .resources.push_back({ data.resources["water"].id,   1.0  });
+       data.tiles["water"]   .resources.push_back({ data.resources["biomass"].id, 0.25 });
+       data.tiles["wheat"]   .resources.push_back({ data.resources["biomass"].id, 1.0  });
+       data.tiles["wheat"]   .resources.push_back({ data.resources["water"].id,   0.25 });
+
        graphics::Format format;
        textures.tiles.Bind();
        textures.tiles.Reserve(256, 256, 14, format);
@@ -186,6 +235,7 @@ Assets::Assets()
        LoadTileTexture("tundra",   textures.tiles, 11);
        LoadTileTexture("water",    textures.tiles, 12);
        LoadTileTexture("wheat",    textures.tiles, 13);
+
        textures.skins.Bind();
        textures.skins.Reserve(256, 256, 9, format);
        LoadSkinTexture("1", textures.skins, 0);
index dcc759052ee2d501d5631719657cdd849371b68a..918925664f3d66f553685d831363e1e0110b5de0 100644 (file)
@@ -5,9 +5,9 @@
 #include "app/MasterState.hpp"
 #include "world/Creature.hpp"
 #include "world/Planet.hpp"
+#include "world/Set.hpp"
 #include "world/Simulation.hpp"
 #include "world/Sun.hpp"
-#include "world/TileSet.hpp"
 #include "world/TileType.hpp"
 
 #include <cstdint>
@@ -20,22 +20,6 @@ int main(int argc, char *argv[]) {
        app::Init init(true, 8);
        app::Assets assets;
 
-       world::TileSet tiles;
-       tiles.Add({ "algae",    "Algae",    0,  0 });
-       tiles.Add({ "desert",   "Desert",   0,  1 });
-       tiles.Add({ "forest",   "Forest",   0,  2 });
-       tiles.Add({ "grass",    "Grass",    0,  3 });
-       tiles.Add({ "ice",      "Ice",      0,  4 });
-       tiles.Add({ "jungle",   "Jungle",   0,  5 });
-       tiles.Add({ "mountain", "Mountain", 0,  6 });
-       tiles.Add({ "ocean",    "Ocean",    0,  7 });
-       tiles.Add({ "rock",     "Rock",     0,  8 });
-       tiles.Add({ "sand",     "Sand",     0,  9 });
-       tiles.Add({ "taiga",    "Taiga",    0, 10 });
-       tiles.Add({ "tundra",   "Tundra",   0, 11 });
-       tiles.Add({ "water",    "Water",    0, 12 });
-       tiles.Add({ "wheat",    "Wheat",    0, 13 });
-
        world::Sun sun;
        sun.Mass(1.0e14);
        sun.Radius(20.0);
@@ -71,9 +55,9 @@ int main(int argc, char *argv[]) {
        sim.AddPlanet(second_planet);
        sim.AddPlanet(moon);
 
-       world::GenerateEarthlike(tiles, planet);
-       world::GenerateTest(tiles, moon);
-       world::GenerateTest(tiles, second_planet);
+       world::GenerateEarthlike(assets.data.tiles, planet);
+       world::GenerateTest(assets.data.tiles, moon);
+       world::GenerateTest(assets.data.tiles, second_planet);
 
        std::cout << "length of year: " << planet.OrbitalPeriod() << "s" << std::endl;
        std::cout << "length of moon cycle: " << moon.OrbitalPeriod() << "s" << std::endl;
index 900ebbbe8ae4fb6412e337e43566fc7899df1da8..af3b512aea6b058bc97b4dadb7435b0bc65d4347 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "Body.hpp"
 
+#include "Set.hpp"
 #include "Tile.hpp"
 #include "../graphics/glm.hpp"
 #include "../graphics/SimpleVAO.hpp"
@@ -15,7 +16,7 @@
 namespace blobs {
 namespace world {
 
-class TileSet;
+class TileType;
 
 /// A planet has six surfaces, numbered 0 to 5, each filled with
 /// sidelength² tiles.
@@ -63,7 +64,7 @@ public:
 
        glm::dvec3 TileCenter(int surface, int x, int y) const noexcept;
 
-       void BuildVAO(const TileSet &);
+       void BuildVAO(const Set<TileType> &);
        void Draw(app::Assets &, graphics::Viewport &) override;
 
 private:
@@ -78,8 +79,8 @@ private:
 
 };
 
-void GenerateEarthlike(const TileSet &, Planet &) noexcept;
-void GenerateTest(const TileSet &, Planet &) noexcept;
+void GenerateEarthlike(const Set<TileType> &, Planet &) noexcept;
+void GenerateTest(const Set<TileType> &, Planet &) noexcept;
 
 }
 }
diff --git a/src/world/Resource.hpp b/src/world/Resource.hpp
new file mode 100644 (file)
index 0000000..5dd3834
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef BLOBS_WORLD_RESOURCE_HPP_
+#define BLOBS_WORLD_RESOURCE_HPP_
+
+#include <string>
+
+
+namespace blobs {
+namespace world {
+
+struct Resource {
+
+       std::string name;
+       std::string label;
+
+       int id;
+
+};
+
+}
+}
+
+#endif
diff --git a/src/world/Resources.hpp b/src/world/Resources.hpp
new file mode 100644 (file)
index 0000000..af30af0
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef BLOBS_WORLD_RESOURCES_HPP_
+#define BLOBS_WORLD_RESOURCES_HPP_
+
+
+namespace blobs {
+namespace world {
+
+struct Resource;
+
+class Resources {
+
+};
+
+}
+}
+
+#endif
diff --git a/src/world/Set.hpp b/src/world/Set.hpp
new file mode 100644 (file)
index 0000000..c4aa6e9
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef BLOBS_WORLD_SET_HPP_
+#define BLOBS_WORLD_SET_HPP_
+
+#include <map>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+namespace blobs {
+namespace world {
+
+template<class Type>
+class Set {
+
+public:
+       int Add(const Type &t) {
+               int id = types.size();
+               if (!names.emplace(t.name, id).second) {
+                       throw std::runtime_error("duplicate type name " + t.name);
+               }
+               types.emplace_back(t);
+               types.back().id = id;
+               return id;
+       }
+
+       Type &operator [](int id) noexcept { return types[id]; }
+       const Type &operator [](int id) const noexcept { return types[id]; }
+
+       Type &operator [](const std::string &name) {
+               auto entry = names.find(name);
+               if (entry != names.end()) {
+                       return types[entry->second];
+               } else {
+                       throw std::runtime_error("unknown type " + name);
+               }
+       }
+       const Type &operator [](const std::string &name) const {
+               auto entry = names.find(name);
+               if (entry != names.end()) {
+                       return types[entry->second];
+               } else {
+                       throw std::runtime_error("unknown type " + name);
+               }
+       }
+
+private:
+       std::vector<Type> types;
+       std::map<std::string, int> names;
+
+};
+
+}
+}
+
+#endif
diff --git a/src/world/TileSet.hpp b/src/world/TileSet.hpp
deleted file mode 100644 (file)
index 683109e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef BLOBS_WORLD_TILESET_HPP_
-#define BLOBS_WORLD_TILESET_HPP_
-
-#include <map>
-#include <string>
-#include <vector>
-
-namespace blobs {
-namespace world {
-
-class TileType;
-
-class TileSet {
-
-public:
-       TileSet();
-       ~TileSet();
-
-       TileSet(const TileSet &) = delete;
-       TileSet &operator =(const TileSet &) = delete;
-
-       TileSet(TileSet &&) = delete;
-       TileSet &operator =(TileSet &&) = delete;
-
-public:
-       int Add(const TileType &);
-
-       TileType &operator [](int id) noexcept { return types[id]; }
-       const TileType &operator [](int id) const noexcept { return types[id]; }
-
-       TileType &operator [](const std::string &name);
-       const TileType &operator [](const std::string &name) const;
-
-private:
-       std::vector<TileType> types;
-       std::map<std::string, int> names;
-
-};
-
-}
-}
-
-#endif
index 58294df071e017d33367c5e29ead1ca21fffc23b..c4eadcfc899a93eeb979f5a91638c8faec8c8e60 100644 (file)
@@ -2,6 +2,7 @@
 #define BLOBS_WORLD_TILETYPE_HPP_
 
 #include <string>
+#include <vector>
 
 
 namespace blobs {
@@ -15,6 +16,12 @@ struct TileType {
        int id;
        int texture;
 
+       struct Yield {
+               int resource;
+               double ubiquity;
+       };
+       std::vector<Yield> resources;
+
 };
 
 }
index a3494b3024f700ca7d78f24e0e5426ed3a7ac515..ed2ade3bb5a6daca721925b3285d759313e3ea72 100644 (file)
@@ -1,10 +1,11 @@
 #include "Body.hpp"
 #include "Orbit.hpp"
 #include "Planet.hpp"
+#include "Resource.hpp"
+#include "Set.hpp"
 #include "Simulation.hpp"
 #include "Sun.hpp"
 #include "Tile.hpp"
-#include "TileSet.hpp"
 #include "TileType.hpp"
 
 #include "Creature.hpp"
@@ -282,7 +283,7 @@ glm::dvec3 Planet::TileCenter(int surface, int x, int y) const noexcept {
        return center;
 }
 
-void Planet::BuildVAO(const TileSet &ts) {
+void Planet::BuildVAO(const Set<TileType> &ts) {
        vao.Bind();
        vao.BindAttributes();
        vao.EnableAttribute(0);
@@ -385,8 +386,9 @@ void Planet::Draw(app::Assets &assets, graphics::Viewport &viewport) {
 }
 
 
-void GenerateEarthlike(const TileSet &tiles, Planet &p) noexcept {
+void GenerateEarthlike(const Set<TileType> &tiles, Planet &p) noexcept {
        rand::SimplexNoise elevation_gen(0);
+       rand::SimplexNoise variation_gen(45623752346);
 
        const int ice = tiles["ice"].id;
        const int ocean = tiles["ocean"].id;
@@ -394,17 +396,24 @@ void GenerateEarthlike(const TileSet &tiles, Planet &p) noexcept {
        const int sand = tiles["sand"].id;
        const int grass = tiles["grass"].id;
        const int tundra = tiles["tundra"].id;
+       const int taiga = tiles["taiga"].id;
        const int desert = tiles["desert"].id;
        const int mntn = tiles["mountain"].id;
+       const int algae = tiles["algae"].id;
+       const int forest = tiles["forest"].id;
+       const int jungle = tiles["jungle"].id;
+       const int rock = tiles["rock"].id;
+       const int wheat = tiles["wheat"].id;
 
        constexpr double ocean_thresh = -0.2;
        constexpr double water_thresh = 0.0;
-       constexpr double beach_thresh = 0.1;
+       constexpr double beach_thresh = 0.05;
+       constexpr double highland_thresh = 0.4;
        constexpr double mountain_thresh = 0.5;
 
        const glm::dvec3 axis(glm::dvec4(0.0, 1.0, 0.0, 0.0) * glm::eulerAngleXY(p.SurfaceTilt().x, p.SurfaceTilt().y));
        const double cap_thresh = std::abs(std::cos(p.AxialTilt().x));
-       const double equ_thresh = 2.0 * (1.0 - cap_thresh);
+       const double equ_thresh = std::abs(std::sin(p.AxialTilt().x)) / 2.0;
        const double fzone_start = equ_thresh - (equ_thresh - cap_thresh) / 3.0;
        const double fzone_end = cap_thresh + (equ_thresh - cap_thresh) / 3.0;
 
@@ -422,26 +431,58 @@ void GenerateEarthlike(const TileSet &tiles, Planet &p) noexcept {
                                        to_tile / p.Radius(),
                                        3,   // octaves
                                        0.5, // persistence
-                                       2 / p.Radius(), // frequency
+                                       5 / p.Radius(), // frequency
+                                       2,   // amplitude
+                                       2    // growth
+                               );
+                               float variation = rand::OctaveNoise(
+                                       variation_gen,
+                                       to_tile / p.Radius(),
+                                       3,   // octaves
+                                       0.5, // persistence
+                                       16 / p.Radius(), // frequency
                                        2,   // amplitude
                                        2    // growth
                                );
                                if (elevation < ocean_thresh) {
                                        p.TileAt(surface, x, y).type = ocean;
                                } else if (elevation < water_thresh) {
-                                       p.TileAt(surface, x, y).type = water;
+                                       if (variation > 0.3) {
+                                               p.TileAt(surface, x, y).type = algae;
+                                       } else {
+                                               p.TileAt(surface, x, y).type = water;
+                                       }
                                } else if (elevation < beach_thresh) {
                                        p.TileAt(surface, x, y).type = sand;
-                               } else if (elevation < mountain_thresh) {
-                                       // TODO: perturb climate rings a little
+                               } else if (elevation < highland_thresh) {
                                        if (near_axis < equ_thresh) {
-                                               p.TileAt(surface, x, y).type = desert;
+                                               if (variation > 0.6) {
+                                                       p.TileAt(surface, x, y).type = grass;
+                                               } else if (variation > 0.2) {
+                                                       p.TileAt(surface, x, y).type = sand;
+                                               } else {
+                                                       p.TileAt(surface, x, y).type = desert;
+                                               }
                                        } else if (near_axis < fzone_start) {
-                                               p.TileAt(surface, x, y).type = grass;
+                                               if (variation > 0.4) {
+                                                       p.TileAt(surface, x, y).type = forest;
+                                               } else if (variation < -0.5) {
+                                                       p.TileAt(surface, x, y).type = jungle;
+                                               } else if (variation > -0.02 && variation < 0.02) {
+                                                       p.TileAt(surface, x, y).type = wheat;
+                                               } else {
+                                                       p.TileAt(surface, x, y).type = grass;
+                                               }
                                        } else if (near_axis < fzone_end) {
                                                p.TileAt(surface, x, y).type = tundra;
                                        } else {
-                                               p.TileAt(surface, x, y).type = grass;
+                                               p.TileAt(surface, x, y).type = taiga;
+                                       }
+                               } else if (elevation < mountain_thresh) {
+                                       if (variation > 0.3) {
+                                               p.TileAt(surface, x, y).type = mntn;
+                                       } else {
+                                               p.TileAt(surface, x, y).type = rock;
                                        }
                                } else {
                                        p.TileAt(surface, x, y).type = mntn;
@@ -452,7 +493,7 @@ void GenerateEarthlike(const TileSet &tiles, Planet &p) noexcept {
        p.BuildVAO(tiles);
 }
 
-void GenerateTest(const TileSet &tiles, Planet &p) noexcept {
+void GenerateTest(const Set<TileType> &tiles, Planet &p) noexcept {
        for (int surface = 0; surface <= 5; ++surface) {
                for (int y = 0; y < p.SideLength(); ++y) {
                        for (int x = 0; x < p.SideLength(); ++x) {
@@ -475,41 +516,5 @@ Sun::Sun()
 Sun::~Sun() {
 }
 
-TileSet::TileSet()
-: types()
-, names() {
-}
-
-TileSet::~TileSet() {
-}
-
-int TileSet::Add(const TileType &t) {
-       int id = types.size();
-       if (!names.emplace(t.name, id).second) {
-               throw std::runtime_error("duplicate tile type name " + t.name);
-       }
-       types.emplace_back(t);
-       types.back().id = id;
-       return id;
-}
-
-TileType &TileSet::operator [](const std::string &name) {
-       auto entry = names.find(name);
-       if (entry != names.end()) {
-               return types[entry->second];
-       } else {
-               throw std::runtime_error("unknown tile type " + name);
-       }
-}
-
-const TileType &TileSet::operator [](const std::string &name) const {
-       auto entry = names.find(name);
-       if (entry != names.end()) {
-               return types[entry->second];
-       } else {
-               throw std::runtime_error("unknown tile type " + name);
-       }
-}
-
 }
 }