// Give a group an order bool scrOrderGroup(void) { DROID_GROUP *psGroup; DROID_ORDER order; if (!stackPopParams(2, ST_GROUP, &psGroup, VAL_INT, &order)) { return false; } ASSERT(psGroup != NULL, "scrOrderGroup: Invalid group pointer"); if (order != DORDER_STOP && order != DORDER_RETREAT && order != DORDER_DESTRUCT && order != DORDER_RTR && order != DORDER_RTB && order != DORDER_RUN) { ASSERT(false, "scrOrderGroup: Invalid order"); return false; } debug(LOG_NEVER, "group %p (%u) order %d", psGroup, psGroup->getNumMembers(), order); psGroup->orderGroup(order); return true; }
// Add droids in an area to a group bool scrGroupAddArea(void) { DROID_GROUP *psGroup; DROID *psDroid; SDWORD x1, y1, x2, y2, player; if (!stackPopParams(6, ST_GROUP, &psGroup, VAL_INT, &player, VAL_INT, &x1, VAL_INT, &y1, VAL_INT, &x2, VAL_INT, &y2)) { return false; } ASSERT(psGroup != NULL, "scrGroupAdd: Invalid group pointer"); if (player < 0 || player >= MAX_PLAYERS) { ASSERT(false, "scrGroupAddArea: invalid player"); return false; } for (psDroid = apsDroidLists[player]; psDroid; psDroid = psDroid->psNext) { if (((SDWORD)psDroid->pos.x >= x1) && ((SDWORD)psDroid->pos.x <= x2) && ((SDWORD)psDroid->pos.y >= y1) && ((SDWORD)psDroid->pos.y <= y2) && psDroid->droidType != DROID_COMMAND && (psDroid->droidType != DROID_TRANSPORTER && psDroid->droidType != DROID_SUPERTRANSPORTER)) { psGroup->add(psDroid); } } return true; }
// Add a droid to a group bool scrGroupAddDroid(void) { DROID_GROUP *psGroup; DROID *psDroid; if (!stackPopParams(2, ST_GROUP, &psGroup, ST_DROID, &psDroid)) { return false; } ASSERT(psGroup != NULL, "scrGroupAdd: Invalid group pointer"); ASSERT(psDroid != NULL, "scrGroupAdd: Invalid droid pointer"); if (psDroid == NULL) { return false; } if (psDroid->droidType == DROID_COMMAND) { debug(LOG_ERROR, "scrGroupAdd: cannot add a command droid to a group"); return false; } if (psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER) { debug(LOG_ERROR, "scrGroupAdd: cannot add a transporter to a group"); return false; } psGroup->add(psDroid); return true; }
/** This function adds the droid to the command group commanded by psCommander. * It creates a group if it doesn't exist. * If the group is not full, it adds the droid to it and sets all the droid's states and orders to the group's. */ void cmdDroidAddDroid(DROID *psCommander, DROID *psDroid) { DROID_GROUP *psGroup; if (psCommander->psGroup == NULL) { psGroup = grpCreate(); psGroup->add(psCommander); psDroid->group = UBYTE_MAX; } if (psCommander->psGroup->getNumMembers() < cmdDroidMaxGroup(psCommander)) { psCommander->psGroup->add(psDroid); psDroid->group = UBYTE_MAX; // set the secondary states for the unit secondarySetState(psDroid, DSO_REPAIR_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_REPLEV_MASK), ModeImmediate); secondarySetState(psDroid, DSO_ATTACK_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_ALEV_MASK), ModeImmediate); orderDroidObj(psDroid, DORDER_GUARD, (BASE_OBJECT *)psCommander, ModeImmediate); } else { audio_PlayTrack( ID_SOUND_BUILD_FAIL ); addConsoleMessage(_("Commander needs a higher level to command more units"), DEFAULT_JUSTIFY, SYSTEM_MESSAGE); } }
bool scrCBTransporterLandedB( void ) { SDWORD player; DROID_GROUP *psGroup; DROID *psTransporter, *psDroid, *psNext; bool retval; DROID **ppsTransp; if (!stackPopParams(3, ST_GROUP, &psGroup, VAL_INT, &player, VAL_REF|ST_DROID, &ppsTransp)) { debug(LOG_ERROR, "scrCBTransporterLandedB(): stack failed"); return false; } psTransporter = transporterGetScriptCurrent(); if ( (psTransporter == NULL) || (psTransporter->player != (UDWORD)player) ) { retval = false; } else { *ppsTransp = psTransporter; //return landed transporter /* if not selectedPlayer unload droids */ //if ( (UDWORD)player != selectedPlayer ) //{ /* transfer droids from transporter group to current group */ for(psDroid=psTransporter->psGroup->psList; psDroid; psDroid=psNext) { psNext = psDroid->psGrpNext; if ( psDroid != psTransporter ) { psGroup->add(psDroid); } } //} retval = true; } scrFunctionResult.v.bval = retval; if (!stackPushResult(VAL_BOOL, &scrFunctionResult)) { debug(LOG_ERROR, "scrCBTransporterLandedB: push landed"); return false; } return true; }
// release a ST_GROUP variable void scrvReleaseGroup(INTERP_VAL *psVal) { DROID_GROUP *psGroup; psGroup = (DROID_GROUP*)psVal->v.oval; psGroup->removeAll(); ASSERT( psGroup->refCount == 1, "scrvReleaseGroup: ref count is wrong" ); // do a final Remove to free the group psGroup->remove(NULL); }
// create a group structure for a ST_GROUP variable bool scrvNewGroup(INTERP_VAL *psVal) { DROID_GROUP *psGroup; psGroup = grpCreate(); // increment the refcount so the group doesn't get automatically freed when empty psGroup->add(NULL); psVal->v.oval = psGroup; return true; }
static QScriptValue js_groupAddDroid(QScriptContext *context, QScriptEngine *engine) { int groupId = context->argument(0).toInt32(); DROID_GROUP *psGroup = grpFind(groupId); QScriptValue droidVal = context->argument(1); int droidId = droidVal.property("id").toInt32(); int droidPlayer = droidVal.property("player").toInt32(); DROID *psDroid = IdToDroid(droidId, droidPlayer); SCRIPT_ASSERT(context, psGroup, "Invalid group index %d", groupId); SCRIPT_ASSERT(context, psDroid, "Invalid droid index %d", droidId); psGroup->add(psDroid); return QScriptValue(); }
bool scrCBTransporterLanded( void ) { SDWORD player; DROID_GROUP *psGroup; DROID *psTransporter, *psDroid, *psNext; bool retval; if (!stackPopParams(2, ST_GROUP, &psGroup, VAL_INT, &player)) { return false; } psTransporter = transporterGetScriptCurrent(); if ( (psTransporter == NULL) || (psTransporter->player != (UDWORD)player) ) { retval = false; } else { /* if not selectedPlayer unload droids */ if ( (UDWORD)player != selectedPlayer ) { /* transfer droids from transporter group to current group */ for(psDroid=psTransporter->psGroup->psList; psDroid; psDroid=psNext) { psNext = psDroid->psGrpNext; if ( psDroid != psTransporter ) { psGroup->add(psDroid); } } } retval = true; } scrFunctionResult.v.bval = retval; if (!stackPushResult(VAL_BOOL, &scrFunctionResult)) { return false; } return true; }
// set the secondary state for a droid bool scrSetGroupSecondary(void) { DROID_GROUP *psGroup; SECONDARY_ORDER sec; SECONDARY_STATE state; if (!stackPopParams(3, ST_GROUP, &psGroup, VAL_INT, &sec, VAL_INT, &state)) { return false; } ASSERT(psGroup != NULL, "scrSetGroupSecondary: invalid group pointer"); psGroup->setSecondary(sec, state); return true; }
static QScriptValue js_groupAddArea(QScriptContext *context, QScriptEngine *engine) { int groupId = context->argument(0).toInt32(); int player = engine->globalObject().property("me").toInt32(); int x1 = context->argument(1).toInt32(); int y1 = context->argument(2).toInt32(); int x2 = context->argument(3).toInt32(); int y2 = context->argument(4).toInt32(); DROID_GROUP *psGroup = grpFind(groupId); SCRIPT_ASSERT(context, psGroup, "Invalid group index %d", groupId); for (DROID *psDroid = apsDroidLists[player]; psGroup && psDroid; psDroid = psDroid->psNext) { if (psDroid->pos.x >= x1 && psDroid->pos.x <= x2 && psDroid->pos.y >= y1 && psDroid->pos.y <= y2 && psDroid->droidType != DROID_COMMAND && psDroid->droidType != DROID_TRANSPORTER) { psGroup->add(psDroid); } } return QScriptValue(); }
// Give a group an order to an object bool scrOrderGroupObj(void) { DROID_GROUP *psGroup; DROID_ORDER order; BASE_OBJECT *psObj; if (!stackPopParams(3, ST_GROUP, &psGroup, VAL_INT, &order, ST_BASEOBJECT, &psObj)) { return false; } ASSERT(psGroup != NULL, "scrOrderGroupObj: Invalid group pointer"); ASSERT(psObj != NULL, "scrOrderGroupObj: Invalid object pointer"); if (order != DORDER_ATTACK && order != DORDER_HELPBUILD && order != DORDER_DEMOLISH && order != DORDER_REPAIR && order != DORDER_OBSERVE && order != DORDER_EMBARK && order != DORDER_FIRESUPPORT && order != DORDER_DROIDREPAIR) { ASSERT(false, "scrOrderGroupObj: Invalid order"); return false; } debug(LOG_NEVER, "group %p (%u) order %d, obj type %d player %d id %d", psGroup, psGroup->getNumMembers(), order, psObj->type, psObj->player, psObj->id); psGroup->orderGroup(order, psObj); return true; }
// Give a group an order to a location bool scrOrderGroupLoc(void) { DROID_GROUP *psGroup; DROID_ORDER order; SDWORD x, y; if (!stackPopParams(4, ST_GROUP, &psGroup, VAL_INT, &order, VAL_INT, &x, VAL_INT, &y)) { return false; } ASSERT(psGroup != NULL, "scrOrderGroupLoc: Invalid group pointer"); if (order != DORDER_MOVE && order != DORDER_SCOUT) { ASSERT(false, "scrOrderGroupLoc: Invalid order"); return false; } if (x < 0 || x > world_coord(mapWidth) || y < 0 || y > world_coord(mapHeight)) { ASSERT(false, "Invalid map location (%d, %d), max is (%d, %d)", x, y, world_coord(mapWidth), world_coord(mapHeight)); return false; } debug(LOG_NEVER, "group %p (%u) order %d (%d,%d)", psGroup, psGroup->getNumMembers(), order, x, y); psGroup->orderGroup(order, (UDWORD)x, (UDWORD)y); return true; }
/// default value load routine bool scrValDefLoad(INTERP_VAL *psVal, WzConfig &ini) { DROID *psCDroid; SDWORD index, members; UDWORD id; LEVEL_DATASET *psLevel; DROID_GROUP *psGroup = NULL; switch ((unsigned)psVal->type) // Unsigned cast to suppress compiler warnings due to enum abuse. { case ST_INTMESSAGE: if (ini.contains("data")) { psVal->v.oval = (void*)getViewData(ini.value("data").toString().toAscii().constData()); } else { psVal->v.oval = NULL; } break; case ST_BASEOBJECT: case ST_DROID: case ST_STRUCTURE: case ST_FEATURE: if (ini.contains("data")) { psVal->v.oval = (void*)getBaseObjFromId(ini.value("data").toInt()); } else { psVal->v.oval = NULL; } break; case ST_BASESTATS: case ST_COMPONENT: break; case ST_STRUCTURESTAT: index = 0; if (ini.contains("data")) { index = getStructStatFromName(ini.value("data").toString().toAscii().constData()); if (index == -1) { debug( LOG_FATAL, "Could not find stat"); index = 0; } } psVal->v.ival = index; break; case ST_FEATURESTAT: index = 0; if (ini.contains("data")) { index = getFeatureStatFromName(ini.value("data").toString().toAscii().constData()); if (index == -1) { debug( LOG_FATAL, "Could not find stat"); index = 0; } } psVal->v.ival = index; break; case ST_BODY: index = getCompFromResName(COMP_BODY, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find body component"); index = 0; } psVal->v.ival = index; break; case ST_PROPULSION: index = getCompFromResName(COMP_PROPULSION, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find propulsion component"); index = 0; } psVal->v.ival = index; break; case ST_ECM: index = getCompFromResName(COMP_ECM, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find ECM component"); index = 0; } psVal->v.ival = index; break; case ST_SENSOR: index = getCompFromResName(COMP_SENSOR, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find sensor component"); index = 0; } psVal->v.ival = index; break; case ST_CONSTRUCT: index = getCompFromResName(COMP_CONSTRUCT, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find constructor component"); index = 0; } psVal->v.ival = index; break; case ST_WEAPON: index = getCompFromResName(COMP_WEAPON, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find weapon"); index = 0; } psVal->v.ival = index; break; case ST_REPAIR: index = getCompFromResName(COMP_REPAIRUNIT, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find repair component"); index = 0; } psVal->v.ival = index; break; case ST_BRAIN: index = getCompFromResName(COMP_BRAIN, ini.value("data").toString().toAscii().constData()); if (index == -1) { debug(LOG_FATAL, "Could not find repair brain"); index = 0; } psVal->v.ival = index; break; case ST_TEMPLATE: psVal->v.oval = NULL; if (ini.contains("data")) { // FIXME: Ugh. Find a better way to show full template info psVal->v.oval = (void*)IdToTemplate(ini.value("data").toInt(), ANYPLAYER); if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL) { debug(LOG_FATAL, "Could not find template %d", ini.value("data").toInt()); } } break; case ST_TEXTSTRING: psVal->v.sval = NULL; if (ini.contains("data")) { psVal->v.sval = strdup(ini.value("data").toString().toAscii().constData()); } break; case ST_LEVEL: psVal->v.sval = NULL; if (ini.contains("data")) { psLevel = levFindDataSet(ini.value("data").toString().toAscii().constData()); if (psLevel == NULL) { debug(LOG_FATAL, "Could not find level dataset"); } psVal->v.sval = psLevel->pName; } break; case ST_RESEARCH: psVal->v.oval = NULL; if (ini.contains("data")) { QString research = ini.value("data").toString(); if (!research.isEmpty()) { psVal->v.oval = (void*)getResearch(research.toUtf8().constData()); ASSERT_OR_RETURN(false, psVal->v.oval, "Could not find research %s", research.toUtf8().constData()); } } break; case ST_GROUP: if (psVal->v.oval == NULL) { DROID_GROUP *tmp = grpCreate(); tmp->add(NULL); psVal->v.oval = tmp; } psGroup = (DROID_GROUP *)(psVal->v.oval); members = ini.value("members", 0).toInt(); if (psGroup && members > 0) { QStringList droids = ini.value("data").toStringList(); // load the retreat data psGroup->sRunData.sPos = ini.vector2i("runpos"); psGroup->sRunData.forceLevel = ini.value("forceLevel").toInt(); psGroup->sRunData.leadership = ini.value("leadership").toInt(); psGroup->sRunData.healthLevel = ini.value("healthLevel").toInt(); // load the droids while (members > 0) { id = droids.takeLast().toInt(); psCDroid = (DROID *)getBaseObjFromId(id); if (!psCDroid) { debug(LOG_ERROR, "Could not find object id %d", id); } else { ((DROID_GROUP*)(psVal->v.oval))->add(psCDroid); } members--; } } break; case ST_SOUND: // find audio id // don't use sound if it's disabled if (audio_Disabled()) { psVal->v.ival = NO_SOUND; break; } index = audio_GetTrackID(ini.value("data").toString().toAscii().constData()); if (index == SAMPLE_NOT_FOUND) { // find empty id and set track vals QString soundname = ini.value("data").toString(); index = audio_SetTrackVals(soundname.toAscii().constData(), false, 100, 1800); if (!index) // this is a NON fatal error. { // We can't find filename of the sound for some reason. debug(LOG_ERROR, "Sound ID not available %s not found", soundname.toAscii().constData()); break; } } psVal->v.ival = index; break; case ST_STRUCTUREID: case ST_DROIDID: default: // just set the contents directly psVal->v.ival = ini.value("data").toInt(); break; } return true; }
/// default value load routine bool scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size) { char *pPos; DROID *psCDroid; SDWORD index, members, savedMembers; UDWORD id; LEVEL_DATASET *psLevel; DROID_GROUP *psGroup = NULL; const char *pName; bool bObjectDefined; switch ((unsigned)psVal->type) // Unsigned cast to suppress compiler warnings due to enum abuse. { case ST_INTMESSAGE: if ((size == 1) && (*pBuffer == 0)) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)getViewData(pBuffer); if (psVal->v.oval == NULL) { return false; } } break; case ST_BASEOBJECT: case ST_DROID: case ST_STRUCTURE: case ST_FEATURE: id = *((UDWORD *)pBuffer); endian_udword(&id); if (id == UDWORD_MAX) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)getBaseObjFromId(id); if (!psVal->v.oval) { debug(LOG_ERROR, "Could not find object id %d", id); } } break; case ST_BASESTATS: case ST_COMPONENT: break; case ST_STRUCTURESTAT: index = getStructStatFromName(pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find structure stat %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_FEATURESTAT: index = getFeatureStatFromName(pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find feature stat %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_BODY: index = getCompFromResName(COMP_BODY, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find body component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_PROPULSION: index = getCompFromResName(COMP_PROPULSION, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find propulsion component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_ECM: index = getCompFromResName(COMP_ECM, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find ECM component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_SENSOR: index = getCompFromResName(COMP_SENSOR, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find sensor component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_CONSTRUCT: index = getCompFromResName(COMP_CONSTRUCT, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find constructor component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_WEAPON: index = getCompFromResName(COMP_WEAPON, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find weapon %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_REPAIR: index = getCompFromResName(COMP_REPAIRUNIT, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find repair component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_BRAIN: index = getCompFromResName(COMP_BRAIN, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find repair brain %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_TEMPLATE: id = *((UDWORD *)pBuffer); endian_udword(&id); if (id == UDWORD_MAX) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)IdToTemplate(id, ANYPLAYER); if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL) { debug( LOG_FATAL, "scrValDefLoad: couldn't find template id %d", id ); abort(); } } break; case ST_TEXTSTRING: { const char* str; char* idStr; uint16_t len; if (size < sizeof(len)) { debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len)), (unsigned int)size); return false; } len = *((uint16_t*)pBuffer); endian_uword(&len); if (size < sizeof(len) + len) { debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len) + len), (unsigned int)size); return false; } if (len == 0) { psVal->v.sval = NULL; return true; } idStr = (char *)malloc(len); if (!idStr) { debug(LOG_ERROR, "Out of memory (tried to allocate %u bytes)", (unsigned int)len); // Don't abort() here, as this might be the result from a bad "len" field in the data return false; } memcpy(idStr, pBuffer + sizeof(len), len); if (idStr[len - 1] != '\0') { debug(LOG_WARNING, "Non-NUL terminated string encountered!"); } idStr[len - 1] = '\0'; str = strresGetString(psStringRes, idStr); if (!str) { debug(LOG_ERROR, "Couldn't find string with id \"%s\"", idStr); free(idStr); return false; } free(idStr); psVal->v.sval = strdup(str); if (!psVal->v.sval) { debug(LOG_FATAL, "Out of memory"); abort(); return false; } } break; case ST_LEVEL: if ((size == 1) && (*pBuffer == 0)) { psVal->v.sval = '\0'; } else { psLevel = levFindDataSet(pBuffer); if (psLevel == NULL) { debug( LOG_FATAL, "scrValDefLoad: couldn't find level dataset %s", pBuffer ); abort(); } psVal->v.sval = psLevel->pName; } break; case ST_RESEARCH: if ((size == 1) && (*pBuffer == 0)) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)getResearch(pBuffer); if (psVal->v.oval == NULL) { debug( LOG_FATAL, "scrValDefLoad: couldn't find research %s", pBuffer ); abort(); } } break; case ST_GROUP: bObjectDefined = true; if (psVal->v.oval == NULL) { DROID_GROUP *tmp = grpCreate(); tmp->add(NULL); psVal->v.oval = tmp; } pPos = pBuffer; if (version < 2) { members = size / sizeof(UDWORD); } else if (version < 3) { members = (size - sizeof(SDWORD)*4) / sizeof(UDWORD); } else { members = (size - sizeof(SDWORD)*6) / sizeof(UDWORD); // get saved group member count/nullpointer flag endian_sdword((SDWORD*)pPos); bObjectDefined = ( *((SDWORD *)pPos) != UNALLOCATED_OBJECT ); if(bObjectDefined) { savedMembers = *((SDWORD *)pPos); // get number of saved group members ASSERT(savedMembers == members, "scrValDefLoad: calculated and saved group member count did not match." ); } pPos += sizeof(SDWORD); } // make sure group was allocated when it was saved (relevant starting from version 3) if( version < 3 || bObjectDefined ) { if (version >= 2) { // load the retreat data psGroup = (DROID_GROUP*)(psVal->v.oval); endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.x = *((SDWORD *)pPos); pPos += sizeof(SDWORD); endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.y = *((SDWORD *)pPos); pPos += sizeof(SDWORD); endian_sdword((SDWORD*)pPos); psGroup->sRunData.forceLevel = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); endian_sdword((SDWORD*)pPos); psGroup->sRunData.leadership = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); } if (version >= 3) { endian_sdword((SDWORD*)pPos); psGroup->sRunData.healthLevel = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); } // load the droids while (members > 0) { endian_udword((UDWORD*)pPos); id = *((UDWORD *) pPos); psCDroid = (DROID *)getBaseObjFromId(id); if (!psCDroid) { debug(LOG_ERROR, "Could not find object id %d", id); } else { ((DROID_GROUP*)(psVal->v.oval))->add(psCDroid); } pPos += sizeof(UDWORD); members -= 1; } } else // a group var was unallocated during saving { pPos += sizeof(UWORD); } break; case ST_SOUND: // find audio id // don't use sound if it's disabled if (audio_Disabled()) { psVal->v.ival = NO_SOUND; break; } pName = pBuffer; index = audio_GetTrackID( pName ); if (index == SAMPLE_NOT_FOUND) { // find empty id and set track vals index = audio_SetTrackVals(pName, false, 100, 1800); if (!index) //this is a NON fatal error. { // We can't find filename of the sound for some reason. debug(LOG_ERROR, "Sound ID not available %s not found", pName); break; } } psVal->v.ival = index; break; case ST_STRUCTUREID: case ST_DROIDID: default: // just set the contents directly psVal->v.ival = *((SDWORD *)pBuffer); endian_sdword(&psVal->v.ival); break; } return true; }