InfoWindow.cpp 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. #define INFOWINDOW_CPP
  2. /*************************************************************************************************\
  3. InfoWindow.cpp : Implementation of the InfoWindow component.
  4. //===========================================================================//
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. //===========================================================================//
  7. \*************************************************************************************************/
  8. #include "InfoWindow.h"
  9. #include "MCLib.h"
  10. #include "..\resource.h"
  11. #include "mover.h"
  12. #include "mechIcon.h"
  13. #include "Team.h"
  14. #include "txmmgr.h"
  15. #include "EString.h"
  16. long InfoWindow::SCROLLLEFT = 0;
  17. long InfoWindow::SCROLLRIGHT = 0;
  18. long InfoWindow::SCROLLTOP = 0;
  19. long InfoWindow::SCROLLBOTTOM = 0;
  20. long InfoWindow::SECTIONSKIP = 0;
  21. long InfoWindow::NAMELEFT = 0;
  22. long InfoWindow::NAMERIGHT = 0;
  23. long InfoWindow::NAMETOP = 0;
  24. long InfoWindow::NAMEBOTTOM = 0;
  25. long InfoWindow::HEALTHLEFT = 0;
  26. long InfoWindow::HEALTHRIGHT = 0;
  27. long InfoWindow::HEALTHTOP = 0;
  28. long InfoWindow::HEALTHBOTTOM = 0;
  29. long InfoWindow::DIVIDERCOLOR = 0;
  30. long InfoWindow::DIVIDERLEFT = 0;
  31. long InfoWindow::DIVIDERRIGHT = 0;
  32. long InfoWindow::PILOTLEFT = 0;
  33. long InfoWindow::PILOTRIGHT = 0;
  34. long InfoWindow::PILOTHEIGHT = 0;
  35. long InfoWindow::MECHLEFT = 0;
  36. long InfoWindow::MECHRIGHT = 0;
  37. long InfoWindow::MECHHEIGHT = 0;
  38. long InfoWindow::MECHBACKLEFT = 0;
  39. long InfoWindow::MECHBACKRIGHT = 0;
  40. long InfoWindow::MECHBACKHEIGHT = 0;
  41. long InfoWindow::SCROLLBUTTONV = 0;
  42. StaticInfo* InfoWindow::skillInfos = 0;
  43. long InfoWindow::SCROLLBUTTONU = 0;
  44. long InfoWindow::SCROLLBUTTONHEIGHT = 0;
  45. long InfoWindow::SCROLLBUTTONWIDTH = 0;
  46. long InfoWindow::SCROLLBUTTONX = 0;
  47. long InfoWindow::SCROLLMAX = 0;
  48. long InfoWindow::SCROLLMIN = 0;
  49. long InfoWindow::NUMBERSKILLBARS = 0;
  50. long InfoWindow::SKILLUNITWIDTH = 0;
  51. long InfoWindow::SKILLSKIP = 0;
  52. long InfoWindow::SKILLHEIGHT = 0;
  53. long InfoWindow::SKILLRIGHT = 0;
  54. long InfoWindow::SKILLLEFT = 0;
  55. long InfoWindow::SCROLLCOLOR = -1;
  56. long InfoWindow::INFOHEIGHT = 0;
  57. long InfoWindow::INFOWIDTH = 0;
  58. long InfoWindow::INFOTOP = 0;
  59. long InfoWindow::INFOLEFT = 0;
  60. long InfoWindow::COMPONENTLEFT = 0;
  61. long InfoWindow::SCROLLBOXLEFT= 0;
  62. long InfoWindow::SCROLLBOXRIGHT= 0;
  63. long InfoWindow::SCROLLBOXTOP= 0;
  64. long InfoWindow::SCROLLBOXBOTTOM= 0;
  65. long InfoWindow::PILOTNAMELEFT = 0;
  66. GUI_RECT InfoWindow::NameRect = { 0 };
  67. ControlButton InfoWindow::buttons[2] = {0};
  68. InfoWindow* InfoWindow::s_instance = NULL;
  69. #define SCROLLAMOUNT 3.f * Environment.screenWidth/640.f
  70. extern float WeaponRanges[NUM_WEAPON_RANGE_TYPES][2];
  71. // initialize statics
  72. ButtonData InfoWindow::buttonData[2];;
  73. extern bool useUnlimitedAmmo;
  74. InfoWindow::InfoWindow()
  75. {
  76. pUnit = NULL;
  77. scrollLength = 0;
  78. scrollPos = 0;
  79. backgroundTexture = 0;
  80. icon = NULL;
  81. infoLength = 0;
  82. skillInfos = new StaticInfo[7];
  83. memset( skillInfos, 0, sizeof( StaticInfo ) * 7);
  84. memset( buttonData, 0, sizeof( buttonData ) );
  85. lastYClick = -1.f;
  86. s_instance = this;
  87. }
  88. void InfoWindow::init( FitIniFile& file )
  89. {
  90. if ( NO_ERR != file.seekBlock( "Fonts" ) )
  91. Assert( 0, 0, "couldn't find the font block" );
  92. for ( int i = 0; i < 7; i++ )
  93. {
  94. if ( skillInfos[i].textureHandle )
  95. {
  96. long gosID = mcTextureManager->get_gosTextureHandle( skillInfos[i].textureHandle );
  97. mcTextureManager->removeTexture( gosID );
  98. }
  99. }
  100. memset( skillInfos, 0, sizeof( skillInfos ) );
  101. memset( buttonData, 0, sizeof( buttonData ) );
  102. for ( i = 0; i < 2; i++ )
  103. {
  104. if ( buttonData[i].textureHandle )
  105. {
  106. long gosID = mcTextureManager->get_gosTextureHandle( buttonData[i].textureHandle );
  107. mcTextureManager->removeTexture( gosID );
  108. }
  109. }
  110. long fontID;
  111. if ( NO_ERR != file.readIdLong( "InfoWndFont", fontID ) )
  112. {
  113. Assert( 0, 0,"couldn't find infoWndFont in button layout file" );
  114. }
  115. s_instance->nameFont.init( fontID );
  116. if ( NO_ERR != file.readIdLong( "ComponentFont", fontID ) )
  117. {
  118. Assert( 0, 0, "couldn't find componentFont in button layout file" );
  119. }
  120. s_instance->componentFont.init( fontID );
  121. if ( NO_ERR != file.seekBlock( "InfoWindow" ) )
  122. {
  123. Assert( 0, 0, "couldn't find Info block in button layout file" );
  124. }
  125. file.readIdLong( "XLocation", InfoWindow::INFOLEFT );
  126. file.readIdLong( "YLocation", InfoWindow::INFOTOP );
  127. file.readIdLong( "Width", InfoWindow::INFOWIDTH );
  128. file.readIdLong( "Height", InfoWindow::INFOHEIGHT );
  129. InfoWindow::INFOLEFT += ControlGui::hiResOffsetX;
  130. InfoWindow::INFOTOP += ControlGui::hiResOffsetY;
  131. file.readIdLong( "SkipBetweenSections", InfoWindow::SECTIONSKIP );
  132. file.readIdLong( "InfoHeaderBoxLeft", NameRect.left );
  133. file.readIdLong( "InfoHeaderBoxRight", NameRect.right );
  134. file.readIdLong( "InfoHeaderBoxTop", NameRect.top );
  135. file.readIdLong( "InfoHeaderBoxBottom", NameRect.bottom );
  136. NameRect.left += ControlGui::hiResOffsetX;
  137. NameRect.right += ControlGui::hiResOffsetX;
  138. NameRect.top += ControlGui::hiResOffsetY;
  139. NameRect.bottom += ControlGui::hiResOffsetY;
  140. file.readIdLong( "ScrollBarToP", InfoWindow::SCROLLTOP );
  141. file.readIdLong( "ScrollBarBottom", InfoWindow::SCROLLBOTTOM );
  142. file.readIdLong( "ScrollBarLeft", InfoWindow::SCROLLLEFT );
  143. file.readIdLong( "ScrollBarRight", InfoWindow::SCROLLRIGHT );
  144. file.readIdLong( "ScrollBarColor", InfoWindow::SCROLLCOLOR );
  145. InfoWindow::SCROLLTOP += ControlGui::hiResOffsetY;
  146. InfoWindow::SCROLLBOTTOM += ControlGui::hiResOffsetY;
  147. InfoWindow::SCROLLLEFT += ControlGui::hiResOffsetX;
  148. InfoWindow::SCROLLRIGHT += ControlGui::hiResOffsetX;
  149. file.readIdLong( "ScrollContentBoxLeft", InfoWindow::SCROLLBOXLEFT );
  150. file.readIdLong( "ScrollContentBoxRight", InfoWindow::SCROLLBOXRIGHT );
  151. file.readIdLong( "ScrollContentBoxBarTop", InfoWindow::SCROLLBOXTOP );
  152. file.readIdLong( "ScrollContentBoxBarBottom", InfoWindow::SCROLLBOXBOTTOM );
  153. InfoWindow::SCROLLBOXLEFT += ControlGui::hiResOffsetX;
  154. InfoWindow::SCROLLBOXRIGHT += ControlGui::hiResOffsetX;
  155. InfoWindow::SCROLLBOXTOP += ControlGui::hiResOffsetY;
  156. InfoWindow::SCROLLBOXBOTTOM += ControlGui::hiResOffsetY;
  157. file.readIdLong( "NameLocationLeft", InfoWindow::NAMELEFT );
  158. file.readIdLong( "NameLocationRight", InfoWindow::NAMERIGHT );
  159. file.readIdLong( "NameLocationTop", InfoWindow::NAMETOP );
  160. file.readIdLong( "NameLocationBottom", InfoWindow::NAMEBOTTOM );
  161. InfoWindow::NAMELEFT += ControlGui::hiResOffsetX;
  162. InfoWindow::NAMERIGHT += ControlGui::hiResOffsetX;
  163. InfoWindow::NAMETOP += ControlGui::hiResOffsetY;
  164. InfoWindow::NAMEBOTTOM += ControlGui::hiResOffsetY;
  165. file.readIdLong( "HealthBarLeft", InfoWindow::HEALTHLEFT );
  166. file.readIdLong( "HealthBarRight", InfoWindow::HEALTHRIGHT );
  167. file.readIdLong( "HealthBarTop", InfoWindow::HEALTHTOP );
  168. file.readIdLong( "HealthBarBottom", InfoWindow::HEALTHBOTTOM );
  169. InfoWindow::HEALTHLEFT += ControlGui::hiResOffsetX;
  170. InfoWindow::HEALTHRIGHT += ControlGui::hiResOffsetX;
  171. InfoWindow::HEALTHTOP += ControlGui::hiResOffsetY;
  172. InfoWindow::HEALTHBOTTOM += ControlGui::hiResOffsetY;
  173. file.readIdLong( "DividerLeft", InfoWindow::DIVIDERLEFT );
  174. file.readIdLong( "DividerRight", InfoWindow::DIVIDERRIGHT );
  175. file.readIdLong( "DividerColor", InfoWindow::DIVIDERCOLOR );
  176. InfoWindow::DIVIDERLEFT += ControlGui::hiResOffsetX;
  177. InfoWindow::DIVIDERRIGHT += ControlGui::hiResOffsetX;
  178. file.readIdLong( "PilotLeft", InfoWindow::PILOTLEFT );
  179. file.readIdLong( "PilotRight", InfoWindow::PILOTRIGHT );
  180. InfoWindow::PILOTLEFT += ControlGui::hiResOffsetX;
  181. InfoWindow::PILOTRIGHT += ControlGui::hiResOffsetX;
  182. file.readIdLong( "PilotHeight", InfoWindow::PILOTHEIGHT );
  183. file.readIdLong( "PilotNameLeft", PILOTNAMELEFT );
  184. PILOTNAMELEFT += ControlGui::hiResOffsetX;
  185. file.readIdLong( "MechIconLeft", InfoWindow::MECHLEFT );
  186. file.readIdLong( "MechIconRight", InfoWindow::MECHRIGHT );
  187. file.readIdLong( "MechIconHeight", InfoWindow::MECHHEIGHT );
  188. file.readIdLong( "MechIconBackLeft", InfoWindow::MECHBACKLEFT );
  189. file.readIdLong( "MechIconBackRight", InfoWindow::MECHBACKRIGHT );
  190. file.readIdLong( "MechIconBackHeight", InfoWindow::MECHBACKHEIGHT );
  191. InfoWindow::MECHLEFT += ControlGui::hiResOffsetX;
  192. InfoWindow::MECHRIGHT += ControlGui::hiResOffsetX;
  193. InfoWindow::MECHBACKLEFT += ControlGui::hiResOffsetX;
  194. InfoWindow::MECHBACKRIGHT += ControlGui::hiResOffsetX;
  195. file.seekBlock( "SkillMeter" );
  196. file.readIdLong( "Left", InfoWindow::SKILLLEFT );
  197. file.readIdLong( "Right", InfoWindow::SKILLRIGHT );
  198. InfoWindow::SKILLLEFT += ControlGui::hiResOffsetX;
  199. InfoWindow::SKILLRIGHT += ControlGui::hiResOffsetX;
  200. file.readIdLong( "Height", InfoWindow::SKILLHEIGHT );
  201. file.readIdLong( "Skip", InfoWindow::SKILLSKIP );
  202. file.readIdLong( "UnitWidth", InfoWindow::SKILLUNITWIDTH );
  203. file.readIdLong( "NumberUnits", InfoWindow::NUMBERSKILLBARS );
  204. file.seekBlock( "ScrollButton" );
  205. file.readIdLong( "Min", SCROLLMIN );
  206. file.readIdLong( "Max", SCROLLMAX );
  207. file.readIdLong( "XLocation", SCROLLBUTTONX );
  208. SCROLLMIN += ControlGui::hiResOffsetY;
  209. SCROLLMAX += ControlGui::hiResOffsetY;
  210. SCROLLBUTTONX += ControlGui::hiResOffsetX;
  211. file.readIdLong( "Width", SCROLLBUTTONWIDTH );
  212. file.readIdLong( "Height", SCROLLBUTTONHEIGHT );
  213. file.readIdLong( "UNormal", SCROLLBUTTONU );
  214. file.readIdLong( "VNormal", SCROLLBUTTONV );
  215. ControlButton::initButtons( file, 2, buttons, buttonData, "InfoButton" );
  216. char SkillText[32];
  217. for ( i = 0; i < 7; i++ )
  218. {
  219. sprintf( SkillText, "Skill%ld", i );
  220. skillInfos[i].init( file, SkillText ,ControlGui::hiResOffsetX, ControlGui::hiResOffsetY);
  221. }
  222. InfoWindow::COMPONENTLEFT = InfoWindow::PILOTLEFT;
  223. }
  224. InfoWindow::~InfoWindow()
  225. {
  226. delete [] skillInfos;
  227. }
  228. void InfoWindow::setUnit(Mover* pNewMover)
  229. {
  230. if ( pNewMover && ( pNewMover->getTeamId() != Team::home->getId() &&
  231. ( CONTACT_VISUAL != pNewMover->getContactStatus(Team::home->getId(), true))
  232. && !pNewMover->isDisabled() ))
  233. {
  234. return;
  235. }
  236. if ( pUnit != pNewMover )
  237. {
  238. pUnit = pNewMover;
  239. bUnitChanged = true;
  240. if ( icon )
  241. {
  242. delete icon;
  243. icon = NULL;
  244. }
  245. icon = NULL;
  246. scrollPos = 0;
  247. infoLength = 0;
  248. if ( pNewMover )
  249. {
  250. if ( pNewMover->getObjectType()->getObjectTypeClass() == BATTLEMECH_TYPE )
  251. {
  252. MechIcon* pIcon = new MechIcon;
  253. pIcon->setLocationIndex( 16 );
  254. pIcon->init( pNewMover );
  255. pIcon->setDrawBack( true );
  256. icon = pIcon;
  257. }
  258. else
  259. {
  260. VehicleIcon* pIcon = new VehicleIcon;
  261. pIcon->setLocationIndex( 16 );
  262. pIcon->setDrawBack( 1 );
  263. pIcon->init( pNewMover );
  264. icon = pIcon;
  265. }
  266. }
  267. }
  268. }
  269. void InfoWindow::drawName( const char* name )
  270. {
  271. GUI_RECT rect = { NAMELEFT, NAMETOP, NAMERIGHT, SCROLLTOP};
  272. drawRect( rect, 0xff000000 );
  273. drawEmptyRect( NameRect, 0xff002f55, 0xff002f55 );
  274. nameFont.render( name, NAMELEFT, NAMETOP, NAMERIGHT - NAMELEFT, NAMEBOTTOM - NAMETOP, 0xff5c96c2, 0, 3 );
  275. }
  276. void InfoWindow::render()
  277. {
  278. drawScrollingStuff();
  279. GUI_RECT tmpRect = { SCROLLBOXLEFT, SCROLLBOXBOTTOM, SCROLLBOXRIGHT, INFOTOP + INFOHEIGHT };
  280. drawRect( tmpRect, 0xff000000 );
  281. for ( int i = 0; i < 2; i++ )
  282. {
  283. if ( buttons[i].isEnabled() )
  284. buttons[i].render();
  285. }
  286. long scrollBarLength = buttons[1].location[0].y - buttons[0].location[2].y - 4 - SCROLLBUTTONHEIGHT;
  287. gos_VERTEX v[4];
  288. for ( i = 0; i < 4; i++ )
  289. {
  290. v[i].argb = 0xff5c96c2;
  291. v[i].frgb = 0;
  292. v[i].rhw = .5;
  293. v[i].x = SCROLLBUTTONX;
  294. v[i].y = SCROLLMIN + scrollPos;
  295. v[i].z = 0.f;
  296. v[i].u = v[i].v = 0.f;
  297. // v[i].u = ((float)SCROLLBUTTONU)/256.f + .1/256.f;
  298. // v[i].v = ((float)SCROLLBUTTONV)/256.f + .1/256.f ;
  299. }
  300. if ( infoLength < scrollBarLength || !pUnit )
  301. {
  302. buttons[0].disable( 1 );
  303. buttons[1].disable( 1 );
  304. SCROLLMAX = 0;
  305. }
  306. else
  307. {
  308. buttons[0].disable( 0 );
  309. buttons[1].disable( 0 );
  310. float physicalRange = buttons[1].location[0].y - buttons[0].location[2].y;
  311. float buttonHeight = SCROLLBUTTONHEIGHT;
  312. float RealRange = infoLength;
  313. buttonHeight = physicalRange * physicalRange/(physicalRange + RealRange);
  314. if ( buttonHeight < SCROLLBUTTONHEIGHT )
  315. buttonHeight = SCROLLBUTTONHEIGHT;
  316. SCROLLMAX = buttons[1].location[0].y - buttonHeight - 2;
  317. v[2].x = v[3].x = SCROLLBUTTONX + SCROLLBUTTONWIDTH;
  318. v[1].y = v[2].y = SCROLLBOTTOM;
  319. v[1].y = v[2].y = v[0].y + buttonHeight;
  320. // v[2].u = v[3].u = .1/256.f + (float)(SCROLLBUTTONU + ((float)SCROLLBUTTONWIDTH))/256.f;
  321. // v[1].v = v[2].v = .1/256.f + (float)(SCROLLBUTTONV + ((float)SCROLLBUTTONHEIGHT))/256.f;
  322. gos_SetRenderState( gos_State_Texture, 0 );
  323. gos_DrawQuads( v, 4 );
  324. }
  325. // draw the name of the unit
  326. if ( pUnit )
  327. {
  328. drawName( pUnit->getIfaceName() );
  329. gos_SetRenderState( gos_State_Texture, 0 );
  330. // draw the health bar
  331. DWORD color;
  332. float barStatus = pUnit->getAppearance()->barStatus;
  333. if (barStatus > 1.0f)
  334. barStatus = 1.0f;
  335. if (barStatus >= 0.5)
  336. color = SB_GREEN;
  337. else if (barStatus > 0.2)
  338. color = SB_YELLOW;
  339. else
  340. color = SB_RED;
  341. v[0].x = v[1].x = HEALTHLEFT;
  342. v[2].x = v[3].x = HEALTHRIGHT;
  343. v[0].y = v[3].y = HEALTHTOP;
  344. v[1].y = v[2].y = HEALTHBOTTOM;
  345. unsigned long dimColor = ( color & 0xff7f7f7f );
  346. for ( int i = 0; i < 4; i++ )
  347. v[i].argb = dimColor;
  348. gos_DrawQuads( v, 4 );
  349. v[2].x = v[3].x = HEALTHLEFT + (HEALTHRIGHT - HEALTHLEFT)* barStatus;
  350. for ( i = 0; i < 4; i++ )
  351. v[i].argb = color | 0xff000000;
  352. gos_DrawQuads( v, 4 );
  353. }
  354. else
  355. {
  356. char noUnit[256];
  357. cLoadString( IDS_NOUNIT, noUnit, 255 );
  358. drawName( noUnit );
  359. }
  360. GUI_RECT border = { SCROLLBOXLEFT, SCROLLBOXTOP, SCROLLBOXRIGHT, SCROLLBOXBOTTOM };
  361. drawEmptyRect( border, SCROLLCOLOR, SCROLLCOLOR );
  362. GUI_RECT rect = { SCROLLLEFT, SCROLLTOP, SCROLLRIGHT, SCROLLBOTTOM };
  363. drawEmptyRect( rect, SCROLLCOLOR, SCROLLCOLOR );
  364. }
  365. void InfoWindow::update()
  366. {
  367. if ( pUnit && ( pUnit->getTeamId() != Team::home->getId() &&
  368. ( CONTACT_VISUAL != (pUnit->getContactStatus(Team::home->getId(), true))
  369. && !pUnit->isDisabled() ) ) )
  370. {
  371. setUnit( 0 );
  372. return;
  373. }
  374. long mouseX = userInput->getMouseX();
  375. long mouseY = userInput->getMouseY();
  376. if ( icon )
  377. icon->update();
  378. for ( int i = 0; i < 2; i++ )
  379. {
  380. if ( buttons[i].location[0].x <= mouseX && mouseX <= buttons[i].location[2].x
  381. && mouseY >= buttons[i].location[0].y && mouseY <= buttons[i].location[1].y )
  382. {
  383. if ( userInput->getMouseLeftButtonState() == MC2_MOUSE_DOWN && buttons[i].isEnabled() )
  384. {
  385. {
  386. handleClick( buttons[i].ID );
  387. return;
  388. }
  389. }
  390. }
  391. }
  392. if ( userInput->isLeftDrag() )
  393. {
  394. if ( lastYClick != -1.f )
  395. {
  396. int tmpLastY = mouseY;
  397. tmpLastY -= userInput->getMouseDragY();
  398. setScrollPos( lastYClick + tmpLastY );
  399. return;
  400. }
  401. }
  402. // see if its in the scroll bar area
  403. else if ( mouseX > SCROLLLEFT && mouseX < SCROLLRIGHT
  404. && mouseY > SCROLLTOP && mouseY < SCROLLBOTTOM
  405. && buttons[0].isEnabled()
  406. && userInput->getMouseDragX() > SCROLLLEFT && userInput->getMouseDragX() < SCROLLRIGHT
  407. && userInput->getMouseDragY() > SCROLLTOP && userInput->getMouseDragY() < SCROLLBOTTOM
  408. )
  409. {
  410. // if its in the thumbdrag thingie, save the y
  411. float physicalRange = buttons[1].location[0].y - buttons[0].location[2].y;
  412. float buttonHeight = SCROLLBUTTONHEIGHT;
  413. float RealRange = infoLength;
  414. buttonHeight = physicalRange * physicalRange/(physicalRange + RealRange);
  415. if ( buttonHeight < SCROLLBUTTONHEIGHT )
  416. buttonHeight = SCROLLBUTTONHEIGHT;
  417. if ( mouseY > scrollPos + SCROLLMIN && mouseY < scrollPos + SCROLLMIN + buttonHeight )
  418. {
  419. lastYClick = scrollPos;
  420. }
  421. else if ( ( userInput->leftMouseReleased() || userInput->getMouseLeftHeld() > .5 ) )
  422. {
  423. lastYClick = -1;
  424. if ( mouseY > buttons[0].location[2].y
  425. && mouseY < buttons[1].location[0].y )
  426. {
  427. float newScrollPos = scrollPos;
  428. // if above the thumb, page up, otherwise page down
  429. if ( mouseY < SCROLLMIN + scrollPos )
  430. {
  431. newScrollPos = scrollPos - buttonHeight;
  432. }
  433. else if ( mouseY > SCROLLMIN + scrollPos + buttonHeight )
  434. {
  435. newScrollPos = scrollPos + buttonHeight;
  436. }
  437. if( newScrollPos < 0 )
  438. newScrollPos = 0;
  439. if( newScrollPos > infoLength )
  440. newScrollPos = infoLength;
  441. setScrollPos( newScrollPos );
  442. }
  443. }
  444. }
  445. if ( userInput->leftMouseReleased() )
  446. lastYClick = -1;
  447. }
  448. void InfoWindow::drawScrollingStuff()
  449. {
  450. if ( !pUnit )
  451. return;
  452. float offset = 0.f;
  453. if ( infoLength )
  454. {
  455. float increment = infoLength/(SCROLLMAX - SCROLLMIN );
  456. offset = -increment * scrollPos;
  457. }
  458. float curY = SCROLLBOXTOP + SECTIONSKIP + offset;
  459. if ( icon )
  460. {
  461. if ( SCROLLTOP + offset > NAMETOP ) // draw icons if visible
  462. {
  463. icon->renderUnitIcon( MECHLEFT, curY, MECHRIGHT, curY + MECHHEIGHT);
  464. icon->renderUnitIconBack( MECHBACKLEFT, curY, MECHBACKRIGHT, curY + MECHHEIGHT );
  465. }
  466. curY += MECHHEIGHT + SECTIONSKIP;
  467. if( curY > NAMEBOTTOM ) // draw divider if visible
  468. drawDivider( curY );
  469. }
  470. long textColors[4] = { 0xff6E7C00, 0xff005392, 0xffA21600 };
  471. char disabledCount[60][2];
  472. long ammo[60];
  473. char ranges[60];
  474. long names[60];
  475. memset( disabledCount, 0, sizeof( char ) * 60 * 2);
  476. memset( names, 0, sizeof( char* ) * 60 );
  477. memset( ranges, 0, sizeof( char ) * 60 );
  478. memset( ammo, 0, sizeof( long ) * 60 );
  479. bool bDraw[4];
  480. memset( bDraw, 0, sizeof( bool ) * 4 );
  481. int curComponentCount = 60;
  482. int i = 0;
  483. for (long curWeapon = pUnit->numOther; curWeapon < (pUnit->numOther + pUnit->numWeapons); curWeapon++)
  484. {
  485. long nName = pUnit->inventory[curWeapon].masterID;
  486. bool bFound = 0;
  487. for ( int j = 0; j < i; j++ )
  488. {
  489. if ( nName == names[j] )
  490. {
  491. disabledCount[j][1] ++;
  492. if (!pUnit->inventory[curWeapon].disabled && (pUnit->getWeaponShots(curWeapon) > 0)
  493. && pUnit->inventory[curWeapon].health > 0 )
  494. {
  495. disabledCount[j][0]++;
  496. }
  497. bFound = true;
  498. }
  499. }
  500. if ( bFound )
  501. continue;
  502. names[i] = nName;
  503. //ONly need to add in the AMMO once!!
  504. // Glenn has taken the liberty of combining all shots of this type
  505. // into one master ammo list!!
  506. if ( MasterComponent::masterList[pUnit->inventory[curWeapon].masterID].getWeaponAmmoType() == WEAPON_AMMO_NONE
  507. || useUnlimitedAmmo )
  508. ammo[i] = -1;
  509. else
  510. ammo[i] += pUnit->getWeaponShots( curWeapon );
  511. int range = MasterComponent::masterList[pUnit->inventory[curWeapon].masterID].getWeaponRange();
  512. ranges[i] = range;
  513. bDraw[range] = true;
  514. if (!pUnit->inventory[curWeapon].disabled && (pUnit->getWeaponShots(curWeapon) > 0)
  515. && pUnit->inventory[curWeapon].health > 0 )
  516. {
  517. disabledCount[i][0]++;
  518. }
  519. disabledCount[i][1]++;
  520. i++;
  521. }
  522. curY += SECTIONSKIP;
  523. unsigned long height = componentFont.height();
  524. // removing headers for now
  525. // long stringIDs[4] = { IDS_SHORT, IDS_MEDIUM, IDS_LONG, IDS_COMPONENT};
  526. // long headerColors[4] = { 0xFFC8E100, 0xff0091FF, 0xFFFF0000, 0xffFF8A00 };
  527. EString capHeader;
  528. for ( int j = 0; j < 3; j++ )
  529. {
  530. if ( !bDraw[j] ) // make sure we have one
  531. continue;
  532. // char header[64];
  533. if ( curY > NAMETOP )
  534. {
  535. // cLoadString( stringIDs[j], header, 63 );
  536. // capHeader = header;
  537. //capHeader.MakeUpper();
  538. // componentFont.render( capHeader, COMPONENTLEFT, curY, SCROLLLEFT - COMPONENTLEFT, height, headerColors[j], 0, 0 );
  539. }
  540. // curY += height;
  541. for ( i = 0; i < curComponentCount; i++ )
  542. {
  543. if ( !names[i] )
  544. break;
  545. char tmpName[256];
  546. if ( ranges[i] == j )
  547. {
  548. if ( curY > NAMETOP )
  549. {
  550. cLoadString( IDS_COMP_ABBR0 + names[i], tmpName, 255 );
  551. capHeader.Format( "%ld/%ld %s", disabledCount[i][0], disabledCount[i][1], tmpName );
  552. componentFont.render( capHeader, COMPONENTLEFT, curY, SCROLLLEFT - COMPONENTLEFT, height, textColors[j], 0, 0 );
  553. }
  554. curY += height;
  555. if ( ammo[i] != -1 )
  556. {
  557. if ( curY > NAMETOP )
  558. {
  559. // make the ammo number
  560. char tmpNumber[64];
  561. char tmpNumber2[64];
  562. cLoadString( IDS_MISSION_SHOTSLEFT, tmpNumber, 63 );
  563. sprintf( tmpNumber2, tmpNumber, ammo[i] );
  564. componentFont.render( tmpNumber2, COMPONENTLEFT, curY, SCROLLLEFT - COMPONENTLEFT, height, textColors[j], 0, 0 );
  565. }
  566. curY += height;
  567. }
  568. }
  569. }
  570. curY += SECTIONSKIP;
  571. if ( curY > NAMEBOTTOM )
  572. drawDivider( curY );
  573. curY += SECTIONSKIP;
  574. }
  575. memset( names, 0, sizeof( char* ) * 60 );
  576. long count[4];
  577. count[0] = pUnit->ecm;
  578. count[1] = pUnit->probe;
  579. count[2] = pUnit->jumpJets;
  580. count[3] = pUnit->isMech() ? pUnit->sensor : 255;
  581. if ((count[0] || count[1] || count[2] || count[3] ) )
  582. {
  583. if ( curY > NAMETOP )
  584. {
  585. // cLoadString( stringIDs[j], header, 63 );
  586. // componentFont.render( header, COMPONENTLEFT, curY, SCROLLLEFT - COMPONENTLEFT, height, headerColors[j], 0, 0 );
  587. }
  588. // curY += height;
  589. }
  590. for ( curWeapon = 0; curWeapon < 4; curWeapon++ )
  591. {
  592. if ( count[curWeapon] != 255)
  593. {
  594. long color = 0xffc29b00;
  595. //Neither the ecm, probe, sensors or JumpJets can ever REALLY be disabled. No matter what the setting is!!
  596. // if (pUnit->inventory[count[curWeapon]].disabled)
  597. // color = 0xff7f7f7f;
  598. char tmpName[256];
  599. cLoadString( IDS_COMP_ABBR0 + pUnit->inventory[count[curWeapon]].masterID, tmpName, 255 );
  600. if ( curY > NAMETOP )
  601. {
  602. componentFont.render( tmpName, COMPONENTLEFT, curY, SCROLLLEFT - COMPONENTLEFT, height, color, 0, 0 );
  603. }
  604. curY += height;
  605. curY += InfoWindow::SECTIONSKIP;
  606. }
  607. }
  608. if ( curY > NAMEBOTTOM )
  609. drawDivider( curY );
  610. curY += SECTIONSKIP;
  611. // DON'T DO PILOT INFO if ENEMY OR mech is destroyed or disabled.
  612. if ( pUnit->getTeam() && !Team::home->isEnemy(pUnit->getTeam()) && pUnit->isMech() && !pUnit->isDisabled() && !pUnit->isDestroyed())
  613. {
  614. MechWarrior* pWarrior = pUnit->getPilot();
  615. if ( icon )
  616. {
  617. if ( curY > NAMETOP )
  618. {
  619. if ( pWarrior->active() )
  620. icon->renderPilotIcon( PILOTLEFT, curY, PILOTRIGHT, curY + PILOTHEIGHT );
  621. GUI_RECT tmpRect = { PILOTLEFT, curY, PILOTRIGHT + 1, curY + PILOTHEIGHT + 1 };
  622. drawEmptyRect( tmpRect, SCROLLCOLOR, SCROLLCOLOR );
  623. float right = SCROLLLEFT;
  624. float top = curY + PILOTHEIGHT/2 - height/2;
  625. float bottom = top + height;
  626. // draw the name of the pilot
  627. char deadPilotName[256];
  628. cLoadString( IDS_NOPILOT, deadPilotName, 255 );
  629. capHeader = pWarrior->active() ? pWarrior->getName() : deadPilotName;
  630. componentFont.render( capHeader, PILOTNAMELEFT, top, right - PILOTNAMELEFT, bottom - top, 0xff005392, 0, 0 );
  631. }
  632. curY += PILOTHEIGHT;
  633. curY += SECTIONSKIP;
  634. }
  635. curY += SECTIONSKIP;
  636. int rank = pWarrior->getRank();
  637. int skills[2] = { MWS_GUNNERY, MWS_PILOTING };
  638. char buffer[256];
  639. //ACE not continguous with other ranks. Added too late!
  640. if (rank != 4)
  641. cLoadString( IDS_GREEN + rank, buffer, 256 );
  642. else
  643. cLoadString( IDS_ACE, buffer, 256 );
  644. if ( curY > NAMETOP )
  645. {
  646. componentFont.render( buffer, SKILLLEFT, curY, SCROLLLEFT - SKILLLEFT, height, 0xff005392, 0, 0 );
  647. }
  648. int currentSkill = rank;
  649. for ( j = 0; j < 3; j ++ )
  650. {
  651. gos_VERTEX v[4];
  652. float height = skillInfos[currentSkill].location[1].y - skillInfos[currentSkill].location[0].y;
  653. for ( i = 0; i < 4; i++ )
  654. {
  655. v[i] = skillInfos[currentSkill].location[i];
  656. v[i].y = curY;
  657. v[i].rhw = .5;
  658. }
  659. v[1].y = v[2].y = curY + height;
  660. if ( curY > NAMETOP )
  661. {
  662. GUI_RECT tmpRect = { v[0].x - .5, v[0].y - .5, v[2].x + 1.5, v[2].y + 1.5 };
  663. drawEmptyRect( tmpRect, 0xff002f55, 0xff002f55 );
  664. unsigned long gosID = mcTextureManager->get_gosTextureHandle( skillInfos[currentSkill].textureHandle );
  665. gos_SetRenderState( gos_State_Texture, gosID );
  666. gos_DrawQuads( v, 4 );
  667. if ( j != 0 )
  668. {
  669. int skill = pWarrior->getSkill( skills[j-1] );
  670. drawSkillBar( skill, curY, height );
  671. }
  672. }
  673. curY += height;
  674. curY += SECTIONSKIP;
  675. currentSkill = j + 5;
  676. }
  677. for ( i = 0; i < NUM_SPECIALTY_SKILLS; i++ )
  678. {
  679. if ( pWarrior->specialtySkills[i] )
  680. {
  681. if ( curY > NAMETOP )
  682. {
  683. cLoadString( IDS_SPECIALTY + i, buffer, 256 );
  684. componentFont.render( buffer, NAMELEFT, curY, NAMERIGHT - NAMELEFT, height, 0xff005392, 0, 0 );
  685. }
  686. curY += height;
  687. }
  688. }
  689. }
  690. else
  691. curY += 10 * SECTIONSKIP;
  692. if ( infoLength == 0 )
  693. infoLength = curY - SCROLLTOP - ( SCROLLBOTTOM - SCROLLTOP );
  694. }
  695. void InfoWindow::handleClick( int ID )
  696. {
  697. switch( ID )
  698. {
  699. case SCROLLUP:
  700. setScrollPos( scrollPos - SCROLLAMOUNT );
  701. break;
  702. case SCROLLDOWN:
  703. setScrollPos( scrollPos + SCROLLAMOUNT );
  704. break;
  705. }
  706. }
  707. void InfoWindow::drawDivider( float yVal )
  708. {
  709. gos_VERTEX v[2];
  710. // gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha );
  711. gos_SetRenderState( gos_State_Specular,FALSE );
  712. gos_SetRenderState( gos_State_AlphaTest, 0 );
  713. gos_SetRenderState( gos_State_Texture, 0 );
  714. gos_SetRenderState( gos_State_Filter, gos_FilterNone );
  715. memset( v, 0, sizeof( gos_VERTEX ) * 2 );
  716. for ( int i = 0; i < 2; i++ )
  717. v[i].rhw = .5f;
  718. v[0].x = DIVIDERLEFT;
  719. v[0].y = v[1].y = yVal;
  720. v[1].x = DIVIDERRIGHT;
  721. v[0].argb = v[1].argb = DIVIDERCOLOR;
  722. gos_DrawLines( v, 2 );
  723. }
  724. void InfoWindow::drawSkillBar( int skill, float yVal, float height )
  725. {
  726. float left = InfoWindow::SKILLLEFT;
  727. float right = InfoWindow::SKILLRIGHT;
  728. int barCount = skill/InfoWindow::NUMBERSKILLBARS;
  729. int redIncrement = 0;
  730. int greenIncrement = 0;
  731. int blueIncrement = 0;
  732. if ( barCount )
  733. {
  734. redIncrement = (205/barCount) << 16;
  735. greenIncrement = ((234-83)/barCount) << 8;
  736. blueIncrement = (255 - 146)/barCount;
  737. }
  738. unsigned long color = 0xff005392;
  739. GUI_RECT outSideRect = { left - SKILLSKIP + .5, yVal - .5, right + SKILLSKIP + .5, yVal + height + 1.5};
  740. drawRect( outSideRect, 0xff000000 );
  741. GUI_RECT rect = { left + InfoWindow::SKILLSKIP, yVal + InfoWindow::SKILLSKIP + .5,
  742. left + InfoWindow::SKILLSKIP + SKILLUNITWIDTH, yVal + height - InfoWindow::SKILLSKIP + .5 };
  743. drawEmptyRect( outSideRect, 0xff002f55, 0xff002f55 );
  744. for ( int i = 0; i < barCount; i++ )
  745. {
  746. drawRect( rect, color );
  747. color += redIncrement;
  748. color += greenIncrement;
  749. color += blueIncrement;
  750. rect.left += SKILLUNITWIDTH + 1;
  751. rect.right = rect.left + SKILLUNITWIDTH;
  752. }
  753. char buffer[32];
  754. sprintf( buffer, "%ld", skill );
  755. componentFont.render( buffer, SKILLRIGHT+2, yVal, SCROLLLEFT - SKILLRIGHT - 2, SKILLHEIGHT, 0xff005392, 0, 0 );
  756. }
  757. void InfoWindow::setScrollPos( int where )
  758. {
  759. if ( where < 0 )
  760. scrollPos = 0;
  761. else if ( where > SCROLLMAX - SCROLLMIN )
  762. scrollPos = SCROLLMAX - SCROLLMIN;
  763. else
  764. scrollPos = where;
  765. }
  766. //*************************************************************************************************
  767. // end of file ( InfoWindow.cpp )