]> git.localhorst.tv Git - blobs.git/blobdiff - src/creature/creature.cpp
simple name generator
[blobs.git] / src / creature / creature.cpp
index 0aa2b396324cc477c75b2c4313866f3d738a51c8..f51f52ca4a16427cf75ab870577b8f5e71df45b6 100644 (file)
@@ -1,5 +1,7 @@
 #include "Creature.hpp"
 #include "Genome.hpp"
+#include "Memory.hpp"
+#include "NameGenerator.hpp"
 #include "Situation.hpp"
 #include "Steering.hpp"
 
@@ -15,6 +17,7 @@
 #include "../world/TileType.hpp"
 
 #include <algorithm>
+#include <sstream>
 #include <glm/gtx/transform.hpp>
 
 #include <iostream>
@@ -35,6 +38,7 @@ Creature::Creature(world::Simulation &sim)
 , health(1.0)
 , on_death()
 , removable(false)
+, memory(*this)
 , needs()
 , goals()
 , situation()
@@ -53,6 +57,8 @@ void Creature::Grow(double amount) noexcept {
 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();
        }
 }
@@ -105,6 +111,12 @@ void Creature::Tick(double dt) {
        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);
        }
@@ -361,7 +373,7 @@ void Split(Creature &c) {
        Creature *a = new Creature(c.GetSimulation());
        const Situation &s = c.GetSituation();
        // TODO: generate names
-       a->Name("Blobby");
+       a->Name(c.GetSimulation().Assets().name.Sequential());
        // TODO: mutate
        c.GetGenome().Configure(*a);
        s.GetPlanet().AddCreature(a);
@@ -372,7 +384,7 @@ void Split(Creature &c) {
        a->BuildVAO();
 
        Creature *b = new Creature(c.GetSimulation());
-       b->Name("Sir Blobalot");
+       b->Name(c.GetSimulation().Assets().name.Sequential());
        c.GetGenome().Configure(*b);
        s.GetPlanet().AddCreature(b);
        b->GetSituation().SetPlanetSurface(
@@ -384,6 +396,53 @@ void Split(Creature &c) {
 }
 
 
+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
+               });
+       }
+}
+
+
+NameGenerator::NameGenerator()
+: counter(0) {
+}
+
+NameGenerator::~NameGenerator() {
+}
+
+std::string NameGenerator::Sequential() {
+       std::stringstream ss;
+       ss << "Blob " << ++counter;
+       return ss.str();
+}
+
+
 Situation::Situation()
 : planet(nullptr)
 , position(0.0)
@@ -402,16 +461,25 @@ bool Situation::OnSurface() const noexcept {
        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 {