return 0.0;
}
+double Composition::Proportion(int res) const noexcept {
+ return Get(res) / TotalMass();
+}
+
+double Composition::Compatibility(const world::Set<world::Resource> &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)
}
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()) {
}
double Creature::Age() const noexcept {
- return sim.Time() - birth;
+ return Dead() ? death - birth : sim.Time() - birth;
}
double Creature::AgeFactor(double peak) const noexcept {
// 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;
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;
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);
}
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;