Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'bugfixes' into 3.1

  • Loading branch information...
commit 4879779b631235bdfa5890a0cbfcdeea79023656 2 parents cf77b27 + 9775d0c
automerge authored cybersphinx committed
View
8 lib/netplay/netplay.cpp
@@ -1061,7 +1061,6 @@ int NETinit(bool bFirstCall)
return 0;
}
-
// ////////////////////////////////////////////////////////////////////////
// SHUTDOWN THE CONNECTION.
int NETshutdown(void)
@@ -1072,7 +1071,12 @@ int NETshutdown(void)
if (IPlist)
free(IPlist);
IPlist = NULL;
-
+ if (NetPlay.MOTD)
+ {
+ free(NetPlay.MOTD);
+ }
+ NetPlay.MOTD = NULL;
+ NETdeleteQueue();
SOCKETshutdown();
if (NetPlay.bComms && NetPlay.isUPNP)
View
2  lib/netplay/netqueue.cpp
@@ -1,5 +1,5 @@
-#include "netqueue.h"
#include "lib/framework/frame.h"
+#include "netqueue.h"
// See comments in netqueue.h.
View
3  lib/netplay/netqueue.h
@@ -1,8 +1,7 @@
#ifndef _NET_QUEUE_H_
#define _NET_QUEUE_H_
-#include "lib/framework/types.h"
-
+#include "lib/framework/frame.h"
#include <vector>
#include <list>
#include <deque>
View
12 lib/netplay/nettypes.cpp
@@ -420,6 +420,18 @@ void NETinitQueue(NETQUEUE queue)
}
}
+void NETdeleteQueue(void)
+{
+ for (int i = 0; i < MAX_PLAYERS; ++i)
+ {
+ delete pairQueue(NETnetQueue(i));
+ delete gameQueues[i];
+ }
+
+ delete broadcastQueue;
+
+}
+
void NETsetNoSendOverNetwork(NETQUEUE queue)
{
sendQueue(queue)->setWillNeverGetMessagesForNet(); // Will not be sending over net.
View
2  lib/netplay/nettypes.h
@@ -64,7 +64,7 @@ NetMessage const *NETgetMessage(NETQUEUE queue);///< Returns the current message
void NETinitQueue(NETQUEUE queue); ///< Allocates the queue. Deletes the old queue, if there was one. Avoids a crash on NULL pointer deference when trying to use the queue.
void NETsetNoSendOverNetwork(NETQUEUE queue); ///< Used to mark that a game queue should not be sent over the network (for example, if it is being sent to us, instead).
void NETmoveQueue(NETQUEUE src, NETQUEUE dst); ///< Used for moving the tmpQueue to a netQueue, once a newly-connected client is assigned a player number.
-
+void NETdeleteQueue(void); ///< Delete queues for cleanup
void NETbeginEncode(NETQUEUE queue, uint8_t type);
void NETbeginDecode(NETQUEUE queue, uint8_t type);
bool NETend(void);
View
13 src/component.cpp
@@ -39,6 +39,7 @@
#include "order.h"
#include "projectile.h"
#include "transporter.h"
+#include "mission.h"
#define GetRadius(x) ((x)->sradius)
@@ -531,13 +532,17 @@ static void displayCompObj(DROID *psDroid, bool bButton)
}
else
{
- MAPTILE *psTile = worldTile(psDroid->pos.x, psDroid->pos.y);
pieFlag = pie_SHADOW;
- if (psTile->jammerBits & alliancebits[psDroid->player])
+ brightness = pal_SetBrightness(psDroid->illumination);
+ // NOTE: Beware of transporters that are offscreen, on a mission! We should *not* be checking tiles at this point in time!
+ if (psDroid->droidType != DROID_TRANSPORTER && !missionIsOffworld())
{
- pieFlag |= pie_ECM;
+ MAPTILE *psTile = worldTile(psDroid->pos.x, psDroid->pos.y);
+ if (psTile->jammerBits & alliancebits[psDroid->player])
+ {
+ pieFlag |= pie_ECM;
+ }
}
- brightness = pal_SetBrightness(psDroid->illumination);
}
/* set default components transparent */
View
44 src/droid.cpp
@@ -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++;
}
}
View
14 src/frontend.cpp
@@ -244,7 +244,8 @@ static void startSinglePlayerMenu(void)
addTextButton(FRONTEND_NEWGAME, FRONTEND_POS2X,FRONTEND_POS2Y,_("New Campaign") , WBUT_TXTCENTRE);
addTextButton(FRONTEND_SKIRMISH, FRONTEND_POS3X,FRONTEND_POS3Y, _("Start Skirmish Game"), WBUT_TXTCENTRE);
addTextButton(FRONTEND_CHALLENGES, FRONTEND_POS4X, FRONTEND_POS4Y, _("Challenges"), WBUT_TXTCENTRE);
- addTextButton(FRONTEND_LOADGAME, FRONTEND_POS5X,FRONTEND_POS5Y, _("Load Game"), WBUT_TXTCENTRE);
+ addTextButton(FRONTEND_LOADGAME_MISSION, FRONTEND_POS5X,FRONTEND_POS5Y, _("Load Campaign Game"), WBUT_TXTCENTRE);
+ addTextButton(FRONTEND_LOADGAME_SKIRMISH, FRONTEND_POS6X,FRONTEND_POS6Y, _("Load Skirmish Game"), WBUT_TXTCENTRE);
addSideText (FRONTEND_SIDETEXT ,FRONTEND_SIDEX,FRONTEND_SIDEY,_("SINGLE PLAYER"));
addMultiBut(psWScreen, FRONTEND_BOTFORM, FRONTEND_QUIT, 10, 10, 30, 29, P_("menu", "Return"), IMAGE_RETURN, IMAGE_RETURN_HI, IMAGE_RETURN_HI);
@@ -317,9 +318,14 @@ bool runSinglePlayerMenu(void)
frontEndNewGame();
break;
- case FRONTEND_LOADGAME:
+ case FRONTEND_LOADGAME_MISSION:
SPinit();
- addLoadSave(LOAD_FRONTEND, _("Load Saved Game")); // change mode when loadsave returns
+ addLoadSave(LOAD_FRONTEND_MISSION, _("Load Campaign Saved Game")); // change mode when loadsave returns
+ break;
+
+ case FRONTEND_LOADGAME_SKIRMISH:
+ SPinit();
+ addLoadSave(LOAD_FRONTEND_SKIRMISH, _("Load Skirmish Saved Game")); // change mode when loadsave returns
break;
case FRONTEND_SKIRMISH:
@@ -400,11 +406,13 @@ bool runMultiPlayerMenu(void)
ingame.bHostSetup = true;
bMultiPlayer = true;
bMultiMessages = true;
+ NETinit(true);
game.type = SKIRMISH; // needed?
lastTitleMode = MULTI;
changeTitleMode(MULTIOPTION);
break;
case FRONTEND_JOIN:
+ NETinit(true);
ingame.bHostSetup = false;
if (getLobbyError() != ERROR_INVALID)
{
View
3  src/frontend.h
@@ -172,7 +172,8 @@ enum
FRONTEND_QUIT,
FRONTEND_FASTPLAY, //tutorial menu option
FRONTEND_NEWGAME = 20200, // single player (menu)
- FRONTEND_LOADGAME,
+ FRONTEND_LOADGAME_MISSION,
+ FRONTEND_LOADGAME_SKIRMISH,
FRONTEND_SKIRMISH,
FRONTEND_CHALLENGES,
FRONTEND_HOST = 20300, //multiplayer menu options
View
43 src/game.cpp
@@ -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;
View
34 src/ingameop.cpp
@@ -269,10 +269,20 @@ static bool _intAddInGameOptions(void)
if ((!bMultiPlayer || (NetPlay.bComms == 0)) && !bInTutorial)
{
- // add 'load'
- addIGTextButton(INTINGAMEOP_LOAD, INTINGAMEOP_1_X, INTINGAMEOP_3_Y, INTINGAMEOP_OP_W, _("Load Game"), OPALIGN);
- // add 'save'
- addIGTextButton(INTINGAMEOP_SAVE, INTINGAMEOP_1_X, INTINGAMEOP_4_Y, INTINGAMEOP_OP_W, _("Save Game"), OPALIGN);
+ if (!bMultiPlayer)
+ {
+ // add 'load'
+ addIGTextButton(INTINGAMEOP_LOAD_MISSION, INTINGAMEOP_1_X, INTINGAMEOP_3_Y, INTINGAMEOP_OP_W, _("Load Game"), OPALIGN);
+ // add 'save'
+ addIGTextButton(INTINGAMEOP_SAVE_MISSION, INTINGAMEOP_1_X, INTINGAMEOP_4_Y, INTINGAMEOP_OP_W, _("Save Game"), OPALIGN);
+ }
+ else
+ {
+ // add 'load'
+ addIGTextButton(INTINGAMEOP_LOAD_SKIRMISH, INTINGAMEOP_1_X, INTINGAMEOP_3_Y, INTINGAMEOP_OP_W, _("Load Game"), OPALIGN);
+ // add 'save'
+ addIGTextButton(INTINGAMEOP_SAVE_SKIRMISH, INTINGAMEOP_1_X, INTINGAMEOP_4_Y, INTINGAMEOP_OP_W, _("Save Game"), OPALIGN);
+ }
}
intMode = INT_INGAMEOP; // change interface mode.
@@ -489,15 +499,21 @@ void intProcessInGameOptions(UDWORD id)
// addConsoleMessage(_("GAME SAVED!"), LEFT_JUSTIFY, SYSTEM_MESSAGE);
// }
// break;
- case INTINGAMEOP_LOAD:
+ case INTINGAMEOP_LOAD_MISSION:
intCloseInGameOptions(true, false);
- addLoadSave(LOAD_INGAME, _("Load Saved Game")); // change mode when loadsave returns
+ addLoadSave(LOAD_INGAME_MISSION, _("Load Campaign Saved Game")); // change mode when loadsave returns
break;
- case INTINGAMEOP_SAVE:
+ case INTINGAMEOP_LOAD_SKIRMISH:
intCloseInGameOptions(true, false);
- addLoadSave(SAVE_INGAME, _("Save Game"));
+ addLoadSave(LOAD_INGAME_SKIRMISH, _("Load Skirmish Saved Game")); // change mode when loadsave returns
break;
-
+ case INTINGAMEOP_SAVE_MISSION:
+ intCloseInGameOptions(true, false);
+ addLoadSave(SAVE_INGAME_MISSION, _("Save Campaign Game"));
+ break;
+ case INTINGAMEOP_SAVE_SKIRMISH:
+ intCloseInGameOptions(true, false);
+ addLoadSave(SAVE_INGAME_SKIRMISH, _("Save Skirmish Game"));
// GAME OPTIONS KEYS
case INTINGAMEOP_FXVOL:
case INTINGAMEOP_3DFXVOL:
View
6 src/ingameop.h
@@ -83,8 +83,10 @@ enum
INTINGAMEOP_QUIT = INTINGAMEOP + 1,
INTINGAMEOP_QUIT_CONFIRM, ///< The all important quit button
INTINGAMEOP_RESUME,
- INTINGAMEOP_LOAD,
- INTINGAMEOP_SAVE,
+ INTINGAMEOP_LOAD_MISSION,
+ INTINGAMEOP_LOAD_SKIRMISH,
+ INTINGAMEOP_SAVE_MISSION,
+ INTINGAMEOP_SAVE_SKIRMISH,
INTINGAMEOP_OPTIONS,
INTINGAMEOP_FXVOL,
INTINGAMEOP_FXVOL_S,
View
81 src/keybind.cpp
@@ -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 */
View
69 src/loadsave.cpp
@@ -117,39 +117,51 @@ bool saveInMissionRes(void)
// return whether the save screen was displayed in the middle of a mission
bool saveMidMission(void)
{
- return bLoadSaveMode == SAVE_INGAME;
+ return bLoadSaveMode == SAVE_INGAME_MISSION;
}
// ////////////////////////////////////////////////////////////////////////////
bool addLoadSave(LOADSAVE_MODE savemode, const char *title)
{
- bool bLoad;
-
+ bool bLoad = true;
+ char NewSaveGamePath[PATH_MAX] = {'\0'};
bLoadSaveMode = savemode;
UDWORD slotCount;
-// removed hardcoded values! change with the defines above! -Q
static char sSlotCaps[totalslots][totalslotspace];
static char sSlotTips[totalslots][totalslotspace];
char **i, **files;
switch(savemode)
{
- case LOAD_FRONTEND:
- case LOAD_MISSIONEND:
- case LOAD_INGAME:
- bLoad = true;
- break;
- case SAVE_MISSIONEND:
- case SAVE_INGAME:
- default:
- bLoad = false;
- break;
+ case LOAD_FRONTEND_MISSION:
+ case LOAD_INGAME_MISSION:
+ case LOAD_MISSIONEND:
+ ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "campaign");
+ break;
+ case LOAD_FRONTEND_SKIRMISH:
+ case LOAD_INGAME_SKIRMISH:
+ ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "skirmish");
+ break;
+ case SAVE_MISSIONEND:
+ case SAVE_INGAME_MISSION:
+ ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "campaign");
+ bLoad = false;
+ break;
+ case SAVE_INGAME_SKIRMISH:
+ ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "skirmish");
+ bLoad = false;
+ break;
+ default:
+ ASSERT("Invalid load/save mode!", "Invalid load/save mode!");
+ ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "campaign");
+ break;
}
mode = bLoad;
debug(LOG_SAVE, "called (%d, %s)", bLoad, title);
- if ((bLoadSaveMode == LOAD_INGAME) || (bLoadSaveMode == SAVE_INGAME))
+ if ((bLoadSaveMode == LOAD_INGAME_MISSION) || (bLoadSaveMode == SAVE_INGAME_MISSION)
+ || (bLoadSaveMode == LOAD_INGAME_SKIRMISH) || (bLoadSaveMode == SAVE_INGAME_SKIRMISH))
{
if (!bMultiPlayer || (NetPlay.bComms ==0))
{
@@ -181,8 +193,6 @@ bool addLoadSave(LOADSAVE_MODE savemode, const char *title)
intRemoveReticule();
}
- (void) PHYSFS_mkdir(SaveGamePath); // just in case
-
psRequestScreen = widgCreateScreen(); // init the screen
widgSetTipFont(psRequestScreen,font_regular);
@@ -277,10 +287,10 @@ bool addLoadSave(LOADSAVE_MODE savemode, const char *title)
// fill slots.
slotCount = 0;
- debug(LOG_SAVE, "Searching \"%s\" for savegames", SaveGamePath);
+ debug(LOG_SAVE, "Searching \"%s\" for savegames", NewSaveGamePath);
// add savegame filenames minus extensions to buttons
- files = PHYSFS_enumerateFiles(SaveGamePath);
+ files = PHYSFS_enumerateFiles(NewSaveGamePath);
for (i = files; *i != NULL; ++i)
{
W_BUTTON *button;
@@ -300,7 +310,7 @@ bool addLoadSave(LOADSAVE_MODE savemode, const char *title)
debug(LOG_SAVE, "We found [%s]", *i);
/* Figure save-time */
- snprintf(savefile, sizeof(savefile), "%s/%s", SaveGamePath, *i);
+ snprintf(savefile, sizeof(savefile), "%s/%s", NewSaveGamePath, *i);
savetime = PHYSFS_getLastModTime(savefile);
timeinfo = localtime(&savetime);
strftime(sSlotTips[slotCount], sizeof(sSlotTips[slotCount]), "%x %X", timeinfo);
@@ -330,7 +340,8 @@ bool closeLoadSave(void)
widgDelete(psRequestScreen,LOADSAVE_FORM);
bLoadSaveUp = false;
- if ((bLoadSaveMode == LOAD_INGAME) || (bLoadSaveMode == SAVE_INGAME))
+ if ((bLoadSaveMode == LOAD_INGAME_MISSION) || (bLoadSaveMode == SAVE_INGAME_MISSION)
+ || (bLoadSaveMode == LOAD_INGAME_SKIRMISH) || (bLoadSaveMode == SAVE_INGAME_SKIRMISH))
{
if (!bMultiPlayer || (NetPlay.bComms == 0))
@@ -410,6 +421,7 @@ bool runLoadSave(bool bResetMissionWidgets)
static char sDelete[PATH_MAX];
UDWORD i, campaign;
W_CONTEXT context;
+ char NewSaveGamePath[PATH_MAX] = {'\0'};
id = widgRunScreen(psRequestScreen);
@@ -420,7 +432,14 @@ bool runLoadSave(bool bResetMissionWidgets)
{
goto cleanup;
}
-
+ if (bMultiPlayer)
+ {
+ ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "skirmish");
+ }
+ else
+ {
+ ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "campaign");
+ }
// clicked a load entry
if( id >= LOADENTRY_START && id <= LOADENTRY_END )
{
@@ -429,7 +448,7 @@ bool runLoadSave(bool bResetMissionWidgets)
{
if( ((W_BUTTON *)widgGetFromID(psRequestScreen,id))->pText )
{
- sprintf(sRequestResult, "%s%s%s", SaveGamePath, ((W_BUTTON *)widgGetFromID(psRequestScreen,id))->pText, sExt);
+ sprintf(sRequestResult, "%s%s%s", NewSaveGamePath, ((W_BUTTON *)widgGetFromID(psRequestScreen,id))->pText, sExt);
}
else
{
@@ -457,7 +476,7 @@ bool runLoadSave(bool bResetMissionWidgets)
if (((W_BUTTON *)widgGetFromID(psRequestScreen,id))->pText != NULL)
{
- snprintf(sDelete, sizeof(sDelete), "%s%s%s", SaveGamePath,
+ snprintf(sDelete, sizeof(sDelete), "%s%s%s", NewSaveGamePath,
((W_BUTTON *)widgGetFromID(psRequestScreen,id))->pText, sExt);
}
else
@@ -524,7 +543,7 @@ bool runLoadSave(bool bResetMissionWidgets)
{
sstrcpy(sTemp, widgGetString(psRequestScreen, id));
removeWildcards(sTemp);
- snprintf(sRequestResult, sizeof(sRequestResult), "%s%s%s", SaveGamePath, sTemp, sExt);
+ snprintf(sRequestResult, sizeof(sRequestResult), "%s%s%s", NewSaveGamePath, sTemp, sExt);
if (strlen(sDelete) != 0)
{
deleteSaveGame(sDelete); //only delete game if a new game fills the slot
View
9 src/loadsave.h
@@ -29,11 +29,14 @@
enum LOADSAVE_MODE
{
-LOAD_FRONTEND,
+LOAD_FRONTEND_MISSION,
LOAD_MISSIONEND,
+LOAD_INGAME_MISSION,
+LOAD_FRONTEND_SKIRMISH,
+LOAD_INGAME_SKIRMISH,
SAVE_MISSIONEND,
-LOAD_INGAME,
-SAVE_INGAME
+SAVE_INGAME_MISSION,
+SAVE_INGAME_SKIRMISH
};
/***************************************************************************/
View
14 src/main.cpp
@@ -1040,7 +1040,7 @@ bool getUTF8CmdLine(int* const utfargc, const char*** const utfargv) // explicit
LocalFree(wargv);
return false;
}
- // the following malloc and UTF16toUTF8 will create leaks.
+ // the following malloc and UTF16toUTF8 will be cleaned up in realmain().
*utfargv = (const char**)malloc(sizeof(const char*) * wargc);
if (!*utfargv)
{
@@ -1118,6 +1118,8 @@ int realmain(int argc, char *argv[])
/*** Initialize directory structure ***/
make_dir(ScreenDumpPath, "screenshots", NULL);
make_dir(SaveGamePath, "savegames", NULL);
+ PHYSFS_mkdir("savegames/campaign");
+ PHYSFS_mkdir("savegames/skirmish");
make_dir(MultiCustomMapsPath, "maps", NULL); // MUST have this to prevent crashes when getting map
PHYSFS_mkdir("music");
PHYSFS_mkdir("logs"); // a place to hold our netplay, mingw crash reports & WZ logs
@@ -1162,8 +1164,6 @@ int realmain(int argc, char *argv[])
loadConfig();
- NETinit(true);
-
// parse the command line
if (!ParseCommandLine(utfargc, utfargv))
{
@@ -1313,6 +1313,14 @@ int realmain(int argc, char *argv[])
wzMain3();
saveConfig();
systemShutdown();
+#ifdef WZ_OS_WIN // clean up the memory allocated for the command line conversion
+ for (int i=0; i<argc; i++)
+ {
+ const char*** const utfargvF = &utfargv;
+ free((void *)(*utfargvF)[i]);
+ }
+ free(utfargv);
+#endif
wzShutdown();
debug(LOG_MAIN, "Completed shutting down Warzone 2100");
return EXIT_SUCCESS;
View
2  src/map.cpp
@@ -1063,6 +1063,7 @@ bool mapShutdown(void)
free(psBlockMap[AUX_ASTARMAP]);
psBlockMap[AUX_ASTARMAP] = NULL;
free(psBlockMap[AUX_DANGERMAP]);
+ free(floodbucket);
psBlockMap[AUX_DANGERMAP] = NULL;
for (x = 0; x < MAX_PLAYERS + AUX_MAX; x++)
{
@@ -1071,6 +1072,7 @@ bool mapShutdown(void)
}
map = NULL;
+ floodbucket = NULL;
psGroundTypes = NULL;
mapDecals = NULL;
psMapTiles = NULL;
View
8 src/mission.cpp
@@ -2468,9 +2468,12 @@ static bool _intAddMissionResult(bool result, bool bPlaySuccess)
widgAddButton(psWScreen, &sButInit);
}
+ // FIXME, We got serious issues with savegames at the *END* of some missions, and while they
+ // will load, they don't have the correct state information or other settings.
+ // See transition from CAM2->CAM3 for a example.
/* Only add save option if in the game for real, ie, not fastplay.
- * And the player hasn't just completed the whole game
- * Don't add save option if just lost and in debug mode. */
+ * And the player hasn't just completed the whole game
+ * Don't add save option if just lost and in debug mode.
if (!bMultiPlayer && !testPlayerHasWon() && !(testPlayerHasLost() && getDebugMappingStatus()))
{
//save
@@ -2483,6 +2486,7 @@ static bool _intAddMissionResult(bool result, bool bPlaySuccess)
// automatically save the game to be able to restart a mission
saveGame((char *)"savegames/Autosave.gam", GTYPE_SAVE_START);
}
+ */
}
else
{
View
20 src/move.cpp
@@ -56,7 +56,7 @@
#include "multiplay.h"
#include "multigifts.h"
#include "random.h"
-
+#include "mission.h"
#include "drive.h"
/* max and min vtol heights above terrain */
@@ -1384,11 +1384,19 @@ SDWORD moveCalcDroidSpeed(DROID *psDroid)
CHECK_DROID(psDroid);
- mapX = map_coord(psDroid->pos.x);
- mapY = map_coord(psDroid->pos.y);
- speed = calcDroidSpeed(psDroid->baseSpeed, terrainType(mapTile(mapX,mapY)),
- psDroid->asBits[COMP_PROPULSION].nStat,
- getDroidEffectiveLevel(psDroid));
+ // NOTE: This screws up since the transporter is offscreen still (on a mission!), and we are trying to find terrainType of a tile (that is offscreen!)
+ if (psDroid->droidType == DROID_TRANSPORTER && missionIsOffworld())
+ {
+ PROPULSION_STATS *propulsion = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
+ speed = propulsion->maxSpeed;
+ }
+ else
+ {
+ mapX = map_coord(psDroid->pos.x);
+ mapY = map_coord(psDroid->pos.y);
+ speed = calcDroidSpeed(psDroid->baseSpeed, terrainType(mapTile(mapX,mapY)), psDroid->asBits[COMP_PROPULSION].nStat, getDroidEffectiveLevel(psDroid));
+ }
+
// now offset the speed for the slope of the droid
pitch = angleDelta(psDroid->rot.pitch);
View
2  src/multigifts.cpp
@@ -81,7 +81,7 @@ bool recvGift(NETQUEUE queue)
if (!canGiveOrdersFor(queue.index, from))
{
- debug(LOG_WARNING, "Gift from wrong player.");
+ debug(LOG_WARNING, "Gift (%d) from %d, to %d, queue.index %d", (int)type, (int)from, (int)to, (int)queue.index);
syncDebug("Wrong player.");
return false;
}
View
33 src/multiplay.cpp
@@ -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;
}
View
3  src/scriptobj.cpp
@@ -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;
View
2  src/structure.cpp
@@ -2581,7 +2581,7 @@ bool CheckHaltOnMaxUnitsReached(STRUCTURE *psStructure)
if ((psStructure->player == selectedPlayer) &&
(lastMaxUnitMessage + MAX_UNIT_MESSAGE_PAUSE < gameTime))
{
- addConsoleMessage(_("Command Control Limit Reached - Production Halted"),DEFAULT_JUSTIFY,SYSTEM_MESSAGE);
+ addConsoleMessage(_("Can't build anymore units, Command Control Limit Reached - Production Halted"), DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
lastMaxUnitMessage = gameTime;
}
return true;
View
165 src/template.cpp
@@ -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;
}
View
4 src/template.h
@@ -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.