]> git.localhorst.tv Git - blobs.git/commitdiff
ingest forgein materials
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 9 Dec 2017 20:39:44 +0000 (21:39 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 9 Dec 2017 20:39:44 +0000 (21:39 +0100)
assets
src/app/app.cpp
src/creature/Composition.hpp
src/creature/LocateResourceGoal.hpp
src/creature/creature.cpp
src/creature/goal.cpp
src/ui/CreaturePanel.hpp
src/ui/ui.cpp
src/world/Resource.hpp

diff --git a/assets b/assets
index 7b1b41f192be522bc6812db7e91798c2fee0e5e1..f2587b6b95d73b9b2d2d871e9a8f5b5dae702965 160000 (submodule)
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit 7b1b41f192be522bc6812db7e91798c2fee0e5e1
+Subproject commit f2587b6b95d73b9b2d2d871e9a8f5b5dae702965
index 913f9f265dc7cffbf7228b24402bb5d621696555..f847a79176701f174a60bdaf323b5efda252320f 100644 (file)
@@ -269,6 +269,24 @@ void Assets::ReadResources(io::TokenStreamReader &in) {
                                }
                        } else if (name == "base_color") {
                                in.ReadVec(data.resources[id].base_color);
+                       } else if (name == "compatibility") {
+                               in.Skip(io::Token::ANGLE_BRACKET_OPEN);
+                               while (in.Peek().type != io::Token::ANGLE_BRACKET_CLOSE) {
+                                       in.ReadIdentifier(name);
+                                       int sub_id = 0;
+                                       if (data.resources.Has(name)) {
+                                               sub_id = data.resources[name].id;
+                                       } else {
+                                               world::Resource res;
+                                               res.name = name;
+                                               sub_id = data.resources.Add(res);
+                                       }
+                                       in.Skip(io::Token::COLON);
+                                       double value = in.GetDouble();
+                                       in.Skip(io::Token::SEMICOLON);
+                                       data.resources[id].compatibility[sub_id] = value;
+                               }
+                               in.Skip(io::Token::ANGLE_BRACKET_CLOSE);
                        } else {
                                throw std::runtime_error("unknown resource property '" + name + "'");
                        }
index c0623348eb8b0168b0232640b68ec73ae0ab0997..da669923972a340d8c68a4219014cad105648256 100644 (file)
@@ -1,10 +1,15 @@
 #ifndef BLOBLS_CREATURE_COMPOSITION_HPP_
 #define BLOBLS_CREATURE_COMPOSITION_HPP_
 
