2016-03-12 01:20:51 +01:00
|
|
|
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation
|
|
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
2016-03-11 14:57:17 +01:00
|
|
|
|
2016-03-29 03:03:54 +02:00
|
|
|
#include "Engine/StdH.h"
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
#include <Engine/Entities/PlayerCharacter.h>
|
|
|
|
#include <Engine/Base/Timer.h>
|
|
|
|
#include <Engine/Base/Stream.h>
|
|
|
|
#include <Engine/Network/NetworkMessage.h>
|
|
|
|
|
2016-03-29 03:03:54 +02:00
|
|
|
#ifdef PLATFORM_WIN32
|
2016-03-11 14:57:17 +01:00
|
|
|
typedef HRESULT __stdcall CoCreateGuid_t(UBYTE *pguid);
|
2016-03-29 03:03:54 +02:00
|
|
|
#else
|
|
|
|
#include <stdlib.h>
|
|
|
|
#endif
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
// get a GUID from system
|
|
|
|
static void GetGUID(UBYTE aub[16])
|
|
|
|
{
|
2016-03-29 03:03:54 +02:00
|
|
|
#ifdef PLATFORM_WIN32
|
2016-03-11 14:57:17 +01:00
|
|
|
HINSTANCE hOle32Lib = NULL;
|
|
|
|
CoCreateGuid_t *pCoCreateGuid = NULL;
|
|
|
|
|
|
|
|
try {
|
|
|
|
// load ole32
|
|
|
|
hOle32Lib = ::LoadLibraryA( "ole32.dll");
|
|
|
|
if( hOle32Lib == NULL) {
|
|
|
|
ThrowF_t(TRANS("Cannot load ole32.dll."));
|
|
|
|
}
|
|
|
|
|
|
|
|
// find GUID function
|
|
|
|
pCoCreateGuid = (CoCreateGuid_t*)GetProcAddress(hOle32Lib, "CoCreateGuid");
|
|
|
|
if (pCoCreateGuid==NULL) {
|
|
|
|
ThrowF_t(TRANS("Cannot find CoCreateGuid()."));
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the guid
|
|
|
|
HRESULT hres = pCoCreateGuid(&aub[0]);
|
|
|
|
|
|
|
|
// check for success
|
|
|
|
if (hres!=S_OK) {
|
|
|
|
ThrowF_t(TRANS("CoCreateGuid(): Error 0x%08x"), hres);
|
|
|
|
}
|
|
|
|
|
|
|
|
// free the ole32 library
|
|
|
|
FreeLibrary(hOle32Lib);
|
|
|
|
|
|
|
|
} catch(char *strError) {
|
|
|
|
FatalError(TRANS("Cannot make GUID for a player:\n%s"), strError);
|
|
|
|
}
|
2016-03-29 03:03:54 +02:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
// !!! FIXME : rcg10112001 Is this sufficient for these purposes?
|
|
|
|
for (int i = 0; i < sizeof (aub) / sizeof (aub[0]); i++)
|
|
|
|
aub[i] = (UBYTE) (255.0 * rand() / (RAND_MAX + 1.0));
|
|
|
|
|
|
|
|
#endif
|
2016-03-11 14:57:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Default constructor -- no character.
|
|
|
|
*/
|
|
|
|
CPlayerCharacter::CPlayerCharacter(void)
|
|
|
|
: pc_strName("<invalid player>"), pc_strTeam("")
|
|
|
|
{
|
|
|
|
memset(pc_aubGUID, 0, PLAYERGUIDSIZE);
|
|
|
|
memset(pc_aubAppearance, 0, MAX_PLAYERAPPEARANCE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a new character with its name.
|
|
|
|
*/
|
|
|
|
CPlayerCharacter::CPlayerCharacter(const CTString &strName)
|
|
|
|
: pc_strName(strName), pc_strTeam("")
|
|
|
|
{
|
|
|
|
// if the name passed to constructor is empty string
|
|
|
|
if (strName=="") {
|
|
|
|
// make this an unnamed player
|
|
|
|
pc_strName = "<unnamed player>";
|
|
|
|
}
|
|
|
|
// create the guid
|
|
|
|
GetGUID(pc_aubGUID);
|
|
|
|
memset(pc_aubAppearance, 0, MAX_PLAYERAPPEARANCE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPlayerCharacter::Load_t( const CTFileName &fnFile) // throw char *
|
|
|
|
{
|
|
|
|
CTFileStream strm;
|
|
|
|
strm.Open_t(fnFile);
|
|
|
|
Read_t(&strm);
|
|
|
|
strm.Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPlayerCharacter::Save_t( const CTFileName &fnFile) // throw char *
|
|
|
|
{
|
|
|
|
CTFileStream strm;
|
|
|
|
strm.Create_t(fnFile);
|
|
|
|
Write_t(&strm);
|
|
|
|
strm.Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read character from a stream.
|
|
|
|
*/
|
|
|
|
void CPlayerCharacter::Read_t(CTStream *pstr) // throw char *
|
|
|
|
{
|
|
|
|
pstr->ExpectID_t("PLC4");
|
|
|
|
(*pstr)>>pc_strName>>pc_strTeam;
|
|
|
|
pstr->Read_t(pc_aubGUID, sizeof(pc_aubGUID));
|
|
|
|
pstr->Read_t(pc_aubAppearance, sizeof(pc_aubAppearance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write character into a stream.
|
|
|
|
*/
|
|
|
|
void CPlayerCharacter::Write_t(CTStream *pstr) // throw char *
|
|
|
|
{
|
|
|
|
pstr->WriteID_t("PLC4");
|
|
|
|
(*pstr)<<pc_strName<<pc_strTeam;
|
|
|
|
pstr->Write_t(pc_aubGUID, sizeof(pc_aubGUID));
|
|
|
|
pstr->Write_t(pc_aubAppearance, sizeof(pc_aubAppearance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get character name. */
|
|
|
|
const CTString &CPlayerCharacter::GetName(void) const
|
|
|
|
{
|
|
|
|
return pc_strName;
|
|
|
|
};
|
|
|
|
const CTString CPlayerCharacter::GetNameForPrinting(void) const
|
|
|
|
{
|
|
|
|
CTString strName(pc_strName);
|
|
|
|
// get rid of newlines in the name
|
|
|
|
strName.ReplaceSubstr("\n", "");
|
|
|
|
strName.ReplaceSubstr("\r", "");
|
|
|
|
return "^o"+pc_strName+"^r";
|
|
|
|
}
|
|
|
|
/* Set character name. */
|
|
|
|
void CPlayerCharacter::SetName(CTString strName)
|
|
|
|
{
|
|
|
|
// limit string length to 20 characters not including decorated text control codes
|
|
|
|
// strName.TrimRightNaked(20); !!!! needs checking
|
|
|
|
pc_strName = strName;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Get character team. */
|
|
|
|
const CTString &CPlayerCharacter::GetTeam(void) const
|
|
|
|
{
|
|
|
|
return pc_strTeam;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CTString CPlayerCharacter::GetTeamForPrinting(void) const
|
|
|
|
{
|
|
|
|
return "^o"+pc_strTeam+"^r";
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set character team. */
|
|
|
|
void CPlayerCharacter::SetTeam(CTString strTeam)
|
|
|
|
{
|
|
|
|
// limit string length to 20 characters not including decorated text control codes
|
|
|
|
// strTeam.TrimRightNaked(20); !!!! needs checking
|
|
|
|
pc_strTeam = strTeam;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Assignment operator. */
|
|
|
|
CPlayerCharacter &CPlayerCharacter::operator=(const CPlayerCharacter &pcOther)
|
|
|
|
{
|
|
|
|
ASSERT(this!=NULL && &pcOther!=NULL);
|
|
|
|
pc_strName = pcOther.pc_strName;
|
|
|
|
pc_strTeam = pcOther.pc_strTeam;
|
|
|
|
memcpy(pc_aubGUID, pcOther.pc_aubGUID, PLAYERGUIDSIZE);
|
|
|
|
memcpy(pc_aubAppearance, pcOther.pc_aubAppearance, MAX_PLAYERAPPEARANCE);
|
|
|
|
return *this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Comparison operator. */
|
|
|
|
BOOL CPlayerCharacter::operator==(const CPlayerCharacter &pcOther) const
|
|
|
|
{
|
|
|
|
for(INDEX i=0;i<PLAYERGUIDSIZE; i++) {
|
|
|
|
if (pc_aubGUID[i] != pcOther.pc_aubGUID[i]) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
};
|
|
|
|
|
|
|
|
// stream operations
|
|
|
|
CTStream &operator<<(CTStream &strm, CPlayerCharacter &pc)
|
|
|
|
{
|
|
|
|
pc.Write_t(&strm);
|
|
|
|
return strm;
|
|
|
|
};
|
|
|
|
CTStream &operator>>(CTStream &strm, CPlayerCharacter &pc)
|
|
|
|
{
|
|
|
|
pc.Read_t(&strm);
|
|
|
|
return strm;
|
|
|
|
};
|
|
|
|
// message operations
|
|
|
|
CNetworkMessage &operator<<(CNetworkMessage &nm, CPlayerCharacter &pc)
|
|
|
|
{
|
|
|
|
nm<<pc.pc_strName<<pc.pc_strTeam;
|
|
|
|
nm.Write(pc.pc_aubGUID, PLAYERGUIDSIZE);
|
|
|
|
nm.Write(pc.pc_aubAppearance, MAX_PLAYERAPPEARANCE);
|
|
|
|
return nm;
|
|
|
|
};
|
|
|
|
CNetworkMessage &operator>>(CNetworkMessage &nm, CPlayerCharacter &pc)
|
|
|
|
{
|
|
|
|
nm>>pc.pc_strName>>pc.pc_strTeam;
|
|
|
|
nm.Read(pc.pc_aubGUID, PLAYERGUIDSIZE);
|
|
|
|
nm.Read(pc.pc_aubAppearance, MAX_PLAYERAPPEARANCE);
|
|
|
|
return nm;
|
|
|
|
};
|