gameBase.cpp

Engine/source/T3D/gameBase/gameBase.cpp

More...

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