Browse Source

Merge pull request #300 from Mystler/newstartup

Avatar clothing files
Adam Johnson 11 years ago
parent
commit
6025621eda
  1. 54
      Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp
  2. 3
      Sources/Plasma/FeatureLib/pfPython/cyAvatar.h
  3. 27
      Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp
  4. 1
      Sources/Plasma/NucleusLib/inc/plCreatableIndex.h
  5. 43
      Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp
  6. 4
      Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h
  7. 6
      Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp
  8. 113
      Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.cpp
  9. 28
      Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.h
  10. 38
      Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.cpp
  11. 9
      Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.h
  12. 1
      Sources/Plasma/PubUtilLib/plMessage/CMakeLists.txt
  13. 106
      Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.cpp
  14. 24
      Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.h
  15. 67
      Sources/Plasma/PubUtilLib/plMessage/plLoadClothingMsg.h
  16. 3
      Sources/Plasma/PubUtilLib/plMessage/plMessageCreatable.h
  17. 2
      Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp
  18. 3
      Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp

54
Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp

@ -1592,6 +1592,60 @@ void cyAvatar::PlaySimpleAnimation(const plString& animName)
}
}
/////////////////////////////////////////////////////////////////////////////
//
// Function : SaveClothingToFile
// PARAMETERS : filename - file to save to
//
// PURPOSE : Save the avatar's clothing to a file. If only a filename is
// given, it will write to UserData/Avatars.
//
bool cyAvatar::SaveClothingToFile(plFileName filename)
{
if (fRecvr.Count() > 0) {
plArmatureMod* avatar = plAvatarMgr::FindAvatar(fRecvr[0]);
if (avatar) {
plClothingOutfit* cl = avatar->GetClothingOutfit();
if (cl) {
// Save file in UserData/Avatars if only a filename is given
if (!filename.StripFileName().IsValid()) {
plFileName path = plFileName::Join(plFileSystem::GetUserDataPath(), "Avatars");
plFileSystem::CreateDir(path, true);
filename = plFileName::Join(path, filename);
}
return cl->WriteToFile(filename);
}
}
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
//
// Function : LoadClothingFromFile
// PARAMETERS : filename - file to load from
//
// PURPOSE : Load the avatar's clothing from a file. If only a filename is
// given, it will read from UserData/Avatars.
//
bool cyAvatar::LoadClothingFromFile(plFileName filename)
{
if (fRecvr.Count() > 0) {
plArmatureMod* avatar = plAvatarMgr::FindAvatar(fRecvr[0]);
if (avatar) {
plClothingOutfit* cl = avatar->GetClothingOutfit();
if (cl) {
// Search for file in UserData/Avatars if only a filename is given
if (!filename.StripFileName().IsValid())
filename = plFileName::Join(plFileSystem::GetUserDataPath(), "Avatars", filename);
cl->SetClothingFile(filename);
return cl->ReadClothing();
}
}
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
//
// Function : ChangeAvatar

3
Sources/Plasma/FeatureLib/pfPython/cyAvatar.h

@ -410,6 +410,9 @@ public:
virtual void PlaySimpleAnimation(const plString& animName);
virtual bool SaveClothingToFile(plFileName filename);
virtual bool LoadClothingFromFile(plFileName filename);
/////////////////////////////////////////////////////////////////////////////
//
// Function : ChangeAvatar

27
Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp

@ -597,6 +597,30 @@ PYTHON_METHOD_DEFINITION(ptAvatar, playSimpleAnimation, args)
PYTHON_RETURN_NONE;
}
PYTHON_METHOD_DEFINITION(ptAvatar, saveClothingToFile, args)
{
PyObject* filename;
if (!PyArg_ParseTuple(args, "O", &filename) || !PyString_CheckEx(filename))
{
PyErr_SetString(PyExc_TypeError, "saveClothingToFile expects a string object");
PYTHON_RETURN_ERROR;
}
PYTHON_RETURN_BOOL(self->fThis->SaveClothingToFile(PyString_AsStringEx(filename)));
}
PYTHON_METHOD_DEFINITION(ptAvatar, loadClothingFromFile, args)
{
PyObject* filename;
if (!PyArg_ParseTuple(args, "O", &filename) || !PyString_CheckEx(filename))
{
PyErr_SetString(PyExc_TypeError, "loadClothingFromFile expects a string object");
PYTHON_RETURN_ERROR;
}
PYTHON_RETURN_BOOL(self->fThis->LoadClothingFromFile(PyString_AsStringEx(filename)));
}
PYTHON_START_METHODS_TABLE(ptAvatar)
PYTHON_METHOD(ptAvatar, netForce, "Params: forceFlag\nSpecify whether this object needs to use messages that are forced to the network\n"
"- This is to be used if your Python program is running on only one client\n"
@ -651,6 +675,9 @@ PYTHON_START_METHODS_TABLE(ptAvatar)
PYTHON_METHOD(ptAvatar, unRegisterForBehaviorNotify, "Params: selfKey\nThis will unregister behavior notifications"),
PYTHON_METHOD(ptAvatar, playSimpleAnimation, "Params: animName\nPlay simple animation on avatar"),
PYTHON_METHOD(ptAvatar, saveClothingToFile, "Params: filename\nSave avatar clothing to a file"),
PYTHON_METHOD(ptAvatar, loadClothingFromFile, "Params: filename\nLoad avatar clothing from a file"),
PYTHON_END_METHODS_TABLE;
PYTHON_GLOBAL_METHOD_DEFINITION(PtSetBehaviorLoopCount, args, "Params: behaviorKey,stage,loopCount,netForce\nThis will set the loop count for a particular stage in a multistage behavior")

1
Sources/Plasma/NucleusLib/inc/plCreatableIndex.h

@ -951,6 +951,7 @@ CLASS_INDEX_LIST_START
CLASS_INDEX(pfGameScoreListMsg),
CLASS_INDEX(pfGameScoreTransferMsg),
CLASS_INDEX(pfGameScoreUpdateMsg),
CLASS_INDEX(plLoadClothingMsg),
CLASS_INDEX_LIST_END
#endif // plCreatableIndex_inc

43
Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp

@ -84,6 +84,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plMessage/plListenerMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plMessage/plParticleUpdateMsg.h"
#include "plMessage/plLoadClothingMsg.h"
#include "plParticleSystem/plParticleSystem.h"
#include "plParticleSystem/plParticleSDLMod.h"
@ -784,29 +785,22 @@ void plArmatureMod::WindowActivate(bool active)
}
}
char *plArmatureMod::fSpawnPointOverride = nil;
plString plArmatureMod::fSpawnPointOverride;
void plArmatureMod::SetSpawnPointOverride( const char *overrideObjName )
void plArmatureMod::SetSpawnPointOverride(const plString &overrideObjName)
{
delete [] fSpawnPointOverride;
if( overrideObjName == nil )
fSpawnPointOverride = nil;
else
{
fSpawnPointOverride = hsStrcpy( overrideObjName );
strlwr( fSpawnPointOverride );
}
fSpawnPointOverride = overrideObjName.ToLower();
}
int plArmatureMod::IFindSpawnOverride( void )
int plArmatureMod::IFindSpawnOverride()
{
if( fSpawnPointOverride == nil || fSpawnPointOverride[ 0 ] == 0 )
if (fSpawnPointOverride.IsEmpty())
return -1;
int i;
int i;
plAvatarMgr *mgr = plAvatarMgr::GetInstance();
for( i = 0; i < mgr->NumSpawnPoints(); i++ )
for (i = 0; i < mgr->NumSpawnPoints(); i++)
{
const plString &name = mgr->GetSpawnPoint( i )->GetTarget(0)->GetKeyName();
const plString &name = mgr->GetSpawnPoint(i)->GetTarget(0)->GetKeyName();
if (name.Find(fSpawnPointOverride, plString::kCaseInsensitive) >= 0)
return i; // Found it!
}
@ -1300,15 +1294,11 @@ bool plArmatureMod::MsgReceive(plMessage* msg)
}
}
// copy the user string over
const char* userStr = avLoadMsg->GetUserStr();
if (userStr)
fUserStr = userStr;
else
fUserStr = "";
// We also want to use the trigger msg when loading an avatar
MsgReceive(avLoadMsg->GetTriggerMsg());
return true;
}
}
plLoadCloneMsg *cloneMsg = plLoadCloneMsg::ConvertNoRef(msg);
if (cloneMsg)
@ -1347,6 +1337,15 @@ bool plArmatureMod::MsgReceive(plMessage* msg)
}
}
plLoadClothingMsg *clothingMsg = plLoadClothingMsg::ConvertNoRef(msg);
if (clothingMsg)
{
// We got a clothing file and are supposed to load our avatar from it.
// Let's tell our outfit to do so!
fClothingOutfit->SetClothingFile(clothingMsg->GetClothingFile());
return true;
}
plLinkEffectBCMsg *linkBCMsg = plLinkEffectBCMsg::ConvertNoRef(msg);
if (linkBCMsg)
{

4
Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h

@ -329,7 +329,7 @@ public:
static void SetMouseTurnSensitivity(float val) { fMouseTurnSensitivity = val / 150.f; }
static float GetMouseTurnSensitivity() { return fMouseTurnSensitivity * 150.f; }
static void SetSpawnPointOverride( const char *overrideObjName );
static void SetSpawnPointOverride(const plString &overrideObjName);
static void WindowActivate(bool active);
void SetFollowerParticleSystemSO(plSceneObject *follower);
plSceneObject *GetFollowerParticleSystemSO();
@ -426,7 +426,7 @@ protected:
hsTArray<const plSceneObject*> fClothToSOMap;
plArmatureEffectsMgr *fEffects;
plSceneObject *fFollowerParticleSystemSO;
static char *fSpawnPointOverride;
static plString fSpawnPointOverride;
// These vectors are used with relevance regions for culling out other objects
hsBitVector fRegionsImIn;

6
Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp

@ -193,8 +193,10 @@ void plAvBrainHuman::Activate(plArmatureModBase *avMod)
if (fAvMod->GetClothingOutfit() && fAvMod->GetClothingOutfit()->fGroup != plClothingMgr::kClothingBaseNoOptions)
{
if (fAvMod->IsLocalAvatar())
fAvMod->GetClothingOutfit()->ReadFromVault();
if (fAvMod->IsLocalAvatar())
{
fAvMod->GetClothingOutfit()->ReadClothing();
}
else
{
fAvMod->GetClothingOutfit()->WearDefaultClothing();

113
Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.cpp

@ -430,7 +430,8 @@ bool plClothingBase::MsgReceive(plMessage* msg)
/////////////////////////////////////////////////////////////////////////////
plClothingOutfit::plClothingOutfit() :
fTargetLayer(nil), fBase(nil), fGroup(0), fAvatar(nil), fSynchClients(false), fMaterial(nil), fVaultSaveEnabled(true), fMorphsInitDone(false)
fTargetLayer(nullptr), fBase(nullptr), fGroup(0), fAvatar(nullptr), fSynchClients(false), fMaterial(nullptr),
fVaultSaveEnabled(true), fMorphsInitDone(false)
{
fSkinTint.Set(1.f, 0.84, 0.71, 1.f);
fItems.Reset();
@ -802,15 +803,24 @@ void plClothingOutfit::IHandleMorphSDR(plStateDataRecord *sdr)
morph->SetCurrentStateFrom(sdr);
}
void plClothingOutfit::ReadFromVault()
bool plClothingOutfit::ReadClothing()
{
// Have we set a clothing file? If that's the case, load from there.
if (fClothingFile.IsValid())
return IReadFromFile(fClothingFile);
else
return IReadFromVault();
}
bool plClothingOutfit::IReadFromVault()
{
SetupMorphSDL();
WearDefaultClothing();
RelVaultNode * rvn;
if (nil == (rvn = VaultGetAvatarOutfitFolderIncRef()))
return;
RelVaultNode * rvn = VaultGetAvatarOutfitFolderIncRef();
if (!rvn)
return false;
ARRAY(RelVaultNode*) nodes;
rvn->GetChildNodesIncRef(plVault::kNodeType_SDL, 1, &nodes);
@ -844,6 +854,7 @@ void plClothingOutfit::ReadFromVault()
ForceUpdate(true);
rvn->DecRef();
return true;
}
void plClothingOutfit::SaveCustomizations(bool retry /* = true */)
@ -1135,7 +1146,7 @@ void plClothingOutfit::WearMaintainerOutfit()
void plClothingOutfit::RemoveMaintainerOutfit()
{
ReadFromVault();
ReadClothing();
fVaultSaveEnabled = true;
}
@ -1482,6 +1493,91 @@ void plClothingOutfit::SetupMorphSDL()
}
}
bool plClothingOutfit::WriteToFile(const plFileName &filename)
{
if (!filename.IsValid())
return false;
RelVaultNode* rvn = VaultGetAvatarOutfitFolderIncRef();
if (!rvn)
return false;
hsUNIXStream S;
if (!S.Open(filename, "wb")) {
rvn->DecRef();
return false;
}
S.WriteByte(fGroup);
ARRAY(RelVaultNode*) nodes;
rvn->GetChildNodesIncRef(plVault::kNodeType_SDL, 1, &nodes);
S.WriteLE32(nodes.Count());
for (size_t i = 0; i < nodes.Count(); i++) {
VaultSDLNode sdl(nodes[i]);
S.WriteLE32(sdl.GetSDLDataLength());
if (sdl.GetSDLDataLength())
S.Write(sdl.GetSDLDataLength(), sdl.GetSDLData());
nodes[i]->DecRef();
}
rvn->DecRef();
S.Close();
return true;
}
bool plClothingOutfit::IReadFromFile(const plFileName &filename)
{
if (!filename.IsValid())
return false;
hsUNIXStream S;
if (!S.Open(filename))
return false;
bool isLocalAvatar = plAvatarMgr::GetInstance()->GetLocalAvatar()->GetClothingOutfit() == this;
uint8_t gender = S.ReadByte();
if (gender != fGroup) {
if (isLocalAvatar) {
if (gender == plClothingMgr::kClothingBaseMale)
plClothingMgr::ChangeAvatar("Male", filename);
else if (gender == plClothingMgr::kClothingBaseFemale)
plClothingMgr::ChangeAvatar("Female", filename);
}
S.Close();
return true;
}
StripAccessories();
uint32_t nodeCount = S.ReadLE32();
for (size_t i = 0; i < nodeCount; i++) {
uint32_t dataLen = S.ReadLE32();
if (dataLen) {
plString sdlRecName;
int sdlRecVersion;
plStateDataRecord::ReadStreamHeader(&S, &sdlRecName, &sdlRecVersion);
plStateDescriptor* desc = plSDLMgr::GetInstance()->FindDescriptor(sdlRecName, sdlRecVersion);
if (desc) {
plStateDataRecord sdlDataRec(desc);
if (sdlDataRec.Read(&S, 0)) {
if (sdlRecName == kSDLMorphSequence)
IHandleMorphSDR(&sdlDataRec);
else
plClothingSDLModifier::HandleSingleSDR(&sdlDataRec, this);
}
}
}
}
S.Close();
fSynchClients = true;
ForceUpdate(true);
SaveCustomizations(); // Sync with the vault
return true;
}
/////////////////////////////////////////////////////////////////////////////
@ -1832,9 +1928,8 @@ void plClothingMgr::IAddItem(plClothingItem *item)
hsAssert(false, "Couldn't match all elements of added clothing item.");
}
void plClothingMgr::ChangeAvatar(char *name)
void plClothingMgr::ChangeAvatar(const char* name, const plFileName &clothingFile)
{
plAvatarMgr::GetInstance()->UnLoadLocalPlayer();
plAvatarMgr::GetInstance()->LoadPlayer(name, nil);
plAvatarMgr::GetInstance()->LoadPlayerFromFile(name, "", clothingFile);
}

