qtscript: Save AI group information in the savegame. This may subtly break existing savegames.

master
Per Inge Mathisen 2011-03-30 21:14:05 +02:00
parent 0ee8b860f8
commit 03618b8d2d
12 changed files with 53 additions and 79 deletions

View File

@ -85,10 +85,7 @@ void cmdDroidAddDroid(DROID *psCommander, DROID *psDroid)
if (psCommander->psGroup == NULL)
{
if (!grpCreate(&psGroup))
{
return;
}
psGroup = grpCreate();
psGroup->add(psCommander);
psDroid->group = UBYTE_MAX;
}

View File

@ -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);
}
if ( (psDroid->droidType == DROID_TRANSPORTER) ||
(psDroid->droidType == DROID_COMMAND) )
if (psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_COMMAND)
{
if (!grpCreate(&psGrp))
{
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 = grpCreate();
psGrp->add(psDroid);
}

View File

@ -1636,7 +1636,7 @@ struct SAVE_DROID_V24
SAVE_MOVE_CONTROL sMove; \
SWORD formationDir; \
SDWORD formationX; \
SDWORD formationY
SDWORD aigroupidx
struct SAVE_DROID_V99
{
@ -5105,7 +5105,6 @@ static void SaveDroidMoveControl(SAVE_DROID * const psSaveDroid, DROID const * c
psSaveDroid->sMove.isInFormation = false;
psSaveDroid->formationDir = 0;
psSaveDroid->formationX = 0;
psSaveDroid->formationY = 0;
}
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
FIXME_CAST_ASSIGN(UDWORD, psDroid->psBaseStruct, psSaveDroid->baseStructID);
psDroid->group = psSaveDroid->group;
if (psSaveDroid->aigroupidx >= 0)
{
psDroid->psGroup = grpFind(psSaveDroid->aigroupidx);
}
else
{
psDroid->psGroup = NULL;
}
psDroid->selected = psSaveDroid->selected;
psDroid->died = psSaveDroid->died;
psDroid->lastEmission = psSaveDroid->lastEmission;
@ -5498,7 +5505,6 @@ static bool loadDroidSetPointers(void)
}
}
return true;
}
@ -5535,7 +5541,6 @@ bool loadSaveDroidV(char *pFileData, UDWORD filesize, UDWORD numDroids, UDWORD v
endian_sdword(&psSaveDroid->resistance);
endian_sword(&psSaveDroid->formationDir);
endian_sdword(&psSaveDroid->formationX);
endian_sdword(&psSaveDroid->formationY);
/* DROID_SAVE_V21 includes DROID_SAVE_V20 */
endian_udword(&psSaveDroid->commandId);
/* 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->aigroupidx = psCurr->psGroup ? psCurr->psGroup->id : -1;
psSaveDroid->selected = psCurr->selected;
psSaveDroid->died = psCurr->died;
psSaveDroid->lastEmission = psCurr->lastEmission;
@ -5794,9 +5800,6 @@ static bool buildSaveDroidFromDroid(SAVE_DROID* psSaveDroid, DROID* psCurr, DROI
/* DROID_SAVE_V24 includes DROID_SAVE_V21 */
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 */
endian_udword(&psSaveDroid->commandId);
/* DROID_SAVE_V20 includes OBJECT_SAVE_V20 */

View File

@ -28,10 +28,10 @@
#include "lib/netplay/netplay.h"
#include "multiplay.h"
#include <QList>
#include <QMap>
// 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;
// initialise the group system
@ -47,7 +47,7 @@ void grpShutDown(void)
{
/* Since we are not very diligent removing groups after we have
* 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++)
{
@ -67,23 +67,33 @@ DROID_GROUP::DROID_GROUP()
}
// create a new group
bool grpCreate(DROID_GROUP **ppsGroup)
DROID_GROUP *grpCreate(int id)
{
ASSERT(grpInitialized, "Group code not initialized yet");
*ppsGroup = new DROID_GROUP;
ASSERT_OR_RETURN(false, *ppsGroup, "Out of memory");
(*ppsGroup)->id = grpGlobalManager.size();
grpGlobalManager.push_back(*ppsGroup);
return true;
DROID_GROUP *psGroup = new DROID_GROUP;
if (id == -1)
{
int i;
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)
{
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
@ -200,7 +210,7 @@ void DROID_GROUP::remove(DROID *psDroid)
// free the group if necessary
if (refCount <= 0)
{
grpGlobalManager.removeOne(this);
grpGlobalManager.remove(id);
delete this;
}
}

View File

@ -63,10 +63,10 @@ bool grpInitialise(void);
// shutdown the group system
void grpShutDown(void);
// create a new group
bool grpCreate(DROID_GROUP **ppsGroup);
/// create a new group, use -1 to generate a new ID. never use id != -1 unless loading from a savegame.
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);
#endif // __INCLUDED_SRC_GROUP_H__

View File

@ -1888,10 +1888,8 @@ void unloadTransporter(DROID *psTransporter, UDWORD x, UDWORD y, bool goingHome)
// a commander needs to get it's group back
if (psDroid->droidType == DROID_COMMAND)
{
if (grpCreate(&psGroup))
{
psGroup->add(psDroid);
}
psGroup = grpCreate();
psGroup->add(psDroid);
clearCommandDroidFactory(psDroid);
}

View File

@ -392,11 +392,8 @@ void addDroid(DROID *psDroidToAdd, DROID *pList[MAX_PLAYERS])
// commanders have to get their group back
if (psDroidToAdd->droidType == DROID_COMMAND)
{
grpCreate(&psGroup);
if (psGroup)
{
psGroup->add(psDroidToAdd);
}
psGroup = grpCreate();
psGroup->add(psDroidToAdd);
}
}
else if (pList[psDroidToAdd->player] == mission.apsDroidLists[psDroidToAdd->player])

View File

@ -95,16 +95,8 @@ static QScriptValue js_enumGroup(QScriptContext *context, QScriptEngine *engine)
static QScriptValue js_newGroup(QScriptContext *, QScriptEngine *)
{
DROID_GROUP *newGrp = NULL;
if (grpCreate(&newGrp))
{
return QScriptValue(newGrp->id);
}
else
{
debug(LOG_ERROR, "Failed to create group");
return QScriptValue();
}
DROID_GROUP *newGrp = grpCreate();
return QScriptValue(newGrp->id);
}
static QScriptValue js_enumStruct(QScriptContext *context, QScriptEngine *engine)

View File

@ -1261,13 +1261,7 @@ bool scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size
if (psVal->v.oval == NULL)
{
DROID_GROUP *tmp;
if (!grpCreate(&tmp))
{
debug( LOG_FATAL, "scrValDefLoad: out of memory" );
abort();
break;
}
DROID_GROUP *tmp = grpCreate();
tmp->add(NULL);
psVal->v.oval = tmp;
}

View File

@ -154,10 +154,7 @@ bool scrvNewGroup(INTERP_VAL *psVal)
{
DROID_GROUP *psGroup;
if (!grpCreate(&psGroup))
{
return false;
}
psGroup = grpCreate();
// increment the refcount so the group doesn't get automatically freed when empty
psGroup->add(NULL);

View File

@ -2052,15 +2052,10 @@ static bool setFunctionality(STRUCTURE *psBuilding, STRUCTURE_TYPE functionType)
psRepairFac->psObj = NULL;
psRepairFac->droidQueue = 0;
if (!grpCreate(&((REPAIR_FACILITY*)psBuilding->pFunctionality)->psGroup))
{
debug(LOG_NEVER, "couldn't create repair facility group");
}
else
{
// Add NULL droid to the group
psRepairFac->psGroup->add(NULL);
}
psRepairFac->psGroup = grpCreate();
// Add NULL droid to the group
psRepairFac->psGroup->add(NULL);
// Take advantage of upgrades
structureRepairUpgrade(psBuilding);

View File

@ -1354,10 +1354,8 @@ void transporterRemoveDroid(UDWORD id)
// check if it is a commander
if (psDroid->droidType == DROID_COMMAND)
{
if (grpCreate(&psGroup))
{
psGroup->add(psDroid);
}
psGroup = grpCreate();
psGroup->add(psDroid);
}
psDroid->selected = true;