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