]> git.localhorst.tv Git - blobs.git/blob - src/creature/Creature.hpp
introduce random genetic mutations
[blobs.git] / src / creature / Creature.hpp
1 #ifndef BLOBS_CREATURE_CREATURE_HPP_
2 #define BLOBS_CREATURE_CREATURE_HPP_
3
4 #include "Genome.hpp"
5 #include "Goal.hpp"
6 #include "Memory.hpp"
7 #include "Need.hpp"
8 #include "Situation.hpp"
9 #include "Steering.hpp"
10 #include "../graphics/SimpleVAO.hpp"
11 #include "../math/glm.hpp"
12
13 #include <memory>
14 #include <string>
15 #include <vector>
16
17
18 namespace blobs {
19 namespace app {
20         struct Assets;
21 }
22 namespace graphics {
23         class Viewport;
24 }
25 namespace world {
26         class Body;
27         class Planet;
28         class Simulation;
29 }
30 namespace creature {
31
32 class Creature {
33
34 public:
35         using Callback = std::function<void(Creature &)>;
36
37 public:
38         explicit Creature(world::Simulation &);
39         ~Creature();
40
41         Creature(const Creature &) = delete;
42         Creature &operator =(const Creature &) = delete;
43
44         Creature(Creature &&) = delete;
45         Creature &operator =(Creature &&) = delete;
46
47 public:
48         world::Simulation &GetSimulation() noexcept { return sim; }
49         const world::Simulation &GetSimulation() const noexcept { return sim; }
50
51         void Name(const std::string &n) noexcept { name = n; }
52         const std::string &Name() const noexcept { return name; }
53
54         Genome &GetGenome() noexcept { return genome; }
55         const Genome &GetGenome() const noexcept { return genome; }
56
57         Genome::Properties<double> &GetProperties() noexcept { return properties; }
58         const Genome::Properties<double> &GetProperties() const noexcept { return properties; }
59
60         const Genome::PropertySet<double> &CurProps() const noexcept { return properties.props[cur_prop]; }
61         const Genome::PropertySet<double> &NextProps() const noexcept { return properties.props[std::min(5, cur_prop + 1)]; }
62
63         void BaseColor(const glm::dvec3 &c) noexcept { base_color = c; }
64         const glm::dvec3 &BaseColor() const noexcept { return base_color; }
65
66         void HighlightColor(const glm::dvec3 &c) noexcept { highlight_color = c; }
67         glm::dvec4 HighlightColor() const noexcept;
68
69         void Mass(double m) noexcept { mass = m; size = std::cbrt(mass / density); }
70         double Mass() const noexcept { return mass; }
71         void Ingest(int res, double amount) noexcept;
72
73         void Density(double d) noexcept { density = d; size = std::cbrt(mass / density); }
74         double Density() const noexcept { return density; }
75
76         double Size() const noexcept;
77         double Age() const noexcept;
78         std::string AgeName() const;
79         double AgeLerp(double from, double to) const noexcept;
80         // chance of giving birth per tick
81         double Fertility() const noexcept;
82         // chance of random genetic mutation per tick
83         double Mutability() const noexcept;
84
85         void Health(double h) noexcept { health = h; }
86         double Health() const noexcept { return health; }
87         void Hurt(double d) noexcept;
88         void Die() noexcept;
89         void OnDeath(Callback cb) noexcept { on_death = cb; }
90         void Remove() noexcept { removable = true; }
91         bool Removable() const noexcept { return removable; }
92
93         Memory &GetMemory() noexcept { return memory; }
94         const Memory &GetMemory() const noexcept { return memory; }
95
96         /// constantly active goal. every creature in the simulation is required to have one
97         void SetBackgroundTask(std::unique_ptr<Goal> &&g) { bg_task = std::move(g); }
98         Goal &BackgroundTask() { return *bg_task; }
99
100         void AddNeed(std::unique_ptr<Need> &&n) { needs.emplace_back(std::move(n)); }
101         const std::vector<std::unique_ptr<Need>> &Needs() const noexcept { return needs; }
102
103         void AddGoal(std::unique_ptr<Goal> &&);
104         const std::vector<std::unique_ptr<Goal>> &Goals() const noexcept { return goals; }
105
106         void Tick(double dt);
107
108         Situation &GetSituation() noexcept { return situation; }
109         const Situation &GetSituation() const noexcept { return situation; }
110
111         Steering &GetSteering() noexcept { return steering; }
112         const Steering &GetSteering() const noexcept { return steering; }
113
114         glm::dmat4 LocalTransform() noexcept;
115
116         void BuildVAO();
117         void Draw(graphics::Viewport &);
118
119 private:
120         Situation::Derivative Step(const Situation::Derivative &ds, double dt) const noexcept;
121
122 private:
123         world::Simulation &sim;
124         std::string name;
125
126         Genome genome;
127         Genome::Properties<double> properties;
128         int cur_prop;
129
130         glm::dvec3 base_color;
131         glm::dvec3 highlight_color;
132
133         double mass;
134         double density;
135         double size;
136
137         double birth;
138         double health;
139         Callback on_death;
140         bool removable;
141
142         Memory memory;
143
144         std::unique_ptr<Goal> bg_task;
145         std::vector<std::unique_ptr<Need>> needs;
146         std::vector<std::unique_ptr<Goal>> goals;
147
148         Situation situation;
149         Steering steering;
150
151         struct Attributes {
152                 glm::vec3 position;
153                 glm::vec3 normal;
154                 glm::vec3 texture;
155         };
156         graphics::SimpleVAO<Attributes, unsigned short> vao;
157
158 };
159
160 /// put creature on planet and configure it to (hopefully) survive
161 void Spawn(Creature &, world::Planet &);
162
163 /// split the creature into two
164 void Split(Creature &);
165
166 }
167 }
168
169 #endif