mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 10:37:41 -04:00
@ -2700,7 +2700,7 @@ PyObject* cyMisc::LoadAvatarModel(const char* modelName, pyKey& spawnPoint, cons
|
|||||||
|
|
||||||
void cyMisc::UnLoadAvatarModel(pyKey& avatar)
|
void cyMisc::UnLoadAvatarModel(pyKey& avatar)
|
||||||
{
|
{
|
||||||
plAvatarMgr::GetInstance()->UnLoadAvatar(avatar.getKey(), false);
|
plAvatarMgr::GetInstance()->UnLoadAvatar(avatar.getKey(), false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyMisc::ForceCursorHidden()
|
void cyMisc::ForceCursorHidden()
|
||||||
@ -2868,14 +2868,7 @@ PyObject* cyMisc::GetAIAvatarsByModelName(const char* name)
|
|||||||
Py_DECREF(tuple);
|
Py_DECREF(tuple);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return avList;
|
||||||
if (PyList_Size(avList) > 0)
|
|
||||||
return avList;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Py_DECREF(avList);
|
|
||||||
PYTHON_RETURN_NONE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyMisc::ForceVaultNodeUpdate(unsigned nodeId)
|
void cyMisc::ForceVaultNodeUpdate(unsigned nodeId)
|
||||||
|
@ -374,7 +374,8 @@ PYTHON_GLOBAL_METHOD_DEFINITION(PtLoadAvatarModel, args, "Params: modelName, spa
|
|||||||
return cyMisc::LoadAvatarModel(modelName, *key, userStr.c_str());
|
return cyMisc::LoadAvatarModel(modelName, *key, userStr.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
PYTHON_GLOBAL_METHOD_DEFINITION(PtUnLoadAvatarModel, args, "Params: avatarKey\nUnloads the specified avatar model")
|
PYTHON_GLOBAL_METHOD_DEFINITION(PtUnLoadAvatarModel, args, "Params: avatarKey\nForcibly unloads the specified avatar model.\n"
|
||||||
|
"Do not use this method unless you require fine-grained control of avatar unloading.")
|
||||||
{
|
{
|
||||||
PyObject* keyObj = NULL;
|
PyObject* keyObj = NULL;
|
||||||
if (!PyArg_ParseTuple(args, "O", &keyObj))
|
if (!PyArg_ParseTuple(args, "O", &keyObj))
|
||||||
|
@ -852,6 +852,34 @@ void plPythonFileMod::AddTarget(plSceneObject* sobj)
|
|||||||
DisplayPythonOutput();
|
DisplayPythonOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Oversight fix... Sometimes PythonFileMods are loaded after the AgeInitialState is received.
|
||||||
|
// We should really let the script know about that via OnServerInitComplete anyway because it's
|
||||||
|
// not good to make assumptions about game state in workarounds for that method not being called
|
||||||
|
plNetClientApp* na = plNetClientApp::GetInstance();
|
||||||
|
if (!na->GetFlagsBit(plNetClientApp::kLoadingInitialAgeState) &&
|
||||||
|
na->GetFlagsBit(plNetClientApp::kPlayingGame))
|
||||||
|
{
|
||||||
|
plgDispatch::Dispatch()->UnRegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
|
||||||
|
plProfile_BeginTiming(PythonUpdate);
|
||||||
|
// call it
|
||||||
|
PyObject* retVal = PyObject_CallMethod(
|
||||||
|
fPyFunctionInstances[kfunc_OnServerInitComplete],
|
||||||
|
(char*)fFunctionNames[kfunc_OnServerInitComplete], nil);
|
||||||
|
if ( retVal == nil )
|
||||||
|
{
|
||||||
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||||
|
// for some reason this function didn't, remember that and not call it again
|
||||||
|
fPyFunctionInstances[kfunc_OnServerInitComplete] = nil;
|
||||||
|
#endif //PLASMA_EXTERNAL_RELEASE
|
||||||
|
// if there was an error make sure that the stderr gets flushed so it can be seen
|
||||||
|
ReportError();
|
||||||
|
}
|
||||||
|
Py_XDECREF(retVal);
|
||||||
|
plProfile_EndTiming(PythonUpdate);
|
||||||
|
// display any output (NOTE: this would be disabled in production)
|
||||||
|
DisplayPythonOutput();
|
||||||
|
}
|
||||||
|
|
||||||
// display python output
|
// display python output
|
||||||
DisplayPythonOutput();
|
DisplayPythonOutput();
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,10 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
*==LICENSE==*/
|
*==LICENSE==*/
|
||||||
#include "pyCritterBrain.h"
|
#include "pyCritterBrain.h"
|
||||||
#include "pyGeometry3.h"
|
#include "pyGeometry3.h"
|
||||||
|
#include "pySceneObject.h"
|
||||||
|
|
||||||
#include "plAvatar/plAvBrainCritter.h"
|
#include "plAvatar/plAvBrainCritter.h"
|
||||||
|
#include "pnSceneObject/plSceneObject.h"
|
||||||
|
|
||||||
pyCritterBrain::pyCritterBrain(): fBrain(nil) {}
|
pyCritterBrain::pyCritterBrain(): fBrain(nil) {}
|
||||||
|
|
||||||
@ -66,18 +68,12 @@ void pyCritterBrain::RemoveReceiver(pyKey& oldReceiver)
|
|||||||
fBrain->RemoveReceiver(oldReceiver.getKey());
|
fBrain->RemoveReceiver(oldReceiver.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
void pyCritterBrain::LocallyControlled(bool local)
|
PyObject* pyCritterBrain::GetSceneObject()
|
||||||
{
|
{
|
||||||
if (!fBrain)
|
if (fBrain)
|
||||||
return;
|
if (plSceneObject* obj = fBrain->GetTarget())
|
||||||
fBrain->LocallyControlled(local);
|
return pySceneObject::New(obj->GetKey());
|
||||||
}
|
PYTHON_RETURN_NONE;
|
||||||
|
|
||||||
bool pyCritterBrain::LocallyControlled() const
|
|
||||||
{
|
|
||||||
if (!fBrain)
|
|
||||||
return false;
|
|
||||||
return fBrain->LocallyControlled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pyCritterBrain::AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop /* = true */,
|
void pyCritterBrain::AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop /* = true */,
|
||||||
|
@ -83,8 +83,7 @@ public:
|
|||||||
void AddReceiver(pyKey& newReceiver);
|
void AddReceiver(pyKey& newReceiver);
|
||||||
void RemoveReceiver(pyKey& oldReceiver);
|
void RemoveReceiver(pyKey& oldReceiver);
|
||||||
|
|
||||||
void LocallyControlled(bool local);
|
PyObject* GetSceneObject();
|
||||||
bool LocallyControlled() const;
|
|
||||||
|
|
||||||
void AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop = true, bool randomStartPos = true,
|
void AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop = true, bool randomStartPos = true,
|
||||||
float fadeInLen = 2.f, float fadeOutLen = 2.f);
|
float fadeInLen = 2.f, float fadeOutLen = 2.f);
|
||||||
|
@ -139,21 +139,9 @@ PYTHON_METHOD_DEFINITION(ptCritterBrain, removeReceiver, args)
|
|||||||
PYTHON_RETURN_NONE;
|
PYTHON_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PYTHON_METHOD_DEFINITION(ptCritterBrain, setLocallyControlled, args)
|
PYTHON_METHOD_DEFINITION(ptCritterBrain, getSceneObject, GetSceneObject)
|
||||||
{
|
{
|
||||||
char local;
|
return self->fThis->GetSceneObject();
|
||||||
if (!PyArg_ParseTuple(args, "b", &local))
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_TypeError, "setLocallyControlled expects a boolean");
|
|
||||||
PYTHON_RETURN_ERROR;
|
|
||||||
}
|
|
||||||
self->fThis->LocallyControlled(local != 0);
|
|
||||||
PYTHON_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PYTHON_METHOD_DEFINITION_NOARGS(ptCritterBrain, getLocallyControlled)
|
|
||||||
{
|
|
||||||
PYTHON_RETURN_BOOL(self->fThis->LocallyControlled());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PYTHON_METHOD_DEFINITION_WKEY(ptCritterBrain, addBehavior, args, keywords)
|
PYTHON_METHOD_DEFINITION_WKEY(ptCritterBrain, addBehavior, args, keywords)
|
||||||
@ -472,10 +460,7 @@ PYTHON_METHOD_DEFINITION(ptCritterBrain, vectorToPlayer, args)
|
|||||||
PYTHON_START_METHODS_TABLE(ptCritterBrain)
|
PYTHON_START_METHODS_TABLE(ptCritterBrain)
|
||||||
PYTHON_METHOD(ptCritterBrain, addReceiver, "Params: key\nTells the brain that the specified key wants AI messages"),
|
PYTHON_METHOD(ptCritterBrain, addReceiver, "Params: key\nTells the brain that the specified key wants AI messages"),
|
||||||
PYTHON_METHOD(ptCritterBrain, removeReceiver, "Params: key\nTells the brain that the specified key no longer wants AI messages"),
|
PYTHON_METHOD(ptCritterBrain, removeReceiver, "Params: key\nTells the brain that the specified key no longer wants AI messages"),
|
||||||
PYTHON_METHOD(ptCritterBrain, setLocallyControlled, "Params: local\nTells the brain that we are the ones making all the AI decisions, and to prop location "
|
PYTHON_METHOD(ptCritterBrain, getSceneObject, "Returns the ptSceneObject this brain controls."),
|
||||||
"and other information to the server."),
|
|
||||||
PYTHON_METHOD_NOARGS(ptCritterBrain, getLocallyControlled, "Are we the one making AI decisions? NOTE: Not set automatically, some python script needs to "
|
|
||||||
"tell the brain this using setLocallyControlled()."),
|
|
||||||
PYTHON_METHOD_WKEY(ptCritterBrain, addBehavior, "Params: animName, behaviorName, loop = 1, randomStartPos = 1, fadeInLen = 2.0, fadeOutLen = 2.0\n"
|
PYTHON_METHOD_WKEY(ptCritterBrain, addBehavior, "Params: animName, behaviorName, loop = 1, randomStartPos = 1, fadeInLen = 2.0, fadeOutLen = 2.0\n"
|
||||||
"Adds a new animation to the brain as a behavior with the specified name and parameters. If multiple animations are assigned to the same behavior, "
|
"Adds a new animation to the brain as a behavior with the specified name and parameters. If multiple animations are assigned to the same behavior, "
|
||||||
"they will be randomly picked from when started."),
|
"they will be randomly picked from when started."),
|
||||||
|
@ -1952,10 +1952,10 @@ hsBool plArmatureMod::IsLocalAvatar()
|
|||||||
|
|
||||||
hsBool plArmatureMod::IsLocalAI()
|
hsBool plArmatureMod::IsLocalAI()
|
||||||
{
|
{
|
||||||
plAvBrainCritter* ai = plAvBrainCritter::ConvertNoRef(FindBrainByClass(plAvBrainCritter::Index()));
|
// Formerly a lot of silly cached rigamaroll... Now, we'll just rely
|
||||||
if (ai)
|
// on the fact that one player is the game master. HACK TURD if net groups
|
||||||
return ai->LocallyControlled();
|
// are ever brought back.
|
||||||
return false; // not an AI, obviously not local
|
return plNetClientApp::GetInstance()->IsLocallyOwned(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void plArmatureMod::SynchIfLocal(double timeNow, int force)
|
void plArmatureMod::SynchIfLocal(double timeNow, int force)
|
||||||
|
@ -126,7 +126,7 @@ protected:
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
plAvBrainCritter::plAvBrainCritter(): fCallbackAction(nil), fCurMode(kIdle), fNextMode(kIdle), fFadingNextBehavior(true),
|
plAvBrainCritter::plAvBrainCritter(): fCallbackAction(nil), fCurMode(kIdle), fNextMode(kIdle), fFadingNextBehavior(true),
|
||||||
fLocallyControlled(false), fAvoidingAvatars(false), fFinalGoalPos(0, 0, 0), fImmediateGoalPos(0, 0, 0), fDotGoal(0),
|
fAvoidingAvatars(false), fFinalGoalPos(0, 0, 0), fImmediateGoalPos(0, 0, 0), fDotGoal(0),
|
||||||
fAngRight(0)
|
fAngRight(0)
|
||||||
{
|
{
|
||||||
SightCone(M_PI/2); // 90deg
|
SightCone(M_PI/2); // 90deg
|
||||||
@ -229,6 +229,13 @@ void plAvBrainCritter::Resume()
|
|||||||
plArmatureBrain::Resume();
|
plArmatureBrain::Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plSceneObject* plAvBrainCritter::GetTarget() const
|
||||||
|
{
|
||||||
|
if (fArmature)
|
||||||
|
return fArmature->GetTarget(0);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
void plAvBrainCritter::AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop /* = true */, bool randomStartPos /* = true */,
|
void plAvBrainCritter::AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop /* = true */, bool randomStartPos /* = true */,
|
||||||
float fadeInLen /* = 2.f */, float fadeOutLen /* = 2.f */)
|
float fadeInLen /* = 2.f */, float fadeOutLen /* = 2.f */)
|
||||||
{
|
{
|
||||||
@ -310,9 +317,13 @@ std::string plAvBrainCritter::RunBehaviorName() const
|
|||||||
void plAvBrainCritter::GoToGoal(hsPoint3 newGoal, bool avoidingAvatars /* = false */)
|
void plAvBrainCritter::GoToGoal(hsPoint3 newGoal, bool avoidingAvatars /* = false */)
|
||||||
{
|
{
|
||||||
fFinalGoalPos = newGoal;
|
fFinalGoalPos = newGoal;
|
||||||
fAvoidingAvatars = avoidingAvatars;
|
fAvoidingAvatars = avoidingAvatars; // TODO: make this do something?
|
||||||
fNextMode = IPickBehavior(kRun);
|
|
||||||
// TODO: Pathfinding here!
|
// Only play the run behavior if it's not already activated
|
||||||
|
// Why? This might just be an update to a preexisting goal.
|
||||||
|
if(!RunningBehavior(RunBehaviorName()))
|
||||||
|
fNextMode = IPickBehavior(kRun);
|
||||||
|
// Missing TODO Turd: Pathfinding.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool plAvBrainCritter::AtGoal() const
|
bool plAvBrainCritter::AtGoal() const
|
||||||
|
@ -83,13 +83,20 @@ public:
|
|||||||
virtual void Suspend();
|
virtual void Suspend();
|
||||||
virtual void Resume();
|
virtual void Resume();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SceneObject root for this avatar
|
||||||
|
*
|
||||||
|
* This is most useful in scripts that need to act upon the SceneObject directly.
|
||||||
|
* There are other ways of obtaining the SceneObject, but network synchronization often
|
||||||
|
* makes those ways more difficult than they need to be, so we have included this method
|
||||||
|
* to make the scripter's life easier.
|
||||||
|
*/
|
||||||
|
plSceneObject* GetTarget() const;
|
||||||
|
|
||||||
void AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop = true, bool randomStartPos = true,
|
void AddBehavior(const std::string& animationName, const std::string& behaviorName, bool loop = true, bool randomStartPos = true,
|
||||||
float fadeInLen = 2.f, float fadeOutLen = 2.f);
|
float fadeInLen = 2.f, float fadeOutLen = 2.f);
|
||||||
void StartBehavior(const std::string& behaviorName, bool fade = true);
|
void StartBehavior(const std::string& behaviorName, bool fade = true);
|
||||||
bool RunningBehavior(const std::string& behaviorName) const;
|
bool RunningBehavior(const std::string& behaviorName) const;
|
||||||
|
|
||||||
void LocallyControlled(bool local) {fLocallyControlled = local;}
|
|
||||||
bool LocallyControlled() const {return fLocallyControlled;}
|
|
||||||
|
|
||||||
std::string BehaviorName(int behavior) const;
|
std::string BehaviorName(int behavior) const;
|
||||||
plString AnimationName(int behavior) const;
|
plString AnimationName(int behavior) const;
|
||||||
@ -157,8 +164,6 @@ protected:
|
|||||||
int fNextMode; // the next behavior to run (-1 if we aren't switching on next eval)
|
int fNextMode; // the next behavior to run (-1 if we aren't switching on next eval)
|
||||||
bool fFadingNextBehavior; // is the next behavior supposed to blend?
|
bool fFadingNextBehavior; // is the next behavior supposed to blend?
|
||||||
|
|
||||||
bool fLocallyControlled; // is our local AI script the one making all the choices?
|
|
||||||
|
|
||||||
bool fAvoidingAvatars; // are we avoiding avatars to the best of our ability when pathfinding?
|
bool fAvoidingAvatars; // are we avoiding avatars to the best of our ability when pathfinding?
|
||||||
hsPoint3 fFinalGoalPos; // the location we are pathfinding to
|
hsPoint3 fFinalGoalPos; // the location we are pathfinding to
|
||||||
hsPoint3 fImmediateGoalPos; // the location of the point we are immediately going towards (not necessarily our final goal)
|
hsPoint3 fImmediateGoalPos; // the location of the point we are immediately going towards (not necessarily our final goal)
|
||||||
|
@ -217,11 +217,17 @@ plKey plAvatarMgr::LoadAvatar(const char *name, const char *accountName, bool is
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void plAvatarMgr::UnLoadAvatar(plKey avatarKey, bool isPlayer)
|
void plAvatarMgr::UnLoadAvatar(const plKey& avatarKey, bool isPlayer, bool netPropagate) const
|
||||||
{
|
{
|
||||||
hsBool isLoading = false;
|
if (avatarKey)
|
||||||
plLoadAvatarMsg *msg = new plLoadAvatarMsg(avatarKey, GetKey(), 0, isPlayer, isLoading);
|
{
|
||||||
msg->Send();
|
plKey requestor = GetKey();
|
||||||
|
plLoadAvatarMsg* msg = new plLoadAvatarMsg(avatarKey, requestor, 0, isPlayer, false);
|
||||||
|
|
||||||
|
// only netprop if the user has a death wish
|
||||||
|
msg->SetBCastFlag(plMessage::kNetPropagate, netPropagate);
|
||||||
|
msg->Send();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// our player's already loaded locally, but we've just linked into an age and others there need to be
|
// our player's already loaded locally, but we've just linked into an age and others there need to be
|
||||||
@ -271,22 +277,6 @@ bool plAvatarMgr::UnPropagateLocalPlayer()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UNLOADREMOTEPLAYER
|
|
||||||
void plAvatarMgr::UnLoadRemotePlayer(plKey remotePlayer)
|
|
||||||
{
|
|
||||||
if(remotePlayer)
|
|
||||||
{
|
|
||||||
plKey requestor = GetKey();
|
|
||||||
bool isPlayer = true;
|
|
||||||
hsBool isLoading = false;
|
|
||||||
plLoadAvatarMsg * msg = new plLoadAvatarMsg(remotePlayer, requestor, 0, isPlayer, isLoading);
|
|
||||||
|
|
||||||
// don't propagate over the network. this is just for removing our local version
|
|
||||||
msg->SetBCastFlag(plMessage::kNetPropagate, false);
|
|
||||||
msg->Send();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UNLOADLOCALPLAYER
|
// UNLOADLOCALPLAYER
|
||||||
void plAvatarMgr::UnLoadLocalPlayer()
|
void plAvatarMgr::UnLoadLocalPlayer()
|
||||||
{
|
{
|
||||||
|
@ -115,15 +115,21 @@ public:
|
|||||||
plKey LoadPlayer(const char* name, const char *account);
|
plKey LoadPlayer(const char* name, const char *account);
|
||||||
plKey LoadPlayer(const char* name, const char *account, const char *linkName);
|
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 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);
|
/**
|
||||||
|
* Unload an avatar clone
|
||||||
|
*
|
||||||
|
* This unloads the clone of an avatar (remote player or NPC) from our local game.
|
||||||
|
* The avatar clone can be unloaded globally by setting netPropagate; however, this
|
||||||
|
* is highly discouraged.
|
||||||
|
*/
|
||||||
|
void UnLoadAvatar(const plKey& avKey, bool isPlayer, bool netPropagate=false) const;
|
||||||
/** send our (already loaded) local player to newly-associated clients - used when linking */
|
/** send our (already loaded) local player to newly-associated clients - used when linking */
|
||||||
void PropagateLocalPlayer(int spawnPoint = -1);
|
void PropagateLocalPlayer(int spawnPoint = -1);
|
||||||
/** Unload our local player on other machines because we're leaving this age.
|
/** Unload our local player on other machines because we're leaving this age.
|
||||||
The player will stay around on our local machine, though. */
|
The player will stay around on our local machine, though. */
|
||||||
bool UnPropagateLocalPlayer();
|
bool UnPropagateLocalPlayer();
|
||||||
|
|
||||||
void UnLoadRemotePlayer(plKey playerKey);
|
|
||||||
void UnLoadLocalPlayer();
|
void UnLoadLocalPlayer();
|
||||||
|
|
||||||
void AddAvatar(plArmatureMod *avatar);
|
void AddAvatar(plArmatureMod *avatar);
|
||||||
|
@ -99,16 +99,6 @@ void plNPCSpawnMod::AddTarget(plSceneObject* so)
|
|||||||
Trigger();
|
Trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
void plNPCSpawnMod::RemoveTarget(plSceneObject *so)
|
|
||||||
{
|
|
||||||
plSingleModifier::RemoveTarget(so);
|
|
||||||
|
|
||||||
if(fSpawnedKey)
|
|
||||||
{
|
|
||||||
plAvatarMgr::GetInstance()->UnLoadAvatar(fSpawnedKey, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TRIGGER
|
// TRIGGER
|
||||||
bool plNPCSpawnMod::Trigger()
|
bool plNPCSpawnMod::Trigger()
|
||||||
{
|
{
|
||||||
@ -123,6 +113,7 @@ bool plNPCSpawnMod::Trigger()
|
|||||||
// spawn the NPC
|
// spawn the NPC
|
||||||
plKey spawnPoint = GetTarget(0)->GetKey();
|
plKey spawnPoint = GetTarget(0)->GetKey();
|
||||||
|
|
||||||
|
// Note: we will be unloaded by the NetApp's NPC magick
|
||||||
fSpawnedKey = plAvatarMgr::GetInstance()->LoadAvatar(fModelName, fAccountName, false, spawnPoint, nil);
|
fSpawnedKey = plAvatarMgr::GetInstance()->LoadAvatar(fModelName, fAccountName, false, spawnPoint, nil);
|
||||||
|
|
||||||
ISendNotify(fSpawnedKey);
|
ISendNotify(fSpawnedKey);
|
||||||
|
@ -58,7 +58,6 @@ public:
|
|||||||
GETINTERFACE_ANY( plNPCSpawnMod, plSingleModifier );
|
GETINTERFACE_ANY( plNPCSpawnMod, plSingleModifier );
|
||||||
|
|
||||||
virtual void AddTarget(plSceneObject* so);
|
virtual void AddTarget(plSceneObject* so);
|
||||||
virtual void RemoveTarget(plSceneObject *so);
|
|
||||||
// hsBool MsgReceive(plMessage* msg);
|
// hsBool MsgReceive(plMessage* msg);
|
||||||
|
|
||||||
virtual void Read(hsStream *stream, hsResMgr *mgr);
|
virtual void Read(hsStream *stream, hsResMgr *mgr);
|
||||||
|
@ -223,6 +223,7 @@ void plNCAgeLeaver::ExecNextOp () {
|
|||||||
plAgeLoader::GetInstance()->UnloadAge(); // unload age
|
plAgeLoader::GetInstance()->UnloadAge(); // unload age
|
||||||
nc->ISendCameraReset(false/*leaving age*/); // reset camera
|
nc->ISendCameraReset(false/*leaving age*/); // reset camera
|
||||||
nc->IUnloadRemotePlayers(); // unload other players
|
nc->IUnloadRemotePlayers(); // unload other players
|
||||||
|
nc->IUnloadNPCs(); // unload non-player clones
|
||||||
|
|
||||||
if (NetCommNeedToLoadAvatar())
|
if (NetCommNeedToLoadAvatar())
|
||||||
am->UnLoadLocalPlayer();
|
am->UnLoadLocalPlayer();
|
||||||
|
@ -181,13 +181,9 @@ void plNetClientMgr::Shutdown()
|
|||||||
|
|
||||||
plNetLinkingMgr::GetInstance()->LeaveAge(true);
|
plNetLinkingMgr::GetInstance()->LeaveAge(true);
|
||||||
|
|
||||||
// release existing remote players
|
// release all avatar clones
|
||||||
int i;
|
IUnloadRemotePlayers();
|
||||||
for (i=0;i<RemotePlayerKeys().size();i++)
|
IUnloadNPCs();
|
||||||
{
|
|
||||||
plKey k=RemotePlayerKeys()[i];
|
|
||||||
plAvatarMgr::GetInstance()->UnLoadRemotePlayer(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, pump the dispatch system so all the new refs get delivered.
|
// Finally, pump the dispatch system so all the new refs get delivered.
|
||||||
plgDispatch::Dispatch()->MsgQueueProcess();
|
plgDispatch::Dispatch()->MsgQueueProcess();
|
||||||
@ -197,7 +193,7 @@ void plNetClientMgr::Shutdown()
|
|||||||
delete fMsgRecorder;
|
delete fMsgRecorder;
|
||||||
fMsgRecorder = nil;
|
fMsgRecorder = nil;
|
||||||
}
|
}
|
||||||
for (i = 0; i < fMsgPlayers.size(); i++)
|
for (int i = 0; i < fMsgPlayers.size(); i++)
|
||||||
delete fMsgPlayers[i];
|
delete fMsgPlayers[i];
|
||||||
fMsgPlayers.clear();
|
fMsgPlayers.clear();
|
||||||
|
|
||||||
@ -424,9 +420,19 @@ int plNetClientMgr::IPrepMsg(plNetMessage* msg)
|
|||||||
//
|
//
|
||||||
void plNetClientMgr::IUnloadRemotePlayers()
|
void plNetClientMgr::IUnloadRemotePlayers()
|
||||||
{
|
{
|
||||||
for(int i=RemotePlayerKeys().size()-1;i>=0;i--)
|
for (size_t i = fRemotePlayerKeys.size(); i > 0; --i)
|
||||||
plAvatarMgr::GetInstance()->UnLoadRemotePlayer(RemotePlayerKeys()[i]);
|
plAvatarMgr::GetInstance()->UnLoadAvatar(fRemotePlayerKeys[i-1], true);
|
||||||
hsAssert(!RemotePlayerKeys().size(),"Still remote players left when linking out");
|
hsAssert(fRemotePlayerKeys.empty(), "Still remote players left when linking out");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// unload NPCs since we're leaving the age
|
||||||
|
//
|
||||||
|
void plNetClientMgr::IUnloadNPCs()
|
||||||
|
{
|
||||||
|
for (size_t i = fNPCKeys.size(); i > 0; --i)
|
||||||
|
plAvatarMgr::GetInstance()->UnLoadAvatar(fNPCKeys[i-1], false);
|
||||||
|
hsAssert(fNPCKeys.empty(), "Still npcs left when linking out");
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -853,6 +859,31 @@ plSynchedObject* plNetClientMgr::GetLocalPlayer(hsBool forceLoad) const
|
|||||||
plSynchedObject::ConvertNoRef(fLocalPlayerKey->ObjectIsLoaded()) : nil;
|
plSynchedObject::ConvertNoRef(fLocalPlayerKey->ObjectIsLoaded()) : nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plSynchedObject* plNetClientMgr::GetNPC(uint32_t i) const
|
||||||
|
{
|
||||||
|
return fNPCKeys[i] ? plSynchedObject::ConvertNoRef(fNPCKeys[i]->ObjectIsLoaded()) : nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plNetClientMgr::AddNPCKey(const plKey& npc)
|
||||||
|
{
|
||||||
|
// note: npc keys have little sanity checking...
|
||||||
|
hsAssert(npc, "adding nil npc key? naughty, naughty...");
|
||||||
|
fNPCKeys.push_back(npc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool plNetClientMgr::IsNPCKey(const plKey& npc, int* idx) const
|
||||||
|
{
|
||||||
|
if (npc)
|
||||||
|
{
|
||||||
|
plKeyVec::const_iterator it = std::find(fNPCKeys.begin(), fNPCKeys.end(), npc);
|
||||||
|
bool found = it != fNPCKeys.end();
|
||||||
|
if (idx)
|
||||||
|
*idx = found ? (it - fNPCKeys.begin()) : -1;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// return a ptr to a remote player
|
// return a ptr to a remote player
|
||||||
//
|
//
|
||||||
|
@ -153,7 +153,7 @@ private:
|
|||||||
// cached char info
|
// cached char info
|
||||||
plKey fLocalPlayerKey;
|
plKey fLocalPlayerKey;
|
||||||
plKeyVec fRemotePlayerKeys;
|
plKeyVec fRemotePlayerKeys;
|
||||||
// plKeyVec fNPCKeys;
|
plKeyVec fNPCKeys;
|
||||||
|
|
||||||
class plNetClientMgrMsg * fDisableMsg;
|
class plNetClientMgrMsg * fDisableMsg;
|
||||||
|
|
||||||
@ -222,6 +222,7 @@ private:
|
|||||||
void IRemoveCloneRoom();
|
void IRemoveCloneRoom();
|
||||||
|
|
||||||
void IUnloadRemotePlayers();
|
void IUnloadRemotePlayers();
|
||||||
|
void IUnloadNPCs();
|
||||||
|
|
||||||
plKey ILoadClone(plLoadCloneMsg *cloneMsg);
|
plKey ILoadClone(plLoadCloneMsg *cloneMsg);
|
||||||
|
|
||||||
@ -309,9 +310,15 @@ public:
|
|||||||
|
|
||||||
// avatar vault actions
|
// avatar vault actions
|
||||||
int UploadPlayerVault(uint32_t vaultFlags);
|
int UploadPlayerVault(uint32_t vaultFlags);
|
||||||
|
|
||||||
|
// npc clones
|
||||||
|
const plKeyVec& NPCKeys() const { return fNPCKeys; }
|
||||||
|
plSynchedObject* GetNPC(uint32_t i) const;
|
||||||
|
void AddNPCKey(const plKey& npc);
|
||||||
|
bool IsNPCKey(const plKey& npc, int* idx=nil) const;
|
||||||
|
|
||||||
// remote players
|
// remote players
|
||||||
const std::vector<plKey>& RemotePlayerKeys() const { return fRemotePlayerKeys; }
|
const plKeyVec& RemotePlayerKeys() const { return fRemotePlayerKeys; }
|
||||||
plSynchedObject* GetRemotePlayer(int i) const;
|
plSynchedObject* GetRemotePlayer(int i) const;
|
||||||
void AddRemotePlayerKey(plKey p);
|
void AddRemotePlayerKey(plKey p);
|
||||||
hsBool IsRemotePlayerKey(const plKey p, int* idx=nil);
|
hsBool IsRemotePlayerKey(const plKey p, int* idx=nil);
|
||||||
|
@ -113,13 +113,16 @@ plKey plNetClientMgr::ILoadClone(plLoadCloneMsg *pCloneMsg)
|
|||||||
|
|
||||||
// check if local or remote player before loading
|
// check if local or remote player before loading
|
||||||
plLoadAvatarMsg* loadAvMsg=plLoadAvatarMsg::ConvertNoRef(pCloneMsg);
|
plLoadAvatarMsg* loadAvMsg=plLoadAvatarMsg::ConvertNoRef(pCloneMsg);
|
||||||
if (loadAvMsg && loadAvMsg->GetIsPlayer())
|
if (loadAvMsg)
|
||||||
{
|
{
|
||||||
bool originating = ( pCloneMsg->GetOriginatingPlayerID() == this->GetPlayerID() );
|
bool originating = ( pCloneMsg->GetOriginatingPlayerID() == this->GetPlayerID() );
|
||||||
if (originating)
|
if (loadAvMsg->GetIsPlayer())
|
||||||
fLocalPlayerKey = cloneKey;
|
if (originating)
|
||||||
else
|
fLocalPlayerKey = cloneKey;
|
||||||
AddRemotePlayerKey(cloneKey);
|
else
|
||||||
|
AddRemotePlayerKey(cloneKey);
|
||||||
|
else // hey, we got a quab or yeesha... or some other such devilry...
|
||||||
|
AddNPCKey(cloneKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
plKey cloneNodeKey = hsgResMgr::ResMgr()->FindKey(kNetClientCloneRoom_KEY);
|
plKey cloneNodeKey = hsgResMgr::ResMgr()->FindKey(kNetClientCloneRoom_KEY);
|
||||||
@ -139,6 +142,12 @@ plKey plNetClientMgr::ILoadClone(plLoadCloneMsg *pCloneMsg)
|
|||||||
return cloneKey;
|
return cloneKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// need to drop our ref if it's an NPC
|
||||||
|
// remote players handled by plPlayerPageMsg--don't sweat that
|
||||||
|
plKeyVec::iterator it = std::find(fNPCKeys.begin(), fNPCKeys.end(), cloneKey);
|
||||||
|
if (it != fNPCKeys.end())
|
||||||
|
fNPCKeys.erase(it);
|
||||||
|
|
||||||
ICheckPendingStateLoad(hsTimer::GetSysSeconds());
|
ICheckPendingStateLoad(hsTimer::GetSysSeconds());
|
||||||
plSynchEnabler p(false); // turn off dirty tracking while in this function
|
plSynchEnabler p(false); // turn off dirty tracking while in this function
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user