28
Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.h

@ -215,25 +215,49 @@ public:
void IInstanceSharedMeshes(plClothingItem *item);
void IRemoveSharedMeshes(plClothingItem *item);
void ReadFromVault();
/** This will load the avatar clothing. If a clothing file is set,
* we will load from the file, otherwise from the vault.
*/
bool ReadClothing();
void WriteToVault();
void WriteToVault(const ARRAY(plStateDataRecord*) & SDRs);
/** Write the avatar clothing to a file */
bool WriteToFile(const plFileName &filename);
void SetupMorphSDL();
// XXX Don't use this. Temp function for a temp HACK console command.
void DirtyTileset(int tileset);
/** Instruct this plClothingOutfit to read clothing from the given file */
void SetClothingFile(const plFileName &file) { fClothingFile = file; }
/** Returns the clothing file of this outfit. If there is none, an empty string
* will be returned.
*/
plFileName GetClothingFile() const { return fClothingFile; }
protected:
hsBitVector fDirtyItems;
bool fVaultSaveEnabled;
bool fMorphsInitDone;
plFileName fClothingFile;
void IAddItem(plClothingItem *item);
void IRemoveItem(plClothingItem *item);
bool ITintItem(plClothingItem *item, hsColorRGBA color, uint8_t layer);
bool IMorphItem(plClothingItem *item, uint8_t layer, uint8_t delta, float weight);
void IHandleMorphSDR(plStateDataRecord *sdr);
bool IReadFromVault();
/** Read the avatar clothing from a file.
* A local avatar will change the clothing group to the one in the file.
* A local avatar will be invisible if the file does not exist. (used in the Startup age)
*/
bool IReadFromFile(const plFileName &filename);
void IUpdate();
@ -281,7 +305,7 @@ public:
plClothingItem *GetLRMatch(plClothingItem *item);
bool IsLRMatch(plClothingItem *item1, plClothingItem *item2);
static void ChangeAvatar(char *name);
static void ChangeAvatar(const char* name, const plFileName &clothingFile = "");
static plClothingMgr *GetClothingMgr() { return fInstance; }
static void Init();

