#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"
#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"
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);
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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);
+}
+
+}
+}
namespace app {
class Assets;
}
+namespace creature {
+ class Creature;
+}
namespace graphics {
class Viewport;
}
namespace world {
-class Creature;
class Simulation;
class Body {
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 &);
glm::dmat4 local;
glm::dmat4 inverse_local;
- std::vector<Creature *> creatures;
+ std::vector<creature::Creature *> creatures;
+ int atmosphere;
};
+++ /dev/null
-#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
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;
int sidelength;
std::vector<Tile> tiles;
- int atmosphere;
-
struct Attributes {
glm::vec3 position;
glm::vec3 tex_coord;
+++ /dev/null
-#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);
- }
-}
-
-}
-}
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);
}
}
#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"
, 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;
}
}
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 =
* 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)
: Body()
, sidelength(sidelength)
, tiles(TilesTotal())
-, atmosphere(-1)
, vao() {
Radius(double(sidelength) / 2.0);
}