Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Do away with apsStaticTemplates completely, it caused multiple issues…

…. There is no difference in accessing the templates for the AI or Humans now. Only write templates out for active players. Make each template's group unique to each player. Fix clone wars templates. Remove hacky functions GetHumanDroidTemplate & GetAIDroidTemplate fixes ticket:3146 close ticket:3369

refs b99e845
refs 0cc7c31
  • Loading branch information...
commit 28c10b00a8f3bf6d87176e3aba8fba65993cedba 1 parent d878966
vexed vexed authored
44 src/droid.cpp
View
@@ -1488,37 +1488,11 @@ bool loadDroidWeapons(const char *pWeaponData, UDWORD bufferSize)
for (unsigned i = 0; i < table.size(); ++i)
{
LineView line(table, i);
-
- DROID_TEMPLATE *pTemplate;
std::string templateName = line.s(0);
- for (int player = 0; player < MAX_PLAYERS + 2; ++player)
+ for (int player = 0; player < MAX_PLAYERS ; ++player)
{
- if (player < MAX_PLAYERS) // a player
- {
- if (!isHumanPlayer(player))
- {
- continue; // no need to add to AIs, they use the static list
- }
- pTemplate = getTemplateFromUniqueName(templateName.c_str(), player);
- }
- else if (player == MAX_PLAYERS) // special exception - the static list
- {
- // Add weapons to static list
- pTemplate = getTemplateFromTranslatedNameNoPlayer(templateName.c_str());
- }
- else // Special exception - the local UI list.
- {
- pTemplate = NULL;
- for (std::list<DROID_TEMPLATE>::iterator j = localTemplates.begin(); j != localTemplates.end(); ++j)
- {
- if (j->pName == templateName)
- {
- pTemplate = &*j;
- break;
- }
- }
- }
+ DROID_TEMPLATE *pTemplate = getTemplateFromUniqueName(templateName.c_str(), player);
/* if Template not found - try default design */
if (!pTemplate)
@@ -1547,6 +1521,20 @@ bool loadDroidWeapons(const char *pWeaponData, UDWORD bufferSize)
//check valid weapon/propulsion
ASSERT_OR_RETURN(false, pTemplate->storeCount <= pTemplate->numWeaps, "Allocating more weapons than allowed for Template %s", templateName.c_str());
ASSERT_OR_RETURN(false, checkValidWeaponForProp(pTemplate), "Weapon is invalid for air propulsion for template %s", templateName.c_str());
+ if (player == selectedPlayer) // FIXME: can you say hack? Why don't we make a list on demmand ? This *will* break on player change!
+ {
+ DROID_TEMPLATE *pUITemplate = NULL;
+ for (std::list<DROID_TEMPLATE>::iterator j = localTemplates.begin(); j != localTemplates.end(); ++j)
+ {
+ if (j->pName == templateName)
+ {
+ pUITemplate = &*j;
+ // update UI template as well (it already passed the checks above)
+ pUITemplate->asWeaps[pTemplate->storeCount] = incWpn;
+ break;
+ }
+ }
+ }
pTemplate->storeCount++;
}
}
43 src/game.cpp
View
@@ -5519,28 +5519,31 @@ bool writeTemplateFile(const char *pFileName)
}
for (int player = 0; player < MAX_PLAYERS; player++)
{
- for (DROID_TEMPLATE *psCurr = apsDroidTemplates[player]; psCurr != NULL; psCurr = psCurr->psNext)
- {
- ini.beginGroup("template_" + QString::number(psCurr->multiPlayerID));
- ini.setValue("name", psCurr->aName);
- 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("weapons", psCurr->numWeaps);
- ini.setValue("enabled", psCurr->enabled);
- for (int j = 0; j < psCurr->numWeaps; j++)
+ if (apsDroidLists[player] || apsStructLists[player]) // only write out templates of players that are still 'alive'
+ {
+ for (DROID_TEMPLATE *psCurr = apsDroidTemplates[player]; psCurr != NULL; psCurr = psCurr->psNext)
{
- ini.setValue("weapon/" + QString::number(j + 1), (asWeaponStats + psCurr->asWeaps[j])->pName);
+ ini.beginGroup("template_" + QString::number(psCurr->multiPlayerID) + "_player" + QString::number(player));
+ ini.setValue("name", psCurr->aName);
+ 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("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.endGroup();
}
- ini.endGroup();
}
}
return true;
81 src/keybind.cpp
View
@@ -92,7 +92,7 @@
#include "clparse.h"
#include "research.h"
#include "template.h"
-
+#include "qtscript.h"
/*
KeyBind.c
Holds all the functions that can be mapped to a key.
@@ -342,13 +342,9 @@ DROID *psDroid;
void kf_CloneSelected( void )
{
- DROID *psDroid;
- DROID_TEMPLATE sTemplate;
- DROID_TEMPLATE *sTemplate2 = NULL;
+ DROID_TEMPLATE *sTemplate = NULL;
const int limit = 10; // make 10 clones
- int i;//, impact_side;
- //const char * msg;
-
+ const char *msg;
#ifndef DEBUG
// Bail out if we're running a _true_ multiplayer game (to prevent MP cheating)
if (runningMultiplayer())
@@ -358,61 +354,52 @@ void kf_CloneSelected( void )
}
#endif
- for (psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid=psDroid->psNext)
+ for (DROID *psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid=psDroid->psNext)
{
- for (i = 0; psDroid->selected && i < limit; i++)
+ if (psDroid->selected)
{
- // create a template based on the droid
- if (!sTemplate2)
+ for (DROID_TEMPLATE *psTempl = apsDroidTemplates[selectedPlayer]; psTempl; psTempl = psTempl->psNext)
{
- sTemplate2 = GetHumanDroidTemplate(psDroid->aName);
- if (!sTemplate2)
- { // we now search the AI template list (apsStaticTemplates)
- sTemplate2 = GetAIDroidTemplate(psDroid->aName);
+ if (!strcmp(psTempl->aName, psDroid->aName))
+ {
+ sTemplate = psTempl;
+ break;
}
}
- if (!sTemplate2)
+
+ if (!sTemplate)
{
- debug(LOG_ERROR, "We can't find the template for this droid: %s, id:%u, type:%d!", psDroid->aName, psDroid->id, psDroid->droidType);
+ debug(LOG_ERROR, "Cloning vat has been destoryed. We can't find the template for this droid: %s, id:%u, type:%d!", psDroid->aName, psDroid->id, psDroid->droidType);
return;
}
- sTemplate = *sTemplate2;
- templateSetParts(psDroid, &sTemplate);
-
- // create a new droid
- buildDroid(&sTemplate, psDroid->pos.x, psDroid->pos.y, psDroid->player, false, NULL);
- /* // TODO psNewDroid is null, since we just sent a message, but haven't actually created the droid locally yet.
- ASSERT_OR_RETURN(, psNewDroid != NULL, "Unable to build a unit");
- addDroid(psNewDroid, apsDroidLists);
- psNewDroid->body = psDroid->body;
- for (impact_side = 0; impact_side < NUM_HIT_SIDES; impact_side=impact_side+1)
- {
- psNewDroid->armour[impact_side][WC_KINETIC] = psDroid->armour[impact_side][WC_KINETIC];
- psNewDroid->armour[impact_side][WC_HEAT] = psDroid->armour[impact_side][WC_HEAT];
- }
- psNewDroid->experience = psDroid->experience;
- psNewDroid->rot.direction = psDroid->rot.direction;
- if (!(psNewDroid->droidType == DROID_PERSON || cyborgDroid(psNewDroid) || psNewDroid->droidType == DROID_TRANSPORTER || psNewDroid->droidType == DROID_SUPERTRANSPORTER))
+
+ // create a new droid army
+ for (int i = 0; i < limit; i++)
{
- updateDroidOrientation(psNewDroid);
+ DROID *psNewDroid = buildDroid(sTemplate, psDroid->pos.x + (i*12), psDroid->pos.y + (i*14), psDroid->player, false, NULL);
+ if (psNewDroid)
+ {
+ addDroid(psNewDroid, apsDroidLists);
+ psScrCBNewDroid = psNewDroid;
+ psScrCBNewDroidFact = NULL;
+ eventFireCallbackTrigger((TRIGGER_TYPE)CALL_NEWDROID); // notify scripts so it will get assigned jobs
+ psScrCBNewDroid = NULL;
+ triggerEventDroidBuilt(psNewDroid, NULL);
+ }
+ else
+ {
+ debug(LOG_ERROR, "Cloning has failed for template:%s id:%d", sTemplate->pName, sTemplate->multiPlayerID);
+ }
}
- }
- if (psNewDroid)
- {
- // Send a text message to all players, notifying them of
- // the fact that we're cheating ourselves a new droid army
- sasprintf((char**)&msg, _("Player %u is cheating him/herself a new droid army of %s(s)."), selectedPlayer, psNewDroid->aName);
+ sasprintf((char**)&msg, _("Player %u is cheating a new droid army of: %s."), selectedPlayer, psDroid->aName);
sendTextMessage(msg, true);
- audio_PlayTrack(ID_SOUND_NEXUS_LAUGH1);
- sTemplate2 = NULL;
- psNewDroid->selected = true;
- psNewDroid = NULL;
Cheated = true;
- */
+ audio_PlayTrack(ID_SOUND_NEXUS_LAUGH1);
+ return;
}
+ debug(LOG_INFO, "Nothing was selected?");
}
}
-
// --------------------------------------------------------------------------
//
///* Prints out the date and time of the build of the game */
33 src/multiplay.cpp
View
@@ -366,25 +366,36 @@ DROID_TEMPLATE *IdToTemplate(UDWORD tempId, UDWORD player)
DROID_TEMPLATE *psTempl = NULL;
UDWORD i;
- // First try static templates from scripts (could potentially also happen for currently human controlled players)
- for (psTempl = apsStaticTemplates; psTempl && psTempl->multiPlayerID != tempId; psTempl = psTempl->psNext) ;
- if (psTempl) return psTempl;
-
// Check if we know which player this is from, in that case, assume it is a player template
- if (player != ANYPLAYER && player < MAX_PLAYERS)
+ // FIXME: nuke the ANYPLAYER hack
+ if (player != ANYPLAYER && player < MAX_PLAYERS )
{
- for (psTempl = apsDroidTemplates[player]; psTempl && (psTempl->multiPlayerID != tempId); psTempl = psTempl->psNext) {} // follow templates
+ for (psTempl = apsDroidTemplates[player]; psTempl && (psTempl->multiPlayerID != tempId); psTempl = psTempl->psNext)
+ {} // follow templates
- return psTempl;
+ if (psTempl)
+ {
+ return psTempl;
+ }
+ else
+ {
+ return NULL;
+ }
}
- // We have no idea, so search through every player template
+ // It could be a AI template...or that of another player
for (i = 0; i < MAX_PLAYERS; i++)
{
- for (psTempl = apsDroidTemplates[i]; psTempl && psTempl->multiPlayerID != tempId; psTempl = psTempl->psNext) ;
- if (psTempl) return psTempl;
- }
+ for (psTempl = apsDroidTemplates[i]; psTempl && psTempl->multiPlayerID != tempId; psTempl = psTempl->psNext)
+ {} // follow templates
+ if (psTempl)
+ {
+ debug(LOG_NEVER, "Found template ID %d, for player %d, but found it in player's %d list?",tempId, player, i);
+ return psTempl;
+ }
+ }
+ // no error, since it is possible that we don't have this template defined yet.
return NULL;
}
3  src/scriptobj.cpp
View
@@ -976,10 +976,11 @@ bool scrValDefLoad(INTERP_VAL *psVal, WzConfig &ini)
psVal->v.oval = NULL;
if (ini.contains("data"))
{
+ // FIXME: Ugh. Find a better way to show full template info
psVal->v.oval = (void*)IdToTemplate(ini.value("data").toInt(), ANYPLAYER);
if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL)
{
- debug(LOG_FATAL, "Could not find template");
+ debug(LOG_FATAL, "Could not find template %d", ini.value("data").toInt());
}
}
break;
165 src/template.cpp
View
@@ -44,7 +44,6 @@ extern DROID_TEMPLATE sDefaultDesignTemplate;
// Template storage
DROID_TEMPLATE *apsDroidTemplates[MAX_PLAYERS];
-DROID_TEMPLATE *apsStaticTemplates; // for AIs and scripts
bool allowDesign = true;
@@ -235,10 +234,7 @@ void initTemplatePoints(void)
initTemplatePoints(pDroidDesign);
}
}
- for (DROID_TEMPLATE *pDroidDesign = apsStaticTemplates; pDroidDesign != NULL; pDroidDesign = pDroidDesign->psNext)
- {
- initTemplatePoints(pDroidDesign);
- }
+
for (std::list<DROID_TEMPLATE>::iterator pDroidDesign = localTemplates.begin(); pDroidDesign != localTemplates.end(); ++pDroidDesign)
{
initTemplatePoints(&*pDroidDesign);
@@ -343,30 +339,36 @@ bool loadDroidTemplates(const char *pDroidData, UDWORD bufferSize)
else
{
std::string playerType = line.s(6);
- // Give those meant for humans to all human players.
- // Also support the old template format, in which those meant
- // for humans were player 0 (in campaign) or 5 (in multiplayer).
- if ((!bMultiPlayer && playerType == "0") ||
- ( bMultiPlayer && playerType == "5") ||
- playerType == "YES"
- )
+
+ for (int i = 0; i < MAX_PLAYERS; ++i)
{
- for (int i = 0; i < MAX_PLAYERS; ++i)
+ // Give those meant for humans to all human players.
+ // Also support the old template format, in which those meant
+ // for humans were player 0 (in campaign) or 5 (in multiplayer), ("YES" is used in MP stats)
+ if (NetPlay.players[i].allocated &&
+ ((!bMultiPlayer && playerType == "0") || (bMultiPlayer && playerType == "5") || playerType == "YES"))
{
- if (NetPlay.players[i].allocated) // human prototype template
- {
- design.prefab = false;
- addTemplateToList(&design, &apsDroidTemplates[i]);
- }
+ debug(LOG_NEVER, "HUMAN (%d): %s id:%d enabled:%d", i, design.aName, design.multiPlayerID, design.enabled);
+ design.prefab = false;
+ addTemplateToList(&design, &apsDroidTemplates[i]);
+
+ // This sets up the UI templates for display purposes ONLY--we still only use apsDroidTemplates for making them.
+ // FIXME: Why are we doing this here, and not on demmand ?
+ localTemplates.push_front(design);
+ localTemplates.front().pName = strdup(localTemplates.front().pName);
+ }
+ else if (NetPlay.players[i].allocated) //skip the ones not meant for puny humans
+ {
+ continue;
+ }
+ else // assume everything else is for AI
+ {
+ debug(LOG_NEVER, "AI (%d): %s id:%d enabled:%d", i, design.aName, design.multiPlayerID, design.enabled);
+ design.prefab = true; // prefabricated templates referenced from VLOs
+ addTemplateToList(&design, &apsDroidTemplates[i]);
}
- localTemplates.push_front(design);
- localTemplates.front().pName = strdup(localTemplates.front().pName);
}
- // Add all templates to static template list
- design.prefab = true; // prefabricated templates referenced from VLOs
- addTemplateToList(&design, &apsStaticTemplates);
}
-
debug(LOG_NEVER, "(default) 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);
}
@@ -391,22 +393,11 @@ bool droidTemplateShutDown(void)
{
free(pTemplate->pName);
}
- ASSERT(!pTemplate->prefab, "Static template %s in player template list!", pTemplate->aName);
delete pTemplate;
}
apsDroidTemplates[player] = NULL;
}
- for (pTemplate = apsStaticTemplates; pTemplate != NULL; pTemplate = pNext)
- {
- pNext = pTemplate->psNext;
- if (pTemplate->pName != sDefaultDesignTemplate.pName) // sanity check probably no longer necessary
- {
- free(pTemplate->pName);
- }
- ASSERT(pTemplate->prefab, "Player template %s in static template list!", pTemplate->aName);
- delete pTemplate;
- }
- apsStaticTemplates = NULL;
+
free(sDefaultDesignTemplate.pName);
sDefaultDesignTemplate.pName = NULL;
@@ -420,83 +411,6 @@ bool droidTemplateShutDown(void)
}
/*!
- * Get a static template from its aName.
- * This checks the all the Human's apsDroidTemplates list.
- * This function is similar to getTemplateFromUniqueName() but we use aName,
- * and not pName, since we don't have that information, and we are checking all player's list.
- * THIS FUNCTION WILL GO AWAY! Only used (badly) in "clone" cheat currently.
- * \param aName Template aName
- *
- */
-DROID_TEMPLATE *GetHumanDroidTemplate(const char *aName)
-{
- DROID_TEMPLATE *templatelist, *found = NULL, *foundOtherPlayer = NULL;
- int i, playerFound = 0;
-
- for (i=0; i < MAX_PLAYERS; i++)
- {
- templatelist = apsDroidTemplates[i];
- while (templatelist)
- {
- if (!strcmp(templatelist->aName, aName))
- {
- debug(LOG_NEVER, "Droid template found, aName: %s, MP ID: %d, ref: %u, pname: %s (for player %d)",
- templatelist->aName, templatelist->multiPlayerID, templatelist->ref, templatelist->pName, i);
- if (i == selectedPlayer)
- {
- found = templatelist;
- }
- else
- {
- foundOtherPlayer = templatelist;
- playerFound = i;
- }
- }
-
- templatelist = templatelist->psNext;
- }
- }
-
- if (foundOtherPlayer && !found)
- {
- debug(LOG_ERROR, "The template was not in our list, but was in another players list.");
- debug(LOG_ERROR, "Droid template's aName: %s, MP ID: %d, ref: %u, pname: %s (for player %d)",
- foundOtherPlayer->aName, foundOtherPlayer->multiPlayerID, foundOtherPlayer->ref, foundOtherPlayer->pName, playerFound);
- return foundOtherPlayer;
- }
-
- return found;
-}
-
-/*!
- * Get a static template from its aName.
- * This checks the AI apsStaticTemplates.
- * This function is similar to getTemplateFromTranslatedNameNoPlayer() but we use aName,
- * and not pName, since we don't have that information.
- * \param aName Template aName
- *
- */
-DROID_TEMPLATE *GetAIDroidTemplate(const char *aName)
-{
- DROID_TEMPLATE *templatelist, *found = NULL;
-
- templatelist = apsStaticTemplates;
- while (templatelist)
- {
- if (!strcmp(templatelist->aName, aName))
- {
- debug(LOG_INFO, "Droid template found, name: %s, MP ID: %d, ref: %u, pname: %s ",
- templatelist->aName, templatelist->multiPlayerID, templatelist->ref, templatelist->pName);
-
- found = templatelist;
- }
- templatelist = templatelist->psNext;
- }
-
- return found;
-}
-
-/*!
* Gets a template from its name
* relies on the name being unique (or it will return the first one it finds!)
* \param pName Template name
@@ -506,15 +420,9 @@ DROID_TEMPLATE *GetAIDroidTemplate(const char *aName)
*/
DROID_TEMPLATE * getTemplateFromUniqueName(const char *pName, unsigned int player)
{
- DROID_TEMPLATE *psCurr;
- DROID_TEMPLATE *list = apsStaticTemplates; // assume AI
+ DROID_TEMPLATE *list = apsDroidTemplates[player];
- if (isHumanPlayer(player))
- {
- list = apsDroidTemplates[player]; // was human
- }
-
- for (psCurr = list; psCurr != NULL; psCurr = psCurr->psNext)
+ for (DROID_TEMPLATE *psCurr = list; psCurr != NULL; psCurr = psCurr->psNext)
{
if (strcmp(psCurr->pName, pName) == 0)
{
@@ -533,18 +441,17 @@ DROID_TEMPLATE * getTemplateFromUniqueName(const char *pName, unsigned int playe
*/
DROID_TEMPLATE *getTemplateFromTranslatedNameNoPlayer(char const *pName)
{
- const char *rName;
- DROID_TEMPLATE *psCurr;
-
- for (psCurr = apsStaticTemplates; psCurr != NULL; psCurr = psCurr->psNext)
+ for (int i=0; i < MAX_PLAYERS; i++)
{
- rName = psCurr->pName ? psCurr->pName : psCurr->aName;
- if (strcmp(rName, pName) == 0)
+ for (DROID_TEMPLATE *psCurr = apsDroidTemplates[i]; psCurr != NULL; psCurr = psCurr->psNext)
{
- return psCurr;
+ const char *rName = psCurr->pName ? psCurr->pName : psCurr->aName;
+ if (strcmp(rName, pName) == 0)
+ {
+ return psCurr;
+ }
}
}
-
return NULL;
}
4 src/template.h
View
@@ -5,7 +5,6 @@
//storage
extern DROID_TEMPLATE *apsDroidTemplates[MAX_PLAYERS];
-extern DROID_TEMPLATE *apsStaticTemplates; // for AIs and scripts
extern bool allowDesign;
@@ -24,9 +23,6 @@ bool templateIsIDF(DROID_TEMPLATE *psTemplate);
/// Fills the list with Templates that can be manufactured in the Factory - based on size
void fillTemplateList(std::vector<DROID_TEMPLATE *> &pList, STRUCTURE *psFactory);
-/* gets a template from its aName (when pName is unknown) */
-DROID_TEMPLATE *GetHumanDroidTemplate(const char *aName);
-DROID_TEMPLATE *GetAIDroidTemplate(const char *aName);
/* gets a template from its name - relies on the name being unique */
DROID_TEMPLATE *getTemplateFromUniqueName(const char *pName, unsigned int player);
/* gets a template from its name - relies on the name being unique */
Please sign in to comment.
Something went wrong with that request. Please try again.