+#include "../world/Set.hpp"
+
 #include <vector>
 
 
 namespace blobs {
+namespace world {
+       class Resource;
+}
 namespace creature {
 
 class Composition {
@@ -31,6 +36,8 @@ public:
        void Add(int res, double amount);
        bool Has(int res) const noexcept;
        double Get(int res) const noexcept;
+       double Proportion(int res) const noexcept;
+       double Compatibility(const world::Set<world::Resource> &, int res) const noexcept;
        double TotalMass() const noexcept { return total_mass; }
 
 public:
index 010b3137489e9f273ed8d2bf495dbeb232b25c27..bbb636e8614c60105f8b345a302d5ddd605700fc 100644 (file)
@@ -16,6 +16,7 @@ public:
        ~LocateResourceGoal() noexcept override;
 
 public:
+       void SetMinimum(double m) noexcept { minimum = m; }
        void Accept(int resource, double attractiveness);
 
        std::string Describe() const override;
@@ -36,6 +37,7 @@ private:
        glm::dvec3 target_pos;
        bool searching;
        double reevaluate;
+       double minimum;
 
 };
 
index 396385e9ce33253c512eea680c1f9a3ee255da5a..536144b276bb4abe2b4f2dd9db33ca4e0223b1df 100644 (file)
@@ -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<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)
@@ -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()) {
index 2d4347c654578220e61c033307c4484fe0376322..55fa6c9ea7cc20b53565f96cffc9428b3748bd4a 100644 (file)
@@ -72,7 +72,13 @@ void BlobBackgroundTask::CheckStats() {
                drink_subtask = new IngestGoal(GetCreature(), stats.Thirst());
                for (const auto &cmp : GetCreature().GetComposition()) {
                        if (Assets().data.resources[cmp.resource].state == world::Resource::LIQUID) {
-                               drink_subtask->Accept(cmp.resource, 1.0);
+                               double value = cmp.value / GetCreature().GetComposition().TotalMass();
+                               drink_subtask->Accept(cmp.resource, value);
+                               for (const auto &compat : Assets().data.resources[cmp.resource].compatibility) {
+                                       if (Assets().data.resources[compat.first].state == world::Resource::LIQUID) {
+                                               drink_subtask->Accept(compat.first, value * compat.second);
+                                       }
+                               }
                        }
                }
                drink_subtask->WhenComplete([&](Goal &) { drink_subtask = nullptr; });
@@ -83,7 +89,13 @@ void BlobBackgroundTask::CheckStats() {
                eat_subtask = new IngestGoal(GetCreature(), stats.Hunger());
                for (const auto &cmp : GetCreature().GetComposition()) {
                        if (Assets().data.resources[cmp.resource].state == world::Resource::SOLID) {
-                               eat_subtask->Accept(cmp.resource, 1.0);
+                               double value = cmp.value / GetCreature().GetComposition().TotalMass();
+                               eat_subtask->Accept(cmp.resource, value);
+                               for (const auto &compat : Assets().data.resources[cmp.resource].compatibility) {
+                                       if (Assets().data.resources[compat.first].state == world::Resource::SOLID) {
+                                               eat_subtask->Accept(compat.first, value * compat.second);
+                                       }
+                               }
                        }
                }
                eat_subtask->WhenComplete([&](Goal &) { eat_subtask = nullptr; });
@@ -286,8 +298,7 @@ void IngestGoal::Tick(double dt) {
        }
        if (ingesting) {
                if (OnSuitableTile() && !GetSituation().Moving()) {
-                       // TODO: determine satisfaction factor
-                       GetCreature().Ingest(resource, yield * dt);
+                       GetCreature().Ingest(resource, yield * GetCreature().GetComposition().Compatibility(Assets().data.resources, resource) * dt);
                        stat.Add(-1.0 * yield * dt);
                        if (stat.Empty()) {
                                SetComplete();
@@ -321,6 +332,7 @@ void IngestGoal::Action() {
                for (const auto &c : accept) {
                        locate_subtask->Accept(c.resource, c.value);
                }
+               locate_subtask->SetMinimum(stat.gain * -1.1);
                locate_subtask->Urgency(Urgency() + 0.1);
                locate_subtask->WhenComplete([&](Goal &){ locate_subtask = nullptr; });
                GetCreature().AddGoal(std::unique_ptr<Goal>(locate_subtask));
@@ -350,7 +362,8 @@ LocateResourceGoal::LocateResourceGoal(Creature &c)
 , found(false)
 , target_pos(0.0)
 , searching(false)
-, reevaluate(0.0) {
+, reevaluate(0.0)
+, minimum(0.0) {
 }
 
 LocateResourceGoal::~LocateResourceGoal() noexcept {
@@ -478,7 +491,7 @@ void LocateResourceGoal::SearchVicinity() {
                }
        }
 
-       if (best_rating > 0.0) {
+       if (best_rating > minimum) {
                found = true;
                searching = false;
                target_pos = glm::normalize(pos + (double(best_pos.x) * step_x) + (double(best_pos.y) * step_y)) * planet.Radius();
index be1234828384d3f8a80901ae0f2d917dd8a73ca5..7a96bf8f4cf09125a47bd4e9b98ed5b2a62c56ba 100644 (file)
@@ -53,6 +53,7 @@ private:
        Label *born;
        Label *age;
        Label *mass;
+       Label *size;
        Label *goal;
        Label *pos;
        Label *tile;
index 98445b408c5bd2f802960a7ed08ed6f5ab2bb4de..dc17b2be7bba5487f35dcf8a6af3329028e5a242 100644 (file)
@@ -29,6 +29,7 @@ CreaturePanel::CreaturePanel(app::Assets &assets)
 , born(new Label(assets.fonts.medium))
 , age(new Label(assets.fonts.medium))
 , mass(new Label(assets.fonts.medium))
+, size(new Label(assets.fonts.medium))
 , goal(new Label(assets.fonts.medium))
 , pos(new Label(assets.fonts.medium))
 , tile(new Label(assets.fonts.medium))
@@ -45,6 +46,8 @@ CreaturePanel::CreaturePanel(app::Assets &assets)
        age_label->Text("Age");
        Label *mass_label = new Label(assets.fonts.medium);
        mass_label->Text("Mass");
+       Label *size_label = new Label(assets.fonts.medium);
+       size_label->Text("Size");
        Label *goal_label = new Label(assets.fonts.medium);
        goal_label->Text("Goal");
 
@@ -55,6 +58,7 @@ CreaturePanel::CreaturePanel(app::Assets &assets)
                ->Add(born_label)
                ->Add(age_label)
                ->Add(mass_label)
+               ->Add(size_label)
                ->Add(goal_label);
        Panel *info_value_panel = new Panel;
        info_value_panel
@@ -63,6 +67,7 @@ CreaturePanel::CreaturePanel(app::Assets &assets)
                ->Add(born)
                ->Add(age)
                ->Add(mass)
+               ->Add(size)
                ->Add(goal);
        Panel *info_panel = new Panel;
        info_panel
@@ -189,7 +194,6 @@ CreaturePanel::~CreaturePanel() {
 
 void CreaturePanel::Show(creature::Creature &cr) {
        c = &cr;
-       name->Text(c->Name());
        born->Text(TimeString(c->Born()));
 
        if (c->Parents().empty()) {
@@ -216,8 +220,10 @@ void CreaturePanel::Hide() noexcept {
 void CreaturePanel::Draw(graphics::Viewport &viewport) noexcept {
        if (!c) return;
 
+       name->Text(c->Name());
        age->Text(TimeString(c->Age()));
        mass->Text(MassString(c->Mass()));
+       size->Text(LengthString(c->Size()));
        if (c->Goals().empty()) {
                goal->Text("none");
        } else {
@@ -265,12 +271,12 @@ void CreaturePanel::Draw(graphics::Viewport &viewport) noexcept {
                }
        }
 
-       props[0]->Text(DecimalString(c->Strength(), 2));
-       props[1]->Text(DecimalString(c->Stamina(), 2));
-       props[2]->Text(DecimalString(c->Dexerty(), 2));
-       props[3]->Text(DecimalString(c->Intelligence(), 2));
+       props[0]->Text(DecimalString(c->Strength(), 2) + " / " + DecimalString(c->GetProperties().Strength(), 2));
+       props[1]->Text(DecimalString(c->Stamina(), 2) + " / " + DecimalString(c->GetProperties().Stamina(), 2));
+       props[2]->Text(DecimalString(c->Dexerty(), 2) + " / " + DecimalString(c->GetProperties().Dexerty(), 2));
+       props[3]->Text(DecimalString(c->Intelligence(), 2) + " / " + DecimalString(c->GetProperties().Intelligence(), 2));
        props[4]->Text(TimeString(c->Lifetime()));
-       props[5]->Text(PercentageString(c->Fertility()));
+       props[5]->Text(PercentageString(c->Fertility()) + " / " + PercentageString(c->GetProperties().Fertility()));
        props[6]->Text(PercentageString(c->Mutability()));
        props[7]->Text(PercentageString(c->Adaptability()));
        props[8]->Text(MassString(c->OffspringMass()));
index ad729c80160d8c84973a4a751d62458f1a397437..17df3244955e55e58b2a540666e02f70ad1f0a84 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "../math/glm.hpp"
 
+#include <map>
 #include <string>
 
 
@@ -32,6 +33,8 @@ struct Resource {
 
        glm::dvec3 base_color = glm::dvec3(1.0);
 
+       std::map<int, double> compatibility;
+
 };
 
 }