Skip to content

Commit 92c19e4

Browse files
committed
destroy facilities after base missions
so if the aliens (or you) destroy a facility during a base defense mission, that may have certain consequences, like cancelling a manufacturing project or destroying a craft.
1 parent a2d7a83 commit 92c19e4

3 files changed

Lines changed: 198 additions & 2 deletions

File tree

‎src/Battlescape/DebriefingState.cpp‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "../Savegame/Tile.h"
5353
#include "../Savegame/Ufo.h"
5454
#include "../Savegame/Vehicle.h"
55+
#include "../Savegame/BaseFacility.h"
5556
#include <sstream>
5657
#include "../Menu/ErrorMessageState.h"
5758
#include "../Menu/MainMenuState.h"
@@ -411,15 +412,15 @@ void DebriefingState::prepareDebriefing()
411412
base->setInBattlescape(false);
412413
for (std::vector<Region*>::iterator k = _game->getSavedGame()->getRegions()->begin(); k != _game->getSavedGame()->getRegions()->end(); ++k)
413414
{
414-
if ((*k)->getRules()->insideRegion((*i)->getLongitude(), (*i)->getLatitude()))
415+
if ((*k)->getRules()->insideRegion(base->getLongitude(), base->getLatitude()))
415416
{
416417
_region = (*k);
417418
break;
418419
}
419420
}
420421
for (std::vector<Country*>::iterator k = _game->getSavedGame()->getCountries()->begin(); k != _game->getSavedGame()->getCountries()->end(); ++k)
421422
{
422-
if ((*k)->getRules()->insideCountry((*i)->getLongitude(), (*i)->getLatitude()))
423+
if ((*k)->getRules()->insideCountry(base->getLongitude(), base->getLatitude()))
423424
{
424425
_country = (*k);
425426
break;
@@ -429,6 +430,18 @@ void DebriefingState::prepareDebriefing()
429430
{
430431
_destroyBase = true;
431432
}
433+
for (std::vector<BaseFacility*>::iterator k = base->getFacilities()->begin(); k != base->getFacilities()->end();)
434+
{
435+
// this facility was demolished
436+
if (battle->getModuleMap()[(*k)->getX()][(*k)->getY()].second == 0)
437+
{
438+
base->destroyFacility(k);
439+
}
440+
else
441+
{
442+
++k;
443+
}
444+
}
432445
}
433446
}
434447

