summary refs log tree commit diff stats
path: root/src/systems/pondering.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2018-04-28 09:22:44 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2018-04-28 09:22:44 -0400
commit8016a7146fec3f6f43ca05723441750e5aae3d4d (patch)
tree0d527c1af80cf9ac34a027f9ee6f1acbb95db9f4 /src/systems/pondering.cpp
parentf782b81ba10c9b7a1e221b16de0aaa7b6c521729 (diff)
downloadtherapy-8016a7146fec3f6f43ca05723441750e5aae3d4d.tar.gz
therapy-8016a7146fec3f6f43ca05723441750e5aae3d4d.tar.bz2
therapy-8016a7146fec3f6f43ca05723441750e5aae3d4d.zip
Restructured the way the world is loaded
The World class was removed and replaced by the RealizingSystem and RealizableComponent. The realizable entity is intended to be a singleton and to represent the world. The Map class was also removed and integrated into the MappableComponent.

These changes are to facilitate implementation of map objects without needing special intermediary objects (including the Map class). Now, map entities are created as soon as the world is created, and map object entities will be as well. They will simply be deactivated while the map is not active. Multiple players are now slightly better supported, which will be important in the future.

This will likely become inefficient as the world becomes bigger, and some sort of sector-loading process will have to be designed. This also reduces the usefulness of EntityManager's entity-searching capabilities (which are not the most efficiently implemented currently anyway), and will likely in the future require some added functionality to better search subsets of entities.