38
Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.cpp

@ -83,6 +83,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plMessage/plMemberUpdateMsg.h"
#include "plMessage/plAvatarMsg.h"
#include "plMessage/plAvCoopMsg.h"
#include "plMessage/plLoadClothingMsg.h"
#include "pnMessage/plTimeMsg.h"
#include "plStatusLog/plStatusLog.h"
@ -149,12 +150,12 @@ void plAvatarMgr::IReset()
fActiveCoops.clear();
}
plKey plAvatarMgr::LoadPlayer(const char *name, const char *account)
plKey plAvatarMgr::LoadPlayer(const plString &name, const plString &account)
{
return LoadAvatar(name, account, true, nil, nil);
return LoadAvatar(name, account, true, nullptr, nullptr);
}
plKey plAvatarMgr::LoadPlayer(const char *name, const char *account, const char *linkInName)
plKey plAvatarMgr::LoadPlayer(const plString &name, const plString &account, const plString &linkInName)
{
// what we'd like to do is turn the linkInName into a spawn point key and
// put that into the plLoadAvatarMsg, which is already set up to handle
@ -163,29 +164,34 @@ plKey plAvatarMgr::LoadPlayer(const char *name, const char *account, const char
// so we're goin to do this the "old way" for now.
plArmatureMod::SetSpawnPointOverride(linkInName);
return LoadAvatar(name, account, true, nil, nil);
return LoadAvatar(name, account, true, nullptr, nullptr);
}
plKey plAvatarMgr::LoadPlayerFromFile(const plString &name, const plString &account, const plFileName &clothingFile)
{
return LoadAvatar(name, account, true, nullptr, nullptr, "", clothingFile);
}
plKey plAvatarMgr::LoadAvatar(const char *name, const char *accountName, bool isPlayer, plKey spawnPoint, plAvTask *initialTask, const char *userStr /*=nil*/)
plKey plAvatarMgr::LoadAvatar(plString name, plString accountName, bool isPlayer, plKey spawnPoint, plAvTask *initialTask,
const plString &userStr, const plFileName &clothingFile)
{
// *** account is currently unused. the idea is that eventually an NPC will
// *** be able to use a customization account
plKey result = nil;
plKey result = nullptr;
plKey requestor = GetKey(); // avatar manager is always the requestor for avatar loads
plNetClientMgr *netMgr = plNetClientMgr::GetInstance();
if(netMgr) // can't clone without the net manager
{
hsAssert(name, "name required by LoadPlayer fxn");
netMgr->DebugMsg("Local: Loading player %s", name);
hsAssert(!name.IsEmpty(), "name required by LoadPlayer fxn");
netMgr->DebugMsg("Local: Loading player %s", name.c_str());
// look up player by key name provided by user.
// this string search should be replaced with some other method of
// avatar selection and key lookup.
// Get the location for the player first
plKey playerKey = nil;
plKey playerKey = nullptr;
const plLocation& globalLoc = plKeyFinder::Instance().FindLocation("GlobalAvatars", name);
const plLocation& maleLoc = plKeyFinder::Instance().FindLocation("GlobalAvatars", "Male");
const plLocation& custLoc = plKeyFinder::Instance().FindLocation("CustomAvatars", name);
@ -199,14 +205,18 @@ plKey plAvatarMgr::LoadAvatar(const char *name, const char *accountName, bool is
const plLocation& loc = (globalLoc.IsValid() ? globalLoc : custLoc.IsValid() ? custLoc : maleLoc);
#endif
plString theName = name;
if ( loc == maleLoc )
theName = "Male";
if (loc == maleLoc)
name = "Male";
if (loc.IsValid())
{
plUoid uID(loc, plSceneObject::Index(), theName);
plLoadAvatarMsg *cloneMsg = new plLoadAvatarMsg (uID, requestor, 0, isPlayer, spawnPoint, initialTask, userStr);
plUoid uID(loc, plSceneObject::Index(), name);
plLoadAvatarMsg *cloneMsg = new plLoadAvatarMsg(uID, requestor, 0, isPlayer, spawnPoint, initialTask, userStr);
if (clothingFile.IsValid())
{
plLoadClothingMsg *clothingMsg = new plLoadClothingMsg(clothingFile);
cloneMsg->SetTriggerMsg(clothingMsg);
}
result = cloneMsg->GetCloneKey();
// the clone message is automatically addressed to the net client manager

9
Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.h

@ -48,6 +48,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "HeadSpin.h"
#include <map>
#include "plFileSystem.h"
#include "hsGeometry3.h"
#include "pnKeyedObject/hsKeyedObject.h"
@ -113,9 +114,11 @@ public:
plOneShotMod *FindOneShot(const plString &name);
// \}
plKey LoadPlayer(const char* name, const char *account);
plKey LoadPlayer(const char* name, const char *account, const char *linkName);
plKey LoadAvatar(const char *name, const char *accountName, bool isPlayer, plKey spawnPoint, plAvTask *initialTask, const char *userStr = nil);
plKey LoadPlayer(const plString &name, const plString &account);
plKey LoadPlayer(const plString &name, const plString &account, const plString &linkName);
plKey LoadPlayerFromFile(const plString &name, const plString &account, const plFileName &clothingFile);
plKey LoadAvatar(plString name, plString accountName, bool isPlayer, plKey spawnPoint, plAvTask *initialTask,
const plString &userStr = "", const plFileName &clothingFile = "");
/**
* Unload an avatar clone

1
Sources/Plasma/PubUtilLib/plMessage/CMakeLists.txt

@ -80,6 +80,7 @@ set(plMessage_HEADERS
plLoadAgeMsg.h
plLoadAvatarMsg.h
plLoadCloneMsg.h
plLoadClothingMsg.h
plLOSHitMsg.h
plLOSRequestMsg.h
plMatRefMsg.h

106
Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.cpp

@ -58,44 +58,30 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
// CTOR (default)
plLoadAvatarMsg::plLoadAvatarMsg()
: fIsPlayer(false),
fSpawnPoint(nil),
fInitialTask(nil),
fUserStr(nil)
fSpawnPoint(nullptr),
fInitialTask(nullptr)
{
}
// CTOR uoidToClone, requestorKey, userData, isPlayer, spawnPOint, initialTask
plLoadAvatarMsg::plLoadAvatarMsg(const plUoid &uoidToClone, const plKey &requestorKey, uint32_t userData,
bool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const char* userStr /*= nil*/)
bool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const plString &userStr)
: plLoadCloneMsg(uoidToClone, requestorKey, userData),
fIsPlayer(isPlayer),
fSpawnPoint(spawnPoint),
fInitialTask(initialTask),
fUserStr(nil) // setting to nil so SetUserStr doesn't try to nuke garbage
fUserStr(userStr)
{
SetUserStr(userStr);
}
plLoadAvatarMsg::plLoadAvatarMsg(const plKey &existing, const plKey &requestor, uint32_t userData,
bool isPlayer, bool isLoading, const char* userStr /*= nil*/)
: plLoadCloneMsg(existing, requestor, userData, isLoading),
fIsPlayer(isPlayer),
fSpawnPoint(nil),
fInitialTask(nil),
fUserStr(nil) // setting to nil so SetUserStr doesn't try to nuke garbage
{
SetUserStr(userStr);
}
// DTOR
plLoadAvatarMsg::~plLoadAvatarMsg()
bool isPlayer, bool isLoading, const plString &userStr)
: plLoadCloneMsg(existing, requestor, userData, isLoading),
fIsPlayer(isPlayer),
fSpawnPoint(nullptr),
fInitialTask(nullptr),
fUserStr(userStr)
{
if (fUserStr)
{
delete [] fUserStr;
fUserStr = nil;
}
}
void plLoadAvatarMsg::Read(hsStream* stream, hsResMgr* mgr)
@ -107,12 +93,7 @@ void plLoadAvatarMsg::Read(hsStream* stream, hsResMgr* mgr)
{
fInitialTask = plAvTask::ConvertNoRef(mgr->ReadCreatable(stream));
}
if (fUserStr)
{
delete [] fUserStr;
fUserStr = nil;
}
fUserStr = stream->ReadSafeString();
fUserStr = stream->ReadSafeString_TEMP();
}
void plLoadAvatarMsg::Write(hsStream *stream, hsResMgr *mgr)
@ -150,13 +131,8 @@ void plLoadAvatarMsg::ReadVersion(hsStream* stream, hsResMgr* mgr)
if (contentFlags.IsBitSet(kLoadAvatarMsgSpawnPoint))
fSpawnPoint = mgr->ReadKey(stream);
if (fUserStr)
{
delete [] fUserStr;
fUserStr = nil;
}
if (contentFlags.IsBitSet(kLoadAvatarMsgUserStr))
fUserStr = stream->ReadSafeString();
fUserStr = stream->ReadSafeString_TEMP();
}
void plLoadAvatarMsg::WriteVersion(hsStream* stream, hsResMgr* mgr)
@ -179,63 +155,5 @@ void plLoadAvatarMsg::WriteVersion(hsStream* stream, hsResMgr* mgr)
stream->WriteSafeString(fUserStr);
}
// SETISPLAYER
void plLoadAvatarMsg::SetIsPlayer(bool is)
{
fIsPlayer = is;
}
// GETISPLAYER
bool plLoadAvatarMsg::GetIsPlayer()
{
return fIsPlayer;
}
// SETSPAWNPOINT
void plLoadAvatarMsg::SetSpawnPoint(const plKey &spawnPoint)
{
fSpawnPoint = spawnPoint;
}
// GETSPAWNPOINT
plKey plLoadAvatarMsg::GetSpawnPoint()
{
return fSpawnPoint;
}
// SETINITIALTASK
void plLoadAvatarMsg::SetInitialTask(plAvTask *initialTask)
{
fInitialTask = initialTask;
}
// GETINITIALTASK
plAvTask * plLoadAvatarMsg::GetInitialTask()
{
return fInitialTask;
}
// SETUSERSTR
void plLoadAvatarMsg::SetUserStr(const char *userStr)
{
if (fUserStr)
delete [] fUserStr;
if (!userStr)
{
fUserStr = nil;
return;
}
fUserStr = new char[strlen(userStr) + 1];
strcpy(fUserStr, userStr);
fUserStr[strlen(userStr)] = '\0';
}
// GETUSERSTR
const char* plLoadAvatarMsg::GetUserStr()
{
return fUserStr;
}
#endif // ndef SERVER
#endif // ndef NO_AV_MSGS

