Advertisement
Guest User

Untitled

a guest
Feb 11th, 2016
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.05 KB | None | 0 0
  1. $botstate_Wait = 0;
  2. $botstate_Moving = 1;
  3. $botstate_fire = 2;
  4. $botstate_ceacefire = 3;
  5. $botstate_PathToNearest = 4;
  6. $botstate_Wander = 5;
  7. $botstate_Confused = 6;
  8.  
  9. $botStateDuration[$botstate_Wait] = 500;
  10. $botStateDuration[$botstate_fire] = 32;
  11. $botStateDuration[$botstate_ceacefire] = 32;
  12. $botStateDuration[$botstate_PathToNearest] = 32;
  13. $botStateDuration[$botstate_Wander] = 128;
  14. $botStateDuration[$botstate_Confused] = 128;
  15. $botStateDuration[$botstate_Moving] = 128;
  16.  
  17. $showBotStates = false;
  18.  
  19. function AIPlayer::customAiSpawn(%spawn, %datablock)
  20. {
  21. if (!isObject(%datablock)) %datablock = DemoPlayer;
  22. // Create the demo player object
  23. %player = new AiPlayer()
  24. {
  25. dataBlock = %datablock;
  26. position = %spawn.getTransform();
  27. isBot = true;
  28. repathTolerance = %datablock.repathTolerance;
  29. searchTolerance = %datablock.searchTolerance;
  30. hieghtPreference = %datablock.hieghtPreference;
  31. mMoveTolerance = 0.25;
  32. MoveStuckTolerance = %datablock.maxForwardSpeed * 0.9;
  33. moveStuckTestDelay = %datablock.stuckTimeWait;
  34. team = 2;
  35. deployed = true;
  36. AttackRadius = %datablock.fireTolerance;
  37. mutter = %datablock.mutter;
  38. mutterCount = %datablock.mutterCount;
  39. mutterTime = 0;
  40. mutterFreq = %datablock.mutterFreq;
  41. mutterProb = %datablock.mutterProb;
  42. haterix = %datablock.haterix;
  43. };
  44.  
  45. //%player.playAudio(1, %datablock.ambientAudio);
  46.  
  47. MissionCleanup.add(%player);
  48. //are we stuck?
  49. %player.stuck = 0;
  50.  
  51. %obj.irritated = false;
  52. //give the Ai a rifle
  53. %player.mountImage(%datablock.weapon, 0);
  54. if (%datablock.dualWeapons)
  55. %player.mountImage(%datablock.altWeapon, 1);
  56. //pause a moment to let behind the scene stuff work out
  57. %player.schedule(1000, "aiStartUp");
  58. %player.skin = addTaggedString(%datablock.getBotSkin());
  59. %player.setSkinName(%player.skin);
  60. WalkaboutIgnore(%player,false);
  61. return %player;
  62. }
  63.  
  64. function AIPlayer::Muttering(%this)
  65. {
  66. if (%this.mutterTime == 0) %this.mutterTime = $Sim::Time;
  67. if (($Sim::Time - %this.mutterTime)> %this.mutterFreq)
  68. {
  69. if (getrandom() < (%this.mutterProb))
  70. {
  71. %trackNum = getrandom(5);
  72. if (%this.irritated) %trackNum +=5;
  73. %track = %this.mutter @ %trackNum;
  74. %this.playAudio(0, %track);
  75. }
  76. %this.mutterTime = $Sim::Time;
  77. }
  78. }
  79.  
  80. function AIPlayer::aiStartUp(%this)
  81. {
  82. if(!isObject(%this)||(%this.getState() $="Dead")) return;
  83. //here the Ai is going to decide what to do when it spawns
  84. //tool up with some bullets
  85. %this.setInventory("aiAmmo", 65535);
  86. %this.setInventory("aiAmmoClip", 65535);
  87. %this.manager = $SAI;
  88. %this.manager.addBot(%this);
  89. %this.enemy = -1;
  90. %this.canfire = true;
  91. %this.setstate($botstate_PathToNearest);
  92. %this.playThread( 1,"gears");
  93. }
  94.  
  95. //reactive callbacks
  96. function AIData::onReachDestination(%this,%obj)
  97. {
  98. if(!isObject(%obj)||(%obj.getState() $="Dead")) return;
  99. }
  100.  
  101. function AIData::onPathFailed(%this,%obj)
  102. {
  103. //error("AIData::onPathFailed - "@%obj);
  104. //if (isObject(%obj.enemy)) %obj.setMoveDestination(%obj.enemy.getWorldBoxCenter());
  105. %obj.setstate($botstate_Wander);
  106. %obj.enemy = -1;
  107. }
  108.  
  109. function AIData::onPathSuccess(%this,%obj)
  110. {
  111. //error("AIData::onPathSuccess - "@%obj);
  112. %obj.setstate($botstate_Moving);
  113. }
  114.  
  115. function AIData::onMoveStuck(%this,%obj)
  116. {
  117. if(!isObject(%obj)||(%obj.getState() $="Dead")) return;
  118. //echo( %obj @ " onMoveStuck");
  119. %obj.setstate($botstate_Wander);
  120. %obj.clearAim();
  121. %offset = (getRandom()-0.5)*4 SPC (getRandom()-0.5)*4 SPC 0;
  122. %pos = vectorAdd(%obj.getposition(), %offset);
  123. %obj.setMoveDestination(%pos);
  124. }
  125.  
  126. function AIData::onTargetInRange(%this,%obj)
  127. {
  128. if (!isObject(%obj.enemy))
  129. {
  130. %obj.setstate($botstate_PathToNearest);
  131. return;
  132. }
  133. //we're close. stop moving.
  134. %obj.targInRange = true;
  135.  
  136. %targ = %obj.enemy;
  137. %targPos = %targ.getPosition();
  138. %objPos = %obj.getPosition();
  139. if (%obj.checkInLos(%obj.enemy))
  140. %obj.aimAt(%obj.enemy);
  141. }
  142.  
  143. function AIData::onTargetInFiringRange(%this,%obj)
  144. {
  145. if (!isObject(%obj.enemy))
  146. {
  147. %obj.setstate($botstate_PathToNearest);
  148. return;
  149. }
  150.  
  151. %targ = %obj.enemy;
  152. %targPos = %targ.getPosition();
  153. %objPos = %obj.getPosition();
  154. if (%obj.checkInLos(%obj.enemy))
  155. %obj.aimAt(%obj.enemy);
  156. }
  157.  
  158. function AIData::onTargetEnterLOS(%this,%obj)
  159. {
  160. if (!isObject(%obj.enemy))
  161. {
  162. %obj.setstate($botstate_PathToNearest);
  163. return;
  164. }
  165. %dist = %obj.getTargetDistance(%obj.enemy);
  166.  
  167. if (%dist < %this.fireTolerance)
  168. %obj.setstate($botstate_fire);
  169. }
  170.  
  171. function AIData::onTargetExitLOS(%this,%obj)
  172. {
  173. %obj.clearAim();
  174. %offset = (getRandom()-0.5)*4 SPC (getRandom()-0.5)*4 SPC 0;
  175. %pos = vectorAdd(%obj.getposition(), %offset);
  176. %obj.setMoveDestination(%pos);
  177. %obj.setstate($botstate_Wander);
  178. }
  179.  
  180.  
  181. function AIData::onDamage(%this, %obj, %delta)
  182. {
  183. if(!isObject(%obj)) return;
  184. %obj.setstate($botstate_PathToNearest);
  185. if(%obj.getstate() $="Dead")
  186. {
  187. //take finger off trigger
  188. %obj.setImageTrigger(0, 0);
  189. $curKills++;
  190. updateKillScore();
  191. tryUnlock();
  192. }
  193. %obj.clearAim();
  194. %obj.enemy = -1;
  195.  
  196. %percentTrauma = %delta/%this.maxDamage;
  197. %centerpoint = %obj.getWorldBoxCenter();
  198.  
  199. %normal[0] = "0.0 0.0 1.0";
  200. %abNormal[0] = "2.0 2.0 0.0";
  201. %normal[1] = "0.0 1.0 0.0";
  202. %abNormal[1] = "2.0 0.0 2.0";
  203. %normal[2] = "1.0 0.0 0.0";
  204. %abNormal[2] = "0.0 2.0 2.0";
  205. %normal[3] = "0.0 0.0 -1.0";
  206. %abNormal[3] = "2.0 2.0 0.0";
  207. %normal[4] = "0.0 -1.0 0.0";
  208. %abNormal[4] = "2.0 0.0 2.0";
  209. %normal[5] = "-1.0 0.0 0.0";
  210. %abNormal[5] = "0.0 2.0 2.0";
  211.  
  212. %clientCount = ClientGroup.getCount();
  213. for (%i=0;%i<6;%i++)
  214. {
  215. %normalScaled = VectorScale(%normal[%i],-2);
  216. %targetPoint = VectorAdd(%centerpoint,%normalScaled);
  217. %mask = $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType;
  218. %hitObject = ContainerRayCast(%centerpoint, %targetPoint, %mask, %obj);
  219.  
  220. if (%hitObject)
  221. {
  222. %splatterPoint = getWords(%hitObject,1,3);
  223. %splatterNorm = getWords(%hitObject,4,6);
  224. %splatterVary = getRandom()*getword(%abNormal[%i],0)-getword(%abNormal[%i],0)/2 SPC getRandom()*getword(%abNormal[%i],1)-getword(%abNormal[%i],1)/2 SPC getRandom()*getword(%abNormal[%i],2)-getword(%abNormal[%i],2)/2;
  225. %Decalposition = VectorAdd(%splatterPoint, %splatterVary);
  226.  
  227. for (%clientIndex = 0; %clientIndex < %clientCount; %clientIndex++)
  228. {
  229. %client = ClientGroup.getObject(%clientIndex);
  230. %ghostIndex = %client.getGhostID(%obj);
  231.  
  232. commandToClient(%client,'Spatter', %Decalposition, %splatterNorm, %percentTrauma);
  233. }
  234. }
  235. }
  236.  
  237. %obj.damagemark+=%delta;
  238. // If the pain is excessive, let's hear about it.
  239. if ((%obj.damagemark > (%this.maxDamage/3))||(%delta > 10))
  240. {
  241. %obj.irritated = true;
  242. %obj.damagemark = 0;
  243. %obj.playPain();
  244. }
  245. }
  246.  
  247. function AIData::onDisabled(%this, %obj, %state)
  248. {
  249. if(isObject(%obj.effectron)) %obj.effectron.interrupt();
  250. if (isObject(%obj.elementalEffect)) %obj.elementalEffect.interrupt();
  251. %obj.manager.removeBot(%obj);
  252. %obj.stop();
  253. Parent::onDisabled(%this, %obj, %state);
  254. }
  255.  
  256. //planning
  257. function AIPlayer::aiDecide(%this)
  258. {
  259. if(!isObject(%this)||(%this.getState() $="Dead")) return;
  260. if (%this.isFalling) return;
  261. %this.Muttering();
  262. if(!isObject(%this.enemy))
  263. {
  264. %this.enemy = -1;
  265. %this.setstate($botstate_PathToNearest);
  266. }
  267.  
  268. if (%this.confused) %this.setstate($botstate_Confused);
  269. if (%this.nextCommandTime>$Sim::Time) return;
  270.  
  271. switch(%this.botstate)
  272. {
  273. case $botstate_Moving:
  274. if( VectorLen(%this.getVelocity()) > 0.1 )
  275. {
  276. NavmeshUpdateAll(%this,true);
  277. %this.moving = true;
  278. return;
  279. }
  280. else
  281. {
  282. %this.moving = false;
  283. %this.setstate($botstate_PathToNearest);
  284. }
  285. case $botstate_Confused:
  286. %this.randomPath();
  287. case $botstate_fire:
  288. %this.aiShoot();
  289. case $botstate_Wander:
  290. %this.randomPath();
  291. case $botstate_PathToNearest:
  292. %this.PathToNearest();
  293. default:
  294. %this.setstate($botstate_Wander);
  295. }
  296. }
  297.  
  298. function AIPlayer::setstate(%this,%state)
  299. {
  300. if (!%this.inState(%state)) %this.nextCommandTime = $Sim::Time + $botStateDuration[%state]/1000;
  301. %this.laststate = %this.botstate;
  302. %this.botstate = %state;
  303. if ($showBotStates) %this.setShapeName(%state);
  304. }
  305.  
  306. function AIPlayer::inState(%this,%state)
  307. {
  308. if (%this.botstate == %state) return true;
  309. return false;
  310. }
  311.  
  312. function AIPlayer::hateBias(%this,%enemy)
  313. {
  314. %hate = 1;
  315. %DB = %enemy.getDataBlock();
  316. if (isObject(%this.haterix))
  317. {
  318. %hateEntry = %this.haterix.getIndexFromKey(%DB.classname);
  319. if (%hateEntry == -1) error("No hate entry for:" SPC %DB.classname);
  320. %hate = %this.haterix.getValue(%hateEntry);
  321. if (%hate == -1) error("No hate value for:" SPC %DB.classname);
  322. }
  323. else
  324. {
  325. error("I bring you love! (No haterix found)");
  326. }
  327. if (%this.damageTaken[%enemy])
  328. {
  329. %hate += %this.damageTaken[%enemy]*10;
  330. }
  331. if ( %DB.isMethod( "getHateMod" )) %hatemod = %DB.call("getHateMod");
  332. if (%hatemod)
  333. %hate *= %hatemod;
  334. %hate = ((101-%hate)/100);
  335. return %hate;
  336. }
  337.  
  338. function AIPlayer::losBias(%this,%enemy)
  339. {
  340. %bias = 1;
  341. //can we see them?
  342. if(%this.checkInLos(%enemy))
  343. %bias = %bias / (%this.getdatablock().losPreference+1);
  344. return %bias;
  345. }
  346.  
  347. function AIPlayer::FoVBias(%this,%enemy,%fov)
  348. {
  349. %bias = 1;
  350. //can we see them?
  351. if(%this.checkInFoV(%enemy,%fov))
  352. %bias = %bias / (%this.getdatablock().losPreference+1);
  353. return %bias;
  354. }
  355.  
  356. function AIPlayer::getNearestTarget(%this)
  357. {
  358. if(!isObject(%this)||(%this.getState() $="Dead")) return false;
  359. %index = -1;
  360. %enemyID = -1;
  361. %tempDist = 0;
  362. %dist = %this.searchTolerance;
  363. %ourPos = %this.getWorldBoxCenter();
  364. for(%i = 0; %i < %this.manager.targetList.count(); %i++)
  365. {
  366. //get the ID from the array
  367. %enemy = %this.manager.targetList.getKey(%i);
  368.  
  369. if((%enemy != %this)&&(isObject(%enemy))&&(%enemy.deployed))
  370. {
  371. %enemyPos = %enemy.getWorldBoxCenter();
  372. %tempDist = VectorDist(%enemyPos, %ourPos);
  373. %actualdist = %tempDist;
  374. //keep your friends close, and your enemies 'closer'
  375. %hatebias = %this.hateBias(%enemy);
  376. %tempDist = %tempDist * %hatebias;
  377.  
  378. %fovCheck = %this.FoVBias(%enemy,90);
  379. %tempDist = %tempDist * %fovCheck;
  380. //if (%fovCheck != 1)
  381. //%tempDist = %tempDist * %this.losBias(%enemy);
  382.  
  383. if ((%tempDist < %dist)&&(%actualdist<%this.searchTolerance))
  384. {
  385. //echo(%this @ " finds closer enemy " @ %enemy @ " than previous " @ %enemyID);
  386. %dist = %tempDist;
  387. %index = %i;
  388. %enemyID = %enemy;
  389. }
  390. }
  391. }
  392. if (!isObject(%enemy)) %enemyID = -1;
  393. //if (%enemyID == -1) error("no target found!");
  394. return %enemyID;//return the closest enemy or else return -1;
  395. }
  396.  
  397. function AIPlayer::getROF(%this)
  398. {
  399. if (%this.getDatablock().rof)
  400. %Rof = (1000/%this.getDatablock().rof);
  401. else
  402. %Rof = 1000;
  403. return %Rof;
  404. }
  405.  
  406. //actions
  407. function AIPlayer::aiShoot(%this)
  408. {
  409. if(!isObject(%this)||(%this.getState() $="Dead")) return;
  410.  
  411. if(!isObject(%this.enemy)||(%this.enemy.getDamageState() !$="Enabled")||(!%this.enemy.deployed))
  412. {
  413. %this.setstate($botstate_PathToNearest);
  414. return;
  415. }
  416.  
  417. %RoF = %this.getROF();
  418. if (%this.controled)
  419. %Rof = %Rof * %this.controler.getDatablock().getTriggerHappyMul();
  420.  
  421. if(%this.canfire)
  422. {
  423. if (!%this.getDatablock().movefire)
  424. {
  425. %this.stop();
  426. %this.moving = false;
  427. }
  428. %this.setImageTrigger(0, true);
  429. if (%this.getDatablock().dualWeapons)
  430. {
  431.  
  432. %this.schedule(%Rof/2,"setImageTrigger", 1, true);
  433. }
  434. %this.lockOutWeapon(true, %Rof);
  435. }
  436. %this.setstate($botstate_PathToNearest);
  437. }
  438.  
  439. function AIPlayer::aiStopShoot(%this)
  440. {
  441. if(!isObject(%this)||(%this.getState() $="Dead")) return;
  442. }
  443.  
  444. function AIPlayer::lockOutWeapon(%this,%flag,%duration)
  445. {
  446. cancel(%this.lockoutTime);
  447. %this.canfire = !%flag;
  448.  
  449. if(%flag)
  450. {
  451. %this.setImageTrigger(0, false);
  452. if (%this.getDatablock().dualWeapons)
  453. %this.setImageTrigger(1, false);
  454. %this.lockoutTime = %this.schedule(%duration,"lockOutWeapon",false,%duration);
  455. }
  456. }
  457.  
  458. function AIPlayer::PathToNearest(%this)
  459. {
  460. if(!isObject(%this)||(%this.getState() $="Dead")) return false;
  461. %enemy = %this.getNearestTarget();
  462.  
  463. if ((%this.enemy == %enemy)&&(%this.moving)) return true;
  464.  
  465. %this.stop();
  466. %this.enemy = %enemy;
  467. %this.followObject(%this.enemy, %this.repathTolerance);
  468. %this.moving = false;
  469. return true;
  470. }
  471.  
  472. function AIPlayer::randomPath(%this)
  473. {
  474. if(!isObject(%this)||(%this.getState() $="Dead")) return;
  475. %this.currentNode = 0;
  476. %this.targetNode = 0;
  477. %start = %this.getPosition();
  478. //get a random goal, count available up
  479. %count = %this.manager.targetList.count();
  480. %index = getRandom(0, %count-1);
  481. %enemy = %this.manager.targetList.getKey(%index);
  482. %this.stop();
  483. %this.enemy = %enemy;
  484. %this.followObject(%this.enemy, %this.repathTolerance);
  485. }
  486.  
  487.  
  488. function AIPlayer::randomPoint(%this, %duration)
  489. {
  490. if(!isObject(%this)||(%this.getState() $="Dead")) return;
  491. %this.stop();
  492. %this.enemy = -1;
  493. %offset = (getRandom()-0.5)*10 SPC (getRandom()-0.5)*10 SPC 0;
  494. %pos = vectorAdd(%this.getposition(), %offset);
  495. %this.setMoveDestination(%pos);
  496. %this.nextCommandTime = $Sim::Time + %duration;
  497. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement