EditorInterface.cpp 103 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include "stdafx.h"
  5. #include "EditorInterface.h"
  6. #include "dstd.h"
  7. #pragma warning( disable:4201 )
  8. #include "mmsystem.h"
  9. #pragma warning( default:4201 )
  10. #ifndef EDITORCAMERA_H
  11. #include "EditorCamera.h"
  12. #endif
  13. #ifndef EDITORMESSAGES_H
  14. #include "EditorMessages.h"
  15. #endif
  16. #ifndef EDITORDATA_H
  17. #include "EditorData.h"
  18. #endif
  19. #ifndef OVERLAYBRUSH_H
  20. #include "OverlayBrush.h"
  21. #endif
  22. #ifndef ACTION_H
  23. #include "Action.h"
  24. #endif
  25. #ifndef TERRAINBRUSH_H
  26. #include "TerrainBrush.h"
  27. #endif
  28. #ifndef UTILITIES_H
  29. #include "Utilities.h"
  30. #endif
  31. #ifndef BUILDINGBRUSH_H
  32. #include "BuildingBrush.h"
  33. #endif
  34. #ifndef ERASER_H
  35. #include "Eraser.h"
  36. #endif
  37. #ifndef SELECTIONBRUSH_H
  38. #include "SelectionBrush.h"
  39. #endif
  40. #ifndef FLATTENBRUSH_H
  41. #include "FlattenBrush.h"
  42. #endif
  43. #ifndef HEIGHTDLG_H
  44. #include "HeightDlg.h"
  45. #endif
  46. #include "SelectSlopeDialog.h"
  47. #ifndef TERRAINDLG_H
  48. #include "TerrainDlg.h"
  49. #endif
  50. #ifndef MAPSIZEDLG_H
  51. #include "MapsizeDlg.h"
  52. #endif
  53. #include "..\resource.h"
  54. #ifndef SUNDLG_H
  55. #include "sunDlg.h"
  56. #endif
  57. #ifndef FOGDLG_H
  58. #include "FogDlg.h"
  59. #endif
  60. #ifndef AFX_WATERDLG_H
  61. #include "WaterDlg.h"
  62. #endif
  63. #ifndef VERTEX_H
  64. #include "Vertex.h"
  65. #endif
  66. #include "NewSingleMission.h"
  67. #ifndef SINGLEVALUEDLG_H
  68. #include "SingleValueDlg.h"
  69. #endif
  70. #include "MissionSettingsDlg.h"
  71. #include "PlayerSettingsDlg.h"
  72. #include "SelectTerrainTypeDlg.h"
  73. #include "FractalDialog.h"
  74. #ifndef EDITOROBJECTS_H
  75. #include "EditorObjects.h"
  76. #endif
  77. #ifndef MESSAGEBOX_H
  78. #include "MessageBox.h"
  79. #endif
  80. #ifndef DRAGTOOL_H
  81. #include "DragTool.h"
  82. #endif
  83. #ifndef DAMAGEBRUSH_H
  84. #include "DamageBrush.h"
  85. #endif
  86. #ifndef MINEBRUSH_H
  87. #include "MineBrush.h"
  88. #endif
  89. #include "resource.h"
  90. #ifndef LINKBRUSH_H
  91. #include "Linkbrush.h"
  92. #endif
  93. #ifndef DROPZONEBRUSH_H
  94. #include "DropZoneBrush.h"
  95. #endif
  96. #include "UnitSettingsDlg.h"
  97. #include "BuildingSettingsDlg.h"
  98. #include "TilingFactorsDialog.h"
  99. #include "MFCPlatform.hpp"
  100. #include "MainFrm.h"
  101. #include "EditorObjects.h"
  102. #include "ForestDlg.h"
  103. #include "EditForestDlg.h"
  104. #include "CampaignDialog.h"
  105. extern bool silentMode;
  106. // ARM
  107. extern char versionStamp[];
  108. #include "../ARM/Microsoft.Xna.Arm.h"
  109. using namespace Microsoft::Xna::Arm;
  110. IProviderEngine * armProvider;
  111. #pragma warning( disable:4244 )
  112. //-----------------------------------
  113. // Frank at work!
  114. CameraPtr eye = NULL;
  115. extern bool drawTerrainTiles;
  116. extern long terrainLineChanged;
  117. extern bool drawTerrainOverlays;
  118. extern bool renderObjects;
  119. extern bool renderTrees;
  120. extern bool drawTerrainGrid;
  121. extern bool drawLOSGrid;
  122. extern bool useClouds;
  123. extern bool useFog;
  124. extern bool useShadows;
  125. extern bool useWaterInterestTexture;
  126. long lightState = 0;
  127. extern bool useFaceLighting;
  128. extern bool useVertexLighting;
  129. extern bool reloadBounds;
  130. bool s_bSensorMapEnabled = false;
  131. extern bool justResaveAllMaps;
  132. extern bool bIsLoading;
  133. EditorInterface* EditorInterface::s_instance = NULL;
  134. extern volatile int ProcessingError;
  135. const float HSCROLLBAR_RANGE = 30000.0;
  136. const float VSCROLLBAR_RANGE = 30000.0;
  137. extern char missionName[];
  138. static char szTGAFilter[] = "TGA Files (*.TGA)|*.tga||";
  139. static char szPAKFilter[] = "Pak Files (*.PAK)|*.pak||";
  140. static bool windowSizeChanged = false;
  141. static float g_newWidth = 0.0;
  142. static float g_newHeight = 0.0;
  143. // EDITOR stuff
  144. void Editor::init( char* loader )
  145. {
  146. volatile float crap = 0;
  147. bool bOK = false;
  148. if ( !eye )
  149. eye = new EditorCamera;
  150. Pilot::initPilots();
  151. FullPathFileName bdgFileName;
  152. bdgFileName.init(artPath,"Buildings",".csv");
  153. FullPathFileName objFileName;
  154. objFileName.init(objectPath,"Object2",".pak");
  155. EditorObjectMgr* pMgr = EditorObjectMgr::instance();
  156. pMgr->init( bdgFileName, objFileName );
  157. FullPathFileName mPath;
  158. mPath.init(missionPath,missionName,".pak");
  159. bool bCanceled = false;
  160. if (!justResaveAllMaps)
  161. {
  162. if (fileExists(mPath))
  163. {
  164. bOK = EditorData::initTerrainFromPCV(mPath);
  165. }
  166. else
  167. {
  168. NewSingleMission dlg;
  169. bool resolved = false;
  170. while (!resolved)
  171. {
  172. int retVal = dlg.DoModal();
  173. if ( retVal == IDCANCEL )
  174. {
  175. EditorInterface::instance()->SetBusyMode();
  176. resolved = true;
  177. gos_TerminateApplication();
  178. PostQuitMessage(0);
  179. bOK = true;
  180. bCanceled = true;
  181. EditorInterface::instance()->UnsetBusyMode();
  182. }
  183. else if ( retVal == ID_NEWMISSION )
  184. {
  185. resolved = true;
  186. while ( !bOK )
  187. {
  188. TerrainDlg dlg;
  189. dlg.terrain = 0;
  190. if ( IDOK == dlg.DoModal() )
  191. {
  192. MapSizeDlg msdlg;
  193. msdlg.mapSize = 0;
  194. if ( IDOK == msdlg.DoModal() )
  195. {
  196. char path[256];
  197. strcpy( path, cameraPath );
  198. strcat( path, "cameras.fit" );
  199. FitIniFile camFile;
  200. if ( NO_ERR != camFile.open( path ) )
  201. {
  202. STOP(( "Need Camera File " ));
  203. }
  204. EditorInterface::instance()->SetBusyMode();
  205. eye->init( &camFile );
  206. bOK = EditorData::initTerrainFromTGA( msdlg.mapSize, 0, 0, dlg.terrain );
  207. EditorInterface::instance()->UnsetBusyMode();
  208. }
  209. else
  210. {
  211. resolved = false;
  212. break;
  213. }
  214. }
  215. else //They pressed cancel. Let 'em cancel, dammit!
  216. {
  217. resolved = false;
  218. break;
  219. }
  220. }
  221. }
  222. else
  223. {
  224. resolved = true;
  225. CFileDialog fileDlg( 1, "pak", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, szPAKFilter );
  226. fileDlg.m_ofn.lpstrInitialDir = missionPath;
  227. bOK = false;
  228. while ( !bOK )
  229. {
  230. if ( IDOK == fileDlg.DoModal() )
  231. {
  232. EditorInterface::instance()->SetBusyMode();
  233. const char* pFile = fileDlg.m_ofn.lpstrFile;
  234. bOK = EditorData::initTerrainFromPCV( pFile );
  235. EditorInterface::instance()->UnsetBusyMode();
  236. }
  237. else
  238. {
  239. resolved = false;
  240. break;
  241. }
  242. }
  243. }
  244. }
  245. }
  246. }
  247. else
  248. {
  249. bOK = true;
  250. }
  251. if (bCanceled)
  252. {
  253. /*We are in the middle of GOS initialization, so even though we are going to exit the
  254. app as soon as possible, we'll allow the GOS initialization to continue.*/
  255. if ( !land )
  256. {
  257. land = new Terrain( );
  258. land->init( 0, (PacketFile*)NULL, EDITOR_VISIBLE_VERTICES, crap, 100 );
  259. }
  260. }
  261. if (bOK)
  262. EditorInterface::instance()->init( loader );
  263. PlaySound("SystemDefault",NULL,SND_ASYNC);
  264. }
  265. void Editor::destroy (void)
  266. {
  267. if (EditorInterface::instance())
  268. {
  269. EditorInterface::instance()->terminate();
  270. }
  271. /*
  272. EditorData::clear()
  273. clears the ActionUndoMgr,
  274. terminates and deletes "land",
  275. and clears EditorObjectMgr
  276. among other things
  277. */
  278. EditorData::clear();
  279. if ( eye )
  280. delete eye;
  281. eye = NULL;
  282. }
  283. void Editor::resaveAll (void)
  284. {
  285. //Startup the editor.
  286. if ( !eye )
  287. eye = new EditorCamera;
  288. // ARM
  289. CoInitialize(NULL);
  290. armProvider = CreateProviderEngine("MC2Editor", versionStamp);
  291. silentMode = true; // shut up the warnings from tgl export
  292. char campaignFiles[2][256] = {0};
  293. strcpy(campaignFiles[0], "Data\\Campaign\\campaign.fit");
  294. strcpy(campaignFiles[1], "Data\\Campaign\\tutorial.fit");
  295. for (int i = 0; i < 2; i++) // once for the campaign, then the tutorial
  296. {
  297. CCampaignData campaignData;
  298. campaignData.Read(campaignFiles[i]);
  299. IProviderAssetPtr campaignAssetPtr = armProvider->OpenAsset(campaignFiles[i],
  300. AssetType_Physical, ProviderType_Primary);
  301. campaignAssetPtr->AddProperty("Type", "Campaign");
  302. int count = 0;
  303. char buf[512] = {0};
  304. // for all groups
  305. for ( EList<CGroupData, CGroupData>::EConstIterator iter = campaignData.m_GroupList.Begin();
  306. !iter.IsDone(); count++, iter++ )
  307. {
  308. CGroupData groupData = (*iter);
  309. // Make a virtual group name
  310. strcpy(buf, campaignFiles[i]);
  311. int campaignLen = strlen(buf);
  312. buf[campaignLen-4] = '_';
  313. buf[campaignLen-3] = 0;
  314. strcat(buf, "group");
  315. char groupId[4] = {0};
  316. sprintf(groupId, "%02d", count+1);
  317. strcat(buf, groupId);
  318. // Add a relationship from the campaign to the virtual group
  319. campaignAssetPtr->AddRelationship("Group", buf);
  320. // Open the virtual asset
  321. IProviderAssetPtr groupAssetPtr = armProvider->OpenAsset(buf, AssetType_Virtual, ProviderType_Primary);
  322. groupAssetPtr->AddProperty("Type", "Mission Group");
  323. // Add all the relationships
  324. if (groupData.m_OperationFile != "")
  325. {
  326. strcpy(buf, "Data\\Art\\");
  327. strcat(buf, groupData.m_OperationFile.GetBuffer());
  328. strcat(buf, ".fit");
  329. groupAssetPtr->AddRelationship("Operation", buf);
  330. }
  331. if (groupData.m_ABLScript != "")
  332. {
  333. strcpy(buf, "Data\\Missions\\");
  334. strcat(buf, groupData.m_ABLScript.GetBuffer());
  335. strcat(buf, ".abl");
  336. groupAssetPtr->AddRelationship("ABLScript", buf);
  337. }
  338. if (groupData.m_PreVideoFile != "")
  339. {
  340. strcpy(buf, "Data\\Movies\\");
  341. strcat(buf, groupData.m_PreVideoFile.GetBuffer());
  342. // The only instances of PreVideoFile I've seen had the extension already
  343. groupAssetPtr->AddRelationship("PreVideo", buf);
  344. }
  345. if (groupData.m_VideoFile != "")
  346. {
  347. strcpy(buf, "Data\\Movies\\");
  348. strcat(buf, groupData.m_VideoFile.GetBuffer());
  349. strcat(buf, ".bik");
  350. groupAssetPtr->AddRelationship("Video", buf);
  351. }
  352. // for all missions part of this group
  353. for ( EList<CMissionData, CMissionData>::EConstIterator iter2 = groupData.m_MissionList.Begin();
  354. !iter2.IsDone(); iter2++ )
  355. {
  356. CMissionData missionData = *(iter2);
  357. if (missionData.m_MissionFile != "")
  358. {
  359. strcpy(buf, "Data\\Missions\\");
  360. strcat(buf, missionData.m_MissionFile.GetBuffer());
  361. strcat(buf, ".fit");
  362. groupAssetPtr->AddRelationship("Mission", buf);
  363. }
  364. if (missionData.m_PurchaseFile != "")
  365. {
  366. strcpy(buf, "Data\\Missions\\");
  367. strcat(buf, missionData.m_PurchaseFile.GetBuffer());
  368. strcat(buf, ".fit");
  369. IProviderRelationshipPtr rel = groupAssetPtr->AddRelationship("PurchaseFile", buf);
  370. rel->AddProperty("Mission", missionData.m_MissionFile.GetBuffer());
  371. }
  372. }
  373. groupAssetPtr->Close();
  374. }
  375. campaignAssetPtr->Close();
  376. }
  377. Pilot::initPilots();
  378. char bdgFileName[256];
  379. strcpy( bdgFileName, artPath );
  380. strcat( bdgFileName, "Buildings.csv" );
  381. _strlwr(bdgFileName);
  382. char objFileName[256];
  383. strcpy( objFileName, objectPath );
  384. strcat( objFileName, "object2.pak" );
  385. _strlwr(objFileName);
  386. EditorObjectMgr* pMgr = EditorObjectMgr::instance();
  387. pMgr->init( bdgFileName, objFileName );
  388. //----------------------------------------------------------------------------
  389. //Recurse through the data\missions directory and resave every .PAK you find!
  390. char findString[512];
  391. sprintf(findString,"%s*.pak",missionPath);
  392. WIN32_FIND_DATA findResult;
  393. HANDLE searchHandle = FindFirstFile(findString,&findResult);
  394. do
  395. {
  396. if ((findResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
  397. {
  398. char baseName[1024];
  399. _splitpath(findResult.cFileName,NULL,NULL,baseName,NULL);
  400. FullPathFileName pakName;
  401. pakName.init(missionPath,baseName,".pak");
  402. FullPathFileName fitName;
  403. fitName.init(missionPath,baseName,".fit");
  404. if (fileExists(pakName))
  405. {
  406. //Force Attributes to RW!
  407. SetFileAttributes(pakName,FILE_ATTRIBUTE_NORMAL);
  408. SetFileAttributes(fitName,FILE_ATTRIBUTE_NORMAL);
  409. long result = EditorData::initTerrainFromPCV(pakName);
  410. if (result)
  411. data.save(pakName);
  412. printf( "Resaved Map %s", pakName );
  413. //Force Back to RO!
  414. //Leave RW per bug 1252
  415. // SetFileAttributes(pakName,FILE_ATTRIBUTE_READONLY);
  416. // SetFileAttributes(fitName,FILE_ATTRIBUTE_READONLY);
  417. }
  418. }
  419. } while (FindNextFile(searchHandle,&findResult) != 0);
  420. FindClose(searchHandle);
  421. // ARM
  422. CoUninitialize();
  423. }
  424. void Editor::render()
  425. {
  426. if ( eye )
  427. eye->render();
  428. }
  429. void Editor::update()
  430. {
  431. if (windowSizeChanged)
  432. {
  433. windowSizeChanged = false;
  434. gos_SetScreenMode(g_newWidth, g_newHeight);
  435. }
  436. //interMgr.update();
  437. mcTextureManager->clearArrays();
  438. eye->update();
  439. if (land->terrainTextures2 && !(land->terrainTextures2->colorMapStarted) && (EditorInterface::instance()))
  440. {
  441. EditorInterface::instance()->SetBusyMode(false/*no redraw*/);
  442. land->update();
  443. EditorInterface::instance()->UnsetBusyMode();
  444. }
  445. else
  446. {
  447. land->update();
  448. }
  449. land->clearObjBlocksActive();
  450. land->geometry();
  451. EditorInterface::instance()->update();
  452. EditorObjectMgr::instance()->update();
  453. }
  454. //--------------------------------------------------------------------------------------
  455. BEGIN_MESSAGE_MAP(EditorInterface,CWnd )
  456. //{{AFX_MSG_MAP(EditorInterface)
  457. ON_WM_CREATE()
  458. ON_WM_LBUTTONDOWN()
  459. ON_WM_LBUTTONUP()
  460. ON_WM_MOUSEMOVE()
  461. ON_WM_SETCURSOR()
  462. ON_WM_KEYUP()
  463. ON_WM_RBUTTONDOWN()
  464. ON_WM_RBUTTONUP()
  465. ON_WM_MOUSEWHEEL()
  466. ON_WM_HSCROLL()
  467. ON_WM_VSCROLL()
  468. ON_WM_SYSKEYDOWN()
  469. ON_WM_LBUTTONDBLCLK()
  470. ON_WM_PAINT()
  471. ON_COMMAND(ID_VIEW_REFRESHTACMAP, OnViewRefreshtacmap)
  472. ON_UPDATE_COMMAND_UI(ID_MISSION_PLAYER_PLAYER3, OnUpdateMissionPlayerPlayer3)
  473. ON_UPDATE_COMMAND_UI(ID_MISSION_PLAYER_PLAYER4, OnUpdateMissionPlayerPlayer4)
  474. ON_UPDATE_COMMAND_UI(ID_MISSION_PLAYER_PLAYER5, OnUpdateMissionPlayerPlayer5)
  475. ON_UPDATE_COMMAND_UI(ID_MISSION_PLAYER_PLAYER6, OnUpdateMissionPlayerPlayer6)
  476. ON_UPDATE_COMMAND_UI(ID_MISSION_PLAYER_PLAYER7, OnUpdateMissionPlayerPlayer7)
  477. ON_UPDATE_COMMAND_UI(ID_MISSION_PLAYER_PLAYER8, OnUpdateMissionPlayerPlayer8)
  478. ON_UPDATE_COMMAND_UI(ID_MISSION_TEAM_TEAM3, OnUpdateMissionTeamTeam3)
  479. ON_UPDATE_COMMAND_UI(ID_MISSION_TEAM_TEAM4, OnUpdateMissionTeamTeam4)
  480. ON_UPDATE_COMMAND_UI(ID_MISSION_TEAM_TEAM5, OnUpdateMissionTeamTeam5)
  481. ON_UPDATE_COMMAND_UI(ID_MISSION_TEAM_TEAM6, OnUpdateMissionTeamTeam6)
  482. ON_UPDATE_COMMAND_UI(ID_MISSION_TEAM_TEAM7, OnUpdateMissionTeamTeam7)
  483. ON_UPDATE_COMMAND_UI(ID_MISSION_TEAM_TEAM8, OnUpdateMissionTeamTeam8)
  484. ON_WM_DESTROY()
  485. ON_COMMAND(ID_FOREST_TOOL, OnForestTool)
  486. ON_COMMAND(ID_OTHER_EDITFORESTS, OnOtherEditforests)
  487. ON_COMMAND(ID_VIEW_ORTHOGRAPHICCAMERA, OnViewOrthographiccamera)
  488. ON_COMMAND(ID_VIEW_SHOWPASSABILITYMAP, OnViewShowpassabilitymap)
  489. ON_WM_MBUTTONUP()
  490. //}}AFX_MSG_MAP
  491. ON_UPDATE_COMMAND_UI_RANGE(0, 0xffff, UpdateButton )
  492. ON_COMMAND_RANGE( 0, 0xffff, OnCommand )
  493. END_MESSAGE_MAP()
  494. EditorInterface::EditorInterface()
  495. {
  496. bThisIsInitialized = false;
  497. painting = false;
  498. curBrush = NULL;
  499. selecting = true;
  500. realRotation = 0.0;
  501. currentBrushID = IDS_SELECT;
  502. currentBrushMenuID = ID_OTHER_SELECT;
  503. smoothRadius = 2;
  504. dragging = false;
  505. prevBrush = NULL;
  506. prevSelecting = false;
  507. highlighted = false;
  508. prevPainting = false;
  509. prevDragging = false;
  510. gosASSERT( !s_instance );
  511. s_instance = this;
  512. bSmooth = false;
  513. lastKey = -1;
  514. lastClickPos.x = lastClickPos.y = lastClickPos.z = 0.;
  515. hCursor = 0;
  516. bObjectSelectOnlyMode = false;
  517. menus = NULL;
  518. m_hAccelTable = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));
  519. m_hSplashBitMap = NULL;
  520. m_hBusyCursor = NULL;
  521. m_AppIsBusy = 0;
  522. m_bInRunGameOSLogicCall = false;
  523. rightDrag = 0;
  524. }
  525. EditorInterface::~EditorInterface()
  526. {
  527. if (bThisIsInitialized)
  528. {
  529. terminate();
  530. }
  531. if (m_hBusyCursor) {
  532. /*this is done here because m_hBusyCursor is sometimes used before EditorInterface
  533. is "initialized" and after it is "terminated" */
  534. DestroyCursor(m_hBusyCursor);
  535. m_hBusyCursor = NULL;
  536. }
  537. if (m_hSplashBitMap) {
  538. DeleteObject(m_hSplashBitMap);
  539. m_hSplashBitMap = NULL;
  540. }
  541. s_instance = NULL;
  542. }
  543. void EditorInterface::terminate()
  544. {
  545. if (bThisIsInitialized)
  546. {
  547. bThisIsInitialized = false;
  548. if ( curBrush )
  549. delete curBrush; curBrush = NULL;
  550. if (EditorObjectMgr::instance())
  551. {
  552. int count = EditorObjectMgr:: instance()->getBuildingGroupCount();
  553. for ( int i = 0; i < count+1; ++i )
  554. {
  555. delete menus[i]; menus[i] = NULL;
  556. }
  557. }
  558. free( menus );
  559. menus = NULL;
  560. objectivesEditState.Clear();
  561. }
  562. }
  563. void EditorInterface::init( const char* fileName )
  564. {
  565. SetBusyMode(false/*no redraw*/);
  566. FitIniFile loader;
  567. loader.open( const_cast<char*>(fileName) );
  568. long result = loader.seekBlock("CameraData");
  569. gosASSERT(result == NO_ERR);
  570. result = loader.readIdFloat("ScrollIncrement",scrollInc);
  571. gosASSERT(result == NO_ERR);
  572. result = loader.readIdFloat("RotationIncrement",rotationInc);
  573. gosASSERT(result == NO_ERR);
  574. result = loader.readIdFloat("ZoomIncrement",zoomInc);
  575. gosASSERT(result == NO_ERR);
  576. result = loader.readIdFloat("ScrollLeft",screenScrollLeft);
  577. gosASSERT(result == NO_ERR);
  578. result = loader.readIdFloat("ScrollRight",screenScrollRight);
  579. gosASSERT(result == NO_ERR);
  580. result = loader.readIdFloat("ScrollUp",screenScrollUp);
  581. gosASSERT(result == NO_ERR);
  582. result = loader.readIdFloat("ScrollDown",screenScrollDown);
  583. gosASSERT(result == NO_ERR);
  584. result = loader.readIdFloat("BaseFrameLength",baseFrameLength);
  585. gosASSERT(result == NO_ERR);
  586. result = loader.readIdFloat("RotationDegPerSec",degPerSecRot);
  587. gosASSERT(result == NO_ERR);
  588. float missionDragThreshold;
  589. result = loader.readIdFloat("MouseDragThreshold",missionDragThreshold);
  590. gosASSERT(result == NO_ERR);
  591. float missionDblClkThreshold;
  592. result = loader.readIdFloat("MouseDoubleClickThreshold",missionDblClkThreshold);
  593. gosASSERT(result == NO_ERR);
  594. addBuildingsToNewMenu();
  595. curBrush = new SelectionBrush( false, -1 );
  596. ChangeCursor( IDC_MC2ARROW );
  597. syncScrollBars();
  598. initTacMap();
  599. UnsetBusyMode();
  600. bThisIsInitialized = true;
  601. }
  602. void EditorInterface::addBuildingsToNewMenu()
  603. {
  604. EditorObjectMgr* pMgr = EditorObjectMgr::instance();
  605. char BuildingHeader[64];
  606. char TerrainHeader[64];
  607. cLoadString( IDS_BUILDINGS, BuildingHeader, 64, gameResourceHandle );
  608. cLoadString( IDS_TERRAINS, TerrainHeader, 64, gameResourceHandle );
  609. CMenu* pMenu = new CMenu;
  610. pMenu->CreatePopupMenu();
  611. // now i need to add the buildings to the toolbars/menus
  612. int groupCount = pMgr->getBuildingGroupCount( );
  613. const char** pNames = ( const char** )malloc( sizeof( const char *) * groupCount );
  614. pMgr->getBuildingGroupNames( pNames, groupCount );
  615. menus = (CMenu**) malloc( sizeof( CMenu* ) * (groupCount + 2) );
  616. menus[0] = pMenu;
  617. int id = IDS_OBJECT_200;
  618. for ( int i = 0; i < groupCount; ++i )
  619. {
  620. CMenu* pChildMenu = new CMenu;
  621. pChildMenu->CreatePopupMenu();
  622. menus[i + 1] = pChildMenu;
  623. // now add sub items to the group
  624. int buildingCount = pMgr->getNumberBuildingsInGroup( i );
  625. const char** pBuildingNames = (const char**)malloc( sizeof( const char * ) * buildingCount );
  626. pMgr->getBuildingNamesInGroup( i, pBuildingNames, buildingCount );
  627. for ( int j = 0; j < buildingCount; ++j, ++id )
  628. {
  629. CString oldName;
  630. bool bAdded = 0;
  631. int count = pChildMenu->GetMenuItemCount();
  632. for (int k = 0; k < count; ++k )
  633. {
  634. pChildMenu->GetMenuString( k, oldName, MF_BYPOSITION );
  635. if ( oldName > pBuildingNames[j] )
  636. {
  637. pChildMenu->InsertMenu( k, MF_BYPOSITION, id, pBuildingNames[j] );
  638. bAdded = 1;
  639. break;
  640. }
  641. }
  642. if ( !bAdded )
  643. pChildMenu->AppendMenu(MF_STRING, id, pBuildingNames[j] );
  644. }
  645. CString oldName;
  646. bool bAdded = 0;
  647. int count = pMenu->GetMenuItemCount();
  648. for (int k = 0; k < count; ++k )
  649. {
  650. pMenu->GetMenuString( k, oldName, MF_BYPOSITION );
  651. if ( oldName > pNames[i] )
  652. {
  653. pMenu->InsertMenu( k, MF_BYPOSITION | MF_POPUP, (UINT)pChildMenu->m_hMenu, pNames[i] );
  654. bAdded = 1;
  655. break;
  656. }
  657. }
  658. if ( !bAdded )
  659. pMenu->AppendMenu(MF_POPUP, (UINT)pChildMenu->m_hMenu, pNames[i]);
  660. free( pBuildingNames );
  661. }
  662. AfxGetMainWnd()->GetMenu()->InsertMenu( 5, MF_BYPOSITION | MF_POPUP, (UINT)pMenu->m_hMenu, BuildingHeader );
  663. CMenu* pChildMenu = new CMenu;
  664. pChildMenu->CreatePopupMenu();
  665. menus[i + 1] = pChildMenu;
  666. int numTerrains = 0;
  667. numTerrains = land->terrainTextures->getNumTypes();
  668. for ( i = groupCount; i < numTerrains + groupCount; i++ )
  669. {
  670. char buffer[256];
  671. int nameID = land->terrainTextures->getTextureNameID(i - groupCount);
  672. bool continueFlag = true;
  673. switch (nameID)
  674. {
  675. case 10020/*Cement 1*/:
  676. case 10021/*Cement 1 (angled)*/:
  677. case 10022/*Cement 2*/:
  678. case 10023/*Cement 2 (angled)*/:
  679. case 10024/*Cement 3*/:
  680. case 10025/*Cement 3 (angled)*/:
  681. case 10026/*Cement 1 (crumbled)*/:
  682. case 10027/*Cement 2 (crumbled)*/:
  683. case 10069/*Cement 3 (crumbled)*/:
  684. continueFlag = false;
  685. break;
  686. };
  687. if (continueFlag)
  688. continue;
  689. cLoadString( land->terrainTextures->getTextureNameID(i - groupCount), buffer, 256 );
  690. int count = pChildMenu->GetMenuItemCount();
  691. bool bPlaced = 0;
  692. CString newStr( buffer );
  693. for ( int j = 0; j < count; ++j )
  694. {
  695. CString tmp;
  696. pChildMenu->GetMenuString( j, tmp, MF_BYPOSITION );
  697. if ( tmp > newStr )
  698. {
  699. pChildMenu->InsertMenu( j, MF_BYPOSITION, ID_TERRAINS_BLUEWATER + i - groupCount, buffer );
  700. bPlaced = 1;
  701. break;
  702. }
  703. }
  704. if ( !bPlaced )
  705. pChildMenu->AppendMenu( MF_STRING, ID_TERRAINS_BLUEWATER + i - groupCount, buffer );
  706. }
  707. AfxGetMainWnd()->GetMenu()->InsertMenu( 4, MF_BYPOSITION | MF_POPUP, (UINT)pChildMenu->m_hMenu, TerrainHeader );
  708. AfxGetMainWnd()->DrawMenuBar();
  709. free( pNames );
  710. }
  711. //--------------------------------------------------------------------------------------
  712. void EditorInterface::handleNewMenuMessage( long specificMessage )
  713. {
  714. if ( !eye || !eye->active )
  715. return;
  716. if (EditorInterface::instance()->ObjectSelectOnlyMode())
  717. {
  718. PlaySound("SystemDefault",NULL,SND_ASYNC);
  719. return;
  720. }
  721. // special check for building range
  722. if ( specificMessage >= IDS_OBJECT_200 && specificMessage <= 30800 )
  723. {
  724. paintBuildings( specificMessage );
  725. }
  726. if ( specificMessage >= ID_TERRAINS_BLUEWATER - 1 && specificMessage <= ID_TERRAINS_BLUEWATER + 255 )
  727. {
  728. PaintTerrain( specificMessage - ID_TERRAINS_BLUEWATER );
  729. return;
  730. }
  731. else if ( specificMessage >= ID_ALIGNMENT_TEAM1 && specificMessage <= ID_ALIGNMENT_TEAM1 + 9 )
  732. {
  733. Alignment( specificMessage );
  734. }
  735. else
  736. {
  737. switch (specificMessage) {
  738. case ID_FILE_ASSIGNHEIGHTMAP:
  739. case ID_FOG:
  740. case ID_OTHER_RELOADBASETEXTURE:
  741. case ID_OTHER_SETBASETEXTURENAME:
  742. case ID_LIGHT:
  743. case ID_WAVES:
  744. case ID_OTHER_ASSIGNHEIGHT:
  745. case ID_MISSION_SETTINGS:
  746. case ID_MISSION_PLAYER_PLAYER1:
  747. case ID_MISSION_PLAYER_PLAYER2:
  748. case ID_MISSION_PLAYER_PLAYER3:
  749. case ID_MISSION_PLAYER_PLAYER4:
  750. case ID_MISSION_PLAYER_PLAYER5:
  751. case ID_MISSION_PLAYER_PLAYER6:
  752. case ID_MISSION_PLAYER_PLAYER7:
  753. case ID_MISSION_PLAYER_PLAYER8:
  754. case ID_OTHER_SELECTDETAILTEXTURE:
  755. case ID_OTHER_SELECTWATERTEXTURE:
  756. case ID_OTHER_SELECTWATERDETAILTEXTURE:
  757. case ID_OTHER_TEXTURETILINGFACTORS:
  758. case ID_SKY_SKY1:
  759. case ID_SKY_SKY2:
  760. case ID_SKY_SKY3:
  761. case ID_SKY_SKY4:
  762. case ID_SKY_SKY5:
  763. case ID_SKY_SKY6:
  764. case ID_SKY_SKY7:
  765. case ID_SKY_SKY8:
  766. case ID_SKY_SKY9:
  767. case ID_SKY_SKY10:
  768. case ID_SKY_SKY11:
  769. case ID_SKY_SKY12:
  770. case ID_SKY_SKY13:
  771. case ID_SKY_SKY14:
  772. case ID_SKY_SKY15:
  773. case ID_SKY_SKY16:
  774. case ID_SKY_SKY17:
  775. case ID_SKY_SKY18:
  776. case ID_SKY_SKY19:
  777. case ID_SKY_SKY20:
  778. case ID_SKY_SKY21:
  779. case ID_OTHER_REFRACTALIZETERRAIN:
  780. /*not sure these are still used*/
  781. case ID_PURGE_TRANSITIONS:
  782. case ID_SHOW_TRANSITIONS:
  783. case ID_DROPZONES_ADD:
  784. case ID_DROPZONES_VTOL:
  785. case IDS_SAVE_CAMERAS:
  786. {
  787. if (EditorData::instance)
  788. {
  789. EditorData::instance->MissionNeedsSaving(true);
  790. }
  791. }
  792. break;
  793. }
  794. switch (specificMessage) {
  795. case ID_FILE_NEW2: { New(); } break;
  796. case ID_FILE_OPEN2: { FileOpen(); } break;
  797. case ID_FILE_SAVEAS: { SaveAs(); } break;
  798. case ID_FILE_SAVE: { Save(); } break;
  799. case ID_FILE_QUICKSAVE: { QuickSave(); } break;
  800. case ID_FILE_ASSIGNHEIGHTMAP: { NewHeightMap(); } break;
  801. case ID_FILE_EXIT: { Quit(); } break;
  802. case ID_EDIT_UNDO2: { Undo(); } break;
  803. case ID_EDIT_REDO2: { Redo(); } break;
  804. case ID_EDIT_COPY2: { ; } break;
  805. case ID_OVERLAYS_DIRTROAD: { PaintDirtRoad(); } break;
  806. case ID_OVERLAYS_PAEVEDROAD: { PaintPaved(); } break;
  807. case ID_OVERLAYS_ROUGH: { PaintRocks(); } break;
  808. case ID_OVERLAYS_TWOLANEDIRTROAD: { PaintTwoLaneDirtRoad(); } break;
  809. case ID_OVERLAYS_DAMAGEDROAD: { PaintDamagedRoad(); } break;
  810. case ID_OVERLAYS_RUNWAY: { PaintRunway(); } break;
  811. case ID_OVERLAYS_BRIDGE: { PaintBridge(); } break;
  812. case ID_OVERLAYS_DAMAGEDBRIDGE: { PaintDamagedBridge(); } break;
  813. case ID_OTHER_ERASE: { Erase(); } break;
  814. case ID_OTHER_SELECT: { Select(); } break;
  815. case ID_OTHER_FLATTEN: { Flatten(); } break;
  816. case IDS_SELECT_SLOPES: SelectSlopes(); break;
  817. case IDS_SELECT_ALTITUDE: SelectAltitude(); break;
  818. case ID_SELECT_TERRAIN_TYPE: SelectTerrainType(); break;
  819. case ID_FOG: Fog(); break;
  820. case ID_OTHER_RELOADBASETEXTURE: ReloadBaseTexture(); break;
  821. case ID_OTHER_SETBASETEXTURENAME: SetBaseTexture(); break;
  822. case ID_PURGE_TRANSITIONS: PurgeTransitions(); break;
  823. case ID_SHOW_TRANSITIONS: ShowTransitions(); break;
  824. case ID_LIGHT: Light(); break;
  825. case IDS_SAVE_CAMERAS: SaveCameras(); break;
  826. case ID_WAVES: Waves(); break;
  827. case ID_DRAGSMOOTH : DragSmooth(); break;
  828. case ID_DRAGNORMAL : DragRough(); break;
  829. case ID_OTHER_ASSIGNHEIGHT : AssignElevation(); break;
  830. case ID_SMOOTH_RADIUS: SmoothRadius(); break;
  831. case ID_SAVE_HEIGHT_MAP : SaveHeightMap(); break;
  832. case ID_MISSION_SETTINGS: MissionSettings(); break;
  833. case ID_MISSION_TEAM_TEAM1: Team(0); break;
  834. case ID_MISSION_TEAM_TEAM2: Team(1); break;
  835. case ID_MISSION_TEAM_TEAM3: Team(2); break;
  836. case ID_MISSION_TEAM_TEAM4: Team(3); break;
  837. case ID_MISSION_TEAM_TEAM5: Team(4); break;
  838. case ID_MISSION_TEAM_TEAM6: Team(5); break;
  839. case ID_MISSION_TEAM_TEAM7: Team(6); break;
  840. case ID_MISSION_TEAM_TEAM8: Team(7); break;
  841. case ID_MISSION_PLAYER_PLAYER1: Player(0); break;
  842. case ID_MISSION_PLAYER_PLAYER2: Player(1); break;
  843. case ID_MISSION_PLAYER_PLAYER3: Player(2); break;
  844. case ID_MISSION_PLAYER_PLAYER4: Player(3); break;
  845. case ID_MISSION_PLAYER_PLAYER5: Player(4); break;
  846. case ID_MISSION_PLAYER_PLAYER6: Player(5); break;
  847. case ID_MISSION_PLAYER_PLAYER7: Player(6); break;
  848. case ID_MISSION_PLAYER_PLAYER8: Player(7); break;
  849. case ID_OTHER_DAMAGE: Damage( 1); break;
  850. case ID_OTHER_REPAIR: Damage( 0 ); break;
  851. case ID_OTHER_LINK: Link( true ); break;
  852. case ID_OTHER_UNLINK: Link( false ); break;
  853. case ID_OTHER_LAYMINES: LayMines(); break;
  854. case ID_OTHER_SELECTDETAILTEXTURE: SelectDetailTexture(); break;
  855. case ID_OTHER_SELECTWATERTEXTURE: SelectWaterTexture(); break;
  856. case ID_OTHER_SELECTWATERDETAILTEXTURE: SelectWaterDetailTexture(); break;
  857. case ID_OTHER_TEXTURETILINGFACTORS: TextureTilingFactors(); break;
  858. case ID_DROPZONES_ADD: DropZone( false ); break;
  859. case ID_DROPZONES_VTOL : DropZone( true ); break;
  860. case ID_UNITSETTINGS : UnitSettings(); break;
  861. case ID_SKY_SKY1 : SetSky(1); break;
  862. case ID_SKY_SKY2 : SetSky(2); break;
  863. case ID_SKY_SKY3 : SetSky(3); break;
  864. case ID_SKY_SKY4 : SetSky(4); break;
  865. case ID_SKY_SKY5 : SetSky(5); break;
  866. case ID_SKY_SKY6 : SetSky(6); break;
  867. case ID_SKY_SKY7 : SetSky(7); break;
  868. case ID_SKY_SKY8 : SetSky(8); break;
  869. case ID_SKY_SKY9 : SetSky(9); break;
  870. case ID_SKY_SKY10 : SetSky(10); break;
  871. case ID_SKY_SKY11 : SetSky(11); break;
  872. case ID_SKY_SKY12 : SetSky(12); break;
  873. case ID_SKY_SKY13 : SetSky(13); break;
  874. case ID_SKY_SKY14 : SetSky(14); break;
  875. case ID_SKY_SKY15 : SetSky(15); break;
  876. case ID_SKY_SKY16 : SetSky(16); break;
  877. case ID_SKY_SKY17 : SetSky(17); break;
  878. case ID_SKY_SKY18 : SetSky(18); break;
  879. case ID_SKY_SKY19 : SetSky(19); break;
  880. case ID_SKY_SKY20 : SetSky(20); break;
  881. case ID_SKY_SKY21 : SetSky(21); break;
  882. case ID_OTHER_REFRACTALIZETERRAIN : RefractalizeTerrain(1); break;
  883. case ID_CAMPAIGN_EDITOR : CampaignEditor(); break;
  884. }
  885. }
  886. }
  887. //--------------------------------------------------------------------------------------
  888. int EditorInterface::Quit()
  889. {
  890. int res = PromptAndSaveIfNecessary();
  891. if (IDCANCEL != res) {
  892. SetBusyMode();
  893. gos_TerminateApplication();
  894. PostQuitMessage(0);
  895. UnsetBusyMode();
  896. }
  897. return 1;
  898. }
  899. //--------------------------------------------------------------------------------------
  900. int EditorInterface::PromptAndSaveIfNecessary()
  901. {
  902. int res = IDNO;
  903. bool endFlag = false;
  904. while (!endFlag) {
  905. endFlag = true;
  906. if (EditorInterface::instance() && EditorInterface::instance()->ThisIsInitialized()
  907. && EditorData::instance) {
  908. if (EditorInterface::instance()->undoMgr.ThereHasBeenANetChangeFromWhenLastSaved()) {
  909. res = AfxMessageBox(IDS_DO_YOU_WANT_TO_SAVE_YOUR_CHANGES, MB_YESNOCANCEL);
  910. } else if (EditorData::instance->MissionNeedsSaving()) {
  911. res = AfxMessageBox(IDS_DO_YOU_WANT_TO_SAVE_THIS_MISSION, MB_YESNOCANCEL);
  912. }
  913. }
  914. if (IDYES == res) {
  915. SetBusyMode();
  916. int saveRes = EditorInterface::instance()->Save();
  917. UnsetBusyMode();
  918. if (IDCANCEL == saveRes) {
  919. endFlag = false;
  920. }
  921. }
  922. }
  923. return res;
  924. }
  925. //--------------------------------------------------------------------------------------
  926. int EditorInterface::New()
  927. {
  928. int res = PromptAndSaveIfNecessary();
  929. if (IDCANCEL == res) {
  930. return false;
  931. }
  932. bool bOK = false;
  933. while ( !bOK )
  934. {
  935. TerrainDlg dlg;
  936. dlg.terrain = 0;
  937. if ( IDOK == dlg.DoModal() )
  938. {
  939. MapSizeDlg msdlg;
  940. msdlg.mapSize = 0;
  941. if ( IDOK == msdlg.DoModal() )
  942. {
  943. SetBusyMode();
  944. eye->reset();
  945. bOK = EditorData::initTerrainFromTGA( msdlg.mapSize, 0, 0, dlg.terrain );
  946. UnsetBusyMode();
  947. }
  948. else
  949. {
  950. return true;
  951. }
  952. }
  953. else //They pressed cancel. Let 'em cancel, dammit!
  954. {
  955. return true;
  956. }
  957. }
  958. tacMap.UpdateMap();
  959. syncScrollBars();
  960. return true;
  961. }
  962. //--------------------------------------------------------------------------------------
  963. int EditorInterface::FileOpen()
  964. {
  965. int res = PromptAndSaveIfNecessary();
  966. if (IDCANCEL == res) {
  967. return false;
  968. }
  969. CFileDialog fileDlg( 1, "pak", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, szPAKFilter );
  970. fileDlg.m_ofn.lpstrInitialDir = missionPath;
  971. if ( IDOK == fileDlg.DoModal() )
  972. {
  973. SetBusyMode();
  974. const char* pFile = fileDlg.m_ofn.lpstrFile;
  975. EditorData::initTerrainFromPCV( pFile );
  976. tacMap.UpdateMap();
  977. syncScrollBars();
  978. PlaySound("SystemDefault",NULL,SND_ASYNC);
  979. UnsetBusyMode();
  980. }
  981. return true;
  982. }
  983. //--------------------------------------------------------------------------------------
  984. void EditorInterface::handleLeftButtonDown( int PosX, int PosY )
  985. {
  986. if ( !eye || !eye->active )
  987. return;
  988. Stuff::Vector3D vector;
  989. Stuff::Vector2DOf<long> v2( PosX, PosY );
  990. eye->inverseProject( v2, vector );
  991. if ( curBrush )
  992. {
  993. painting = true;
  994. curBrush->beginPaint( );
  995. if ( curBrush->canPaint( vector, PosX, PosY, 0 ) )
  996. curBrush->paint( vector, PosX, PosY );
  997. }
  998. lastClickPos = vector;
  999. }
  1000. void EditorInterface::handleMouseMove( int PosX, int PosY )
  1001. {
  1002. if ( !eye || !eye->active )
  1003. return;
  1004. Stuff::Vector3D vector;
  1005. Stuff::Vector2DOf<long> v2( PosX, PosY );
  1006. eye->inverseProject( v2, vector );
  1007. if ( curBrush && ( painting ) )
  1008. {
  1009. if ( curBrush->canPaint( vector, PosX, PosY, 0 ) )
  1010. curBrush->paint( vector, PosX, PosY );
  1011. }
  1012. //------------------------------------------------
  1013. // Right drag is camera rotation and tilt now.
  1014. if ( rightDrag )
  1015. {
  1016. long mouseXDelta = PosX - lastX;
  1017. float actualRot = rotationInc * 0.1f * abs(mouseXDelta);
  1018. if (mouseXDelta > 0)
  1019. {
  1020. eye->rotateRight(actualRot);
  1021. }
  1022. else if (mouseXDelta < 0)
  1023. {
  1024. eye->rotateLeft(actualRot);
  1025. }
  1026. long mouseYDelta = PosY - lastY;
  1027. float actualTilt = rotationInc * 0.1f * abs(mouseYDelta);
  1028. if (mouseYDelta > 0)
  1029. {
  1030. eye->tiltDown(actualTilt);
  1031. }
  1032. else if (mouseYDelta < 0)
  1033. {
  1034. eye->tiltUp(actualTilt);
  1035. }
  1036. lastX = PosX;
  1037. lastY = PosY;
  1038. SafeRunGameOSLogic();
  1039. tacMap.RedrawWindow();
  1040. syncScrollBars();
  1041. }
  1042. char buffer2[256];
  1043. sprintf( buffer2, "%.3f, %.3f", vector.x, vector.y );
  1044. // need to put this value in the appropriate place.
  1045. ((MainFrame*)AfxGetMainWnd())->m_wndDlgBar.GetDlgItem( IDC_COORDINATES_EDIT )->SetWindowText( buffer2 );
  1046. char buffer3[256];
  1047. sprintf( buffer3, "%.3f", vector.z );
  1048. // need to put this value in the appropriate place.
  1049. ((MainFrame*)AfxGetMainWnd())->m_wndDlgBar.GetDlgItem( IDC_ALTITUDE_EDIT )->SetWindowText( buffer3 );
  1050. vector -= lastClickPos;
  1051. float distance = vector.GetLength();
  1052. char buffer[256];
  1053. sprintf( buffer, "%.3f", distance );
  1054. // need to put this value in the appropriate place.
  1055. ((MainFrame*)AfxGetMainWnd())->m_wndDlgBar.GetDlgItem( IDC_DISTANCE_EDIT )->SetWindowText( buffer );
  1056. //IF there is a selected object, find distance to it from camera.
  1057. float eyeDistance = 0.0f;
  1058. long selectionCount = EditorObjectMgr::instance()->getSelectionCount();
  1059. if (selectionCount)
  1060. {
  1061. EditorObjectMgr::EDITOR_OBJECT_LIST selectedObjectsList = EditorObjectMgr::instance()->getSelectedObjectList();
  1062. EditorObjectMgr::EDITOR_OBJECT_LIST::EIterator it = selectedObjectsList.Begin();
  1063. const EditorObject* pInfo = (*it);
  1064. if ( pInfo )
  1065. {
  1066. Stuff::Point3D eyePosition(eye->getCameraOrigin());
  1067. Stuff::Point3D objPosition;
  1068. objPosition.x = -pInfo->appearance()->position.x;
  1069. objPosition.y = pInfo->appearance()->position.z;
  1070. objPosition.z = pInfo->appearance()->position.y;
  1071. Stuff::Vector3D Distance;
  1072. Distance.Subtract(objPosition,eyePosition);
  1073. eyeDistance = Distance.GetApproximateLength();
  1074. }
  1075. }
  1076. // need to put this value in the appropriate place.
  1077. sprintf( buffer, "%.3f", eyeDistance);
  1078. ((MainFrame*)AfxGetMainWnd())->m_wndDlgBar.GetDlgItem( IDC_OBJDISTANCEEDIT )->SetWindowText( buffer );
  1079. }
  1080. void EditorInterface::handleLeftButtonUp( int PosX, int PosY )
  1081. {
  1082. if ( !eye || !eye->active )
  1083. return;
  1084. if ( curBrush && painting )
  1085. {
  1086. painting = false;
  1087. Action* pAction = curBrush->endPaint();
  1088. if ( pAction )
  1089. undoMgr.AddAction( pAction );
  1090. }
  1091. }
  1092. //--------------------------------------------------------------------------------------
  1093. // THE EDITOR CLASS, kind of like the mission in MCommander
  1094. void EditorInterface::handleKeyDown( int Key )
  1095. {
  1096. if ( !eye || !eye->active )
  1097. return;
  1098. if ( DebuggerActive )
  1099. return;
  1100. //----------------------
  1101. // Adjust for frameRate
  1102. float frameFactor = frameLength / baseFrameLength;
  1103. float scrollFactor = scrollInc / eye->getScaleFactor() * frameFactor;
  1104. bool shiftDn = GetAsyncKeyState( KEY_LSHIFT ) ? true : false;
  1105. bool ctrlDn = GetAsyncKeyState( KEY_LCONTROL ) ? true : false;
  1106. long altDn = GetAsyncKeyState( KEY_LMENU ) ? true : false;
  1107. if ( Key == KEY_SPACE )
  1108. {
  1109. if ( !dragging )
  1110. {
  1111. prevBrush = curBrush;
  1112. prevSelecting = selecting;
  1113. prevPainting = painting;
  1114. prevDragging = dragging;
  1115. curBrush = new DragTool;
  1116. oldCursor = curCursorID;
  1117. ChangeCursor( IDC_HAND );
  1118. dragging = true;
  1119. }
  1120. }
  1121. if ( currentBrushID >= IDS_OBJECT_200 && currentBrushID <= IDS_OBJECT_200 + 600 )
  1122. {
  1123. if (Key == KEY_LBRACKET)
  1124. {
  1125. ((BuildingBrush*)curBrush)->rotateBrush( 1 );
  1126. }
  1127. else if (Key == KEY_RBRACKET)
  1128. {
  1129. ((BuildingBrush*)curBrush)->rotateBrush( -1 );
  1130. }
  1131. }
  1132. else
  1133. {
  1134. if (Key == KEY_LBRACKET)
  1135. {
  1136. rotateSelectedObjects( 1 );
  1137. }
  1138. else if (Key == KEY_RBRACKET)
  1139. {
  1140. rotateSelectedObjects( -1 );
  1141. }
  1142. }
  1143. if ( lastKey != Key ) // only want to do these if something has changed
  1144. {
  1145. if ( Key == KEY_ESCAPE)
  1146. {
  1147. Select();
  1148. DragRough();
  1149. if (EditorInterface::instance()->ObjectSelectOnlyMode())
  1150. {
  1151. ReleaseCapture();
  1152. EditorInterface::instance()->Team(EditorInterface::instance()->objectivesEditState.alignment);
  1153. }
  1154. }
  1155. if (GetAsyncKeyState(KEY_T) && ctrlDn && altDn && !shiftDn)
  1156. {
  1157. drawTerrainTiles ^= TRUE;
  1158. terrainLineChanged = turn;
  1159. }
  1160. if (GetAsyncKeyState(KEY_O) && ctrlDn && altDn && !shiftDn)
  1161. {
  1162. drawTerrainOverlays ^= TRUE;
  1163. terrainLineChanged = turn;
  1164. }
  1165. if (GetAsyncKeyState(KEY_S) && ctrlDn && altDn && !shiftDn)
  1166. {
  1167. renderObjects ^= TRUE;
  1168. terrainLineChanged = turn;
  1169. }
  1170. if (GetAsyncKeyState(KEY_G) && ctrlDn && altDn && !shiftDn)
  1171. {
  1172. //drawTerrainGrid ^= TRUE;
  1173. OnViewShowpassabilitymap();
  1174. terrainLineChanged = turn;
  1175. }
  1176. if (GetAsyncKeyState (KEY_L) && ctrlDn && altDn && !shiftDn)
  1177. {
  1178. drawLOSGrid ^= TRUE;
  1179. terrainLineChanged = turn;
  1180. }
  1181. if (GetAsyncKeyState (KEY_Q) && ctrlDn && altDn && !shiftDn)
  1182. {
  1183. land->reCalcLight(true);
  1184. }
  1185. if (GetAsyncKeyState(KEY_C) && ctrlDn && altDn && !shiftDn)
  1186. {
  1187. useClouds ^= true;
  1188. terrainLineChanged = turn;
  1189. }
  1190. if (GetAsyncKeyState(KEY_F) && ctrlDn && altDn && !shiftDn)
  1191. {
  1192. useFog ^= true;
  1193. terrainLineChanged = turn;
  1194. }
  1195. if (GetAsyncKeyState(KEY_P) && ctrlDn && altDn && !shiftDn)
  1196. {
  1197. //eye->usePerspective ^= true;
  1198. OnViewOrthographiccamera();
  1199. terrainLineChanged = turn;
  1200. }
  1201. if (GetAsyncKeyState(KEY_R) && ctrlDn && altDn && !shiftDn)
  1202. {
  1203. reloadBounds = true;
  1204. terrainLineChanged = turn;
  1205. }
  1206. if (GetAsyncKeyState(KEY_V) && ctrlDn && altDn && !shiftDn)
  1207. {
  1208. useWaterInterestTexture ^= true;
  1209. terrainLineChanged = turn;
  1210. }
  1211. if (GetAsyncKeyState(KEY_W) && ctrlDn && altDn && !shiftDn)
  1212. {
  1213. Terrain::mapData->recalcWater();
  1214. terrainLineChanged = turn;
  1215. }
  1216. if (GetAsyncKeyState(KEY_D) && ctrlDn && altDn && !shiftDn)
  1217. {
  1218. useShadows ^= true;
  1219. terrainLineChanged = turn;
  1220. }
  1221. }
  1222. //------------------------
  1223. // Keyboard Checks First
  1224. bool scrollUp = (GetAsyncKeyState(KEY_UP) && !shiftDn && !ctrlDn && !altDn);
  1225. bool scrollDn = (GetAsyncKeyState(KEY_DOWN) && !shiftDn && !ctrlDn && !altDn);
  1226. bool scrollLf = (GetAsyncKeyState(KEY_LEFT) && !shiftDn && !ctrlDn && !altDn);
  1227. bool scrollRt = (GetAsyncKeyState(KEY_RIGHT) && !shiftDn && !ctrlDn && !altDn);
  1228. bool zoomOut = (GetAsyncKeyState (KEY_SUBTRACT) && !shiftDn && !ctrlDn && !altDn);
  1229. bool zoomIn = (GetAsyncKeyState (KEY_ADD) && !shiftDn && !ctrlDn && !altDn);
  1230. bool rotateLf = (GetAsyncKeyState (KEY_LEFT) && shiftDn && !ctrlDn && !altDn);
  1231. bool rotateRt = (GetAsyncKeyState (KEY_RIGHT) && shiftDn && !ctrlDn && !altDn);
  1232. bool rotateLightLf = (GetAsyncKeyState (KEY_LEFT) && !shiftDn && ctrlDn && !altDn);
  1233. bool rotateLightRt = (GetAsyncKeyState (KEY_RIGHT) && !shiftDn && ctrlDn && !altDn);
  1234. bool rotateLightUp = (GetAsyncKeyState (KEY_UP) && !shiftDn && ctrlDn && !altDn);
  1235. bool rotateLightDn = (GetAsyncKeyState (KEY_DOWN) && !shiftDn && ctrlDn && !altDn);
  1236. bool tiltUp = (GetAsyncKeyState (KEY_DOWN) && shiftDn && !ctrlDn && !altDn);
  1237. bool tiltDn = (GetAsyncKeyState (KEY_UP) && shiftDn && !ctrlDn && !altDn);
  1238. bool tiltNormal = (GetAsyncKeyState (KEY_HOME) && !shiftDn && !ctrlDn && !altDn);
  1239. // Update the Camera based on Input
  1240. if (scrollLf)
  1241. {
  1242. eye->moveLeft(scrollFactor);
  1243. syncScrollBars();
  1244. }
  1245. if (scrollRt)
  1246. {
  1247. eye->moveRight(scrollFactor);
  1248. syncScrollBars();
  1249. }
  1250. if (scrollDn)
  1251. {
  1252. eye->moveDown(scrollFactor);
  1253. syncScrollBars();
  1254. }
  1255. if (scrollUp)
  1256. {
  1257. eye->moveUp(scrollFactor);
  1258. syncScrollBars();
  1259. }
  1260. if (zoomOut)
  1261. {
  1262. eye->ZoomOut(zoomInc * frameFactor * eye->getScaleFactor());
  1263. if (eye->getScaleFactor() <= 0.3)
  1264. renderTrees = false;
  1265. syncScrollBars();
  1266. tacMap.RedrawWindow();
  1267. }
  1268. if (zoomIn)
  1269. {
  1270. eye->ZoomIn(zoomInc * frameFactor * eye->getScaleFactor());
  1271. if (eye->getScaleFactor() > 0.3)
  1272. renderTrees = true;
  1273. syncScrollBars();
  1274. tacMap.RedrawWindow();
  1275. }
  1276. if (tiltDn)
  1277. {
  1278. eye->tiltDown(scrollFactor * frameFactor * 10.0f);
  1279. syncScrollBars();
  1280. tacMap.RedrawWindow();
  1281. }
  1282. if (tiltUp)
  1283. {
  1284. eye->tiltUp(scrollFactor * frameFactor * 10.0f);
  1285. syncScrollBars();
  1286. tacMap.RedrawWindow();
  1287. }
  1288. if (tiltNormal)
  1289. {
  1290. eye->tiltNormal();
  1291. syncScrollBars();
  1292. tacMap.RedrawWindow();
  1293. }
  1294. if (rotateLf)
  1295. {
  1296. realRotation += degPerSecRot * frameFactor;
  1297. if (realRotation >= rotationInc)
  1298. {
  1299. eye->rotateLeft(rotationInc);
  1300. realRotation = 0;
  1301. }
  1302. syncScrollBars();
  1303. }
  1304. if (rotateRt)
  1305. {
  1306. realRotation -= degPerSecRot * frameFactor;
  1307. if (realRotation <= -rotationInc)
  1308. {
  1309. eye->rotateRight(rotationInc);
  1310. realRotation = 0;
  1311. }
  1312. syncScrollBars();
  1313. }
  1314. //------------------------------------------------
  1315. // TEST LIGHTING MODEL
  1316. if (rotateLightRt)
  1317. {
  1318. eye->rotateLightRight(rotationInc);
  1319. }
  1320. if (rotateLightLf)
  1321. {
  1322. eye->rotateLightLeft(rotationInc);
  1323. }
  1324. if (rotateLightUp)
  1325. {
  1326. eye->rotateLightUp(rotationInc);
  1327. }
  1328. if (rotateLightDn)
  1329. {
  1330. eye->rotateLightDown(rotationInc);
  1331. }
  1332. lastKey = Key;
  1333. if (scrollUp || scrollDn || scrollLf || scrollRt || zoomOut || zoomIn || rotateLf || rotateRt
  1334. || rotateLightLf || rotateLightRt || rotateLightUp || rotateLightDn || tiltUp || tiltDn || tiltNormal)
  1335. {
  1336. SafeRunGameOSLogic();
  1337. }
  1338. //------------------------------------------------
  1339. //IF there is a selected object, find distance to it from camera.
  1340. char buffer[256];
  1341. float eyeDistance = 0.0f;
  1342. long selectionCount = EditorObjectMgr::instance()->getSelectionCount();
  1343. if (selectionCount)
  1344. {
  1345. EditorObjectMgr::EDITOR_OBJECT_LIST selectedObjectsList = EditorObjectMgr::instance()->getSelectedObjectList();
  1346. EditorObjectMgr::EDITOR_OBJECT_LIST::EIterator it = selectedObjectsList.Begin();
  1347. const EditorObject* pInfo = (*it);
  1348. if ( pInfo )
  1349. {
  1350. Stuff::Point3D eyePosition(eye->getCameraOrigin());
  1351. Stuff::Point3D objPosition;
  1352. objPosition.x = -pInfo->appearance()->position.x;
  1353. objPosition.y = pInfo->appearance()->position.z;
  1354. objPosition.z = pInfo->appearance()->position.y;
  1355. Stuff::Vector3D Distance;
  1356. Distance.Subtract(objPosition,eyePosition);
  1357. eyeDistance = Distance.GetApproximateLength();
  1358. }
  1359. }
  1360. // need to put this value in the appropriate place.
  1361. sprintf( buffer, "%.3f", eyeDistance);
  1362. ((MainFrame*)AfxGetMainWnd())->m_wndDlgBar.GetDlgItem( IDC_OBJDISTANCEEDIT )->SetWindowText( buffer );
  1363. }
  1364. void EditorInterface::KillCurBrush()
  1365. {
  1366. if ( curBrush ) // might want to do a check to make sure this guy isn't being used
  1367. {
  1368. delete curBrush;
  1369. }
  1370. curBrush = NULL;
  1371. selecting = false;
  1372. ChangeCursor( IDC_MC2ARROW );
  1373. }
  1374. int EditorInterface::PaintDirtRoad()
  1375. {
  1376. return PaintOverlay( DIRT_ROAD, PAINT_OVERLAY_DIRT );
  1377. }
  1378. int EditorInterface::PaintRocks()
  1379. {
  1380. return PaintOverlay( ROUGH, PAINT_OVERLAY_ROUGH );
  1381. }
  1382. int EditorInterface::PaintPaved()
  1383. {
  1384. return PaintOverlay( PAVED_ROAD, PAINT_OVERLAY_PAVED );
  1385. }
  1386. int EditorInterface::PaintTwoLaneDirtRoad()
  1387. {
  1388. return PaintOverlay( TWO_LANE_DIRT_ROAD, PAINT_OVERLAY_PAVED );
  1389. }
  1390. int EditorInterface::PaintDamagedRoad()
  1391. {
  1392. return PaintOverlay( DAMAGED_ROAD, PAINT_OVERLAY_PAVED );
  1393. }
  1394. int EditorInterface::PaintRunway()
  1395. {
  1396. return PaintOverlay( RUNWAY, PAINT_OVERLAY_PAVED );
  1397. }
  1398. int EditorInterface::PaintBridge()
  1399. {
  1400. return PaintOverlay( OBRIDGE, PAINT_OVERLAY_PAVED );
  1401. }
  1402. int EditorInterface::PaintDamagedBridge()
  1403. {
  1404. return PaintOverlay( DAMAGED_BRIDGE, PAINT_OVERLAY_PAVED );
  1405. }
  1406. int EditorInterface::PaintOverlay( int type, int message )
  1407. {
  1408. KillCurBrush();
  1409. curBrush = new OverlayBrush( type );
  1410. ChangeCursor( IDC_PAINT );
  1411. currentBrushID = message;
  1412. return true;
  1413. }
  1414. int EditorInterface::PaintTerrain( int type )
  1415. {
  1416. if ( selecting && ( land->hasSelection() ) )
  1417. {
  1418. TerrainBrush brush( type );
  1419. Action* pRetAction = brush.applyToSelection( );
  1420. if ( pRetAction )
  1421. undoMgr.AddAction( pRetAction );
  1422. }
  1423. else
  1424. {
  1425. KillCurBrush();
  1426. curBrush = new TerrainBrush( type );
  1427. ChangeCursor( IDC_PAINT );
  1428. currentBrushID = type;
  1429. }
  1430. return true;
  1431. }
  1432. int EditorInterface::SaveAs()
  1433. {
  1434. int retVal = IDOK;
  1435. CFileDialog fileDlg( 0, "pak", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, szPAKFilter );
  1436. {
  1437. /* if the mission directory doesn't exist, we attempt to create it */
  1438. int curDirStrSize = GetCurrentDirectory(0, NULL);
  1439. TCHAR *curDirStr = (TCHAR *)gos_Malloc(curDirStrSize);
  1440. GetCurrentDirectory(curDirStrSize, curDirStr);
  1441. BOOL result = SetCurrentDirectory(missionPath);
  1442. SetCurrentDirectory(curDirStr);
  1443. delete curDirStr; curDirStr = 0;
  1444. if (0 == result)
  1445. {
  1446. gosASSERT(false);
  1447. CreateDirectory(missionPath, NULL);
  1448. CreateDirectory(warriorPath, NULL);
  1449. CreateDirectory(terrainPath, NULL);
  1450. CreateDirectory(texturePath, NULL);
  1451. }
  1452. }
  1453. fileDlg.m_ofn.lpstrInitialDir = missionPath;
  1454. retVal = fileDlg.DoModal();
  1455. if ( IDOK == retVal )
  1456. {
  1457. SetBusyMode();
  1458. const char* pFile = fileDlg.m_ofn.lpstrFile;
  1459. //-----------------------------------------------------
  1460. //New Stuff here.
  1461. // Must resave the following for the new map methods to insure goodness.
  1462. // -Base height Map (in terrainPath)
  1463. // -Hi-res height Map (in terrainPath)
  1464. // -Color Map (texturePath)
  1465. // -Color Map Burnin (texturePath)
  1466. // -Detail Map (texturePath)
  1467. // -Water Map (texturePath)
  1468. // -Water Detail Maps (texturePath)
  1469. char name[1024];
  1470. char name2[1024];
  1471. _splitpath(pFile,NULL,NULL,name2,NULL);
  1472. if (EditorData::instance->getMapName())
  1473. _splitpath(EditorData::instance->getMapName(),NULL,NULL,name,NULL);
  1474. else
  1475. strcpy(name,name2);
  1476. FullPathFileName oldBaseFile;
  1477. oldBaseFile.init(terrainPath,name,".tga");
  1478. FullPathFileName newBaseFile;
  1479. newBaseFile.init(terrainPath,name2,".tga");
  1480. SetFileAttributes(newBaseFile,FILE_ATTRIBUTE_NORMAL);
  1481. CopyFile(oldBaseFile,newBaseFile,false);
  1482. oldBaseFile.init(terrainPath,name,".height.tga");
  1483. newBaseFile.init(terrainPath,name2,".height.tga");
  1484. SetFileAttributes(newBaseFile,FILE_ATTRIBUTE_NORMAL);
  1485. CopyFile(oldBaseFile,newBaseFile,false);
  1486. oldBaseFile.init(texturePath,name,".tga");
  1487. newBaseFile.init(texturePath,name2,".tga");
  1488. SetFileAttributes(newBaseFile,FILE_ATTRIBUTE_NORMAL);
  1489. CopyFile(oldBaseFile,newBaseFile,false);
  1490. oldBaseFile.init(texturePath,name,".burnin.tga");
  1491. newBaseFile.init(texturePath,name2,".burnin.tga");
  1492. SetFileAttributes(newBaseFile,FILE_ATTRIBUTE_NORMAL);
  1493. CopyFile(oldBaseFile,newBaseFile,false);
  1494. oldBaseFile.init(texturePath,name,".detail.tga");
  1495. newBaseFile.init(texturePath,name2,".detail.tga");
  1496. SetFileAttributes(newBaseFile,FILE_ATTRIBUTE_NORMAL);
  1497. CopyFile(oldBaseFile,newBaseFile,false);
  1498. oldBaseFile.init(texturePath,name,".water.tga");
  1499. newBaseFile.init(texturePath,name2,".water.tga");
  1500. SetFileAttributes(newBaseFile,FILE_ATTRIBUTE_NORMAL);
  1501. CopyFile(oldBaseFile,newBaseFile,false);
  1502. for (long i=0;i<MAX_WATER_DETAIL_TEXTURES;i++)
  1503. {
  1504. char detailExt[256];
  1505. sprintf(detailExt,".water%04d.tga",i);
  1506. oldBaseFile.init(texturePath,name,detailExt);
  1507. newBaseFile.init(texturePath,name2,detailExt);
  1508. SetFileAttributes(newBaseFile,FILE_ATTRIBUTE_NORMAL);
  1509. CopyFile(oldBaseFile,newBaseFile,false);
  1510. }
  1511. //Then do a regular save of everything else!!
  1512. EditorData::instance->save( pFile );
  1513. UnsetBusyMode();
  1514. }
  1515. return retVal;
  1516. }
  1517. int EditorInterface::Save()
  1518. {
  1519. const char* pFileName = EditorData::instance->getMapName();
  1520. if ( pFileName && (0 != strcmp("data\\missions\\newmap.pak", pFileName)) )
  1521. {
  1522. EditorData::instance->save( pFileName );
  1523. }
  1524. else
  1525. return SaveAs();
  1526. return IDOK;
  1527. }
  1528. int EditorInterface::QuickSave()
  1529. {
  1530. const char* pFileName = EditorData::instance->getMapName();
  1531. if ( pFileName && (0 != strcmp("data\\missions\\newmap.pak", pFileName)) )
  1532. EditorData::instance->quickSave( pFileName );
  1533. else
  1534. return SaveAs();
  1535. return true;
  1536. }
  1537. int EditorInterface::Undo()
  1538. {
  1539. if ( undoMgr.HaveUndo() )
  1540. undoMgr.Undo();
  1541. return true;
  1542. }
  1543. int EditorInterface::Redo()
  1544. {
  1545. if ( undoMgr.HaveRedo() )
  1546. undoMgr.Redo();
  1547. return true;
  1548. }
  1549. int EditorInterface::paintBuildings( int message )
  1550. {
  1551. EditorObjectMgr* pMgr = EditorObjectMgr::instance();
  1552. int groupCount = pMgr->getBuildingGroupCount();
  1553. int id = IDS_OBJECT_200;
  1554. for ( int i = 0; i < groupCount; ++i )
  1555. {
  1556. int buildCount = pMgr->getNumberBuildingsInGroup( i );
  1557. if ( id <= message && message < id + buildCount )
  1558. {
  1559. int alignment = EDITOR_TEAM2;
  1560. for ( int j = 0; j < 9; ++j )
  1561. {
  1562. if ( GetParent()->GetMenu()->GetMenuState( ID_ALIGNMENT_TEAM1 + j, MF_BYCOMMAND ) & MF_CHECKED )
  1563. {
  1564. if (j != 8)
  1565. alignment = EDITOR_TEAM1 + j;
  1566. else
  1567. alignment = EDITOR_TEAMNONE;
  1568. }
  1569. }
  1570. //Check groups for movers.
  1571. // If they are Movers, they must NOT be neutral.
  1572. // Bring up a dialog and DO NOT create a brush!!
  1573. if (((i == 4) || (i == 6)) && (alignment == EDITOR_TEAMNONE))
  1574. {
  1575. EMessageBox(IDS_NO_NEUTRAL_MOVERS,IDS_ERROR,MB_OK);
  1576. return false;
  1577. }
  1578. KillCurBrush();
  1579. curBrush = new BuildingBrush( i, message - id, alignment );
  1580. currentBrushID = message;
  1581. currentBrushMenuID = message;
  1582. break;
  1583. }
  1584. id += buildCount;
  1585. }
  1586. return true;
  1587. }
  1588. int EditorInterface::Erase()
  1589. {
  1590. if ( selecting && ( EditorObjectMgr::instance()->hasSelection() ||
  1591. land->hasSelection() ) )
  1592. {
  1593. Eraser tmp;
  1594. Action* pRetAction = tmp.applyToSelection( );
  1595. if ( pRetAction )
  1596. undoMgr.AddAction( pRetAction );
  1597. }
  1598. else if (0 == dynamic_cast<Eraser *>(curBrush))
  1599. {
  1600. KillCurBrush();
  1601. curBrush = new Eraser();
  1602. ChangeCursor( IDC_ERASER );
  1603. currentBrushID = ID_OTHER_ERASE;
  1604. currentBrushMenuID = ID_OTHER_ERASE;
  1605. }
  1606. return true;
  1607. }
  1608. void EditorInterface::update()
  1609. {
  1610. if ( !bThisIsInitialized )
  1611. return;
  1612. if ( curBrush )
  1613. {
  1614. POINT pt;
  1615. GetCursorPos( &pt );
  1616. ScreenToClient( &pt );
  1617. curBrush->update( pt.x, pt.y );
  1618. }
  1619. }
  1620. void EditorInterface::render()
  1621. {
  1622. if ( !bThisIsInitialized )
  1623. return;
  1624. ModifyStyle( 0, WS_HSCROLL | WS_VSCROLL );
  1625. Stuff::Vector3D worldPos;
  1626. Stuff::Vector2DOf<long> screenPos;
  1627. screenPos.x = Environment.screenWidth/2;
  1628. screenPos.y = Environment.screenHeight/2;
  1629. //eye->inverseProject( screenPos, worldPos );
  1630. /*if ( worldPos.x != 0.0 || worldPos.y != 0.0 )
  1631. {
  1632. worldPos.y += 128.f;
  1633. Stuff::Vector4D screenPos2;
  1634. eye->projectZ( worldPos, screenPos2 );
  1635. gos_VERTEX vertices[2];
  1636. memset( vertices, 0, sizeof( vertices ) );
  1637. float val = 1.4142135623730950488016887242097f;
  1638. Stuff::Vector2DOf<float> screenVector;
  1639. screenVector.x = screenPos.x - screenPos2.x;
  1640. screenVector.y = screenPos.y - screenPos2.y;
  1641. screenVector.Normalize( screenVector );
  1642. Rotate( screenVector, 45.f );
  1643. vertices[0].x = (float)screenPos.x;
  1644. vertices[0].y = (float)screenPos.y;
  1645. vertices[0].argb = 0xffff0000;
  1646. vertices[0].rhw = 1.0;
  1647. vertices[1].x = screenPos2.x;
  1648. vertices[1].y = screenPos2.y;
  1649. vertices[1].argb = 0xffff0000;
  1650. vertices[1].rhw = 1.0;
  1651. gos_DrawLines( vertices, 2 );
  1652. Stuff::Vector4D arrowVector;
  1653. arrowVector.x = screenVector.x + val;
  1654. arrowVector.x = screenVector.x;
  1655. vertices[0].x = screenPos2.x + 10 * screenVector.x;
  1656. vertices[0].y = screenPos2.y + 10 * screenVector.y;
  1657. gos_DrawLines( vertices, 2 );
  1658. Rotate( screenVector, -90.f );
  1659. vertices[0].x = screenPos2.x + 10 * screenVector.x;
  1660. vertices[0].y = screenPos2.y + 10 * screenVector.y;
  1661. gos_DrawLines( vertices, 2 );
  1662. }*/
  1663. if ( curBrush )
  1664. {
  1665. POINT pt;
  1666. GetCursorPos( &pt );
  1667. ScreenToClient( &pt );
  1668. //curBrush->beginPaint();
  1669. curBrush->render( pt.x, pt.y );
  1670. //curBrush->endPaint();
  1671. if ( painting && !dragging )
  1672. {
  1673. GetCursorPos( &pt );
  1674. ScreenToClient( &pt );
  1675. int PosX = (int)pt.x;
  1676. int PosY = (int)pt.y;
  1677. // scroll if painting
  1678. int scrollLf = (PosX <= (screenScrollLeft));
  1679. int scrollRt = (PosX >= (Width() - screenScrollRight));
  1680. int scrollUp = (PosY <= (screenScrollUp));
  1681. int scrollDn = (PosY >= (Height() - screenScrollDown));
  1682. float frameFactor = frameLength / baseFrameLength;
  1683. float scrollFactor = scrollInc / eye->getScaleFactor() * frameFactor;
  1684. if (scrollLf)
  1685. {
  1686. eye->moveLeft(scrollFactor);
  1687. syncScrollBars();
  1688. }
  1689. if (scrollRt)
  1690. {
  1691. eye->moveRight(scrollFactor);
  1692. syncScrollBars();
  1693. }
  1694. if (scrollDn)
  1695. {
  1696. eye->moveDown(scrollFactor);
  1697. syncScrollBars();
  1698. }
  1699. if (scrollUp)
  1700. {
  1701. eye->moveUp(scrollFactor);
  1702. syncScrollBars();
  1703. }
  1704. }
  1705. }
  1706. }
  1707. int EditorInterface::NewHeightMap()
  1708. {
  1709. CFileDialog fileDlg( 1, "tga", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, szTGAFilter );
  1710. fileDlg.m_ofn.lpstrInitialDir = terrainPath;
  1711. bool endFlag = false;
  1712. while (!endFlag)
  1713. {
  1714. endFlag = true;
  1715. if ( IDOK == fileDlg.DoModal() )
  1716. {
  1717. const char* pFile = fileDlg.m_ofn.lpstrFile;
  1718. if (pFile)
  1719. {
  1720. File tgaFile;
  1721. gosASSERT( strstr( pFile, ".tga" ) || strstr( pFile, ".TGA" ) );
  1722. long result = tgaFile.open(const_cast<char*>(pFile));
  1723. gosASSERT(result == NO_ERR);
  1724. struct TGAFileHeader theader;
  1725. tgaFile.read((MemoryPtr)&theader,sizeof(TGAFileHeader));
  1726. if ((theader.width != land->realVerticesMapSide) || (theader.height != land->realVerticesMapSide))
  1727. {
  1728. /*wrong size*/
  1729. AfxMessageBox(IDS_WRONG_SIZE_HEIGHT_MAP);
  1730. endFlag = false;
  1731. continue;
  1732. }
  1733. }
  1734. else
  1735. {
  1736. gosASSERT(false);
  1737. endFlag = false;
  1738. continue;
  1739. }
  1740. HeightDlg htDlg;
  1741. long tileR, tileC;
  1742. htDlg.SetMin( (int)land->getLowestVertex( tileR, tileC ) );
  1743. htDlg.SetMax( (int)land->getHighestVertex( tileR, tileC ) );
  1744. bool chkStatus = false;
  1745. if ( IDOK == htDlg.DoModal() )
  1746. {
  1747. SetBusyMode();
  1748. chkStatus = EditorData::reassignHeightsFromTGA( pFile, htDlg.GetMin(), htDlg.GetMax() );
  1749. UnsetBusyMode();
  1750. }
  1751. if (chkStatus)
  1752. tacMap.UpdateMap();
  1753. }
  1754. }
  1755. return true;
  1756. }
  1757. #define MAX_THRESHOLD 5
  1758. #define MAX_NOISE 5
  1759. #define MIN_THRESHOLD 1
  1760. #define MIN_NOISE 0
  1761. int EditorInterface::RefractalizeTerrain(long Threshold)
  1762. {
  1763. FractalDlg fDlg;
  1764. fDlg.SetThreshold(Terrain::fractalThreshold);
  1765. fDlg.SetNoise(Terrain::fractalNoise);
  1766. if (IDOK == fDlg.DoModal())
  1767. {
  1768. SetBusyMode();
  1769. Terrain::fractalThreshold = fDlg.GetThreshold();
  1770. Terrain::fractalNoise = fDlg.GetNoise();
  1771. if (Terrain::fractalThreshold > MAX_THRESHOLD)
  1772. Terrain::fractalThreshold = MAX_THRESHOLD;
  1773. if (Terrain::fractalThreshold < MIN_THRESHOLD)
  1774. Terrain::fractalThreshold = MIN_THRESHOLD;
  1775. if (Terrain::fractalNoise > MAX_NOISE)
  1776. Terrain::fractalNoise = MAX_NOISE;
  1777. if (Terrain::fractalNoise < MIN_NOISE)
  1778. Terrain::fractalNoise = MIN_NOISE;
  1779. if (Terrain::terrainTextures2)
  1780. Terrain::terrainTextures2->refractalizeBaseMesh(Terrain::terrainName, Terrain::fractalThreshold, Terrain::fractalNoise);
  1781. UnsetBusyMode();
  1782. }
  1783. return true;
  1784. }
  1785. int EditorInterface::SetSky (long skyId)
  1786. {
  1787. EditorData::instance->TheSkyNumber(skyId);
  1788. return true;
  1789. }
  1790. int EditorInterface::Select()
  1791. {
  1792. if ( currentBrushID == IDS_SELECT )
  1793. {
  1794. land->unselectAll();
  1795. EditorObjectMgr::instance()->unselectAll();
  1796. }
  1797. else
  1798. {
  1799. KillCurBrush();
  1800. int radius = GetParent()->GetMenu()->GetMenuState( ID_DRAGNORMAL, MF_BYCOMMAND ) & MF_CHECKED? -1 : smoothRadius;
  1801. curBrush = new SelectionBrush( false, radius );
  1802. currentBrushID = IDS_SELECT;
  1803. currentBrushMenuID = ID_OTHER_SELECT;
  1804. ChangeCursor( IDC_MC2ARROW );
  1805. }
  1806. selecting = true;
  1807. return true;
  1808. }
  1809. int EditorInterface::Flatten()
  1810. {
  1811. if ( selecting && ( land->hasSelection() ) )
  1812. {
  1813. FlattenBrush brush;
  1814. Action* pAction = brush.applyToSelection();
  1815. if ( pAction )
  1816. {
  1817. undoMgr.AddAction( pAction );
  1818. }
  1819. }
  1820. else if (0 == dynamic_cast<FlattenBrush *>(curBrush))
  1821. {
  1822. KillCurBrush();
  1823. curBrush = new FlattenBrush();
  1824. ChangeCursor( IDC_FLATTEN );
  1825. currentBrushID = IDS_FLATTEN;
  1826. currentBrushMenuID = ID_OTHER_FLATTEN;
  1827. }
  1828. return true;
  1829. }
  1830. int EditorInterface::SaveCameras()
  1831. {
  1832. if ( !EditorData::getMapName() )
  1833. {
  1834. // message box that you must save here
  1835. EMessageBox( IDS_SAVE_CAMERA_FAIL, IDS_ERROR, MB_OK );
  1836. }
  1837. else
  1838. {
  1839. char base[256];
  1840. strcpy( base, cameraPath );
  1841. strcat( base, EditorData::getMapName() );
  1842. strcat( base, "cam" );
  1843. strcat( base, ".fit" );
  1844. FitIniFile file;
  1845. file.open( base );
  1846. return eye->save( &file );
  1847. }
  1848. return true;
  1849. }
  1850. int EditorInterface::SelectSlopes()
  1851. {
  1852. SelectSlopeDialog dlg;
  1853. if ( dlg.DoModal() == IDOK )
  1854. {
  1855. float minAngle = dlg.m_MinEdit;
  1856. float maxAngle = dlg.m_MaxEdit;
  1857. float minHeight = float(fabs(float(tan( minAngle * float(PI)/180.f ) * land->worldUnitsPerVertex)));
  1858. float maxHeight = float(fabs(float(tan( maxAngle * float(PI)/180.f ) * land->worldUnitsPerVertex)));
  1859. float centerElv;
  1860. float tmpElv;
  1861. int left;
  1862. int right;
  1863. int top;
  1864. int bottom;
  1865. land->unselectAll();
  1866. for ( int j = 0; j < land->realVerticesMapSide; ++j )
  1867. {
  1868. for ( int i = 0; i < land->realVerticesMapSide; ++i )
  1869. {
  1870. left = i > 0 ? i - 1 : 0;
  1871. right = i < land->realVerticesMapSide ? i + 1 : i;
  1872. top = j > 0 ? j - 1 : 0;
  1873. bottom = j < land->realVerticesMapSide ? j + 1 : j;
  1874. centerElv = land->getVertexHeight( j * land->realVerticesMapSide + i );
  1875. tmpElv = land->getVertexHeight( top * land->realVerticesMapSide + left );
  1876. if ( fabs(tmpElv - centerElv) >= minHeight && fabs(tmpElv - centerElv) <= maxHeight )
  1877. {
  1878. land->selectVertex( j, i );
  1879. }
  1880. else
  1881. {
  1882. tmpElv = land->getVertexHeight( top * land->realVerticesMapSide + right );
  1883. if ( fabs(tmpElv - centerElv) >= minHeight && fabs(tmpElv - centerElv) <= maxHeight )
  1884. {
  1885. land->selectVertex( j, i );
  1886. }
  1887. else
  1888. {
  1889. tmpElv = land->getVertexHeight( bottom * land->realVerticesMapSide + right );
  1890. if ( fabs(tmpElv - centerElv) >= minHeight && fabs(tmpElv - centerElv) <= maxHeight )
  1891. {
  1892. land->selectVertex( j, i );
  1893. }
  1894. else
  1895. {
  1896. tmpElv = land->getVertexHeight( bottom * land->realVerticesMapSide + left );
  1897. if ( fabs(tmpElv - centerElv) >= minHeight && fabs(tmpElv - centerElv) <= maxHeight )
  1898. {
  1899. land->selectVertex( j, i );
  1900. }
  1901. }
  1902. }
  1903. }
  1904. }
  1905. }// done looping over vertices
  1906. }
  1907. selecting = true;
  1908. return true;
  1909. }
  1910. int EditorInterface::SelectAltitude()
  1911. {
  1912. HeightDlg dlg;
  1913. if ( dlg.DoModal() == IDOK )
  1914. {
  1915. float minHeight = (float)dlg.GetMin();
  1916. float maxHeight = (float)dlg.GetMax();
  1917. float centerElv;
  1918. land->unselectAll();
  1919. for ( int j = 0; j < land->realVerticesMapSide; ++j )
  1920. {
  1921. for ( int i = 0; i < land->realVerticesMapSide; ++i )
  1922. {
  1923. centerElv = land->getVertexHeight( j * land->realVerticesMapSide + i );
  1924. if ( (centerElv >= minHeight) && (centerElv <= maxHeight) )
  1925. {
  1926. land->selectVertex( j, i );
  1927. }
  1928. }
  1929. }// done looping over vertices
  1930. }
  1931. selecting = true;
  1932. return true;
  1933. }
  1934. int EditorInterface::SelectTerrainType()
  1935. {
  1936. SelectTerrainTypeDlg dlg;
  1937. dlg.SelectedTerrainType(-1);
  1938. if (( dlg.DoModal() == IDOK ) && (ID_TERRAINS_BLUEWATER <= dlg.SelectedTerrainType()))
  1939. {
  1940. const int selectedTerrainType = dlg.SelectedTerrainType() - ID_TERRAINS_BLUEWATER;
  1941. land->unselectAll();
  1942. for ( int j = 0; j < land->realVerticesMapSide; ++j )
  1943. {
  1944. for ( int i = 0; i < land->realVerticesMapSide; ++i )
  1945. {
  1946. int tmp = land->getTerrain( j, i );
  1947. if (land->getTerrain( j, i ) == selectedTerrainType)
  1948. {
  1949. land->selectVertex( j, i );
  1950. }
  1951. }
  1952. }// done looping over vertices
  1953. }
  1954. selecting = true;
  1955. return true;
  1956. }
  1957. int EditorInterface::PurgeTransitions()
  1958. {
  1959. land->purgeTransitions();
  1960. highlighted = false;
  1961. Terrain::mapData->unhighlightAll();
  1962. return true;
  1963. }
  1964. int EditorInterface::ShowTransitions()
  1965. {
  1966. highlighted ^= true;
  1967. if (highlighted)
  1968. Terrain::mapData->highlightAllTransitionsOver2();
  1969. else
  1970. Terrain::mapData->unhighlightAll();
  1971. return true;
  1972. }
  1973. int EditorInterface::Fog()
  1974. {
  1975. FogDlg dlg;
  1976. dlg.m_blue = (eye->dayFogColor) & 0xff;
  1977. dlg.m_green = (eye->dayFogColor >> 8) & 0xff;
  1978. dlg.m_red = (eye->dayFogColor >> 16) & 0xff;
  1979. dlg.m_start = eye->fogStart;
  1980. dlg.m_end = eye->fogFull;
  1981. if ( IDOK == dlg.DoModal() )
  1982. {
  1983. eye->dayFogColor = ((DWORD)dlg.m_blue) + (((DWORD)dlg.m_green) << 8) + (((DWORD)dlg.m_red) << 16);
  1984. eye->fogColor = eye->dayFogColor;
  1985. eye->fogStart = dlg.m_start;
  1986. eye->fogFull = dlg.m_end;
  1987. // land->reCalcLight();
  1988. // eye->updateDaylight();
  1989. }
  1990. return true;
  1991. }
  1992. int EditorInterface::Light()
  1993. {
  1994. SunDlg dlg;
  1995. if ( IDOK == dlg.DoModal() )
  1996. {
  1997. /*
  1998. SafeRunGameOSLogic();
  1999. land->reCalcLight();
  2000. SafeRunGameOSLogic();
  2001. tacMap.UpdateMap();
  2002. */
  2003. }
  2004. return true;
  2005. }
  2006. int EditorInterface::Waves()
  2007. {
  2008. WaterDlg dlg;
  2009. dlg.alphaDeep = Terrain::alphaDeep;
  2010. dlg.alphaElevation = Terrain::mapData->alphaDepth;
  2011. dlg.alphaMiddle = Terrain::alphaMiddle;
  2012. dlg.alphaShallow = Terrain::alphaEdge;
  2013. dlg.amplitude = Terrain::waterAmplitude;
  2014. dlg.elevation = Terrain::mapData->waterDepth;
  2015. dlg.frequency = Terrain::waterFreq;
  2016. dlg.shallowElevation = Terrain::mapData->shallowDepth;
  2017. if ( IDOK == dlg.DoModal() )
  2018. {
  2019. Terrain::alphaDeep = dlg.alphaDeep;
  2020. Terrain::alphaMiddle = dlg.alphaMiddle;
  2021. Terrain::alphaEdge = dlg.alphaShallow;
  2022. Terrain::waterAmplitude = dlg.amplitude;
  2023. Terrain::waterElevation = dlg.elevation;
  2024. Terrain::waterFreq = dlg.frequency;
  2025. Terrain::mapData->shallowDepth = dlg.shallowElevation;
  2026. Terrain::mapData->alphaDepth = dlg.alphaElevation;
  2027. Terrain::mapData->waterDepth = dlg.elevation;
  2028. land->recalcWater();
  2029. tacMap.UpdateMap();
  2030. }
  2031. return true;
  2032. }
  2033. int EditorInterface::DragSmooth()
  2034. {
  2035. if ( IDS_SELECT == currentBrushID )
  2036. {
  2037. currentBrushID = -1;
  2038. currentBrushMenuID = -1;
  2039. GetParent()->GetMenu()->CheckMenuItem( ID_DRAGSMOOTH, MF_BYCOMMAND | MF_CHECKED );
  2040. GetParent()->GetMenu()->CheckMenuItem( ID_DRAGNORMAL, MF_BYCOMMAND | MF_UNCHECKED );
  2041. Select();
  2042. }
  2043. return true;
  2044. }
  2045. int EditorInterface::DragRough()
  2046. {
  2047. if ( IDS_SELECT == currentBrushID )
  2048. {
  2049. currentBrushID = -1;
  2050. currentBrushMenuID = -1;
  2051. GetParent()->GetMenu()->CheckMenuItem( ID_DRAGSMOOTH, MF_BYCOMMAND | MF_UNCHECKED );
  2052. GetParent()->GetMenu()->CheckMenuItem( ID_DRAGNORMAL, MF_BYCOMMAND | MF_CHECKED );
  2053. Select();
  2054. }
  2055. return true;
  2056. }
  2057. int EditorInterface::AssignElevation()
  2058. {
  2059. if ( !land->hasSelection() )
  2060. {
  2061. // nothing to assign heights to, let the user know
  2062. char buffer[256];
  2063. cLoadString( IDS_NO_VERTEX_SEL, buffer, 256, gameResourceHandle );
  2064. MessageBox( buffer );
  2065. }
  2066. else
  2067. {
  2068. FlattenBrush tmp;
  2069. float val = tmp.getAverageHeightOfSelection( );
  2070. SingleValueDlg dlg( IDS_ASSIGN_ELEVATION, IDS_ELEVATION, (int)val );
  2071. dlg.SetVal( (int)val );
  2072. if ( IDOK == dlg.DoModal() )
  2073. {
  2074. ActionPaintTile *pAction = new ActionPaintTile;
  2075. for ( int j = 0; j < land->realVerticesMapSide; ++j )
  2076. {
  2077. for ( int i = 0; i < land->realVerticesMapSide; ++i )
  2078. {
  2079. if ( land->isVertexSelected( j, i ) )
  2080. {
  2081. land->setVertexHeight( j * land->realVerticesMapSide + i, (float)dlg.GetVal() );
  2082. }
  2083. }
  2084. }
  2085. //Action* pAction = tmp.applyHeightToSelection( (float)dlg.GetVal() );
  2086. if ( pAction )
  2087. undoMgr.AddAction( pAction );
  2088. /*Designers say refreshing the tacmap takes too long. User can do it manually.*/
  2089. //tacMap.UpdateMap();
  2090. }
  2091. }
  2092. return true;
  2093. }
  2094. int EditorInterface::SmoothRadius()
  2095. {
  2096. SingleValueDlg dlg( IDS_SMOOTH_RADIUS, IDS_RADIUS, smoothRadius );
  2097. if ( IDOK == dlg.DoModal() )
  2098. {
  2099. smoothRadius = dlg.GetVal();
  2100. if ( IDS_SELECT == currentBrushID )
  2101. {
  2102. currentBrushID = -1;
  2103. currentBrushMenuID = -1;
  2104. Select();
  2105. }
  2106. }
  2107. return true;
  2108. }
  2109. int EditorInterface::Alignment( int specific )
  2110. {
  2111. for ( int i = 0; i < 9; ++i )
  2112. GetParent()->GetMenu()->CheckMenuItem( ID_ALIGNMENT_TEAM1 + i, MF_BYCOMMAND | MF_UNCHECKED );
  2113. GetParent()->GetMenu()->CheckMenuItem( specific, MF_BYCOMMAND | MF_CHECKED );
  2114. if ( currentBrushID >= IDS_OBJECT_200 && currentBrushID <= 30800 )
  2115. {
  2116. int tmp = currentBrushID;
  2117. currentBrushID = 0;
  2118. paintBuildings( tmp );
  2119. }
  2120. return true;
  2121. }
  2122. int EditorInterface::SaveHeightMap()
  2123. {
  2124. CreateDirectory(terrainPath, NULL);
  2125. CFileDialog fileDlg( 0, "tga", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, szTGAFilter );
  2126. fileDlg.m_ofn.lpstrInitialDir = terrainPath;
  2127. if ( IDOK == fileDlg.DoModal() )
  2128. {
  2129. const char* pFile = fileDlg.m_ofn.lpstrFile;
  2130. File file;
  2131. if ( NO_ERR != file.create( (char*)pFile ) )
  2132. {
  2133. EMessageBox( IDS_INVALID_FILE, IDS_CANT_SAVE, MB_OK );
  2134. return false;
  2135. }
  2136. SetBusyMode();
  2137. bool ret = EditorData::saveHeightMap( &file );
  2138. UnsetBusyMode();
  2139. return ret;
  2140. }
  2141. return true;
  2142. }
  2143. int EditorInterface::MissionSettings()
  2144. {
  2145. MissionSettingsDlg dlg;
  2146. dlg.m_MissionNameUnlocalizedText = EditorData::instance->MissionName().Data();
  2147. dlg.m_MissionNameUseResourceString = EditorData::instance->MissionNameUseResourceString();
  2148. dlg.m_MissionNameResourceStringID = EditorData::instance->MissionNameResourceStringID();
  2149. dlg.m_AuthorEdit = EditorData::instance->Author().Data();
  2150. dlg.m_BlurbUnlocalizedText = EditorData::instance->Blurb().Data();
  2151. dlg.m_BlurbUseResourceString = EditorData::instance->BlurbUseResourceString();
  2152. dlg.m_BlurbResourceStringID = EditorData::instance->BlurbResourceStringID();
  2153. dlg.m_Blurb2UnlocalizedText = EditorData::instance->Blurb2().Data();
  2154. dlg.m_Blurb2UseResourceString = EditorData::instance->Blurb2UseResourceString();
  2155. dlg.m_Blurb2ResourceStringID = EditorData::instance->Blurb2ResourceStringID();
  2156. dlg.m_TimeLimit = EditorData::instance->TimeLimit();
  2157. dlg.m_DropWeightLimit = EditorData::instance->DropWeightLimit();
  2158. dlg.m_InitialResourcePoints = EditorData::instance->InitialResourcePoints();
  2159. dlg.m_SinglePlayerCheck = (BOOL)EditorData::instance->IsSinglePlayer();
  2160. dlg.m_MaxTeams = EditorData::instance->MaxTeams();
  2161. dlg.m_MaxPlayers = EditorData::instance->MaxPlayers();
  2162. dlg.m_ScenarioTune.Empty();
  2163. dlg.m_ScenarioTune.Format(_T("%d"), EditorData::instance->ScenarioTune());
  2164. dlg.m_VideoFilename = EditorData::instance->VideoFilename().Data();
  2165. dlg.m_CBills = EditorData::instance->CBills();
  2166. dlg.m_NumRPBuildings = EditorData::instance->NumRandomRPbuildings();
  2167. dlg.m_DownloadUrlEdit = EditorData::instance->DownloadURL().Data();
  2168. dlg.m_MissionType = EditorData::instance->MissionType();
  2169. dlg.m_AirStrikeCheck = EditorData::instance->AirStrikesEnabledDefault();
  2170. dlg.m_MineLayerCheck = EditorData::instance->MineLayersEnabledDefault();
  2171. dlg.m_ScoutCopterCheck = EditorData::instance->ScoutCoptersEnabledDefault();
  2172. dlg.m_SensorProbeCheck = EditorData::instance->SensorProbesEnabledDefault();
  2173. dlg.m_UnlimitedAmmoCheck = EditorData::instance->UnlimitedAmmoEnabledDefault();
  2174. dlg.m_AllTech = EditorData::instance->AllTechEnabledDefault();
  2175. dlg.m_RepairVehicleCheck = EditorData::instance->RepairVehicleEnabledDefault();
  2176. dlg.m_SalvageCraftCheck = EditorData::instance->SalvageCraftEnabledDefault();
  2177. dlg.m_ResourceBuildingCheck = EditorData::instance->ResourceBuildingsEnabledDefault();
  2178. dlg.m_NoVariantsCheck = EditorData::instance->NoVariantsEnabledDefault();
  2179. dlg.m_ArtilleryPieceCheck = EditorData::instance->ArtilleryPieceEnabledDefault();
  2180. dlg.m_RPsForMechsCheck = EditorData::instance->RPsForMechsEnabledDefault();
  2181. if ( IDOK == dlg.DoModal() )
  2182. {
  2183. EditorData::instance->MissionName(dlg.m_MissionNameUnlocalizedText.GetBuffer(0));
  2184. EditorData::instance->MissionNameUseResourceString(dlg.m_MissionNameUseResourceString);
  2185. EditorData::instance->MissionNameResourceStringID(dlg.m_MissionNameResourceStringID);
  2186. EditorData::instance->Author(dlg.m_AuthorEdit.GetBuffer(0));
  2187. EditorData::instance->Blurb(dlg.m_BlurbUnlocalizedText.GetBuffer(0));
  2188. EditorData::instance->BlurbUseResourceString(dlg.m_BlurbUseResourceString);
  2189. EditorData::instance->BlurbResourceStringID(dlg.m_BlurbResourceStringID);
  2190. EditorData::instance->Blurb2(dlg.m_Blurb2UnlocalizedText.GetBuffer(0));
  2191. EditorData::instance->Blurb2UseResourceString(dlg.m_Blurb2UseResourceString);
  2192. EditorData::instance->Blurb2ResourceStringID(dlg.m_Blurb2ResourceStringID);
  2193. EditorData::instance->TimeLimit(dlg.m_TimeLimit);
  2194. EditorData::instance->DropWeightLimit(dlg.m_DropWeightLimit);
  2195. EditorData::instance->InitialResourcePoints(dlg.m_InitialResourcePoints);
  2196. EditorData::instance->IsSinglePlayer((bool)dlg.m_SinglePlayerCheck);
  2197. EditorData::instance->MaxTeams(dlg.m_MaxTeams);
  2198. EditorData::instance->MaxPlayers(dlg.m_MaxPlayers);
  2199. EditorData::instance->ScenarioTune(atoi(dlg.m_ScenarioTune.GetBuffer(0)));
  2200. EditorData::instance->VideoFilename(dlg.m_VideoFilename.GetBuffer(0));
  2201. EditorData::instance->CBills( dlg.m_CBills);
  2202. EditorData::instance->NumRandomRPbuildings(dlg.m_NumRPBuildings);
  2203. EditorData::instance->DownloadURL(dlg.m_DownloadUrlEdit.GetBuffer(0));
  2204. EditorData::instance->MissionType(dlg.m_MissionType);
  2205. EditorData::instance->AirStrikesEnabledDefault(dlg.m_AirStrikeCheck);
  2206. EditorData::instance->MineLayersEnabledDefault(dlg.m_MineLayerCheck);
  2207. EditorData::instance->ScoutCoptersEnabledDefault(dlg.m_ScoutCopterCheck);
  2208. EditorData::instance->SensorProbesEnabledDefault(dlg.m_SensorProbeCheck);
  2209. EditorData::instance->UnlimitedAmmoEnabledDefault(dlg.m_UnlimitedAmmoCheck);
  2210. EditorData::instance->AllTechEnabledDefault(dlg.m_AllTech);
  2211. EditorData::instance->RepairVehicleEnabledDefault(dlg.m_RepairVehicleCheck);
  2212. EditorData::instance->SalvageCraftEnabledDefault(dlg.m_SalvageCraftCheck);
  2213. EditorData::instance->ResourceBuildingsEnabledDefault(dlg.m_ResourceBuildingCheck);
  2214. EditorData::instance->NoVariantsEnabledDefault(dlg.m_NoVariantsCheck);
  2215. EditorData::instance->ArtilleryPieceEnabledDefault(dlg.m_ArtilleryPieceCheck);
  2216. EditorData::instance->RPsForMechsEnabledDefault(dlg.m_RPsForMechsCheck);
  2217. }
  2218. return true;
  2219. }
  2220. int EditorInterface::Team( int team )
  2221. {
  2222. static CTeams originalTeams;
  2223. if (!ObjectSelectOnlyMode()) {
  2224. originalTeams = EditorData::instance->TeamsRef();
  2225. }
  2226. EditorData::instance->DoTeamDialog(team);
  2227. if (!ObjectSelectOnlyMode()) {
  2228. if (!(originalTeams == EditorData::instance->TeamsRef())) {
  2229. TeamsAction *pTeamsAction = new TeamsAction(originalTeams);
  2230. undoMgr.AddAction(pTeamsAction);
  2231. }
  2232. originalTeams.Clear();
  2233. }
  2234. return true;
  2235. }
  2236. int EditorInterface::Player( int player )
  2237. {
  2238. PlayerSettingsDlg dlg;
  2239. dlg.m_playerEdit = player + 1;
  2240. dlg.m_oldDefaultTeam = EditorData::instance->PlayersRef().PlayerRef(player).DefaultTeam();
  2241. dlg.m_numTeams = EditorData::instance->MaxTeams();
  2242. if ((IDOK == dlg.DoModal()) && (0 <= dlg.m_newDefaultTeam))
  2243. {
  2244. EditorData::instance->PlayersRef().PlayerRef(player).DefaultTeam(dlg.m_newDefaultTeam);
  2245. }
  2246. return true;
  2247. }
  2248. static const float SQRT_2 = 1.4142135623730950488016887242097f;
  2249. /* make the horizontal scroll bar reflect the current camera position */
  2250. void EditorInterface::syncHScroll()
  2251. {
  2252. /* this calculation was based in the code for Camera::moveRight(float amount) */
  2253. Stuff::Vector3D direction;
  2254. if (!eye->usePerspective)
  2255. {
  2256. direction.x = 1.0;
  2257. direction.y = 0.0;
  2258. direction.z = 0.0;
  2259. }
  2260. else
  2261. {
  2262. direction.x = -1.0;
  2263. direction.y = 0.0;
  2264. direction.z = 0.0;
  2265. }
  2266. float worldCameraRotation = eye->getCameraRotation();
  2267. OppRotate(direction,worldCameraRotation);
  2268. Stuff::Vector3D eyeDisplacement = eye->getPosition();
  2269. /* maxVisual was taken from Camera::setPosition(). */
  2270. float maxVisual = (Terrain::worldUnitsMapSide / 2) - Terrain::worldUnitsPerVertex;
  2271. float bound = SQRT_2 * maxVisual;
  2272. float scrollPos = ((direction * eyeDisplacement) / bound * 0.5f + 0.5f) * HSCROLLBAR_RANGE;
  2273. SetScrollRange( SB_HORZ, 0, HSCROLLBAR_RANGE, true );
  2274. SetScrollPos(SB_HORZ, (int)scrollPos);
  2275. {
  2276. /* figure out what proportion of the map is visible */
  2277. Stuff::Vector2DOf< long > screen;
  2278. Stuff::Vector3D world1, world2;
  2279. screen.y = Environment.screenHeight / 2;
  2280. screen.x = 1;
  2281. eye->inverseProject( screen, world1 );
  2282. screen.x = Environment.screenWidth - 1;
  2283. eye->inverseProject( screen, world2 );
  2284. float dx = world2.x - world1.x;
  2285. float dy = world2.y - world1.y;
  2286. float span = sqrt(dx * dx + dy * dy);
  2287. /* make the size of the scroll bar proportional to the proportion of the map that's visible */
  2288. SCROLLINFO si;
  2289. GetScrollInfo(SB_HORZ, &si, SIF_PAGE);
  2290. si.nPage = HSCROLLBAR_RANGE * span / ( 2.0 * bound);
  2291. si.fMask = SIF_PAGE;
  2292. SetScrollInfo(SB_HORZ, &si);
  2293. }
  2294. tacMap.RedrawWindow();
  2295. }
  2296. /* make the vertical scroll bar reflect the current camera position */
  2297. void EditorInterface::syncVScroll()
  2298. {
  2299. /* this calculation was based in the code for Camera::moveRight(float amount) */
  2300. Stuff::Vector3D direction;
  2301. if (!eye->usePerspective)
  2302. {
  2303. direction.x = 0.0;
  2304. direction.y = -1.0;
  2305. direction.z = 0.0;
  2306. }
  2307. else
  2308. {
  2309. direction.x = 0.0;
  2310. direction.y = 1.0;
  2311. direction.z = 0.0;
  2312. }
  2313. float worldCameraRotation = eye->getCameraRotation();
  2314. OppRotate(direction,worldCameraRotation);
  2315. Stuff::Vector3D eyeDisplacement = eye->getPosition();
  2316. /* maxVisual was taken from Camera::setPosition(). */
  2317. float maxVisual = (Terrain::worldUnitsMapSide / 2) - Terrain::worldUnitsPerVertex;
  2318. float bound = SQRT_2 * maxVisual;
  2319. float scrollPos = ((direction * eyeDisplacement) / bound * 0.5f + 0.5f) * VSCROLLBAR_RANGE;
  2320. SetScrollRange( SB_VERT, 0, VSCROLLBAR_RANGE, false );
  2321. SetScrollPos(SB_VERT, (int)scrollPos);
  2322. {
  2323. /* figure out what proportion of the map is visible */
  2324. Stuff::Vector2DOf< long > screen;
  2325. Stuff::Vector3D world1, world2;
  2326. screen.x = Environment.screenWidth / 2;
  2327. screen.y = 1;
  2328. eye->inverseProject( screen, world1 );
  2329. screen.y = Environment.screenHeight - 1;
  2330. eye->inverseProject( screen, world2 );
  2331. float dx = world2.x - world1.x;
  2332. float dy = world2.y - world1.y;
  2333. float span = sqrt(dx * dx + dy * dy);
  2334. /* make the size of the scroll bar proportional to the proportion of the map that's visible */
  2335. SCROLLINFO si;
  2336. GetScrollInfo(SB_VERT, &si, SIF_PAGE);
  2337. si.nPage = VSCROLLBAR_RANGE * span / ( 2.0 * bound);
  2338. si.fMask = SIF_PAGE;
  2339. SetScrollInfo(SB_VERT, &si);
  2340. }
  2341. tacMap.RedrawWindow();
  2342. }
  2343. void EditorInterface::SetBusyMode(bool bRedrawWindow)
  2344. {
  2345. if (bRedrawWindow) {
  2346. //SendMessage(WM_PAINT, 0, 0);
  2347. //tacMap.SendMessage(WM_PAINT, 0, 0);
  2348. RedrawWindow();
  2349. tacMap.RedrawWindow();
  2350. }
  2351. if (0 == m_AppIsBusy) {
  2352. if (!m_hBusyCursor) {
  2353. #ifndef _DEBUG /*the debugger seems to encounter an infinite loop of user breaks (int 3) ntdll when executing this line*/
  2354. m_hBusyCursor = (HCURSOR)LoadImage(NULL, "bmech.ani", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
  2355. #endif
  2356. }
  2357. if (m_hBusyCursor) {
  2358. ::SetCursor(m_hBusyCursor);
  2359. } else {
  2360. ::SetCursor(LoadCursor(NULL, IDC_WAIT));
  2361. }
  2362. }
  2363. m_AppIsBusy += 1;
  2364. }
  2365. void EditorInterface::UnsetBusyMode()
  2366. {
  2367. if (1 == m_AppIsBusy) {
  2368. if (hCursor) {
  2369. ::SetCursor( hCursor );
  2370. }
  2371. }
  2372. m_AppIsBusy -= 1;
  2373. }
  2374. int EditorInterface::Damage( bool bDamage )
  2375. {
  2376. if ( selecting && EditorObjectMgr::instance()->hasSelection() )
  2377. {
  2378. DamageBrush tmp( bDamage );
  2379. Action* pRetAction = tmp.applyToSelection( );
  2380. if ( pRetAction )
  2381. undoMgr.AddAction( pRetAction );
  2382. }
  2383. else
  2384. {
  2385. DamageBrush *pCurDamageBrush = dynamic_cast<DamageBrush *>(curBrush);
  2386. if ((0 == pCurDamageBrush) || (pCurDamageBrush->damage != bDamage))
  2387. {
  2388. KillCurBrush();
  2389. curBrush = new DamageBrush( bDamage );
  2390. ChangeCursor( IDC_HAMMER + !bDamage );
  2391. currentBrushID = ID_OTHER_DAMAGE + bDamage;
  2392. }
  2393. }
  2394. return true;
  2395. }
  2396. int EditorInterface::LayMines()
  2397. {
  2398. if ( selecting && ( land->hasSelection() ) )
  2399. {
  2400. MineBrush brush;
  2401. Action* pRetAction = brush.applyToSelection( );
  2402. if ( pRetAction )
  2403. undoMgr.AddAction( pRetAction );
  2404. }
  2405. else if (0 == dynamic_cast<MineBrush *>(curBrush))
  2406. {
  2407. KillCurBrush();
  2408. curBrush = new MineBrush();
  2409. ChangeCursor( IDC_HAMMER ); // need a minebrush cursor
  2410. currentBrushID = ID_OTHER_LAYMINES;
  2411. }
  2412. return true;
  2413. }
  2414. int EditorInterface::SelectDetailTexture()
  2415. {
  2416. CFileDialog fileDlg( TRUE, "tga", NULL, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, szTGAFilter );
  2417. fileDlg.m_ofn.lpstrInitialDir = texturePath;
  2418. if ( IDOK == fileDlg.DoModal() )
  2419. {
  2420. CString path = fileDlg.m_ofn.lpstrFile;
  2421. path.MakeLower();
  2422. if ( land->terrainTextures2 && (land->terrainTextures2->colorMapStarted))
  2423. {
  2424. land->terrainTextures2->resetDetailTexture(path.GetBuffer(0));
  2425. EditorData::instance->DetailTextureNeedsSaving(true);
  2426. }
  2427. }
  2428. return true;
  2429. }
  2430. int EditorInterface::SelectWaterTexture()
  2431. {
  2432. CFileDialog fileDlg( TRUE, "tga", NULL, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, szTGAFilter );
  2433. fileDlg.m_ofn.lpstrInitialDir = texturePath;
  2434. if ( IDOK == fileDlg.DoModal() )
  2435. {
  2436. CString path = fileDlg.m_ofn.lpstrFile;
  2437. path.MakeLower();
  2438. if ( land->terrainTextures2 && (land->terrainTextures2->colorMapStarted))
  2439. {
  2440. land->terrainTextures2->resetWaterTexture(path.GetBuffer(0));
  2441. EditorData::instance->WaterTextureNeedsSaving(true);
  2442. }
  2443. }
  2444. return true;
  2445. }
  2446. //---------------------------------------------------------------------------
  2447. inline bool colorMapIsOKFormat (const char *fileName)
  2448. {
  2449. DWORD localColorMapSizeCheck = land->realVerticesMapSide * 12.8;
  2450. File tgaFile;
  2451. long result = tgaFile.open(fileName);
  2452. if (result == NO_ERR)
  2453. {
  2454. struct TGAFileHeader tgaHeader;
  2455. tgaFile.read((MemoryPtr)&tgaHeader,sizeof(TGAFileHeader));
  2456. if ((tgaHeader.image_type == UNC_TRUE) &&
  2457. (tgaHeader.width == tgaHeader.height) &&
  2458. (tgaHeader.width == localColorMapSizeCheck))
  2459. return true;
  2460. tgaFile.close();
  2461. }
  2462. return false;
  2463. }
  2464. int EditorInterface::SetBaseTexture()
  2465. {
  2466. CFileDialog fileDlg( TRUE, "tga", NULL, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, szTGAFilter );
  2467. fileDlg.m_ofn.lpstrInitialDir = texturePath;
  2468. if ( IDOK == fileDlg.DoModal() )
  2469. {
  2470. CString path = fileDlg.m_ofn.lpstrFile;
  2471. path.MakeLower();
  2472. //Check that this is a valid colormap of EXACTLY the same size!!!
  2473. if (colorMapIsOKFormat(path))
  2474. {
  2475. char name[1024];
  2476. _splitpath(path,NULL,NULL,name,NULL);
  2477. char *testLoc = strstr(name,".burnin");
  2478. if (testLoc)
  2479. testLoc[0] = 0; //Prune off the burnin name.
  2480. land->setColorMapName(name);
  2481. if ( land->terrainTextures2 && (land->terrainTextures2->colorMapStarted))
  2482. {
  2483. if (land->colorMapName)
  2484. land->terrainTextures2->resetBaseTexture(land->colorMapName);
  2485. else
  2486. land->terrainTextures2->resetBaseTexture(land->terrainName);
  2487. }
  2488. }
  2489. else
  2490. {
  2491. EMessageBox(IDS_INVALID_COLOR_MAP,IDS_ERROR,MB_OK);
  2492. }
  2493. }
  2494. return true;
  2495. }
  2496. int EditorInterface::ReloadBaseTexture()
  2497. {
  2498. if ( land->terrainTextures2 && (land->terrainTextures2->colorMapStarted))
  2499. {
  2500. if (land->colorMapName)
  2501. land->terrainTextures2->resetBaseTexture(land->colorMapName);
  2502. else
  2503. land->terrainTextures2->resetBaseTexture(land->terrainName);
  2504. }
  2505. return true;
  2506. }
  2507. int EditorInterface::SelectWaterDetailTexture()
  2508. {
  2509. CFileDialog fileDlg( TRUE, "tga", NULL, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, szTGAFilter );
  2510. fileDlg.m_ofn.lpstrInitialDir = texturePath;
  2511. if ( IDOK == fileDlg.DoModal() )
  2512. {
  2513. CString path = fileDlg.m_ofn.lpstrFile;
  2514. path.MakeLower();
  2515. if ( land->terrainTextures2 && (land->terrainTextures2->colorMapStarted))
  2516. {
  2517. land->terrainTextures2->resetWaterDetailTextures(path.GetBuffer(0));
  2518. EditorData::instance->WaterDetailTextureNeedsSaving(true);
  2519. }
  2520. }
  2521. return true;
  2522. }
  2523. int EditorInterface::TextureTilingFactors()
  2524. {
  2525. TilingFactorsDialog tilingFactorsDlg;
  2526. tilingFactorsDlg.m_TerrainDetailTilingFactor = land->terrainTextures2->getDetailTilingFactor();
  2527. tilingFactorsDlg.m_WaterTilingFactor = land->terrainTextures2->getWaterTextureTilingFactor();
  2528. tilingFactorsDlg.m_WaterDetailTilingFactor = land->terrainTextures2->getWaterDetailTilingFactor();
  2529. if (IDOK == tilingFactorsDlg.DoModal())
  2530. {
  2531. land->terrainTextures2->setDetailTilingFactor(tilingFactorsDlg.m_TerrainDetailTilingFactor);
  2532. land->terrainTextures2->setWaterTextureTilingFactor(tilingFactorsDlg.m_WaterTilingFactor);
  2533. land->terrainTextures2->setWaterDetailTilingFactor(tilingFactorsDlg.m_WaterDetailTilingFactor);
  2534. }
  2535. return true;
  2536. }
  2537. int EditorInterface::Link( bool bLink )
  2538. {
  2539. LinkBrush *pCurLinkBrush = dynamic_cast<LinkBrush *>(curBrush);
  2540. if ((0 == pCurLinkBrush) || (pCurLinkBrush->bLink != bLink))
  2541. {
  2542. KillCurBrush();
  2543. curBrush = new LinkBrush( bLink );
  2544. ChangeCursor( IDC_LINK + !bLink );
  2545. currentBrushID = ID_OTHER_LINK + bLink;
  2546. }
  2547. return 1;
  2548. }
  2549. int EditorInterface::DropZone( bool bVTol )
  2550. {
  2551. KillCurBrush();
  2552. int alignment = EDITOR_TEAM1;
  2553. // you'll need this for multiplayer
  2554. /*for ( int j = 0; j < 9; ++j )
  2555. {
  2556. if ( GetParent()->GetMenu()->GetMenuState( ID_ALIGNMENT_TEAM1 + j, MF_BYCOMMAND ) & MF_CHECKED )
  2557. {
  2558. if (j != 8)
  2559. alignment = EDITOR_TEAM1 + j;
  2560. else
  2561. alignment = EDITOR_TEAMNONE;
  2562. }
  2563. }*/
  2564. curBrush = new DropZoneBrush( alignment, bVTol );
  2565. currentBrushID = ID_DROPZONES_ADD + bVTol;
  2566. ChangeCursor( IDC_DROPZONE );
  2567. return true;
  2568. }
  2569. int EditorInterface::CampaignEditor()
  2570. {
  2571. CCampaignDialog campaignDialog;
  2572. campaignDialog.DoModal();
  2573. return 1;
  2574. }
  2575. int EditorInterface::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2576. {
  2577. if (CWnd ::OnCreate(lpCreateStruct) == -1)
  2578. return -1;
  2579. if (!tacMap.m_hWnd)
  2580. {
  2581. tacMap.Create( IDD_TACMAP, this );
  2582. tacMap.ShowWindow( true );
  2583. tacMap.RedrawWindow();
  2584. }
  2585. else
  2586. {
  2587. gosASSERT(false);
  2588. }
  2589. return 0;
  2590. }
  2591. extern bool gActive;
  2592. extern bool gGotFocus;
  2593. extern Editor* editor;
  2594. LRESULT EditorInterface::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  2595. {
  2596. //We're not ready to draw anything.
  2597. // If you let an event through it'll probably crash!
  2598. //
  2599. if ( message == WM_KEYDOWN )
  2600. handleKeyDown( wParam );
  2601. if ( message == WM_CREATE )
  2602. {
  2603. gActive = true;
  2604. gGotFocus= true;
  2605. }
  2606. if ( WM_MOUSEWHEEL == message)
  2607. {
  2608. //int i = 17;
  2609. }
  2610. int retVal = 0;
  2611. retVal = CWnd::WindowProc(message, wParam, lParam);
  2612. if ( message == WM_KEYDOWN && wParam == VK_SCROLL )
  2613. return 0;
  2614. if ( (eye || message == WM_MOVE) )
  2615. {
  2616. switch (message)
  2617. {
  2618. case WM_SYSCOLORCHANGE:
  2619. case WM_DISPLAYCHANGE:
  2620. case WM_SETCURSOR:
  2621. case WM_ACTIVATEAPP:
  2622. case WM_KILLFOCUS:
  2623. case WM_SETFOCUS:
  2624. case WM_MOVE:
  2625. case WM_ERASEBKGND:
  2626. case 0x20b:
  2627. case 0x20c:
  2628. case WM_KEYDOWN:
  2629. case WM_KEYUP:
  2630. case WM_CHAR:
  2631. case WM_CLOSE:
  2632. retVal = GameOSWinProc( m_hWnd,message,wParam,lParam );
  2633. break;
  2634. case WM_LBUTTONDOWN:
  2635. case WM_LBUTTONUP:
  2636. case WM_RBUTTONDOWN:
  2637. case WM_RBUTTONUP:
  2638. case WM_MBUTTONDOWN:
  2639. case WM_MBUTTONUP:
  2640. {
  2641. retVal = GameOSWinProc( m_hWnd,message,wParam,lParam );
  2642. }
  2643. break;
  2644. case WM_SIZE:
  2645. {
  2646. float w = LOWORD(lParam);
  2647. float h = HIWORD(lParam);
  2648. windowSizeChanged = true;
  2649. g_newWidth = w + 16/*scrollbar thickness*/;
  2650. g_newHeight = h + 16/*scrollbar thickness*/;
  2651. retVal = GameOSWinProc( m_hWnd,message,wParam,lParam );
  2652. if (editor && bThisIsInitialized)
  2653. {
  2654. editor->update();
  2655. }
  2656. //EditorObjectMgr::instance()->update();
  2657. }
  2658. break;
  2659. }
  2660. }
  2661. return retVal;
  2662. }
  2663. afx_msg void EditorInterface::OnCommand(WPARAM wParam)
  2664. {
  2665. handleNewMenuMessage( wParam );
  2666. }
  2667. void EditorInterface::UpdateButton( CCmdUI* pButton )
  2668. {
  2669. pButton->Enable( true );
  2670. if ( pButton->m_nID == ID_DROPZONES_ADD || pButton->m_nID == ID_DROPZONES_VTOL )
  2671. {
  2672. Stuff::Vector3D pos;
  2673. pos.x = -1;
  2674. pos.y = -1;
  2675. if ( !EditorObjectMgr::instance()->canAddDropZone( pos, 0, (pButton->m_nID - ID_DROPZONES_ADD) ? true : false ) )
  2676. pButton->Enable( false );
  2677. }
  2678. }
  2679. void EditorInterface::OnLButtonDown(UINT nFlags, CPoint point)
  2680. {
  2681. SetCapture();
  2682. handleLeftButtonDown( point.x, point.y );
  2683. SPEW( (0, "GotClick"));
  2684. }
  2685. void EditorInterface::OnLButtonUp(UINT nFlags, CPoint point)
  2686. {
  2687. // TODO: Add your message handler code here and/or call default
  2688. handleLeftButtonUp( point.x, point.y );
  2689. ReleaseCapture();
  2690. }
  2691. void EditorInterface::OnMouseMove(UINT nFlags, CPoint point)
  2692. {
  2693. handleMouseMove( point.x, point.y );
  2694. }
  2695. void EditorInterface::ChangeCursor( int ID )
  2696. {
  2697. if ( hCursor )
  2698. DestroyCursor( hCursor );
  2699. hCursor = AfxGetApp()->LoadCursor( ID );
  2700. if (0 >= m_AppIsBusy)
  2701. {
  2702. ::SetCursor( hCursor );
  2703. }
  2704. curCursorID = ID;
  2705. }
  2706. BOOL EditorInterface::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  2707. {
  2708. if (0 < m_AppIsBusy)
  2709. {
  2710. if (m_hBusyCursor) {
  2711. ::SetCursor(m_hBusyCursor);
  2712. } else {
  2713. ::SetCursor(LoadCursor(NULL, IDC_WAIT));
  2714. }
  2715. }
  2716. else if ( hCursor )
  2717. {
  2718. ::SetCursor( hCursor );
  2719. return true;
  2720. }
  2721. return CWnd::OnSetCursor( pWnd, nHitTest, message );
  2722. }
  2723. BOOL EditorInterface::PreCreateWindow(CREATESTRUCT& cs)
  2724. {
  2725. cs.lpszClass = AfxRegisterWndClass(
  2726. CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, // use any window styles
  2727. NULL,
  2728. (HBRUSH) (COLOR_WINDOW + 1));
  2729. return CWnd ::PreCreateWindow(cs);
  2730. }
  2731. void EditorInterface::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  2732. {
  2733. if ( nChar == KEY_SPACE )
  2734. {
  2735. KillCurBrush();
  2736. curBrush = prevBrush;
  2737. selecting = prevSelecting;
  2738. painting = prevPainting;
  2739. dragging = prevDragging;
  2740. prevBrush = NULL;
  2741. prevSelecting = false;
  2742. prevPainting = false;
  2743. prevDragging = false;
  2744. ChangeCursor( oldCursor );
  2745. syncScrollBars();
  2746. //dragging = false;
  2747. }
  2748. lastKey = -1;
  2749. CWnd ::OnKeyUp(nChar, nRepCnt, nFlags);
  2750. }
  2751. void EditorInterface::OnRButtonDown(UINT nFlags, CPoint point)
  2752. {
  2753. SetCapture( );
  2754. lastX = point.x;
  2755. lastY = point.y;
  2756. rightDrag = true;
  2757. lastRightClickTime = timeGetTime();
  2758. }
  2759. void EditorInterface::OnRButtonUp(UINT nFlags, CPoint point)
  2760. {
  2761. rightDrag = false;
  2762. ReleaseCapture();
  2763. if ( timeGetTime() - lastRightClickTime < 200 )
  2764. {
  2765. Select();
  2766. }
  2767. else
  2768. {
  2769. tacMap.RedrawWindow();
  2770. syncScrollBars();
  2771. }
  2772. // is there anything under the mouse
  2773. /*Stuff::Vector3D pos;
  2774. Stuff::Vector2DOf<long> screen;
  2775. screen.x = point.x;
  2776. screen.y = point.y;
  2777. eye->inverseProject( screen, pos );
  2778. EditorObject* pObject = EditorObjectMgr::instance()->getObjectAtPosition( pos );
  2779. Unit* pUnit = dynamic_cast<Unit*>(pObject);
  2780. if ( pUnit )
  2781. {
  2782. CMenu Menu;
  2783. Menu.LoadMenu( IDR_POPUP );
  2784. CMenu* pPopUp = Menu.GetSubMenu( 0 );
  2785. ClientToScreen( &point );
  2786. pPopUp->TrackPopupMenu( nFlags, point.x, point.y, this );
  2787. CWnd ::OnRButtonUp(nFlags, point);
  2788. }*/
  2789. }
  2790. BOOL EditorInterface::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
  2791. {
  2792. //--------------------------------------------------
  2793. // Zoom Camera based on Mouse Wheel input.
  2794. long mouseWheelDelta = zDelta; // 240 is the weird increment that the mouse wheel is in
  2795. if (mouseWheelDelta)
  2796. {
  2797. float actualZoom = zoomInc * abs(mouseWheelDelta) * 0.0001f * eye->getScaleFactor();
  2798. if (mouseWheelDelta < 0)
  2799. {
  2800. eye->ZoomOut(actualZoom);
  2801. }
  2802. else
  2803. {
  2804. eye->ZoomIn(actualZoom);
  2805. }
  2806. }
  2807. //int middleClicked = nFlags & MK_MBUTTON;
  2808. int middleClicked = (nFlags & MK_MBUTTON) && (nFlags & MK_RBUTTON); // it's too easy to accidentally press the middle button while scrolling on some mice
  2809. //-----------------------------------------------------------------
  2810. // If middle mouse button is pressed, go to normal tilt, 50% zoom
  2811. if (middleClicked)
  2812. {
  2813. eye->tiltNormal();
  2814. eye->ZoomNormal();
  2815. }
  2816. //IF there is a selected object, find distance to it from camera.
  2817. float eyeDistance = 0.0f;
  2818. long selectionCount = EditorObjectMgr::instance()->getSelectionCount();
  2819. if (selectionCount)
  2820. {
  2821. EditorObjectMgr::EDITOR_OBJECT_LIST selectedObjectsList = EditorObjectMgr::instance()->getSelectedObjectList();
  2822. EditorObjectMgr::EDITOR_OBJECT_LIST::EIterator it = selectedObjectsList.Begin();
  2823. const EditorObject* pInfo = (*it);
  2824. if ( pInfo )
  2825. {
  2826. Stuff::Point3D eyePosition(eye->getCameraOrigin());
  2827. Stuff::Point3D objPosition;
  2828. objPosition.x = -pInfo->appearance()->position.x;
  2829. objPosition.y = pInfo->appearance()->position.z;
  2830. objPosition.z = pInfo->appearance()->position.y;
  2831. Stuff::Vector3D Distance;
  2832. Distance.Subtract(objPosition,eyePosition);
  2833. eyeDistance = Distance.GetApproximateLength();
  2834. }
  2835. }
  2836. // need to put this value in the appropriate place.
  2837. char buffer[1024];
  2838. sprintf( buffer, "%.3f", eyeDistance);
  2839. ((MainFrame*)AfxGetMainWnd())->m_wndDlgBar.GetDlgItem( IDC_OBJDISTANCEEDIT )->SetWindowText( buffer );
  2840. tacMap.RedrawWindow();
  2841. syncScrollBars();
  2842. return CWnd ::OnMouseWheel(nFlags, zDelta, pt);
  2843. }
  2844. void EditorInterface::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  2845. {
  2846. if (pScrollBar != NULL && pScrollBar->SendChildNotifyLastMsg())
  2847. return; // eat it
  2848. // ignore scroll bar msgs from other controls
  2849. if (pScrollBar != GetScrollBarCtrl(SB_HORZ))
  2850. return;
  2851. // OnScroll(MAKEWORD(nSBCode, -1), nPos);
  2852. SCROLLINFO sInfo;
  2853. sInfo.cbSize = sizeof ( SCROLLINFO );
  2854. sInfo.fMask = SIF_POS | SIF_PAGE;
  2855. sInfo.nMin = 0;
  2856. sInfo.nMax = 0;
  2857. sInfo.nPage = 0;
  2858. sInfo.nPos = 0;
  2859. sInfo.nTrackPos = 0;
  2860. CPoint pt;
  2861. GetScrollInfo( SB_HORZ, &sInfo );
  2862. pt.x = sInfo.nPos;
  2863. switch ( nSBCode )
  2864. {
  2865. case SB_LINELEFT:
  2866. pt.x += (-0.01 * HSCROLLBAR_RANGE);
  2867. pt.y = 0;
  2868. break;
  2869. case SB_LINERIGHT:
  2870. pt.x += (0.01 * HSCROLLBAR_RANGE);
  2871. pt.y = 0;
  2872. break;
  2873. case SB_PAGELEFT:
  2874. pt.x -= sInfo.nPage;
  2875. break;
  2876. case SB_PAGERIGHT:
  2877. pt.x += sInfo.nPage;
  2878. break;
  2879. case SB_THUMBPOSITION:
  2880. pt.x = nPos;
  2881. break;
  2882. case SB_THUMBTRACK:
  2883. pt.x = nPos;
  2884. break;
  2885. default:
  2886. break;
  2887. }
  2888. /* this calculation was based in the code for Camera::moveRight(float amount) */
  2889. Stuff::Vector3D direction;
  2890. if (!eye->usePerspective)
  2891. {
  2892. direction.x = 1.0;
  2893. direction.y = 0.0;
  2894. direction.z = 0.0;
  2895. }
  2896. else
  2897. {
  2898. direction.x = -1.0;
  2899. direction.y = 0.0;
  2900. direction.z = 0.0;
  2901. }
  2902. float worldCameraRotation = eye->getCameraRotation();
  2903. OppRotate(direction,worldCameraRotation);
  2904. Stuff::Vector3D eyeDisplacement = eye->getPosition();
  2905. /* maxVisual was taken from Camera::setPosition(). */
  2906. float maxVisual = (Terrain::worldUnitsMapSide / 2) - Terrain::worldUnitsPerVertex;
  2907. float bound = SQRT_2 * maxVisual;
  2908. float amount = bound * 2.0f * (((float)pt.x) / HSCROLLBAR_RANGE - 0.5f);
  2909. float amountMore = amount - direction * eyeDisplacement;
  2910. eye->moveRight(amountMore);
  2911. sInfo.nPos = pt.x;
  2912. sInfo.fMask = SIF_POS;
  2913. this->SetScrollPos( SB_HORZ, pt.x );
  2914. CWnd ::OnHScroll(nSBCode, nPos, pScrollBar);
  2915. SafeRunGameOSLogic();
  2916. tacMap.RedrawWindow();
  2917. syncScrollBars();
  2918. }
  2919. void EditorInterface::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  2920. {
  2921. SCROLLINFO sInfo;
  2922. sInfo.cbSize = sizeof ( SCROLLINFO );
  2923. sInfo.fMask = SIF_POS | SIF_PAGE;
  2924. sInfo.nMin = 0;
  2925. sInfo.nMax = 0;
  2926. sInfo.nPage = 0;
  2927. sInfo.nPos = 0;
  2928. sInfo.nTrackPos = 0;
  2929. CPoint pt;
  2930. GetScrollInfo( SB_VERT, &sInfo );
  2931. pt.y = sInfo.nPos;
  2932. switch ( nSBCode )
  2933. {
  2934. case SB_LINELEFT:
  2935. pt.x = 0;
  2936. pt.y += (-0.01 * VSCROLLBAR_RANGE);
  2937. break;
  2938. case SB_LINERIGHT:
  2939. pt.x = 0;
  2940. pt.y += (0.01 * VSCROLLBAR_RANGE);
  2941. break;
  2942. case SB_PAGELEFT:
  2943. pt.y -= sInfo.nPage;
  2944. break;
  2945. case SB_PAGERIGHT:
  2946. pt.y += sInfo.nPage;
  2947. break;
  2948. case SB_THUMBPOSITION:
  2949. pt.y = nPos;
  2950. break;
  2951. case SB_THUMBTRACK:
  2952. pt.y = nPos;
  2953. break;
  2954. default:
  2955. break;
  2956. }
  2957. /* this calculation was based in the code for Camera::moveRight(float amount) */
  2958. Stuff::Vector3D direction;
  2959. if (!eye->usePerspective)
  2960. {
  2961. direction.x = 0.0;
  2962. direction.y = -1.0;
  2963. direction.z = 0.0;
  2964. }
  2965. else
  2966. {
  2967. direction.x = 0.0;
  2968. direction.y = 1.0;
  2969. direction.z = 0.0;
  2970. }
  2971. float worldCameraRotation = eye->getCameraRotation();
  2972. OppRotate(direction,worldCameraRotation);
  2973. Stuff::Vector3D eyeDisplacement = eye->getPosition();
  2974. /* maxVisual was taken from Camera::setPosition(). */
  2975. float maxVisual = (Terrain::worldUnitsMapSide / 2) - Terrain::worldUnitsPerVertex;
  2976. float bound = SQRT_2 * maxVisual;
  2977. float amount = bound * 2.0f * ((float)pt.y / VSCROLLBAR_RANGE - 0.5f);
  2978. float amountMore = amount - direction * eyeDisplacement;
  2979. eye->moveDown(amountMore);
  2980. SetScrollPos( SB_VERT, pt.y );
  2981. CWnd ::OnVScroll(nSBCode, nPos, pScrollBar);
  2982. SafeRunGameOSLogic();
  2983. tacMap.RedrawWindow();
  2984. syncScrollBars();
  2985. }
  2986. void EditorInterface::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  2987. {
  2988. handleKeyDown( nChar );
  2989. CWnd ::OnSysKeyDown(nChar, nRepCnt, nFlags);
  2990. }
  2991. int EditorInterface::UnitSettings()
  2992. {
  2993. EList<Unit*, Unit* > list;
  2994. // ok, find the rest of the selected units
  2995. EditorObjectMgr::instance()->getSelectedUnits( list );
  2996. if ( list.Count() )
  2997. {
  2998. // dialog for units (mechs and vehicles)
  2999. UnitSettingsDlg dlg( list, undoMgr );
  3000. if ( IDOK == dlg.DoModal() )
  3001. {
  3002. }
  3003. }
  3004. EditorObjectMgr::EDITOR_OBJECT_LIST list2 = EditorObjectMgr::instance()->getSelectedObjectList();
  3005. if (list2.Count() > list.Count())
  3006. {
  3007. EditorObjectMgr::EDITOR_OBJECT_LIST::EIterator iter;
  3008. for ( iter = list2.End(); !iter.IsDone(); iter-- )
  3009. {
  3010. if ((0 != dynamic_cast<Unit *>(*iter)) || (0 != dynamic_cast<::DropZone *>(*iter)))
  3011. {
  3012. list2.Delete(iter);
  3013. }
  3014. }
  3015. if ( list2.Count() )
  3016. {
  3017. // dialog for buildings (not units, not dropzones)
  3018. BuildingSettingsDlg dlg( list2, undoMgr );
  3019. if ( IDOK == dlg.DoModal() )
  3020. {
  3021. }
  3022. }
  3023. }
  3024. return true;
  3025. }
  3026. void EditorInterface::initTacMap()
  3027. {
  3028. // Why don't we just load it from the frickin' file?
  3029. // We go through all the damned trouble to save it every time!
  3030. // This takes a LONG time.
  3031. // -fs
  3032. BYTE* pData = NULL;
  3033. long size = 0;
  3034. FullPathFileName mPath;
  3035. bool bFile = false;
  3036. if ( EditorData::instance->getMapName() )
  3037. {
  3038. mPath.init(missionPath,(char *)EditorData::instance->getMapName(),".pak");
  3039. bFile = true;
  3040. }
  3041. if ( bFile && fileExists(mPath))
  3042. {
  3043. PacketFile file;
  3044. file.open(mPath);
  3045. EditorData::instance->loadTacMap(&file, pData, size, 128);
  3046. file.close();
  3047. }
  3048. else
  3049. {
  3050. EditorData::instance->makeTacMap(pData, size, 128);
  3051. }
  3052. tacMap.SetData( pData, size );
  3053. free( pData );
  3054. pData = NULL;
  3055. tacMap.RedrawWindow();
  3056. }
  3057. BOOL EditorInterface::PreTranslateMessage(MSG* pMsg)
  3058. {
  3059. if (m_hAccelTable)
  3060. {
  3061. if (::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))
  3062. return(TRUE);
  3063. }
  3064. return CWnd ::PreTranslateMessage(pMsg);
  3065. }
  3066. void EditorInterface::OnLButtonDblClk(UINT nFlags, CPoint point)
  3067. {
  3068. Stuff::Vector3D pos;
  3069. Stuff::Vector2DOf<long> screen;
  3070. screen.x = point.x;
  3071. screen.y = point.y;
  3072. eye->inverseProject( screen, pos );
  3073. EditorObject* pObject = EditorObjectMgr::instance()->getObjectAtPosition( pos );
  3074. if (NULL != pObject)
  3075. {
  3076. UnitSettings();
  3077. }
  3078. CWnd ::OnLButtonDblClk(nFlags, point);
  3079. }
  3080. void EditorInterface::OnPaint()
  3081. {
  3082. CPaintDC dc(this); // device context for painting
  3083. static bool bFirstLoad = true;
  3084. if (bFirstLoad) {
  3085. if (!bThisIsInitialized) {
  3086. /*paint splash screen*/
  3087. if (!m_hSplashBitMap) {
  3088. m_hSplashBitMap = (HBITMAP)LoadImage(NULL, "esplash.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  3089. }
  3090. if (m_hSplashBitMap) {
  3091. CRect rcClient;
  3092. GetClientRect(rcClient);
  3093. BITMAP bm_struct;
  3094. CBitmap* pbmOld = NULL;
  3095. CDC dcMem;
  3096. dcMem.CreateCompatibleDC(&dc);
  3097. {
  3098. CBitmap *pSplashBitmap = CBitmap::FromHandle(m_hSplashBitMap);
  3099. pSplashBitmap->GetBitmap(&bm_struct);
  3100. pbmOld = dcMem.SelectObject(pSplashBitmap);
  3101. }
  3102. int gbmLeft = rcClient.right / 2 - bm_struct.bmWidth / 2;
  3103. int gbmTop = rcClient.bottom / 2 - bm_struct.bmHeight / 2;
  3104. int gbmRight = gbmLeft + bm_struct.bmWidth;
  3105. int gbmBottom = gbmTop + bm_struct.bmHeight;
  3106. CRect rcTmp;
  3107. rcTmp = rcClient;
  3108. rcTmp.bottom = gbmTop;
  3109. dc.FillSolidRect(&rcTmp, RGB(0, 0, 0));
  3110. rcTmp = rcClient;
  3111. rcTmp.top = gbmBottom;
  3112. dc.FillSolidRect(&rcTmp, RGB(0, 0, 0));
  3113. rcTmp = rcClient;
  3114. rcTmp.right = gbmLeft;
  3115. dc.FillSolidRect(&rcTmp, RGB(0, 0, 0));
  3116. rcTmp = rcClient;
  3117. rcTmp.left = gbmRight;
  3118. dc.FillSolidRect(&rcTmp, RGB(0, 0, 0));
  3119. dc.BitBlt(rcClient.right / 2 - bm_struct.bmWidth / 2,
  3120. rcClient.bottom / 2 - bm_struct.bmHeight / 2,
  3121. bm_struct.bmWidth, bm_struct.bmHeight,
  3122. &dcMem, 0, 0, SRCCOPY);
  3123. dcMem.SelectObject(pbmOld);
  3124. dcMem.DeleteDC();
  3125. }
  3126. } else {
  3127. bFirstLoad = false;
  3128. }
  3129. }
  3130. if (ProcessingError || !bThisIsInitialized || bIsLoading)
  3131. {
  3132. return;
  3133. }
  3134. SafeRunGameOSLogic();
  3135. /* This hack is here because syncScrollBars() depends on the function
  3136. Camera::inverseProject(...) which, for some reason, doesn't return the correct value until
  3137. four frames have been drawn.*/
  3138. if (4 == turn)
  3139. {
  3140. syncScrollBars();
  3141. }
  3142. // Do not call CWnd ::OnPaint() for painting messages
  3143. }
  3144. void EditorInterface::OnViewRefreshtacmap()
  3145. {
  3146. tacMap.UpdateMap();
  3147. }
  3148. bool EditorInterface::SafeRunGameOSLogic()
  3149. {
  3150. if (bThisIsInitialized && (NULL != land))
  3151. {
  3152. if (!m_bInRunGameOSLogicCall)
  3153. {
  3154. m_bInRunGameOSLogicCall = true;
  3155. RunGameOSLogic();
  3156. m_bInRunGameOSLogicCall = false;
  3157. return true;
  3158. }
  3159. }
  3160. return false;
  3161. }
  3162. void EditorInterface::rotateSelectedObjects( int direction )
  3163. {
  3164. ModifyBuildingAction *pAction = new ModifyBuildingAction;
  3165. EditorObjectMgr::EDITOR_OBJECT_LIST selectedObjects;
  3166. selectedObjects = EditorObjectMgr::instance()->getSelectedObjectList();
  3167. EditorObjectMgr::EDITOR_OBJECT_LIST::EIterator iter = selectedObjects.Begin();
  3168. while (!iter.IsDone())
  3169. {
  3170. pAction->addBuildingInfo(*(*iter));
  3171. int id = (*iter)->getID();
  3172. int fitID = EditorObjectMgr::instance()->getFitID(id);
  3173. if ((EditorObjectMgr::WALL == (*iter)->getSpecialType()) || (33/*repair bay*/ == fitID))
  3174. {
  3175. (*iter)->appearance()->rotation += direction * 90;
  3176. }
  3177. else
  3178. {
  3179. (*iter)->appearance()->rotation += direction * 45;
  3180. }
  3181. iter++;
  3182. }
  3183. undoMgr.AddAction(pAction);
  3184. pAction = NULL;
  3185. }
  3186. static void UpdateMissionPlayerPlayer(int player, CCmdUI* pCmdUI)
  3187. {
  3188. if (EditorData::instance->MaxPlayers() < player) {
  3189. pCmdUI->Enable(FALSE);
  3190. } else {
  3191. pCmdUI->Enable(TRUE);
  3192. }
  3193. }
  3194. void EditorInterface::OnUpdateMissionPlayerPlayer3(CCmdUI* pCmdUI)
  3195. {
  3196. UpdateMissionPlayerPlayer(3, pCmdUI);
  3197. }
  3198. void EditorInterface::OnUpdateMissionPlayerPlayer4(CCmdUI* pCmdUI)
  3199. {
  3200. UpdateMissionPlayerPlayer(4, pCmdUI);
  3201. }
  3202. void EditorInterface::OnUpdateMissionPlayerPlayer5(CCmdUI* pCmdUI)
  3203. {
  3204. UpdateMissionPlayerPlayer(5, pCmdUI);
  3205. }
  3206. void EditorInterface::OnUpdateMissionPlayerPlayer6(CCmdUI* pCmdUI)
  3207. {
  3208. UpdateMissionPlayerPlayer(6, pCmdUI);
  3209. }
  3210. void EditorInterface::OnUpdateMissionPlayerPlayer7(CCmdUI* pCmdUI)
  3211. {
  3212. UpdateMissionPlayerPlayer(7, pCmdUI);
  3213. }
  3214. void EditorInterface::OnUpdateMissionPlayerPlayer8(CCmdUI* pCmdUI)
  3215. {
  3216. UpdateMissionPlayerPlayer(8, pCmdUI);
  3217. }
  3218. static void UpdateMissionTeamTeam(int team, CCmdUI* pCmdUI)
  3219. {
  3220. if (EditorData::instance->MaxTeams() < team) {
  3221. pCmdUI->Enable(FALSE);
  3222. } else {
  3223. pCmdUI->Enable(TRUE);
  3224. }
  3225. }
  3226. void EditorInterface::OnUpdateMissionTeamTeam3(CCmdUI* pCmdUI)
  3227. {
  3228. UpdateMissionTeamTeam(3, pCmdUI);
  3229. }
  3230. void EditorInterface::OnUpdateMissionTeamTeam4(CCmdUI* pCmdUI)
  3231. {
  3232. UpdateMissionTeamTeam(4, pCmdUI);
  3233. }
  3234. void EditorInterface::OnUpdateMissionTeamTeam5(CCmdUI* pCmdUI)
  3235. {
  3236. UpdateMissionTeamTeam(5, pCmdUI);
  3237. }
  3238. void EditorInterface::OnUpdateMissionTeamTeam6(CCmdUI* pCmdUI)
  3239. {
  3240. UpdateMissionTeamTeam(6, pCmdUI);
  3241. }
  3242. void EditorInterface::OnUpdateMissionTeamTeam7(CCmdUI* pCmdUI)
  3243. {
  3244. UpdateMissionTeamTeam(7, pCmdUI);
  3245. }
  3246. void EditorInterface::OnUpdateMissionTeamTeam8(CCmdUI* pCmdUI)
  3247. {
  3248. UpdateMissionTeamTeam(8, pCmdUI);
  3249. }
  3250. void EditorInterface::OnDestroy()
  3251. {
  3252. CWnd ::OnDestroy();
  3253. if (tacMap.m_hWnd)
  3254. {
  3255. tacMap.DestroyWindow();
  3256. }
  3257. else
  3258. {
  3259. gosASSERT(false);
  3260. }
  3261. }
  3262. #pragma warning( default:4244 )
  3263. void EditorInterface::OnForestTool()
  3264. {
  3265. if (EditorInterface::instance()->ObjectSelectOnlyMode())
  3266. {
  3267. return;
  3268. }
  3269. ForestDlg dlg;
  3270. long count = 0;
  3271. float xAvg = 0;
  3272. float yAvg = 0;
  3273. // figure out selection
  3274. for ( int j = 0; j < land->realVerticesMapSide; ++j )
  3275. {
  3276. for ( int i = 0; i < land->realVerticesMapSide; ++i )
  3277. {
  3278. if ( land->isVertexSelected( j, i ) )
  3279. {
  3280. Stuff::Vector3D pos;
  3281. land->tileCellToWorld( j, i, 0, 0, pos );
  3282. xAvg += pos.x;
  3283. yAvg += pos.y;
  3284. count++;
  3285. }
  3286. }
  3287. }
  3288. float centerX = xAvg/count;
  3289. float centerY = yAvg/count;
  3290. float dist = 0;
  3291. for ( j = 0; j < land->realVerticesMapSide; ++j )
  3292. {
  3293. for ( int i = 0; i < land->realVerticesMapSide; ++i )
  3294. {
  3295. if ( land->isVertexSelected( j, i ) )
  3296. {
  3297. Stuff::Vector3D pos;
  3298. land->tileCellToWorld( j, i, 0, 0, pos );
  3299. float deltaX = pos.x - centerX;
  3300. float deltaY = pos.y - centerY;
  3301. float tmpDist = deltaX * deltaX + deltaY * deltaY;
  3302. if ( tmpDist > dist )
  3303. dist = tmpDist;
  3304. }
  3305. }
  3306. }
  3307. dlg.m_xLoc = centerX;
  3308. dlg.m_yLoc = centerY;
  3309. dist += 128 * 128; // always make as big as one tile
  3310. dlg.m_radius = (float)sqrt( dist );
  3311. if ( IDOK == dlg.DoModal() )
  3312. {
  3313. EditorObjectMgr::instance()->createForest( dlg.forest );
  3314. }
  3315. }
  3316. void EditorInterface::OnOtherEditforests()
  3317. {
  3318. if (EditorInterface::instance()->ObjectSelectOnlyMode())
  3319. {
  3320. return;
  3321. }
  3322. EditForestDlg dlg;
  3323. dlg.DoModal();
  3324. }
  3325. bool TeamsAction::undo() {
  3326. CTeams swap = EditorData::instance->TeamsRef();
  3327. EditorData::instance->TeamsRef() = PreviousTeams();
  3328. PreviousTeams(swap);
  3329. return true;
  3330. }
  3331. CTeams TeamsAction::PreviousTeams() {
  3332. m_previousTeams.RestoreObjectPointerReferencesFromNotedPositions();
  3333. return m_previousTeams;
  3334. }
  3335. void TeamsAction::PreviousTeams(const CTeams &teams) {
  3336. m_previousTeams = teams;
  3337. /*Some of the objective conditions have pointers to objects. These pointers may become
  3338. invalid in the case that an object is deleted then restored (via undo/redo), so we store the
  3339. positions of the objects referred to so that we can use them later to retrieve valid pointers
  3340. to the objects. Btw, we do know that the object positions will be valid when we need to infer
  3341. the pointers from them. */
  3342. m_previousTeams.NoteThePositionsOfObjectsReferenced();
  3343. }
  3344. void EditorInterface::OnViewOrthographiccamera()
  3345. {
  3346. if (GetParent()->GetMenu()->GetMenuState( ID_VIEW_ORTHOGRAPHICCAMERA, MF_BYCOMMAND ) & MF_CHECKED) {
  3347. GetParent()->GetMenu()->CheckMenuItem( ID_VIEW_ORTHOGRAPHICCAMERA, MF_BYCOMMAND | MF_UNCHECKED );
  3348. eye->usePerspective = true;
  3349. } else {
  3350. GetParent()->GetMenu()->CheckMenuItem( ID_VIEW_ORTHOGRAPHICCAMERA, MF_BYCOMMAND | MF_CHECKED );
  3351. eye->usePerspective = false;
  3352. }
  3353. eye->rotateRight(180.0/*degrees*/);
  3354. SafeRunGameOSLogic();
  3355. syncScrollBars();
  3356. }
  3357. void EditorInterface::OnViewShowpassabilitymap()
  3358. {
  3359. if (GetParent()->GetMenu()->GetMenuState( ID_VIEW_SHOWPASSABILITYMAP, MF_BYCOMMAND ) & MF_CHECKED) {
  3360. GetParent()->GetMenu()->CheckMenuItem( ID_VIEW_SHOWPASSABILITYMAP, MF_BYCOMMAND | MF_UNCHECKED );
  3361. drawTerrainGrid = false;
  3362. } else {
  3363. GetParent()->GetMenu()->CheckMenuItem( ID_VIEW_SHOWPASSABILITYMAP, MF_BYCOMMAND | MF_CHECKED );
  3364. drawTerrainGrid = true;
  3365. }
  3366. }
  3367. void EditorInterface::OnMButtonUp(UINT nFlags, CPoint point)
  3368. {
  3369. if (ThisIsInitialized() && eye)
  3370. {
  3371. eye->allNormal();
  3372. }
  3373. CWnd ::OnMButtonUp(nFlags, point);
  3374. }