24
Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.h

@ -83,7 +83,7 @@ public:
\param userStr - a string that the user can set
*/
plLoadAvatarMsg(const plUoid &uoidToClone, const plKey &requestorKey, uint32_t userData,
bool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const char *userStr = nil);
bool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const plString &userStr = "");
/** Use this form if you're sending a message about an existing clone -- either
to propagate it to other machines or to tell them to unload it.
@ -97,21 +97,19 @@ public:
\param userStr - a string that the user can set
*/
plLoadAvatarMsg(const plKey &existing, const plKey &requestorKey, uint32_t userData,
bool isPlayer, bool isLoading, const char *userStr = nil);
bool isPlayer, bool isLoading, const plString &userStr = "");
virtual ~plLoadAvatarMsg();
void SetIsPlayer(bool is) { fIsPlayer = is; }
bool GetIsPlayer() { return fIsPlayer; }
void SetIsPlayer(bool is);
bool GetIsPlayer();
void SetSpawnPoint(const plKey &spawnPoint) { fSpawnPoint = spawnPoint; }
plKey GetSpawnPoint() { return fSpawnPoint; }
void SetSpawnPoint(const plKey &spawnSceneObjectKey);
plKey GetSpawnPoint();
void SetInitialTask(plAvTask *task) { fInitialTask = task; }
plAvTask * GetInitialTask() { return fInitialTask; }
void SetInitialTask(plAvTask *task);
plAvTask * GetInitialTask();
void SetUserStr(const char *userStr);
const char* GetUserStr();
void SetUserStr(const plString &userStr) { fUserStr = userStr; }
plString GetUserStr() { return fUserStr; }
CLASSNAME_REGISTER(plLoadAvatarMsg);
GETINTERFACE_ANY(plLoadAvatarMsg, plLoadCloneMsg);
@ -126,7 +124,7 @@ protected:
bool fIsPlayer;
plKey fSpawnPoint;
plAvTask *fInitialTask;
char *fUserStr;
plString fUserStr;
};

