mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
@ -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
|
||||
|
@ -410,6 +410,9 @@ public:
|
||||
|
||||
virtual void PlaySimpleAnimation(const plString& animName);
|
||||
|
||||
virtual bool SaveClothingToFile(plFileName filename);
|
||||
virtual bool LoadClothingFromFile(plFileName filename);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : ChangeAvatar
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -80,6 +80,7 @@ set(plMessage_HEADERS
|
||||
plLoadAgeMsg.h
|
||||
plLoadAvatarMsg.h
|
||||
plLoadCloneMsg.h
|
||||
plLoadClothingMsg.h
|
||||
plLOSHitMsg.h
|
||||
plLOSRequestMsg.h
|
||||
plMatRefMsg.h
|
||||
|
@ -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
|
||||
bool isPlayer, bool isLoading, const plString &userStr)
|
||||
: plLoadCloneMsg(existing, requestor, userData, isLoading),
|
||||
fIsPlayer(isPlayer),
|
||||
fSpawnPoint(nullptr),
|
||||
fInitialTask(nullptr),
|
||||
fUserStr(userStr)
|
||||
{
|
||||
SetUserStr(userStr);
|
||||
}
|
||||
|
||||
|
||||
// DTOR
|
||||
plLoadAvatarMsg::~plLoadAvatarMsg()
|
||||
{
|
||||
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
|
||||
|
@ -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
Normal file
67
Sources/Plasma/PubUtilLib/plMessage/plLoadClothingMsg.h
Normal file
@ -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
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user