Skip to content

Commit 7f98a69

Browse files
committed
Fix ignored units making it through to the next stage
1. No aliens can ever make it to the next stage 2. No civilians can ever make it to the next stage 3. No dead xcom units can ever make it to the next stage 4. Conscious and unconscious xcom units can make it to the next stage if: a/ All aliens in the current stage are neutralized (killed or stunned) b/ Unit stands on exit tile or lies unconscious on exit tile when aborted This fixes various consistency bugs, e.g. showing live units as dead in the inventory.
1 parent efa947e commit 7f98a69

3 files changed

Lines changed: 51 additions & 2 deletions

File tree

‎src/Battlescape/BattlescapeGenerator.cpp‎

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,44 @@ void BattlescapeGenerator::setMissionSite(MissionSite *mission)
192192
*/
193193
void BattlescapeGenerator::nextStage()
194194
{
195+
// preventively drop all units from soldier's inventory (makes handling easier)
196+
// 1. no alien/civilian living, dead or unconscious is allowed to transition
197+
// 2. no dead xcom unit is allowed to transition
198+
// 3. only living or unconscious xcom units can transition
199+
for (std::vector<BattleUnit*>::iterator unit = _save->getUnits()->begin(); unit != _save->getUnits()->end(); ++unit)
200+
{
201+
if ((*unit)->getOriginalFaction() == FACTION_PLAYER && !(*unit)->isOut())
202+
{
203+
std::vector<BattleItem*> unitsToDrop;
204+
for (std::vector<BattleItem*>::iterator item = (*unit)->getInventory()->begin(); item != (*unit)->getInventory()->end(); ++item)
205+
{
206+
if ((*item)->getUnit())
207+
{
208+
unitsToDrop.push_back(*item);
209+
}
210+
}
211+
for (std::vector<BattleItem*>::iterator corpseItem = unitsToDrop.begin(); corpseItem != unitsToDrop.end(); ++corpseItem)
212+
{
213+
(*corpseItem)->moveToOwner(0);
214+
(*unit)->getTile()->addItem(*corpseItem, (*corpseItem)->getSlot());
215+
}
216+
}
217+
}
218+
195219
int aliensAlive = 0;
196220
// send all enemy units, or those not in endpoint area (if aborted) to time out
197221
for (std::vector<BattleUnit*>::iterator i = _save->getUnits()->begin(); i != _save->getUnits()->end(); ++i)
198222
{
199223
(*i)->clearVisibleUnits();
200224
(*i)->clearVisibleTiles();
201225

226+
Tile *tmpTile = _save->getTile((*i)->getPosition());
227+
bool isInExit = (*i)->isInExitArea(END_POINT) || (*i)->liesInExitArea(tmpTile, END_POINT);
228+
202229
if ((*i)->getStatus() != STATUS_DEAD // if they're not dead
203230
&& (((*i)->getOriginalFaction() == FACTION_PLAYER // and they're a soldier
204231
&& _save->isAborted() // and you aborted
205-
&& !(*i)->isInExitArea(END_POINT)) // and they're not on the exit
232+
&& !isInExit) // and they're not on the exit
206233
|| (*i)->getOriginalFaction() != FACTION_PLAYER)) // or they're not a soldier
207234
{
208235
if ((*i)->getOriginalFaction() == FACTION_HOSTILE && !(*i)->isOut())
@@ -309,7 +336,17 @@ void BattlescapeGenerator::nextStage()
309336
// on the exit grid? it goes to stage two.
310337
else if (tile->getMapData(O_FLOOR)->getSpecialType() == END_POINT)
311338
{
312-
toContainer = &takeToNextStage;
339+
// apply similar logic (for units) as in protocol 1
340+
if ((*i)->getUnit() &&
341+
((*i)->getUnit()->getOriginalFaction() != FACTION_PLAYER ||
342+
(*i)->getUnit()->getStatus() == STATUS_DEAD))
343+
{
344+
toContainer = takeHomeConditional;
345+
}
346+
else
347+
{
348+
toContainer = &takeToNextStage;
349+
}
313350
}
314351
}
315352
}

‎src/Savegame/BattleUnit.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,6 +2099,17 @@ bool BattleUnit::isInExitArea(SpecialTileType stt) const
20992099
return _tile && _tile->getMapData(O_FLOOR) && (_tile->getMapData(O_FLOOR)->getSpecialType() == stt);
21002100
}
21012101

2102+
/**
2103+
* Check if this unit lies (e.g. unconscious) in the exit area.
2104+
* @param tile Unit's location.
2105+
* @param stt Type of exit tile to check for.
2106+
* @return Is in the exit area?
2107+
*/
2108+
bool BattleUnit::liesInExitArea(Tile *tile, SpecialTileType stt) const
2109+
{
2110+
return tile && tile->getMapData(O_FLOOR) && (tile->getMapData(O_FLOOR)->getSpecialType() == stt);
2111+
}
2112+
21022113
/**
21032114
* Gets the unit height taking into account kneeling/standing.
21042115
* @return Unit's height.

‎src/Savegame/BattleUnit.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ class BattleUnit
309309
bool checkAmmo();
310310
/// Check if this unit is in the exit area
311311
bool isInExitArea(SpecialTileType stt = START_POINT) const;
312+
bool liesInExitArea(Tile *tile, SpecialTileType stt = START_POINT) const;
312313
/// Gets the unit height taking into account kneeling/standing.
313314
int getHeight() const;
314315
/// Gets the unit floating elevation.

0 commit comments

Comments
 (0)