A lot of the components were also rewritten to use bare member variables instead of accessor methods, as they never had special functionality and just took up space. These components were also documented.
Diffstat (limited to 'src/systems/pondering.cpp')
-rw-r--r--src/systems/pondering.cpp354
1 files changed, 199 insertions, 155 deletions
diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp index 02d5cfc..4ae6176 100644 --- a/src/systems/pondering.cpp +++ b/src/systems/pondering.cpp
@@ -5,149 +5,153 @@
5#include "components/transformable.h" 5#include "components/transformable.h"
6#include "components/orientable.h" 6#include "components/orientable.h"
7#include "components/mappable.h" 7#include "components/mappable.h"
8#include "components/realizable.h"
9#include "components/playable.h"
8#include "systems/orienting.h" 10#include "systems/orienting.h"
9#include "systems/playing.h" 11#include "systems/playing.h"
12#include "systems/realizing.h"
10#include "consts.h" 13#include "consts.h"
11#include "collision.h" 14#include "collision.h"
12 15
13void PonderingSystem::tick(double dt) 16void PonderingSystem::tick(double dt)
14{ 17{
18 auto& realizable = game_.getEntityManager().
19 getComponent<RealizableComponent>(
20 game_.getSystemManager().getSystem<RealizingSystem>().getSingleton());
21
22 id_type mapEntity = realizable.activeMap;
23
24 auto& mappable = game_.getEntityManager().
25 getComponent<MappableComponent>(mapEntity);
26
15 auto entities = game_.getEntityManager().getEntitiesWithComponents< 27 auto entities = game_.getEntityManager().getEntitiesWithComponents<
16 PonderableComponent, 28 PonderableComponent,
17 TransformableComponent>(); 29 TransformableComponent>();
18 30
19 auto maps = game_.getEntityManager().getEntitiesWithComponents<
20 MappableComponent>();
21
22 for (id_type entity : entities) 31 for (id_type entity : entities)
23 { 32 {
24 auto& transformable = game_.getEntityManager().
25 getComponent<TransformableComponent>(entity);
26
27 auto& ponderable = game_.getEntityManager(). 33 auto& ponderable = game_.getEntityManager().
28 getComponent<PonderableComponent>(entity); 34 getComponent<PonderableComponent>(entity);
29 35
30 if (ponderable.isFrozen()) 36 if (!ponderable.active || ponderable.frozen)
31 { 37 {
32 continue; 38 continue;
33 } 39 }
34 40
35 // Accelerate 41 auto& transformable = game_.getEntityManager().
36 ponderable.setVelocityX( 42 getComponent<TransformableComponent>(entity);
37 ponderable.getVelocityX() + ponderable.getAccelX() * dt);
38 43
39 ponderable.setVelocityY( 44 // Accelerate
40 ponderable.getVelocityY() + ponderable.getAccelY() * dt); 45 ponderable.velX += ponderable.accelX * dt;
46 ponderable.velY += ponderable.accelY * dt;
41 47
42 if ((ponderable.getType() == PonderableComponent::Type::freefalling) 48 if ((ponderable.type == PonderableComponent::Type::freefalling)
43 && (ponderable.getVelocityY() > TERMINAL_VELOCITY)) 49 && (ponderable.velY > TERMINAL_VELOCITY))
44 { 50 {
45 ponderable.setVelocityY(TERMINAL_VELOCITY); 51 ponderable.velY = TERMINAL_VELOCITY;
46 } 52 }
47 53
48 const double oldX = transformable.getX(); 54 const double oldX = transformable.x;
49 const double oldY = transformable.getY(); 55 const double oldY = transformable.y;
50 const double oldRight = oldX + transformable.getW(); 56 const double oldRight = oldX + transformable.w;
51 const double oldBottom = oldY + transformable.getH(); 57 const double oldBottom = oldY + transformable.h;
52 58
53 double newX = oldX + ponderable.getVelocityX() * dt; 59 double newX = oldX + ponderable.velX * dt;
54 double newY = oldY + ponderable.getVelocityY() * dt; 60 double newY = oldY + ponderable.velY * dt;
55 61
56 bool oldGrounded = ponderable.isGrounded(); 62 bool oldGrounded = ponderable.grounded;
57 ponderable.setGrounded(false); 63 ponderable.grounded = false;
58 64
59 std::priority_queue<Collision> collisions; 65 std::priority_queue<Collision> collisions;
60 66
61 // Find collisions 67 // Find collisions
62 for (id_type mapEntity : maps) 68 if (newX < oldX)
63 { 69 {
64 auto& mappable = game_.getEntityManager(). 70 for (auto it = mappable.leftBoundaries.lower_bound(oldX);
65 getComponent<MappableComponent>(mapEntity); 71 (it != std::end(mappable.leftBoundaries)) && (it->first >= newX);
66 72 it++)
67 if (newX < oldX)
68 { 73 {
69 for (auto it = mappable.getLeftBoundaries().lower_bound(oldX); 74 if ((oldBottom > it->second.lower)
70 (it != std::end(mappable.getLeftBoundaries())) && (it->first >= newX); 75 && (oldY < it->second.upper))
71 it++)
72 { 76 {
73 if ((oldBottom > it->second.getLower()) 77 // We have a collision!
74 && (oldY < it->second.getUpper())) 78 collisions.emplace(
75 { 79 mapEntity,
76 // We have a collision! 80 Direction::left,
77 collisions.emplace( 81 it->second.type,
78 mapEntity, 82 it->first,
79 Direction::left, 83 it->second.lower,
80 it->second.getType(), 84 it->second.upper);
81 it->first,
82 it->second.getLower(),
83 it->second.getUpper());
84 }
85 } 85 }
86 } else if (newX > oldX) 86 }
87 } else if (newX > oldX)
88 {
89 for (auto it = mappable.rightBoundaries.lower_bound(oldRight);
90 (it != std::end(mappable.rightBoundaries))
91 && (it->first <= (newX + transformable.w));
92 it++)
87 { 93 {
88 for (auto it = mappable.getRightBoundaries().lower_bound(oldRight); 94 if ((oldBottom > it->second.lower)
89 (it != std::end(mappable.getRightBoundaries())) 95 && (oldY < it->second.upper))
90 && (it->first <= (newX + transformable.getW()));
91 it++)
92 { 96 {
93 if ((oldBottom > it->second.getLower()) 97 // We have a collision!
94 && (oldY < it->second.getUpper())) 98 collisions.emplace(
95 { 99 mapEntity,
96 // We have a collision! 100 Direction::right,
97 collisions.emplace( 101 it->second.type,
98 mapEntity, 102 it->first,
99 Direction::right, 103 it->second.lower,
100 it->second.getType(), 104 it->second.upper);
101 it->first,
102 it->second.getLower(),
103 it->second.getUpper());
104 }
105 } 105 }
106 } 106 }
107 }
107 108
108 if (newY < oldY) 109 if (newY < oldY)
110 {
111 for (auto it = mappable.upBoundaries.lower_bound(oldY);
112 (it != std::end(mappable.upBoundaries)) && (it->first >= newY);
113 it++)
109 { 114 {
110 for (auto it = mappable.getUpBoundaries().lower_bound(oldY); 115 if ((oldRight > it->second.lower)
111 (it != std::end(mappable.getUpBoundaries())) && (it->first >= newY); 116 && (oldX < it->second.upper))
112 it++)
113 { 117 {
114 if ((oldRight > it->second.getLower()) 118 // We have a collision!
115 && (oldX < it->second.getUpper())) 119 collisions.emplace(
116 { 120 mapEntity,
117 // We have a collision! 121 Direction::up,
118 collisions.emplace( 122 it->second.type,
119 mapEntity, 123 it->first,
120 Direction::up, 124 it->second.lower,
121 it->second.getType(), 125 it->second.upper);
122 it->first,
123 it->second.getLower(),
124 it->second.getUpper());
125 }
126 } 126 }
127 } else if (newY > oldY) 127 }
128 } else if (newY > oldY)
129 {
130 for (auto it = mappable.downBoundaries.lower_bound(oldBottom);
131 (it != std::end(mappable.downBoundaries))
132 && (it->first <= (newY + transformable.h));
133 it++)
128 { 134 {
129 for (auto it = mappable.getDownBoundaries().lower_bound(oldBottom); 135 if ((oldRight > it->second.lower)
130 (it != std::end(mappable.getDownBoundaries())) 136 && (oldX < it->second.upper))
131 && (it->first <= (newY + transformable.getH()));
132 it++)
133 { 137 {
134 if ((oldRight > it->second.getLower()) 138 // We have a collision!
135 && (oldX < it->second.getUpper())) 139 collisions.emplace(
136 { 140 mapEntity,
137 // We have a collision! 141 Direction::down,
138 collisions.emplace( 142 it->second.type,
139 mapEntity, 143 it->first,
140 Direction::down, 144 it->second.lower,
141 it->second.getType(), 145 it->second.upper);
142 it->first,
143 it->second.getLower(),
144 it->second.getUpper());
145 }
146 } 146 }
147 } 147 }
148 } 148 }
149 149
150 // Process collisions in order of priority 150 // Process collisions in order of priority
151 bool adjacentlyWarping = false;
152 Direction adjWarpDir;
153 size_t adjWarpMapId;
154
151 while (!collisions.empty()) 155 while (!collisions.empty())
152 { 156 {
153 Collision collision = collisions.top(); 157 Collision collision = collisions.top();
@@ -157,8 +161,8 @@ void PonderingSystem::tick(double dt)
157 if (!collision.isColliding( 161 if (!collision.isColliding(
158 newX, 162 newX,
159 newY, 163 newY,
160 transformable.getW(), 164 transformable.w,
161 transformable.getH())) 165 transformable.h))
162 { 166 {
163 continue; 167 continue;
164 } 168 }
@@ -201,33 +205,33 @@ void PonderingSystem::tick(double dt)
201 { 205 {
202 auto& mappable = game_.getEntityManager(). 206 auto& mappable = game_.getEntityManager().
203 getComponent<MappableComponent>(collision.getCollider()); 207 getComponent<MappableComponent>(collision.getCollider());
204 const Map& map = game_.getWorld().getMap(mappable.getMapId()); 208
205 auto& adj = [&] () -> const Map::Adjacent& { 209 auto& adj = [&] () -> const MappableComponent::Adjacent& {
206 switch (collision.getDirection()) 210 switch (collision.getDirection())
207 { 211 {
208 case Direction::left: return map.getLeftAdjacent(); 212 case Direction::left: return mappable.leftAdjacent;
209 case Direction::right: return map.getRightAdjacent(); 213 case Direction::right: return mappable.rightAdjacent;
210 case Direction::up: return map.getUpAdjacent(); 214 case Direction::up: return mappable.upAdjacent;
211 case Direction::down: return map.getDownAdjacent(); 215 case Direction::down: return mappable.downAdjacent;
212 } 216 }
213 }(); 217 }();
214 218
215 switch (adj.getType()) 219 switch (adj.type)
216 { 220 {
217 case Map::Adjacent::Type::wall: 221 case MappableComponent::Adjacent::Type::wall:
218 { 222 {
219 touchedWall = true; 223 touchedWall = true;
220 224
221 break; 225 break;
222 } 226 }
223 227
224 case Map::Adjacent::Type::wrap: 228 case MappableComponent::Adjacent::Type::wrap:
225 { 229 {
226 switch (collision.getDirection()) 230 switch (collision.getDirection())
227 { 231 {
228 case Direction::left: 232 case Direction::left:
229 { 233 {
230 newX = GAME_WIDTH + WALL_GAP - transformable.getW(); 234 newX = GAME_WIDTH + WALL_GAP - transformable.w;
231 235
232 break; 236 break;
233 } 237 }
@@ -241,8 +245,7 @@ void PonderingSystem::tick(double dt)
241 245
242 case Direction::up: 246 case Direction::up:
243 { 247 {
244 newY = MAP_HEIGHT * TILE_HEIGHT + WALL_GAP - 248 newY = MAP_HEIGHT * TILE_HEIGHT + WALL_GAP - transformable.h;
245 transformable.getH();
246 249
247 break; 250 break;
248 } 251 }
@@ -256,46 +259,22 @@ void PonderingSystem::tick(double dt)
256 } 259 }
257 } 260 }
258 261
259 case Map::Adjacent::Type::warp: 262 case MappableComponent::Adjacent::Type::warp:
260 { 263 {
261 double warpX = newX; 264 if (game_.getEntityManager().
262 double warpY = newY; 265 hasComponent<PlayableComponent>(entity))
263
264 switch (collision.getDirection())
265 { 266 {
266 case Direction::left: 267 adjacentlyWarping = true;
267 { 268 adjWarpDir = collision.getDirection();
268 warpX = GAME_WIDTH + WALL_GAP - transformable.getW(); 269 adjWarpMapId = adj.mapId;
269
270 break;
271 }
272
273 case Direction::right:
274 {
275 warpX = -WALL_GAP;
276
277 break;
278 }
279
280 case Direction::up:
281 {
282 warpY = MAP_HEIGHT * TILE_HEIGHT - transformable.getH();
283
284 break;
285 }
286
287 case Direction::down:
288 {
289 warpY = -WALL_GAP;
290
291 break;
292 }
293 } 270 }
294 271
295 game_.getSystemManager().getSystem<PlayingSystem>(). 272 break;
296 changeMap(adj.getMapId(), warpX, warpY); 273 }
297 274
298 stopProcessing = true; 275 case MappableComponent::Adjacent::Type::reverse:
276 {
277 // TODO: not yet implemented.
299 278
300 break; 279 break;
301 } 280 }
@@ -306,7 +285,13 @@ void PonderingSystem::tick(double dt)
306 285
307 case Collision::Type::danger: 286 case Collision::Type::danger:
308 { 287 {
309 game_.getSystemManager().getSystem<PlayingSystem>().die(); 288 if (game_.getEntityManager().
289 hasComponent<PlayableComponent>(entity))
290 {
291 game_.getSystemManager().getSystem<PlayingSystem>().die(entity);
292
293 adjacentlyWarping = false;
294 }
310 295
311 stopProcessing = true; 296 stopProcessing = true;
312 297
@@ -333,15 +318,15 @@ void PonderingSystem::tick(double dt)
333 case Direction::left: 318 case Direction::left:
334 { 319 {
335 newX = collision.getAxis(); 320 newX = collision.getAxis();
336 ponderable.setVelocityX(0.0); 321 ponderable.velX = 0.0;
337 322
338 break; 323 break;
339 } 324 }
340 325
341 case Direction::right: 326 case Direction::right:
342 { 327 {
343 newX = collision.getAxis() - transformable.getW(); 328 newX = collision.getAxis() - transformable.w;
344 ponderable.setVelocityX(0.0); 329 ponderable.velX = 0.0;
345 330
346 break; 331 break;
347 } 332 }
@@ -349,16 +334,16 @@ void PonderingSystem::tick(double dt)
349 case Direction::up: 334 case Direction::up:
350 { 335 {
351 newY = collision.getAxis(); 336 newY = collision.getAxis();
352 ponderable.setVelocityY(0.0); 337 ponderable.velY = 0.0;
353 338
354 break; 339 break;
355 } 340 }
356 341
357 case Direction::down: 342 case Direction::down:
358 { 343 {
359 newY = collision.getAxis() - transformable.getH(); 344 newY = collision.getAxis() - transformable.h;
360 ponderable.setVelocityY(0.0); 345 ponderable.velY = 0.0;
361 ponderable.setGrounded(true); 346 ponderable.grounded = true;
362 347
363 break; 348 break;
364 } 349 }
@@ -367,8 +352,8 @@ void PonderingSystem::tick(double dt)
367 } 352 }
368 353
369 // Move 354 // Move
370 transformable.setX(newX); 355 transformable.x = newX;
371 transformable.setY(newY); 356 transformable.y = newY;
372 357
373 // Perform cleanup for orientable entites 358 // Perform cleanup for orientable entites
374 if (game_.getEntityManager().hasComponent<OrientableComponent>(entity)) 359 if (game_.getEntityManager().hasComponent<OrientableComponent>(entity))
@@ -377,9 +362,9 @@ void PonderingSystem::tick(double dt)
377 getComponent<OrientableComponent>(entity); 362 getComponent<OrientableComponent>(entity);
378 363
379 // Handle changes in groundedness 364 // Handle changes in groundedness
380 if (ponderable.isGrounded() != oldGrounded) 365 if (ponderable.grounded != oldGrounded)
381 { 366 {
382 if (ponderable.isGrounded()) 367 if (ponderable.grounded)
383 { 368 {
384 game_.getSystemManager().getSystem<OrientingSystem>().land(entity); 369 game_.getSystemManager().getSystem<OrientingSystem>().land(entity);
385 } else { 370 } else {
@@ -394,6 +379,51 @@ void PonderingSystem::tick(double dt)
394 orientable.setDropState(OrientableComponent::DropState::none); 379 orientable.setDropState(OrientableComponent::DropState::none);
395 } 380 }
396 } 381 }
382
383 // Move to an adjacent map, if necessary
384 if (adjacentlyWarping)
385 {
386 double warpX = newX;
387 double warpY = newY;
388
389 switch (adjWarpDir)
390 {
391 case Direction::left:
392 {
393 warpX = GAME_WIDTH + WALL_GAP - transformable.w;
394
395 break;
396 }
397
398 case Direction::right:
399 {
400 warpX = -WALL_GAP;
401
402 break;
403 }
404
405 case Direction::up:
406 {
407 warpY = MAP_HEIGHT * TILE_HEIGHT - transformable.h;
408
409 break;
410 }
411
412 case Direction::down:
413 {
414 warpY = -WALL_GAP;
415
416 break;
417 }
418 }
419
420 game_.getSystemManager().getSystem<PlayingSystem>().
421 changeMap(
422 entity,
423 adjWarpMapId,
424 warpX,
425 warpY);
426 }
397 } 427 }
398} 428}
399 429
@@ -406,6 +436,20 @@ void PonderingSystem::initializeBody(
406 436
407 if (type == PonderableComponent::Type::freefalling) 437 if (type == PonderableComponent::Type::freefalling)
408 { 438 {
409 ponderable.setAccelY(NORMAL_GRAVITY); 439 ponderable.accelY = NORMAL_GRAVITY;
410 } 440 }
411} 441}
442
443void PonderingSystem::initPrototype(id_type prototype)
444{
445 auto& ponderable = game_.getEntityManager().
446 getComponent<PonderableComponent>(prototype);
447
448 ponderable.velX = 0.0;
449 ponderable.velY = 0.0;
450 ponderable.accelX = 0.0;
451 ponderable.accelY = 0.0;
452 ponderable.grounded = false;
453 ponderable.frozen = false;
454 ponderable.collidable = true;
455}