X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fcreature%2Fcreature.cpp;h=536144b276bb4abe2b4f2dd9db33ca4e0223b1df;hb=c49dd02dfabb123e0c6c4b49f761ce6578dfc464;hp=deb5a10e4173376ca27e3e9434459f570350367f;hpb=76c09039792065ca1c259fb4b681c84c29a9dbd8;p=blobs.git diff --git a/src/creature/creature.cpp b/src/creature/creature.cpp index deb5a10..536144b 100644 --- a/src/creature/creature.cpp +++ b/src/creature/creature.cpp @@ -80,6 +80,35 @@ double Composition::Get(int res) const noexcept { return 0.0; } +double Composition::Proportion(int res) const noexcept { + return Get(res) / TotalMass(); +} + +double Composition::Compatibility(const world::Set &resources, int res) const noexcept { + if (Has(res)) { + return Proportion(res); + } + double max_compat = -1.0; + double min_compat = 1.0; + for (const auto &c : components) { + double prop = c.value / TotalMass(); + for (const auto &compat : resources[c.resource].compatibility) { + double value = compat.second * prop; + if (value > max_compat) { + max_compat = value; + } + if (value < min_compat) { + min_compat = value; + } + } + } + if (min_compat < 0.0) { + return min_compat; + } else { + return max_compat; + } +} + Creature::Creature(world::Simulation &sim) : sim(sim) @@ -131,13 +160,12 @@ void Creature::HighlightColor(const glm::dvec3 &c) noexcept { } void Creature::Ingest(int res, double amount) noexcept { - // TODO: check foreign materials if (sim.Resources()[res].state == world::Resource::SOLID) { - // 15% of solids stays in body - AddMass(res, amount * 0.15); + // 30% of solids stays in body + AddMass(res, amount * 0.3 * composition.Compatibility(sim.Resources(), res)); } else { // 10% of fluids stays in body - AddMass(res, amount * 0.05); + AddMass(res, amount * 0.1 * composition.Compatibility(sim.Resources(), res)); } math::GaloisLFSR &random = sim.Assets().random; if (random.UNorm() < AdaptChance()) { @@ -266,7 +294,7 @@ void Creature::AddParent(Creature &p) { } double Creature::Age() const noexcept { - return sim.Time() - birth; + return Dead() ? death - birth : sim.Time() - birth; } double Creature::AgeFactor(double peak) const noexcept { @@ -756,7 +784,7 @@ void Split(Creature &c) { // TODO: duplicate situation somehow a->GetSituation().SetPlanetSurface( s.GetPlanet(), - s.Position() + glm::dvec3(0.0, 0.55 * a->Size(), 0.0)); + s.Position() + glm::rotate(s.Heading() * a->Size() * 0.6, PI * 0.5, s.SurfaceNormal())); a->BuildVAO(); c.GetSimulation().Log() << a->Name() << " was born" << std::endl; @@ -770,7 +798,7 @@ void Split(Creature &c) { s.GetPlanet().AddCreature(b); b->GetSituation().SetPlanetSurface( s.GetPlanet(), - s.Position() - glm::dvec3(0.0, 0.55 * b->Size(), 0.0)); + s.Position() + glm::rotate(s.Heading() * b->Size() * 0.6, PI * -0.5, s.SurfaceNormal())); b->BuildVAO(); c.GetSimulation().Log() << b->Name() << " was born" << std::endl; @@ -891,6 +919,10 @@ bool Situation::OnSurface() const noexcept { return type == PLANET_SURFACE; } +glm::dvec3 Situation::SurfaceNormal() const noexcept { + return planet->NormalAt(state.pos); +} + world::Tile &Situation::GetTile() const noexcept { return planet->TileAt(state.pos); } @@ -1003,8 +1035,8 @@ glm::dvec3 Steering::Force(const Situation::State &s) const noexcept { result += repulse; } if (halting) { - // break twice as hard - result += -2.0 * s.vel * force; + // brake hard + result += -5.0 * s.vel * force; } if (seeking) { glm::dvec3 diff = target - s.pos;