]> git.localhorst.tv Git - blobs.git/blob - src/creature/need.cpp
60e7cb816b3a0b8cd375df295da00e80723dbc3a
[blobs.git] / src / creature / need.cpp
1 #include "Need.hpp"
2 #include "InhaleNeed.hpp"
3 #include "IngestNeed.hpp"
4
5 #include "Creature.hpp"
6 #include "LocateResourceGoal.hpp"
7 #include "../world/Planet.hpp"
8 #include "../world/TileType.hpp"
9
10
11 namespace blobs {
12 namespace creature {
13
14 Need::~Need() {
15 }
16
17 void Need::Tick(double dt) noexcept {
18         Increase(gain * dt);
19 }
20
21 void Need::Increase(double delta) noexcept {
22         value = std::min(1.0, value + delta);
23 }
24
25 void Need::Decrease(double delta) noexcept {
26         value = std::max(0.0, value - delta);
27 }
28
29
30 IngestNeed::IngestNeed(int resource, double speed, double damage)
31 : resource(resource)
32 , speed(speed)
33 , damage(damage)
34 , ingesting(false)
35 , locating(false) {
36 }
37
38 IngestNeed::~IngestNeed() {
39 }
40
41 void IngestNeed::ApplyEffect(Creature &c, double dt) {
42         if (!IsSatisfied()) {
43                 ingesting = true;
44         }
45         if (ingesting) {
46                 if (c.GetSituation().OnSurface()) {
47                         const world::TileType &t = c.GetSituation().GetTileType();
48                         bool found = false;
49                         for (auto &yield : t.resources) {
50                                 if (yield.resource == resource) {
51                                         found = true;
52                                         // TODO: check if not busy with something else
53                                         Decrease(std::min(yield.ubiquity, speed) * dt);
54                                         if (value == 0.0) {
55                                                 ingesting = false;
56                                                 locating = false;
57                                         }
58                                         break;
59                                 }
60                         }
61                         if (!found && !locating) {
62                                 c.AddGoal(std::unique_ptr<Goal>(new LocateResourceGoal(resource)));
63                                 locating = true;
64                         }
65                 }
66         }
67         if (IsCritical()) {
68                 c.Hurt(damage * dt);
69         }
70 }
71
72
73 InhaleNeed::InhaleNeed(int resource, double speed, double damage)
74 : resource(resource)
75 , speed(speed)
76 , damage(damage)
77 , inhaling(false) {
78 }
79
80 InhaleNeed::~InhaleNeed() {
81 }
82
83 void InhaleNeed::ApplyEffect(Creature &c, double dt) {
84         if (!IsSatisfied()) {
85                 inhaling = true;
86         }
87         if (inhaling) {
88                 if (c.GetSituation().OnPlanet() && c.GetSituation().GetPlanet().Atmosphere() == resource) {
89                         Decrease(speed * dt);
90                         if (value == 0.0) {
91                                 inhaling = false;
92                         }
93                 } else {
94                         // TODO: panic
95                 }
96         }
97         if (IsCritical()) {
98                 c.Hurt(damage * dt);
99         }
100 }
101
102 }
103 }