‎src/Savegame/Base.cpp‎

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,4 +1232,185 @@ std::vector<Vehicle*> *Base::getVehicles()
12321232
{
12331233
return &_vehicles;
12341234
}
1235+
1236+
/**
1237+
* removes a base module, and deals with the ramifications thereof
1238+
* @param facility an iterator reference to the facility to destroy and remove.
1239+
*/
1240+
void Base::destroyFacility(std::vector<BaseFacility*>::iterator &facility)
1241+
{
1242+
if ((*facility)->getRules()->getCrafts() > 0)
1243+
{
1244+
// hangar destruction - destroy crafts and any production of crafts
1245+
// if this will mean there is no hangar to contain it
1246+
if ((*facility)->getCraft())
1247+
{
1248+
// remove all soldiers
1249+
if ((*facility)->getCraft()->getNumSoldiers())
1250+
{
1251+
for (std::vector<Soldier*>::iterator i = _soldiers.begin(); i != _soldiers.end(); ++i)
1252+
{
1253+
if ((*i)->getCraft() == (*facility)->getCraft())
1254+
{
1255+
(*i)->setCraft(0);
1256+
}
1257+
}
1258+
}
1259+
// remove all items
1260+
while (!(*facility)->getCraft()->getItems()->getContents()->empty())
1261+
{
1262+
std::map<std::string, int>::iterator i = (*facility)->getCraft()->getItems()->getContents()->begin();
1263+
_items->addItem((*i).first, (*i).second);
1264+
(*facility)->getCraft()->getItems()->removeItem((*i).first, (*i).second);
1265+
}
1266+
for (std::vector<Craft*>::iterator i = _crafts.begin(); i != _crafts.end(); ++i)
1267+
{
1268+
if (*i = (*facility)->getCraft())
1269+
{
1270+
delete (*i);
1271+
_crafts.erase(i);
1272+
break;
1273+
}
1274+
}
1275+
}
1276+
else
1277+
{
1278+
bool remove = true;
1279+
// no craft - check productions.
1280+
for (std::vector<Production*>::iterator i = _productions.begin(); i != _productions.end();)
1281+
{
1282+
if (getAvailableHangars() - getUsedHangars() - (*facility)->getRules()->getCrafts() < 0 && (*i)->getRules()->getCategory() == "STR_CRAFT")
1283+
{
1284+
_engineers += (*i)->getAssignedEngineers();
1285+
delete *i;
1286+
_productions.erase(i);
1287+
remove = false;
1288+
break;
1289+
}
1290+
else
1291+
{
1292+
++i;
1293+
}
1294+
}
1295+
if (remove && !_transfers.empty())
1296+
{
1297+
for (std::vector<Transfer*>::iterator i = _transfers.begin(); i != _transfers.end(); )
1298+
{
1299+
if ((*i)->getType() == TRANSFER_CRAFT)
1300+
{
1301+
delete *i;
1302+
_transfers.erase(i);
1303+
break;
1304+
}
1305+
}
1306+
}
1307+
}
1308+
}
1309+
else if ((*facility)->getRules()->getPsiLaboratories() > 0)
1310+
{
1311+
// psi lab destruction: remove any soldiers over the maximum allowable from psi training.
1312+
int toRemove = getUsedPsiLabs() - (getAvailablePsiLabs() - (*facility)->getRules()->getPsiLaboratories());
1313+
for (std::vector<Soldier*>::iterator i = _soldiers.begin(); i != _soldiers.end() && toRemove > 0; ++i)
1314+
{
1315+
if ((*i)->isInPsiTraining())
1316+
{
1317+
(*i)->setPsiTraining();
1318+
--toRemove;
1319+
}
1320+
}
1321+
}
1322+
else if ((*facility)->getRules()->getLaboratories())
1323+
{
1324+
// lab destruction: enforce lab space limits. take scientists off projects until
1325+
// it all evens out.
1326+
int toRemove = getUsedLaboratories() - (getAvailableLaboratories() - (*facility)->getRules()->getLaboratories());
1327+
for (std::vector<ResearchProject*>::iterator i = _research.begin(); i != _research.end() && toRemove > 0;)
1328+
{
1329+
if ((*i)->getAssigned() > toRemove)
1330+
{
1331+
(*i)->setAssigned((*i)->getAssigned() - toRemove);
1332+
break;
1333+
}
1334+
else
1335+
{
1336+
toRemove -= (*i)->getAssigned();
1337+
_scientists += (*i)->getAssigned();
1338+
delete *i;
1339+
i = _research.erase(i);
1340+
}
1341+
}
1342+
}
1343+
else if ((*facility)->getRules()->getWorkshops())
1344+
{
1345+
// workshop destruction: similar to lab destruction, but we'll lay off engineers instead
1346+
int toRemove = getUsedWorkshops() - (getAvailableWorkshops() - (*facility)->getRules()->getWorkshops());
1347+
for (std::vector<Production*>::iterator i = _productions.begin(); i != _productions.end() && toRemove > 0;)
1348+
{
1349+
if ((*i)->getAssignedEngineers() > toRemove)
1350+
{
1351+
(*i)->setAssignedEngineers((*i)->getAssignedEngineers() - toRemove);
1352+
break;
1353+
}
1354+
else
1355+
{
1356+
toRemove -= (*i)->getAssignedEngineers();
1357+
_scientists += (*i)->getAssignedEngineers();
1358+
delete *i;
1359+
i = _productions.erase(i);
1360+
}
1361+
}
1362+
}
1363+
else if ((*facility)->getRules()->getStorage())
1364+
{
1365+
// we won't destroy the items physically AT the base,
1366+
// but any items in transit will end up at the dead letter office.
1367+
if (getUsedStores() - (getAvailableStores() - (*facility)->getRules()->getStorage()) < 0 && !_transfers.empty())
1368+
{
1369+
for (std::vector<Transfer*>::iterator i = _transfers.begin(); i != _transfers.end(); )
1370+
{
1371+
if ((*i)->getType() == TRANSFER_ITEM)
1372+
{
1373+
delete *i;
1374+
i = _transfers.erase(i);
1375+
}
1376+
}
1377+
}
1378+
}
1379+
else if ((*facility)->getRules()->getPersonnel())
1380+
{
1381+
// as above, we won't actually fire people, but we'll block any new ones coming in.
1382+
if (getUsedQuarters() - (getAvailableQuarters() - (*facility)->getRules()->getPersonnel()) < 0 && !_transfers.empty())
1383+
{
1384+
for (std::vector<Transfer*>::iterator i = _transfers.begin(); i != _transfers.end(); )
1385+
{
1386+
bool del = false;
1387+
if ((*i)->getType() == TRANSFER_ENGINEER)
1388+
{
1389+
_engineers -= (*i)->getQuantity();
1390+
del = true;
1391+
}
1392+
else if ((*i)->getType() == TRANSFER_SCIENTIST)
1393+
{
1394+
_scientists -= (*i)->getQuantity();
1395+
del = true;
1396+
}
1397+
else if ((*i)->getType() == TRANSFER_SOLDIER)
1398+
{
1399+
del = true;
1400+
}
1401+
if (del)
1402+
{
1403+
delete *i;
1404+
i = _transfers.erase(i);
1405+
}
1406+
else
1407+
{
1408+
++i;
1409+
}
1410+
}
1411+
}
1412+
}
1413+
delete *facility;
1414+
facility = _facilities.erase(facility);
1415+
}
12351416
}

‎src/Savegame/Base.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ class Base : public Target
193193
std::vector<BaseFacility*> *getDefenses();
194194
/// Gets the base's vehicles.
195195
std::vector<Vehicle*> *getVehicles();
196+
/// destroy a facility and deal with the side effects.
197+
void destroyFacility(std::vector<BaseFacility*>::iterator &facility);
196198
};
197199

198200
}

0 commit comments

Comments
 (0)