@@ -442,9 +442,9 @@ void TerrainModifier::explode(const Position ¢er, int power, ItemDamageType
442442 }
443443 else
444444 {
445- double centerZ = (center.z / 24 ) + 0.5 ;
446- double centerX = (center.x / 16 ) + 0.5 ;
447- double centerY = (center.y / 16 ) + 0.5 ;
445+ double centerZ = (int )( center.z / 24 ) + 0.5 ;
446+ double centerX = (int )( center.x / 16 ) + 0.5 ;
447+ double centerY = (int )( center.y / 16 ) + 0.5 ;
448448 int power_;
449449
450450 if (type == DT_IN )
@@ -496,13 +496,17 @@ void TerrainModifier::explode(const Position ¢er, int power, ItemDamageType
496496 if (type == DT_SMOKE )
497497 {
498498 // smoke from explosions always stay 15 to 20 turns
499- dest->setSmoke (RNG::generate (15 , 20 ));
499+ if (dest->getSmoke () < 10 )
500+ {
501+ dest->addSmoke (RNG::generate (15 , 20 ));
502+ }
500503 }
501504 if (type == DT_IN )
502505 {
503- // fire from explosions always stay 1 to 2 turns + it ignites stuff
504- dest->setFire (RNG::generate (15 , 20 ));
505- dest->ignite ();
506+ if (dest->getFire () == 0 )
507+ {
508+ dest->ignite ();
509+ }
506510 }
507511 }
508512
@@ -846,4 +850,73 @@ void TerrainModifier::spawnItem(const Position &position, BattleItem *item)
846850 _save->getTile (p)->addItem (item);
847851}
848852
853+ /* *
854+ * New turn preparations. Like fire and smoke spreading.
855+ */
856+ void TerrainModifier::prepareNewTurn ()
857+ {
858+ std::vector<Tile*> tilesOnFire;
859+ std::vector<Tile*> tilesOnSmoke;
860+
861+ // prepare a list of tiles on fire/smoke
862+ for (int i = 0 ; i < _save->getWidth () * _save->getLength () * _save->getHeight (); i++)
863+ {
864+ if (_save->getTiles ()[i]->getFire () > 0 )
865+ {
866+ tilesOnFire.push_back (_save->getTiles ()[i]);
867+ }
868+ if (_save->getTiles ()[i]->getSmoke () > 0 )
869+ {
870+ tilesOnSmoke.push_back (_save->getTiles ()[i]);
871+ }
872+ }
873+
874+ for (std::vector<Tile*>::iterator i = tilesOnSmoke.begin (); i != tilesOnSmoke.end (); i++)
875+ {
876+
877+ (*i)->prepareNewTurn ();
878+ }
879+
880+ for (std::vector<Tile*>::iterator i = tilesOnFire.begin (); i != tilesOnFire.end (); i++)
881+ {
882+ int z = (*i)->getPosition ().z ;
883+ for (int x = (*i)->getPosition ().x -1 ; x <= (*i)->getPosition ().x +1 ; x++)
884+ {
885+ for (int y = (*i)->getPosition ().y -1 ; y <= (*i)->getPosition ().y +1 ; y++)
886+ {
887+ Tile *t = _save->getTile (Position (x, y, z));
888+ if (t && t->getFire () == 0 )
889+ {
890+ // check adjacent tiles - if they have a flammability of < 255, there is a chance...
891+ if (horizontalBlockage ((*i), t, DT_IN ) == 0 )
892+ {
893+ int flam = t->getFlammability ();
894+ if (flam < 255 )
895+ {
896+ double base = RNG::boxMuller (0 ,126 );
897+ if (base < 0 ) base *= -1 ;
898+
899+ if (flam < base)
900+ {
901+ if (RNG::generate (0 , flam) < 2 )
902+ {
903+ t->ignite ();
904+ }
905+ }
906+ }
907+ }
908+ }
909+ }
910+ }
911+
912+ (*i)->prepareNewTurn ();
913+ }
914+
915+ if (tilesOnFire.size () > 0 )
916+ {
917+ calculateTerrainLighting (); // fires could have been stopped
918+ }
919+
920+ }
921+
849922}
0 commit comments