arcaneFX.cpp

Engine/source/afx/arcaneFX.cpp

More...

Classes:

Public Defines

Public Functions

ConsoleDocClass(ClientZoneInEvent , "@brief Event posted when player is fully loaded into the game and ready <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">interaction.\n\n</a>" "@internal" )
ConsoleGetType(TypeByteRange )
ConsoleSetType(TypeByteRange )
ConsoleType(ByteRange , TypeByteRange , ByteRange , "" )
DefineEngineFunction(afxEndMissionNotify , void , () , "...\n\n" "@ingroup AFX" )
DefineEngineFunction(afxGetEngine , const char * , () , "...\n\n" "@ingroup AFX" )
DefineEngineFunction(afxGetVersion , const char * , () , "...\n\n" "@ingroup AFX" )
DefineEngineFunction(ColorScale , const char * , (LinearColorF color, float scalar) , "Returns color scaled by scalar (color*scalar).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param color The color <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scaled.\n</a>" "@param scalar The amount <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scale the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">color.\n</a>" "@ingroup AFX" )
DefineEngineFunction(getColorFromHSV , const char * , (float hue, float sat, float val, float alpha) , (0.0, 0.0, 1.0, 1.0) , "Coverts an HSV formatted color into an RBG <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">color.\n\n</a>" "@param hue The hue of the color (0-360).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param sat The saturation of the color (0-1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param val The <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> of the color (0-1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param alpha The alpha of the color (0-1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@ingroup AFX" )
DefineEngineFunction(getFreeTargetPosition , Point3F , () , "@brief Returns the current location of the free <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(getMaxF , F32 , (float a, float b) , "Returns the greater of the two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">arguments.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(getMinF , F32 , (float a, float b) , "Returns the lesser of the two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">arguments.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(getRandomDir , Point3F , (Point3F axis, float thetaMin, float thetaMax, float phiMin, float phiMax) , (Point3F(0.0f, 0.0f, 0.0f), 0.0f, 180.0f, 0.0f, 360.0f) , "Get <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random direction <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">vector.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(getRandomF , F32 , (float a, float b) , (F32_MAX, F32_MAX) , "Get <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random float number between <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">b.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(markDataBlocks , void , () , "@brief Called before <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> series of datablocks are reloaded <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "help distinguish reloaded datablocks from already loaded <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ones.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(MatrixInverseMulVector , Point3F , (MatrixF xfrm, Point3F vector) , "@brief Multiply the vector by the affine inverse of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">transform.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(moveTransformAbs , MatrixF , (MatrixF xfrm, Point3F pos) , "@brief <a href="/coding/class/structmove/">Move</a> the transform <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> absolute <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(moveTransformRel , MatrixF , (MatrixF xfrm, Point3F pos) , "@brief <a href="/coding/class/structmove/">Move</a> the transform <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> relative <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(touchDataBlocks , void , () , "@brief Called after <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> series of datablocks are reloaded <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "trigger some important actions on the reloaded <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablocks.\n\n</a>" "@ingroup AFX" )
DefineEngineFunction(wasSyntaxError , bool , () , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> script compiler had <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> syntax error. Useful " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> detecting syntax errors after reloading <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">script.\n\n</a>" "@ingroup AFX" )
DefineEngineMethod(NetConnection , GetGhostIndex , S32 , (NetObject *obj) , "Returns the ghost-index <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@ingroup AFX" )
DefineEngineMethod(NetConnection , ResolveGhost , S32 , (int ghostIndex) , "Resolves <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> ghost-index into an object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n\n</a>" "@ingroup AFX" )
DefineEngineMethod(SceneObject , getSpeed , F32 , () , "Returns the velocity of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> scene-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@ingroup AFX" )
DefineEngineStringlyVariadicFunction(echoThru , const char * , 2 , 0 , " , but first argument is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n</a>" " @ingroup AFX" )
DefineEngineStringlyVariadicFunction(errorThru , const char * , 2 , 0 , " , but first argument is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n</a>" " @ingroup AFX" )
DefineEngineStringlyVariadicFunction(warnThru , const char * , 2 , 0 , " , but first argument is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n</a>" " @ingroup AFX" )
HSVtoRGB(F32 h, F32 s, F32 v, F32 & r, F32 & g, F32 & b)

Detailed Description

Public Defines

N_LIGHTING_MODELS() 6

Public Variables

 ByteRange 
StringTableEntry lm_new_names [N_LIGHTING_MODELS]
StringTableEntry lm_old_names [N_LIGHTING_MODELS]
S32 mark_modkey 
 MODULE_END 
 MODULE_INIT 
 MODULE_SHUTDOWN 
 TypeByteRange2 

Public Functions

ConsoleDocClass(ClientZoneInEvent , "@brief Event posted when player is fully loaded into the game and ready <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">interaction.\n\n</a>" "@internal" )

ConsoleGetType(TypeByteRange )

ConsoleGetType(TypeByteRange2 )

ConsoleSetType(TypeByteRange )

ConsoleSetType(TypeByteRange2 )

ConsoleType(ByteRange , TypeByteRange , ByteRange , "" )

DefineEngineFunction(afxEndMissionNotify , void , () , "...\n\n" "@ingroup AFX" )

DefineEngineFunction(afxGetEngine , const char * , () , "...\n\n" "@ingroup AFX" )

DefineEngineFunction(afxGetVersion , const char * , () , "...\n\n" "@ingroup AFX" )

DefineEngineFunction(ColorScale , const char * , (LinearColorF color, float scalar) , "Returns color scaled by scalar (color*scalar).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param color The color <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scaled.\n</a>" "@param scalar The amount <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scale the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">color.\n</a>" "@ingroup AFX" )

DefineEngineFunction(getColorFromHSV , const char * , (float hue, float sat, float val, float alpha) , (0.0, 0.0, 1.0, 1.0) , "Coverts an HSV formatted color into an RBG <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">color.\n\n</a>" "@param hue The hue of the color (0-360).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param sat The saturation of the color (0-1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param val The <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> of the color (0-1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param alpha The alpha of the color (0-1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@ingroup AFX" )

DefineEngineFunction(getFreeTargetPosition , Point3F , () , "@brief Returns the current location of the free <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(getMaxF , F32 , (float a, float b) , "Returns the greater of the two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">arguments.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(getMinF , F32 , (float a, float b) , "Returns the lesser of the two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">arguments.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(getRandomDir , Point3F , (Point3F axis, float thetaMin, float thetaMax, float phiMin, float phiMax) , (Point3F(0.0f, 0.0f, 0.0f), 0.0f, 180.0f, 0.0f, 360.0f) , "Get <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random direction <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">vector.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(getRandomF , F32 , (float a, float b) , (F32_MAX, F32_MAX) , "Get <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random float number between <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">b.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(markDataBlocks , void , () , "@brief Called before <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> series of datablocks are reloaded <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "help distinguish reloaded datablocks from already loaded <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ones.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(MatrixInverseMulVector , Point3F , (MatrixF xfrm, Point3F vector) , "@brief Multiply the vector by the affine inverse of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">transform.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(moveTransformAbs , MatrixF , (MatrixF xfrm, Point3F pos) , "@brief <a href="/coding/class/structmove/">Move</a> the transform <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> absolute <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(moveTransformRel , MatrixF , (MatrixF xfrm, Point3F pos) , "@brief <a href="/coding/class/structmove/">Move</a> the transform <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> relative <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(touchDataBlocks , void , () , "@brief Called after <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> series of datablocks are reloaded <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "trigger some important actions on the reloaded <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablocks.\n\n</a>" "@ingroup AFX" )

DefineEngineFunction(wasSyntaxError , bool , () , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> script compiler had <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> syntax error. Useful " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> detecting syntax errors after reloading <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">script.\n\n</a>" "@ingroup AFX" )

DefineEngineMethod(NetConnection , GetGhostIndex , S32 , (NetObject *obj) , "Returns the ghost-index <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@ingroup AFX" )

DefineEngineMethod(NetConnection , ResolveGhost , S32 , (int ghostIndex) , "Resolves <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> ghost-index into an object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n\n</a>" "@ingroup AFX" )

DefineEngineMethod(SceneObject , getSpeed , F32 , () , "Returns the velocity of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> scene-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@ingroup AFX" )

DefineEngineStringlyVariadicFunction(echoThru , const char * , 2 , 0 , " , but first argument is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n</a>" " @ingroup AFX" )

DefineEngineStringlyVariadicFunction(errorThru , const char * , 2 , 0 , " , but first argument is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n</a>" " @ingroup AFX" )

DefineEngineStringlyVariadicFunction(warnThru , const char * , 2 , 0 , " , but first argument is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n</a>" " @ingroup AFX" )

HSVtoRGB(F32 h, F32 s, F32 v, F32 & r, F32 & g, F32 & b)

IMPLEMENT_CO_SERVEREVENT_V1(ClientZoneInEvent )

IMPLEMENT_STRUCT(ByteRange , ByteRange , "" )

  1
  2
  3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  5// Copyright (C) 2015 Faust Logic, Inc.
  6//
  7// Permission is hereby granted, free of charge, to any person obtaining a copy
  8// of this software and associated documentation files (the "Software"), to
  9// deal in the Software without restriction, including without limitation the
 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 11// sell copies of the Software, and to permit persons to whom the Software is
 12// furnished to do so, subject to the following conditions:
 13//
 14// The above copyright notice and this permission notice shall be included in
 15// all copies or substantial portions of the Software.
 16//
 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 23// IN THE SOFTWARE.
 24//
 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 26
 27#include "afx/arcaneFX.h"
 28
 29#include "scene/sceneObject.h"
 30#include "scene/sceneManager.h"
 31#include "T3D/gameBase/gameConnection.h"
 32#include "T3D/gameBase/gameProcess.h"
 33#include "T3D/player.h"
 34#include "math/mathUtils.h"
 35#include "console/compiler.h"
 36#include "console/engineAPI.h"
 37
 38#include "afx/afxChoreographer.h"
 39#include "afx/afxSelectron.h"
 40#include "afx/afxResidueMgr.h"
 41#include "afx/ce/afxZodiacMgr.h"
 42
 43//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 44
 45#define N_LIGHTING_MODELS 6
 46//
 47// "SG - Original Advanced (Lighting Pack)"
 48// "SG - Original Stock (Lighting Pack)"
 49// "SG - Inverse Square (Lighting Pack)"
 50// "SG - Inverse Square Fast Falloff (Lighting Pack)"
 51// "SG - Near Linear (Lighting Pack)"
 52// "SG - Near Linear Fast Falloff (Lighting Pack)"
 53static StringTableEntry lm_old_names[N_LIGHTING_MODELS];
 54//
 55// "Original Advanced"
 56// "Original Stock"
 57// "Inverse Square"
 58// "Inverse Square Fast Falloff"
 59// "Near Linear"
 60// "Near Linear Fast Falloff"
 61static StringTableEntry lm_new_names[N_LIGHTING_MODELS];
 62
 63//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 64
 65class ClientZoneInEvent : public NetEvent
 66{
 67  typedef NetEvent Parent;
 68public:
 69  ClientZoneInEvent() { mGuaranteeType = Guaranteed; }
 70  ~ClientZoneInEvent() { }
 71
 72  virtual void pack(NetConnection*, BitStream*bstream) { }
 73  virtual void write(NetConnection*, BitStream *bstream) { }
 74  virtual void unpack(NetConnection* /*ps*/, BitStream *bstream) { }
 75
 76  virtual void process(NetConnection* conn)
 77  {
 78    GameConnection* game_conn = dynamic_cast<GameConnection*>(conn);
 79    if (game_conn && !game_conn->isZonedIn())
 80    {
 81      arcaneFX::syncToNewConnection(game_conn);
 82    }
 83  }
 84
 85  DECLARE_CONOBJECT(ClientZoneInEvent);
 86  DECLARE_CATEGORY("AFX");
 87};
 88IMPLEMENT_CO_SERVEREVENT_V1(ClientZoneInEvent);
 89
 90ConsoleDocClass( ClientZoneInEvent,
 91            "@brief Event posted when player is fully loaded into the game and ready for interaction.\n\n"
 92            "@internal");
 93
 94//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 95
 96Vector<afxChoreographer*> arcaneFX::active_choreographers;
 97Vector<afxChoreographer*> arcaneFX::client_choreographers;
 98Vector<afxSelectronData*> arcaneFX::selectrons;
 99Vector<SceneObject*>      arcaneFX::scoped_objs;
100
101StringTableEntry arcaneFX::NULLSTRING = 0;
102U32              arcaneFX::sTargetSelectionMask = 0;
103U32              arcaneFX::sFreeTargetSelectionMask = 0;
104bool             arcaneFX::sIsFreeTargeting = false;
105Point3F          arcaneFX::sFreeTargetPos = Point3F(0.0f, 0.0f, 0.0f);
106bool             arcaneFX::sFreeTargetPosValid = false;
107F32              arcaneFX::sTargetSelectionRange = 200.0f;
108U32              arcaneFX::sTargetSelectionTimeoutMS = 500;
109bool             arcaneFX::sClickToTargetSelf = false;
110U32              arcaneFX::sMissileCollisionMask = 0;
111StringTableEntry arcaneFX::sParameterFieldPrefix = 0;
112F32              arcaneFX::sTerrainZodiacZBias = -0.00025f;
113F32              arcaneFX::sInteriorZodiacZBias = -0.0001f;
114F32              arcaneFX::sPolysoupZodiacZBias = -0.0001f;
115U32              arcaneFX::master_choreographer_id = 1;
116U16              arcaneFX::master_scope_id = 1;
117bool             arcaneFX::is_shutdown = true;
118
119bool             arcaneFX::sUsePlayerCentricListener = false;
120
121void arcaneFX::init()
122{
123  NULLSTRING = StringTable->insert("");
124  sParameterFieldPrefix = StringTable->insert("_");
125
126#if defined(TORQUE_OS_MAC)
127  arcaneFX::sTerrainZodiacZBias = -0.00025f;
128  arcaneFX::sInteriorZodiacZBias = -0.00025f;
129  arcaneFX::sPolysoupZodiacZBias = -0.00025f;
130#endif
131
132  Con::addVariable(  "pref::AFX::targetSelectionMask",      TypeS32,    &sTargetSelectionMask);
133  Con::addVariable(  "pref::AFX::freeTargetSelectionMask",  TypeS32,    &sFreeTargetSelectionMask);
134  Con::addVariable(  "pref::AFX::targetSelectionRange",     TypeF32,    &sTargetSelectionRange);
135  Con::addVariable(  "pref::AFX::targetSelectionTimeoutMS", TypeS32,    &sTargetSelectionTimeoutMS);
136  Con::addVariable(  "pref::AFX::missileCollisionMask",     TypeS32,    &sMissileCollisionMask);
137  Con::addVariable(  "pref::AFX::clickToTargetSelf",        TypeBool,   &sClickToTargetSelf);
138  Con::addVariable(  "Pref::Server::AFX::parameterFieldPrefix",     TypeString,  &sParameterFieldPrefix);
139
140  Con::addVariable(  "pref::AFX::terrainZodiacZBias",       TypeF32,    &sTerrainZodiacZBias);
141  Con::addVariable(  "pref::AFX::interiorZodiacZBias",      TypeF32,    &sInteriorZodiacZBias);
142  Con::addVariable(  "pref::AFX::polysoupZodiacZBias",      TypeF32,    &sPolysoupZodiacZBias);
143
144  Con::setIntVariable(    "$AFX::TARGETING_OFF",                TARGETING_OFF);
145  Con::setIntVariable(    "$AFX::TARGETING_STANDARD",           TARGETING_STANDARD);
146  Con::setIntVariable(    "$AFX::TARGETING_FREE",               TARGETING_FREE);
147  Con::setIntVariable(    "$AFX::TARGET_CHECK_POLL",            TARGET_CHECK_POLL);
148  Con::setIntVariable(    "$AFX::TARGET_CHECK_ON_MOUSE_MOVE",   TARGET_CHECK_ON_MOUSE_MOVE);
149
150  Con::setIntVariable(    "$AFX::IMPACTED_SOMETHING", afxEffectDefs::IMPACTED_SOMETHING);
151  Con::setIntVariable(    "$AFX::IMPACTED_TARGET",    afxEffectDefs::IMPACTED_TARGET);
152  Con::setIntVariable(    "$AFX::IMPACTED_PRIMARY",   afxEffectDefs::IMPACTED_PRIMARY);
153  Con::setIntVariable(    "$AFX::IMPACT_IN_WATER",    afxEffectDefs::IMPACT_IN_WATER);
154  Con::setIntVariable(    "$AFX::CASTER_IN_WATER",    afxEffectDefs::CASTER_IN_WATER);
155
156  Con::setIntVariable(    "$AFX::SERVER_ONLY",        afxEffectDefs::SERVER_ONLY);
157  Con::setIntVariable(    "$AFX::SCOPE_ALWAYS",       afxEffectDefs::SCOPE_ALWAYS);
158  Con::setIntVariable(    "$AFX::GHOSTABLE",          afxEffectDefs::GHOSTABLE);
159  Con::setIntVariable(    "$AFX::CLIENT_ONLY",        afxEffectDefs::CLIENT_ONLY);
160  Con::setIntVariable(    "$AFX::SERVER_AND_CLIENT",  afxEffectDefs::SERVER_AND_CLIENT);
161
162  Con::setIntVariable(    "$AFX::DELAY",              afxEffectDefs::TIMING_DELAY);
163  Con::setIntVariable(    "$AFX::LIFETIME",           afxEffectDefs::TIMING_LIFETIME);
164  Con::setIntVariable(    "$AFX::FADE_IN_TIME",       afxEffectDefs::TIMING_FADE_IN);
165  Con::setIntVariable(    "$AFX::FADE_OUT_TIME",      afxEffectDefs::TIMING_FADE_OUT);
166
167  Con::setFloatVariable(  "$AFX::INFINITE_TIME",      -1.0f);
168  Con::setIntVariable(    "$AFX::INFINITE_REPEATS",   -1);
169
170  Con::setIntVariable(    "$AFX::PLAYER_MOVE_TRIGGER_0",      Player::PLAYER_MOVE_TRIGGER_0);
171  Con::setIntVariable(    "$AFX::PLAYER_MOVE_TRIGGER_1",      Player::PLAYER_MOVE_TRIGGER_1);
172  Con::setIntVariable(    "$AFX::PLAYER_MOVE_TRIGGER_2",      Player::PLAYER_MOVE_TRIGGER_2);
173  Con::setIntVariable(    "$AFX::PLAYER_MOVE_TRIGGER_3",      Player::PLAYER_MOVE_TRIGGER_3);
174  Con::setIntVariable(    "$AFX::PLAYER_MOVE_TRIGGER_4",      Player::PLAYER_MOVE_TRIGGER_4);
175  Con::setIntVariable(    "$AFX::PLAYER_MOVE_TRIGGER_5",      Player::PLAYER_MOVE_TRIGGER_5);
176
177  Con::setIntVariable(    "$AFX::PLAYER_FIRE_S_TRIGGER",      Player::PLAYER_FIRE_S_TRIGGER);
178  Con::setIntVariable(    "$AFX::PLAYER_FIRE_ALT_S_TRIGGER",  Player::PLAYER_FIRE_ALT_S_TRIGGER);
179  Con::setIntVariable(    "$AFX::PLAYER_JUMP_S_TRIGGER",      Player::PLAYER_JUMP_S_TRIGGER);
180  Con::setIntVariable(    "$AFX::PLAYER_LANDING_S_TRIGGER",   Player::PLAYER_LANDING_S_TRIGGER);
181
182  Con::setIntVariable(    "$AFX::PLAYER_LF_FOOT_C_TRIGGER",   Player::PLAYER_LF_FOOT_C_TRIGGER);
183  Con::setIntVariable(    "$AFX::PLAYER_RT_FOOT_C_TRIGGER",   Player::PLAYER_RT_FOOT_C_TRIGGER);
184  Con::setIntVariable(    "$AFX::PLAYER_LANDING_C_TRIGGER",   Player::PLAYER_LANDING_C_TRIGGER);
185  Con::setIntVariable(    "$AFX::PLAYER_IDLE_C_TRIGGER",      Player::PLAYER_IDLE_C_TRIGGER);
186
187  Con::setIntVariable(    "$AFX::ILLUM_TERRAIN",      0);
188  Con::setIntVariable(    "$AFX::ILLUM_ATLAS",        0);
189  Con::setIntVariable(    "$AFX::ILLUM_DIF",          0);
190  Con::setIntVariable(    "$AFX::ILLUM_DTS",          0);
191  Con::setIntVariable(    "$AFX::ILLUM_ALL",          0);
192
193  Con::setIntVariable("$TypeMasks::TerrainLikeObjectType", TerrainLikeObjectType);
194  Con::setIntVariable("$TypeMasks::InteriorLikeObjectType", InteriorLikeObjectType);
195  Con::setIntVariable("$TypeMasks::PolysoupObjectType", InteriorLikeObjectType); // deprecated
196
197  Con::addVariable("$pref::Audio::usePlayerCentricListener", TypeBool, &sUsePlayerCentricListener);
198
199  afxResidueMgr* residue_mgr = new afxResidueMgr;
200  afxResidueMgr::setMaster(residue_mgr);
201
202  master_scope_id = 1;
203  master_choreographer_id = 1;
204  is_shutdown = false;
205
206  if (lm_old_names[0] == 0)
207  {
208    lm_old_names[0] = StringTable->insert("SG - Original Advanced (Lighting Pack)");
209    lm_old_names[1] = StringTable->insert("SG - Original Stock (Lighting Pack)");
210    lm_old_names[2] = StringTable->insert("SG - Inverse Square (Lighting Pack)");
211    lm_old_names[3] = StringTable->insert("SG - Inverse Square Fast Falloff (Lighting Pack)");
212    lm_old_names[4] = StringTable->insert("SG - Near Linear (Lighting Pack)");
213    lm_old_names[5] = StringTable->insert("SG - Near Linear Fast Falloff (Lighting Pack)");
214    //
215    lm_new_names[0] = StringTable->insert("Original Advanced");
216    lm_new_names[1] = StringTable->insert("Original Stock");
217    lm_new_names[2] = StringTable->insert("Inverse Square");
218    lm_new_names[3] = StringTable->insert("Inverse Square Fast Falloff");
219    lm_new_names[4] = StringTable->insert("Near Linear");
220    lm_new_names[5] = StringTable->insert("Near Linear Fast Falloff");
221  }
222}
223
224void arcaneFX::shutdown()
225{
226  is_shutdown = true;
227
228  for (S32 i = 0; i < scoped_objs.size(); i++)
229     if (scoped_objs[i])
230       scoped_objs[i]->setScopeRegistered(false);
231  scoped_objs.clear();
232
233  for (S32 i = 0; i < client_choreographers.size(); i++)
234     if (client_choreographers[i])
235       client_choreographers[i]->clearChoreographerId();
236  client_choreographers.clear();
237
238  for (S32 i = 0; i < selectrons.size(); i++)
239    if (selectrons[i])
240       selectrons[i]->registered = false;
241  selectrons.clear();
242
243  afxResidueMgr* residue_mgr = afxResidueMgr::getMaster();
244  delete residue_mgr;
245  afxResidueMgr::setMaster(NULL);
246}
247
248MODULE_BEGIN( arcaneFX )
249
250   MODULE_INIT
251   {
252      arcaneFX::init();
253   }
254
255   MODULE_SHUTDOWN
256   {
257      arcaneFX::shutdown();
258   }
259
260MODULE_END;
261
262//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
263
264void arcaneFX::advanceTime(U32 delta)
265{
266  GameConnection* conn = GameConnection::getConnectionToServer();
267  if (conn && !conn->isZonedIn() && conn->getCameraObject() != 0)
268  {
269    conn->setZonedIn();
270    conn->postNetEvent(new ClientZoneInEvent());
271  }
272
273  afxZodiacMgr::frameReset();
274  afxResidueMgr::getMaster()->residueAdvanceTime();
275}
276
277//
278
279U32 arcaneFX::registerChoreographer(afxChoreographer* ch)
280{
281  if (!ch)
282    return 0;
283
284  active_choreographers.push_back(ch);
285
286  //Con::printf("registerChoreographer() -- size=%d %s", active_choreographers.size(),
287  //  (ch->isServerObject()) ? "server" : "client");
288
289  return master_choreographer_id++;
290}
291
292void arcaneFX::unregisterChoreographer(afxChoreographer* ch)
293{
294  if (!ch)
295    return;
296
297  for (U32 i = 0; i < active_choreographers.size(); i++)
298  {
299    if (ch == active_choreographers[i])
300    {
301      active_choreographers.erase_fast(i);
302      //Con::printf("unregisterChoreographer() -- size=%d %s", active_choreographers.size(),
303      //  (ch->isServerObject()) ? "server" : "client");
304      return;
305    }
306  }
307
308  Con::errorf("arcaneFX::unregisterChoreographer() -- failed to find choreographer in list.");
309}
310
311void arcaneFX::registerClientChoreographer(afxChoreographer* ch)
312{
313  if (!ch || ch->getChoreographerId() == 0)
314    return;
315
316  client_choreographers.push_back(ch);
317}
318
319void arcaneFX::unregisterClientChoreographer(afxChoreographer* ch)
320{
321  if (!ch || ch->getChoreographerId() == 0)
322    return;
323
324  for (U32 i = 0; i < client_choreographers.size(); i++)
325  {
326    if (ch == client_choreographers[i])
327    {
328      client_choreographers.erase_fast(i);
329      return;
330    }
331  }
332
333  Con::errorf("arcaneFX::unregisterClientChoreographer() -- failed to find choreographer in list.");
334}
335
336afxChoreographer* arcaneFX::findClientChoreographer(U32 id)
337{
338  for (U32 i = 0; i < client_choreographers.size(); i++)
339  {
340    if (id == client_choreographers[i]->getChoreographerId())
341      return client_choreographers[i];
342  }
343
344  return 0;
345}
346
347//
348
349void arcaneFX::registerSelectronData(afxSelectronData* selectron)
350{
351  if (!selectron)
352    return;
353
354  selectrons.push_back(selectron);
355}
356
357void arcaneFX::unregisterSelectronData(afxSelectronData* selectron)
358{
359  if (!selectron)
360    return;
361
362  for (U32 i = 0; i < selectrons.size(); i++)
363  {
364    if (selectron == selectrons[i])
365    {
366      selectrons.erase_fast(i);
367      return;
368    }
369  }
370
371  Con::errorf("arcaneFX::unregisterSelectronData() -- failed to find selectron in list.");
372}
373
374afxSelectronData* arcaneFX::findSelectronData(U32 mask, U8 style)
375{
376  for (U32 i = 0; i < selectrons.size(); i++)
377    if (selectrons[i]->matches(mask, style))
378      return selectrons[i];
379
380  return 0;
381}
382
383U16 arcaneFX::generateScopeId()
384{
385  U16 ret_id = master_scope_id++;
386  if (master_scope_id >= BIT(GameBase::SCOPE_ID_BITS))
387    master_scope_id = 1;
388  return ret_id;
389}
390
391void arcaneFX::registerScopedObject(SceneObject* object)
392{
393  scoped_objs.push_back(object);
394  object->setScopeRegistered(true);
395
396  for (S32 i = 0; i < client_choreographers.size(); i++)
397    if (client_choreographers[i])
398      client_choreographers[i]->restoreScopedObject(object);
399}
400
401SceneObject* arcaneFX::findScopedObject(U16 scope_id)
402{
403  if (scoped_objs.size() > 0)
404  {
405    for (S32 i = scoped_objs.size()-1; i >= 0; i--)
406      if (scoped_objs[i] && scoped_objs[i]->getScopeId() == scope_id)
407        return scoped_objs[i];
408  }
409  return 0;
410}
411
412void arcaneFX::unregisterScopedObject(SceneObject* object)
413{
414  if (scoped_objs.size() > 0)
415  {
416    for (S32 i = scoped_objs.size()-1; i >= 0; i--)
417      if (scoped_objs[i] == object)
418      {
419        scoped_objs.erase_fast(i);
420        if (object)
421          object->setScopeRegistered(false);
422        return;
423      }
424  }
425}
426
427void arcaneFX::syncToNewConnection(GameConnection* conn)
428{
429  if (conn)
430    conn->setZonedIn();
431
432  for (U32 i = 0; i < active_choreographers.size(); i++)
433  {
434    if (active_choreographers[i])
435      active_choreographers[i]->sync_with_clients();
436  }
437}
438
439void arcaneFX::endMissionNotify()
440{
441  for (S32 i = 0; i < scoped_objs.size(); i++)
442     if (scoped_objs[i])
443       scoped_objs[i]->setScopeRegistered(false);
444  scoped_objs.clear();
445
446  for (S32 i = 0; i < client_choreographers.size(); i++)
447     if (client_choreographers[i])
448       client_choreographers[i]->clearChoreographerId();
449  client_choreographers.clear();
450
451  for (S32 i = 0; i < selectrons.size(); i++)
452    if (selectrons[i])
453       selectrons[i]->registered = false;
454  selectrons.clear();
455
456  if (afxResidueMgr::getMaster())
457    afxResidueMgr::getMaster()->cleanup();
458  afxZodiacMgr::missionCleanup();
459}
460
461S32 arcaneFX::rolloverRayCast(Point3F start, Point3F end, U32 mask)
462{
463  sIsFreeTargeting = false;
464#if !defined(AFX_CAP_ROLLOVER_RAYCASTS)
465  return -1;
466#else
467  GameConnection* conn = GameConnection::getConnectionToServer();
468  SceneObject* ctrl_obj = NULL;
469
470  if (!arcaneFX::sClickToTargetSelf && conn != NULL)
471    ctrl_obj = conn->getControlObject();
472
473  if (ctrl_obj)
474    ctrl_obj->disableCollision();
475
476  SceneObject* rollover_obj = (conn) ? conn->getRolloverObj() : 0;
477  SceneObject* picked_obj = 0;
478
479  RayInfo hit_info;
480  if (gClientContainer.castRay(start, end, mask, &hit_info))
481    picked_obj = dynamic_cast<SceneObject*>(hit_info.object);
482
483  if (ctrl_obj)
484    ctrl_obj->enableCollision();
485
486  if (picked_obj != rollover_obj)
487  {
488    if (rollover_obj)
489      rollover_obj->setSelectionFlags(rollover_obj->getSelectionFlags() & ~<a href="/coding/class/classsceneobject/">SceneObject</a>::PRE_SELECTED);
490    if (picked_obj)
491      picked_obj->setSelectionFlags(picked_obj->getSelectionFlags() | SceneObject::PRE_SELECTED);
492    rollover_obj = picked_obj;
493
494    if (conn)
495      conn->setRolloverObj(rollover_obj);
496  }
497
498  return (picked_obj) ? picked_obj->getId() : -1;
499#endif
500}
501
502bool arcaneFX::freeTargetingRayCast(Point3F start, Point3F end, U32 mask)
503{
504  sIsFreeTargeting = true;
505
506  RayInfo hit_info;
507  if (!gClientContainer.castRay(start, end, mask, &hit_info))
508  {
509    sFreeTargetPosValid = false;
510    return false;
511  }
512
513  sFreeTargetPosValid = true;
514  sFreeTargetPos = hit_info.point;
515
516  return true;
517}
518
519StringTableEntry arcaneFX::convertLightingModelName(StringTableEntry lm_name)
520{
521  for (U32 i = 0; i < N_LIGHTING_MODELS; i++)
522  {
523    if (lm_name == lm_old_names[i])
524      return lm_new_names[i];
525  }
526
527  return lm_name;
528}
529
530//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
531// Console Functions
532
533DefineEngineFunction(afxEndMissionNotify, void, (),,
534                     "...\n\n"
535                     "@ingroup AFX")
536{
537  arcaneFX::endMissionNotify();
538}
539
540DefineEngineFunction(afxGetVersion, const char*, (),,
541                     "...\n\n"
542                     "@ingroup AFX")
543{
544  return AFX_VERSION_STRING;
545}
546
547DefineEngineFunction(afxGetEngine, const char*, (),,
548                     "...\n\n"
549                     "@ingroup AFX")
550{
551  return "T3D";
552}
553
554#if defined(AFX_CAP_ROLLOVER_RAYCASTS)
555DefineEngineFunction(rolloverRayCast, S32, (Point3F start, Point3F end, U32 mask),,
556                     "Performs a raycast from points start to end and returns the ID of nearest "
557                     "intersecting object with a type found in the specified mask. "
558                     "Returns -1 if no object is found.\n\n"
559                     "@ingroup AFX")
560{
561  return arcaneFX::rolloverRayCast(start, end, mask);
562}
563#endif
564
565DefineEngineFunction(getRandomF, F32, (float a, float b), (F32_MAX, F32_MAX),
566                "Get a random float number between a and b.\n\n"
567                "@ingroup AFX")
568{
569  if (b == F32_MAX)
570  {
571    if (a == F32_MAX)
572      return gRandGen.randF();
573
574    return gRandGen.randF(0.0f, a);
575  }
576
577  return (a + (b-a)*gRandGen.randF());
578}
579
580DefineEngineFunction(getRandomDir, Point3F, (Point3F axis, float thetaMin, float thetaMax, float phiMin, float phiMax),
581                     (Point3F(0.0f,0.0f,0.0f), 0.0f, 180.0f, 0.0f, 360.0f),
582                     "Get a random direction vector.\n\n"
583                     "@ingroup AFX")
584{
585  return MathUtils::randomDir(axis, thetaMin, thetaMax, phiMin, phiMax);
586}
587
588DefineEngineFunction(MatrixInverseMulVector, Point3F, (MatrixF xfrm, Point3F vector),,
589   "@brief Multiply the vector by the affine inverse of the transform.\n\n"
590   "@ingroup AFX")
591{
592   xfrm.affineInverse();
593
594   Point3F result;
595   xfrm.mulV(vector, &result);
596
597   return result;
598}
599
600DefineEngineFunction(moveTransformAbs, MatrixF, (MatrixF xfrm, Point3F pos),,
601   "@brief Move the transform to the new absolute position.\n\n"
602   "@ingroup AFX")
603{
604   xfrm.setPosition(pos);
605   return xfrm;
606}
607
608DefineEngineFunction(moveTransformRel, MatrixF, (MatrixF xfrm, Point3F pos),,
609   "@brief Move the transform to the new relative position.\n\n"
610   "@ingroup AFX")
611{
612   pos += xfrm.getPosition();
613   xfrm.setPosition(pos);
614   return xfrm;
615}
616
617DefineEngineFunction(getFreeTargetPosition, Point3F, (),,
618                     "@brief Returns the current location of the free target.\n\n"
619                     "@ingroup AFX")
620{
621  if (!arcaneFX::sFreeTargetPosValid)
622    return Point3F(0.0f, 0.0f, 0.0f);
623  return arcaneFX::sFreeTargetPos;
624}
625
626DefineEngineMethod(SceneObject, getSpeed, F32, (),,
627                   "Returns the velocity of a scene-object.\n\n"
628                   "@ingroup AFX")
629{
630   return object->getVelocity().len();
631}
632
633static S32 mark_modkey = -1;
634
635DefineEngineFunction(markDataBlocks, void, (),,
636                     "@brief Called before a series of datablocks are reloaded to "
637                     "help distinguish reloaded datablocks from already loaded ones.\n\n"
638                     "@ingroup AFX")
639{
640  mark_modkey = SimDataBlock::getNextModifiedKey();
641}
642
643DefineEngineFunction(touchDataBlocks, void, (),,
644                     "@brief Called after a series of datablocks are reloaded to "
645                     "trigger some important actions on the reloaded datablocks.\n\n"
646                     "@ingroup AFX")
647{
648  if (mark_modkey < 0)
649    return;
650
651  SimDataBlockGroup* g = Sim::getDataBlockGroup();
652
653  U32 groupCount = g->size();
654  for (S32 i = groupCount-1; i >= 0; i--)
655  {
656    SimDataBlock* simdb = (SimDataBlock*)(*g)[i];
657    if (simdb->getModifiedKey() > mark_modkey)
658    {
659      simdb->unregisterObject();
660      simdb->registerObject();
661    }
662  }
663
664  mark_modkey = -1;
665}
666
667//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
668// Syntax Error Checking
669// (for checking eval() and compile() calls)
670
671DefineEngineFunction(wasSyntaxError, bool, (),,
672                     "@brief Returns true if script compiler had a syntax error. Useful "
673                     "for detecting syntax errors after reloading a script.\n\n"
674                     "@ingroup AFX")
675{
676  return Compiler::gSyntaxError;
677}
678
679//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
680// Network Object Identification
681
682//  These useful console methods come from the following code resource:
683//
684//  How to Identify Objects from Client to Server or Server to Client by Nathan Davies
685//    http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4852
686//
687
688DefineEngineMethod(NetConnection, GetGhostIndex, S32, (NetObject* obj),,
689                   "Returns the ghost-index for an object.\n\n"
690                   "@ingroup AFX")
691{
692  if (obj)
693    return object->getGhostIndex(obj);
694  return 0;
695}
696
697DefineEngineMethod(NetConnection, ResolveGhost, S32, (int ghostIndex),,
698                   "Resolves a ghost-index into an object ID.\n\n"
699                   "@ingroup AFX")
700{
701  if (ghostIndex != -1)
702  {
703    NetObject* pObject = NULL;
704    if( object->isGhostingTo())
705      pObject = object->resolveGhost(ghostIndex);
706    else if( object->isGhostingFrom())
707      pObject = object->resolveObjectFromGhostIndex(ghostIndex);
708    if (pObject)
709      return pObject->getId();
710  }
711  return 0;
712}
713
714//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
715
716//////////////////////////////////////////////////////////////////////////
717// TypeByteRange
718//////////////////////////////////////////////////////////////////////////
719
720IMPLEMENT_STRUCT( ByteRange, ByteRange,,
721   "" )
722END_IMPLEMENT_STRUCT;
723
724ConsoleType( ByteRange, TypeByteRange, ByteRange, "")
725ConsoleType( ByteRange, TypeByteRange2, ByteRange, "")
726
727ConsoleGetType( TypeByteRange )
728{
729   ByteRange* pt = (ByteRange *) dptr;
730   char* returnBuffer = Con::getReturnBuffer(256);
731   dSprintf(returnBuffer, 256, "%u %u", pt->low, pt->high);
732   return returnBuffer;
733}
734
735ConsoleSetType( TypeByteRange )
736{
737  if(argc == 1)
738  {
739    ByteRange* range = (ByteRange*) dptr;
740    U32 lo, hi;
741    S32 args = dSscanf(argv[0], "%u %u", &lo, &hi);
742    range->low = (args > 0) ? lo : 0;
743    range->high = (args > 1) ? hi : 255;
744  }
745  else
746    Con::printf("ByteRange must be set as \"low\" or \"low high\"");
747}
748
749ConsoleGetType( TypeByteRange2 )
750{
751   ByteRange* pt = (ByteRange *) dptr;
752   char* returnBuffer = Con::getReturnBuffer(256);
753   dSprintf(returnBuffer, 256, "%u %u", pt->low, pt->high);
754   return returnBuffer;
755}
756
757ConsoleSetType( TypeByteRange2 )
758{
759  if(argc == 1)
760  {
761    ByteRange* range = (ByteRange*) dptr;
762    U32 lo, hi;
763    S32 args = dSscanf(argv[0], "%u %u", &lo, &hi);
764    range->low = (args > 0) ? lo : 0;
765    range->high = (args > 1) ? hi : lo;
766  }
767  else
768    Con::printf("ByteRange must be set as \"low\" or \"low high\"");
769}
770
771//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
772
773static void HSVtoRGB(F32 h, F32 s, F32 v, F32& r, F32& g, F32& b)
774{
775  h = mFmod(h, 360.0f);
776
777  if (v == 0.0f)
778    r = g = b = 0.0f;
779  else if (s == 0.0f)
780    r = g = b = v;
781  else
782  {
783    F32 hf = h/60.0f;
784    S32 i = (S32) mFloor(hf);
785    F32 f = hf - i;
786
787    F32 pv = v*(1.0f - s);
788    F32 qv = v*(1.0f - s*f);
789    F32 tv = v*(1.0f - s*(1.0f - f));
790
791    switch (i)
792    {
793    case 0:
794      r = v;  g = tv; b = pv;
795      break;
796    case 1:
797      r = qv; g = v;  b = pv;
798      break;
799    case 2:
800      r = pv; g = v;  b = tv;
801      break;
802    case 3:
803      r = pv; g = qv; b = v;
804      break;
805    case 4:
806      r = tv; g = pv; b = v;
807      break;
808    case 5:
809      r = v;  g = pv; b = qv;
810      break;
811    default:
812      r = g = b = 0.0f;
813      break;
814    }
815  }
816}
817
818DefineEngineFunction(getColorFromHSV, const char*, (float hue, float sat, float val, float alpha), (0.0, 0.0, 1.0, 1.0),
819                     "Coverts an HSV formatted color into an RBG color.\n\n"
820                     "@param hue The hue of the color (0-360).\n"
821                     "@param sat The saturation of the color (0-1).\n"
822                     "@param val The value of the color (0-1).\n"
823                     "@param alpha The alpha of the color (0-1).\n"
824                     "@ingroup AFX")
825{
826  LinearColorF rgb;
827  HSVtoRGB(hue, sat, val, rgb.red, rgb.green, rgb.blue);
828  rgb.alpha = alpha;
829
830  char* returnBuffer = Con::getReturnBuffer(256);
831  dSprintf(returnBuffer, 256, "%g %g %g %g", rgb.red, rgb.green, rgb.blue, rgb.alpha);
832
833  return returnBuffer;
834}
835
836DefineEngineFunction(ColorScale, const char*, ( LinearColorF color, float scalar ),,
837                     "Returns color scaled by scalar (color*scalar).\n\n"
838                     "@param color The color to be scaled.\n"
839                     "@param scalar The amount to scale the color.\n"
840                     "@ingroup AFX")
841{
842  color *= scalar;
843
844  char* returnBuffer = Con::getReturnBuffer(256);
845  dSprintf(returnBuffer, 256, "%g %g %g %g", color.red, color.green, color.blue, color.alpha);
846
847  return returnBuffer;
848}
849
850DefineEngineFunction(getMinF, F32, (float a, float b),,
851                     "Returns the lesser of the two arguments.\n\n"
852                     "@ingroup AFX")
853{
854   return getMin(a, b);
855}
856
857DefineEngineFunction(getMaxF, F32, (float a, float b),,
858                     "Returns the greater of the two arguments.\n\n"
859                     "@ingroup AFX")
860{
861   return getMax(a, b);
862}
863
864DefineEngineStringlyVariadicFunction(echoThru, const char*, 2, 0, "(string passthru, string text...)"
865   "Like echo(), but first argument is returned.\n"
866   "@ingroup AFX")
867{
868   U32 len = 0;
869   S32 i;
870   for (i = 2; i < argc; i++)
871      len += dStrlen(argv[i]);
872
873   char *ret = Con::getReturnBuffer(len + 1);
874   ret[0] = 0;
875   for (i = 2; i < argc; i++)
876      dStrcat(ret, argv[i], len + 1);
877
878   Con::printf("%s -- [%s]", ret, argv[1].getStringValue());
879   ret[0] = 0;
880
881   return argv[1];
882}
883
884DefineEngineStringlyVariadicFunction(warnThru, const char*, 2, 0, "(string passthru, string text...)"
885                "Like warn(), but first argument is returned.\n"
886                "@ingroup AFX")
887{
888   U32 len = 0;
889   S32 i;
890   for(i = 2; i < argc; i++)
891      len += dStrlen(argv[i]);
892
893   char *ret = Con::getReturnBuffer(len + 1);
894   ret[0] = 0;
895   for(i = 2; i < argc; i++)
896      dStrcat(ret, argv[i], len + 1);
897
898   Con::warnf("%s -- [%s]", ret, argv[1].getStringValue());
899   ret[0] = 0;
900
901   return argv[1];
902}
903
904DefineEngineStringlyVariadicFunction(errorThru, const char*, 2, 0, "(string passthru, string text...)"
905                "Like error(), but first argument is returned.\n"
906                "@ingroup AFX")
907{
908   U32 len = 0;
909   S32 i;
910   for(i = 2; i < argc; i++)
911      len += dStrlen(argv[i]);
912
913   char *ret = Con::getReturnBuffer(len + 1);
914   ret[0] = 0;
915   for(i = 2; i < argc; i++)
916      dStrcat(ret, argv[i], len + 1);
917
918   Con::errorf("%s -- [%s]", ret, argv[1].getStringValue());
919   ret[0] = 0;
920
921   return argv[1];
922}
923
924//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
925