controlGui.cpp 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200
  1. /*************************************************************************************************\
  2. controlGui.cpp : Implementation of the controlGui component.
  3. //---------------------------------------------------------------------------//
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. //===========================================================================//
  6. \*************************************************************************************************/
  7. #include "controlGui.h"
  8. #include "Team.h"
  9. #include "gamesound.h"
  10. #include "comndr.h"
  11. #ifndef MULTPLYR_H
  12. #include "multplyr.h"
  13. #endif
  14. #ifndef GAMETACMAP_H
  15. #include "GameTacMap.h"
  16. #endif
  17. #ifndef LOGISTICSDATA_H
  18. #include "LogisticsData.h"
  19. #endif
  20. #ifndef PAUSEWINDOW_H
  21. #include "PauseWindow.h"
  22. #endif
  23. #include "Objective.h"
  24. #include "mission.h"
  25. #include "infoWindow.h"
  26. #include "txmmgr.h"
  27. #include "..\resource.h"
  28. #include "malloc.h"
  29. #include "ChatWindow.h"
  30. ControlGui* ControlGui::instance = 0;
  31. extern long helpTextHeaderID;
  32. extern long helpTextID;
  33. extern bool neverEndingStory;
  34. ButtonData* ControlGui::buttonData = NULL;
  35. ButtonData* ControlGui::vehicleData = NULL;
  36. long ControlGui::hiResOffsetX = 0;
  37. long ControlGui::hiResOffsetY = 0;
  38. long ControlGui::OBJECTIVESTOP= 0;
  39. long ControlGui::OBJECTIVESLEFT= 0;
  40. long ControlGui::OBJECTIVESSKIP= 0;
  41. long ControlGui::OBJECTIVESTOTALRIGHT= 0;
  42. long ControlGui::OBJEECTIVESHEADERSKIP= 0;
  43. long ControlGui::OBJECTIVESHEADERTOP= 0;
  44. long ControlGui::OBJECTIVEBOXX= 0;
  45. long ControlGui::OBJECTIVEBOXSKIP= 0;
  46. long ControlGui::OBJECTIVECHECKSKIP= 0;
  47. long ControlGui::OBJECTIVEHEADERLEFT = 0;
  48. long ControlGui::HELPAREA_LEFT = 0;
  49. long ControlGui::HELPAREA_BOTTOM = 0;
  50. long ControlGui::RPLEFT = 0;
  51. long ControlGui::RPTOP = 0;
  52. extern bool useLeftRightMouseProfile;
  53. extern bool drawGUIOn; //Used to shut off GUI for Screen Shots and Movie Mode
  54. extern bool paintingMyVtol;
  55. #define TEXT_SKIP 5.f * Environment.screenHeight/600.f
  56. #define CHAT_DISPLAY_TIME 30
  57. int __cdecl sortStats( const void* pPlayer1, const void* pPlayer2 );
  58. long ControlGui::vehicleCosts[LAST_VEHICLE] =
  59. {
  60. 7000,
  61. 8000,
  62. 2000,
  63. 6000,
  64. 2000,
  65. 4000,
  66. 10000,
  67. 0
  68. };
  69. const char* ControlGui::vehicleNames[5] = {
  70. "repairTruck",
  71. "scout",
  72. "minelayer",
  73. "pv20600",
  74. "guardTower"// needs to be recovery
  75. };
  76. long ControlGui::vehicleIDs[5] =
  77. {
  78. 182,
  79. 393,
  80. 120,
  81. 147,
  82. 415
  83. };
  84. const char* ControlGui::vehiclePilots[5] =
  85. {
  86. "PMWRepair",
  87. "PMWScout",
  88. "PMWMinelayer",
  89. "PMWRecover",
  90. "PMWGuardTower"
  91. };
  92. unsigned long ControlGui::WALK = 0;
  93. unsigned long ControlGui::RUN = 0x01;
  94. unsigned long ControlGui::GUARD = 0x02;
  95. unsigned long ControlGui::JUMP = 0x04;
  96. MoveInfo ControlGui::objectiveMoveInfo[OBJECTVE_MOVE_COUNT] =
  97. {
  98. 0.0f,-640,
  99. 0.0f, 0
  100. };
  101. MoveInfo ControlGui::missionResultsMoveInfo[RESULTS_MOVE_COUNT] =
  102. {
  103. 0.0f, -65,
  104. 0.16f, 0,
  105. 0.24f, -10
  106. };
  107. ControlGui::ControlGui()
  108. {
  109. gosASSERT( !instance );
  110. instance = this;
  111. idToUnPress = -1;
  112. renderObjectives = 0;
  113. addingVehicle = 0;
  114. addingArtillery = 0;
  115. addingSalvage = 0;
  116. wasLayingMines = 0;
  117. bMovie = NULL;
  118. moviePlaying = 0;
  119. helpTextHeaderID = 0;
  120. helpTextID = 0;
  121. rectInfos = NULL;
  122. rectCount = NULL;
  123. staticInfos = 0;
  124. staticCount = 0;
  125. buttons = 0;
  126. buttonData = 0;
  127. vehicleButtons = 0;
  128. vehicleData = 0;
  129. videoInfos = 0;
  130. videoInfoCount = 0;
  131. timerInfos = 0;
  132. timerInfoCount = 0;
  133. curOrder = 0;
  134. fireFromCurrentPos = 0;
  135. pauseWnd = new PauseWindow;
  136. renderStatusInfo = 0;
  137. missionStatusInfos = 0;
  138. objectiveTime = 0.0f;
  139. infoWnd = 0;
  140. bChatting = 0;
  141. if ( !infoWnd )
  142. {
  143. infoWnd = new InfoWindow;
  144. }
  145. objectiveInfos = 0;
  146. swapResolutions( Environment.screenWidth );
  147. resultsTime = 0;
  148. twoMinWarningPlayed = false;
  149. thirtySecondWarningPlayed = false;
  150. tabFlashTime = 0;
  151. memset( chatInfos, 0, MAX_CHAT_COUNT * sizeof ( ChatInfo ) );
  152. chatEdit.text.SetBufferSize( 512 );
  153. playerNameEdit.setBufferSize( 16 ); // pre - alloc
  154. buttonToPress = -1;
  155. rpNumFlashes = 0;
  156. rpFlashTime = 0.0f;
  157. chatIsTeamOnly = 0;
  158. bServerWarningShown = 0;
  159. }
  160. ControlGui::~ControlGui()
  161. {
  162. if ( staticInfos )
  163. delete [] staticInfos;
  164. staticInfos = 0;
  165. if ( videoInfos )
  166. delete [] videoInfos;
  167. if ( objectiveInfos )
  168. delete [] objectiveInfos;
  169. if ( timerInfos )
  170. delete [] timerInfos;
  171. timerInfos = 0;
  172. if ( rectInfos )
  173. delete [] rectInfos;
  174. rectInfos = 0;
  175. if ( buttonData )
  176. delete [] buttonData;
  177. buttonData = 0;
  178. if ( buttons )
  179. delete [] buttons;
  180. buttons = 0;
  181. if ( infoWnd )
  182. delete infoWnd;
  183. infoWnd = 0;
  184. if ( pauseWnd )
  185. delete pauseWnd;
  186. pauseWnd = 0;
  187. if ( vehicleButtons )
  188. delete [] vehicleButtons;
  189. vehicleButtons = 0;
  190. if ( vehicleData )
  191. delete [] vehicleData;
  192. vehicleData = 0;
  193. if ( missionStatusInfos )
  194. delete [] missionStatusInfos;
  195. missionStatusInfos = 0;
  196. instance = NULL;
  197. if (bMovie)
  198. {
  199. delete bMovie;
  200. bMovie = NULL;
  201. }
  202. }
  203. bool ControlGui::pushButton (long buttonId)
  204. {
  205. buttonToPress = buttonId;
  206. //I KNOW its hard-coded, OK?
  207. if ((buttonId >= 12) && (buttonId <= 14))
  208. {
  209. //Unpress TacMap if we didn't want to press that.
  210. if ((buttonId != 12) && getButton(12)->state & ControlButton::PRESSED)
  211. getButton(12)->press(false);
  212. //Unpress Info Button if we didn't want to press that.
  213. if ((buttonId != 13) && getButton(13)->state & ControlButton::PRESSED)
  214. getButton(13)->press(false);
  215. //Unpress VehicleTab if we didn't want to press that.
  216. if ((buttonId != 14) && getButton(14)->state & ControlButton::PRESSED)
  217. getButton(14)->press(false);
  218. }
  219. return true;
  220. }
  221. bool ControlGui::flashRPTotal (long numFlashes)
  222. {
  223. rpNumFlashes = numFlashes;
  224. rpFlashTime = 0.0f;
  225. return true;
  226. }
  227. bool ControlGui::animateTacMap (long buttonId,float timeToScroll,long numFlashes)
  228. {
  229. return tacMap.animate(abs(buttonId), numFlashes);
  230. }
  231. void ControlGui::render( bool bPaused )
  232. {
  233. if (drawGUIOn)
  234. {
  235. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha );
  236. gos_SetRenderState( gos_State_Specular,FALSE );
  237. gos_SetRenderState( gos_State_AlphaTest, TRUE );
  238. gos_SetRenderState( gos_State_Filter, gos_FilterNone );
  239. gos_SetRenderState( gos_State_ZWrite, 0 );
  240. gos_SetRenderState( gos_State_ZCompare, 0 );
  241. for ( int i = 0; i < rectCount; i++ )
  242. {
  243. drawRect( rectInfos[i].rect, rectInfos[i].color );
  244. }
  245. if ( getButton( TACMAP_TAB )->state & ControlButton::PRESSED )
  246. tacMap.render();
  247. else if ( getButton( VEHICLE_TAB )->state & ControlButton::PRESSED )
  248. renderVehicleTab();
  249. else
  250. renderInfoTab();
  251. for ( i = 0; i < staticCount; i++ )
  252. {
  253. staticInfos[i].render();
  254. }
  255. forceGroupBar.render();
  256. renderHelpText();
  257. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero );
  258. for ( i = 0; i < LAST_COMMAND; ++i )
  259. buttons[i].render();
  260. // want to draw the tab on top last
  261. for ( i = TACMAP_TAB; i < TACMAP_TAB + 3; i++ )
  262. {
  263. if ( (getButton( i )->state) & ControlButton::PRESSED )
  264. {
  265. buttons[i].render();
  266. }
  267. }
  268. getButton( LAYMINES )->render();
  269. RenderObjectives();
  270. }
  271. if ( moviePlaying && bMovie)
  272. {
  273. for ( int i = 0; i < videoInfoCount; i++ )
  274. videoInfos[i].render();
  275. bMovie->render();
  276. }
  277. if (drawGUIOn)
  278. {
  279. // draw the mission timer if we have one
  280. if ( mission->m_timeLimit > 0 )
  281. {
  282. float fTime = (float)mission->m_timeLimit - scenarioTime;
  283. int time = (int)fTime;
  284. if ( time <= 120 && !twoMinWarningPlayed )
  285. {
  286. twoMinWarningPlayed = true;
  287. soundSystem->playBettySample( BETTY_TWO_MIN_LEFT );
  288. }
  289. else if ( time <= 30 && !thirtySecondWarningPlayed )
  290. {
  291. thirtySecondWarningPlayed = true;
  292. soundSystem->playBettySample( BETTY_THIRTY_LEFT );
  293. }
  294. else if ( time < 0)
  295. {
  296. time = 0;
  297. }
  298. char buffer[32];
  299. unsigned long minutes = time/60;
  300. unsigned long seconds = time%60;
  301. sprintf( buffer, "%03ld : %02ld", minutes, seconds );
  302. unsigned long color = timerRect.color;
  303. if ( minutes < 5 )
  304. {
  305. color = 0xffc61c00;
  306. if ( minutes < 2 )
  307. {
  308. if ( seconds % 2 )
  309. {
  310. color = 0;
  311. }
  312. }
  313. }
  314. long width = timerFont.width( buffer );
  315. drawShadowText( color, 0x00000000, timerFont.getTempHandle(),
  316. timerRect.rect.left - width, timerRect.rect.top, true,
  317. buffer, 0, guiFont.getSize() );
  318. for (long i = 0; i < timerInfoCount; i++ )
  319. timerInfos[i].render();
  320. }
  321. if ( bPaused )
  322. pauseWnd->render();
  323. if ((!MPlayer && (Team::home->objectives.Count() != 0) && (Team::home->objectives.Status() != OS_UNDETERMINED))
  324. || mission->terminationCounterStarted)
  325. {
  326. if ( !resultsTime )
  327. resultsTime = .001f;
  328. renderStatusInfo = 1;
  329. }
  330. renderResults();
  331. renderChatText();
  332. //l XLocation = 80
  333. //l YLocation = 505
  334. //l Width = 41
  335. //l Height = 34
  336. //l Color = 0xff000000
  337. //b outline = FALSE
  338. // flash the rp tab if we just got kudos
  339. if ( LogisticsData::instance->rpJustAdded )
  340. {
  341. tabFlashTime += frameLength;
  342. if ( tabFlashTime > .5 )
  343. {
  344. tabFlashTime = 0;
  345. }
  346. else if ( tabFlashTime > .25 )
  347. {
  348. float scaleX = Environment.screenWidth <= 1024 ? Environment.screenWidth : 1024;
  349. float scaleY = Environment.screenHeight <= 768 ? Environment.screenHeight : 768;
  350. GUI_RECT rect = { 51 * scaleX/640.f + ControlGui::hiResOffsetX, 317 * scaleY/480.f + ControlGui::hiResOffsetY,
  351. 74 *scaleX/640.f + ControlGui::hiResOffsetX, 337 * scaleY/480.f + ControlGui::hiResOffsetY};
  352. drawRect( rect, 0xff000000 );
  353. }
  354. }
  355. }
  356. }
  357. void ControlGui::startObjectives( bool bStart )
  358. {
  359. if ( !renderObjectives )
  360. objectiveTime = 0.f;
  361. else if ( renderStatusInfo ) // reset timer, if we are in results land
  362. objectiveTime = objectiveMoveInfo[OBJECTVE_MOVE_COUNT-1].time;
  363. renderObjectives = bStart;
  364. if ( MPlayer )
  365. {
  366. MPlayer->calcPlayerRanks();
  367. bool scoreShown[MAX_MC_PLAYERS]; // keep track of whose shown the score
  368. memset( scoreShown, 0, sizeof( bool ) * MAX_MC_PLAYERS );
  369. long playerCount = 0;
  370. const MC2Player* players = MPlayer->getPlayers(playerCount);
  371. const MC2Player* sorted[MAX_MC_PLAYERS];
  372. for ( int j = 0; j < playerCount; j++ )
  373. {
  374. sorted[j] = &players[j];
  375. }
  376. qsort( sorted, playerCount, sizeof( MC2Player* ), sortStats );
  377. mpStats[0].setData( NULL, 1 ); // this is the header...
  378. for ( int i = 1; i < MAX_MC_PLAYERS+1; i++ )
  379. {
  380. if ( i-1 < playerCount )
  381. {
  382. mpStats[i].setData( sorted[i-1], !scoreShown[sorted[i-1]->team] );
  383. scoreShown[sorted[i-1]->team] = true;
  384. mpStats[i].showGUIWindow( true );
  385. }
  386. else
  387. mpStats[i].showGUIWindow( 0 );
  388. }
  389. }
  390. };
  391. void ControlGui::renderResults()
  392. {
  393. if ( renderStatusInfo )
  394. {
  395. if ( infoWnd ) // kill info wnd stuff
  396. infoWnd->setUnit( NULL );
  397. resultsTime += frameLength;
  398. float t0, t1, p0, p1;
  399. t1 = p1 = t0 = p0 = 0.f;
  400. float delta = 0.f;
  401. // figure out where we are in animation
  402. for ( int j = 0; j < RESULTS_MOVE_COUNT - 1; j++ )
  403. {
  404. if ( missionResultsMoveInfo[j].time <= resultsTime && missionResultsMoveInfo[j+1].time > resultsTime )
  405. {
  406. t0 = missionResultsMoveInfo[j].time;
  407. t1 = missionResultsMoveInfo[j + 1].time;
  408. p0 = (missionResultsMoveInfo[j].position) * ((float)Environment.screenWidth)/640.f;
  409. p1 = (missionResultsMoveInfo[j + 1].position) * ((float)Environment.screenWidth)/640.f;
  410. break;
  411. }
  412. }
  413. // if not done yet
  414. if ( t1 )
  415. {
  416. float dT = resultsTime - t0;
  417. float currentPosition = p0 + dT * ( (p1 - p0)/(t1 -t0) );
  418. delta = currentPosition - missionStatusInfos[0].location[0].y;
  419. }
  420. else
  421. {
  422. delta = missionResultsMoveInfo[OBJECTVE_MOVE_COUNT - 1].position - missionStatusInfos[0].location[0].y;
  423. // grey down the screen
  424. GUI_RECT rect = { 0, 0, Environment.screenWidth, Environment.screenHeight };
  425. drawEmptyRect( rect, 0x44000000 );
  426. if ( resultsTime < missionResultsMoveInfo[OBJECTVE_MOVE_COUNT - 1].time + .25 )
  427. startObjectives( 1 );
  428. }
  429. for ( int i = 0; i < missionStatusInfoCount; i++ )
  430. {
  431. missionStatusInfos[i].move( 0, delta );
  432. missionStatusInfos[i].render();
  433. }
  434. missionStatusRect.rect.top += delta;
  435. missionStatusRect.rect.bottom += delta;
  436. char text[256];
  437. if ( Team::home->objectives.Status() == OS_SUCCESSFUL )
  438. cLoadString( IDS_MISSION_SUCCESS, text, 256 );
  439. else
  440. cLoadString( IDS_MISSION_FAILED, text, 256 );
  441. if ( MPlayer )
  442. {
  443. if ( MPlayer->playerInfo[MPlayer->commanderID].winner )
  444. cLoadString( IDS_MISSION_SUCCESS, text, 256 );
  445. else
  446. cLoadString( IDS_MISSION_FAILED, text, 256 );
  447. }
  448. gos_TextDrawBackground( missionStatusRect.rect.left, missionStatusRect.rect.top, missionStatusRect.rect.right,
  449. missionStatusRect.rect.bottom, 0xff000000 );
  450. missionResultsFont.render( text, missionStatusRect.rect.left, missionStatusRect.rect.top,
  451. missionStatusRect.rect.right - missionStatusRect.rect.left,
  452. missionStatusRect.rect.bottom - missionStatusRect.rect.top,
  453. missionStatusRect.color,
  454. 0, 3 );
  455. float fadeTime = objectiveTime - objectiveMoveInfo[OBJECTVE_MOVE_COUNT - 1].time - 3.0f
  456. - Team::home->objectives.Count();
  457. if ( !neverEndingStory && (fadeTime > 0.f) )
  458. {
  459. long color = interpolateColor( 0x00000000, 0xff000000, fadeTime/1.0f );
  460. GUI_RECT rect = { 0,0, Environment.screenWidth, Environment.screenHeight };
  461. drawRect( rect, color );
  462. }
  463. }
  464. }
  465. bool playedObjectiveClick[100];
  466. void ControlGui::RenderObjectives()
  467. {
  468. // make sure we need to do it.
  469. if ( renderObjectives || renderStatusInfo )
  470. {
  471. if ( renderStatusInfo )
  472. {
  473. if ( resultsTime < .24f ) // don't start objectives until mission results is done
  474. {
  475. memset(playedObjectiveClick,0,sizeof(bool) * 100);
  476. return;
  477. }
  478. }
  479. objectiveTime += frameLength;
  480. float t0, t1, p0, p1;
  481. t1 = p1 = t0 = p0 = 0.f;
  482. float delta = 0.f;
  483. // figure out where we are in animation
  484. for ( int j = 0; j < OBJECTVE_MOVE_COUNT - 1; j++ )
  485. {
  486. if ( objectiveMoveInfo[j].time <= objectiveTime && objectiveMoveInfo[j+1].time > objectiveTime )
  487. {
  488. t0 = objectiveMoveInfo[j].time;
  489. t1 = objectiveMoveInfo[j + 1].time;
  490. p0 = (objectiveMoveInfo[j].position) * ((float)Environment.screenWidth)/640.f;
  491. p1 = (objectiveMoveInfo[j + 1].position) * ((float)Environment.screenWidth)/640.f;
  492. break;
  493. }
  494. }
  495. // if not done yet
  496. if ( t1 )
  497. {
  498. float dT = objectiveTime - t0;
  499. float currentPosition = p0 + dT * ( (p1 - p0)/(t1 -t0) );
  500. delta = currentPosition - objectiveInfos[0].location[0].x;
  501. }
  502. else
  503. {
  504. delta = objectiveMoveInfo[OBJECTVE_MOVE_COUNT - 1].position - objectiveInfos[0].location[0].x;
  505. }
  506. // draw little edge pieces
  507. for ( int i = 0; i < objectiveInfoCount - 3; i++ )
  508. {
  509. objectiveInfos[i].move( delta, 0 );
  510. objectiveInfos[i].render();
  511. }
  512. if ( delta )
  513. {
  514. OBJECTIVEHEADERLEFT += delta;
  515. OBJECTIVESLEFT += delta;
  516. }
  517. if ( MPlayer && MPlayer->missionSettings.missionType != MISSION_TYPE_OTHER )
  518. {
  519. renderPlayerStatus(delta);
  520. return;
  521. }
  522. // draw "Primary"
  523. char buffer[256];
  524. cLoadString( IDS_PRIMARY, buffer, 245 );
  525. drawShadowText( 0xffffffff, 0xff000000, guiFont.getTempHandle(), OBJECTIVEHEADERLEFT, OBJECTIVESTOP, 1, buffer, 0,
  526. guiFont.getSize() );
  527. // draw primary objectives
  528. unsigned long pos = OBJECTIVESTOP;
  529. pos+= OBJECTIVESSKIP;
  530. float objectiveCount = -objectiveMoveInfo[OBJECTVE_MOVE_COUNT-1].time;
  531. int sum = 0;
  532. int objectiveNum = 0;
  533. for ( EList< CObjective*, CObjective* >::EIterator iter = Team::home->objectives.Begin();
  534. !iter.IsDone(); iter++ )
  535. {
  536. if ( ((*iter)->IsActive()) && (!(*iter)->IsHiddenTrigger()) && (1 == (*iter)->Priority()) )
  537. {
  538. bool bTotal = renderStatusInfo && objectiveCount < objectiveTime; // drawing one per second
  539. renderObjective( (*iter), OBJECTIVESLEFT, pos, bTotal );
  540. if ( (*iter)->Status(Team::home->objectives) == OS_SUCCESSFUL && bTotal )
  541. {
  542. sum += (*iter)->ResourcePoints();
  543. if (!playedObjectiveClick[objectiveNum])
  544. {
  545. playedObjectiveClick[objectiveNum] = true;
  546. soundSystem->playDigitalSample(LOG_KILLMARKER);
  547. }
  548. }
  549. pos += OBJECTIVESSKIP;
  550. objectiveCount += 1.f;
  551. objectiveNum++;
  552. }
  553. }
  554. pos -= OBJECTIVESSKIP;
  555. // draw "Secondary"
  556. cLoadString( IDS_SECONDARY, buffer, 245 );
  557. pos += OBJEECTIVESHEADERSKIP;
  558. drawShadowText( 0xffffffff, 0xff000000, guiFont.getTempHandle(), OBJECTIVEHEADERLEFT, pos, 1, buffer, 0,
  559. guiFont.getSize() );
  560. // draw secondary objectives
  561. for ( iter = Team::home->objectives.Begin();
  562. !iter.IsDone(); iter++ )
  563. {
  564. if ( ((*iter)->IsActive()) && (!(*iter)->IsHiddenTrigger()) && (!(1 == (*iter)->Priority())) )
  565. {
  566. pos += OBJECTIVESSKIP;
  567. bool bTotal = renderStatusInfo && objectiveCount < objectiveTime; // drawing one per second
  568. renderObjective( (*iter), OBJECTIVESLEFT, pos, bTotal );
  569. if ( (*iter)->Status(Team::home->objectives) == OS_SUCCESSFUL && bTotal )
  570. {
  571. sum += (*iter)->ResourcePoints();
  572. if (!playedObjectiveClick[objectiveNum])
  573. {
  574. playedObjectiveClick[objectiveNum] = true;
  575. soundSystem->playDigitalSample(LOG_KILLMARKER);
  576. }
  577. }
  578. objectiveCount += 1.f;
  579. objectiveNum++;
  580. }
  581. }
  582. if ( renderStatusInfo ) // draw the total
  583. {
  584. pos += OBJECTIVESSKIP;
  585. char total[256];
  586. char total2[256];
  587. cLoadString( IDS_TOTAL, total2, 255 );
  588. sprintf( total, total2, sum );
  589. unsigned long width = guiFont.width( total );
  590. drawShadowText( 0xffffffff, 0xff000000, guiFont.getTempHandle(), OBJECTIVESTOTALRIGHT - width, pos, 0, total,
  591. 0, guiFont.getSize() );
  592. }
  593. }
  594. }
  595. void ControlGui::renderPlayerStatus(float xDelta)
  596. {
  597. bool scoreShown[MAX_MC_PLAYERS]; // keep track of whose shown the score
  598. memset( scoreShown, 0, sizeof( bool ) * MAX_MC_PLAYERS );
  599. MPlayer->calcPlayerRanks();
  600. long playerCount = 0;
  601. const MC2Player* players = MPlayer->getPlayers(playerCount);
  602. const MC2Player* sorted[MAX_MC_PLAYERS];
  603. for ( int j = 0; j < playerCount; j++ )
  604. {
  605. sorted[j] = &players[j];
  606. }
  607. qsort( sorted, playerCount, sizeof( MC2Player* ), sortStats );
  608. mpStats[0].setData( NULL, 1 ); // this is the header...
  609. for ( int i = 1; i < MAX_MC_PLAYERS+1; i++ )
  610. {
  611. if ( i-1 < playerCount )
  612. {
  613. mpStats[i].setData( sorted[i-1], !scoreShown[sorted[i-1]->team] );
  614. scoreShown[sorted[i-1]->team] = true;
  615. mpStats[i].showGUIWindow( true );
  616. }
  617. else
  618. mpStats[i].showGUIWindow( 0 );
  619. }
  620. GUI_RECT rect = { mpStats[0].left()-5+xDelta, mpStats[0].top()-5,
  621. mpStats[0].right()+5+xDelta, mpStats[0].bottom()+5};
  622. for ( i = 1; i < 9; i++ )
  623. {
  624. if ( mpStats[i].isShowing() )
  625. rect.bottom += mpStats[0].height() + 4;
  626. }
  627. drawRect( rect, 0x7f000000 );
  628. for ( i = 0; i < 9; i++ )
  629. {
  630. mpStats[i].render( xDelta, ((i) * (mpStats[0].height() + 4) ));
  631. }
  632. /* long xLocs[4] = { mpStats[0].getPlayerHeadingX(),
  633. mpStats[0].getRankingX(),
  634. mpStats[0].getKillsX(),
  635. mpStats[0].getLossesX()
  636. };
  637. long textIDs[4] = { IDS_MP_STATS_PLAYER_NAME,
  638. IDS_MP_STATS_SCORE,
  639. IDS_MP_STATS_KILLS,
  640. IDS_MP_STATS_LOSSES
  641. };
  642. char text[256];
  643. for ( i = 0; i < 4; i++ )
  644. {
  645. cLoadString( textIDs[i], text, 255 );
  646. drawShadowText( 0xffffffff, 0xff000000, missionResultsFont.getTempHandle(),
  647. xLocs[i] + OBJECTIVEHEADERLEFT, OBJECTIVESTOP, 1, text, 0, 1 );
  648. }*/
  649. }
  650. void ControlGui::renderObjective( CObjective* pObjective, long xPos, long yPos, bool bDrawTotal )
  651. {
  652. // draw description
  653. long color = pObjective->Status(Team::home->objectives) == OS_FAILED ? 0xffc61c00 :
  654. ( pObjective->Status(Team::home->objectives) == OS_SUCCESSFUL ? 0xff41c700 : 0xffffc600 );
  655. gosASSERT(pObjective->IsActive());
  656. if (pObjective->ActivateOnFlag() && (20.0/*seconds*//*arbitrary*/ > (mission->actualTime - pObjective->ActivationTime())))
  657. {
  658. /* flash the objective text */
  659. int tempI = (int)(2.0/*Hz*//*flash frequency*/ * (mission->actualTime - pObjective->ActivationTime()));
  660. int parity = (tempI % 2);
  661. if (0 == parity)
  662. {
  663. color = 0xffffffff;
  664. }
  665. }
  666. drawShadowText( color, 0xff000000, guiFont.getTempHandle(), xPos, yPos, 1, pObjective->LocalizedDescription(), 0,
  667. guiFont.getSize() );
  668. if ( bDrawTotal )
  669. {
  670. /*these used to be declared as unsigned, but mixing signed and unsigned values
  671. in arithmetic expressions can be bad news if any intermediate result is negative */
  672. long width, height;
  673. long descWidth;
  674. long dotWidth;
  675. char total[64];
  676. int amount = pObjective->Status(Team::home->objectives) == OS_SUCCESSFUL ? pObjective->ResourcePoints() : 0;
  677. sprintf( total, "%ld", amount );
  678. width = guiFont.width( total );
  679. // draw total
  680. drawShadowText( 0xffffffff, 0xff000000, guiFont.getTempHandle(), OBJECTIVESTOTALRIGHT - width, yPos, 0, total, 0,
  681. guiFont.getSize() );
  682. // draw .............
  683. unsigned long tmpULong1, tmpULong2;
  684. gos_TextStringLength( &tmpULong1, &tmpULong2, pObjective->LocalizedDescription() );
  685. descWidth = (int)tmpULong1;
  686. height = (int)tmpULong2;
  687. gos_TextStringLength( &tmpULong1, &tmpULong2, "...................." );
  688. dotWidth = (int)tmpULong1;
  689. height = (int)tmpULong2;
  690. gosASSERT(0 < dotWidth);
  691. float dotRealWidth = (((float)dotWidth)/20.f);
  692. float totalLength = (OBJECTIVESTOTALRIGHT - width - xPos - descWidth);
  693. long numberOfDots = ((float)totalLength)/dotRealWidth;
  694. if (3 > numberOfDots)
  695. {
  696. numberOfDots = 3;
  697. }
  698. char* dots = (char*)_alloca( sizeof( char ) * (numberOfDots+1) );
  699. for ( int i = 0; i < numberOfDots - 2; i++ )
  700. dots[i] = '.';
  701. dots[i] = 0;
  702. float dotFinalLength = dotRealWidth * (float)(numberOfDots - 2);
  703. drawShadowText( color, 0xff000000, guiFont.getTempHandle(), OBJECTIVESTOTALRIGHT - width - dotFinalLength, yPos, 0, dots,
  704. 0, guiFont.getSize() );
  705. }
  706. // draw little boxes and check marks
  707. float height = objectiveInfos[objectiveInfoCount-3].location[2].y - objectiveInfos[objectiveInfoCount-3].location[0].y;
  708. objectiveInfos[objectiveInfoCount-3].location[0].y =yPos + OBJECTIVEBOXSKIP;
  709. objectiveInfos[objectiveInfoCount-3].location[3].y =yPos + OBJECTIVEBOXSKIP;
  710. objectiveInfos[objectiveInfoCount-3].location[1].y =yPos + OBJECTIVEBOXSKIP + height;
  711. objectiveInfos[objectiveInfoCount-3].location[2].y =yPos + OBJECTIVEBOXSKIP + height;
  712. int x = objectiveInfos[objectiveInfoCount-3].location[0].x;
  713. objectiveInfos[objectiveInfoCount-3].setLocation( x, yPos + OBJECTIVEBOXSKIP );
  714. objectiveInfos[objectiveInfoCount-3].render();
  715. if ( pObjective->Status(Team::home->objectives) == OS_FAILED )
  716. {
  717. float height = objectiveInfos[objectiveInfoCount-1].location[2].y - objectiveInfos[objectiveInfoCount-1].location[0].y;
  718. objectiveInfos[objectiveInfoCount-1].location[0].y =yPos + OBJECTIVECHECKSKIP;
  719. objectiveInfos[objectiveInfoCount-1].location[3].y =yPos + OBJECTIVECHECKSKIP;
  720. objectiveInfos[objectiveInfoCount-1].location[1].y =yPos + OBJECTIVECHECKSKIP + height;
  721. objectiveInfos[objectiveInfoCount-1].location[2].y =yPos + OBJECTIVECHECKSKIP + height;
  722. int x = objectiveInfos[objectiveInfoCount-1].location[0].x;
  723. objectiveInfos[objectiveInfoCount-1].setLocation( x, yPos + OBJECTIVECHECKSKIP );
  724. objectiveInfos[objectiveInfoCount-1].render();
  725. }
  726. else if ( pObjective->Status(Team::home->objectives) == OS_SUCCESSFUL )
  727. {
  728. float height = objectiveInfos[objectiveInfoCount-2].location[2].y - objectiveInfos[objectiveInfoCount-2].location[0].y;
  729. objectiveInfos[objectiveInfoCount-2].location[0].y =yPos + OBJECTIVECHECKSKIP;
  730. objectiveInfos[objectiveInfoCount-2].location[3].y =yPos + OBJECTIVECHECKSKIP;
  731. objectiveInfos[objectiveInfoCount-2].location[1].y =yPos + OBJECTIVECHECKSKIP + height;
  732. objectiveInfos[objectiveInfoCount-2].location[2].y =yPos + OBJECTIVECHECKSKIP + height;
  733. int x = objectiveInfos[objectiveInfoCount-2].location[0].x;
  734. objectiveInfos[objectiveInfoCount-2].setLocation( x, yPos + OBJECTIVECHECKSKIP );
  735. objectiveInfos[objectiveInfoCount-2].render();
  736. }
  737. }
  738. void ControlGui::update( bool bPaused, bool bLOS )
  739. {
  740. mouseInVehicleStopButton = 0;
  741. bool bMouseInButton = 0;
  742. showServerMissing();
  743. if ( bPaused )
  744. pauseWnd->update();
  745. if (moviePlaying && bMovie)
  746. {
  747. bool result = bMovie->update();
  748. if (result)
  749. {
  750. moviePlaying = false;
  751. delete bMovie;
  752. bMovie = NULL;
  753. }
  754. }
  755. //Just update the movie. DO not update anything else if in movieMode!!
  756. if (eye && eye->inMovieMode)
  757. return;
  758. if ( idToUnPress != -1 )
  759. {
  760. getButton( idToUnPress )->press( false );
  761. }
  762. float mouseX = userInput->getMouseX();
  763. float mouseY = userInput->getMouseY();
  764. // also going to initialize buttons here
  765. for ( int i = LAST_COMMAND - 1; i > -1; i-- )
  766. {
  767. if ( buttons[i].location[0].x <= mouseX && mouseX <= buttons[i].location[2].x
  768. && mouseY >= buttons[i].location[0].y && mouseY <= buttons[i].location[1].y )
  769. {
  770. if ( buttons[i].state != ControlButton::HIDDEN )
  771. {
  772. helpTextHeaderID = buttonData[i].helpTextHeader;
  773. helpTextID = buttonData[i].helpTextID;
  774. bMouseInButton = true;
  775. long lastX = mouseX - userInput->getMouseXDelta();
  776. long lastY = mouseY - userInput->getMouseYDelta();
  777. if ( buttons[i].location[0].x > lastX || lastX > buttons[i].location[2].x
  778. || lastY < buttons[i].location[0].y || lastY > buttons[i].location[1].y )
  779. {
  780. soundSystem->playDigitalSample( LOG_HIGHLIGHTBUTTONS );
  781. }
  782. }
  783. if ( userInput->leftMouseReleased() && !userInput->isLeftDrag()
  784. && !userInput->wasLeftDrag() )
  785. {
  786. {
  787. handleClick( buttons[i].ID );
  788. }
  789. }
  790. }
  791. }
  792. if ((buttonToPress != -1) && getButton(buttonToPress))
  793. {
  794. getButton(buttonToPress)->press(true);
  795. buttonToPress = -1;
  796. }
  797. // update all the attack ranges
  798. Team* pTeam = Team::home;
  799. long bMover = 0;
  800. bool bJump = 1;
  801. // if no mover is selected, disable range buttons
  802. for ( i = DEFAULT_RANGE; i < STOP_COMMAND; i++ )
  803. {
  804. buttons[i].disable( false );
  805. }
  806. bool bMineLayer = 1;
  807. bool bSalvage = 1;
  808. bool bRepair = 1;
  809. bool bGuardTower = 1;
  810. bool bPressGuardTower = 1;
  811. Mover* pSelectedMover = 0;
  812. int holdPositionCount = 0;
  813. for ( i = 0; i < pTeam->getRosterSize(); ++i )
  814. {
  815. Mover* pMover = (Mover*)pTeam->getMover( i );
  816. if ( pMover->isSelected() && pMover->getCommander()->getId() == Commander::home->getId() )
  817. {
  818. // if ( !isSelectingebject() )
  819. {
  820. bMineLayer &= ( (pMover->isMineLayer()) ? 1 : 0 );
  821. bSalvage &= ( pMover->isRecover() ? 1 : 0 );
  822. bRepair &= ( pMover->isRefit() && pMover->getRefitPoints() ? 1 : 0 );
  823. bGuardTower &= ( pMover->maxMoveSpeed ? 0 : 1 );
  824. if ( bGuardTower )
  825. bPressGuardTower &= pMover->suppressionFire;
  826. if ( pMover->getPilot()->getNumTacOrdersQueued () )
  827. getButton( STOP_COMMAND )->disable( false );
  828. switch( pMover->attackRange )
  829. {
  830. case FIRERANGE_SHORT:
  831. getButton( SHORT_RANGE )->press( true );
  832. break;
  833. case FIRERANGE_LONG:
  834. getButton( LONG_RANGE )->press( true );
  835. break;
  836. case FIRERANGE_MEDIUM:
  837. getButton( MED_RANGE )->press( true );
  838. break;
  839. case FIRERANGE_OPTIMAL:
  840. getButton( DEFAULT_RANGE )->press( true );
  841. break;
  842. case FIRERANGE_CURRENT:
  843. holdPositionCount++;
  844. break;
  845. }
  846. bJump &= pMover->canJump();
  847. pSelectedMover = pMover;
  848. bMover ++;
  849. }
  850. }
  851. }
  852. if ( !holdPositionCount )
  853. {
  854. getButton( CUR_RANGE )->press( 0 );
  855. }
  856. else if ( holdPositionCount != bMover )
  857. {
  858. getButton( CUR_RANGE )->makeAmbiguous( true );
  859. }
  860. else
  861. getButton( CUR_RANGE )->press( 1 );
  862. int rangeCount = 0;
  863. for ( i = 0; i < 4; i++ )
  864. {
  865. if ( getButton( DEFAULT_RANGE + i )->state & ControlButton::PRESSED )
  866. {
  867. rangeCount ++;
  868. }
  869. }
  870. if ( rangeCount > 1 )
  871. {
  872. for ( i = 0; i < 4; i++ )
  873. {
  874. if ( getButton( DEFAULT_RANGE + i )->state & ControlButton::PRESSED )
  875. {
  876. getButton( DEFAULT_RANGE + i )->makeAmbiguous( true );
  877. }
  878. }
  879. }
  880. // if no mover is selected, disable range buttons
  881. if ( !bMover )
  882. {
  883. for ( i = DEFAULT_RANGE; i < STOP_COMMAND; i++ )
  884. buttons[i].disable( true );
  885. }
  886. else
  887. {
  888. getButton( STOP_COMMAND )->disable( false );
  889. }
  890. if ( bMover && bMineLayer )
  891. {
  892. if ( !bMouseInButton )
  893. setRolloverHelpText( IDS_MINELAYER_HELP );
  894. getButton( LAYMINES )->disable( 0 );
  895. getButton( SALVAGE )->hide( 1 );
  896. getButton( REPAIR )->hide( 1 );
  897. getButton( GUARDTOWER )->hide( 1 );
  898. }
  899. else if ( bMover && bSalvage )
  900. {
  901. if ( !bMouseInButton )
  902. setRolloverHelpText( IDS_RECOVER_HELP );
  903. getButton( SALVAGE )->disable( 0 );
  904. getButton( SALVAGE )->press( 1 );
  905. getButton( LAYMINES )->hide( 1 );
  906. getButton( REPAIR )->hide( 1 );
  907. getButton( GUARDTOWER )->hide( 1 );
  908. wasLayingMines = 0;
  909. }
  910. else if ( bMover && bRepair )
  911. {
  912. if ( !bMouseInButton )
  913. setRolloverHelpText( IDS_REPAIR_HELP );
  914. getButton( REPAIR )->disable( 0 );
  915. getButton( REPAIR )->press( 1 );
  916. getButton( LAYMINES )->hide( 1 );
  917. getButton( SALVAGE )->hide( 1 );
  918. getButton( GUARDTOWER )->hide( 1 );
  919. wasLayingMines = 0;
  920. }
  921. else if ( bMover && bGuardTower )
  922. {
  923. getButton( REPAIR )->hide( 1 );
  924. getButton( LAYMINES )->hide( 1 );
  925. getButton( SALVAGE )->hide( 1 );
  926. getButton( GUARDTOWER )->hide( 0 );
  927. if ( bPressGuardTower )
  928. getButton( GUARDTOWER )->press( 1 );
  929. else
  930. getButton( GUARDTOWER )->press ( 0 );
  931. }
  932. else
  933. {
  934. getButton( LAYMINES )->hide( 1 );
  935. getButton( REPAIR )->hide( 1 );
  936. getButton( SALVAGE )->hide( 1 );
  937. getButton( GUARDTOWER )->hide( 1 );
  938. wasLayingMines = 0;
  939. }
  940. if ( bMover && bJump )
  941. getButton( JUMP_COMMAND )->disable( false );
  942. else
  943. getButton( JUMP_COMMAND )->disable( true );
  944. // upate all the orders
  945. if ( curOrder != WALK && bMover && !isSelectingInfoObject())
  946. {
  947. if ( curOrder == JUMP )
  948. getButton( JUMP_COMMAND )->press( true );
  949. else if ( curOrder == GUARD )
  950. getButton( GUARD_COMMAND )->press( true );
  951. else if ( curOrder == RUN )
  952. getButton( RUN_COMMAND )->press( true );
  953. }
  954. if ( fireFromCurrentPos && bMover )
  955. getButton( FIRE_FROM_CURRENT_POS )->press( true );
  956. else
  957. getButton( FIRE_FROM_CURRENT_POS )->press( false );
  958. bool bMouseInsideTacArea = 0;
  959. if ( rectInfos[0].rect.left <= userInput->getMouseX()
  960. && rectInfos[0].rect.right >= userInput->getMouseX()
  961. && rectInfos[0].rect.top <= userInput->getMouseY()
  962. && rectInfos[0].rect.bottom >= userInput->getMouseY() )
  963. {
  964. bMouseInsideTacArea = true;
  965. }
  966. if ( getButton( TACMAP_TAB )->state & ControlButton::PRESSED )
  967. {
  968. tacMap.update();
  969. if ( bMouseInsideTacArea )
  970. {
  971. helpTextHeaderID = IDS_TACMAP;
  972. helpTextID = IDS_TACMAP_DESC;
  973. }
  974. }
  975. else if ( getButton( INFO_TAB )->state & ControlButton::PRESSED )
  976. {
  977. infoWnd->update();
  978. if ( bMouseInsideTacArea )
  979. {
  980. helpTextHeaderID = IDS_INFOTAB;
  981. helpTextID = IDS_INFOTAB_DESC;
  982. }
  983. }
  984. else if ( bMouseInsideTacArea )
  985. {
  986. helpTextHeaderID = IDS_VEHICLE_TAB;
  987. helpTextID = IDS_VEHICLE_TAB_DESC;
  988. }
  989. updateVehicleTab( mouseX, mouseY, bLOS );
  990. if ( renderObjectives )
  991. getButton( OBJECTIVES_COMMAND )->press( true );
  992. else
  993. getButton( OBJECTIVES_COMMAND )->press( false );
  994. forceGroupBar.update();
  995. getButton( DEFAULT_RANGE )->hide(true);
  996. getButton( SHORT_RANGE )->hide(true);
  997. getButton( MED_RANGE )->hide(true);
  998. getButton( LONG_RANGE )->hide(true);
  999. }
  1000. bool ControlGui::isOverTacMap()
  1001. {
  1002. bool bMouseInsideTacArea = 0;
  1003. if ( rectInfos[0].rect.left <= userInput->getMouseX()
  1004. && rectInfos[0].rect.right >= userInput->getMouseX()
  1005. && rectInfos[0].rect.top <= userInput->getMouseY()
  1006. && rectInfos[0].rect.bottom >= userInput->getMouseY() )
  1007. {
  1008. bMouseInsideTacArea = true;
  1009. }
  1010. if ( getButton( TACMAP_TAB )->state & ControlButton::PRESSED )
  1011. return true;
  1012. return false;
  1013. }
  1014. bool ControlGui::inRegion( int mouseX, int mouseY, bool bPaused )
  1015. {
  1016. for ( int i = 0; i < LAST_COMMAND; i++ )
  1017. {
  1018. if ( (buttons[i].location[0].x) <= mouseX &&
  1019. buttons[i].location[3].x >= mouseX &&
  1020. buttons[i].location[0].y <= mouseY &&
  1021. buttons[i].location[1].y >= mouseY )
  1022. return true;
  1023. }
  1024. for ( i = 0; i < staticCount; i++ )
  1025. {
  1026. if ( staticInfos[i].isInside( mouseX, mouseY ) )
  1027. return true;
  1028. }
  1029. for ( i = 0; i < rectCount; i++ )
  1030. {
  1031. if ( (rectInfos[i].rect.left) <= mouseX &&
  1032. rectInfos[i].rect.right >= mouseX &&
  1033. rectInfos[i].rect.top <= mouseY &&
  1034. rectInfos[i].rect.bottom >= mouseY )
  1035. return true;
  1036. }
  1037. if ( bPaused && pauseWnd->inRect( mouseX, mouseY ) )
  1038. return true;
  1039. return false;
  1040. }
  1041. void ControlGui::addMover (MoverPtr mover)
  1042. {
  1043. if (mover->getCommanderId() == Commander::home->getId())
  1044. {
  1045. if ( turn > 3 )
  1046. mover->removeFromUnitGroup( 1 );
  1047. if ( mover->getObjectType()->getObjectTypeClass() == BATTLEMECH_TYPE )
  1048. forceGroupBar.addMech( mover );
  1049. else //if ( mover->getSpeed() > 0 ) // don't add guard towers
  1050. forceGroupBar.addVehicle( mover );
  1051. }
  1052. }
  1053. void ControlGui::removeMover (MoverPtr mover) {
  1054. if (mover->getCommanderId() == Commander::home->getId())
  1055. forceGroupBar.removeMover(mover);
  1056. }
  1057. void ControlGui::initMechs()
  1058. {
  1059. forceGroupBar.removeAll();
  1060. Team* pTeam = Team::home;
  1061. if ( !pTeam )
  1062. return;
  1063. for ( int i = 0; i < pTeam->getRosterSize(); ++i )
  1064. {
  1065. Mover* pMover = pTeam->getMover( i );
  1066. if (pMover && pMover->getExists() && pMover->isOnGUI())
  1067. {
  1068. if (pMover->getCommander()->getId() == Commander::home->getId())
  1069. {
  1070. pMover->setSelected( 1 );
  1071. addMover(pMover);
  1072. }
  1073. }
  1074. }
  1075. if ( MPlayer )
  1076. {
  1077. mpStats[0].init();
  1078. for ( int i = 0; i < 8; i++ )
  1079. {
  1080. mpStats[i+1] = mpStats[i];
  1081. }
  1082. }
  1083. }
  1084. bool ControlGui::getRun( )
  1085. {
  1086. return curOrder == RUN;
  1087. }
  1088. void ControlGui::toggleJump( )
  1089. {
  1090. curOrder ^= JUMP;
  1091. curOrder &= JUMP;
  1092. getButton( JUMP_COMMAND )->press( curOrder & JUMP ? true : false);
  1093. getButton( RUN_COMMAND )->press( curOrder & RUN ? true : false);
  1094. getButton( GUARD_COMMAND )->press( curOrder & GUARD ? true : false);
  1095. }
  1096. bool ControlGui::getJump( )
  1097. {
  1098. return curOrder == JUMP;
  1099. }
  1100. void ControlGui::toggleDefaultSpeed( )
  1101. {
  1102. curOrder ^= RUN;
  1103. curOrder &= ( RUN | GUARD );
  1104. getButton( RUN_COMMAND )->press( curOrder & RUN ? true : false );
  1105. getButton( GUARD_COMMAND )->press( curOrder & GUARD ? true : false );
  1106. getButton( JUMP_COMMAND )->press( curOrder & JUMP ? true : false);
  1107. }
  1108. void ControlGui::setDefaultSpeed()
  1109. {
  1110. curOrder = 0;
  1111. getButton( JUMP_COMMAND )->press( 0 );
  1112. getButton( GUARD_COMMAND )->press( 0 );
  1113. getButton( RUN_COMMAND )->press( 0 );
  1114. getButton( REPAIR )->press( 0 );
  1115. getButton( SALVAGE )->press( 0 );
  1116. getButton( INFO_COMMAND )->press( 0 );
  1117. }
  1118. bool ControlGui::isDefaultSpeed()
  1119. {
  1120. return getWalk();
  1121. }
  1122. bool ControlGui::getWalk( )
  1123. {
  1124. return curOrder == WALK;
  1125. }
  1126. void ControlGui::toggleGuard( )
  1127. {
  1128. curOrder ^= GUARD;
  1129. curOrder &= ( GUARD | RUN ); // can run and guard
  1130. getButton( GUARD_COMMAND )->press( curOrder & GUARD ? true : false );
  1131. getButton( JUMP_COMMAND )->press( curOrder & JUMP ? true : false);
  1132. getButton( RUN_COMMAND )->press( curOrder & RUN ? true : false);
  1133. }
  1134. bool ControlGui::getGuard( )
  1135. {
  1136. return curOrder == GUARD;
  1137. }
  1138. void ControlGui::setRange( int Range )
  1139. {
  1140. // apply to all selected mechs
  1141. Team* pTeam = Team::home;
  1142. for ( int i = 0; i < pTeam->getRosterSize(); ++i )
  1143. {
  1144. Mover* pMover = pTeam->getMover( i );
  1145. if ( pMover->isSelected() && pMover->getCommander()->getId() == Commander::home->getId() )
  1146. {
  1147. pMover->attackRange = Range;
  1148. // only want to apply to future order
  1149. // pMover->getPilot()->changeAttackRange( Range );
  1150. }
  1151. }
  1152. }
  1153. int ControlGui::getCurrentRange()
  1154. {
  1155. int range = -1;
  1156. Team* pTeam = Team::home;
  1157. for ( int i = 0; i < pTeam->getRosterSize(); ++i )
  1158. {
  1159. Mover* pMover = pTeam->getMover( i );
  1160. if ( pMover->isSelected() && pMover->getCommander()->getId() == Commander::home->getId() )
  1161. {
  1162. if ( range != -1 && range != pMover->attackRange )
  1163. {
  1164. return FIRERANGE_OPTIMAL;
  1165. }
  1166. else
  1167. range = pMover->attackRange;
  1168. }
  1169. }
  1170. return range;
  1171. }
  1172. void ControlButton::render()
  1173. {
  1174. if ( state != HIDDEN )
  1175. {
  1176. unsigned long gosID = mcTextureManager->get_gosTextureHandle( data->textureHandle );
  1177. gos_SetRenderState( gos_State_Texture, gosID );
  1178. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha);
  1179. gos_SetRenderState( gos_State_Filter, gos_FilterNone);
  1180. gos_SetRenderState( gos_State_AlphaTest, true);
  1181. gos_SetRenderState( gos_State_TextureAddress, gos_TextureClamp );
  1182. gos_DrawQuads( location, 4 );
  1183. if ( data->textID )
  1184. {
  1185. char buffer[256];
  1186. cLoadString( data->textID, buffer, 256 );
  1187. unsigned long height = data->textFont.height();
  1188. data->textFont.render( buffer, location[0].x,
  1189. (location[0].y + location[2].y)/2 - height/2 + 1,
  1190. location[2].x - location[0].x,
  1191. location[2].y - location[0].y,
  1192. data->textColors[state], 0, 2 );
  1193. }
  1194. }
  1195. }
  1196. void ControlButton::press(bool bPress)
  1197. {
  1198. if ( !isEnabled() )
  1199. return;
  1200. state = bPress ? PRESSED : ENABLED;
  1201. ControlButton::makeUVs( location, state, *data );
  1202. }
  1203. void ControlButton::makeAmbiguous( bool bAmbiguous )
  1204. {
  1205. state = bAmbiguous ? AMBIGUOUS : ENABLED;
  1206. ControlButton::makeUVs( location, state, *data );
  1207. }
  1208. void ControlButton::disable( bool bDisable )
  1209. {
  1210. state = (bDisable ? DISABLED : (state == PRESSED ? PRESSED : ENABLED));
  1211. ControlButton::makeUVs( location, state, *data );
  1212. }
  1213. void ControlButton::hide( bool bHide )
  1214. {
  1215. if ( !bHide && state != HIDDEN )
  1216. return;
  1217. state = bHide ? HIDDEN : ENABLED;
  1218. if ( state != HIDDEN )
  1219. ControlButton::makeUVs( location, state, *data );
  1220. }
  1221. bool ControlButton::isEnabled()
  1222. {
  1223. return state == ENABLED || state == PRESSED || state == AMBIGUOUS;
  1224. }
  1225. void ControlButton::move( float deltaX, float deltaY )
  1226. {
  1227. for ( int i = 0; i < 4;i++ )
  1228. {
  1229. location[i].x += deltaX;
  1230. location[i].y += deltaY;
  1231. }
  1232. }
  1233. ControlButton* ControlGui::getButton( int ID )
  1234. {
  1235. for( int i = 0; i < LAST_COMMAND; i++ )
  1236. {
  1237. if ( buttons[i].ID == ID )
  1238. return &buttons[i];
  1239. }
  1240. for ( i = 0; i < LAST_VEHICLE; i++ )
  1241. {
  1242. if ( vehicleButtons[i].ID == ID )
  1243. return &vehicleButtons[i];
  1244. }
  1245. return NULL;
  1246. }
  1247. void ControlGui::handleClick( int ID )
  1248. {
  1249. if ( getButton( ID )->state & ControlButton::HIDDEN )
  1250. return;
  1251. if ( !getButton( ID )->isEnabled() )
  1252. {
  1253. // need to play sound here
  1254. soundSystem->playDigitalSample(INVALID_GUI);
  1255. return;
  1256. }
  1257. int i;
  1258. int sound = LOG_SELECT;
  1259. switch( ID )
  1260. {
  1261. case SAVE_COMMAND:
  1262. mission->missionInterface->togglePause();
  1263. break;
  1264. case SHORT_RANGE:
  1265. setRange( FIRERANGE_SHORT );
  1266. idToUnPress = ID;
  1267. getButton( ID )->press( true );
  1268. break;
  1269. case MED_RANGE:
  1270. setRange( FIRERANGE_MEDIUM );
  1271. idToUnPress = ID;
  1272. getButton( ID )->press( true );
  1273. break;
  1274. case LONG_RANGE:
  1275. setRange( FIRERANGE_LONG );
  1276. idToUnPress = ID;
  1277. getButton( ID )->press( true );
  1278. break;
  1279. case CUR_RANGE:
  1280. toggleHoldPosition();
  1281. break;
  1282. case DEFAULT_RANGE:
  1283. setRange( FIRERANGE_OPTIMAL );
  1284. idToUnPress = ID;
  1285. getButton( ID )->press( true );
  1286. break;
  1287. case JUMP_COMMAND:
  1288. toggleJump();
  1289. break;
  1290. case RUN_COMMAND:
  1291. toggleDefaultSpeed();
  1292. break;
  1293. case GUARD_COMMAND:
  1294. toggleGuard();
  1295. break;
  1296. case STOP_COMMAND:
  1297. idToUnPress = ID;
  1298. getButton( ID )->press( true );
  1299. doStop();
  1300. break;
  1301. case FIRE_FROM_CURRENT_POS:
  1302. toggleFireFromCurrentPos();
  1303. break;
  1304. case TACMAP_TAB:
  1305. case INFO_TAB:
  1306. case VEHICLE_TAB:
  1307. for ( i = TACMAP_TAB; i < TACMAP_TAB + 3; i ++ )
  1308. {
  1309. getButton( i )->press( false );
  1310. }
  1311. getButton( ID )->press( true );
  1312. if ( ID == VEHICLE_TAB )
  1313. LogisticsData::instance->rpJustAdded = 0;
  1314. break;
  1315. case OBJECTIVES_COMMAND:
  1316. if ( !renderObjectives )
  1317. {
  1318. startObjectives( 1 );
  1319. getButton( ID )->press( true );
  1320. }
  1321. else
  1322. renderObjectives = 0;
  1323. sound = LOG_CLICKONBUTTON;
  1324. break;
  1325. case LAYMINES:
  1326. case REPAIR:
  1327. case SALVAGE:
  1328. getButton( ID )->toggle();
  1329. break;
  1330. case GUARDTOWER:
  1331. {
  1332. getButton( ID )->toggle();
  1333. bool bPress = getButton( ID )->state == ControlButton::PRESSED ? 1 : 0;
  1334. for (long i = 0; i < Team::home->getRosterSize(); i++)
  1335. {
  1336. Mover* pMover = (Mover*)Team::home->getMover( i );
  1337. if ( pMover->isSelected() && pMover->isGuardTower() && pMover->getCommander()->getId() == Commander::home->getId())
  1338. {
  1339. pMover->suppressionFire = bPress;
  1340. if (!bPress && MPlayer && !MPlayer->isServer())
  1341. {
  1342. //We send a TAC_ORDER_WAIT which will clear the suppression fire message.
  1343. TacticalOrder tacOrder;
  1344. tacOrder.init(ORDER_ORIGIN_PLAYER, TACTICAL_ORDER_WAIT);
  1345. MPlayer->sendPlayerOrder(&tacOrder, false, 1, &pMover);
  1346. }
  1347. }
  1348. }
  1349. }
  1350. break;
  1351. case INFO_COMMAND:
  1352. for ( i = JUMP_COMMAND; i < INFO_COMMAND; i++ )
  1353. {
  1354. getButton( i )->press( false );
  1355. }
  1356. getButton( ID )->toggle();
  1357. break;
  1358. default:
  1359. sound = -1;
  1360. break;
  1361. }
  1362. soundSystem->playDigitalSample( sound );
  1363. }
  1364. void ControlGui::doStop()
  1365. {
  1366. TacticalOrder tacOrder;
  1367. tacOrder.init(ORDER_ORIGIN_PLAYER, TACTICAL_ORDER_STOP );
  1368. soundSystem->playDigitalSample(BUTTON5);
  1369. Team* pTeam = Team::home;
  1370. for (long i = 0; i < pTeam->getRosterSize(); i++)
  1371. {
  1372. Mover* pMover = (Mover*)pTeam->getMover( i );
  1373. if ( pMover->isSelected() && pMover->getCommander()->getId() == Commander::home->getId() )
  1374. {
  1375. tacOrder.attackParams.range = (FireRangeType)pMover->attackRange;
  1376. tacOrder.pack(NULL, NULL);
  1377. //---------------------------------------------------------------------
  1378. // Helper function--perhaps this should just be a part of the mover and
  1379. // group handleTacticalOrder() functions?
  1380. if (MPlayer && !MPlayer->isServer())
  1381. MPlayer->sendPlayerOrder(&tacOrder, false, 1, &pMover);
  1382. else
  1383. pMover->handleTacticalOrder(tacOrder);
  1384. }
  1385. }
  1386. if ( getMines() )
  1387. getButton( LAYMINES )->press( 0 );
  1388. if ( addingArtillery || addingVehicle || addingSalvage )
  1389. {
  1390. handleVehicleClick( STOP_VEHICLE );
  1391. LogisticsData::instance->rpJustAdded = 0;
  1392. }
  1393. if ( getFireFromCurrentPos() )
  1394. toggleFireFromCurrentPos();
  1395. setDefaultSpeed();
  1396. }
  1397. void ControlGui::toggleFireFromCurrentPos()
  1398. {
  1399. fireFromCurrentPos = !fireFromCurrentPos;
  1400. }
  1401. void ControlButton::makeUVs( gos_VERTEX* vertices, int State, ButtonData& data )
  1402. {
  1403. float left = data.stateCoords[State][0];
  1404. float top = data.stateCoords[State][1];
  1405. if ( left == -1 || top == -1 )
  1406. {
  1407. SPEW(( 0, "makeUVs given an Invalid state\n" ));
  1408. }
  1409. float width = data.textureWidth;
  1410. float height = data.textureHeight;
  1411. float right = left + width;
  1412. float bottom = top + height;
  1413. if ( data.fileWidth && data.fileHeight ) // will crash if 0
  1414. {
  1415. if ( data.textureRotated )
  1416. {
  1417. vertices[0].u = right/(float)data.fileWidth + (.1f / (float)data.fileWidth);;
  1418. vertices[1].u = left/(float)data.fileWidth + (.1f / (float)data.fileWidth);;
  1419. vertices[2].u = left/(float)data.fileWidth + (.1f / (float)data.fileWidth);
  1420. vertices[3].u = right/(float)data.fileWidth + (.1f / (float)data.fileWidth);
  1421. vertices[0].v = top/(float)data.fileHeight + (.1f / (float)data.fileWidth);;
  1422. vertices[1].v = top/(float)data.fileHeight + (.1f / (float)data.fileWidth);;
  1423. vertices[2].v = bottom/(float)data.fileHeight + (.1f / (float)data.fileHeight);;
  1424. vertices[3].v = bottom/(float)data.fileHeight + (.1f / (float)data.fileHeight);;
  1425. }
  1426. else
  1427. {
  1428. {
  1429. vertices[0].u = vertices[1].u = left/(float)data.fileWidth + (.1f / (float)data.fileWidth);;
  1430. vertices[2].u = vertices[3].u = right/(float)data.fileWidth + (.1f / (float)data.fileWidth);
  1431. vertices[0].v = vertices[3].v = top/(float)data.fileHeight + (.1f / (float)data.fileWidth);;
  1432. vertices[1].v = vertices[2].v = bottom/(float)data.fileHeight + (.1f / (float)data.fileHeight);
  1433. }
  1434. }
  1435. }
  1436. }
  1437. void ControlGui::updateVehicleTab(int mouseX, int mouseY, bool bLOS )
  1438. {
  1439. for ( int i = LAST_VEHICLE - 1; i > -1 ; i-- )
  1440. {
  1441. if ( getButton( VEHICLE_TAB )->state & ControlButton::PRESSED )
  1442. {
  1443. if ( vehicleButtons[i].state & ControlButton::PRESSED )
  1444. {
  1445. setRolloverHelpText( IDS_AIRSTRIKE_HELP_NO_LOS + 2 * (i) );
  1446. if ( i == 0 && bLOS )
  1447. {
  1448. setRolloverHelpText( IDS_AIRSTRIKE_HELP );
  1449. }
  1450. }
  1451. if ( vehicleButtons[i].location[0].x <= mouseX && mouseX <= vehicleButtons[i].location[2].x
  1452. && mouseY >= vehicleButtons[i].location[0].y && mouseY <= vehicleButtons[i].location[1].y )
  1453. {
  1454. helpTextHeaderID = vehicleData[i].helpTextHeader;
  1455. helpTextID = vehicleData[i].helpTextID;
  1456. if ( vehicleButtons[i].ID == STOP_VEHICLE )
  1457. {
  1458. mouseInVehicleStopButton = true;
  1459. }
  1460. if ( userInput->leftMouseReleased() && !userInput->isLeftDrag()
  1461. && !userInput->wasLeftDrag()
  1462. && !(vehicleButtons[i].state & ControlButton::PRESSED) )
  1463. {
  1464. {
  1465. handleVehicleClick( vehicleButtons[i].ID );
  1466. }
  1467. }
  1468. long lastX = mouseX - userInput->getMouseXDelta();
  1469. long lastY = mouseY - userInput->getMouseYDelta();
  1470. if ( vehicleButtons[i].location[0].x >= lastX || lastX >= vehicleButtons[i].location[2].x
  1471. || lastY <= vehicleButtons[i].location[0].y || lastY >= vehicleButtons[i].location[1].y )
  1472. soundSystem->playDigitalSample( LOG_HIGHLIGHTBUTTONS );
  1473. }
  1474. }
  1475. if ( vehicleButtons[i].ID != STOP_VEHICLE )
  1476. {
  1477. if ( vehicleCosts[i] > LogisticsData::instance->getResourcePoints()
  1478. && (!addingVehicle && !( vehicleButtons[i].state & ControlButton::PRESSED ) ) )
  1479. {
  1480. vehicleButtons[i].disable( true );
  1481. }
  1482. else if ( ( addingArtillery || addingVehicle || addingSalvage ) && !( vehicleButtons[i].state & ControlButton::PRESSED ) )
  1483. vehicleButtons[i].disable( true );
  1484. else
  1485. vehicleButtons[i].disable( false );
  1486. }
  1487. else
  1488. vehicleButtons[i].disable( false );
  1489. }
  1490. long maxUnits = MAX_ICONS;
  1491. if ( MPlayer )
  1492. {
  1493. long playerCount;
  1494. MPlayer->getPlayers( playerCount );
  1495. if (playerCount)
  1496. maxUnits = (MAX_MULTIPLAYER_MECHS_IN_LOGISTICS/playerCount) + 4;
  1497. else
  1498. maxUnits = 0;
  1499. if ( maxUnits > MAX_ICONS )
  1500. maxUnits = MAX_ICONS;
  1501. }
  1502. if ( forceGroupBar.getIconCount() >= maxUnits )
  1503. {
  1504. getButton( REPAIR_VEHICLE )->disable( true );
  1505. getButton( PEGASUS_SCOUT )->disable( true );
  1506. getButton( RECOVERY_TEAM )->disable( true );
  1507. getButton( MINELAYER )->disable( true );
  1508. getButton( GUARD_TOWER )->disable( true );
  1509. }
  1510. if ( LogisticsData::instance && !LogisticsData::instance->gotPilotsLeft() )
  1511. getButton( RECOVERY_TEAM )->disable( true );
  1512. if ( LogisticsData::instance ) // turn off things that aren't allowed in mplayer
  1513. {
  1514. bool disableAll = (MPlayer && MPlayer->allUnitsDestroyed[MPlayer->commanderID]);
  1515. if (disableAll) {
  1516. getButton( LARGE_AIRSTRIKE )->disable( true );
  1517. getButton( GUARD_TOWER )->disable( true );
  1518. getButton( SENSOR_PROBE )->disable( true );
  1519. getButton( REPAIR_VEHICLE )->disable( true );
  1520. getButton( PEGASUS_SCOUT )->disable( true );
  1521. getButton( MINELAYER )->disable( true );
  1522. getButton( RECOVERY_TEAM )->disable( true );
  1523. }
  1524. else {
  1525. if ( !LogisticsData::instance->canHaveAirStrike() )
  1526. getButton( LARGE_AIRSTRIKE )->disable( true );
  1527. if ( !LogisticsData::instance->canHaveArtilleryPiece() )
  1528. getButton( GUARD_TOWER )->disable( true );
  1529. if ( !LogisticsData::instance->canHaveSensorStrike() )
  1530. getButton( SENSOR_PROBE )->disable( true );
  1531. if ( !LogisticsData::instance->canHaveRepairTruck() )
  1532. getButton( REPAIR_VEHICLE )->disable( true );
  1533. if ( !LogisticsData::instance->canHaveScoutCopter() )
  1534. getButton( PEGASUS_SCOUT )->disable( true );
  1535. if ( !LogisticsData::instance->canHaveMineLayer() )
  1536. getButton( MINELAYER )->disable( true );
  1537. if ( !LogisticsData::instance->canHaveSalavageCraft() )
  1538. getButton( RECOVERY_TEAM )->disable( true );
  1539. }
  1540. }
  1541. }
  1542. void ControlGui::renderVehicleTab()
  1543. {
  1544. long cost = -1;
  1545. char buffer[256];
  1546. LogisticsData::instance->rpJustAdded = 0;
  1547. for ( int i = 0; i < LAST_VEHICLE; i++ )
  1548. {
  1549. vehicleButtons[i].render();
  1550. long color = vehicleButtons[i].isEnabled() ? 0xff005392 : 0xff7f7f7f;
  1551. if ( vehicleButtons[i].state & ControlButton::PRESSED )
  1552. {
  1553. ControlButton::makeUVs( vehicleButtons[i].location, ControlButton::ENABLED, *vehicleButtons[i].data );
  1554. cost = vehicleCosts[i];
  1555. GUI_RECT rect = { vehicleButtons[i].location[0].x, vehicleButtons[i].location[0].y,
  1556. vehicleButtons[i].location[2].x, vehicleButtons[i].location[2].y };
  1557. vehicleButtons[i].render();
  1558. drawEmptyRect( rect, 0xffffffff, 0xffffffff );
  1559. color = 0xffffffff;
  1560. }
  1561. if ( vehicleCosts[i] )
  1562. {
  1563. // need to draw cost under the button
  1564. long left = float2long(vehicleButtons[i].location[0].x);
  1565. long top = float2long(vehicleButtons[i].location[2].y + TEXT_SKIP);
  1566. long right = float2long(vehicleButtons[i].location[2].x);
  1567. long bottom = float2long(vehicleButtons[i].location[2].y + 30 + TEXT_SKIP);
  1568. sprintf( buffer, "%ld", vehicleCosts[i] );
  1569. vehicleFont.render( buffer, left, top, right - left, bottom - top, color, 0, 2 );
  1570. }
  1571. }
  1572. long left = RPLEFT;
  1573. long top = RPTOP;
  1574. // draw in RP
  1575. char originalStr[256];
  1576. cLoadString( IDS_RP, originalStr, 256 );
  1577. sprintf( buffer, originalStr, (long)LogisticsData::instance->getResourcePoints() );
  1578. //We are there. Start flashing.
  1579. /// TUTORIAL!!!
  1580. if (rpNumFlashes)
  1581. {
  1582. rpFlashTime += frameLength;
  1583. if ( rpFlashTime > .5f )
  1584. {
  1585. rpFlashTime = 0.0f;
  1586. rpNumFlashes--;
  1587. }
  1588. else if ( rpFlashTime > .25f )
  1589. {
  1590. vehicleFont.render( buffer, left, top, 0, 0, 0xff5c96c2, 0, 0 );
  1591. }
  1592. }
  1593. else
  1594. {
  1595. vehicleFont.render( buffer, left, top, 0, 0, 0xff5c96c2, 0, 0 );
  1596. }
  1597. }
  1598. void ControlGui::handleVehicleClick( int ID )
  1599. {
  1600. if ( getButton( ID )->state & ControlButton::HIDDEN )
  1601. return;
  1602. if ( getButton( ID )->state & ControlButton::DISABLED ) // ignore disabled button
  1603. {
  1604. // need to play sound here
  1605. soundSystem->playDigitalSample(INVALID_GUI);
  1606. return;
  1607. }
  1608. if ((ID == STOP_VEHICLE) && paintingMyVtol)
  1609. {
  1610. //You cannot stop it once the VTOL is in flight, no matter what the button looks like.
  1611. soundSystem->playDigitalSample(INVALID_GUI);
  1612. return;
  1613. }
  1614. int oldID = -1;
  1615. for ( int i = 0; i < LAST_VEHICLE; i++ )
  1616. {
  1617. if ( vehicleButtons[i].state & ControlButton::PRESSED )
  1618. oldID = vehicleButtons[i].ID;
  1619. if ( vehicleButtons[i].ID != ID )
  1620. vehicleButtons[i].disable( 1 );
  1621. else
  1622. {
  1623. vehicleButtons[i].press( 1 );
  1624. if ( ID != STOP_VEHICLE )
  1625. {
  1626. int cost = vehicleCosts[i];
  1627. LogisticsData::instance->decrementResourcePoints( cost );
  1628. if (MPlayer) {
  1629. Stuff::Vector3D pos;
  1630. MPlayer->sendReinforcement(-cost, 0, "noname", MPlayer->commanderID, pos, 6);
  1631. }
  1632. }
  1633. }
  1634. }
  1635. soundSystem->playDigitalSample( LOG_SELECT );
  1636. switch ( ID )
  1637. {
  1638. case LARGE_AIRSTRIKE:
  1639. case SENSOR_PROBE:
  1640. addingArtillery = true;
  1641. getButton( INFO_COMMAND )->press( 0 );
  1642. break;
  1643. case REPAIR_VEHICLE:
  1644. case PEGASUS_SCOUT:
  1645. case MINELAYER:
  1646. case GUARD_TOWER:
  1647. addingVehicle = true;
  1648. getButton( INFO_COMMAND )->press( 0 );
  1649. break;
  1650. case RECOVERY_TEAM:
  1651. addingSalvage = true;
  1652. getButton( INFO_COMMAND )->press( 0 );
  1653. break;
  1654. case STOP_VEHICLE:
  1655. addingArtillery = addingVehicle = addingSalvage = false;
  1656. for ( i = 0; i < LAST_VEHICLE - 1; i++ )
  1657. {
  1658. if ( vehicleCosts[i] <= LogisticsData::instance->getResourcePoints() )
  1659. {
  1660. vehicleButtons[i].disable( 0 );
  1661. vehicleButtons[i].press( 0 );
  1662. }
  1663. }
  1664. if ( oldID != -1 )
  1665. {
  1666. int cost = vehicleCosts[oldID - LARGE_AIRSTRIKE];
  1667. LogisticsData::instance->addResourcePoints( cost );
  1668. if ( MPlayer )
  1669. {
  1670. MPlayer->playerInfo[MPlayer->commanderID].resourcePoints += cost;
  1671. MPlayer->playerInfo[MPlayer->commanderID].resourcePointsGained += cost;
  1672. if (!MPlayer->isHost())
  1673. {
  1674. MPlayer->sendPlayerUpdate( 0, 5, MPlayer->commanderID );
  1675. }
  1676. }
  1677. }
  1678. idToUnPress = ID;
  1679. break;
  1680. default:
  1681. // gosASSERT( 0 );
  1682. break;
  1683. }
  1684. }
  1685. void ControlGui::unPressAllVehicleButtons()
  1686. {
  1687. for ( int i = LARGE_AIRSTRIKE; i < MAX_VEHICLE; i++ )
  1688. {
  1689. getButton( i )->press( 0 );
  1690. }
  1691. addingArtillery = 0;
  1692. addingVehicle = 0;
  1693. addingSalvage = 0;
  1694. }
  1695. void ControlGui::disableAllVehicleButtons()
  1696. {
  1697. for ( int i = LARGE_AIRSTRIKE; i < MAX_VEHICLE - 1; i++ )
  1698. {
  1699. getButton( i )->disable( 1 );
  1700. }
  1701. // addingArtillery = 0;
  1702. // addingVehicle = 0;
  1703. }
  1704. const char* ControlGui::getVehicleName( long& ID)
  1705. {
  1706. for ( int i = GUARD_TOWER; i <= RECOVERY_TEAM; i++ )
  1707. {
  1708. if ( getButton( i )->state & ControlButton::PRESSED )
  1709. {
  1710. if ( i == GUARD_TOWER)
  1711. {
  1712. ID = vehicleIDs[4];
  1713. return vehiclePilots[4];
  1714. }
  1715. ID = vehicleIDs[i - REPAIR_VEHICLE];
  1716. return vehiclePilots[i - REPAIR_VEHICLE];
  1717. }
  1718. }
  1719. // char s[1024];
  1720. // sprintf(s, "getvehiclename: ID = %d", ID);
  1721. // PAUSE((s));
  1722. return 0;
  1723. }
  1724. const char* ControlGui::getVehicleNameFromID (long ID) {
  1725. for (long i = 0; i < 5; i++)
  1726. if (vehicleIDs[i] == ID)
  1727. return(vehiclePilots[i]);
  1728. return(NULL);
  1729. }
  1730. bool ControlGui::getMines()
  1731. {
  1732. if ( getButton( LAYMINES )->state & ControlButton::PRESSED )
  1733. return 1;
  1734. return 0;
  1735. }
  1736. bool ControlGui::getSalvage()
  1737. {
  1738. if ( getButton( SALVAGE )->state & ControlButton::PRESSED )
  1739. return 1;
  1740. return 0;
  1741. }
  1742. bool ControlGui::getRepair()
  1743. {
  1744. if ( getButton( REPAIR )->state & ControlButton::PRESSED )
  1745. return 1;
  1746. return 0;
  1747. }
  1748. bool ControlGui::getGuardTower()
  1749. {
  1750. if ( getButton( GUARDTOWER )->state & ControlButton::PRESSED )
  1751. return 1;
  1752. return 0;
  1753. }
  1754. void ControlGui::renderHelpText()
  1755. {
  1756. if ( helpTextID )
  1757. {
  1758. char buffer[1024];
  1759. cLoadString( helpTextID, buffer, 1024 );
  1760. unsigned long width, height;
  1761. width = helpFont.width( buffer );
  1762. height = helpFont.height( buffer, width );
  1763. gos_TextStringLength( &width, &height, buffer );
  1764. gos_TextSetRegion( HELPAREA_LEFT, HELPAREA_BOTTOM - 3 * height, Environment.screenWidth, Environment.screenHeight );
  1765. drawShadowText( 0xffffffff, 0xff000000, helpFont.getTempHandle(),
  1766. HELPAREA_LEFT, HELPAREA_BOTTOM - height, true, buffer, false,
  1767. helpFont.getSize() );
  1768. if ( helpTextHeaderID )
  1769. {
  1770. cLoadString( helpTextHeaderID, buffer, 1024 );
  1771. long yPos = HELPAREA_BOTTOM - height;
  1772. drawShadowText( 0xffffffff, 0xff000000, helpFont.getTempHandle(),
  1773. HELPAREA_LEFT, yPos - height, 1, buffer, true, helpFont.getSize() );
  1774. }
  1775. }
  1776. }
  1777. void ControlGui::renderInfoTab()
  1778. {
  1779. if ( getButton( INFO_TAB )->state & ControlButton::PRESSED )
  1780. {
  1781. infoWnd->render();
  1782. }
  1783. }
  1784. bool ControlGui::isSelectingInfoObject()
  1785. {
  1786. if ( getButton( INFO_COMMAND )->state & ControlButton::PRESSED )
  1787. return true;
  1788. return false;
  1789. }
  1790. void ControlGui::setInfoWndMover( Mover* pMover )
  1791. {
  1792. infoWnd->setUnit( pMover );
  1793. if ( isSelectingInfoObject() )
  1794. {
  1795. handleClick( INFO_TAB ); // fake click
  1796. // unpress the info button
  1797. gosEnum_KeyIndex key;
  1798. bool bC, bA, bS;
  1799. MissionInterfaceManager::instance()->getHotKey( INFO_COMMAND_INDEX, key, bS, bC, bA );
  1800. if ( gos_GetKeyStatus( key )!= KEY_HELD )
  1801. getButton( INFO_COMMAND )->press( 0 );
  1802. }
  1803. }
  1804. void ControlGui::setVehicleCommand( bool bSet )
  1805. {
  1806. if ( (getButton( REPAIR )->isEnabled()) )
  1807. getButton( REPAIR )->press( bSet );
  1808. else if ( (getButton( SALVAGE )->isEnabled()) )
  1809. getButton( SALVAGE )->press( bSet );
  1810. else if ( (getButton( LAYMINES )->isEnabled()) )
  1811. getButton( LAYMINES )->press( bSet );
  1812. else
  1813. {
  1814. Team* pTeam = Team::home;
  1815. if ( pTeam )
  1816. {
  1817. for ( int i = 0; i < pTeam->getRosterSize(); ++i )
  1818. {
  1819. Mover* pMover = (Mover*)pTeam->getMover( i );
  1820. if ( pMover->getCommander()->getId() != Commander::home->getId() )
  1821. continue;
  1822. bool bGuardTower = ( pMover->maxMoveSpeed ? 0 : 1 );
  1823. if ( bGuardTower )
  1824. {
  1825. pMover->suppressionFire = bSet;
  1826. if (!bSet && MPlayer && !MPlayer->isServer())
  1827. {
  1828. //We send a TAC_ORDER_WAIT which will clear the suppression fire message.
  1829. // Otherwise, this is handled when we doGuardTower if pressed.
  1830. TacticalOrder tacOrder;
  1831. tacOrder.init(ORDER_ORIGIN_PLAYER, TACTICAL_ORDER_WAIT);
  1832. MPlayer->sendPlayerOrder(&tacOrder, false, 1, &pMover);
  1833. }
  1834. }
  1835. }
  1836. }
  1837. }
  1838. }
  1839. bool ControlGui::getVehicleCommand( )
  1840. {
  1841. if ( (getButton( REPAIR )->state & ControlButton::PRESSED)
  1842. || (getButton( SALVAGE )->state & ControlButton::PRESSED)
  1843. || (getButton( LAYMINES )->state & ControlButton::PRESSED)
  1844. || (getButton( GUARDTOWER )->state & ControlButton::PRESSED))
  1845. return true;
  1846. return false;
  1847. }
  1848. void ControlButton::initButtons( FitIniFile& buttonFile, long buttonCount, ControlButton* Buttons, ButtonData* Data, const char* str, aFont* font )
  1849. {
  1850. char path[256];
  1851. for ( int i = 0; i < buttonCount; ++i )
  1852. {
  1853. sprintf( path, "%s%ld", str, i );
  1854. Data[i].textureHandle = 0;
  1855. long result = buttonFile.seekBlock( path );
  1856. if ( result != NO_ERR )
  1857. {
  1858. char errorStr[256];
  1859. sprintf( errorStr, "couldn't find button %s", path );
  1860. Assert( 0, 0, errorStr );
  1861. continue;
  1862. }
  1863. buttonFile.readIdLong( "ID", Buttons[i].ID );
  1864. buttonFile.readIdString("FileName", Data[i].fileName, 32 );
  1865. buttonFile.readIdLong( "HelpCaption", Data[i].helpTextHeader );
  1866. buttonFile.readIdLong( "HelpDesc", Data[i].helpTextID );
  1867. buttonFile.readIdLong( "TextID", Data[i].textID );
  1868. buttonFile.readIdLong( "TextNormal", Data[i].textColors[0] );
  1869. buttonFile.readIdLong( "TextPressed", Data[i].textColors[1] );
  1870. buttonFile.readIdLong( "TextDisabled", Data[i].textColors[2] );
  1871. buttonFile.readIdLong( "TextHighlight", Data[i].textColors[3] );
  1872. if ( font )
  1873. Data[i].textFont = *font;
  1874. long x, y, width, height;
  1875. buttonFile.readIdLong( "XLocation", x );
  1876. buttonFile.readIdLong( "YLocation", y );
  1877. x += ControlGui::hiResOffsetX;
  1878. y += ControlGui::hiResOffsetY;
  1879. buttonFile.readIdLong( "Width", width );
  1880. buttonFile.readIdLong( "Height", height );
  1881. buttonFile.readIdLong( "HelpCaption", Data[i].helpTextHeader );
  1882. buttonFile.readIdLong( "HelpDesc", Data[i].helpTextID );
  1883. buttonFile.readIdBoolean( "texturesRotated", Data[i].textureRotated );
  1884. Buttons[i].data = &Data[i];
  1885. Buttons[i].location[0].x = Buttons[i].location[1].x = x;
  1886. Buttons[i].location[0].y = Buttons[i].location[3].y = y;
  1887. Buttons[i].location[2].x = Buttons[i].location[3].x = x + width;
  1888. Buttons[i].location[1].y = Buttons[i].location[2].y = y + height;
  1889. for ( int j = 0; j < 4; j++ )
  1890. {
  1891. Buttons[i].location[j].argb = 0xffffffff;
  1892. Buttons[i].location[j].frgb = 0;
  1893. Buttons[i].location[j].rhw = .5;
  1894. Buttons[i].location[j].u = 0.f;
  1895. Buttons[i].location[j].v = 0.f;
  1896. Buttons[i].location[j].z = 0.f;
  1897. }
  1898. if ( 0 == Buttons[i].data->textureHandle )
  1899. {
  1900. char file[256];
  1901. strcpy( file, artPath );
  1902. strcat( file, Buttons[i].data->fileName );
  1903. strcat( file, ".tga" );
  1904. _strlwr( file );
  1905. int ID = mcTextureManager->loadTexture( file, gos_Texture_Alpha, 0, 0, 0x2 );
  1906. int gosID = mcTextureManager->get_gosTextureHandle( ID );
  1907. TEXTUREPTR textureData;
  1908. gos_LockTexture( gosID, 0, 0, &textureData );
  1909. gos_UnLockTexture( gosID );
  1910. Buttons[i].data->textureHandle = ID;
  1911. Buttons[i].data->fileWidth = textureData.Width;
  1912. Buttons[i].data->fileHeight = Buttons[i].data->fileWidth;
  1913. }
  1914. if ( NO_ERR != buttonFile.readIdLong( "UNormal", Buttons[i].data->stateCoords[0][0] ) )
  1915. Buttons[i].data->stateCoords[0][0] = -1.f;
  1916. if ( NO_ERR != buttonFile.readIdLong( "VNormal", Buttons[i].data->stateCoords[0][1] ) )
  1917. Buttons[i].data->stateCoords[0][1] = -1.f;
  1918. if ( NO_ERR != buttonFile.readIdLong( "UPressed", Buttons[i].data->stateCoords[1][0] ) )
  1919. Buttons[i].data->stateCoords[1][0] = -1.f;
  1920. if ( NO_ERR != buttonFile.readIdLong( "VPressed", Buttons[i].data->stateCoords[1][1] ) )
  1921. Buttons[i].data->stateCoords[1][1] = -1.f;
  1922. if ( NO_ERR != buttonFile.readIdLong( "UDisabled", Buttons[i].data->stateCoords[2][0] ) )
  1923. Buttons[i].data->stateCoords[2][0] = -1.f;
  1924. if ( NO_ERR != buttonFile.readIdLong( "VDisabled", Buttons[i].data->stateCoords[2][1] ) )
  1925. Buttons[i].data->stateCoords[2][1] = -1.f;
  1926. if ( NO_ERR != buttonFile.readIdLong( "UAmbiguous", Buttons[i].data->stateCoords[3][0] ) )
  1927. {
  1928. if ( NO_ERR != buttonFile.readIdLong( "UHighlight", Buttons[i].data->stateCoords[3][0] ) )
  1929. Buttons[i].data->stateCoords[3][0] = -1.f;
  1930. }
  1931. if ( NO_ERR != buttonFile.readIdLong( "VAmbiguous", Buttons[i].data->stateCoords[3][1] ) )
  1932. {
  1933. if ( NO_ERR != buttonFile.readIdLong( "VHighlight", Buttons[i].data->stateCoords[3][1] ) )
  1934. Buttons[i].data->stateCoords[3][1] = -1.f;
  1935. }
  1936. buttonFile.readIdLong( "UWidth", Buttons[i].data->textureWidth );
  1937. buttonFile.readIdLong( "VHeight", Buttons[i].data->textureHeight );
  1938. Buttons[i].disable( 0 );
  1939. Buttons[i].press( 0 );
  1940. }
  1941. }
  1942. void ControlGui::initStatics( FitIniFile& file )
  1943. {
  1944. if ( infoWnd )
  1945. infoWnd->setUnit( 0 );
  1946. if ( staticInfos )
  1947. delete [] staticInfos;
  1948. staticInfos = NULL;
  1949. if ( objectiveInfos )
  1950. delete [] objectiveInfos;
  1951. objectiveInfos = 0;
  1952. if ( videoInfos )
  1953. delete [] videoInfos;
  1954. videoInfos = 0;
  1955. if ( timerInfos )
  1956. delete [] timerInfos;
  1957. timerInfos = 0;
  1958. if ( missionStatusInfos )
  1959. delete [] missionStatusInfos;
  1960. missionStatusInfos = 0;
  1961. staticCount = 0;
  1962. file.seekBlock( "Statics" );
  1963. file.readIdLong( "staticCount", staticCount );
  1964. if ( !staticCount )
  1965. return;
  1966. staticInfos = new StaticInfo[staticCount];
  1967. for ( int i = 0; i < staticCount; i++ )
  1968. {
  1969. char buffer[32];
  1970. sprintf( buffer, "Static%ld", i );
  1971. staticInfos[i].init( file, buffer ,hiResOffsetX, hiResOffsetY);
  1972. }
  1973. if ( staticCount > 20 )
  1974. staticInfos[20].showGUIWindow( 0 );
  1975. if ( NO_ERR != file.seekBlock( "HelpText" ) )
  1976. {
  1977. Assert( 0, 0, "couldn't find the help text block in the layout file" );
  1978. }
  1979. file.readIdLong( "HelpTextLeft", HELPAREA_LEFT );
  1980. file.readIdLong( "HelpTextBottom", HELPAREA_BOTTOM );
  1981. HELPAREA_LEFT += hiResOffsetX;
  1982. HELPAREA_BOTTOM += hiResOffsetY;
  1983. if ( NO_ERR != file.seekBlock( "ResourcePoints" ) )
  1984. {
  1985. Assert( 0, 0, "couldn't find the help text block in the layout file" );
  1986. }
  1987. file.readIdLong( "RPTextLeft", RPLEFT );
  1988. file.readIdLong( "RPTextTop", RPTOP );
  1989. RPLEFT += hiResOffsetX;
  1990. RPTOP += hiResOffsetY;
  1991. //TUTORIAL!!
  1992. rpCallout.rect.left = RPLEFT;
  1993. rpCallout.rect.right = RPLEFT;
  1994. rpCallout.rect.top = RPTOP;
  1995. rpCallout.rect.bottom = RPTOP;
  1996. if ( NO_ERR != file.seekBlock( "Objectives" ) )
  1997. {
  1998. Assert( 0, 0, "couldn't find the objective block in the button layout file" );
  1999. }
  2000. file.readIdLong( "ObjStaticCount", objectiveInfoCount );
  2001. file.readIdLong( "ObjectiveLeft", OBJECTIVESLEFT );
  2002. file.readIdLong( "ObjectiveSkip", OBJECTIVESSKIP );
  2003. file.readIdLong( "SecondObjSkip", OBJEECTIVESHEADERSKIP );
  2004. file.readIdLong( "totalRight", OBJECTIVESTOTALRIGHT );
  2005. file.seekBlock( "PrimaryObjHeader" );
  2006. file.readIdLong( "HeaderLeft", OBJECTIVEHEADERLEFT );
  2007. file.readIdLong( "HeaderTop", OBJECTIVESTOP );
  2008. objectiveInfos = new StaticInfo[objectiveInfoCount + 3];
  2009. char blockName[64];
  2010. for ( i = 0; i < objectiveInfoCount; i++ )
  2011. {
  2012. sprintf( blockName, "ObjStatic%ld", i );
  2013. objectiveInfos[i].init( file, blockName );
  2014. }
  2015. objectiveInfos[i++].init( file, "PrimaryObjBox" );
  2016. file.readIdLong( "objBoxSkip", OBJECTIVEBOXSKIP );
  2017. objectiveInfos[i++].init( file, "PrimaryObjCheck" );
  2018. file.readIdLong( "objBoxSkip", OBJECTIVECHECKSKIP );
  2019. objectiveInfos[i++].init( file, "PrimaryObjX" );
  2020. objectiveInfoCount = i;
  2021. if ( NO_ERR != file.seekBlock( "VideoWindow" ) )
  2022. {
  2023. Assert( 0, 0, "couldn't find th videoWindow block in the button layout file" );
  2024. }
  2025. file.readIdLong( "VideoStaticCount", videoInfoCount );
  2026. file.readIdLong( "left", videoRect.left );
  2027. file.readIdLong( "right", videoRect.right );
  2028. file.readIdLong( "top", videoRect.top );
  2029. file.readIdLong( "bottom", videoRect.bottom );
  2030. videoRect.left += hiResOffsetX;
  2031. videoRect.right += hiResOffsetX;
  2032. file.seekBlock( "VideoTextBox" );
  2033. file.readIdLong( "left", videoTextRect.left );
  2034. file.readIdLong( "right", videoTextRect.right );
  2035. file.readIdLong( "top", videoTextRect.top );
  2036. file.readIdLong( "bottom", videoTextRect.bottom );
  2037. videoTextRect.left += hiResOffsetX;
  2038. videoTextRect.right += hiResOffsetX;
  2039. if ( videoInfoCount )
  2040. {
  2041. videoInfos = new StaticInfo[videoInfoCount];
  2042. for ( i = 0; i < videoInfoCount; i++ )
  2043. {
  2044. sprintf( blockName, "VideoStatic%ld", i );
  2045. videoInfos[i].init( file, blockName );
  2046. }
  2047. }
  2048. file.seekBlock( "MissionTimer" );
  2049. file.readIdLong( "left", timerRect.rect.left );
  2050. file.readIdLong( "top", timerRect.rect.top );
  2051. file.readIdLong( "color", timerRect.color );
  2052. file.readIdLong( "TimerStaticCount", timerInfoCount );
  2053. timerRect.rect.left += hiResOffsetX;
  2054. timerRect.rect.right += hiResOffsetX;
  2055. timerRect.rect.top += hiResOffsetY;
  2056. timerRect.rect.bottom += hiResOffsetY;
  2057. if ( timerInfoCount )
  2058. {
  2059. timerInfos = new StaticInfo[timerInfoCount];
  2060. for ( i = 0; i < timerInfoCount; i++ )
  2061. {
  2062. sprintf( blockName, "TimerStatic%ld", i );
  2063. timerInfos[i].init( file, blockName, hiResOffsetX, hiResOffsetY );
  2064. }
  2065. }
  2066. file.seekBlock( "MissionResults" );
  2067. file.readIdLong( "ResultsStaticCount", missionStatusInfoCount );
  2068. if ( missionStatusInfoCount )
  2069. {
  2070. missionStatusInfos = new StaticInfo[missionStatusInfoCount ];
  2071. for ( i = 0; i < missionStatusInfoCount; i++ )
  2072. {
  2073. sprintf( blockName, "ResultsStatic%ld", i );
  2074. missionStatusInfos[i].init( file, blockName );
  2075. }
  2076. }
  2077. file.seekBlock( "ResultsTextBox" );
  2078. file.readIdLong( "left", missionStatusRect.rect.left );
  2079. file.readIdLong( "right", missionStatusRect.rect.right );
  2080. file.readIdLong( "top", missionStatusRect.rect.top );
  2081. file.readIdLong( "bottom", missionStatusRect.rect.bottom );
  2082. file.readIdLong( "ResultsTextColor", missionStatusRect.color );
  2083. file.seekBlock( "ChatPlayerNameRect" );
  2084. long left, top, width, height;
  2085. file.readIdLong( "xlocation", left );
  2086. file.readIdLong( "yLocation", top );
  2087. file.readIdLong( "Width", width );
  2088. file.readIdLong( "Height", height );
  2089. ((aObject*)&playerNameEdit)->init( left+2, top, width, height );
  2090. playerNameEdit.setFont( IDS_CHAT_PLAYERNAME_FONT );
  2091. timerFont.init( IDS_OUTLINE_CHAT_FONT );
  2092. int fontHeight = playerNameEdit.getFontObject()->height();
  2093. playerNameEdit.resize( playerNameEdit.width(), fontHeight );
  2094. playerNameEdit.setTextColor( 0xffffffff );
  2095. file.seekBlock( "ChatTextRect" );
  2096. file.readIdLong( "xlocation", left );
  2097. file.readIdLong( "yLocation", top );
  2098. file.readIdLong( "Width", width );
  2099. file.readIdLong( "Height", height );
  2100. ((aObject*)&chatEdit)->init( left, top, width, height );
  2101. chatEdit.font.init( IDS_OUTLINE_CHAT_FONT );
  2102. chatEdit.setColor( 0xffffffff );
  2103. chatEdit.resize( chatEdit.width(), fontHeight );
  2104. ((aObject*)&personalEdit)->init( left, top, width, height );
  2105. personalEdit.setFont( IDS_OUTLINE_CHAT_FONT );
  2106. personalEdit.setTextColor( 0xffffffff );
  2107. personalEdit.resize( personalEdit.width(), fontHeight );
  2108. personalEdit.setColor( 0 );// make tranparent
  2109. }
  2110. void ControlGui::initRects( FitIniFile& file )
  2111. {
  2112. if ( rectInfos )
  2113. delete rectInfos;
  2114. rectInfos = 0;
  2115. rectCount = 0;
  2116. if ( NO_ERR != file.seekBlock( "Rects" ) )
  2117. return;
  2118. file.readIdLong( "rectCount", rectCount );
  2119. if ( rectCount )
  2120. {
  2121. rectInfos = new RectInfo[rectCount];
  2122. char buffer[32];
  2123. for ( int i = 0; i < rectCount; i++ )
  2124. {
  2125. sprintf( buffer, "Rect%ld", i );
  2126. if ( NO_ERR != file.seekBlock( buffer ) )
  2127. {
  2128. Assert( 0, i, "couldn't find the rect block" );
  2129. return;
  2130. }
  2131. file.readIdLong( "left", rectInfos[i].rect.left );
  2132. file.readIdLong( "top", rectInfos[i].rect.top );
  2133. file.readIdLong( "right", rectInfos[i].rect.right );
  2134. file.readIdLong( "bottom", rectInfos[i].rect.bottom );
  2135. file.readIdLong( "color", rectInfos[i].color );
  2136. rectInfos[i].rect.left += hiResOffsetX;
  2137. rectInfos[i].rect.top += hiResOffsetY;
  2138. rectInfos[i].rect.right += hiResOffsetX;
  2139. rectInfos[i].rect.bottom += hiResOffsetY;
  2140. }
  2141. tacMap.setPos( rectInfos[0].rect );
  2142. }
  2143. }
  2144. void ControlGui::swapResolutions( int resolution )
  2145. {
  2146. FitIniFile buttonFile;
  2147. char path[256];
  2148. strcpy( path, artPath );
  2149. char fileName[32];
  2150. if ( resolution == 1600)
  2151. strcpy( fileName, "buttonlayout1600.fit" );
  2152. else if ( resolution == 1280)
  2153. strcpy( fileName, "buttonlayout1280.fit" );
  2154. else if ( resolution == 1024)
  2155. strcpy( fileName, "buttonlayout1024.fit" );
  2156. else if ( resolution == 800 )
  2157. strcpy( fileName, "buttonlayout800.fit" );
  2158. else if ( resolution == 640 )
  2159. strcpy( fileName, "buttonlayout640.fit" );
  2160. else
  2161. strcpy( fileName, "buttonlayout1024.fit" );
  2162. strcat( path, fileName );
  2163. if ( NO_ERR != buttonFile.open( path ) )
  2164. {
  2165. char error[256];
  2166. sprintf( error, "couldn't find the file %s", path );
  2167. Assert( 0, 0, error );
  2168. }
  2169. //------------------------------------
  2170. //Get the Resolution Centering Values
  2171. long result = buttonFile.seekBlock("HiresOffsets");
  2172. if (result == NO_ERR)
  2173. {
  2174. result = buttonFile.readIdLong("xOffset",hiResOffsetX);
  2175. if (result != NO_ERR)
  2176. hiResOffsetX = 0;
  2177. result = buttonFile.readIdLong("yOffset",hiResOffsetY);
  2178. if (result != NO_ERR)
  2179. hiResOffsetY = 0;
  2180. }
  2181. else
  2182. {
  2183. hiResOffsetX = hiResOffsetY = 0;
  2184. }
  2185. infoWnd->init( buttonFile );
  2186. if ( NO_ERR != buttonFile.seekBlock( "Fonts" ) )
  2187. Assert( 0, 0, "couldn't find the font block" );
  2188. long fontID;
  2189. buttonFile.readIdLong( "HelpFont", fontID );
  2190. helpFont.init( fontID );
  2191. buttonFile.readIdLong( "ObjectiveFont", fontID );
  2192. guiFont.init( fontID );
  2193. buttonFile.readIdLong( "vehicleFont", fontID );
  2194. vehicleFont.init( fontID );
  2195. buttonFile.readIdLong( "MissionResultsFont", fontID );
  2196. missionResultsFont.init( fontID );
  2197. result = buttonFile.seekBlock( "ControlButtons" );
  2198. if ( result != NO_ERR )
  2199. {
  2200. Assert( 0, 0, "Control button block not found" );
  2201. }
  2202. long buttonCount;
  2203. buttonFile.readIdLong( "ButtonCount", buttonCount );
  2204. Assert( buttonCount == 20, buttonCount, "wrong number of control buttons" );
  2205. // clean up old texture memeory
  2206. if ( buttonData )
  2207. {
  2208. for ( int i = 0; i < buttonCount; i++ )
  2209. {
  2210. unsigned long gosID = mcTextureManager->get_gosTextureHandle( buttonData[i].textureHandle );
  2211. mcTextureManager->removeTexture( gosID );
  2212. }
  2213. }
  2214. if ( vehicleData )
  2215. {
  2216. for ( int i = 0; i < LAST_VEHICLE; i++ )
  2217. {
  2218. unsigned long gosID = mcTextureManager->get_gosTextureHandle( vehicleData[i].textureHandle );
  2219. mcTextureManager->removeTexture( gosID );
  2220. }
  2221. }
  2222. if ( !buttons )
  2223. buttons = new ControlButton[buttonCount];
  2224. if ( !buttonData )
  2225. buttonData = new ButtonData[buttonCount];
  2226. memset( buttonData, 0, buttonCount * sizeof( ButtonData ) );
  2227. ControlButton::initButtons( buttonFile, buttonCount, buttons, buttonData, "Button" );
  2228. //getButton( REPAIR )->setColor( 0 );
  2229. getButton( SALVAGE )->setColor( 0 );
  2230. result = buttonFile.seekBlock( "VehicleButtons" );
  2231. if ( result != NO_ERR )
  2232. {
  2233. Assert( 0, 0, "No Vehicle Buttons" );
  2234. }
  2235. buttonFile.readIdLong( "ButtonCount", buttonCount );
  2236. Assert( buttonCount == 8, buttonCount, "wrong number of vehicle buttons" );
  2237. if ( !vehicleButtons )
  2238. vehicleButtons = new ControlButton[buttonCount];
  2239. if ( !vehicleData )
  2240. vehicleData = new ButtonData[buttonCount];
  2241. memset( vehicleData, 0, buttonCount * sizeof( ButtonData ) );
  2242. ControlButton::initButtons( buttonFile, buttonCount, vehicleButtons, vehicleData, "Vehicle" );
  2243. getButton( TACMAP_TAB )->press( true );
  2244. initStatics( buttonFile );
  2245. initRects( buttonFile );
  2246. forceGroupBar.init( buttonFile, &staticInfos[20] );
  2247. staticInfos[20].showGUIWindow( 0 );
  2248. pauseWnd->init( buttonFile );
  2249. }
  2250. void ControlGui::beginPause()
  2251. {
  2252. getButton( SAVE_COMMAND )->press( 1 );
  2253. pauseWnd->begin(renderObjectives);
  2254. }
  2255. void ControlGui::endPause()
  2256. {
  2257. getButton( SAVE_COMMAND )->press( 0 );
  2258. pauseWnd->end();
  2259. }
  2260. void ControlGui::switchTabs(int direction)
  2261. {
  2262. int ID = TACMAP_TAB;
  2263. for ( int i = TACMAP_TAB; i < TACMAP_TAB + 3; i ++ )
  2264. {
  2265. if ( getButton( i )->state & ControlButton::PRESSED )
  2266. {
  2267. ID = i;
  2268. getButton( i )->press( false );
  2269. }
  2270. }
  2271. if ( ID == INFO_TAB )
  2272. {
  2273. if ( direction > 0 )
  2274. ID = TACMAP_TAB;
  2275. else
  2276. ID = VEHICLE_TAB;
  2277. }
  2278. else if ( ID == VEHICLE_TAB )
  2279. {
  2280. if ( direction > 0 )
  2281. ID = INFO_TAB;
  2282. else
  2283. ID = TACMAP_TAB;
  2284. }
  2285. else
  2286. {
  2287. if ( direction > 0 )
  2288. ID = VEHICLE_TAB;
  2289. else
  2290. ID = INFO_TAB;
  2291. }
  2292. getButton( ID )->press( true );
  2293. }
  2294. void ControlGui::playMovie( const char* fileName )
  2295. {
  2296. if (moviePlaying)
  2297. return;
  2298. RECT vRect;
  2299. vRect.left = videoRect.left;
  2300. vRect.right = videoRect.right;
  2301. vRect.top = videoRect.top;
  2302. vRect.bottom = videoRect.bottom;
  2303. //Chop everything but the actual name.
  2304. // Assume extension is BIK.
  2305. // Assume the movie is in data\movies.
  2306. char realName[1024];
  2307. _splitpath(fileName,NULL,NULL,realName,NULL);
  2308. FullPathFileName movieName;
  2309. movieName.init(moviePath,realName,".bik");
  2310. bMovie = new MC2Movie;
  2311. bMovie->init((char *)movieName,vRect,true);
  2312. //Maybe not enough frames to run. Do not flash the border!
  2313. // Do ONE update to make sure the damned sound starts at least!!
  2314. bMovie->update();
  2315. if (bMovie->isPlaying())
  2316. {
  2317. moviePlaying = true;
  2318. }
  2319. else
  2320. {
  2321. //If we couldn't play it cause of the frame Rate, TOSS it!!
  2322. moviePlaying = false;
  2323. delete bMovie;
  2324. bMovie = NULL;
  2325. }
  2326. }
  2327. void ControlButton::toggle()
  2328. {
  2329. if ( state & DISABLED )
  2330. return;
  2331. else if ( state & HIDDEN )
  2332. return;
  2333. if ( state & PRESSED )
  2334. press( 0 );
  2335. else
  2336. press( 1 );
  2337. }
  2338. bool ControlGui::resultsDone()
  2339. {
  2340. if( ( renderStatusInfo && objectiveTime > Team::home->objectives.Count() + 4 ) )
  2341. {
  2342. // need to empty out force group bar now...
  2343. forceGroupBar.removeAll();
  2344. return true;
  2345. }
  2346. return false;
  2347. }
  2348. void ControlButton::setColor( unsigned long newColor )
  2349. {
  2350. for ( int i = 0; i < 4; i++ )
  2351. location[i].argb = newColor;
  2352. }
  2353. void ControlGui::setRolloverHelpText( unsigned long textID )
  2354. {
  2355. if ( helpTextID && textID != 0 )
  2356. return;
  2357. if ( useLeftRightMouseProfile )
  2358. textID ++;
  2359. helpTextHeaderID = 0;
  2360. helpTextID = textID;
  2361. }
  2362. void ControlGui::toggleHoldPosition()
  2363. {
  2364. if ( getButton( CUR_RANGE )->state == ControlButton::ENABLED )
  2365. {
  2366. setRange( FIRERANGE_CURRENT );
  2367. }
  2368. else
  2369. {
  2370. setRange( FIRERANGE_OPTIMAL );
  2371. }
  2372. soundSystem->playDigitalSample( LOG_SELECT );
  2373. if (MPlayer && !MPlayer->isServer())
  2374. MPlayer->sendHoldPosition();
  2375. else {
  2376. for (long i = 0; i < Team::home->getRosterSize(); i++) {
  2377. Mover* pMover = Team::home->getMover( i );
  2378. if ( pMover->isSelected() && pMover->getCommander()->getId() == Commander::home->getId() )
  2379. {
  2380. if (pMover->getPilot()->getCurTacOrder()->code != TACTICAL_ORDER_NONE) {
  2381. pMover->getPilot()->getCurTacOrder()->attackParams.range = (FireRangeType)pMover->attackRange;
  2382. if (pMover->attackRange == FIRERANGE_CURRENT)
  2383. pMover->getPilot()->getCurTacOrder()->attackParams.pursue = false;
  2384. else if (getFireFromCurrentPos())
  2385. pMover->getPilot()->getCurTacOrder()->attackParams.pursue = false;
  2386. else
  2387. pMover->getPilot()->getCurTacOrder()->attackParams.pursue = true;
  2388. pMover->getPilot()->getCurTacOrder()->pack(NULL, NULL);
  2389. pMover->handleTacticalOrder(*pMover->getPilot()->getCurTacOrder());
  2390. }
  2391. }
  2392. }
  2393. }
  2394. }
  2395. int ControlGui::updateChat()
  2396. {
  2397. if ( bChatting && MPlayer)
  2398. {
  2399. personalEdit.update();
  2400. if ( !personalEdit.hasFocus() )
  2401. {
  2402. // toggleChat(0);
  2403. }
  2404. return 1;
  2405. }
  2406. return 0;
  2407. }
  2408. void ControlGui::toggleChat(bool isTeamOnly)
  2409. {
  2410. bChatting ^= 1;
  2411. if ( !bChatting && MPlayer ) // over -- broadcast messages
  2412. {
  2413. EString tmp;
  2414. personalEdit.getEntry( tmp );
  2415. if ( tmp.Length() )
  2416. {
  2417. char team = chatIsTeamOnly ? MPlayer->getPlayerInfo( MPlayer->commanderID )->team : -1;
  2418. MPlayer->sendChat(0, team, (char*)(const char*)tmp);
  2419. }
  2420. personalEdit.setFocus( 0 );
  2421. }
  2422. else if ( MPlayer )
  2423. {
  2424. personalEdit.limitEntry( 127 );
  2425. personalEdit.setFocus( true );
  2426. personalEdit.setEntry( "" );
  2427. }
  2428. chatIsTeamOnly = isTeamOnly;
  2429. }
  2430. void ControlGui::eatChatKey()
  2431. {
  2432. if ( bChatting )
  2433. personalEdit.setFocus( true );
  2434. else
  2435. personalEdit.setFocus( false );
  2436. }
  2437. void ControlGui::setChatText( const char* playerName, const char* message, unsigned long color, unsigned long chatColor )
  2438. {
  2439. for ( int i = 0; i < MAX_CHAT_COUNT - 1; i++ )
  2440. {
  2441. memcpy( &chatInfos[i], &chatInfos[i+1], sizeof( ChatInfo ) );
  2442. }
  2443. i = MAX_CHAT_COUNT - 1;
  2444. gosASSERT( strlen( message ) < 128 );
  2445. gosASSERT( strlen( playerName ) < 32 );
  2446. chatInfos[i].backgroundColor = color;
  2447. strcpy( chatInfos[i].message, message );
  2448. strcpy( chatInfos[i].playerName, playerName );
  2449. chatInfos[i].time = scenarioTime;
  2450. chatInfos[i].chatTextColor = chatColor;
  2451. long totalHeight = chatEdit.font.height( message, chatEdit.width() );
  2452. long lineHeight = chatEdit.font.height( "A", chatEdit.width() );
  2453. chatInfos[i].messageLength = totalHeight/lineHeight;
  2454. if ( chatInfos[i].messageLength > 1 )
  2455. chatInfos[i].messageLength --;
  2456. if ( MPlayer && ChatWindow::instance() )
  2457. {
  2458. ChatWindow::instance()->update();
  2459. }
  2460. }
  2461. void ControlGui::renderChatText()
  2462. {
  2463. long curLine = 0;
  2464. if ( bChatting && MPlayer)
  2465. {
  2466. playerNameEdit.setColor( 0xff007f00 );
  2467. if ( MPlayer )
  2468. {
  2469. MC2Player* pInfo = MPlayer->getPlayerInfo( MPlayer->commanderID );
  2470. long color = MPlayer->colors[pInfo->baseColor[BASECOLOR_TEAM]];
  2471. long textColor = 0xff000000;
  2472. if ( ((color & 0xff) + ( (color & 0xff00)>>8 ) + ( (color & 0xff0000)>>16 ))/3 < 85 )
  2473. textColor = 0xffffffff;
  2474. playerNameEdit.setColor( color );
  2475. playerNameEdit.setTextColor( textColor );
  2476. long width = playerNameEdit.getFontObject()->width( pInfo->name ) + playerNameEdit.getFontObject()->width( " " );
  2477. playerNameEdit.resize( width + 8, playerNameEdit.height() );
  2478. playerNameEdit.setEntry( pInfo->name );
  2479. personalEdit.move( playerNameEdit.right() - personalEdit.left(), 0 );
  2480. }
  2481. else
  2482. playerNameEdit.setEntry( "Heidi" );
  2483. playerNameEdit.render();
  2484. personalEdit.render();
  2485. curLine++;
  2486. }
  2487. int lineCount = 0;
  2488. int curTime = scenarioTime;
  2489. for ( int i = MAX_CHAT_COUNT - 1; i > -1; i-- )
  2490. {
  2491. if ( chatInfos[i].messageLength && curTime - chatInfos[i].time < CHAT_DISPLAY_TIME )
  2492. {
  2493. lineCount += chatInfos[i].messageLength;
  2494. }
  2495. if ( lineCount > MAX_CHAT_COUNT || curTime - chatInfos[i].time > CHAT_DISPLAY_TIME )
  2496. break;
  2497. }
  2498. i++;
  2499. float height = chatEdit.height();
  2500. for ( ; i < MAX_CHAT_COUNT; i++ )
  2501. {
  2502. if ( i < 0 )
  2503. continue;
  2504. if ( lineCount > MAX_CHAT_COUNT )
  2505. {
  2506. // for now ignore
  2507. // int numToMove = lineCount - MAX_CHAT_COUNT;
  2508. // chatEdit.move( 0, -numToMove * (height + 1 ));
  2509. // chatEdit.render();
  2510. // chatEdit.move( 0, numToMove * (height+1 ));
  2511. // curLine += MAX_CHAT_COUNT - numToMove;
  2512. lineCount -= chatInfos[i].messageLength;
  2513. }
  2514. else
  2515. {
  2516. if ( chatInfos[i].messageLength )
  2517. {
  2518. long color = chatInfos[i].backgroundColor;
  2519. long textColor = 0xff000000;
  2520. if ( ((color & 0xff) + ( (color & 0xff00)>>8 ) + ( (color & 0xff0000)>>16 ))/3 < 85 )
  2521. textColor = 0xffffffff;
  2522. chatEdit.resize( chatEdit.width(), (chatEdit.height()+2) * chatInfos[i].messageLength );
  2523. playerNameEdit.setColor( color );
  2524. playerNameEdit.setTextColor( textColor );
  2525. playerNameEdit.move( 0, curLine * (height+1) );
  2526. long width = playerNameEdit.getFontObject()->width( chatInfos[i].playerName ) + playerNameEdit.getFontObject()->width( " " );
  2527. playerNameEdit.resize( width + 8, playerNameEdit.height() );
  2528. playerNameEdit.setEntry( chatInfos[i].playerName );
  2529. chatEdit.setText( chatInfos[i].message );
  2530. chatEdit.setColor( chatInfos[i].chatTextColor );
  2531. chatEdit.move( playerNameEdit.right() - chatEdit.left() + 4, curLine * (height+1) );
  2532. int oldHeight = chatEdit.font.height();
  2533. chatEdit.resize( chatEdit.width(), chatInfos->messageLength * oldHeight );
  2534. playerNameEdit.render();
  2535. chatEdit.render();
  2536. chatEdit.resize( chatEdit.width(), oldHeight );
  2537. chatEdit.move( 0, -curLine * (height+1) );
  2538. playerNameEdit.move( 0, -curLine * (height+1) );
  2539. }
  2540. curLine += chatInfos[i].messageLength;
  2541. }
  2542. }
  2543. chatEdit.resize( chatEdit.width(), height );
  2544. }
  2545. bool ControlGui::isMoviePlaying()
  2546. {
  2547. if ( moviePlaying )
  2548. return true;
  2549. else if ( forceGroupBar.isPlayingVideo() )
  2550. return true;
  2551. return false;
  2552. }
  2553. bool ControlGui::playPilotVideo( MechWarrior* pPilot, char movieCode )
  2554. {
  2555. // stupid name format = "Worm 1 filter.avi"
  2556. //CHANGED to "worm1" for CD 8.3 reasons.
  2557. // -fs
  2558. char fileName[512];
  2559. strcpy( fileName, moviePath );
  2560. char realPilotName[8];
  2561. strncpy(realPilotName, pPilot->getName(), 7);
  2562. strcat( fileName, realPilotName ); // swap in pilot name when videos are done
  2563. char tmp[3];
  2564. tmp[0] = movieCode;
  2565. tmp[1] = NULL;
  2566. tmp[2] = NULL;
  2567. strcat( fileName, tmp );
  2568. return forceGroupBar.setPilotVideo( fileName, pPilot );
  2569. }
  2570. void ControlGui::endPilotVideo()
  2571. {
  2572. forceGroupBar.setPilotVideo( NULL, NULL );
  2573. }
  2574. void ControlGui::cancelInfo()
  2575. {
  2576. gosEnum_KeyIndex key;
  2577. bool bC, bA, bS;
  2578. MissionInterfaceManager::instance()->getHotKey( INFO_COMMAND_INDEX, key, bS, bC, bA );
  2579. if ( gos_GetKeyStatus( key )!= KEY_HELD )
  2580. getButton( INFO_COMMAND )->press( 0 );
  2581. }
  2582. void ControlGui::showServerMissing()
  2583. {
  2584. if ( !MPlayer )
  2585. return;
  2586. if ( MPlayer->isServerMissing() )
  2587. {
  2588. // send a chat message
  2589. if ( !bServerWarningShown )
  2590. {
  2591. char text[256];
  2592. cLoadString(IDS_SERVER_MIGRATING, text, 255 );
  2593. setChatText( "", text, 0, 0xffffffff );
  2594. bServerWarningShown = true;
  2595. // pause the game
  2596. MissionInterfaceManager::instance()->togglePauseWithoutMenu();
  2597. }
  2598. }
  2599. else
  2600. {
  2601. if ( bServerWarningShown )
  2602. MissionInterfaceManager::instance()->togglePauseWithoutMenu();
  2603. bServerWarningShown = 0;
  2604. }
  2605. }
  2606. //*************************************************************************************************
  2607. // end of file ( controlGui.cpp )