summary refs log tree commit diff stats
path: root/src/systems/pondering.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2018-05-17 15:55:37 -0400
committerGitHub <noreply@github.com>2018-05-17 15:55:37 -0400
commit90aadf3844386824140a20d7fbb847bc16009a94 (patch)
tree6f83fce90e71abb22b1a8f3e09c79963b2a34d5d /src/systems/pondering.cpp
parentbc63fa57ced1c7329f7fdcfd168eaf7e290158bc (diff)
parent86f0106d0523825549f1e74b835688c78a10cf6c (diff)
downloadtherapy-90aadf3844386824140a20d7fbb847bc16009a94.tar.gz
therapy-90aadf3844386824140a20d7fbb847bc16009a94.tar.bz2
therapy-90aadf3844386824140a20d7fbb847bc16009a94.zip
Merge pull request #7 from hatkirby/es-rewrite
The ECS rewrite exceeds the original branch in functionality, so it is time to merge it in.
Diffstat (limited to 'src/systems/pondering.cpp')
-rw-r--r--src/systems/pondering.cpp916
1 files changed, 916 insertions, 0 deletions
diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp new file mode 100644 index 0000000..d841679 --- /dev/null +++ b/src/systems/pondering.cpp
@@ -0,0 +1,916 @@
1#include "pondering.h"
2#include <queue>
3#include <algorithm>
4#include "game.h"
5#include "components/ponderable.h"
6#include "components/transformable.h"
7#include "components/orientable.h"
8#include "components/mappable.h"
9#include "components/playable.h"
10#include "systems/orienting.h"
11#include "systems/playing.h"
12#include "systems/realizing.h"
13#include "systems/scripting.h"
14#include "consts.h"
15
16void PonderingSystem::tick(double dt)
17{
18 auto entities = game_.getEntityManager().getEntitiesWithComponents<
19 PonderableComponent,
20 TransformableComponent>();
21
22 for (id_type entity : entities)
23 {
24 auto& ponderable = game_.getEntityManager().
25 getComponent<PonderableComponent>(entity);
26
27 // We will recursively process ferried bodies after their ferries have been
28 // processed, so hold off on processing ferried bodies at the top level.
29 if (ponderable.ferried)
30 {
31 continue;
32 }
33
34 tickBody(entity, dt);
35 }
36}
37
38void PonderingSystem::initializeBody(
39 id_type entity,
40 PonderableComponent::Type type)
41{
42 auto& ponderable = game_.getEntityManager().
43 emplaceComponent<PonderableComponent>(entity, type);
44
45 if (type == PonderableComponent::Type::freefalling)
46 {
47 ponderable.accel.y() = NORMAL_GRAVITY;
48 }
49}
50
51void PonderingSystem::initPrototype(id_type prototype)
52{
53 auto& ponderable = game_.getEntityManager().
54 getComponent<PonderableComponent>(prototype);
55
56 ponderable.vel.x() = 0.0;
57 ponderable.vel.y() = 0.0;
58 ponderable.accel.x() = 0.0;
59 ponderable.accel.y() = 0.0;
60 ponderable.grounded = false;
61 ponderable.frozen = false;
62 ponderable.collidable = true;
63 ponderable.ferried = false;
64 ponderable.passengers.clear();
65}
66
67void PonderingSystem::unferry(id_type entity)
68{
69 auto& ponderable = game_.getEntityManager().
70 getComponent<PonderableComponent>(entity);
71
72 if (ponderable.ferried)
73 {
74 ponderable.ferried = false;
75
76 auto& ferryPonder = game_.getEntityManager().
77 getComponent<PonderableComponent>(ponderable.ferry);
78
79 ferryPonder.passengers.erase(entity);
80 }
81}
82
83void PonderingSystem::tickBody(
84 id_type entity,
85 double dt)
86{
87 auto& ponderable = game_.getEntityManager().
88 getComponent<PonderableComponent>(entity);
89
90 if (!ponderable.active)
91 {
92 return;
93 }
94
95 auto& transformable = game_.getEntityManager().
96 getComponent<TransformableComponent>(entity);
97
98 // Accelerate
99 if (!ponderable.frozen)
100 {
101 ponderable.vel += ponderable.accel * dt;
102
103 if ((ponderable.type == PonderableComponent::Type::freefalling)
104 && (ponderable.vel.y() > TERMINAL_VELOCITY))
105 {
106 ponderable.vel.y() = TERMINAL_VELOCITY;
107 }
108 }
109
110 // Move
111 vec2d newPos = transformable.pos;
112
113 if (!ponderable.frozen)
114 {
115 newPos += ponderable.vel * dt;
116 }
117
118 CollisionResult result = moveBody(entity, newPos);
119
120 // Perform cleanup for orientable entites
121 bool groundedChanged = (ponderable.grounded != result.grounded);
122 ponderable.grounded = result.grounded;
123
124 if (game_.getEntityManager().hasComponent<OrientableComponent>(entity))
125 {
126 auto& orientable = game_.getEntityManager().
127 getComponent<OrientableComponent>(entity);
128
129 // Handle changes in groundedness
130 if (groundedChanged)
131 {
132 if (ponderable.grounded)
133 {
134 game_.getSystemManager().getSystem<OrientingSystem>().land(entity);
135 } else {
136 game_.getSystemManager().
137 getSystem<OrientingSystem>().startFalling(entity);
138 }
139 }
140
141 // Complete dropping, if necessary
142 if (orientable.getDropState() == OrientableComponent::DropState::active)
143 {
144 orientable.setDropState(OrientableComponent::DropState::none);
145 }
146 }
147
148 // Ferry or unferry as necessary
149 if ((ponderable.type == PonderableComponent::Type::freefalling) &&
150 groundedChanged)
151 {
152 if (ponderable.grounded &&
153 game_.getEntityManager().
154 hasComponent<PonderableComponent>(result.groundEntity))
155 {
156 // The body is now being ferried
157 auto& ferryPonder = game_.getEntityManager().
158 getComponent<PonderableComponent>(result.groundEntity);
159
160 ponderable.ferried = true;
161 ponderable.ferry = result.groundEntity;
162 ponderable.ferrySide = Direction::up;
163
164 ferryPonder.passengers.insert(entity);
165 } else if (ponderable.ferried)
166 {
167 // The body is no longer being ferried
168 unferry(entity);
169 }
170 }
171
172 // Handle ferry passengers
173 std::set<id_type> passengers = ponderable.passengers;
174
175 for (id_type passenger : passengers)
176 {
177 tickBody(passenger, dt);
178 }
179}
180
181PonderingSystem::CollisionResult PonderingSystem::moveBody(
182 id_type entity,
183 vec2d newPos)
184{
185 auto& ponderable = game_.getEntityManager().
186 getComponent<PonderableComponent>(entity);
187
188 CollisionResult result;
189
190 if (ponderable.collidable)
191 {
192 result = detectCollisions(entity, newPos);
193 } else {
194 result.pos = newPos;
195 }
196
197 if (!ponderable.frozen)
198 {
199 auto& transformable = game_.getEntityManager().
200 getComponent<TransformableComponent>(entity);
201
202 vec2d delta = result.pos - transformable.pos;
203
204 // Move.
205 transformable.pos = result.pos;
206
207 // Stop if the entity hit a wall.
208 if (result.blockedHoriz)
209 {
210 ponderable.vel.x() = 0.0;
211 }
212
213 if (result.blockedVert)
214 {
215 ponderable.vel.y() = 0.0;
216 }
217
218 // Move ferry passengers by the appropriate amount.
219 auto passengers = ponderable.passengers;
220
221 for (id_type passenger : passengers)
222 {
223 auto& passTrans = game_.getEntityManager().
224 getComponent<TransformableComponent>(passenger);
225
226 moveBody(passenger, passTrans.pos + delta);
227 }
228
229 // Move to an adjacent map, if necessary
230 if (result.adjacentlyWarping)
231 {
232 vec2d warpPos = result.pos;
233
234 switch (result.adjWarpDir)
235 {
236 case Direction::left:
237 {
238 warpPos.x() = GAME_WIDTH + WALL_GAP - transformable.size.w();
239
240 break;
241 }
242
243 case Direction::right:
244 {
245 warpPos.x() = -WALL_GAP;
246
247 break;
248 }
249
250 case Direction::up:
251 {
252 warpPos.y() = MAP_HEIGHT * TILE_HEIGHT - transformable.size.h();
253
254 break;
255 }
256
257 case Direction::down:
258 {
259 warpPos.y() = -WALL_GAP;
260
261 break;
262 }
263 }
264
265 game_.getSystemManager().getSystem<PlayingSystem>().
266 changeMap(
267 entity,
268 result.adjWarpMapId,
269 warpPos);
270 }
271 }
272
273 return result;
274}
275
276namespace CollisionParams {
277
278 template <typename HorizVert>
279 class Desc : public HorizVert {
280 public:
281
282 inline static bool AtLeastInAxisSweep(
283 double boundaryAxis,
284 double entityAxis)
285 {
286 return (boundaryAxis >= entityAxis);
287 }
288
289 inline static bool IsPastAxis(
290 double colliderAxis,
291 double entityAxis)
292 {
293 return (colliderAxis > entityAxis);
294 }
295
296 inline static double EntityAxis(const vec2d& pos, const vec2i& size)
297 {
298 return HorizVert::AxisLower(pos);
299 }
300
301 inline static double ObjectAxis(const vec2d& pos, const vec2i& size)
302 {
303 return HorizVert::AxisUpper(pos, size);
304 }
305
306 inline static bool Closer(double left, double right)
307 {
308 return right < left;
309 }
310 };
311
312 template <typename HorizVert>
313 class Asc : public HorizVert {
314 public:
315
316 inline static bool AtLeastInAxisSweep(
317 double boundaryAxis,
318 double entityAxis)
319 {
320 return (boundaryAxis <= entityAxis);
321 }
322
323 inline static bool IsPastAxis(
324 double colliderAxis,
325 double entityAxis)
326 {
327 return (colliderAxis < entityAxis);
328 }
329
330 inline static double EntityAxis(const vec2d& pos, const vec2i& size)
331 {
332 return HorizVert::AxisUpper(pos, size);
333 }
334
335 inline static double ObjectAxis(const vec2d& pos, const vec2i& size)
336 {
337 return HorizVert::AxisLower(pos);
338 }
339
340 inline static bool Closer(double left, double right)
341 {
342 return left < right;
343 }
344 };
345
346 template <size_t Axis, size_t NonAxis>
347 class HorizVert {
348 public:
349
350 inline static double AxisLower(const vec2d& pos)
351 {
352 return pos.coords[Axis];
353 }
354
355 inline static double AxisUpper(const vec2d& pos, const vec2i& size)
356 {
357 return pos.coords[Axis] + size.coords[Axis];
358 }
359
360 inline static double NonAxisLower(const vec2d& pos)
361 {
362 return pos.coords[NonAxis];
363 }
364
365 inline static double NonAxisUpper(const vec2d& pos, const vec2i& size)
366 {
367 return pos.coords[NonAxis] + size.coords[NonAxis];
368 }
369
370 };
371
372 using Horizontal = HorizVert<0, 1>;
373 using Vertical = HorizVert<1, 0>;
374
375 template <Direction dir, typename AscDesc>
376 class DetectCollisions : public AscDesc {
377 public:
378
379 static const Direction Dir = dir;
380
381 inline static double EntityAxis(const vec2d& pos, const vec2i& size)
382 {
383 return AscDesc::EntityAxis(pos, size);
384 }
385
386 inline static double ObjectAxis(const vec2d& pos, const vec2i& size)
387 {
388 return AscDesc::ObjectAxis(pos, size);
389 }
390
391 inline static double EntityAxis(const TransformableComponent& transformable)
392 {
393 return AscDesc::EntityAxis(transformable.pos, transformable.size);
394 }
395
396 inline static double ObjectAxis(const TransformableComponent& transformable)
397 {
398 return AscDesc::ObjectAxis(transformable.pos, transformable.size);
399 }
400 };
401
402 class Left : public DetectCollisions<Direction::left, Desc<Horizontal>> {
403 public:
404
405 inline static const MappableComponent::desc_boundaries_type& MapBoundaries(
406 const MappableComponent& mappable)
407 {
408 return mappable.leftBoundaries;
409 }
410 };
411
412 class Right : public DetectCollisions<Direction::right, Asc<Horizontal>> {
413 public:
414
415 inline static const MappableComponent::asc_boundaries_type& MapBoundaries(
416 const MappableComponent& mappable)
417 {
418 return mappable.rightBoundaries;
419 }
420 };
421
422 class Up : public DetectCollisions<Direction::up, Desc<Vertical>> {
423 public:
424
425 inline static const MappableComponent::desc_boundaries_type& MapBoundaries(
426 const MappableComponent& mappable)
427 {
428 return mappable.upBoundaries;
429 }
430 };
431
432 class Down : public DetectCollisions<Direction::down, Asc<Vertical>> {
433 public:
434
435 inline static const MappableComponent::asc_boundaries_type& MapBoundaries(
436 const MappableComponent& mappable)
437 {
438 return mappable.downBoundaries;
439 }
440 };
441};
442
443PonderingSystem::CollisionResult PonderingSystem::detectCollisions(
444 id_type entity,
445 vec2d newPos)
446{
447 auto& transformable = game_.getEntityManager().
448 getComponent<TransformableComponent>(entity);
449
450 CollisionResult result;
451 result.pos.x() = newPos.x();
452 result.pos.y() = transformable.pos.y();
453
454 // Find horizontal collisions.
455 if (result.pos.x() < transformable.pos.x())
456 {
457 detectCollisionsInDirection<CollisionParams::Left>(entity, result);
458 } else if (result.pos.x() > transformable.pos.x())
459 {
460 detectCollisionsInDirection<CollisionParams::Right>(entity, result);
461 }
462
463 // Find vertical collisions
464 if (!result.stopProcessing)
465 {
466 result.pos.y() = newPos.y();
467 result.touchedWall = false;
468
469 if (result.pos.y() < transformable.pos.y())
470 {
471 detectCollisionsInDirection<CollisionParams::Up>(entity, result);
472 } else if (result.pos.y() > transformable.pos.y())
473 {
474 detectCollisionsInDirection<CollisionParams::Down>(entity, result);
475 }
476 }
477
478 return result;
479}
480
481template <typename Param>
482void PonderingSystem::detectCollisionsInDirection(
483 id_type entity,
484 CollisionResult& result)
485{
486 // Get map data.
487 id_type mapEntity =
488 game_.getSystemManager().getSystem<RealizingSystem>().getActiveMap();
489
490 auto& mappable = game_.getEntityManager().
491 getComponent<MappableComponent>(mapEntity);
492
493 // Get old location.
494 auto& transform = game_.getEntityManager().
495 getComponent<TransformableComponent>(entity);
496
497 auto& ponderable = game_.getEntityManager().
498 getComponent<PonderableComponent>(entity);
499
500 bool boundaryCollision = false;
501
502 auto boundaries = Param::MapBoundaries(mappable);
503 auto it = boundaries.lower_bound(Param::EntityAxis(transform));
504
505 // Find the axis distance of the closest environmental boundary.
506 for (;
507 (it != std::end(boundaries)) &&
508 Param::AtLeastInAxisSweep(
509 it->first,
510 Param::EntityAxis(result.pos, transform.size));
511 it++)
512 {
513 // Check that the boundary is in range for the other axis.
514 if ((Param::NonAxisUpper(result.pos, transform.size) > it->second.lower) &&
515 (Param::NonAxisLower(result.pos) < it->second.upper))
516 {
517 // We have a collision!
518 boundaryCollision = true;
519
520 break;
521 }
522 }
523
524 // Find the results of pretending to move the entity's passengers, if there
525 // are any.
526 vec2d delta = result.pos - transform.pos;
527 std::map<id_type, CollisionResult> passResults;
528
529 for (id_type passenger : ponderable.passengers)
530 {
531 auto& passPonder = game_.getEntityManager().
532 getComponent<PonderableComponent>(passenger);
533
534 if (passPonder.ferrySide == Param::Dir)
535 {
536 auto& passTrans = game_.getEntityManager().
537 getComponent<TransformableComponent>(passenger);
538
539 passResults[passenger] =
540 detectCollisions(passenger, passTrans.pos + delta);
541 }
542 }
543
544 // Find a list of potential colliders, sorted so that the closest is
545 // first.
546 std::vector<id_type> colliders;
547
548 auto entities = game_.getEntityManager().getEntitiesWithComponents<
549 PonderableComponent,
550 TransformableComponent>();
551
552 for (id_type collider : entities)
553 {
554 // Can't collide with self.
555 if (collider == entity)
556 {
557 continue;
558 }
559
560 auto& colliderPonder = game_.getEntityManager().
561 getComponent<PonderableComponent>(collider);
562
563 // Only check objects that are active and collidable.
564 if (!colliderPonder.active || !colliderPonder.collidable)
565 {
566 continue;
567 }
568
569 // If the collider is a passenger of the entity, pretend that it has already
570 // moved.
571 auto& colliderTrans = game_.getEntityManager().
572 getComponent<TransformableComponent>(collider);
573
574 vec2d colliderPos = colliderTrans.pos;
575 vec2i colliderSize = colliderTrans.size;
576
577 if (passResults.count(collider))
578 {
579 colliderPos = passResults[collider].pos;
580 }
581
582 // Check if the entity would move into the potential collider,
583 if (Param::IsPastAxis(
584 Param::ObjectAxis(colliderPos, colliderSize),
585 Param::EntityAxis(result.pos, transform.size)) &&
586 // that it wasn't already colliding,
587 !Param::IsPastAxis(
588 Param::ObjectAxis(colliderPos, colliderSize),
589 Param::EntityAxis(transform)) &&
590 // that the position on the non-axis is in range,
591 (Param::NonAxisUpper(colliderPos, colliderSize) >
592 Param::NonAxisLower(result.pos)) &&
593 (Param::NonAxisLower(colliderPos) <
594 Param::NonAxisUpper(result.pos, transform.size)) &&
595 // and that the collider is not farther away than the environmental
596 // boundary.
597 (!boundaryCollision ||
598 Param::AtLeastInAxisSweep(
599 Param::ObjectAxis(colliderPos, colliderSize),
600 it->first)))
601 {
602 colliders.push_back(collider);
603 }
604 }
605
606 // Sort the potential colliders such that the closest to the axis of movement
607 // is first. When sorting, treat passengers of the entity as having already
608 // moved.
609 std::sort(
610 std::begin(colliders),
611 std::end(colliders),
612 [&] (id_type left, id_type right) {
613 auto& leftTrans = game_.getEntityManager().
614 getComponent<TransformableComponent>(left);
615
616 vec2d leftPos = leftTrans.pos;
617
618 if (passResults.count(left))
619 {
620 leftPos = passResults[left].pos;
621 }
622
623 auto& rightTrans = game_.getEntityManager().
624 getComponent<TransformableComponent>(right);
625
626 vec2d rightPos = rightTrans.pos;
627
628 if (passResults.count(right))
629 {
630 rightPos = passResults[right].pos;
631 }
632
633 return Param::Closer(
634 Param::ObjectAxis(leftPos, leftTrans.size),
635 Param::ObjectAxis(rightPos, rightTrans.size));
636 });
637
638 for (id_type collider : colliders)
639 {
640 auto& colliderTrans = game_.getEntityManager().
641 getComponent<TransformableComponent>(collider);
642
643 // If the collider is a passenger of the entity, pretend that it has already
644 // moved.
645 vec2d colliderPos = colliderTrans.pos;
646 vec2i colliderSize = colliderTrans.size;
647
648 if (passResults.count(collider))
649 {
650 colliderPos = passResults[collider].pos;
651 }
652
653 // Check if the entity would still move into the potential collider.
654 if (!Param::IsPastAxis(
655 Param::ObjectAxis(colliderPos, colliderSize),
656 Param::EntityAxis(result.pos, transform.size)))
657 {
658 break;
659 }
660
661 // TODO: Check if the entity is moving into one of its passengers.
662 auto& colliderPonder = game_.getEntityManager().
663 getComponent<PonderableComponent>(collider);
664
665 processCollision(
666 entity,
667 collider,
668 Param::Dir,
669 colliderPonder.colliderType,
670 Param::ObjectAxis(colliderPos, colliderSize),
671 Param::NonAxisLower(colliderPos),
672 Param::NonAxisUpper(colliderPos, colliderSize),
673 result);
674
675 if (result.stopProcessing)
676 {
677 break;
678 }
679 }
680
681 // If movement hasn't been stopped by an intermediary object, and
682 // collision checking hasn't been stopped, process the environmental
683 // boundaries closest to the entity.
684 if (!result.stopProcessing && !result.touchedWall && boundaryCollision)
685 {
686 double boundaryAxis = it->first;
687
688 for (;
689 (it != std::end(boundaries)) &&
690 (it->first == boundaryAxis);
691 it++)
692 {
693 if ((Param::NonAxisLower(result.pos) < it->second.upper) &&
694 (Param::NonAxisUpper(result.pos, transform.size) > it->second.lower))
695 {
696 processCollision(
697 entity,
698 mapEntity,
699 Param::Dir,
700 it->second.type,
701 it->first,
702 it->second.lower,
703 it->second.upper,
704 result);
705
706 if (result.stopProcessing)
707 {
708 break;
709 }
710 }
711 }
712 }
713}
714
715void PonderingSystem::processCollision(
716 id_type entity,
717 id_type collider,
718 Direction dir,
719 PonderableComponent::Collision type,
720 double axis,
721 double lower,
722 double upper,
723 CollisionResult& result)
724{
725 auto& transformable = game_.getEntityManager().
726 getComponent<TransformableComponent>(entity);
727
728 switch (type)
729 {
730 case PonderableComponent::Collision::wall:
731 {
732 result.touchedWall = true;
733
734 break;
735 }
736
737 case PonderableComponent::Collision::platform:
738 {
739 if (game_.getEntityManager().
740 hasComponent<OrientableComponent>(entity))
741 {
742 auto& orientable = game_.getEntityManager().
743 getComponent<OrientableComponent>(entity);
744
745 if (orientable.getDropState() !=
746 OrientableComponent::DropState::none)
747 {
748 orientable.setDropState(OrientableComponent::DropState::active);
749 } else {
750 result.touchedWall = true;
751 }
752 } else {
753 result.touchedWall = true;
754 }
755
756 break;
757 }
758
759 case PonderableComponent::Collision::adjacency:
760 {
761 auto& mappable = game_.getEntityManager().
762 getComponent<MappableComponent>(collider);
763
764 auto& adj = [&] () -> const MappableComponent::Adjacent& {
765 switch (dir)
766 {
767 case Direction::left: return mappable.leftAdjacent;
768 case Direction::right: return mappable.rightAdjacent;
769 case Direction::up: return mappable.upAdjacent;
770 case Direction::down: return mappable.downAdjacent;
771 }
772 }();
773
774 switch (adj.type)
775 {
776 case MappableComponent::Adjacent::Type::wall:
777 {
778 result.touchedWall = true;
779
780 break;
781 }
782
783 case MappableComponent::Adjacent::Type::wrap:
784 {
785 switch (dir)
786 {
787 case Direction::left:
788 {
789 result.pos.x() = GAME_WIDTH + WALL_GAP - transformable.size.w();
790
791 break;
792 }
793
794 case Direction::right:
795 {
796 result.pos.x() = -WALL_GAP;
797
798 break;
799 }
800
801 case Direction::up:
802 {
803 result.pos.y() =
804 MAP_HEIGHT * TILE_HEIGHT + WALL_GAP - transformable.pos.h();
805
806 break;
807 }
808
809 case Direction::down:
810 {
811 result.pos.y() = -WALL_GAP;
812
813 break;
814 }
815 }
816 }
817
818 case MappableComponent::Adjacent::Type::warp:
819 {
820 if (game_.getEntityManager().
821 hasComponent<PlayableComponent>(entity))
822 {
823 result.adjacentlyWarping = true;
824 result.adjWarpDir = dir;
825 result.adjWarpMapId = adj.mapId;
826 }
827
828 break;
829 }
830
831 case MappableComponent::Adjacent::Type::reverse:
832 {
833 // TODO: not yet implemented.
834
835 break;
836 }
837 }
838
839 break;
840 }
841
842 case PonderableComponent::Collision::danger:
843 {
844 if (game_.getEntityManager().
845 hasComponent<PlayableComponent>(entity))
846 {
847 game_.getSystemManager().getSystem<PlayingSystem>().die(entity);
848
849 result.adjacentlyWarping = false;
850 }
851
852 result.stopProcessing = true;
853
854 break;
855 }
856
857 case PonderableComponent::Collision::event:
858 {
859 if (game_.getEntityManager().
860 hasComponent<PlayableComponent>(entity))
861 {
862 game_.getSystemManager().getSystem<ScriptingSystem>().
863 onTouch(collider, entity);
864 }
865
866 break;
867 }
868
869 default:
870 {
871 // Not yet implemented.
872
873 break;
874 }
875 }
876
877 if (!result.stopProcessing && result.touchedWall)
878 {
879 switch (dir)
880 {
881 case Direction::left:
882 {
883 result.pos.x() = axis;
884 result.blockedHoriz = true;
885
886 break;
887 }
888
889 case Direction::right:
890 {
891 result.pos.x() = axis - transformable.size.w();
892 result.blockedHoriz = true;
893
894 break;
895 }
896
897 case Direction::up:
898 {
899 result.pos.y() = axis;
900 result.blockedVert = true;
901
902 break;
903 }
904
905 case Direction::down:
906 {
907 result.pos.y() = axis - transformable.size.h();
908 result.blockedVert = true;
909 result.groundEntity = collider;
910 result.grounded = true;
911
912 break;
913 }
914 }
915 }
916}