MapData.cpp 169 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461
  1. /*
  2. FinalSun/FinalAlert 2 Mission Editor
  3. Copyright (C) 1999-2024 Electronic Arts, Inc.
  4. Authored by Matthias Wagner
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. */
  16. // Map->cpp: Implementierung der Klasse CMap.
  17. //
  18. //////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "MapData.h"
  21. #include "DynamicGraphDlg.h"
  22. #include "MissionEditorPackLib.h"
  23. #include "inlines.h"
  24. #include "variables.h"
  25. #include "maploadingdlg.h"
  26. #include "progressdlg.h"
  27. #include "Structs.h"
  28. #include "Tube.h"
  29. #ifdef _DEBUG
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #define new DEBUG_NEW
  33. #endif
  34. typedef map<CString, CString, SortDummy> OURMAP;
  35. void DoEvents()
  36. {
  37. /*MSG msg;
  38. while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  39. {
  40. TranslateMessage(&msg);
  41. DispatchMessage(&msg);
  42. }*/
  43. }
  44. void GetNodeName(CString& name, int n);
  45. CString GetFree(const char* section)
  46. {
  47. CIniFile& ini = Map->GetIniFile();
  48. int i = 0;
  49. char l[50];
  50. itoa(i, l, 10);
  51. while (ini.sections[section].values.find(l) != ini.sections[section].values.end())
  52. {
  53. i++;
  54. itoa(i, l, 10);
  55. }
  56. return l;
  57. }
  58. /*
  59. This function calculates a number for the specified building type.
  60. Because this function is slow, you should only use it to fill the
  61. buildingid map
  62. */
  63. inline int GetBuildingNumber(LPCTSTR name)
  64. {
  65. CIniFile& ini = Map->GetIniFile();
  66. int v = rules.sections["BuildingTypes"].FindValue(name);
  67. if (v > -1)
  68. {
  69. return v;
  70. }
  71. v = ini.sections["BuildingTypes"].FindValue(name);
  72. if (v > -1)
  73. {
  74. return v + 0x0C00;
  75. }
  76. return -1;
  77. }
  78. inline int GetTerrainNumber(LPCTSTR name)
  79. {
  80. CIniFile& ini = Map->GetIniFile();
  81. int v = rules.sections["TerrainTypes"].FindValue(name);
  82. if (v > -1)
  83. {
  84. return v;
  85. }
  86. v = ini.sections["TerrainTypes"].FindValue(name);
  87. if (v > -1)
  88. {
  89. return v + 0x0C00;
  90. }
  91. return -1;
  92. }
  93. #ifdef SMUDGE_SUPP
  94. inline int GetSmudgeNumber(LPCTSTR name)
  95. {
  96. CIniFile& ini = Map->GetIniFile();
  97. int v = rules.sections["SmudgeTypes"].FindValue(name);
  98. if (v > -1)
  99. {
  100. return v;
  101. }
  102. v = ini.sections["SmudgeTypes"].FindValue(name);
  103. if (v > -1)
  104. {
  105. return v + 0x0C00;
  106. }
  107. return -1;
  108. }
  109. #endif
  110. SNAPSHOTDATA::SNAPSHOTDATA()
  111. {
  112. memset(this, 0, sizeof(SNAPSHOTDATA));
  113. }
  114. NODEDATA::NODEDATA()
  115. {
  116. type = -1;
  117. house = "";
  118. index = -1;
  119. }
  120. FIELDDATA::FIELDDATA()
  121. {
  122. #ifdef SMUDGE_SUPP
  123. smudge = -1;
  124. smudgetype = -1;
  125. #endif
  126. unit = -1;
  127. int i;
  128. for (i = 0;i < SUBPOS_COUNT;i++)
  129. infantry[i] = -1;
  130. aircraft = -1;
  131. structure = -1;
  132. structuretype = -1;
  133. terrain = -1;
  134. waypoint = -1;
  135. overlay = 0xFF;
  136. overlaydata = 0x0;
  137. bMapData = 0x0;
  138. bSubTile = 0;
  139. bMapData2 = 0x0;
  140. wGround = 0xFFFF;
  141. bHeight = 0;
  142. celltag = -1;
  143. bReserved = 0;
  144. bCliffHack = 0;
  145. bRedrawTerrain = 0;
  146. terraintype = -1;
  147. bHide = FALSE;
  148. //sTube = 0xFFFF;
  149. //cTubePart = -1;
  150. if (tiledata_count && (*tiledata_count)) // only if initialized
  151. {
  152. // algorithm taken from UpdateMapFieldData
  153. int replacement = 0;
  154. int ground = wGround;
  155. if (ground == 0xFFFF) ground = 0;
  156. ASSERT(ground == 0);
  157. // we assume ground 0 will never be a bridge set, so don't do this check here in contrast to UpdateMapFieldData
  158. if ((*tiledata)[ground].bReplacementCount) //&& atoi((*tiles).sections["General"].values["BridgeSet"]) != (*tiledata)[ground].wTileSet)
  159. {
  160. replacement = rand() * (1 + (*tiledata)[ground].bReplacementCount) / RAND_MAX;
  161. }
  162. bRNDImage = replacement;
  163. }
  164. };
  165. CMapData::CMapData()
  166. {
  167. m_noAutoObjectUpdate = FALSE;
  168. m_money = 0;
  169. m_cursnapshot = -1;
  170. fielddata = NULL;
  171. fielddata_size = 0;
  172. m_IsoSize = 0;
  173. isInitialized = FALSE;
  174. tiledata = NULL;
  175. m_mfd = NULL;
  176. dwIsoMapSize = 0;
  177. m_snapshots = NULL;
  178. dwSnapShotCount = 0;
  179. memset(&m_mini_biinfo, 0, sizeof(BITMAPINFO));
  180. m_mini_biinfo.bmiHeader.biBitCount = 24;
  181. m_mini_biinfo.bmiHeader.biWidth = 0;
  182. m_mini_biinfo.bmiHeader.biHeight = 0;
  183. m_mini_biinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  184. m_mini_biinfo.bmiHeader.biClrUsed = 0;
  185. m_mini_biinfo.bmiHeader.biPlanes = 1;
  186. m_mini_biinfo.bmiHeader.biCompression = BI_RGB;
  187. m_mini_biinfo.bmiHeader.biClrImportant = 0;
  188. }
  189. CMapData::~CMapData()
  190. {
  191. errstream << "CMapData::~CMapData()\n";
  192. errstream.flush();
  193. // MW : Do not delete tiledata here!
  194. //if(*tiledata!=NULL) delete[] *tiledata;
  195. tiledata = NULL;
  196. if (m_mfd != NULL) delete[] m_mfd;
  197. m_mfd = NULL;
  198. if (fielddata != NULL) delete[] fielddata;
  199. fielddata = NULL;
  200. fielddata_size = 0;
  201. int i;
  202. for (i = 0;i < dwSnapShotCount;i++)
  203. {
  204. delete[] m_snapshots[i].bHeight;
  205. delete[] m_snapshots[i].bMapData;
  206. delete[] m_snapshots[i].bSubTile;
  207. delete[] m_snapshots[i].bMapData2;
  208. delete[] m_snapshots[i].wGround;
  209. delete[] m_snapshots[i].bRedrawTerrain;
  210. delete[] m_snapshots[i].overlay;
  211. delete[] m_snapshots[i].overlaydata;
  212. // m_snapshots[i].mapfile.Clear();
  213. }
  214. if (m_snapshots) delete[] m_snapshots;
  215. m_snapshots = NULL;
  216. dwSnapShotCount = 0;
  217. }
  218. void CMapData::CalcMapRect()
  219. {
  220. CIniFileSection& sec = m_mapfile.sections["Map"];
  221. char msize[50];
  222. strcpy_s(msize, sec.values["Size"]);
  223. int cupos = 0;
  224. static const int custr_size = 20;
  225. char custr[custr_size];
  226. char* cucomma;
  227. cucomma = strchr(&msize[cupos], ',');
  228. if (cucomma == NULL) return;
  229. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  230. custr[(cucomma - msize) - cupos] = 0;
  231. cupos = cucomma - msize + 1;
  232. m_maprect.left = atoi(custr);
  233. cucomma = strchr(&msize[cupos], ',');
  234. if (cucomma == NULL) return;
  235. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  236. custr[((cucomma - msize)) - cupos] = 0;
  237. cupos = cucomma - msize + 1;
  238. m_maprect.top = atoi(custr);
  239. cucomma = strchr(&msize[cupos], ',');
  240. if (cucomma == NULL) return;
  241. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  242. custr[((cucomma - msize)) - cupos] = 0;
  243. cupos = cucomma - msize + 1;
  244. m_maprect.right = atoi(custr);
  245. cucomma = strchr(&msize[cupos], ','); // we check again... could be there is a new ini format
  246. if (cucomma == NULL) cucomma = (char*)((int)msize + strlen(msize));
  247. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  248. custr[((cucomma - msize)) - cupos] = 0;
  249. cupos = cucomma - msize + 1;
  250. m_maprect.bottom = atoi(custr);
  251. m_IsoSize = m_maprect.right + m_maprect.bottom;
  252. // local size
  253. strcpy_s(msize, sec.values["LocalSize"]);
  254. cupos = 0;
  255. cucomma = strchr(&msize[cupos], ',');
  256. if (cucomma == NULL) return;
  257. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  258. custr[(cucomma - msize) - cupos] = 0;
  259. cupos = cucomma - msize + 1;
  260. m_vismaprect.left = atoi(custr);
  261. cucomma = strchr(&msize[cupos], ',');
  262. if (cucomma == NULL) return;
  263. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  264. custr[((cucomma - msize)) - cupos] = 0;
  265. cupos = cucomma - msize + 1;
  266. m_vismaprect.top = atoi(custr);
  267. cucomma = strchr(&msize[cupos], ',');
  268. if (cucomma == NULL) return;
  269. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  270. custr[((cucomma - msize)) - cupos] = 0;
  271. cupos = cucomma - msize + 1;
  272. m_vismaprect.right = atoi(custr);
  273. cucomma = strchr(&msize[cupos], ','); // we check again... could be there is a new ini format
  274. if (cucomma == NULL) cucomma = (char*)((int)msize + strlen(msize));
  275. memcpy_s(custr, custr_size, &msize[cupos], (cucomma - msize) - cupos + 1);
  276. custr[((cucomma - msize)) - cupos] = 0;
  277. cupos = cucomma - msize + 1;
  278. m_vismaprect.bottom = atoi(custr);
  279. }
  280. WORD CMapData::GetHousesCount(BOOL bCountries)
  281. {
  282. #ifndef RA2_MODE
  283. bCountries = FALSE;
  284. #endif
  285. CString sSection = MAPHOUSES;
  286. if (bCountries) sSection = HOUSES;
  287. if (m_mapfile.sections.find(sSection) != m_mapfile.sections.end())
  288. if (m_mapfile.sections[sSection].values.size() > 0) return m_mapfile.sections[sSection].values.size();
  289. return(rules.sections[HOUSES].values.size());
  290. }
  291. CString CMapData::GetHouseID(WORD wHouse, BOOL bCountry)
  292. {
  293. if (wHouse >= GetHousesCount())
  294. return CString("");
  295. #ifndef RA2_MODE
  296. bCountry = FALSE;
  297. #endif
  298. CString sSection = MAPHOUSES;
  299. if (bCountry) sSection = HOUSES;
  300. if (m_mapfile.sections.find(sSection) != m_mapfile.sections.end())
  301. if (m_mapfile.sections[sSection].values.size() > 0) return *m_mapfile.sections[sSection].GetValue(wHouse);
  302. return(*rules.sections[HOUSES].GetValue(wHouse));
  303. }
  304. DWORD CMapData::GetAITriggerTypeCount()
  305. {
  306. if (m_mapfile.sections.find("AITriggerTypes") != m_mapfile.sections.end())
  307. return(m_mapfile.sections["AITriggerTypes"].values.size());
  308. return 0;
  309. }
  310. void CMapData::GetAITriggerType(DWORD dwAITriggerType, AITRIGGERTYPE* pAITrg)
  311. {
  312. CString data;
  313. if (dwAITriggerType >= GetAITriggerTypeCount())
  314. return;
  315. data = *m_mapfile.sections["AITriggerTypes"].GetValue(dwAITriggerType);
  316. pAITrg->ID = *m_mapfile.sections["AITriggerTypes"].GetValueName(dwAITriggerType);
  317. pAITrg->name = GetParam(data, 0);
  318. pAITrg->teamtype1 = GetParam(data, 1);
  319. pAITrg->owner = GetParam(data, 2);
  320. pAITrg->techlevel = GetParam(data, 3);
  321. pAITrg->type = GetParam(data, 4);
  322. pAITrg->unittype = GetParam(data, 5);
  323. pAITrg->data = GetParam(data, 6);
  324. pAITrg->float1 = GetParam(data, 7);
  325. pAITrg->float2 = GetParam(data, 8);
  326. pAITrg->float3 = GetParam(data, 9);
  327. pAITrg->skirmish = GetParam(data, 10);
  328. pAITrg->flag4 = GetParam(data, 11);
  329. pAITrg->multihouse = GetParam(data, 12);
  330. pAITrg->basedefense = GetParam(data, 13);
  331. pAITrg->teamtype2 = GetParam(data, 14);
  332. pAITrg->easy = GetParam(data, 15);
  333. pAITrg->medium = GetParam(data, 16);
  334. pAITrg->hard = GetParam(data, 17);
  335. }
  336. WORD CMapData::GetHouseIndex(LPCTSTR lpHouse)
  337. {
  338. if (m_mapfile.sections.find(HOUSES) != m_mapfile.sections.end())
  339. if (m_mapfile.sections[HOUSES].values.size() > 0)
  340. return m_mapfile.sections[HOUSES].FindValue(lpHouse);
  341. return rules.sections[HOUSES].FindValue(lpHouse);
  342. }
  343. DWORD CMapData::GetAITriggerTypeIndex(LPCTSTR lpID)
  344. {
  345. if (GetAITriggerTypeCount() == 0) return 0;
  346. return m_mapfile.sections["AITriggerTypes"].FindName(lpID);
  347. }
  348. CString CMapData::GetAITriggerTypeID(DWORD dwAITriggerType)
  349. {
  350. if (dwAITriggerType >= GetAITriggerTypeCount()) return CString("");
  351. return *m_mapfile.sections["AITriggerTypes"].GetValueName(dwAITriggerType);
  352. }
  353. CIniFile& CMapData::GetIniFile()
  354. {
  355. UpdateIniFile();
  356. return m_mapfile;
  357. }
  358. /*
  359. UpdateIniFile();
  360. This will update the mapfile member if bSave==TRUE,
  361. else the other data will be updated according to the info in mapfile.
  362. This sections will NOT be updated during loading from ini,
  363. because of perfomance issues. They will not be updated not
  364. during saving to ini if MAPDATA_UPDATE_TO_INI_ALL is not specified:
  365. - IsoMapPack5
  366. - OverlayPack
  367. - OverlayDataPack
  368. If you want to load these sections, the caller needs to call Unpack();
  369. in order to do this.
  370. */
  371. void CMapData::UpdateIniFile(DWORD dwFlags)
  372. {
  373. BOOL bSave = TRUE;
  374. if (dwFlags == MAPDATA_UPDATE_FROM_INI)
  375. bSave = FALSE;
  376. if (dwFlags == MAPDATA_UPDATE_FROM_INI)
  377. {
  378. CalcMapRect();
  379. InitMinimap();
  380. slopesetpiecesset = atoi((*tiles).sections["General"].values["SlopeSetPieces"]);
  381. rampset = atoi((*tiles).sections["General"].values["RampBase"]);
  382. rampsmoothset = atoi((*tiles).sections["General"].values["RampSmooth"]);
  383. cliffset = atoi((*tiles).sections["General"].values["CliffSet"]);
  384. cliffset_start = GetTileID(cliffset, 0);
  385. waterset = atoi((*tiles).sections["General"].values["WaterSet"]);
  386. shoreset = atoi((*tiles).sections["General"].values["ShorePieces"]);
  387. rampset_start = GetTileID(atoi((*tiles).sections["General"].values["RampBase"]), 0);
  388. ramp2set = atoi(g_data.sections["NewUrbanInfo"].values["Ramps2"]);
  389. ramp2set_start = GetTileID(ramp2set, 0);
  390. pave2set = atoi(g_data.sections["NewUrbanInfo"].values["Morphable2"]);
  391. pave2set_start = GetTileID(pave2set, 0);
  392. cliff2set = atoi(g_data.sections["NewUrbanInfo"].values["Cliffs2"]);
  393. cliff2set_start = GetTileID(cliff2set, 0);
  394. cliffwater2set = atoi(g_data.sections["NewUrbanInfo"].values["CliffsWater2"]);
  395. InitializeUnitTypes();
  396. UpdateBuildingInfo();
  397. UpdateTreeInfo();
  398. #ifdef SMUDGE_SUPP
  399. UpdateSmudgeInfo();
  400. #endif
  401. UpdateMapFieldData(bSave);
  402. }
  403. else if (dwFlags & MAPDATA_UPDATE_TO_INI_ALL)
  404. {
  405. UpdateAircraft(bSave);
  406. UpdateCelltags(bSave);
  407. UpdateInfantry(bSave);
  408. UpdateNodes(bSave);
  409. UpdateOverlay(bSave);
  410. UpdateStructures(bSave);
  411. UpdateTerrain(bSave);
  412. #ifdef SMUDGE_SUPP
  413. UpdateSmudges(bSave);
  414. #endif
  415. UpdateUnits(bSave);
  416. UpdateWaypoints(bSave);
  417. UpdateTubes(bSave);
  418. errstream << "UpdateMapFieldData() called" << endl;
  419. errstream.flush();
  420. UpdateMapFieldData(bSave);
  421. errstream << "About to call Pack()" << endl;
  422. errstream.flush();
  423. Pack(dwFlags & MAPDATA_UPDATE_TO_INI_ALL_PREVIEW, dwFlags & MAPDATA_UPDATE_TO_INI_ALL_COMPRESSED);
  424. return;
  425. }
  426. if (!bSave) UpdateAircraft(bSave);
  427. UpdateCelltags(bSave);
  428. if (!bSave) UpdateInfantry(bSave);
  429. UpdateNodes(bSave);
  430. if (!bSave) UpdateOverlay(bSave);
  431. if (!bSave) UpdateStructures(bSave);
  432. if (!bSave) UpdateTerrain(bSave);
  433. #ifdef SMUDGE_SUPP
  434. if (!bSave) UpdateSmudges(bSave);
  435. #endif
  436. if (!bSave) UpdateUnits(bSave);
  437. UpdateWaypoints(bSave);
  438. UpdateTubes(bSave);
  439. }
  440. void CMapData::LoadMap(const std::string& file)
  441. {
  442. errstream << "LoadMap() frees memory\n";
  443. errstream.flush();
  444. if (fielddata != NULL) delete[] fielddata;
  445. int i;
  446. for (i = 0;i < dwSnapShotCount;i++)
  447. {
  448. delete[] m_snapshots[i].bHeight;
  449. delete[] m_snapshots[i].bMapData;
  450. delete[] m_snapshots[i].bSubTile;
  451. delete[] m_snapshots[i].bMapData2;
  452. delete[] m_snapshots[i].wGround;
  453. delete[] m_snapshots[i].bRedrawTerrain;
  454. delete[] m_snapshots[i].overlay;
  455. delete[] m_snapshots[i].overlaydata;
  456. // m_snapshots[i].mapfile.Clear();
  457. }
  458. if (m_snapshots != NULL) delete[] m_snapshots;
  459. fielddata = NULL;
  460. fielddata_size = 0;
  461. m_snapshots = NULL;
  462. dwSnapShotCount = 0;
  463. m_cursnapshot = -1;
  464. m_tubes.clear();
  465. m_tubes.reserve(32);
  466. m_infantry.clear();
  467. m_terrain.clear();
  468. m_units.clear();
  469. m_structures.clear();
  470. #ifdef SMUDGE_SUPP
  471. m_smudges.clear();
  472. #endif
  473. errstream << "LoadMap() loads map file\n";
  474. errstream.flush();
  475. m_mapfile.Clear();
  476. m_mapfile.LoadFile(file, TRUE);
  477. // any .mpr is a multi map. Previous FinalAlert/FinalSun versions did not set this value correctly->
  478. char lowc[MAX_PATH] = { 0 };
  479. strcpy_s(lowc, file.c_str());
  480. _strlwr(lowc);
  481. if (strstr(lowc, ".mpr"))
  482. {
  483. m_mapfile.sections["Basic"].values["MultiplayerOnly"] = "1";
  484. if (m_mapfile.sections["Basic"].FindName("Player") >= 0) m_mapfile.sections["Basic"].values.erase("Player");
  485. }
  486. errstream << "LoadMap() repairs Taskforces (if needed)\n";
  487. errstream.flush();
  488. // repair taskforces (bug in earlier 0.95 versions)
  489. for (i = 0;i < m_mapfile.sections["TaskForces"].values.size();i++)
  490. {
  491. vector<CString> toDelete;
  492. toDelete.reserve(5);
  493. CIniFileSection& sec = m_mapfile.sections[*m_mapfile.sections["TaskForces"].GetValue(i)];
  494. int e;
  495. for (e = 0;e < sec.values.size();e++)
  496. {
  497. if (sec.GetValue(e)->GetLength() == 0)
  498. {
  499. toDelete.push_back(*sec.GetValueName(e));
  500. }
  501. }
  502. for (e = 0;e < toDelete.size();e++)
  503. {
  504. sec.values.erase(toDelete[e]);
  505. }
  506. }
  507. errstream << "LoadMap() loads graphics\n";
  508. errstream.flush();
  509. CDynamicGraphDlg dlg(theApp.m_pMainWnd);
  510. dlg.ShowWindow(SW_SHOW);
  511. dlg.UpdateWindow();
  512. theApp.m_loading->Unload();
  513. theApp.m_loading->InitMixFiles();
  514. map<CString, PICDATA>::iterator it = pics.begin();
  515. for (int e = 0;e < pics.size();e++)
  516. {
  517. try
  518. {
  519. #ifdef NOSURFACES_OBJECTS
  520. if (it->second.bType == PICDATA_TYPE_BMP)
  521. {
  522. if (it->second.pic != NULL)
  523. {
  524. ((LPDIRECTDRAWSURFACE4)it->second.pic)->Release();
  525. }
  526. }
  527. else
  528. {
  529. if (it->second.pic != NULL)
  530. {
  531. delete[] it->second.pic;
  532. }
  533. if (it->second.vborder) delete[] it->second.vborder;
  534. }
  535. #else
  536. if (it->second.pic != NULL) it->second.pic->Release();
  537. #endif
  538. it->second.pic = NULL;
  539. }
  540. catch (...)
  541. {
  542. CString err;
  543. err = "Access violation while trying to release surface ";
  544. char c[6];
  545. itoa(e, c, 10);
  546. err += c;
  547. err += "\n";
  548. OutputDebugString(err);
  549. continue;
  550. }
  551. it++;
  552. }
  553. pics.clear();
  554. missingimages.clear();
  555. theApp.m_loading->InitPics();
  556. UpdateBuildingInfo();
  557. UpdateTreeInfo();
  558. ((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview->UpdateOverlayPictures();
  559. if (m_mapfile.sections["Map"].values["Theater"] == THEATER0)
  560. {
  561. tiledata = &s_tiledata;
  562. tiledata_count = &s_tiledata_count;
  563. tiles = &tiles_s;
  564. theApp.m_loading->FreeTileSet();
  565. tiledata = &u_tiledata;
  566. tiledata_count = &u_tiledata_count;
  567. tiles = &tiles_u;
  568. theApp.m_loading->FreeTileSet();
  569. // MW new tilesets
  570. tiledata = &un_tiledata;
  571. tiledata_count = &un_tiledata_count;
  572. tiles = &tiles_un;
  573. theApp.m_loading->FreeTileSet();
  574. tiledata = &d_tiledata;
  575. tiledata_count = &d_tiledata_count;
  576. tiles = &tiles_d;
  577. theApp.m_loading->FreeTileSet();
  578. tiledata = &l_tiledata;
  579. tiledata_count = &l_tiledata_count;
  580. tiles = &tiles_l;
  581. theApp.m_loading->FreeTileSet();
  582. tiledata = &t_tiledata;
  583. tiledata_count = &t_tiledata_count;
  584. tiles = &tiles_t;
  585. theApp.m_loading->FreeTileSet();
  586. theApp.m_loading->InitTMPs(&dlg.m_Progress);
  587. theApp.m_loading->cur_theat = 'T';
  588. }
  589. else if (m_mapfile.sections["Map"].values["Theater"] == THEATER1)
  590. {
  591. tiledata = &t_tiledata;
  592. tiledata_count = &t_tiledata_count;
  593. tiles = &tiles_t;
  594. theApp.m_loading->FreeTileSet();
  595. tiledata = &u_tiledata;
  596. tiledata_count = &u_tiledata_count;
  597. tiles = &tiles_u;
  598. theApp.m_loading->FreeTileSet();
  599. // MW new tilesets
  600. tiledata = &un_tiledata;
  601. tiledata_count = &un_tiledata_count;
  602. tiles = &tiles_un;
  603. theApp.m_loading->FreeTileSet();
  604. tiledata = &d_tiledata;
  605. tiledata_count = &d_tiledata_count;
  606. tiles = &tiles_d;
  607. theApp.m_loading->FreeTileSet();
  608. tiledata = &l_tiledata;
  609. tiledata_count = &l_tiledata_count;
  610. tiles = &tiles_l;
  611. theApp.m_loading->FreeTileSet();
  612. tiledata = &s_tiledata;
  613. tiledata_count = &s_tiledata_count;
  614. tiles = &tiles_s;
  615. theApp.m_loading->FreeTileSet();
  616. theApp.m_loading->InitTMPs(&dlg.m_Progress);
  617. theApp.m_loading->cur_theat = 'A';
  618. }
  619. else if (m_mapfile.sections["Map"].values["Theater"] == THEATER2)
  620. {
  621. tiledata = &t_tiledata;
  622. tiledata_count = &t_tiledata_count;
  623. tiles = &tiles_t;
  624. theApp.m_loading->FreeTileSet();
  625. tiledata = &s_tiledata;
  626. tiledata_count = &s_tiledata_count;
  627. tiles = &tiles_s;
  628. theApp.m_loading->FreeTileSet();
  629. // MW new tilesets
  630. tiledata = &un_tiledata;
  631. tiledata_count = &un_tiledata_count;
  632. tiles = &tiles_un;
  633. theApp.m_loading->FreeTileSet();
  634. tiledata = &d_tiledata;
  635. tiledata_count = &d_tiledata_count;
  636. tiles = &tiles_d;
  637. theApp.m_loading->FreeTileSet();
  638. tiledata = &l_tiledata;
  639. tiledata_count = &l_tiledata_count;
  640. tiles = &tiles_l;
  641. theApp.m_loading->FreeTileSet();
  642. tiledata = &u_tiledata;
  643. tiledata_count = &u_tiledata_count;
  644. tiles = &tiles_u;
  645. theApp.m_loading->FreeTileSet();
  646. theApp.m_loading->InitTMPs(&dlg.m_Progress);
  647. theApp.m_loading->cur_theat = 'U';
  648. }
  649. else if (yuri_mode && m_mapfile.sections["Map"].values["Theater"] == THEATER3)
  650. {
  651. tiledata = &t_tiledata;
  652. tiledata_count = &t_tiledata_count;
  653. tiles = &tiles_t;
  654. theApp.m_loading->FreeTileSet();
  655. tiledata = &s_tiledata;
  656. tiledata_count = &s_tiledata_count;
  657. tiles = &tiles_s;
  658. theApp.m_loading->FreeTileSet();
  659. // MW new tilesets
  660. tiledata = &d_tiledata;
  661. tiledata_count = &d_tiledata_count;
  662. tiles = &tiles_d;
  663. theApp.m_loading->FreeTileSet();
  664. tiledata = &l_tiledata;
  665. tiledata_count = &l_tiledata_count;
  666. tiles = &tiles_l;
  667. theApp.m_loading->FreeTileSet();
  668. tiledata = &u_tiledata;
  669. tiledata_count = &u_tiledata_count;
  670. tiles = &tiles_u;
  671. theApp.m_loading->FreeTileSet();
  672. tiledata = &un_tiledata;
  673. tiledata_count = &un_tiledata_count;
  674. tiles = &tiles_un;
  675. theApp.m_loading->FreeTileSet();
  676. theApp.m_loading->InitTMPs(&dlg.m_Progress);
  677. theApp.m_loading->cur_theat = 'N';
  678. }
  679. else if (yuri_mode && m_mapfile.sections["Map"].values["Theater"] == THEATER4)
  680. {
  681. tiledata = &t_tiledata;
  682. tiledata_count = &t_tiledata_count;
  683. tiles = &tiles_t;
  684. theApp.m_loading->FreeTileSet();
  685. tiledata = &s_tiledata;
  686. tiledata_count = &s_tiledata_count;
  687. tiles = &tiles_s;
  688. theApp.m_loading->FreeTileSet();
  689. // MW new tilesets
  690. tiledata = &un_tiledata;
  691. tiledata_count = &un_tiledata_count;
  692. tiles = &tiles_un;
  693. theApp.m_loading->FreeTileSet();
  694. tiledata = &d_tiledata;
  695. tiledata_count = &d_tiledata_count;
  696. tiles = &tiles_d;
  697. theApp.m_loading->FreeTileSet();
  698. tiledata = &u_tiledata;
  699. tiledata_count = &u_tiledata_count;
  700. tiles = &tiles_u;
  701. theApp.m_loading->FreeTileSet();
  702. tiledata = &l_tiledata;
  703. tiledata_count = &l_tiledata_count;
  704. tiles = &tiles_l;
  705. theApp.m_loading->FreeTileSet();
  706. theApp.m_loading->InitTMPs(&dlg.m_Progress);
  707. theApp.m_loading->cur_theat = 'L';
  708. }
  709. else if (m_mapfile.sections["Map"].values["Theater"] == THEATER5)
  710. {
  711. tiledata = &t_tiledata;
  712. tiledata_count = &t_tiledata_count;
  713. tiles = &tiles_t;
  714. theApp.m_loading->FreeTileSet();
  715. tiledata = &s_tiledata;
  716. tiledata_count = &s_tiledata_count;
  717. tiles = &tiles_s;
  718. theApp.m_loading->FreeTileSet();
  719. // MW new tilesets
  720. tiledata = &un_tiledata;
  721. tiledata_count = &un_tiledata_count;
  722. tiles = &tiles_un;
  723. theApp.m_loading->FreeTileSet();
  724. tiledata = &l_tiledata;
  725. tiledata_count = &l_tiledata_count;
  726. tiles = &tiles_l;
  727. theApp.m_loading->FreeTileSet();
  728. tiledata = &u_tiledata;
  729. tiledata_count = &u_tiledata_count;
  730. tiles = &tiles_u;
  731. theApp.m_loading->FreeTileSet();
  732. tiledata = &d_tiledata;
  733. tiledata_count = &d_tiledata_count;
  734. tiles = &tiles_d;
  735. theApp.m_loading->FreeTileSet();
  736. theApp.m_loading->InitTMPs(&dlg.m_Progress);
  737. theApp.m_loading->cur_theat = 'D';
  738. }
  739. else
  740. {
  741. theApp.m_loading->FreeAll();
  742. CString s = "Fatal error! %9 doesn´t support the theater of this map!";
  743. s = TranslateStringACP(s);
  744. MessageBox(0, s, "Error", 0);
  745. exit(0);
  746. }
  747. dlg.DestroyWindow();
  748. CalcMapRect();
  749. isInitialized = TRUE;
  750. errstream << "LoadMap() allocates fielddata\n";
  751. errstream.flush();
  752. fielddata = new(FIELDDATA[(GetIsoSize() + 1) * (GetIsoSize() + 1)]);
  753. fielddata_size = (GetIsoSize() + 1) * (GetIsoSize() + 1);
  754. errstream << "LoadMap() unpacks data\n";
  755. errstream.flush();
  756. Unpack();
  757. errstream << "LoadMap() updates from ini\n";
  758. errstream.flush();
  759. UpdateIniFile(MAPDATA_UPDATE_FROM_INI);
  760. }
  761. void CMapData::Unpack()
  762. {
  763. if (!isInitialized) return;
  764. CMapLoadingDlg d;
  765. d.ShowWindow(SW_SHOW);
  766. d.UpdateWindow();
  767. CString ovrl;
  768. int i;
  769. ovrl = "";
  770. for (i = 0;i < m_mapfile.sections["OverlayPack"].values.size();i++)
  771. {
  772. ovrl += *m_mapfile.sections["OverlayPack"].GetValue(i);
  773. }
  774. //BYTE values[262144];
  775. const size_t VALUESIZE = 262144;
  776. std::vector<BYTE> values(VALUESIZE, 0xFF);
  777. int hexlen;
  778. if (ovrl.GetLength() > 0)
  779. {
  780. std::vector<BYTE> hex;
  781. hexlen = FSunPackLib::DecodeBase64(ovrl, hex);
  782. FSunPackLib::DecodeF80(hex.data(), hexlen, values, VALUESIZE);
  783. values.resize(VALUESIZE, 0xFF); // fill rest
  784. }
  785. memcpy(m_Overlay, values.data(), std::min(VALUESIZE, values.size()));
  786. ovrl = "";
  787. for (i = 0;i < m_mapfile.sections["OverlayDataPack"].values.size();i++)
  788. {
  789. ovrl += *m_mapfile.sections["OverlayDataPack"].GetValue(i);
  790. }
  791. values.assign(VALUESIZE, 0);
  792. if (ovrl.GetLength() > 0)
  793. {
  794. std::vector<BYTE> hex;
  795. hexlen = FSunPackLib::DecodeBase64(ovrl, hex);
  796. FSunPackLib::DecodeF80(hex.data(), hexlen, values, VALUESIZE);
  797. values.resize(VALUESIZE, 0xFF); // fill rest
  798. }
  799. memcpy(m_OverlayData, values.data(), std::min(VALUESIZE, values.size()));
  800. CString IsoMapPck;
  801. int len_needed = 0;
  802. CIniFileSection& sec = m_mapfile.sections["IsoMapPack5"];
  803. int lines = sec.values.size();
  804. /*char c[50];
  805. itoa(m_mapfile.sections["IsoMapPack5"].values.size(), c, 10);
  806. MessageBox(0,c,"",0);*/
  807. for (i = 0;i < lines;i++)
  808. {
  809. len_needed += sec.GetValue(i)->GetLength();
  810. }
  811. LPSTR lpMapPack = new(char[len_needed + 1]);
  812. memset(lpMapPack, 0, len_needed + 1);
  813. int cur_pos = 0;
  814. for (i = 0;i < lines;i++)
  815. {
  816. memcpy(lpMapPack + cur_pos, (LPCSTR)*sec.GetValue(i), sec.GetValue(i)->GetLength());
  817. cur_pos += sec.GetValue(i)->GetLength();
  818. DoEvents();
  819. //IsoMapPck+=*sec.GetValue(i);
  820. }
  821. IsoMapPck = lpMapPack;
  822. delete[] lpMapPack;
  823. if (m_mfd != NULL) delete[] m_mfd;
  824. m_mfd = NULL;
  825. dwIsoMapSize = 0;
  826. if (IsoMapPck.GetLength() > 0)
  827. {
  828. std::vector<BYTE> hexC;
  829. //DoEvents();
  830. hexlen = FSunPackLib::DecodeBase64(IsoMapPck, hexC);
  831. // first let´s find out the size of the mappack data
  832. const auto hex = hexC.data();
  833. int SP = 0;
  834. int MapSizeBytes = 0;
  835. int sec = 0;
  836. while (SP < hexlen)
  837. {
  838. WORD wSrcSize;
  839. WORD wDestSize;
  840. memcpy(&wSrcSize, hex + SP, 2);
  841. SP += 2;
  842. memcpy(&wDestSize, hex + SP, 2);
  843. SP += 2;
  844. MapSizeBytes += wDestSize;
  845. SP += wSrcSize;
  846. sec++;
  847. }
  848. m_mfd = new(BYTE[MapSizeBytes]);
  849. dwIsoMapSize = MapSizeBytes / MAPFIELDDATA_SIZE;
  850. FSunPackLib::DecodeIsoMapPack5(hex, hexlen, (BYTE*)m_mfd, d.m_Progress.m_hWnd, TRUE);
  851. int k;
  852. /*fstream f;
  853. f.open("C:\\isomappack5.txt",ios_base::in | ios_base::out | ios_base::trunc);
  854. for(k=0;k<150;k++)
  855. {
  856. f << "Byte " << k << ": " << (int)m_mfd[k] << endl;
  857. }
  858. f.flush();*/
  859. }
  860. d.DestroyWindow();
  861. }
  862. void CMapData::Pack(BOOL bCreatePreview, BOOL bCompression)
  863. {
  864. if (!isInitialized) return;
  865. errstream << "Erasing sections" << endl;
  866. errstream.flush();
  867. int i;
  868. BYTE* base64 = NULL; // must be freed!
  869. m_mapfile.sections.erase("OverlayPack");
  870. m_mapfile.sections.erase("OverlayDataPack");
  871. m_mapfile.sections.erase("IsoMapPack5"); // only activate when packing isomappack is supported
  872. DWORD pos;
  873. errstream << "Creating Digest" << endl;
  874. errstream.flush();
  875. if (m_mapfile.sections["Digest"].values.size() == 0)
  876. {
  877. srand(GetTickCount());
  878. unsigned short vals[10];
  879. for (i = 0;i < 10;i++)
  880. vals[i] = rand() * 65536 / RAND_MAX;
  881. base64 = FSunPackLib::EncodeBase64((BYTE*)vals, 20);
  882. i = 0;
  883. pos = 0;
  884. while (TRUE)
  885. {
  886. i++;
  887. char cLine[50];
  888. itoa(i, cLine, 10);
  889. char str[200];
  890. memset(str, 0, 200);
  891. WORD cpysize = 70;
  892. if (pos + cpysize > strlen((char*)base64)) cpysize = strlen((char*)base64) - pos;
  893. memcpy(str, &base64[pos], cpysize);
  894. if (strlen(str) > 0)
  895. m_mapfile.sections["Digest"].values[cLine] = str;
  896. if (cpysize < 70) break;
  897. pos += 70;
  898. }
  899. delete[] base64;
  900. base64 = NULL;
  901. }
  902. BYTE* values = new(BYTE[262144]);
  903. BYTE* hexpacked = NULL; // must be freed!
  904. errstream << "Values allocated. Pointer: " << (int)values << endl;
  905. errstream.flush();
  906. errstream << "Packing overlay" << endl;
  907. errstream.flush();
  908. for (i = 0;i < 262144;i++)
  909. {
  910. values[i] = m_Overlay[i];
  911. }
  912. int hexpackedLen = FSunPackLib::EncodeF80(values, 262144, 32, &hexpacked);
  913. base64 = FSunPackLib::EncodeBase64(hexpacked, hexpackedLen);
  914. errstream << "Saving overlay" << endl;
  915. i = 0;
  916. pos = 0;
  917. while (TRUE)
  918. {
  919. i++;
  920. char cLine[50];
  921. itoa(i, cLine, 10);
  922. char str[200];
  923. memset(str, 0, 200);
  924. WORD cpysize = 70;
  925. if (pos + cpysize > strlen((char*)base64)) cpysize = strlen((char*)base64) - pos;
  926. memcpy(str, &base64[pos], cpysize);
  927. if (strlen(str) > 0)
  928. m_mapfile.sections["OverlayPack"].values[cLine] = str;
  929. if (cpysize < 70) break;
  930. pos += 70;
  931. }
  932. #ifndef _DEBUG__
  933. delete[] hexpacked;
  934. delete[] base64;
  935. #endif
  936. errstream << "Pack overlaydata" << endl;
  937. errstream.flush();
  938. for (i = 0;i < 262144;i++)
  939. {
  940. values[i] = m_OverlayData[i];
  941. }
  942. hexpacked = NULL;
  943. errstream << "Format80" << endl;
  944. errstream.flush();
  945. hexpackedLen = FSunPackLib::EncodeF80(values, 262144, 32, &hexpacked);
  946. errstream << "Base64" << endl;
  947. errstream.flush();
  948. base64 = FSunPackLib::EncodeBase64(hexpacked, hexpackedLen);
  949. errstream << "Overlaydata done" << endl;
  950. errstream.flush();
  951. i = 0;
  952. pos = 0;
  953. while (TRUE)
  954. {
  955. i++;
  956. char cLine[50];
  957. itoa(i, cLine, 10);
  958. char str[200];
  959. memset(str, 0, 200);
  960. WORD cpysize = 70;
  961. if (pos + cpysize > strlen((char*)base64)) cpysize = strlen((char*)base64) - pos;
  962. memcpy(str, &base64[pos], cpysize);
  963. if (strlen(str) > 0)
  964. m_mapfile.sections["OverlayDataPack"].values[cLine] = str;
  965. if (cpysize < 70) break;
  966. pos += 70;
  967. }
  968. #ifndef _DEBUG__
  969. delete[] hexpacked;
  970. delete[] base64;
  971. #endif
  972. hexpacked = NULL;
  973. errstream << "Pack isomappack" << endl;
  974. errstream.flush();
  975. hexpackedLen = FSunPackLib::EncodeIsoMapPack5(m_mfd, dwIsoMapSize * MAPFIELDDATA_SIZE, &hexpacked);
  976. errstream << "done" << endl;
  977. errstream.flush();
  978. errstream << "hexdata size: " << hexpackedLen;
  979. errstream << endl << "Now converting to base64";
  980. errstream.flush();
  981. base64 = FSunPackLib::EncodeBase64(hexpacked, hexpackedLen);
  982. errstream << "done" << endl;
  983. errstream.flush();
  984. i = 0;
  985. pos = 0;
  986. int base64len = strlen((char*)base64);
  987. while (TRUE)
  988. {
  989. i++;
  990. char cLine[50];
  991. itoa(i, cLine, 10);
  992. char str[200];
  993. memset(str, 0, 200);
  994. int cpysize = 70;
  995. if (pos + cpysize > base64len) cpysize = base64len - pos;
  996. memcpy(str, &base64[pos], cpysize);
  997. if (cpysize)
  998. m_mapfile.sections["IsoMapPack5"].values[cLine] = str;
  999. if (cpysize < 70) break;
  1000. pos += 70;
  1001. }
  1002. errstream << "finished copying into inifile" << endl;
  1003. errstream.flush();
  1004. #ifndef _DEBUG__
  1005. delete[] hexpacked;
  1006. delete[] base64;
  1007. #endif
  1008. // create minimap
  1009. if (bCreatePreview)
  1010. {
  1011. BITMAPINFO biinfo;
  1012. BYTE* lpDibData;
  1013. int pitch;
  1014. ((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_minimap.DrawMinimap(&lpDibData, biinfo, pitch);
  1015. m_mapfile.sections.erase("PreviewPack");
  1016. m_mapfile.sections["Preview"].values["Size"] = m_mapfile.sections["Map"].values["Size"];
  1017. char c[50];
  1018. itoa(biinfo.bmiHeader.biWidth, c, 10);
  1019. m_mapfile.sections["Preview"].values["Size"] = SetParam(m_mapfile.sections["Preview"].values["Size"], 2, c);
  1020. itoa(biinfo.bmiHeader.biHeight, c, 10);
  1021. m_mapfile.sections["Preview"].values["Size"] = SetParam(m_mapfile.sections["Preview"].values["Size"], 3, c);
  1022. BYTE* lpRAW = new(BYTE[biinfo.bmiHeader.biWidth * biinfo.bmiHeader.biHeight * 3]);
  1023. int mapwidth = GetWidth();
  1024. int mapheight = GetHeight();
  1025. int e;
  1026. for (i = 0;i < biinfo.bmiHeader.biWidth;i++)
  1027. {
  1028. for (e = 0;e < biinfo.bmiHeader.biHeight;e++)
  1029. {
  1030. int dest = i * 3 + e * biinfo.bmiHeader.biWidth * 3;
  1031. int src = i * 3 + (biinfo.bmiHeader.biHeight - e - 1) * pitch;
  1032. memcpy(&lpRAW[dest + 2], &lpDibData[src + 0], 1);
  1033. memcpy(&lpRAW[dest + 1], &lpDibData[src + 1], 1);
  1034. memcpy(&lpRAW[dest + 0], &lpDibData[src + 2], 1);
  1035. }
  1036. }
  1037. hexpacked = NULL;
  1038. hexpackedLen = FSunPackLib::EncodeIsoMapPack5(lpRAW, biinfo.bmiHeader.biWidth * biinfo.bmiHeader.biHeight * 3, &hexpacked);
  1039. base64 = FSunPackLib::EncodeBase64(hexpacked, hexpackedLen);
  1040. // uses IsoMapPack5 encoding routine
  1041. errstream << "Saving minimap" << endl;
  1042. i = 0;
  1043. pos = 0;
  1044. while (TRUE)
  1045. {
  1046. i++;
  1047. char cLine[50];
  1048. itoa(i, cLine, 10);
  1049. char str[200];
  1050. memset(str, 0, 200);
  1051. WORD cpysize = 70;
  1052. if (pos + cpysize > strlen((char*)base64)) cpysize = strlen((char*)base64) - pos;
  1053. memcpy(str, &base64[pos], cpysize);
  1054. if (strlen(str) > 0)
  1055. m_mapfile.sections["PreviewPack"].values[cLine] = str;
  1056. if (cpysize < 70) break;
  1057. pos += 70;
  1058. }
  1059. //#ifndef _DEBUG__
  1060. delete[] base64;
  1061. delete[] hexpacked;
  1062. //#endif
  1063. delete[] lpRAW;
  1064. //delete[] lpDibData;
  1065. }
  1066. delete[] values;
  1067. }
  1068. void CMapData::ClearOverlayData()
  1069. {
  1070. memset(m_OverlayData, 0x0, 262144);
  1071. // Pack();
  1072. }
  1073. void CMapData::ClearOverlay()
  1074. {
  1075. memset(m_Overlay, 0xFF, 262144);
  1076. // Pack();
  1077. }
  1078. void CMapData::SetOverlayAt(DWORD dwPos, BYTE bValue)
  1079. {
  1080. int y = dwPos / m_IsoSize;
  1081. int x = dwPos % m_IsoSize;
  1082. if (y + x * 512 > 262144 || dwPos > m_IsoSize * m_IsoSize) return;
  1083. BYTE& ovrl = m_Overlay[y + x * 512];
  1084. BYTE& ovrld = m_OverlayData[y + x * 512];
  1085. RemoveOvrlMoney(ovrl, ovrld);
  1086. m_Overlay[y + x * 512] = bValue;
  1087. m_OverlayData[y + x * 512] = 0;
  1088. fielddata[dwPos].overlay = bValue;
  1089. fielddata[dwPos].overlaydata = 0;
  1090. BYTE& ovrl2 = m_Overlay[y + x * 512];
  1091. BYTE& ovrld2 = m_OverlayData[y + x * 512];
  1092. AddOvrlMoney(ovrl2, ovrld2);
  1093. int i, e;
  1094. for (i = -1;i < 2;i++)
  1095. for (e = -1;e < 2;e++)
  1096. if (i + x > 0 && i + x < m_IsoSize && y + e >= 0 && y + e < m_IsoSize)
  1097. SmoothTiberium(dwPos + i + e * m_IsoSize);
  1098. Mini_UpdatePos(x, y, IsMultiplayer());
  1099. }
  1100. BYTE CMapData::GetOverlayAt(DWORD dwPos)
  1101. {
  1102. if (dwPos > fielddata_size) return 0;
  1103. return fielddata[dwPos].overlay;
  1104. }
  1105. void CMapData::SetOverlayDataAt(DWORD dwPos, BYTE bValue)
  1106. {
  1107. int y = dwPos / m_IsoSize;
  1108. int x = dwPos % m_IsoSize;
  1109. if (y + x * 512 > 262144 || dwPos > m_IsoSize * m_IsoSize) return;
  1110. BYTE& ovrl = m_Overlay[y + x * 512];
  1111. BYTE& ovrld = m_OverlayData[y + x * 512];
  1112. if (ovrl >= RIPARIUS_BEGIN && ovrl <= RIPARIUS_END)
  1113. {
  1114. //m_money-=(ovrld+1)*(atoi(rules.sections["Riparius"].values["Value"]));
  1115. return;
  1116. }
  1117. if (ovrl >= CRUENTUS_BEGIN && ovrl <= CRUENTUS_END)
  1118. {
  1119. //m_money-=(ovrld+1)*(atoi(rules.sections["Cruentus"].values["Value"]));
  1120. return;
  1121. }
  1122. if (ovrl >= VINIFERA_BEGIN && ovrl <= VINIFERA_END)
  1123. {
  1124. //m_money-=(ovrld+1)*(atoi(rules.sections["Vinifera"].values["Value"]));
  1125. return;
  1126. }
  1127. if (ovrl >= ABOREUS_BEGIN && ovrl <= ABOREUS_END)
  1128. {
  1129. //m_money-=(ovrld+1)*(atoi(rules.sections["Aboreus"].values["Value"]));
  1130. return;
  1131. }
  1132. m_OverlayData[y + x * 512] = bValue;
  1133. fielddata[dwPos].overlaydata = bValue;
  1134. BYTE& ovrl2 = m_Overlay[y + x * 512];
  1135. BYTE& ovrld2 = m_OverlayData[y + x * 512];
  1136. /*if(ovrl2>=RIPARIUS_BEGIN && ovrl2<=RIPARIUS_END)
  1137. {
  1138. m_money+=(ovrld2+1)*(atoi(rules.sections["Riparius"].values["Value"]));
  1139. }
  1140. if(ovrl2>=CRUENTUS_BEGIN && ovrl2<=CRUENTUS_END)
  1141. {
  1142. m_money+=(ovrld2+1)*(atoi(rules.sections["Cruentus"].values["Value"]));
  1143. }
  1144. if(ovrl2>=VINIFERA_BEGIN && ovrl2<=VINIFERA_END)
  1145. {
  1146. m_money+=(ovrld2+1)*(atoi(rules.sections["Vinifera"].values["Value"]));
  1147. }
  1148. if(ovrl2>=ABOREUS_BEGIN && ovrl2<=ABOREUS_END)
  1149. {
  1150. m_money+=(ovrld2+1)*(atoi(rules.sections["Aboreus"].values["Value"]));
  1151. }*/
  1152. }
  1153. BYTE CMapData::GetOverlayDataAt(DWORD dwPos)
  1154. {
  1155. return fielddata[dwPos].overlaydata;
  1156. }
  1157. /*
  1158. UpdateInfantry();
  1159. Updates the tiledata if bSave==FALSE (standard) according to the mapfile.
  1160. If bSave==TRUE, nothing is done at the moment (would be for updating the mapfile, but not needed yet,
  1161. because the mapfile is modified directly)
  1162. */
  1163. void CMapData::UpdateInfantry(BOOL bSave)
  1164. {
  1165. vector<INFANTRY>& iv = m_infantry;
  1166. if (bSave == FALSE)
  1167. {
  1168. iv.clear();
  1169. iv.reserve(100);
  1170. int i;
  1171. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1172. {
  1173. int e;
  1174. for (e = 0;e < SUBPOS_COUNT;e++)
  1175. fielddata[i].infantry[e] = -1;
  1176. }
  1177. if (m_mapfile.sections.find("Infantry") != m_mapfile.sections.end())
  1178. {
  1179. CIniFileSection& sec = m_mapfile.sections["Infantry"];
  1180. for (i = 0;i < sec.values.size();i++)
  1181. {
  1182. CString data = *sec.GetValue(i);
  1183. int x = atoi(GetParam(data, 4));
  1184. int y = atoi(GetParam(data, 3));
  1185. int sp = atoi(GetParam(data, 5));
  1186. int pos = x + y * GetIsoSize();
  1187. INFANTRY id;
  1188. id.deleted = 0;
  1189. id.house = GetParam(data, 0);
  1190. id.type = GetParam(data, 1);
  1191. id.strength = GetParam(data, 2);
  1192. id.y = GetParam(data, 3);
  1193. id.x = GetParam(data, 4);
  1194. id.pos = GetParam(data, 5);
  1195. id.action = GetParam(data, 6);
  1196. id.direction = GetParam(data, 7);
  1197. id.tag = GetParam(data, 8);
  1198. id.flag1 = GetParam(data, 9);
  1199. id.flag2 = GetParam(data, 10);
  1200. id.flag3 = GetParam(data, 11);
  1201. id.flag4 = GetParam(data, 12);
  1202. id.flag5 = GetParam(data, 13);
  1203. iv.push_back(id);
  1204. int spp = sp - 1;
  1205. if (spp < 0) spp = 0;
  1206. if (spp < SUBPOS_COUNT)
  1207. if (pos < fielddata_size)
  1208. fielddata[pos].infantry[spp] = iv.size() - 1;
  1209. Mini_UpdatePos(x, y, IsMultiplayer());
  1210. /*else
  1211. {
  1212. int e;
  1213. for(e=0;e<SUBPOS_COUNT;e++)
  1214. {
  1215. if(fielddata[pos].infantry[e]<0)
  1216. {
  1217. fielddata[pos].infantry[e]=i;
  1218. break;
  1219. }
  1220. }
  1221. }*/
  1222. }
  1223. }
  1224. }
  1225. else
  1226. {
  1227. m_mapfile.sections.erase("Infantry");
  1228. int i;
  1229. int count = 0;
  1230. for (i = 0;i < iv.size();i++)
  1231. {
  1232. INFANTRY& id = iv[i];
  1233. if (!id.deleted)
  1234. {
  1235. INFANTRY& infantry = id;
  1236. CString value;
  1237. value = infantry.house + "," + infantry.type + "," + infantry.strength + "," + infantry.y +
  1238. "," + infantry.x + "," + infantry.pos + "," + infantry.action + "," + infantry.direction + "," +
  1239. infantry.tag + "," + infantry.flag1 + "," + infantry.flag2 + "," + infantry.flag3 + "," +
  1240. infantry.flag4 + "," + infantry.flag5;
  1241. char c[50];
  1242. itoa(count, c, 10);
  1243. m_mapfile.sections["Infantry"].values[c] = value;
  1244. count++;
  1245. }
  1246. }
  1247. }
  1248. }
  1249. void CMapData::UpdateAircraft(BOOL bSave)
  1250. {
  1251. if (bSave == FALSE)
  1252. {
  1253. int i;
  1254. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1255. {
  1256. fielddata[i].aircraft = -1;
  1257. }
  1258. if (m_mapfile.sections.find("Aircraft") != m_mapfile.sections.end())
  1259. {
  1260. CIniFileSection& sec = m_mapfile.sections["Aircraft"];
  1261. for (i = 0;i < sec.values.size();i++)
  1262. {
  1263. int x = atoi(GetParam(*sec.GetValue(i), 4));
  1264. int y = atoi(GetParam(*sec.GetValue(i), 3));
  1265. int pos = x + y * GetIsoSize();
  1266. if (pos < fielddata_size) fielddata[pos].aircraft = i;
  1267. Mini_UpdatePos(x, y, IsMultiplayer());
  1268. }
  1269. }
  1270. }
  1271. }
  1272. void CMapData::UpdateStructures(BOOL bSave)
  1273. {
  1274. if (bSave == FALSE)
  1275. {
  1276. int i;
  1277. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1278. {
  1279. fielddata[i].structure = -1;
  1280. fielddata[i].structuretype = -1;
  1281. }
  1282. m_structurepaint.clear();
  1283. if (m_mapfile.sections.find("Structures") != m_mapfile.sections.end())
  1284. {
  1285. CIniFileSection& sec = m_mapfile.sections["Structures"];
  1286. for (i = 0;i < sec.values.size();i++)
  1287. {
  1288. STRUCTUREPAINT sp;
  1289. sp.col = ((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview->GetColor(GetParam(*sec.GetValue(i), 0));
  1290. sp.strength = atoi(GetParam(*sec.GetValue(i), 2));
  1291. sp.upgrade1 = GetParam(*sec.GetValue(i), 12);
  1292. sp.upgrade2 = GetParam(*sec.GetValue(i), 13);
  1293. sp.upgrade3 = GetParam(*sec.GetValue(i), 14);
  1294. sp.upradecount = atoi(GetParam(*sec.GetValue(i), 10));
  1295. sp.x = atoi(GetParam(*sec.GetValue(i), 4));
  1296. sp.y = atoi(GetParam(*sec.GetValue(i), 3));
  1297. sp.direction = atoi(GetParam(*sec.GetValue(i), 5));
  1298. sp.type = GetParam(*sec.GetValue(i), 1);
  1299. TruncSpace(sp.upgrade1);
  1300. TruncSpace(sp.upgrade2);
  1301. TruncSpace(sp.upgrade3);
  1302. m_structurepaint.push_back(sp);
  1303. int x = atoi(GetParam(*sec.GetValue(i), 4));
  1304. int y = atoi(GetParam(*sec.GetValue(i), 3));
  1305. int d, e;
  1306. int bid = buildingid[GetParam(*sec.GetValue(i), 1)];
  1307. for (d = 0;d < buildinginfo[bid].h;d++)
  1308. {
  1309. for (e = 0;e < buildinginfo[bid].w;e++)
  1310. {
  1311. int pos = (x + d) + (y + e) * GetIsoSize();
  1312. if (pos < fielddata_size)
  1313. {
  1314. fielddata[pos].structure = i;
  1315. fielddata[pos].structuretype = bid;
  1316. }
  1317. Mini_UpdatePos(x + d, y + e, IsMultiplayer());
  1318. }
  1319. }
  1320. }
  1321. }
  1322. }
  1323. }
  1324. void CMapData::UpdateTerrain(BOOL bSave, int num)
  1325. {
  1326. vector<TERRAIN>& t = m_terrain;
  1327. if (bSave == FALSE)
  1328. {
  1329. if (m_mapfile.sections.find("Terrain") == m_mapfile.sections.end() || m_mapfile.sections["Terrain"].values.size() <= 0)
  1330. return;
  1331. if (num < 0)
  1332. {
  1333. t.clear();
  1334. t.reserve(100);
  1335. int i;
  1336. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1337. {
  1338. fielddata[i].terrain = -1;
  1339. }
  1340. CIniFileSection& sec = m_mapfile.sections["Terrain"];
  1341. for (i = 0;i < sec.values.size();i++)
  1342. {
  1343. int x, y;
  1344. PosToXY(*sec.GetValueName(i), &x, &y);
  1345. // check for valid coordinates ; MW May 17th 2001
  1346. ASSERT(x >= 0 && x < GetIsoSize());
  1347. ASSERT(y >= 0 && y < GetIsoSize());
  1348. if (x < 0 || x >= GetIsoSize() || y < 0 || y >= GetIsoSize())
  1349. {
  1350. // invalid coordinates - ignore in release
  1351. }
  1352. else
  1353. {
  1354. TERRAIN td;
  1355. td.deleted = 0;
  1356. td.type = *sec.GetValue(i);
  1357. td.x = x;
  1358. td.y = y;
  1359. t.push_back(td);
  1360. int pos = x + y * GetIsoSize();
  1361. fielddata[pos].terrain = i;
  1362. fielddata[pos].terraintype = terrainid[td.type];
  1363. }
  1364. }
  1365. m_mapfile.sections.erase("Terrain");
  1366. }
  1367. }
  1368. else
  1369. {
  1370. //if(num<0)
  1371. {
  1372. //if(m_mapfile.sections.find("Terrain")!=m_mapfile.sections.end()) MessageBox(0,"Reupdate!","",0);
  1373. m_mapfile.sections.erase("Terrain");
  1374. int i;
  1375. for (i = 0;i < t.size();i++)
  1376. {
  1377. TERRAIN& td = t[i];
  1378. if (!td.deleted)
  1379. {
  1380. char j1[15];
  1381. char k1[15];
  1382. int x, y;
  1383. x = td.x;
  1384. y = td.y;
  1385. itoa(y, j1, 10);
  1386. if (strlen(j1) < 3)
  1387. {
  1388. strcpy_safe(j1 + 1, j1);
  1389. j1[0] = '0';
  1390. }
  1391. if (strlen(j1) < 3)
  1392. {
  1393. strcpy_safe(j1 + 1, j1);
  1394. j1[0] = '0';
  1395. }
  1396. itoa(x, k1, 10);
  1397. strcat(k1, j1);
  1398. m_mapfile.sections["Terrain"].values[k1] = td.type;
  1399. }
  1400. }
  1401. }
  1402. }
  1403. }
  1404. void CMapData::UpdateUnits(BOOL bSave)
  1405. {
  1406. if (bSave == FALSE)
  1407. {
  1408. int i;
  1409. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1410. {
  1411. fielddata[i].unit = -1;
  1412. }
  1413. if (m_mapfile.sections.find("Units") != m_mapfile.sections.end())
  1414. {
  1415. CIniFileSection& sec = m_mapfile.sections["Units"];
  1416. for (i = 0;i < sec.values.size();i++)
  1417. {
  1418. int x = atoi(GetParam(*sec.GetValue(i), 4));
  1419. int y = atoi(GetParam(*sec.GetValue(i), 3));
  1420. int pos = x + y * GetIsoSize();
  1421. if (pos < fielddata_size) fielddata[pos].unit = i;
  1422. Mini_UpdatePos(x, y, IsMultiplayer());
  1423. }
  1424. }
  1425. }
  1426. }
  1427. void CMapData::UpdateWaypoints(BOOL bSave)
  1428. {
  1429. if (bSave == FALSE)
  1430. {
  1431. int i;
  1432. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1433. {
  1434. fielddata[i].waypoint = -1;
  1435. }
  1436. if (m_mapfile.sections.find("Waypoints") != m_mapfile.sections.end())
  1437. {
  1438. CIniFileSection& sec = m_mapfile.sections["Waypoints"];
  1439. for (i = 0;i < sec.values.size();i++)
  1440. {
  1441. int x, y;
  1442. PosToXY(*sec.GetValue(i), &x, &y);
  1443. int pos = x + y * GetIsoSize();
  1444. if (pos < 0 || pos >= fielddata_size) continue;
  1445. fielddata[pos].waypoint = i;
  1446. int k, l;
  1447. for (k = -1;k < 2;k++)
  1448. for (l = -1;l < 2;l++)
  1449. Mini_UpdatePos(x + k, y + l, IsMultiplayer());
  1450. }
  1451. }
  1452. }
  1453. }
  1454. void CMapData::UpdateNodes(BOOL bSave)
  1455. {
  1456. if (bSave == FALSE)
  1457. {
  1458. int i;
  1459. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1460. {
  1461. fielddata[i].node.index = -1;
  1462. fielddata[i].node.type = -1;
  1463. fielddata[i].node.house = "";
  1464. }
  1465. if (m_mapfile.sections.find(MAPHOUSES) != m_mapfile.sections.end())
  1466. {
  1467. for (i = 0;i < m_mapfile.sections[MAPHOUSES].values.size();i++)
  1468. {
  1469. CIniFileSection& sec = m_mapfile.sections[*m_mapfile.sections[MAPHOUSES].GetValue(i)];
  1470. int c = atoi(sec.values["NodeCount"]);
  1471. int e;
  1472. for (e = 0;e < c;e++)
  1473. {
  1474. CString p;
  1475. GetNodeName(p, e);
  1476. CString type, sx, sy;
  1477. type = GetParam(sec.values[p], 0);
  1478. sy = GetParam(sec.values[p], 1);
  1479. sx = GetParam(sec.values[p], 2);
  1480. int x = atoi(sx);
  1481. int y = atoi(sy);
  1482. int bid = buildingid[type];
  1483. int d, f;
  1484. for (d = 0;d < buildinginfo[bid].h;d++)
  1485. {
  1486. for (f = 0;f < buildinginfo[bid].w;f++)
  1487. {
  1488. int pos = x + d + (y + f) * GetIsoSize();
  1489. fielddata[pos].node.type = buildingid[type];
  1490. fielddata[pos].node.house = *m_mapfile.sections[MAPHOUSES].GetValue(i);
  1491. fielddata[pos].node.index = e;
  1492. }
  1493. }
  1494. }
  1495. }
  1496. }
  1497. }
  1498. }
  1499. void CMapData::UpdateOverlay(BOOL bSave)
  1500. {
  1501. if (bSave == FALSE)
  1502. {
  1503. int u, v;
  1504. const bool mp = IsMultiplayer();
  1505. for (u = 0;u < GetIsoSize();u++)
  1506. {
  1507. for (v = 0;v < GetIsoSize();v++)
  1508. {
  1509. fielddata[u + v * GetIsoSize()].overlay = m_Overlay[v + u * 512];
  1510. fielddata[u + v * GetIsoSize()].overlaydata = m_OverlayData[v + u * 512];
  1511. Mini_UpdatePos(u, v, mp);
  1512. }
  1513. }
  1514. }
  1515. else
  1516. {
  1517. int u, v;
  1518. for (u = 0;u < GetIsoSize();u++)
  1519. {
  1520. for (v = 0;v < GetIsoSize();v++)
  1521. {
  1522. m_Overlay[v + u * 512] = fielddata[u + v * GetIsoSize()].overlay;
  1523. m_OverlayData[v + u * 512] = fielddata[u + v * GetIsoSize()].overlaydata;
  1524. }
  1525. }
  1526. }
  1527. m_money = CalcMoneyOnMap();
  1528. }
  1529. void CMapData::UpdateCelltags(BOOL bSave)
  1530. {
  1531. if (bSave == FALSE)
  1532. {
  1533. int i;
  1534. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  1535. {
  1536. fielddata[i].celltag = -1;
  1537. }
  1538. if (m_mapfile.sections.find("CellTags") != m_mapfile.sections.end())
  1539. {
  1540. CIniFileSection& sec = m_mapfile.sections["CellTags"];
  1541. for (i = 0;i < sec.values.size();i++)
  1542. {
  1543. int x, y;
  1544. PosToXY(*sec.GetValueName(i), &x, &y);
  1545. int pos = x + y * GetIsoSize();
  1546. if (pos < fielddata_size) fielddata[pos].celltag = i;
  1547. }
  1548. }
  1549. }
  1550. }
  1551. INT CMapData::GetNodeAt(DWORD dwPos, CString& lpHouse) const
  1552. {
  1553. lpHouse = fielddata[dwPos].node.house;
  1554. return fielddata[dwPos].node.index;
  1555. }
  1556. void CMapData::DeleteInfantry(DWORD dwIndex)
  1557. {
  1558. //if(dwIndex>=m_infantry.size()) MessageBox(0,"CMapData::DeleteInfantry(): Out of range error", "Error", 0);
  1559. if (dwIndex >= m_infantry.size()) return;
  1560. // BUG TRACING HERE, FOR THE COPY INSTEAD MOVE INFANTRY BUG!
  1561. // SOLUTION WAS IN ADDINFANTRY();
  1562. if (m_infantry[dwIndex].deleted)
  1563. {
  1564. //MessageBox(0,"CMapData::DeleteInfantry() called for infantry that already got deleted!", "Error",0);
  1565. errstream << "CMapData::DeleteInfantry() called for infantry that already got deleted! Index: " << dwIndex << endl;
  1566. errstream.flush();
  1567. }
  1568. if (m_infantry[dwIndex].deleted) return;
  1569. m_infantry[dwIndex].deleted = 1;
  1570. int x = atoi(m_infantry[dwIndex].x);
  1571. int y = atoi(m_infantry[dwIndex].y);
  1572. int pos = atoi(m_infantry[dwIndex].pos);
  1573. if (pos > 0) pos--;
  1574. if (x + y * m_IsoSize < fielddata_size) fielddata[x + y * m_IsoSize].infantry[pos] = -1;
  1575. Mini_UpdatePos(x, y, IsMultiplayer());
  1576. /*if(dwIndex>=m_mapfile.sections["Infantry"].values.size()) return;
  1577. CIniFileSection& sec=m_mapfile.sections["Infantry"];
  1578. int x=atoi(GetParam(*sec.GetValue(dwIndex),4));
  1579. int y=atoi(GetParam(*sec.GetValue(dwIndex),3));
  1580. m_mapfile.sections["Infantry"].values.erase(*m_mapfile.sections["Infantry"].GetValueName(dwIndex));
  1581. UpdateInfantry(FALSE);*/
  1582. }
  1583. void CMapData::DeleteWaypoint(DWORD dwIndex)
  1584. {
  1585. if (dwIndex >= GetWaypointCount()) return;
  1586. CString id;
  1587. DWORD pos;
  1588. Map->GetWaypointData(dwIndex, &id, &pos);
  1589. int x = pos % m_IsoSize;
  1590. int y = pos / m_IsoSize;
  1591. m_mapfile.sections["Waypoints"].values.erase(*m_mapfile.sections["Waypoints"].GetValueName(dwIndex));
  1592. if (!m_noAutoObjectUpdate) UpdateWaypoints(FALSE);
  1593. int k, l;
  1594. for (k = -1;k < 2;k++)
  1595. for (l = -1;l < 2;l++)
  1596. Mini_UpdatePos(x + k, y + l, IsMultiplayer());
  1597. }
  1598. void CMapData::DeleteCelltag(DWORD dwIndex)
  1599. {
  1600. if (dwIndex >= GetCelltagCount()) return;
  1601. m_mapfile.sections["CellTags"].values.erase(*m_mapfile.sections["CellTags"].GetValueName(dwIndex));
  1602. if (!m_noAutoObjectUpdate) UpdateCelltags(FALSE);
  1603. }
  1604. void CMapData::DeleteUnit(DWORD dwIndex)
  1605. {
  1606. if (dwIndex >= GetUnitCount()) return;
  1607. CIniFileSection& sec = m_mapfile.sections["Units"];
  1608. int x = atoi(GetParam(*sec.GetValue(dwIndex), 4));
  1609. int y = atoi(GetParam(*sec.GetValue(dwIndex), 3));
  1610. m_mapfile.sections["Units"].values.erase(*m_mapfile.sections["Units"].GetValueName(dwIndex));
  1611. if (!m_noAutoObjectUpdate) UpdateUnits(FALSE);
  1612. Mini_UpdatePos(x, y, IsMultiplayer());
  1613. }
  1614. void CMapData::DeleteStructure(DWORD dwIndex)
  1615. {
  1616. if (dwIndex >= GetStructureCount()) return;
  1617. CIniFileSection& sec = m_mapfile.sections["Structures"];
  1618. int x = atoi(GetParam(*sec.GetValue(dwIndex), 4));
  1619. int y = atoi(GetParam(*sec.GetValue(dwIndex), 3));
  1620. CString type = GetParam(*sec.GetValue(dwIndex), 1);
  1621. m_mapfile.sections["Structures"].values.erase(*m_mapfile.sections["Structures"].GetValueName(dwIndex));
  1622. if (!m_noAutoObjectUpdate) UpdateStructures(FALSE);
  1623. int d, e;
  1624. int bid = buildingid[type];
  1625. for (d = 0;d < buildinginfo[bid].h;d++)
  1626. {
  1627. for (e = 0;e < buildinginfo[bid].w;e++)
  1628. {
  1629. int pos = (x + d) + (y + e) * GetIsoSize();
  1630. Mini_UpdatePos(x + d, y + e, IsMultiplayer());
  1631. }
  1632. }
  1633. }
  1634. void CMapData::DeleteAircraft(DWORD dwIndex)
  1635. {
  1636. if (dwIndex >= GetAircraftCount()) return;
  1637. CIniFileSection& sec = m_mapfile.sections["Aircraft"];
  1638. int x = atoi(GetParam(*sec.GetValue(dwIndex), 4));
  1639. int y = atoi(GetParam(*sec.GetValue(dwIndex), 3));
  1640. m_mapfile.sections["Aircraft"].values.erase(*m_mapfile.sections["Aircraft"].GetValueName(dwIndex));
  1641. if (!m_noAutoObjectUpdate) UpdateAircraft(FALSE);
  1642. Mini_UpdatePos(x, y, IsMultiplayer());
  1643. }
  1644. void CMapData::DeleteTerrain(DWORD dwIndex)
  1645. {
  1646. /* March 23th 2001: MW: Rewrote code, much faster */
  1647. if (dwIndex >= GetTerrainCount()) return;
  1648. if (m_terrain[dwIndex].deleted) return;
  1649. //UpdateTerrain(FALSE);
  1650. // replacement of slow UpdateTerrain():
  1651. //CString valuename=*m_mapfile.sections["Terrain"].GetValueName(dwIndex);
  1652. int x, y;
  1653. //PosToXY(valuename, &x, &y);
  1654. //m_mapfile.sections["Terrain"].values.erase(valuename);
  1655. x = m_terrain[dwIndex].x;
  1656. y = m_terrain[dwIndex].y;
  1657. m_terrain[dwIndex].deleted = 1;
  1658. int pos = x + y * GetIsoSize();
  1659. if (x + y * m_IsoSize < fielddata_size)
  1660. {
  1661. fielddata[pos].terrain = -1;
  1662. fielddata[pos].terraintype = -1;
  1663. }
  1664. }
  1665. void CMapData::DeleteNode(LPCTSTR lpHouse, DWORD dwIndex)
  1666. {
  1667. CString p; // p is last node
  1668. GetNodeName(p, atoi(m_mapfile.sections[lpHouse].values["NodeCount"]) - 1);
  1669. char c[50];
  1670. itoa(atoi(m_mapfile.sections[lpHouse].values["NodeCount"]) - 1, c, 10);
  1671. int i;
  1672. for (i = dwIndex;i < atoi(m_mapfile.sections[lpHouse].values["NodeCount"]) - 1;i++)
  1673. {
  1674. CString d1, d2;
  1675. GetNodeName(d1, i);
  1676. GetNodeName(d2, i + 1);
  1677. m_mapfile.sections[lpHouse].values[d1] = m_mapfile.sections[lpHouse].values[d2];
  1678. }
  1679. m_mapfile.sections[lpHouse].values.erase(p);
  1680. m_mapfile.sections[lpHouse].values["NodeCount"] = c;
  1681. UpdateNodes(FALSE);
  1682. }
  1683. BOOL CMapData::AddWaypoint(CString lpID, DWORD dwPos)
  1684. {
  1685. // create waypoint, auto number
  1686. CString id = lpID;
  1687. if (lpID.GetLength() == 0) id = GetFree("Waypoints");
  1688. char j[15];
  1689. char k[15];
  1690. memset(j, 0, 15);
  1691. memset(k, 0, 15);
  1692. itoa(dwPos / GetIsoSize(), j, 10);
  1693. if (strlen(j) < 3)
  1694. {
  1695. strcpy_safe(j + 1, j);
  1696. j[0] = '0';
  1697. }
  1698. if (strlen(j) < 3)
  1699. {
  1700. strcpy_safe(j + 1, j);
  1701. j[0] = '0';
  1702. }
  1703. itoa(dwPos % GetIsoSize(), k, 10);
  1704. strcat(k, j);
  1705. //MessageBox(0,k,"",0);
  1706. m_mapfile.sections["Waypoints"].values[id] = k;
  1707. if (!m_noAutoObjectUpdate) UpdateWaypoints(FALSE);
  1708. return TRUE;
  1709. }
  1710. void CMapData::GetStructureData(DWORD dwIndex, STRUCTURE* lpStructure) const
  1711. {
  1712. const auto section = m_mapfile.GetSection("Structures");
  1713. if (!section || dwIndex >= section->values.size())
  1714. return;
  1715. CString data = *section->GetValue(dwIndex);
  1716. lpStructure->house = GetParam(data, 0);
  1717. lpStructure->type = GetParam(data, 1);
  1718. lpStructure->strength = GetParam(data, 2);
  1719. lpStructure->y = GetParam(data, 3);
  1720. lpStructure->x = GetParam(data, 4);
  1721. lpStructure->direction = GetParam(data, 5);
  1722. lpStructure->tag = GetParam(data, 6);
  1723. lpStructure->flag1 = GetParam(data, 7);
  1724. lpStructure->flag2 = GetParam(data, 8);
  1725. lpStructure->energy = GetParam(data, 9);
  1726. lpStructure->upgradecount = GetParam(data, 10);
  1727. lpStructure->spotlight = GetParam(data, 11);
  1728. lpStructure->upgrade1 = GetParam(data, 12);
  1729. lpStructure->upgrade2 = GetParam(data, 13);
  1730. lpStructure->upgrade3 = GetParam(data, 14);
  1731. lpStructure->flag3 = GetParam(data, 15);
  1732. lpStructure->flag4 = GetParam(data, 16);
  1733. }
  1734. void CMapData::GetStdStructureData(DWORD dwIndex, STDOBJECTDATA* lpStdStructure) const
  1735. {
  1736. const auto section = m_mapfile.GetSection("Structures");
  1737. if (!section || dwIndex >= section->values.size())
  1738. return;
  1739. CString data = *section->GetValue(dwIndex);
  1740. lpStdStructure->house = GetParam(data, 0);
  1741. lpStdStructure->type = GetParam(data, 1);
  1742. lpStdStructure->strength = GetParam(data, 2);
  1743. lpStdStructure->y = GetParam(data, 3);
  1744. lpStdStructure->x = GetParam(data, 4);
  1745. }
  1746. BOOL CMapData::AddNode(NODE* lpNode, WORD dwPos)
  1747. {
  1748. NODE node;
  1749. if (lpNode != NULL)
  1750. {
  1751. node = *lpNode;
  1752. }
  1753. else
  1754. {
  1755. node.x.Format("%d", dwPos % Map->GetIsoSize());
  1756. node.y.Format("%d", dwPos / Map->GetIsoSize());
  1757. node.house = GetHouseID(0);
  1758. node.type = *rules.sections["BuildingTypes"].GetValue(0);
  1759. }
  1760. if (m_mapfile.sections.find(HOUSES) == m_mapfile.sections.end() || m_mapfile.sections[HOUSES].values.size() == 0)
  1761. {
  1762. return FALSE;
  1763. }
  1764. int c = atoi(m_mapfile.sections[(LPCTSTR)node.house].values["NodeCount"]);
  1765. c++;
  1766. char sc[50];
  1767. itoa(c, sc, 10);
  1768. m_mapfile.sections[(LPCTSTR)node.house].values["NodeCount"] = sc;
  1769. c--;
  1770. CString p;
  1771. GetNodeName(p, c);
  1772. m_mapfile.sections[(LPCTSTR)node.house].values[p] = node.type;
  1773. m_mapfile.sections[(LPCTSTR)node.house].values[p] += ",";
  1774. m_mapfile.sections[(LPCTSTR)node.house].values[p] += node.y;
  1775. m_mapfile.sections[(LPCTSTR)node.house].values[p] += ",";
  1776. m_mapfile.sections[(LPCTSTR)node.house].values[p] += node.x;
  1777. UpdateNodes(FALSE);
  1778. return TRUE;
  1779. }
  1780. BOOL CMapData::AddInfantry(INFANTRY* lpInfantry, LPCTSTR lpType, LPCTSTR lpHouse, DWORD dwPos, int suggestedIndex)
  1781. {
  1782. INFANTRY infantry;
  1783. if (lpInfantry != NULL)
  1784. {
  1785. infantry = *lpInfantry;
  1786. dwPos = atoi(infantry.x) + atoi(infantry.y) * Map->GetIsoSize();
  1787. // MW Bugfix: not checking if infantry.pos does already exist caused crashes with user scripts!
  1788. if (GetInfantryAt(dwPos, atoi(infantry.pos)) >= 0)
  1789. infantry.pos = "-1";
  1790. }
  1791. else
  1792. {
  1793. char cx[10], cy[10];
  1794. itoa(dwPos % Map->GetIsoSize(), cx, 10);
  1795. itoa(dwPos / Map->GetIsoSize(), cy, 10);
  1796. infantry.action = "Guard";
  1797. infantry.tag = "None";
  1798. infantry.direction = "64";
  1799. infantry.flag1 = "0";
  1800. infantry.flag2 = "-1";
  1801. infantry.flag3 = "0";
  1802. infantry.flag4 = "1";
  1803. infantry.flag5 = "0";
  1804. infantry.strength = "256";
  1805. infantry.house = lpHouse;
  1806. infantry.pos = "-1";
  1807. infantry.type = lpType;
  1808. infantry.x = cx;
  1809. infantry.y = cy;
  1810. }
  1811. if (infantry.pos == "-1")
  1812. {
  1813. int subpos = -1;
  1814. int i;
  1815. if (GetInfantryCountAt(dwPos) == 0)
  1816. subpos = 0;
  1817. else
  1818. {
  1819. int oldInf = GetInfantryAt(dwPos, 0);
  1820. if (oldInf > -1)
  1821. {
  1822. INFANTRY inf;
  1823. GetInfantryData(oldInf, &inf);
  1824. if (inf.pos == "0")
  1825. for (i = 1;i < SUBPOS_COUNT;i++)
  1826. {
  1827. if (GetInfantryAt(dwPos, i) == -1)
  1828. {
  1829. //subpos=i+1;
  1830. char c[50];
  1831. itoa(i, c, 10);
  1832. inf.pos = c;
  1833. DeleteInfantry(oldInf);
  1834. AddInfantry(&inf);
  1835. break;
  1836. }
  1837. }
  1838. }
  1839. // if(GetInfantryAt(dwPos, 0)==oldInf) return FALSE;
  1840. for (i = 0;i < SUBPOS_COUNT;i++)
  1841. {
  1842. if (GetInfantryAt(dwPos, i) == -1)
  1843. {
  1844. subpos = i + 1;
  1845. break;
  1846. }
  1847. }
  1848. }
  1849. if (subpos < 0) return FALSE;
  1850. char c[50];
  1851. itoa(subpos, c, 10);
  1852. infantry.pos = c;
  1853. }
  1854. /*
  1855. CString id=GetFree("Infantry");
  1856. CString value;
  1857. value=infantry.house+","+infantry.type+","+infantry.strength+","+infantry.y+
  1858. ","+infantry.x+","+infantry.pos+","+infantry.action+","+infantry.direction+","+
  1859. infantry.tag+","+infantry.flag1+","+infantry.flag2+","+infantry.flag3+","+
  1860. infantry.flag4+","+infantry.flag5;
  1861. m_mapfile.sections["Infantry"].values[id]=(LPCTSTR)value;
  1862. UpdateInfantry(FALSE);
  1863. */
  1864. infantry.deleted = 0;
  1865. /* This code just pushed it back to the end, caused some trouble (and used memory)
  1866. m_infantry.push_back(infantry);
  1867. int sp=atoi(infantry.pos);
  1868. if(sp>0) sp--;
  1869. int pos=dwPos;
  1870. fielddata[pos].infantry[sp]=m_infantry.size()-1;
  1871. */
  1872. // below code should be much more compatible to the very old code (the direct ini one)
  1873. int sp = atoi(infantry.pos);
  1874. if (sp > 0) sp--;
  1875. int i;
  1876. BOOL bFound = FALSE;
  1877. if (suggestedIndex >= 0 && suggestedIndex < m_infantry.size())
  1878. {
  1879. if (m_infantry[suggestedIndex].deleted)
  1880. {
  1881. m_infantry[suggestedIndex] = infantry;
  1882. if (dwPos < fielddata_size) fielddata[dwPos].infantry[sp] = suggestedIndex;
  1883. bFound = TRUE;
  1884. }
  1885. }
  1886. if (!bFound)
  1887. for (i = 0;i < m_infantry.size();i++)
  1888. {
  1889. if (m_infantry[i].deleted) // yep, found one, replace it
  1890. {
  1891. m_infantry[i] = infantry;
  1892. if (dwPos < fielddata_size) fielddata[dwPos].infantry[sp] = i;
  1893. bFound = TRUE;
  1894. break;
  1895. }
  1896. }
  1897. if (!bFound)
  1898. {
  1899. m_infantry.push_back(infantry);
  1900. if (dwPos < fielddata_size) fielddata[dwPos].infantry[sp] = m_infantry.size() - 1;
  1901. }
  1902. return TRUE;
  1903. }
  1904. BOOL CMapData::AddStructure(STRUCTURE* lpStructure, LPCTSTR lpType, LPCTSTR lpHouse, DWORD dwPos, CString suggestedID)
  1905. {
  1906. STRUCTURE structure;
  1907. if (lpStructure != NULL)
  1908. {
  1909. structure = *lpStructure;
  1910. }
  1911. else
  1912. {
  1913. char cx[10], cy[10];
  1914. itoa(dwPos % Map->GetIsoSize(), cx, 10);
  1915. itoa(dwPos / Map->GetIsoSize(), cy, 10);
  1916. structure.tag = "None";
  1917. structure.direction = "64";
  1918. structure.flag1 = "1";
  1919. structure.flag2 = "0";
  1920. structure.spotlight = "0";
  1921. structure.flag3 = "0";
  1922. structure.flag4 = "0";
  1923. structure.energy = "1";
  1924. structure.upgrade1 = "None";
  1925. structure.upgrade2 = "None";
  1926. structure.upgrade3 = "None";
  1927. structure.upgradecount = "0";
  1928. structure.strength = "256";
  1929. structure.house = lpHouse;
  1930. structure.type = lpType;
  1931. structure.x = cx;
  1932. structure.y = cy;
  1933. }
  1934. CString id = GetFree("Structures");
  1935. if (suggestedID.GetLength() > 0)
  1936. {
  1937. if (m_mapfile.sections["Structures"].values.find(suggestedID) == m_mapfile.sections["Structures"].values.end())
  1938. id = suggestedID;
  1939. }
  1940. CString value;
  1941. value = structure.house + "," + structure.type + "," + structure.strength + "," + structure.y +
  1942. "," + structure.x + "," + structure.direction + "," + structure.tag + "," + structure.flag1 + "," +
  1943. structure.flag2 + "," + structure.energy + "," + structure.upgradecount + "," + structure.spotlight + ","
  1944. + structure.upgrade1 + "," + structure.upgrade2 + "," + structure.upgrade3 + "," + structure.flag3 + "," + structure.flag4;
  1945. m_mapfile.sections["Structures"].values[id] = (LPCTSTR)value;
  1946. if (!m_noAutoObjectUpdate) UpdateStructures(FALSE);
  1947. return TRUE;
  1948. }
  1949. void CMapData::InitializeUnitTypes()
  1950. {
  1951. buildingid.clear();
  1952. terrainid.clear();
  1953. int i;
  1954. m_overlayCredits[OverlayCredits_Riparius] = atoi(m_mapfile.GetValueByName("Riparius", "Value", rules.sections["Riparius"].AccessValueByName("Value")));
  1955. m_overlayCredits[OverlayCredits_Cruentus] = atoi(m_mapfile.GetValueByName("Cruentus", "Value", rules.sections["Cruentus"].AccessValueByName("Value")));
  1956. m_overlayCredits[OverlayCredits_Vinifera] = atoi(m_mapfile.GetValueByName("Vinifera", "Value", rules.sections["Vinifera"].AccessValueByName("Value")));
  1957. m_overlayCredits[OverlayCredits_Aboreus] = atoi(m_mapfile.GetValueByName("Aboreus", "Value", rules.sections["Aboreus"].AccessValueByName("Value")));
  1958. for (i = 0;i < rules.sections["BuildingTypes"].values.size();i++)
  1959. {
  1960. CString type = *rules.sections["BuildingTypes"].GetValue(i);
  1961. int n = GetBuildingNumber(type);
  1962. buildingid[type] = n;
  1963. }
  1964. for (i = 0;i < m_mapfile.sections["BuildingTypes"].values.size();i++)
  1965. {
  1966. CString type = *m_mapfile.sections["BuildingTypes"].GetValue(i);
  1967. int n = GetBuildingNumber(type);
  1968. buildingid[type] = n;
  1969. }
  1970. for (i = 0;i < rules.sections["TerrainTypes"].values.size();i++)
  1971. {
  1972. CString type = *rules.sections["TerrainTypes"].GetValue(i);
  1973. int n = GetTerrainNumber(type);
  1974. terrainid[type] = n;
  1975. }
  1976. for (i = 0;i < m_mapfile.sections["TerrainTypes"].values.size();i++)
  1977. {
  1978. CString type = *m_mapfile.sections["TerrainTypes"].GetValue(i);
  1979. int n = GetTerrainNumber(type);
  1980. terrainid[type] = n;
  1981. }
  1982. #ifdef SMUDGE_SUPP
  1983. for (i = 0;i < rules.sections["SmudgeTypes"].values.size();i++)
  1984. {
  1985. CString type = *rules.sections["SmudgeTypes"].GetValue(i);
  1986. int n = GetSmudgeNumber(type);
  1987. smudgeid[type] = n;
  1988. }
  1989. for (i = 0;i < m_mapfile.sections["SmudgeTypes"].values.size();i++)
  1990. {
  1991. CString type = *m_mapfile.sections["SmudgeTypes"].GetValue(i);
  1992. int n = GetSmudgeNumber(type);
  1993. smudgeid[type] = n;
  1994. }
  1995. #endif
  1996. }
  1997. INT CMapData::GetUnitTypeID(LPCTSTR lpType)
  1998. {
  1999. // we only support building types, terrain types and smudge types at the moment
  2000. if (buildingid.find(lpType) != buildingid.end()) return buildingid[lpType];
  2001. if (terrainid.find(lpType) != terrainid.end()) return terrainid[lpType];
  2002. #ifdef SMUDGE_SUPP
  2003. if (smudgeid.find(lpType) != smudgeid.end()) return smudgeid[lpType];
  2004. #endif
  2005. return 0;
  2006. }
  2007. void CMapData::GetStdInfantryData(DWORD dwIndex, STDOBJECTDATA* lpStdInfantry) const
  2008. {
  2009. /*CString data=*m_mapfile.sections["Infantry"].GetValue(dwIndex);
  2010. lpStdInfantry->house=GetParam(data, 0);
  2011. lpStdInfantry->type=GetParam(data, 1);
  2012. lpStdInfantry->strength=atoi(GetParam(data, 2));
  2013. lpStdInfantry->y=GetParam(data, 3);
  2014. lpStdInfantry->x=atoi(GetParam(data, 4));*/
  2015. lpStdInfantry->house = m_infantry[dwIndex].house;
  2016. lpStdInfantry->type = m_infantry[dwIndex].type;
  2017. lpStdInfantry->strength = m_infantry[dwIndex].strength;
  2018. lpStdInfantry->y = m_infantry[dwIndex].y;
  2019. lpStdInfantry->x = m_infantry[dwIndex].x;
  2020. }
  2021. void CMapData::GetInfantryData(DWORD dwIndex, INFANTRY* lpInfantry) const
  2022. {
  2023. ASSERT(dwIndex < m_infantry.size());
  2024. if (dwIndex >= m_infantry.size()) return;
  2025. /*lpInfantry->house=m_infantry.house;
  2026. lpInfantry->type=m_infantry.;
  2027. lpInfantry->strength=m_infantry.;
  2028. lpInfantry->y=m_infantry.;
  2029. lpInfantry->x=m_infantry.;
  2030. lpInfantry->pos=m_infantry.;
  2031. lpInfantry->action=m_infantry.;
  2032. lpInfantry->direction=m_infantry.;
  2033. lpInfantry->tag=m_infantry.;
  2034. lpInfantry->flag1=m_infantry.;
  2035. lpInfantry->flag2=m_infantry.;
  2036. lpInfantry->flag3=m_infantry.;
  2037. lpInfantry->flag4=m_infantry.;
  2038. lpInfantry->flag5=m_infantry.;*/
  2039. *lpInfantry = m_infantry[dwIndex];
  2040. //memcpy(lpInfantry, &m_infantry[dwIndex], sizeof(INFANTRY));
  2041. //ASSERT(dwIndex>=0 && dwIndex<m_mapfile.sections["Infantry"].values.size());
  2042. /*if(dwIndex>=m_mapfile.sections["Infantry"].values.size()) return;
  2043. CString data=*m_mapfile.sections["Infantry"].GetValue(dwIndex);
  2044. lpInfantry->house=GetParam(data, 0);
  2045. lpInfantry->type=GetParam(data, 1);
  2046. lpInfantry->strength=GetParam(data, 2);
  2047. lpInfantry->y=GetParam(data, 3);
  2048. lpInfantry->x=GetParam(data, 4);
  2049. lpInfantry->pos=GetParam(data, 5);
  2050. lpInfantry->action=GetParam(data, 6);
  2051. lpInfantry->direction=GetParam(data, 7);
  2052. lpInfantry->tag=GetParam(data, 8);
  2053. lpInfantry->flag1=GetParam(data, 9);
  2054. lpInfantry->flag2=GetParam(data, 10);
  2055. lpInfantry->flag3=GetParam(data, 11);
  2056. lpInfantry->flag4=GetParam(data, 12);
  2057. lpInfantry->flag5=GetParam(data, 13);*/
  2058. }
  2059. void CMapData::GetUnitData(DWORD dwIndex, UNIT* lpUnit) const
  2060. {
  2061. const auto section = m_mapfile.GetSection("Units");
  2062. if (!section || dwIndex >= section->values.size())
  2063. return;
  2064. CString data = *section->GetValue(dwIndex);
  2065. lpUnit->house = GetParam(data, 0);
  2066. lpUnit->type = GetParam(data, 1);
  2067. lpUnit->strength = GetParam(data, 2);
  2068. lpUnit->y = GetParam(data, 3);
  2069. lpUnit->x = GetParam(data, 4);
  2070. lpUnit->direction = GetParam(data, 5);
  2071. lpUnit->action = GetParam(data, 6);
  2072. lpUnit->tag = GetParam(data, 7);
  2073. lpUnit->flag1 = GetParam(data, 8);
  2074. lpUnit->flag2 = GetParam(data, 9);
  2075. lpUnit->flag3 = GetParam(data, 10);
  2076. lpUnit->flag4 = GetParam(data, 11);
  2077. lpUnit->flag5 = GetParam(data, 12);
  2078. lpUnit->flag6 = GetParam(data, 13);
  2079. }
  2080. void CMapData::GetAircraftData(DWORD dwIndex, AIRCRAFT* lpAircraft) const
  2081. {
  2082. const auto section = m_mapfile.GetSection("Aircraft");
  2083. if (!section || dwIndex >= section->values.size())
  2084. return;
  2085. CString data = *section->GetValue(dwIndex);
  2086. lpAircraft->house = GetParam(data, 0);
  2087. lpAircraft->type = GetParam(data, 1);
  2088. lpAircraft->strength = GetParam(data, 2);
  2089. lpAircraft->y = GetParam(data, 3);
  2090. lpAircraft->x = GetParam(data, 4);
  2091. lpAircraft->direction = GetParam(data, 5);
  2092. lpAircraft->action = GetParam(data, 6);
  2093. lpAircraft->tag = GetParam(data, 7);
  2094. lpAircraft->flag1 = GetParam(data, 8);
  2095. lpAircraft->flag2 = GetParam(data, 9);
  2096. lpAircraft->flag3 = GetParam(data, 10);
  2097. lpAircraft->flag4 = GetParam(data, 11);
  2098. }
  2099. BOOL CMapData::AddCelltag(LPCTSTR lpTag, DWORD dwPos)
  2100. {
  2101. char j[15];
  2102. char k[15];
  2103. memset(j, 0, 15);
  2104. memset(k, 0, 15);
  2105. itoa(dwPos / GetIsoSize(), j, 10);
  2106. if (strlen(j) < 3)
  2107. {
  2108. strcpy_safe(j + 1, j);
  2109. j[0] = '0';
  2110. }
  2111. if (strlen(j) < 3)
  2112. {
  2113. strcpy_safe(j + 1, j);
  2114. j[0] = '0';
  2115. }
  2116. itoa(dwPos % GetIsoSize(), k, 10);
  2117. strcat(k, j);
  2118. m_mapfile.sections["CellTags"].values[k] = lpTag;
  2119. if (!m_noAutoObjectUpdate) UpdateCelltags(FALSE);
  2120. return TRUE;
  2121. }
  2122. void CMapData::GetCelltagData(DWORD dwIndex, CString* lpTag, DWORD* lpdwPos) const
  2123. {
  2124. const auto section = m_mapfile.GetSection("CellTags");
  2125. if (!section || dwIndex >= section->values.size())
  2126. return;
  2127. int x, y;
  2128. CString pos;
  2129. pos = *section->GetValueName(dwIndex);
  2130. PosToXY(pos, &x, &y);
  2131. const auto tag = section->GetValueByName(pos);
  2132. *lpTag = tag;
  2133. *lpdwPos = x + y * GetIsoSize();
  2134. }
  2135. BOOL CMapData::AddAircraft(AIRCRAFT* lpAircraft, LPCTSTR lpType, LPCTSTR lpHouse, DWORD dwPos, CString suggestedID)
  2136. {
  2137. AIRCRAFT aircraft;
  2138. if (lpAircraft != NULL)
  2139. {
  2140. aircraft = *lpAircraft;
  2141. }
  2142. else
  2143. {
  2144. char sx[15], sy[15];
  2145. itoa(dwPos % GetIsoSize(), sx, 10);
  2146. itoa(dwPos / GetIsoSize(), sy, 10);
  2147. aircraft.type = lpType;
  2148. aircraft.house = lpHouse;
  2149. aircraft.action = "Guard";
  2150. aircraft.tag = "None";
  2151. aircraft.direction = "64";
  2152. aircraft.strength = "256";
  2153. aircraft.x = sx;
  2154. aircraft.y = sy;
  2155. aircraft.flag1 = "0";
  2156. aircraft.flag2 = "0";
  2157. aircraft.flag3 = "1";
  2158. aircraft.flag4 = "0";
  2159. }
  2160. CString id = GetFree("Aircraft");
  2161. if (suggestedID.GetLength() > 0)
  2162. {
  2163. if (m_mapfile.sections["Aircraft"].values.find(suggestedID) == m_mapfile.sections["Aircraft"].values.end())
  2164. id = suggestedID;
  2165. }
  2166. CString value;
  2167. value = aircraft.house + "," + aircraft.type + "," + aircraft.strength + "," + aircraft.y + "," +
  2168. aircraft.x + "," + aircraft.direction + "," + aircraft.action + "," + aircraft.tag + ","
  2169. + aircraft.flag1 + "," + aircraft.flag2 + "," + aircraft.flag3 + "," + aircraft.flag4;
  2170. m_mapfile.sections["Aircraft"].values[id] = value;
  2171. if (!m_noAutoObjectUpdate) UpdateAircraft(FALSE);
  2172. return TRUE;
  2173. }
  2174. BOOL CMapData::AddUnit(UNIT* lpUnit, LPCTSTR lpType, LPCTSTR lpHouse, DWORD dwPos, CString suggestedID)
  2175. {
  2176. UNIT unit;
  2177. if (lpUnit != NULL)
  2178. {
  2179. unit = *lpUnit;
  2180. }
  2181. else
  2182. {
  2183. char sx[15], sy[15];
  2184. itoa(dwPos % GetIsoSize(), sx, 10);
  2185. itoa(dwPos / GetIsoSize(), sy, 10);
  2186. unit.type = lpType;
  2187. unit.house = lpHouse;
  2188. unit.action = "Guard";
  2189. unit.tag = "None";
  2190. unit.direction = "64";
  2191. unit.strength = "256";
  2192. unit.x = sx;
  2193. unit.y = sy;
  2194. unit.flag1 = "0";
  2195. unit.flag2 = "-1";
  2196. unit.flag3 = "0";
  2197. unit.flag4 = "-1";
  2198. unit.flag5 = "1";
  2199. unit.flag6 = "0";
  2200. }
  2201. CString id = GetFree("Units");
  2202. if (suggestedID.GetLength() > 0)
  2203. {
  2204. if (m_mapfile.sections["Units"].values.find(suggestedID) == m_mapfile.sections["Units"].values.end())
  2205. id = suggestedID;
  2206. }
  2207. CString value;
  2208. value = unit.house + "," + unit.type + "," + unit.strength + "," + unit.y + "," +
  2209. unit.x + "," + unit.direction + "," + unit.action + "," + unit.tag + ","
  2210. + unit.flag1 + "," + unit.flag2 + "," + unit.flag3 + "," + unit.flag4 + "," + unit.flag5 + "," + unit.flag6;
  2211. m_mapfile.sections["Units"].values[id] = value;
  2212. if (!m_noAutoObjectUpdate) UpdateUnits(FALSE);
  2213. return TRUE;
  2214. }
  2215. void CMapData::GetTerrainData(DWORD dwIndex, CString* lpType) const
  2216. {
  2217. ASSERT(m_terrain.size() > dwIndex);
  2218. /* if(m_mapfile.sections["Terrain"].values.size()<=dwIndex)
  2219. {
  2220. errstream << "GetTerrainData() fails..." << endl;
  2221. errstream.flush();
  2222. *lpType="";
  2223. return;
  2224. }*/
  2225. *lpType = m_terrain[dwIndex].type;//*m_mapfile.sections["Terrain"].GetValue(dwIndex);
  2226. }
  2227. // MW New for script interpreter:
  2228. void CMapData::GetTerrainData(DWORD dwIndex, TERRAIN* lpType) const
  2229. {
  2230. ASSERT(m_terrain.size() > dwIndex);
  2231. *lpType = m_terrain[dwIndex];
  2232. }
  2233. BOOL CMapData::AddTerrain(LPCTSTR lpType, DWORD dwPos, int suggestedIndex)
  2234. {
  2235. /*char j1[15];
  2236. char k1[15];*/
  2237. int x, y;
  2238. x = dwPos % GetIsoSize();
  2239. y = dwPos / GetIsoSize();
  2240. /*itoa(y, j1, 10);
  2241. if(strlen(j1)<3)
  2242. {
  2243. strcpy_safe(j1+1, j1);
  2244. j1[0]='0';
  2245. }
  2246. if(strlen(j1)<3)
  2247. {
  2248. strcpy_safe(j1+1, j1);
  2249. j1[0]='0';
  2250. }
  2251. itoa(x, k1, 10);
  2252. strcat(k1, j1);*/
  2253. /*
  2254. March 23th, 2001: Replaced slow UpdateTerrain() call with direct modification:
  2255. */
  2256. TERRAIN td;
  2257. td.deleted = 0;
  2258. td.type = lpType;
  2259. td.x = x;
  2260. td.y = y;
  2261. if (terrainid.find(td.type) == terrainid.end()) return FALSE;
  2262. BOOL bFound = FALSE;
  2263. if (suggestedIndex >= 0 && suggestedIndex < m_terrain.size())
  2264. {
  2265. if (m_terrain[suggestedIndex].deleted)
  2266. {
  2267. m_terrain[suggestedIndex] = td;
  2268. if (dwPos < fielddata_size)
  2269. {
  2270. fielddata[dwPos].terrain = suggestedIndex;
  2271. fielddata[dwPos].terraintype = terrainid[lpType];
  2272. }
  2273. bFound = TRUE;
  2274. }
  2275. }
  2276. int i;
  2277. if (!bFound)
  2278. for (i = 0;i < m_terrain.size();i++)
  2279. {
  2280. if (m_terrain[i].deleted) // yep, found one, replace it
  2281. {
  2282. m_terrain[i] = td;
  2283. if (dwPos < fielddata_size)
  2284. {
  2285. fielddata[dwPos].terrain = i;
  2286. fielddata[dwPos].terraintype = terrainid[lpType];
  2287. }
  2288. bFound = TRUE;
  2289. break;
  2290. }
  2291. }
  2292. if (!bFound)
  2293. {
  2294. m_terrain.push_back(td);
  2295. int pos = x + y * GetIsoSize();
  2296. if (pos < fielddata_size)
  2297. {
  2298. fielddata[pos].terrain = m_terrain.size() - 1;
  2299. fielddata[pos].terraintype = terrainid[lpType];
  2300. }
  2301. }
  2302. //UpdateTerrain();
  2303. return TRUE;
  2304. }
  2305. BOOL CMapData::IsGroundObjectAt(DWORD dwPos) const
  2306. {
  2307. int m_id = 0;
  2308. m_id = GetInfantryAt(dwPos);
  2309. if (m_id < 0)
  2310. m_id = GetUnitAt(dwPos);
  2311. if (m_id < 0)
  2312. m_id = GetAirAt(dwPos);
  2313. if (m_id < 0)
  2314. m_id = GetStructureAt(dwPos);
  2315. if (m_id < 0)
  2316. m_id = GetTerrainAt(dwPos);
  2317. if (m_id < 0) return FALSE;
  2318. return TRUE;
  2319. }
  2320. void CMapData::GetWaypointData(DWORD dwIndex, CString* lpID, DWORD* lpdwPos) const
  2321. {
  2322. if (lpID) *lpID = "";
  2323. if (lpdwPos) *lpdwPos = 0;
  2324. const auto section = m_mapfile.GetSection("Waypoints");
  2325. if (!section || dwIndex >= section->values.size())
  2326. return;
  2327. CString data = *section->GetValue(dwIndex);
  2328. int x, y;
  2329. PosToXY(data, &x, &y);
  2330. if (lpID) *lpID = *section->GetValueName(dwIndex);
  2331. if (lpdwPos) *lpdwPos = x + y * GetIsoSize();
  2332. }
  2333. void CMapData::GetStdAircraftData(DWORD dwIndex, STDOBJECTDATA* lpStdAircraft) const
  2334. {
  2335. const auto section = m_mapfile.GetSection("Aircraft");
  2336. if (!section || dwIndex >= section->values.size())
  2337. return;
  2338. CString data = *section->GetValue(dwIndex);
  2339. lpStdAircraft->house = GetParam(data, 0);
  2340. lpStdAircraft->type = GetParam(data, 1);
  2341. lpStdAircraft->strength.Format("%d", atoi(GetParam(data, 2)));
  2342. lpStdAircraft->y = GetParam(data, 3);
  2343. lpStdAircraft->x.Format("%d", atoi(GetParam(data, 4)));
  2344. }
  2345. void CMapData::GetStdUnitData(DWORD dwIndex, STDOBJECTDATA* lpStdUnit) const
  2346. {
  2347. const auto section = m_mapfile.GetSection("Units");
  2348. if (!section || dwIndex >= section->values.size())
  2349. return;
  2350. CString data = *section->GetValue(dwIndex);
  2351. lpStdUnit->house = GetParam(data, 0);
  2352. lpStdUnit->type = GetParam(data, 1);
  2353. lpStdUnit->strength.Format("%d", atoi(GetParam(data, 2)));
  2354. lpStdUnit->y = GetParam(data, 3);
  2355. lpStdUnit->x.Format("%d", atoi(GetParam(data, 4)));
  2356. }
  2357. DWORD CMapData::GetInfantryCount() const
  2358. {
  2359. return m_infantry.size();//m_mapfile.sections["Infantry"].values.size();
  2360. }
  2361. DWORD CMapData::GetUnitCount() const
  2362. {
  2363. const auto section = m_mapfile.GetSection("Units");
  2364. return section ? section->values.size() : 0;
  2365. }
  2366. DWORD CMapData::GetStructureCount() const
  2367. {
  2368. const auto section = m_mapfile.GetSection("Structures");
  2369. return section ? section->values.size() : 0;
  2370. }
  2371. DWORD CMapData::GetAircraftCount() const
  2372. {
  2373. const auto section = m_mapfile.GetSection("Aircraft");
  2374. return section ? section->values.size() : 0;
  2375. }
  2376. DWORD CMapData::GetTerrainCount() const
  2377. {
  2378. return m_terrain.size();//m_mapfile.sections["Terrain"].values.size();
  2379. }
  2380. /*
  2381. CString CMapData::GetUnitName(LPCTSTR lpID);
  2382. Returns the name of the unit identified with the ID lpID.
  2383. Note: takes care of the current mapfile settings
  2384. */
  2385. WCHAR unknown[] = L"MISSING";
  2386. WCHAR* CMapData::GetUnitName(LPCTSTR lpID) const
  2387. {
  2388. WCHAR* res = NULL;
  2389. if (g_data.sections["Rename"].FindName(lpID) >= 0)
  2390. {
  2391. CCStrings[lpID].SetString((LPSTR)(LPCSTR)GetLanguageStringACP(g_data.sections["Rename"].values[(LPCSTR)lpID]));
  2392. res = CCStrings[lpID].wString;
  2393. return res;
  2394. }
  2395. if (CCStrings.find(lpID) != CCStrings.end() && CCStrings[lpID].len > 0) res = CCStrings[lpID].wString;
  2396. if (!res && m_mapfile.sections.find(lpID) != m_mapfile.sections.end())
  2397. {
  2398. const auto section = m_mapfile.GetSection(lpID);
  2399. if (section && section->values.find("Name") != section->values.end())
  2400. {
  2401. CCStrings[lpID].SetString(section->values.at("Name"));
  2402. res = CCStrings[lpID].wString;
  2403. }
  2404. }
  2405. if (!res && rules.sections.find(lpID) != rules.sections.end())
  2406. {
  2407. const auto section = rules.GetSection(lpID);
  2408. if (section && section->values.find("Name") != section->values.end())
  2409. {
  2410. CCStrings[lpID].SetString(section->values.at("Name"));
  2411. res = CCStrings[lpID].wString;
  2412. }
  2413. }
  2414. if (!res)
  2415. {
  2416. CCStrings[lpID].SetString(L"MISSING", 7);
  2417. res = CCStrings[lpID].wString;
  2418. }
  2419. return res;
  2420. //return CString("");
  2421. }
  2422. DWORD CMapData::GetCelltagCount() const
  2423. {
  2424. const auto section = m_mapfile.GetSection("CellTags");
  2425. return section ? section->values.size() : 0;
  2426. }
  2427. DWORD CMapData::GetWaypointCount() const
  2428. {
  2429. const auto section = m_mapfile.GetSection("Waypoints");
  2430. return section ? section->values.size() : 0;
  2431. }
  2432. void CMapData::DeleteRulesSections()
  2433. {
  2434. int i;
  2435. // delete any rules sections except the types lists (we need those to get the data of new units in the map)...
  2436. for (i = 0; i < m_mapfile.sections.size(); i++)
  2437. {
  2438. CString name = *m_mapfile.GetSectionName(i);
  2439. if (IsRulesSection(name) && name.Find("Types") < 0)
  2440. {
  2441. m_mapfile.sections.erase(name);
  2442. }
  2443. }
  2444. // now delete these types lists...
  2445. for (i = 0; i < m_mapfile.sections.size(); i++)
  2446. {
  2447. CString name = *m_mapfile.GetSectionName(i);
  2448. if (IsRulesSection(name))
  2449. {
  2450. m_mapfile.sections.erase(name);
  2451. }
  2452. }
  2453. }
  2454. BOOL CMapData::IsRulesSection(LPCTSTR lpSection)
  2455. {
  2456. int i;
  2457. for (i = 0;i < GetHousesCount();i++)
  2458. if (GetHouseID(i) == lpSection) return FALSE;
  2459. if (strcmp(lpSection, HOUSES) == NULL) return FALSE;
  2460. if (strcmp(lpSection, "VariableNames") == NULL) return FALSE;
  2461. if (rules.sections.find(lpSection) != rules.sections.end()) return TRUE;
  2462. if (m_mapfile.sections.find("InfantryTypes") != m_mapfile.sections.end())
  2463. if (m_mapfile.sections["InfantryTypes"].FindValue(lpSection) >= 0)
  2464. return TRUE;
  2465. if (m_mapfile.sections.find("VehicleTypes") != m_mapfile.sections.end())
  2466. if (m_mapfile.sections["VehicleTypes"].FindValue(lpSection) >= 0)
  2467. return TRUE;
  2468. if (m_mapfile.sections.find("AircraftTypes") != m_mapfile.sections.end())
  2469. if (m_mapfile.sections["AircraftTypes"].FindValue(lpSection) >= 0)
  2470. return TRUE;
  2471. if (m_mapfile.sections.find("BuildingTypes") != m_mapfile.sections.end())
  2472. if (m_mapfile.sections["BuildingTypes"].FindValue(lpSection) >= 0)
  2473. return TRUE;
  2474. if (m_mapfile.sections.find("TerrainTypes") != m_mapfile.sections.end())
  2475. if (m_mapfile.sections["TerrainTypes"].FindValue(lpSection) >= 0)
  2476. return TRUE;
  2477. if ((CString)"IsoMapPack5" != lpSection && (CString)"OverlayPack" != lpSection && (CString)"OverlayDataPack" != lpSection && m_mapfile.sections.find(lpSection) != m_mapfile.sections.end())
  2478. {
  2479. CIniFileSection& sec = m_mapfile.sections[lpSection];
  2480. if (sec.FindName("ROF") > -1 && sec.FindName("Range") > -1 &&
  2481. sec.FindName("Damage") > -1 && sec.FindName("Warhead") > -1)
  2482. return TRUE; // a weapon
  2483. if (sec.FindName("Spread") > -1 && sec.FindName("Range") > -1 &&
  2484. sec.FindName("Damage") > -1 && sec.FindName("Warhead") > -1)
  2485. return TRUE; // a warhead
  2486. // check for projectile/warhead
  2487. for (i = 0;i < m_mapfile.sections.size();i++)
  2488. {
  2489. CString name = *m_mapfile.GetSectionName(i);
  2490. if ((CString)"IsoMapPack5" != name && (CString)"OverlayPack" != name && (CString)"OverlayDataPack" != name && (m_mapfile.GetSection(i)->FindName("Projectile") > -1 || m_mapfile.GetSection(i)->FindName("Warhead") > -1))
  2491. {
  2492. // MW Bugfix: Check if is found in Projectile first...
  2493. // This may have caused several crashes while saving
  2494. if (m_mapfile.GetSection(i)->FindName("Projectile") >= 0)
  2495. if (*m_mapfile.GetSection(i)->GetValue(m_mapfile.GetSection(i)->FindName("Projectile")) == lpSection)
  2496. return TRUE;
  2497. }
  2498. }
  2499. }
  2500. return FALSE;
  2501. }
  2502. void CMapData::ExportRulesChanges(const char* filename)
  2503. {
  2504. CIniFile rul;
  2505. int i;
  2506. for (i = 0;i < m_mapfile.sections.size();i++)
  2507. {
  2508. CString name = *m_mapfile.GetSectionName(i);
  2509. if (IsRulesSection(name))
  2510. {
  2511. rul.sections[name] = *m_mapfile.GetSection(i);
  2512. }
  2513. }
  2514. rul.SaveFile(std::string(filename));
  2515. }
  2516. void CMapData::ImportRUL(LPCTSTR lpFilename)
  2517. {
  2518. m_mapfile.InsertFile(std::string(lpFilename), NULL);
  2519. m_mapfile.sections.erase("Editor");
  2520. UpdateBuildingInfo();
  2521. UpdateTreeInfo();
  2522. }
  2523. void CMapData::UpdateMapFieldData(BOOL bSave)
  2524. {
  2525. if (bSave == FALSE)
  2526. {
  2527. int i;
  2528. int e;
  2529. /*for(i=0;i<GetIsoSize()*GetIsoSize();i++)
  2530. {
  2531. int dwX=i%m_IsoSize;
  2532. int dwY=i/m_IsoSize;
  2533. int mapwidth=Map->GetWidth();
  2534. int mapheight=Map->GetHeight();
  2535. int k=1;
  2536. if( dwX<1|| dwY<1 || dwX+dwY<mapwidth+k || dwX+dwY>mapwidth+mapheight*2 || (dwY+k>mapwidth && dwX-k<dwY-mapwidth) || (dwX+k>mapwidth && dwY+mapwidth-k<dwX))
  2537. {
  2538. }
  2539. else
  2540. {
  2541. BOOL bFound=FALSE;
  2542. for(e=0;e<dwIsoMapSize;e++)
  2543. {
  2544. MAPFIELDDATA* mfd=(MAPFIELDDATA*)&m_mfd[e*MAPFIELDDATA_SIZE];
  2545. if(mfd->wY==dwX && mfd->wX==dwY)
  2546. {
  2547. bFound=TRUE;
  2548. break;
  2549. }
  2550. }
  2551. if(!bFound)
  2552. {
  2553. errstream << dwX << " " << dwY << " not found";
  2554. errstream.flush();
  2555. }
  2556. }
  2557. }*/
  2558. /* int count=0;
  2559. int max_count=0;
  2560. BYTE b;
  2561. b=m_mfd[0];
  2562. for (i=0;i<dwIsoMapSize*MAPFIELDDATA_SIZE;i++)
  2563. {
  2564. if(m_mfd[i]!=b) { b=m_mfd[i]; count=0; }
  2565. if(m_mfd[i]==b) count++;
  2566. if(max_count<count) max_count=count;
  2567. if(count>10) MessageBox(0,"uh","",0);
  2568. }
  2569. char c[50];
  2570. itoa(max_count,c,10);
  2571. MessageBox(0,c,"",0);*/
  2572. const bool mp = IsMultiplayer();
  2573. for (i = 0;i < dwIsoMapSize;i++)
  2574. {
  2575. MAPFIELDDATA* mfd = (MAPFIELDDATA*)&m_mfd[i * MAPFIELDDATA_SIZE];
  2576. int pos = mfd->wY + mfd->wX * GetIsoSize();
  2577. if (dwIsoMapSize - i < 50) errstream << mfd->wY << " " << mfd->wX << endl;
  2578. if (pos < (GetIsoSize() + 1) * (GetIsoSize() + 1))
  2579. {
  2580. fielddata[pos].wGround = mfd->wGround;
  2581. fielddata[pos].bHeight = mfd->bHeight;
  2582. memcpy(&fielddata[pos].bMapData, mfd->bData, 3);
  2583. memcpy(&fielddata[pos].bMapData2, mfd->bData2, 1);
  2584. int replacement = 0;
  2585. int ground = mfd->wGround;
  2586. if (ground == 0xFFFF) ground = 0;
  2587. if ((*tiledata)[ground].bReplacementCount && atoi((*tiles).sections["General"].values["BridgeSet"]) != (*tiledata)[ground].wTileSet)
  2588. {
  2589. replacement = rand() * (1 + (*tiledata)[ground].bReplacementCount) / RAND_MAX;
  2590. }
  2591. fielddata[pos].bRNDImage = replacement;
  2592. Mini_UpdatePos(i % GetIsoSize(), i / GetIsoSize(), mp);
  2593. /*int dwX=mfd->wY;
  2594. int dwY=mfd->wX;
  2595. int mapwidth=Map->GetWidth();
  2596. int mapheight=Map->GetHeight();
  2597. const int k=1;
  2598. if( dwX<1|| dwY<1 || dwX+dwY<mapwidth+k || dwX+dwY>mapwidth+mapheight*2 || (dwY+k>mapwidth && dwX-k<dwY-mapwidth) || (dwX+k>mapwidth && dwY+mapwidth-k<dwX))
  2599. {
  2600. errstream << "Outside " << dwX << " " << dwY << endl;
  2601. errstream.flush();
  2602. }*/
  2603. }
  2604. else // if(mfd->wY==0xFFFE && mfd->wX==0xFFFE)
  2605. {
  2606. char c[2];
  2607. c[0] = mfd->bHeight;
  2608. c[1] = 0;
  2609. OutputDebugString(c);
  2610. }
  2611. /*if(mfd->bData[0] || mfd->bData[1] || mfd->bData2[0])
  2612. {
  2613. char c[50];
  2614. itoa(mfd->wY, c, 10);
  2615. OutputDebugString("Data at ");
  2616. OutputDebugString(c);
  2617. OutputDebugString(" ");
  2618. itoa(mfd->wX,c,10);
  2619. OutputDebugString(c);
  2620. OutputDebugString(": ");
  2621. itoa(mfd->bData[0], c, 10);
  2622. OutputDebugString(c);
  2623. OutputDebugString(" ");
  2624. itoa(mfd->bData[1], c, 10);
  2625. OutputDebugString(c);
  2626. OutputDebugString(" ");
  2627. itoa(mfd->bData[2], c, 10);
  2628. OutputDebugString(c);
  2629. OutputDebugString(" ");
  2630. itoa(mfd->bData2[0], c, 10);
  2631. OutputDebugString(c);
  2632. OutputDebugString("\n");
  2633. }*/
  2634. }
  2635. for (i = 0;i < m_IsoSize;i++)
  2636. {
  2637. for (e = 0;e < m_IsoSize;e++)
  2638. {
  2639. int pos = i + e * m_IsoSize;
  2640. int xx, yy;
  2641. fielddata[pos].bRedrawTerrain = FALSE;
  2642. for (xx = -2;xx < 0;xx++)
  2643. {
  2644. for (yy = -2;yy < 0;yy++)
  2645. {
  2646. int npos = pos + xx + yy * m_IsoSize;
  2647. if (npos > 0 && fielddata[pos].bHeight - fielddata[npos].bHeight >= 4)
  2648. {
  2649. fielddata[pos].bRedrawTerrain = TRUE;
  2650. break;
  2651. }
  2652. }
  2653. if (fielddata[pos].bRedrawTerrain) break;
  2654. }
  2655. }
  2656. }
  2657. }
  2658. else
  2659. {
  2660. int x, y, n = 0;
  2661. // this code here must be improved to produce smaller maps. Just ignore the data outside the visible rect!
  2662. if (m_mfd) delete[] m_mfd;
  2663. dwIsoMapSize = m_IsoSize * m_IsoSize + 15;
  2664. m_mfd = new(BYTE[(dwIsoMapSize + m_IsoSize * m_IsoSize) * MAPFIELDDATA_SIZE]);
  2665. memset(m_mfd, 0, dwIsoMapSize * MAPFIELDDATA_SIZE);
  2666. int p = 0;
  2667. const int width = m_maprect.right;
  2668. const int height = m_maprect.bottom;
  2669. errstream << "Memory allocated for mappack, saving fielddata into mapfields" << endl;
  2670. errstream.flush();
  2671. int i;
  2672. int mapwidth = m_maprect.right;
  2673. int mapheight = m_maprect.bottom;
  2674. //#ifdef UNUSED
  2675. int dwX, dwY;
  2676. for (dwX = 0;dwX <= m_IsoSize;dwX++)
  2677. {
  2678. for (dwY = 0;dwY <= m_IsoSize;dwY++)
  2679. {
  2680. /*for(i=0;i<fielddata_size;i++)
  2681. {*/
  2682. //int dwX=i%m_IsoSize;
  2683. //int dwY=i/m_IsoSize;
  2684. i = dwX + dwY * m_IsoSize;
  2685. //if( dwX<2|| dwY<2 || dwX+dwY<mapwidth+2 || dwX+dwY+2>mapwidth+mapheight*2 || (dwY+2>mapwidth && dwX-2<dwY-mapwidth) || (dwX+2>mapwidth && dwY+mapwidth-2<dwX)) continue;
  2686. if (dwX < 1 || dwY < 1 || dwX + dwY<mapwidth + 1 || dwX + dwY>mapwidth + mapheight * 2 || (dwY + 1 > mapwidth && dwX - 1 < dwY - mapwidth) || (dwX + 1 > mapwidth && dwY + mapwidth - 1 < dwX)) continue;
  2687. MAPFIELDDATA* mfd = (MAPFIELDDATA*)&m_mfd[p * MAPFIELDDATA_SIZE];
  2688. mfd->wGround = fielddata[i].wGround;
  2689. mfd->wX = dwY;
  2690. mfd->wY = dwX;
  2691. mfd->bHeight = fielddata[i].bHeight;
  2692. memcpy(&mfd->bData, &fielddata[i].bMapData, 3); // includes fielddata[i].bSubTile!
  2693. memcpy(&mfd->bData2, &fielddata[i].bMapData2, 1);
  2694. p++;
  2695. }
  2696. }
  2697. //#endif
  2698. /*
  2699. if(width>height)
  2700. {
  2701. int add_bottom=1;
  2702. int add_top=-1;
  2703. int n_bottom, n_top;
  2704. n_bottom=n_top=width;
  2705. for(x=0;x<width+height+1;x++)
  2706. {
  2707. for(y=n_top;y<=n_bottom;y++)
  2708. {
  2709. if(y<width+height+1 && y>=0)
  2710. {
  2711. if( x<1|| y<1 || x+y<mapwidth+1 || x+y>mapwidth+mapheight*2 || (y+1>mapwidth && x-1<y-mapwidth) || (x+1>mapwidth && y+mapwidth-1<x)) continue;
  2712. int pos=y+x*GetIsoSize();
  2713. MAPFIELDDATA* mfd=(MAPFIELDDATA*)&m_mfd[p*MAPFIELDDATA_SIZE];
  2714. mfd->wGround=fielddata[pos].wGround;
  2715. mfd->wX=x;
  2716. mfd->wY=y;
  2717. mfd->bHeight=fielddata[pos].bHeight;
  2718. memcpy(&mfd->bData, &fielddata[pos].bMapData, 3);
  2719. memcpy(&mfd->bData2, &fielddata[pos].bMapData2, 1);
  2720. p++;
  2721. }
  2722. }
  2723. if(x==height) add_bottom=-1;
  2724. if(x==width) add_top=1;
  2725. n_top+=add_top;
  2726. n_bottom+=add_bottom;
  2727. }
  2728. }
  2729. else
  2730. {
  2731. int add_right=1;
  2732. int add_left=-1;
  2733. int n_right, n_left;
  2734. n_right=n_left=height;
  2735. for(y=width+height;y>=0;y--)
  2736. {
  2737. for(x=n_left;x<=n_right;x++)
  2738. {
  2739. if(x<width+height && x>=0)
  2740. {
  2741. if( x<1|| y<1 || x+y<mapwidth+1 || x+y>mapwidth+mapheight*2 || (y+1>mapwidth && x-1<y-mapwidth) || (x+1>mapwidth && y+mapwidth-1<x)) continue;
  2742. int pos=y+x*GetIsoSize();
  2743. //if(pos>0 && pos<=
  2744. MAPFIELDDATA* mfd=(MAPFIELDDATA*)&m_mfd[p*MAPFIELDDATA_SIZE];
  2745. mfd->wGround=fielddata[pos].wGround;
  2746. mfd->wX=x;
  2747. mfd->wY=y;
  2748. mfd->bHeight=fielddata[pos].bHeight;
  2749. memcpy(&mfd->bData, &fielddata[pos].bMapData, 3);
  2750. memcpy(&mfd->bData2, &fielddata[pos].bMapData2, 1);
  2751. p++;
  2752. }
  2753. }
  2754. if(y==height) add_right=-1;
  2755. if(y==width) add_left=1;
  2756. n_left+=add_left;
  2757. n_right+=add_right;
  2758. }
  2759. }*/
  2760. /*
  2761. else
  2762. {
  2763. for(y=height;y>=0;y--)
  2764. {
  2765. for(x=0;x<=n;x++)
  2766. {
  2767. int pos=y+x*GetIsoSize();
  2768. MAPFIELDDATA* mfd=(MAPFIELDDATA*)&m_mfd[p*MAPFIELDDATA_SIZE];
  2769. mfd->wGround=fielddata[pos].wGround;
  2770. mfd->wX=x;
  2771. mfd->wY=y;
  2772. mfd->bHeight=fielddata[pos].bHeight;
  2773. memcpy(&mfd->bData, &fielddata[pos].bMapData, 3);
  2774. memcpy(&mfd->bData2, &fielddata[pos].bMapData2, 1);
  2775. char c[50];
  2776. itoa(x,c,10);
  2777. OutputDebugString(c);
  2778. OutputDebugString(" ");
  2779. itoa(y,c,10);
  2780. OutputDebugString(c);
  2781. OutputDebugString(" ");
  2782. itoa(p,c,10);
  2783. OutputDebugString(c);
  2784. OutputDebugString(" ");
  2785. OutputDebugString("\n");
  2786. p++;
  2787. }
  2788. if(height-y<width)
  2789. n++;
  2790. else if(y<=width)
  2791. n--;
  2792. }
  2793. }*/
  2794. dwIsoMapSize = p;//+14; // dwIsoMapSize is smaller than whole iso map!
  2795. int startpos = (p)*MAPFIELDDATA_SIZE;
  2796. /*for(i=0;i<14;i++)
  2797. {
  2798. MAPFIELDDATA* mfd=(MAPFIELDDATA*)&m_mfd[startpos+i*MAPFIELDDATA_SIZE];
  2799. mfd->wX=0xFFFE;
  2800. mfd->wY=0xFFFE;
  2801. int c;
  2802. switch(i)
  2803. {
  2804. case 0:
  2805. c='F';
  2806. break;
  2807. case 1:
  2808. c='I';
  2809. break;
  2810. case 2:
  2811. c='N';
  2812. break;
  2813. case 3:
  2814. c='A';
  2815. break;
  2816. case 4:
  2817. c='L';
  2818. break;
  2819. case 5:
  2820. c='S';
  2821. break;
  2822. case 6:
  2823. c='U';
  2824. break;
  2825. case 7:
  2826. c='N';
  2827. break;
  2828. case 8:
  2829. c='/';
  2830. break;
  2831. case 9:
  2832. c='A';
  2833. break;
  2834. case 10:
  2835. c='L';
  2836. break;
  2837. case 11:
  2838. c='E';
  2839. break;
  2840. case 12:
  2841. c='R';
  2842. break;
  2843. case 13:
  2844. c='T';
  2845. break;
  2846. }
  2847. mfd->bHeight=c;
  2848. }*/
  2849. /*for(i=0;i<m_IsoSize;i++)
  2850. {
  2851. for(e=0;e<m_IsoSize;e++)
  2852. {
  2853. int pos=e+i*GetIsoSize();
  2854. MAPFIELDDATA* mfd=(MAPFIELDDATA*)&m_mfd[n*MAPFIELDDATA_SIZE];
  2855. mfd->wGround=fielddata[pos].wGround;
  2856. mfd->wX=i;
  2857. mfd->wY=e;
  2858. mfd->bHeight=fielddata[pos].bHeight;
  2859. memcpy(&mfd->bData, &fielddata[pos].bMapData, 3);
  2860. memcpy(&mfd->bData2, &fielddata[pos].bMapData2, 1);
  2861. n++;
  2862. }
  2863. }*/
  2864. }
  2865. }
  2866. void CMapData::UpdateBuildingInfo(LPCSTR lpUnitType)
  2867. {
  2868. CIniFile& ini = GetIniFile();
  2869. if (!lpUnitType)
  2870. {
  2871. memset(buildinginfo, 0, 0x0F00 * sizeof(BUILDING_INFO));
  2872. int i;
  2873. for (i = 0;i < rules.sections["BuildingTypes"].values.size();i++)
  2874. {
  2875. CString type = *rules.sections["BuildingTypes"].GetValue(i);
  2876. CString artname = type;
  2877. if (rules.sections[type].values.find("Image") != rules.sections[type].values.end())
  2878. {
  2879. artname = rules.sections[type].values["Image"];
  2880. }
  2881. if (ini.sections.find(type) != ini.sections.end())
  2882. {
  2883. if (ini.sections[type].values.find("Image") != ini.sections[type].values.end())
  2884. {
  2885. artname = ini.sections[type].values["Image"];
  2886. }
  2887. }
  2888. int w, h;
  2889. char d[6];
  2890. memcpy(d, art.sections[artname].values["Foundation"], 1);
  2891. d[1] = 0;
  2892. w = atoi(d);
  2893. if (w == 0) w = 1;
  2894. memcpy(d, (LPCTSTR)art.sections[artname].values["Foundation"] + 2, 1);
  2895. d[1] = 0;
  2896. h = atoi(d);
  2897. if (h == 0) h = 1;
  2898. int n = Map->GetUnitTypeID(type);
  2899. if (n >= 0 && n < 0x0F00)
  2900. {
  2901. buildinginfo[n].w = w;
  2902. buildinginfo[n].h = h;
  2903. buildinginfo[n].bSnow = FALSE;
  2904. buildinginfo[n].bTemp = FALSE;
  2905. buildinginfo[n].bUrban = FALSE;
  2906. CString lpPicFile = GetUnitPictureFilename(type, 0);
  2907. if (pics.find(lpPicFile) != pics.end())
  2908. {
  2909. if (pics[lpPicFile].bTerrain == TheaterChar::None)
  2910. {
  2911. buildinginfo[n].bSnow = TRUE;
  2912. buildinginfo[n].bTemp = TRUE;
  2913. buildinginfo[n].bUrban = TRUE;
  2914. }
  2915. else if (pics[lpPicFile].bTerrain == TheaterChar::T) buildinginfo[n].bTemp = TRUE;
  2916. else if (pics[lpPicFile].bTerrain == TheaterChar::A) buildinginfo[n].bSnow = TRUE;
  2917. else if (pics[lpPicFile].bTerrain == TheaterChar::U) buildinginfo[n].bUrban = TRUE;
  2918. }
  2919. else
  2920. {
  2921. buildinginfo[n].bSnow = TRUE;
  2922. buildinginfo[n].bTemp = TRUE;
  2923. buildinginfo[n].bUrban = TRUE;
  2924. }
  2925. buildinginfo[n].pic_count = 8;
  2926. int k;
  2927. for (k = 0;k < 8;k++)
  2928. {
  2929. lpPicFile = GetUnitPictureFilename(type, k);
  2930. if (pics.find(lpPicFile) != pics.end())
  2931. {
  2932. buildinginfo[n].pic[k] = pics[lpPicFile];
  2933. }
  2934. else
  2935. {
  2936. buildinginfo[n].pic[k].pic = NULL;
  2937. }
  2938. }
  2939. }
  2940. else
  2941. {
  2942. errstream << "Building not found " << endl;
  2943. errstream.flush();
  2944. }
  2945. }
  2946. for (i = 0;i < ini.sections["BuildingTypes"].values.size();i++)
  2947. {
  2948. CString type = *ini.sections["BuildingTypes"].GetValue(i);
  2949. CString artname = type;
  2950. if (ini.sections.find(type) != ini.sections.end())
  2951. {
  2952. if (ini.sections[type].values.find("Image") != ini.sections[type].values.end())
  2953. {
  2954. artname = ini.sections[type].values["Image"];
  2955. }
  2956. }
  2957. int w, h;
  2958. char d[6];
  2959. memcpy(d, art.sections[artname].values["Foundation"], 1);
  2960. d[1] = 0;
  2961. w = atoi(d);
  2962. if (w == 0) w = 1;
  2963. memcpy(d, (LPCTSTR)art.sections[artname].values["Foundation"] + 2, 1);
  2964. d[1] = 0;
  2965. h = atoi(d);
  2966. if (h == 0) h = 1;
  2967. int n = Map->GetUnitTypeID(type);
  2968. if (n >= 0 && n < 0x0F00)
  2969. {
  2970. buildinginfo[n].w = w;
  2971. buildinginfo[n].h = h;
  2972. buildinginfo[n].bSnow = TRUE;
  2973. buildinginfo[n].bTemp = TRUE;
  2974. buildinginfo[n].bUrban = TRUE;
  2975. CString lpPicFile = GetUnitPictureFilename(type, 0);
  2976. int k;
  2977. for (k = 0;k < 8;k++)
  2978. {
  2979. lpPicFile = GetUnitPictureFilename(type, k);
  2980. if (pics.find(lpPicFile) != pics.end())
  2981. {
  2982. buildinginfo[n].pic[k] = pics[lpPicFile];
  2983. }
  2984. else
  2985. {
  2986. buildinginfo[n].pic[k].pic = NULL;
  2987. }
  2988. }
  2989. }
  2990. }
  2991. }
  2992. else
  2993. {
  2994. // only for specific building -> faster
  2995. CString type = lpUnitType;
  2996. CString artname = type;
  2997. if (rules.sections[type].values.find("Image") != rules.sections[type].values.end())
  2998. {
  2999. artname = rules.sections[type].values["Image"];
  3000. }
  3001. if (ini.sections.find(type) != ini.sections.end())
  3002. {
  3003. if (ini.sections[type].values.find("Image") != ini.sections[type].values.end())
  3004. {
  3005. artname = ini.sections[type].values["Image"];
  3006. }
  3007. }
  3008. int w, h;
  3009. char d[6];
  3010. memcpy(d, art.sections[artname].values["Foundation"], 1);
  3011. d[1] = 0;
  3012. w = atoi(d);
  3013. if (w == 0) w = 1;
  3014. memcpy(d, (LPCTSTR)art.sections[artname].values["Foundation"] + 2, 1);
  3015. d[1] = 0;
  3016. h = atoi(d);
  3017. if (h == 0) h = 1;
  3018. int n = Map->GetUnitTypeID(type);
  3019. if (n >= 0 && n < 0x0F00)
  3020. {
  3021. buildinginfo[n].w = w;
  3022. buildinginfo[n].h = h;
  3023. CString lpPicFile = GetUnitPictureFilename(type, 0);
  3024. buildinginfo[n].pic_count = 8;
  3025. int k;
  3026. for (k = 0;k < 8;k++)
  3027. {
  3028. lpPicFile = GetUnitPictureFilename(type, k);
  3029. if (pics.find(lpPicFile) != pics.end())
  3030. {
  3031. buildinginfo[n].pic[k] = pics[lpPicFile];
  3032. }
  3033. else
  3034. {
  3035. buildinginfo[n].pic[k].pic = NULL;
  3036. }
  3037. }
  3038. }
  3039. }
  3040. }
  3041. void CMapData::UpdateTreeInfo(LPCSTR lpTreeType)
  3042. {
  3043. CIniFile& ini = GetIniFile();
  3044. if (!lpTreeType)
  3045. {
  3046. memset(treeinfo, 0, 0x0F00 * sizeof(TREE_INFO));
  3047. int i;
  3048. for (i = 0;i < rules.sections["TerrainTypes"].values.size();i++)
  3049. {
  3050. CString type = *rules.sections["TerrainTypes"].GetValue(i);
  3051. CString artname = type;
  3052. if (rules.sections[type].values.find("Image") != rules.sections[type].values.end())
  3053. {
  3054. artname = rules.sections[type].values["Image"];
  3055. }
  3056. if (ini.sections.find(type) != ini.sections.end())
  3057. {
  3058. if (ini.sections[type].values.find("Image") != ini.sections[type].values.end())
  3059. {
  3060. artname = ini.sections[type].values["Image"];
  3061. }
  3062. }
  3063. int w, h;
  3064. char d[6];
  3065. memcpy(d, art.sections[artname].values["Foundation"], 1);
  3066. d[1] = 0;
  3067. w = atoi(d);
  3068. if (w == 0) w = 1;
  3069. memcpy(d, (LPCTSTR)art.sections[artname].values["Foundation"] + 2, 1);
  3070. d[1] = 0;
  3071. h = atoi(d);
  3072. if (h == 0) h = 1;
  3073. int n = GetUnitTypeID(type);
  3074. if (n >= 0 && n < 0x0F00)
  3075. {
  3076. treeinfo[n].w = w;
  3077. treeinfo[n].h = h;
  3078. CString lpPicFile = GetUnitPictureFilename(type, 0);
  3079. if (pics.find(lpPicFile) != pics.end())
  3080. {
  3081. treeinfo[n].pic = pics[lpPicFile];
  3082. }
  3083. else
  3084. treeinfo[n].pic.pic = NULL;
  3085. }
  3086. }
  3087. for (i = 0;i < ini.sections["TerrainTypes"].values.size();i++)
  3088. {
  3089. CString type = *ini.sections["TerrainTypes"].GetValue(i);
  3090. CString artname = type;
  3091. if (ini.sections.find(type) != ini.sections.end())
  3092. {
  3093. if (ini.sections[type].values.find("Image") != ini.sections[type].values.end())
  3094. {
  3095. artname = ini.sections[type].values["Image"];
  3096. }
  3097. }
  3098. int w, h;
  3099. char d[6];
  3100. memcpy(d, art.sections[artname].values["Foundation"], 1);
  3101. d[1] = 0;
  3102. w = atoi(d);
  3103. if (w == 0) w = 1;
  3104. memcpy(d, (LPCTSTR)art.sections[artname].values["Foundation"] + 2, 1);
  3105. d[1] = 0;
  3106. h = atoi(d);
  3107. if (h == 0) h = 1;
  3108. int n = Map->GetUnitTypeID(type);
  3109. if (n >= 0 && n < 0x0F00)
  3110. {
  3111. treeinfo[n].w = w;
  3112. treeinfo[n].h = h;
  3113. CString lpPicFile = GetUnitPictureFilename(type, 0);
  3114. if (pics.find(lpPicFile) != pics.end())
  3115. {
  3116. treeinfo[n].pic = pics[lpPicFile];
  3117. }
  3118. else
  3119. treeinfo[n].pic.pic = NULL;
  3120. }
  3121. }
  3122. }
  3123. else
  3124. {
  3125. CString type = lpTreeType;
  3126. CString artname = type;
  3127. if (rules.sections[type].values.find("Image") != rules.sections[type].values.end())
  3128. {
  3129. artname = rules.sections[type].values["Image"];
  3130. }
  3131. if (ini.sections.find(type) != ini.sections.end())
  3132. {
  3133. if (ini.sections[type].values.find("Image") != ini.sections[type].values.end())
  3134. {
  3135. artname = ini.sections[type].values["Image"];
  3136. }
  3137. }
  3138. int w, h;
  3139. char d[6];
  3140. memcpy(d, art.sections[artname].values["Foundation"], 1);
  3141. d[1] = 0;
  3142. w = atoi(d);
  3143. if (w == 0) w = 1;
  3144. memcpy(d, (LPCTSTR)art.sections[artname].values["Foundation"] + 2, 1);
  3145. d[1] = 0;
  3146. h = atoi(d);
  3147. if (h == 0) h = 1;
  3148. int n = Map->GetUnitTypeID(type);
  3149. if (n >= 0 && n < 0x0F00)
  3150. {
  3151. treeinfo[n].w = w;
  3152. treeinfo[n].h = h;
  3153. CString lpPicFile = GetUnitPictureFilename(type, 0);
  3154. if (pics.find(lpPicFile) != pics.end())
  3155. {
  3156. treeinfo[n].pic = pics[lpPicFile];
  3157. }
  3158. else
  3159. treeinfo[n].pic.pic = NULL;
  3160. }
  3161. }
  3162. }
  3163. int CMapData::GetBuildingID(LPCSTR lpBuildingName)
  3164. {
  3165. if (buildingid.find(lpBuildingName) == buildingid.end()) return -1;
  3166. return buildingid[lpBuildingName];
  3167. }
  3168. MAPFIELDDATA* CMapData::GetMappackPointer(DWORD dwPos)
  3169. {
  3170. int x = dwPos % GetIsoSize(); // note that x=y and y=x in the mappack (according to our struct)!
  3171. int y = dwPos / GetIsoSize();
  3172. int i = 0;
  3173. for (i = 0;i < dwIsoMapSize;i++)
  3174. {
  3175. MAPFIELDDATA* cur = (MAPFIELDDATA*)&m_mfd[i * MAPFIELDDATA_SIZE];
  3176. if (cur->wX == y && cur->wY == x)
  3177. return cur;
  3178. }
  3179. return NULL;
  3180. }
  3181. void CMapData::CreateMap(DWORD dwWidth, DWORD dwHeight, LPCTSTR lpTerrainType, DWORD dwGroundHeight)
  3182. {
  3183. if (fielddata != NULL) delete[] fielddata;
  3184. int i;
  3185. for (i = 0;i < dwSnapShotCount;i++)
  3186. {
  3187. delete[] m_snapshots[i].bHeight;
  3188. delete[] m_snapshots[i].bMapData;
  3189. delete[] m_snapshots[i].bSubTile;
  3190. delete[] m_snapshots[i].bMapData2;
  3191. delete[] m_snapshots[i].wGround;
  3192. delete[] m_snapshots[i].bRedrawTerrain;
  3193. delete[] m_snapshots[i].overlay;
  3194. delete[] m_snapshots[i].overlaydata;
  3195. // m_snapshots[i].mapfile.Clear();
  3196. }
  3197. if (m_snapshots != NULL) delete[] m_snapshots;
  3198. fielddata = NULL;
  3199. fielddata_size = 0;
  3200. m_snapshots = NULL;
  3201. dwSnapShotCount = 0;
  3202. m_cursnapshot = -1;
  3203. m_tubes.clear();
  3204. m_tubes.reserve(32);
  3205. m_infantry.clear();
  3206. m_terrain.clear();
  3207. m_units.clear();
  3208. m_structures.clear();
  3209. #ifdef SMUDGE_SUPP
  3210. m_smudges.clear();
  3211. #endif
  3212. m_mapfile.Clear();
  3213. CString stdMap;
  3214. stdMap = AppPath;
  3215. #ifdef TS_MODE
  3216. stdMap += "\\StdMapTS.ini";
  3217. #endif
  3218. #ifdef RA2_MODE
  3219. stdMap += "\\StdMapRA2.ini";
  3220. #endif
  3221. m_mapfile.InsertFile(stdMap, NULL);
  3222. char c[50];
  3223. CString mapsize;
  3224. itoa(dwWidth, c, 10);
  3225. mapsize = "0,0,";
  3226. mapsize += c;
  3227. itoa(dwHeight, c, 10);
  3228. mapsize += ",";
  3229. mapsize += c;
  3230. m_mapfile.sections["Map"].values["Size"] = mapsize;
  3231. itoa(dwWidth - 4, c, 10);
  3232. mapsize = "2,4,";
  3233. mapsize += c;
  3234. itoa(dwHeight - 6, c, 10);
  3235. mapsize += ",";
  3236. mapsize += c;
  3237. m_mapfile.sections["Map"].values["Theater"] = lpTerrainType;
  3238. m_mapfile.sections["Map"].values["LocalSize"] = mapsize;
  3239. map<CString, PICDATA>::iterator it = pics.begin();
  3240. for (int e = 0;e < pics.size();e++)
  3241. {
  3242. try
  3243. {
  3244. #ifdef NOSURFACES_OBJECTS
  3245. if (it->second.bType == PICDATA_TYPE_BMP)
  3246. {
  3247. if (it->second.pic != NULL)
  3248. {
  3249. ((LPDIRECTDRAWSURFACE4)it->second.pic)->Release();
  3250. }
  3251. }
  3252. else
  3253. {
  3254. if (it->second.pic != NULL)
  3255. {
  3256. delete[] it->second.pic;
  3257. }
  3258. if (it->second.vborder) delete[] it->second.vborder;
  3259. }
  3260. #else
  3261. if (it->second.pic != NULL) it->second.pic->Release();
  3262. #endif
  3263. it->second.pic = NULL;
  3264. }
  3265. catch (...)
  3266. {
  3267. CString err;
  3268. err = "Access violation while trying to release surface ";
  3269. char c[6];
  3270. itoa(e, c, 10);
  3271. err += c;
  3272. err += "\n";
  3273. OutputDebugString(err);
  3274. continue;
  3275. }
  3276. it++;
  3277. }
  3278. std::unique_ptr<CDynamicGraphDlg> dlg;
  3279. if (theApp.m_pMainWnd)
  3280. {
  3281. dlg.reset(new CDynamicGraphDlg(theApp.m_pMainWnd));
  3282. dlg->ShowWindow(SW_SHOW);
  3283. dlg->UpdateWindow();
  3284. }
  3285. pics.clear();
  3286. missingimages.clear();
  3287. UpdateBuildingInfo();
  3288. UpdateTreeInfo();
  3289. if (theApp.m_loading)
  3290. {
  3291. theApp.m_loading->Unload();
  3292. theApp.m_loading->InitMixFiles();
  3293. if (theApp.m_pMainWnd)
  3294. ((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview->UpdateOverlayPictures();
  3295. theApp.m_loading->InitPics();
  3296. if (m_mapfile.sections["Map"].values["Theater"] == THEATER0)
  3297. {
  3298. tiledata = &s_tiledata;
  3299. tiledata_count = &s_tiledata_count;
  3300. tiles = &tiles_s;
  3301. theApp.m_loading->FreeTileSet();
  3302. tiledata = &u_tiledata;
  3303. tiledata_count = &u_tiledata_count;
  3304. tiles = &tiles_u;
  3305. theApp.m_loading->FreeTileSet();
  3306. // MW new tilesets
  3307. tiledata = &un_tiledata;
  3308. tiledata_count = &un_tiledata_count;
  3309. tiles = &tiles_un;
  3310. theApp.m_loading->FreeTileSet();
  3311. tiledata = &d_tiledata;
  3312. tiledata_count = &d_tiledata_count;
  3313. tiles = &tiles_d;
  3314. theApp.m_loading->FreeTileSet();
  3315. tiledata = &l_tiledata;
  3316. tiledata_count = &l_tiledata_count;
  3317. tiles = &tiles_l;
  3318. theApp.m_loading->FreeTileSet();
  3319. tiledata = &t_tiledata;
  3320. tiledata_count = &t_tiledata_count;
  3321. tiles = &tiles_t;
  3322. theApp.m_loading->FreeTileSet();
  3323. if (dlg)
  3324. theApp.m_loading->InitTMPs(&dlg->m_Progress);
  3325. theApp.m_loading->cur_theat = 'T';
  3326. }
  3327. else if (m_mapfile.sections["Map"].values["Theater"] == THEATER1)
  3328. {
  3329. tiledata = &t_tiledata;
  3330. tiledata_count = &t_tiledata_count;
  3331. tiles = &tiles_t;
  3332. theApp.m_loading->FreeTileSet();
  3333. tiledata = &u_tiledata;
  3334. tiledata_count = &u_tiledata_count;
  3335. tiles = &tiles_u;
  3336. theApp.m_loading->FreeTileSet();
  3337. // MW new tilesets
  3338. tiledata = &un_tiledata;
  3339. tiledata_count = &un_tiledata_count;
  3340. tiles = &tiles_un;
  3341. theApp.m_loading->FreeTileSet();
  3342. tiledata = &d_tiledata;
  3343. tiledata_count = &d_tiledata_count;
  3344. tiles = &tiles_d;
  3345. theApp.m_loading->FreeTileSet();
  3346. tiledata = &l_tiledata;
  3347. tiledata_count = &l_tiledata_count;
  3348. tiles = &tiles_l;
  3349. theApp.m_loading->FreeTileSet();
  3350. tiledata = &s_tiledata;
  3351. tiledata_count = &s_tiledata_count;
  3352. tiles = &tiles_s;
  3353. theApp.m_loading->FreeTileSet();
  3354. if (dlg)
  3355. theApp.m_loading->InitTMPs(&dlg->m_Progress);
  3356. theApp.m_loading->cur_theat = 'A';
  3357. }
  3358. else if (m_mapfile.sections["Map"].values["Theater"] == THEATER2)
  3359. {
  3360. tiledata = &t_tiledata;
  3361. tiledata_count = &t_tiledata_count;
  3362. tiles = &tiles_t;
  3363. theApp.m_loading->FreeTileSet();
  3364. tiledata = &s_tiledata;
  3365. tiledata_count = &s_tiledata_count;
  3366. tiles = &tiles_s;
  3367. theApp.m_loading->FreeTileSet();
  3368. // MW new tilesets
  3369. tiledata = &un_tiledata;
  3370. tiledata_count = &un_tiledata_count;
  3371. tiles = &tiles_un;
  3372. theApp.m_loading->FreeTileSet();
  3373. tiledata = &d_tiledata;
  3374. tiledata_count = &d_tiledata_count;
  3375. tiles = &tiles_d;
  3376. theApp.m_loading->FreeTileSet();
  3377. tiledata = &l_tiledata;
  3378. tiledata_count = &l_tiledata_count;
  3379. tiles = &tiles_l;
  3380. theApp.m_loading->FreeTileSet();
  3381. tiledata = &u_tiledata;
  3382. tiledata_count = &u_tiledata_count;
  3383. tiles = &tiles_u;
  3384. theApp.m_loading->FreeTileSet();
  3385. if (dlg)
  3386. theApp.m_loading->InitTMPs(&dlg->m_Progress);
  3387. theApp.m_loading->cur_theat = 'U';
  3388. }
  3389. else if (yuri_mode && m_mapfile.sections["Map"].values["Theater"] == THEATER3)
  3390. {
  3391. tiledata = &t_tiledata;
  3392. tiledata_count = &t_tiledata_count;
  3393. tiles = &tiles_t;
  3394. theApp.m_loading->FreeTileSet();
  3395. tiledata = &s_tiledata;
  3396. tiledata_count = &s_tiledata_count;
  3397. tiles = &tiles_s;
  3398. theApp.m_loading->FreeTileSet();
  3399. // MW new tilesets
  3400. tiledata = &d_tiledata;
  3401. tiledata_count = &d_tiledata_count;
  3402. tiles = &tiles_d;
  3403. theApp.m_loading->FreeTileSet();
  3404. tiledata = &l_tiledata;
  3405. tiledata_count = &l_tiledata_count;
  3406. tiles = &tiles_l;
  3407. theApp.m_loading->FreeTileSet();
  3408. tiledata = &u_tiledata;
  3409. tiledata_count = &u_tiledata_count;
  3410. tiles = &tiles_u;
  3411. theApp.m_loading->FreeTileSet();
  3412. tiledata = &un_tiledata;
  3413. tiledata_count = &un_tiledata_count;
  3414. tiles = &tiles_un;
  3415. theApp.m_loading->FreeTileSet();
  3416. if (dlg)
  3417. theApp.m_loading->InitTMPs(&dlg->m_Progress);
  3418. theApp.m_loading->cur_theat = 'N';
  3419. }
  3420. else if (yuri_mode && m_mapfile.sections["Map"].values["Theater"] == THEATER4)
  3421. {
  3422. tiledata = &t_tiledata;
  3423. tiledata_count = &t_tiledata_count;
  3424. tiles = &tiles_t;
  3425. theApp.m_loading->FreeTileSet();
  3426. tiledata = &s_tiledata;
  3427. tiledata_count = &s_tiledata_count;
  3428. tiles = &tiles_s;
  3429. theApp.m_loading->FreeTileSet();
  3430. // MW new tilesets
  3431. tiledata = &un_tiledata;
  3432. tiledata_count = &un_tiledata_count;
  3433. tiles = &tiles_un;
  3434. theApp.m_loading->FreeTileSet();
  3435. tiledata = &d_tiledata;
  3436. tiledata_count = &d_tiledata_count;
  3437. tiles = &tiles_d;
  3438. theApp.m_loading->FreeTileSet();
  3439. tiledata = &u_tiledata;
  3440. tiledata_count = &u_tiledata_count;
  3441. tiles = &tiles_u;
  3442. theApp.m_loading->FreeTileSet();
  3443. tiledata = &l_tiledata;
  3444. tiledata_count = &l_tiledata_count;
  3445. tiles = &tiles_l;
  3446. theApp.m_loading->FreeTileSet();
  3447. if (dlg)
  3448. {
  3449. theApp.m_loading->InitTMPs(&dlg->m_Progress);
  3450. }
  3451. theApp.m_loading->cur_theat = 'L';
  3452. }
  3453. else if (m_mapfile.sections["Map"].values["Theater"] == THEATER5)
  3454. {
  3455. tiledata = &t_tiledata;
  3456. tiledata_count = &t_tiledata_count;
  3457. tiles = &tiles_t;
  3458. theApp.m_loading->FreeTileSet();
  3459. tiledata = &s_tiledata;
  3460. tiledata_count = &s_tiledata_count;
  3461. tiles = &tiles_s;
  3462. theApp.m_loading->FreeTileSet();
  3463. // MW new tilesets
  3464. tiledata = &un_tiledata;
  3465. tiledata_count = &un_tiledata_count;
  3466. tiles = &tiles_un;
  3467. theApp.m_loading->FreeTileSet();
  3468. tiledata = &l_tiledata;
  3469. tiledata_count = &l_tiledata_count;
  3470. tiles = &tiles_l;
  3471. theApp.m_loading->FreeTileSet();
  3472. tiledata = &u_tiledata;
  3473. tiledata_count = &u_tiledata_count;
  3474. tiles = &tiles_u;
  3475. theApp.m_loading->FreeTileSet();
  3476. tiledata = &d_tiledata;
  3477. tiledata_count = &d_tiledata_count;
  3478. tiles = &tiles_d;
  3479. theApp.m_loading->FreeTileSet();
  3480. if (dlg)
  3481. theApp.m_loading->InitTMPs(&dlg->m_Progress);
  3482. theApp.m_loading->cur_theat = 'D';
  3483. }
  3484. else
  3485. {
  3486. theApp.m_loading->FreeAll();
  3487. CString s = "Fatal error! %9 doesn´t support the theater of this map!";
  3488. s = TranslateStringACP(s);
  3489. MessageBox(0, s, "Error", 0);
  3490. exit(0);
  3491. }
  3492. }
  3493. else
  3494. {
  3495. // e.g. unittests
  3496. tiles = &tiles_t;
  3497. }
  3498. errstream << "CreateMap() clears data\n";
  3499. errstream.flush();
  3500. CalcMapRect();
  3501. ClearOverlay();
  3502. ClearOverlayData();
  3503. isInitialized = TRUE;
  3504. if (fielddata != NULL) delete[] fielddata;
  3505. errstream << "CreateMap() allocates memory\n";
  3506. errstream.flush();
  3507. fielddata = new(FIELDDATA[(GetIsoSize() + 1) * (GetIsoSize() + 1)]); // +1 because of some unpacking problems
  3508. fielddata_size = (GetIsoSize() + 1) * (GetIsoSize() + 1);
  3509. dwIsoMapSize = 0;
  3510. errstream << "CreateMap() frees m_mfd\n";
  3511. errstream.flush();
  3512. if (m_mfd != NULL) delete[] m_mfd;
  3513. m_mfd = NULL;
  3514. errstream << "CreateMap() loads from ini\n";
  3515. errstream.flush();
  3516. UpdateIniFile(MAPDATA_UPDATE_FROM_INI);
  3517. AddWaypoint("98", (dwWidth + dwHeight) / 2 + (dwWidth + dwHeight) * (dwWidth + dwHeight) / 2);
  3518. AddWaypoint("99", (dwWidth + dwHeight) / 2 + (dwWidth + dwHeight) * (dwWidth + dwHeight) / 2 - 1);
  3519. errstream << "CreateMap() sets terrain height\n";
  3520. errstream.flush();
  3521. for (i = 0;i < fielddata_size;i++)
  3522. {
  3523. fielddata[i].bHeight = dwGroundHeight;
  3524. }
  3525. errstream << "CreateMap() finished\n";
  3526. errstream.flush();
  3527. }
  3528. /*void CMapData::CreateSlopesAt(DWORD dwPos)
  3529. {
  3530. //OutputDebugString("CreateSlopes()\n");
  3531. FIELDDATA m=*GetFielddataAt(dwPos);
  3532. if(m.wGround==0xFFFF) m.wGround=0;
  3533. TILEDATA& d=(*tiledata)[m.wGround];
  3534. int ns=-1;
  3535. int i,e,p=0;
  3536. int h[3][3];
  3537. for(i=0;i<3; i++)
  3538. {
  3539. for(e=0;e<3;e++)
  3540. {
  3541. int pos=dwPos+(i-1)+(e-1)*m_IsoSize;
  3542. if(pos<0 || pos>=m_IsoSize*m_IsoSize)
  3543. {
  3544. h[i][e]=0;
  3545. }
  3546. else
  3547. {
  3548. FIELDDATA m2=*GetFielddataAt(pos);
  3549. h[i][e]=m.bHeight-m2.bHeight;
  3550. }
  3551. }
  3552. }
  3553. // hmm... check if the current tile must be heightened anyway
  3554. if(!theApp.m_Options.bDisableSlopeCorrection && d.bMorphable)
  3555. {
  3556. if((h[0][1]<0 && h[2][1]<0) || (h[1][0]<0 && h[1][2]<0)
  3557. || (h[1][0]<0 && h[0][2]<0 && h[0][1]>=0)
  3558. || (h[1][0]<0 && h[2][2]<0 && h[2][1]>=0)
  3559. || (h[0][1]<0 && h[2][0]<0 && h[1][0]>=0)
  3560. || (h[0][1]<0 && h[2][2]<0 && h[1][2]>=0)
  3561. || (h[1][2]<0 && h[0][0]<0 && h[0][1]>=0)
  3562. || (h[1][2]<0 && h[2][0]<0 && h[2][1]>=0)
  3563. || (h[2][1]<0 && h[0][0]<0 && h[1][0]>=0)
  3564. || (h[2][1]<0 && h[0][2]<0 && h[1][2]>=0)
  3565. || (h[1][0]<0 && h[0][1]<0 && h[0][0]>=0)
  3566. || (h[0][1]<0 && h[1][2]<0 && h[0][2]>=0)
  3567. || (h[1][2]<0 && h[2][1]<0 && h[2][2]>=0)
  3568. || (h[2][1]<0 && h[1][0]<0 && h[2][0]>=0)
  3569. )
  3570. {
  3571. SetHeightAt(dwPos, m.bHeight+1);
  3572. for(i=-1;i<2;i++)
  3573. for(e=-1;e<2;e++)
  3574. CreateSlopesAt(dwPos+i+e*m_IsoSize);
  3575. return;
  3576. }
  3577. }
  3578. //OutputDebugString("Running check\n");
  3579. BOOL checkOtherSlopes=FALSE;
  3580. /*if(h[0][0] && h[0][1] && h[0][2] && h[1][0] && h[1][2] && h[2][0] && h[2][1] && h[2][2])
  3581. {
  3582. ns=-1;
  3583. checkOtherSlopes=TRUE;
  3584. }*//*
  3585. if(h[0][0]==-1 && h[2][2]==-1 && h[2][0]>=0 && h[0][2]>=0 && h[1][0]>=0 && h[1][2]>=0 && h[0][1]>=0 && h[2][1]>=0) ns=SLOPE_UP_LEFTTOP_AND_RIGHTBOTTOM;
  3586. if(h[0][2]==-1 && h[2][0]==-1 && h[0][0]>=0 && h[2][2]>=0 && h[0][1]>=0 && h[1][0]>=0 && h[1][2]>=0 && h[2][1]>=0) ns=SLOPE_UP_LEFTBOTTOM_AND_RIGHTTOP;
  3587. // that would just be another solution:
  3588. // if(h[0][0]==-1 && h[2][2]==-1 && h[2][0]>=0 && h[0][2]>=0 && h[1][0]>=0 && h[1][2]>=0 && h[0][1]>=0 && h[2][1]>=0) ns=SLOPE_UP_LEFTTOP_AND_RIGHTBOTTOM2;
  3589. // if(h[0][2]==-1 && h[2][0]==-1 && h[0][0]>=0 && h[2][2]>=0 && h[0][1]>=0 && h[1][0]>=0 && h[1][2]>=0 && h[2][1]>=0) ns=SLOPE_UP_LEFTBOTTOM_AND_RIGHTTOP2;
  3590. if(ns==-1)
  3591. if(h[1][0]==-1 && h[0][1]!=-1 && h[1][2]!=-1 && h[2][1]!=-1)
  3592. {
  3593. ns=SLOPE_UP_LEFT;
  3594. }
  3595. else if(h[0][1]==-1 && h[1][0]!=-1 && h[2][1]!=-1 && h[1][2]!=-1)
  3596. {
  3597. ns=SLOPE_UP_TOP;
  3598. }
  3599. else if(h[1][2]==-1 && h[0][1]!=-1 && h[1][0]!=-1 && h[2][1]!=-1)
  3600. {
  3601. ns=SLOPE_UP_RIGHT;
  3602. }
  3603. else if(h[2][1]==-1 && h[0][1]!=-1 && h[1][0]!=-1 && h[1][2]!=-1)
  3604. {
  3605. ns=SLOPE_UP_BOTTOM;
  3606. }
  3607. if(ns==-1)
  3608. {
  3609. if(h[0][0]==-2) ns=SLOPE_DOWN_BOTTOM;
  3610. if(h[2][0]==-2) ns=SLOPE_DOWN_RIGHT;
  3611. if(h[0][2]==-2) ns=SLOPE_DOWN_LEFT;
  3612. if(h[2][2]==-2) ns=SLOPE_DOWN_TOP;
  3613. }
  3614. if(ns==-1 && h[0][0]==-1)
  3615. {
  3616. if(h[1][0]==-1 && h[0][1]==-1 ) ns=SLOPE_DOWN_RIGHTBOTTOM;
  3617. else if(h[1][0]==0 && h[0][1]==0) ns=SLOPE_UP_LEFTTOP;
  3618. //else if(h[2][2]==1) ns=SLOPE_DOWN_BOTTOM;
  3619. }
  3620. if( ns==-1 && h[2][0]==-1)
  3621. {
  3622. if(h[1][0]==-1 && h[2][1]==-1 ) ns=SLOPE_DOWN_RIGHTTOP;
  3623. else if(h[1][0]==0 && h[2][1]==0) ns=SLOPE_UP_LEFTBOTTOM;
  3624. //else if(h[0][2]==1) ns=SLOPE_DOWN_RIGHT;
  3625. }
  3626. if( ns==-1 && h[0][2]==-1)
  3627. {
  3628. if(h[1][2]==-1 && h[0][1]==-1 ) ns=SLOPE_DOWN_LEFTBOTTOM;
  3629. else if(h[1][2]==0 && h[0][1]==0) ns=SLOPE_UP_RIGHTTOP;
  3630. //else if(h[2][0]==1) ns=SLOPE_DOWN_LEFT;
  3631. }
  3632. if( ns==-1 && h[2][2]==-1)
  3633. {
  3634. if(h[1][2]==-1 && h[2][1]==-1 ) ns=SLOPE_DOWN_LEFTTOP;
  3635. else if(h[1][2]==0 && h[2][1]==0) ns=SLOPE_UP_RIGHTBOTTOM;
  3636. //else if(h[0][0]==1) ns=SLOPE_DOWN_TOP;
  3637. }
  3638. if(ns==-1 && h[1][0]==-1 && h[2][1]==-1 ) ns=SLOPE_DOWN_RIGHTTOP;
  3639. if(ns==-1 && h[1][2]==-1 && h[2][1]==-1 ) ns=SLOPE_DOWN_LEFTTOP;
  3640. if(ns==-1 && h[1][0]==-1 && h[0][1]==-1 ) ns=SLOPE_DOWN_RIGHTBOTTOM;
  3641. if(ns==-1 && h[1][2]==-1 && h[0][1]==-1 ) ns=SLOPE_DOWN_LEFTBOTTOM;
  3642. //OutputDebugString("Applying changes()\n");
  3643. int rampbase=atoi((*tiles).sections["General"].values["RampBase"]);
  3644. int rampsmooth=atoi((*tiles).sections["General"].values["RampSmooth"]);
  3645. //if((rampbase==d.wTileSet || rampsmooth==d.wTileSet) && m.bSubTile==ns)
  3646. // return;
  3647. if(ns==-1 && (d.wTileSet==rampbase || d.wTileSet==rampsmooth) && d.bMorphable)
  3648. {
  3649. SetTileAt(dwPos, 0, 0);
  3650. }
  3651. if(d.bMorphable && ns!=-1)
  3652. {
  3653. SetTileAt(dwPos, GetTileID(rampbase, ns-1), 0);
  3654. }
  3655. /*if(ns!=-1 || checkOtherSlopes)
  3656. {
  3657. for(i=-1;i<2;i++)
  3658. {
  3659. for(e=-1;e<2;e++)
  3660. {
  3661. int pos=dwPos+(i)+(e)*m_IsoSize;
  3662. if(pos>0 && pos<m_IsoSize*m_IsoSize)
  3663. {
  3664. CreateSlopesAt(pos);
  3665. }
  3666. }
  3667. }
  3668. }*//*
  3669. }*/
  3670. int CMapData::GetNecessarySlope(DWORD dwPos)
  3671. {
  3672. return 0;
  3673. }
  3674. DWORD CMapData::GetTileID(DWORD dwTileSet, int iTile)
  3675. {
  3676. int i, e;
  3677. DWORD tilecount = 0;
  3678. for (i = 0;i < 10000;i++)
  3679. {
  3680. CString tset;
  3681. char c[50];
  3682. itoa(i, c, 10);
  3683. int e;
  3684. for (e = 0;e < 4 - strlen(c);e++)
  3685. tset += "0";
  3686. tset += c;
  3687. CString sec = "TileSet";
  3688. sec += tset;
  3689. if (tiles->sections.find(sec) == tiles->sections.end()) return 0xFFFFFFFF;
  3690. for (e = 0;e < atoi(tiles->sections[sec].values["TilesInSet"]);e++)
  3691. {
  3692. if (i == dwTileSet && e == iTile) return tilecount;
  3693. tilecount++;
  3694. }
  3695. }
  3696. return tilecount;
  3697. }
  3698. void CMapData::SetReserved(DWORD dwPos, BYTE val)
  3699. {
  3700. fielddata[dwPos].bReserved = val;
  3701. }
  3702. void CMapData::HideField(DWORD dwPos, BOOL bHide)
  3703. {
  3704. fielddata[dwPos].bHide = bHide;
  3705. }
  3706. void CMapData::UpdateTubes(BOOL bSave)
  3707. {
  3708. if (!bSave)
  3709. {
  3710. m_tubes.clear();
  3711. if (m_mapfile.sections.find("Tubes") == m_mapfile.sections.end())
  3712. return;
  3713. auto& tubeSection = m_mapfile.sections["Tubes"];
  3714. std::uint16_t secSize = tubeSection.values.size();
  3715. m_tubes.reserve(secSize + 10);
  3716. for (auto& [sTubeId, value] : tubeSection)
  3717. {
  3718. const auto tubeId = std::atoi(sTubeId);
  3719. if (tubeId < 0 || tubeId >= std::numeric_limits<std::uint16_t>::max())
  3720. continue;
  3721. m_tubes.push_back(std::make_unique<CTube>(static_cast<std::uint16_t>(tubeId), value.GetString()));
  3722. }
  3723. }
  3724. else
  3725. {
  3726. }
  3727. }
  3728. void CMapData::SetTube(CTube* lpTI)
  3729. {
  3730. CString sTubeId;
  3731. if (lpTI->hasId())
  3732. sTubeId = std::to_string(lpTI->getId()).c_str();
  3733. else
  3734. {
  3735. for (std::uint16_t i = 0;i < 10000;i++)
  3736. {
  3737. sTubeId = std::to_string(i).c_str();
  3738. if (m_mapfile.sections["Tubes"].values.find(sTubeId) == m_mapfile.sections["Tubes"].values.end())
  3739. {
  3740. lpTI->setId(i);
  3741. break;
  3742. }
  3743. }
  3744. }
  3745. if (!lpTI->hasId())
  3746. return;
  3747. m_mapfile.sections["Tubes"].values[sTubeId] = lpTI->toString().c_str();
  3748. UpdateTubes(FALSE);
  3749. }
  3750. CTube* CMapData::GetTube(std::uint16_t wID)
  3751. {
  3752. auto it = std::find_if(m_tubes.begin(), m_tubes.end(), [wID](const auto& el) {return el->getId() == wID;});
  3753. if (it == m_tubes.end())
  3754. return nullptr;
  3755. return it->get();
  3756. }
  3757. void CMapData::DeleteTube(std::uint16_t wID)
  3758. {
  3759. if (m_mapfile.sections.find("Tubes") == m_mapfile.sections.end())
  3760. return;
  3761. auto& tubeSection = m_mapfile.sections["Tubes"];
  3762. const CString sTubeId = std::to_string(wID).c_str();
  3763. std::erase_if(tubeSection.values, [&sTubeId](const auto& el) {return el.first == sTubeId;});
  3764. //CString id1 = *m_mapfile.sections["Tubes"].GetValueName(wID);
  3765. /*CTube i1 = m_tubes[wID];
  3766. vector<CString> toErase;
  3767. toErase.reserve(10);
  3768. // we delete every tube with same starting coordinates or when starting coordinate of i1 is ending of curi
  3769. int i;
  3770. for (i = 0;i < m_tubes.size();i++)
  3771. {
  3772. CTube& curi = m_tubes[i];
  3773. if ((curi.getEndX() == i1.getStartX() && curi.getEndY() == i1.getStartY()) || (curi.getStartX() == i1.getStartX() && curi.getStartY() == i1.getStartY()))
  3774. {
  3775. toErase.push_back(*m_mapfile.sections["Tubes"].GetValueName(i));
  3776. }
  3777. }
  3778. for (i = 0;i < toErase.size();i++)
  3779. {
  3780. m_mapfile.sections["Tubes"].values.erase(toErase[i]);
  3781. }*/
  3782. UpdateTubes(FALSE);
  3783. }
  3784. int CMapData::GetInfantryCountAt(DWORD dwPos)
  3785. {
  3786. int i;
  3787. int sc = 0;
  3788. for (i = 0;i < SUBPOS_COUNT;i++)
  3789. {
  3790. if (fielddata[dwPos].infantry[i] > -1) sc++;
  3791. }
  3792. return sc;
  3793. }
  3794. /*
  3795. Checks if the map data is valid
  3796. May fail if the user changed the tileset manually,
  3797. or if loading maps made with modified tilesets
  3798. */
  3799. BOOL CMapData::CheckMapPackData()
  3800. {
  3801. int i;
  3802. for (i = 0;i < fielddata_size;i++)
  3803. {
  3804. int gr = fielddata[i].wGround;
  3805. if (gr != 0xFFFF && gr >= (*tiledata_count))
  3806. return FALSE;
  3807. if (gr == 0xFFFF) gr = 0;
  3808. if ((*tiledata)[gr].wTileCount <= fielddata[i].bSubTile) return FALSE;
  3809. }
  3810. return TRUE;
  3811. }
  3812. /*
  3813. Takes a snapshot of the map at a certain location.
  3814. Be aware that this won´t make a copy of any units etc.
  3815. This is used for undo and similar things (like displaying and immediatly removing tiles when moving
  3816. the mouse on the map before placing a tile).
  3817. This method is very fast, as long as you don´t copy the whole map all the time.
  3818. */
  3819. void CMapData::TakeSnapshot(BOOL bEraseFollowing, int left, int top, int right, int bottom)
  3820. {
  3821. DWORD dwOldSnapShotCount = dwSnapShotCount;
  3822. if (left < 0) left = 0;
  3823. if (top < 0) top = 0;
  3824. if (right > m_IsoSize) right = m_IsoSize;
  3825. if (bottom > m_IsoSize) bottom = m_IsoSize;
  3826. if (right == 0) right = m_IsoSize;
  3827. if (bottom == 0) bottom = m_IsoSize;
  3828. int e;
  3829. if (bEraseFollowing)
  3830. {
  3831. for (e = dwSnapShotCount - 1;e > m_cursnapshot;e--)
  3832. {
  3833. delete[] m_snapshots[e].bHeight;
  3834. delete[] m_snapshots[e].bMapData;
  3835. delete[] m_snapshots[e].bSubTile;
  3836. delete[] m_snapshots[e].bMapData2;
  3837. delete[] m_snapshots[e].overlay;
  3838. delete[] m_snapshots[e].overlaydata;
  3839. delete[] m_snapshots[e].wGround;
  3840. delete[] m_snapshots[e].bRedrawTerrain;
  3841. delete[] m_snapshots[e].bRNDData;
  3842. // m_snapshots[0].mapfile.Clear();
  3843. }
  3844. dwSnapShotCount = m_cursnapshot + 1;
  3845. }
  3846. dwSnapShotCount += 1;
  3847. m_cursnapshot++;
  3848. if (dwSnapShotCount > 64)
  3849. {
  3850. dwSnapShotCount = 64;
  3851. m_cursnapshot = 63;
  3852. int i;
  3853. delete[] m_snapshots[0].bHeight;
  3854. delete[] m_snapshots[0].bMapData;
  3855. delete[] m_snapshots[0].bSubTile;
  3856. delete[] m_snapshots[0].bMapData2;
  3857. delete[] m_snapshots[0].overlay;
  3858. delete[] m_snapshots[0].overlaydata;
  3859. delete[] m_snapshots[0].wGround;
  3860. delete[] m_snapshots[0].bRedrawTerrain;
  3861. delete[] m_snapshots[0].bRNDData;
  3862. // m_snapshots[0].mapfile.Clear();
  3863. for (i = 1;i < dwSnapShotCount;i++)
  3864. {
  3865. m_snapshots[i - 1] = m_snapshots[i];
  3866. }
  3867. }
  3868. else
  3869. {
  3870. SNAPSHOTDATA* b = new(SNAPSHOTDATA[dwSnapShotCount]);
  3871. if (m_snapshots)
  3872. {
  3873. memcpy(b, m_snapshots, sizeof(SNAPSHOTDATA) * (dwSnapShotCount - 1));
  3874. delete[] m_snapshots;
  3875. }
  3876. m_snapshots = b;
  3877. }
  3878. m_cursnapshot = dwSnapShotCount - 1;
  3879. SNAPSHOTDATA ss = m_snapshots[dwSnapShotCount - 1];
  3880. // ss.mapfile=m_mapfile;
  3881. int width, height;
  3882. width = right - left;
  3883. height = bottom - top;
  3884. int size = width * height;
  3885. ss.left = left;
  3886. ss.top = top;
  3887. ss.right = right;
  3888. ss.bottom = bottom;
  3889. ss.bHeight = new(BYTE[size]);
  3890. ss.bMapData = new(WORD[size]);
  3891. ss.bSubTile = new(BYTE[size]);
  3892. ss.bMapData2 = new(BYTE[size]);
  3893. ss.wGround = new(WORD[size]);
  3894. ss.overlay = new(BYTE[size]);
  3895. ss.overlaydata = new(BYTE[size]);
  3896. ss.bRedrawTerrain = new(BOOL[size]);
  3897. ss.bRNDData = new(BYTE[size]);
  3898. int i;
  3899. for (i = 0;i < width;i++)
  3900. {
  3901. for (e = 0;e < height;e++)
  3902. {
  3903. int pos_w, pos_r;
  3904. pos_w = i + e * width;
  3905. pos_r = left + i + (top + e) * m_IsoSize;
  3906. ss.bHeight[pos_w] = fielddata[pos_r].bHeight;
  3907. ss.bMapData[pos_w] = fielddata[pos_r].bMapData;
  3908. ss.bSubTile[pos_w] = fielddata[pos_r].bSubTile;
  3909. ss.bMapData2[pos_w] = fielddata[pos_r].bMapData2;
  3910. ss.wGround[pos_w] = fielddata[pos_r].wGround;
  3911. ss.overlay[pos_w] = fielddata[pos_r].overlay;
  3912. ss.overlaydata[pos_w] = fielddata[pos_r].overlaydata;
  3913. ss.bRedrawTerrain[pos_w] = fielddata[pos_r].bRedrawTerrain;
  3914. ss.bRNDData[pos_w] = fielddata[pos_r].bRNDImage;
  3915. }
  3916. }
  3917. m_snapshots[dwSnapShotCount - 1] = ss;
  3918. }
  3919. /*
  3920. Just uses the last SnapShot to reverse changes on the map.
  3921. Very fast
  3922. */
  3923. void CMapData::Undo()
  3924. {
  3925. if (dwSnapShotCount == 0) return;
  3926. if (m_cursnapshot < 0) return;
  3927. //dwSnapShotCount--;
  3928. m_cursnapshot -= 1;
  3929. int left, top, width, height;
  3930. left = m_snapshots[m_cursnapshot + 1].left;
  3931. top = m_snapshots[m_cursnapshot + 1].top;
  3932. width = m_snapshots[m_cursnapshot + 1].right - left;
  3933. height = m_snapshots[m_cursnapshot + 1].bottom - top;
  3934. const bool mp = IsMultiplayer();
  3935. int i, e;
  3936. for (i = 0;i < width;i++)
  3937. {
  3938. for (e = 0;e < height;e++)
  3939. {
  3940. int pos_w, pos_r;
  3941. pos_r = i + e * width;
  3942. pos_w = left + i + (top + e) * m_IsoSize;
  3943. fielddata[pos_w].bHeight = m_snapshots[m_cursnapshot + 1].bHeight[pos_r];
  3944. fielddata[pos_w].bMapData = m_snapshots[m_cursnapshot + 1].bMapData[pos_r];
  3945. fielddata[pos_w].bSubTile = m_snapshots[m_cursnapshot + 1].bSubTile[pos_r];
  3946. fielddata[pos_w].bMapData2 = m_snapshots[m_cursnapshot + 1].bMapData2[pos_r];
  3947. fielddata[pos_w].wGround = m_snapshots[m_cursnapshot + 1].wGround[pos_r];
  3948. RemoveOvrlMoney(fielddata[pos_w].overlay, fielddata[pos_w].overlaydata);
  3949. fielddata[pos_w].overlay = m_snapshots[m_cursnapshot + 1].overlay[pos_r];
  3950. fielddata[pos_w].overlaydata = m_snapshots[m_cursnapshot + 1].overlaydata[pos_r];
  3951. AddOvrlMoney(fielddata[pos_w].overlay, fielddata[pos_w].overlaydata);
  3952. fielddata[pos_w].bRedrawTerrain = m_snapshots[m_cursnapshot + 1].bRedrawTerrain[pos_r];
  3953. fielddata[pos_w].bRNDImage = m_snapshots[m_cursnapshot + 1].bRNDData[pos_r];
  3954. Mini_UpdatePos(left + i, top + e, mp);
  3955. }
  3956. }
  3957. // no need for SmoothTiberium: handled externally, because we undo more than just the very needed area
  3958. // when changing overlay!
  3959. }
  3960. BOOL CMapData::GetLocalSize(RECT* rect) const
  3961. {
  3962. if (!isInitialized) return FALSE;
  3963. *rect = m_vismaprect;
  3964. return TRUE;
  3965. }
  3966. /*
  3967. Opposite of Undo(). If possible, redoes the changes.
  3968. Very fast.
  3969. */
  3970. void CMapData::Redo()
  3971. {
  3972. if (dwSnapShotCount <= m_cursnapshot + 1 || !dwSnapShotCount) return;
  3973. m_cursnapshot += 1; // dwSnapShotCount-1;
  3974. if (m_cursnapshot + 1 >= dwSnapShotCount) m_cursnapshot = dwSnapShotCount - 2;
  3975. int left, top, width, height;
  3976. left = m_snapshots[m_cursnapshot + 1].left;
  3977. top = m_snapshots[m_cursnapshot + 1].top;
  3978. width = m_snapshots[m_cursnapshot + 1].right - left;
  3979. height = m_snapshots[m_cursnapshot + 1].bottom - top;
  3980. int i, e;
  3981. const bool mp = IsMultiplayer();
  3982. for (i = 0;i < width;i++)
  3983. {
  3984. for (e = 0;e < height;e++)
  3985. {
  3986. int pos_w, pos_r;
  3987. pos_r = i + e * width;
  3988. pos_w = left + i + (top + e) * m_IsoSize;
  3989. fielddata[pos_w].bHeight = m_snapshots[m_cursnapshot + 1].bHeight[pos_r];
  3990. fielddata[pos_w].bMapData = m_snapshots[m_cursnapshot + 1].bMapData[pos_r];
  3991. fielddata[pos_w].bSubTile = m_snapshots[m_cursnapshot + 1].bSubTile[pos_r];
  3992. fielddata[pos_w].bMapData2 = m_snapshots[m_cursnapshot + 1].bMapData2[pos_r];
  3993. fielddata[pos_w].wGround = m_snapshots[m_cursnapshot + 1].wGround[pos_r];
  3994. RemoveOvrlMoney(fielddata[pos_w].overlay, fielddata[pos_w].overlaydata);
  3995. fielddata[pos_w].overlay = m_snapshots[m_cursnapshot + 1].overlay[pos_r];
  3996. fielddata[pos_w].overlaydata = m_snapshots[m_cursnapshot + 1].overlaydata[pos_r];
  3997. AddOvrlMoney(fielddata[pos_w].overlay, fielddata[pos_w].overlaydata);
  3998. fielddata[pos_w].bRedrawTerrain = m_snapshots[m_cursnapshot + 1].bRedrawTerrain[pos_r];
  3999. fielddata[pos_w].bRNDImage = m_snapshots[m_cursnapshot + 1].bRNDData[pos_r];
  4000. Mini_UpdatePos(left + i, top + e, mp);
  4001. }
  4002. }
  4003. /*
  4004. int i;
  4005. for(i=0;i<fielddata_size;i++)
  4006. {
  4007. fielddata[i].bHeight=m_snapshots[m_cursnapshot+1].bHeight[i];
  4008. fielddata[i].bMapData=m_snapshots[m_cursnapshot+1].bMapData[i];
  4009. fielddata[i].bSubTile=m_snapshots[m_cursnapshot+1].bSubTile[i];
  4010. fielddata[i].bMapData2=m_snapshots[m_cursnapshot+1].bMapData2[i];
  4011. fielddata[i].wGround=m_snapshots[m_cursnapshot+1].wGround[i];
  4012. fielddata[i].overlay=m_snapshots[m_cursnapshot+1].overlay[i];
  4013. fielddata[i].overlaydata=m_snapshots[m_cursnapshot+1].overlaydata[i];
  4014. fielddata[i].bRedrawTerrain=m_snapshots[m_cursnapshot+1].bRedrawTerrain[i];
  4015. }
  4016. */
  4017. }
  4018. static const int tile_to_lat_count = 7;
  4019. static const CString tile_to_lat[tile_to_lat_count][3] = {
  4020. {"SandTile", "ClearToSandLat", "ClearTile"},
  4021. {"GreenTile", "ClearToGreenLat", "ClearTile"},
  4022. {"RoughTile", "ClearToRoughLat", "ClearTile"},
  4023. {"PaveTile", "ClearToPaveLat", "ClearTile"},
  4024. {"BlueMoldTile", "ClearToBlueMoldLat", ""}, //"ClearTile"}, // TODO: fix
  4025. {"CrystalTile", "ClearToCrystalLat", "ClearTile"},
  4026. {"SwampTile", "WaterToSwampLat", "WaterSet"}
  4027. };
  4028. bool CMapData::hasLat(WORD wGround) const
  4029. {
  4030. if (wGround >= *tiledata_count)
  4031. return false;
  4032. const auto set = (*tiledata)[wGround].wTileSet;
  4033. const auto& sec = tiles->sections["General"];
  4034. const CString empty;
  4035. for (int i = 0; i < tile_to_lat_count; ++i)
  4036. {
  4037. const int tile = atoi(sec.GetValueByName(tile_to_lat[i][0], empty));
  4038. const int lat = atoi(sec.GetValueByName(tile_to_lat[i][1], empty));
  4039. const int target_tile = atoi(sec.GetValueByName(tile_to_lat[i][2], empty));
  4040. if (lat &&
  4041. (set == tile ||
  4042. set == lat ||
  4043. set == target_tile))
  4044. return true;
  4045. }
  4046. return false;
  4047. }
  4048. void CMapData::SmoothAllAt(DWORD dwPos)
  4049. {
  4050. if (theApp.m_Options.bDisableAutoLat) return;
  4051. if (dwPos > fielddata_size) return;
  4052. int set = 0, ground = fielddata[dwPos].wGround;
  4053. if (ground == 0xFFFF) ground = 0;
  4054. set = (*tiledata)[ground].wTileSet;
  4055. const auto& sec = tiles->sections["General"];
  4056. const CString empty;
  4057. for (int i = 0; i < tile_to_lat_count; ++i)
  4058. {
  4059. const int tile = atoi(sec.GetValueByName(tile_to_lat[i][0], empty));
  4060. const int lat = atoi(sec.GetValueByName(tile_to_lat[i][1], empty));
  4061. const int target_tile = atoi(sec.GetValueByName(tile_to_lat[i][2], empty));
  4062. if (strlen(tile_to_lat[i][2]) &&
  4063. lat &&
  4064. (set == tile ||
  4065. set == lat))
  4066. SmoothAt(dwPos, tile, lat, target_tile);
  4067. }
  4068. }
  4069. void CMapData::CreateShore(int left, int top, int right, int bottom, BOOL bRemoveUseless)
  4070. {
  4071. int i;
  4072. int isosize = Map->GetIsoSize();
  4073. int mapsize = isosize * isosize;
  4074. int mapwidth = Map->GetWidth();
  4075. int mapheight = Map->GetHeight();
  4076. // int shoreset=atoi((*tiles).sections["General"].values["ShorePieces"]);
  4077. short* tsets = new(short[mapsize]);
  4078. BYTE* terrain = new(BYTE[mapsize]);
  4079. int* tile = new(int[mapsize]);
  4080. BOOL* hasChanged = new(BOOL[isosize * isosize]);
  4081. BOOL* noChange = new(BOOL[isosize * isosize]);
  4082. //BOOL* replaced=new(BOOL[isosize*isosize]); // replaced by water<->ground
  4083. memset(hasChanged, 0, sizeof(BOOL) * isosize * isosize);
  4084. memset(noChange, 0, sizeof(BOOL) * isosize * isosize);
  4085. //memset(replaced, 0, sizeof(BOOL)*isosize*isosize);
  4086. int watercliffset = atoi((*tiles).sections["General"].values["WaterCliffs"]);
  4087. int xx, yy;
  4088. for (i = 0;i < *tiledata_count;i++)
  4089. {
  4090. if ((*tiledata)[i].wTileSet == waterset && (*tiledata)[i].cx == 1 && (*tiledata)[i].cy == 1) break;
  4091. }
  4092. int smallwater = i;
  4093. last_succeeded_operation = 7002;
  4094. map<int, int> softsets;
  4095. CString sec = "SoftTileSets";
  4096. for (i = 0;i < g_data.sections[sec].values.size();i++)
  4097. {
  4098. CString tset = *g_data.sections[sec].GetValueName(i);
  4099. TruncSpace(tset);
  4100. int p = (*tiles).sections["General"].FindName(tset);
  4101. if (p < 0) continue;
  4102. int set = atoi(*(*tiles).sections["General"].GetValue(p));
  4103. if (atoi(*g_data.sections[sec].GetValue(i))) softsets[set] = 1;
  4104. }
  4105. last_succeeded_operation = 7001;
  4106. // remove partial shore pieces (wrong ones)
  4107. for (xx = left - 2;xx < right + 2;xx++)
  4108. {
  4109. for (yy = top - 2;yy < bottom + 2;yy++)
  4110. {
  4111. if (xx < 1 || yy < 1 || xx + yy<mapwidth + 1 || xx + yy>mapwidth + mapheight * 2 || (yy + 1 > mapwidth && xx - 1 < yy - mapwidth) || (xx + 1 > mapwidth && yy + mapwidth - 1 < xx)) continue;
  4112. int pos = xx + yy * isosize;
  4113. if (noChange[pos]) continue;
  4114. FIELDDATA* fd = Map->GetFielddataAt(pos);
  4115. int ground = fd->wGround;
  4116. if (ground == 0xFFFF) ground = 0;
  4117. TILEDATA& td = (*tiledata)[ground];
  4118. if (td.wTileSet != shoreset) continue;
  4119. // we have a shore piece here. check if it is set correct
  4120. BOOL bCorrect = TRUE;
  4121. int of = fd->bSubTile;
  4122. int ox = of / td.cy;
  4123. int oy = of % td.cy;
  4124. int xxx, yyy;
  4125. int p = 0;
  4126. for (xxx = xx - ox;xxx < xx + td.cx - ox;xxx++)
  4127. {
  4128. for (yyy = yy - oy;yyy < yy + td.cy - oy;yyy++)
  4129. {
  4130. int pos = xxx + yyy * isosize;
  4131. if (td.tiles[p].pic != NULL)
  4132. {
  4133. FIELDDATA* curf = Map->GetFielddataAt(pos);
  4134. int curg = curf->wGround;
  4135. if (curg == 0xFFFF) curg = 0;
  4136. if (curg != ground || curf->bSubTile != p)
  4137. {
  4138. bCorrect = FALSE;
  4139. break;
  4140. }
  4141. }
  4142. p++;
  4143. }
  4144. if (!bCorrect) break;
  4145. }
  4146. if (!bCorrect)
  4147. {
  4148. int iWaterFound = 0;
  4149. /*for(xxx=xx-1;xxx<=xx+1;xxx++)
  4150. {
  4151. for(yyy=yy-1;yyy<=yy+1;yyy++)
  4152. {
  4153. if(xxx==xx && yyy==yy) continue;
  4154. int pos=xxx+yyy*isosize;
  4155. FIELDDATA* curf=Map->GetFielddataAt(pos);
  4156. int curg=curf->wGround;
  4157. if(curg==0xFFFF) curg=0;
  4158. if((*tiledata)[curg].tiles[curf->bSubTile].bHackedTerrainType==TERRAINTYPE_WATER)
  4159. iWaterFound++;
  4160. }
  4161. }*/
  4162. int pos = xx + yy * isosize;
  4163. FIELDDATA* curf = Map->GetFielddataAt(pos);
  4164. int curg = curf->wGround;
  4165. if (curg == 0xFFFF) curg = 0;
  4166. if ((*tiledata)[curg].tiles[curf->bSubTile].bHackedTerrainType == TERRAINTYPE_WATER) iWaterFound = 8;
  4167. if (iWaterFound > 7)
  4168. {
  4169. for (i = 0;i < *tiledata_count;i++)
  4170. {
  4171. if ((*tiledata)[i].wTileSet == waterset && (*tiledata)[i].cx == 1 && (*tiledata)[i].cy == 1) break;
  4172. }
  4173. SetTileAt(xx + yy * isosize, i, 0);
  4174. noChange[xx + yy * isosize] = FALSE;
  4175. //replaced[xx+yy*isosize]=TRUE;
  4176. }
  4177. else
  4178. {
  4179. SetTileAt(xx + yy * isosize, 0, 0);
  4180. noChange[xx + yy * isosize] = FALSE;
  4181. //replaced[xx+yy*isosize]=TRUE;
  4182. }
  4183. }
  4184. }
  4185. }
  4186. // remove too small water and ground pieces (NEW)
  4187. if (bRemoveUseless)
  4188. {
  4189. for (xx = left;xx < right;xx++)
  4190. {
  4191. for (yy = top;yy < bottom;yy++)
  4192. {
  4193. if (xx < 1 || yy < 1 || xx + yy<mapwidth + 1 || xx + yy>mapwidth + mapheight * 2 || (yy + 1 > mapwidth && xx - 1 < yy - mapwidth) || (xx + 1 > mapwidth && yy + mapwidth - 1 < xx)) continue;
  4194. int dwPos = xx + yy * isosize;
  4195. //if(noChange[dwPos]) continue;
  4196. FIELDDATA* fd = Map->GetFielddataAt(dwPos);
  4197. int ground = fd->wGround;
  4198. if (ground == 0xFFFF) ground = 0;
  4199. TILEDATA& td = (*tiledata)[ground];
  4200. if (softsets.find(td.wTileSet) == softsets.end()) continue;
  4201. if (td.tiles[fd->bSubTile].bHackedTerrainType != TERRAINTYPE_WATER && td.tiles[fd->bSubTile].bHackedTerrainType != TERRAINTYPE_GROUND) continue;
  4202. int ts[3][3]; // terrain info
  4203. int i, e;
  4204. for (i = 0;i < 3; i++)
  4205. {
  4206. for (e = 0;e < 3;e++)
  4207. {
  4208. int pos = dwPos + (i - 1) + (e - 1) * m_IsoSize;
  4209. if (pos < 0 || pos >= fielddata_size)
  4210. {
  4211. ts[i][e] = 0;
  4212. }
  4213. else
  4214. {
  4215. FIELDDATA m2 = *GetFielddataAt(pos);
  4216. if (m2.wGround == 0xFFFF) m2.wGround = 0;
  4217. ts[i][e] = (*tiledata)[m2.wGround].tiles[m2.bSubTile].bHackedTerrainType;
  4218. }
  4219. }
  4220. }
  4221. if ((ts[1][0] != ts[1][1] && ts[1][2] != ts[1][1]) ||
  4222. (ts[0][1] != ts[1][1] && ts[2][1] != ts[1][1]))
  4223. {
  4224. if (ts[1][1] == TERRAINTYPE_WATER)
  4225. {
  4226. SetTileAt(dwPos, 0, 0);
  4227. //replaced[dwPos]=TRUE;
  4228. }
  4229. else if (ts[1][1] == TERRAINTYPE_GROUND)
  4230. {
  4231. if ((ts[1][0] == TERRAINTYPE_WATER && ts[1][2] == TERRAINTYPE_WATER) || (ts[0][1] == TERRAINTYPE_WATER && ts[2][1] == TERRAINTYPE_WATER))
  4232. {
  4233. SetTileAt(dwPos, smallwater, 0);
  4234. //replaced[dwPos]=TRUE;
  4235. }
  4236. }
  4237. }
  4238. }
  4239. }
  4240. }
  4241. last_succeeded_operation = 7003;
  4242. // retrieve non-changeable fields
  4243. for (xx = left;xx < right;xx++)
  4244. {
  4245. for (yy = top;yy < bottom;yy++)
  4246. {
  4247. if (xx < 1 || yy < 1 || xx + yy<mapwidth + 1 || xx + yy>mapwidth + mapheight * 2 || (yy + 1 > mapwidth && xx - 1 < yy - mapwidth) || (xx + 1 > mapwidth && yy + mapwidth - 1 < xx)) continue;
  4248. int pos = xx + yy * isosize;
  4249. FIELDDATA* fd = GetFielddataAt(pos);
  4250. int ground = fd->wGround;
  4251. if (ground == 0xFFFF) ground = 0;
  4252. tsets[pos] = (*tiledata)[ground].wTileSet;
  4253. terrain[pos] = (*tiledata)[ground].tiles[fd->bSubTile].bHackedTerrainType;
  4254. tile[pos] = ground;
  4255. if (xx >= left && xx < right && yy >= top && yy < bottom)
  4256. {
  4257. if (softsets.find((*tiledata)[ground].wTileSet) == softsets.end()/*(*tiledata)[ground].wTileSet==cliffset || (*tiledata)[ground].wTileSet==watercliffset*/)
  4258. {
  4259. noChange[pos] = TRUE; continue;
  4260. }
  4261. TILEDATA& td = (*tiledata)[ground];
  4262. if (td.wTileSet == shoreset)
  4263. {
  4264. int of = fd->bSubTile;
  4265. int ox = of / td.cy;
  4266. int oy = of % td.cy;
  4267. if (xx - ox < left || yy - oy < top || xx - ox + td.cx >= right || yy - oy + td.cy >= bottom)
  4268. {
  4269. /*if(!replaced[pos])*/ noChange[pos] = TRUE;
  4270. }
  4271. }
  4272. }
  4273. }
  4274. }
  4275. /*CProgressCtrl pc;
  4276. RECT r,rw;
  4277. GetWindowRect(&r);
  4278. rw.left=r.left+(r.right-r.left)/2-80;
  4279. rw.top=r.top+(r.bottom-r.top)/2-15;
  4280. rw.right=rw.left+160;
  4281. rw.bottom=rw.top+30;
  4282. pc.Create(WS_POPUPWINDOW | PBS_SMOOTH, rw, m_view.m_isoview, 0);*/
  4283. int tStart, tEnd;
  4284. tStart = -1;
  4285. tEnd = 0;
  4286. for (i = 0;i < *tiledata_count;i++)
  4287. {
  4288. if ((*tiledata)[i].wTileSet == shoreset)
  4289. {
  4290. if (tStart < 0) tStart = i;
  4291. if (i > tEnd) tEnd = i;
  4292. }
  4293. }
  4294. /*pc.SetRange(0, (tEnd-tStart)*2);
  4295. pc.ShowWindow(SW_SHOW);
  4296. pc.RedrawWindow();*/
  4297. last_succeeded_operation = 7004;
  4298. for (i = tStart;i <= tEnd;i++)
  4299. {
  4300. /*pc.SetPos(i-tStart);
  4301. pc.UpdateWindow();*/
  4302. TILEDATA& td = (*tiledata)[i];
  4303. if (td.wTileSet == shoreset)
  4304. {
  4305. int pos = i - tStart;
  4306. if (pos != 4 && pos != 5 && pos != 12 && pos != 13 && pos != 20 && pos != 21 && pos != 28 && pos != 29
  4307. && pos != 6 && pos != 7 && pos != 14 && pos != 15 && pos != 22 && pos != 23 && pos != 30 && pos != 31 && (pos < 32 || pos>39))
  4308. continue;
  4309. int x, y;
  4310. int water_count = 0;
  4311. int p = 0;
  4312. for (x = 0;x < td.cx;x++)
  4313. {
  4314. for (y = 0;y < td.cy;y++)
  4315. {
  4316. if (td.tiles[p].bHackedTerrainType == TERRAINTYPE_WATER)
  4317. water_count++;
  4318. p++;
  4319. }
  4320. }
  4321. // tsets now has the tileset of every single field in range (x+16, y+16)
  4322. // terrain has the terrain type of every single field
  4323. int max_x = td.cx < 16 ? td.cx : 16;
  4324. int max_y = td.cy < 16 ? td.cy : 16;
  4325. for (x = left;x < right;x++)
  4326. {
  4327. for (y = top;y < bottom;y++)
  4328. {
  4329. last_succeeded_operation = 7010;
  4330. int xx, yy;
  4331. //if(!replaced[x+y*isosize] && (x<left || y<top || x>=right || y>=bottom)) continue;
  4332. if (x < 1 || y < 1 || x + y<mapwidth + 1 || x + y>mapwidth + mapheight * 2 || (y + 1 > mapwidth && x - 1 < y - mapwidth) || (x + 1 > mapwidth && y + mapwidth - 1 < x)) continue;
  4333. /*BOOL wat_ex=FALSE;
  4334. for(xx=x;xx<x+max_x;xx++)
  4335. {
  4336. for(yy=y;yy<y+max_y;yy++)
  4337. {
  4338. FIELDDATA* fd=Map->GetFielddataAt(xx+yy*isosize);
  4339. int ground=fd->wGround;
  4340. if(ground==0xFFFF) ground=0;
  4341. int tile_t=(*tiledata)[ground].tiles[fd->bSubTile].bHackedTerrainType;
  4342. if(tile_t==TERRAINTYPE_WATER || tile_t==0xa)
  4343. wat_ex=TRUE;
  4344. if(wat_ex) break;
  4345. }
  4346. if(wat_ex) break;
  4347. }
  4348. if(!wat_ex) continue;*/
  4349. BOOL bFits = TRUE;
  4350. int p = 0;
  4351. for (xx = x;xx < x + max_x;xx++)
  4352. {
  4353. for (yy = y;yy < y + max_y;yy++)
  4354. {
  4355. if (xx >= isosize || yy >= isosize) continue;
  4356. int tpos = i - tStart;
  4357. int xadd = 0, yadd = 0;
  4358. /*
  4359. if(tpos>=0 && tpos<=7) xadd=1;
  4360. if(tpos>=6 && tpos<=15) yadd=1;
  4361. if(tpos>=14 && tpos<=23) xadd=-1;
  4362. if(tpos>=22 && tpos<=31) yadd=-1;
  4363. if(tpos>=30 && tpos<=31) xadd=1;
  4364. if(tpos>=32 && tpos<=33)
  4365. {
  4366. xadd=1; yadd=1;
  4367. }
  4368. if(tpos>=34 && tpos<=35)
  4369. {
  4370. xadd=-1; yadd=1;
  4371. }
  4372. if(tpos>=36 && tpos<=37)
  4373. {
  4374. xadd=-1; yadd=-1;
  4375. }
  4376. if(tpos>=38 && tpos<=39)
  4377. {
  4378. xadd=1; yadd=-1;
  4379. }*/
  4380. /*if(tpos>=32 && tpos<=33)
  4381. {
  4382. xadd=1; yadd=1;
  4383. if(
  4384. terrain[xx+1+yy*isosize]==TERRAINTYPE_WATER || terrain[xx+(yy+1)*isosize]==TERRAINTYPE_WATER
  4385. )
  4386. {bFits=FALSE; break;}
  4387. }
  4388. if(tpos>=34 && tpos<=35)
  4389. {
  4390. xadd=-1; yadd=1;
  4391. if(
  4392. terrain[xx-1+yy*isosize]==TERRAINTYPE_WATER || terrain[xx+(yy+1)*isosize]==TERRAINTYPE_WATER
  4393. )
  4394. {bFits=FALSE; break;}
  4395. }
  4396. if(tpos>=36 && tpos<=37)
  4397. {
  4398. xadd=-1; yadd=-1;
  4399. if(
  4400. terrain[xx-1+yy*isosize]==TERRAINTYPE_WATER || terrain[xx+(yy-1)*isosize]==TERRAINTYPE_WATER
  4401. )
  4402. {bFits=FALSE; break;}
  4403. }
  4404. if(tpos>=38 && tpos<=39)
  4405. {
  4406. xadd=1; yadd=-1;
  4407. if(
  4408. terrain[xx+1+yy*isosize]==TERRAINTYPE_WATER || terrain[xx+(yy-1)*isosize]==TERRAINTYPE_WATER
  4409. )
  4410. {bFits=FALSE; break;}
  4411. }*/
  4412. last_succeeded_operation = 7011;
  4413. if (xadd && yadd)
  4414. {
  4415. if (tsets[xx + xadd + yy * isosize] == waterset || tsets[xx + (yy + yadd) * isosize] == waterset)
  4416. {
  4417. bFits = FALSE;
  4418. break;
  4419. }
  4420. }
  4421. int pos_water = xx + xadd + (yy + yadd) * isosize;
  4422. int pos_data = xx + yy * isosize;
  4423. BYTE& tile_t = td.tiles[p].bHackedTerrainType;
  4424. if (tsets[pos_data] == shoreset)
  4425. {
  4426. if (hasChanged[pos_data]) // only cancel if this routine set the shore
  4427. {
  4428. // curves are preferred
  4429. if ((max_x != 2 || max_y != 2 || water_count != 3))
  4430. {
  4431. if (!((max_x == 3 && max_y == 2) || (max_x == 2 && max_y == 3)))
  4432. {
  4433. bFits = FALSE;
  4434. break;
  4435. }
  4436. }
  4437. }
  4438. }
  4439. last_succeeded_operation = 7012;
  4440. // one step curves
  4441. if (noChange[pos_data])
  4442. {
  4443. bFits = FALSE;
  4444. break;
  4445. }
  4446. // 2 big shore pieces need special treatment
  4447. if (tile[pos_data] <= tEnd && tile[pos_data] >= tEnd - 2)
  4448. bFits = FALSE;
  4449. if (tile_t == TERRAINTYPE_WATER)
  4450. {
  4451. if (terrain[pos_water] != TERRAINTYPE_WATER)
  4452. {
  4453. bFits = FALSE;
  4454. }
  4455. }
  4456. else
  4457. {
  4458. if (terrain[pos_water] != TERRAINTYPE_GROUND)
  4459. //if(tsets[pos_water]==waterset)
  4460. {
  4461. bFits = FALSE;
  4462. }
  4463. }
  4464. if (!bFits) break;
  4465. p++;
  4466. }
  4467. if (!bFits) break;
  4468. }
  4469. last_succeeded_operation = 7012;
  4470. if (bFits) // ok, place shore (later we need to do random choose of the different tiles here
  4471. {
  4472. // find similar shore piece (randomness)
  4473. int count = 0;
  4474. int pieces[16];
  4475. int k;
  4476. TILEDATA& t_orig = (*tiledata)[i];
  4477. for (k = 0;k < *tiledata_count;k++)
  4478. {
  4479. TILEDATA& t = (*tiledata)[k];
  4480. if (t.bMarbleMadness) continue;
  4481. if (t.cx != t_orig.cx || t.cy != t_orig.cy) continue;
  4482. if (k != 4 && k != 5 && k != 12 && k != 13 && k != 20 && k != 21 && k != 28 && k != 29
  4483. && (k < 32 || k>39))
  4484. {
  4485. }
  4486. else continue;
  4487. int xx, yy;
  4488. BOOL bSame = TRUE;
  4489. int p = 0;
  4490. for (xx = 0;xx < t.cx;xx++)
  4491. {
  4492. for (yy = 0;yy < t.cy;yy++)
  4493. {
  4494. if (t.tiles[p].bHackedTerrainType != t_orig.tiles[p].bHackedTerrainType)
  4495. bSame = FALSE;
  4496. p++;
  4497. if (!bSame) break;
  4498. }
  4499. if (!bSame) break;
  4500. }
  4501. if (bSame && count < 16)
  4502. {
  4503. pieces[count] = k;
  4504. count++;
  4505. }
  4506. }
  4507. last_succeeded_operation = 7013;
  4508. k = ((float)rand() * count) / (float)RAND_MAX;
  4509. if (k >= count) k = count - 1;
  4510. k = pieces[k];
  4511. TILEDATA& t = (*tiledata)[k];
  4512. int p = 0;
  4513. int xx, yy;
  4514. int startheight = GetHeightAt(x + y * isosize);
  4515. for (xx = 0;xx < t.cx;xx++)
  4516. {
  4517. for (yy = 0;yy < t.cy;yy++)
  4518. {
  4519. if (x + xx >= isosize || y + yy >= isosize) continue;
  4520. int pos = x + xx + (y + yy) * isosize;
  4521. last_succeeded_operation = 7014;
  4522. if (t.tiles[p].pic != NULL)
  4523. {
  4524. SetHeightAt(pos, startheight + t.tiles[p].bZHeight);
  4525. SetTileAt(pos, k, p);
  4526. last_succeeded_operation = 7015;
  4527. tile[pos] = i;
  4528. tsets[pos] = (*tiledata)[k].wTileSet;
  4529. terrain[pos] = (*tiledata)[k].tiles[p].bHackedTerrainType;
  4530. hasChanged[pos] = TRUE;
  4531. if ((t.cx == 3 && t.cy == 2) || (t.cx == 2 && t.cy == 3)) noChange[pos] = TRUE;
  4532. }
  4533. p++;
  4534. }
  4535. }
  4536. }
  4537. }
  4538. }
  4539. }
  4540. }
  4541. last_succeeded_operation = 7005;
  4542. for (i = tStart;i <= tEnd;i++)
  4543. {
  4544. /*pc.SetPos(i-tStart+(tEnd-tStart));
  4545. pc.UpdateWindow();*/
  4546. TILEDATA& td = (*tiledata)[i];
  4547. if ((*tiledata)[i].wTileSet == shoreset)
  4548. {
  4549. int pos = i - tStart;
  4550. if (pos != 4 && pos != 5 && pos != 12 && pos != 13 && pos != 20 && pos != 21 && pos != 28 && pos != 29
  4551. && pos != 6 && pos != 7 && pos != 14 && pos != 15 && pos != 22 && pos != 23 && pos != 30 && pos != 31 && (pos < 32 || pos>39))
  4552. {
  4553. }
  4554. else continue;
  4555. int x, y;
  4556. int water_count = 0;
  4557. int p = 0;
  4558. for (x = 0;x < td.cx;x++)
  4559. {
  4560. for (y = 0;y < td.cy;y++)
  4561. {
  4562. if (td.tiles[p].bHackedTerrainType == TERRAINTYPE_WATER)
  4563. water_count++;
  4564. p++;
  4565. }
  4566. }
  4567. // tsets now has the tileset of every single field in range (x+16, y+16)
  4568. // terrain has the terrain type of every single field
  4569. int max_x = td.cx < 16 ? td.cx : 16;
  4570. int max_y = td.cy < 16 ? td.cy : 16;
  4571. for (x = left;x < right;x++)
  4572. {
  4573. for (y = top;y < bottom;y++)
  4574. {
  4575. int xx, yy;
  4576. //if(!replaced[x+y*isosize] && (x<left || y<top || x>=right || y>=bottom)) continue;
  4577. if (x < 1 || y < 1 || x + y<mapwidth + 1 || x + y>mapwidth + mapheight * 2 || (y + 1 > mapwidth && x - 1 < y - mapwidth) || (x + 1 > mapwidth && y + mapwidth - 1 < x)) continue;
  4578. /*BOOL wat_ex=FALSE;
  4579. for(xx=x;xx<x+max_x;xx++)
  4580. {
  4581. for(yy=y;yy<y+max_y;yy++)
  4582. {
  4583. FIELDDATA* fd=Map->GetFielddataAt(xx+yy*isosize);
  4584. int ground=fd->wGround;
  4585. if(ground==0xFFFF) ground=0;
  4586. int tile_t=(*tiledata)[ground].tiles[fd->bSubTile].bHackedTerrainType;
  4587. if(tile_t==TERRAINTYPE_WATER || tile_t==0xa)
  4588. wat_ex=TRUE;
  4589. if(wat_ex) break;
  4590. }
  4591. if(wat_ex) break;
  4592. }
  4593. if(!wat_ex) continue;*/
  4594. BOOL bFits = TRUE;
  4595. int p = 0;
  4596. for (xx = x;xx < x + max_x;xx++)
  4597. {
  4598. for (yy = y;yy < y + max_y;yy++)
  4599. {
  4600. if (xx >= isosize || yy >= isosize) continue;
  4601. int tpos = i - tStart;
  4602. int xadd = 0, yadd = 0;
  4603. /*if(tpos>=0 && tpos<=7) xadd=1;
  4604. if(tpos>=6 && tpos<=15) yadd=1;
  4605. if(tpos>=14 && tpos<=23) xadd=-1;
  4606. if(tpos>=22 && tpos<=31) yadd=-1;
  4607. if(tpos>=30 && tpos<=31) xadd=1;
  4608. if(tpos>=32 && tpos<=33)
  4609. {
  4610. xadd=1; yadd=1;
  4611. }
  4612. if(tpos>=34 && tpos<=35)
  4613. {
  4614. xadd=-1; yadd=1;
  4615. }
  4616. if(tpos>=36 && tpos<=37)
  4617. {
  4618. xadd=-1; yadd=-1;
  4619. }
  4620. if(tpos>=38 && tpos<=39)
  4621. {
  4622. xadd=1; yadd=-1;
  4623. }
  4624. if(xadd && yadd)
  4625. {
  4626. if(tsets[xx+xadd+yy*isosize]==waterset || tsets[xx+(yy+yadd)*isosize]==waterset)
  4627. {
  4628. bFits=FALSE;
  4629. break;
  4630. }
  4631. }*/
  4632. int pos_water = xx + xadd + (yy + yadd) * isosize;
  4633. int pos_data = xx + yy * isosize;
  4634. BYTE& tile_t = td.tiles[p].bHackedTerrainType;
  4635. if (tsets[pos_data] == shoreset)
  4636. {
  4637. if (hasChanged[pos_data]) // only cancel if this routine set the shore
  4638. {
  4639. // curves are preferred
  4640. if ((max_x != 2 || max_y != 2 || water_count != 3))
  4641. {
  4642. if (!((max_x == 3 && max_y == 2) || (max_x == 2 && max_y == 3)))
  4643. {
  4644. bFits = FALSE;
  4645. break;
  4646. }
  4647. }
  4648. }
  4649. }
  4650. // one step curves
  4651. if (noChange[pos_data])
  4652. {
  4653. bFits = FALSE;
  4654. break;
  4655. }
  4656. if (tile[pos_data] <= tEnd && tile[pos_data] >= tEnd - 2)
  4657. bFits = FALSE;
  4658. if (tile_t == TERRAINTYPE_WATER)
  4659. {
  4660. if (terrain[pos_water] != TERRAINTYPE_WATER)
  4661. {
  4662. bFits = FALSE;
  4663. }
  4664. }
  4665. else
  4666. {
  4667. if (terrain[pos_water] != TERRAINTYPE_GROUND)
  4668. //if(tsets[pos_water]==waterset)
  4669. {
  4670. bFits = FALSE;
  4671. }
  4672. }
  4673. if (!bFits) break;
  4674. p++;
  4675. }
  4676. if (!bFits) break;
  4677. }
  4678. last_succeeded_operation = 7031;
  4679. if (bFits) // ok, place shore
  4680. {
  4681. // find similar shore piece (randomness)
  4682. int count = 0;
  4683. int pieces[16];
  4684. int k;
  4685. TILEDATA& t_orig = (*tiledata)[i];
  4686. for (k = 0;k < *tiledata_count;k++)
  4687. {
  4688. TILEDATA& t = (*tiledata)[k];
  4689. if (t.cx != t_orig.cx || t.cy != t_orig.cy) continue;
  4690. if (t.bMarbleMadness) continue;
  4691. if (k != 4 && k != 5 && k != 12 && k != 13 && k != 20 && k != 21 && k != 28 && k != 29
  4692. && (k < 32 || k>39))
  4693. {
  4694. }
  4695. else continue;
  4696. int xx, yy;
  4697. BOOL bSame = TRUE;
  4698. int p = 0;
  4699. for (xx = 0;xx < t.cx;xx++)
  4700. {
  4701. for (yy = 0;yy < t.cy;yy++)
  4702. {
  4703. if (t.tiles[p].bHackedTerrainType != t_orig.tiles[p].bHackedTerrainType)
  4704. bSame = FALSE;
  4705. p++;
  4706. if (!bSame) break;
  4707. }
  4708. if (!bSame) break;
  4709. }
  4710. if (bSame && count < 16)
  4711. {
  4712. pieces[count] = k;
  4713. count++;
  4714. }
  4715. }
  4716. last_succeeded_operation = 7032;
  4717. k = ((float)rand() * count) / (float)RAND_MAX;
  4718. if (k >= count) k = count - 1;
  4719. k = pieces[k];
  4720. TILEDATA& t = (*tiledata)[k];
  4721. int p = 0;
  4722. int xx, yy;
  4723. int startheight = GetHeightAt(x + y * isosize);
  4724. for (xx = 0;xx < t.cx;xx++)
  4725. {
  4726. for (yy = 0;yy < t.cy;yy++)
  4727. {
  4728. if (x + xx >= isosize || y + yy >= isosize) continue;
  4729. int pos = x + xx + (y + yy) * isosize;
  4730. if (t.tiles[p].pic != NULL)
  4731. {
  4732. SetHeightAt(pos, startheight + t.tiles[p].bZHeight);
  4733. SetTileAt(pos, k, p);
  4734. tile[pos] = i;
  4735. tsets[pos] = (*tiledata)[k].wTileSet;
  4736. terrain[pos] = (*tiledata)[k].tiles[p].bHackedTerrainType;
  4737. hasChanged[pos] = TRUE;
  4738. if ((t.cx == 3 && t.cy == 2) || (t.cx == 2 && t.cy == 3)) noChange[pos] = TRUE;
  4739. }
  4740. p++;
  4741. }
  4742. }
  4743. }
  4744. }
  4745. }
  4746. }
  4747. }
  4748. last_succeeded_operation = 7006;
  4749. memset(hasChanged, 0, sizeof(BOOL) * isosize * isosize);
  4750. // now make LAT (RA2 only)
  4751. #ifdef RA2_MODE
  4752. int x, y;
  4753. for (x = left;x < right;x++)
  4754. {
  4755. for (y = top;y < bottom;y++)
  4756. {
  4757. int xx, yy;
  4758. if (x < 1 || y < 1 || x + y<mapwidth + 1 || x + y>mapwidth + mapheight * 2 || (y + 1 > mapwidth && x - 1 < y - mapwidth) || (x + 1 > mapwidth && y + mapwidth - 1 < x)) continue;
  4759. int pos = x + y * isosize;
  4760. if (noChange[pos]) continue;
  4761. if (terrain[pos] == TERRAINTYPE_GROUND && tsets[pos] != shoreset && tsets[pos] != cliffset && tsets[pos] != watercliffset)
  4762. {
  4763. int i, e;
  4764. BOOL bShoreFound = FALSE;
  4765. for (i = x - 1;i <= x + 1;i++)
  4766. {
  4767. for (e = y - 1;e <= y + 1;e++)
  4768. {
  4769. if (tsets[i + e * isosize] == shoreset) bShoreFound = TRUE;
  4770. if (bShoreFound) break;
  4771. }
  4772. if (bShoreFound) break;
  4773. }
  4774. if (bShoreFound)
  4775. {
  4776. int sandtile = atoi(tiles->sections["General"].values["GreenTile"]);
  4777. int sandlat = atoi(tiles->sections["General"].values["ClearToGreenLat"]);
  4778. int i;
  4779. for (i = 0;i < *tiledata_count;i++)
  4780. if ((*tiledata)[i].wTileSet == sandtile) break;
  4781. Map->SetTileAt(pos, i, 0);
  4782. hasChanged[pos] = TRUE;
  4783. }
  4784. }
  4785. }
  4786. }
  4787. for (x = left - 1;x < right + 1;x++)
  4788. {
  4789. for (y = top - 1;y < bottom + 1;y++)
  4790. {
  4791. int xx, yy;
  4792. if (x < 1 || y < 1 || x + y<mapwidth + 1 || x + y>mapwidth + mapheight * 2 || (y + 1 > mapwidth && x - 1 < y - mapwidth) || (x + 1 > mapwidth && y + mapwidth - 1 < x)) continue;
  4793. int pos = x + y * isosize;
  4794. if (noChange[pos]) continue;
  4795. if (terrain[pos] == TERRAINTYPE_GROUND && tsets[pos] != shoreset && tsets[pos] != cliffset && tsets[pos] != watercliffset)
  4796. {
  4797. int i, e;
  4798. BOOL bShoreFound = FALSE;
  4799. BOOL bSomethingChanged = FALSE;
  4800. for (i = x - 1;i <= x + 1;i++)
  4801. {
  4802. for (e = y - 1;e <= y + 1;e++)
  4803. {
  4804. if (tsets[i + e * isosize] == shoreset) bShoreFound = TRUE;
  4805. if (hasChanged[i + e * isosize]) bSomethingChanged = TRUE;
  4806. if (bShoreFound && hasChanged[i + e * isosize]) break;
  4807. }
  4808. if (bShoreFound && hasChanged[i + e * isosize]) break;
  4809. }
  4810. if (bShoreFound && hasChanged)
  4811. {
  4812. int sandtile = atoi(tiles->sections["General"].values["GreenTile"]);
  4813. int sandlat = atoi(tiles->sections["General"].values["ClearToGreenLat"]);
  4814. SmoothAt(pos, sandtile, sandlat, atoi(tiles->sections["General"].values["ClearTile"]));
  4815. }
  4816. }
  4817. }
  4818. }
  4819. #endif
  4820. //delete[] replaced;
  4821. delete[] hasChanged;
  4822. delete[] noChange;
  4823. delete[] tsets;
  4824. delete[] terrain;
  4825. delete[] tile;
  4826. //pc.DestroyWindow();
  4827. }
  4828. BOOL CMapData::IsMultiplayer()
  4829. {
  4830. if (m_mapfile.sections["Basic"].FindName("Player") >= 0) return FALSE;
  4831. if (isTrue(m_mapfile.sections["Basic"].values["MultiplayerOnly"])) return TRUE;
  4832. if (m_mapfile.sections.find(MAPHOUSES) == m_mapfile.sections.end()) return TRUE;
  4833. return FALSE;
  4834. }
  4835. CString CMapData::GetTheater()
  4836. {
  4837. return m_mapfile.sections["Map"].values["Theater"];
  4838. }
  4839. void CMapData::Copy(int left, int top, int right, int bottom)
  4840. {
  4841. if (left < 0) left = 0;
  4842. if (top < 0) top = 0;
  4843. if (right > m_IsoSize) right = m_IsoSize;
  4844. if (bottom > m_IsoSize) bottom = m_IsoSize;
  4845. if (right == 0) right = m_IsoSize;
  4846. if (bottom == 0) bottom = m_IsoSize;
  4847. if (left >= right) return;
  4848. if (top >= bottom) return;
  4849. CLIPBOARD_DATA cd;
  4850. cd.dwType = 1;
  4851. cd.iWidth = right - left;
  4852. cd.iHeight = bottom - top;
  4853. cd.dwVersion = 0;
  4854. cd.dwReserved = 0;
  4855. if (editor_mode == ra2_mode) cd.bGame = 1; else cd.bGame = 0;
  4856. HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(CLIPBOARD_DATA) + cd.iWidth * cd.iHeight * sizeof(CLIPBOARD_MAPCOPY_ENTRY));
  4857. last_succeeded_operation = 80200;
  4858. void* lpVoid = GlobalLock(hGlob);
  4859. if (!lpVoid)
  4860. {
  4861. MessageBox(0, "Failed to lock memory", "Error", 0);
  4862. return;
  4863. }
  4864. memcpy(lpVoid, &cd, sizeof(CLIPBOARD_DATA));
  4865. CLIPBOARD_MAPCOPY_ENTRY* data = (CLIPBOARD_MAPCOPY_ENTRY*)(((BYTE*)lpVoid) + sizeof(CLIPBOARD_DATA));
  4866. int i;
  4867. int e;
  4868. int lowestheight = 255;
  4869. for (i = 0;i < cd.iWidth;i++)
  4870. {
  4871. for (e = 0;e < cd.iHeight;e++)
  4872. {
  4873. if (i + left < 0 || e + top < 0 || i + left >= m_IsoSize || e + top >= m_IsoSize) continue;
  4874. int pos_r;
  4875. pos_r = left + i + (top + e) * m_IsoSize;
  4876. int ground = fielddata[pos_r].wGround;
  4877. if (ground == 0xFFFF) ground = 0;
  4878. if (fielddata[pos_r].bHeight - (*tiledata)[ground].tiles[fielddata[pos_r].bSubTile].bZHeight < lowestheight) lowestheight = fielddata[pos_r].bHeight - (*tiledata)[ground].tiles[fielddata[pos_r].bSubTile].bZHeight;
  4879. }
  4880. }
  4881. last_succeeded_operation = 80201;
  4882. for (i = 0;i < cd.iWidth;i++)
  4883. {
  4884. for (e = 0;e < cd.iHeight;e++)
  4885. {
  4886. if (i + left < 0 || e + top < 0 || i + left >= m_IsoSize || e + top >= m_IsoSize) continue;
  4887. int pos_w, pos_r;
  4888. pos_w = i + e * cd.iWidth;
  4889. pos_r = left + i + (top + e) * m_IsoSize;
  4890. data[pos_w].bHeight = fielddata[pos_r].bHeight - lowestheight;
  4891. data[pos_w].bMapData = fielddata[pos_r].bMapData;
  4892. data[pos_w].bSubTile = fielddata[pos_r].bSubTile;
  4893. data[pos_w].bMapData2 = fielddata[pos_r].bMapData2;
  4894. data[pos_w].wGround = fielddata[pos_r].wGround;
  4895. data[pos_w].overlay = fielddata[pos_r].overlay;
  4896. data[pos_w].overlaydata = fielddata[pos_r].overlaydata;
  4897. data[pos_w].bRedrawTerrain = fielddata[pos_r].bRedrawTerrain;
  4898. int ground = fielddata[pos_r].wGround;
  4899. if (ground == 0xFFFF) ground = 0;
  4900. int tset = (*tiledata)[ground].wTileSet;
  4901. int k;
  4902. for (k = 0;k < *tiledata_count;k++)
  4903. {
  4904. if ((*tiledata)[k].wTileSet == tset) break;
  4905. }
  4906. data[pos_w].wTileSet = tset;
  4907. data[pos_w].bTile = ground - k;
  4908. }
  4909. }
  4910. last_succeeded_operation = 80202;
  4911. while (GlobalUnlock(hGlob));
  4912. OpenClipboard(theApp.m_pMainWnd->m_hWnd);
  4913. EmptyClipboard();
  4914. if (!SetClipboardData(theApp.m_cf, hGlob))
  4915. {
  4916. MessageBox(0, "Failed to set clipboard data", "Error", 0);
  4917. }
  4918. CloseClipboard();
  4919. }
  4920. void CMapData::Paste(int x, int y, int z_mod)
  4921. {
  4922. OpenClipboard(theApp.m_pMainWnd->m_hWnd);
  4923. HANDLE handle = GetClipboardData(theApp.m_cf);
  4924. void* lpVoid = GlobalLock(handle);
  4925. if (!lpVoid)
  4926. {
  4927. CloseClipboard();
  4928. return;
  4929. }
  4930. last_succeeded_operation = 3001;
  4931. CLIPBOARD_DATA cd;
  4932. memcpy(&cd, lpVoid, sizeof(CLIPBOARD_DATA));
  4933. x -= cd.iWidth / 2;
  4934. y -= cd.iHeight / 2;
  4935. CLIPBOARD_MAPCOPY_ENTRY* data = (CLIPBOARD_MAPCOPY_ENTRY*)(((BYTE*)lpVoid) + sizeof(CLIPBOARD_DATA));
  4936. last_succeeded_operation = 3002;
  4937. int lowestheight = 255;
  4938. int mapwidth, mapheight;
  4939. mapwidth = GetWidth();
  4940. mapheight = GetHeight();
  4941. int i;
  4942. int e;
  4943. for (i = 0;i < cd.iWidth;i++)
  4944. {
  4945. for (e = 0;e < cd.iHeight;e++)
  4946. {
  4947. if (x + i < 0 || y + e < 0 || x + i >= m_IsoSize || y + e >= m_IsoSize) continue;
  4948. FIELDDATA* fd = Map->GetFielddataAt(i + x + (y + e) * m_IsoSize);
  4949. int ground = fd->wGround;
  4950. if (ground = 0xFFFF) ground = 0;
  4951. int height = fd->bHeight;//-(*tiledata)[ground].tiles[fd->bSubTile].bZHeight;
  4952. if (height < lowestheight) lowestheight = height;
  4953. }
  4954. }
  4955. int ground = GetFielddataAt(x + y * m_IsoSize)->wGround;
  4956. if (ground == 0xFFFF) ground = 0;
  4957. int startheight = lowestheight + z_mod;//-(*tiledata)[ground].tiles[GetFielddataAt(x+y*m_IsoSize)->bSubTile].bZHeight;
  4958. //char c[50];
  4959. //itoa(startheight, c, 10);
  4960. //MessageBox(0,c,"",0);
  4961. last_succeeded_operation = 3003;
  4962. const bool mp = IsMultiplayer();
  4963. for (i = 0;i < cd.iWidth;i++)
  4964. {
  4965. for (e = 0;e < cd.iHeight;e++)
  4966. {
  4967. int pos_w, pos_r;
  4968. pos_r = i + e * cd.iWidth;
  4969. pos_w = x + i + (y + e) * m_IsoSize;
  4970. if (x + i < 0 || y + e < 0 || x + i >= m_IsoSize || y + e >= m_IsoSize) continue;
  4971. RemoveOvrlMoney(fielddata[pos_w].overlay, fielddata[pos_w].overlaydata);
  4972. fielddata[pos_w].overlay = data[pos_r].overlay;
  4973. fielddata[pos_w].overlaydata = data[pos_r].overlaydata;
  4974. AddOvrlMoney(fielddata[pos_w].overlay, fielddata[pos_w].overlaydata);
  4975. SetHeightAt(pos_w, startheight + data[pos_r].bHeight);
  4976. int tset = data[pos_r].wTileSet;
  4977. int tile = data[pos_r].bTile;
  4978. int k;
  4979. int found = -1;
  4980. for (k = 0;k < *tiledata_count;k++)
  4981. {
  4982. if ((*tiledata)[k].wTileSet == tset)
  4983. {
  4984. found = k;
  4985. break;
  4986. }
  4987. }
  4988. if (found < 0) continue;
  4989. if ((*tiledata)[found + tile].wTileSet != tset)
  4990. {
  4991. continue;
  4992. }
  4993. if ((*tiledata)[found + tile].wTileCount <= data[pos_r].bSubTile) continue;
  4994. fielddata[pos_w].bSubTile = data[pos_r].bSubTile;
  4995. fielddata[pos_w].bRedrawTerrain = data[pos_r].bRedrawTerrain;
  4996. fielddata[pos_w].wGround = found + tile;
  4997. fielddata[pos_w].bMapData = data[pos_r].bMapData;
  4998. fielddata[pos_w].bMapData2 = data[pos_r].bMapData2;
  4999. Mini_UpdatePos(x + i, y + e, mp);
  5000. }
  5001. }
  5002. last_succeeded_operation = 3005;
  5003. GlobalUnlock(handle);
  5004. CloseClipboard();
  5005. }
  5006. void CMapData::GetStructurePaint(int index, STRUCTUREPAINT* lpStructurePaint) const
  5007. {
  5008. if (index < 0 || index >= m_structurepaint.size()) return;
  5009. *lpStructurePaint = m_structurepaint[index];
  5010. }
  5011. void CMapData::InitMinimap()
  5012. {
  5013. int pwidth = GetWidth() * 2;
  5014. int pheight = GetHeight();
  5015. memset(&m_mini_biinfo, 0, sizeof(BITMAPINFO));
  5016. m_mini_biinfo.bmiHeader.biBitCount = 24;
  5017. m_mini_biinfo.bmiHeader.biWidth = pwidth;
  5018. m_mini_biinfo.bmiHeader.biHeight = pheight;
  5019. m_mini_biinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  5020. m_mini_biinfo.bmiHeader.biClrUsed = 0;
  5021. m_mini_biinfo.bmiHeader.biPlanes = 1;
  5022. m_mini_biinfo.bmiHeader.biCompression = BI_RGB;
  5023. m_mini_biinfo.bmiHeader.biClrImportant = 0;
  5024. int pitch = pwidth * 3;
  5025. if (pitch == 0) return;
  5026. if (pitch % sizeof(DWORD))
  5027. {
  5028. pitch += sizeof(DWORD) - (pwidth * 3) % sizeof(DWORD);
  5029. }
  5030. m_mini_pitch = pitch;
  5031. //m_mini_colors=new(BYTE[pitch*pheight]);
  5032. m_mini_colors.resize(pitch * pheight);
  5033. memset(m_mini_colors.data(), 255, pitch * (pheight));
  5034. /*DWORD dwIsoSize=GetIsoSize();
  5035. int mapwidth=GetWidth();
  5036. int mapheight=GetHeight();
  5037. int i,e;
  5038. int size=pitch*pheight;
  5039. for(i=0;i<dwIsoSize;i++)
  5040. {
  5041. for(e=0;e<dwIsoSize;e++)
  5042. {
  5043. Mini_UpdatePos(i,e);
  5044. }
  5045. }*/
  5046. }
  5047. void CMapData::GetMinimap(BYTE** lpData, BITMAPINFO* lpBI, int* pitch)
  5048. {
  5049. *lpData = m_mini_colors.data();
  5050. *pitch = m_mini_pitch;
  5051. memcpy(lpBI, &m_mini_biinfo, sizeof(BITMAPINFO));
  5052. }
  5053. int CMapData::CalcMoneyOnMap()
  5054. {
  5055. int i;
  5056. int money = 0;
  5057. for (i = 0;i < fielddata_size;i++)
  5058. {
  5059. FIELDDATA& fd = fielddata[i];
  5060. BYTE& ovrl = fd.overlay;
  5061. BYTE& ovrld = fd.overlaydata;
  5062. if (ovrl >= RIPARIUS_BEGIN && ovrl <= RIPARIUS_END)
  5063. {
  5064. money += (ovrld + 1) * (atoi(rules.sections["Riparius"].values["Value"]));
  5065. }
  5066. if (ovrl >= CRUENTUS_BEGIN && ovrl <= CRUENTUS_END)
  5067. {
  5068. money += (ovrld + 1) * (atoi(rules.sections["Cruentus"].values["Value"]));
  5069. }
  5070. if (ovrl >= VINIFERA_BEGIN && ovrl <= VINIFERA_END)
  5071. {
  5072. money += (ovrld + 1) * (atoi(rules.sections["Vinifera"].values["Value"]));
  5073. }
  5074. if (ovrl >= ABOREUS_BEGIN && ovrl <= ABOREUS_END)
  5075. {
  5076. money += (ovrld + 1) * (atoi(rules.sections["Aboreus"].values["Value"]));
  5077. }
  5078. }
  5079. return money;
  5080. }
  5081. int CMapData::GetMoneyOnMap() const
  5082. {
  5083. return m_money;
  5084. }
  5085. int CMapData::GetPowerOfHouse(LPCTSTR lpHouse)
  5086. {
  5087. // stub
  5088. return 0;
  5089. }
  5090. void CMapData::SmoothTiberium(DWORD dwPos)
  5091. {
  5092. static int _adj[9] = { 0,1,3,4,6,7,8,10,11 };
  5093. BYTE& ovrl = fielddata[dwPos].overlay;
  5094. if (!(ovrl >= RIPARIUS_BEGIN && ovrl <= RIPARIUS_END) &&
  5095. !(ovrl >= CRUENTUS_BEGIN && ovrl <= CRUENTUS_END) &&
  5096. !(ovrl >= VINIFERA_BEGIN && ovrl <= VINIFERA_END) &&
  5097. !(ovrl >= ABOREUS_BEGIN && ovrl <= ABOREUS_END))
  5098. return;
  5099. RemoveOvrlMoney(ovrl, fielddata[dwPos].overlaydata);
  5100. int i, e;
  5101. int x, y;
  5102. x = dwPos % m_IsoSize;
  5103. y = dwPos / m_IsoSize;
  5104. int count = 0;
  5105. for (i = -1;i < 2;i++)
  5106. {
  5107. for (e = -1;e < 2;e++)
  5108. {
  5109. int xx = x + i;
  5110. int yy = y + e;
  5111. if (xx < 0 || xx >= m_IsoSize || yy < 0 || yy >= m_IsoSize) continue;
  5112. FIELDDATA& fd = fielddata[xx + yy * m_IsoSize];
  5113. BYTE& ovrl = fd.overlay;
  5114. BYTE& ovrld = fd.overlaydata;
  5115. if (ovrl >= RIPARIUS_BEGIN && ovrl <= RIPARIUS_END)
  5116. {
  5117. count++;
  5118. }
  5119. if (ovrl >= CRUENTUS_BEGIN && ovrl <= CRUENTUS_END)
  5120. {
  5121. count++;
  5122. }
  5123. if (ovrl >= VINIFERA_BEGIN && ovrl <= VINIFERA_END)
  5124. {
  5125. count++;
  5126. }
  5127. if (ovrl >= ABOREUS_BEGIN && ovrl <= ABOREUS_END)
  5128. {
  5129. count++;
  5130. }
  5131. }
  5132. }
  5133. ASSERT(count);
  5134. fielddata[dwPos].overlaydata = _adj[count - 1];
  5135. m_OverlayData[y + x * 512] = _adj[count - 1];
  5136. AddOvrlMoney(ovrl, fielddata[dwPos].overlaydata);
  5137. }
  5138. void CMapData::ResizeMap(int iLeft, int iTop, DWORD dwNewWidth, DWORD dwNewHeight)
  5139. {
  5140. #ifndef RA2_MODE
  5141. if (MessageBox(0, "Tunnels may be damaged after changing the map size. Continue?", "Warning", MB_YESNO) == IDNO) return;
  5142. #endif
  5143. // MW: New object replacing code to fix crashes
  5144. INFANTRY* inf = new(INFANTRY[GetInfantryCount()]);
  5145. int inf_count = GetInfantryCount();
  5146. STRUCTURE* str = new(STRUCTURE[GetStructureCount()]);
  5147. int str_count = GetStructureCount();
  5148. UNIT* unit = new(UNIT[GetUnitCount()]);
  5149. int unit_count = GetUnitCount();
  5150. AIRCRAFT* air = new(AIRCRAFT[GetAircraftCount()]);
  5151. int air_count = GetAircraftCount();
  5152. TERRAIN* terrain = new(TERRAIN[GetTerrainCount()]);
  5153. int terrain_count = GetTerrainCount();
  5154. CString* wp_id = new(CString[GetWaypointCount()]);
  5155. int wp_count = GetWaypointCount();
  5156. DWORD* wp_pos = new(DWORD[GetWaypointCount()]);
  5157. CString* ct_tag = new(CString[GetCelltagCount()]);
  5158. int ct_count = GetCelltagCount();
  5159. DWORD* ct_pos = new(DWORD[GetCelltagCount()]);
  5160. int i;
  5161. // Now copy the objects into above arrays and delete them from map
  5162. for (i = 0;i < inf_count;i++)
  5163. {
  5164. INFANTRY obj;
  5165. GetInfantryData(i, &obj);
  5166. inf[i] = obj;
  5167. }
  5168. for (i = inf_count - 1;i >= 0;i--)
  5169. DeleteInfantry(i);
  5170. for (i = 0;i < air_count;i++)
  5171. {
  5172. AIRCRAFT obj;
  5173. GetAircraftData(i, &obj);
  5174. air[i] = obj;
  5175. }
  5176. for (i = air_count - 1;i >= 0;i--)
  5177. DeleteAircraft(i);
  5178. for (i = 0;i < str_count;i++)
  5179. {
  5180. STRUCTURE obj;
  5181. GetStructureData(i, &obj);
  5182. str[i] = obj;
  5183. }
  5184. for (i = str_count - 1;i >= 0;i--)
  5185. DeleteStructure(i);
  5186. for (i = 0;i < unit_count;i++)
  5187. {
  5188. UNIT obj;
  5189. GetUnitData(i, &obj);
  5190. unit[i] = obj;
  5191. }
  5192. for (i = unit_count - 1;i >= 0;i--)
  5193. DeleteUnit(i);
  5194. for (i = 0;i < terrain_count;i++)
  5195. {
  5196. terrain[i] = m_terrain[i];
  5197. }
  5198. for (i = 0;i < terrain_count;i++)
  5199. DeleteTerrain(i);
  5200. for (i = 0;i < wp_count;i++)
  5201. {
  5202. DWORD pos;
  5203. CString id;
  5204. GetWaypointData(i, &id, &pos);
  5205. wp_id[i] = id;
  5206. wp_pos[i] = pos;
  5207. }
  5208. // for(i=0;i<wp_count;i++) DeleteWaypoint(0);
  5209. for (i = 0;i < ct_count;i++)
  5210. {
  5211. DWORD pos;
  5212. CString tag;
  5213. GetCelltagData(i, &tag, &pos);
  5214. ct_tag[i] = tag;
  5215. ct_pos[i] = pos;
  5216. }
  5217. for (i = 0;i < ct_count;i++) DeleteCelltag(0);
  5218. FIELDDATA* old_fd = fielddata;
  5219. int ow = GetWidth();
  5220. int oh = GetHeight();
  5221. int os = GetIsoSize();
  5222. int old_fds = fielddata_size;
  5223. int left = iLeft;
  5224. int top = iTop;
  5225. // hmm, erase any snapshots... we probably can remove this and do coordinate conversion instead
  5226. // but for now we just delete them...
  5227. for (i = 0;i < dwSnapShotCount;i++)
  5228. {
  5229. delete[] m_snapshots[i].bHeight;
  5230. delete[] m_snapshots[i].bMapData;
  5231. delete[] m_snapshots[i].bSubTile;
  5232. delete[] m_snapshots[i].bMapData2;
  5233. delete[] m_snapshots[i].wGround;
  5234. delete[] m_snapshots[i].bRedrawTerrain;
  5235. delete[] m_snapshots[i].overlay;
  5236. delete[] m_snapshots[i].overlaydata;
  5237. // m_snapshots[i].mapfile.Clear();
  5238. }
  5239. if (m_snapshots != NULL) delete[] m_snapshots;
  5240. fielddata = NULL;
  5241. fielddata_size = 0;
  5242. m_snapshots = NULL;
  5243. dwSnapShotCount = 0;
  5244. m_cursnapshot = -1;
  5245. char c[50];
  5246. CString mapsize;
  5247. itoa(dwNewWidth, c, 10);
  5248. mapsize = "0,0,";
  5249. mapsize += c;
  5250. itoa(dwNewHeight, c, 10);
  5251. mapsize += ",";
  5252. mapsize += c;
  5253. m_mapfile.sections["Map"].values["Size"] = mapsize;
  5254. itoa(dwNewWidth - 4, c, 10);
  5255. mapsize = "2,4,";
  5256. mapsize += c;
  5257. itoa(dwNewHeight - 6, c, 10);
  5258. mapsize += ",";
  5259. mapsize += c;
  5260. m_mapfile.sections["Map"].values["LocalSize"] = mapsize;
  5261. CalcMapRect();
  5262. ClearOverlay();
  5263. ClearOverlayData();
  5264. errstream << "ResizeMap() allocates memory\n";
  5265. errstream.flush();
  5266. fielddata = new(FIELDDATA[(GetIsoSize() + 1) * (GetIsoSize() + 1)]); // +1 because of some unpacking problems
  5267. fielddata_size = (GetIsoSize() + 1) * (GetIsoSize() + 1);
  5268. dwIsoMapSize = 0; // our iso mappack is empty now, as we didn´t load from a file
  5269. errstream << "ResizeMap() frees m_mfd\n";
  5270. errstream.flush();
  5271. if (m_mfd != NULL) delete[] m_mfd;
  5272. m_mfd = NULL;
  5273. // x_move and y_move specify the movement for each field, related to the old position
  5274. int x_move = 0;
  5275. int y_move = 0;
  5276. x_move += (dwNewWidth - ow);
  5277. // x_move and y_move now take care of the map sizing. This means,
  5278. // all new or removed tiles will now be added/deleted to/from the bottom right
  5279. // but we want to consider left and right, as the user selected it.
  5280. // so, do some coordinate conversion:
  5281. x_move += top;
  5282. y_move += top;
  5283. x_move += -left;
  5284. y_move += left;
  5285. //char c[50];
  5286. /*char d[50];
  5287. itoa(y_move, d, 10);
  5288. itoa(x_move, c, 10);
  5289. MessageBox(0, c, d,0);*/
  5290. // copy tiles now
  5291. int e;
  5292. for (i = 0;i < os;i++)
  5293. {
  5294. for (e = 0;e < os;e++)
  5295. {
  5296. int x, y;
  5297. x = i + x_move;
  5298. y = e + y_move;
  5299. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5300. FIELDDATA& fdd = fielddata[x + y * m_IsoSize];
  5301. FIELDDATA& fdo = old_fd[i + e * os];
  5302. fdd.bCliffHack = fdo.bCliffHack;
  5303. fdd.bHeight = fdo.bHeight;
  5304. fdd.bHide = fdo.bHide;
  5305. fdd.bMapData = fdo.bMapData;
  5306. fdd.bMapData2 = fdo.bMapData2;
  5307. fdd.bRedrawTerrain = fdo.bRedrawTerrain;
  5308. fdd.bRNDImage = fdo.bRNDImage;
  5309. fdd.bSubTile = fdo.bSubTile;
  5310. fdd.overlay = fdo.overlay;
  5311. fdd.overlaydata = fdo.overlaydata;
  5312. fdd.wGround = fdo.wGround;
  5313. }
  5314. }
  5315. // MW 07/22/01: Added Progress dialog - it just was slow, and did not crash...
  5316. int allcount = GetInfantryCount() + GetAircraftCount() + GetUnitCount() + GetStructureCount() + GetTerrainCount() + GetWaypointCount() + GetCelltagCount();
  5317. int curcount = 0;
  5318. CProgressDlg* dlg = new(CProgressDlg)("Updating objects, please wait");
  5319. dlg->SetRange(0, allcount - 1);
  5320. dlg->ShowWindow(SW_SHOW);
  5321. //m_noAutoObjectUpdate=TRUE; // deactivate Update*()... faster
  5322. int count = inf_count; // this temp variable is *needed* (infinite loop)!!!
  5323. for (i = 0;i < count;i++)
  5324. {
  5325. if (inf[i].deleted)
  5326. {
  5327. dlg->SetPosition(i + curcount);
  5328. dlg->UpdateWindow();
  5329. continue; // MW June 12 01
  5330. }
  5331. INFANTRY obj;
  5332. obj = inf[i];
  5333. char c[50];
  5334. obj.x = itoa(atoi(obj.x) + x_move, c, 10);
  5335. obj.y = itoa(atoi(obj.y) + y_move, c, 10);
  5336. int x = atoi(obj.x);
  5337. int y = atoi(obj.y);
  5338. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5339. AddInfantry(&obj);
  5340. dlg->SetPosition(i + curcount);
  5341. dlg->UpdateWindow();
  5342. }
  5343. curcount += count;
  5344. count = air_count;
  5345. for (i = 0;i < count;i++)
  5346. {
  5347. // if(air[i].deleted) continue;
  5348. AIRCRAFT obj;
  5349. obj = air[i];
  5350. char c[50];
  5351. obj.x = itoa(atoi(obj.x) + x_move, c, 10);
  5352. obj.y = itoa(atoi(obj.y) + y_move, c, 10);
  5353. int x = atoi(obj.x);
  5354. int y = atoi(obj.y);
  5355. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5356. AddAircraft(&obj);
  5357. dlg->SetPosition(i + curcount);
  5358. dlg->UpdateWindow();
  5359. }
  5360. UpdateAircraft(FALSE);
  5361. curcount += count;
  5362. count = str_count;
  5363. for (i = 0;i < count;i++)
  5364. {
  5365. // if(str[i].deleted) continue;
  5366. STRUCTURE obj;
  5367. obj = str[i];
  5368. char c[50];
  5369. obj.x = itoa(atoi(obj.x) + x_move, c, 10);
  5370. obj.y = itoa(atoi(obj.y) + y_move, c, 10);
  5371. int x = atoi(obj.x);
  5372. int y = atoi(obj.y);
  5373. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5374. AddStructure(&obj);
  5375. dlg->SetPosition(i + curcount);
  5376. dlg->UpdateWindow();
  5377. }
  5378. UpdateStructures(FALSE);
  5379. curcount += count;
  5380. count = unit_count;
  5381. for (i = 0;i < count;i++)
  5382. {
  5383. // if(units[i].deleted) continue;
  5384. UNIT obj;
  5385. obj = unit[i];
  5386. char c[50];
  5387. obj.x = itoa(atoi(obj.x) + x_move, c, 10);
  5388. obj.y = itoa(atoi(obj.y) + y_move, c, 10);
  5389. int x = atoi(obj.x);
  5390. int y = atoi(obj.y);
  5391. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5392. AddUnit(&obj);
  5393. dlg->SetPosition(i + curcount);
  5394. dlg->UpdateWindow();
  5395. }
  5396. UpdateUnits(FALSE);
  5397. curcount += count;
  5398. count = terrain_count;
  5399. for (i = 0;i < count;i++)
  5400. {
  5401. if (terrain[i].deleted)
  5402. {
  5403. dlg->SetPosition(i + curcount);
  5404. dlg->UpdateWindow();
  5405. continue; // MW June 12 01
  5406. }
  5407. CString obj;
  5408. int x = terrain[i].x;
  5409. int y = terrain[i].y;
  5410. obj = terrain[i].type;
  5411. char c[50];
  5412. x = x + x_move;
  5413. y = y + y_move;
  5414. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5415. AddTerrain(obj, x + y * m_IsoSize);
  5416. dlg->SetPosition(i + curcount);
  5417. dlg->UpdateWindow();
  5418. }
  5419. //UpdateTerrain(TRUE);
  5420. //UpdateTerrain(FALSE);
  5421. curcount += count;
  5422. count = wp_count;
  5423. for (i = 0;i < count;i++)
  5424. {
  5425. DWORD pos;
  5426. CString id;
  5427. pos = wp_pos[i];
  5428. id = wp_id[i];
  5429. int x = pos % os + x_move;
  5430. int y = pos / os + y_move;
  5431. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5432. AddWaypoint(id, x + y * m_IsoSize);
  5433. dlg->SetPosition(i + curcount);
  5434. dlg->UpdateWindow();
  5435. }
  5436. UpdateWaypoints(FALSE);
  5437. curcount += count;
  5438. for (i = 0;i < ct_count;i++)
  5439. {
  5440. DWORD pos = ct_pos[i];
  5441. CString tag = ct_tag[i];
  5442. int x = pos % os + x_move;
  5443. int y = pos / os + y_move;
  5444. if (x < 0 || y < 0 || x >= m_IsoSize || y >= m_IsoSize) continue;
  5445. AddCelltag(tag, x + y * m_IsoSize);
  5446. dlg->SetPosition(i + curcount);
  5447. dlg->UpdateWindow();
  5448. }
  5449. UpdateCelltags(FALSE);
  5450. m_noAutoObjectUpdate = FALSE;
  5451. errstream << "Delete old_fd" << endl;
  5452. errstream.flush();
  5453. dlg->DestroyWindow();
  5454. dlg = new(CProgressDlg)("Updating Minimap, please wait");
  5455. count = 0;
  5456. dlg->SetRange(0, m_IsoSize * m_IsoSize);
  5457. dlg->ShowWindow(SW_SHOW);
  5458. if (old_fd) delete[] old_fd;
  5459. errstream << "Init minimap" << endl;
  5460. errstream.flush();
  5461. InitMinimap();
  5462. errstream << "Fill minimap" << endl;
  5463. errstream.flush();
  5464. const bool mp = IsMultiplayer();
  5465. for (i = 0;i < m_IsoSize;i++)
  5466. {
  5467. for (e = 0;e < m_IsoSize;e++)
  5468. {
  5469. Mini_UpdatePos(i, e, mp);
  5470. count++;
  5471. }
  5472. dlg->SetPosition(count);
  5473. dlg->UpdateWindow();
  5474. }
  5475. errstream << "Finished" << endl;
  5476. errstream.flush();
  5477. if (inf) delete[] inf;
  5478. if (str) delete[] str;
  5479. if (unit) delete[] unit;
  5480. if (air) delete[] air;
  5481. if (terrain) delete[] terrain;
  5482. if (wp_id) delete[] wp_id;
  5483. if (wp_pos) delete[] wp_pos;
  5484. if (ct_tag) delete[] ct_tag;
  5485. if (ct_pos) delete[] ct_pos;
  5486. dlg->DestroyWindow();
  5487. }
  5488. /*
  5489. Returns TRUE for all sections that should not be modified using the INI editor,
  5490. because they become modified whenever the map is saved by the editor itself.
  5491. */
  5492. BOOL CMapData::IsMapSection(LPCSTR lpSectionName)
  5493. {
  5494. CString str;
  5495. str = lpSectionName;
  5496. if (str == "IsoMapPack5" || str == "OverlayPack" || str == "OverlayDataPack" ||
  5497. str == "Preview" || str == "PreviewPack" || str == "Map" ||
  5498. str == "Structures" || str == "Terrain" || str == "Units" || str == "Aircraft" || str == "Infantry"
  5499. || str == "Variables")
  5500. return TRUE;
  5501. return FALSE;
  5502. }
  5503. int GetEventParamStart(CString& EventData, int param);
  5504. BOOL CMapData::IsYRMap()
  5505. {
  5506. #ifdef TS_MODE
  5507. return FALSE;
  5508. #else
  5509. //if(yuri_mode) // always check for this
  5510. {
  5511. if (Map->GetTheater() == THEATER3 || Map->GetTheater() == THEATER4 || Map->GetTheater() == THEATER5)
  5512. return TRUE;
  5513. int i;
  5514. int max = 0;
  5515. if (tiledata == &u_tiledata)
  5516. {
  5517. max = atoi(g_data.sections["RA2TileMax"].values["Urban"]);
  5518. }
  5519. else if (tiledata == &s_tiledata) max = atoi(g_data.sections["RA2TileMax"].values["Snow"]);
  5520. else if (tiledata == &t_tiledata) max = atoi(g_data.sections["RA2TileMax"].values["Temperat"]);
  5521. int yroverlay = atoi(g_data.sections["YROverlay"].values["Begin"]);
  5522. for (i = 0;i < fielddata_size;i++)
  5523. {
  5524. if (fielddata[i].wGround != 0xFFFF && fielddata[i].wGround >= max)
  5525. {
  5526. return TRUE;
  5527. }
  5528. if (fielddata[i].overlay >= yroverlay && fielddata[i].overlay != 0xFF)
  5529. return TRUE;
  5530. }
  5531. int count;
  5532. count = GetInfantryCount();
  5533. for (i = 0;i < count;i++)
  5534. {
  5535. INFANTRY inf;
  5536. GetInfantryData(i, &inf);
  5537. if (inf.deleted) continue;
  5538. CIniFileSection& sec = g_data.sections["YRInfantry"];
  5539. if (sec.values.find(inf.type) != sec.values.end())
  5540. {
  5541. return TRUE;
  5542. }
  5543. }
  5544. count = GetStructureCount();
  5545. for (i = 0;i < count;i++)
  5546. {
  5547. STRUCTURE str;
  5548. GetStructureData(i, &str);
  5549. if (str.deleted) continue;
  5550. CIniFileSection& sec = g_data.sections["YRBuildings"];
  5551. if (sec.values.find(str.type) != sec.values.end())
  5552. {
  5553. return TRUE;
  5554. }
  5555. }
  5556. count = GetUnitCount();
  5557. for (i = 0;i < count;i++)
  5558. {
  5559. UNIT unit;
  5560. GetUnitData(i, &unit);
  5561. if (unit.deleted) continue;
  5562. CIniFileSection& sec = g_data.sections["YRUnits"];
  5563. if (sec.values.find(unit.type) != sec.values.end())
  5564. {
  5565. return TRUE;
  5566. }
  5567. }
  5568. count = GetAircraftCount();
  5569. for (i = 0;i < count;i++)
  5570. {
  5571. AIRCRAFT air;
  5572. GetAircraftData(i, &air);
  5573. if (air.deleted) continue;
  5574. CIniFileSection& sec = g_data.sections["YRAircraft"];
  5575. if (sec.values.find(air.type) != sec.values.end())
  5576. {
  5577. return TRUE;
  5578. }
  5579. }
  5580. count = GetTerrainCount();
  5581. for (i = 0;i < count;i++)
  5582. {
  5583. TERRAIN& tr = m_terrain[i];
  5584. if (tr.deleted) continue;
  5585. CIniFileSection& sec = g_data.sections["YRTerrain"];
  5586. if (sec.values.find(tr.type) != sec.values.end())
  5587. {
  5588. return TRUE;
  5589. }
  5590. }
  5591. count = m_mapfile.sections["Triggers"].values.size();
  5592. for (i = 0;i < count;i++)
  5593. {
  5594. CString event;
  5595. CString action;
  5596. CString id;
  5597. id = *m_mapfile.sections["Triggers"].GetValueName(i);
  5598. event = m_mapfile.sections["Events"].values[id];
  5599. action = m_mapfile.sections["Actions"].values[id];
  5600. int eventcount, actioncount;
  5601. eventcount = atoi(GetParam(event, 0));
  5602. actioncount = atoi(GetParam(action, 0));
  5603. int e;
  5604. for (e = 0;e < eventcount;e++)
  5605. {
  5606. CString type = GetParam(event, GetEventParamStart(event, e));
  5607. if (g_data.sections["EventsRA2"].values.find(type) != g_data.sections["EventsRA2"].values.end())
  5608. {
  5609. if (isTrue(GetParam(g_data.sections["EventsRA2"].values[type], 9)))
  5610. return TRUE;
  5611. }
  5612. }
  5613. for (e = 0;e < actioncount;e++)
  5614. {
  5615. CString type = GetParam(action, 1 + e * 8);
  5616. if (g_data.sections["ActionsRA2"].values.find(type) != g_data.sections["ActionsRA2"].values.end())
  5617. {
  5618. if (isTrue(GetParam(g_data.sections["ActionsRA2"].values[type], 14)))
  5619. return TRUE;
  5620. }
  5621. }
  5622. }
  5623. }
  5624. return FALSE;
  5625. #endif
  5626. }
  5627. #ifdef SMUDGE_SUPP
  5628. BOOL CMapData::AddSmudge(SMUDGE* lpSmudge)
  5629. {
  5630. SMUDGE td;
  5631. td = *lpSmudge;
  5632. int pos = td.x + td.y * GetIsoSize();
  5633. if (smudgeid.find(td.type) == smudgeid.end()) return FALSE;
  5634. BOOL bFound = FALSE;
  5635. int i;
  5636. for (i = 0;i < m_smudges.size();i++)
  5637. {
  5638. if (m_smudges[i].deleted) // yep, found one, replace it
  5639. {
  5640. m_smudges[i] = td;
  5641. if (pos < fielddata_size)
  5642. {
  5643. fielddata[pos].smudge = i;
  5644. fielddata[pos].smudgetype = smudgeid[td.type];
  5645. }
  5646. bFound = TRUE;
  5647. break;
  5648. }
  5649. }
  5650. if (!bFound)
  5651. {
  5652. m_smudges.push_back(td);
  5653. if (pos < fielddata_size)
  5654. {
  5655. fielddata[pos].smudge = m_smudges.size() - 1;
  5656. fielddata[pos].smudgetype = smudgeid[td.type];
  5657. }
  5658. }
  5659. return TRUE;
  5660. }
  5661. void CMapData::DeleteSmudge(DWORD dwIndex)
  5662. {
  5663. if (m_smudges[dwIndex].deleted) return;
  5664. int x, y;
  5665. x = m_smudges[dwIndex].x;
  5666. y = m_smudges[dwIndex].y;
  5667. m_smudges[dwIndex].deleted = 1;
  5668. int pos = x + y * GetIsoSize();
  5669. if (x + y * m_IsoSize < fielddata_size)
  5670. {
  5671. fielddata[pos].smudge = -1;
  5672. fielddata[pos].smudgetype = -1;
  5673. }
  5674. }
  5675. void CMapData::UpdateSmudges(BOOL bSave, int num)
  5676. {
  5677. vector<SMUDGE>& t = m_smudges;
  5678. if (bSave == FALSE)
  5679. {
  5680. if (m_mapfile.sections.find("Smudge") == m_mapfile.sections.end() || m_mapfile.sections["Smudge"].values.size() <= 0)
  5681. return;
  5682. if (num < 0)
  5683. {
  5684. t.clear();
  5685. t.reserve(100);
  5686. int i;
  5687. for (i = 0;i < GetIsoSize() * GetIsoSize();i++)
  5688. {
  5689. fielddata[i].smudge = -1;
  5690. }
  5691. CIniFileSection& sec = m_mapfile.sections["Smudge"];
  5692. for (i = 0;i < sec.values.size();i++)
  5693. {
  5694. int x, y;
  5695. x = atoi(GetParam(*sec.GetValue(i), 2));
  5696. y = atoi(GetParam(*sec.GetValue(i), 1));
  5697. // check for valid coordinates ; MW May 17th 2001
  5698. ASSERT(x >= 0 && x < GetIsoSize());
  5699. ASSERT(y >= 0 && y < GetIsoSize());
  5700. if (x < 0 || x >= GetIsoSize() || y < 0 || y >= GetIsoSize())
  5701. {
  5702. // invalid coordinates - ignore in release
  5703. }
  5704. else
  5705. {
  5706. SMUDGE td;
  5707. td.deleted = 0;
  5708. td.type = GetParam(*sec.GetValue(i), 0);
  5709. td.x = x;
  5710. td.y = y;
  5711. t.push_back(td);
  5712. int pos = x + y * GetIsoSize();
  5713. fielddata[pos].smudge = i;
  5714. fielddata[pos].smudgetype = smudgeid[td.type];
  5715. }
  5716. }
  5717. m_mapfile.sections.erase("Smudge");
  5718. }
  5719. }
  5720. else
  5721. {
  5722. //if(num<0)
  5723. {
  5724. //if(m_mapfile.sections.find("Smudge")!=m_mapfile.sections.end()) MessageBox(0,"Reupdate!","",0);
  5725. m_mapfile.sections.erase("Smudge");
  5726. int i;
  5727. for (i = 0;i < t.size();i++)
  5728. {
  5729. SMUDGE& td = t[i];
  5730. if (!td.deleted)
  5731. {
  5732. char c[50];
  5733. CString val = td.type;
  5734. val += ",";
  5735. itoa(td.y, c, 10);
  5736. val += c;
  5737. val += ",";
  5738. itoa(td.x, c, 10);
  5739. val += c;
  5740. val += ",0";
  5741. itoa(i, c, 10);
  5742. m_mapfile.sections["Smudge"].values[c] = val;
  5743. }
  5744. }
  5745. }
  5746. }
  5747. }
  5748. void CMapData::UpdateSmudgeInfo(LPCSTR lpSmudgeType)
  5749. {
  5750. CIniFile& ini = GetIniFile();
  5751. if (!lpSmudgeType)
  5752. {
  5753. memset(smudgeinfo, 0, 0x0F00 * sizeof(SMUDGE_INFO));
  5754. int i;
  5755. for (i = 0;i < rules.sections["SmudgeTypes"].values.size();i++)
  5756. {
  5757. CString type = *rules.sections["SmudgeTypes"].GetValue(i);
  5758. CString artname = type;
  5759. int n = GetUnitTypeID(type);
  5760. if (n >= 0 && n < 0x0F00)
  5761. {
  5762. CString lpPicFile = GetUnitPictureFilename(type, 0);
  5763. if (pics.find(lpPicFile) != pics.end())
  5764. {
  5765. smudgeinfo[n].pic = pics[lpPicFile];
  5766. }
  5767. else
  5768. smudgeinfo[n].pic.pic = NULL;
  5769. }
  5770. }
  5771. for (i = 0;i < ini.sections["SmudgeTypes"].values.size();i++)
  5772. {
  5773. CString type = *ini.sections["SmudgeTypes"].GetValue(i);
  5774. CString artname = type;
  5775. int n = Map->GetUnitTypeID(type);
  5776. if (n >= 0 && n < 0x0F00)
  5777. {
  5778. //smudgeinfo[n].w=w;
  5779. //smudgeinfo[n].h=h;
  5780. CString lpPicFile = GetUnitPictureFilename(type, 0);
  5781. if (pics.find(lpPicFile) != pics.end())
  5782. {
  5783. smudgeinfo[n].pic = pics[lpPicFile];
  5784. }
  5785. else
  5786. smudgeinfo[n].pic.pic = NULL;
  5787. }
  5788. }
  5789. }
  5790. else
  5791. {
  5792. CString type = lpSmudgeType;
  5793. CString artname = type;
  5794. int n = Map->GetUnitTypeID(type);
  5795. if (n >= 0 && n < 0x0F00)
  5796. {
  5797. CString lpPicFile = GetUnitPictureFilename(type, 0);
  5798. if (pics.find(lpPicFile) != pics.end())
  5799. {
  5800. smudgeinfo[n].pic = pics[lpPicFile];
  5801. }
  5802. else
  5803. smudgeinfo[n].pic.pic = NULL;
  5804. }
  5805. }
  5806. }
  5807. void CMapData::GetSmudgeData(DWORD dwIndex, SMUDGE* lpData) const
  5808. {
  5809. ASSERT(m_smudges.size() > dwIndex);
  5810. *lpData = m_smudges[dwIndex];//*m_mapfile.sections["Terrain"].GetValue(dwIndex);
  5811. }
  5812. #endif
  5813. BOOL CMapData::GetInfantryINIData(int index, CString* lpINI)
  5814. {
  5815. ASSERT(index < m_infantry.size());
  5816. if (index >= m_infantry.size() || index < 0) return FALSE;
  5817. INFANTRY& infantry = m_infantry[index];
  5818. CString value;
  5819. value = infantry.house + "," + infantry.type + "," + infantry.strength + "," + infantry.y +
  5820. "," + infantry.x + "," + infantry.pos + "," + infantry.action + "," + infantry.direction + "," +
  5821. infantry.tag + "," + infantry.flag1 + "," + infantry.flag2 + "," + infantry.flag3 + "," +
  5822. infantry.flag4 + "," + infantry.flag5;
  5823. *lpINI = value;
  5824. return TRUE;
  5825. }
  5826. void CMapData::RedrawMinimap()
  5827. {
  5828. const bool mp = IsMultiplayer();
  5829. int i, e;
  5830. for (i = 0; i < m_IsoSize; i++)
  5831. for (e = 0; e < m_IsoSize; e++)
  5832. Mini_UpdatePos(i, e, mp);
  5833. }