Skip to content

Commit

Permalink
Experimental: Support for grenades exploding before battle
Browse files Browse the repository at this point in the history
  • Loading branch information
MeridianOXC committed Jan 21, 2024
1 parent 6bfa0dc commit af6052f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
78 changes: 78 additions & 0 deletions src/Battlescape/BattlescapeGenerator.cpp
Expand Up @@ -949,6 +949,11 @@ void BattlescapeGenerator::run()
{
explodePowerSources();
}

if (!isPreview)
{
explodeOtherJunk();
}
}

/**
Expand Down Expand Up @@ -2403,6 +2408,79 @@ void BattlescapeGenerator::explodePowerSources()
}
}

/**
* Terraforming.
*/
void BattlescapeGenerator::explodeOtherJunk()
{
std::vector<BattleItem*> itemsToGoBoom;
std::vector<std::tuple<Tile*, const RuleItem*> > 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<Tile*>(params);
const RuleItem* rule = std::get<const RuleItem*>(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.
Expand Down
1 change: 1 addition & 0 deletions src/Battlescape/BattlescapeGenerator.h
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/Savegame/BattleItem.cpp
Expand Up @@ -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
Expand Down

0 comments on commit af6052f

Please sign in to comment.