SalvageMechArea.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. #define SALVAGEMECHAREA_CPP
  2. /*************************************************************************************************\
  3. SalvageMechArea.cpp : Implementation of the SalvageMechArea component.
  4. //---------------------------------------------------------------------------//
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. //===========================================================================//
  7. \*************************************************************************************************/
  8. #include "SalvageMechArea.h"
  9. #include "IniFile.h"
  10. #include "objMgr.h"
  11. #include "Mech.h"
  12. #include "LogisticsVariant.h"
  13. #include "MechIcon.h"
  14. #include "LogisticsData.h"
  15. #include "..\resource.h"
  16. #include "gamesound.h"
  17. #include <malloc.h>
  18. aAnimButton* SalvageListItem::templateCheckButton = NULL;
  19. SalvageMechArea* SalvageMechArea::instance = NULL;
  20. aText* SalvageListItem::variantNameText = NULL;
  21. aText* SalvageListItem::mechNameText = NULL;
  22. aText* SalvageListItem::weightText = NULL;
  23. aText* SalvageListItem::costText = NULL;
  24. aObject* SalvageListItem::cBillsIcon = NULL;
  25. aObject* SalvageListItem::weightIcon = NULL;
  26. GUI_RECT SalvageListItem::iconRect;
  27. GUI_RECT SalvageListItem::rect;
  28. aAnimation* SalvageListItem::s_pressedAnim = NULL;
  29. aAnimation* SalvageListItem::s_highlightAnim = NULL;
  30. aAnimation* SalvageListItem::s_normalAnim = NULL;
  31. #define RP_TEXTID 3
  32. #define NAME_TEXTID 0
  33. #define WEIGHT_TEXTID 2
  34. #define ARMOR_TEXTID 3
  35. #define SPEED_TEXTID 4
  36. #define JUMP_TEXTID 5
  37. #define RANGE_TEXTID 6
  38. #define MECH_RECT 6
  39. #define CHECK_BUTTON 200
  40. SalvageMechScreen::SalvageMechScreen()
  41. {
  42. bDone = 0;
  43. // this MUST be initialized
  44. LogisticsData::instance->init();
  45. helpTextArrayID = 2;
  46. countDownTime = .5;
  47. curCount = 0.0;
  48. previousAmount = 0;
  49. oldCBillsAmount =0;
  50. salvageListBox.setSpaceBetweenItems( 5 );
  51. salvageListBox.setTopSkip( 2 );
  52. }
  53. SalvageMechScreen::~SalvageMechScreen()
  54. {
  55. delete SalvageListItem::s_pressedAnim;
  56. SalvageListItem::s_pressedAnim = NULL;
  57. delete SalvageListItem::s_highlightAnim;
  58. SalvageListItem::s_highlightAnim = NULL;
  59. delete SalvageListItem::s_normalAnim;
  60. SalvageListItem::s_normalAnim = NULL;
  61. delete SalvageListItem::templateCheckButton;
  62. SalvageListItem::templateCheckButton = NULL;
  63. delete SalvageListItem::weightText;
  64. SalvageListItem::weightText = NULL;
  65. delete SalvageListItem::costText;
  66. SalvageListItem::costText = NULL;
  67. delete SalvageListItem::variantNameText;
  68. SalvageListItem::variantNameText = NULL;
  69. delete SalvageListItem::mechNameText;
  70. SalvageListItem::mechNameText = NULL;
  71. delete SalvageListItem::weightIcon;
  72. SalvageListItem::weightIcon = NULL;
  73. delete SalvageListItem::cBillsIcon;
  74. SalvageListItem::cBillsIcon = NULL;
  75. }
  76. int __cdecl sortMechs( const void* pW1, const void* pW2 )
  77. {
  78. BattleMech* p1 = *(BattleMech**)pW1;
  79. BattleMech* p2 = *(BattleMech**)pW2;
  80. LogisticsVariant* pV1 = LogisticsData::instance->getVariant(p1->variantName);
  81. LogisticsVariant* pV2 = LogisticsData::instance->getVariant(p2->variantName);
  82. if ( pV1 && pV2 )
  83. {
  84. long cost1 = pV1->getCost();
  85. long cost2 = pV2->getCost();
  86. if ( cost1 < cost2 )
  87. return -1;
  88. else if ( cost2 < cost1 )
  89. return 1;
  90. }
  91. return 0;
  92. }
  93. void SalvageMechScreen::init(FitIniFile* file)
  94. {
  95. LogisticsScreen::init( *file, "SalvageAreaStatic", "SalvageAreaText", "SalvageAreaRect",
  96. "SalvageAreaButton" );
  97. SalvageListItem::init( file );
  98. for ( int i = 0; i < buttonCount; i++ )
  99. {
  100. buttons[i].setMessageOnRelease();
  101. }
  102. long left, right, top, bottom;
  103. file->seekBlock( "SalvageAreaRect3" );
  104. file->readIdLong( "Left", left );
  105. file->readIdLong( "Right", right );
  106. file->readIdLong( "Top", top );
  107. file->readIdLong( "Bottom", bottom );
  108. salvageListBox.init( left, top, right - left, bottom - top );
  109. BattleMech** pSortedMechs = (BattleMech**)_alloca( ObjectManager->numMechs * sizeof( BattleMech* ) );
  110. int count = 0;
  111. for ( i = 0; i < ObjectManager->numMechs; i++ )
  112. {
  113. BattleMech* pMech = ObjectManager->getMech( i );
  114. if ( pMech->isDisabled() && !pMech->isDestroyed() && pMech->moveLevel != 2 )
  115. pSortedMechs[count++] = pMech;
  116. }
  117. qsort( pSortedMechs, count, sizeof ( BattleMech* ), sortMechs );
  118. for ( i = 0; i < count; i++ )
  119. {
  120. BattleMech* pMech = pSortedMechs[i];
  121. if ( pMech->isDisabled() && !pMech->isDestroyed() && pMech->moveLevel != 2 ) // don't put copters in the list
  122. {
  123. SalvageListItem* pItem = new SalvageListItem( pMech );
  124. salvageListBox.AddItem( pItem );
  125. pItem->setParent( this );
  126. }
  127. }
  128. selMechArea.init( file );
  129. salvageListBox.SelectItem( 0 );
  130. exitAnim.initWithBlockName( file, "SalvageAreaDoneAnimation" );
  131. entryAnim.initWithBlockName( file, "SalvageAreaFadeInAnimation" );
  132. entryAnim.begin();
  133. beginFadeIn( 1.0 );
  134. }
  135. void SalvageMechScreen::render()
  136. {
  137. long xOffset = 0;
  138. long yOffset = 0;
  139. if ( bDone )
  140. {
  141. xOffset = exitAnim.getXDelta();
  142. yOffset = exitAnim.getYDelta();
  143. }
  144. salvageListBox.move( xOffset, yOffset );
  145. salvageListBox.render( );
  146. salvageListBox.move( -xOffset, -yOffset );
  147. selMechArea.render(xOffset, yOffset);
  148. LogisticsScreen::render(xOffset, yOffset);
  149. // this animation draw a big white square and looks like crap
  150. // if ( !entryAnim.isDone() )
  151. // {
  152. // unsigned long color = entryAnim.getColor();
  153. // GUI_RECT rect = { 0, 0, Environment.screenWidth, Environment.screenHeight };
  154. // drawRect( rect, color );
  155. // }
  156. }
  157. int SalvageMechScreen::handleMessage( unsigned long message, unsigned long who)
  158. {
  159. if ( who == 101 )
  160. {
  161. bDone = true;
  162. {
  163. soundSystem->stopBettySample(); // don't want to carry droning on to next screen
  164. if ( LogisticsData::instance->skipPilotReview() )
  165. {
  166. beginFadeOut(.5);
  167. }
  168. else
  169. {
  170. exitAnim.begin();
  171. exitAnim.update();
  172. fadeTime = 0.0f;
  173. fadeInTime= 0.f;
  174. }
  175. return 1;
  176. }
  177. }
  178. return 0;
  179. }
  180. bool SalvageMechScreen::isDone()
  181. {
  182. return bDone && ( exitAnim.isDone() || ( fadeTime > fadeOutTime ) );
  183. }
  184. void SalvageMechScreen::update()
  185. {
  186. int amount = LogisticsData::instance->getCBills();
  187. long color = 0xff005392;
  188. if ( amount != oldCBillsAmount )
  189. {
  190. previousAmount = oldCBillsAmount - amount;
  191. curCount = .00001f;
  192. oldCBillsAmount = amount;
  193. if ( previousAmount < 0 )
  194. soundSystem->playDigitalSample( WINDOW_OPEN );
  195. else
  196. soundSystem->playDigitalSample( WINDOW_CLOSE );
  197. }
  198. if ( curCount && curCount + frameLength < countDownTime )
  199. {
  200. curCount += frameLength;
  201. float curAmount = previousAmount - (curCount/countDownTime * previousAmount);
  202. amount += curAmount;
  203. color = 0xffc8e100;
  204. if ( curAmount > 0 )
  205. color = 0xffa21600;
  206. }
  207. char cBillText[32];
  208. sprintf( cBillText, "%ld", amount );
  209. textObjects[RP_TEXTID].setText( cBillText );
  210. textObjects[RP_TEXTID].setColor( color );
  211. salvageListBox.update();
  212. for ( int i = 0; i < buttonCount; i++ )
  213. {
  214. buttons[i].update();
  215. /* if ( buttons[i].pointInside( userInput->getMouseX(), userInput->getMouseY() )
  216. && userInput->isLeftClick() )
  217. {
  218. handleMessage( aMSG_DONE, aMSG_DONE );
  219. }*/
  220. }
  221. entryAnim.update();
  222. exitAnim.update();
  223. selMechArea.update();
  224. LogisticsScreen::update();
  225. if ( exitAnim.isAnimating() )
  226. fadeTime = 0.f;
  227. }
  228. void SalvageMechScreen::updateSalvage()
  229. {
  230. for ( int i = 0; i < salvageListBox.GetItemCount(); i++ )
  231. {
  232. SalvageListItem* item = (SalvageListItem*)salvageListBox.GetItem( i );
  233. if ( item && item->isChecked() )
  234. {
  235. LogisticsData::instance->addMechToInventory( item->getMech(), (LogisticsPilot*)NULL, 0 );
  236. }
  237. }
  238. }
  239. //////////////////////////////////////////////
  240. SalvageListItem::~SalvageListItem()
  241. {
  242. removeAllChildren( true );
  243. }
  244. void SalvageListItem::init( FitIniFile* file )
  245. {
  246. if ( templateCheckButton )
  247. return; // already initialized
  248. templateCheckButton = new aAnimButton;
  249. mechNameText = new aText;
  250. variantNameText = new aText;
  251. weightText = new aText;
  252. costText = new aText;
  253. cBillsIcon = new aObject;
  254. weightIcon = new aObject;
  255. templateCheckButton->init( *file, "SalvageAreaCheckBoxButton" );
  256. cBillsIcon->init( file, "CBillsIcon" );
  257. weightIcon->init( file, "WeightIcon" );
  258. mechNameText->init( file, "MechNameText" );
  259. variantNameText->init( file, "VariantNameText" );
  260. costText->init( file, "CBillsText" );
  261. weightText->init( file, "WeightText" );
  262. file->seekBlock( "SalvageAreaMechEntryBox" );
  263. file->readIdLong( "XLocation", rect.left );
  264. file->readIdLong( "YLocation", rect.top );
  265. long width, height;
  266. file->readIdLong( "Width", width );
  267. file->readIdLong( "Height", height );
  268. rect.right = rect.left + width;
  269. rect.bottom = rect.top + height;
  270. s_normalAnim = new aAnimation;
  271. s_pressedAnim = new aAnimation;
  272. s_highlightAnim = new aAnimation;
  273. s_normalAnim->init( file, "Normal" );
  274. s_pressedAnim->init( file, "Pressed" );
  275. s_highlightAnim->init( file, "Highlight" );
  276. file->seekBlock( "MechEntryIcon" );
  277. file->readIdLong( "XLocation", iconRect.left );
  278. file->readIdLong( "YLocation", iconRect.right );
  279. file->readIdLong( "Width", width );
  280. file->readIdLong( "Height", height );
  281. iconRect.right= iconRect.left + width;
  282. iconRect.bottom = iconRect.top + height;
  283. }
  284. SalvageListItem::SalvageListItem( BattleMech* pMech )
  285. {
  286. gosASSERT( pMech );
  287. long width = rect.right - rect.left;
  288. aObject::init( 0, 2, width, rect.bottom - rect.top );
  289. icon = new MechIcon();
  290. icon->init( pMech );
  291. icon->update();
  292. ((Mech3DAppearance*)pMech->getAppearance())->getPaintScheme( psRed, psGreen, psBlue );
  293. normalAnim = *s_normalAnim;
  294. pressedAnim = *s_pressedAnim;
  295. highlightAnim = *s_highlightAnim;
  296. pVariant = LogisticsData::instance->getVariant( pMech->variantName );
  297. if ( !pVariant )
  298. return;
  299. costToSalvage = .8f * (float)pVariant->getCost();
  300. // add the chassis
  301. aText* pText = new aText();
  302. *pText = *mechNameText;
  303. int nameID = pVariant->getChassisName();
  304. char tmp[64];
  305. cLoadString( nameID, tmp, 63 );
  306. pText->setText( tmp );
  307. addChild( pText );
  308. // add the variant name
  309. pText = new aText( );
  310. *pText = *variantNameText;
  311. pText->setText( pVariant->getName() );
  312. addChild( pText );
  313. // add salvage
  314. char text[64];
  315. long salvageAmount = costToSalvage;
  316. sprintf( text, "%ld", salvageAmount );
  317. pText = new aText( );
  318. *pText = *costText;
  319. pText->setText( text );
  320. addChild( pText );
  321. // add tonnage
  322. long tonnage = pMech->tonnage;
  323. sprintf( text, "%ld", tonnage );
  324. pText = new aText( );
  325. *pText = *weightText;
  326. pText->setText( text );
  327. addChild( pText );
  328. // need to make the check box button
  329. aAnimButton* pButton = new aAnimButton;
  330. *pButton = *templateCheckButton;
  331. pButton->setID( CHECK_BUTTON );
  332. addChild( pButton );
  333. checkButton = pButton;
  334. // add the icons
  335. aObject* pObject = new aObject;
  336. *pObject = *cBillsIcon;
  337. addChild( pObject );
  338. pObject = new aObject;
  339. *pObject = *weightIcon;
  340. addChild( pObject );
  341. normalAnim.begin();
  342. }
  343. void SalvageListItem::update()
  344. {
  345. long mouseX = userInput->getMouseX();
  346. long mouseY = userInput->getMouseY();
  347. if ( costToSalvage > LogisticsData::instance->getCBills()
  348. && !isChecked() )
  349. {
  350. disable( );
  351. checkButton->disable( 1 );
  352. if ( pointInside( mouseX, mouseY ) && showWindow == true )
  353. {
  354. if ( userInput->isLeftClick() )
  355. {
  356. SalvageMechArea::instance->setMech( pVariant, psBlue, psGreen, psRed );
  357. soundSystem->playDigitalSample( LOG_WRONGBUTTON );
  358. }
  359. }
  360. }
  361. else if ( !isChecked() && getState() == DISABLED )
  362. {
  363. setState( ENABLED );
  364. checkButton->disable( 0 );
  365. if ( pointInside( mouseX, mouseY ) && showWindow == true )
  366. {
  367. if ( userInput->isLeftClick() )
  368. {
  369. SalvageMechArea::instance->setMech( pVariant, psBlue, psGreen, psRed );
  370. }
  371. }
  372. }
  373. else
  374. {
  375. if ( pointInside( mouseX, mouseY ) && showWindow == true )
  376. {
  377. if ( userInput->isLeftClick() )
  378. {
  379. SalvageMechArea::instance->setMech( pVariant, psBlue, psGreen, psRed );
  380. pressedAnim.begin();
  381. }
  382. // here's where you'd do the highlight thing
  383. else
  384. {
  385. if ( state != aListItem::HIGHLITE )
  386. {
  387. highlightAnim.begin();
  388. }
  389. else
  390. {
  391. if ( !highlightAnim.isAnimating() )
  392. highlightAnim.begin();
  393. highlightAnim.update();
  394. }
  395. }
  396. }
  397. if ( state == aListItem::SELECTED )
  398. {
  399. if ( !pressedAnim.isAnimating() )
  400. {
  401. pressedAnim.begin();
  402. SalvageMechArea::instance->setMech( pVariant, psBlue, psGreen, psRed );
  403. }
  404. pressedAnim.update();
  405. }
  406. }
  407. normalAnim.update();
  408. aObject::update();
  409. }
  410. void SalvageListItem::render()
  411. {
  412. aObject::render();
  413. icon->renderUnitIcon( iconRect.left + location[0].x + 3, iconRect.top + location[0].y + 5,
  414. iconRect.right + location[0].x, iconRect.bottom + location[0].y );
  415. long color = state == HIGHLITE ? highlightAnim.getColor() : normalAnim.getColor();
  416. if ( state == SELECTED )
  417. color = pressedAnim.getColor();
  418. if ( state == DISABLED )
  419. color = 0xff373737;
  420. for ( int i = 0; i < this->pNumberOfChildren; i++ )
  421. {
  422. pChildren[i]->setColor( color, 1 );
  423. }
  424. GUI_RECT tmp;
  425. tmp.left = location[0].x + templateCheckButton->width() + 3;
  426. tmp.right = tmp.left + rect.right - rect.left;
  427. tmp.top = location[0].y;
  428. tmp.bottom = location[2].y;
  429. drawEmptyRect( tmp, color, color );
  430. }
  431. bool SalvageListItem::isChecked()
  432. {
  433. return checkButton->isPressed();
  434. }
  435. int SalvageListItem::handleMessage( unsigned long message, unsigned long who )
  436. {
  437. if ( message == aMSG_LEFTMOUSEDOWN )
  438. {
  439. if ( who == CHECK_BUTTON )
  440. {
  441. if ( checkButton->isPressed() )
  442. LogisticsData::instance->decrementCBills( costToSalvage );
  443. else
  444. LogisticsData::instance->addCBills( costToSalvage );
  445. }
  446. return 1;
  447. }
  448. return 0;
  449. }
  450. //////////////////////////////////
  451. SalvageMechArea::SalvageMechArea()
  452. {
  453. statics = 0;
  454. rects = 0;
  455. staticCount = rectCount = textCount = 0;
  456. textObjects = 0;
  457. gosASSERT( !instance );
  458. instance = this;
  459. unit = 0;
  460. }
  461. SalvageMechArea::~SalvageMechArea()
  462. {
  463. instance = NULL;
  464. }
  465. void SalvageMechArea::init( FitIniFile* file )
  466. {
  467. file->seekBlock( "SalvageAreaRect8" );
  468. long left, right, top, bottom;
  469. file->readIdLong( "left", left );
  470. file->readIdLong( "top", top );
  471. file->readIdLong( "right", right );
  472. file->readIdLong( "top", top );
  473. file->readIdLong( "bottom", bottom );
  474. loadoutListBox.init( left, top, right - left, bottom - top );
  475. file->seekBlock( "SalvageAreaRect6" );
  476. file->readIdLong( "left", left );
  477. file->readIdLong( "top", top );
  478. file->readIdLong( "right", right );
  479. file->readIdLong( "top", top );
  480. file->readIdLong( "bottom", bottom );
  481. mechCamera.init( left, top, right, bottom );
  482. LogisticsScreen::init(*file, 0, "SalvageAreaMechText", 0, 0 );
  483. char blockName[64];
  484. for ( int i = 0; i < 3; i++ )
  485. {
  486. sprintf( blockName, "AttributeMeter%ld", i );
  487. attributeMeters[i].init( file, blockName );
  488. }
  489. }
  490. void SalvageMechArea::update()
  491. {
  492. loadoutListBox.update();
  493. mechCamera.update();
  494. }
  495. void SalvageMechArea::setMech( LogisticsVariant* pMech, long red, long green, long blue )
  496. {
  497. if ( pMech == unit )
  498. return;
  499. loadoutListBox.setMech( pMech );
  500. if ( pMech )
  501. {
  502. EString fileName = pMech->getFileName();
  503. int index = fileName.Find( '.' );
  504. fileName = fileName.Left( index );
  505. index = fileName.ReverseFind( '\\' );
  506. fileName = fileName.Right( fileName.Length() - index - 1 );
  507. mechCamera.setMech( fileName, red, green, blue );
  508. textObjects[NAME_TEXTID].setText( pMech->getName() );
  509. char text[256];
  510. sprintf( text, "%ld", pMech->getMaxWeight() );
  511. textObjects[WEIGHT_TEXTID].setText( text );
  512. sprintf( text, "%ld", pMech->getArmor() );
  513. textObjects[ARMOR_TEXTID].setText( text );
  514. sprintf( text, "%ld", pMech->getDisplaySpeed() );
  515. textObjects[SPEED_TEXTID].setText( text );
  516. sprintf( text, "%ld", pMech->getJumpRange() * 25 );
  517. textObjects[JUMP_TEXTID].setText( text );
  518. long tmpColor;
  519. textObjects[RANGE_TEXTID].setText( pMech->getOptimalRangeString( tmpColor ) );
  520. textObjects[RANGE_TEXTID].setColor( ( tmpColor ) );
  521. attributeMeters[0].setValue( ((float)pMech->getArmor())/MAX_ARMOR_RANGE );
  522. attributeMeters[1].setValue( ((float)pMech->getSpeed())/MAX_SPEED_RANGE );
  523. attributeMeters[2].setValue( ((float)pMech->getJumpRange() * 25.0f)/MAX_JUMP_RANGE );
  524. }
  525. else
  526. {
  527. textObjects[WEIGHT_TEXTID].setText( "" );
  528. textObjects[ARMOR_TEXTID].setText( "" );
  529. textObjects[SPEED_TEXTID].setText( "" );
  530. textObjects[JUMP_TEXTID].setText( "" );
  531. attributeMeters[0].setValue( 0 );
  532. attributeMeters[1].setValue( 0 );
  533. attributeMeters[2].setValue( 0 );
  534. mechCamera.setMech( 0 );
  535. }
  536. unit = pMech;
  537. }
  538. void SalvageMechArea::render(long xOffset, long yOffset)
  539. {
  540. loadoutListBox.move( xOffset, yOffset );
  541. loadoutListBox.render();
  542. loadoutListBox.move( -xOffset, -yOffset );
  543. if ( this->unit )
  544. {
  545. for ( int i = 0; i < textCount; i++ )
  546. {
  547. textObjects[i].move( xOffset, yOffset );
  548. textObjects[i].render();
  549. textObjects[i].move( -xOffset, -yOffset );
  550. }
  551. for ( i = 0; i < 3; i++ )
  552. {
  553. attributeMeters[i].render(xOffset, yOffset);
  554. }
  555. if ( !xOffset && !yOffset )
  556. mechCamera.render();
  557. }
  558. }
  559. //*************************************************************************************************
  560. // end of file ( SalvageMechArea.cpp )