aiClient.cpp
Engine/source/T3D/aiClient.cpp
Public Functions
ConsoleDocClass(AIClient , "@brief Simulated client driven by AI <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">commands.\n\n</a>" "This object is derived from the <a href="/coding/class/classaiconnection/">AIConnection</a> class. It introduces its own <a href="/coding/class/classplayer/">Player</a> object " "<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> solidify the purpose of this class: Simulated client connecting as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">player\n\n</a>" "To get more specific, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> you want <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> strong alternative <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> AIPlayer, consider AIClient. <a href="/coding/class/classaiclient/">AIClient</a> inherits from AIConnection, " "contains quite <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> bit of functionality you will find in AIPlayer, and has its own <a href="/coding/class/classplayer/">Player</a> " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" " @note This is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> legacy class, which you are discouraged from using as it will " "most likely be deprecated in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> future version. For now it has been left in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> " "backwards compatibility with TGE and the old RTS Kit. Use <a href="/coding/class/classaiplayer/">AIPlayer</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">instead.\n\n</a>" " @see AIPlayer, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AIConnection\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AI\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineFunction(aiAddPlayer , S32 , (const char *name, const char *ns) , ("") , "'playerName' )
Adds an AI Player to the game.
DefineEngineMethod(AIClient , getAimLocation , Point3F , () , "ai.getAimLocation();" )
Returns the point the AI is aiming at.
DefineEngineMethod(AIClient , getLocation , Point3F , () , "ai.getLocation();" )
Gets the AI's location in the world.
DefineEngineMethod(AIClient , getMoveDestination , Point3F , () , "ai.getMoveDestination();" )
Returns the point the AI is set to move to.
DefineEngineMethod(AIClient , getTargetObject , S32 , () , "ai.getTargetObject();" )
Gets the object the AI is targeting.
DefineEngineMethod(AIClient , missionCycleCleanup , void , () , "ai.missionCycleCleanup();" )
Tells the bot the mission is cycling.
DefineEngineMethod(AIClient , move , void , () , "ai.move();" )
Sets the AI to run mode.
DefineEngineMethod(AIClient , moveForward , void , () , "ai.moveForward();" )
Tells the AI to move forward 100 units...TEST FXN.
DefineEngineMethod(AIClient , setAimLocation , void , (Point3F v) , "ai.setAimLocation( x y z );" )
Tells the AI to aim at the location provided.
DefineEngineMethod(AIClient , setMoveDestination , void , (Point3F v) , "ai.setMoveDestination( x y z );" )
Tells the AI to move to the location provided.
DefineEngineMethod(AIClient , setMoveSpeed , void , (F32 speed) , "ai.setMoveSpeed( float );" )
Sets the move speed for an AI object.
DefineEngineMethod(AIClient , setTargetObject , void , (const char *objName) , "ai.setTargetObject( obj );" )
Sets the bots target object.
DefineEngineMethod(AIClient , stop , void , () , "ai.stop();" )
Stops all AI movement, halt!
IMPLEMENT_CALLBACK(AIClient , onConnect , void , (const char *idString) , (idString) , "" )
Detailed Description
Public Functions
ConsoleDocClass(AIClient , "@brief Simulated client driven by AI <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">commands.\n\n</a>" "This object is derived from the <a href="/coding/class/classaiconnection/">AIConnection</a> class. It introduces its own <a href="/coding/class/classplayer/">Player</a> object " "<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> solidify the purpose of this class: Simulated client connecting as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">player\n\n</a>" "To get more specific, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> you want <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> strong alternative <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> AIPlayer, consider AIClient. <a href="/coding/class/classaiclient/">AIClient</a> inherits from AIConnection, " "contains quite <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> bit of functionality you will find in AIPlayer, and has its own <a href="/coding/class/classplayer/">Player</a> " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" " @note This is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> legacy class, which you are discouraged from using as it will " "most likely be deprecated in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> future version. For now it has been left in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> " "backwards compatibility with TGE and the old RTS Kit. Use <a href="/coding/class/classaiplayer/">AIPlayer</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">instead.\n\n</a>" " @see AIPlayer, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AIConnection\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AI\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineFunction(aiAddPlayer , S32 , (const char *name, const char *ns) , ("") , "'playerName' )
Adds an AI Player to the game.
DefineEngineMethod(AIClient , getAimLocation , Point3F , () , "ai.getAimLocation();" )
Returns the point the AI is aiming at.
DefineEngineMethod(AIClient , getLocation , Point3F , () , "ai.getLocation();" )
Gets the AI's location in the world.
DefineEngineMethod(AIClient , getMoveDestination , Point3F , () , "ai.getMoveDestination();" )
Returns the point the AI is set to move to.
DefineEngineMethod(AIClient , getTargetObject , S32 , () , "ai.getTargetObject();" )
Gets the object the AI is targeting.
DefineEngineMethod(AIClient , missionCycleCleanup , void , () , "ai.missionCycleCleanup();" )
Tells the bot the mission is cycling.
DefineEngineMethod(AIClient , move , void , () , "ai.move();" )
Sets the AI to run mode.
DefineEngineMethod(AIClient , moveForward , void , () , "ai.moveForward();" )
Tells the AI to move forward 100 units...TEST FXN.
DefineEngineMethod(AIClient , setAimLocation , void , (Point3F v) , "ai.setAimLocation( x y z );" )
Tells the AI to aim at the location provided.
DefineEngineMethod(AIClient , setMoveDestination , void , (Point3F v) , "ai.setMoveDestination( x y z );" )
Tells the AI to move to the location provided.
DefineEngineMethod(AIClient , setMoveSpeed , void , (F32 speed) , "ai.setMoveSpeed( float );" )
Sets the move speed for an AI object.
DefineEngineMethod(AIClient , setTargetObject , void , (const char *objName) , "ai.setTargetObject( obj );" )
Sets the bots target object.
DefineEngineMethod(AIClient , stop , void , () , "ai.stop();" )
Stops all AI movement, halt!
IMPLEMENT_CALLBACK(AIClient , onConnect , void , (const char *idString) , (idString) , "" )
IMPLEMENT_CONOBJECT(AIClient )
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#include "platform/platform.h" 25#include "T3D/aiClient.h" 26 27#include "math/mMatrix.h" 28#include "T3D/shapeBase.h" 29#include "T3D/player.h" 30#include "T3D/gameBase/moveManager.h" 31#include "console/consoleInternal.h" 32#include "console/engineAPI.h" 33 34 35IMPLEMENT_CONOBJECT( AIClient ); 36 37ConsoleDocClass( AIClient, 38 "@brief Simulated client driven by AI commands.\n\n" 39 40 "This object is derived from the AIConnection class. It introduces its own Player object " 41 "to solidify the purpose of this class: Simulated client connecting as a player\n\n" 42 "To get more specific, if you want a strong alternative to AIPlayer (and wish to make use " 43 "of the AIConnection structure), consider AIClient. AIClient inherits from AIConnection, " 44 "contains quite a bit of functionality you will find in AIPlayer, and has its own Player " 45 "object.\n\n" 46 47 "@note This is a legacy class, which you are discouraged from using as it will " 48 "most likely be deprecated in a future version. For now it has been left in for " 49 "backwards compatibility with TGE and the old RTS Kit. Use AIPlayer instead.\n\n" 50 51 "@see AIPlayer, AIConnection\n\n" 52 53 "@ingroup AI\n" 54 "@ingroup Networking\n" 55); 56 57IMPLEMENT_CALLBACK(AIClient, onConnect, void, (const char* idString), (idString),""); 58 59/** 60 * Constructor 61 */ 62AIClient::AIClient() { 63 mMoveMode = ModeStop; 64 mMoveDestination.set( 0.0f, 0.0f, 0.0f ); 65 mAimLocation.set( 0.0f, 0.0f, 0.0f ); 66 mMoveSpeed = 1.0f; 67 mMoveTolerance = 0.25f; 68 69 // Clear the triggers 70 for( S32 i = 0; i < MaxTriggerKeys; i++ ) 71 mTriggers[i] = false; 72 73 mAimToDestination = true; 74 mTargetInLOS = false; 75 76 mLocation.set( 0.0f, 0.0f, 0.0f ); 77 mPlayer = NULL; 78} 79 80/** 81 * Destructor 82 */ 83AIClient::~AIClient() { 84 // Blah 85} 86 87/** 88 * Sets the object the bot is targeting 89 * 90 * @param targetObject The object to target 91 */ 92void AIClient::setTargetObject( ShapeBase *targetObject ) { 93 if ( !targetObject || !bool( mTargetObject ) || targetObject->getId() != mTargetObject->getId() ) 94 mTargetInLOS = false; 95 96 mTargetObject = targetObject; 97} 98 99/** 100 * Returns the target object 101 * 102 * @return Object bot is targeting 103 */ 104S32 AIClient::getTargetObject() const { 105 if( bool( mTargetObject ) ) 106 return mTargetObject->getId(); 107 else 108 return -1; 109} 110 111/** 112 * Sets the speed at which this AI moves 113 * 114 * @param speed Speed to move, default player was 10 115 */ 116void AIClient::setMoveSpeed( F32 speed ) { 117 if( speed <= 0.0f ) 118 mMoveSpeed = 0.0f; 119 else 120 mMoveSpeed = getMin( 1.0f, speed ); 121} 122 123/** 124 * Sets the movement mode for this AI 125 * 126 * @param mode Movement mode, see enum 127 */ 128void AIClient::setMoveMode( S32 mode ) { 129 if( mode < 0 || mode >= ModeCount ) 130 mode = 0; 131 132 if( mode != mMoveMode ) { 133 switch( mode ) { 134 case ModeStuck: 135 throwCallback( "onStuck" ); 136 break; 137 case ModeMove: 138 if( mMoveMode == ModeStuck ) 139 throwCallback( "onUnStuck" ); 140 else 141 throwCallback( "onMove" ); 142 break; 143 case ModeStop: 144 throwCallback( "onStop" ); 145 break; 146 } 147 } 148 149 mMoveMode = mode; 150} 151 152/** 153 * Sets how far away from the move location is considered 154 * "on target" 155 * 156 * @param tolerance Movement tolerance for error 157 */ 158void AIClient::setMoveTolerance( const F32 tolerance ) { 159 mMoveTolerance = getMax( 0.1f, tolerance ); 160} 161 162/** 163 * Sets the location for the bot to run to 164 * 165 * @param location Point to run to 166 */ 167void AIClient::setMoveDestination( const Point3F &location ) { 168 // Ok, here's the story...we're going to aim where we are going UNLESS told otherwise 169 if( mAimToDestination ) { 170 mAimLocation = location; 171 mAimLocation.z = 0.0f; 172 } 173 174 mMoveDestination = location; 175} 176 177/** 178 * Sets the location for the bot to aim at 179 * 180 * @param location Point to aim at 181 */ 182void AIClient::setAimLocation( const Point3F &location ) { 183 mAimLocation = location; 184 mAimToDestination = false; 185} 186 187/** 188 * Clears the aim location and sets it to the bot's 189 * current destination so he looks where he's going 190 */ 191void AIClient::clearAim() { 192 mAimLocation = Point3F( 0.0f, 0.0f, 0.0f ); 193 mAimToDestination = true; 194} 195 196/** 197 * This method gets the move list for an object, in the case 198 * of the AI, it actually calculates the moves, and then 199 * sends them down the pipe. 200 * 201 * @param movePtr Pointer to move the move list into 202 * @param numMoves Number of moves in the move list 203 */ 204U32 AIClient::getMoveList( Move **movePtr,U32 *numMoves ) { 205 //initialize the move structure and return pointers 206 mMove = NullMove; 207 *movePtr = &mMove; 208 *numMoves = 1; 209 210 // Check if we got a player 211 mPlayer = NULL; 212 mPlayer = dynamic_cast<Player *>( getControlObject() ); 213 214 // We got a something controling us? 215 if( !mPlayer ) 216 return 1; 217 218 219 // What is The Matrix? 220 MatrixF moveMatrix; 221 moveMatrix.set( EulerF( 0, 0, 0 ) ); 222 moveMatrix.setColumn( 3, Point3F( 0, 0, 0 ) ); 223 moveMatrix.transpose(); 224 225 // Position / rotation variables 226 F32 curYaw, curPitch; 227 F32 newYaw, newPitch; 228 F32 xDiff, yDiff; 229 230 231 F32 moveSpeed = mMoveSpeed; 232 233 switch( mMoveMode ) { 234 235 case ModeStop: 236 return 1; // Stop means no action 237 break; 238 239 case ModeStuck: 240 // Fall through, so we still try to move 241 case ModeMove: 242 243 // Get my location 244 MatrixF const& myTransform = mPlayer->getTransform(); 245 myTransform.getColumn( 3, &mLocation ); 246 247 // Set rotation variables 248 Point3F rotation = mPlayer->getRotation(); 249 Point3F headRotation = mPlayer->getHeadRotation(); 250 curYaw = rotation.z; 251 curPitch = headRotation.x; 252 xDiff = mAimLocation.x - mLocation.x; 253 yDiff = mAimLocation.y - mLocation.y; 254 255 // first do Yaw 256 if( !mIsZero( xDiff ) || !mIsZero( yDiff ) ) { 257 // use the cur yaw between -Pi and Pi 258 while( curYaw > M_2PI_F ) 259 curYaw -= M_2PI_F; 260 while( curYaw < -M_2PI_F ) 261 curYaw += M_2PI_F; 262 263 // find the new yaw 264 newYaw = mAtan2( xDiff, yDiff ); 265 266 // find the yaw diff 267 F32 yawDiff = newYaw - curYaw; 268 269 // make it between 0 and 2PI 270 if( yawDiff < 0.0f ) 271 yawDiff += M_2PI_F; 272 else if( yawDiff >= M_2PI_F ) 273 yawDiff -= M_2PI_F; 274 275 // now make sure we take the short way around the circle 276 if( yawDiff > M_2PI_F ) 277 yawDiff -= M_2PI_F; 278 else if( yawDiff < -M_2PI_F ) 279 yawDiff += M_2PI_F; 280 281 mMove.yaw = yawDiff; 282 283 // set up the movement matrix 284 moveMatrix.set( EulerF( 0.0f, 0.0f, newYaw ) ); 285 } 286 else 287 moveMatrix.set( EulerF( 0.0f, 0.0f, curYaw ) ); 288 289 // next do pitch 290 F32 horzDist = Point2F( mAimLocation.x, mAimLocation.y ).len(); 291 292 if( !mIsZero( horzDist ) ) { 293 //we shoot from the gun, not the eye... 294 F32 vertDist = mAimLocation.z; 295 296 newPitch = mAtan2( horzDist, vertDist ) - ( M_2PI_F / 2.0f ); 297 298 F32 pitchDiff = newPitch - curPitch; 299 mMove.pitch = pitchDiff; 300 } 301 302 // finally, mMove towards mMoveDestination 303 xDiff = mMoveDestination.x - mLocation.x; 304 yDiff = mMoveDestination.y - mLocation.y; 305 306 307 // Check if we should mMove, or if we are 'close enough' 308 if( ( ( mFabs( xDiff ) > mMoveTolerance ) || 309 ( mFabs( yDiff ) > mMoveTolerance ) ) && ( !mIsZero( mMoveSpeed ) ) ) 310 { 311 if( mIsZero( xDiff ) ) 312 mMove.y = ( mLocation.y > mMoveDestination.y ? -moveSpeed : moveSpeed ); 313 else if( mIsZero( yDiff ) ) 314 mMove.x = ( mLocation.x > mMoveDestination.x ? -moveSpeed : moveSpeed ); 315 else if( mFabs( xDiff ) > mFabs( yDiff ) ) { 316 F32 value = mFabs( yDiff / xDiff ) * mMoveSpeed; 317 mMove.y = ( mLocation.y > mMoveDestination.y ? -value : value ); 318 mMove.x = ( mLocation.x > mMoveDestination.x ? -moveSpeed : moveSpeed ); 319 } 320 else { 321 F32 value = mFabs( xDiff / yDiff ) * mMoveSpeed; 322 mMove.x = ( mLocation.x > mMoveDestination.x ? -value : value ); 323 mMove.y = ( mLocation.y > mMoveDestination.y ? -moveSpeed : moveSpeed ); 324 } 325 326 //now multiply the mMove vector by the transpose of the object rotation matrix 327 moveMatrix.transpose(); 328 Point3F newMove; 329 moveMatrix.mulP( Point3F( mMove.x, mMove.y, 0.0f ), &newMove ); 330 331 //and sub the result back in the mMove structure 332 mMove.x = newMove.x; 333 mMove.y = newMove.y; 334 335 // We should check to see if we are stuck... 336 if( mLocation.x == mLastLocation.x && 337 mLocation.y == mLastLocation.y && 338 mLocation.z == mLastLocation.z ) { 339 340 // We're stuck...probably 341 setMoveMode( ModeStuck ); 342 } 343 else 344 setMoveMode( ModeMove ); 345 } 346 else { 347 // Ok, we are close enough, lets stop 348 349 // setMoveMode( ModeStop ); // DON'T use this, it'll throw the wrong callback 350 mMoveMode = ModeStop; 351 throwCallback( "onReachDestination" ); // Callback 352 353 } 354 break; 355 } 356 357 // Test for target location in sight 358 RayInfo dummy; 359 Point3F targetLoc = mMoveDestination; // Change this 360 361 if( mPlayer ) { 362 if( !mPlayer->getContainer()->castRay( mLocation, targetLoc, 363 StaticShapeObjectType | StaticObjectType | 364 TerrainObjectType, &dummy ) ) { 365 if( !mTargetInLOS ) 366 throwCallback( "onTargetEnterLOS" ); 367 } 368 else { 369 if( mTargetInLOS ) 370 throwCallback( "onTargetExitLOS" ); 371 372 } 373 } 374 375 // Copy over the trigger status 376 for( S32 i = 0; i < MaxTriggerKeys; i++ ) { 377 mMove.trigger[i] = mTriggers[i]; 378 mTriggers[i] = false; 379 } 380 381 return 1; 382} 383 384/** 385 * This method is just called to stop the bots from running amuck 386 * while the mission cycles 387 */ 388void AIClient::missionCycleCleanup() { 389 setMoveMode( ModeStop ); 390} 391 392 393/** 394 * Utility function to throw callbacks 395 */ 396void AIClient::throwCallback( const char *name ) { 397 Con::executef( this, name ); 398} 399 400/** 401 * What gets called when this gets created, different from constructor 402 */ 403void AIClient::onAdd( const char *nameSpace ) { 404 405 // This doesn't work... 406 // 407 if( String::compare( nameSpace, mNameSpace->mName ) ) { 408 Con::linkNamespaces( mNameSpace->mName, nameSpace ); 409 mNameSpace = Con::lookupNamespace( nameSpace ); 410 } 411 412 throwCallback( "onAdd" ); 413} 414 415// -------------------------------------------------------------------------------------------- 416// Console Functions 417// -------------------------------------------------------------------------------------------- 418 419/** 420 * Sets the move speed for an AI object 421 */ 422DefineEngineMethod( AIClient, setMoveSpeed, void, (F32 speed), , "ai.setMoveSpeed( float );" ) 423{ 424 AIClient *ai = static_cast<AIClient *>( object ); 425 ai->setMoveSpeed( speed ); 426} 427 428/** 429 * Stops all AI movement, halt! 430 */ 431DefineEngineMethod( AIClient, stop, void, (),, "ai.stop();" ) 432{ 433 AIClient *ai = static_cast<AIClient *>( object ); 434 ai->setMoveMode( AIClient::ModeStop ); 435} 436 437/** 438 * Tells the AI to aim at the location provided 439 */ 440DefineEngineMethod( AIClient, setAimLocation, void, (Point3F v), , "ai.setAimLocation( x y z );" ) 441{ 442 AIClient *ai = static_cast<AIClient *>( object ); 443 444 ai->setAimLocation( v ); 445} 446 447/** 448 * Tells the AI to move to the location provided 449 */ 450DefineEngineMethod( AIClient, setMoveDestination, void, (Point3F v), , "ai.setMoveDestination( x y z );" ) 451{ 452 AIClient *ai = static_cast<AIClient *>( object ); 453 454 ai->setMoveDestination( v ); 455} 456 457/** 458 * Returns the point the AI is aiming at 459 */ 460DefineEngineMethod( AIClient, getAimLocation, Point3F, (),, "ai.getAimLocation();" ) 461{ 462 AIClient *ai = static_cast<AIClient *>( object ); 463 return ai->getAimLocation(); 464} 465 466/** 467 * Returns the point the AI is set to move to 468 */ 469DefineEngineMethod( AIClient, getMoveDestination, Point3F, (),, "ai.getMoveDestination();" ) 470{ 471 AIClient *ai = static_cast<AIClient *>( object ); 472 return ai->getMoveDestination(); 473} 474 475/** 476 * Sets the bots target object 477 */ 478DefineEngineMethod( AIClient, setTargetObject, void, (const char * objName), , "ai.setTargetObject( obj );" ) 479{ 480 AIClient *ai = static_cast<AIClient *>( object ); 481 482 // Find the target 483 ShapeBase *targetObject; 484 if( Sim::findObject( objName, targetObject ) ) 485 ai->setTargetObject( targetObject ); 486 else 487 ai->setTargetObject( NULL ); 488} 489 490/** 491 * Gets the object the AI is targeting 492 */ 493DefineEngineMethod( AIClient, getTargetObject, S32, (),, "ai.getTargetObject();" ) 494{ 495 AIClient *ai = static_cast<AIClient *>( object ); 496 497 return ai->getTargetObject(); 498} 499 500/** 501 * Tells the bot the mission is cycling 502 */ 503DefineEngineMethod( AIClient, missionCycleCleanup, void, (),, "ai.missionCycleCleanup();" ) 504{ 505 AIClient *ai = static_cast<AIClient*>( object ); 506 ai->missionCycleCleanup(); 507} 508 509/** 510 * Sets the AI to run mode 511 */ 512DefineEngineMethod( AIClient, move, void, (),, "ai.move();" ) 513{ 514 AIClient *ai = static_cast<AIClient *>( object ); 515 ai->setMoveMode( AIClient::ModeMove ); 516} 517 518/** 519 * Gets the AI's location in the world 520 */ 521DefineEngineMethod( AIClient, getLocation, Point3F, (),, "ai.getLocation();" ) 522{ 523 AIClient *ai = static_cast<AIClient *>( object ); 524 return ai->getLocation(); 525} 526 527/** 528 * Adds an AI Player to the game 529 */ 530DefineEngineFunction( aiAddPlayer, S32, (const char * name, const char * ns), (""), "'playerName'[, 'AIClassType'] );") 531{ 532 // Create the player 533 AIClient *aiPlayer = new AIClient(); 534 aiPlayer->registerObject(); 535 aiPlayer->setGhostFrom(false); 536 aiPlayer->setGhostTo(false); 537 aiPlayer->setSendingEvents(false); 538 aiPlayer->setTranslatesStrings(true); 539 aiPlayer->setEstablished(); 540 541 // Add the connection to the client group 542 SimGroup *g = Sim::getClientGroup(); 543 g->addObject( aiPlayer ); 544 545 546 // Execute the connect console function, this is the same 547 // onConnect function invoked for normal client connections 548 aiPlayer->onConnect_callback( name ); 549 550 // Now execute the onAdd command and feed it the namespace 551 if(String::compare( ns,"" ) != 0 ) 552 aiPlayer->onAdd( ns ); 553 else 554 aiPlayer->onAdd( "AIClient" ); 555 556 return aiPlayer->getId(); 557} 558 559 560/** 561 * Tells the AI to move forward 100 units...TEST FXN 562 */ 563DefineEngineMethod( AIClient, moveForward, void, (),, "ai.moveForward();" ) 564{ 565 566 AIClient *ai = static_cast<AIClient *>( object ); 567 ShapeBase *player = dynamic_cast<ShapeBase*>(ai->getControlObject()); 568 Point3F location; 569 MatrixF const &myTransform = player->getTransform(); 570 myTransform.getColumn( 3, &location ); 571 572 location.y += 100.0f; 573 574 ai->setMoveDestination( location ); 575} // *** /TEST FXN 576