mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
* Merged Source Code from Development Trunk: Revision 4063 * ************************************************************ - Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP - This will be the Source for the Beta 2011 Test git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
252 lines
5.6 KiB
C++
252 lines
5.6 KiB
C++
#include "MPXmlTeams.hpp"
|
|
#include "sgp.h"
|
|
#include "FileMan.h"
|
|
#include "expat.h"
|
|
#include "XML.h"
|
|
#include "random.h"
|
|
#include <cstdio>
|
|
|
|
MultiplayerTeams mpTeams = MultiplayerTeams();
|
|
|
|
// fallback data
|
|
const int MultiplayerTeams::random_merc_teams[NUM_RANDOM_MERC_TEAMS][RANDOM_MERC_TEAM_SIZE] = {
|
|
{ 16, 10, 19, 25, 4 , 11, 39 }, // Gus , Shadow, Spider , Raven , Vicki , Red , Meltdown
|
|
{ 173, 36, 28, 2 , 22, 8 , 32 }, // Henning , Scope, Danny , Lynx , Hitman , Steroid , Malice
|
|
{ 12, 175, 20, 23, 48, 34, 17 }, // Reaper , Laura, Cliff , Buzz , Cougar , Nails , Buns
|
|
{ 31, 7, 33, 35, 27, 37, 1 }, // Scully , Ivan , Dr Q , Thor , Len , Wolf , Blood
|
|
};
|
|
|
|
void MultiplayerTeams::SerializeProfiles(int* dest)
|
|
{
|
|
int id;
|
|
int r = Random(teams.size());
|
|
|
|
// if team is already used, choose next
|
|
while (teamsTaken.at(r))
|
|
{
|
|
r++;
|
|
if (r == teams.size())
|
|
r = 0;
|
|
}
|
|
|
|
teamsTaken.at(r) = true;
|
|
id = r;
|
|
|
|
this->SerializeProfiles(dest, id);
|
|
}
|
|
|
|
void MultiplayerTeams::SerializeProfiles(int* dest, int teamID)
|
|
{
|
|
teamID = teamID % this->teams.size();
|
|
for (int i = 0; i < RANDOM_MERC_TEAM_SIZE; i++)
|
|
{
|
|
// poor man's memcpy
|
|
*dest = teams.at(teamID).members.at(i);
|
|
dest++;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void MultiplayerTeams::HandleServerStarted()
|
|
{
|
|
// reset
|
|
teamsTaken = std::vector<bool>(teams.size(), false);
|
|
}
|
|
|
|
void MultiplayerTeams::UseFallbackDataIfNecessary()
|
|
{
|
|
for (size_t team = 0; team < max(NUM_RANDOM_MERC_TEAMS, teams.size()); team++)
|
|
{
|
|
if (teams.size() <= team)
|
|
{
|
|
// create teams 1-4
|
|
teams.push_back(MPTeam());
|
|
}
|
|
|
|
// fill any empty merc slots
|
|
for (int merc = teams.at(team).members.size(); merc < RANDOM_MERC_TEAM_SIZE; merc++)
|
|
{
|
|
teams.at(team).members.push_back(MultiplayerTeams::random_merc_teams[team%NUM_RANDOM_MERC_TEAMS][merc]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN MultiplayerTeams::ReadInMPTeams(STR fileName)
|
|
{
|
|
BOOLEAN result = this->ReadXMLFile(fileName);
|
|
this->UseFallbackDataIfNecessary();
|
|
return result;
|
|
}
|
|
|
|
BOOLEAN MultiplayerTeams::ReadXMLFile(STR fileName)
|
|
{
|
|
|
|
HWFILE hFile;
|
|
UINT32 uiBytesRead;
|
|
UINT32 uiFSize;
|
|
CHAR8 *lpcBuffer;
|
|
|
|
|
|
CHAR8 msg[128];
|
|
sprintf(msg, "Loading %s", fileName);
|
|
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, msg);
|
|
|
|
if(!FileExists(fileName))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// open file
|
|
hFile = FileOpen(fileName, FILE_ACCESS_READ, FALSE);
|
|
if (!hFile)
|
|
{
|
|
// this might issue an error in the caller
|
|
// but we can proceed, actually
|
|
return FALSE;
|
|
}
|
|
|
|
uiFSize = FileGetSize(hFile);
|
|
lpcBuffer = (CHAR*) MemAlloc(uiFSize);
|
|
|
|
// read in block
|
|
if (!FileRead(hFile, lpcBuffer, uiFSize, &uiBytesRead))
|
|
{
|
|
MemFree(lpcBuffer);
|
|
return FALSE;
|
|
}
|
|
|
|
FileClose(hFile);
|
|
|
|
XML_Parser parser = XML_ParserCreate(NULL);
|
|
struct teamsParseData parseData = { };
|
|
parseData.mpTeams = this;
|
|
|
|
XML_SetElementHandler(parser, &MultiplayerTeams::teamsStartElementHandler, &MultiplayerTeams::teamsEndElementHandler);
|
|
XML_SetCharacterDataHandler(parser, this->teamsCharacterDataHandler);
|
|
XML_SetUserData(parser, &parseData);
|
|
|
|
|
|
if (this->initialized)
|
|
this->TrashTeams();
|
|
|
|
if (!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
|
|
{
|
|
// Cannot load, but that's okay. There is fallback data.
|
|
MemFree(lpcBuffer);
|
|
XML_ParserFree(parser);
|
|
return FALSE;
|
|
}
|
|
else
|
|
this->initialized = true;
|
|
|
|
|
|
MemFree(lpcBuffer);
|
|
|
|
XML_ParserFree(parser);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
MultiplayerTeams::MultiplayerTeams()
|
|
{
|
|
this->initialized = false;
|
|
}
|
|
|
|
MultiplayerTeams::~MultiplayerTeams()
|
|
{
|
|
}
|
|
|
|
void MultiplayerTeams::TrashTeams()
|
|
{
|
|
this->teams.clear();
|
|
this->initialized = false;
|
|
}
|
|
|
|
void XMLCALL MultiplayerTeams::teamsStartElementHandler(void *userData, const XML_Char *name, const XML_Char **atts)
|
|
{
|
|
struct teamsParseData * pData = (struct teamsParseData *)userData;
|
|
|
|
if (pData->currentDepth <= pData->maxReadDepth)
|
|
{
|
|
if (!strcmp(name, "mp_teams") && pData->curElement == ELEMENT_NONE)
|
|
{
|
|
// root element
|
|
pData->curElement = ELEMENT_LIST;
|
|
pData->maxReadDepth++;
|
|
}
|
|
else if (!strcmp(name, "team") && pData->curElement == ELEMENT_LIST)
|
|
{
|
|
pData->curElement = ELEMENT;
|
|
MPTeam team = MPTeam();
|
|
|
|
if (atts[0] && !strcmp(atts[0], "name"))
|
|
{
|
|
team.name = std::string(atts[1]);
|
|
}
|
|
else
|
|
{
|
|
team.name = std::string("unnamed team");
|
|
}
|
|
|
|
pData->mpTeams->teams.push_back(team);
|
|
|
|
pData->maxReadDepth++;
|
|
}
|
|
else if (!strcmp(name, "id"))
|
|
{
|
|
pData->curElement = ELEMENT_PROPERTY;
|
|
pData->maxReadDepth++;
|
|
}
|
|
|
|
pData->szCharData[0] = '\0';
|
|
}
|
|
|
|
pData->currentDepth++;
|
|
|
|
return;
|
|
}
|
|
|
|
void XMLCALL MultiplayerTeams::teamsEndElementHandler(void *userData, const XML_Char *name)
|
|
{
|
|
struct teamsParseData *pData = (struct teamsParseData *)userData;
|
|
|
|
if (pData->currentDepth <= pData->maxReadDepth)
|
|
{
|
|
if (!strcmp(name, "mp_teams"))
|
|
{
|
|
pData->curElement = ELEMENT_NONE;
|
|
}
|
|
else if (!strcmp(name, "team"))
|
|
{
|
|
pData->curElement = ELEMENT_LIST;
|
|
}
|
|
else if(!strcmp(name, "id"))
|
|
{
|
|
pData->curElement = ELEMENT;
|
|
|
|
INT8 id = atoi(pData->szCharData);
|
|
pData->mpTeams->teams.back().members.push_back(id);
|
|
}
|
|
|
|
pData->maxReadDepth--;
|
|
}
|
|
|
|
pData->currentDepth--;
|
|
|
|
return;
|
|
}
|
|
|
|
void XMLCALL MultiplayerTeams::teamsCharacterDataHandler(void *userData, const XML_Char *s, int len)
|
|
{
|
|
struct teamsParseData *pData = (struct teamsParseData *)userData;
|
|
|
|
if ((pData->currentDepth <= pData->maxReadDepth)
|
|
&& (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH))
|
|
{
|
|
strncat(pData->szCharData, s, __min((unsigned int)len, MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
|
|
}
|
|
|
|
return;
|
|
}
|