| 230 | } |
| 231 | |
| 232 | void TileObjectBattleUnit::setPosition(Vec3<float> newPosition) |
| 233 | { |
| 234 | auto u = getUnit(); |
| 235 | |
| 236 | // Set appropriate bounds for the unit |
| 237 | auto size = std::max(u->agent->type->bodyType->size[u->current_body_state][u->facing], |
| 238 | u->agent->type->bodyType->size[u->target_body_state][u->facing]); |
| 239 | auto maxHeight = std::max(u->agent->type->bodyType->height[u->current_body_state], |
| 240 | u->agent->type->bodyType->height[u->target_body_state]); |
| 241 | setBounds({size.x, size.y, (float)maxHeight / 40.0f}); |
| 242 | |
| 243 | if (u->isLarge()) |
| 244 | { |
| 245 | centerOffset = {0.0f, 0.0f, 1.0f}; |
| 246 | } |
| 247 | else // if small |
| 248 | { |
| 249 | if (u->current_body_state == BodyState::Prone || u->target_body_state == BodyState::Prone) |
| 250 | { |
| 251 | centerOffset = {-u->facing.x * bounds.x / 4.0f, -u->facing.y * bounds.y / 4.0f, 0.5f}; |
| 252 | } |
| 253 | else |
| 254 | { |
| 255 | centerOffset = {0.0f, 0.0f, 0.5f}; |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | occupiedTiles.clear(); |
| 260 | |
| 261 | TileObject::setPosition(newPosition); |
| 262 | for (auto &t : intersectingTiles) |
| 263 | { |
| 264 | t->updateBattlescapeUnitPresent(); |
| 265 | } |
| 266 | |
| 267 | auto pos = owningTile->position; |
| 268 | |
| 269 | // Vanilla allowed units to "pop into" other units without any limit |
| 270 | // That is, unit can stand on height 38 while another unit is hovering in the tile above, |
| 271 | // and cause no problems whatsoever, even though they're almost fully inside each other |
| 272 | // (their positions only differ by 1 pixel) |
| 273 | // We could introduce an option to disallow this? |
| 274 | // Right now, here goes vanilla behavior |
| 275 | if (u->current_movement_state == MovementState::Brainsuck) |
| 276 | { |
| 277 | // Sucking headcrab occupies nothing |
| 278 | } |
| 279 | else if (u->isLarge()) |
| 280 | { |
| 281 | // Large units occupy 2x2x2 box, where position is the point |
| 282 | // with max x, max y and min z |
| 283 | // Also the same but on destination |
| 284 | occupiedTiles.insert(pos); |
| 285 | occupiedTiles.insert({pos.x - 1, pos.y, pos.z}); |
| 286 | occupiedTiles.insert({pos.x, pos.y - 1, pos.z}); |
| 287 | occupiedTiles.insert({pos.x - 1, pos.y - 1, pos.z}); |
| 288 | occupiedTiles.insert({pos.x, pos.y, pos.z + 1}); |
| 289 | occupiedTiles.insert({pos.x - 1, pos.y, pos.z + 1}); |
nothing calls this directly
no test coverage detected