67
Sources/Plasma/PubUtilLib/plMessage/plLoadClothingMsg.h

@ -0,0 +1,67 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
#ifndef plLoadClothingMsg_INC
#define plLoadClothingMsg_INC
#include "plFileSystem.h"
#include "pnMessage/plMessage.h"
/** This message is sent when we want to load our clothing from a file. */
class plLoadClothingMsg : public plMessage {
private:
plFileName fClothingFile;
public:
plLoadClothingMsg() { }
plLoadClothingMsg(const plFileName& file) : fClothingFile(file) { }
CLASSNAME_REGISTER(plLoadClothingMsg);
GETINTERFACE_ANY(plLoadClothingMsg, plMessage);
void Read(hsStream*, hsResMgr*) { }
void Write(hsStream*, hsResMgr*) { }
plFileName GetClothingFile() const { return fClothingFile; }
};
#endif // plLoadClothingMsg_INC

3
Sources/Plasma/PubUtilLib/plMessage/plMessageCreatable.h

@ -355,6 +355,9 @@ REGISTER_CREATABLE(plLoadCloneMsg);
# include "plLoadAvatarMsg.h"
REGISTER_CREATABLE(plLoadAvatarMsg);
#include "plLoadClothingMsg.h"
REGISTER_CREATABLE(plLoadClothingMsg);
# include "plAvCoopMsg.h"
REGISTER_CREATABLE(plAvCoopMsg);

2
Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp

@ -281,7 +281,7 @@ void plNCAgeJoiner::ExecNextOp () {
else
avatarName = NetCommGetPlayer()->avatarDatasetName;
plString linkInName = plNetLinkingMgr::GetInstance()->GetAgeLink()->SpawnPoint().GetName();
am->LoadPlayer( avatarName, nil, linkInName.c_str() );
am->LoadPlayer(avatarName, "", linkInName);
}
else {
LogMsg(kLogPerf, L"AgeJoiner: Next:kPropagatePlayer");

3
Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp

@ -198,9 +198,6 @@ void plNetClientMgr::Shutdown()
IRemoveCloneRoom();
// RATHER BAD DEBUG HACK: Clear the spawn override in armatureMod so there's no memory leak
plArmatureMod::SetSpawnPointOverride( nil );
VaultDestroy();
}

Loading…
Cancel
Save