LogisticsPilot.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. #define LOGISTICSPILOT_CPP
  2. //===========================================================================//
  3. // LogisticsPilot.cpp : Implementation of the LogisticsPilot component.//
  4. //---------------------------------------------------------------------------//
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. //===========================================================================//
  7. #include "McLib.h"
  8. #include "LogisticsPilot.h"
  9. #include "LogisticsErrors.h"
  10. #include "LogisticsData.h"
  11. #include "warrior.h"
  12. #include "..\resource.h"
  13. #include "MechIcon.h"
  14. #include "objmgr.h"
  15. char LogisticsPilot::skillTexts[NUM_SPECIALTY_SKILLS][255] = {0};
  16. extern char* SpecialtySkillsTable[NUM_SPECIALTY_SKILLS];
  17. LogisticsPilot::LogisticsPilot()
  18. {
  19. bIsUsed = 0;
  20. bJustDied = 0;
  21. mechKills = vehicleKills = infantryKills = 0;
  22. missionsCompleted = 0;
  23. memset(missionsPlayed,0,sizeof(unsigned char) * MAX_MISSIONS);
  24. bDead = 0;
  25. bAvailable = 0;
  26. newPiloting = 0;
  27. newGunnery = 0;
  28. memset( specialtySkills, 0, sizeof( bool ) * NUM_SPECIALTY_SKILLS );
  29. if ( !strlen( skillTexts[0] ) )
  30. {
  31. char tmp[256];
  32. for ( int i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  33. {
  34. cLoadString( IDS_SPECIALTY + i, tmp, 255 );
  35. strcpy( skillTexts[i], tmp );
  36. }
  37. }
  38. memset( medals, 0, sizeof( bool ) * MAX_MEDAL );
  39. }
  40. LogisticsPilot::~LogisticsPilot()
  41. {
  42. }
  43. int LogisticsPilot::init( char* pilotFileName )
  44. {
  45. fileName = pilotFileName;
  46. char path[256];
  47. strcpy( path, warriorPath );
  48. strcat( path, fileName );
  49. strcat( path, ".fit" );
  50. FitIniFile pilotFile;
  51. if ( NO_ERR != pilotFile.open( path ) )
  52. {
  53. char errorString[256];
  54. sprintf( errorString, "Couldn't open file %s", fileName);
  55. Assert( 0, 0, errorString );
  56. return -1;
  57. }
  58. // if we got this far we have a file, make a pilot
  59. int result = pilotFile.seekBlock( "General" );
  60. gosASSERT( result == 0 );
  61. long tmp;
  62. result = pilotFile.readIdLong( "descIndex", tmp );
  63. gosASSERT( result == NO_ERR );
  64. cLoadString( tmp, path, 256 );
  65. name = path;
  66. result = pilotFile.readIdLong("PictureIndex", photoIndex);
  67. if (result != NO_ERR)
  68. photoIndex = 0;
  69. result = pilotFile.readIdLong( "Rank", rank );
  70. gosASSERT( result == 0 );
  71. // result = pilotFile.readIdULong( "ID", id );
  72. // gosASSERT( result == 0 );
  73. result = pilotFile.readIdLong( "FlavorText", flavorTextID );
  74. result = pilotFile.readIdString( "pilotAudio", path, 256 );
  75. gosASSERT( result == 0 );
  76. audio = path;
  77. result = pilotFile.readIdString( "pilotVideo", path, 256 );
  78. gosASSERT( result == 0 );
  79. video = path;
  80. result = pilotFile.readIdString( "Picture", path, 256 );
  81. iconFile = artPath;
  82. iconFile += path;
  83. pilotFile.seekBlock( "Skills" );
  84. char tPilot, tGunnery;
  85. result = pilotFile.readIdChar( "Piloting", tPilot );
  86. gosASSERT( result == NO_ERR );
  87. pilotFile.readIdChar( "Gunnery", tGunnery );
  88. piloting = tPilot;
  89. gunnery = tGunnery;
  90. result = pilotFile.seekBlock("SpecialtySkills");
  91. if (result == NO_ERR)
  92. {
  93. for (int i = 0; i < NUM_SPECIALTY_SKILLS; i++)
  94. {
  95. char tmpChar;
  96. result = pilotFile.readIdChar(SpecialtySkillsTable[i], tmpChar);
  97. if (result == NO_ERR)
  98. specialtySkills[i] = (tmpChar == 1);
  99. }
  100. }
  101. rank = turnAverageIntoRank( (gunnery + piloting)/2.f );
  102. return 0;
  103. }
  104. const char* LogisticsPilot::getSkillText( int skillID )
  105. {
  106. gosASSERT( skillID <= NUM_SKILLS );
  107. if ( skillTexts[skillID] )
  108. {
  109. return skillTexts[skillID];
  110. }
  111. // char tmp[256];
  112. // cLoadString( IDS_SKILL0 + skillID, tmp, 256 );
  113. // skillTexts[skillID] = tmp;
  114. return skillTexts[skillID];
  115. }
  116. int LogisticsPilot::getNumberMissions() const
  117. {
  118. return missionsCompleted;
  119. }
  120. long LogisticsPilot::save( FitIniFile& file, long which )
  121. {
  122. char tmp[256];
  123. sprintf( tmp, "Pilot%ld", which );
  124. file.writeBlock( tmp );
  125. file.writeIdString( "FileName", fileName );
  126. file.writeIdLong( "Rank", rank );
  127. file.writeIdFloat( "Gunnery", gunnery );
  128. file.writeIdFloat( "Piloting", piloting );
  129. file.writeIdLong( "Kills", mechKills );
  130. file.writeIdLong( "VehicleKills", vehicleKills );
  131. file.writeIdLong( "InfantryKills", infantryKills );
  132. file.writeIdLong( "MissionsCompleted", missionsCompleted );
  133. file.writeIdUCharArray( "MissionsPlayed", missionsPlayed, MAX_MISSIONS);
  134. file.writeIdBoolean( "Dead", bDead );
  135. char buffer[64];
  136. for ( int i = 0; i < MAX_MEDAL; i++ )
  137. {
  138. sprintf( buffer, "Medal%ld", i );
  139. file.writeIdBoolean( buffer, medals[i] );
  140. }
  141. for ( i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  142. {
  143. sprintf( buffer, "SpecialtySkill%ld", i );
  144. file.writeIdBoolean( buffer, specialtySkills[i] );
  145. }
  146. return 0;
  147. }
  148. long LogisticsPilot::load( FitIniFile& file )
  149. {
  150. char tmp[256];
  151. file.readIdString( "FileName", tmp, 255 );
  152. fileName = tmp;
  153. file.readIdLong( "Rank", rank );
  154. file.readIdFloat( "Gunnery", gunnery );
  155. file.readIdFloat( "Piloting", piloting );
  156. file.readIdLong( "Kills", mechKills );
  157. file.readIdLong( "VehicleKills", vehicleKills );
  158. file.readIdLong( "InfantryKills", infantryKills );
  159. file.readIdLong( "MissionsCompleted", missionsCompleted );
  160. long result = file.readIdUCharArray( "MissionsPlayed", missionsPlayed, MAX_MISSIONS);
  161. if (result != NO_ERR)
  162. memset(missionsPlayed,0,sizeof(unsigned char) * MAX_MISSIONS);
  163. file.readIdBoolean( "Dead", bDead );
  164. char buffer[64];
  165. for ( int i = 0; i < MAX_MEDAL; i++ )
  166. {
  167. sprintf( buffer, "Medal%ld", i );
  168. file.readIdBoolean( buffer, medals[i] );
  169. }
  170. for ( i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  171. {
  172. sprintf( buffer, "SpecialtySkill%ld", i );
  173. file.readIdBoolean( buffer, specialtySkills[i] );
  174. }
  175. rank = turnAverageIntoRank((gunnery + piloting)/2.f);
  176. return 0;
  177. }
  178. void LogisticsPilot::clearIcons()
  179. {
  180. // clear out the old ones
  181. for ( EList<ForceGroupIcon*, ForceGroupIcon*>::EIterator iter =
  182. killedIcons.Begin(); !iter.IsDone(); iter++ )
  183. {
  184. delete (*iter);
  185. }
  186. killedIcons.Clear();
  187. }
  188. long LogisticsPilot::update( MechWarrior* pWarrior )
  189. {
  190. #ifndef VIEWER
  191. // clear out the old ones
  192. for ( EList<ForceGroupIcon*, ForceGroupIcon*>::EIterator iter =
  193. killedIcons.Begin(); !iter.IsDone(); iter++ )
  194. {
  195. delete (*iter);
  196. }
  197. killedIcons.Clear();
  198. missionsCompleted++;
  199. long missionJustPlayed = LogisticsData::instance->getCurrentMissionId();
  200. if ((missionJustPlayed < 0) || (missionJustPlayed > MAX_MISSIONS))
  201. STOP(("Logistics thinks last mission played was %d",missionJustPlayed));
  202. missionsPlayed[missionJustPlayed] = 1;
  203. if ( pWarrior->getStatus() == WARRIOR_STATUS_DEAD )
  204. {
  205. bDead = true;
  206. bJustDied = true;
  207. }
  208. setUsed( 1 );
  209. pWarrior->updateMissionSkills();
  210. newGunnery = pWarrior->skillRank[MWS_GUNNERY] - gunnery;
  211. newPiloting = pWarrior->skillRank[MWS_PILOTING] - piloting;
  212. gunnery = pWarrior->skillRank[MWS_GUNNERY];
  213. piloting = pWarrior->skillRank[MWS_PILOTING];
  214. // make sure no more than 4 points per mission
  215. if ( newGunnery > 4.f)
  216. {
  217. gunnery -= newGunnery;
  218. newGunnery = 4.f;
  219. gunnery += newGunnery;
  220. }
  221. if ( newPiloting > 4.f )
  222. {
  223. piloting -= newPiloting;
  224. newPiloting = 4.f;
  225. piloting += newPiloting;
  226. }
  227. infantryKills += pWarrior->numMechKills[VEHICLE_CLASS_ELEMENTAL][COMBAT_STAT_MISSION];
  228. mechKills += pWarrior->numMechKills[VEHICLE_CLASS_LIGHTMECH][COMBAT_STAT_MISSION];
  229. mechKills += pWarrior->numMechKills[VEHICLE_CLASS_MEDIUMMECH][COMBAT_STAT_MISSION];
  230. mechKills += pWarrior->numMechKills[VEHICLE_CLASS_HEAVYMECH][COMBAT_STAT_MISSION];
  231. mechKills += pWarrior->numMechKills[VEHICLE_CLASS_ASSAULTMECH][COMBAT_STAT_MISSION];
  232. vehicleKills += pWarrior->numMechKills[VEHICLE_CLASS_GROUND][COMBAT_STAT_MISSION];
  233. rank = pWarrior->getRank();
  234. long deadMechCount = 0;
  235. for ( int i = 0; i < pWarrior->numKilled; i++ )
  236. {
  237. GameObject* pDead = ObjectManager->getByWatchID(pWarrior->killed[i]);
  238. if ( pDead->getObjectClass() == BATTLEMECH )
  239. {
  240. MechIcon* pIcon = new MechIcon();
  241. pIcon->swapResolutions(0);
  242. killedIcons.Append( pIcon );
  243. pIcon->init( (Mover*)pDead );
  244. pIcon->update();
  245. if (((MoverPtr)pDead)->getMoveType() != MOVETYPE_AIR)
  246. deadMechCount++;
  247. }
  248. else if ( pDead->getObjectClass() == GROUNDVEHICLE )
  249. {
  250. VehicleIcon* pIcon = new VehicleIcon();
  251. pIcon->swapResolutions(0);
  252. killedIcons.Append( pIcon );
  253. pIcon->init( (Mover*)pDead );
  254. pIcon->update();
  255. }
  256. }
  257. memset( medalsLastMission, 0, sizeof( bool ) * MAX_MEDAL );
  258. if ( deadMechCount >= 7 )
  259. {
  260. medalsLastMission[UNCOMMON_VALOR] = true;
  261. medals[UNCOMMON_VALOR] = true;
  262. }
  263. if ( (deadMechCount >= 3) && (deadMechCount < 7) )
  264. {
  265. medalsLastMission[VALOR] = true;
  266. medals[VALOR] = true;
  267. }
  268. if ( pWarrior->getWounds() )
  269. {
  270. if ( !medals[PURPLE_HEART] )
  271. medalsLastMission[PURPLE_HEART] = true;
  272. medals[PURPLE_HEART] = true;
  273. }
  274. //Check for the campaign ribbons and medals.
  275. // NOTE: NONE of these should be awarded UNLESS we are playing the shipping campaign.
  276. long anySteinerPlayed = missionsPlayed[0] +
  277. missionsPlayed[1] +
  278. missionsPlayed[2] +
  279. missionsPlayed[3] +
  280. missionsPlayed[4] +
  281. missionsPlayed[5] +
  282. missionsPlayed[6] +
  283. missionsPlayed[7] +
  284. missionsPlayed[8];
  285. long anyLiaoPlayed = missionsPlayed[9] +
  286. missionsPlayed[10] +
  287. missionsPlayed[11] +
  288. missionsPlayed[12] +
  289. missionsPlayed[13] +
  290. missionsPlayed[14] +
  291. missionsPlayed[15] +
  292. missionsPlayed[16];
  293. long anyDavionPlayed = missionsPlayed[17] +
  294. missionsPlayed[18] +
  295. missionsPlayed[19] +
  296. missionsPlayed[20] +
  297. missionsPlayed[21] +
  298. missionsPlayed[22] +
  299. missionsPlayed[23];
  300. bool allSteinerPlayed = (anySteinerPlayed == 9);
  301. bool allLiaoPlayed = (anyLiaoPlayed == 8);
  302. bool allDavionPlayed = (anyDavionPlayed == 7);
  303. if (anySteinerPlayed)
  304. {
  305. if (!medals[CAMPAIGN_RIBBON1])
  306. medalsLastMission[CAMPAIGN_RIBBON1] = true;
  307. medals[CAMPAIGN_RIBBON1] = true;
  308. }
  309. if (anyLiaoPlayed)
  310. {
  311. if (!medals[CAMPAIGN_RIBBON2])
  312. medalsLastMission[CAMPAIGN_RIBBON2] = true;
  313. medals[CAMPAIGN_RIBBON2] = true;
  314. }
  315. if (anyDavionPlayed)
  316. {
  317. if (!medals[CAMPAIGN_RIBBON3])
  318. medalsLastMission[CAMPAIGN_RIBBON3] = true;
  319. medals[CAMPAIGN_RIBBON3] = true;
  320. }
  321. if (allSteinerPlayed)
  322. {
  323. if (!medals[CAMPAIGN_FULLRIBBON1])
  324. medalsLastMission[CAMPAIGN_FULLRIBBON1] = true;
  325. medals[CAMPAIGN_FULLRIBBON1] = true;
  326. }
  327. if (allLiaoPlayed)
  328. {
  329. if (!medals[CAMPAIGN_FULLRIBBON2])
  330. medalsLastMission[CAMPAIGN_FULLRIBBON2] = true;
  331. medals[CAMPAIGN_FULLRIBBON2] = true;
  332. }
  333. if (allDavionPlayed)
  334. {
  335. if (!medals[CAMPAIGN_FULLRIBBON3])
  336. medalsLastMission[CAMPAIGN_FULLRIBBON3] = true;
  337. medals[CAMPAIGN_FULLRIBBON3] = true;
  338. }
  339. if (missionsPlayed[8])
  340. {
  341. if (!medals[STEINER_MEDAL])
  342. medalsLastMission[STEINER_MEDAL] = true;
  343. medals[STEINER_MEDAL] = true;
  344. }
  345. if (missionsPlayed[12])
  346. {
  347. if (!medals[LIAO_MEDAL])
  348. medalsLastMission[LIAO_MEDAL] = true;
  349. medals[LIAO_MEDAL] = true;
  350. }
  351. if (missionsPlayed[21])
  352. {
  353. if (!medals[DAVION_MEDAL])
  354. medalsLastMission[DAVION_MEDAL] = true;
  355. medals[DAVION_MEDAL] = true;
  356. }
  357. for ( i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  358. {
  359. if ( pWarrior->specialtySkills[i] )
  360. {
  361. specialtySkills[i] = true;
  362. }
  363. }
  364. #endif
  365. return 0;
  366. }
  367. bool LogisticsPilot::promotePilot()
  368. {
  369. float oldGunnery = gunnery - newGunnery;
  370. float oldPiloting = piloting - newPiloting;
  371. float oldAvg = (oldGunnery + oldPiloting)/2.f;
  372. float newAvg = (gunnery + piloting)/2.f;
  373. int oldRank = turnAverageIntoRank( oldAvg );
  374. int newRank = turnAverageIntoRank( newAvg );
  375. if ( rank != newRank )
  376. {
  377. // go ahead and set that rank
  378. rank = newRank;
  379. }
  380. if ( oldRank != newRank )
  381. {
  382. gosASSERT( newRank > oldRank ); // bad to demote
  383. if ( rank > WARRIOR_RANK_GREEN )
  384. return true;
  385. return false;
  386. }
  387. // temporary for testing change to false
  388. return false;
  389. }
  390. int LogisticsPilot::turnAverageIntoRank( float avg)
  391. {
  392. if ( avg > 79 )
  393. return WARRIOR_RANK_ACE;
  394. else if ( avg > 70 )
  395. return WARRIOR_RANK_ELITE;
  396. else if ( avg > 60 )
  397. return WARRIOR_RANK_VETERAN;
  398. else if ( avg > 50 )
  399. return WARRIOR_RANK_REGULAR;
  400. return WARRIOR_RANK_GREEN;
  401. }
  402. int LogisticsPilot::getSpecialtySkillCount() const
  403. {
  404. int count = 0;
  405. for ( int i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  406. {
  407. if ( specialtySkills[i] )
  408. count++;
  409. }
  410. return count;
  411. }
  412. int LogisticsPilot::getSpecialtySkills( const char** array, int& count )
  413. {
  414. int max = count;
  415. count = 0;
  416. for ( int i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  417. {
  418. if ( count >= max )
  419. {
  420. return NEED_BIGGER_ARRAY;
  421. }
  422. if ( specialtySkills[i] )
  423. {
  424. array[count] = skillTexts[i];
  425. count++;
  426. }
  427. }
  428. return 0;
  429. }
  430. int LogisticsPilot::getSpecialtySkills( int* array, int& count )
  431. {
  432. int max = count;
  433. count = 0;
  434. for ( int i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  435. {
  436. if ( i >= max )
  437. {
  438. return NEED_BIGGER_ARRAY;
  439. }
  440. if ( specialtySkills[i] )
  441. {
  442. array[count] = i;
  443. count++;
  444. }
  445. }
  446. return 0;
  447. }
  448. void LogisticsPilot::setSpecialtySkill( int skill, bool set )
  449. {
  450. if ( skill >= NUM_SPECIALTY_SKILLS )
  451. {
  452. gosASSERT( 0 );
  453. return;
  454. }
  455. specialtySkills[skill] = set;
  456. }
  457. //*************************************************************************************************
  458. // end of file ( LogisticsPilot.cpp )