#include "Creature.hpp"
-#include "Need.hpp"
+#include "Situation.hpp"
+#include "InhaleNeed.hpp"
+#include "IngestNeed.hpp"
+#include "Need.hpp"
#include "../app/Assets.hpp"
#include "../world/Body.hpp"
#include "../world/Planet.hpp"
namespace creature {
Creature::Creature()
-: body(nullptr)
-, surface(0)
-, position()
-, name()
+: name()
, health(1.0)
, needs()
+, situation()
, vao() {
}
Creature::~Creature() {
}
+void Creature::Hurt(double dt) noexcept {
+ health = std::max(0.0, health - dt);
+}
void Creature::Tick(double dt) {
- for (Need &need : needs) {
- need.Tick(dt);
- if (!need.IsSatisfied()) {
- health = std::max(0.0, health - need.penalty * dt);
- }
+ // update needs
+ for (auto &need : needs) {
+ need->Tick(dt);
+ }
+ // do background stuff
+ for (auto &need : needs) {
+ need->ApplyEffect(*this, 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))
+ const glm::dvec3 &pos = situation.Position();
+ return glm::translate(glm::dvec3(pos.x, pos.y, pos.z + situation.GetPlanet().Radius() + half_height))
* glm::scale(glm::dvec3(half_height, half_height, half_height));
}
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));
+ c.GetSituation().SetPlanetSurface(p, 0, glm::dvec3(0.0, 0.0, 0.0));
// probe surrounding area for common resources
int start = p.SideLength() / 2 - 2;
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);
+ std::unique_ptr<Need> need(new InhaleNeed(p.Atmosphere(), 0.25, 0.1));
+ need->name = assets.data.resources[p.Atmosphere()].label;
+ need->gain = 0.25;
+ need->inconvenient = 0.4;
+ need->critical = 0.95;
+ c.AddNeed(std::move(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);
+ std::unique_ptr<Need> need(new IngestNeed(liquid, 0.2, 0.01));
+ need->name = assets.data.resources[liquid].label;
+ need->gain = 0.0001;
+ need->inconvenient = 0.6;
+ need->critical = 0.95;
+ c.AddNeed(std::move(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);
+ std::unique_ptr<Need> need(new IngestNeed(solid, 0.03, 0.001));
+ need->name = assets.data.resources[solid].label;
+ need->gain = 0.00001;
+ need->inconvenient = 0.6;
+ need->critical = 0.95;
+ c.AddNeed(std::move(need));
}
}
+Situation::Situation()
+: planet(nullptr)
+, position(0.0)
+, surface(0)
+, type(LOST) {
+}
+
+Situation::~Situation() {
+}
+
+bool Situation::OnPlanet() const noexcept {
+ return type == PLANET_SURFACE;
+}
-void Need::Tick(double dt) noexcept {
- value = std::min(1.0, value + gain * dt);
+void Situation::SetPlanetSurface(world::Planet &p, int srf, const glm::dvec3 &pos) noexcept {
+ type = PLANET_SURFACE;
+ planet = &p;
+ surface = srf;
+ position = pos;
}
}