Use 'names' fields in ini files instead of looking up names in names.txt

master
per 2013-05-12 23:50:57 +02:00
parent 9c8f362c2c
commit 100f5e9560
50 changed files with 564 additions and 1002 deletions

View File

@ -1030,7 +1030,7 @@ type = DROID
weapons = RailGun2Mk1
[BabaPickUp]
compBody = B2RKJeepBody
compBody = BabaJeepBody
compConstruct = Spade1Mk1
type = DROID

View File

@ -103,7 +103,10 @@ public:
{
return m_settings.status();
}
QString group()
{
return m_settings.group();
}
};
#endif

View File

@ -26,6 +26,7 @@
#include "lib/framework/wzglobal.h"
#include "lib/framework/string_ext.h"
#include <string.h>
#include <QtCore/QStringList>
#ifndef WZ_OS_WIN
#include <arpa/inet.h>
@ -620,7 +621,6 @@ void NETbool(bool *bp)
*bp = !!i;
}
/** Sends or receives a string to or from the current network package.
* \param str When encoding a packet this is the (NUL-terminated string to
* be sent in the current network package. When decoding this
@ -664,6 +664,31 @@ void NETstring(char *str, uint16_t maxlen)
}
}
void NETqstring(QString &str)
{
uint16_t len = str.size();
queueAuto(len);
if (NETgetPacketDir() == PACKET_DECODE)
{
str.resize(len);
}
for (unsigned i = 0; i < len; ++i)
{
uint16_t c;
if (NETgetPacketDir() == PACKET_ENCODE)
{
c = str[i].unicode();
}
queueAuto(c);
if (NETgetPacketDir() == PACKET_DECODE)
{
str[i] = QChar(c);
}
}
}
void NETstring(char const *str, uint16_t maxlen)
{
ASSERT(NETgetPacketDir() == PACKET_ENCODE, "Writing to const!");

View File

@ -28,6 +28,8 @@
#include "lib/framework/vector.h"
#include "lib/netplay/netqueue.h"
class QString;
enum PACKETDIR
{
PACKET_ENCODE,
@ -86,6 +88,7 @@ void NETint64_t(int64_t *ip);
void NETuint64_t(uint64_t *ip);
void NETbool(bool *bp);
void NETbool(bool *bp);
void NETqstring(QString &str);
void NETstring(char *str, uint16_t maxlen);
void NETstring(char const *str, uint16_t maxlen); ///< Encode-only version of NETstring.
void NETbin(uint8_t *str, uint32_t len);

View File

@ -42,7 +42,6 @@ W_BARINIT::W_BARINIT()
, precision(0)
//sCol
//sMinorCol
, pTip(NULL)
{
sCol.rgba = 0;
sMinorCol.rgba = 0;
@ -61,7 +60,7 @@ W_BARGRAPH::W_BARGRAPH(W_BARINIT const *init)
, majorCol(init->sCol)
, minorCol(init->sMinorCol)
, textCol(WZCOL_BLACK)
, pTip(QString::fromUtf8(init->pTip))
, pTip(init->pTip)
, backgroundColour(WZCOL_FORM_BACKGROUND)
{
/* Set the minor colour if necessary */

View File

@ -37,7 +37,6 @@
W_BUTINIT::W_BUTINIT()
: pText(NULL)
, pTip(NULL)
, FontID(font_regular)
{}
@ -45,7 +44,7 @@ W_BUTTON::W_BUTTON(W_BUTINIT const *init)
: WIDGET(init, WIDG_BUTTON)
, state(WBUT_PLAIN)
, pText(QString::fromUtf8(init->pText))
, pTip(QString::fromUtf8(init->pTip))
, pTip(init->pTip)
, HilightAudioID(WidgGetHilightAudioID())
, ClickedAudioID(WidgGetClickedAudioID())
, AudioCallback(WidgGetAudioCallback())

View File

@ -38,7 +38,6 @@
W_FORMINIT::W_FORMINIT()
: disableChildren(false)
, pTip(NULL)
{}
W_FORM::W_FORM(W_FORMINIT const *init)
@ -58,7 +57,7 @@ W_FORM::W_FORM(WIDGET *parent)
W_CLICKFORM::W_CLICKFORM(W_FORMINIT const *init)
: W_FORM(init)
, state(WBUT_PLAIN)
, pTip(QString::fromUtf8(init->pTip))
, pTip(init->pTip)
, HilightAudioID(WidgGetHilightAudioID())
, ClickedAudioID(WidgGetClickedAudioID())
, AudioCallback(WidgGetAudioCallback())

View File

@ -35,7 +35,6 @@
W_LABINIT::W_LABINIT()
: pText(NULL)
, pTip(NULL)
, FontID(font_regular)
{}
@ -43,7 +42,7 @@ W_LABEL::W_LABEL(W_LABINIT const *init)
: WIDGET(init, WIDG_LABEL)
, aText(QString::fromUtf8(init->pText))
, FontID(init->FontID)
, pTip(QString::fromUtf8(init->pTip))
, pTip(init->pTip)
, fontColour(WZCOL_FORM_TEXT)
{
ASSERT((init->style & ~(WLAB_PLAIN | WLAB_ALIGNLEFT | WLAB_ALIGNRIGHT | WLAB_ALIGNCENTRE | WLAB_ALIGNTOP | WLAB_ALIGNBOTTOM | WIDG_HIDDEN)) == 0, "Unknown button style");

View File

@ -42,7 +42,6 @@ W_SLDINIT::W_SLDINIT()
, numStops(0)
, barSize(0)
, pos(0)
, pTip(NULL)
{}
W_SLIDER::W_SLIDER(W_SLDINIT const *init)
@ -52,7 +51,7 @@ W_SLIDER::W_SLIDER(W_SLDINIT const *init)
, barSize(init->barSize)
, pos(init->pos)
, state(0)
, pTip(QString::fromUtf8(init->pTip))
, pTip(init->pTip)
{
ASSERT((init->style & ~(WBAR_PLAIN | WIDG_HIDDEN)) == 0, "Unknown style");
ASSERT(init->orientation >= WSLD_LEFT || init->orientation <= WSLD_BOTTOM, "Unknown orientation");

View File

@ -480,7 +480,7 @@ void WIDGET::setTip(QString)
}
/* Set tip string for a widget */
void widgSetTip(W_SCREEN *psScreen, UDWORD id, const char *pTip)
void widgSetTip(W_SCREEN *psScreen, UDWORD id, QString pTip)
{
WIDGET *psWidget = widgGetFromID(psScreen, id);

View File

@ -125,7 +125,7 @@ struct W_FORMINIT : public W_INIT
W_FORMINIT();
bool disableChildren;
const char *pTip; ///< Tool tip for the form itself
QString pTip; ///< Tool tip for the form itself
};
/** Label initialisation structure */
@ -134,7 +134,7 @@ struct W_LABINIT : public W_INIT
W_LABINIT();
const char *pText; ///< label text
const char *pTip; ///< Tool tip for the label.
QString pTip; ///< Tool tip for the label.
enum iV_fonts FontID; ///< ID of the IVIS font to use for this widget.
};
@ -144,7 +144,7 @@ struct W_BUTINIT : public W_INIT
W_BUTINIT();
const char *pText; ///< Button text
const char *pTip; ///< Tool tip text
QString pTip; ///< Tool tip text
enum iV_fonts FontID; //< ID of the IVIS font to use for this widget.
};
@ -180,7 +180,7 @@ struct W_BARINIT : public W_INIT
int precision; ///< Number of places after the decimal point to display, 0 by default.
PIELIGHT sCol; ///< Bar colour
PIELIGHT sMinorCol; ///< Minor bar colour
const char *pTip; ///< Tool tip text
QString pTip; ///< Tool tip text
};
@ -202,7 +202,7 @@ struct W_SLDINIT : public W_INIT
UWORD numStops; ///< Number of stops on the slider
UWORD barSize; ///< Size of the bar
UWORD pos; ///< Initial position of the slider bar
const char *pTip; ///< Tip string
QString pTip; ///< Tip string
};
/***********************************************************************************/
@ -289,7 +289,7 @@ extern void widgSetUserData2(W_SCREEN *psScreen, UDWORD id, UDWORD UserData);
extern WIDGET *widgGetFromID(W_SCREEN *psScreen, UDWORD id);
/** Set tip string for a widget */
extern void widgSetTip(W_SCREEN *psScreen, UDWORD id, const char *pTip);
extern void widgSetTip(W_SCREEN *psScreen, UDWORD id, QString pTip);
/** Colour numbers */
enum _w_colour

View File

