/// 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; }