diff --git a/Sources/Plasma/FeatureLib/pfPython/cyMisc.cpp b/Sources/Plasma/FeatureLib/pfPython/cyMisc.cpp index b29a516d..4265ca48 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyMisc.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyMisc.cpp @@ -42,6 +42,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include #include "plgDispatch.h" +#include "hsResMgr.h" #include "pyKey.h" #pragma hdrstop @@ -49,6 +50,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plResMgr/plKeyFinder.h" #include "pnKeyedObject/plKey.h" +#include "pnKeyedObject/plKeyImp.h" #include "pnKeyedObject/plFixedKey.h" #include "plMessage/plLinkToAgeMsg.h" #include "plMessage/plConsoleMsg.h" @@ -302,7 +304,7 @@ void cyMisc::ClearTimerCallbacks(pyKey& selfkey) // // PURPOSE : Attach an object to another object, knowing only their pyKeys // -void cyMisc::AttachObject(pyKey& ckey, pyKey& pkey) +void cyMisc::AttachObject(pyKey& ckey, pyKey& pkey, bool netForce) { plKey childKey = ckey.getKey(); plKey parentKey = pkey.getKey(); @@ -312,10 +314,16 @@ void cyMisc::AttachObject(pyKey& ckey, pyKey& pkey) { // create the attach message to attach the child plAttachMsg* pMsg = new plAttachMsg(parentKey, childKey->GetObjectPtr(), plRefMsg::kOnRequest); + + if (netForce) { + pMsg->SetBCastFlag(plMessage::kNetPropagate); + pMsg->SetBCastFlag(plMessage::kNetForce); + } + plgDispatch::MsgSend( pMsg ); } } -void cyMisc::AttachObjectSO(pySceneObject& cobj, pySceneObject& pobj) +void cyMisc::AttachObjectSO(pySceneObject& cobj, pySceneObject& pobj, bool netForce) { plKey childKey = cobj.getObjKey(); plKey parentKey = pobj.getObjKey(); @@ -325,6 +333,12 @@ void cyMisc::AttachObjectSO(pySceneObject& cobj, pySceneObject& pobj) { // create the attach message to attach the child plAttachMsg* pMsg = new plAttachMsg(parentKey, childKey->GetObjectPtr(), plRefMsg::kOnRequest); + + if (netForce) { + pMsg->SetBCastFlag(plMessage::kNetPropagate); + pMsg->SetBCastFlag(plMessage::kNetForce); + } + plgDispatch::MsgSend( pMsg ); } } @@ -338,7 +352,7 @@ void cyMisc::AttachObjectSO(pySceneObject& cobj, pySceneObject& pobj) // // PURPOSE : Attach an object to another object, knowing only their pyKeys // -void cyMisc::DetachObject(pyKey& ckey, pyKey& pkey) +void cyMisc::DetachObject(pyKey& ckey, pyKey& pkey, bool netForce) { plKey childKey = ckey.getKey(); plKey parentKey = pkey.getKey(); @@ -348,10 +362,16 @@ void cyMisc::DetachObject(pyKey& ckey, pyKey& pkey) { // create the attach message to detach the child plAttachMsg* pMsg = new plAttachMsg(parentKey, childKey->GetObjectPtr(), plRefMsg::kOnRemove); + + if (netForce) { + pMsg->SetBCastFlag(plMessage::kNetPropagate); + pMsg->SetBCastFlag(plMessage::kNetForce); + } + plgDispatch::MsgSend( pMsg ); } } -void cyMisc::DetachObjectSO(pySceneObject& cobj, pySceneObject& pobj) +void cyMisc::DetachObjectSO(pySceneObject& cobj, pySceneObject& pobj, bool netForce) { plKey childKey = cobj.getObjKey(); plKey parentKey = pobj.getObjKey(); @@ -361,6 +381,12 @@ void cyMisc::DetachObjectSO(pySceneObject& cobj, pySceneObject& pobj) { // create the attach message to detach the child plAttachMsg* pMsg = new plAttachMsg(parentKey, childKey->GetObjectPtr(), plRefMsg::kOnRemove); + + if (netForce) { + pMsg->SetBCastFlag(plMessage::kNetPropagate); + pMsg->SetBCastFlag(plMessage::kNetForce); + } + plgDispatch::MsgSend( pMsg ); } } @@ -1415,7 +1441,7 @@ int cyMisc::GetNumRemotePlayers() // PURPOSE : page in, hold or out a particular node // -void cyMisc::PageInNodes(const std::vector & nodeNames, const char* age) +void cyMisc::PageInNodes(const std::vector & nodeNames, const char* age, bool netForce) { if (hsgResMgr::ResMgr()) { @@ -1424,6 +1450,11 @@ void cyMisc::PageInNodes(const std::vector & nodeNames, const char* plKey clientKey = hsgResMgr::ResMgr()->FindKey(kClient_KEY); msg->AddReceiver(clientKey); + if (netForce) { + msg->SetBCastFlag(plMessage::kNetPropagate); + msg->SetBCastFlag(plMessage::kNetForce); + } + int numNames = nodeNames.size(); for (int i = 0; i < numNames; i++) msg->AddRoomLoc(plKeyFinder::Instance().FindLocation(age ? age : NetCommGetAge()->ageDatasetName, nodeNames[i].c_str())); @@ -1432,7 +1463,7 @@ void cyMisc::PageInNodes(const std::vector & nodeNames, const char* } } -void cyMisc::PageOutNode(const char* nodeName) +void cyMisc::PageOutNode(const char* nodeName, bool netForce) { if ( hsgResMgr::ResMgr() ) { @@ -1441,6 +1472,11 @@ void cyMisc::PageOutNode(const char* nodeName) plKey clientKey = hsgResMgr::ResMgr()->FindKey( kClient_KEY ); pMsg1->AddReceiver( clientKey ); pMsg1->AddRoomLoc(plKeyFinder::Instance().FindLocation("", nodeName)); + + if (netForce) { + pMsg1->SetBCastFlag(plMessage::kNetPropagate); + pMsg1->SetBCastFlag(plMessage::kNetForce); + } plgDispatch::MsgSend(pMsg1); } } @@ -2866,3 +2902,39 @@ void cyMisc::VaultDownload(unsigned nodeId) nil ); } + +PyObject* cyMisc::CloneKey(pyKey* object, bool netForce) { + + plKey obj = object->getKey(); + plUoid uoid = obj->GetUoid(); + plLoadCloneMsg* cloneMsg; + if (uoid.IsClone()) + cloneMsg = new plLoadCloneMsg(obj, plNetClientMgr::GetInstance()->GetKey(), 0, true); + else + cloneMsg = new plLoadCloneMsg(uoid, plNetClientMgr::GetInstance()->GetKey(), 0); + + if (netForce) { + cloneMsg->SetBCastFlag(plMessage::kNetPropagate); + cloneMsg->SetBCastFlag(plMessage::kNetForce); + } + + cloneMsg->Send(); + + return pyKey::New(cloneMsg->GetCloneKey()); +} + +PyObject* cyMisc::FindClones(pyKey* object) { + plKey obj = object->getKey(); + plUoid uoid = obj->GetUoid(); + + plKeyImp* imp = ((plKeyImp*)obj); + uint32_t cloneNum = imp->GetNumClones(); + PyObject* keyList = PyList_New(cloneNum); + + for (int i=0; i < cloneNum; i++) { + PyObject* key = pyKey::New(imp->GetCloneByIdx(i)); + PyList_SET_ITEM(keyList, i, key); + } + + return keyList; +} diff --git a/Sources/Plasma/FeatureLib/pfPython/cyMisc.h b/Sources/Plasma/FeatureLib/pfPython/cyMisc.h index 3f6f543c..ef0fc7a0 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyMisc.h +++ b/Sources/Plasma/FeatureLib/pfPython/cyMisc.h @@ -184,8 +184,8 @@ public: // // PURPOSE : Attach an object to another object, knowing only their pyKeys // - static void AttachObject(pyKey& ckey, pyKey& pkey); - static void AttachObjectSO(pySceneObject& cobj, pySceneObject& pobj); + static void AttachObject(pyKey& ckey, pyKey& pkey, bool netForce); + static void AttachObjectSO(pySceneObject& cobj, pySceneObject& pobj, bool netForce); ///////////////////////////////////////////////////////////////////////////// // @@ -195,8 +195,8 @@ public: // // PURPOSE : Attach an object to another object, knowing only their pyKeys // - static void DetachObject(pyKey& ckey, pyKey& pkey); - static void DetachObjectSO(pySceneObject& cobj, pySceneObject& pobj); + static void DetachObject(pyKey& ckey, pyKey& pkey, bool netForce); + static void DetachObjectSO(pySceneObject& cobj, pySceneObject& pobj, bool netForce); ///////////////////////////////////////////////////////////////////////////// // @@ -593,8 +593,8 @@ public: // // PURPOSE : page in, or out a paritcular node // - static void PageInNodes(const std::vector & nodeNames, const char* age); - static void PageOutNode(const char* nodeName); + static void PageInNodes(const std::vector & nodeNames, const char* age, bool netForce); + static void PageOutNode(const char* nodeName, bool netForce); ///////////////////////////////////////////////////////////////////////////// // @@ -954,6 +954,8 @@ public: static PyObject* GetAIAvatarsByModelName(const char* name); static void ForceVaultNodeUpdate(unsigned nodeId); static void VaultDownload(unsigned nodeId); + static PyObject* CloneKey(pyKey* object, bool netForce); + static PyObject* FindClones(pyKey* object); }; #endif // cyMisc_h diff --git a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue.cpp index a01c13a5..43806e18 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue.cpp @@ -484,6 +484,31 @@ PYTHON_GLOBAL_METHOD_DEFINITION(PtDumpLogs, args, "Params: folder\nDumps all cur } } +PYTHON_GLOBAL_METHOD_DEFINITION(PtCloneKey, args, "Params: key, netForce=false\nCreates clone of key") +{ + PyObject* keyObj = NULL; + char netForce = 0; + if (!PyArg_ParseTuple(args, "O|b", &keyObj, &netForce) || !pyKey::Check(keyObj)) + { + PyErr_SetString(PyExc_TypeError, "PtCloneKey expects a ptKey and bool"); + PYTHON_RETURN_ERROR; + } + pyKey* key = pyKey::ConvertFrom(keyObj); + return cyMisc::CloneKey(key, netForce); +} + +PYTHON_GLOBAL_METHOD_DEFINITION(PtFindClones, args, "Params: key\nFinds all clones") +{ + PyObject* keyObj = NULL; + if (!PyArg_ParseTuple(args, "O", &keyObj) || !pyKey::Check(keyObj)) + { + PyErr_SetString(PyExc_TypeError, "PtFindClones expects a ptKey"); + PYTHON_RETURN_ERROR; + } + pyKey* key = pyKey::ConvertFrom(keyObj); + return cyMisc::FindClones(key); +} + /////////////////////////////////////////////////////////////////////////// // // AddPlasmaMethods - the python method definitions @@ -530,6 +555,8 @@ void cyMisc::AddPlasmaMethods(std::vector &methods) PYTHON_GLOBAL_METHOD(methods, PtGetLocalizedString); PYTHON_GLOBAL_METHOD(methods, PtDumpLogs); + PYTHON_GLOBAL_METHOD(methods, PtCloneKey); + PYTHON_GLOBAL_METHOD(methods, PtFindClones); AddPlasmaMethods2(methods); AddPlasmaMethods3(methods); diff --git a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue2.cpp b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue2.cpp index 53baabf8..a37485bb 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue2.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue2.cpp @@ -183,11 +183,12 @@ PYTHON_GLOBAL_METHOD_DEFINITION_NOARGS(PtGetFrameDeltaTime, "Returns the amount return PyFloat_FromDouble(cyMisc::GetDelSysSeconds()); } -PYTHON_GLOBAL_METHOD_DEFINITION(PtPageInNode, args, "Params: nodeName, ageName=\"\"\nPages in node, or a list of nodes") +PYTHON_GLOBAL_METHOD_DEFINITION(PtPageInNode, args, "Params: nodeName, netForce=false, ageName=\"\"\nPages in node, or a list of nodes") { PyObject* nodeNameObj = NULL; char* ageName = NULL; - if (!PyArg_ParseTuple(args, "O|s", &nodeNameObj, &ageName)) + char netForce = 0; + if (!PyArg_ParseTuple(args, "O|bs", &nodeNameObj, &netForce, &ageName)) { PyErr_SetString(PyExc_TypeError, "PtPageInNode expects a string or list of strings, and optionally a string"); PYTHON_RETURN_ERROR; @@ -217,19 +218,20 @@ PYTHON_GLOBAL_METHOD_DEFINITION(PtPageInNode, args, "Params: nodeName, ageName=\ PYTHON_RETURN_ERROR; } - cyMisc::PageInNodes(nodeNames, ageName); + cyMisc::PageInNodes(nodeNames, ageName, netForce); PYTHON_RETURN_NONE; } -PYTHON_GLOBAL_METHOD_DEFINITION(PtPageOutNode, args, "Params: nodeName\nPages out a node") +PYTHON_GLOBAL_METHOD_DEFINITION(PtPageOutNode, args, "Params: nodeName, netForce = false\nPages out a node") { char* nodeName; - if (!PyArg_ParseTuple(args, "s", &nodeName)) + char netForce = 0; + if (!PyArg_ParseTuple(args, "s|b", &nodeName, &netForce)) { - PyErr_SetString(PyExc_TypeError, "PtPageOutNode expects a string"); + PyErr_SetString(PyExc_TypeError, "PtPageOutNode expects a string and bool"); PYTHON_RETURN_ERROR; } - cyMisc::PageOutNode(nodeName); + cyMisc::PageOutNode(nodeName, netForce); PYTHON_RETURN_NONE; } diff --git a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp index 15016870..71313789 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp @@ -223,65 +223,67 @@ PYTHON_GLOBAL_METHOD_DEFINITION(PtWasLocallyNotified, args, "Params: selfKey\nRe PYTHON_RETURN_BOOL(cyMisc::WasLocallyNotified(*key)); } -PYTHON_GLOBAL_METHOD_DEFINITION(PtAttachObject, args, "Params: child,parent\nAttach child to parent based on ptKey or ptSceneobject\n" +PYTHON_GLOBAL_METHOD_DEFINITION(PtAttachObject, args, "Params: child,parent,netForce=false\nAttach child to parent based on ptKey or ptSceneobject\n" "- childKey is the ptKey or ptSceneobject of the one being attached\n" "- parentKey is the ptKey or ptSceneobject of the one being attached to\n" "(both arguments must be ptKeys or ptSceneobjects, you cannot mix types)") { PyObject* childObj = NULL; PyObject* parentObj = NULL; - if (!PyArg_ParseTuple(args, "OO", &childObj, &parentObj)) + char netForce = 0; + if (!PyArg_ParseTuple(args, "OO|b", &childObj, &parentObj, &netForce)) { - PyErr_SetString(PyExc_TypeError, "PtAttachObject expects either two ptKeys or two ptSceneobjects"); + PyErr_SetString(PyExc_TypeError, "PtAttachObject expects either two ptKeys or two ptSceneobjects and bool"); PYTHON_RETURN_ERROR; } if ((pyKey::Check(childObj)) && (pyKey::Check(parentObj))) { pyKey* child = pyKey::ConvertFrom(childObj); pyKey* parent = pyKey::ConvertFrom(parentObj); - cyMisc::AttachObject(*child, *parent); + cyMisc::AttachObject(*child, *parent, netForce); } else if ((pySceneObject::Check(childObj)) && (pySceneObject::Check(parentObj))) { pySceneObject* child = pySceneObject::ConvertFrom(childObj); pySceneObject* parent = pySceneObject::ConvertFrom(parentObj); - cyMisc::AttachObjectSO(*child, *parent); + cyMisc::AttachObjectSO(*child, *parent, netForce); } else { - PyErr_SetString(PyExc_TypeError, "PtAttachObject expects either two ptKeys or two ptSceneobjects"); + PyErr_SetString(PyExc_TypeError, "PtAttachObject expects either two ptKeys or two ptSceneobjects and bool"); PYTHON_RETURN_ERROR; } PYTHON_RETURN_NONE; } -PYTHON_GLOBAL_METHOD_DEFINITION(PtDetachObject, args, "Params: child,parent\nDetach child from parent based on ptKey or ptSceneobject\n" +PYTHON_GLOBAL_METHOD_DEFINITION(PtDetachObject, args, "Params: child,parent,netForce=false\nDetach child from parent based on ptKey or ptSceneobject\n" "- child is the ptKey or ptSceneobject of the one being detached\n" "- parent is the ptKey or ptSceneobject of the one being detached from\n" "(both arguments must be ptKeys or ptSceneobjects, you cannot mix types)") { PyObject* childObj = NULL; PyObject* parentObj = NULL; - if (!PyArg_ParseTuple(args, "OO", &childObj, &parentObj)) + char netForce = 0; + if (!PyArg_ParseTuple(args, "OO|b", &childObj, &parentObj, &netForce)) { - PyErr_SetString(PyExc_TypeError, "PtDetachObject expects either two ptKeys or two ptSceneobjects"); + PyErr_SetString(PyExc_TypeError, "PtDetachObject expects either two ptKeys or two ptSceneobjects and bool"); PYTHON_RETURN_ERROR; } if ((pyKey::Check(childObj)) && (pyKey::Check(parentObj))) { pyKey* child = pyKey::ConvertFrom(childObj); pyKey* parent = pyKey::ConvertFrom(parentObj); - cyMisc::DetachObject(*child, *parent); + cyMisc::DetachObject(*child, *parent, netForce); } else if ((pySceneObject::Check(childObj)) && (pySceneObject::Check(parentObj))) { pySceneObject* child = pySceneObject::ConvertFrom(childObj); pySceneObject* parent = pySceneObject::ConvertFrom(parentObj); - cyMisc::DetachObjectSO(*child, *parent); + cyMisc::DetachObjectSO(*child, *parent, netForce); } else { - PyErr_SetString(PyExc_TypeError, "PtDetachObject expects either two ptKeys or two ptSceneobjects"); + PyErr_SetString(PyExc_TypeError, "PtDetachObject expects either two ptKeys or two ptSceneobjects and bool"); PYTHON_RETURN_ERROR; } PYTHON_RETURN_NONE;