unitcombat.cpp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/Scripts/unitcombat.cpp $*
  25. * *
  26. * $Author:: David_y $*
  27. * *
  28. * $Modtime:: 4/27/00 11:44a $*
  29. * *
  30. * $Revision:: 2 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "scripts.h"
  36. #include "unitcombat.h"
  37. #define STATE_IDLE 5010
  38. #define STATE_IDLE_MOVEMENT 5011
  39. #define STATE_IDLE_ANIMATION 5012
  40. #define STATE_SEARCH 5020
  41. #define STATE_OFFENSIVE 5030
  42. #define STATE_DEFENSIVE 5040
  43. #define STATE_SUPPORT 5050
  44. #define STATE_CRITICAL 5060
  45. #define FUNC_CIRCLE_ATTACK 5110
  46. #define FUNC_CROUCH_ATTACK 5120
  47. #define FUNC_STAND_ATTACK 5130
  48. #define FUNC_DODGE_ENEMY 5140
  49. #define FUNC_SUPPRESSIVE_FIRE 5150
  50. #define FUNC_PANIC 5160
  51. #define FUNC_SEARCH_LOCATION 5170
  52. #define FUNC_SEARCH_CIRCLE 5180
  53. #define FUNC_SEARCH_FACING 5190
  54. DECLARE_SCRIPT ( Unit_Combat,"Scoreboard_ID=0:int,Controller_ID=0:int,Script_Override=0:int,Soldier_Type=0:int" )
  55. {
  56. int state;
  57. int function;
  58. int enemy_id;
  59. int self_id;
  60. int scoreboard_id;
  61. int controller_id;
  62. int script_override;
  63. const char * anim_script;
  64. const char * speech_script;
  65. Vector3 idleposition;
  66. Vector3 searchposition;
  67. bool combatspeech;
  68. int soldier_type;
  69. // Sodier type is a Script Param that adjusts the UnitCombat behavior
  70. // 0 - Default
  71. // 1 - Crouch Attack with Circle for Motion
  72. // 2 - Crouch Attack Only
  73. // 3 - Stand in Place and Fire
  74. /***********************************************************************************************
  75. ** Script Events
  76. ************************************************************************************************/
  77. void Animation_Complete( GameObject * obj, const char * anim )
  78. {
  79. if ( script_override > 0 )
  80. {
  81. GameObject *controller = Commands->Find_Object(controller_id);
  82. if ( controller )
  83. {
  84. Commands->Send_Custom_Event( obj, controller, OV_ANIMCOMPLETE, 0);
  85. return;
  86. }
  87. }
  88. else if ( (state == STATE_IDLE_ANIMATION) )
  89. {
  90. state = STATE_IDLE;
  91. }
  92. else if ( (state == STATE_SEARCH) )
  93. {
  94. if ( function == FUNC_PANIC )
  95. {
  96. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  97. {
  98. Sound_Create_Search( obj );
  99. }
  100. if ( soldier_type == 3 )
  101. {
  102. Function_Search_Facing( obj , searchposition, 0.0f );
  103. return;
  104. }
  105. Function_Search_Location( obj, searchposition , true );
  106. }
  107. else if ( function == FUNC_SEARCH_CIRCLE )
  108. {
  109. Function_Search_Circle( obj, searchposition, 7.5f );
  110. }
  111. }
  112. }
  113. void Created(GameObject * obj)
  114. {
  115. anim_script = NULL;
  116. self_id = Commands->Get_ID( obj );
  117. idleposition = Commands->Get_Position( obj );
  118. state = STATE_IDLE;
  119. float duration;
  120. duration = Commands->Get_Random( 5, 15 );
  121. Commands->Start_Timer ( obj, duration, TIMER_IDLE_ANIM );
  122. if ( script_override > 0 )
  123. {
  124. GameObject *controller = Commands->Find_Object(controller_id);
  125. if ( controller )
  126. {
  127. Commands->Send_Custom_Event( obj, controller, OV_CREATED, 0);
  128. }
  129. }
  130. else
  131. {
  132. Commands->Enable_Enemy_Seen( obj, true );
  133. // Commands->Enable_Sound_Heard( obj, true );
  134. }
  135. if ( Get_Int_Parameter(0) )
  136. {
  137. scoreboard_id = Get_Int_Parameter(0);
  138. }
  139. else
  140. {
  141. scoreboard_id = 0;
  142. }
  143. if ( Get_Int_Parameter(1) )
  144. {
  145. controller_id = Get_Int_Parameter(1);
  146. }
  147. else
  148. {
  149. controller_id = 0;
  150. }
  151. if ( Get_Int_Parameter(2) )
  152. {
  153. script_override = Get_Int_Parameter(2);
  154. }
  155. else
  156. {
  157. script_override = 0;
  158. }
  159. if ( Get_Int_Parameter(3) )
  160. {
  161. soldier_type = Get_Int_Parameter(3);
  162. }
  163. else
  164. {
  165. soldier_type = 0;
  166. }
  167. if ( soldier_type > 3 )
  168. {
  169. soldier_type;
  170. }
  171. else
  172. {
  173. soldier_type = 0;
  174. }
  175. }
  176. void Custom ( GameObject * obj, int type, int param, GameObject *sender )
  177. {
  178. if ( type == OV_OVERRIDE )
  179. {
  180. script_override = param;
  181. }
  182. if ( type == OV_AWARE )
  183. {
  184. if ( param == 1 )
  185. {
  186. Commands->Enable_Enemy_Seen( obj, true );
  187. // Commands->Enable_Sound_Heard( Me(), true );
  188. }
  189. if ( param == 0 )
  190. {
  191. Commands->Enable_Enemy_Seen( obj, false );
  192. // Commands->Enable_Sound_Heard( Me(), false );
  193. }
  194. }
  195. if ( script_override > 0 )
  196. {
  197. if ( type == OV_VERIFY )
  198. {
  199. GameObject *controller = Commands->Find_Object(controller_id);
  200. if ( controller )
  201. {
  202. Commands->Send_Custom_Event( obj, controller, OV_CONFIRM, 0);
  203. }
  204. }
  205. return;
  206. }
  207. else if ( type == CUSTOM_ALLY_INFO )
  208. {
  209. if ( sender )
  210. {
  211. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  212. {
  213. Sound_Create_Defensive_Attack( obj );
  214. }
  215. Commands->Send_Custom_Event( obj, sender, CUSTOM_TARGET_INFO, enemy_id);
  216. }
  217. }
  218. else if ( type == CUSTOM_TARGET_INFO )
  219. {
  220. GameObject *obj = Commands->Find_Object(param);
  221. if ( obj )
  222. {
  223. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  224. {
  225. Sound_Create_Attack( obj );
  226. }
  227. searchposition = Commands->Get_Position( obj );
  228. if ( soldier_type == 3 )
  229. {
  230. Function_Search_Facing( obj, searchposition, 0.0f );
  231. return;
  232. }
  233. Function_Search_Location( obj, searchposition, true );
  234. }
  235. }
  236. }
  237. void Damaged( GameObject * obj, GameObject *damager)
  238. {
  239. // Not using score system
  240. // Score_Hit_Tally( obj );
  241. Sound_Create_Damaged ( obj );
  242. if (Commands->Get_Health(obj) < 10.0f)
  243. {
  244. State_Change_Critical( obj );
  245. // Handled by innate animation system.
  246. // Function_Play_Knockdown_Anim( obj );
  247. }
  248. else
  249. {
  250. Commands->Set_Animation( obj,NULL,0);
  251. if ( script_override > 0 )
  252. {
  253. GameObject *controller = Commands->Find_Object(controller_id);
  254. if ( controller )
  255. {
  256. Commands->Send_Custom_Event( obj, controller, OV_DAMAGED, 0);
  257. return;
  258. }
  259. }
  260. else if ( state < STATE_OFFENSIVE )
  261. {
  262. if (Commands->Is_Object_Visible(obj,damager) == false)
  263. {
  264. if ( Commands->Get_Random( 0.0f, 100.0f) < 25.0f )
  265. {
  266. Sound_Create_Search( obj );
  267. }
  268. searchposition = Commands->Get_Position( damager );
  269. if ( soldier_type == 3 )
  270. {
  271. Function_Search_Facing( obj, searchposition, 0.0f );
  272. return;
  273. }
  274. Function_Search_Location( obj, searchposition, true );
  275. }
  276. }
  277. }
  278. }
  279. void Destroyed(GameObject * obj )
  280. {
  281. if ( script_override > 0 )
  282. {
  283. return;
  284. }
  285. /*
  286. float random = Commands->Get_Random( 0.0f, 1.0f );
  287. if ( random <= 0.25f )
  288. {
  289. Create_Crate( obj, Commands->Get_Position( obj ), 1 );
  290. }
  291. */
  292. }
  293. void Enemy_Seen(GameObject * obj, GameObject *enemy )
  294. {
  295. if ( script_override > 0 )
  296. {
  297. GameObject *controller = Commands->Find_Object(controller_id);
  298. if ( controller )
  299. {
  300. Commands->Send_Custom_Event( obj, Commands->Find_Object(controller_id), OV_ENEMYSEEN, 0);
  301. }
  302. return;
  303. }
  304. else if ( state < STATE_OFFENSIVE )
  305. {
  306. if ( Commands->Is_Object_Visible( obj, enemy ) == true )
  307. {
  308. enemy_id = Commands->Get_ID(enemy);
  309. if ( Commands->Get_Random( 0.0f, 100.0f) < 25.0f )
  310. {
  311. Sound_Create_Enemy_Seen( obj );
  312. }
  313. // Commands->Create_Instant_Logical_Sound( (CombatSoundType)(SOUND_ENEMY_SEEN), 20.0, obj, Commands->Get_Position(obj) );
  314. Commands->Enable_Enemy_Seen( obj, false );
  315. if ( soldier_type == 3 )
  316. {
  317. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  318. {
  319. Sound_Create_Attack( obj );
  320. }
  321. Function_Stand_Attack( obj, enemy, 5.0f, 100.0f );
  322. }
  323. else if ( Commands->Get_Random(0.0f, 1.0f) < 0.2f )
  324. {
  325. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  326. {
  327. Sound_Create_Attack( obj );
  328. }
  329. Function_Circle_Attack( obj, enemy, 10.0f, 100.0f, 15.0f );
  330. }
  331. else
  332. {
  333. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  334. {
  335. Sound_Create_Defensive_Attack( obj );
  336. }
  337. Function_Crouch_Attack( obj, enemy, 10.0f, 100.0f, 4.0f );
  338. }
  339. }
  340. }
  341. }
  342. void Movement_Complete( GameObject* obj, MovementCompleteReason reason)
  343. // void Goto_Failed( GameObject * me, GotoFailedReason reason )
  344. {
  345. if ( script_override > 0 )
  346. {
  347. return;
  348. }
  349. GameObject *target = Commands->Find_Object(enemy_id);
  350. switch(reason)
  351. {
  352. case ( MOVEMENT_COMPLETE_ARRIVED ):
  353. {
  354. if ( script_override > 0 )
  355. {
  356. GameObject *controller = Commands->Find_Object(controller_id);
  357. if ( controller )
  358. {
  359. Commands->Send_Custom_Event( obj, controller, OV_ARRIVED, 0);
  360. return;
  361. }
  362. }
  363. else if ( (state == STATE_OFFENSIVE) && (function == FUNC_CIRCLE_ATTACK) )
  364. {
  365. GameObject * target = Commands->Find_Object(enemy_id);
  366. if ( target )
  367. {
  368. if ( Commands->Get_Random(0.0f, 1.0f) < 0.2f )
  369. {
  370. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  371. {
  372. Sound_Create_Attack( obj );
  373. }
  374. Function_Circle_Attack( obj, target, 10.0f, 100.0f, 15.0f );
  375. }
  376. else
  377. {
  378. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  379. {
  380. Sound_Create_Defensive_Attack( obj );
  381. }
  382. Function_Crouch_Attack( obj, target, 10.0f, 100.0f, 4.0f );
  383. }
  384. }
  385. else
  386. {
  387. State_Change_Idle( obj, idleposition );
  388. }
  389. }
  390. else if ( state == STATE_IDLE_MOVEMENT )
  391. {
  392. state = STATE_IDLE;
  393. }
  394. else if ( state == STATE_SEARCH )
  395. {
  396. if ( function == FUNC_SEARCH_LOCATION )
  397. {
  398. Commands->Start_Timer( obj, 10.0, TIMER_SEARCH_LOCATION );
  399. Function_Search_Circle( obj, searchposition, 10.0f);
  400. }
  401. else if ( function == FUNC_SEARCH_CIRCLE )
  402. {
  403. Function_Play_Search_Anim( obj );
  404. }
  405. }
  406. }
  407. case (MOVEMENT_COMPLETE_BAD_START):
  408. {
  409. }
  410. case (MOVEMENT_COMPLETE_BAD_DEST):
  411. {
  412. if ( (state==STATE_OFFENSIVE) && (function == FUNC_CIRCLE_ATTACK) )
  413. {
  414. if ( target )
  415. {
  416. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  417. {
  418. Sound_Create_Attack( obj );
  419. }
  420. Function_Circle_Attack( obj, target, 10.0f, 100.0f, 15.0f);
  421. }
  422. else
  423. {
  424. State_Change_Idle( obj, idleposition);
  425. }
  426. }
  427. break;
  428. }
  429. case (MOVEMENT_COMPLETE_NO_PROGRESS_MADE):
  430. {
  431. if ( (state==STATE_OFFENSIVE) && (function == FUNC_CIRCLE_ATTACK) )
  432. {
  433. if ( target )
  434. {
  435. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  436. {
  437. Sound_Create_Defensive_Attack( obj );
  438. }
  439. Function_Circle_Attack( obj, target, 10.0f, 100.0f, 15.0f);
  440. }
  441. else
  442. {
  443. State_Change_Idle( obj, idleposition);
  444. }
  445. }
  446. break;
  447. }
  448. }
  449. }
  450. void Killed(GameObject * obj, GameObject *killer )
  451. {
  452. GameObject *scoreboard = Commands->Find_Object(scoreboard_id);
  453. if ( scoreboard )
  454. {
  455. Commands->Send_Custom_Event(obj,scoreboard,TALLY,TALLY_KILL);
  456. }
  457. Commands->Action_Movement_Stop( obj );
  458. Commands->Action_Attack_Stop( obj );
  459. Commands->Create_Sound("Death01",Commands->Get_Position(obj), obj );
  460. // Commands->Create_Instant_Logical_Sound( (CombatSoundType)(SOUND_DEATH), 30.0, obj, Commands->Get_Position( obj ) );
  461. if ( killer == Commands->Get_The_Star() )
  462. {
  463. float death_random = Commands->Get_Random(0,100);
  464. if ( death_random < 25.0 )
  465. {
  466. Sound_Create_Commando_Taunt(killer);
  467. }
  468. }
  469. GameObject *controller = Commands->Find_Object(controller_id);
  470. if (controller)
  471. {
  472. Commands->Send_Custom_Event( obj, controller, OV_KILLED, 0);
  473. }
  474. }
  475. void Sound_Heard(GameObject * obj, const CombatSound &sound)
  476. {
  477. if ( script_override > 0 )
  478. {
  479. // Commands->Send_Custom_Event( obj, Commands->Find_Object(controller_id), OV_SOUNDHEARD, 0);
  480. return;
  481. }
  482. if ( Commands->Get_Player_Type(sound.Creator) == Commands->Get_Player_Type( obj) )
  483. {
  484. if ( sound.Type == SOUND_DEATH )
  485. {
  486. if ( Commands->Get_Random( 0.0f, 100.0f) < 50.0f )
  487. {
  488. Sound_Create_Support( obj );
  489. }
  490. GameObject *commando = Commands->Get_The_Star();
  491. if ( commando )
  492. {
  493. searchposition = Commands->Get_Position( commando );
  494. }
  495. Function_Panic( obj );
  496. }
  497. }
  498. else if ( state < STATE_OFFENSIVE )
  499. {
  500. if ( sound.Type == SOUND_TYPE_BULLET_HIT ) // WAS WEAPON
  501. {
  502. searchposition = sound.Position;
  503. if ( Commands->Get_Random( 0.0f, 100.0f) < 25.0f )
  504. {
  505. Sound_Create_Panic( obj );
  506. }
  507. Function_Panic( obj );
  508. }
  509. else if ( sound.Type == SOUND_TYPE_GUNSHOT )
  510. {
  511. searchposition = sound.Position;
  512. if ( Commands->Get_Random( 0.0f, 100.0f) < 25.0f )
  513. {
  514. Sound_Create_Panic( obj );
  515. }
  516. Function_Panic( obj );
  517. }
  518. else if(sound.Type == SOUND_TYPE_FOOTSTEPS)
  519. {
  520. searchposition = sound.Position;
  521. if ( Commands->Get_Random( 0.0f, 100.0f) < 25.0f )
  522. {
  523. Sound_Create_Search( obj );
  524. }
  525. if ( soldier_type == 3 )
  526. {
  527. Function_Search_Facing( obj, searchposition, 0.0f );
  528. return;
  529. }
  530. Function_Search_Location( obj, searchposition, false );
  531. }
  532. else if (sound.Type == SOUND_TYPE_VEHICLE)
  533. {
  534. searchposition = sound.Position;
  535. if ( Commands->Get_Random( 0.0f, 100.0f) < 25.0f )
  536. {
  537. Sound_Create_Search( obj );
  538. }
  539. if ( soldier_type == 3 )
  540. {
  541. Function_Search_Facing( obj, searchposition, 0.0f );
  542. return;
  543. }
  544. Function_Search_Location( obj, searchposition, false );
  545. }
  546. else if ( sound.Type == SOUND_ENEMY_SEEN )
  547. {
  548. if ( sound.Creator )
  549. {
  550. Commands->Send_Custom_Event( obj, sound.Creator, CUSTOM_ALLY_INFO, self_id);
  551. }
  552. }
  553. }
  554. }
  555. void Timer_Expired(GameObject * obj, int timer )
  556. {
  557. if ( script_override > 0 )
  558. {
  559. if ( timer == TIMER_IDLE_ANIM )
  560. {
  561. float duration;
  562. duration = Commands->Get_Random( 15, 25);
  563. Commands->Start_Timer(obj, duration ,TIMER_IDLE_ANIM);
  564. }
  565. return;
  566. }
  567. if ( timer == TIMER_CROUCH_ATTACK )
  568. {
  569. GameObject *target = Commands->Find_Object(enemy_id);
  570. if ( target )
  571. {
  572. if ( Commands->Get_Random(0.0f, 1.0f) < 0.2f )
  573. {
  574. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  575. {
  576. Sound_Create_Attack( obj );
  577. }
  578. Function_Circle_Attack( obj, target, 10.0f, 100.0f, 15.0f );
  579. }
  580. else
  581. {
  582. if ( Commands->Get_Random( 0.0f, 100.0f) < 10.0f )
  583. {
  584. Sound_Create_Defensive_Attack( obj );
  585. }
  586. Function_Crouch_Attack( obj, target, 10.0f, 100.0f, 4.0f );
  587. }
  588. }
  589. else
  590. {
  591. State_Change_Idle( obj, idleposition );
  592. }
  593. }
  594. else if ( timer == TIMER_COMBAT_SPEECH )
  595. {
  596. combatspeech = false;
  597. }
  598. else if ( timer == TIMER_SEARCH_LOCATION )
  599. {
  600. State_Change_Idle( obj, idleposition );
  601. }
  602. else if ( timer == TIMER_IDLE_ANIM )
  603. {
  604. float duration;
  605. duration = Commands->Get_Random( 15, 25);
  606. Commands->Start_Timer( obj, duration ,TIMER_IDLE_ANIM);
  607. if ( state == STATE_IDLE )
  608. {
  609. Function_Play_Idle_Anim( obj );
  610. }
  611. }
  612. }
  613. /***********************************************************************************************
  614. ** Save / Load Events
  615. ************************************************************************************************/
  616. /*
  617. typedef enum
  618. {
  619. DATA_ID_STATE,
  620. DATA_ID_FUNCTION,
  621. DATA_ID_ENEMY_ID,
  622. DATA_ID_SELF_ID,
  623. DATA_ID_SCOREBOARD_ID,
  624. DATA_ID_CONTROLLER_ID,
  625. DATA_ID_SCRIPT_OVERRIDE,
  626. DATA_ID_ANIM_SCRIPT,
  627. DATA_ID_SPEECH_SCRIPT,
  628. DATA_ID_IDLEPOSITION,
  629. DATA_ID_SEARCHPOSITION,
  630. DATA_ID_COMBATSPEECH,
  631. DATA_ID_SOLDIER_TYPE,
  632. };
  633. void Save_Data( ScriptSaver & saver )
  634. {
  635. SAVE_BEGIN
  636. SAVE_DATA( DATA_ID_STATE, state )
  637. SAVE_DATA( DATA_ID_FUNCTION, function )
  638. SAVE_DATA( DATA_ID_ENEMY_ID, enemy_id )
  639. SAVE_DATA( DATA_ID_SELF_ID, self_id )
  640. SAVE_DATA( DATA_ID_SCOREBOARD_ID, scoreboard_id )
  641. SAVE_DATA( DATA_ID_CONTROLLER_ID, controller_id )
  642. SAVE_DATA( DATA_ID_SCRIPT_OVERRIDE, script_override )
  643. SAVE_DATA( DATA_ID_ANIM_SCRIPT, anim_script )
  644. SAVE_DATA( DATA_ID_SPEECH_SCRIPT, speech_script)
  645. SAVE_DATA( DATA_ID_IDLEPOSITION, idleposition )
  646. SAVE_DATA( DATA_ID_SEARCHPOSITION, searchposition )
  647. SAVE_DATA( DATA_ID_COMBATSPEECH, combatspeech )
  648. SAVE_DATA( DATA_ID_SOLDIER_TYPE, soldier_type )
  649. SAVE_END
  650. }
  651. void Load_Data( ScriptLoader & loader )
  652. {
  653. LOAD_BEGIN
  654. LOAD_DATA( DATA_ID_STATE, state )
  655. LOAD_DATA( DATA_ID_FUNCTION, function )
  656. LOAD_DATA( DATA_ID_ENEMY_ID, enemy_id )
  657. LOAD_DATA( DATA_ID_SELF_ID, self_id )
  658. LOAD_DATA( DATA_ID_SCOREBOARD_ID, scoreboard_id )
  659. LOAD_DATA( DATA_ID_CONTROLLER_ID, controller_id )
  660. LOAD_DATA( DATA_ID_SCRIPT_OVERRIDE, script_override )
  661. LOAD_DATA( DATA_ID_ANIM_SCRIPT, anim_script )
  662. LOAD_DATA( DATA_ID_SPEECH_SCRIPT, speech_script)
  663. LOAD_DATA( DATA_ID_IDLEPOSITION, idleposition )
  664. LOAD_DATA( DATA_ID_SEARCHPOSITION, searchposition )
  665. LOAD_DATA( DATA_ID_COMBATSPEECH, combatspeech )
  666. LOAD_DATA( DATA_ID_SOLDIER_TYPE, soldier_type )
  667. LOAD_END
  668. }
  669. */
  670. /***********************************************************************************************
  671. ** Functions - SlaveCombat State Change Functions (Replace Old Queen Calls to Custom)
  672. ************************************************************************************************/
  673. /*
  674. void Create_Crate( GameObject * obj, Vector3 position, int powerup_type )
  675. {
  676. // powerup_type refers to a random set of powerups
  677. // 1 - Health
  678. // 2 - Armor
  679. // 3 - Weapon
  680. // 4 - Ammo
  681. //
  682. // Only types 1 & 2 are to be used in a normal soldier drop
  683. position.Z += .25;
  684. const char * crate;
  685. float random;
  686. random = Commands->Get_Random( 0.0f, 5.0f );
  687. if ( random <= 0.5f )
  688. {
  689. crate = "Health_100";
  690. }
  691. else if ( random <= 1.0f )
  692. {
  693. crate = "Shield_Kevlar_100";
  694. }
  695. else if ( random <= 2.33f )
  696. {
  697. crate = "Health_50";
  698. }
  699. else if ( random <= 3.66f )
  700. {
  701. crate = "Shield_Kevlar_25";
  702. }
  703. else
  704. {
  705. crate = "Health_25";
  706. }
  707. Commands->Create_Object( crate, position);
  708. }
  709. */
  710. void Function_Circle_Attack(GameObject * obj, GameObject * Enemy, float Accuracy, float Range , float Radius)
  711. {
  712. state = STATE_OFFENSIVE;
  713. function = FUNC_CIRCLE_ATTACK;
  714. Commands->Enable_Enemy_Seen( obj, false);
  715. // Commands->Enable_Sound_Heard( Me, false);
  716. // Commands->Create_Instant_Logical_Sound( (CombatSoundType)(SOUND_ENEMY_SEEN), 20.0, Me, Commands->Get_Position( Me ) );
  717. Commands->Action_Movement_Set_Crouch( obj, false);
  718. double theta_angle = (360/5);
  719. float temp = Commands->Get_Random(0.0f,1.0f);
  720. if (temp > 0.4f)
  721. {
  722. theta_angle *= -1;
  723. }
  724. Vector3 targetlocation = Commands->Get_Position( obj ) - Commands->Get_Position(Enemy);
  725. targetlocation.Normalize();
  726. targetlocation *= Radius;
  727. targetlocation.Rotate_Z( DEG_TO_RADF(theta_angle) );
  728. targetlocation += Commands->Get_Position( Enemy );
  729. targetlocation.Z += 0.5;
  730. Commands->Action_Movement_Set_Forward_Speed( obj, 0.3f );
  731. Commands->Action_Movement_Goto_Location( obj, targetlocation, 2.0f);
  732. if ( soldier_type > 0 )
  733. {
  734. return;
  735. }
  736. Commands->Action_Attack_Object( obj, Enemy, Accuracy , Range );
  737. }
  738. void Function_Crouch_Attack(GameObject * obj, GameObject * Enemy, float Accuracy, float Range, float Duration )
  739. {
  740. state = STATE_OFFENSIVE;
  741. function = FUNC_CROUCH_ATTACK;
  742. Commands->Enable_Enemy_Seen( obj, false);
  743. // Commands->Enable_Sound_Heard( Me, false);
  744. // Commands->Create_Instant_Logical_Sound( (CombatSoundType)(SOUND_ENEMY_SEEN), 20.0, Me, Commands->Get_Position( Me ) );
  745. Commands->Action_Movement_Set_Crouch( obj, true );
  746. Commands->Start_Timer( obj, Duration, TIMER_CROUCH_ATTACK );
  747. Commands->Action_Attack_Object( obj, Enemy, Accuracy, Range );
  748. }
  749. void Function_Stand_Attack(GameObject * obj, GameObject * Enemy, float Accuracy, float Range )
  750. {
  751. state = STATE_OFFENSIVE;
  752. function = FUNC_STAND_ATTACK;
  753. Commands->Enable_Enemy_Seen( obj, false);
  754. // Commands->Enable_Sound_Heard( Me, false);
  755. // Commands->Create_Instant_Logical_Sound( (CombatSoundType)(SOUND_ENEMY_SEEN), 20.0, Me, Commands->Get_Position( Me ) );
  756. Commands->Action_Attack_Object( obj, Enemy, Accuracy, Range );
  757. }
  758. void Function_Panic(GameObject * obj)
  759. {
  760. if ( function != FUNC_PANIC )
  761. {
  762. state = STATE_SEARCH;
  763. function = FUNC_PANIC;
  764. Commands->Set_Animation( obj, NULL, 0);
  765. if ( Commands->Get_Random( 0.0f, 1.0f) < 0.5f )
  766. {
  767. Commands->Set_Animation( obj, "human.j21c01",0);
  768. }
  769. }
  770. }
  771. void Function_Play_Idle_Anim(GameObject * obj)
  772. {
  773. Commands->Set_Animation( obj, NULL, 0);
  774. float animnum = Commands->Get_Random(0,90);
  775. if (animnum <= 10)
  776. {anim_script = "human.j03c01";}else
  777. if (animnum <= 20)
  778. {anim_script = "human.j04c01";}else
  779. if (animnum <= 30)
  780. {anim_script = "human.j13c01";}else
  781. if (animnum <= 40)
  782. {anim_script = "human.j14c01";}else
  783. if (animnum <= 50)
  784. {anim_script = "human.j15c01";}else
  785. if (animnum <= 60)
  786. {anim_script = "human.j17c01";}else
  787. if (animnum <= 70)
  788. {anim_script = "human.j24c01";}else
  789. if (animnum <= 80)
  790. {anim_script = "human.j22c01";}else
  791. if (animnum <= 90)
  792. {anim_script = "human.j20c01";}
  793. state = STATE_IDLE_ANIMATION;
  794. Commands->Set_Animation( obj, anim_script, 0);
  795. }
  796. /*
  797. void Function_Play_Knockdown_Anim( GameObject * obj )
  798. {
  799. Commands->Set_Animation( obj, NULL, 0);
  800. const char * damaged_bone = Commands->Get_Damage_Bone_Name();
  801. bool direction = Commands->Get_Damage_Bone_Direction();
  802. if (direction == false)
  803. {
  804. if (!strcmp(damaged_bone,"CHEADD"))
  805. {
  806. anim_script = "human.635a01";
  807. }else
  808. if (!strcmp(damaged_bone,"CTHORAXD"))
  809. {
  810. anim_script ="human.621a";
  811. }else
  812. if (!strcmp(damaged_bone,"CLHUMERUSD"))
  813. {
  814. anim_script ="human.624a01";
  815. }else
  816. if (!strcmp(damaged_bone,"CRHUMERUSD"))
  817. {
  818. anim_script ="human.623a01";
  819. }else
  820. if (!strcmp(damaged_bone,"CLRADIUSD"))
  821. {
  822. anim_script="human.624a01";
  823. }else
  824. if (!strcmp(damaged_bone,"CRRADIUSD"))
  825. {
  826. anim_script="human.623a01";
  827. }else
  828. if (!strcmp(damaged_bone,"CPELVISD"))
  829. {
  830. anim_script="human.612a01";
  831. }else
  832. if (!strcmp(damaged_bone,"CLFEMURD"))
  833. {
  834. anim_script="human.624a01";
  835. }else
  836. if (!strcmp(damaged_bone,"CRFEMURD"))
  837. {
  838. anim_script="human.623a01";
  839. }else
  840. if (!strcmp(damaged_bone,"CLTIBIAD"))
  841. {
  842. anim_script="human.624a01";
  843. }else
  844. if (!strcmp(damaged_bone,"CRTIBIAD"))
  845. {
  846. anim_script="human.623a01";
  847. }
  848. }
  849. else if (direction == true)
  850. {
  851. if (!strcmp(damaged_bone,"CHEADD"))
  852. {
  853. anim_script = "human.635a01";
  854. }else
  855. if (!strcmp(damaged_bone,"CTHORAXD"))
  856. {
  857. anim_script ="human.622a";
  858. }else
  859. if (!strcmp(damaged_bone,"CLHUMERUSD"))
  860. {
  861. anim_script ="human.624a01";
  862. }else
  863. if (!strcmp(damaged_bone,"CRHUMERUSD"))
  864. {
  865. anim_script="human.623a01";
  866. }else
  867. if (!strcmp(damaged_bone,"CLRADIUSD"))
  868. {
  869. anim_script="human.624a01";
  870. }else
  871. if (!strcmp(damaged_bone,"CRRADIUSD"))
  872. {
  873. anim_script="human.623a01";
  874. }else
  875. if (!strcmp(damaged_bone,"CLFEMURD"))
  876. {
  877. anim_script="human.624a01";
  878. }else
  879. if (!strcmp(damaged_bone,"CRFEMURD"))
  880. {
  881. anim_script="human.623a01";
  882. }else
  883. if (!strcmp(damaged_bone,"CLTIBIAD"))
  884. {
  885. anim_script="human.624a01";
  886. }else
  887. if (!strcmp(damaged_bone,"CRTIBIAD"))
  888. {
  889. anim_script="human.623a01";
  890. }
  891. }
  892. else
  893. {
  894. anim_script ="human.622a";
  895. }
  896. Commands->Set_Animation( obj, anim_script, 0);
  897. }
  898. */
  899. void Function_Play_Search_Anim( GameObject * obj )
  900. {
  901. Commands->Set_Animation( obj, NULL, 0);
  902. float animnum = Commands->Get_Random(0,30);
  903. if ( animnum <= 10 )
  904. {anim_script = "human.j09c01";}
  905. else if ( animnum <= 20 )
  906. {anim_script = "human.j10c01";}
  907. else if( animnum <= 30 )
  908. {anim_script = "human.j11c01";}
  909. Commands->Set_Animation( obj, anim_script, 0);
  910. }
  911. void Function_Search_Circle( GameObject * obj, Vector3 position, float Radius )
  912. {
  913. state = STATE_SEARCH;
  914. function = FUNC_SEARCH_CIRCLE;
  915. Commands->Enable_Enemy_Seen( obj, true);
  916. // Commands->Enable_Sound_Heard( Me, true);
  917. Commands->Action_Movement_Set_Crouch( obj, false);
  918. Commands->Action_Attack_Stop( obj );
  919. Commands->Action_Movement_Set_Forward_Speed( obj, 0.4f );
  920. double theta_angle = (360/5);
  921. float reverse = Commands->Get_Random(0.0f,1.0f);
  922. if ( reverse < 0.1f)
  923. {
  924. theta_angle *= -1;
  925. }
  926. Vector3 targetlocation = Commands->Get_Position( obj ) - position;
  927. targetlocation.Normalize();
  928. targetlocation *= Radius;
  929. targetlocation.Rotate_Z(DEG_TO_RADF(theta_angle));
  930. targetlocation += position;
  931. targetlocation.Z += 0.5;
  932. Commands->Action_Movement_Goto_Location( obj, targetlocation, 2.0f);
  933. }
  934. void Function_Search_Facing( GameObject * obj, Vector3 position, float Distance )
  935. {
  936. state = STATE_SEARCH;
  937. function = FUNC_SEARCH_FACING;
  938. Commands->Enable_Enemy_Seen( obj, true);
  939. // Commands->Enable_Sound_Heard( Me, true);
  940. Commands->Action_Attack_Location( obj, searchposition, 0, 0 );
  941. }
  942. void Function_Search_Location( GameObject * obj, Vector3 position , bool Crouch )
  943. {
  944. state = STATE_SEARCH;
  945. function = FUNC_SEARCH_LOCATION;
  946. Commands->Enable_Enemy_Seen( obj, true);
  947. // Commands->Enable_Sound_Heard( Me, true);
  948. Commands->Action_Movement_Set_Crouch( obj, Crouch );
  949. Commands->Action_Movement_Set_Forward_Speed( obj, 0.4f );
  950. Commands->Action_Attack_Location( obj, searchposition, 0, 0 );
  951. Commands->Action_Movement_Goto_Location( obj, searchposition, 3.0f );
  952. }
  953. /*
  954. void Score_Hit_Tally( GameObject * obj )
  955. {
  956. const char * damaged_bone = Commands->Get_Damage_Bone_Name();
  957. bool direction = Commands->Get_Damage_Bone_Direction();
  958. GameObject *scoreboard = Commands->Find_Object(scoreboard_id);
  959. if ( scoreboard )
  960. {
  961. if ( direction == false )
  962. {
  963. Commands->Send_Custom_Event ( obj, scoreboard, HITDIRECTION, HD_FRONTHIT );
  964. }
  965. else if ( direction == true )
  966. {
  967. Commands->Send_Custom_Event ( obj, scoreboard, HITDIRECTION, HD_BACKHIT );
  968. }
  969. if (!strcmp(damaged_bone,"CHEADD"))
  970. {
  971. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_HEAD );
  972. }
  973. else if (!strcmp(damaged_bone,"CTHORAXD"))
  974. {
  975. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_CHEST );
  976. }
  977. else if (!strcmp(damaged_bone,"CLHUMERUSD"))
  978. {
  979. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_LEFTARM );
  980. }
  981. else if (!strcmp(damaged_bone,"CRHUMERUSD"))
  982. {
  983. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_RIGHTARM );
  984. }
  985. else if (!strcmp(damaged_bone,"CLRADIUSD"))
  986. {
  987. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_LEFTARM );
  988. }
  989. else if (!strcmp(damaged_bone,"CRRADIUSD"))
  990. {
  991. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_RIGHTARM );
  992. }
  993. else if (!strcmp(damaged_bone,"CPELVISD"))
  994. {
  995. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_GROIN );
  996. }
  997. else if (!strcmp(damaged_bone,"CLFEMURD"))
  998. {
  999. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_LEFTLEG );
  1000. }
  1001. else if (!strcmp(damaged_bone,"CRFEMURD"))
  1002. {
  1003. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_RIGHTLEG );
  1004. }
  1005. else if (!strcmp(damaged_bone,"CLTIBIAD"))
  1006. {
  1007. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_LEFTLEG );
  1008. }
  1009. else if (!strcmp(damaged_bone,"CRTIBIAD"))
  1010. {
  1011. Commands->Send_Custom_Event ( obj, scoreboard, BODYLOCATION, BL_RIGHTLEG );
  1012. }
  1013. }
  1014. }
  1015. */
  1016. void Sound_Create_Attack(GameObject * obj)
  1017. {
  1018. if (combatspeech == false )
  1019. {
  1020. combatspeech = true;
  1021. Commands->Start_Timer( obj, 4.0f, TIMER_COMBAT_SPEECH );
  1022. float sound_random = Commands->Get_Random( 0.0f , 80.0f);
  1023. if ( sound_random <= 10)
  1024. { speech_script = "FireAtWill01"; }
  1025. else if ( sound_random <= 20)
  1026. { speech_script = "LookAlive01"; }
  1027. else if ( sound_random <= 30)
  1028. { speech_script = "SearchAndDestroy01"; }
  1029. else if ( sound_random <= 40)
  1030. { speech_script = "TargetHasBeenEngaged01"; }
  1031. else if ( sound_random <= 50)
  1032. { speech_script = "FireAtWill02"; }
  1033. else if ( sound_random <= 60)
  1034. { speech_script = "LookAlive02"; }
  1035. else if ( sound_random <= 70)
  1036. { speech_script = "SearchAndDestroy02"; }
  1037. else if ( sound_random <= 80)
  1038. { speech_script = "TargetHasBeenEngaged02"; }
  1039. Commands->Create_Sound( speech_script, Commands->Get_Position( obj ), obj );
  1040. }
  1041. }
  1042. void Sound_Create_Commando_Taunt(GameObject * Commando)
  1043. {
  1044. float sound_random = Commands->Get_Random( 0.0 , 60.0 );
  1045. if ( sound_random <=10.0 )
  1046. { speech_script = "CVoice03KeepEmComin"; }
  1047. else if ( sound_random <=20.0 )
  1048. { speech_script = "CVoice04HaHa"; }
  1049. else if ( sound_random <=30.0 )
  1050. { speech_script = "CVoice05LeftHanded"; }
  1051. else if ( sound_random <=40.0 )
  1052. { speech_script = "CVoice06NoProblem"; }
  1053. else if ( sound_random <=50.0 )
  1054. { speech_script = "CVoice10TuffGuy"; }
  1055. else
  1056. { speech_script = "CVoice14Cmon"; }
  1057. Commands->Create_Sound( speech_script,Commands->Get_Position(Commando), Commando );
  1058. }
  1059. void Sound_Create_Damaged( GameObject * obj )
  1060. {
  1061. float sound_random = Commands->Get_Random( 0.0f, 20.0f );
  1062. if ( sound_random <= 10.0f )
  1063. {
  1064. speech_script = "BodyHit01";
  1065. }
  1066. else if ( sound_random <= 20.0 )
  1067. {
  1068. speech_script = "BodyHit02";
  1069. }
  1070. Commands->Create_Sound( speech_script, Commands->Get_Position( obj ), obj);
  1071. }
  1072. void Sound_Create_Defensive_Attack(GameObject * obj)
  1073. {
  1074. if (combatspeech == false )
  1075. {
  1076. combatspeech = true;
  1077. Commands->Start_Timer( obj, 4.0f, TIMER_COMBAT_SPEECH );
  1078. float sound_random = Commands->Get_Random( 0.0f , 40.0f);
  1079. if ( sound_random <=10.0 )
  1080. { speech_script = "HoldYourPositions01"; }
  1081. else if ( sound_random <=20.0 )
  1082. { speech_script = "KeepYourHeadDown01"; }
  1083. else if ( sound_random <=30.0 )
  1084. { speech_script = "HoldYourPositions02"; }
  1085. else if ( sound_random <=40.0 )
  1086. { speech_script = "KeepYourHeadDown02"; }
  1087. Commands->Create_Sound( speech_script,Commands->Get_Position( obj ), obj );
  1088. }
  1089. }
  1090. void Sound_Create_Enemy_Seen(GameObject * obj)
  1091. {
  1092. if (combatspeech == false )
  1093. {
  1094. combatspeech = true;
  1095. Commands->Start_Timer( obj, 4.0f, TIMER_COMBAT_SPEECH );
  1096. float sound_random = Commands->Get_Random( 0.0f , 120.0f);
  1097. if ( sound_random <= 10.0 )
  1098. { speech_script = "ForKane01"; }
  1099. else if ( sound_random <= 20.0 )
  1100. { speech_script = "GetHim01"; }
  1101. else if ( sound_random <= 30.0 )
  1102. { speech_script = "Incoming01"; }
  1103. else if ( sound_random <= 40.0 )
  1104. { speech_script = "KillHim01"; }
  1105. else if ( sound_random <= 50.0 )
  1106. { speech_script = "SoundAlarm01"; }
  1107. else if ( sound_random <= 60.0 )
  1108. { speech_script = "ThereHeIs01"; }
  1109. else if ( sound_random <= 70.0 )
  1110. { speech_script = "ForKane02"; }
  1111. else if ( sound_random <= 80.0 )
  1112. { speech_script = "GetHim02"; }
  1113. else if ( sound_random <= 90.0 )
  1114. { speech_script = "Incoming02"; }
  1115. else if ( sound_random <= 100.0 )
  1116. { speech_script = "KillHim02"; }
  1117. else if ( sound_random <= 110.0 )
  1118. { speech_script = "SoundAlarm02"; }
  1119. else if ( sound_random <= 120.0 )
  1120. { speech_script = "ThereHeIs02"; }
  1121. Commands->Create_Sound( speech_script,Commands->Get_Position( obj ), obj );
  1122. }
  1123. }
  1124. void Sound_Create_Panic(GameObject * obj)
  1125. {
  1126. if (combatspeech == false )
  1127. {
  1128. combatspeech = true;
  1129. Commands->Start_Timer( obj, 4.0f, TIMER_COMBAT_SPEECH );
  1130. float sound_random = Commands->Get_Random( 0.0f , 20.0f);
  1131. if ( sound_random <= 10.0 )
  1132. { speech_script = "UhOh01"; }
  1133. else if ( sound_random <= 20.0 )
  1134. { speech_script = "WatchOut01"; }
  1135. else if ( sound_random <= 30.0 )
  1136. { speech_script = "UhOh02"; }
  1137. else if ( sound_random <= 40.0 )
  1138. { speech_script = "WatchOut02"; }
  1139. Commands->Create_Sound( speech_script,Commands->Get_Position( obj ), obj );
  1140. }
  1141. }
  1142. void Sound_Create_Search(GameObject * obj)
  1143. {
  1144. if (combatspeech == false )
  1145. {
  1146. combatspeech = true;
  1147. Commands->Start_Timer( obj, 4.0f, TIMER_COMBAT_SPEECH );
  1148. float taunt_random = Commands->Get_Random( 0.0f , 20.0f);
  1149. if ( taunt_random <= 10.0 )
  1150. { speech_script = "Q_Huh01"; }
  1151. else if ( taunt_random <= 20.0 )
  1152. { speech_script = "Q_WhatThat01"; }
  1153. else if ( taunt_random <= 30.0 )
  1154. { speech_script = "Q_Huh02"; }
  1155. else if ( taunt_random <= 40.0 )
  1156. { speech_script = "Q_WhatThat02"; }
  1157. Commands->Create_Sound( speech_script,Commands->Get_Position( obj ), obj );
  1158. }
  1159. }
  1160. void Sound_Create_Support(GameObject * obj )
  1161. {
  1162. if (combatspeech == false )
  1163. {
  1164. combatspeech = true;
  1165. Commands->Start_Timer( obj, 4.0f, TIMER_COMBAT_SPEECH );
  1166. float taunt_random = Commands->Get_Random( 0.0f , 20.0f);
  1167. if ( taunt_random <= 10.0 )
  1168. { speech_script = "GonnaDieHere01"; }
  1169. else if ( taunt_random <= 20.0 )
  1170. { speech_script = "Medic01"; }
  1171. else if ( taunt_random <= 30.0 )
  1172. { speech_script = "GonnaDieHere02"; }
  1173. else if ( taunt_random <= 40.0 )
  1174. { speech_script = "Medic02"; }
  1175. Commands->Create_Sound( speech_script,Commands->Get_Position( obj ), obj );
  1176. }
  1177. }
  1178. void State_Change_Critical( GameObject *obj )
  1179. {
  1180. state = STATE_CRITICAL;
  1181. Commands->Action_Movement_Stop( obj );
  1182. Commands->Action_Attack_Stop( obj );
  1183. Commands->Set_Animation( obj, NULL, 0);
  1184. Commands->Enable_Enemy_Seen( obj, false);
  1185. // Commands->Enable_Sound_Heard( Me, false);
  1186. }
  1187. void State_Change_Idle( GameObject * obj, Vector3 position )
  1188. {
  1189. state = STATE_IDLE_MOVEMENT;
  1190. Commands->Action_Attack_Stop( obj );
  1191. Commands->Action_Movement_Set_Crouch( obj, false);
  1192. Commands->Action_Movement_Set_Forward_Speed( obj, 0.1f);
  1193. Commands->Enable_Enemy_Seen( obj, true);
  1194. // Commands->Enable_Sound_Heard( Me, true);
  1195. Commands->Action_Movement_Goto_Location( obj, position , 1.0 );
  1196. }
  1197. };