]> git.localhorst.tv Git - blobs.git/commitdiff
basic needs
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 19 Nov 2017 15:06:32 +0000 (16:06 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 19 Nov 2017 16:52:48 +0000 (17:52 +0100)
src/app/states.cpp
src/blobs.cpp
src/creature/Creature.hpp [new file with mode: 0644]
src/creature/Need.hpp [new file with mode: 0644]
src/creature/creature.cpp [new file with mode: 0644]
src/world/Body.hpp
src/world/Creature.hpp [deleted file]
src/world/Planet.hpp
src/world/creature.cpp [deleted file]
src/world/sim.cpp
src/world/world.cpp

index 5a9ae0a3379760711ef75ddd2048d183e734df5b..d344e875ae413824e22ba71b9812a536b0dc89db 100644 (file)
@@ -1,7 +1,7 @@
 #include "MasterState.hpp"
 
+#include "../creature/Creature.hpp"
 #include "../world/Body.hpp"
-#include "../world/Creature.hpp"
 #include "../world/Planet.hpp"
 #include "../world/Simulation.hpp"
 #include "../world/Sun.hpp"
index e0a4769ba2eadd965fadca11b81d26613fdaee2c..49813d585ce04c90c051b97fec5a6c104afe93f3 100644 (file)
@@ -3,7 +3,7 @@
 #include "app/Assets.hpp"
 #include "app/init.hpp"
 #include "app/MasterState.hpp"
-#include "world/Creature.hpp"
+#include "creature/Creature.hpp"
 #include "world/Planet.hpp"
 #include "world/Set.hpp"
 #include "world/Simulation.hpp"
@@ -67,7 +67,7 @@ int main(int argc, char *argv[]) {
        std::cout << "moon cycle in days: " << (moon.OrbitalPeriod() / planet.RotationalPeriod()) << std::endl;
        std::cout << "moon cycles per year: " << (planet.OrbitalPeriod() / moon.OrbitalPeriod()) << std::endl;
 
-       auto blob = new world::Creature;
+       auto blob = new creature::Creature;
        blob->BuildVAO();
        Spawn(*blob, planet, assets);
 
diff --git a/src/creature/Creature.hpp b/src/creature/Creature.hpp
new file mode 100644 (file)
index 0000000..e912553
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef BLOBS_CREATURE_CREATURE_HPP_
+#define BLOBS_CREATURE_CREATURE_HPP_
+
+#include "Need.hpp"
+#include "../graphics/glm.hpp"
+#include "../graphics/SimpleVAO.hpp"
+
+#include <string>
+#include <vector>
+
+
+namespace blobs {
+namespace app {
+       struct Assets;
+}
+namespace graphics {
+       class Viewport;
+}
+namespace world {
+       class Body;
+       class Planet;
+}
+namespace creature {
+
+class Creature {
+
+public:
+       Creature();
+       ~Creature();
+
+       Creature(const Creature &) = delete;
+       Creature &operator =(const Creature &) = delete;
+
+       Creature(Creature &&) = delete;
+       Creature &operator =(Creature &&) = delete;
+
+public:
+       void SetBody(world::Body &b) noexcept { body = &b; }
+       world::Body &GetBody() noexcept { return *body; }
+       const world::Body &GetBody() const noexcept { return *body; }
+
+       void Surface(int s) noexcept { surface = s; }
+       void Position(const glm::dvec3 &p) noexcept { position = p; }
+
+       void Name(const std::string &n) noexcept { name = n; }
+       const std::string &Name() const noexcept { return name; }
+
+       void Health(double h) noexcept { health = h; }
+       double Health() const noexcept { return health; }
+
+       void AddNeed(const Need &n) { needs.push_back(n); }
+
+       void Tick(double dt);
+
+       glm::dmat4 LocalTransform() noexcept;
+
+       void BuildVAO();
+       void Draw(app::Assets &, graphics::Viewport &);
+
+private:
+       world::Body *body;
+       int surface;
+       glm::dvec3 position;
+
+       std::string name;
+       double health;
+       std::vector<Need> needs;
+
+       struct Attributes {
+               glm::vec3 position;
+               glm::vec3 normal;
+               glm::vec3 texture;
+       };
+       graphics::SimpleVAO<Attributes, unsigned short> vao;
+
+};
+
+/// put creature on planet and configure it to (hopefully) survive
+void Spawn(Creature &, world::Planet &, app::Assets &);
+
+}
+}
+
+#endif
diff --git a/src/creature/Need.hpp b/src/creature/Need.hpp
new file mode 100644 (file)
index 0000000..93d46e8
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef BLOBS_CREATURE_NEED_HPP_
+#define BLOBS_CREATURE_NEED_HPP_
+
+namespace blobs {
+namespace creature {
+
+struct Need {
+
+       int resource = -1;
+       double value = 0.0;
+
+       // how fast value grows per second
+       double gain = 0.0;
+       // the value at which this need is no longer satisfied
+       double critical = 0.0;
+       // the price to pay for not satsfying the need
+       double penalty = 0.0;
+
+       void Tick(double dt) noexcept;
+
+       bool IsSatisfied() const noexcept { return value < critical; }
+
+};
+
+}
+}
+
+#endif
diff --git a/src/creature/creature.cpp b/src/creature/creature.cpp
new file mode 100644 (file)
index 0000000..ed8551c
--- /dev/null
@@ -0,0 +1,201 @@
+#include "Creature.hpp"
+#include "Need.hpp"
+
+#include "../app/Assets.hpp"
+#include "../world/Body.hpp"
+#include "../world/Planet.hpp"
+#include "../world/TileType.hpp"
+
+#include <glm/gtx/transform.hpp>
+
+#include <iostream>
+
+
+namespace blobs {
+namespace creature {
+
+Creature::Creature()
+: body(nullptr)
+, surface(0)
+, position()
+, name()
+, health(1.0)
+, needs()
+, vao() {
+}
+
+Creature::~Creature() {
+}
+
+
+void Creature::Tick(double dt) {
+       for (Need &need : needs) {
+               need.Tick(dt);
+               if (!need.IsSatisfied()) {
+                       health = std::max(0.0, health - need.penalty * dt);
+               }
+       }
+}
+
+glm::dmat4 Creature::LocalTransform() noexcept {
+       // TODO: surface transform
+       constexpr double half_height = 0.25;
+       return glm::translate(glm::dvec3(position.x, position.y, position.z + body->Radius() + half_height))
+               * glm::scale(glm::dvec3(half_height, half_height, half_height));
+}
+
+void Creature::BuildVAO() {
+       vao.Bind();
+       vao.BindAttributes();
+       vao.EnableAttribute(0);
+       vao.EnableAttribute(1);
+       vao.EnableAttribute(2);
+       vao.AttributePointer<glm::vec3>(0, false, offsetof(Attributes, position));
+       vao.AttributePointer<glm::vec3>(1, false, offsetof(Attributes, normal));
+       vao.AttributePointer<glm::vec3>(2, false, offsetof(Attributes, texture));
+       vao.ReserveAttributes(6 * 4, GL_STATIC_DRAW);
+       {
+               auto attrib = vao.MapAttributes(GL_WRITE_ONLY);
+               const float offset = 1.0f;
+               for (int surface = 0; surface < 6; ++surface) {
+                       const float tex_u_begin = surface < 3 ? 1.0f : 0.0f;
+                       const float tex_u_end = surface < 3 ? 0.0f : 1.0f;
+
+                       attrib[4 * surface + 0].position[(surface + 0) % 3] = -offset;
+                       attrib[4 * surface + 0].position[(surface + 1) % 3] = -offset;
+                       attrib[4 * surface + 0].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
+                       attrib[4 * surface + 0].normal[(surface + 0) % 3] = 0.0f;
+                       attrib[4 * surface + 0].normal[(surface + 1) % 3] = 0.0f;
+                       attrib[4 * surface + 0].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
+                       attrib[4 * surface + 0].texture.x = tex_u_begin;
+                       attrib[4 * surface + 0].texture.y = 1.0f;
+                       attrib[4 * surface + 0].texture.z = surface;
+
+                       attrib[4 * surface + 1].position[(surface + 0) % 3] = -offset;
+                       attrib[4 * surface + 1].position[(surface + 1) % 3] =  offset;
+                       attrib[4 * surface + 1].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
+                       attrib[4 * surface + 1].normal[(surface + 0) % 3] = 0.0f;
+                       attrib[4 * surface + 1].normal[(surface + 1) % 3] = 0.0f;
+                       attrib[4 * surface + 1].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
+                       attrib[4 * surface + 1].texture.x = tex_u_end;
+                       attrib[4 * surface + 1].texture.y = 1.0f;
+                       attrib[4 * surface + 1].texture.z = surface;
+
+                       attrib[4 * surface + 2].position[(surface + 0) % 3] =  offset;
+                       attrib[4 * surface + 2].position[(surface + 1) % 3] = -offset;
+                       attrib[4 * surface + 2].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
+                       attrib[4 * surface + 2].normal[(surface + 0) % 3] = 0.0f;
+                       attrib[4 * surface + 2].normal[(surface + 1) % 3] = 0.0f;
+                       attrib[4 * surface + 2].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
+                       attrib[4 * surface + 2].texture.x = tex_u_begin;
+                       attrib[4 * surface + 2].texture.y = 0.0f;
+                       attrib[4 * surface + 2].texture.z = surface;
+
+                       attrib[4 * surface + 3].position[(surface + 0) % 3] = offset;
+                       attrib[4 * surface + 3].position[(surface + 1) % 3] = offset;
+                       attrib[4 * surface + 3].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
+                       attrib[4 * surface + 3].normal[(surface + 0) % 3] = 0.0f;
+                       attrib[4 * surface + 3].normal[(surface + 1) % 3] = 0.0f;
+                       attrib[4 * surface + 3].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
+                       attrib[4 * surface + 3].texture.x = tex_u_end;
+                       attrib[4 * surface + 3].texture.y = 0.0f;
+                       attrib[4 * surface + 3].texture.z = surface;
+               }
+       }
+       vao.BindElements();
+       vao.ReserveElements(6 * 6, GL_STATIC_DRAW);
+       {
+               auto element = vao.MapElements(GL_WRITE_ONLY);
+               for (int surface = 0; surface < 3; ++surface) {
+                       element[6 * surface + 0] = 4 * surface + 0;
+                       element[6 * surface + 1] = 4 * surface + 2;
+                       element[6 * surface + 2] = 4 * surface + 1;
+                       element[6 * surface + 3] = 4 * surface + 1;
+                       element[6 * surface + 4] = 4 * surface + 2;
+                       element[6 * surface + 5] = 4 * surface + 3;
+               }
+               for (int surface = 3; surface < 6; ++surface) {
+                       element[6 * surface + 0] = 4 * surface + 0;
+                       element[6 * surface + 1] = 4 * surface + 1;
+                       element[6 * surface + 2] = 4 * surface + 2;
+                       element[6 * surface + 3] = 4 * surface + 2;
+                       element[6 * surface + 4] = 4 * surface + 1;
+                       element[6 * surface + 5] = 4 * surface + 3;
+               }
+       }
+       vao.Unbind();
+}
+
+void Creature::Draw(app::Assets &assets, graphics::Viewport &viewport) {
+       vao.Bind();
+       vao.DrawTriangles(6 * 6);
+}
+
+
+void Spawn(Creature &c, world::Planet &p, app::Assets &assets) {
+       p.AddCreature(&c);
+       c.Surface(0);
+       c.Position(glm::dvec3(0.0, 0.0, 0.0));
+
+       // probe surrounding area for common resources
+       int start = p.SideLength() / 2 - 2;
+       int end = start + 5;
+       std::map<int, double> yields;
+       for (int y = start; y < end; ++y) {
+               for (int x = start; x < end; ++x) {
+                       const world::TileType &t = assets.data.tiles[p.TileAt(0, x, y).type];
+                       for (auto yield : t.resources) {
+                               yields[yield.resource] += yield.ubiquity;
+                       }
+               }
+       }
+       int liquid = -1;
+       int solid = -1;
+       for (auto e : yields) {
+               if (assets.data.resources[e.first].state == world::Resource::LIQUID) {
+                       if (liquid < 0 || e.second > yields[liquid]) {
+                               liquid = e.first;
+                       }
+               } else if (assets.data.resources[e.first].state == world::Resource::SOLID) {
+                       if (solid < 0 || e.second > yields[solid]) {
+                               solid = e.first;
+                       }
+               }
+       }
+
+       if (p.HasAtmosphere()) {
+               std::cout << "require breathing " << assets.data.resources[p.Atmosphere()].label << std::endl;
+               Need need;
+               need.resource = p.Atmosphere();
+               need.gain = 0.25;
+               need.critical = 0.95;
+               need.penalty = 0.1;
+               c.AddNeed(need);
+       }
+       if (liquid > -1) {
+               std::cout << "require drinking " << assets.data.resources[liquid].label << std::endl;
+               Need need;
+               need.resource = liquid;
+               need.gain = 0.0001;
+               need.critical = 0.95;
+               need.penalty = 0.01;
+               c.AddNeed(need);
+       }
+       if (solid > -1) {
+               std::cout << "require eating " << assets.data.resources[solid].label << std::endl;
+               Need need;
+               need.resource = solid;
+               need.gain = 0.00001;
+               need.critical = 0.95;
+               need.penalty = 0.001;
+               c.AddNeed(need);
+       }
+}
+
+
+void Need::Tick(double dt) noexcept {
+       value = std::min(1.0, value + gain * dt);
+}
+
+}
+}
index fba121b90995d113c2fad374c39db8bd7ae28942..3db5e37e362b3de7352dac22ee6a4a848dac5652 100644 (file)
@@ -11,12 +11,14 @@ namespace blobs {
 namespace app {
        class Assets;
 }
+namespace creature {
+       class Creature;
+}
 namespace graphics {
        class Viewport;
 }
 namespace world {
 
-class Creature;
 class Simulation;
 
 class Body {
@@ -82,12 +84,18 @@ public:
 
        virtual void Draw(app::Assets &, graphics::Viewport &) { }
 
+       void Tick(double dt);
        void Cache() noexcept;
 
        // body takes over ownership of given pointer
-       void AddCreature(Creature *);
-       std::vector<Creature *> &Creatures() noexcept { return creatures; }
-       const std::vector<Creature *> &Creatures() const noexcept { return creatures; }
+       void AddCreature(creature::Creature *);
+       void RemoveCreature(creature::Creature *);
+       std::vector<creature::Creature *> &Creatures() noexcept { return creatures; }
+       const std::vector<creature::Creature *> &Creatures() const noexcept { return creatures; }
+
+       void Atmosphere(int a) noexcept { atmosphere = a; }
+       int Atmosphere() const noexcept { return atmosphere; }
+       bool HasAtmosphere() const noexcept { return atmosphere >= 0; }
 
 private:
        void AddChild(Body &);
@@ -110,7 +118,8 @@ private:
        glm::dmat4 local;
        glm::dmat4 inverse_local;
 
-       std::vector<Creature *> creatures;
+       std::vector<creature::Creature *> creatures;
+       int atmosphere;
 
 };
 
diff --git a/src/world/Creature.hpp b/src/world/Creature.hpp
deleted file mode 100644 (file)
index 83623a2..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef BLOBS_WORLD_CREATURE_HPP_
-#define BLOBS_WORLD_CREATURE_HPP_
-
-#include "../graphics/glm.hpp"
-#include "../graphics/SimpleVAO.hpp"
-
-
-namespace blobs {
-namespace app {
-       struct Assets;
-}
-namespace graphics {
-       class Viewport;
-}
-namespace world {
-
-class Body;
-class Planet;
-
-class Creature {
-
-public:
-       Creature();
-       ~Creature();
-
-       Creature(const Creature &) = delete;
-       Creature &operator =(const Creature &) = delete;
-
-       Creature(Creature &&) = delete;
-       Creature &operator =(Creature &&) = delete;
-
-public:
-       void SetBody(Body &b) noexcept { body = &b; }
-       Body &GetBody() noexcept { return *body; }
-       const Body &GetBody() const noexcept { return *body; }
-
-       void Surface(int s) noexcept { surface = s; }
-       void Position(const glm::dvec3 &p) noexcept { position = p; }
-
-       void RequireBreathing(int r) noexcept { breathes = r; }
-       int Breathes() const noexcept { return breathes; }
-       bool MustBreathe() const noexcept { return breathes > -1; }
-
-       void RequireDrinking(int r) noexcept { drinks = r; }
-       int Drinks() const noexcept { return drinks; }
-       bool MustDrink() const noexcept { return drinks > -1; }
-
-       void RequireEating(int r) noexcept { eats = r; }
-       int Eats() const noexcept { return eats; }
-       bool MustEat() const noexcept { return eats > -1; }
-
-       glm::dmat4 LocalTransform() noexcept;
-
-       void BuildVAO();
-       void Draw(app::Assets &, graphics::Viewport &);
-
-private:
-       Body *body;
-       int surface;
-       glm::dvec3 position;
-
-       int breathes;
-       int drinks;
-       int eats;
-
-       struct Attributes {
-               glm::vec3 position;
-               glm::vec3 normal;
-               glm::vec3 texture;
-       };
-       graphics::SimpleVAO<Attributes, unsigned short> vao;
-
-};
-
-/// put creature on planet and configure it to (hopefully) survive
-void Spawn(Creature &, Planet &, app::Assets &);
-
-}
-}
-
-#endif
index 991985f968173e2eb98f0ddac4b4e3fcdaa9984f..af3b512aea6b058bc97b4dadb7435b0bc65d4347 100644 (file)
@@ -64,10 +64,6 @@ public:
 
        glm::dvec3 TileCenter(int surface, int x, int y) const noexcept;
 
-       void Atmosphere(int a) noexcept { atmosphere = a; }
-       int Atmosphere() const noexcept { return atmosphere; }
-       bool HasAtmosphere() const noexcept { return atmosphere >= 0; }
-
        void BuildVAO(const Set<TileType> &);
        void Draw(app::Assets &, graphics::Viewport &) override;
 
@@ -75,8 +71,6 @@ private:
        int sidelength;
        std::vector<Tile> tiles;
 
-       int atmosphere;
-
        struct Attributes {
                glm::vec3 position;
                glm::vec3 tex_coord;
diff --git a/src/world/creature.cpp b/src/world/creature.cpp
deleted file mode 100644 (file)
index 8018e7c..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-#include "Creature.hpp"
-
-#include "Body.hpp"
-#include "Planet.hpp"
-#include "TileType.hpp"
-#include "../app/Assets.hpp"
-
-#include <glm/gtx/transform.hpp>
-
-#include <iostream>
-
-
-namespace blobs {
-namespace world {
-
-Creature::Creature()
-: body(nullptr)
-, surface(0)
-, position()
-, breathes(-1)
-, drinks(-1)
-, eats(-1)
-, vao() {
-}
-
-Creature::~Creature() {
-}
-
-
-glm::dmat4 Creature::LocalTransform() noexcept {
-       // TODO: surface transform
-       constexpr double half_height = 0.25;
-       return glm::translate(glm::dvec3(position.x, position.y, position.z + body->Radius() + half_height))
-               * glm::scale(glm::dvec3(half_height, half_height, half_height));
-}
-
-void Creature::BuildVAO() {
-       vao.Bind();
-       vao.BindAttributes();
-       vao.EnableAttribute(0);
-       vao.EnableAttribute(1);
-       vao.EnableAttribute(2);
-       vao.AttributePointer<glm::vec3>(0, false, offsetof(Attributes, position));
-       vao.AttributePointer<glm::vec3>(1, false, offsetof(Attributes, normal));
-       vao.AttributePointer<glm::vec3>(2, false, offsetof(Attributes, texture));
-       vao.ReserveAttributes(6 * 4, GL_STATIC_DRAW);
-       {
-               auto attrib = vao.MapAttributes(GL_WRITE_ONLY);
-               const float offset = 1.0f;
-               for (int surface = 0; surface < 6; ++surface) {
-                       const float tex_u_begin = surface < 3 ? 1.0f : 0.0f;
-                       const float tex_u_end = surface < 3 ? 0.0f : 1.0f;
-
-                       attrib[4 * surface + 0].position[(surface + 0) % 3] = -offset;
-                       attrib[4 * surface + 0].position[(surface + 1) % 3] = -offset;
-                       attrib[4 * surface + 0].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
-                       attrib[4 * surface + 0].normal[(surface + 0) % 3] = 0.0f;
-                       attrib[4 * surface + 0].normal[(surface + 1) % 3] = 0.0f;
-                       attrib[4 * surface + 0].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
-                       attrib[4 * surface + 0].texture.x = tex_u_begin;
-                       attrib[4 * surface + 0].texture.y = 1.0f;
-                       attrib[4 * surface + 0].texture.z = surface;
-
-                       attrib[4 * surface + 1].position[(surface + 0) % 3] = -offset;
-                       attrib[4 * surface + 1].position[(surface + 1) % 3] =  offset;
-                       attrib[4 * surface + 1].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
-                       attrib[4 * surface + 1].normal[(surface + 0) % 3] = 0.0f;
-                       attrib[4 * surface + 1].normal[(surface + 1) % 3] = 0.0f;
-                       attrib[4 * surface + 1].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
-                       attrib[4 * surface + 1].texture.x = tex_u_end;
-                       attrib[4 * surface + 1].texture.y = 1.0f;
-                       attrib[4 * surface + 1].texture.z = surface;
-
-                       attrib[4 * surface + 2].position[(surface + 0) % 3] =  offset;
-                       attrib[4 * surface + 2].position[(surface + 1) % 3] = -offset;
-                       attrib[4 * surface + 2].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
-                       attrib[4 * surface + 2].normal[(surface + 0) % 3] = 0.0f;
-                       attrib[4 * surface + 2].normal[(surface + 1) % 3] = 0.0f;
-                       attrib[4 * surface + 2].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
-                       attrib[4 * surface + 2].texture.x = tex_u_begin;
-                       attrib[4 * surface + 2].texture.y = 0.0f;
-                       attrib[4 * surface + 2].texture.z = surface;
-
-                       attrib[4 * surface + 3].position[(surface + 0) % 3] = offset;
-                       attrib[4 * surface + 3].position[(surface + 1) % 3] = offset;
-                       attrib[4 * surface + 3].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
-                       attrib[4 * surface + 3].normal[(surface + 0) % 3] = 0.0f;
-                       attrib[4 * surface + 3].normal[(surface + 1) % 3] = 0.0f;
-                       attrib[4 * surface + 3].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
-                       attrib[4 * surface + 3].texture.x = tex_u_end;
-                       attrib[4 * surface + 3].texture.y = 0.0f;
-                       attrib[4 * surface + 3].texture.z = surface;
-               }
-       }
-       vao.BindElements();
-       vao.ReserveElements(6 * 6, GL_STATIC_DRAW);
-       {
-               auto element = vao.MapElements(GL_WRITE_ONLY);
-               for (int surface = 0; surface < 3; ++surface) {
-                       element[6 * surface + 0] = 4 * surface + 0;
-                       element[6 * surface + 1] = 4 * surface + 2;
-                       element[6 * surface + 2] = 4 * surface + 1;
-                       element[6 * surface + 3] = 4 * surface + 1;
-                       element[6 * surface + 4] = 4 * surface + 2;
-                       element[6 * surface + 5] = 4 * surface + 3;
-               }
-               for (int surface = 3; surface < 6; ++surface) {
-                       element[6 * surface + 0] = 4 * surface + 0;
-                       element[6 * surface + 1] = 4 * surface + 1;
-                       element[6 * surface + 2] = 4 * surface + 2;
-                       element[6 * surface + 3] = 4 * surface + 2;
-                       element[6 * surface + 4] = 4 * surface + 1;
-                       element[6 * surface + 5] = 4 * surface + 3;
-               }
-       }
-       vao.Unbind();
-}
-
-void Creature::Draw(app::Assets &assets, graphics::Viewport &viewport) {
-       vao.Bind();
-       vao.DrawTriangles(6 * 6);
-}
-
-
-void Spawn(Creature &c, Planet &p, app::Assets &assets) {
-       p.AddCreature(&c);
-       c.Surface(0);
-       c.Position(glm::dvec3(0.0, 0.0, 0.0));
-
-       // probe surrounding area for common resources
-       int start = p.SideLength() / 2 - 2;
-       int end = start + 5;
-       std::map<int, double> yields;
-       for (int y = start; y < end; ++y) {
-               for (int x = start; x < end; ++x) {
-                       const TileType &t = assets.data.tiles[p.TileAt(0, x, y).type];
-                       for (auto yield : t.resources) {
-                               yields[yield.resource] += yield.ubiquity;
-                       }
-               }
-       }
-       int liquid = -1;
-       int solid = -1;
-       for (auto e : yields) {
-               if (assets.data.resources[e.first].state == Resource::LIQUID) {
-                       if (liquid < 0 || e.second > yields[liquid]) {
-                               liquid = e.first;
-                       }
-               } else if (assets.data.resources[e.first].state == Resource::SOLID) {
-                       if (solid < 0 || e.second > yields[solid]) {
-                               solid = e.first;
-                       }
-               }
-       }
-
-       if (p.HasAtmosphere()) {
-               std::cout << "require breathing " << assets.data.resources[p.Atmosphere()].label << std::endl;
-               c.RequireBreathing(p.Atmosphere());
-       }
-       if (liquid > -1) {
-               std::cout << "require drinking " << assets.data.resources[liquid].label << std::endl;
-               c.RequireDrinking(liquid);
-       }
-       if (solid > -1) {
-               std::cout << "require eating " << assets.data.resources[solid].label << std::endl;
-               c.RequireEating(solid);
-       }
-}
-
-}
-}
index 8b4c2140c2ba96b672c9dd08ac7987223b52c9f9..aedc5cf01017df98b217b87dcc4991b9ddf8848e 100644 (file)
@@ -40,8 +40,7 @@ void Simulation::Tick() {
        constexpr double dt = 0.01666666666666666666666666666666;
        time += dt;
        for (auto body : bodies) {
-               body->Rotation(body->Rotation() + dt * body->AngularMomentum() / body->Inertia());
-               body->Cache();
+               body->Tick(dt);
        }
 }
 
index 9f19b68c02cdaa866a5c7bdc687daf945ad97f7b..18cb2414b53aa5cce993b549e2919054cdcba673 100644 (file)
@@ -8,9 +8,9 @@
 #include "Tile.hpp"
 #include "TileType.hpp"
 
-#include "Creature.hpp"
 #include "../const.hpp"
 #include "../app/Assets.hpp"
+#include "../creature/Creature.hpp"
 #include "../graphics/Viewport.hpp"
 #include "../rand/OctaveNoise.hpp"
 #include "../rand/SimplexNoise.hpp"
@@ -50,11 +50,12 @@ Body::Body()
 , inverse_orbital(1.0)
 , local(1.0)
 , inverse_local(1.0)
-, creatures() {
+, creatures()
+, atmosphere(-1) {
 }
 
 Body::~Body() {
-       for (Creature *c : creatures) {
+       for (creature::Creature *c : creatures) {
                delete c;
        }
 }
@@ -137,6 +138,14 @@ glm::dmat4 Body::FromUniverse() const noexcept {
        return m;
 }
 
+void Body::Tick(double dt) {
+       rotation += dt * AngularMomentum() / Inertia();
+       Cache();
+       for (creature::Creature *c : Creatures()) {
+               c->Tick(dt);
+       }
+}
+
 void Body::Cache() noexcept {
        if (parent) {
                orbital =
@@ -157,11 +166,18 @@ void Body::Cache() noexcept {
                * glm::eulerAngleY(-rotation);
 }
 
-void Body::AddCreature(Creature *c) {
+void Body::AddCreature(creature::Creature *c) {
        c->SetBody(*this);
        creatures.push_back(c);
 }
 
+void Body::RemoveCreature(creature::Creature *c) {
+       auto entry = std::find(creatures.begin(), creatures.end(), c);
+       if (entry != creatures.end()) {
+               creatures.erase(entry);
+       }
+}
+
 
 Orbit::Orbit()
 : sma(1.0)
@@ -268,7 +284,6 @@ Planet::Planet(int sidelength)
 : Body()
 , sidelength(sidelength)
 , tiles(TilesTotal())
-, atmosphere(-1)
 , vao() {
        Radius(double(sidelength) / 2.0);
 }