You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
6.5 KiB

/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plUoid.h"
#include "hsStream.h"
#include "hsUtils.h"
//// plLocation //////////////////////////////////////////////////////////////
const plLocation plLocation::kGlobalFixedLoc(plLocation::kGlobalFixedLocIdx);
const plLocation plLocation::kLocalStartLoc(plLocation::kLocalLocStartIdx);
const plLocation plLocation::kLocalEndLoc(plLocation::kLocalLocEndIdx);
const plLocation plLocation::kNormalStartLoc(plLocation::kNormalLocStartIdx);
const plLocation plLocation::kGlobalServerLoc(plLocation::kGlobalServerLocIdx, plLocation::kReserved);
const plLocation plLocation::kInvalidLoc;
plLocation::plLocation(const plLocation& toCopyFrom)
{
*this = toCopyFrom;
}
void plLocation::Read(hsStream* s)
{
s->LogReadSwap(&fSequenceNumber, "Location Sequence Number");
s->LogReadSwap(&fFlags, "Location Flags");
}
void plLocation::Write(hsStream* s) const
{
s->WriteSwap(fSequenceNumber);
s->WriteSwap(fFlags);
}
plLocation& plLocation::operator=(const plLocation& rhs)
{
fSequenceNumber = rhs.fSequenceNumber;
fFlags = rhs.fFlags;
return *this;
}
hsBool plLocation::operator==(const plLocation& u) const
{
// Ignore the itinerant flag when comparing, because
return (fSequenceNumber == u.fSequenceNumber) && ((fFlags & ~kItinerant) == (u.fFlags & ~kItinerant));
}
void plLocation::Set(UInt32 seqNum)
{
fSequenceNumber = seqNum;
}
void plLocation::Invalidate()
{
fSequenceNumber = kInvalidLocIdx;
fFlags = 0; // Set to kInvalid?
}
hsBool plLocation::IsValid() const
{
return (fSequenceNumber == kInvalidLocIdx) ? false : true;
}
hsBool plLocation::IsReserved() const
{
return hsCheckBits(fFlags, kReserved);
}
hsBool plLocation::IsItinerant() const
{
return hsCheckBits(fFlags, kItinerant);
}
hsBool plLocation::IsVirtual() const
{
// This returns whether the location is "virtual", i.e. isn't a true room per se. Like fixed keys
if (fSequenceNumber == kGlobalFixedLocIdx)
return true;
return false;
}
// THIS SHOULD BE FOR DEBUGGING ONLY <hint hint>
char* plLocation::StringIze(char* str) const // Format to displayable string
{
sprintf(str, "S0x%xF0x%x", fSequenceNumber, int(fFlags));
return str;
}
plLocation plLocation::MakeReserved(UInt32 number)
{
return plLocation(kReservedLocAvailableStart + number, kReserved);
}
plLocation plLocation::MakeNormal(UInt32 number)
{
return plLocation(kNormalLocStartIdx + number);
}
//// plUoid //////////////////////////////////////////////////////////////////
plUoid::plUoid(const plLocation& location, UInt16 classType, const char* objectName, const plLoadMask& m)
{
fObjectName = nil;
Invalidate();
fLocation = location;
fClassType = classType;
fObjectName = hsStrcpy(objectName);
fLoadMask = m;
fClonePlayerID = 0;
}
plUoid::plUoid(const plUoid& src)
{
fObjectName = nil;
Invalidate();
*this = src;
}
plUoid::~plUoid()
{
Invalidate();
}
void plUoid::Read(hsStream* s)
{
hsAssert(fObjectName == nil, "Reading over an old uoid? You're just asking for trouble, aren't you?");
// first read contents flags
UInt8 contents = s->ReadByte();
fLocation.Read(s);
// conditional loadmask read
if (contents & kHasLoadMask)
fLoadMask.Read(s);
else
fLoadMask.SetAlways();
s->LogReadSwap(&fClassType, "ClassType");
s->LogReadSwap(&fObjectID, "ObjectID");
s->LogSubStreamPushDesc("ObjectName");
fObjectName = s->LogReadSafeString();
// conditional cloneIDs read
if (contents & kHasCloneIDs)
{
s->LogReadSwap( &fCloneID ,"CloneID");
UInt16 dummy;
s->LogReadSwap(&dummy, "dummy"); // To avoid breaking format
s->LogReadSwap( &fClonePlayerID ,"ClonePlayerID");
}
else
{
fCloneID = 0;
fClonePlayerID = 0;
}
}
void plUoid::Write(hsStream* s) const
{
// first write contents byte
UInt8 contents = IsClone() ? kHasCloneIDs : 0;
if (fLoadMask.IsUsed())
contents |= kHasLoadMask;
s->WriteByte(contents);
fLocation.Write(s);
// conditional loadmask write
if (contents & kHasLoadMask)
fLoadMask.Write(s);
s->WriteSwap( fClassType );
s->WriteSwap( fObjectID );
s->WriteSafeString( fObjectName );
// conditional cloneIDs write
if (contents & kHasCloneIDs)
{
s->WriteSwap(fCloneID);
UInt16 dummy = 0;
s->WriteSwap(dummy); // to avoid breaking format
s->WriteSwap(fClonePlayerID);
}
}
void plUoid::Invalidate()
{
fObjectID = 0;
fCloneID = 0;
fClonePlayerID = 0;
fClassType = 0;
if (fObjectName)
delete [] fObjectName;
fObjectName = nil;
fLocation.Invalidate();
fLoadMask = plLoadMask::kAlways;
}
hsBool plUoid::IsValid() const
{
if (!fLocation.IsValid() || fObjectName == nil)
return false;
return true;
}
hsBool plUoid::operator==(const plUoid& u) const
{
return fLocation == u.fLocation
&& fLoadMask == u.fLoadMask
&& fClassType == u.fClassType
&& hsStrEQ(fObjectName, u.fObjectName)
&& fObjectID == u.fObjectID
&& fCloneID == u.fCloneID
&& fClonePlayerID == u.fClonePlayerID;
}
plUoid& plUoid::operator=(const plUoid& rhs)
{
fObjectID = rhs.fObjectID;
fCloneID = rhs.fCloneID;
fClonePlayerID = rhs.fClonePlayerID;
fClassType = rhs.fClassType;
if (fObjectName)
delete [] fObjectName;
fObjectName = hsStrcpy(rhs.fObjectName);
fLocation = rhs.fLocation;
fLoadMask = rhs.fLoadMask;
return *this;
}
// THIS SHOULD BE FOR DEBUGGING ONLY <hint hint>
char* plUoid::StringIze(char* str) const // Format to displayable string
{
sprintf(str, "(0x%x:0x%x:%s:C:[%lu,%lu])",
fLocation.GetSequenceNumber(),
int(fLocation.GetFlags()),
fObjectName,
GetClonePlayerID(),
GetCloneID());
return str;
}