]> git.localhorst.tv Git - blobs.git/blob - src/world/creature.cpp
figure out our creature's metabolism
[blobs.git] / src / world / creature.cpp
1 #include "Creature.hpp"
2
3 #include "Body.hpp"
4 #include "Planet.hpp"
5 #include "TileType.hpp"
6 #include "../app/Assets.hpp"
7
8 #include <glm/gtx/transform.hpp>
9
10 #include <iostream>
11
12
13 namespace blobs {
14 namespace world {
15
16 Creature::Creature()
17 : body(nullptr)
18 , surface(0)
19 , position()
20 , breathes(-1)
21 , drinks(-1)
22 , eats(-1)
23 , vao() {
24 }
25
26 Creature::~Creature() {
27 }
28
29
30 glm::dmat4 Creature::LocalTransform() noexcept {
31         // TODO: surface transform
32         constexpr double half_height = 0.25;
33         return glm::translate(glm::dvec3(position.x, position.y, position.z + body->Radius() + half_height))
34                 * glm::scale(glm::dvec3(half_height, half_height, half_height));
35 }
36
37 void Creature::BuildVAO() {
38         vao.Bind();
39         vao.BindAttributes();
40         vao.EnableAttribute(0);
41         vao.EnableAttribute(1);
42         vao.EnableAttribute(2);
43         vao.AttributePointer<glm::vec3>(0, false, offsetof(Attributes, position));
44         vao.AttributePointer<glm::vec3>(1, false, offsetof(Attributes, normal));
45         vao.AttributePointer<glm::vec3>(2, false, offsetof(Attributes, texture));
46         vao.ReserveAttributes(6 * 4, GL_STATIC_DRAW);
47         {
48                 auto attrib = vao.MapAttributes(GL_WRITE_ONLY);
49                 const float offset = 1.0f;
50                 for (int surface = 0; surface < 6; ++surface) {
51                         const float tex_u_begin = surface < 3 ? 1.0f : 0.0f;
52                         const float tex_u_end = surface < 3 ? 0.0f : 1.0f;
53
54                         attrib[4 * surface + 0].position[(surface + 0) % 3] = -offset;
55                         attrib[4 * surface + 0].position[(surface + 1) % 3] = -offset;
56                         attrib[4 * surface + 0].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
57                         attrib[4 * surface + 0].normal[(surface + 0) % 3] = 0.0f;
58                         attrib[4 * surface + 0].normal[(surface + 1) % 3] = 0.0f;
59                         attrib[4 * surface + 0].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
60                         attrib[4 * surface + 0].texture.x = tex_u_begin;
61                         attrib[4 * surface + 0].texture.y = 1.0f;
62                         attrib[4 * surface + 0].texture.z = surface;
63
64                         attrib[4 * surface + 1].position[(surface + 0) % 3] = -offset;
65                         attrib[4 * surface + 1].position[(surface + 1) % 3] =  offset;
66                         attrib[4 * surface + 1].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
67                         attrib[4 * surface + 1].normal[(surface + 0) % 3] = 0.0f;
68                         attrib[4 * surface + 1].normal[(surface + 1) % 3] = 0.0f;
69                         attrib[4 * surface + 1].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
70                         attrib[4 * surface + 1].texture.x = tex_u_end;
71                         attrib[4 * surface + 1].texture.y = 1.0f;
72                         attrib[4 * surface + 1].texture.z = surface;
73
74                         attrib[4 * surface + 2].position[(surface + 0) % 3] =  offset;
75                         attrib[4 * surface + 2].position[(surface + 1) % 3] = -offset;
76                         attrib[4 * surface + 2].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
77                         attrib[4 * surface + 2].normal[(surface + 0) % 3] = 0.0f;
78                         attrib[4 * surface + 2].normal[(surface + 1) % 3] = 0.0f;
79                         attrib[4 * surface + 2].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
80                         attrib[4 * surface + 2].texture.x = tex_u_begin;
81                         attrib[4 * surface + 2].texture.y = 0.0f;
82                         attrib[4 * surface + 2].texture.z = surface;
83
84                         attrib[4 * surface + 3].position[(surface + 0) % 3] = offset;
85                         attrib[4 * surface + 3].position[(surface + 1) % 3] = offset;
86                         attrib[4 * surface + 3].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
87                         attrib[4 * surface + 3].normal[(surface + 0) % 3] = 0.0f;
88                         attrib[4 * surface + 3].normal[(surface + 1) % 3] = 0.0f;
89                         attrib[4 * surface + 3].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
90                         attrib[4 * surface + 3].texture.x = tex_u_end;
91                         attrib[4 * surface + 3].texture.y = 0.0f;
92                         attrib[4 * surface + 3].texture.z = surface;
93                 }
94         }
95         vao.BindElements();
96         vao.ReserveElements(6 * 6, GL_STATIC_DRAW);
97         {
98                 auto element = vao.MapElements(GL_WRITE_ONLY);
99                 for (int surface = 0; surface < 3; ++surface) {
100                         element[6 * surface + 0] = 4 * surface + 0;
101                         element[6 * surface + 1] = 4 * surface + 2;
102                         element[6 * surface + 2] = 4 * surface + 1;
103                         element[6 * surface + 3] = 4 * surface + 1;
104                         element[6 * surface + 4] = 4 * surface + 2;
105                         element[6 * surface + 5] = 4 * surface + 3;
106                 }
107                 for (int surface = 3; surface < 6; ++surface) {
108                         element[6 * surface + 0] = 4 * surface + 0;
109                         element[6 * surface + 1] = 4 * surface + 1;
110                         element[6 * surface + 2] = 4 * surface + 2;
111                         element[6 * surface + 3] = 4 * surface + 2;
112                         element[6 * surface + 4] = 4 * surface + 1;
113                         element[6 * surface + 5] = 4 * surface + 3;
114                 }
115         }
116         vao.Unbind();
117 }
118
119 void Creature::Draw(app::Assets &assets, graphics::Viewport &viewport) {
120         vao.Bind();
121         vao.DrawTriangles(6 * 6);
122 }
123
124
125 void Spawn(Creature &c, Planet &p, app::Assets &assets) {
126         p.AddCreature(&c);
127         c.Surface(0);
128         c.Position(glm::dvec3(0.0, 0.0, 0.0));
129
130         // probe surrounding area for common resources
131         int start = p.SideLength() / 2 - 2;
132         int end = start + 5;
133         std::map<int, double> yields;
134         for (int y = start; y < end; ++y) {
135                 for (int x = start; x < end; ++x) {
136                         const TileType &t = assets.data.tiles[p.TileAt(0, x, y).type];
137                         for (auto yield : t.resources) {
138                                 yields[yield.resource] += yield.ubiquity;
139                         }
140                 }
141         }
142         int liquid = -1;
143         int solid = -1;
144         for (auto e : yields) {
145                 if (assets.data.resources[e.first].state == Resource::LIQUID) {
146                         if (liquid < 0 || e.second > yields[liquid]) {
147                                 liquid = e.first;
148                         }
149                 } else if (assets.data.resources[e.first].state == Resource::SOLID) {
150                         if (solid < 0 || e.second > yields[solid]) {
151                                 solid = e.first;
152                         }
153                 }
154         }
155
156         if (p.HasAtmosphere()) {
157                 std::cout << "require breathing " << assets.data.resources[p.Atmosphere()].label << std::endl;
158                 c.RequireBreathing(p.Atmosphere());
159         }
160         if (liquid > -1) {
161                 std::cout << "require drinking " << assets.data.resources[liquid].label << std::endl;
162                 c.RequireDrinking(liquid);
163         }
164         if (solid > -1) {
165                 std::cout << "require eating " << assets.data.resources[solid].label << std::endl;
166                 c.RequireEating(solid);
167         }
168 }
169
170 }
171 }