]> git.localhorst.tv Git - blobs.git/blob - src/creature/need.cpp
remove outdated TODOs
[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 : locate_goal(nullptr)
32 , resource(resource)
33 , speed(speed)
34 , damage(damage)
35 , ingesting(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                                         double amount = std::min(yield.ubiquity, speed) * dt;
54                                         c.Ingest(resource, amount * growth * dt);
55                                         Decrease(amount);
56                                         if (value == 0.0) {
57                                                 ingesting = false;
58                                                 if (locate_goal) {
59                                                         // abort
60                                                         locate_goal->Complete();
61                                                 }
62                                         }
63                                         break;
64                                 }
65                         }
66                         if (!found && !locate_goal) {
67                                 locate_goal = new LocateResourceGoal(c, resource);
68                                 locate_goal->OnComplete([&](Goal &g){ OnLocateComplete(g); });
69                                 c.AddGoal(std::unique_ptr<Goal>(locate_goal));
70                         }
71                 }
72         }
73         if (IsCritical()) {
74                 c.Hurt(damage * dt);
75         }
76         if (locate_goal) {
77                 locate_goal->Urgency(value);
78         }
79 }
80
81 void IngestNeed::OnLocateComplete(Goal &g) {
82         if (&g == locate_goal) {
83                 locate_goal = nullptr;
84         }
85 }
86
87
88 InhaleNeed::InhaleNeed(int resource, double speed, double damage)
89 : resource(resource)
90 , speed(speed)
91 , damage(damage)
92 , inhaling(false) {
93 }
94
95 InhaleNeed::~InhaleNeed() {
96 }
97
98 void InhaleNeed::ApplyEffect(Creature &c, double dt) {
99         if (!IsSatisfied()) {
100                 inhaling = true;
101         }
102         if (inhaling) {
103                 if (c.GetSituation().OnPlanet() && c.GetSituation().GetPlanet().Atmosphere() == resource) {
104                         Decrease(speed * dt);
105                         if (value == 0.0) {
106                                 inhaling = false;
107                         }
108                 } else {
109                         // TODO: panic
110                 }
111         }
112         if (IsCritical()) {
113                 c.Hurt(damage * dt);
114         }
115 }
116
117 }
118 }