X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fcreature%2Fcreature.cpp;h=376ad3ffe86438272c52ac221eb9efdaa0426863;hb=631f0cfd6b421f5be68d60375db2ce91176d923d;hp=de82f86ad9a7db52924106735450f49ee8033a8c;hpb=d364d8a9203138be1c569cdc31144f51883ec79f;p=blobs.git diff --git a/src/creature/creature.cpp b/src/creature/creature.cpp index de82f86..376ad3f 100644 --- a/src/creature/creature.cpp +++ b/src/creature/creature.cpp @@ -92,7 +92,7 @@ Creature::Creature(world::Simulation &sim) , mass(1.0) , size(1.0) , birth(sim.Time()) -, death(0.0) +, death(-1.0) , on_death() , removable(false) , parents() @@ -209,36 +209,42 @@ void Creature::DoWork(double amount) noexcept { void Creature::Hurt(double amount) noexcept { stats.Damage().Add(amount); if (stats.Damage().Full()) { - std::cout << "[" << ui::TimeString(sim.Time()) << "] " << name << " "; + std::ostream &log = sim.Log() << name << " "; if (stats.Exhaustion().Full()) { - std::cout << "died of exhaustion"; + log << "died of exhaustion"; } else if (stats.Breath().Full()) { - std::cout << "suffocated"; + log << "suffocated"; } else if (stats.Thirst().Full()) { - std::cout << "died of thirst"; + log << "died of thirst"; } else if (stats.Hunger().Full()) { - std::cout << "starved to death"; + log << "starved to death"; } else { - std::cout << "succumed to wounds"; + log << "succumed to wounds"; } - std::cout << " at an age of " << ui::TimeString(Age()) + log << " at an age of " << ui::TimeString(Age()) << " (" << ui::PercentageString(Age() / properties.Lifetime()) - << "% of life expectancy of " << ui::TimeString(properties.Lifetime()) + << " of life expectancy of " << ui::TimeString(properties.Lifetime()) << ")" << std::endl; Die(); } } void Creature::Die() noexcept { + if (Dead()) return; + sim.SetDead(this); death = sim.Time(); - steering.Halt(); + steering.Off(); if (on_death) { on_death(*this); } Remove(); } +bool Creature::Dead() const noexcept { + return death > birth; +} + void Creature::Remove() noexcept { removable = true; } @@ -691,8 +697,7 @@ void Split(Creature &c) { s.GetPlanet(), s.Surface(), s.Position() + glm::dvec3(0.0, 0.55 * a->Size(), 0.0)); a->BuildVAO(); - std::cout << "[" << ui::TimeString(c.GetSimulation().Time()) << "] " - << a->Name() << " was born" << std::endl; + c.GetSimulation().Log() << a->Name() << " was born" << std::endl; Creature *b = new Creature(c.GetSimulation()); b->AddParent(c); @@ -706,8 +711,7 @@ void Split(Creature &c) { s.GetPlanet(), s.Surface(), s.Position() - glm::dvec3(0.0, 0.55 * b->Size(), 0.0)); b->BuildVAO(); - std::cout << "[" << ui::TimeString(c.GetSimulation().Time()) << "] " - << b->Name() << " was born" << std::endl; + c.GetSimulation().Log() << b->Name() << " was born" << std::endl; c.Die(); } @@ -868,6 +872,13 @@ Steering::Steering(const Creature &c) Steering::~Steering() { } +void Steering::Off() noexcept { + separating = false; + halting = false; + seeking = false; + arriving = false; +} + void Steering::Separate(double min_distance, double max_lookaround) noexcept { separating = true; min_dist = min_distance; @@ -919,47 +930,29 @@ glm::dvec3 Steering::Force(const Situation::State &s) const noexcept { repulse += normalize(diff) * (1.0 - sep / min_dist); } } - SumForce(result, repulse, force); + result += repulse; } if (halting) { // break twice as hard - SumForce(result, s.vel * force * -2.0, force); + result += -2.0 * s.vel * force; } if (seeking) { glm::dvec3 diff = target - s.pos; if (!allzero(diff)) { - SumForce(result, TargetVelocity(s, (normalize(diff) * speed), force), force); + result += TargetVelocity(s, (normalize(diff) * speed), force); } } if (arriving) { glm::dvec3 diff = target - s.pos; double dist = length(diff); if (!allzero(diff) && dist > std::numeric_limits::epsilon()) { - SumForce(result, TargetVelocity(s, diff * std::min(dist * force, speed) / dist, force), force); + result += TargetVelocity(s, diff * std::min(dist * force, speed) / dist, force); } } - return result; -} - -bool Steering::SumForce(glm::dvec3 &out, const glm::dvec3 &in, double max) const noexcept { - if (allzero(in) || anynan(in)) { - return false; - } - double cur = allzero(out) ? 0.0 : length(out); - double rem = max - cur; - if (rem < 0.0) { - return true; - } - double add = length(in); - if (add > rem) { - // this method is off if in and out are in different - // directions, but gives okayish results - out += in * (1.0 / add); - return true; - } else { - out += in; - return false; + if (length2(result) > max_force * max_force) { + result = normalize(result) * max_force; } + return result; } glm::dvec3 Steering::TargetVelocity(const Situation::State &s, const glm::dvec3 &vel, double acc) const noexcept {