diff options
Diffstat (limited to 'src/transform_system.cpp')
-rw-r--r-- | src/transform_system.cpp | 84 |
1 files changed, 47 insertions, 37 deletions
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 | ||