]> git.localhorst.tv Git - blobs.git/commitdiff
lose weight through exercise
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 3 Dec 2017 21:04:25 +0000 (22:04 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 3 Dec 2017 21:04:25 +0000 (22:04 +0100)
assets
src/app/app.cpp
src/creature/Composition.hpp
src/creature/Creature.hpp
src/creature/Situation.hpp
src/creature/creature.cpp
src/creature/goal.cpp
src/world/Resource.hpp

diff --git a/assets b/assets
index 3c715b39e3aece21fc1f0fd6042611e79bfbeb44..7b1b41f192be522bc6812db7e91798c2fee0e5e1 160000 (submodule)
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit 3c715b39e3aece21fc1f0fd6042611e79bfbeb44
+Subproject commit 7b1b41f192be522bc6812db7e91798c2fee0e5e1
index a732ca64b21cc8cc5130864a740f47b5ccc47291..3f87c8f5cf39011e0734d936bf315e1be7ababdb 100644 (file)
@@ -251,6 +251,9 @@ void Assets::ReadResources(io::TokenStreamReader &in) {
                                in.ReadString(data.resources[id].label);
                        } else if (name == "density") {
                                data.resources[id].density = in.GetDouble();
+                       } else if (name == "energy") {
+                               data.resources[id].energy = in.GetDouble();
+                               data.resources[id].inverse_energy = 1.0 / data.resources[id].energy;
                        } else if (name == "state") {
                                in.ReadIdentifier(name);
                                if (name == "solid") {
index 621f6406f77dbd696bbdf248f77f31854e9471b0..c0623348eb8b0168b0232640b68ec73ae0ab0997 100644 (file)
@@ -21,11 +21,11 @@ public:
        Composition();
        ~Composition();
 
-       Composition(const Composition &) = delete;
-       Composition &operator =(const Composition &) = delete;
+       Composition(const Composition &) = default;
+       Composition &operator =(const Composition &) = default;
 
-       Composition(Composition &&) = delete;
-       Composition &operator =(Composition &&) = delete;
+       Composition(Composition &&) = default;
+       Composition &operator =(Composition &&) = default;
 
 public:
        void Add(int res, double amount);
index 3f86670eba4a9aa885e8056c5b3b1e7dd15a7c08..4d16f99bd35857689b5f1e09b8dcb9deffcd854a 100644 (file)
@@ -105,6 +105,8 @@ public:
        double Mass() const noexcept { return mass; }
        void Ingest(int res, double amount) noexcept;
 
+       void DoWork(double amount) noexcept;
+
        void Size(double s) noexcept { size = s; }
        double Size() const noexcept { return size; }
 
@@ -113,6 +115,7 @@ public:
        /// age-depended multiplier, peak being the maximum in lifetime [0,1]
        double AgeFactor(double peak) const noexcept;
 
+       double EnergyEfficiency() const noexcept;
        double ExhaustionFactor() const noexcept;
        double FatigueFactor() const noexcept;
 
index 3c4a28a567ef4877b09ad68c94575c12545179cf..4d635f5e8ba223ba94225df3b2701ccd4767485c 100644 (file)
@@ -64,7 +64,7 @@ public:
        const State &GetState() const noexcept { return state; }
 
        const glm::dvec3 &Velocity() const noexcept { return state.vel; }
-       bool Moving() const noexcept { return glm::length2(state.vel) > 0.0000001; }
+       bool Moving() const noexcept { return glm::length2(state.vel) > 0.000001; }
        void Move(const glm::dvec3 &dp) noexcept;
        void Accelerate(const glm::dvec3 &dv) noexcept;
        void EnforceConstraints(State &) noexcept;
index fb6e9f6540b2872152bc390d07623cf779cfe26b..9ef8dd9d3148f691160f5effaf5e80974133d68f 100644 (file)
@@ -45,14 +45,17 @@ bool CompositionCompare(const Composition::Component &a, const Composition::Comp
 
 void Composition::Add(int res, double amount) {
        bool found = false;
-       for (auto &c : components) {
-               if (c.resource == res) {
-                       c.value += amount;
+       for (auto c = components.begin(); c != components.end(); ++c) {
+               if (c->resource == res) {
+                       c->value += amount;
+                       if (c->value <= 0.0) {
+                               components.erase(c);
+                       }
                        found = true;
                        break;
                }
        }
-       if (!found) {
+       if (!found && amount > 0.0) {
                components.emplace_back(res, amount);
        }
        std::sort(components.begin(), components.end(), CompositionCompare);
@@ -138,6 +141,20 @@ void Creature::Ingest(int res, double amount) noexcept {
        }
 }
 
+void Creature::DoWork(double amount) noexcept {
+       stats.Exhaustion().Add(amount / Stamina());
+       // burn resources proportional to composition
+       // factor = 1/total * 1/efficiency * amount * -1
+       double factor = -amount / (composition.TotalMass() * EnergyEfficiency());
+       // make a copy to total remains constant and
+       // no entries disappear during iteration
+       Composition comp(composition);
+       for (auto &cmp : comp) {
+               double value = cmp.value * factor * sim.Resources()[cmp.resource].inverse_energy;
+               AddMass(cmp.resource, value);
+       }
+}
+
 void Creature::Hurt(double amount) noexcept {
        stats.Damage().Add(amount);
        if (stats.Damage().Full()) {
@@ -194,7 +211,12 @@ double Creature::AgeFactor(double peak) const noexcept {
        // shifted inverse hermite, y = 1 - (3t² - 2t³) with t = normalized age - peak
        // goes negative below -0.5 and starts to rise again above 1.0
        double t = glm::clamp((Age() / properties.Lifetime()) - peak, -0.5, 1.0);
-       return 1.0 - (3.0 * t * t) + (2.0 * t * t * t);
+       // guarantee at least 1%
+       return std::max(0.01, 1.0 - (3.0 * t * t) + (2.0 * t * t * t));
+}
+
+double Creature::EnergyEfficiency() const noexcept {
+       return 0.25 * AgeFactor(0.05);
 }
 
 double Creature::ExhaustionFactor() const noexcept {
@@ -293,7 +315,8 @@ void Creature::TickState(double dt) {
                }
        }
        situation.SetState(state);
-       stats.Exhaustion().Add(length(f.acc) * Mass() / Stamina() * 0.5 * dt);
+       // work is force times distance
+       DoWork(length(f.acc) * Mass() * length(f.vel) * dt);
 }
 
 Situation::Derivative Creature::Step(const Situation::Derivative &ds, double dt) const noexcept {
@@ -835,7 +858,8 @@ glm::dvec3 Steering::Force(const Situation::State &s) const noexcept {
                SumForce(result, repulse, force);
        }
        if (halting) {
-               SumForce(result, s.vel * -force, force);
+               // break twice as hard
+               SumForce(result, s.vel * force * -2.0, force);
        }
        if (seeking) {
                glm::dvec3 diff = target - s.pos;
index f3e0891c1e1ca5cf7e6b98846f4ed43aca0688f2..5f9f1e839d9ed24bdff82c62caaf7ea50bd2b42d 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "Creature.hpp"
 #include "../app/Assets.hpp"
+#include "../ui/String.hpp"
 #include "../world/Planet.hpp"
 #include "../world/Resource.hpp"
 #include "../world/Simulation.hpp"
@@ -41,9 +42,9 @@ void BlobBackgroundTask::Tick(double dt) {
                // TODO: check if in compatible atmosphere
                double amount = GetCreature().GetStats().Breath().gain * -(1.5 + 0.5 * GetCreature().ExhaustionFactor());
                GetCreature().GetStats().Breath().Add(amount * dt);
-               // maintain ~2.5% gas composition
+               // maintain ~1% gas composition
                double gas_amount = GetCreature().GetComposition().Get(gas);
-               if (gas_amount < GetCreature().GetComposition().TotalMass() * 0.025) {
+               if (gas_amount < GetCreature().GetComposition().TotalMass() * 0.01) {
                        double add = std::min(GetCreature().GetComposition().TotalMass() * 0.025 - gas_amount, -amount * dt);
                        GetCreature().Ingest(gas, add);
                }
@@ -99,8 +100,8 @@ void BlobBackgroundTask::CheckStats() {
 void BlobBackgroundTask::CheckSplit() {
        if (GetCreature().Mass() > GetCreature().OffspringMass() * 2.0
                && GetCreature().OffspringChance() > Assets().random.UNorm()) {
-               std::cout << "[" << int(GetCreature().GetSimulation().Time())
-                       << "s] " << GetCreature().Name() << " split" << std::endl;
+               std::cout << "[" << ui::TimeString(GetCreature().GetSimulation().Time())
+                       << "] " << GetCreature().Name() << " split" << std::endl;
                Split(GetCreature());
                return;
        }
index 3abe8f3b83c11f4b5fb57d2b8304bf46d83eab2c..ad729c80160d8c84973a4a751d62458f1a397437 100644 (file)
@@ -15,6 +15,8 @@ struct Resource {
        std::string label = "";
 
        double density = 1.0;
+       double energy = 1.0;
+       double inverse_energy = 1.0;
 
        int id = -1;