summary refs log tree commit diff stats
path: root/src/transform_system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/transform_system.cpp')
-rw-r--r--src/transform_system.cpp84
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