summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/behaviour_system.cpp2
-rw-r--r--src/character_system.cpp47
-rw-r--r--src/input_system.cpp18
-rw-r--r--src/transform_system.cpp84
-rw-r--r--src/transform_system.h11
5 files changed, 75 insertions, 87 deletions
diff --git a/src/behaviour_system.cpp b/src/behaviour_system.cpp index f4f7546..ce980f6 100644 --- a/src/behaviour_system.cpp +++ b/src/behaviour_system.cpp
@@ -196,7 +196,7 @@ void BehaviourSystem::createPath(int spriteId) {
196 } 196 }
197 197
198 CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, searchNode.point, newPos, dir); 198 CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, searchNode.point, newPos, dir);
199 if (collision.horiz.blocked || collision.vert.blocked) { 199 if (collision.blocked) {
200 // There isn't actually an edge to this neighbor. 200 // There isn't actually an edge to this neighbor.
201 continue; 201 continue;
202 } 202 }
diff --git a/src/character_system.cpp b/src/character_system.cpp index 548bd9d..10cb06f 100644 --- a/src/character_system.cpp +++ b/src/character_system.cpp
@@ -154,46 +154,35 @@ void CharacterSystem::tick(double dt) {
154 154
155 // Check collision. 155 // Check collision.
156 CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, sprite.loc, pLoc, sprite.movementDir); 156 CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, sprite.loc, pLoc, sprite.movementDir);
157 bool blocked = collision.horiz.blocked || collision.vert.blocked;
158 int colliderSpriteId = (collision.horiz.colliderSprite == -1) ? collision.vert.colliderSprite : collision.horiz.colliderSprite;
159 157
160 if (collision.horiz.blocked && !sprite.clipping) { 158 if (!(collision.blocked && sprite.clipping)) {
161 pLoc.x() = sprite.loc.x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1; 159 pLoc = collision.adjustedLoc;
162 } else if (collision.horiz.colliderSprite != -1) {
163 Sprite& collider = game_.getSprite(collision.horiz.colliderSprite);
164
165 if (collider.walkthroughScript != "") {
166 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), collider.walkthroughScript);
167 }
168 } 160 }
169 161
170 if (collision.vert.blocked && !sprite.clipping) { 162 for (int colliderSpriteId : collision.colliders) {
171 pLoc.y() = sprite.loc.y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1; 163 Sprite& collider = game_.getSprite(colliderSpriteId);
172 } else if (collision.vert.colliderSprite != -1) {
173 Sprite& collider = game_.getSprite(collision.vert.colliderSprite);
174 164
175 if (collider.walkthroughScript != "") { 165 if (!collider.walkthroughScript.empty()) {
176 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), collider.walkthroughScript); 166 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), collider.walkthroughScript);
177 } 167 }
178 }
179 168
180 if (blocked && sprite.characterState == CharacterState::Running && !sprite.clipping) { 169 if (!sprite.bumpPlayerScript.empty()) {
181 stopRunning(spriteId); 170 bool bumpedPlayer = collider.player;
182 game_.getMixer().playSound("../res/sfx/bump.wav");
183 }
184 171
185 if (colliderSpriteId != -1 && !sprite.bumpPlayerScript.empty()) { 172 if (!bumpedPlayer && collider.leaderId != -1) {
186 Sprite& collider = game_.getSprite(colliderSpriteId); 173 Sprite& colliderLeader = game_.getSprite(collider.leaderId);
187 bool bumpedPlayer = collider.player; 174 bumpedPlayer = colliderLeader.player;
175 }
188 176
189 if (!bumpedPlayer && collider.leaderId != -1) { 177 if (bumpedPlayer) {
190 Sprite& colliderLeader = game_.getSprite(collider.leaderId); 178 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), sprite.bumpPlayerScript);
191 bumpedPlayer = colliderLeader.player; 179 }
192 } 180 }
181 }
193 182
194 if (bumpedPlayer) { 183 if (collision.blocked && sprite.characterState == CharacterState::Running && !sprite.clipping) {
195 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), sprite.bumpPlayerScript); 184 stopRunning(spriteId);
196 } 185 game_.getMixer().playSound("../res/sfx/bump.wav");
197 } 186 }
198 187
199 // Move everything 188 // Move everything
diff --git a/src/input_system.cpp b/src/input_system.cpp index 38423a2..c399e91 100644 --- a/src/input_system.cpp +++ b/src/input_system.cpp
@@ -87,25 +87,17 @@ void InputSystem::tick(double dt) {
87 vec2i checkLoc = sprite.loc + (unitVecInDirection(sprite.dir) * LUCAS_MOVEMENT_SPEED); 87 vec2i checkLoc = sprite.loc + (unitVecInDirection(sprite.dir) * LUCAS_MOVEMENT_SPEED);
88 CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, sprite.loc, checkLoc, sprite.dir); 88 CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, sprite.loc, checkLoc, sprite.dir);
89 89
90 if (collision.horiz.blocked || collision.vert.blocked) { 90 if (collision.blocked) {
91 inFrontOfSomething = true; 91 inFrontOfSomething = true;
92 } 92 }
93 93
94 // If there is a sprite to be interacted with, rotate that sprite so it is facing the player. 94 // If there is a sprite to be interacted with, rotate that sprite so it is facing the player.
95 // Then, run its interaction script if present. 95 // Then, run its interaction script if present.
96 if (collision.horiz.colliderSprite != -1) { 96 for (int colliderSpriteId : collision.colliders) {
97 game_.getSystem<AnimationSystem>().setSpriteDirection(collision.horiz.colliderSprite, oppositeDirection(sprite.dir)); 97 game_.getSystem<AnimationSystem>().setSpriteDirection(colliderSpriteId, oppositeDirection(sprite.dir));
98 98
99 Sprite& collider = game_.getSprite(collision.horiz.colliderSprite); 99 Sprite& collider = game_.getSprite(colliderSpriteId);
100 if (collider.interactionScript != "") { 100 if (!collider.interactionScript.empty()) {
101 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), collider.interactionScript);
102 activated = true;
103 }
104 } else if (collision.vert.colliderSprite != -1) {
105 game_.getSystem<AnimationSystem>().setSpriteDirection(collision.vert.colliderSprite, oppositeDirection(sprite.dir));
106
107 Sprite& collider = game_.getSprite(collision.vert.colliderSprite);
108 if (collider.interactionScript != "") {
109 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), collider.interactionScript); 101 game_.getSystem<ScriptSystem>().runScript(game_.getMap().getName(), collider.interactionScript);
110 activated = true; 102 activated = true;
111 } 103 }
diff --git a/src/transform_system.cpp b/src/transform_system.cpp index 4ed47c0..a643255 100644 --- a/src/transform_system.cpp +++ b/src/transform_system.cpp
@@ -59,6 +59,7 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
59 59
60 // First check horizontal movement only. 60 // First check horizontal movement only.
61 vec2i horizMovement = { newLoc.x(), curLoc.y() }; 61 vec2i horizMovement = { newLoc.x(), curLoc.y() };
62 bool horizBlocked = false;
62 63
63 vec2i oldColUL = curLoc + sprite.collisionOffset; 64 vec2i oldColUL = curLoc + sprite.collisionOffset;
64 vec2i oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1}; 65 vec2i oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1};
@@ -80,23 +81,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
80 newColDR.x() < mapBounds.w()) { 81 newColDR.x() < mapBounds.w()) {
81 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { 82 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) {
82 if (map.isBlocked(newTileDR.x(), y)) { 83 if (map.isBlocked(newTileDR.x(), y)) {
83 result.horiz.blocked = true; 84 horizBlocked = true;
84 result.horiz.dir = Direction::right; 85 result.dir = Direction::right;
85 86
86 break; 87 break;
87 } 88 }
88 } 89 }
89 } 90 }
90 91
91 if (!result.horiz.blocked && enclosureZone) { 92 if (!horizBlocked && enclosureZone) {
92 if (oldColDR.x() <= enclosureZone->dr.x()-1 && 93 if (oldColDR.x() <= enclosureZone->dr.x()-1 &&
93 newColDR.x() > enclosureZone->dr.x()-1) { 94 newColDR.x() > enclosureZone->dr.x()-1) {
94 result.horiz.blocked = true; 95 horizBlocked = true;
95 result.horiz.dir = Direction::right; 96 result.dir = Direction::right;
96 } 97 }
97 } 98 }
98 99
99 if (!result.horiz.blocked) { 100 if (!horizBlocked) {
100 auto it = rightCollidables_.lower_bound({oldColDR.x()+1, 0}); 101 auto it = rightCollidables_.lower_bound({oldColDR.x()+1, 0});
101 for (; 102 for (;
102 (it != std::end(rightCollidables_) && 103 (it != std::end(rightCollidables_) &&
@@ -106,9 +107,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
106 newColUL.y() <= it->second.upper) { 107 newColUL.y() <= it->second.upper) {
107 int colliderSpriteId = std::get<1>(it->first); 108 int colliderSpriteId = std::get<1>(it->first);
108 Sprite& collider = game_.getSprite(colliderSpriteId); 109 Sprite& collider = game_.getSprite(colliderSpriteId);
109 result.horiz.blocked = collider.solid; 110 horizBlocked = collider.solid;
110 result.horiz.dir = Direction::right; 111 result.dir = Direction::right;
111 result.horiz.colliderSprite = colliderSpriteId; 112 result.colliders.push_back(colliderSpriteId);
112 113
113 break; 114 break;
114 } 115 }
@@ -121,23 +122,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
121 newColUL.x() >= 0) { 122 newColUL.x() >= 0) {
122 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { 123 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) {
123 if (map.isBlocked(newTileUL.x(), y)) { 124 if (map.isBlocked(newTileUL.x(), y)) {
124 result.horiz.blocked = true; 125 horizBlocked = true;
125 result.horiz.dir = Direction::left; 126 result.dir = Direction::left;
126 127
127 break; 128 break;
128 } 129 }
129 } 130 }
130 } 131 }
131 132
132 if (!result.horiz.blocked && enclosureZone) { 133 if (!horizBlocked && enclosureZone) {
133 if (oldColUL.x() >= enclosureZone->ul.x() && 134 if (oldColUL.x() >= enclosureZone->ul.x() &&
134 newColUL.x() < enclosureZone->ul.x()) { 135 newColUL.x() < enclosureZone->ul.x()) {
135 result.horiz.blocked = true; 136 horizBlocked = true;
136 result.horiz.dir = Direction::left; 137 result.dir = Direction::left;
137 } 138 }
138 } 139 }
139 140
140 if (!result.horiz.blocked) { 141 if (!horizBlocked) {
141 auto it = leftCollidables_.lower_bound({oldColUL.x()-1, INT_MAX}); 142 auto it = leftCollidables_.lower_bound({oldColUL.x()-1, INT_MAX});
142 for (; 143 for (;
143 (it != std::end(leftCollidables_) && 144 (it != std::end(leftCollidables_) &&
@@ -147,9 +148,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
147 newColUL.y() <= it->second.upper) { 148 newColUL.y() <= it->second.upper) {
148 int colliderSpriteId = std::get<1>(it->first); 149 int colliderSpriteId = std::get<1>(it->first);
149 Sprite& collider = game_.getSprite(colliderSpriteId); 150 Sprite& collider = game_.getSprite(colliderSpriteId);
150 result.horiz.blocked = collider.solid; 151 horizBlocked = collider.solid;
151 result.horiz.dir = Direction::left; 152 result.dir = Direction::left;
152 result.horiz.colliderSprite = colliderSpriteId; 153 result.colliders.push_back(colliderSpriteId);
153 154
154 break; 155 break;
155 } 156 }
@@ -161,12 +162,14 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
161 // taken place (as long as it was not in fact blocked). 162 // taken place (as long as it was not in fact blocked).
162 vec2i effectiveCurLoc = curLoc; 163 vec2i effectiveCurLoc = curLoc;
163 vec2i vertMovement = newLoc; 164 vec2i vertMovement = newLoc;
164 if (result.horiz.blocked) { 165 if (horizBlocked) {
165 vertMovement.x() = curLoc.x(); 166 vertMovement.x() = curLoc.x();
166 } else { 167 } else {
167 effectiveCurLoc.x() = newLoc.x(); 168 effectiveCurLoc.x() = newLoc.x();
168 } 169 }
169 170
171 bool vertBlocked = false;
172
170 oldColUL = effectiveCurLoc + sprite.collisionOffset; 173 oldColUL = effectiveCurLoc + sprite.collisionOffset;
171 oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1}; 174 oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1};
172 newColUL = vertMovement + sprite.collisionOffset; 175 newColUL = vertMovement + sprite.collisionOffset;
@@ -182,23 +185,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
182 newColDR.y() < mapBounds.h()) { 185 newColDR.y() < mapBounds.h()) {
183 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { 186 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) {
184 if (map.isBlocked(x, newTileDR.y())) { 187 if (map.isBlocked(x, newTileDR.y())) {
185 result.vert.blocked = true; 188 vertBlocked = true;
186 result.vert.dir = Direction::down; 189 result.dir = Direction::down;
187 190
188 break; 191 break;
189 } 192 }
190 } 193 }
191 } 194 }
192 195
193 if (!result.vert.blocked && enclosureZone) { 196 if (!vertBlocked && enclosureZone) {
194 if (oldColDR.y() <= enclosureZone->dr.y()-1 && 197 if (oldColDR.y() <= enclosureZone->dr.y()-1 &&
195 newColDR.y() > enclosureZone->dr.y()-1) { 198 newColDR.y() > enclosureZone->dr.y()-1) {
196 result.vert.blocked = true; 199 vertBlocked = true;
197 result.vert.dir = Direction::down; 200 result.dir = Direction::down;
198 } 201 }
199 } 202 }
200 203
201 if (!result.vert.blocked) { 204 if (!vertBlocked) {
202 auto it = downCollidables_.lower_bound({oldColDR.y()+1, 0}); 205 auto it = downCollidables_.lower_bound({oldColDR.y()+1, 0});
203 for (; 206 for (;
204 (it != std::end(downCollidables_) && 207 (it != std::end(downCollidables_) &&
@@ -208,9 +211,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
208 newColUL.x() <= it->second.upper) { 211 newColUL.x() <= it->second.upper) {
209 int colliderSpriteId = std::get<1>(it->first); 212 int colliderSpriteId = std::get<1>(it->first);
210 Sprite& collider = game_.getSprite(colliderSpriteId); 213 Sprite& collider = game_.getSprite(colliderSpriteId);
211 result.vert.blocked = collider.solid; 214 vertBlocked = collider.solid;
212 result.vert.dir = Direction::down; 215 result.dir = Direction::down;
213 result.vert.colliderSprite = colliderSpriteId; 216 result.colliders.push_back(colliderSpriteId);
214 217
215 break; 218 break;
216 } 219 }
@@ -223,23 +226,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
223 newColUL.y() >= 0) { 226 newColUL.y() >= 0) {
224 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { 227 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) {
225 if (map.isBlocked(x, newTileUL.y())) { 228 if (map.isBlocked(x, newTileUL.y())) {
226 result.vert.blocked = true; 229 vertBlocked = true;
227 result.vert.dir = Direction::up; 230 result.dir = Direction::up;
228 231
229 break; 232 break;
230 } 233 }
231 } 234 }
232 } 235 }
233 236
234 if (!result.vert.blocked && enclosureZone) { 237 if (!vertBlocked && enclosureZone) {
235 if (oldColUL.y() >= enclosureZone->ul.y() && 238 if (oldColUL.y() >= enclosureZone->ul.y() &&
236 newColUL.y() < enclosureZone->ul.y()) { 239 newColUL.y() < enclosureZone->ul.y()) {
237 result.vert.blocked = true; 240 vertBlocked = true;
238 result.vert.dir = Direction::up; 241 result.dir = Direction::up;
239 } 242 }
240 } 243 }
241 244
242 if (!result.vert.blocked) { 245 if (!vertBlocked) {
243 auto it = upCollidables_.lower_bound({oldColUL.y()-1, INT_MAX}); 246 auto it = upCollidables_.lower_bound({oldColUL.y()-1, INT_MAX});
244 for (; 247 for (;
245 (it != std::end(upCollidables_) && 248 (it != std::end(upCollidables_) &&
@@ -249,9 +252,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
249 newColUL.x() <= it->second.upper) { 252 newColUL.x() <= it->second.upper) {
250 int colliderSpriteId = std::get<1>(it->first); 253 int colliderSpriteId = std::get<1>(it->first);
251 Sprite& collider = game_.getSprite(colliderSpriteId); 254 Sprite& collider = game_.getSprite(colliderSpriteId);
252 result.vert.blocked = collider.solid; 255 vertBlocked = collider.solid;
253 result.vert.dir = Direction::up; 256 result.dir = Direction::up;
254 result.vert.colliderSprite = colliderSpriteId; 257 result.colliders.push_back(colliderSpriteId);
255 258
256 break; 259 break;
257 } 260 }
@@ -259,6 +262,13 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
259 } 262 }
260 } 263 }
261 264
265 result.adjustedLoc = vertMovement;
266 if (vertBlocked) {
267 result.adjustedLoc.y() = effectiveCurLoc.y();
268 }
269
270 result.blocked = horizBlocked || vertBlocked;
271
262 return result; 272 return result;
263} 273}
264 274
diff --git a/src/transform_system.h b/src/transform_system.h index 7fa3423..476b8d8 100644 --- a/src/transform_system.h +++ b/src/transform_system.h
@@ -5,6 +5,7 @@
5#include <set> 5#include <set>
6#include <map> 6#include <map>
7#include <tuple> 7#include <tuple>
8#include <list>
8#include "direction.h" 9#include "direction.h"
9#include "system.h" 10#include "system.h"
10#include "vector.h" 11#include "vector.h"
@@ -13,15 +14,11 @@
13 14
14class Game; 15class Game;
15 16
16struct AxisResult { 17struct CollisionResult {
17 Direction dir; 18 Direction dir;
18 bool blocked = false; 19 bool blocked = false;
19 int colliderSprite = -1; 20 std::list<int> colliders;
20}; 21 vec2i adjustedLoc;
21
22struct CollisionResult {
23 AxisResult horiz;
24 AxisResult vert;
25}; 22};
26 23
27class TransformSystem : public System { 24class TransformSystem : public System {