@ -475,7 +475,7 @@ static SDWORD targetAttackWeight(BASE_OBJECT *psTarget, BASE_OBJECT *psAttacker,
/* indirect firing units have slow reload times, so give the target a chance to die,
* and give a different unit a chance to get in range, too. */
if (weaponROF(attackerWeapon, psAttacker->player) < TARGET_DOOMED_SLOW_RELOAD_T) {
debug(LOG_NEVER,"Not killing unit - doomed. My ROF: %i (%s)", weaponROF(attackerWeapon, psAttacker->player), attackerWeapon->pName);
debug(LOG_NEVER,"Not killing unit - doomed. My ROF: %i (%s)", weaponROF(attackerWeapon, psAttacker->player), getName(attackerWeapon));
return noTarget;
}
attackWeight /= TARGET_DOOMED_PENALTY_F;

View File

@ -75,9 +75,12 @@ Spacetime interpolateObjectSpacetime(const SIMPLE_OBJECT *obj, uint32_t t)
SIMPLE_OBJECT::SIMPLE_OBJECT(OBJECT_TYPE type, uint32_t id, unsigned player)
: type(type)
, id(id)
, pos(0, 0, 0)
, rot(0, 0, 0)
, player(player)
, born(gameTime)
, died(0)
, time(0)
{}
SIMPLE_OBJECT::~SIMPLE_OBJECT()
@ -96,9 +99,13 @@ BASE_OBJECT::BASE_OBJECT(OBJECT_TYPE type, uint32_t id, unsigned player)
, lastEmission(0)
, lastHitWeapon(WSC_NUM_WEAPON_SUBCLASSES) // No such weapon.
, timeLastHit(UDWORD_MAX)
, body(0)
, periodicalDamageStart(0)
, periodicalDamage(0)
, bTargetted(false)
, watchedTiles(NULL)
{
memset(visible, 0, sizeof(visible));
sDisplay.imd = NULL;
sDisplay.frameNumber = 0;
sDisplay.screenX = 0;

View File

@ -105,7 +105,7 @@ bool combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
if (psTarget->visible[psAttacker->player] != UBYTE_MAX)
{
// Can't see it - can't hit it
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Object has no indirect sight of target", psAttacker->id, psStats->pName, psTarget->id);
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Object has no indirect sight of target", psAttacker->id, getName(psStats), psTarget->id);
return false;
}
@ -172,7 +172,7 @@ bool combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
else
{
/* Out of range */
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Out of range", psAttacker->id, psStats->pName, psTarget->id);
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Out of range", psAttacker->id, getName(psStats), psTarget->id);
return false;
}
@ -267,7 +267,7 @@ bool combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
if (isHit)
{
/* Kerrrbaaang !!!!! a hit */
objTrace(psAttacker->id, "combFire: [%s]->%u: resultHitChance=%d, visibility=%d", psStats->pName, psTarget->id, resultHitChance, (int)psTarget->visible[psAttacker->player]);
objTrace(psAttacker->id, "combFire: [%s]->%u: resultHitChance=%d, visibility=%d", getName(psStats), psTarget->id, resultHitChance, (int)psTarget->visible[psAttacker->player]);
syncDebug("hit=(%d,%d,%d)", predict.x, predict.y, predict.z);
}
else /* Deal with a missed shot */

View File

@ -401,10 +401,9 @@ static bool _intAddDesign(bool bShowCentreScreen)
/* Initialise the current design */
sDefaultDesignTemplate.droidType = DROID_ANY;
sCurrDesign = sDefaultDesignTemplate;
sCurrDesign.pName = NULL;
sCurrDesign.stored = false;
sstrcpy(aCurrName, _("New Vehicle"));
sstrcpy(sCurrDesign.aName, aCurrName);
sCurrDesign.name = aCurrName;
/* Add the design templates form */
if (!intAddTemplateForm(NULL)) // Was psCurrTemplate instead of NULL, but psCurrTemplate was always NULL. Deleted psCurrTemplate, but leaving this here, in case intAddTemplateForm(NULL) does something useful.
@ -1065,8 +1064,7 @@ const char *GetDefaultTemplateName(DROID_TEMPLATE *psTemplate)
psTemplate->asParts[COMP_REPAIRUNIT] != 0 ||
psTemplate->asParts[COMP_BRAIN] != 0)
{
const char *pStr = getStatName(psStats);
sstrcpy(aCurrName, pStr);
sstrcpy(aCurrName, getName(psStats));
sstrcat(aCurrName, " ");
}
@ -1080,15 +1078,13 @@ const char *GetDefaultTemplateName(DROID_TEMPLATE *psTemplate)
psStats = (COMPONENT_STATS *)(asBodyStats + compIndex);
if (psTemplate->asParts[COMP_BODY] != 0)
{
const char *pStr = getStatName(psStats);
if (strlen(aCurrName) + strlen(pStr) > MAX_STR_LENGTH)
if (strlen(aCurrName) + psStats->name.size() > MAX_STR_LENGTH)
{
debug(LOG_ERROR, "Name string too long %s+%s > %u", aCurrName, pStr, MAX_STR_LENGTH);
debug(LOG_ERROR, "Name string too long %s+%s > %u", aCurrName, getName(psStats), MAX_STR_LENGTH);
debug(LOG_ERROR, "Please report what language you are using in the bug report!");
}
sstrcat(aCurrName, pStr);
sstrcat(aCurrName, getName(psStats));
sstrcat(aCurrName, " ");
}
@ -1097,15 +1093,13 @@ const char *GetDefaultTemplateName(DROID_TEMPLATE *psTemplate)
psStats = (COMPONENT_STATS *)(asPropulsionStats + compIndex);
if (psTemplate->asParts[COMP_PROPULSION] != 0)
{
const char *pStr = getStatName(psStats);
if (strlen(aCurrName) + strlen(pStr) > MAX_STR_LENGTH)
if (strlen(aCurrName) + psStats->name.size() > MAX_STR_LENGTH)
{
debug(LOG_ERROR, "Name string too long %s+%s", aCurrName, pStr);
debug(LOG_ERROR, "Name string too long %s+%s", aCurrName, getName(psStats));
debug(LOG_ERROR, "Please report what language you are using in the bug report!");
}
sstrcat(aCurrName, pStr);
sstrcat(aCurrName, getName(psStats));
}
return aCurrName;
@ -1118,7 +1112,7 @@ static void intSetEditBoxTextFromTemplate(DROID_TEMPLATE *psTemplate)
/* show component names if default template else show stat name */
if (psTemplate->droidType != DROID_DEFAULT)
{
sstrcpy(aCurrName, getTemplateName(psTemplate));
sstrcpy(aCurrName, getName(psTemplate));
}
else
{
@ -2915,7 +2909,7 @@ bool intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName, bool complai
psTempl->enabled = true;
/* copy name into template */
sstrcpy(psTempl->aName, newName);
psTempl->name = newName;
return true;
}
@ -2924,7 +2918,6 @@ static void desCreateDefaultTemplate(void)
{
/* set current design to default */
sCurrDesign = sDefaultDesignTemplate;
sCurrDesign.pName = NULL;
sCurrDesign.stored = false;
/* reset stats */
@ -2974,7 +2967,7 @@ static void intSetButtonFlash(UDWORD id, bool bFlash)
static bool desTemplateNameCustomised(DROID_TEMPLATE *psTemplate)
{
if ((psTemplate->droidType == DROID_DEFAULT) ||
(strcmp(getTemplateName(psTemplate),
(strcmp(getName(psTemplate),
GetDefaultTemplateName(psTemplate)) == 0))
{
return false;
@ -3011,8 +3004,7 @@ void intProcessDesign(UDWORD id)
desCreateDefaultTemplate();
aCurrName[0] = '\0';
sCurrDesign.aName[0] = '\0';
sstrcpy(sCurrDesign.aName, aCurrName);
sCurrDesign.name = aCurrName;
/* reveal body button */
widgReveal(psWScreen, IDDES_BODYBUTTON);
@ -3042,7 +3034,7 @@ void intProcessDesign(UDWORD id)
{
/* Set the new template */
sCurrDesign = *psTempl;
sstrcpy(aCurrName, getTemplateName(psTempl));
sstrcpy(aCurrName, getName(psTempl));
/* reveal body/propulsion/turret component buttons */
widgReveal(psWScreen, IDDES_BODYBUTTON);
@ -3343,7 +3335,7 @@ void intProcessDesign(UDWORD id)
/* update name if not customised */
if (bTemplateNameCustomised == false)
{
sstrcpy(sCurrDesign.aName, GetDefaultTemplateName(&sCurrDesign));
sCurrDesign.name = GetDefaultTemplateName(&sCurrDesign);
}
/* Update the name in the edit box */
@ -3473,7 +3465,7 @@ void intProcessDesign(UDWORD id)
/* update name if not customised */
if (bTemplateNameCustomised == false)
{
sstrcpy(sCurrDesign.aName, GetDefaultTemplateName(&sCurrDesign));
sCurrDesign.name = GetDefaultTemplateName(&sCurrDesign);
}
/* Update the name in the edit box */
@ -3519,8 +3511,8 @@ void intProcessDesign(UDWORD id)
break;
/* The name edit box */
case IDDES_NAMEBOX:
sstrcpy(sCurrDesign.aName, widgGetString(psWScreen, IDDES_NAMEBOX));
sstrcpy(aCurrName, sCurrDesign.aName);
sCurrDesign.name = widgGetString(psWScreen, IDDES_NAMEBOX);
sstrcpy(aCurrName, getName(&sCurrDesign));
break;
case IDDES_BIN:
{
@ -3540,7 +3532,6 @@ void intProcessDesign(UDWORD id)
//before deleting the template, need to make sure not being used in production
deleteTemplateFromProduction(psTempl, selectedPlayer, ModeQueue);
// Delete the template.
free(i->pName);
localTemplates.erase(i);
break;
}
@ -3558,7 +3549,7 @@ void intProcessDesign(UDWORD id)
/* Set the new template */
sCurrDesign = *psTempl;
sstrcpy(aCurrName, getTemplateName(psTempl));
sstrcpy(aCurrName, getName(psTempl));
intSetEditBoxTextFromTemplate(psTempl);
@ -4001,7 +3992,6 @@ static bool saveTemplate(void)
/* Copy the template */
*psTempl = sCurrDesign;
sstrcpy(psTempl->aName, aCurrName);
/* Now update the droid template form */
widgDelete(psWScreen, IDDES_TEMPLBASE);

View File

@ -1806,7 +1806,7 @@ static void dealWithLMBStructure(STRUCTURE* psStructure, SELECTION_TYPE selectio
#ifdef DEBUG
if (getDebugMappingStatus())
{
CONPRINTF(ConsoleString, (ConsoleString, "(Enemy!) %s, ref: %d, ID: %d Damage %d%%", psStructure->pStructureType->pName, psStructure->pStructureType->ref,
CONPRINTF(ConsoleString, (ConsoleString, "(Enemy!) %s, ref: %d, ID: %d Damage %d%%", getID(psStructure->pStructureType), psStructure->pStructureType->ref,
psStructure->id, 100 - clip(PERCENT(psStructure->body, psStructure->pStructureType->upgrade[psStructure->player].hitpoints), 0, 100)));
}
#endif
@ -1976,7 +1976,7 @@ static void dealWithLMBFeature(FEATURE* psFeature)
#ifdef DEBUG
if (getDebugMappingStatus())
{
CONPRINTF(ConsoleString, (ConsoleString, "(Feature) %s, ID: %d, ref: %d, body: (%d):%d", psFeature->psStats->pName, psFeature->id, psFeature->psStats->ref, psFeature->psStats->body, psFeature->body ));
CONPRINTF(ConsoleString, (ConsoleString, "(Feature) %s, ID: %d, ref: %d, body: (%d):%d", getID(psFeature->psStats), psFeature->id, psFeature->psStats->ref, psFeature->psStats->body, psFeature->body ));
}
#endif
driveDisableTactical();

View File

@ -333,6 +333,8 @@ DROID::DROID(uint32_t id, unsigned player)
, actionPos(0, 0)
, psCurAnim(NULL)
{
memset(aName, 0, sizeof(aName));
memset(asBits, 0, sizeof(asBits));
pos = Vector3i(0, 0, 0);
rot = Vector3i(0, 0, 0);
order.type = DORDER_NONE;
@ -1668,7 +1670,7 @@ UDWORD calcTemplateBuild(DROID_TEMPLATE *psTemplate)
// FIX ME:
ASSERT( psTemplate->asWeaps[i]<numWeaponStats,
//"Invalid Template weapon for %s", psTemplate->pName );
"Invalid Template weapon for %s", getTemplateName(psTemplate) );
"Invalid Template weapon for %s", getName(psTemplate) );
build += (asWeaponStats + psTemplate->asWeaps[i])->buildPoints;
}
@ -1766,7 +1768,7 @@ DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, Position pos, UDWORD player,
ASSERT(!bMultiPlayer || worldOnMap(pos.x, pos.y), "the build locations are not on the map");
psDroid = new DROID(generateSynchronisedObjectId(), player);
droidSetName(psDroid, pTemplate->aName);
droidSetName(psDroid, getName(pTemplate));
// Set the droids type
psDroid->droidType = droidTemplateType(pTemplate); // Is set again later to the same thing, in droidSetBits.
@ -3232,7 +3234,7 @@ DROID *giftSingleDroid(DROID *psD, UDWORD to)
return NULL;
}
templateSetParts(psD, &sTemplate); // create a template based on the droid
sstrcpy(sTemplate.aName, psD->aName); // copy the name across
sTemplate.name = psD->aName; // copy the name across
// only play the nexus sound if unit being taken over is selectedPlayer's but not going to the selectedPlayer
if (psD->player == selectedPlayer && to != selectedPlayer && !bMultiPlayer)
{

View File

@ -60,9 +60,6 @@ struct DROID_TEMPLATE : public BASE_STATS
{
DROID_TEMPLATE();
/// this contains the full editable UTF-8 encoded name of the template
char aName[MAX_STR_LENGTH];
/*!
* The droid components.
*

View File

@ -80,8 +80,10 @@ bool loadFeatureStats(const char *pFileName)
for (int i = 0; i < list.size(); ++i)
{
ini.beginGroup(list[i]);
asFeatureStats[i] = FEATURE_STATS(REF_FEATURE_START + i, list[i].toUtf8().constData());
asFeatureStats[i] = FEATURE_STATS(REF_FEATURE_START + i);
FEATURE_STATS *p = &asFeatureStats[i];
p->name = ini.value("name").toString();
p->id = list[i];
QString subType = ini.value("type").toString();
if (subType == "TANK WRECK") p->subType = FEAT_TANK;
else if (subType == "GENERIC ARTEFACT") p->subType = FEAT_GEN_ARTE;
@ -117,10 +119,6 @@ bool loadFeatureStats(const char *pFileName)
/* Release the feature stats memory */
void featureStatsShutDown(void)
{
for (unsigned i = 0; i < numFeatureStats; ++i)
{
free(asFeatureStats[i].pName);
}
delete[] asFeatureStats;
asFeatureStats = NULL;
numFeatureStats = 0;
@ -239,8 +237,8 @@ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,bool FromSave)
MAPTILE *psTile = mapTile(b.map.x + width, b.map.y + breadth);
//check not outside of map - for load save game
ASSERT_OR_RETURN(NULL, b.map.x + width < mapWidth, "x coord bigger than map width - %s, id = %d", getName(psFeature->psStats->pName), psFeature->id);
ASSERT_OR_RETURN(NULL, b.map.y + breadth < mapHeight, "y coord bigger than map height - %s, id = %d", getName(psFeature->psStats->pName), psFeature->id);
ASSERT_OR_RETURN(NULL, b.map.x + width < mapWidth, "x coord bigger than map width - %s, id = %d", getName(psFeature->psStats), psFeature->id);
ASSERT_OR_RETURN(NULL, b.map.y + breadth < mapHeight, "y coord bigger than map height - %s, id = %d", getName(psFeature->psStats), psFeature->id);
if (width != psStats->baseWidth && breadth != psStats->baseBreadth)
{
@ -249,8 +247,8 @@ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,bool FromSave)
FEATURE *psBlock = (FEATURE *)psTile->psObject;
debug(LOG_ERROR, "%s(%d) already placed at (%d+%d, %d+%d) when trying to place %s(%d) at (%d+%d, %d+%d) - removing it",
getName(psBlock->psStats->pName), psBlock->id, map_coord(psBlock->pos.x), psBlock->psStats->baseWidth, map_coord(psBlock->pos.y),
psBlock->psStats->baseBreadth, getName(psFeature->psStats->pName), psFeature->id, b.map.x, b.size.x, b.map.y, b.size.y);
getName(psBlock->psStats), psBlock->id, map_coord(psBlock->pos.x), psBlock->psStats->baseWidth, map_coord(psBlock->pos.y),
psBlock->psStats->baseBreadth, getName(psFeature->psStats), psFeature->id, b.map.x, b.size.x, b.map.y, b.size.y);
removeFeature(psBlock);
}
@ -490,15 +488,14 @@ bool destroyFeature(FEATURE *psDel, unsigned impactTime)
}
SDWORD getFeatureStatFromName( const char *pName )
SDWORD getFeatureStatFromName(const char *pName)
{
unsigned int inc;
FEATURE_STATS *psStat;
for (inc = 0; inc < numFeatureStats; inc++)
for (int inc = 0; inc < numFeatureStats; inc++)
{
psStat = &asFeatureStats[inc];
if (!strcmp(psStat->pName, pName))
if (psStat->id.compare(pName) == 0)
{
return inc;
}

View File

@ -45,8 +45,7 @@ enum FEATURE_TYPE
/* Stats for a feature */
struct FEATURE_STATS : public BASE_STATS
{
FEATURE_STATS() {}
FEATURE_STATS(int idx, const char *s) : BASE_STATS(idx, s) {}
FEATURE_STATS(int idx = 0) : BASE_STATS(idx) {}
FEATURE_TYPE subType; ///< type of feature

View File

@ -1826,7 +1826,6 @@ void addSmallTextButton(UDWORD id, UDWORD PosX, UDWORD PosY, const char *txt, u
{
W_BUTINIT sButInit;
memset(&sButInit, 0, sizeof(W_BUTINIT));
sButInit.formID = FRONTEND_BOTFORM;
sButInit.id = id;
sButInit.x = (short)PosX;

View File

@ -1608,7 +1608,7 @@ static void setIniStructureStats(WzConfig &ini, QString const &key, STRUCTURE_ST
{
if (stats != NULL)
{
ini.setValue(key, stats->pName);
ini.setValue(key, stats->id);
}
}
@ -1964,10 +1964,6 @@ bool loadGame(const char *pGameToLoad, bool keepObjects, bool freeMem, bool User
}
}
}
for (std::list<DROID_TEMPLATE>::iterator i = localTemplates.begin(); i != localTemplates.end(); ++i)
{
free(i->pName);
}
localTemplates.clear();
//load in the templates
@ -4248,21 +4244,20 @@ static bool loadSaveDroid(const char *pFileName, DROID **ppsCurrentDroidLists)
else
{
// Create fake template
psTemplate->pName = NULL;
sstrcpy(templ.aName, ini.value("name", "UNKNOWN").toString().toUtf8().constData());
templ.name = ini.value("name", "UNKNOWN").toString();
psTemplate->droidType = (DROID_TYPE)ini.value("droidType").toInt();
psTemplate->numWeaps = ini.value("weapons", 0).toInt();
ini.beginGroup("parts"); // the following is copy-pasted from loadSaveTemplate() -- fixme somehow
psTemplate->asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", QString("ZNULLBODY")).toString().toUtf8().constData());
psTemplate->asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", QString("ZNULLBRAIN")).toString().toUtf8().constData());
psTemplate->asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", QString("ZNULLPROP")).toString().toUtf8().constData());
psTemplate->asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", QString("ZNULLREPAIR")).toString().toUtf8().constData());
psTemplate->asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", QString("ZNULLECM")).toString().toUtf8().constData());
psTemplate->asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", QString("ZNULLSENSOR")).toString().toUtf8().constData());
psTemplate->asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", QString("ZNULLCONSTRUCT")).toString().toUtf8().constData());
psTemplate->asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", QString("ZNULLWEAPON")).toString().toUtf8().constData());
psTemplate->asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", QString("ZNULLWEAPON")).toString().toUtf8().constData());
psTemplate->asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", QString("ZNULLWEAPON")).toString().toUtf8().constData());
psTemplate->asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", "ZNULLBODY").toString());
psTemplate->asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", "ZNULLBRAIN").toString());
psTemplate->asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", "ZNULLPROP").toString());
psTemplate->asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", "ZNULLREPAIR").toString());
psTemplate->asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", "ZNULLECM").toString());
psTemplate->asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", "ZNULLSENSOR").toString());
psTemplate->asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", "ZNULLCONSTRUCT").toString());
psTemplate->asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", "ZNULLWEAPON").toString());
psTemplate->asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", "ZNULLWEAPON").toString());
psTemplate->asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", "ZNULLWEAPON").toString());
ini.endGroup();
}
@ -4483,16 +4478,16 @@ static bool writeDroid(WzConfig &ini, DROID *psCurr, bool onMission, int &counte
if (psCurr->periodicalDamage > 0) ini.setValue("periodicalDamage", psCurr->periodicalDamage);
ini.setValue("droidType", psCurr->droidType);
ini.setValue("weapons", psCurr->numWeaps);
ini.setValue("parts/body", (asBodyStats + psCurr->asBits[COMP_BODY])->pName);
ini.setValue("parts/propulsion", (asPropulsionStats + psCurr->asBits[COMP_PROPULSION])->pName);
ini.setValue("parts/brain", (asBrainStats + psCurr->asBits[COMP_BRAIN])->pName);
ini.setValue("parts/repair", (asRepairStats + psCurr->asBits[COMP_REPAIRUNIT])->pName);
ini.setValue("parts/ecm", (asECMStats + psCurr->asBits[COMP_ECM])->pName);
ini.setValue("parts/sensor", (asSensorStats + psCurr->asBits[COMP_SENSOR])->pName);
ini.setValue("parts/construct", (asConstructStats + psCurr->asBits[COMP_CONSTRUCT])->pName);
ini.setValue("parts/body", (asBodyStats + psCurr->asBits[COMP_BODY])->id);
ini.setValue("parts/propulsion", (asPropulsionStats + psCurr->asBits[COMP_PROPULSION])->id);
ini.setValue("parts/brain", (asBrainStats + psCurr->asBits[COMP_BRAIN])->id);
ini.setValue("parts/repair", (asRepairStats + psCurr->asBits[COMP_REPAIRUNIT])->id);
ini.setValue("parts/ecm", (asECMStats + psCurr->asBits[COMP_ECM])->id);
ini.setValue("parts/sensor", (asSensorStats + psCurr->asBits[COMP_SENSOR])->id);
ini.setValue("parts/construct", (asConstructStats + psCurr->asBits[COMP_CONSTRUCT])->id);
for (int j = 0; j < psCurr->numWeaps; j++)
{
ini.setValue("parts/weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j].nStat)->pName);
ini.setValue("parts/weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j].nStat)->id);
}
ini.setValue("moveStatus", psCurr->sMove.Status);
ini.setValue("pathIndex", psCurr->sMove.pathIndex);
@ -4642,7 +4637,7 @@ bool loadSaveStructure(char *pFileData, UDWORD filesize)
psStats = asStructureStats + statInc;
//loop until find the same name
if (!strcmp(psStats->pName, psSaveStructure->name))
if (psStats->id.compare(psSaveStructure->name) == 0)
{
found = true;
break;
@ -4721,7 +4716,7 @@ static UDWORD getResearchIdFromName(const char *pName)
{
for (int inc = 0; inc < asResearch.size(); inc++)
{
if (!strcmp(asResearch[inc].pName, pName))
if (asResearch[inc].id.compare(pName) == 0)
{
return inc;
}
@ -4767,7 +4762,7 @@ static bool loadSaveStructure2(const char *pFileName, STRUCTURE **ppList)
{
psStats = asStructureStats + statInc;
//loop until find the same name
if (name.compare(psStats->pName) == 0)
if (name.compare(psStats->id) == 0)
{
found = true;
break;
@ -5046,7 +5041,7 @@ bool writeStructFile(const char *pFileName)
ini.beginGroup("structure_" + QString("%1").arg(counter++, 10, 10, QLatin1Char('0'))); // Zero padded so that alphabetical sort works.
ini.setValue("id", psCurr->id);
setPlayer(ini, psCurr->player);
ini.setValue("name", psCurr->pStructureType->pName);
ini.setValue("name", psCurr->pStructureType->id);
ini.setVector3i("position", psCurr->pos);
ini.setVector3i("rotation", psCurr->rot);
ini.setValue("health", psCurr->body);
@ -5065,7 +5060,7 @@ bool writeStructFile(const char *pFileName)
ini.setValue("weapons", psCurr->numWeaps);
for (int j = 0; j < psCurr->numWeaps; j++)
{
ini.setValue("parts/weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j].nStat)->pName);
ini.setValue("parts/weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j].nStat)->id);
if (psCurr->asWeaps[j].nStat > 0)
{
ini.setValue("ammo/" + QString::number(j), psCurr->asWeaps[j].ammo);
@ -5136,7 +5131,7 @@ bool writeStructFile(const char *pFileName)
ini.setValue("Research/timeStartHold", ((RESEARCH_FACILITY *)psCurr->pFunctionality)->timeStartHold);
if (((RESEARCH_FACILITY *)psCurr->pFunctionality)->psSubject)
{
ini.setValue("Research/target", ((RESEARCH_FACILITY *)psCurr->pFunctionality)->psSubject->pName);
ini.setValue("Research/target", ((RESEARCH_FACILITY *)psCurr->pFunctionality)->psSubject->id);
}
}
else if (psCurr->pStructureType->type == REF_POWER_GEN)
@ -5333,7 +5328,7 @@ bool loadSaveFeature(char *pFileData, UDWORD filesize)
{
psStats = asFeatureStats + statInc;
//loop until find the same name
if (!strcmp(psStats->pName, psSaveFeature->name))
if (psStats->id.compare(psSaveFeature->name) == 0)
{
found = true;
break;
@ -5399,7 +5394,7 @@ bool loadSaveFeature2(const char *pFileName)
{
psStats = asFeatureStats + statInc;
//loop until find the same name
if (!strcmp(psStats->pName, name.toUtf8().constData()))
if (psStats->id.compare(name) == 0)
{
found = true;
break;
@ -5454,7 +5449,7 @@ bool writeFeatureFile(const char *pFileName)
{
ini.beginGroup("feature_" + QString("%1").arg(counter++, 10, 10, QLatin1Char('0'))); // Zero padded so that alphabetical sort works.
ini.setValue("id", psCurr->id);
ini.setValue("name", psCurr->psStats->pName);
ini.setValue("name", psCurr->psStats->id);
ini.setVector3i("position", psCurr->pos);
ini.setVector3i("rotation", psCurr->rot);
ini.setValue("periodicalDamage", psCurr->periodicalDamage);
@ -5483,21 +5478,20 @@ bool loadSaveTemplate(const char *pFileName)
ini.beginGroup(list[i]);
int player = getPlayer(ini);
DROID_TEMPLATE *psTemplate = new DROID_TEMPLATE;
psTemplate->pName = NULL;
sstrcpy(psTemplate->aName, ini.value("name").toString().toUtf8().constData());
psTemplate->name = ini.value("name").toString();
psTemplate->ref = ini.value("ref").toInt();
psTemplate->droidType = (DROID_TYPE)ini.value("droidType").toInt();
psTemplate->multiPlayerID = ini.value("multiPlayerID").toInt();
psTemplate->asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", QString("ZNULLBODY")).toString().toUtf8().constData());
psTemplate->asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", QString("ZNULLBRAIN")).toString().toUtf8().constData());
psTemplate->asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", QString("ZNULLPROP")).toString().toUtf8().constData());
psTemplate->asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", QString("ZNULLREPAIR")).toString().toUtf8().constData());
psTemplate->asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", QString("ZNULLECM")).toString().toUtf8().constData());
psTemplate->asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", QString("ZNULLSENSOR")).toString().toUtf8().constData());
psTemplate->asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", QString("ZNULLCONSTRUCT")).toString().toUtf8().constData());
psTemplate->asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", QString("ZNULLWEAPON")).toString().toUtf8().constData());
psTemplate->asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", QString("ZNULLWEAPON")).toString().toUtf8().constData());
psTemplate->asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", QString("ZNULLWEAPON")).toString().toUtf8().constData());
psTemplate->asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", "ZNULLBODY").toString());
psTemplate->asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", "ZNULLBRAIN").toString());
psTemplate->asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", "ZNULLPROP").toString());
psTemplate->asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", "ZNULLREPAIR").toString());
psTemplate->asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", "ZNULLECM").toString());
psTemplate->asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", "ZNULLSENSOR").toString());
psTemplate->asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", "ZNULLCONSTRUCT").toString());
psTemplate->asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", "ZNULLWEAPON").toString());
psTemplate->asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", "ZNULLWEAPON").toString());
psTemplate->asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", "ZNULLWEAPON").toString());
psTemplate->numWeaps = ini.value("weapons").toInt();
psTemplate->enabled = ini.value("enabled").toBool();
psTemplate->prefab = false; // not AI template
@ -5549,23 +5543,23 @@ bool writeTemplateFile(const char *pFileName)
for (DROID_TEMPLATE *psCurr = apsDroidTemplates[player]; psCurr != NULL; psCurr = psCurr->psNext)
{
ini.beginGroup("template_" + QString::number(psCurr->multiPlayerID) + "_player" + QString::number(player));
ini.setValue("name", psCurr->aName);
ini.setValue("name", psCurr->name);
ini.setValue("ref", psCurr->ref);
ini.setValue("droidType", psCurr->droidType);
ini.setValue("multiPlayerID", psCurr->multiPlayerID);
setPlayer(ini, player);
ini.setValue("body", (asBodyStats + psCurr->asParts[COMP_BODY])->pName);
ini.setValue("propulsion", (asPropulsionStats + psCurr->asParts[COMP_PROPULSION])->pName);
ini.setValue("brain", (asBrainStats + psCurr->asParts[COMP_BRAIN])->pName);
ini.setValue("repair", (asRepairStats + psCurr->asParts[COMP_REPAIRUNIT])->pName);
ini.setValue("ecm", (asECMStats + psCurr->asParts[COMP_ECM])->pName);
ini.setValue("sensor", (asSensorStats + psCurr->asParts[COMP_SENSOR])->pName);
ini.setValue("construct", (asConstructStats + psCurr->asParts[COMP_CONSTRUCT])->pName);
ini.setValue("body", (asBodyStats + psCurr->asParts[COMP_BODY])->id);
ini.setValue("propulsion", (asPropulsionStats + psCurr->asParts[COMP_PROPULSION])->id);
ini.setValue("brain", (asBrainStats + psCurr->asParts[COMP_BRAIN])->id);
ini.setValue("repair", (asRepairStats + psCurr->asParts[COMP_REPAIRUNIT])->id);
ini.setValue("ecm", (asECMStats + psCurr->asParts[COMP_ECM])->id);
ini.setValue("sensor", (asSensorStats + psCurr->asParts[COMP_SENSOR])->id);
ini.setValue("construct", (asConstructStats + psCurr->asParts[COMP_CONSTRUCT])->id);
ini.setValue("weapons", psCurr->numWeaps);
ini.setValue("enabled", psCurr->enabled);
for (int j = 0; j < psCurr->numWeaps; j++)
{
ini.setValue("weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j])->pName);
ini.setValue("weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j])->id);
}
ini.endGroup();
}
@ -5692,20 +5686,12 @@ bool loadSaveCompList(const char *pFileName)
{
QString name = list[i];
int state = ini.value(name, UNAVAILABLE).toInt();
int type = -1;
int compInc = -1;
for (int j = 0; j < COMP_NUMCOMPONENTS && compInc == -1; j++)
{
// this is very inefficient, but I am so not giving in to the deranged nature of the components code
// and convoluting the new savegame format for its sake
compInc = getCompFromName(j, name.toUtf8().constData());
type = j;
}
ASSERT(compInc >= 0, "Bad component %d", compInc);
ASSERT(type >= 0 && type != COMP_NUMCOMPONENTS, "Bad type %d", type);
COMPONENT_STATS *psComp = getCompStatsFromName(name);
ASSERT(psComp, "Bad component %s", name.toUtf8().constData());
ASSERT(psComp->compType >= 0 && psComp->compType != COMP_NUMCOMPONENTS, "Bad type %d", psComp->compType);
ASSERT_OR_RETURN(false, state == UNAVAILABLE || state == AVAILABLE || state == FOUND || state == REDUNDANT,
"Bad state %d for %s", state, name.toUtf8().constData());
apCompLists[player][type][compInc] = state;
apCompLists[player][psComp->compType][psComp->index] = state;
}
ini.endGroup();
}
@ -5726,49 +5712,49 @@ static bool writeCompListFile(const char *pFileName)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asBodyStats + i);
const int state = apCompLists[player][COMP_BODY][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
for (int i = 0; i < numWeaponStats; i++)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asWeaponStats + i);
const int state = apCompLists[player][COMP_WEAPON][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
for (int i = 0; i < numConstructStats; i++)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asConstructStats + i);
const int state = apCompLists[player][COMP_CONSTRUCT][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
for (int i = 0; i < numECMStats; i++)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asECMStats + i);
const int state = apCompLists[player][COMP_ECM][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
for (int i = 0; i < numPropulsionStats; i++)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asPropulsionStats + i);
const int state = apCompLists[player][COMP_PROPULSION][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
for (int i = 0; i < numSensorStats; i++)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asSensorStats + i);
const int state = apCompLists[player][COMP_SENSOR][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
for (int i = 0; i < numRepairStats; i++)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asRepairStats + i);
const int state = apCompLists[player][COMP_REPAIRUNIT][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
for (int i = 0; i < numBrainStats; i++)
{
COMPONENT_STATS *psStats = (COMPONENT_STATS *)(asBrainStats + i);
const int state = apCompLists[player][COMP_BRAIN][i];
if (state != UNAVAILABLE) ini.setValue(psStats->pName, state);
if (state != UNAVAILABLE) ini.setValue(psStats->id, state);
}
ini.endGroup();
}
@ -5797,7 +5783,7 @@ static bool loadSaveStructTypeList(const char *pFileName)
{
STRUCTURE_STATS *psStats = asStructureStats + statInc;
if (name.compare(psStats->pName) == 0)
if (name.compare(psStats->id) == 0)
{
apStructTypeLists[player][statInc] = state;
break;
@ -5823,7 +5809,7 @@ static bool writeStructTypeListFile(const char *pFileName)
STRUCTURE_STATS *psStats = asStructureStats;
for (int i = 0; i < numStructureStats; i++, psStats++)
{
if (apStructTypeLists[player][i] != UNAVAILABLE) ini.setValue(psStats->pName, apStructTypeLists[player][i]);
if (apStructTypeLists[player][i] != UNAVAILABLE) ini.setValue(psStats->id, apStructTypeLists[player][i]);
}
ini.endGroup();
}
@ -5848,7 +5834,7 @@ bool loadSaveResearch(const char *pFileName)
{
RESEARCH *psStats = &asResearch[statInc];
//loop until find the same name
if (!strcmp(psStats->pName, name))
if (psStats->id.compare(name) == 0)
{
found = true;
@ -5916,7 +5902,7 @@ static bool writeResearchFile(char *pFileName)
if (valid)
{
ini.beginGroup("research_" + QString::number(i));
ini.setValue("name", psStats->pName);
ini.setValue("name", psStats->id);
ini.setValue("possible", possibles);
ini.setValue("researched", researched);
ini.setValue("currentPoints", points);
@ -6145,7 +6131,7 @@ bool loadSaveStructLimits(const char *pFileName)
for (statInc = 0; statInc < numStructureStats; statInc++)
{
STRUCTURE_STATS *psStats = asStructureStats + statInc;
if (name.compare(psStats->pName) == 0)
if (name.compare(psStats->id) == 0)
{
asStructLimits[player][statInc].limit = limit != 255? limit : LOTS_OF;
break;
@ -6174,7 +6160,7 @@ bool writeStructLimitsFile(const char *pFileName)
for (int i = 0; i < numStructureStats; i++, psStats++)
{
const int limit = MIN(asStructLimits[player][i].limit, 255);
if (limit != 255) ini.setValue(psStats->pName, limit);
if (limit != 255) ini.setValue(psStats->id, limit);
}
ini.endGroup();
}

View File

@ -1476,7 +1476,7 @@ INT_RETVAL intRunWidgets(void)
// the fact that we're cheating ourselves a new
// structure.
sasprintf((char **)&msg, _("Player %u is cheating (debug menu) him/herself a new structure: %s."),
selectedPlayer, psStructure->pStructureType->pName);
selectedPlayer, getName(psStructure->pStructureType));
sendTextMessage(msg, true);
Cheated = true;
}
@ -1487,7 +1487,7 @@ INT_RETVAL intRunWidgets(void)
// Send a text message to all players, notifying them of the fact that we're cheating ourselves a new feature.
sasprintf((char **)&msg, _("Player %u is cheating (debug menu) him/herself a new feature: %s."),
selectedPlayer, psPositionStats->pName);
selectedPlayer, getName(psPositionStats));
sendTextMessage(msg, true);
Cheated = true;
// Notify the other hosts that we've just built ourselves a feature
@ -3092,8 +3092,6 @@ static bool intAddObjectWindow(BASE_OBJECT *psObjects, BASE_OBJECT *psSelected,
sBarInit2.x = STAT_POWERBARX;
sBarInit2.y = STAT_POWERBARY;
sBarInit2.size = 50;
// don't set the tip cos we haven't got a suitable text string at this point - 2/2/99
sBarInit2.pTip = NULL;
W_LABINIT sLabInit;
sLabInit.id = IDOBJ_COUNTSTART;
@ -3221,11 +3219,11 @@ static bool intAddObjectWindow(BASE_OBJECT *psObjects, BASE_OBJECT *psSelected,
default:
ASSERT(false, "intAddObject: invalid structure type");
}
objButton->setTip(getName(((STRUCTURE *)psObj)->pStructureType->pName));
objButton->setTip(getName(((STRUCTURE *)psObj)->pStructureType));
break;
case OBJ_FEATURE:
objButton->setTip(getName(((FEATURE *)psObj)->psStats->pName));
objButton->setTip(getName(((FEATURE *)psObj)->psStats));
break;
default:
@ -3306,17 +3304,7 @@ static bool intAddObjectWindow(BASE_OBJECT *psObjects, BASE_OBJECT *psSelected,
if (psStats != NULL)
{
// If it's a droid the name might not be a stringID
if (psStats->ref >= REF_TEMPLATE_START &&
psStats->ref < REF_TEMPLATE_START + REF_RANGE)
{
statButton->setTip(getTemplateName((DROID_TEMPLATE *)psStats));
}
else
{
statButton->setTip(getName(psStats->pName));
}
statButton->setTip(getName(psStats));
statButton->setObjectAndStats(psObj, psStats);
}
else if ((psObj->type == OBJ_DROID) && (((DROID *)psObj)->droidType == DROID_COMMAND))
@ -3606,17 +3594,7 @@ static void intSetStats(UDWORD id, BASE_STATS *psStats)
if (psStats)
{
// If it's a droid the name might not be a stringID
if (psStats->ref >= REF_TEMPLATE_START &&
psStats->ref < REF_TEMPLATE_START + REF_RANGE)
{
statButton->setTip(getTemplateName((DROID_TEMPLATE *)psStats));
}
else
{
statButton->setTip(getName(psStats->pName));
}
statButton->setTip(getName(psStats));
statButton->setObjectAndStats(intGetObject(id), psStats);
// Add a text label for the size of the production run.
@ -3823,18 +3801,7 @@ static bool intAddStats(BASE_STATS **ppsStatsList, UDWORD numStats,
statList->addWidgetToLayout(button);
BASE_STATS *Stat = ppsStatsList[i];
// If it's a droid the name might not be a stringID
QString tipString;
if (Stat->ref >= REF_TEMPLATE_START &&
Stat->ref < REF_TEMPLATE_START + REF_RANGE)
{
tipString = QString::fromUtf8(getTemplateName((DROID_TEMPLATE *)ppsStatsList[i]));
}
else
{
tipString = QString::fromUtf8(getName(ppsStatsList[i]->pName));
}
QString tipString = ppsStatsList[i]->name;
unsigned powerCost = 0;
W_BARGRAPH *bar;
if (Stat->ref >= REF_STRUCTURE_START &&

View File

@ -1606,12 +1606,12 @@ void IntFancyButton::displayIMD(Image image, ImdObject imdObject, int xOffset, i
Radius = getComponentRadius((BASE_STATS *)Object);
scale = rescaleButtonObject(Radius, COMP_BUT_SCALE, COMPONENT_RADIUS);
// NOTE: The Super transport is huge, and is considered a component type, so refit it to inside the button.
const char *const name = ((BASE_STATS *)Object)->pName;
if (!strcmp(name, "SuperTransportBody"))
BASE_STATS *psStats = (BASE_STATS *)Object;
if (psStats->id.compare("SuperTransportBody") == 0)
{
scale *= .4;
}
else if (!strcmp(name, "TransporterBody"))
else if (psStats->id.compare("TransporterBody") == 0)
{
scale *= .6;
}

View File

@ -149,7 +149,7 @@ public:
void setStats(BASE_STATS *stats) { Stat = stats; }
void setStatsAndTip(BASE_STATS *stats) { setStats(stats); setTip(getStatName(Stat)); }
void setStatsAndTip(DROID_TEMPLATE *stats) { setStats(stats); setTip(getTemplateName(stats)); }
void setStatsAndTip(DROID_TEMPLATE *stats) { setStats(stats); setTip(getName(stats)); }
protected:
BASE_STATS *Stat;

View File

@ -387,7 +387,7 @@ void kf_CloneSelected( void )
{
for (DROID_TEMPLATE *psTempl = apsDroidTemplates[selectedPlayer]; psTempl; psTempl = psTempl->psNext)
{
if (!strcmp(psTempl->aName, psDroid->aName))
if (psTempl->name.compare(psDroid->aName) == 0)
{
sTemplate = psTempl;
break;
@ -415,7 +415,7 @@ void kf_CloneSelected( void )
}
else
{
debug(LOG_ERROR, "Cloning has failed for template:%s id:%d", sTemplate->pName, sTemplate->multiPlayerID);
debug(LOG_ERROR, "Cloning has failed for template:%s id:%d", getID(sTemplate), sTemplate->multiPlayerID);
}
}
sasprintf((char**)&msg, _("Player %u is cheating a new droid army of: %s."), selectedPlayer, psDroid->aName);
@ -1541,7 +1541,7 @@ void kf_FinishResearch( void )
{
researchResult(rindex, selectedPlayer, true, psCurr, true);
}
sasprintf((char**)&cmsg, _("(Player %u) is using cheat :%s %s"), selectedPlayer, _("Researched"), getName(pSubject->pName));
sasprintf((char**)&cmsg, _("(Player %u) is using cheat :%s %s"), selectedPlayer, _("Researched"), getName(pSubject));
sendTextMessage(cmsg, true);
intResearchFinished(psCurr);
}

View File

@ -762,13 +762,6 @@ static void startGameLoop(void)
debug( LOG_FATAL, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
//after data is loaded check the research stats are valid
if (!checkResearchStats())
{
debug( LOG_FATAL, "Invalid Research Stats" );
debug( LOG_FATAL, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
screen_StopBackDrop();

View File

@ -110,12 +110,11 @@ void renderResearchToBuffer(RESEARCH *psResearch, UDWORD OriginX, UDWORD OriginY
IMDType = IMDTYPE_COMPONENT;
psResGraphic = psResearch->psStat;
// FIXME: Another kludge to deal with the superTransport to make it "fit" the display.
// Using pName, should be safe to compare, pName doesn't get translated.
if (!strcmp("R-SuperTransport", psResearch->pName))
if (psResearch->id.compare("R-SuperTransport") == 0)
{
scale = RESEARCH_COMPONENT_SCALE / 3;
}
else if (!strcmp("R-Cyborg-Transport", psResearch->pName))
else if (psResearch->id.compare("R-Cyborg-Transport") == 0)
{
scale = RESEARCH_COMPONENT_SCALE / 2;
}

View File

@ -2299,7 +2299,6 @@ static bool _intAddMissionResult(bool result, bool bPlaySuccess)
sButInit.style = WBUT_TXTCENTRE;
sButInit.width = MISSION_TEXT_W;
sButInit.height = MISSION_TEXT_H;
sButInit.pTip = NULL;
sButInit.pDisplay = displayTextOption;
// If won or in debug mode
if (result || getDebugMappingStatus() || bMultiPlayer)

View File

@ -283,14 +283,7 @@ bool SendDroid(DROID_TEMPLATE* pTemplate, uint32_t x, uint32_t y, uint8_t player
NETuint8_t(&player);
NETuint32_t(&id);
NETPosition(&pos);
if (pTemplate->pName)
{
NETstring(pTemplate->pName, strlen(pTemplate->pName) + 1);
}
else
{
NETstring(pTemplate->aName, strlen(pTemplate->aName) + 1);
}
NETqstring(pTemplate->name);
NETint32_t(&droidType);
NETuint8_t(&pTemplate->asParts[COMP_BODY]);
NETuint8_t(&pTemplate->asParts[COMP_BRAIN]);
@ -337,8 +330,8 @@ bool recvDroid(NETQUEUE queue)
NETuint8_t(&player);
NETuint32_t(&id);
NETPosition(&pos);
NETstring(pT->aName, sizeof(pT->aName));
pT->pName = pT->aName;
NETqstring(pT->name);
pT->id = pT->name;
NETint32_t(&droidType);
NETuint8_t(&pT->asParts[COMP_BODY]);
NETuint8_t(&pT->asParts[COMP_BRAIN]);

View File

@ -726,14 +726,14 @@ bool pickupArtefact(int toPlayer, int fromPlayer)
MakeResearchPossible(&asPlayerResList[toPlayer][topic]);
if (toPlayer == selectedPlayer)
{
CONPRINTF(ConsoleString,(ConsoleString,_("You Discover Blueprints For %s"), getName(asResearch[topic].pName)));
CONPRINTF(ConsoleString,(ConsoleString,_("You Discover Blueprints For %s"), getName(&asResearch[topic])));
}
break;
}
// Invalid topic
else
{
debug(LOG_WARNING, "%s is a invalid research topic?", getName(asResearch[topic].pName));
debug(LOG_WARNING, "%s is a invalid research topic?", getName(&asResearch[topic]));
}
}
}

View File

@ -1718,7 +1718,6 @@ static void addDifficultyChooser(int player)
sButInit.y = (MULTIOP_PLAYERHEIGHT + 5) * i + 4;
sButInit.width = MULTIOP_PLAYERWIDTH + 1;
sButInit.height = MULTIOP_PLAYERHEIGHT;
sButInit.pTip = NULL;
switch (i)
{
case 0: sButInit.pTip = _("Starts disadvantaged"); break;
@ -2431,10 +2430,6 @@ void addPlayerBox(bool players)
{
sButInit.pTip = _("Teams locked");
}
else
{
sButInit.pTip = NULL;
}
sButInit.pDisplay = displayTeamChooser;
sButInit.UserData = i;
@ -2461,10 +2456,6 @@ void addPlayerBox(bool players)
{
sColInit.pTip = _("Click to change player colour");
}
else
{
sColInit.pTip = NULL;
}
sColInit.pDisplay = displayColour;
sColInit.UserData = i;
widgAddButton(psWScreen, &sColInit);
@ -2484,7 +2475,6 @@ void addPlayerBox(bool players)
sButInit.y = playerBoxHeight(i);
sButInit.width = MULTIOP_PLAYERWIDTH - MULTIOP_TEAMSWIDTH - MULTIOP_READY_WIDTH - MULTIOP_COLOUR_WIDTH;
sButInit.height = MULTIOP_PLAYERHEIGHT;
sButInit.pTip = NULL;
if ((selectedPlayer == i || NetPlay.isHost) && NetPlay.players[i].allocated && !locked.position)
{
sButInit.pTip = _("Click to change player position");

View File

@ -379,7 +379,7 @@ static void displayStructureBar(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset
// draw name
iV_SetFont(font_regular); // font
iV_SetTextColour(WZCOL_TEXT_BRIGHT);
iV_DrawText(_(getName(stat->pName)), x + 80, y + psWidget->height()/2 + 3);
iV_DrawText(_(getName(stat)), x + 80, y + psWidget->height()/2 + 3);
// draw limit
ssprintf(str, "%d", ((W_SLIDER *)widgGetFromID(psWScreen, psWidget->id + 1))->pos);

View File

@ -314,12 +314,6 @@ bool multiShutdown(void)
bool addTemplateToList(DROID_TEMPLATE *psNew, DROID_TEMPLATE **ppList)
{
DROID_TEMPLATE *psTempl = new DROID_TEMPLATE(*psNew);
psTempl->pName = NULL;
if (psNew->pName)
{
psTempl->pName = strdup(psNew->pName);
}
psTempl->psNext = *ppList;
*ppList = psTempl;

View File

@ -1014,7 +1014,7 @@ bool recvResearchStatus(NETQUEUE queue)
if (!researchAvailable(index, player, ModeImmediate) && bMultiPlayer)
{
debug(LOG_ERROR, "Player %d researching impossible topic \"%s\".", player, asResearch[index].pName);
debug(LOG_ERROR, "Player %d researching impossible topic \"%s\".", player, getName(&asResearch[index]));
return false;
}
@ -1420,7 +1420,7 @@ bool recvTextMessageAI(NETQUEUE queue)
static void NETtemplate(DROID_TEMPLATE *pTempl)
{
NETstring(pTempl->aName, sizeof(pTempl->aName));
NETqstring(pTempl->name);
for (unsigned i = 0; i < ARRAY_SIZE(pTempl->asParts); ++i)
{
@ -1468,7 +1468,6 @@ bool recvTemplate(NETQUEUE queue)
t.prefab = false;
t.psNext = NULL;
t.pName = NULL;
t.ref = REF_TEMPLATE_START;
psTempl = IdToTemplate(t.multiPlayerID,player);
@ -1598,7 +1597,7 @@ bool recvDestroyFeature(NETQUEUE queue)
return false;
}
debug(LOG_FEATURE, "p%d feature id %d destroyed (%s)", pF->player, pF->id, pF->psStats->pName);
debug(LOG_FEATURE, "p%d feature id %d destroyed (%s)", pF->player, pF->id, getName(pF->psStats));
// Remove the feature locally
turnOffMultiMsg(true);
destroyFeature(pF, gameTime - deltaGameTime + 1); // deltaGameTime is actually 0 here, since we're between updates. However, the value of gameTime - deltaGameTime + 1 will not change when we start the next tick.

View File

@ -77,20 +77,19 @@ const char *objInfo(const BASE_OBJECT *psObj)
case OBJ_DROID:
{
const DROID *psDroid = (const DROID *)psObj;
return droidGetName(psDroid);
}
case OBJ_STRUCTURE:
{
const STRUCTURE *psStruct = (const STRUCTURE *)psObj;
return getName(psStruct->pStructureType->pName);
sstrcpy(info, getName(psStruct->pStructureType));
break;
}
case OBJ_FEATURE:
{
const FEATURE *psFeat = (const FEATURE *)psObj;
return getName(psFeat->psStats->pName);
sstrcpy(info, getName(psFeat->psStats));
break;
}
case OBJ_PROJECTILE:
sstrcpy(info, "Projectile"); // TODO

View File

@ -1496,7 +1496,7 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder)
psDroid->order = *psOrder;
ASSERT(!psDroid->order.psStats || psDroid->order.psStats->type != REF_DEMOLISH, "Cannot build demolition");
actionDroid(psDroid, DACTION_BUILD, psOrder->pos.x, psOrder->pos.y);
objTrace(psDroid->id, "Starting new construction effort of %s", psOrder->psStats ? psOrder->psStats->pName : "NULL POINTER");
objTrace(psDroid->id, "Starting new construction effort of %s", psOrder->psStats ? getName(psOrder->psStats) : "NULL");
break;
case DORDER_BUILDMODULE:
//build a module onto the structure
@ -1508,7 +1508,7 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder)
ASSERT(psDroid->order.psStats != NULL, "should have found a module stats");
ASSERT(!psDroid->order.psStats || psDroid->order.psStats->type != REF_DEMOLISH, "Cannot build demolition");
actionDroid(psDroid, DACTION_BUILD, psOrder->psObj->pos.x,psOrder->psObj->pos.y);
objTrace(psDroid->id, "Starting new upgrade of %s", psOrder->psStats ? psOrder->psStats->pName : "NULL POINTER");
objTrace(psDroid->id, "Starting new upgrade of %s", psOrder->psStats ? getName(psOrder->psStats) : "NULL");
break;
case DORDER_HELPBUILD:
// help to build a structure that is starting to be built
@ -1519,7 +1519,7 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder)
psDroid->order.psStats = ((STRUCTURE *)psOrder->psObj)->pStructureType;
ASSERT(!psDroid->order.psStats || psDroid->order.psStats->type != REF_DEMOLISH, "Cannot build demolition");
actionDroid(psDroid, DACTION_BUILD, psDroid->order.pos.x, psDroid->order.pos.y);
objTrace(psDroid->id, "Helping construction of %s", psDroid->order.psStats ? psDroid->order.psStats->pName : "NULL POINTER");
objTrace(psDroid->id, "Helping construction of %s", psOrder->psStats ? getName(psDroid->order.psStats) : "NULL");
break;
case DORDER_DEMOLISH:
if (!(psDroid->droidType == DROID_CONSTRUCT || psDroid->droidType == DROID_CYBORG_CONSTRUCT))

View File

@ -307,9 +307,9 @@ QScriptValue convResearch(RESEARCH *psResearch, QScriptEngine *engine, int playe
}
value.setProperty("started", started); // including whether an ally has started it
value.setProperty("done", IsResearchCompleted(&asPlayerResList[player][psResearch->index]));
value.setProperty("fullname", getName(psResearch->pName)); // temporary
value.setProperty("name", psResearch->pName); // will be changed to contain fullname
value.setProperty("id", psResearch->pName);
value.setProperty("fullname", psResearch->name); // temporary
value.setProperty("name", psResearch->id); // will be changed to contain fullname
value.setProperty("id", psResearch->id);
value.setProperty("type", SCRIPT_RESEARCH);
QScriptValue results = engine->newArray(psResearch->resultStrings.size());
for (int i = 0; i < psResearch->resultStrings.size(); i++)
@ -404,7 +404,9 @@ QScriptValue convStructure(STRUCTURE *psStruct, QScriptEngine *engine)
{
QScriptValue weapon = engine->newObject();
const WEAPON_STATS *psStats = asWeaponStats + psStruct->asWeaps[j].nStat;
weapon.setProperty("name", psStats->pName, QScriptValue::ReadOnly);
weapon.setProperty("fullname", psStats->name, QScriptValue::ReadOnly);
weapon.setProperty("name", psStats->id, QScriptValue::ReadOnly); // will be changed to contain full name
weapon.setProperty("id", psStats->id, QScriptValue::ReadOnly);
weapon.setProperty("lastFired", psStruct->asWeaps[j].lastFired, QScriptValue::ReadOnly);
weaponlist.setProperty(j, weapon, QScriptValue::ReadOnly);
}
@ -556,8 +558,8 @@ QScriptValue convDroid(DROID *psDroid, QScriptEngine *engine)
value.setProperty("droidType", (int)type, QScriptValue::ReadOnly);
value.setProperty("experience", (double)psDroid->experience / 65536.0, QScriptValue::ReadOnly);
value.setProperty("health", 100.0 / (double)psDroid->originalBody * (double)psDroid->body, QScriptValue::ReadOnly);
value.setProperty("body", asBodyStats[psDroid->asBits[COMP_BODY]].pName, QScriptValue::ReadOnly);
value.setProperty("propulsion", asPropulsionStats[psDroid->asBits[COMP_PROPULSION]].pName, QScriptValue::ReadOnly);
value.setProperty("body", asBodyStats[psDroid->asBits[COMP_BODY]].id, QScriptValue::ReadOnly);
value.setProperty("propulsion", asPropulsionStats[psDroid->asBits[COMP_PROPULSION]].id, QScriptValue::ReadOnly);
value.setProperty("armed", 0.0, QScriptValue::ReadOnly); // deprecated!
QScriptValue weaponlist = engine->newArray(psDroid->numWeaps);
for (int j = 0; j < psDroid->numWeaps; j++)
@ -565,7 +567,9 @@ QScriptValue convDroid(DROID *psDroid, QScriptEngine *engine)
int armed = droidReloadBar(psDroid, &psDroid->asWeaps[j], j);
QScriptValue weapon = engine->newObject();
const WEAPON_STATS *psStats = asWeaponStats + psDroid->asWeaps[j].nStat;
weapon.setProperty("name", psStats->pName, QScriptValue::ReadOnly);
weapon.setProperty("fullname", psStats->name, QScriptValue::ReadOnly);
weapon.setProperty("id", psStats->id, QScriptValue::ReadOnly); // will be changed to full name
weapon.setProperty("name", psStats->id, QScriptValue::ReadOnly);
weapon.setProperty("lastFired", psDroid->asWeaps[j].lastFired, QScriptValue::ReadOnly);
weapon.setProperty("armed", armed, QScriptValue::ReadOnly);
weaponlist.setProperty(j, weapon, QScriptValue::ReadOnly);
@ -626,7 +630,7 @@ QScriptValue convObj(BASE_OBJECT *psObj, QScriptEngine *engine)
//;; and subject to change.
//;; The following properties are defined:
//;; \begin{description}
//;; \item[id] The unique ID of this object.
//;; \item[id] The ID of this object.
//;; \item[name] Name of the template.
//;; \item[cost] The power cost of the template if put into production.
//;; \item[droidType] The type of droid that would be created.
@ -642,23 +646,24 @@ QScriptValue convTemplate(DROID_TEMPLATE *psTempl, QScriptEngine *engine)
{
QScriptValue value = engine->newObject();
ASSERT_OR_RETURN(value, psTempl, "No object for conversion");
value.setProperty("id", psTempl->multiPlayerID, QScriptValue::ReadOnly);
value.setProperty("name", psTempl->pName, QScriptValue::ReadOnly);
value.setProperty("fullname", psTempl->name, QScriptValue::ReadOnly);
value.setProperty("name", psTempl->id, QScriptValue::ReadOnly);
value.setProperty("id", psTempl->id, QScriptValue::ReadOnly);
value.setProperty("points", calcTemplateBuild(psTempl), QScriptValue::ReadOnly);
value.setProperty("power", calcTemplatePower(psTempl), QScriptValue::ReadOnly); // deprecated, use cost below
value.setProperty("cost", calcTemplatePower(psTempl), QScriptValue::ReadOnly);
value.setProperty("droidType", psTempl->droidType, QScriptValue::ReadOnly);
value.setProperty("body", (asBodyStats + psTempl->asParts[COMP_BODY])->pName, QScriptValue::ReadOnly);
value.setProperty("propulsion", (asPropulsionStats + psTempl->asParts[COMP_PROPULSION])->pName, QScriptValue::ReadOnly);
value.setProperty("brain", (asBrainStats + psTempl->asParts[COMP_BRAIN])->pName, QScriptValue::ReadOnly);
value.setProperty("repair", (asRepairStats + psTempl->asParts[COMP_REPAIRUNIT])->pName, QScriptValue::ReadOnly);
value.setProperty("ecm", (asECMStats + psTempl->asParts[COMP_ECM])->pName, QScriptValue::ReadOnly);
value.setProperty("sensor", (asSensorStats + psTempl->asParts[COMP_SENSOR])->pName, QScriptValue::ReadOnly);
value.setProperty("construct", (asConstructStats + psTempl->asParts[COMP_CONSTRUCT])->pName, QScriptValue::ReadOnly);
value.setProperty("body", (asBodyStats + psTempl->asParts[COMP_BODY])->id, QScriptValue::ReadOnly);
value.setProperty("propulsion", (asPropulsionStats + psTempl->asParts[COMP_PROPULSION])->id, QScriptValue::ReadOnly);
value.setProperty("brain", (asBrainStats + psTempl->asParts[COMP_BRAIN])->id, QScriptValue::ReadOnly);
value.setProperty("repair", (asRepairStats + psTempl->asParts[COMP_REPAIRUNIT])->id, QScriptValue::ReadOnly);
value.setProperty("ecm", (asECMStats + psTempl->asParts[COMP_ECM])->id, QScriptValue::ReadOnly);
value.setProperty("sensor", (asSensorStats + psTempl->asParts[COMP_SENSOR])->id, QScriptValue::ReadOnly);
value.setProperty("construct", (asConstructStats + psTempl->asParts[COMP_CONSTRUCT])->id, QScriptValue::ReadOnly);
QScriptValue weaponlist = engine->newArray(psTempl->numWeaps);
for (int j = 0; j < psTempl->numWeaps; j++)
{
weaponlist.setProperty(j, QScriptValue((asWeaponStats + psTempl->asWeaps[j])->pName), QScriptValue::ReadOnly);
weaponlist.setProperty(j, QScriptValue((asWeaponStats + psTempl->asWeaps[j])->id), QScriptValue::ReadOnly);
}
value.setProperty("weapons", weaponlist);
return value;
@ -857,7 +862,7 @@ bool writeLabels(const char *filename)
static QScriptValue js_getWeaponInfo(QScriptContext *context, QScriptEngine *engine)
{
QString id = context->argument(0).toString();
int idx = getCompFromName(COMP_WEAPON, id.toUtf8().constData());
int idx = getCompFromName(COMP_WEAPON, id);
SCRIPT_ASSERT(context, idx >= 0, "No such weapon: %s", id.toUtf8().constData());
WEAPON_STATS *psStats = asWeaponStats + idx;
QScriptValue info = engine->newObject();
@ -1213,7 +1218,7 @@ static QScriptValue js_findResearch(QScriptContext *context, QScriptEngine *engi
{
if (!(asPlayerResList[player][cur->index].ResearchStatus & RESEARCHED))
{
debug(LOG_SCRIPT, "Added research in %d's %s for %s", player, cur->pName, psTarget->pName);
debug(LOG_SCRIPT, "Added research in %d's %s for %s", player, getID(cur), getID(psTarget));
list.append(cur);
}
RESEARCH *prev = cur;
@ -1314,11 +1319,11 @@ static QScriptValue js_pursueResearch(QScriptContext *context, QScriptEngine *en
sendResearchStatus(psStruct, cur->index, player, true);
#if defined (DEBUG)
char sTemp[128];
sprintf(sTemp, "player:%d starts topic from script: %s", player, cur->pName);
sprintf(sTemp, "player:%d starts topic from script: %s", player, getID(cur));
NETlogEntry(sTemp, SYNC_FLAG, 0);
#endif
debug(LOG_SCRIPT, "Started research in %d's %s(%d) of %s", player,
objInfo(psStruct), psStruct->id, cur->pName);
objInfo(psStruct), psStruct->id, getName(cur));
return QScriptValue(true);
}
}
@ -1337,7 +1342,7 @@ static QScriptValue js_pursueResearch(QScriptContext *context, QScriptEngine *en
{
cur = reslist.takeFirst(); // retrieve options from the stack
}
ASSERT_OR_RETURN(QScriptValue(false), ++iterations < asResearch.size()*100 || !cur, "Possible cyclic dependencies in prerequisites, possibly of research \"%s\".", cur->pName);
ASSERT_OR_RETURN(QScriptValue(false), ++iterations < asResearch.size()*100 || !cur, "Possible cyclic dependencies in prerequisites, possibly of research \"%s\".", getName(cur));
}
debug(LOG_SCRIPT, "No research topic found for %s(%d)", objInfo(psStruct), psStruct->id);
return QScriptValue(false); // none found
@ -1386,35 +1391,10 @@ static QScriptValue js_enumResearch(QScriptContext *context, QScriptEngine *engi
static QScriptValue js_componentAvailable(QScriptContext *context, QScriptEngine *engine)
{
int player = engine->globalObject().property("me").toInt32();
if (context->argumentCount() == 1)
{
QString id = context->argument(0).toString();
int idx = -1;
#define CHECK_COMPONENT(_comp) \
if ((idx = getCompFromName(_comp, id.toUtf8().constData())) >= 0) \
{ \
return QScriptValue(apCompLists[player][_comp][idx] == AVAILABLE); \
}
CHECK_COMPONENT(COMP_BODY);
CHECK_COMPONENT(COMP_BRAIN);
CHECK_COMPONENT(COMP_PROPULSION);
CHECK_COMPONENT(COMP_REPAIRUNIT);
CHECK_COMPONENT(COMP_ECM);
CHECK_COMPONENT(COMP_SENSOR);
CHECK_COMPONENT(COMP_CONSTRUCT);
CHECK_COMPONENT(COMP_WEAPON);
#undef CHECK_COMPONENT
SCRIPT_ASSERT(context, false, "No such component: %s", id.toUtf8().constData());
return QScriptValue::NullValue; // to satisfy compiler
}
else
{
COMPONENT_TYPE comp = (COMPONENT_TYPE)(context->argument(0).toInt32() + 1); // backwards compat crap
QString compName = context->argument(1).toString();
int result = getCompFromName(comp, compName.toUtf8().constData());
SCRIPT_ASSERT(context, result >= 0, "No such component: %s", compName.toUtf8().constData());
return QScriptValue(apCompLists[player][comp][result] == AVAILABLE);
}
QString id = (context->argumentCount() == 1) ? context->argument(0).toString() : context->argument(1).toString();
COMPONENT_STATS *psComp = getCompStatsFromName(id);
SCRIPT_ASSERT(context, psComp, "No such component: %s", id.toUtf8().constData());
return QScriptValue(apCompLists[player][psComp->compType][psComp->index] == AVAILABLE);
}
//-- \subsection{addFeature(name, x, y)}
@ -1445,7 +1425,7 @@ static int get_first_available_component(int player, int capacity, const QScript
for (k = 0; k < length; k++)
{
QString compName = list.property(k).toString();
int result = getCompFromName(type, compName.toUtf8().constData());
int result = getCompFromName(type, compName);
if (result >= 0 && (apCompLists[player][type][result] == AVAILABLE || !strict)
&& (type != COMP_BODY || asBodyStats[result].size <= capacity))
{
@ -1459,7 +1439,7 @@ static int get_first_available_component(int player, int capacity, const QScript
}
else if (list.isString())
{
int result = getCompFromName(type, list.toString().toUtf8().constData());
int result = getCompFromName(type, list.toString());
if (result >= 0 && (apCompLists[player][type][result] == AVAILABLE || !strict)
&& (type != COMP_BODY || asBodyStats[result].size <= capacity))
{
@ -1473,7 +1453,7 @@ static int get_first_available_component(int player, int capacity, const QScript
return -1; // no available component found in list
}
static DROID_TEMPLATE *makeTemplate(int player, int x, int y, const QString &templName, QScriptContext *context, int paramstart, int capacity, bool strict)
static DROID_TEMPLATE *makeTemplate(int player, const QString &templName, QScriptContext *context, int paramstart, int capacity, bool strict)
{
const int firstTurret = paramstart + 4; // index position of first turret parameter
DROID_TEMPLATE *psTemplate = new DROID_TEMPLATE;
@ -1517,12 +1497,19 @@ static DROID_TEMPLATE *makeTemplate(int player, int x, int y, const QString &tem
{
compName = context->argument(firstTurret).toString();
}
if ((result = getCompFromName(COMP_WEAPON, compName.toUtf8().constData())) >= 0)
COMPONENT_STATS *psComp = getCompStatsFromName(compName);
if (psComp == NULL)
{
debug(LOG_ERROR, "Wanted to build %s but %s does not exist", templName.toUtf8().constData(), compName.toUtf8().constData());
delete psTemplate;
return NULL;
}
if (psComp->compType == COMP_WEAPON)
{
for (int i = 0; i < numTurrets; i++) // may be multi-weapon
{
result = get_first_available_component(player, SIZE_NUM, context->argument(firstTurret + i), COMP_WEAPON, strict);
if (result < 0)
if (result < -0)
{
debug(LOG_SCRIPT, "Wanted to build %s but no weapon available", templName.toUtf8().constData());
delete psTemplate;
@ -1534,43 +1521,18 @@ static DROID_TEMPLATE *makeTemplate(int player, int x, int y, const QString &tem
}
else
{
COMPONENT_TYPE compType = COMP_NUMCOMPONENTS;
if ((result = getCompFromName(COMP_CONSTRUCT, compName.toUtf8().constData())) >= 0)
if (psComp->compType == COMP_BRAIN)
{
compType = COMP_CONSTRUCT;
}
else if ((result = getCompFromName(COMP_BRAIN, compName.toUtf8().constData())) >= 0)
{
compType = COMP_BRAIN;
psTemplate->numWeaps = 1; // hack, necessary to pass intValidTemplate
}
else if ((result = getCompFromName(COMP_REPAIRUNIT, compName.toUtf8().constData())) >= 0)
{
compType = COMP_REPAIRUNIT;
}
else if ((result = getCompFromName(COMP_ECM, compName.toUtf8().constData())) >= 0)
{
compType = COMP_ECM;
}
else if ((result = getCompFromName(COMP_SENSOR, compName.toUtf8().constData())) >= 0)
{
compType = COMP_SENSOR;
}
else
{
debug(LOG_ERROR, "No known component type found for %s", compName.toUtf8().constData());
delete psTemplate;
return NULL;
}
result = get_first_available_component(player, SIZE_NUM, context->argument(firstTurret), compType, strict);
result = get_first_available_component(player, SIZE_NUM, context->argument(firstTurret), psComp->compType, strict);
if (result < 0)
{
debug(LOG_SCRIPT, "Wanted to build %s but turret unavailable", templName.toUtf8().constData());
delete psTemplate;
return NULL;
}
psTemplate->asParts[compType] = result;
psTemplate->asParts[psComp->compType] = result;
}
bool valid = intValidTemplate(psTemplate, templName.toUtf8().constData(), true, player);
if (valid)
@ -1597,7 +1559,7 @@ static QScriptValue js_addDroid(QScriptContext *context, QScriptEngine *engine)
int x = context->argument(1).toInt32();
int y = context->argument(2).toInt32();
QString templName = context->argument(3).toString();
DROID_TEMPLATE *psTemplate = makeTemplate(player, x, y, templName, context, 4, SIZE_NUM, false);
DROID_TEMPLATE *psTemplate = makeTemplate(player, templName, context, 4, SIZE_NUM, false);
if (psTemplate)
{
bool oldMulti = bMultiMessages;
@ -1627,7 +1589,7 @@ static QScriptValue js_makeTemplate(QScriptContext *context, QScriptEngine *engi
{
int player = context->argument(0).toInt32();
QString templName = context->argument(1).toString();
DROID_TEMPLATE *psTemplate = makeTemplate(player, -1, -1, templName, context, 2, SIZE_NUM, true);
DROID_TEMPLATE *psTemplate = makeTemplate(player, templName, context, 2, SIZE_NUM, true);
if (!psTemplate)
{
return QScriptValue::NullValue;
@ -1655,33 +1617,33 @@ static QScriptValue js_buildDroid(QScriptContext *context, QScriptEngine *engine
|| psStruct->pStructureType->type == REF_VTOL_FACTORY), "Structure %s is not a factory", objInfo(psStruct));
QString templName = context->argument(1).toString();
const int capacity = psStruct->capacity; // body size limit
DROID_TEMPLATE *psTemplate = makeTemplate(player, psStruct->pos.x, psStruct->pos.y, templName, context, 2, capacity, true);
DROID_TEMPLATE *psTemplate = makeTemplate(player, templName, context, 2, capacity, true);
if (psTemplate)
{
SCRIPT_ASSERT(context, validTemplateForFactory(psTemplate, psStruct, true),
"Invalid template %s for factory %s",
psTemplate->aName, psStruct->pStructureType->pName);
getName(psTemplate), getName(psStruct->pStructureType));
// Delete similar template from existing list before adding this one
for (int j = 0; j < apsTemplateList.size(); j++)
{
DROID_TEMPLATE *t = apsTemplateList[j];
if (strcmp(t->aName, psTemplate->aName) == 0)
if (t->name.compare(psTemplate->name) == 0)
{
debug(LOG_SCRIPT, "deleting %s for player %d", t->aName, player);
debug(LOG_SCRIPT, "deleting %s for player %d", getName(t), player);
deleteTemplateFromProduction(t, player, ModeQueue); // duplicate? done below?
SendDestroyTemplate(t, player);
break;
}
}
// Add to list
debug(LOG_SCRIPT, "adding template %s for player %d", psTemplate->aName, player);
debug(LOG_SCRIPT, "adding template %s for player %d", getName(psTemplate), player);
psTemplate->multiPlayerID = generateNewObjectId();
psTemplate->psNext = apsDroidTemplates[player];
apsDroidTemplates[player] = psTemplate;
sendTemplate(player, psTemplate);
if (!structSetManufacture(psStruct, psTemplate, ModeQueue))
{
debug(LOG_ERROR, "Could not produce template %s in %s", psTemplate->aName, objInfo(psStruct));
debug(LOG_ERROR, "Could not produce template %s in %s", getName(psTemplate), objInfo(psStruct));
return QScriptValue(false);
}
}
@ -1727,7 +1689,7 @@ static QScriptValue js_enumStruct(QScriptContext *context, QScriptEngine *engine
if ((looking == -1 || psStruct->visible[looking])
&& !psStruct->died
&& (type == NUM_DIFF_BUILDINGS || type == psStruct->pStructureType->type)
&& (statsName.isEmpty() || statsName.compare(psStruct->pStructureType->pName) == 0))
&& (statsName.isEmpty() || statsName.compare(psStruct->pStructureType->id) == 0))
{
matches.push_back(psStruct);
}
@ -1780,7 +1742,7 @@ static QScriptValue js_enumStructOffWorld(QScriptContext *context, QScriptEngine
if ((looking == -1 || psStruct->visible[looking])
&& !psStruct->died
&& (type == NUM_DIFF_BUILDINGS || type == psStruct->pStructureType->type)
&& (statsName.isEmpty() || statsName.compare(psStruct->pStructureType->pName) == 0))
&& (statsName.isEmpty() || statsName.compare(psStruct->pStructureType->id) == 0))
{
matches.push_back(psStruct);
}
@ -1812,7 +1774,7 @@ static QScriptValue js_enumFeature(QScriptContext *context, QScriptEngine *engin
{
if ((looking == -1 || psFeat->visible[looking])
&& !psFeat->died
&& (statsName.isEmpty() || statsName.compare(psFeat->psStats->pName) == 0))
&& (statsName.isEmpty() || statsName.compare(psFeat->psStats->id) == 0))
{
matches.push_back(psFeat);
}
@ -2060,7 +2022,7 @@ endstructloc:
}
else
{
debug(LOG_SCRIPT, "Did not find valid positioning for %s", psStat->pName);
debug(LOG_SCRIPT, "Did not find valid positioning for %s", getName(psStat));
}
return QScriptValue();
}
@ -2255,7 +2217,7 @@ static QScriptValue js_droidCanReach(QScriptContext *context, QScriptEngine *)
static QScriptValue js_propulsionCanReach(QScriptContext *context, QScriptEngine *)
{
QScriptValue propulsionValue = context->argument(0);
int propulsion = getCompFromName(COMP_PROPULSION, propulsionValue.toString().toUtf8().constData());
int propulsion = getCompFromName(COMP_PROPULSION, propulsionValue.toString());
SCRIPT_ASSERT(context, propulsion > 0, "No such propulsion: %s", propulsionValue.toString().toUtf8().constData());
int x1 = context->argument(1).toInt32();
int y1 = context->argument(2).toInt32();
@ -2328,7 +2290,7 @@ static QScriptValue js_orderDroidBuild(QScriptContext *context, QScriptEngine *)
uint16_t direction = 0;
SCRIPT_ASSERT(context, order == DORDER_BUILD, "Invalid order");
SCRIPT_ASSERT(context, strcmp(psStats->pName, "A0ADemolishStructure") != 0, "Cannot build demolition");
SCRIPT_ASSERT(context, psStats->id.compare("A0ADemolishStructure") != 0, "Cannot build demolition");
if (context->argumentCount() > 5)
{
direction = DEG(context->argument(5).toNumber());
@ -2731,7 +2693,7 @@ static QScriptValue js_enableTemplate(QScriptContext *context, QScriptEngine *en
// FIXME: This dual data structure for templates is just plain insane.
for (psCurr = apsDroidTemplates[selectedPlayer]; psCurr != NULL; psCurr = psCurr->psNext)
{
if (!templateName.compare(psCurr->pName))
if (templateName.compare(psCurr->id) == 0)
{
psCurr->enabled = true;
found = true;
@ -2745,7 +2707,7 @@ static QScriptValue js_enableTemplate(QScriptContext *context, QScriptEngine *en
for (std::list<DROID_TEMPLATE>::iterator i = localTemplates.begin(); i != localTemplates.end(); ++i)
{
psCurr = &*i;
if (!templateName.compare(psCurr->pName))
if (templateName.compare(psCurr->id) == 0)
{
psCurr->enabled = true;
}
@ -2785,17 +2747,9 @@ static QScriptValue js_applyLimitSet(QScriptContext *context, QScriptEngine *eng
static void setComponent(QString name, int player, int value)
{
int type = -1;
int compInc = -1;
for (int j = 0; j < COMP_NUMCOMPONENTS && compInc == -1; j++)
{
// this is very inefficient, but I am so not giving in to the deranged nature of the components code
// and convoluting the new script system for its sake
compInc = getCompFromName(j, name.toUtf8().constData());
type = j;
}
ASSERT_OR_RETURN(, compInc != -1 && type != -1, "Bad component value");
apCompLists[player][type][compInc] = value;
COMPONENT_STATS *psComp = getCompStatsFromName(name);
ASSERT_OR_RETURN(, psComp, "Bad component %s", name.toUtf8().constData());
apCompLists[player][psComp->compType][psComp->index] = value;
}
//-- \subsection{enableComponent(component, player)}
@ -3499,7 +3453,7 @@ static QScriptValue js_getDroidProduction(QScriptContext *context, QScriptEngine
psDroid->pos = psStruct->pos;
psDroid->rot = psStruct->rot;
psDroid->experience = 0;
droidSetName(psDroid, psTemp->aName);
droidSetName(psDroid, getName(psTemp));
droidSetBits(psTemp, psDroid);
psDroid->weight = calcDroidWeight(psTemp);
psDroid->baseSpeed = calcDroidBaseSpeed(psTemp, psDroid->weight, player);
@ -4118,7 +4072,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
{
BODY_STATS *psStats = asBodyStats + j;
QScriptValue body = engine->newObject();
body.setProperty("Id", psStats->pName, QScriptValue::ReadOnly | QScriptValue::Undeletable);
body.setProperty("Id", psStats->id, QScriptValue::ReadOnly | QScriptValue::Undeletable);
body.setProperty("Weight", psStats->weight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
body.setProperty("BuildPower", psStats->buildPower, QScriptValue::ReadOnly | QScriptValue::Undeletable);
body.setProperty("BuildTime", psStats->buildPoints, QScriptValue::ReadOnly | QScriptValue::Undeletable);
@ -4139,7 +4093,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
{
SENSOR_STATS *psStats = asSensorStats + j;
QScriptValue sensor = engine->newObject();
sensor.setProperty("Id", psStats->pName, QScriptValue::ReadOnly | QScriptValue::Undeletable);
sensor.setProperty("Id", psStats->id, QScriptValue::ReadOnly | QScriptValue::Undeletable);
sensor.setProperty("Weight", psStats->weight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
sensor.setProperty("BuildPower", psStats->buildPower, QScriptValue::ReadOnly | QScriptValue::Undeletable);
sensor.setProperty("BuildTime", psStats->buildPoints, QScriptValue::ReadOnly | QScriptValue::Undeletable);
@ -4154,7 +4108,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
{
ECM_STATS *psStats = asECMStats + j;
QScriptValue ecm = engine->newObject();
ecm.setProperty("Id", psStats->pName, QScriptValue::ReadOnly | QScriptValue::Undeletable);
ecm.setProperty("Id", psStats->id, QScriptValue::ReadOnly | QScriptValue::Undeletable);
ecm.setProperty("Weight", psStats->weight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
ecm.setProperty("BuildPower", psStats->buildPower, QScriptValue::ReadOnly | QScriptValue::Undeletable);
ecm.setProperty("BuildTime", psStats->buildPoints, QScriptValue::ReadOnly | QScriptValue::Undeletable);
@ -4169,7 +4123,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
{
REPAIR_STATS *psStats = asRepairStats + j;
QScriptValue repair = engine->newObject();
repair.setProperty("Id", psStats->pName, QScriptValue::ReadOnly | QScriptValue::Undeletable);
repair.setProperty("Id", psStats->id, QScriptValue::ReadOnly | QScriptValue::Undeletable);
repair.setProperty("Weight", psStats->weight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
repair.setProperty("BuildPower", psStats->buildPower, QScriptValue::ReadOnly | QScriptValue::Undeletable);
repair.setProperty("BuildTime", psStats->buildPoints, QScriptValue::ReadOnly | QScriptValue::Undeletable);
@ -4184,7 +4138,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
{
CONSTRUCT_STATS *psStats = asConstructStats + j;
QScriptValue con = engine->newObject();
con.setProperty("Id", psStats->pName, QScriptValue::ReadOnly | QScriptValue::Undeletable);
con.setProperty("Id", psStats->id, QScriptValue::ReadOnly | QScriptValue::Undeletable);
con.setProperty("Weight", psStats->weight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
con.setProperty("BuildPower", psStats->buildPower, QScriptValue::ReadOnly | QScriptValue::Undeletable);
con.setProperty("BuildTime", psStats->buildPoints, QScriptValue::ReadOnly | QScriptValue::Undeletable);
@ -4199,7 +4153,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
{
WEAPON_STATS *psStats = asWeaponStats + j;
QScriptValue weap = engine->newObject();
weap.setProperty("Id", psStats->pName, QScriptValue::ReadOnly | QScriptValue::Undeletable);
weap.setProperty("Id", psStats->id, QScriptValue::ReadOnly | QScriptValue::Undeletable);
weap.setProperty("Weight", psStats->weight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
weap.setProperty("BuildPower", psStats->buildPower, QScriptValue::ReadOnly | QScriptValue::Undeletable);
weap.setProperty("BuildTime", psStats->buildPoints, QScriptValue::ReadOnly | QScriptValue::Undeletable);
@ -4240,7 +4194,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
{
STRUCTURE_STATS *psStats = asStructureStats + j;
QScriptValue strct = engine->newObject();
strct.setProperty("Id", psStats->pName, QScriptValue::ReadOnly | QScriptValue::Undeletable);
strct.setProperty("Id", psStats->id, QScriptValue::ReadOnly | QScriptValue::Undeletable);
if (psStats->type == REF_DEFENSE || psStats->type == REF_WALL || psStats->type == REF_WALLCORNER
|| psStats->type == REF_BLASTDOOR || psStats->type == REF_GATE)
{

View File

@ -67,16 +67,11 @@ UDWORD aDefaultECM[MAX_PLAYERS];
UDWORD aDefaultRepair[MAX_PLAYERS];
//set the iconID based on the name read in in the stats
static UWORD setIconID(char *pIconName, char *pName);
static UWORD setIconID(char *pIconName, const char *pName);
static void replaceComponent(COMPONENT_STATS *pNewComponent, COMPONENT_STATS *pOldComponent,
UBYTE player);
static bool checkResearchName(RESEARCH *psRes, UDWORD numStats);
static const char *getResearchName(RESEARCH *pResearch)
{
return(getName(pResearch->pName));
}
//flag that indicates whether the player can self repair
static UBYTE bSelfRepair[MAX_PLAYERS];
static void replaceDroidComponent(DROID *pList, UDWORD oldType, UDWORD oldCompInc,
@ -107,32 +102,6 @@ bool researchInitVars(void)
return true;
}
//searches for component with given name
//returns NULL if record not found
BASE_STATS* get_any_component_from_ID(QString name)
{
for (int compType=0; compType<COMP_NUMCOMPONENTS; compType++)
{
BASE_STATS *psStats = NULL;
UDWORD numStats = 0, statSize = 0;
getStatsDetails(compType, &psStats, &numStats, &statSize);
//find the stat with the same name
for (unsigned int count = 0; count < numStats; count++)
{
if (name.compare(psStats->pName, Qt::CaseInsensitive) == 0)
{
return psStats;
}
psStats = (BASE_STATS *)((char *)psStats + statSize);
}
}
//return NULL if record not found or an invalid component type is passed in
return NULL;
}
/** Load the research stats */
bool loadResearch(QString filename)
{
@ -153,21 +122,20 @@ bool loadResearch(QString filename)
ini.beginGroup(list[inc]);
RESEARCH research;
research.index = inc;
research.pName = allocateName(list[inc].toUtf8().constData());
ASSERT_OR_RETURN(false, research.pName != NULL, "Failed allocating research name");
research.name = ini.value("name").toString();
research.id = list[inc];
//check the name hasn't been used already
ASSERT_OR_RETURN(false, checkResearchName(&research, inc), "Research name '%s' used already", research.pName);
ASSERT_OR_RETURN(false, checkResearchName(&research, inc), "Research name '%s' used already", getName(&research));
research.ref = REF_RESEARCH_START + inc;
research.resultStrings = ini.value("results").toStringList();
//set subGroup icon
QString subGroup = ini.value("subgroupIconID", "").toString();
if (subGroup.compare("") != 0)
{
research.subGroup = setIconID(subGroup.toUtf8().data(), research.pName);
research.subGroup = setIconID(subGroup.toUtf8().data(), getName(&research));
}
else
{
@ -176,7 +144,7 @@ bool loadResearch(QString filename)
//set key topic
unsigned int keyTopic = ini.value("keyTopic", 0).toUInt();
ASSERT(keyTopic <= 1, "Invalid keyTopic for research topic - '%s' ", getResearchName(&research));
ASSERT(keyTopic <= 1, "Invalid keyTopic for research topic - '%s' ", getName(&research));
if(keyTopic <= 1)
research.keyTopic = ini.value("keyTopic", 0).toUInt();
else
@ -184,7 +152,7 @@ bool loadResearch(QString filename)
//set tech code
UBYTE techCode = ini.value("techCode", 0).toUInt();
ASSERT(techCode <= 1, "Invalid tech code for research topic - '%s' ", getResearchName(&research));
ASSERT(techCode <= 1, "Invalid tech code for research topic - '%s' ", getName(&research));
if (techCode == 0)
{
research.techCode = TC_MAJOR;
@ -198,7 +166,7 @@ bool loadResearch(QString filename)
QString iconID = ini.value("iconID", "").toString();
if (iconID.compare("") != 0)
{
research.iconID = setIconID(iconID.toUtf8().data(), research.pName);
research.iconID = setIconID(iconID.toUtf8().data(), getName(&research));
}
else
{
@ -218,20 +186,16 @@ bool loadResearch(QString filename)
}else
{
//try find the component stat with given name
BASE_STATS* tmpComp = get_any_component_from_ID(statID);
if(tmpComp != NULL)
{
research.psStat = tmpComp;
}
research.psStat = getCompStatsFromName(statID);
}
ASSERT_OR_RETURN(false, research.psStat != NULL, "Cannot find the statID '%s' for Research '%s'", statID.toUtf8().data(), getResearchName(&research));
ASSERT_OR_RETURN(false, research.psStat != NULL, "Cannot find the statID '%s' for Research '%s'", statID.toUtf8().data(), getName(&research));
}
QString imdName = ini.value("imdName", "").toString();
if (imdName.compare("") != 0)
{
research.pIMD = (iIMDShape *) resGetData("IMD", imdName.toUtf8().data());
ASSERT(research.pIMD != NULL, "Cannot find the research PIE '%s' for record '%s'",imdName.toUtf8().data(), getResearchName(&research));
ASSERT(research.pIMD != NULL, "Cannot find the research PIE '%s' for record '%s'",imdName.toUtf8().data(), getName(&research));
}
else
{
@ -242,7 +206,7 @@ bool loadResearch(QString filename)
if (imdName2.compare("") != 0)
{
research.pIMD2 = (iIMDShape *) resGetData("IMD", imdName2.toUtf8().data());
ASSERT(research.pIMD2 != NULL, "Cannot find the 2nd research '%s' PIE for record '%s'",imdName2.toUtf8().data(), getResearchName(&research));
ASSERT(research.pIMD2 != NULL, "Cannot find the 2nd research '%s' PIE for record '%s'",imdName2.toUtf8().data(), getName(&research));
}
else
{
@ -253,7 +217,7 @@ bool loadResearch(QString filename)
if (msgName.compare("") != 0)
{
//check its a major tech code
ASSERT(research.techCode == TC_MAJOR, "This research should not have a message associated with it, '%s' the message will be ignored!", getResearchName(&research));
ASSERT(research.techCode == TC_MAJOR, "This research should not have a message associated with it, '%s' the message will be ignored!", getName(&research));
if (research.techCode == TC_MAJOR)
{
research.pViewData = getViewData(msgName.toUtf8().data());
@ -262,12 +226,12 @@ bool loadResearch(QString filename)
//set the researchPoints
unsigned int resPoints = ini.value("researchPoints", 0).toUInt();
ASSERT_OR_RETURN(false, resPoints <= UWORD_MAX, "Research Points too high for research topic - '%s' ", getResearchName(&research));
ASSERT_OR_RETURN(false, resPoints <= UWORD_MAX, "Research Points too high for research topic - '%s' ", getName(&research));
research.researchPoints = resPoints;
//set the research power
unsigned int resPower = ini.value("researchPower", 0).toUInt();
ASSERT_OR_RETURN(false, resPower <= UWORD_MAX, "Research Power too high for research topic - '%s' ", getResearchName(&research));
ASSERT_OR_RETURN(false, resPower <= UWORD_MAX, "Research Power too high for research topic - '%s' ", getName(&research));
research.researchPower = resPower;
//rememeber research pre-requisites for futher checking
@ -278,13 +242,13 @@ bool loadResearch(QString filename)
for (int j = 0; j < compResults.size(); j++)
{
QString compID = compResults[j].trimmed();
BASE_STATS *pComp = get_any_component_from_ID(compID);
COMPONENT_STATS *pComp = getCompStatsFromName(compID);
if (pComp != NULL)
{
research.componentResults.push_back((COMPONENT_STATS*)pComp);
research.componentResults.push_back(pComp);
}else
{
ASSERT(false, "Invalid item '%s' in list of result components of research '%s' ", compID.toUtf8().constData(), getResearchName(&research));
ASSERT(false, "Invalid item '%s' in list of result components of research '%s' ", compID.toUtf8().constData(), getName(&research));
}
}
@ -294,23 +258,23 @@ bool loadResearch(QString filename)
{
//read pair of components oldComponent:newComponent
QStringList pair = replacedComp[j].split(':');
ASSERT(pair.size() == 2, "Invalid item '%s' in list of replaced components of research '%s'. Required format: 'oldItem:newItem, item1:item2'", replacedComp[j].toUtf8().constData(), getResearchName(&research));
ASSERT(pair.size() == 2, "Invalid item '%s' in list of replaced components of research '%s'. Required format: 'oldItem:newItem, item1:item2'", replacedComp[j].toUtf8().constData(), getName(&research));
if (pair.size() != 2)
{
continue; //skip invalid entries
}
QString oldCompID = pair[0].trimmed();
QString newCompID = pair[1].trimmed();
COMPONENT_STATS *oldComp = (COMPONENT_STATS *)get_any_component_from_ID(oldCompID);
COMPONENT_STATS *oldComp = getCompStatsFromName(oldCompID);
if (oldComp == NULL)
{
ASSERT(false, "Invalid item '%s' in list of replaced components of research '%s'. Wrong component code.", oldCompID.toUtf8().constData(), getResearchName(&research));
ASSERT(false, "Invalid item '%s' in list of replaced components of research '%s'. Wrong component code.", oldCompID.toUtf8().constData(), getName(&research));
continue;
}
COMPONENT_STATS *newComp = (COMPONENT_STATS *)get_any_component_from_ID(newCompID);
COMPONENT_STATS *newComp = getCompStatsFromName(newCompID);
if(newComp == NULL)
{
ASSERT(false, "Invalid item '%s' in list of replaced components of research '%s'. Wrong component code.", newCompID.toUtf8().constData(), getResearchName(&research));
ASSERT(false, "Invalid item '%s' in list of replaced components of research '%s'. Wrong component code.", newCompID.toUtf8().constData(), getName(&research));
continue;
}
RES_COMP_REPLACEMENT replItem;
@ -324,13 +288,13 @@ bool loadResearch(QString filename)
for (int j = 0; j < redComp.size(); j++)
{
QString compID = redComp[j].trimmed();
BASE_STATS *pComp = get_any_component_from_ID(compID);
COMPONENT_STATS *pComp = getCompStatsFromName(compID);
if (pComp == NULL)
{
ASSERT(false, "Invalid item '%s' in list of redundant components of research '%s' ", compID.toUtf8().constData(), getResearchName(&research));
ASSERT(false, "Invalid item '%s' in list of redundant components of research '%s' ", compID.toUtf8().constData(), getName(&research));
}else
{
research.pRedArtefacts.push_back((COMPONENT_STATS*)pComp);
research.pRedArtefacts.push_back(pComp);
}
}
@ -340,7 +304,7 @@ bool loadResearch(QString filename)
{
QString strucID = resStruct[j].trimmed();
int structIndex = getStructStatFromName(strucID.toUtf8().data());
ASSERT(structIndex >= 0, "Invalid item '%s' in list of result structures of research '%s' ", strucID.toUtf8().constData(), getResearchName(&research));
ASSERT(structIndex >= 0, "Invalid item '%s' in list of result structures of research '%s' ", strucID.toUtf8().constData(), getName(&research));
if (structIndex >= 0)
{
research.pStructureResults.push_back(structIndex);
@ -353,7 +317,7 @@ bool loadResearch(QString filename)
{
QString strucID = reqStruct[j].trimmed();
int structIndex = getStructStatFromName(strucID.toUtf8().data());
ASSERT(structIndex >= 0, "Invalid item '%s' in list of required structures of research '%s' ", strucID.toUtf8().constData(), getResearchName(&research));
ASSERT(structIndex >= 0, "Invalid item '%s' in list of required structures of research '%s' ", strucID.toUtf8().constData(), getName(&research));
if(structIndex >= 0)
{
research.pStructList.push_back(structIndex);
@ -366,7 +330,7 @@ bool loadResearch(QString filename)
{
QString strucID = redStruct[j].trimmed();
int structIndex = getStructStatFromName(strucID.toUtf8().data());
ASSERT(structIndex >= 0, "Invalid item '%s' in list of redundant structures of research '%s' ", strucID.toUtf8().constData(), getResearchName(&research));
ASSERT(structIndex >= 0, "Invalid item '%s' in list of redundant structures of research '%s' ", strucID.toUtf8().constData(), getName(&research));
if (structIndex >= 0)
{
research.pRedStructs.push_back(structIndex);
@ -385,7 +349,7 @@ bool loadResearch(QString filename)
{
QString resID = preRes[j].trimmed();
RESEARCH *preResItem = getResearch(resID.toUtf8().constData());
ASSERT(preResItem != NULL, "Invalid item '%s' in list of pre-requisites of research '%s' ", resID.toUtf8().constData(), getResearchName(&asResearch[inc]));
ASSERT(preResItem != NULL, "Invalid item '%s' in list of pre-requisites of research '%s' ", resID.toUtf8().constData(), getName(&asResearch[inc]));
if (preResItem != NULL)
asResearch[inc].pPRList.push_back(preResItem->index);
}
@ -837,7 +801,7 @@ RESEARCH *getResearchForMsg(VIEWDATA *pViewData)
}
//set the iconID based on the name read in in the stats
static UWORD setIconID(char *pIconName, char *pName)
static UWORD setIconID(char *pIconName, const char *pName)
{
//compare the names with those created in 'Framer'
if (!strcmp(pIconName, "IMAGE_ROCKET"))
@ -1087,11 +1051,9 @@ SDWORD mapIconToRID(UDWORD iconID)
//return a pointer to a research topic based on the name
RESEARCH *getResearch(const char *pName)
{
unsigned int inc = 0;
for (inc = 0; inc < asResearch.size(); inc++)
for (int inc = 0; inc < asResearch.size(); inc++)
{
if (!strcasecmp(asResearch[inc].pName, pName))
if (asResearch[inc].id.compare(pName) == 0)
{
return &asResearch[inc];
}
@ -1168,18 +1130,11 @@ static void replaceComponent(COMPONENT_STATS *pNewComponent, COMPONENT_STATS *pO
a duplicate*/
static bool checkResearchName(RESEARCH *psResearch, UDWORD numStats)
{
UDWORD inc;
char *pName=psResearch->pName;
for (inc = 0; inc < numStats; inc++)
for (int inc = 0; inc < numStats; inc++)
{
if (!strcmp(asResearch[inc].pName, pName))
{
//oops! found the name
ASSERT( false, "Research name has already been used - %s", pName );
return false;
}
ASSERT_OR_RETURN(false, asResearch[inc].id.compare(psResearch->id) != 0,
"Research name has already been used - %s", getName(psResearch));
}
return true;
}
@ -1195,7 +1150,7 @@ bool enableResearch(RESEARCH *psResearch, UDWORD player)
inc = psResearch->index;
if (inc > asResearch.size())
{
ASSERT( false, "enableResearch: Invalid research topic - %s", getResearchName(psResearch) );
ASSERT( false, "enableResearch: Invalid research topic - %s", getName(psResearch) );
return false;
}
@ -1255,52 +1210,11 @@ void researchReward(UBYTE losingPlayer, UBYTE rewardPlayer)
//name the actual reward
CONPRINTF(ConsoleString,(ConsoleString,"%s :- %s",
_("Research Award"),
getName(asResearch[rewardID].pName)));
getName(&asResearch[rewardID])));
}
}
}
/*checks that the research has loaded up as expected - must be done after
all research parts have been loaded*/
bool checkResearchStats(void)
{
UDWORD resInc, inc;
for (resInc = 0; resInc < asResearch.size(); resInc++)
{
for (inc = 0; inc < asResearch[resInc].pPRList.size(); inc++)
{
ASSERT(asResearch[resInc].pPRList[inc] <= asResearch.size(), "Invalid PreReq for topic %s", asResearch[resInc].pName);
}
for (inc = 0; inc < asResearch[resInc].pStructList.size(); inc++)
{
ASSERT(asResearch[resInc].pStructList[inc] <= numStructureStats, "Invalid Structure for topic %s", asResearch[resInc].pName);
}
for (inc = 0; inc < asResearch[resInc].pRedStructs.size(); inc++)
{
ASSERT(asResearch[resInc].pRedStructs[inc] <= numStructureStats,
"Invalid Redundant Structure for topic %s", asResearch[resInc].pName);
}
for (inc = 0; inc < asResearch[resInc].pStructureResults.size(); inc++)
{
ASSERT(asResearch[resInc].pStructureResults[inc] <= numStructureStats,
"Invalid Result Structure for topic %s", asResearch[resInc].pName);
}
for (inc = 0; inc < asResearch[resInc].componentResults.size(); inc++)
{
ASSERT(asResearch[resInc].componentResults[inc] != NULL,
"Invalid Comp Result for topic %s", asResearch[resInc].pName);
}
for (inc = 0; inc < asResearch[resInc].pRedArtefacts.size(); inc++)
{
ASSERT(asResearch[resInc].pRedArtefacts[inc] != NULL,
"Invalid Redundant Comp for topic %s", asResearch[resInc].pName);
}
}
return true;
}
/*flag self repair so droids can start when idle*/
void enableSelfRepair(UBYTE player)
{

View File

@ -125,7 +125,6 @@ extern bool selfRepairEnabled(UBYTE player);
extern SDWORD mapRIDToIcon( UDWORD rid );
extern SDWORD mapIconToRID(UDWORD iconID);
extern bool checkResearchStats(void);
/*puts research facility on hold*/
extern void holdResearch(STRUCTURE *psBuilding, QUEUE_MODE mode);

View File

@ -66,7 +66,7 @@ struct RESEARCH : public BASE_STATS
iIMDShape *pIMD2; /* the 2nd IMD for base plates/turrets*/
int index; ///< Unique index for this research, set incrementally
RESEARCH() : pViewData(NULL), iconID(0), psStat(NULL), pIMD(NULL), pIMD2(NULL) { pName = NULL; }
RESEARCH() : pViewData(NULL), iconID(0), psStat(NULL), pIMD(NULL), pIMD2(NULL) {}
};
struct PLAYER_RESEARCH

View File

@ -611,7 +611,7 @@ bool scrOrderDroidStatsLoc(void)
// HACK: FIXME: Looks like a script error in the player*.slo files
// buildOnExactLocation() which references previously destroyed buildings from
// _stat = rebuildStructStat[_count] causes this.
if (strcmp(psStats->pName, "A0ADemolishStructure") == 0)
if (psStats->id.compare("A0ADemolishStructure") == 0)
{
// I don't feel like spamming a ASSERT here, we *know* it is a issue.
return true;
@ -1612,7 +1612,7 @@ bool scrSkDoResearch(void)
#if defined (DEBUG)
{
char sTemp[128];
sprintf(sTemp, "[debug]player:%d starts topic: %s", player, asResearch[i].pName);
sprintf(sTemp, "[debug]player:%d starts topic: %s", player, getName(&asResearch[i]));
NETlogEntry(sTemp, SYNC_FLAG, 0);
}
#endif

View File

@ -1017,7 +1017,7 @@ bool scrAddDroidToMissionList(void)
if (IsPlayerDroidLimitReached(player) && (psTemplate->droidType != DROID_TRANSPORTER && psTemplate->droidType != DROID_SUPERTRANSPORTER))
{
debug(LOG_SCRIPT, "Max units reached for player %d adding %s to mission list (type %d)",
player, psTemplate->aName, psTemplate->droidType);
player, getName(psTemplate), psTemplate->droidType);
psDroid = NULL;
}
else
@ -1488,7 +1488,7 @@ bool scrBuildDroid(void)
psFactory->pStructureType->type == REF_VTOL_FACTORY),
"Structure is not a factory");
ASSERT_OR_RETURN(false, validTemplateForFactory(psTemplate, psFactory, true), "Invalid template - %s for factory - %s",
psTemplate->aName, psFactory->pStructureType->pName);
getName(psTemplate), getID(psFactory->pStructureType));
if (productionRun != 1)
{
debug(LOG_WARNING, "A wzscript is trying to build a different number (%d) than 1 droid.", productionRun);
@ -1499,7 +1499,7 @@ bool scrBuildDroid(void)
}
else
{
debug(LOG_WARNING, "A wzscript tried to build a template (%s) that has not been researched yet", psTemplate->aName);
debug(LOG_WARNING, "A wzscript tried to build a template (%s) that has not been researched yet", getName(psTemplate));
}
return true;
}
@ -3922,7 +3922,7 @@ bool scrStructureBuiltInRange(void)
psStruct = (STRUCTURE *)psCurr;
if ((psStruct->status == SS_BUILT || player == -1)
&& (player == -1 || psStruct->player == player)
&& strcmp(psStruct->pStructureType->pName, psTarget->pName) == 0)
&& psStruct->pStructureType->id.compare(psTarget->id) == 0)
{
break;
}
@ -5241,7 +5241,7 @@ endstructloc:
}
else
{
debug(LOG_SCRIPT, "Did not find valid positioning for %s", psStat->pName);
debug(LOG_SCRIPT, "Did not find valid positioning for %s", getID(psStat));
}
scrFunctionResult.v.bval = found;
if (!stackPushResult(VAL_BOOL, &scrFunctionResult)) // success!
@ -6054,6 +6054,7 @@ bool scrIsVtol(void)
// In short, we want to design a ViperLtMGWheels, but it is already available to make, so we must delete it.
bool scrTutorialTemplates(void)
{
#if 0
DROID_TEMPLATE *psCurr, *psPrev;
// find ViperLtMGWheels
@ -6061,7 +6062,7 @@ bool scrTutorialTemplates(void)
for (psCurr = apsDroidTemplates[selectedPlayer], psPrev = NULL; psCurr != NULL; psCurr = psCurr->psNext)
{
if (strcmp(pName, psCurr->aName) == 0)
if (psCurr->name.compare(pName) == 0)
{
if (psPrev)
{
@ -6097,15 +6098,11 @@ bool scrTutorialTemplates(void)
abort();
return false;
}
#endif
return true;
}
//-----------------------------------------
//New functions
//-----------------------------------------
@ -7828,7 +7825,7 @@ bool scrNumStructsByStatInRange(void)
ydiff = (SDWORD)psCurr->pos.y - y;
if (xdiff *xdiff + ydiff *ydiff <= rangeSquared)
{
if (strcmp(psCurr->pStructureType->pName, psTarget->pName) == 0)
if (psCurr->pStructureType->id.compare(psTarget->id) == 0)
{
if (psCurr->visible[lookingPlayer]) //can we see it?
{
@ -9553,7 +9550,7 @@ bool scrPursueResearch(void)
#if defined (DEBUG)
{
char sTemp[128];
sprintf(sTemp, "player:%d starts topic: %s", player, asResearch[foundIndex].pName);
sprintf(sTemp, "player:%d starts topic: %s", player, getName(&asResearch[foundIndex]));
NETlogEntry(sTemp, SYNC_FLAG, 0);
}
#endif

View File

@ -593,70 +593,70 @@ bool scrGroupObjGet(UDWORD index)
// get the name from a stat pointer
static char *scrGetStatName(INTERP_TYPE type, UDWORD data)
static const QString scrGetStatName(INTERP_TYPE type, UDWORD data)
{
char *pName = NULL;
QString pName;
switch ((unsigned)type) // Unsigned cast to suppress compiler warnings due to enum abuse.
{
case ST_STRUCTURESTAT:
if (data < numStructureStats)
{
pName = asStructureStats[data].pName;
pName = asStructureStats[data].id;
}
break;
case ST_FEATURESTAT:
if (data < numFeatureStats)
{
pName = asFeatureStats[data].pName;
pName = asFeatureStats[data].id;
}
break;
case ST_BODY:
if (data < numBodyStats)
{
pName = asBodyStats[data].pName;
pName = asBodyStats[data].id;
}
break;
case ST_PROPULSION:
if (data < numPropulsionStats)
{
pName = asPropulsionStats[data].pName;
pName = asPropulsionStats[data].id;
}
break;
case ST_ECM:
if (data < numECMStats)
{
pName = asECMStats[data].pName;
pName = asECMStats[data].id;
}
break;
case ST_SENSOR:
if (data < numSensorStats)
{
pName = asSensorStats[data].pName;
pName = asSensorStats[data].id;
}
break;
case ST_CONSTRUCT:
if (data < numConstructStats)
{
pName = asConstructStats[data].pName;
pName = asConstructStats[data].id;
}
break;
case ST_WEAPON:
if (data < numWeaponStats)
{
pName = asWeaponStats[data].pName;
pName = asWeaponStats[data].id;
}
break;
case ST_REPAIR:
if (data < numRepairStats)
{
pName = asRepairStats[data].pName;
pName = asRepairStats[data].id;
}
break;
case ST_BRAIN:
if (data < numBrainStats)
{
pName = asBrainStats[data].pName;
pName = asBrainStats[data].id;
}
break;
case ST_BASESTATS:
@ -667,11 +667,7 @@ static char *scrGetStatName(INTERP_TYPE type, UDWORD data)
break;
}
if (pName == NULL)
{
debug( LOG_FATAL, "scrGetStatName: cannot get name for a base stat" );
abort();
}
ASSERT(!pName.isEmpty(), "cannot get name for a base stat");
return pName;
}
@ -681,7 +677,7 @@ static char *scrGetStatName(INTERP_TYPE type, UDWORD data)
bool scrValDefSave(INTERP_VAL *psVal, WzConfig &ini)
{
VIEWDATA *psIntMessage;
const char *pName;
QString pName;
RESEARCH *psResearch;
DROID *psCDroid;
@ -718,7 +714,7 @@ bool scrValDefSave(INTERP_VAL *psVal, WzConfig &ini)
case ST_REPAIR:
case ST_BRAIN:
pName = scrGetStatName(psVal->type, psVal->v.ival);
if (pName)
if (!pName.isEmpty())
{
ini.setValue("data", QString(pName));
}
@ -746,10 +742,10 @@ bool scrValDefSave(INTERP_VAL *psVal, WzConfig &ini)
break;
case ST_RESEARCH:
psResearch = (RESEARCH *)psVal->v.oval;
if (psResearch && psResearch->pName && psResearch->pName[0] != '\0')
if (psResearch && !psResearch->id.isEmpty())
{
ini.setValue("data", QString(psResearch->pName));
ASSERT(psResearch == getResearch(psResearch->pName), "Research %s not found!", psResearch->pName);
ini.setValue("data", psResearch->id);
ASSERT(psResearch == getResearch(getID(psResearch)), "Research %s not found!", getID(psResearch));
}
break;
case ST_GROUP:
@ -782,17 +778,13 @@ bool scrValDefSave(INTERP_VAL *psVal, WzConfig &ini)
// can also return NULL
pName = sound_GetTrackName((UDWORD)psVal->v.ival);
}
else
{
pName = NULL;
}
if (!pName)
if (pName.isEmpty())
{
debug(LOG_WARNING, "Could not get sound track name");
}
if (pName)
else
{
ini.setValue("data", QString(pName));
ini.setValue("data", pName);
}
break;
case ST_STRUCTUREID:

View File

@ -25,6 +25,7 @@
*/
#include <string.h>
#include <algorithm>
#include <QtCore/QHash>
#include "lib/framework/frame.h"
#include "lib/framework/strres.h"
@ -87,6 +88,8 @@ UBYTE *apCompLists[MAX_PLAYERS][COMP_NUMCOMPONENTS];
//store for each players Structure states
UBYTE *apStructTypeLists[MAX_PLAYERS];
QHash<QString, COMPONENT_STATS *> lookupStatPtr;
static bool getMovementModel(const char *movementModel, MOVEMENT_MODEL *model);
static void storeSpeedFactor(UDWORD terrainType, UDWORD propulsionType, UDWORD speedFactor);
@ -112,11 +115,6 @@ static void updateMaxECMStats(UWORD maxValue);
static void updateMaxBodyStats(UWORD maxBody, UWORD maxPower, UWORD maxArmour);
static void updateMaxConstStats(UWORD maxValue);
BASE_STATS::BASE_STATS(unsigned ref, std::string const &str)
: ref(ref)
, pName(allocateName(str.c_str()))
{}
static inline bool stringToEnumFindFunction(std::pair<char const *, unsigned> const &a, char const *b)
{
return strcmp(a.first, b) < 0;
@ -145,16 +143,15 @@ static void deallocTerrainTable(void)
/* Macro to allocate memory for a set of stats */
#define ALLOC_STATS(numEntries, list, listSize, type) \
ASSERT( (numEntries) < REF_RANGE, \
"allocStats: number of stats entries too large for " #type );\
if ((list)) free((list)); \
(list) = (type *)malloc(sizeof(type) * (numEntries)); \
ASSERT((numEntries) < REF_RANGE, "Number of stats entries too large for " #type);\
if ((list)) delete [] (list); \
(list) = new type[numEntries]; \
(listSize) = (numEntries); \
return true
/*Macro to Deallocate stats*/
#define STATS_DEALLOC(list, listSize) \
free((COMPONENT_STATS*)(list)); \
delete [] (list); \
listSize = 0; \
(list) = NULL
@ -177,23 +174,17 @@ void statsInitVars(void)
maxPropulsionSpeed = 0;
}
static void allocateStatName(BASE_STATS *pStat, const char *Name)
{
pStat->pName = allocateName(Name);
}
/* body stats need the extra list removing */
static void deallocBodyStats(void)
{
BODY_STATS *psStat;
UDWORD inc;
for (inc = 0; inc < numBodyStats; inc++)
for (int inc = 0; inc < numBodyStats; inc++)
{
psStat = &asBodyStats[inc];
free(psStat->ppIMDList);
}
free(asBodyStats);
delete [] asBodyStats;
asBodyStats = NULL;
numBodyStats = 0;
}
@ -201,72 +192,21 @@ static void deallocBodyStats(void)
/*Deallocate all the stats assigned from input data*/
bool statsShutDown(void)
{
lookupStatPtr.clear();
STATS_DEALLOC(asWeaponStats, numWeaponStats);
deallocBodyStats();
STATS_DEALLOC(asBrainStats, numBrainStats);
STATS_DEALLOC(asPropulsionStats, numPropulsionStats);
STATS_DEALLOC(asRepairStats, numRepairStats);
STATS_DEALLOC(asConstructStats, numConstructStats);
STATS_DEALLOC(asECMStats, numECMStats);
deallocPropulsionTypes();
deallocTerrainTable();
return true;
}
/* Macro to set the stats for a particular ref
* The macro uses the ref number in the stats structure to
* index the correct array entry
*/
#define SET_STATS(stats, list, index, type, refStart) \
ASSERT( ((stats)->ref >= (refStart)) && ((stats)->ref < (refStart) + REF_RANGE), \
"setStats: Invalid " #type " ref number" ); \
memcpy((list) + (index), (stats), sizeof(type))
/*******************************************************************************
* Set stats functions
*******************************************************************************/
/* Set the stats for a particular weapon type */
static void statsSetWeapon(WEAPON_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asWeaponStats, index, WEAPON_STATS, REF_WEAPON_START);
}
/* Set the stats for a particular body type */
static void statsSetBody(BODY_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asBodyStats, index, BODY_STATS, REF_BODY_START);
}
/* Set the stats for a particular brain type */
static void statsSetBrain(BRAIN_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asBrainStats, index, BRAIN_STATS, REF_BRAIN_START);
}
/* Set the stats for a particular power type */
static void statsSetPropulsion(PROPULSION_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asPropulsionStats, index, PROPULSION_STATS,
REF_PROPULSION_START);
}
/* Set the stats for a particular sensor type */
static void statsSetSensor(SENSOR_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asSensorStats, index, SENSOR_STATS, REF_SENSOR_START);
}
/* Set the stats for a particular ecm type */
static void statsSetECM(ECM_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asECMStats, index, ECM_STATS, REF_ECM_START);
}
/* Set the stats for a particular repair type */
static void statsSetRepair(REPAIR_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asRepairStats, index, REPAIR_STATS, REF_REPAIR_START);
}
/* Set the stats for a particular construct type */
static void statsSetConstruct(CONSTRUCT_STATS *psStats, UDWORD index)
{
SET_STATS(psStats, asConstructStats, index, CONSTRUCT_STATS, REF_CONSTRUCT_START);
}
/* Return the number of newlines in a file buffer */
UDWORD numCR(const char *pFileBuffer, UDWORD fileSize)
{
@ -330,16 +270,6 @@ bool statsAllocConstruct(UDWORD numStats)
ALLOC_STATS(numStats, asConstructStats, numConstructStats, CONSTRUCT_STATS);
}
const char *getStatName(const void *Stat)
{
const BASE_STATS *const psStats = (const BASE_STATS *)Stat;
ASSERT(psStats->pName, "No pName for stats!");
return getName(psStats->pName);
}
/*******************************************************************************
* Load stats functions
*******************************************************************************/
@ -357,33 +287,37 @@ static iIMDShape *statsGetIMD(WzConfig &ini, BASE_STATS *psStats, QString key)
return retval;
}
void loadCompStats(WzConfig &ini, COMPONENT_STATS *psStats, int index)
{
psStats->name = ini.value("name").toString();
psStats->id = ini.group();
psStats->buildPower = ini.value("buildPower", 0).toUInt();
psStats->buildPoints = ini.value("buildPoints", 0).toUInt();
psStats->index = index;
ASSERT(!lookupStatPtr.contains(psStats->id), "Duplicate ID found! (%s)", getID(psStats));
lookupStatPtr.insert(psStats->id, psStats);
}
/*Load the weapon stats from the file exported from Access*/
bool loadWeaponStats(const char *pFileName)
{
WEAPON_STATS sStats, * const psStats = &sStats;
UDWORD i, surfaceToAir;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
if (!statsAllocWeapons(list.size()))
{
return false;
}
statsAllocWeapons(list.size());
// Hack to make sure ZNULLWEAPON is always first in list
int nullweapon = list.indexOf("ZNULLWEAPON");
ASSERT_OR_RETURN(false, nullweapon >= 0, "ZNULLWEAPON is mandatory");
if (nullweapon > 0)
{
list.swap(nullweapon, 0);
}
list.swap(nullweapon, 0);
for (i = 0; i < list.size(); ++i)
{
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(WEAPON_STATS));
WEAPON_STATS *psStats = &asWeaponStats[i];
ini.beginGroup(list[i]);
loadCompStats(ini, psStats, i);
psStats->compType = COMP_WEAPON;
psStats->buildPower = ini.value("buildPower", 0).toUInt();
psStats->buildPoints = ini.value("buildPoints", 0).toUInt();
psStats->weight = ini.value("weight", 0).toUInt();
psStats->body = ini.value("body", 0).toUInt();
psStats->radiusLife = ini.value("radiusLife", 0).toUInt();
@ -429,7 +363,6 @@ bool loadWeaponStats(const char *pFileName)
ASSERT(psStats->flightSpeed > 0, "Invalid flight speed for %s", list[i].toUtf8().constData());
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
psStats->ref = REF_WEAPON_START + i;
//get the IMD for the component
@ -558,9 +491,6 @@ bool loadWeaponStats(const char *pFileName)
psStats->iAudioFireID = NO_SOUND;
psStats->iAudioImpactID = NO_SOUND;
//save the stats
statsSetWeapon(psStats, i);
// Set the max stat values for the design screen
if (psStats->designable)
{
@ -579,24 +509,22 @@ bool loadWeaponStats(const char *pFileName)
/*Load the Body stats from the file exported from Access*/
bool loadBodyStats(const char *pFileName)
{
BODY_STATS sStats, * const psStats = &sStats;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
statsAllocBody(list.size());
// Hack to make sure ZNULLBODY is always first in list
int nullbody = list.indexOf("ZNULLBODY");
ASSERT_OR_RETURN(false, nullbody >= 0, "ZNULLBODY is mandatory");
if (nullbody > 0)
{
list.swap(nullbody, 0);
}
list.swap(nullbody, 0);
for (int i = 0; i < list.size(); ++i)
{
BODY_STATS *psStats = &asBodyStats[i];
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(*psStats));
loadCompStats(ini, psStats, i);
psStats->compType = COMP_BODY;
psStats->weight = ini.value("weight", 0).toInt();
psStats->buildPower = ini.value("buildPower", 0).toInt();
psStats->buildPoints = ini.value("buildPoints", 0).toInt();
psStats->body = ini.value("hitpoints").toInt();
psStats->weaponSlots = ini.value("weaponSlots").toInt();
psStats->designable = ini.value("designable", false).toBool();
@ -647,9 +575,6 @@ bool loadBodyStats(const char *pFileName)
ini.endGroup();
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
statsSetBody(psStats, i); // save the stats
//set the max stat values for the design screen
if (psStats->designable)
{
@ -666,42 +591,36 @@ bool loadBodyStats(const char *pFileName)
/*Load the Brain stats from the file exported from Access*/
bool loadBrainStats(const char *pFileName)
{
BRAIN_STATS sStats, * const psStats = &sStats;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
statsAllocBrain(list.size());
// Hack to make sure ZNULLBRAIN is always first in list
int nullbrain = list.indexOf("ZNULLBRAIN");
ASSERT_OR_RETURN(false, nullbrain >= 0, "ZNULLBRAIN is mandatory");
if (nullbrain > 0)
{
list.swap(nullbrain, 0);
}
list.swap(nullbrain, 0);
for (int i = 0; i < list.size(); ++i)
{
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(BRAIN_STATS));
BRAIN_STATS *psStats = &asBrainStats[i];
ini.beginGroup(list[i]);
loadCompStats(ini, psStats, i);
psStats->compType = COMP_BRAIN;
psStats->buildPower = ini.value("buildPower", 0).toInt();
psStats->buildPoints = ini.value("buildPoints", 0).toInt();
psStats->weight = ini.value("weight", 0).toInt();
psStats->maxDroids = ini.value("maxDroids").toInt();
psStats->maxDroidsMult = ini.value("maxDroidsMult").toInt();
psStats->ref = REF_BRAIN_START + i;
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
// check weapon attached
psStats->psWeaponStat = NULL;
if (ini.contains("turret"))
{
int weapon = getCompFromName(COMP_WEAPON, ini.value("turret").toString().toUtf8().constData());
ASSERT_OR_RETURN(false, weapon >= 0, "Unable to find weapon for brain %s", psStats->pName);
int weapon = getCompFromName(COMP_WEAPON, ini.value("turret").toString());
ASSERT_OR_RETURN(false, weapon >= 0, "Unable to find weapon for brain %s", getStatName(psStats));
psStats->psWeaponStat = asWeaponStats + weapon;
}
psStats->designable = ini.value("designable", false).toBool();
ini.endGroup();
// save the stats
statsSetBrain(psStats, i);
}
return true;
}
@ -758,23 +677,21 @@ bool getPropulsionType(const char *typeName, PROPULSION_TYPE *type)
/*Load the Propulsion stats from the file exported from Access*/
bool loadPropulsionStats(const char *pFileName)
{
PROPULSION_STATS sStats, *const psStats = &sStats;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
statsAllocPropulsion(list.size());
// Hack to make sure ZNULLPROP is always first in list
int nullprop = list.indexOf("ZNULLPROP");
ASSERT_OR_RETURN(false, nullprop >= 0, "ZNULLPROP is mandatory");
if (nullprop > 0)
{
list.swap(nullprop, 0);
}
list.swap(nullprop, 0);
for (int i = 0; i < list.size(); ++i)
{
PROPULSION_STATS *psStats = &asPropulsionStats[i];
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(*psStats));
psStats->buildPower = ini.value("buildPower").toInt();
psStats->buildPoints = ini.value("buildPoints").toInt();
loadCompStats(ini, psStats, i);
psStats->compType = COMP_PROPULSION;
psStats->weight = ini.value("weight").toInt();
psStats->body = ini.value("hitpoints").toInt();
psStats->maxSpeed = ini.value("speed").toInt();
@ -795,10 +712,6 @@ bool loadPropulsionStats(const char *pFileName)
}
ini.endGroup();
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
// save the stats
statsSetPropulsion(psStats, i);
// set the max stat values for the design screen
if (psStats->designable)
{
@ -834,27 +747,21 @@ bool loadPropulsionStats(const char *pFileName)
/*Load the Sensor stats from the file exported from Access*/
bool loadSensorStats(const char *pFileName)
{
SENSOR_STATS sStats, * const psStats = &sStats;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
if (!statsAllocSensor(list.size()))
{
return false;
}
statsAllocSensor(list.size());
// Hack to make sure ZNULLSENSOR is always first in list
int nullsensor = list.indexOf("ZNULLSENSOR");
ASSERT_OR_RETURN(false, nullsensor >= 0, "ZNULLSENSOR is mandatory");
if (nullsensor > 0)
{
list.swap(nullsensor, 0);
}
list.swap(nullsensor, 0);
for (int i = 0; i < list.size(); ++i)
{
SENSOR_STATS *psStats = &asSensorStats[i];
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(SENSOR_STATS));
psStats->buildPower = ini.value("buildPower", 0).toInt();
psStats->buildPoints = ini.value("buildPoints", 0).toInt();
loadCompStats(ini, psStats, i);
psStats->compType = COMP_SENSOR;
psStats->weight = ini.value("weight", 0).toInt();
psStats->body = ini.value("bodyPoints", 0).toInt();
psStats->base.range = ini.value("range").toInt();
@ -865,7 +772,6 @@ bool loadSensorStats(const char *pFileName)
psStats->time = ini.value("time").toInt();
psStats->designable = ini.value("designable", false).toBool();
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
psStats->ref = REF_SENSOR_START + i;
QString location = ini.value("location").toString();
@ -918,8 +824,6 @@ bool loadSensorStats(const char *pFileName)
psStats->pMountGraphic = statsGetIMD(ini, psStats, "mountModel");
ini.endGroup();
//save the stats
statsSetSensor(psStats, i);
// set the max stat values for the design screen
if (psStats->designable)
@ -935,27 +839,21 @@ bool loadSensorStats(const char *pFileName)
/*Load the ECM stats from the file exported from Access*/
bool loadECMStats(const char *pFileName)
{
ECM_STATS sStats, * const psStats = &sStats;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
if (!statsAllocECM(list.size()))
{
return false;
}
statsAllocECM(list.size());
// Hack to make sure ZNULLECM is always first in list
int nullecm = list.indexOf("ZNULLECM");
ASSERT_OR_RETURN(false, nullecm >= 0, "ZNULLECM is mandatory");
if (nullecm > 0)
{
list.swap(nullecm, 0);
}
list.swap(nullecm, 0);
for (int i = 0; i < list.size(); ++i)
{
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(ECM_STATS));
ECM_STATS *psStats = &asECMStats[i];
ini.beginGroup(list[i]);
loadCompStats(ini, psStats, i);
psStats->compType = COMP_ECM;
psStats->buildPower = ini.value("buildPower", 0).toInt();
psStats->buildPoints = ini.value("buildPoints", 0).toInt();
psStats->weight = ini.value("weight", 0).toInt();
psStats->body = ini.value("body", 0).toInt();
psStats->base.range = ini.value("range").toInt();
@ -965,7 +863,6 @@ bool loadECMStats(const char *pFileName)
}
psStats->designable = ini.value("designable", false).toBool();
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
psStats->ref = REF_ECM_START + i;
QString location = ini.value("location").toString();
@ -987,8 +884,6 @@ bool loadECMStats(const char *pFileName)
psStats->pMountGraphic = statsGetIMD(ini, psStats, "mountModel");
ini.endGroup();
//save the stats
statsSetECM(psStats, i);
// Set the max stat values for the design screen
if (psStats->designable)
@ -1003,28 +898,21 @@ bool loadECMStats(const char *pFileName)
/*Load the Repair stats from the file exported from Access*/
bool loadRepairStats(const char *pFileName)
{
REPAIR_STATS sStats, * const psStats = &sStats;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
if (!statsAllocRepair(list.size()))
{
return false;
}
statsAllocRepair(list.size());
// Hack to make sure ZNULLREPAIR is always first in list
int nullrepair = list.indexOf("ZNULLREPAIR");
ASSERT_OR_RETURN(false, nullrepair >= 0, "ZNULLREPAIR is mandatory");
if (nullrepair > 0)
{
list.swap(nullrepair, 0);
}
list.swap(nullrepair, 0);
for (int i = 0; i < list.size(); ++i)
{
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(REPAIR_STATS));
REPAIR_STATS *psStats = &asRepairStats[i];
ini.beginGroup(list[i]);
loadCompStats(ini, psStats, i);
psStats->compType = COMP_REPAIRUNIT;
psStats->buildPower = ini.value("buildPower", 0).toInt();
psStats->buildPoints = ini.value("buildPoints", 0).toInt();
psStats->weight = ini.value("weight", 0).toInt();
psStats->base.repairPoints = ini.value("repairPoints").toInt();
for (int j = 0; j < MAX_PLAYERS; j++)
@ -1034,7 +922,6 @@ bool loadRepairStats(const char *pFileName)
psStats->time = ini.value("time", 0).toInt() * WEAPON_TIME;
psStats->designable = ini.value("designable", false).toBool();
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
psStats->ref = REF_REPAIR_START + i;
QString location = ini.value("location").toString();
@ -1059,8 +946,6 @@ bool loadRepairStats(const char *pFileName)
psStats->pMountGraphic = statsGetIMD(ini, psStats, "mountModel");
ini.endGroup();
//save the stats
statsSetRepair(psStats, i);
//set the max stat values for the design screen
if (psStats->designable)
@ -1068,7 +953,6 @@ bool loadRepairStats(const char *pFileName)
setMaxRepairPoints(psStats->base.repairPoints);
setMaxComponentWeight(psStats->weight);
}
}
return true;
}
@ -1076,27 +960,21 @@ bool loadRepairStats(const char *pFileName)
/*Load the Construct stats from the file exported from Access*/
bool loadConstructStats(const char *pFileName)
{
CONSTRUCT_STATS sStats, * const psStats = &sStats;
WzConfig ini(pFileName, WzConfig::ReadOnlyAndRequired);
QStringList list = ini.childGroups();
if (!statsAllocConstruct(list.size()))
{
return false;
}
statsAllocConstruct(list.size());
// Hack to make sure ZNULLCONSTRUCT is always first in list
int nullconstruct = list.indexOf("ZNULLCONSTRUCT");
ASSERT_OR_RETURN(false, nullconstruct >= 0, "ZNULLCONSTRUCT is mandatory");
if (nullconstruct > 0)
{
list.swap(nullconstruct, 0);
}
list.swap(nullconstruct, 0);
for (int i = 0; i < list.size(); ++i)
{
ini.beginGroup(list[i]);
memset(psStats, 0, sizeof(CONSTRUCT_STATS));
CONSTRUCT_STATS *psStats = &asConstructStats[i];
ini.beginGroup(list[i]);
loadCompStats(ini, psStats, i);
psStats->compType = COMP_CONSTRUCT;
psStats->buildPower = ini.value("buildPower", 0).toInt();
psStats->buildPoints = ini.value("buildPoints", 0).toInt();
psStats->weight = ini.value("weight", 0).toInt();
psStats->body = ini.value("bodyPoints", 0).toInt();
psStats->base.constructPoints = ini.value("constructPoints").toInt();
@ -1105,8 +983,6 @@ bool loadConstructStats(const char *pFileName)
psStats->upgrade[j].constructPoints = psStats->base.constructPoints;
}
psStats->designable = ini.value("designable", false).toBool();
allocateStatName((BASE_STATS *)psStats, list[i].toUtf8().constData());
psStats->ref = REF_CONSTRUCT_START + i;
//get the IMD for the component
@ -1114,8 +990,6 @@ bool loadConstructStats(const char *pFileName)
psStats->pMountGraphic = statsGetIMD(ini, psStats, "mountModel");
ini.endGroup();
//save the stats
statsSetConstruct(psStats, i);
// Set the max stat values for the design screen
if (psStats->designable)
@ -1278,7 +1152,7 @@ bool loadBodyPropulsionIMDs(const char *pFileName)
for (numStats = 0; numStats < numBodyStats; ++numStats)
{
psBodyStat = &asBodyStats[numStats];
if (list[i].compare(psBodyStat->pName) == 0)
if (list[i].compare(psBodyStat->id) == 0)
{
break;
}
@ -1294,7 +1168,7 @@ bool loadBodyPropulsionIMDs(const char *pFileName)
for (numStats = 0; numStats < numPropulsionStats; numStats++)
{
PROPULSION_STATS *psPropulsionStat = &asPropulsionStats[numStats];
if (keys[j].compare(psPropulsionStat->pName) == 0)
if (keys[j].compare(psPropulsionStat->id) == 0)
{
break;
}
@ -1393,7 +1267,7 @@ bool loadWeaponSounds(const char *pFileName)
}
for (inc = 0; inc < (SDWORD)numWeaponStats; ++inc)
{
if (list[i].compare(asWeaponStats[inc].pName) == 0)
if (list[i].compare(asWeaponStats[inc].id) == 0)
{
asWeaponStats[inc].iAudioFireID = weaponSoundID;
asWeaponStats[inc].iAudioImpactID = explosionSoundID;
@ -1692,97 +1566,23 @@ unsigned int componentType(const char *pType)
//used in Scripts
SDWORD getCompFromResName(UDWORD compType, const char *pName)
{
return getCompFromName(compType, pName);
return getCompFromName((COMPONENT_TYPE)compType, pName);
}
void getStatsDetails(UDWORD compType, BASE_STATS **ppsStats, UDWORD *pnumStats, UDWORD *pstatSize)
/// Get the component index for a stat based on the name, and verify correct type
int getCompFromName(COMPONENT_TYPE compType, const QString &name)
{
switch (compType)
{
case COMP_BODY:
*ppsStats = (BASE_STATS *)asBodyStats;
*pnumStats = numBodyStats;
*pstatSize = sizeof(BODY_STATS);
break;
case COMP_BRAIN:
*ppsStats = (BASE_STATS *)asBrainStats;
*pnumStats = numBrainStats;
*pstatSize = sizeof(BRAIN_STATS);
break;
case COMP_PROPULSION:
*ppsStats = (BASE_STATS *)asPropulsionStats;
*pnumStats = numPropulsionStats;
*pstatSize = sizeof(PROPULSION_STATS);
break;
case COMP_REPAIRUNIT:
*ppsStats = (BASE_STATS *)asRepairStats;
*pnumStats = numRepairStats;
*pstatSize = sizeof(REPAIR_STATS);
break;
case COMP_ECM:
*ppsStats = (BASE_STATS *)asECMStats;
*pnumStats = numECMStats;
*pstatSize = sizeof(ECM_STATS);
break;
case COMP_SENSOR:
*ppsStats = (BASE_STATS *)asSensorStats;
*pnumStats = numSensorStats;
*pstatSize = sizeof(SENSOR_STATS);
break;
case COMP_CONSTRUCT:
*ppsStats = (BASE_STATS *)asConstructStats;
*pnumStats = numConstructStats;
*pstatSize = sizeof(CONSTRUCT_STATS);
break;
case COMP_WEAPON:
*ppsStats = (BASE_STATS *)asWeaponStats;
*pnumStats = numWeaponStats;
*pstatSize = sizeof(WEAPON_STATS);
break;
default:
debug(LOG_FATAL, "Invalid component type");
}
COMPONENT_STATS *psComp = lookupStatPtr.value(name, NULL);
ASSERT_OR_RETURN(-1, psComp, "No such component [%s] found", name.toUtf8().constData());
ASSERT_OR_RETURN(-1, compType == psComp->compType, "Wrong component type for %s", name.toUtf8().constData());
return psComp->index;
}
//get the component Inc for a stat based on the name and type
//returns -1 if record not found
SDWORD getCompFromName(UDWORD compType, const char *pName)
/// Get the component for a stat based on the name alone.
/// Returns NULL if record not found
COMPONENT_STATS *getCompStatsFromName(const QString &name)
{
BASE_STATS *psStats = NULL;
UDWORD numStats = 0, count, statSize = 0;
getStatsDetails(compType, &psStats, &numStats, &statSize);
//find the stat with the same name
for (count = 0; count < numStats; count++)
{
if (!strcmp(pName, psStats->pName))
{
return count;
}
psStats = (BASE_STATS *)((char *)psStats + statSize);
}
//return -1 if record not found or an invalid component type is passed in
return -1;
}
/*return the name to display for the interface - valid for OBJECTS and STATS*/
const char *getName(const char *pNameID)
{
/* See if the name has a string resource associated with it by trying
* to get the string resource.
*/
const char *const name = strresGetString(psStringRes, pNameID);
if (!name)
{
debug(LOG_ERROR, "Unable to find string resource for %s", pNameID);
return "Name Unknown";
}
return name;
return lookupStatPtr.value(name, NULL);
}
/*sets the store to the body size based on the name passed in - returns false
@ -2016,25 +1816,6 @@ bool getWeaponClass(QString weaponClassStr, WEAPON_CLASS *weaponClass)
return true;
}
/*
looks up the name to get the resource associated with it - or allocates space
and stores the name. Eventually ALL names will be 'resourced' for translation
*/
char *allocateName(const char *name)
{
/* Check whether the given string has a string resource associated with
* it.
*/
if (!strresGetString(psStringRes, name))
{
ASSERT(false, "Unable to find string resource for %s", name);
return NULL;
}
return strdup(name);
}
/*Access functions for the upgradeable stats of a weapon*/
int weaponFirePause(const WEAPON_STATS *psStats, int player)
{

View File

@ -182,7 +182,8 @@ extern UDWORD statRefStart(UDWORD stat);
/*Returns the component type based on the string - used for reading in data */
extern UDWORD componentType(const char* pType);
//get the component Inc for a stat based on the name
extern SDWORD getCompFromName(UDWORD compType, const char *pName);
int getCompFromName(COMPONENT_TYPE compType, const QString &name);
COMPONENT_STATS *getCompStatsFromName(const QString &name);
//get details for given component type
extern void getStatsDetails(UDWORD compType, BASE_STATS **ppsStats, UDWORD *pnumStats, UDWORD *pstatSize);
//get the component Inc for a stat based on the Resource name held in Names.txt
@ -190,17 +191,10 @@ extern SDWORD getCompFromResName(UDWORD compType, const char *pName);
/*returns the weapon sub class based on the string name passed in */
extern bool getWeaponSubClass(const char* subClass, WEAPON_SUBCLASS* wclass);
const char *getWeaponSubClass(WEAPON_SUBCLASS wclass);
/*either gets the name associated with the resource (if one) or allocates space and copies pName*/
extern char* allocateName(const char* name);
/*return the name to display for the interface - valid for OBJECTS and STATS*/
extern const char* getName(const char *pNameID);
/*sets the store to the body size based on the name passed in - returns false
if doesn't compare with any*/
extern bool getBodySize(const char *pSize, BODY_SIZE *pStore);
// Pass in a stat and get its name
extern const char* getStatName(const void * pStat);
/**
* Determines the propulsion type indicated by the @c typeName string passed
* in.

View File

@ -52,32 +52,6 @@ enum DROID_TYPE
};
static inline bool stringToEnumSortFunction(std::pair<char const *, unsigned> const &a, std::pair<char const *, unsigned> const &b) { return strcmp(a.first, b.first) < 0; }
template <typename STATS>
static inline STATS *findStatsByName(std::string const &name, STATS *asStats, unsigned numStats)
{
for (unsigned inc = 0; inc < numStats; ++inc) // Could be more efficient, if the stats were sorted by name...
{
//compare the names
if (name == asStats[inc].pName)
{
return &asStats[inc];
}
}
return NULL; // Not found.
}
template <typename STATS>
static inline STATS *findStatsByName(std::string const &name, STATS **asStats, unsigned numStats)
{
for (unsigned inc = 0; inc < numStats; ++inc) // Could be more efficient, if the stats were sorted by name...
{
//compare the names
if (name == asStats[inc]->pName)
{
return asStats[inc];
}
}
return NULL; // Not found.
}
template <typename Enum>
struct StringToEnum
@ -264,29 +238,38 @@ enum TRAVEL_MEDIUM
/* Stats common to all stats structs */
struct BASE_STATS
{
BASE_STATS(unsigned ref = 0) : ref(ref), pName(NULL) {} ///< Only initialised here when using new/delete! TODO Use new/delete only, not malloc()/free().
BASE_STATS(unsigned ref, std::string const &str); ///< Only initialised here when using new/delete! TODO Use new/delete only, not malloc()/free(). TODO Then pName could be a QString...
//Gah, too soon to add destructors to BASE_STATS, thanks to local temporaries that are copied with memcpy()... --- virtual ~BASE_STATS() { free(pName); } ///< pName is only freed here when using new/delete! TODO Use new/delete only, not malloc()/free().
//So this one isn't needed for now, maybe not ever. --- BASE_STATS(BASE_STATS const &stats) : ref(stats.ref), pName(strdup(stats.pName)) {} // TODO Not needed when pName is a QString...
//So this one isn't needed for now, maybe not ever. --- BASE_STATS const &operator =(BASE_STATS const &stats) { ref = stats.ref; free(pName); pName = strdup(stats.pName); return *this; } // TODO Not needed when pName is a QString...
BASE_STATS(unsigned ref = 0) : ref(ref) {}
UDWORD ref; /**< Unique ID of the item */
char *pName; /**< pointer to the text id name (i.e. short language-independant name) */
UDWORD ref; /**< Unique ID of the item */
QString id; /**< Text id (i.e. short language-independant name) */
QString name; /**< Full / real name of the item */
};
#define getName(_psStats) (_psStats)->name.toUtf8().constData()
#define getStatName(_psStats) (_psStats)->name.toUtf8().constData()
#define getID(_psStats) (_psStats)->id.toUtf8().constData()
/* Stats common to all droid components */
struct COMPONENT_STATS : public BASE_STATS
{
COMPONENT_STATS() : buildPower(0), buildPoints(0), weight(0), body(0), designable(false), pIMD(NULL),
compType(COMP_NUMCOMPONENTS), index(0) {}
UDWORD buildPower; /**< Power required to build the component */
UDWORD buildPoints; /**< Time required to build the component */
UDWORD weight; /**< Component's weight */
UDWORD body; /**< Component's body points */
bool designable; /**< flag to indicate whether this component can be used in the design screen */
iIMDShape *pIMD; /**< The IMD to draw for this component */
COMPONENT_TYPE compType;
int index; ///< Index into containing array
};
struct PROPULSION_STATS : public COMPONENT_STATS
{
PROPULSION_STATS() : maxSpeed(0), propulsionType(PROPULSION_TYPE_NUM), turnSpeed(0), spinSpeed(0),
spinAngle(0), skidDeceleration(0), deceleration(0), acceleration(0) {}
UDWORD maxSpeed; ///< Max speed for the droid
PROPULSION_TYPE propulsionType; ///< Type of propulsion used - index into PropulsionTable
UDWORD turnSpeed;
@ -299,6 +282,12 @@ struct PROPULSION_STATS : public COMPONENT_STATS
struct SENSOR_STATS : public COMPONENT_STATS
{
SENSOR_STATS() : location(0), type(STANDARD_SENSOR), time(0), pMountGraphic(NULL)
{
memset(&upgrade, 0, sizeof(upgrade));
memset(&base, 0, sizeof(base));
}
UDWORD location; ///< specifies whether the Sensor is default or for the Turret
SENSOR_TYPE type; ///< used for combat
UDWORD time; ///< time delay before associated weapon droids 'know' where the attack is from
@ -312,6 +301,12 @@ struct SENSOR_STATS : public COMPONENT_STATS
struct ECM_STATS : public COMPONENT_STATS
{
ECM_STATS() : location(0), pMountGraphic(NULL)
{
memset(&upgrade, 0, sizeof(upgrade));
memset(&base, 0, sizeof(base));
}
UDWORD location; ///< specifies whether the ECM is default or for the Turret
iIMDShape *pMountGraphic; ///< The turret mount to use
@ -323,6 +318,12 @@ struct ECM_STATS : public COMPONENT_STATS
struct REPAIR_STATS : public COMPONENT_STATS
{
REPAIR_STATS() : location(0), time(0), pMountGraphic(NULL)
{
memset(&upgrade, 0, sizeof(upgrade));
memset(&base, 0, sizeof(base));
}
UDWORD location; ///< specifies whether the Repair is default or for the Turret
UDWORD time; ///< time delay for repair cycle
iIMDShape *pMountGraphic; ///< The turret mount to use
@ -335,6 +336,14 @@ struct REPAIR_STATS : public COMPONENT_STATS
struct WEAPON_STATS : public COMPONENT_STATS
{
WEAPON_STATS() : pMountGraphic(NULL), pMuzzleGraphic(NULL), pInFlightGraphic(NULL), pTargetHitGraphic(NULL),
pTargetMissGraphic(NULL), pWaterHitGraphic(NULL), pTrailGraphic(NULL), iAudioFireID(0),
iAudioImpactID(0)
{
memset(&upgrade, 0, sizeof(upgrade));
memset(&base, 0, sizeof(base));
}
struct
{
short maxRange;
@ -395,6 +404,12 @@ struct WEAPON_STATS : public COMPONENT_STATS
struct CONSTRUCT_STATS : public COMPONENT_STATS
{
CONSTRUCT_STATS() : pMountGraphic(NULL)
{
memset(&upgrade, 0, sizeof(upgrade));
memset(&base, 0, sizeof(base));
}
iIMDShape *pMountGraphic; ///< The turret mount to use
struct
@ -405,21 +420,28 @@ struct CONSTRUCT_STATS : public COMPONENT_STATS
struct BRAIN_STATS : public COMPONENT_STATS
{
BRAIN_STATS() : psWeaponStat(NULL), maxDroids(0), maxDroidsMult(0) {}
WEAPON_STATS *psWeaponStat; ///< weapon stats associated with this brain - for Command Droids
UDWORD maxDroids; ///< base maximum number of droids that the commander can control
UDWORD maxDroidsMult; ///< maximum number of controlled droids multiplied by level
};
/*
* Stats structures type definitions
*/
#define SHOOT_ON_GROUND 0x01
#define SHOOT_IN_AIR 0x02
struct BODY_STATS : public COMPONENT_STATS
{
BODY_STATS() : size(SIZE_NUM), weaponSlots(0), droidTypeOverride(DROID_ANY), ppIMDList(NULL), pFlameIMD(NULL)
{
memset(bodyClass, 0, sizeof(bodyClass));
memset(&upgrade, 0, sizeof(upgrade));
memset(&base, 0, sizeof(base));
}
BODY_SIZE size; ///< How big the body is - affects how hit
UDWORD weaponSlots; ///< The number of weapon slots on the body
DROID_TYPE droidTypeOverride; // if not DROID_ANY, sets droid type

View File

@ -163,16 +163,6 @@ static int constructorLimit[MAX_PLAYERS];
#define MAX_UNIT_MESSAGE_PAUSE 20000
/*
Check to see if the stats is some kind of expansion module
... this replaces the thousands of occurance that is spread through out the code
... There were a couple of places where it skipping around a routine if the stat was a expansion module
(loadSaveStructureV7 & 9) this code seemed suspect, and to clarify it we replaced it with the routine below
... the module stuff seemed to work though ... TJC (& AB) 8-DEC-98
*/
static void auxStructureNonblocking(STRUCTURE *psStructure)
{
StructureBounds b = getStructureBounds(psStructure);
@ -455,18 +445,18 @@ bool loadStructureStats(QString filename)
{
ini.beginGroup(list[inc]);
STRUCTURE_STATS *psStats = &asStructureStats[inc];
psStats->pName = allocateName(list[inc].toUtf8().constData());
ASSERT_OR_RETURN(false, psStats->pName != NULL, "Failed allocating structure ID");
psStats->name = ini.value("name").toString();
psStats->id = list[inc];
// check that the name has not been used already
ASSERT_OR_RETURN(false, !checkIDdict.contains(psStats->pName), "Structure ID '%s' used already", psStats->pName);
checkIDdict.insert(psStats->pName,0);
ASSERT_OR_RETURN(false, !checkIDdict.contains(getID(psStats)), "Structure ID '%s' used already", getID(psStats));
checkIDdict.insert(psStats->id, inc);
psStats->ref = REF_STRUCTURE_START + inc;
// set structure type
QString type = ini.value("type", "").toString();
ASSERT_OR_RETURN(false, structType.contains(type), "Invalid type '%s' of structure '%s'", type.toUtf8().constData(), psStats->pName);
ASSERT_OR_RETURN(false, structType.contains(type), "Invalid type '%s' of structure '%s'", type.toUtf8().constData(), getID(psStats));
psStats->type = structType[type];
// save indexes of special structures for futher use
@ -496,16 +486,16 @@ bool loadStructureStats(QString filename)
// set structure strength
QString strength = ini.value("strength", "").toString();
ASSERT_OR_RETURN(false, structStrength.contains(strength), "Invalid strength '%s' of structure '%s'", strength.toUtf8().constData(), psStats->pName);
ASSERT_OR_RETURN(false, structStrength.contains(strength), "Invalid strength '%s' of structure '%s'", strength.toUtf8().constData(), getID(psStats));
psStats->strength = structStrength[strength];
// set baseWidth
psStats->baseWidth = ini.value("baseWidth", 0).toUInt();
ASSERT_OR_RETURN(false, psStats->baseWidth <= 100, "Invalid baseWidth '%d' for structure '%s'", psStats->baseWidth, psStats->pName);
ASSERT_OR_RETURN(false, psStats->baseWidth <= 100, "Invalid baseWidth '%d' for structure '%s'", psStats->baseWidth, getID(psStats));
// set baseBreadth
psStats->baseBreadth = ini.value("baseBreadth", 0).toUInt();
ASSERT_OR_RETURN(false, psStats->baseBreadth < 100, "Invalid baseBreadth '%d' for structure '%s'", psStats->baseBreadth, psStats->pName);
ASSERT_OR_RETURN(false, psStats->baseBreadth < 100, "Invalid baseBreadth '%d' for structure '%s'", psStats->baseBreadth, getID(psStats));
psStats->height = ini.value("height").toUInt();
psStats->powerToBuild = ini.value("buildPower").toUInt();
@ -516,7 +506,7 @@ bool loadStructureStats(QString filename)
for (int j = 0; j < models.size(); j++)
{
iIMDShape *imd = (iIMDShape *)resGetData("IMD", models[j].trimmed().toUtf8().constData());
ASSERT(imd != NULL, "Cannot find the PIE structureModel '%s' for structure '%s'", models[j].toUtf8().constData(), psStats->pName);
ASSERT(imd != NULL, "Cannot find the PIE structureModel '%s' for structure '%s'", models[j].toUtf8().constData(), getID(psStats));
psStats->pIMD.push_back(imd);
}
@ -525,26 +515,29 @@ bool loadStructureStats(QString filename)
if (baseModel.compare("") != 0)
{
iIMDShape *imd = (iIMDShape *)resGetData("IMD", baseModel.toUtf8().constData());
ASSERT(imd != NULL, "Cannot find the PIE baseModel '%s' for structure '%s'", baseModel.toUtf8().constData(), psStats->pName);
ASSERT(imd != NULL, "Cannot find the PIE baseModel '%s' for structure '%s'", baseModel.toUtf8().constData(), getID(psStats));
psStats->pBaseIMD = imd;
}
psStats->pECM = findStatsByName(ini.value("ecmID", "ZNULLECM").toString().toUtf8().constData(), asECMStats, numECMStats);
ASSERT(psStats->pECM != NULL, "Invalid ECM found for '%s'", psStats->pName);
int ecm = getCompFromName(COMP_ECM, ini.value("ecmID", "ZNULLECM").toString());
ASSERT(ecm >= 0, "Invalid ECM found for '%s'", getID(psStats));
psStats->pECM = asECMStats + ecm;
psStats->pSensor = findStatsByName(ini.value("sensorID", "ZNULLSENSOR").toString().toUtf8().constData(), asSensorStats, numSensorStats);
ASSERT(psStats->pSensor != NULL, "Invalid sensor found for structure '%s'", psStats->pName);
int sensor = getCompFromName(COMP_SENSOR, ini.value("sensorID", "ZNULLSENSOR").toString());
ASSERT(sensor >= 0, "Invalid sensor found for structure '%s'", getID(psStats));
psStats->pSensor = asSensorStats + sensor;
// set list of weapons
std::fill_n(psStats->psWeapStat, STRUCT_MAXWEAPS, (WEAPON_STATS *)NULL);
QStringList weapons = ini.value("weapons").toStringList();
ASSERT_OR_RETURN(false, weapons.size() <= STRUCT_MAXWEAPS, "Too many weapons are attached to structure '%s'. Maximum is %d", psStats->pName, STRUCT_MAXWEAPS);
ASSERT_OR_RETURN(false, weapons.size() <= STRUCT_MAXWEAPS, "Too many weapons are attached to structure '%s'. Maximum is %d", getID(psStats), STRUCT_MAXWEAPS);
psStats->numWeaps = weapons.size();
for (int j = 0; j < psStats->numWeaps; j++)
{
QString weaponsID = weapons[j].trimmed();
WEAPON_STATS *pWeap = findStatsByName(weaponsID.toUtf8().constData(), asWeaponStats, numWeaponStats);
ASSERT_OR_RETURN(false, pWeap, "Invalid item '%s' in list of weapons of structure '%s' ", weaponsID.toUtf8().constData(), psStats->pName);
int weapon = getCompFromName(COMP_WEAPON, weaponsID);
ASSERT_OR_RETURN(false, weapon >= 0, "Invalid item '%s' in list of weapons of structure '%s' ", weaponsID.toUtf8().constData(), getID(psStats));
WEAPON_STATS *pWeap = asWeaponStats + weapon;
psStats->psWeapStat[j] = pWeap;
}
@ -553,7 +546,7 @@ bool loadStructureStats(QString filename)
types += psStats->numWeaps != 0;
types += psStats->pECM != NULL && psStats->pECM->location == LOC_TURRET;
types += psStats->pSensor != NULL && psStats->pSensor->location == LOC_TURRET;
ASSERT(types <= 1, "Too many turret types for structure '%s'", psStats->pName);
ASSERT(types <= 1, "Too many turret types for structure '%s'", getID(psStats));
ini.endGroup();
}
@ -630,7 +623,7 @@ void setCurrentStructQuantity(bool displayError)
{
//check quantity never exceeds the limit
ASSERT(psStructLimits[inc].currentQuantity <= psStructLimits[inc].limit,
"There appears to be too many %s on this map!", asStructureStats[inc].pName);
"There appears to be too many %s on this map!", getName(&asStructureStats[inc]));
}
}
}
@ -1299,7 +1292,7 @@ STRUCTURE* buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y
ASSERT_OR_RETURN(NULL, max <= numStructureStats, "Invalid structure type");
if (!strcmp(pStructureType->pName, "A0CyborgFactory") && player == 0 && !bMultiPlayer)
if (pStructureType->id.compare("A0CyborgFactory") == 0 && player == 0 && !bMultiPlayer)
{
// HACK: correcting SP bug, needs fixing in script(!!) (only applies for player 0)
// should be OK for Skirmish/MP games, since that is set correctly.
@ -1311,7 +1304,7 @@ STRUCTURE* buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y
if (asStructLimits[player][max].currentQuantity + 1 > asStructLimits[player][max].limit)
{
debug(LOG_ERROR, "Player %u: Building %s could not be built due to building limits (has %d, max %d)!",
player, pStructureType->pName, asStructLimits[player][max].currentQuantity,
player, getName(pStructureType), asStructLimits[player][max].currentQuantity,
asStructLimits[player][max].limit);
return NULL;
}
@ -1417,8 +1410,8 @@ STRUCTURE* buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y
else if (TileHasStructure(psTile))
{
debug(LOG_ERROR, "Player %u (%s): is building %s at (%d, %d) but found %s already at (%d, %d)",
player, isHumanPlayer(player) ? "Human" : "AI", pStructureType->pName, map.x, map.y,
getTileStructure(map.x + width, map.y + breadth)->pStructureType->pName,
player, isHumanPlayer(player) ? "Human" : "AI", getName(pStructureType), map.x, map.y,
getName(getTileStructure(map.x + width, map.y + breadth)->pStructureType),
map.x + width, map.y + breadth);
delete psBuilding;
return NULL;
@ -3857,7 +3850,7 @@ UDWORD fillStructureList(STRUCTURE_STATS **ppList, UDWORD selectedPlayer, UDWORD
}
}
debug(LOG_NEVER, "adding %s (%x)", psBuilding->pName, apStructTypeLists[selectedPlayer][inc]);
debug(LOG_NEVER, "adding %s (%x)", getName(psBuilding), apStructTypeLists[selectedPlayer][inc]);
ppList[count++] = psBuilding;
if (count == limit)
{
@ -4699,13 +4692,10 @@ bool destroyStruct(STRUCTURE *psDel, unsigned impactTime)
return the first one it finds!! */
int32_t getStructStatFromName(char const *pName)
{
UDWORD inc;
STRUCTURE_STATS *psStat;
for (inc = 0; inc < numStructureStats; inc++)
for (int inc = 0; inc < numStructureStats; inc++)
{
psStat = &asStructureStats[inc];
if (!strcmp(psStat->pName, pName))
STRUCTURE_STATS *psStat = &asStructureStats[inc];
if (psStat->id.compare(pName) == 0)
{
return inc;
}
@ -5934,7 +5924,7 @@ void factoryReward(UBYTE losingPlayer, UBYTE rewardPlayer)
{
CONPRINTF(ConsoleString,(ConsoleString,"%s :- %s",
_("Factory Reward - Propulsion"),
getName(asPropulsionStats[comp].pName)));
getName(&asPropulsionStats[comp])));
}
return;
}
@ -5958,7 +5948,7 @@ void factoryReward(UBYTE losingPlayer, UBYTE rewardPlayer)
{
CONPRINTF(ConsoleString,(ConsoleString,"%s :- %s",
_("Factory Reward - Body"),
getName(asBodyStats[comp].pName)));
getName(&asBodyStats[comp])));
}
return;
}
@ -5982,7 +5972,7 @@ void factoryReward(UBYTE losingPlayer, UBYTE rewardPlayer)
{
CONPRINTF(ConsoleString,(ConsoleString,"%s :- %s",
_("Factory Reward - Weapon"),
getName(asWeaponStats[comp].pName)));
getName(&asWeaponStats[comp])));
}
return;
}
@ -6019,7 +6009,7 @@ void repairFacilityReward(UBYTE losingPlayer, UBYTE rewardPlayer)
{
CONPRINTF(ConsoleString,(ConsoleString,"%s :- %s",
_("Repair Facility Award - Repair"),
getName(asRepairStats[comp].pName)));
getName(&asRepairStats[comp])));
}
return;
}

View File

@ -94,7 +94,7 @@ bool researchedTemplate(DROID_TEMPLATE *psCurr, int player, bool allowRedundant,
bool researchedEverything = resBody && resBrain && resProp && resSensor && resEcm && resRepair && resConstruct;
if (verbose && !researchedEverything)
{
debug(LOG_ERROR, "%s : not researched : body=%d brai=%d prop=%d sensor=%d ecm=%d rep=%d con=%d", psCurr->aName,
debug(LOG_ERROR, "%s : not researched : body=%d brai=%d prop=%d sensor=%d ecm=%d rep=%d con=%d", getName(psCurr),
(int)resBody, (int)resBrain, (int)resProp, (int)resSensor, (int)resEcm, (int)resRepair, (int)resConstruct);
}
unsigned ignoreFirstWeapon = psCurr->asParts[COMP_BRAIN] != 0? 1 : 0;
@ -103,7 +103,7 @@ bool researchedTemplate(DROID_TEMPLATE *psCurr, int player, bool allowRedundant,
researchedEverything = researchedWeap(psCurr, player, weapIndex, allowRedundant);
if (!researchedEverything && verbose)
{
debug(LOG_ERROR, "%s : not researched weapon %u", psCurr->aName, weapIndex);
debug(LOG_ERROR, "%s : not researched weapon %u", getName(psCurr), weapIndex);
}
}
return researchedEverything;
@ -122,19 +122,18 @@ bool initTemplates()
{
ini.beginGroup(list[i]);
DROID_TEMPLATE design;
design.pName = NULL;
design.droidType = (DROID_TYPE)ini.value("droidType").toInt();
design.multiPlayerID = generateNewObjectId();
design.asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", QString("ZNULLBODY")).toString().toUtf8().constData());
design.asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", QString("ZNULLBRAIN")).toString().toUtf8().constData());
design.asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", QString("ZNULLPROP")).toString().toUtf8().constData());
design.asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", QString("ZNULLREPAIR")).toString().toUtf8().constData());
design.asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", QString("ZNULLECM")).toString().toUtf8().constData());
design.asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", QString("ZNULLSENSOR")).toString().toUtf8().constData());
design.asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", QString("ZNULLCONSTRUCT")).toString().toUtf8().constData());
design.asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", QString("ZNULLWEAPON")).toString().toUtf8().constData());
design.asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", QString("ZNULLWEAPON")).toString().toUtf8().constData());
design.asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", QString("ZNULLWEAPON")).toString().toUtf8().constData());
design.asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", QString("ZNULLBODY")).toString());
design.asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", QString("ZNULLBRAIN")).toString());
design.asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", QString("ZNULLPROP")).toString());
design.asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", QString("ZNULLREPAIR")).toString());
design.asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", QString("ZNULLECM")).toString());
design.asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", QString("ZNULLSENSOR")).toString());
design.asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", QString("ZNULLCONSTRUCT")).toString());
design.asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", QString("ZNULLWEAPON")).toString());
design.asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", QString("ZNULLWEAPON")).toString());
design.asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", QString("ZNULLWEAPON")).toString());
design.numWeaps = ini.value("weapons").toInt();
design.prefab = false; // not AI template
design.stored = true;
@ -163,7 +162,7 @@ bool initTemplates()
{
// Check if template is identical to a loaded template
if (psDestTemplate->droidType == design.droidType
&& strcmp(psDestTemplate->aName, design.aName) == 0
&& psDestTemplate->name.compare(design.name) == 0
&& psDestTemplate->numWeaps == design.numWeaps
&& psDestTemplate->asWeaps[0] == design.asWeaps[0]
&& psDestTemplate->asWeaps[1] == design.asWeaps[1]
@ -208,34 +207,34 @@ bool storeTemplates()
{
if (!psCurr->stored) continue; // not stored
ini.beginGroup("template_" + QString::number(psCurr->multiPlayerID));
ini.setValue("name", psCurr->aName);
ini.setValue("name", psCurr->name);
ini.setValue("droidType", psCurr->droidType);
ini.setValue("body", (asBodyStats + psCurr->asParts[COMP_BODY])->pName);
ini.setValue("propulsion", (asPropulsionStats + psCurr->asParts[COMP_PROPULSION])->pName);
ini.setValue("body", (asBodyStats + psCurr->asParts[COMP_BODY])->id);
ini.setValue("propulsion", (asPropulsionStats + psCurr->asParts[COMP_PROPULSION])->id);
if (psCurr->asParts[COMP_BRAIN] != 0)
{
ini.setValue("brain", (asBrainStats + psCurr->asParts[COMP_BRAIN])->pName);
ini.setValue("brain", (asBrainStats + psCurr->asParts[COMP_BRAIN])->id);
}
if ((asRepairStats + psCurr->asParts[COMP_REPAIRUNIT])->location == LOC_TURRET) // avoid auto-repair...
{
ini.setValue("repair", (asRepairStats + psCurr->asParts[COMP_REPAIRUNIT])->pName);
ini.setValue("repair", (asRepairStats + psCurr->asParts[COMP_REPAIRUNIT])->id);
}
if ((asECMStats + psCurr->asParts[COMP_ECM])->location == LOC_TURRET)
{
ini.setValue("ecm", (asECMStats + psCurr->asParts[COMP_ECM])->pName);
ini.setValue("ecm", (asECMStats + psCurr->asParts[COMP_ECM])->id);
}
if ((asSensorStats + psCurr->asParts[COMP_SENSOR])->location == LOC_TURRET)
{
ini.setValue("sensor", (asSensorStats + psCurr->asParts[COMP_SENSOR])->pName);
ini.setValue("sensor", (asSensorStats + psCurr->asParts[COMP_SENSOR])->id);
}
if (psCurr->asParts[COMP_CONSTRUCT] != 0)
{
ini.setValue("construct", (asConstructStats + psCurr->asParts[COMP_CONSTRUCT])->pName);
ini.setValue("construct", (asConstructStats + psCurr->asParts[COMP_CONSTRUCT])->id);
}
ini.setValue("weapons", psCurr->numWeaps);
for (int j = 0; j < psCurr->numWeaps; j++)
{
ini.setValue("weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j])->pName);
ini.setValue("weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j])->id);
}
ini.endGroup();
}
@ -249,7 +248,6 @@ bool shutdownTemplates()
DROID_TEMPLATE::DROID_TEMPLATE() // This constructor replaces a memset in scrAssembleWeaponTemplate(), not needed elsewhere.
: BASE_STATS(REF_TEMPLATE_START)
//, aName
//, asParts
, numWeaps(0)
//, asWeaps
@ -260,7 +258,6 @@ DROID_TEMPLATE::DROID_TEMPLATE() // This constructor replaces a memset in scrAs
, stored(false)
, enabled(false)
{
aName[0] = '\0';
std::fill_n(asParts, DROID_MAXCOMP, 0);
std::fill_n(asWeaps, DROID_MAXWEAPS, 0);
}
@ -275,7 +272,8 @@ bool loadDroidTemplates(const char *filename)
ini.beginGroup(list[i]);
DROID_TEMPLATE design;
QString droidType = ini.value("type").toString();
design.pName = strdup(list[i].toUtf8().constData());
design.id = list[i];
design.name = ini.value("name").toString();
if (droidType == "PERSON") design.droidType = DROID_PERSON;
else if (droidType == "CYBORG") design.droidType = DROID_CYBORG;
else if (droidType == "CYBORG_SUPER") design.droidType = DROID_CYBORG_SUPER;
@ -284,19 +282,19 @@ bool loadDroidTemplates(const char *filename)
else if (droidType == "TRANSPORTER") design.droidType = DROID_TRANSPORTER;
else if (droidType == "SUPERTRANSPORTER") design.droidType = DROID_SUPERTRANSPORTER;
else if (droidType == "DROID") design.droidType = DROID_DEFAULT;
else ASSERT(false, "No such droid type \"%s\" for %s", droidType.toUtf8().constData(), design.pName);
else ASSERT(false, "No such droid type \"%s\" for %s", droidType.toUtf8().constData(), getID(&design));
design.multiPlayerID = generateNewObjectId();
design.asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("compBody", "ZNULLBODY").toString().toUtf8().constData());
design.asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("compBrain", "ZNULLBRAIN").toString().toUtf8().constData());
design.asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("compRepair", "ZNULLREPAIR").toString().toUtf8().constData());
design.asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("compConstruct", "ZNULLCONSTRUCT").toString().toUtf8().constData());
design.asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("compECM", "ZNULLECM").toString().toUtf8().constData());
design.asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("compSensor", "ZNULLSENSOR").toString().toUtf8().constData());
design.asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("compPropulsion", "ZNULLPROP").toString().toUtf8().constData());
design.asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("compBody", "ZNULLBODY").toString());
design.asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("compBrain", "ZNULLBRAIN").toString());
design.asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("compRepair", "ZNULLREPAIR").toString());
design.asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("compConstruct", "ZNULLCONSTRUCT").toString());
design.asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("compECM", "ZNULLECM").toString());
design.asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("compSensor", "ZNULLSENSOR").toString());
design.asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("compPropulsion", "ZNULLPROP").toString());
QStringList weapons = ini.value("weapons").toStringList();
for (int j = 0; j < weapons.size(); j++)
{
design.asWeaps[j] = getCompFromName(COMP_WEAPON, weapons[j].toUtf8().constData());
design.asWeaps[j] = getCompFromName(COMP_WEAPON, weapons[j]);
}
design.numWeaps = weapons.size();
design.prefab = true;
@ -304,7 +302,7 @@ bool loadDroidTemplates(const char *filename)
design.enabled = true;
bool available = ini.value("available", false).toBool();
char const *droidResourceName = getDroidResourceName(list[i].toUtf8().constData());
sstrcpy(design.aName, droidResourceName != NULL? droidResourceName : GetDefaultTemplateName(&design));
design.name = droidResourceName != NULL? droidResourceName : GetDefaultTemplateName(&design);
ini.endGroup();
for (int i = 0; i < MAX_PLAYERS; ++i)
@ -324,26 +322,25 @@ bool loadDroidTemplates(const char *filename)
DROID_TEMPLATE *psCurr = &*it;
if (psCurr->multiPlayerID == design.multiPlayerID)
{
debug(LOG_ERROR, "Design id:%d (%s) *NOT* added to UI list (duplicate), player= %d", design.multiPlayerID, design.aName, i);
debug(LOG_ERROR, "Design id:%d (%s) *NOT* added to UI list (duplicate), player= %d", design.multiPlayerID, getName(&design), i);
break;
}
}
if (it == localTemplates.end())
{
debug(LOG_NEVER, "Design id:%d (%s) added to UI list, player =%d", design.multiPlayerID, design.aName, i);
debug(LOG_NEVER, "Design id:%d (%s) added to UI list, player =%d", design.multiPlayerID, getName(&design), i);
localTemplates.push_front(design);
localTemplates.front().pName = strdup(localTemplates.front().pName);
}
}
else if (!NetPlay.players[i].allocated) // AI template
{
debug(LOG_NEVER, "AI (%d): %s id:%d enabled:%d", i, design.aName, design.multiPlayerID, design.enabled);
debug(LOG_NEVER, "AI (%d): %s id:%d enabled:%d", i, getName(&design), design.multiPlayerID, design.enabled);
design.prefab = true; // prefabricated templates referenced from VLOs
addTemplateToList(&design, &apsDroidTemplates[i]);
}
}
debug(LOG_NEVER, "Droid template found, aName: %s, MP ID: %d, ref: %u, pname: %s, prefab: %s, type:%d (loading)",
design.aName, design.multiPlayerID, design.ref, design.pName, design.prefab ? "yes":"no", design.droidType);
debug(LOG_NEVER, "Droid template found, Name: %s, MP ID: %d, ref: %u, ID: %s, prefab: %s, type:%d (loading)",
getName(&design), design.multiPlayerID, design.ref, getID(&design), design.prefab ? "yes":"no", design.droidType);
}
return true;
@ -360,16 +357,11 @@ bool droidTemplateShutDown(void)
for (pTemplate = apsDroidTemplates[player]; pTemplate != NULL; pTemplate = pNext)
{
pNext = pTemplate->psNext;
free(pTemplate->pName);
delete pTemplate;
}
apsDroidTemplates[player] = NULL;
}
for (std::list<DROID_TEMPLATE>::iterator i = localTemplates.begin(); i != localTemplates.end(); ++i)
{
free(i->pName);
}
localTemplates.clear();
return true;
@ -387,8 +379,7 @@ DROID_TEMPLATE *getTemplateFromTranslatedNameNoPlayer(char const *pName)
{
for (DROID_TEMPLATE *psCurr = apsDroidTemplates[i]; psCurr != NULL; psCurr = psCurr->psNext)
{
const char *rName = psCurr->pName ? psCurr->pName : psCurr->aName;
if (strcmp(rName, pName) == 0)
if (psCurr->id.compare(pName) == 0)
{
return psCurr;
}
@ -416,11 +407,6 @@ DROID_TEMPLATE* getTemplateFromMultiPlayerID(UDWORD multiPlayerID)
return NULL;
}
const char* getTemplateName(const DROID_TEMPLATE *psTemplate)
{
return psTemplate->aName;
}
/*called when a Template is deleted in the Design screen*/
void deleteTemplateFromProduction(DROID_TEMPLATE *psTemplate, unsigned player, QUEUE_MODE mode)
{

View File

@ -22,13 +22,10 @@ void fillTemplateList(std::vector<DROID_TEMPLATE *> &pList, STRUCTURE *psFactory
/* gets a template from its name - relies on the name being unique */
DROID_TEMPLATE *getTemplateFromTranslatedNameNoPlayer(char const *pName);
/*getTemplateFromMultiPlayerID gets template for unique ID searching all lists */
DROID_TEMPLATE *getTemplateFromMultiPlayerID(UDWORD multiPlayerID);
/*return the name to display for the interface - we don't know if this is
a string ID or something the user types in*/
const char* getTemplateName(const DROID_TEMPLATE *psTemplate);
/// Have we researched the components of this template?
bool researchedTemplate(DROID_TEMPLATE *psCurr, int player, bool allowRedundant = false, bool verbose = false);