qtscript: Save AI group information in the savegame. This may subtly break existing savegames.
parent
0ee8b860f8
commit
03618b8d2d
|
@ -85,10 +85,7 @@ void cmdDroidAddDroid(DROID *psCommander, DROID *psDroid)
|
||||||
|
|
||||||
if (psCommander->psGroup == NULL)
|
if (psCommander->psGroup == NULL)
|
||||||
{
|
{
|
||||||
if (!grpCreate(&psGroup))
|
psGroup = grpCreate();
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
psGroup->add(psCommander);
|
psGroup->add(psCommander);
|
||||||
psDroid->group = UBYTE_MAX;
|
psDroid->group = UBYTE_MAX;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2247,16 +2247,9 @@ DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD pl
|
||||||
psDroid->pos.z = map_Height(psDroid->pos.x, psDroid->pos.y);
|
psDroid->pos.z = map_Height(psDroid->pos.x, psDroid->pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (psDroid->droidType == DROID_TRANSPORTER) ||
|
if (psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_COMMAND)
|
||||||
(psDroid->droidType == DROID_COMMAND) )
|
|
||||||
{
|
{
|
||||||
if (!grpCreate(&psGrp))
|
psGrp = grpCreate();
|
||||||
{
|
|
||||||
debug(LOG_NEVER, "unit build: unable to create group");
|
|
||||||
ASSERT(!"unable to create group", "Can't create unit because can't create group");
|
|
||||||
delete psDroid;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
psGrp->add(psDroid);
|
psGrp->add(psDroid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
src/game.cpp
17
src/game.cpp
|
@ -1636,7 +1636,7 @@ struct SAVE_DROID_V24
|
||||||
SAVE_MOVE_CONTROL sMove; \
|
SAVE_MOVE_CONTROL sMove; \
|
||||||
SWORD formationDir; \
|
SWORD formationDir; \
|
||||||
SDWORD formationX; \
|
SDWORD formationX; \
|
||||||
SDWORD formationY
|
SDWORD aigroupidx
|
||||||
|
|
||||||
struct SAVE_DROID_V99
|
struct SAVE_DROID_V99
|
||||||
{
|
{
|
||||||
|
@ -5105,7 +5105,6 @@ static void SaveDroidMoveControl(SAVE_DROID * const psSaveDroid, DROID const * c
|
||||||
psSaveDroid->sMove.isInFormation = false;
|
psSaveDroid->sMove.isInFormation = false;
|
||||||
psSaveDroid->formationDir = 0;
|
psSaveDroid->formationDir = 0;
|
||||||
psSaveDroid->formationX = 0;
|
psSaveDroid->formationX = 0;
|
||||||
psSaveDroid->formationY = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadDroidMoveControl(DROID * const psDroid, SAVE_DROID const * const psSaveDroid)
|
static void LoadDroidMoveControl(DROID * const psDroid, SAVE_DROID const * const psSaveDroid)
|
||||||
|
@ -5334,6 +5333,14 @@ static DROID* buildDroidFromSaveDroid(SAVE_DROID* psSaveDroid, UDWORD version)
|
||||||
//rebuild the object pointer from the ID
|
//rebuild the object pointer from the ID
|
||||||
FIXME_CAST_ASSIGN(UDWORD, psDroid->psBaseStruct, psSaveDroid->baseStructID);
|
FIXME_CAST_ASSIGN(UDWORD, psDroid->psBaseStruct, psSaveDroid->baseStructID);
|
||||||
psDroid->group = psSaveDroid->group;
|
psDroid->group = psSaveDroid->group;
|
||||||
|
if (psSaveDroid->aigroupidx >= 0)
|
||||||
|
{
|
||||||
|
psDroid->psGroup = grpFind(psSaveDroid->aigroupidx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
psDroid->psGroup = NULL;
|
||||||
|
}
|
||||||
psDroid->selected = psSaveDroid->selected;
|
psDroid->selected = psSaveDroid->selected;
|
||||||
psDroid->died = psSaveDroid->died;
|
psDroid->died = psSaveDroid->died;
|
||||||
psDroid->lastEmission = psSaveDroid->lastEmission;
|
psDroid->lastEmission = psSaveDroid->lastEmission;
|
||||||
|
@ -5498,7 +5505,6 @@ static bool loadDroidSetPointers(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5535,7 +5541,6 @@ bool loadSaveDroidV(char *pFileData, UDWORD filesize, UDWORD numDroids, UDWORD v
|
||||||
endian_sdword(&psSaveDroid->resistance);
|
endian_sdword(&psSaveDroid->resistance);
|
||||||
endian_sword(&psSaveDroid->formationDir);
|
endian_sword(&psSaveDroid->formationDir);
|
||||||
endian_sdword(&psSaveDroid->formationX);
|
endian_sdword(&psSaveDroid->formationX);
|
||||||
endian_sdword(&psSaveDroid->formationY);
|
|
||||||
/* DROID_SAVE_V21 includes DROID_SAVE_V20 */
|
/* DROID_SAVE_V21 includes DROID_SAVE_V20 */
|
||||||
endian_udword(&psSaveDroid->commandId);
|
endian_udword(&psSaveDroid->commandId);
|
||||||
/* DROID_SAVE_V20 includes OBJECT_SAVE_V20, SAVE_WEAPON */
|
/* DROID_SAVE_V20 includes OBJECT_SAVE_V20, SAVE_WEAPON */
|
||||||
|
@ -5752,6 +5757,7 @@ static bool buildSaveDroidFromDroid(SAVE_DROID* psSaveDroid, DROID* psCurr, DROI
|
||||||
}
|
}
|
||||||
|
|
||||||
psSaveDroid->group = psCurr->group;
|
psSaveDroid->group = psCurr->group;
|
||||||
|
psSaveDroid->aigroupidx = psCurr->psGroup ? psCurr->psGroup->id : -1;
|
||||||
psSaveDroid->selected = psCurr->selected;
|
psSaveDroid->selected = psCurr->selected;
|
||||||
psSaveDroid->died = psCurr->died;
|
psSaveDroid->died = psCurr->died;
|
||||||
psSaveDroid->lastEmission = psCurr->lastEmission;
|
psSaveDroid->lastEmission = psCurr->lastEmission;
|
||||||
|
@ -5794,9 +5800,6 @@ static bool buildSaveDroidFromDroid(SAVE_DROID* psSaveDroid, DROID* psCurr, DROI
|
||||||
/* DROID_SAVE_V24 includes DROID_SAVE_V21 */
|
/* DROID_SAVE_V24 includes DROID_SAVE_V21 */
|
||||||
endian_sdword(&psSaveDroid->resistance);
|
endian_sdword(&psSaveDroid->resistance);
|
||||||
|
|
||||||
// psSaveDroid->formationDir, psSaveDroid->formationX and psSaveDroid->formationY are set by SaveDroidMoveControl
|
|
||||||
// already, which also performs endian swapping, so we can (and should!) safely ignore those here.
|
|
||||||
|
|
||||||
/* DROID_SAVE_V21 includes DROID_SAVE_V20 */
|
/* DROID_SAVE_V21 includes DROID_SAVE_V20 */
|
||||||
endian_udword(&psSaveDroid->commandId);
|
endian_udword(&psSaveDroid->commandId);
|
||||||
/* DROID_SAVE_V20 includes OBJECT_SAVE_V20 */
|
/* DROID_SAVE_V20 includes OBJECT_SAVE_V20 */
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
#include "lib/netplay/netplay.h"
|
#include "lib/netplay/netplay.h"
|
||||||
|
|
||||||
#include "multiplay.h"
|
#include "multiplay.h"
|
||||||
#include <QList>
|
#include <QMap>
|
||||||
|
|
||||||
// Group system variables: grpGlobalManager enables to remove all the groups to Shutdown the system
|
// Group system variables: grpGlobalManager enables to remove all the groups to Shutdown the system
|
||||||
static QList<DROID_GROUP *> grpGlobalManager;
|
static QMap<int, DROID_GROUP *> grpGlobalManager;
|
||||||
static bool grpInitialized = false;
|
static bool grpInitialized = false;
|
||||||
|
|
||||||
// initialise the group system
|
// initialise the group system
|
||||||
|
@ -47,7 +47,7 @@ void grpShutDown(void)
|
||||||
{
|
{
|
||||||
/* Since we are not very diligent removing groups after we have
|
/* Since we are not very diligent removing groups after we have
|
||||||
* created them; we need this hack to remove them on level end. */
|
* created them; we need this hack to remove them on level end. */
|
||||||
QList<DROID_GROUP *>::iterator iter;
|
QMap<int, DROID_GROUP *>::iterator iter;
|
||||||
|
|
||||||
for(iter = grpGlobalManager.begin(); iter != grpGlobalManager.end(); iter++)
|
for(iter = grpGlobalManager.begin(); iter != grpGlobalManager.end(); iter++)
|
||||||
{
|
{
|
||||||
|
@ -67,23 +67,33 @@ DROID_GROUP::DROID_GROUP()
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new group
|
// create a new group
|
||||||
bool grpCreate(DROID_GROUP **ppsGroup)
|
DROID_GROUP *grpCreate(int id)
|
||||||
{
|
{
|
||||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||||
*ppsGroup = new DROID_GROUP;
|
DROID_GROUP *psGroup = new DROID_GROUP;
|
||||||
ASSERT_OR_RETURN(false, *ppsGroup, "Out of memory");
|
if (id == -1)
|
||||||
(*ppsGroup)->id = grpGlobalManager.size();
|
{
|
||||||
grpGlobalManager.push_back(*ppsGroup);
|
int i;
|
||||||
return true;
|
for (i = 0; grpGlobalManager.contains(i); i++) {} // surly hack
|
||||||
|
psGroup->id = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(!grpGlobalManager.contains(id), "Group %d is already created!", id);
|
||||||
|
psGroup->id = id;
|
||||||
|
}
|
||||||
|
grpGlobalManager.insert(psGroup->id, psGroup);
|
||||||
|
return psGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DROID_GROUP *grpFind(int id)
|
DROID_GROUP *grpFind(int id)
|
||||||
{
|
{
|
||||||
if (id >= grpGlobalManager.size())
|
DROID_GROUP *psGroup = grpGlobalManager.value(id, NULL);
|
||||||
|
if (!psGroup)
|
||||||
{
|
{
|
||||||
return NULL;
|
psGroup = grpCreate(id);
|
||||||
}
|
}
|
||||||
return grpGlobalManager.at(id);
|
return psGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a droid to a group
|
// add a droid to a group
|
||||||
|
@ -200,7 +210,7 @@ void DROID_GROUP::remove(DROID *psDroid)
|
||||||
// free the group if necessary
|
// free the group if necessary
|
||||||
if (refCount <= 0)
|
if (refCount <= 0)
|
||||||
{
|
{
|
||||||
grpGlobalManager.removeOne(this);
|
grpGlobalManager.remove(id);
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,10 @@ bool grpInitialise(void);
|
||||||
// shutdown the group system
|
// shutdown the group system
|
||||||
void grpShutDown(void);
|
void grpShutDown(void);
|
||||||
|
|
||||||
// create a new group
|
/// create a new group, use -1 to generate a new ID. never use id != -1 unless loading from a savegame.
|
||||||
bool grpCreate(DROID_GROUP **ppsGroup);
|
DROID_GROUP *grpCreate(int id = -1);
|
||||||
|
|
||||||
/// lookup group by its unique id
|
/// lookup group by its unique id, or create it if not found
|
||||||
DROID_GROUP *grpFind(int id);
|
DROID_GROUP *grpFind(int id);
|
||||||
|
|
||||||
#endif // __INCLUDED_SRC_GROUP_H__
|
#endif // __INCLUDED_SRC_GROUP_H__
|
||||||
|
|
|
@ -1888,10 +1888,8 @@ void unloadTransporter(DROID *psTransporter, UDWORD x, UDWORD y, bool goingHome)
|
||||||
// a commander needs to get it's group back
|
// a commander needs to get it's group back
|
||||||
if (psDroid->droidType == DROID_COMMAND)
|
if (psDroid->droidType == DROID_COMMAND)
|
||||||
{
|
{
|
||||||
if (grpCreate(&psGroup))
|
psGroup = grpCreate();
|
||||||
{
|
psGroup->add(psDroid);
|
||||||
psGroup->add(psDroid);
|
|
||||||
}
|
|
||||||
clearCommandDroidFactory(psDroid);
|
clearCommandDroidFactory(psDroid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -392,11 +392,8 @@ void addDroid(DROID *psDroidToAdd, DROID *pList[MAX_PLAYERS])
|
||||||
// commanders have to get their group back
|
// commanders have to get their group back
|
||||||
if (psDroidToAdd->droidType == DROID_COMMAND)
|
if (psDroidToAdd->droidType == DROID_COMMAND)
|
||||||
{
|
{
|
||||||
grpCreate(&psGroup);
|
psGroup = grpCreate();
|
||||||
if (psGroup)
|
psGroup->add(psDroidToAdd);
|
||||||
{
|
|
||||||
psGroup->add(psDroidToAdd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pList[psDroidToAdd->player] == mission.apsDroidLists[psDroidToAdd->player])
|
else if (pList[psDroidToAdd->player] == mission.apsDroidLists[psDroidToAdd->player])
|
||||||
|
|
|
@ -95,16 +95,8 @@ static QScriptValue js_enumGroup(QScriptContext *context, QScriptEngine *engine)
|
||||||
|
|
||||||
static QScriptValue js_newGroup(QScriptContext *, QScriptEngine *)
|
static QScriptValue js_newGroup(QScriptContext *, QScriptEngine *)
|
||||||
{
|
{
|
||||||
DROID_GROUP *newGrp = NULL;
|
DROID_GROUP *newGrp = grpCreate();
|
||||||
if (grpCreate(&newGrp))
|
return QScriptValue(newGrp->id);
|
||||||
{
|
|
||||||
return QScriptValue(newGrp->id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug(LOG_ERROR, "Failed to create group");
|
|
||||||
return QScriptValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QScriptValue js_enumStruct(QScriptContext *context, QScriptEngine *engine)
|
static QScriptValue js_enumStruct(QScriptContext *context, QScriptEngine *engine)
|
||||||
|
|
|
@ -1261,13 +1261,7 @@ bool scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size
|
||||||
|
|
||||||
if (psVal->v.oval == NULL)
|
if (psVal->v.oval == NULL)
|
||||||
{
|
{
|
||||||
DROID_GROUP *tmp;
|
DROID_GROUP *tmp = grpCreate();
|
||||||
if (!grpCreate(&tmp))
|
|
||||||
{
|
|
||||||
debug( LOG_FATAL, "scrValDefLoad: out of memory" );
|
|
||||||
abort();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmp->add(NULL);
|
tmp->add(NULL);
|
||||||
psVal->v.oval = tmp;
|
psVal->v.oval = tmp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,10 +154,7 @@ bool scrvNewGroup(INTERP_VAL *psVal)
|
||||||
{
|
{
|
||||||
DROID_GROUP *psGroup;
|
DROID_GROUP *psGroup;
|
||||||
|
|
||||||
if (!grpCreate(&psGroup))
|
psGroup = grpCreate();
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment the refcount so the group doesn't get automatically freed when empty
|
// increment the refcount so the group doesn't get automatically freed when empty
|
||||||
psGroup->add(NULL);
|
psGroup->add(NULL);
|
||||||
|
|
|
@ -2052,15 +2052,10 @@ static bool setFunctionality(STRUCTURE *psBuilding, STRUCTURE_TYPE functionType)
|
||||||
psRepairFac->psObj = NULL;
|
psRepairFac->psObj = NULL;
|
||||||
psRepairFac->droidQueue = 0;
|
psRepairFac->droidQueue = 0;
|
||||||
|
|
||||||
if (!grpCreate(&((REPAIR_FACILITY*)psBuilding->pFunctionality)->psGroup))
|
psRepairFac->psGroup = grpCreate();
|
||||||
{
|
|
||||||
debug(LOG_NEVER, "couldn't create repair facility group");
|
// Add NULL droid to the group
|
||||||
}
|
psRepairFac->psGroup->add(NULL);
|
||||||
else
|
|
||||||
{
|
|
||||||
// Add NULL droid to the group
|
|
||||||
psRepairFac->psGroup->add(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take advantage of upgrades
|
// Take advantage of upgrades
|
||||||
structureRepairUpgrade(psBuilding);
|
structureRepairUpgrade(psBuilding);
|
||||||
|
|
|
@ -1354,10 +1354,8 @@ void transporterRemoveDroid(UDWORD id)
|
||||||
// check if it is a commander
|
// check if it is a commander
|
||||||
if (psDroid->droidType == DROID_COMMAND)
|
if (psDroid->droidType == DROID_COMMAND)
|
||||||
{
|
{
|
||||||
if (grpCreate(&psGroup))
|
psGroup = grpCreate();
|
||||||
{
|
psGroup->add(psDroid);
|
||||||
psGroup->add(psDroid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
psDroid->selected = true;
|
psDroid->selected = true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue