summary refs log tree commit diff stats
path: root/src/systems/pondering.cpp
diff options
context:
space:
mode:
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}