void TileObjectBattleMapPart::removeFromMap() { bool requireRecalc = owningTile != nullptr; auto prevOwningTile = owningTile; auto prevDrawOnTile = drawOnTile; TileObject::removeFromMap(); if (requireRecalc) { prevOwningTile->updateBattlescapeParameters(); prevDrawOnTile->updateBattlescapeUIDrawOrder(); } }
void Tile::updateBattlescapeParameters() { if (map.ceaseUpdates) { return; } bool providedGroundUpwards = solidGround && height >= 0.9625f; height = 0.0f; movementCostIn = -1; // -1 means empty, and will be set to 4 afterwards movementCostOver = 255; movementCostLeft = 0; movementCostRight = 0; solidGround = false; canStand = false; hasLift = false; hasExit = false; walkSfx = nullptr; objectDropSfx = nullptr; supportProviderForItems = nullptr; closedDoorLeft = false; closedDoorRight = false; for (auto &o : ownedObjects) { if (o->getType() == TileObject::Type::Ground || o->getType() == TileObject::Type::Feature) { auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(o)->getOwner(); if (!mp->isAlive()) { continue; } height = std::max(height, (float)mp->type->height); if (mp->type->floor || (o->getType() == TileObject::Type::Feature && !mp->type->gravlift)) { if (!supportProviderForItems || supportProviderForItems->type->height < mp->type->height) { supportProviderForItems = mp; } } solidGround = solidGround || (mp->type->floor && !mp->type->gravlift) || (o->getType() == TileObject::Type::Feature && !mp->type->gravlift); hasLift = hasLift || mp->type->gravlift; hasExit = hasExit || mp->type->exit; movementCostIn = std::max(movementCostIn, mp->type->movement_cost); if (mp->type->sfxIndex != -1) { walkSfx = mp->type->walkSounds; objectDropSfx = mp->type->objectDropSound; } } if (o->getType() == TileObject::Type::LeftWall) { auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(o)->getOwner(); if (!mp->isAlive()) { continue; } movementCostLeft = mp->type->movement_cost; closedDoorLeft = mp->door && !mp->door->open; } if (o->getType() == TileObject::Type::RightWall) { auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(o)->getOwner(); if (!mp->isAlive()) { continue; } movementCostRight = mp->type->movement_cost; closedDoorRight = mp->door && !mp->door->open; } } canStand = solidGround || hasLift; if (!canStand && position.z > 0) { // check if tile below is full height auto t = map.getTile(position.x, position.y, position.z - 1); // Floating point precision is lacking somtimes so even though we have to compare with // 0.975, we do this canStand = t->solidGround && t->height >= 0.9625f; if (canStand) { movementCostIn = std::max(movementCostIn, t->movementCostOver); } } if (movementCostIn == -1) { movementCostIn = 4; } // Height of 39 means whole tile if (height == 39 && solidGround) { movementCostOver = movementCostIn; movementCostIn = 255; // Provide solid ground upwards if (position.z + 1 < map.size.z) { auto t = map.getTile(position.x, position.y, position.z + 1); if (!t->canStand) { t->canStand = true; t->movementCostIn = std::max(movementCostOver, t->movementCostIn); } } } height = height / (float)TILE_Z_BATTLE; // Propagate update upwards if we provided ground and ceased to do so if (!(solidGround && height >= 0.9625f) && providedGroundUpwards && position.z + 1 < map.size.z) { auto t = map.getTile(position.x, position.y, position.z + 1); t->updateBattlescapeParameters(); } }