@@ -1118,6 +1118,7 @@ void TileEngine::explode(const Position ¢er, int power, ItemDamageType type,
11181118
11191119 int exHeight = std::max (0 , std::min (3 , Options::battleExplosionHeight));
11201120 int vertdec = 1000 ; // default flat explosion
1121+ int dmgRng = (type == DT_HE || Options::TFTDDamage) ? 50 : 100 ;
11211122
11221123 switch (exHeight)
11231124 {
@@ -1131,7 +1132,6 @@ void TileEngine::explode(const Position ¢er, int power, ItemDamageType type,
11311132 vertdec = 5 ;
11321133 }
11331134
1134-
11351135 for (int fi = -90 ; fi <= 90 ; fi += 5 )
11361136 {
11371137 // raytrace every 3 degrees makes sure we cover all tiles in a circle.
@@ -1160,7 +1160,6 @@ void TileEngine::explode(const Position ¢er, int power, ItemDamageType type,
11601160 ret = tilesAffected.insert (dest); // check if we had this tile already
11611161 if (ret.second )
11621162 {
1163- int dmgRng = (type == DT_HE || Options::TFTDDamage) ? 50 : 100 ;
11641163 int min = power_ * (100 - dmgRng) / 100 ;
11651164 int max = power_ * (100 + dmgRng) / 100 ;
11661165 BattleUnit *bu = dest->getUnit ();
@@ -1325,10 +1324,9 @@ void TileEngine::explode(const Position ¢er, int power, ItemDamageType type,
13251324 calculateFOV (center / Position (16 ,16 ,24 ));
13261325}
13271326
1328-
13291327/* *
13301328 * Applies the explosive power to the tile parts. This is where the actual destruction takes place.
1331- * Must affect 7 objects (6 box sides and the object inside).
1329+ * Must affect 9 objects (6 box sides and the object inside plus 2 outer walls ).
13321330 * @param tile Tile affected.
13331331 * @return True if the objective was destroyed.
13341332 */
@@ -1339,77 +1337,96 @@ bool TileEngine::detonate(Tile* tile)
13391337
13401338 tile->setExplosive (0 ,true );
13411339 bool objective = false ;
1342- Tile* tiles[7 ];
1343- static const int parts[7 ]={0 ,1 ,2 ,0 ,1 ,2 ,3 };
1340+ Tile* tiles[9 ];
1341+ static const int parts[9 ]={0 ,1 ,2 ,0 ,1 ,2 ,3 , 3 , 3 }; // 6th is the object of current
13441342 Position pos = tile->getPosition ();
1343+
13451344 tiles[0 ] = _save->getTile (Position (pos.x , pos.y , pos.z +1 )); // ceiling
13461345 tiles[1 ] = _save->getTile (Position (pos.x +1 , pos.y , pos.z )); // east wall
13471346 tiles[2 ] = _save->getTile (Position (pos.x , pos.y +1 , pos.z )); // south wall
13481347 tiles[3 ] = tiles[4 ] = tiles[5 ] = tiles[6 ] = tile;
1348+ tiles[7 ] = _save->getTile (Position (pos.x , pos.y -1 , pos.z )); // north bigwall
1349+ tiles[8 ] = _save->getTile (Position (pos.x -1 , pos.y , pos.z )); // west bigwall
13491350
13501351 // explosions create smoke which only stays 1 or 2 turns
13511352// tile->setSmoke(std::max(1, std::min(tile->getSmoke() + RNG::generate(0,2), 15)));
13521353
13531354 int remainingPower, fireProof, fuel;
1354- bool destroyed;
1355- for (int i = 0 ; i < 7 ; ++i)
1356- {
1357- if (tiles[i] && tiles[i]->getMapData (parts[i]))
1358- {
1359- remainingPower = explosive;
1360- destroyed = false ;
1361- int volume = 0 ;
1362- int currentpart = parts[i], currentpart2, diemcd;
1363- fireProof = tiles[i]->getFlammability (currentpart);
1364- fuel = tiles[i]->getFuel (currentpart) + 1 ;
1365- // get the volume of the object by checking it's loftemps objects.
1366- for (int j=0 ; j < 12 ; j++)
1355+ bool destroyed, bigwalldestroyed = true ;
1356+ for (int i = 8 ; i >=0 ; --i)
1357+ {
1358+ if (!tiles[i] || !tiles[i]->getMapData (parts[i]))
1359+ continue ; // skip out of map and emptiness
1360+ int bigwall = tiles[i]->getMapData (parts[i])->getBigWall ();
1361+ if (i > 6 && !( (bigwall==1 ) || (bigwall==8 ) || (i==8 && bigwall==6 ) || (i==7 && bigwall==7 )))
1362+ continue ;
1363+ if (!bigwalldestroyed && parts[i]==0 ) // when ground shouldn't be destroyed
1364+ continue ;
1365+ remainingPower = explosive;
1366+ destroyed = false ;
1367+ int volume = 0 ;
1368+ int currentpart = parts[i], currentpart2, diemcd;
1369+ fireProof = tiles[i]->getFlammability (currentpart);
1370+ fuel = tiles[i]->getFuel (currentpart) + 1 ;
1371+ // get the volume of the object by checking it's loftemps objects.
1372+ for (int j = 0 ; j < 12 ; j++)
1373+ {
1374+ if (tiles[i]->getMapData (currentpart)->getLoftID (j) != 0 )
1375+ ++volume;
1376+ }
1377+ if ( i == 6 &&
1378+ (bigwall == 2 || bigwall == 3 ) && // diagonals
1379+ (2 * tiles[i]->getMapData (currentpart)->getArmor ()) > remainingPower) // not enough to destroy
1380+ {
1381+ bigwalldestroyed = false ;
1382+ }
1383+ // iterate through tile armor and destroy if can
1384+ while ( tiles[i]->getMapData (currentpart) &&
1385+ (2 * tiles[i]->getMapData (currentpart)->getArmor ()) <= remainingPower &&
1386+ tiles[i]->getMapData (currentpart)->getArmor () != 255 )
1387+ {
1388+ if ( i == 6 && (bigwall == 2 || bigwall == 3 )) // diagonals for the current tile
13671389 {
1368- if (tiles[i]->getMapData (currentpart)->getLoftID (j) != 0 )
1369- ++volume;
1390+ bigwalldestroyed = true ;
13701391 }
1371- // iterate through tile armor and destroy if can
1372- while ( tiles[i]-> getMapData (currentpart) &&
1373- ( 2 * tiles[i]-> getMapData (currentpart)-> getArmor ()) <= remainingPower &&
1374- tiles[i]->getMapData (currentpart)->getArmor () != 255 )
1392+ remainingPower -= 2 * tiles[i]-> getMapData (currentpart)-> getArmor ();
1393+ destroyed = true ;
1394+ if (_save-> getMissionType () == " STR_BASE_DEFENSE " &&
1395+ tiles[i]->getMapData (currentpart)->isBaseModule () )
13751396 {
1376- remainingPower -= 2 * tiles[i]->getMapData (currentpart)->getArmor ();
1377- destroyed = true ;
1378- if (_save->getMissionType () == " STR_BASE_DEFENSE" &&
1379- tiles[i]->getMapData (currentpart)->isBaseModule ())
1380- {
1381- _save->getModuleMap ()[tile->getPosition ().x /10 ][tile->getPosition ().y /10 ].second --;
1382- }
1383- // this trick is to follow transformed object parts (object can become a ground)
1384- diemcd = tiles[i]->getMapData (currentpart)->getDieMCD ();
1385- if (diemcd!=0 )
1386- currentpart2 = tiles[i]->getMapData (currentpart)->getDataset ()->getObjects ()->at (diemcd)->getObjectType ();
1387- else
1388- currentpart2 = currentpart;
1389- if (tiles[i]->destroy (currentpart))
1390- objective = true ;
1391- currentpart = currentpart2;
1392- if (tiles[i]->getMapData (currentpart)) // take new values
1393- {
1394- fireProof = tiles[i]->getFlammability (currentpart);
1395- fuel = tiles[i]->getFuel (currentpart) + 1 ;
1396- }
1397+ _save->getModuleMap ()[tile->getPosition ().x /10 ][tile->getPosition ().y /10 ].second --;
13971398 }
1398- // set tile on fire
1399- if ((2 * fireProof) < remainingPower)
1399+ // this trick is to follow transformed object parts (object can become a ground)
1400+ diemcd = tiles[i]->getMapData (currentpart)->getDieMCD ();
1401+ if (diemcd!=0 )
1402+ currentpart2 = tiles[i]->getMapData (currentpart)->getDataset ()->getObjects ()->at (diemcd)->getObjectType ();
1403+ else
1404+ currentpart2 = currentpart;
1405+ if (tiles[i]->destroy (currentpart))
1406+ objective = true ;
1407+ currentpart = currentpart2;
1408+ if (tiles[i]->getMapData (currentpart)) // take new values
14001409 {
1401- // if (tiles[i]->getMapData(MapData::O_FLOOR) || tiles[i]->getMapData(MapData::O_OBJECT))
1402- tiles[i]->setFire (fuel);
1410+ fireProof = tiles[i]->getFlammability (currentpart);
1411+ fuel = tiles[i]->getFuel (currentpart) + 1 ;
1412+ }
1413+ }
1414+ // set tile on fire
1415+ if ((2 * fireProof) < remainingPower)
1416+ {
1417+ if (tiles[i]->getMapData (MapData::O_FLOOR ) || tiles[i]->getMapData (MapData::O_OBJECT ))
1418+ {
1419+ tiles[i]->setFire (fuel);
14031420 tiles[i]->setSmoke (std::max (1 , std::min (15 - (fireProof / 10 ), 12 )));
14041421 }
1405- // add some smoke if tile was destroyed and not set on fire
1406- if (destroyed && !tiles[i]->getFire ())
1422+ }
1423+ // add some smoke if tile was destroyed and not set on fire
1424+ if (destroyed && !tiles[i]->getFire ())
1425+ {
1426+ int smoke = RNG::generate (1 , (volume / 2 ) + 3 ) + (volume / 2 );
1427+ if (smoke > tiles[i]->getSmoke ())
14071428 {
1408- int smoke = RNG::generate (1 , (volume / 2 ) + 3 ) + (volume / 2 );
1409- if (smoke > tiles[i]->getSmoke ())
1410- {
1411- tiles[i]->setSmoke (std::max (0 , std::min (smoke, 15 )));
1412- }
1429+ tiles[i]->setSmoke (std::max (0 , std::min (smoke, 15 )));
14131430 }
14141431 }
14151432 }
@@ -1543,13 +1560,9 @@ int TileEngine::horizontalBlockage(Tile *startTile, Tile *endTile, ItemDamageTyp
15431560 block = (blockage (startTile,MapData::O_NORTHWALL , type) + blockage (endTile,MapData::O_WESTWALL , type))/2
15441561 + (blockage (_save->getTile (startTile->getPosition () + oneTileEast),MapData::O_WESTWALL , type)
15451562 + blockage (_save->getTile (startTile->getPosition () + oneTileEast),MapData::O_NORTHWALL , type))/2 ;
1546-
1547- if (!endTile->getMapData (MapData::O_OBJECT ))
1548- {
1549- block += (blockage (_save->getTile (startTile->getPosition () + oneTileEast),MapData::O_OBJECT , type, direction)
1550- + blockage (_save->getTile (startTile->getPosition () + oneTileNorth),MapData::O_OBJECT , type, 4 )
1551- + blockage (_save->getTile (startTile->getPosition () + oneTileNorth),MapData::O_OBJECT , type, 2 ))/2 ;
1552- }
1563+
1564+ block += (blockage (_save->getTile (startTile->getPosition () + oneTileNorth),MapData::O_OBJECT , type, 4 )
1565+ + blockage (_save->getTile (startTile->getPosition () + oneTileEast),MapData::O_OBJECT , type, 6 ))/2 ;
15531566 }
15541567 break ;
15551568 case 2 : // east
@@ -1571,12 +1584,8 @@ int TileEngine::horizontalBlockage(Tile *startTile, Tile *endTile, ItemDamageTyp
15711584 block = (blockage (endTile,MapData::O_WESTWALL , type) + blockage (endTile,MapData::O_NORTHWALL , type))/2
15721585 + (blockage (_save->getTile (startTile->getPosition () + oneTileEast),MapData::O_WESTWALL , type)
15731586 + blockage (_save->getTile (startTile->getPosition () + oneTileSouth),MapData::O_NORTHWALL , type))/2 ;
1574-
1575- if (!endTile->getMapData (MapData::O_OBJECT ))
1576- {
1577- block += (blockage (_save->getTile (startTile->getPosition () + oneTileSouth),MapData::O_OBJECT , type, 2 )
1578- + blockage (_save->getTile (startTile->getPosition () + oneTileEast),MapData::O_OBJECT , type, 4 ))/2 ;
1579- }
1587+ block += (blockage (_save->getTile (startTile->getPosition () + oneTileSouth),MapData::O_OBJECT , type, 0 )
1588+ + blockage (_save->getTile (startTile->getPosition () + oneTileEast),MapData::O_OBJECT , type, 6 ))/2 ;
15801589 }
15811590 break ;
15821591 case 4 : // south
@@ -1597,12 +1606,8 @@ int TileEngine::horizontalBlockage(Tile *startTile, Tile *endTile, ItemDamageTyp
15971606 block = (blockage (endTile,MapData::O_NORTHWALL , type) + blockage (startTile,MapData::O_WESTWALL , type))/2
15981607 + (blockage (_save->getTile (startTile->getPosition () + oneTileSouth),MapData::O_WESTWALL , type)
15991608 + blockage (_save->getTile (startTile->getPosition () + oneTileSouth),MapData::O_NORTHWALL , type))/2 ;
1600- if (!endTile->getMapData (MapData::O_OBJECT ))
1601- {
1602- block += (blockage (_save->getTile (startTile->getPosition () + oneTileSouth),MapData::O_OBJECT , type, direction)
1603- + blockage (_save->getTile (startTile->getPosition () + oneTileWest),MapData::O_OBJECT , type, 2 )
1604- + blockage (_save->getTile (startTile->getPosition () + oneTileWest),MapData::O_OBJECT , type, 4 ))/2 ;
1605- }
1609+ block += (blockage (_save->getTile (startTile->getPosition () + oneTileSouth),MapData::O_OBJECT , type, 0 )
1610+ + blockage (_save->getTile (startTile->getPosition () + oneTileWest),MapData::O_OBJECT , type, 2 ))/2 ;
16061611 }
16071612 break ;
16081613 case 6 : // west
@@ -1625,23 +1630,20 @@ int TileEngine::horizontalBlockage(Tile *startTile, Tile *endTile, ItemDamageTyp
16251630 block = (blockage (startTile,MapData::O_WESTWALL , type) + blockage (startTile,MapData::O_NORTHWALL , type))/2
16261631 + (blockage (_save->getTile (startTile->getPosition () + oneTileNorth),MapData::O_WESTWALL , type)
16271632 + blockage (_save->getTile (startTile->getPosition () + oneTileWest),MapData::O_NORTHWALL , type))/2 ;
1628-
1629- if (!endTile->getMapData (MapData::O_OBJECT ))
1630- {
1631- block += (blockage (_save->getTile (startTile->getPosition () + oneTileNorth),MapData::O_OBJECT , type, 4 )
1632- + blockage (_save->getTile (startTile->getPosition () + oneTileWest),MapData::O_OBJECT , type, 2 ))/2 ;
1633- }
1633+ block += (blockage (_save->getTile (startTile->getPosition () + oneTileNorth),MapData::O_OBJECT , type, 4 )
1634+ + blockage (_save->getTile (startTile->getPosition () + oneTileWest),MapData::O_OBJECT , type, 2 ))/2 ;
16341635 }
16351636 break ;
16361637 }
16371638
1638- block += blockage (startTile,MapData::O_OBJECT , type, direction, true );
1639+ block += blockage (startTile,MapData::O_OBJECT , type, direction);
16391640 if (type != DT_NONE )
16401641 {
16411642 direction += 4 ;
16421643 if (direction > 7 )
16431644 direction -= 8 ;
1644- block += blockage (endTile,MapData::O_OBJECT , type, direction);
1645+ if (endTile->isBigWall ())
1646+ block += blockage (endTile,MapData::O_OBJECT , type, direction, true );
16451647 }
16461648 else
16471649 {
@@ -1650,7 +1652,7 @@ int TileEngine::horizontalBlockage(Tile *startTile, Tile *endTile, ItemDamageTyp
16501652 direction += 4 ;
16511653 if (direction > 7 )
16521654 direction -= 8 ;
1653- if (blockage (endTile,MapData::O_OBJECT , type, direction) > 127 ){
1655+ if (blockage (endTile,MapData::O_OBJECT , type, direction, true ) > 127 ){
16541656 return -1 ; // hit bigwall, reveal bigwall tile
16551657 }
16561658 }
@@ -1680,7 +1682,8 @@ int TileEngine::blockage(Tile *tile, const int part, ItemDamageType type, int di
16801682 {
16811683 wall = tile->getMapData (MapData::O_OBJECT )->getBigWall ();
16821684
1683- if (checkingFromOrigin &&
1685+ if (type != DT_SMOKE &&
1686+ checkingFromOrigin &&
16841687 (wall == Pathfinding::BIGWALLNESW ||
16851688 wall == Pathfinding::BIGWALLNWSE ))
16861689 {
0 commit comments