#include "Creature.hpp"
#include "Genome.hpp"
+#include "Memory.hpp"
#include "Situation.hpp"
#include "Steering.hpp"
, health(1.0)
, on_death()
, removable(false)
+, memory(*this)
, needs()
, goals()
, situation()
void Creature::Hurt(double dt) noexcept {
health = std::max(0.0, health - dt);
if (health == 0.0) {
+ std::cout << "[" << int(sim.Time()) << "s] "
+ << name << " died" << std::endl;
Die();
}
}
situation.Move(vel * dt);
vel += acc * dt;
+ if (Age() > properties.death_age) {
+ std::cout << "[" << int(sim.Time()) << "s] "
+ << name << " died of old age" << std::endl;
+ }
+
+ memory.Tick(dt);
for (auto &need : needs) {
need->Tick(dt);
}
}
+Memory::Memory(Creature &c)
+: c(c) {
+}
+
+Memory::~Memory() {
+}
+
+void Memory::Tick(double dt) {
+ Situation &s = c.GetSituation();
+ if (s.OnSurface()) {
+ TrackStay({ &s.GetPlanet(), s.Surface(), s.SurfacePosition() }, dt);
+ }
+}
+
+void Memory::TrackStay(const Location &l, double t) {
+ const world::TileType &type = l.planet->TypeAt(l.surface, l.coords.x, l.coords.y);
+ auto entry = known_types.find(type.id);
+ if (entry != known_types.end()) {
+ entry->second.last_been = c.GetSimulation().Time();
+ entry->second.last_loc = l;
+ entry->second.time_spent += t;
+ } else {
+ known_types.emplace(type.id, Stay{
+ c.GetSimulation().Time(),
+ l,
+ c.GetSimulation().Time(),
+ l,
+ t
+ });
+ }
+}
+
+
Situation::Situation()
: planet(nullptr)
, position(0.0)
return type == PLANET_SURFACE;
}
+bool Situation::OnTile() const noexcept {
+ glm::ivec2 t(planet->SurfacePosition(surface, position));
+ return type == PLANET_SURFACE
+ && t.x >= 0 && t.x < planet->SideLength()
+ && t.y >= 0 && t.y < planet->SideLength();
+}
+
+glm::ivec2 Situation::SurfacePosition() const noexcept {
+ return planet->SurfacePosition(surface, position);
+}
+
world::Tile &Situation::GetTile() const noexcept {
- double side_length = planet->SideLength();
- double offset = side_length * 0.5;
- double x = std::max(0.0, std::min(side_length, position.x + offset));
- double y = std::max(0.0, std::min(side_length, position.y + offset));
- return planet->TileAt(surface, int(x), int(y));
+ glm::ivec2 t(planet->SurfacePosition(surface, position));
+ return planet->TileAt(surface, t.x, t.y);
}
const world::TileType &Situation::GetTileType() const noexcept {
- return planet->GetSimulation().TileTypes()[GetTile().type];
+ glm::ivec2 t(planet->SurfacePosition(surface, position));
+ return planet->TypeAt(surface, t.x, t.y);
}
void Situation::Move(const glm::dvec3 &dp) noexcept {