From 343b4f7e7cdd53dc1eab7dc32196ae5fa604ba48 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 19 Nov 2017 16:06:32 +0100 Subject: [PATCH] basic needs --- src/app/states.cpp | 2 +- src/blobs.cpp | 4 +- src/{world => creature}/Creature.hpp | 47 +++++++++++----------- src/creature/Need.hpp | 28 ++++++++++++++ src/{world => creature}/creature.cpp | 58 +++++++++++++++++++++------- src/world/Body.hpp | 19 ++++++--- src/world/Planet.hpp | 6 --- src/world/sim.cpp | 3 +- src/world/world.cpp | 25 +++++++++--- 9 files changed, 135 insertions(+), 57 deletions(-) rename src/{world => creature}/Creature.hpp (52%) create mode 100644 src/creature/Need.hpp rename src/{world => creature}/creature.cpp (82%) diff --git a/src/app/states.cpp b/src/app/states.cpp index 5a9ae0a..d344e87 100644 --- a/src/app/states.cpp +++ b/src/app/states.cpp @@ -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" diff --git a/src/blobs.cpp b/src/blobs.cpp index e0a4769..49813d5 100644 --- a/src/blobs.cpp +++ b/src/blobs.cpp @@ -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/world/Creature.hpp b/src/creature/Creature.hpp similarity index 52% rename from src/world/Creature.hpp rename to src/creature/Creature.hpp index 83623a2..e912553 100644 --- a/src/world/Creature.hpp +++ b/src/creature/Creature.hpp @@ -1,9 +1,13 @@ -#ifndef BLOBS_WORLD_CREATURE_HPP_ -#define BLOBS_WORLD_CREATURE_HPP_ +#ifndef BLOBS_CREATURE_CREATURE_HPP_ +#define BLOBS_CREATURE_CREATURE_HPP_ +#include "Need.hpp" #include "../graphics/glm.hpp" #include "../graphics/SimpleVAO.hpp" +#include +#include + namespace blobs { namespace app { @@ -13,9 +17,10 @@ namespace graphics { class Viewport; } namespace world { - -class Body; -class Planet; + class Body; + class Planet; +} +namespace creature { class Creature { @@ -30,24 +35,22 @@ public: 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 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 RequireBreathing(int r) noexcept { breathes = r; } - int Breathes() const noexcept { return breathes; } - bool MustBreathe() const noexcept { return breathes > -1; } + 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 RequireDrinking(int r) noexcept { drinks = r; } - int Drinks() const noexcept { return drinks; } - bool MustDrink() const noexcept { return drinks > -1; } + void AddNeed(const Need &n) { needs.push_back(n); } - void RequireEating(int r) noexcept { eats = r; } - int Eats() const noexcept { return eats; } - bool MustEat() const noexcept { return eats > -1; } + void Tick(double dt); glm::dmat4 LocalTransform() noexcept; @@ -55,13 +58,13 @@ public: void Draw(app::Assets &, graphics::Viewport &); private: - Body *body; + world::Body *body; int surface; glm::dvec3 position; - int breathes; - int drinks; - int eats; + std::string name; + double health; + std::vector needs; struct Attributes { glm::vec3 position; @@ -73,7 +76,7 @@ private: }; /// put creature on planet and configure it to (hopefully) survive -void Spawn(Creature &, Planet &, app::Assets &); +void Spawn(Creature &, world::Planet &, app::Assets &); } } diff --git a/src/creature/Need.hpp b/src/creature/Need.hpp new file mode 100644 index 0000000..93d46e8 --- /dev/null +++ b/src/creature/Need.hpp @@ -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/world/creature.cpp b/src/creature/creature.cpp similarity index 82% rename from src/world/creature.cpp rename to src/creature/creature.cpp index 8018e7c..ed8551c 100644 --- a/src/world/creature.cpp +++ b/src/creature/creature.cpp @@ -1,9 +1,10 @@ #include "Creature.hpp" +#include "Need.hpp" -#include "Body.hpp" -#include "Planet.hpp" -#include "TileType.hpp" #include "../app/Assets.hpp" +#include "../world/Body.hpp" +#include "../world/Planet.hpp" +#include "../world/TileType.hpp" #include @@ -11,15 +12,15 @@ namespace blobs { -namespace world { +namespace creature { Creature::Creature() : body(nullptr) , surface(0) , position() -, breathes(-1) -, drinks(-1) -, eats(-1) +, name() +, health(1.0) +, needs() , vao() { } @@ -27,6 +28,15 @@ 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; @@ -122,7 +132,7 @@ void Creature::Draw(app::Assets &assets, graphics::Viewport &viewport) { } -void Spawn(Creature &c, Planet &p, app::Assets &assets) { +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)); @@ -133,7 +143,7 @@ void Spawn(Creature &c, Planet &p, app::Assets &assets) { std::map 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]; + const world::TileType &t = assets.data.tiles[p.TileAt(0, x, y).type]; for (auto yield : t.resources) { yields[yield.resource] += yield.ubiquity; } @@ -142,11 +152,11 @@ void Spawn(Creature &c, Planet &p, app::Assets &assets) { int liquid = -1; int solid = -1; for (auto e : yields) { - if (assets.data.resources[e.first].state == Resource::LIQUID) { + 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 == Resource::SOLID) { + } else if (assets.data.resources[e.first].state == world::Resource::SOLID) { if (solid < 0 || e.second > yields[solid]) { solid = e.first; } @@ -155,17 +165,37 @@ void Spawn(Creature &c, Planet &p, app::Assets &assets) { if (p.HasAtmosphere()) { std::cout << "require breathing " << assets.data.resources[p.Atmosphere()].label << std::endl; - c.RequireBreathing(p.Atmosphere()); + 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; - c.RequireDrinking(liquid); + 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; - c.RequireEating(solid); + 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); +} + } } diff --git a/src/world/Body.hpp b/src/world/Body.hpp index fba121b..3db5e37 100644 --- a/src/world/Body.hpp +++ b/src/world/Body.hpp @@ -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 &Creatures() noexcept { return creatures; } - const std::vector &Creatures() const noexcept { return creatures; } + void AddCreature(creature::Creature *); + void RemoveCreature(creature::Creature *); + std::vector &Creatures() noexcept { return creatures; } + const std::vector &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 creatures; + std::vector creatures; + int atmosphere; }; diff --git a/src/world/Planet.hpp b/src/world/Planet.hpp index 991985f..af3b512 100644 --- a/src/world/Planet.hpp +++ b/src/world/Planet.hpp @@ -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 &); void Draw(app::Assets &, graphics::Viewport &) override; @@ -75,8 +71,6 @@ private: int sidelength; std::vector tiles; - int atmosphere; - struct Attributes { glm::vec3 position; glm::vec3 tex_coord; diff --git a/src/world/sim.cpp b/src/world/sim.cpp index 8b4c214..aedc5cf 100644 --- a/src/world/sim.cpp +++ b/src/world/sim.cpp @@ -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); } } diff --git a/src/world/world.cpp b/src/world/world.cpp index 9f19b68..18cb241 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -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); } -- 2.39.2