diff --git a/src/Battlescape/BattlescapeGenerator.cpp b/src/Battlescape/BattlescapeGenerator.cpp index 25719024f5..8c7b28b98e 100644 --- a/src/Battlescape/BattlescapeGenerator.cpp +++ b/src/Battlescape/BattlescapeGenerator.cpp @@ -949,6 +949,11 @@ void BattlescapeGenerator::run() { explodePowerSources(); } + + if (!isPreview) + { + explodeOtherJunk(); + } } /** @@ -2403,6 +2408,79 @@ void BattlescapeGenerator::explodePowerSources() } } +/** + * Terraforming. + */ +void BattlescapeGenerator::explodeOtherJunk() +{ + std::vector itemsToGoBoom; + std::vector > explosionParams; + + for (auto* bi : *_save->getItems()) + { + if (bi->isOwnerIgnored() || !bi->getTile()) + { + continue; + } + if ((!bi->getRules()->getSpawnUnit() && !bi->getRules()->getSpawnItem()) && !bi->getXCOMProperty() && !bi->isSpecialWeapon()) + { + // fuseTimer == 0 cannot be used, because it is already used for "explode after the first player turn" + // fuseTimer == -1 is also used, means "unprimed grenade" + if (bi->getRules()->getBattleType() == BT_GRENADE && bi->getFuseTimer() == -2 /* && !bi->isFuseEnabled() */) + { + itemsToGoBoom.push_back(bi); + explosionParams.push_back(std::tuple(bi->getTile(), bi->getRules())); + } + } + } + + for (auto* item : itemsToGoBoom) + { + _save->removeItem(item); + } + + for (auto& params : explosionParams) + { + Tile* tile = std::get(params); + const RuleItem* rule = std::get(params); + + Position p = tile->getPosition().toVoxel() + Position(8, 8, -tile->getTerrainLevel()); + _save->getTileEngine()->explode( + { }, + p, + rule->getPower(), + rule->getDamageType(), + rule->getExplosionRadius({ }) + ); + } + + Tile* t = _save->getTileEngine()->checkForTerrainExplosions(); + while (t) + { + ItemDamageType DT; + switch (t->getExplosiveType()) + { + case 0: + DT = DT_HE; + break; + case 5: + DT = DT_IN; + break; + case 6: + DT = DT_STUN; + break; + default: + DT = DT_SMOKE; + break; + } + int power = t->getExplosive(); + t->setExplosive(0, 0, true); + Position p = t->getPosition().toVoxel() + Position(8, 8, 0); + _save->getTileEngine()->explode({ }, p, power, _game->getMod()->getDamageType(DT), power / 10); + t = _save->getTileEngine()->checkForTerrainExplosions(); + } +} + /** * Spawns civilians on a terror mission. * @param max Maximum number of civilians to spawn. diff --git a/src/Battlescape/BattlescapeGenerator.h b/src/Battlescape/BattlescapeGenerator.h index 481ffba686..f390befef8 100644 --- a/src/Battlescape/BattlescapeGenerator.h +++ b/src/Battlescape/BattlescapeGenerator.h @@ -117,6 +117,7 @@ class BattlescapeGenerator void fuelPowerSources(); /// Possibly explodes ufo power sources. void explodePowerSources(); + void explodeOtherJunk(); /// Deploys the XCOM units on the mission. void deployXCOM(const RuleStartingCondition* startingCondition, const RuleEnviroEffects* enviro); /// Runs necessary checks before physically setting the position. diff --git a/src/Savegame/BattleItem.cpp b/src/Savegame/BattleItem.cpp index dfa0f72d0a..628df05e1c 100644 --- a/src/Savegame/BattleItem.cpp +++ b/src/Savegame/BattleItem.cpp @@ -217,7 +217,7 @@ const RuleItem *BattleItem::getRules() const } /** - * Gets the turns until detonation. -1 = unprimed grenade + * Gets the turns until detonation. -1 = unprimed grenade. -2 = mapblock grenade to explode before battle. * @return turns until detonation. */ int BattleItem::getFuseTimer() const