objectives.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  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/Combat/objectives.cpp $*
  25. * *
  26. * $Author:: Patrick $*
  27. * *
  28. * $Modtime:: 1/24/02 5:10p $*
  29. * *
  30. * $Revision:: 38 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "objectives.h"
  36. #include "gameobjref.h"
  37. #include "debug.h"
  38. #include "radar.h"
  39. #include "scriptablegameobj.h"
  40. #include "translatedb.h"
  41. #include "combat.h"
  42. #include "messagewindow.h"
  43. #include "globalsettings.h"
  44. #include "physicalgameobj.h"
  45. #include "diaglog.h"
  46. #include "wwaudio.h"
  47. #include "hud.h"
  48. #include "string_ids.h"
  49. /*
  50. ** Static member initialization
  51. */
  52. SimpleDynVecClass<Objective*> ObjectiveManager::ObjectiveList;
  53. ObjectivesViewerClass ObjectiveManager::Viewer;
  54. bool ObjectiveManager::DebugMode = false;
  55. bool ObjectiveManager::HUDUpdate = true;
  56. int ObjectiveManager::NumSpecifiedTertiaryObjectives;
  57. /*
  58. **
  59. */
  60. const Vector3 & Objective::Type_To_Base_Color( void )
  61. {
  62. static Vector3 color (1.0F, 1.0F, 1.0F);
  63. if ( HUDGlobalSettingsDef::Get_Instance() != NULL ) {
  64. switch ( Type ) {
  65. case ObjectiveManager::TYPE_PRIMARY:
  66. color = HUDGlobalSettingsDef::Get_Instance()->Get_Primary_Objective_Color();
  67. break;
  68. case ObjectiveManager::TYPE_SECONDARY:
  69. color = HUDGlobalSettingsDef::Get_Instance()->Get_Secondary_Objective_Color();
  70. break;
  71. case ObjectiveManager::TYPE_TERTIARY:
  72. color = HUDGlobalSettingsDef::Get_Instance()->Get_Tertiary_Objective_Color();
  73. break;
  74. }
  75. }
  76. return color;
  77. }
  78. /*
  79. **
  80. */
  81. const Vector3 & Objective::Type_To_Color( void )
  82. {
  83. static Vector3 color (1.0F, 1.0F, 1.0F);
  84. color = Type_To_Base_Color ();
  85. //
  86. // Dim the colors if this objective has been accomplished
  87. //
  88. if( Status == ObjectiveManager::STATUS_ACCOMPLISHED ) {
  89. color *= 0.6F;
  90. }
  91. return color;
  92. }
  93. const WCHAR * Objective::Type_To_Name( void )
  94. {
  95. switch ( Type ) {
  96. case ObjectiveManager::TYPE_PRIMARY: return TRANSLATE (IDS_MENU_TEXT145);
  97. case ObjectiveManager::TYPE_SECONDARY: return TRANSLATE (IDS_MENU_TEXT113);
  98. case ObjectiveManager::TYPE_TERTIARY: return TRANSLATE (IDS_MENU_TERTIARY);
  99. default: return TRANSLATE (IDS_LOCALE_UNKNOWN);
  100. }
  101. }
  102. const WCHAR * Objective::Status_To_Name( void )
  103. {
  104. if ( Status == ObjectiveManager::STATUS_ACCOMPLISHED ) return TRANSLATE (IDS_MENU_OBJ_ACCOMPLISHED);
  105. if ( Status == ObjectiveManager::STATUS_FAILED ) return TRANSLATE (IDS_MENU_OBJ_FAILED);
  106. if ( Status == ObjectiveManager::STATUS_HIDDEN ) return TRANSLATE (IDS_MENU_OBJ_HIDDEN);
  107. return TRANSLATE (IDS_MENU_OBJ_PENDING);
  108. }
  109. const Vector3 & Objective::Status_To_Color( void )
  110. {
  111. static const Vector3 RED(1,0,0);
  112. static const Vector3 GREEN(0,1,0);
  113. static const Vector3 YELLOW(1,1,0);
  114. static const Vector3 GREY(0.8F,0.8F,0.8F);
  115. switch ( Status ) {
  116. case ObjectiveManager::STATUS_IS_PENDING: return GREEN;
  117. case ObjectiveManager::STATUS_ACCOMPLISHED: return YELLOW;
  118. case ObjectiveManager::STATUS_FAILED: return RED;
  119. case ObjectiveManager::STATUS_HIDDEN: return GREY;
  120. default: return GREEN;
  121. }
  122. }
  123. Objective::Objective( void ) :
  124. ID( 0 ),
  125. Type( 0 ),
  126. Status( 0 ),
  127. DrawBlip( false ),
  128. Position( 0,0,0 ),
  129. BlipIntensity( 0 ),
  130. HUDMessageStringID( 0 ),
  131. LongDescriptionID( 0 ),
  132. ShortDescriptionID( 0 ),
  133. HUDPriority( 0 ),
  134. Age( 0 )
  135. {
  136. }
  137. Objective::~Objective( void )
  138. {
  139. Set_Object( NULL );
  140. }
  141. int Objective::Radar_Blip_Color_Type( void )
  142. {
  143. return Type - ObjectiveManager::TYPE_PRIMARY + RadarManager::BLIP_COLOR_TYPE_PRIMARY_OBJECTIVE;
  144. }
  145. void Objective::Set_Object( PhysicalGameObj * object )
  146. {
  147. PhysicalGameObj * obj = (PhysicalGameObj*)Object.Get_Ptr();
  148. if ( obj != NULL ) {
  149. obj->Reset_Radar_Blip_Shape_Type();
  150. obj->Reset_Radar_Blip_Color_Type();
  151. }
  152. Object = object;
  153. Update_Object_Blip();
  154. }
  155. void Objective::Update_Object_Blip( void )
  156. {
  157. PhysicalGameObj * obj = (PhysicalGameObj*)Object.Get_Ptr();
  158. if ( obj != NULL ) {
  159. if ( Status == ObjectiveManager::STATUS_IS_PENDING ) {
  160. obj->Set_Radar_Blip_Shape_Type( RadarManager::BLIP_SHAPE_TYPE_OBJECTIVE );
  161. obj->Set_Radar_Blip_Color_Type( Radar_Blip_Color_Type() );
  162. } else {
  163. obj->Reset_Radar_Blip_Shape_Type();
  164. obj->Reset_Radar_Blip_Color_Type();
  165. }
  166. }
  167. }
  168. Vector3 Objective::Get_Position( void )
  169. {
  170. if ( Object.Get_Ptr() != NULL ) {
  171. Vector3 pos;
  172. Object.Get_Ptr()->Get_Position( &pos );
  173. return pos;
  174. }
  175. return Position;
  176. }
  177. /*
  178. **
  179. */
  180. enum {
  181. CHUNKID_VARIABLES = 629001440,
  182. CHUNKID_OBJECT,
  183. MICROCHUNKID_ID = 1,
  184. MICROCHUNKID_TYPE,
  185. MICROCHUNKID_STATUS,
  186. MICROCHUNKID_DESCRIPTION,
  187. MICROCHUNKID_DESCRIPTION_SOUND,
  188. XXXMICROCHUNKID_RADAR_MARKER_ID,
  189. MICROCHUNKID_DESCRIPTION_ID,
  190. MICROCHUNKID_DRAW_BLIP,
  191. MICROCHUNKID_POSITION,
  192. MICROCHUNKID_LONG_DESCRIPTION_ID,
  193. MICROCHUNKID_AGE,
  194. MICROCHUNKID_HUD_POG_TEXTURE_NAME,
  195. MICROCHUNKID_HUD_MESSAGE_STRING_ID,
  196. MICROCHUNKID_HUD_PRIORITY,
  197. MICROCHUNKID_HUD_AGE,
  198. };
  199. bool Objective::Save( ChunkSaveClass & csave )
  200. {
  201. csave.Begin_Chunk( CHUNKID_VARIABLES );
  202. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ID, ID );
  203. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TYPE, Type );
  204. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STATUS, Status );
  205. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DESCRIPTION_ID, ShortDescriptionID );
  206. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_LONG_DESCRIPTION_ID, LongDescriptionID );
  207. WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_DESCRIPTION_SOUND, DescriptionSoundFilename );
  208. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DRAW_BLIP, DrawBlip );
  209. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_POSITION, Position );
  210. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_AGE, Age );
  211. WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_HUD_POG_TEXTURE_NAME, HUDPogTextureName );
  212. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_HUD_MESSAGE_STRING_ID, HUDMessageStringID );
  213. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_HUD_PRIORITY, HUDPriority );
  214. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_HUD_AGE, Age );
  215. csave.End_Chunk();
  216. if ( Object.Get_Ptr() != NULL ) {
  217. csave.Begin_Chunk( CHUNKID_OBJECT );
  218. Object.Save( csave );
  219. csave.End_Chunk();
  220. }
  221. return true;
  222. }
  223. bool Objective::Load( ChunkLoadClass &cload )
  224. {
  225. while (cload.Open_Chunk()) {
  226. switch(cload.Cur_Chunk_ID()) {
  227. case CHUNKID_VARIABLES:
  228. while (cload.Open_Micro_Chunk()) {
  229. switch(cload.Cur_Micro_Chunk_ID()) {
  230. READ_MICRO_CHUNK( cload, MICROCHUNKID_ID, ID );
  231. READ_MICRO_CHUNK( cload, MICROCHUNKID_TYPE, Type );
  232. READ_MICRO_CHUNK( cload, MICROCHUNKID_STATUS, Status );
  233. READ_MICRO_CHUNK( cload, MICROCHUNKID_DESCRIPTION_ID, ShortDescriptionID );
  234. READ_MICRO_CHUNK( cload, MICROCHUNKID_LONG_DESCRIPTION_ID, LongDescriptionID );
  235. READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_DESCRIPTION_SOUND, DescriptionSoundFilename );
  236. READ_MICRO_CHUNK( cload, MICROCHUNKID_DRAW_BLIP, DrawBlip );
  237. READ_MICRO_CHUNK( cload, MICROCHUNKID_POSITION, Position );
  238. READ_MICRO_CHUNK( cload, MICROCHUNKID_AGE, Age );
  239. READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_HUD_POG_TEXTURE_NAME, HUDPogTextureName );
  240. READ_MICRO_CHUNK( cload, MICROCHUNKID_HUD_MESSAGE_STRING_ID, HUDMessageStringID );
  241. READ_MICRO_CHUNK( cload, MICROCHUNKID_HUD_PRIORITY, HUDPriority );
  242. READ_MICRO_CHUNK( cload, MICROCHUNKID_HUD_AGE, Age );
  243. default:
  244. Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  245. break;
  246. }
  247. cload.Close_Micro_Chunk();
  248. }
  249. break;
  250. case CHUNKID_OBJECT:
  251. Object.Load( cload );
  252. break;
  253. default:
  254. Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  255. break;
  256. }
  257. cload.Close_Chunk();
  258. }
  259. return true;
  260. }
  261. /*
  262. **
  263. */
  264. Objective * ObjectiveManager::Add_Loadable_Objective( void )
  265. {
  266. Objective * objective = new Objective();
  267. ObjectiveList.Add( objective );
  268. return objective;
  269. }
  270. Objective * ObjectiveManager::Find_Objective( int id )
  271. {
  272. for ( int i = 0; i < ObjectiveList.Count(); i++ ) {
  273. if ( ObjectiveList[i]->ID == id ) {
  274. return ObjectiveList[i];
  275. }
  276. }
  277. return NULL;
  278. }
  279. /*
  280. **
  281. */
  282. void ObjectiveManager::Init( void )
  283. {
  284. Viewer.Initialize();
  285. HUDUpdate = true;
  286. NumSpecifiedTertiaryObjectives = 0;
  287. }
  288. void ObjectiveManager::Shutdown( void )
  289. {
  290. Viewer.Shutdown();
  291. Reset();
  292. }
  293. void ObjectiveManager::Reset( void )
  294. {
  295. HUDUpdate = true;
  296. while ( ObjectiveList.Count() != 0 ) {
  297. Objective * objective = ObjectiveList[0];
  298. ObjectiveList.Delete( 0 );
  299. delete objective;
  300. }
  301. }
  302. /*
  303. **
  304. */
  305. enum {
  306. CHUNKID_OBJECTIVE_ENTRY = 629001432,
  307. CHUNKID_MANAGER_VARIABLES,
  308. MICROCHUNKID_NUM_SPECIFIED_TERTIARY_OBJECTIVES = 1,
  309. };
  310. /*
  311. **
  312. */
  313. bool ObjectiveManager::Save( ChunkSaveClass &csave )
  314. {
  315. for ( int i = 0; i < ObjectiveList.Count(); i++ ) {
  316. csave.Begin_Chunk( CHUNKID_OBJECTIVE_ENTRY );
  317. ObjectiveList[i]->Save( csave );
  318. csave.End_Chunk();
  319. }
  320. csave.Begin_Chunk( CHUNKID_MANAGER_VARIABLES );
  321. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_NUM_SPECIFIED_TERTIARY_OBJECTIVES, NumSpecifiedTertiaryObjectives );
  322. csave.End_Chunk();
  323. return true;
  324. }
  325. bool ObjectiveManager::Load( ChunkLoadClass &cload )
  326. {
  327. WWASSERT( ObjectiveList.Count() == 0 );
  328. while (cload.Open_Chunk()) {
  329. switch(cload.Cur_Chunk_ID()) {
  330. case CHUNKID_MANAGER_VARIABLES:
  331. while (cload.Open_Micro_Chunk()) {
  332. switch(cload.Cur_Micro_Chunk_ID()) {
  333. READ_MICRO_CHUNK( cload, MICROCHUNKID_NUM_SPECIFIED_TERTIARY_OBJECTIVES, NumSpecifiedTertiaryObjectives );
  334. default:
  335. Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  336. break;
  337. }
  338. cload.Close_Micro_Chunk();
  339. }
  340. break;
  341. case CHUNKID_OBJECTIVE_ENTRY:
  342. {
  343. Objective * objective = Add_Loadable_Objective();
  344. objective->Load( cload );
  345. break;
  346. }
  347. default:
  348. Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  349. break;
  350. }
  351. cload.Close_Chunk();
  352. }
  353. Viewer.Update ();
  354. HUDUpdate = true;
  355. return true;
  356. }
  357. /*
  358. **
  359. */
  360. void ObjectiveManager::Add_Objective( int id, int type, int status, int short_description_id, int long_description_id, char * description_sound_filename )
  361. {
  362. if ( Find_Objective( id ) != NULL ) {
  363. Debug_Say(( "Adding a duplicate Objective ID\n" ));
  364. return;
  365. }
  366. Objective * objective = Add_Loadable_Objective();
  367. objective->ID = id;
  368. objective->Type = type;
  369. objective->Status = status;
  370. objective->ShortDescriptionID = short_description_id;
  371. objective->LongDescriptionID = long_description_id;
  372. objective->DescriptionSoundFilename = description_sound_filename;
  373. #if 01
  374. //
  375. // Update our EVA message window
  376. //
  377. if ( status != ObjectiveManager::STATUS_HIDDEN ) {
  378. WideStringClass message;
  379. WideStringClass description = TranslateDBClass::Get_String( short_description_id );
  380. message.Format( TRANSLATE (IDS_OBJ_NEW_OBJ), objective->Type_To_Name(), description );
  381. CombatManager::Get_Message_Window ()->Add_Message (message, objective->Type_To_Base_Color());
  382. HUDClass::Add_Objective( type );
  383. }
  384. const char * preset_name = NULL;
  385. switch ( type ) {
  386. case ObjectiveManager::TYPE_PRIMARY: preset_name = "EVA_Primary_Add"; break;
  387. case ObjectiveManager::TYPE_SECONDARY: preset_name = "EVA_Secondary_Add"; break;
  388. }
  389. if ( preset_name ) {
  390. // WWAudioClass::Get_Instance()->Create_Instant_Sound( preset_name, Matrix3D(1) );
  391. }
  392. #endif
  393. Viewer.Update ();
  394. HUDUpdate = true;
  395. return ;
  396. }
  397. void ObjectiveManager::Remove_Objective( int id )
  398. {
  399. Objective * objective = Find_Objective( id );
  400. if ( objective != NULL ) {
  401. #if 01
  402. WideStringClass message;
  403. message.Format( TRANSLATE (IDS_OBJ_CANCELLED), objective->Type_To_Name () );
  404. CombatManager::Get_Message_Window ()->Add_Message( message, objective->Type_To_Base_Color() );
  405. // WWAudioClass::Get_Instance()->Create_Instant_Sound( "EVA_Complete", Matrix3D(1) );
  406. #endif
  407. ObjectiveList.Delete( objective );
  408. delete objective;
  409. } else {
  410. Debug_Say(( "Objective not found to delete\n" ));
  411. }
  412. Viewer.Update ();
  413. HUDUpdate = true;
  414. return ;
  415. }
  416. void ObjectiveManager::Set_Objective_Status( int id, int status )
  417. {
  418. Objective * objective = Find_Objective( id );
  419. if ( objective != NULL ) {
  420. bool is_unhiding = (objective->Status == ObjectiveManager::STATUS_HIDDEN) &&
  421. (status != ObjectiveManager::STATUS_HIDDEN);
  422. objective->Status = status;
  423. if ( status == STATUS_FAILED ) {
  424. DIAG_LOG(( "OBFA", "%d; %s", id, objective->Status_To_Name() ));
  425. }
  426. if ( status == STATUS_ACCOMPLISHED ) {
  427. DIAG_LOG(( "OBCO", "%d; %s", id, objective->Status_To_Name() ));
  428. }
  429. objective->Update_Object_Blip();
  430. if ( is_unhiding ) {
  431. objective->Age = 0; // Reset age
  432. }
  433. #if 01
  434. //
  435. // Special case changing an objective from hidden to pending... (Note: for
  436. // a completed objective, we display the normal message even if it was hidden).
  437. //
  438. WideStringClass message;
  439. if (is_unhiding && (status != ObjectiveManager::STATUS_ACCOMPLISHED)) {
  440. WideStringClass description = TranslateDBClass::Get_String( objective->ShortDescriptionID );
  441. message.Format( TRANSLATE (IDS_OBJ_NEW_OBJ), objective->Type_To_Name(), description );
  442. HUDClass::Add_Objective( objective->Type );
  443. } else {
  444. if ( objective->Status != ObjectiveManager::STATUS_HIDDEN ) {
  445. message.Format( TRANSLATE (IDS_OBJ_STATUS_CHANGED), objective->Type_To_Name(), objective->Status_To_Name() );
  446. }
  447. }
  448. CombatManager::Get_Message_Window ()->Add_Message( message, objective->Type_To_Base_Color() );
  449. #endif
  450. } else {
  451. Debug_Say(( "Objective not found to set status\n" ));
  452. }
  453. Sort_Objectives();
  454. Viewer.Update ();
  455. HUDUpdate = true;
  456. return ;
  457. }
  458. void ObjectiveManager::Change_Objective_Type( int id, int type )
  459. {
  460. Objective * objective = Find_Objective( id );
  461. if ( objective != NULL ) {
  462. objective->Type = type;
  463. objective->Update_Object_Blip();
  464. //DebugManager::Display_Text( "Mission objective priority changed\n", objective->Type_To_Color () );
  465. } else {
  466. Debug_Say(( "Objective not found to change type\n" ));
  467. }
  468. Viewer.Update ();
  469. HUDUpdate = true;
  470. return ;
  471. }
  472. void ObjectiveManager::Set_Objective_Radar_Blip( int id, Vector3 position )
  473. {
  474. Objective * objective = Find_Objective( id );
  475. if ( objective != NULL ) {
  476. objective->Set_Object( NULL );
  477. objective->Position = position;
  478. objective->DrawBlip = true;
  479. } else {
  480. Debug_Say(( "Objective not found to set_radar_blip\n" ));
  481. }
  482. }
  483. void ObjectiveManager::Set_Objective_Radar_Blip( int id, PhysicalGameObj * object )
  484. {
  485. Objective * objective = Find_Objective( id );
  486. if ( objective != NULL ) {
  487. objective->Set_Object( object );
  488. } else {
  489. Debug_Say(( "Objective not found to set_radar_blip\n" ));
  490. }
  491. }
  492. ////////////////////////////////////////////////////////////////
  493. //
  494. // fnCompareObjectivesCallback
  495. //
  496. ////////////////////////////////////////////////////////////////
  497. int __cdecl ObjectiveManager::ObjectiveSortCallback( const void *elem1, const void *elem2 )
  498. {
  499. WWASSERT (elem1 != NULL);
  500. WWASSERT (elem2 != NULL);
  501. Objective *objective1 = *((Objective **)elem1);
  502. Objective *objective2 = *((Objective **)elem2);
  503. // Sort first on status, low first
  504. if (objective1->Status < objective2->Status) {
  505. return -1;
  506. }
  507. if (objective1->Status > objective2->Status) {
  508. return 1;
  509. }
  510. // Sort Next on Priority, high first
  511. if (objective1->HUDPriority > objective2->HUDPriority) {
  512. return -1;
  513. }
  514. if (objective1->HUDPriority < objective2->HUDPriority) {
  515. return 1;
  516. }
  517. return 0;
  518. }
  519. void ObjectiveManager::Sort_Objectives( void )
  520. {
  521. // Assume the rest of the list is sorted
  522. // And bubble him to where he belongs
  523. if ( ObjectiveList.Count() != 0 ) {
  524. ::qsort (&ObjectiveList[0], ObjectiveList.Count(), sizeof(ObjectiveList[0]), ObjectiveSortCallback );
  525. }
  526. }
  527. void ObjectiveManager::Set_Objective_HUD_Info( int id, float priority, const char * texture_name, int message_id )
  528. {
  529. Objective * objective = Find_Objective( id );
  530. if ( objective != NULL ) {
  531. objective->HUDPriority = priority;
  532. objective->HUDPogTextureName = texture_name;
  533. objective->HUDMessageStringID = message_id;
  534. Sort_Objectives();
  535. HUDUpdate = true;
  536. } else {
  537. Debug_Say(( "Objective not found to Set_Objective_HUD_Info\n" ));
  538. }
  539. }
  540. void ObjectiveManager::Set_Objective_HUD_Info( int id, float priority, const char * texture_name, int message_id, const Vector3 & position )
  541. {
  542. Objective * objective = Find_Objective( id );
  543. if ( objective != NULL ) {
  544. objective->HUDPriority = priority;
  545. objective->HUDPogTextureName = texture_name;
  546. objective->HUDMessageStringID = message_id;
  547. objective->Position = position;
  548. Sort_Objectives();
  549. HUDUpdate = true;
  550. } else {
  551. Debug_Say(( "Objective not found to Set_Objective_HUD_Info\n" ));
  552. }
  553. }
  554. int ObjectiveManager::Get_Num_HUD_Objectives( void )
  555. {
  556. // Assume the pendings are first, in priority order
  557. int count = 0;
  558. for ( int i = 0; i < ObjectiveList.Count(); i++ ) {
  559. if ( ( ObjectiveList[i]->Status == STATUS_IS_PENDING ) &&
  560. ( ObjectiveList[i]->HUDPriority > 0 ) ) {
  561. count++;
  562. }
  563. }
  564. return count;
  565. }
  566. const char * ObjectiveManager::Get_HUD_Objectives_Pog_Texture_Name( int index )
  567. {
  568. return ObjectiveList[index]->HUDPogTextureName;
  569. }
  570. const WCHAR * ObjectiveManager::Get_HUD_Objectives_Message( int index )
  571. {
  572. return TranslateDBClass::Get_String( ObjectiveList[index]->HUDMessageStringID );
  573. }
  574. Vector3 ObjectiveManager::Get_HUD_Objectives_Location( int index )
  575. {
  576. return ObjectiveList[index]->Get_Position();
  577. }
  578. float ObjectiveManager::Get_HUD_Objectives_Age( int index )
  579. {
  580. return ObjectiveList[index]->Age;
  581. }
  582. int ObjectiveManager::Get_Num_Objectives( int type )
  583. {
  584. int count = 0;
  585. for ( int i = 0; i < ObjectiveList.Count(); i++ ) {
  586. if ( ( ObjectiveList[i]->Type == type ) &&
  587. ( ObjectiveList[i]->Status != STATUS_HIDDEN ) ) {
  588. count++;
  589. }
  590. }
  591. if ( type == TYPE_TERTIARY ) {
  592. if ( count < NumSpecifiedTertiaryObjectives ) {
  593. count = NumSpecifiedTertiaryObjectives;
  594. }
  595. }
  596. return count;
  597. }
  598. int ObjectiveManager::Get_Num_Completed_Objectives( int type )
  599. {
  600. int count = 0;
  601. for ( int i = 0; i < ObjectiveList.Count(); i++ ) {
  602. if ( ( ObjectiveList[i]->Type == type ) &&
  603. ( ObjectiveList[i]->Status == STATUS_ACCOMPLISHED ) ) {
  604. count++;
  605. }
  606. }
  607. return count;
  608. }
  609. void ObjectiveManager::Update( float dt )
  610. {
  611. for ( int i = 0; i < ObjectiveList.Count(); i++ ) {
  612. if ( ObjectiveList[i]->Status != STATUS_HIDDEN ) {
  613. ObjectiveList[i]->Age += dt;
  614. }
  615. }
  616. }