Skip to content

Commit a974722

Browse files
committed
Do some extra sanity checking of droids' actions and orders before saving a game,
to help prevent corrupted savegames. Backported from qt branch. Closes ticket:2100
1 parent d422105 commit a974722

File tree

5 files changed

+46
-21
lines changed

5 files changed

+46
-21
lines changed

src/action.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -990,25 +990,9 @@ static void actionHomeBasePos(SDWORD player, SDWORD *px, SDWORD *py)
990990

991991
#define VTOL_ATTACK_AUDIO_DELAY (3*GAME_TICKS_PER_SEC)
992992

993-
// Update the action state for a droid
994-
void actionUpdateDroid(DROID *psDroid)
993+
void actionSanity(DROID *psDroid)
995994
{
996-
BASE_OBJECT *psTarget;
997-
PROPULSION_STATS *psPropStats;
998-
BOOL (*actionUpdateFunc)(DROID *psDroid) = NULL;
999-
signed int i;
1000-
unsigned int j;
1001-
//this is a bit field
1002-
bool nonNullWeapon[DROID_MAXWEAPS] = { false };
1003-
BASE_OBJECT *psTargets[DROID_MAXWEAPS];
1004-
bool hasVisibleTarget = false;
1005-
bool targetVisibile[DROID_MAXWEAPS] = { false };
1006-
bool bHasTarget;
1007-
1008-
CHECK_DROID(psDroid);
1009-
1010-
psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
1011-
ASSERT_OR_RETURN(, psPropStats != NULL, "Invalid propulsion stats pointer");
995+
int i;
1012996

1013997
// clear the target if it has died
1014998
for (i = 0; i < DROID_MAXWEAPS; i++)
@@ -1040,6 +1024,29 @@ void actionUpdateDroid(DROID *psDroid)
10401024
}
10411025
}
10421026
}
1027+
}
1028+
1029+
// Update the action state for a droid
1030+
void actionUpdateDroid(DROID *psDroid)
1031+
{
1032+
BASE_OBJECT *psTarget;
1033+
PROPULSION_STATS *psPropStats;
1034+
BOOL (*actionUpdateFunc)(DROID *psDroid) = NULL;
1035+
signed int i;
1036+
unsigned int j;
1037+
//this is a bit field
1038+
bool nonNullWeapon[DROID_MAXWEAPS] = { false };
1039+
BASE_OBJECT *psTargets[DROID_MAXWEAPS];
1040+
bool hasVisibleTarget = false;
1041+
bool targetVisibile[DROID_MAXWEAPS] = { false };
1042+
bool bHasTarget;
1043+
1044+
CHECK_DROID(psDroid);
1045+
1046+
psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
1047+
ASSERT_OR_RETURN(, psPropStats != NULL, "Invalid propulsion stats pointer");
1048+
1049+
actionSanity(psDroid);
10431050

10441051
//if the droid has been attacked by an EMP weapon, it is temporarily disabled
10451052
if (psDroid->lastHitWeapon == WSC_EMP)

src/action.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ extern const char* getDroidActionName(DROID_ACTION action);
110110
*/
111111
extern void actionUpdateDroid(DROID *psDroid);
112112

113+
/** Do sanity update only. Called from actionUpdateDroid() normally. */
114+
void actionSanity(DROID *psDroid);
115+
113116
/** Give a droid an action. */
114117
extern void actionDroid(DROID *psDroid, DROID_ACTION action);
115118

src/game.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,6 +2347,20 @@ BOOL loadMissionExtras(const char *pGameToLoad, SWORD levelType)
23472347
return true;
23482348
}
23492349

2350+
static void sanityUpdate(void)
2351+
{
2352+
int player;
2353+
DROID *psDroid;
2354+
2355+
for (player = 0; player < game.maxPlayers; player++)
2356+
{
2357+
for (psDroid = apsDroidLists[player]; psDroid; psDroid = psDroid->psNext)
2358+
{
2359+
orderCheckList(psDroid);
2360+
actionSanity(psDroid);
2361+
}
2362+
}
2363+
}
23502364

23512365
// -----------------------------------------------------------------------------------------
23522366
// UserSaveGame ... this is true when you are loading a players save game
@@ -3527,6 +3541,7 @@ BOOL saveGame(char *aFileName, SDWORD saveType)
35273541

35283542
fileExtension = strlen(CurrentFileName) - 3;
35293543
gameTimeStop();
3544+
sanityUpdate();
35303545

35313546
/* Write the data to the file */
35323547
if (!writeGameFile(CurrentFileName, saveType))

src/order.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ RUN_DATA asRunData[MAX_PLAYERS];
8989
// deal with a droid receiving a primary order
9090
BOOL secondaryGotPrimaryOrder(DROID *psDroid, DROID_ORDER order);
9191

92-
// check all the orders in the list for died objects
93-
void orderCheckList(DROID *psDroid);
94-
9592
// clear all the orders from the list
9693
void orderClearDroidList(DROID *psDroid);
9794

src/order.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ typedef enum _secondary_state
144144
//call this *AFTER* every mission so it gets reset
145145
extern void initRunData(void);
146146

147+
/// Check all the orders in the list for died objects
148+
void orderCheckList(DROID *psDroid);
149+
147150
/* Update a droids order state */
148151
extern void orderUpdateDroid(DROID *psDroid);
149152

0 commit comments

Comments
 (0)