diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp index 42bf2e5d..c4337b9d 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp +++ b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp @@ -788,23 +788,30 @@ void plArmatureMod::WindowActivate(bool active) } } -plString plArmatureMod::fSpawnPointOverride; +char *plArmatureMod::fSpawnPointOverride = nil; -void plArmatureMod::SetSpawnPointOverride(const plString &overrideObjName) +void plArmatureMod::SetSpawnPointOverride( const char *overrideObjName ) { - fSpawnPointOverride = overrideObjName.ToLower(); + delete [] fSpawnPointOverride; + if( overrideObjName == nil ) + fSpawnPointOverride = nil; + else + { + fSpawnPointOverride = hsStrcpy( overrideObjName ); + strlwr( fSpawnPointOverride ); + } } -int plArmatureMod::IFindSpawnOverride() +int plArmatureMod::IFindSpawnOverride( void ) { - if (fSpawnPointOverride.IsEmpty()) + if( fSpawnPointOverride == nil || fSpawnPointOverride[ 0 ] == 0 ) return -1; - int i; + int i; plAvatarMgr *mgr = plAvatarMgr::GetInstance(); - for (i = 0; i < mgr->NumSpawnPoints(); i++) + for( i = 0; i < mgr->NumSpawnPoints(); i++ ) { char str2[ 256 ]; - strcpy(str2, mgr->GetSpawnPoint(i)->GetTarget(0)->GetKeyName()); + strcpy(str2, mgr->GetSpawnPoint( i )->GetTarget(0)->GetKeyName()); strlwr(str2); if (strstr(str2, fSpawnPointOverride) != nil) diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h index eff00fdc..77eecb45 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h +++ b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h @@ -330,7 +330,7 @@ public: static void SetMouseTurnSensitivity(hsScalar val) { fMouseTurnSensitivity = val / 150.f; } static hsScalar GetMouseTurnSensitivity() { return fMouseTurnSensitivity * 150.f; } - static void SetSpawnPointOverride(const plString &overrideObjName ); + static void SetSpawnPointOverride( const char *overrideObjName ); static void WindowActivate(bool active); void SetFollowerParticleSystemSO(plSceneObject *follower); plSceneObject *GetFollowerParticleSystemSO(); @@ -428,7 +428,7 @@ protected: hsTArray fClothToSOMap; plArmatureEffectsMgr *fEffects; plSceneObject *fFollowerParticleSystemSO; - static plString *fSpawnPointOverride; + static char *fSpawnPointOverride; // These vectors are used with relevance regions for culling out other objects hsBitVector fRegionsImIn; diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.cpp index 83af150a..887ac9bc 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.cpp +++ b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.cpp @@ -431,8 +431,8 @@ hsBool plClothingBase::MsgReceive(plMessage* msg) ///////////////////////////////////////////////////////////////////////////// plClothingOutfit::plClothingOutfit() : - fTargetLayer(nullptr), fBase(nullptr), fGroup(0), fAvatar(nullptr), fSynchClients(false), fMaterial(nullptr), - 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(); @@ -1938,9 +1938,9 @@ void plClothingMgr::IAddItem(plClothingItem *item) hsAssert(false, "Couldn't match all elements of added clothing item."); } -void plClothingMgr::ChangeAvatar(const char* name, const plFileName &clothingFile) +void plClothingMgr::ChangeAvatar(char *name) { plAvatarMgr::GetInstance()->UnLoadLocalPlayer(); - plAvatarMgr::GetInstance()->LoadPlayerFromFile(name, "", clothingFile); + plAvatarMgr::GetInstance()->LoadPlayer(name, nil); } diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.h b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.h index 6ddb672e..31db6de4 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.h +++ b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarClothing.h @@ -303,7 +303,7 @@ public: plClothingItem *GetLRMatch(plClothingItem *item); hsBool IsLRMatch(plClothingItem *item1, plClothingItem *item2); - static void ChangeAvatar(const char* name, const plFileName &clothingFile = ""); + static void ChangeAvatar(char *name); static plClothingMgr *GetClothingMgr() { return fInstance; } static void Init(); diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.cpp index 79927ff4..cb4f774c 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.cpp +++ b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.cpp @@ -83,7 +83,6 @@ 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" @@ -154,12 +153,12 @@ void plAvatarMgr::IReset() fActiveCoops.clear(); } -plKey plAvatarMgr::LoadPlayer(const plString &name, const plString &account) +plKey plAvatarMgr::LoadPlayer(const char *name, const char *account) { - return LoadAvatar(name, account, true, nullptr, nullptr); + return LoadAvatar(name, account, true, nil, nil); } -plKey plAvatarMgr::LoadPlayer(const plString &name, const plString &account, const plString &linkInName) +plKey plAvatarMgr::LoadPlayer(const char *name, const char *account, const char *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 @@ -168,34 +167,29 @@ plKey plAvatarMgr::LoadPlayer(const plString &name, const plString &account, con // so we're goin to do this the "old way" for now. plArmatureMod::SetSpawnPointOverride(linkInName); - return LoadAvatar(name, account, true, nullptr, nullptr); + return LoadAvatar(name, account, true, nil, nil); } -plKey plAvatarMgr::LoadPlayerFromFile(const plString &name, const plString &account, const plFileName &clothingFile) -{ - return LoadAvatar(name, account, true, nullptr, nullptr, "", clothingFile); -} -plKey plAvatarMgr::LoadAvatar(plString name, plString accountName, bool isPlayer, plKey spawnPoint, plAvTask *initialTask, - const plString &userStr, const plFileName &clothingFile) +plKey plAvatarMgr::LoadAvatar(const char *name, const char *accountName, bool isPlayer, plKey spawnPoint, plAvTask *initialTask, const char *userStr /*=nil*/) { // *** account is currently unused. the idea is that eventually an NPC will // *** be able to use a customization account - plKey result = nullptr; + plKey result = nil; 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.IsEmpty(), "name required by LoadPlayer fxn"); - netMgr->DebugMsg("Local: Loading player %s", name.c_str()); + hsAssert(name, "name required by LoadPlayer fxn"); + netMgr->DebugMsg("Local: Loading player %s", name); // 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 = nullptr; + plKey playerKey = nil; const plLocation& globalLoc = plKeyFinder::Instance().FindLocation("GlobalAvatars", name); const plLocation& maleLoc = plKeyFinder::Instance().FindLocation("GlobalAvatars", "Male"); const plLocation& custLoc = plKeyFinder::Instance().FindLocation("CustomAvatars", name); @@ -210,13 +204,8 @@ plKey plAvatarMgr::LoadAvatar(plString name, plString accountName, bool isPlayer if (loc.IsValid()) { - 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); - } + plUoid uID(loc, plSceneObject::Index(), theName); + plLoadAvatarMsg *cloneMsg = TRACKED_NEW plLoadAvatarMsg (uID, requestor, 0, isPlayer, spawnPoint, initialTask, userStr); result = cloneMsg->GetCloneKey(); // the clone message is automatically addressed to the net client manager diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.h b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.h index 1b2d7184..fafea066 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.h +++ b/Sources/Plasma/PubUtilLib/plAvatar/plAvatarMgr.h @@ -47,7 +47,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "hsStlUtils.h" #include "hsStlSortUtils.h" -#include "plFileSystem.h" #include "hsGeometry3.h" #include "../pnKeyedObject/hsKeyedObject.h" @@ -113,11 +112,9 @@ public: plOneShotMod *FindOneShot(char *name); // \} - 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 = ""); + 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); /** Unload an avatar - player or npc - both locally and remotely. */ void UnLoadAvatar(plKey avKey, bool isPlayer); /** send our (already loaded) local player to newly-associated clients - used when linking */ diff --git a/Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.cpp b/Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.cpp index e48e6e35..0218c9ef 100644 --- a/Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.cpp +++ b/Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.cpp @@ -58,31 +58,44 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com // CTOR (default) plLoadAvatarMsg::plLoadAvatarMsg() : fIsPlayer(false), - fSpawnPoint(nullptr), - fInitialTask(nullptr) + fSpawnPoint(nil), + fInitialTask(nil), + fUserStr(nil) { } // CTOR uoidToClone, requestorKey, userData, isPlayer, spawnPOint, initialTask plLoadAvatarMsg::plLoadAvatarMsg(const plUoid &uoidToClone, const plKey &requestorKey, UInt32 userData, - hsBool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const plString &userStr) + hsBool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const char* userStr /*= nil*/) : plLoadCloneMsg(uoidToClone, requestorKey, userData), fIsPlayer(isPlayer), fSpawnPoint(spawnPoint), fInitialTask(initialTask), - fUserStr(userStr) + fUserStr(nil) // setting to nil so SetUserStr doesn't try to nuke garbage { SetUserStr(userStr); } plLoadAvatarMsg::plLoadAvatarMsg(const plKey &existing, const plKey &requestor, UInt32 userData, - hsBool isPlayer, bool isLoading, const plString &userStr) + hsBool isPlayer, hsBool isLoading, const char* userStr /*= nil*/) : plLoadCloneMsg(existing, requestor, userData, isLoading), fIsPlayer(isPlayer), - fSpawnPoint(nullptr), - fInitialTask(nullptr), - fUserStr(userStr) + fSpawnPoint(nil), + fInitialTask(nil), + fUserStr(nil) // setting to nil so SetUserStr doesn't try to nuke garbage { + SetUserStr(userStr); +} + + +// DTOR +plLoadAvatarMsg::~plLoadAvatarMsg() +{ + if (fUserStr) + { + delete [] fUserStr; + fUserStr = nil; + } } void plLoadAvatarMsg::Read(hsStream* stream, hsResMgr* mgr) @@ -94,7 +107,12 @@ void plLoadAvatarMsg::Read(hsStream* stream, hsResMgr* mgr) { fInitialTask = plAvTask::ConvertNoRef(mgr->ReadCreatable(stream)); } - fUserStr = stream->ReadSafeString_TEMP(); + if (fUserStr) + { + delete [] fUserStr; + fUserStr = nil; + } + fUserStr = stream->ReadSafeString(); } void plLoadAvatarMsg::Write(hsStream *stream, hsResMgr *mgr) @@ -132,8 +150,13 @@ 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_TEMP(); + fUserStr = stream->ReadSafeString(); } void plLoadAvatarMsg::WriteVersion(hsStream* stream, hsResMgr* mgr) @@ -156,5 +179,63 @@ void plLoadAvatarMsg::WriteVersion(hsStream* stream, hsResMgr* mgr) stream->WriteSafeString(fUserStr); } +// SETISPLAYER +void plLoadAvatarMsg::SetIsPlayer(bool is) +{ + fIsPlayer = is; +} + +// GETISPLAYER +hsBool 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 = TRACKED_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 diff --git a/Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.h b/Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.h index 12d8a72e..5ca1b060 100644 --- a/Sources/Plasma/PubUtilLib/plMessage/plLoadAvatarMsg.h +++ b/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 userData, - hsBool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const plString &userStr = ""); + hsBool isPlayer, const plKey &spawnPoint, plAvTask *initialTask, const char *userStr = nil); /** 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,19 +97,21 @@ public: \param userStr - a string that the user can set */ plLoadAvatarMsg(const plKey &existing, const plKey &requestorKey, UInt32 userData, - hsool isPlayer, bool isLoading, const plString &userStr = ""); + hsBool isPlayer, hsBool isLoading, const char *userStr = nil); - void SetIsPlayer(bool is) { fIsPlayer = is; } - bool GetIsPlayer() { return fIsPlayer; } + virtual ~plLoadAvatarMsg(); - void SetSpawnPoint(const plKey &spawnPoint) { fSpawnPoint = spawnPoint; } - plKey GetSpawnPoint() { return fSpawnPoint; } + void SetIsPlayer(bool is); + hsBool GetIsPlayer(); - void SetInitialTask(plAvTask *task) { fInitialTask = task; } - plAvTask * GetInitialTask() { return fInitialTask; } + void SetSpawnPoint(const plKey &spawnSceneObjectKey); + plKey GetSpawnPoint(); - void SetUserStr(const plString &userStr) { fUserStr = userStr; } - plString GetUserStr() { return fUserStr; } + void SetInitialTask(plAvTask *task); + plAvTask * GetInitialTask(); + + void SetUserStr(const char *userStr); + const char* GetUserStr(); CLASSNAME_REGISTER(plLoadAvatarMsg); GETINTERFACE_ANY(plLoadAvatarMsg, plLoadCloneMsg); @@ -124,7 +126,7 @@ protected: hsBool fIsPlayer; plKey fSpawnPoint; plAvTask *fInitialTask; - plString fUserStr; + char *fUserStr; }; diff --git a/Sources/Plasma/PubUtilLib/plMessage/plLoadClothingMsg.h b/Sources/Plasma/PubUtilLib/plMessage/plLoadClothingMsg.h deleted file mode 100644 index cab22ede..00000000 --- a/Sources/Plasma/PubUtilLib/plMessage/plLoadClothingMsg.h +++ /dev/null @@ -1,67 +0,0 @@ -/*==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 . - -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 diff --git a/Sources/Plasma/PubUtilLib/plMessage/plMessageCreatable.h b/Sources/Plasma/PubUtilLib/plMessage/plMessageCreatable.h index 2f99f7af..25dac2e2 100644 --- a/Sources/Plasma/PubUtilLib/plMessage/plMessageCreatable.h +++ b/Sources/Plasma/PubUtilLib/plMessage/plMessageCreatable.h @@ -370,9 +370,6 @@ REGISTER_CREATABLE(plLoadCloneMsg); # include "plLoadAvatarMsg.h" REGISTER_CREATABLE(plLoadAvatarMsg); -#include "plLoadClothingMsg.h" -REGISTER_CREATABLE(plLoadClothingMsg); - # include "plAvCoopMsg.h" REGISTER_CREATABLE(plAvCoopMsg); diff --git a/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp b/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp index 74dbe58d..6581052d 100644 --- a/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp +++ b/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp @@ -279,8 +279,8 @@ void plNCAgeJoiner::ExecNextOp () { avatarName = "Male"; else avatarName = NetCommGetPlayer()->avatarDatasetName; - plString linkInName = plNetLinkingMgr::GetInstance()->GetAgeLink()->SpawnPoint().GetName(); - am->LoadPlayer(avatarName, "", linkInName); + const char * linkInName = plNetLinkingMgr::GetInstance()->GetAgeLink()->SpawnPoint().GetName(); + am->LoadPlayer( avatarName, nil, linkInName ); } else { LogMsg(kLogPerf, L"AgeJoiner: Next:kPropagatePlayer"); diff --git a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp index e12d2a07..dc5d4e12 100644 --- a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp +++ b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp @@ -202,6 +202,9 @@ void plNetClientMgr::Shutdown() IRemoveCloneRoom(); + // RATHER BAD DEBUG HACK: Clear the spawn override in armatureMod so there's no memory leak + plArmatureMod::SetSpawnPointOverride( nil ); + VaultDestroy(); }