gameBase.cpp
Engine/source/T3D/gameBase/gameBase.cpp
Public Variables
Public Functions
ConsoleDocClass(GameBase , "@brief Base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> game objects which use datablocks, networking , are " " editable, and need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ticks.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gameObjects\n</a>" )
ConsoleDocClass(GameBaseData , "@brief Scriptable, demo-able datablock. Used by <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GameBase\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gameObjects\n</a>" )
DefineEngineMethod(GameBase , applyImpulse , bool , (Point3F pos, VectorF vel) , "@brief Apply an impulse <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this object as defined by <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> world position and velocity <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">vector.\n\n</a>" "@param pos impulse world <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position\n</a>" "@param vel impulse velocity (impulse force F = m * v)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@return Always <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">true\n</a>" "@note Not all objects that derrive from <a href="/coding/class/classgamebase/">GameBase</a> have this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">defined.\n</a>" )
DefineEngineMethod(GameBase , applyRadialImpulse , void , (Point3F origin, F32 radius, F32 magnitude) , "@brief Applies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> radial impulse <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the object using the given origin and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">force.\n\n</a>" "@param origin <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a81f4537631c9ab219ec74de554483adc">World</a> point of origin of the radial <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">impulse.\n</a>" "@param radius The radius of the impulse <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">area.\n</a>" "@param magnitude The strength of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">impulse.\n</a>" "@note Not all objects that derrive from <a href="/coding/class/classgamebase/">GameBase</a> have this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">defined.\n</a>" )
DefineEngineMethod(GameBase , attachChild , bool , (GameBase *_subObject) , (nullAsType< GameBase * >()) , "(SceneObject subObject)" "attach an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this one, preserving its present transform." )
DefineEngineMethod(GameBase , detachChild , bool , (GameBase *_subObject) , (nullAsType< GameBase * >()) , "(SceneObject subObject)" "attach an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this one, preserving its present transform." )
DefineEngineMethod(GameBase , getDataBlock , S32 , () , "@brief Get the datablock used by this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@return the datablock this <a href="/coding/class/classgamebase/">GameBase</a> is using." "@see setDataBlock()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" )
DefineEngineMethod(GameBase , setDataBlock , bool , (GameBaseData *data) , "@brief Assign this <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use the specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@param data <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> datablock <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">use\n</a>" "@return true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> failed." " @see getDataBlock()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" )
IMPLEMENT_CALLBACK(GameBase , setControl , void , (bool controlled) , (controlled) , "@brief Called when the client controlling the object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">changes.\n\n</a>" "@param controlled true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> client now controls this object, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no " "client controls this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onAdd , void , (GameBase *obj) , (obj) , "@brief Called when the object is added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "datablock <a href="/coding/class/structgamebasedata/">GameBaseData</a>(MyObjectData)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " category = \"Misc\";\n" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onAdd( %this, %obj )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( \"Added \" @ %obj.getName() @ \" to the scene.\" );\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onNewDataBlock( %this, %obj )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( \"Assign \" @ %this.getName() @ \" datablock <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> \" %obj.getName() );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onRemove( %this, %obj )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( \"Removed \" @ %obj.getName() @ \" to the scene.\" );\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onMount( %this, %obj, %mountObj, %node )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( %obj.getName() @ \" mounted <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> \" @ %mountObj.getName() );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onUnmount( %this, %obj, %mountObj, %node )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( %obj.getName() @ \" unmounted from \" @ %mountObj.getName() );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onMount , void , (SceneObject *obj, SceneObject *mountObj, S32 node) , (obj, mountObj, node) , "@brief Called when the object is mounted <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> another object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> object being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mounted\n</a>" "@param mountObj the object we are mounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param node the mountObj node we are mounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onNewDataBlock , void , (GameBase *obj) , (obj) , "@brief Called when the object has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> datablock <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">assigned.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onRemove , void , (GameBase *obj) , (obj) , "@brief Called when the object is removed from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onUnmount , void , (SceneObject *obj, SceneObject *mountObj, S32 node) , (obj, mountObj, node) , "@brief Called when the object is unmounted from another object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> object being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">unmounted\n</a>" "@param mountObj the object we are unmounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from\n</a>" "@param node the mountObj node we are unmounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
bool
PACK_DB_ID(BitStream * stream, U32 id)
bool
PRELOAD_DB(U32 & id, SimDataBlock ** data, bool server, const char * clientMissing, const char * serverMissing)
bool
UNPACK_DB_ID(BitStream * stream, U32 & id)
Detailed Description
Public Variables
F32 sUpDistance
F32 sUpFov
F32 sUpInterest
F32 sUpSkips
F32 sUpVelocity
Public Functions
ConsoleDocClass(GameBase , "@brief Base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> game objects which use datablocks, networking , are " " editable, and need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ticks.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gameObjects\n</a>" )
ConsoleDocClass(GameBaseData , "@brief Scriptable, demo-able datablock. Used by <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GameBase\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gameObjects\n</a>" )
DefineEngineMethod(GameBase , applyImpulse , bool , (Point3F pos, VectorF vel) , "@brief Apply an impulse <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this object as defined by <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> world position and velocity <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">vector.\n\n</a>" "@param pos impulse world <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position\n</a>" "@param vel impulse velocity (impulse force F = m * v)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@return Always <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">true\n</a>" "@note Not all objects that derrive from <a href="/coding/class/classgamebase/">GameBase</a> have this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">defined.\n</a>" )
DefineEngineMethod(GameBase , applyRadialImpulse , void , (Point3F origin, F32 radius, F32 magnitude) , "@brief Applies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> radial impulse <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the object using the given origin and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">force.\n\n</a>" "@param origin <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a81f4537631c9ab219ec74de554483adc">World</a> point of origin of the radial <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">impulse.\n</a>" "@param radius The radius of the impulse <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">area.\n</a>" "@param magnitude The strength of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">impulse.\n</a>" "@note Not all objects that derrive from <a href="/coding/class/classgamebase/">GameBase</a> have this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">defined.\n</a>" )
DefineEngineMethod(GameBase , attachChild , bool , (GameBase *_subObject) , (nullAsType< GameBase * >()) , "(SceneObject subObject)" "attach an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this one, preserving its present transform." )
DefineEngineMethod(GameBase , detachChild , bool , (GameBase *_subObject) , (nullAsType< GameBase * >()) , "(SceneObject subObject)" "attach an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this one, preserving its present transform." )
DefineEngineMethod(GameBase , getDataBlock , S32 , () , "@brief Get the datablock used by this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@return the datablock this <a href="/coding/class/classgamebase/">GameBase</a> is using." "@see setDataBlock()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" )
DefineEngineMethod(GameBase , setDataBlock , bool , (GameBaseData *data) , "@brief Assign this <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use the specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@param data <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> datablock <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">use\n</a>" "@return true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> failed." " @see getDataBlock()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" )
IMPLEMENT_CALLBACK(GameBase , setControl , void , (bool controlled) , (controlled) , "@brief Called when the client controlling the object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">changes.\n\n</a>" "@param controlled true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> client now controls this object, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no " "client controls this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onAdd , void , (GameBase *obj) , (obj) , "@brief Called when the object is added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "datablock <a href="/coding/class/structgamebasedata/">GameBaseData</a>(MyObjectData)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " category = \"Misc\";\n" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onAdd( %this, %obj )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( \"Added \" @ %obj.getName() @ \" to the scene.\" );\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onNewDataBlock( %this, %obj )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( \"Assign \" @ %this.getName() @ \" datablock <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> \" %obj.getName() );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onRemove( %this, %obj )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( \"Removed \" @ %obj.getName() @ \" to the scene.\" );\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onMount( %this, %obj, %mountObj, %node )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( %obj.getName() @ \" mounted <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> \" @ %mountObj.getName() );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "function MyObjectData::onUnmount( %this, %obj, %mountObj, %node )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>( %obj.getName() @ \" unmounted from \" @ %mountObj.getName() );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onMount , void , (SceneObject *obj, SceneObject *mountObj, S32 node) , (obj, mountObj, node) , "@brief Called when the object is mounted <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> another object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> object being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mounted\n</a>" "@param mountObj the object we are mounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param node the mountObj node we are mounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onNewDataBlock , void , (GameBase *obj) , (obj) , "@brief Called when the object has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> datablock <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">assigned.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onRemove , void , (GameBase *obj) , (obj) , "@brief Called when the object is removed from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
IMPLEMENT_CALLBACK(GameBaseData , onUnmount , void , (SceneObject *obj, SceneObject *mountObj, S32 node) , (obj, mountObj, node) , "@brief Called when the object is unmounted from another object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n\n</a>" "@param obj the <a href="/coding/class/classgamebase/">GameBase</a> object being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">unmounted\n</a>" "@param mountObj the object we are unmounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from\n</a>" "@param node the mountObj node we are unmounted <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from\n\n</a>" "@see onAdd <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example\n</a>" )
IMPLEMENT_CO_DATABLOCK_V1(GameBaseData )
IMPLEMENT_CO_NETOBJECT_V1(GameBase )
PACK_DB_ID(BitStream * stream, U32 id)
PRELOAD_DB(U32 & id, SimDataBlock ** data, bool server, const char * clientMissing, const char * serverMissing)
UNPACK_DB_ID(BitStream * stream, U32 & id)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 25// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 26// Copyright (C) 2015 Faust Logic, Inc. 27//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 28 29#include "platform/platform.h" 30#include "T3D/gameBase/gameBase.h" 31#include "console/consoleTypes.h" 32#include "console/engineAPI.h" 33#include "console/consoleInternal.h" 34#include "core/stream/bitStream.h" 35#include "sim/netConnection.h" 36#include "T3D/gameBase/gameConnection.h" 37#include "math/mathIO.h" 38#include "T3D/gameBase/moveManager.h" 39#include "T3D/gameBase/gameProcess.h" 40 41#ifdef TORQUE_DEBUG_NET_MOVES 42#include "T3D/aiConnection.h" 43#endif 44 45#ifdef TORQUE_AFX_ENABLED 46#include "afx/arcaneFX.h" 47#endif 48//---------------------------------------------------------------------------- 49// Ghost update relative priority values 50 51static F32 sUpFov = 1.0; 52static F32 sUpDistance = 0.4f; 53static F32 sUpVelocity = 0.4f; 54static F32 sUpSkips = 0.2f; 55static F32 sUpInterest = 0.2f; 56 57//---------------------------------------------------------------------------- 58 59IMPLEMENT_CO_DATABLOCK_V1(GameBaseData); 60 61ConsoleDocClass( GameBaseData, 62 "@brief Scriptable, demo-able datablock. Used by GameBase objects.\n\n" 63 "@see GameBase\n" 64 "@ingroup gameObjects\n" 65); 66 67IMPLEMENT_CALLBACK( GameBaseData, onAdd, void, ( GameBase* obj ), ( obj ), 68 "@brief Called when the object is added to the scene.\n\n" 69 70 "@param obj the GameBase object\n\n" 71 72 "@tsexample\n" 73 "datablock GameBaseData(MyObjectData)\n" 74 "{\n" 75 " category = \"Misc\";\n" 76 "};\n\n" 77 "function MyObjectData::onAdd( %this, %obj )\n" 78 "{\n" 79 " echo( \"Added \" @ %obj.getName() @ \" to the scene.\" );\n" 80 "}\n\n" 81 "function MyObjectData::onNewDataBlock( %this, %obj )\n" 82 "{\n" 83 " echo( \"Assign \" @ %this.getName() @ \" datablock to \" %obj.getName() );\n" 84 "}\n\n" 85 "function MyObjectData::onRemove( %this, %obj )\n" 86 "{\n" 87 " echo( \"Removed \" @ %obj.getName() @ \" to the scene.\" );\n" 88 "}\n\n" 89 "function MyObjectData::onMount( %this, %obj, %mountObj, %node )\n" 90 "{\n" 91 " echo( %obj.getName() @ \" mounted to \" @ %mountObj.getName() );\n" 92 "}\n\n" 93 "function MyObjectData::onUnmount( %this, %obj, %mountObj, %node )\n" 94 "{\n" 95 " echo( %obj.getName() @ \" unmounted from \" @ %mountObj.getName() );\n" 96 "}\n\n" 97 "@endtsexample\n" ); 98 99IMPLEMENT_CALLBACK( GameBaseData, onNewDataBlock, void, ( GameBase* obj ), ( obj ), 100 "@brief Called when the object has a new datablock assigned.\n\n" 101 "@param obj the GameBase object\n\n" 102 "@see onAdd for an example\n" ); 103 104IMPLEMENT_CALLBACK( GameBaseData, onRemove, void, ( GameBase* obj ), ( obj ), 105 "@brief Called when the object is removed from the scene.\n\n" 106 "@param obj the GameBase object\n\n" 107 "@see onAdd for an example\n" ); 108 109IMPLEMENT_CALLBACK( GameBaseData, onMount, void, ( SceneObject* obj, SceneObject* mountObj, S32 node ), ( obj, mountObj, node ), 110 "@brief Called when the object is mounted to another object in the scene.\n\n" 111 "@param obj the GameBase object being mounted\n" 112 "@param mountObj the object we are mounted to\n" 113 "@param node the mountObj node we are mounted to\n\n" 114 "@see onAdd for an example\n" ); 115 116IMPLEMENT_CALLBACK( GameBaseData, onUnmount, void, ( SceneObject* obj, SceneObject* mountObj, S32 node ), ( obj, mountObj, node ), 117 "@brief Called when the object is unmounted from another object in the scene.\n\n" 118 "@param obj the GameBase object being unmounted\n" 119 "@param mountObj the object we are unmounted from\n" 120 "@param node the mountObj node we are unmounted from\n\n" 121 "@see onAdd for an example\n" ); 122 123IMPLEMENT_CALLBACK( GameBase, setControl, void, ( bool controlled ), ( controlled ), 124 "@brief Called when the client controlling the object changes.\n\n" 125 "@param controlled true if a client now controls this object, false if no " 126 "client controls this object.\n" ); 127 128 129GameBaseData::GameBaseData() 130{ 131 mCategory = ""; 132 mPacked = false; 133} 134GameBaseData::GameBaseData(const GameBaseData& other, bool temp_clone) : SimDataBlock(other, temp_clone) 135{ 136 mPacked = other.mPacked; 137 mCategory = other.mCategory; 138 //mReloadSignal = other.mReloadSignal; // DO NOT copy the mReloadSignal member. 139} 140 141void GameBaseData::inspectPostApply() 142{ 143 Parent::inspectPostApply(); 144 145 // Tell interested parties ( like objects referencing this datablock ) 146 // that we have been modified and they might want to rebuild... 147 mReloadSignal.trigger(); 148} 149 150bool GameBaseData::onAdd() 151{ 152 if (!Parent::onAdd()) 153 return false; 154 155 return true; 156} 157 158void GameBaseData::initPersistFields() 159{ 160 addGroup("Scripting"); 161 162 addField( "category", TypeCaseString, Offset(mCategory, GameBaseData ), 163 "The group that this datablock will show up in under the \"Scripted\" " 164 "tab in the World Editor Library." ); 165 166 endGroup("Scripting"); 167 168 Parent::initPersistFields(); 169} 170 171bool GameBaseData::preload(bool server, String &errorStr) 172{ 173 if (!Parent::preload(server, errorStr)) 174 return false; 175 mPacked = false; 176 return true; 177} 178 179void GameBaseData::unpackData(BitStream* stream) 180{ 181 Parent::unpackData(stream); 182 mPacked = true; 183} 184 185//---------------------------------------------------------------------------- 186bool UNPACK_DB_ID(BitStream * stream, U32 & id) 187{ 188 if (stream->readFlag()) 189 { 190 id = stream->readRangedU32(DataBlockObjectIdFirst,DataBlockObjectIdLast); 191 return true; 192 } 193 return false; 194} 195 196bool PACK_DB_ID(BitStream * stream, U32 id) 197{ 198 if (stream->writeFlag(id)) 199 { 200 stream->writeRangedU32(id,DataBlockObjectIdFirst,DataBlockObjectIdLast); 201 return true; 202 } 203 return false; 204} 205 206bool PRELOAD_DB(U32 & id, SimDataBlock ** data, bool server, const char * clientMissing, const char * serverMissing) 207{ 208 if (server) 209 { 210 if (*data) 211 id = (*data)->getId(); 212 else if (server && serverMissing) 213 { 214 Con::errorf(ConsoleLogEntry::General,serverMissing); 215 return false; 216 } 217 } 218 else 219 { 220 if (id && !Sim::findObject(id,*data) && clientMissing) 221 { 222 Con::errorf(ConsoleLogEntry::General,clientMissing); 223 return false; 224 } 225 } 226 return true; 227} 228//---------------------------------------------------------------------------- 229 230bool GameBase::gShowBoundingBox = false; 231 232//---------------------------------------------------------------------------- 233IMPLEMENT_CO_NETOBJECT_V1(GameBase); 234 235ConsoleDocClass( GameBase, 236 "@brief Base class for game objects which use datablocks, networking, are " 237 "editable, and need to process ticks.\n\n" 238 "@ingroup gameObjects\n" 239); 240 241GameBase::GameBase() 242: mDataBlock( NULL ), 243 mControllingClient( NULL ), 244 mCurrentWaterObject( NULL ) 245{ 246 mNetFlags.set(Ghostable); 247 mTypeMask |= GameBaseObjectType; 248 mProcessTag = 0; 249 250 // From ProcessObject 251 mIsGameBase = true; 252 253#ifdef TORQUE_DEBUG_NET_MOVES 254 mLastMoveId = 0; 255 mTicksSinceLastMove = 0; 256 mIsAiControlled = false; 257#endif 258 mCameraFov = 90.f; 259} 260 261GameBase::~GameBase() 262{ 263#ifdef TORQUE_AFX_ENABLED 264 if (mScope_registered) 265 arcaneFX::unregisterScopedObject(this); 266#endif 267} 268 269 270//---------------------------------------------------------------------------- 271 272bool GameBase::onAdd() 273{ 274 if ( !Parent::onAdd() ) 275 return false; 276 277 // Datablock must be initialized on the server. 278 // Client datablock are initialized by the initial update. 279#ifdef TORQUE_AFX_ENABLED 280 if (isClientObject()) 281 { 282 if (mScope_id > 0 && !mScope_registered) 283 arcaneFX::registerScopedObject(this); 284 } 285 else 286 { 287 if ( mDataBlock && !onNewDataBlock( mDataBlock, false ) ) 288 return false; 289 } 290#else 291 if ( isServerObject() && mDataBlock && !onNewDataBlock( mDataBlock, false ) ) 292 return false; 293#endif 294 295 setProcessTick( true ); 296 297 return true; 298} 299 300void GameBase::onRemove() 301{ 302#ifdef TORQUE_AFX_ENABLED 303 if (mScope_registered) 304 arcaneFX::unregisterScopedObject(this); 305#endif 306 // EDITOR FEATURE: Remove us from the reload signal of our datablock. 307 if ( mDataBlock ) 308 mDataBlock->mReloadSignal.remove( this, &GameBase::_onDatablockModified ); 309 310 Parent::onRemove(); 311} 312 313bool GameBase::onNewDataBlock( GameBaseData *dptr, bool reload ) 314{ 315 // EDITOR FEATURE: Remove us from old datablock's reload signal and 316 // add us to the new one. 317 if ( !reload ) 318 { 319 if ( mDataBlock ) 320 mDataBlock->mReloadSignal.remove( this, &GameBase::_onDatablockModified ); 321 if ( dptr ) 322 dptr->mReloadSignal.notify( this, &GameBase::_onDatablockModified ); 323 } 324 325 326 mDataBlock = dptr; 327 328 if ( !mDataBlock ) 329 return false; 330#ifdef TORQUE_AFX_ENABLED 331 // Don't set mask when new datablock is a temp-clone. 332 if (mDataBlock->isTempClone()) 333 return true; 334#endif 335 336 setMaskBits(DataBlockMask); 337 return true; 338} 339 340void GameBase::_onDatablockModified() 341{ 342 AssertFatal( mDataBlock, "GameBase::onDatablockModified - mDataBlock is NULL." ); 343 onNewDataBlock( mDataBlock, true ); 344} 345 346void GameBase::inspectPostApply() 347{ 348 Parent::inspectPostApply(); 349 setMaskBits(ExtendedInfoMask); 350} 351 352//---------------------------------------------------------------------------- 353 354void GameBase::processTick(const Move * move) 355{ 356#ifdef TORQUE_DEBUG_NET_MOVES 357 if (!move) 358 mTicksSinceLastMove++; 359 360 const char * srv = isClientObject() ? "client" : "server"; 361 const char * who = ""; 362 if (isClientObject()) 363 { 364 if (this == (GameBase*)GameConnection::getConnectionToServer()->getControlObject()) 365 who = " player"; 366 else 367 who = " ghost"; 368 if (mIsAiControlled) 369 who = " ai"; 370 } 371 if (isServerObject()) 372 { 373 if (dynamic_cast<AIConnection*>(getControllingClient())) 374 { 375 who = " ai"; 376 mIsAiControlled = true; 377 } 378 else if (getControllingClient()) 379 { 380 who = " player"; 381 mIsAiControlled = false; 382 } 383 else 384 { 385 who = ""; 386 mIsAiControlled = false; 387 } 388 } 389 U32 moveid = mLastMoveId+mTicksSinceLastMove; 390 if (move) 391 moveid = move->id; 392 393 if (getTypeMask() & GameBaseHiFiObjectType) 394 { 395 if (move) 396 Con::printf("Processing (%s%s id %i) move %i",srv,who,getId(), move->id); 397 else 398 Con::printf("Processing (%s%s id %i) move %i (%i)",srv,who,getId(),mLastMoveId+mTicksSinceLastMove,mTicksSinceLastMove); 399 } 400 401 if (move) 402 { 403 mLastMoveId = move->id; 404 mTicksSinceLastMove=0; 405 } 406#endif 407} 408 409void GameBase::interpolateTick(F32 dt) 410{ 411 // PATHSHAPE 412 updateRenderChangesByParent(); 413 // PATHSHAPE END 414} 415//---------------------------------------------------------------------------- 416 417F32 GameBase::getUpdatePriority(CameraScopeQuery *camInfo, U32 updateMask, S32 updateSkips) 418{ 419 TORQUE_UNUSED(updateMask); 420 421 // Calculate a priority used to decide if this object 422 // will be updated on the client. All the weights 423 // are calculated 0 -> 1 Then weighted together at the 424 // end to produce a priority. 425 Point3F pos; 426 getWorldBox().getCenter(&pos); 427 pos -= camInfo->pos; 428 F32 dist = pos.len(); 429 if (dist == 0.0f) dist = 0.001f; 430 pos *= 1.0f / dist; 431 432 // Weight based on linear distance, the basic stuff. 433 F32 wDistance = (dist < camInfo->visibleDistance)? 434 1.0f - (dist / camInfo->visibleDistance): 0.0f; 435 436 // Weight by field of view, objects directly in front 437 // will be weighted 1, objects behind will be 0 438 F32 dot = mDot(pos,camInfo->orientation); 439 440 bool inFov = dot > camInfo->cosFov * 1.5f; 441 442 F32 wFov = inFov? 1.0f: 0; 443 444 // Weight by linear velocity parallel to the viewing plane 445 // (if it's the field of view, 0 if it's not). 446 F32 wVelocity = 0.0f; 447 if (inFov) 448 { 449 Point3F vec; 450 mCross(camInfo->orientation,getVelocity(),&vec); 451 wVelocity = (vec.len() * camInfo->fov) / 452 (camInfo->fov * camInfo->visibleDistance); 453 if (wVelocity > 1.0f) 454 wVelocity = 1.0f; 455 } 456 457 // Weight by interest. 458 F32 wInterest; 459 if (getTypeMask() & (PlayerObjectType || VehicleObjectType )) 460 wInterest = 0.75f; 461 else if (getTypeMask() & ProjectileObjectType) 462 { 463 // Projectiles are more interesting if they 464 // are heading for us. 465 wInterest = 0.30f; 466 dot = -mDot(pos,getVelocity()); 467 if (dot > 0.0f) 468 wInterest += 0.20 * dot; 469 } 470 else 471 { 472 if (getTypeMask() & ItemObjectType) 473 wInterest = 0.25f; 474 else 475 // Everything else is less interesting. 476 wInterest = 0.0f; 477 } 478 479 // Weight by updateSkips 480 F32 wSkips = updateSkips * 0.5; 481 482 // Calculate final priority, should total to about 1.0f (plus children) 483 // 484 return 485 wFov * sUpFov + 486 wDistance * sUpDistance + 487 wVelocity * sUpVelocity + 488 wSkips * sUpSkips + 489 wInterest * sUpInterest + 490 getNumChildren(); 491} 492 493//---------------------------------------------------------------------------- 494bool GameBase::setDataBlock(GameBaseData* dptr) 495{ 496 if (isGhost() || isProperlyAdded()) { 497 if (mDataBlock != dptr) 498 return onNewDataBlock(dptr,false); 499 } 500 else 501 mDataBlock = dptr; 502 return true; 503} 504 505 506//-------------------------------------------------------------------------- 507void GameBase::scriptOnAdd() 508{ 509 // Script onAdd() must be called by the leaf class after 510 // everything is ready. 511 if (mDataBlock && !isGhost()) 512 mDataBlock->onAdd_callback( this ); 513} 514 515void GameBase::scriptOnNewDataBlock() 516{ 517 // Script onNewDataBlock() must be called by the leaf class 518 // after everything is loaded. 519 if (mDataBlock && !isGhost()) 520 mDataBlock->onNewDataBlock_callback( this ); 521} 522 523void GameBase::scriptOnRemove() 524{ 525 // Script onRemove() must be called by leaf class while 526 // the object state is still valid. 527 if (!isGhost() && mDataBlock) 528 mDataBlock->onRemove_callback( this ); 529} 530 531//---------------------------------------------------------------------------- 532 533void GameBase::setControllingClient(GameConnection* client) 534{ 535 if (isClientObject()) 536 { 537 if (mControllingClient) 538 setControl_callback( 0 ); 539 if (client) 540 setControl_callback( 1 ); 541 } 542 543 mControllingClient = client; 544} 545 546U32 GameBase::getPacketDataChecksum(GameConnection * connection) 547{ 548 // just write the packet data into a buffer 549 // then we can CRC the buffer. This should always let us 550 // know when there is a checksum problem. 551 552 static U8 buffer[1500] = { 0, }; 553 BitStream stream(buffer, sizeof(buffer)); 554 555 writePacketData(connection, &stream); 556 U32 byteCount = stream.getPosition(); 557 U32 ret = CRC::calculateCRC(buffer, byteCount, 0xFFFFFFFF); 558 dMemset(buffer, 0, byteCount); 559 return ret; 560} 561 562void GameBase::writePacketData(GameConnection*, BitStream*) 563{ 564} 565 566void GameBase::readPacketData(GameConnection*, BitStream*) 567{ 568} 569 570U32 GameBase::packUpdate( NetConnection *connection, U32 mask, BitStream *stream ) 571{ 572 U32 retMask = Parent::packUpdate( connection, mask, stream ); 573 574 if ( stream->writeFlag( mask & ScaleMask ) ) 575 { 576 // Only write one bit if the scale is one. 577 if ( stream->writeFlag( mObjScale != Point3F::One ) ) 578 mathWrite( *stream, mObjScale ); 579 } 580 581 if ( stream->writeFlag( ( mask & DataBlockMask ) && mDataBlock != NULL ) ) 582 { 583 stream->writeRangedU32( mDataBlock->getId(), 584 DataBlockObjectIdFirst, 585 DataBlockObjectIdLast ); 586 if ( stream->writeFlag( mNetFlags.test( NetOrdered ) ) ) 587 stream->writeInt( mOrderGUID, 16 ); 588 } 589 590#ifdef TORQUE_DEBUG_NET_MOVES 591 stream->write(mLastMoveId); 592 stream->writeFlag(mIsAiControlled); 593#endif 594 595#ifdef TORQUE_AFX_ENABLED 596 if (stream->writeFlag(mask & ScopeIdMask)) 597 { 598 if (stream->writeFlag(mScope_refs > 0)) 599 stream->writeInt(mScope_id, SCOPE_ID_BITS); 600 } 601#endif 602 return retMask; 603} 604 605void GameBase::unpackUpdate(NetConnection *con, BitStream *stream) 606{ 607 Parent::unpackUpdate( con, stream ); 608 609 // ScaleMask 610 if ( stream->readFlag() ) 611 { 612 if ( stream->readFlag() ) 613 { 614 VectorF scale; 615 mathRead( *stream, &scale ); 616 setScale( scale ); 617 } 618 else 619 setScale( Point3F::One ); 620 } 621 622 // DataBlockMask 623 if ( stream->readFlag() ) 624 { 625 GameBaseData *dptr = 0; 626 SimObjectId id = stream->readRangedU32( DataBlockObjectIdFirst, 627 DataBlockObjectIdLast ); 628 if ( stream->readFlag() ) 629 mOrderGUID = stream->readInt( 16 ); 630 631 if ( !Sim::findObject( id, dptr ) || !setDataBlock( dptr ) ) 632 con->setLastError( "Invalid packet GameBase::unpackUpdate()" ); 633 } 634 635#ifdef TORQUE_DEBUG_NET_MOVES 636 stream->read(&mLastMoveId); 637 mTicksSinceLastMove = 0; 638 mIsAiControlled = stream->readFlag(); 639#endif 640#ifdef TORQUE_AFX_ENABLED 641 if (stream->readFlag()) 642 { 643 mScope_id = (stream->readFlag()) ? (U16) stream->readInt(SCOPE_ID_BITS) : 0; 644 mScope_refs = 0; 645 } 646#endif 647} 648 649void GameBase::onMount( SceneObject *obj, S32 node ) 650{ 651 deleteNotify( obj ); 652 653 // Are we mounting to a GameBase object? 654 GameBase *gbaseObj = dynamic_cast<GameBase*>( obj ); 655 656 if ( gbaseObj && gbaseObj->getControlObject() != this && gbaseObj->getControllingObject() != this) 657 processAfter( gbaseObj ); 658 659 if (!isGhost()) { 660 setMaskBits(MountedMask); 661 mDataBlock->onMount_callback( this, obj, node ); 662 } 663} 664 665void GameBase::onUnmount( SceneObject *obj, S32 node ) 666{ 667 clearNotify(obj); 668 669 GameBase *gbaseObj = dynamic_cast<GameBase*>( obj ); 670 671 if ( gbaseObj && gbaseObj->getControlObject() != this ) 672 clearProcessAfter(); 673 674 if (!isGhost()) { 675 setMaskBits(MountedMask); 676 mDataBlock->onUnmount_callback( this, obj, node ); 677 } 678} 679 680bool GameBase::setDataBlockProperty( void *obj, const char *index, const char *db) 681{ 682 if( db == NULL || !db[ 0 ] ) 683 { 684 Con::errorf( "GameBase::setDataBlockProperty - Can't unset datablock on GameBase objects" ); 685 return false; 686 } 687 688 GameBase* object = static_cast< GameBase* >( obj ); 689 GameBaseData* data; 690 if( Sim::findObject( db, data ) ) 691 return object->setDataBlock( data ); 692 693 Con::errorf( "GameBase::setDatablockProperty - Could not find data block \"%s\"", db ); 694 return false; 695} 696 697MoveList* GameBase::getMoveList() 698{ 699 return mControllingClient ? mControllingClient->mMoveList : NULL; 700} 701 702//---------------------------------------------------------------------------- 703DefineEngineMethod( GameBase, getDataBlock, S32, (),, 704 "@brief Get the datablock used by this object.\n\n" 705 "@return the datablock this GameBase is using." 706 "@see setDataBlock()\n") 707{ 708 return object->getDataBlock()? object->getDataBlock()->getId(): 0; 709} 710 711//---------------------------------------------------------------------------- 712DefineEngineMethod( GameBase, setDataBlock, bool, ( GameBaseData* data ),, 713 "@brief Assign this GameBase to use the specified datablock.\n\n" 714 "@param data new datablock to use\n" 715 "@return true if successful, false if failed." 716 "@see getDataBlock()\n") 717{ 718 return ( data && object->setDataBlock(data) ); 719} 720 721//---------------------------------------------------------------------------- 722 723void GameBase::initPersistFields() 724{ 725 addGroup( "Game" ); 726 727 addProtectedField( "dataBlock", TYPEID< GameBaseData >(), Offset(mDataBlock, GameBase), 728 &setDataBlockProperty, &defaultProtectedGetFn, 729 "Script datablock used for game objects." ); 730 731 endGroup( "Game" ); 732 733 Parent::initPersistFields(); 734} 735 736void GameBase::consoleInit() 737{ 738#ifdef TORQUE_DEBUG 739 Con::addVariable( "GameBase::boundingBox", TypeBool, &gShowBoundingBox, 740 "@brief Toggles on the rendering of the bounding boxes for certain types of objects in scene.\n\n" 741 "@ingroup GameBase" ); 742#endif 743} 744 745DefineEngineMethod( GameBase, applyImpulse, bool, ( Point3F pos, VectorF vel ),, 746 "@brief Apply an impulse to this object as defined by a world position and velocity vector.\n\n" 747 748 "@param pos impulse world position\n" 749 "@param vel impulse velocity (impulse force F = m * v)\n" 750 "@return Always true\n" 751 752 "@note Not all objects that derrive from GameBase have this defined.\n") 753{ 754 object->applyImpulse(pos,vel); 755 return true; 756} 757 758DefineEngineMethod( GameBase, applyRadialImpulse, void, ( Point3F origin, F32 radius, F32 magnitude ),, 759 "@brief Applies a radial impulse to the object using the given origin and force.\n\n" 760 761 "@param origin World point of origin of the radial impulse.\n" 762 "@param radius The radius of the impulse area.\n" 763 "@param magnitude The strength of the impulse.\n" 764 765 "@note Not all objects that derrive from GameBase have this defined.\n") 766{ 767 object->applyRadialImpulse( origin, radius, magnitude ); 768} 769 770// PATHSHAPE 771// Console Methods for attach children. can't put them in sceneobject because // 772// we want the processafter functions//////////////////////////////////////////// 773 774DefineEngineMethod(GameBase, attachChild, bool, (GameBase* _subObject), (nullAsType<GameBase*>()), "(SceneObject subObject)" 775 "attach an object to this one, preserving its present transform.") 776{ 777 if (_subObject != nullptr) 778 { 779 if (_subObject->getParent() != object){ 780 Con::errorf("Object is (%d)", _subObject->getId()); 781 _subObject->clearProcessAfter(); 782 _subObject->processAfter(object); 783 return object->attachChild(_subObject); 784 } 785 else 786 return false; 787 } 788 else 789 { 790 Con::errorf("Couldn't addObject()!"); 791 return false; 792 } 793} 794 795 796DefineEngineMethod(GameBase, detachChild, bool, (GameBase* _subObject), (nullAsType<GameBase*>()), "(SceneObject subObject)" 797 "attach an object to this one, preserving its present transform.") 798{ 799 if (_subObject != nullptr) 800 { 801 _subObject->clearProcessAfter(); 802 return _subObject->attachToParent(NULL); 803 } 804 else 805 { 806 return false; 807 } 808}//end 809// PATHSHAPE END 810