objmgr.cpp 105 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634
  1. //---------------------------------------------------------------------------
  2. //
  3. // objmgr.cpp - This file contains the GameObject Manager class code
  4. //
  5. // MechCommander 2
  6. //
  7. //---------------------------------------------------------------------------//
  8. // Copyright (C) Microsoft Corporation. All rights reserved. //
  9. //===========================================================================//
  10. // Include Files
  11. //=============
  12. #ifndef MCLIB_H
  13. #include "mclib.h"
  14. #endif
  15. #ifndef DOBJMGR_H
  16. #include "dobjmgr.h"
  17. #endif
  18. #ifndef OBJMGR_H
  19. #include "objmgr.h"
  20. #endif
  21. #ifndef OBJTYPE_H
  22. #include "objtype.h"
  23. #endif
  24. #ifndef GAMEOBJ_H
  25. #include "gameobj.h"
  26. #endif
  27. #ifndef BLDNG_H
  28. #include "bldng.h"
  29. #endif
  30. #ifndef UNITDESG_H
  31. #include "unitdesg.h"
  32. #endif
  33. #ifndef ARTLRY_H
  34. #include "artlry.h"
  35. #endif
  36. #ifndef TURRET_H
  37. #include "turret.h"
  38. #endif
  39. #ifndef GROUP_H
  40. #include "group.h"
  41. #endif
  42. #ifndef TEAM_H
  43. #include "team.h"
  44. #endif
  45. #ifndef COMNDR_H
  46. #include "comndr.h"
  47. #endif
  48. #ifndef MECH_H
  49. #include "mech.h"
  50. #endif
  51. #ifndef GVEHICL_H
  52. #include "gvehicl.h"
  53. #endif
  54. #ifndef TERROBJ_H
  55. #include "terrobj.h"
  56. #endif
  57. #ifndef WEAPONBOLT_H
  58. #include "weaponbolt.h"
  59. #endif
  60. #ifndef CARNAGE_H
  61. #include "carnage.h"
  62. #endif
  63. #ifndef LIGHT_H
  64. #include "light.h"
  65. #endif
  66. #ifndef GATE_H
  67. #include "gate.h"
  68. #endif
  69. #ifdef USE_ELEMENTALS
  70. #ifndef ELEMNTL_H
  71. #include "elemntl.h"
  72. #endif
  73. #endif
  74. #ifndef COLLSN_H
  75. #include "collsn.h"
  76. #endif
  77. #ifndef WEAPONFX_H
  78. #include "weaponfx.h"
  79. #endif
  80. #ifndef MISSION_H
  81. #include "mission.h"
  82. #endif
  83. #define BRIDGE_OBJTYPE 448
  84. #define MINE1 60
  85. #define MINE2 251
  86. #define MINE3 521
  87. #define MINE4 522
  88. #define MINE5 610
  89. #define MINE6 611
  90. #define MINE7 612
  91. //---------------------------------------------------------------------------
  92. // Static Globals
  93. #if 1 // ids can be 8 long, INCLUDING TERMINATOR!!!!!
  94. char DEFAULT_LIST_ID[] = "DEFAULT";
  95. char CLANMECH_LIST_ID[] = "CLANMEC";
  96. char ISMECH_LIST_ID[] = "ISMECH";
  97. char ICON_LIST_ID[] = "ICONS";
  98. char WEAPON_LIST_ID[] = "WEAPON";
  99. #else
  100. char DEFAULT_LIST_ID[] = "DEFAULT!";
  101. char CLANMECH_LIST_ID[] = "CLANMECH";
  102. char ISMECH_LIST_ID[] = "ISMECH";
  103. char ICON_LIST_ID[] = "ICONS";
  104. char WEAPON_LIST_ID[] = "WEAPON";
  105. #endif
  106. //long ObjectQueue::objectsInList = 0;
  107. extern long usedBlockList[]; //Trust ME~~!!!!!!!!!!!!!!!!!!!!!!!!
  108. extern long moverBlockList[]; //Trust ME~~!!!!!!!!!!!!!!!!!!!!!!!! AGAIN
  109. extern bool updateTerrainObjects;
  110. extern bool updateObjects;
  111. extern bool renderTerrainObjects;
  112. extern bool renderObjects;
  113. extern GameObjectPtr MoverRoster[MAX_MOVER_PART_ID - MIN_MOVER_PART_ID + 1];
  114. extern bool MaxObjectsDrawn;
  115. extern bool drawOldWay;
  116. /*
  117. ObjectQueuePtr objectList = NULL;
  118. ObjectQueueNodePtr clanMechList = NULL;
  119. ObjectQueueNodePtr innerSphereMechList = NULL;
  120. ObjectQueueNodePtr iconList = NULL;
  121. ObjectQueueNodePtr weaponList = NULL;
  122. */
  123. #define VISIBLE_THRESHOLD 1
  124. GameObjectManagerPtr ObjectManager = NULL;
  125. GameObjectPtr* collisionList = NULL;
  126. long numCollidables = 0;
  127. //***************************************************************************
  128. //* MISC routines
  129. //***************************************************************************
  130. bool blockInList (long blockNum)
  131. {
  132. long totalBlocks = Terrain::blocksMapSide * Terrain::blocksMapSide;
  133. for (long i = 0; i < totalBlocks; i++) {
  134. if (usedBlockList[i] == blockNum)
  135. return(TRUE);
  136. else if (usedBlockList[i] == -1)
  137. return(FALSE);
  138. }
  139. return(FALSE);
  140. }
  141. //---------------------------------------------------------------------------
  142. bool moverInList (long blockNum)
  143. {
  144. long totalBlocks = Terrain::blocksMapSide * Terrain::blocksMapSide;
  145. for (long i = 0; i < totalBlocks; i++) {
  146. if (moverBlockList[i] == blockNum)
  147. return(TRUE);
  148. else if (moverBlockList[i] == -1)
  149. return(FALSE);
  150. }
  151. return(FALSE);
  152. }
  153. //***************************************************************************
  154. //* GAMEOBJECT MANAGER class
  155. //***************************************************************************
  156. void* GameObjectManager::operator new (size_t ourSize) {
  157. void* result = systemHeap->Malloc(ourSize);
  158. if (!result)
  159. {
  160. Fatal(0, " GameObjectManager.new: unable to create GameObject Manager ");
  161. }
  162. return(result);
  163. }
  164. //---------------------------------------------------------------------------
  165. void GameObjectManager::operator delete (void* us) {
  166. systemHeap->Free(us);
  167. }
  168. //---------------------------------------------------------------------------
  169. void GameObjectManager::init (void) {
  170. objTypeManager = NULL;
  171. numMechs = 0;
  172. numVehicles = 0;
  173. numElementals = 0;
  174. numTerrainObjects = 0;
  175. numBuildings = 0;
  176. numTurrets = 0;
  177. numWeapons = 0;
  178. numCarnage = 0;
  179. numLights = 0;
  180. numGates = 0;
  181. numArtillery = 0;
  182. numGateControls = 0;
  183. numTurretControls = 0;
  184. numPowerGenerators = 0;
  185. numSpecialBuildings = 0;
  186. //carnageCount = 0;
  187. Terrain::numObjBlocks = 0;
  188. mechs = NULL;
  189. vehicles = NULL;
  190. elementals = NULL;
  191. terrainObjects = NULL;
  192. buildings = NULL;
  193. turrets = 0;
  194. weapons = NULL;
  195. carnage = NULL;
  196. lights = NULL;
  197. artillery = NULL;
  198. gates = NULL;
  199. objList = NULL;
  200. collidableList = NULL;
  201. numCollidables = 0;
  202. numGoodMovers = 0;
  203. numBadMovers = 0;
  204. numMovers = 0;
  205. nextReinforcementPartId = MIN_REINFORCEMENT_PART_ID;
  206. numRemoved = 0;
  207. nextWatchID = 1;
  208. currentWeaponsIndex = 0;
  209. currentCarnageIndex = 0;
  210. currentLightIndex = 0;
  211. currentArtilleryIndex = 0;
  212. long totalBlocks = Terrain::blocksMapSide * Terrain::blocksMapSide;
  213. for (long i = 0; i < totalBlocks; i++) {
  214. Terrain::objBlockInfo[i].active = false;
  215. Terrain::objBlockInfo[i].firstHandle = 0;
  216. Terrain::objBlockInfo[i].numObjects = 0;
  217. }
  218. }
  219. //---------------------------------------------------------------------------
  220. void GameObjectManager::init (char* objTypeDataFile, long objTypeHeapSize, long objHeapSize) {
  221. if (objTypeManager)
  222. delete objTypeManager;
  223. objTypeManager = new ObjectTypeManager;
  224. if (!objTypeManager)
  225. Fatal(0, " GameObjectManager.init: unable to create objTypeManager ");
  226. long result = objTypeManager->init(objTypeDataFile, objTypeHeapSize, objHeapSize);
  227. if (result != NO_ERR)
  228. Fatal(0, " GameObjectManager.init: unable to init objTypeManager ");
  229. }
  230. //---------------------------------------------------------------------------
  231. void GameObjectManager::setNumObjects (long nMechs,
  232. long nVehicles,
  233. long nElementals,
  234. long nTerrainObjects,
  235. long nBuildings,
  236. long nTurrets,
  237. long nWeapons,
  238. long nCarnage,
  239. long nLights,
  240. long nArtillery,
  241. long nGates)
  242. {
  243. long i=0;
  244. numMechs = nMechs;
  245. numVehicles = nVehicles;
  246. numElementals = nElementals;
  247. //-------------------------------------------------------------------------
  248. // We need to make room for a potential max # of reinforcements per team...
  249. //
  250. // Please DONT add 2 to each of these. You wind up pointing into the next list!!!!
  251. // -fs 6/14/2000
  252. maxMechs = numMechs + MAX_TEAMS * MAX_REINFORCEMENTS_PER_TEAM;
  253. maxVehicles = numVehicles + MAX_TEAMS * MAX_REINFORCEMENTS_PER_TEAM;
  254. maxMovers = maxMechs + maxVehicles + numElementals;
  255. if (nTerrainObjects > -1)
  256. numTerrainObjects = nTerrainObjects;
  257. if (nBuildings > -1)
  258. numBuildings = nBuildings;
  259. if (nTurrets > -1)
  260. numTurrets = nTurrets;
  261. if (nWeapons > -1)
  262. numWeapons = nWeapons;
  263. if (nCarnage > -1)
  264. numCarnage = nCarnage;
  265. if (nLights > -1)
  266. numLights = nLights;
  267. if (nArtillery > -1)
  268. numArtillery = nArtillery;
  269. if (nGates > -1)
  270. numGates = nGates;
  271. GameObject::setInitialize(true);
  272. //-----------------------------------------------------------
  273. // First element in list is NULL (handle of 0 is always NULL)
  274. objList = (GameObjectPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  275. memset(objList,0,sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  276. watchList = (GameObjectPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  277. memset(watchList,0,sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  278. long curHandle = 1;
  279. //--------------------------------------------------------------
  280. // For now, we'll use an array of pointers due to the irritating
  281. // 'new' for arrays problem...
  282. if (maxMechs > 0) {
  283. mechs = (BattleMechPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(BattleMechPtr) * maxMechs);
  284. if (!mechs)
  285. Fatal(maxMechs, " GameObjectManager.setNumObjects: cannot malloc mechs ");
  286. for (i = 0; i < maxMechs; i++) {
  287. mechs[i] = new BattleMech;
  288. mechs[i]->setHandle(curHandle);
  289. objList[curHandle++] = mechs[i];
  290. }
  291. for (i = numMechs; i < maxMechs; i++)
  292. mechs[i]->setExists(false);
  293. }
  294. //--------------------------------------------------------------
  295. // For now, we'll use an array of pointers due to the irritating
  296. // 'new' for arrays problem...
  297. if (maxVehicles > 0) {
  298. vehicles = (GroundVehiclePtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GroundVehiclePtr) * maxVehicles);
  299. if (!vehicles)
  300. Fatal(maxVehicles, " GameObjectManager.setNumObjects: cannot malloc vehicles ");
  301. for (i = 0; i < maxVehicles; i++) {
  302. vehicles[i] = new GroundVehicle;
  303. vehicles[i]->setHandle(curHandle);
  304. objList[curHandle++] = vehicles[i];
  305. }
  306. for (i = numVehicles; i < maxVehicles; i++)
  307. vehicles[i]->setExists(false);
  308. }
  309. //--------------------------------------------------------------
  310. // For now, we'll use an array of pointers due to the irritating
  311. // 'new' for arrays problem...
  312. #ifdef USE_ELEMENTALS
  313. if (numElementals > 0) {
  314. elementals = (ElementalPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(ElementalPtr) * numElementals);
  315. if (!elementals)
  316. Fatal(numElementals, " GameObjectManager.setNumObjects: cannot malloc elementals ");
  317. for (i = 0; i < numElementals; i++) {
  318. elementals[i] = new Elemental;
  319. elementals[i]->setHandle(curHandle);
  320. objList[curHandle++] = elementals[i];
  321. }
  322. }
  323. #endif
  324. //--------------------------------------------------------------
  325. // For now, we'll use an array of pointers due to the irritating
  326. // 'new' for arrays problem...
  327. if (numTerrainObjects > 0) {
  328. terrainObjects = (TerrainObjectPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(TerrainObjectPtr) * numTerrainObjects);
  329. if (!terrainObjects)
  330. Fatal(numTerrainObjects, " GameObjectManager.setNumObjects: cannot malloc terrain objects ");
  331. for (i = 0; i < numTerrainObjects; i++) {
  332. terrainObjects[i] = new TerrainObject;
  333. terrainObjects[i]->setHandle(curHandle);
  334. objList[curHandle++] = terrainObjects[i];
  335. }
  336. }
  337. //--------------------------------------------------------------
  338. // For now, we'll use an array of pointers due to the irritating
  339. // 'new' for arrays problem...
  340. if (numBuildings > 0) {
  341. buildings = (BuildingPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(BuildingPtr) * numBuildings);
  342. if (!buildings)
  343. Fatal(numBuildings, " GameObjectManager.setNumObjects: cannot malloc buildings ");
  344. for (i = 0; i < numBuildings; i++) {
  345. buildings[i] = new Building;
  346. buildings[i]->setHandle(curHandle);
  347. objList[curHandle++] = buildings[i];
  348. }
  349. }
  350. if (numTurrets > 0)
  351. {
  352. turrets = (TurretPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(TurretPtr) * numTurrets);
  353. if ( !turrets )
  354. Fatal(numTurrets, " GameObjectManager.setNumObjects: cannot malloc Turrets ");
  355. for (i = 0; i < numTurrets; i++)
  356. {
  357. turrets[i] = new Turret;
  358. turrets[i]->setHandle(curHandle);
  359. objList[curHandle++] = turrets[i];
  360. }
  361. }
  362. if (numGates > 0)
  363. {
  364. gates = (GatePtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GatePtr) * numGates);
  365. if ( !gates )
  366. Fatal(numGates, " GameObjectManager.setNumObjects: cannot malloc Gates ");
  367. for (i = 0; i < numGates; i++)
  368. {
  369. gates[i] = new Gate;
  370. gates[i]->setHandle(curHandle);
  371. objList[curHandle++] = gates[i];
  372. }
  373. }
  374. //--------------------------------------------------------------
  375. // For now, we'll use an array of pointers due to the irritating
  376. // 'new' for arrays problem...
  377. if (numWeapons > 0) {
  378. weapons = (WeaponBoltPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(WeaponBoltPtr) * numWeapons);
  379. if (!weapons)
  380. Fatal(numWeapons, " GameObjectManager.setNumObjects: cannot malloc weapons ");
  381. for (i = 0; i < numWeapons; i++) {
  382. weapons[i] = new WeaponBolt;
  383. weapons[i]->setHandle(curHandle);
  384. objList[curHandle++] = weapons[i];
  385. }
  386. }
  387. if (numCarnage > 0) {
  388. carnage = (CarnagePtr*)ObjectTypeManager::objectCache->Malloc(sizeof(CarnagePtr) * numCarnage);
  389. if (!carnage)
  390. Fatal(numCarnage, " GameObjectManager.setNumObjects: cannot malloc carnage ");
  391. for (i = 0; i < numCarnage; i++) {
  392. carnage[i] = new Carnage;
  393. carnage[i]->setHandle(curHandle);
  394. objList[curHandle++] = carnage[i];
  395. }
  396. }
  397. if (numArtillery > 0) {
  398. artillery = (ArtilleryPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(ArtilleryPtr) * numArtillery);
  399. if (!artillery)
  400. Fatal(numArtillery, " GameObjectManager.setNumObjects: cannot malloc artillery ");
  401. for (i = 0; i < numArtillery; i++) {
  402. artillery[i] = new Artillery;
  403. artillery[i]->setHandle(curHandle);
  404. objList[curHandle++] = artillery[i];
  405. }
  406. }
  407. useMoverLineOfSightTable = true;
  408. moverLineOfSightTable = (char*)systemHeap->Malloc(maxMovers * maxMovers);
  409. if (!moverLineOfSightTable)
  410. Fatal(numGates, " GameObjectManager.setNumObjects: cannot malloc moverLineOfSightTable ");
  411. GameObject::setInitialize(false);
  412. }
  413. //---------------------------------------------------------------------------
  414. BattleMechPtr GameObjectManager::getMech (long mechIndex) {
  415. if (!mechs || (mechIndex < 0) || (mechIndex >= numMechs))
  416. return(NULL);
  417. return(mechs[mechIndex]);
  418. }
  419. //---------------------------------------------------------------------------
  420. GroundVehiclePtr GameObjectManager::getVehicle (long vehicleIndex) {
  421. if (!vehicles || (vehicleIndex < 0) || (vehicleIndex >= numVehicles))
  422. return(NULL);
  423. return(vehicles[vehicleIndex]);
  424. }
  425. //---------------------------------------------------------------------------
  426. GroundVehiclePtr GameObjectManager::getOpenVehicle (void)
  427. {
  428. for (long i=0;i<maxVehicles;i++)
  429. {
  430. if (!vehicles[i]->getExists())
  431. {
  432. if (i > numVehicles)
  433. numVehicles = i;
  434. return vehicles[i];
  435. }
  436. }
  437. return NULL;
  438. }
  439. //---------------------------------------------------------------------------
  440. ElementalPtr GameObjectManager::getElemental (long elementalIndex) {
  441. if (!elementals || (elementalIndex < 0) || (elementalIndex >= numElementals))
  442. return(NULL);
  443. return(elementals[elementalIndex]);
  444. }
  445. //---------------------------------------------------------------------------
  446. BattleMechPtr GameObjectManager::newMech (void) {
  447. if (numMechs < maxMechs) {
  448. mechs[numMechs]->init(false);
  449. mechs[numMechs]->setExists(true);
  450. setPartId(mechs[numMechs], -1, -1, -1);
  451. mechs[numMechs]->watchID = 0;
  452. //Gotta rebuild the list or the new stuff don't show up!
  453. // This flag will force rebuild at next collision check
  454. rebuildCollidableList = true;
  455. return(mechs[numMechs++]);
  456. }
  457. return(NULL);
  458. }
  459. //---------------------------------------------------------------------------
  460. GroundVehiclePtr GameObjectManager::newVehicle (void) {
  461. if (numVehicles < maxVehicles) {
  462. vehicles[numVehicles]->init(false);
  463. vehicles[numVehicles]->setExists(true);
  464. setPartId(vehicles[numVehicles], -1, -1, -1);
  465. vehicles[numVehicles]->watchID = 0;
  466. //Gotta rebuild the list or the new stuff don't show up!
  467. // This flag will force rebuild at next collision check
  468. rebuildCollidableList = true;
  469. return(vehicles[numVehicles++]);
  470. }
  471. return(NULL);
  472. }
  473. //---------------------------------------------------------------------------
  474. void GameObjectManager::setWatchID (GameObjectPtr obj) {
  475. if (obj->watchID == 0) {
  476. watchList[nextWatchID] = obj;
  477. obj->watchID = nextWatchID++;
  478. }
  479. }
  480. //---------------------------------------------------------------------------
  481. void GameObjectManager::freeMover (MoverPtr mover) {
  482. bool foundIt = modifyMoverLists(mover, MOVERLIST_DELETE);
  483. if (foundIt) {
  484. mover->release();
  485. mover->setExists(false);
  486. mover->setFlag(OBJECT_FLAG_REMOVED, true);
  487. mover->setPartId(0);
  488. watchList[mover->watchID] = NULL;
  489. mover->watchID = 0;
  490. }
  491. }
  492. //---------------------------------------------------------------------------
  493. void GameObjectManager::tradeMover (MoverPtr mover, long newTeamID, long newCommanderID) {
  494. if (newTeamID > -1) {
  495. if (mover->teamId != newTeamID)
  496. mover->salvaged = true;
  497. if (mover->getObjectClass() == BATTLEMECH) {
  498. ((BattleMech*)mover)->killed = false;
  499. ((BattleMech*)mover)->lost = false;
  500. }
  501. mover->tradeRefresh();
  502. }
  503. mover->setTeamId(newTeamID, true);
  504. if (mover->getGroup())
  505. mover->getGroup()->remove(mover);
  506. mover->watchID = 0;
  507. if (newTeamID > -1)
  508. Team::teams[newTeamID]->addToRoster(mover);
  509. mover->setCommanderId(newCommanderID);
  510. modifyMoverLists(mover, MOVERLIST_TRADE);
  511. }
  512. //---------------------------------------------------------------------------
  513. #ifdef USE_ELEMENTALS
  514. ElementalPtr GameObjectManager::addElemental (void) {
  515. if (numMechs < maxMechs) {
  516. elementals[numElementals]->setExists(true);
  517. setPartId(elementals[numElementals], -1, -1, -1);
  518. return(elementals[numElementals++]);
  519. }
  520. return(NULL);
  521. }
  522. #endif
  523. //---------------------------------------------------------------------------
  524. TerrainObjectPtr GameObjectManager::getTerrainObject (long terrainObjectIndex) {
  525. if (!terrainObjects || (terrainObjectIndex < 0) || (terrainObjectIndex >= numTerrainObjects))
  526. return(NULL);
  527. return(terrainObjects[terrainObjectIndex]);
  528. }
  529. //---------------------------------------------------------------------------
  530. BuildingPtr GameObjectManager::getBuilding (long buildingIndex) {
  531. if (!buildings || (buildingIndex < 0) || (buildingIndex >= numBuildings))
  532. return(NULL);
  533. return(buildings[buildingIndex]);
  534. }
  535. //---------------------------------------------------------------------------
  536. TurretPtr GameObjectManager::getTurret (long turretIndex)
  537. {
  538. if (!turrets || (turretIndex < 0) || (turretIndex >= numTurrets))
  539. return(NULL);
  540. return(turrets[turretIndex]);
  541. }
  542. //---------------------------------------------------------------------------
  543. GatePtr GameObjectManager::getGate (long gateIndex)
  544. {
  545. if (!gates || (gateIndex < 0) || (gateIndex >= numGates))
  546. return(NULL);
  547. return(gates[gateIndex]);
  548. }
  549. //---------------------------------------------------------------------------
  550. WeaponBoltPtr GameObjectManager::getWeapon (void)
  551. {
  552. if (!weapons || (currentWeaponsIndex < 0) || (currentWeaponsIndex >= numWeapons))
  553. return(NULL);
  554. currentWeaponsIndex++;
  555. if (currentWeaponsIndex >= numWeapons)
  556. currentWeaponsIndex = 0;
  557. //Make sure this weapon has an opportunity to damage its target
  558. weapons[currentWeaponsIndex]->finishNow();
  559. return(weapons[currentWeaponsIndex]);
  560. }
  561. //---------------------------------------------------------------------------
  562. CarnagePtr GameObjectManager::getCarnage (CarnageEnumType carnageType) {
  563. if (!carnage || (currentCarnageIndex < 0) || (currentCarnageIndex >= numCarnage))
  564. return(NULL);
  565. currentCarnageIndex++;
  566. if (currentCarnageIndex >= numCarnage)
  567. currentCarnageIndex = 0;
  568. carnage[currentCarnageIndex]->finishNow();
  569. carnage[currentCarnageIndex]->init(carnageType);
  570. return(carnage[currentCarnageIndex]);
  571. }
  572. //---------------------------------------------------------------------------
  573. void GameObjectManager::releaseCarnage (CarnagePtr obj) {
  574. obj->setExists(false);
  575. obj->setOwner(NULL);
  576. }
  577. //---------------------------------------------------------------------------
  578. LightPtr GameObjectManager::getLight (void) {
  579. if (!lights || (currentLightIndex < 0) || (currentLightIndex >= numLights))
  580. return(NULL);
  581. if (currentLightIndex >= numLights)
  582. currentLightIndex = 0;
  583. // lights[currentLightIndex]->finishNow();
  584. lights[currentLightIndex]->init(false);
  585. lights[currentLightIndex]->setExists(true);
  586. return(lights[currentLightIndex++]);
  587. }
  588. //---------------------------------------------------------------------------
  589. void GameObjectManager::releaseLight (LightPtr obj) {
  590. obj->setExists(false);
  591. // obj->setOwner(NULL);
  592. }
  593. //---------------------------------------------------------------------------
  594. ArtilleryPtr GameObjectManager::getArtillery (void)
  595. {
  596. if (!artillery || (currentArtilleryIndex < 0) || (currentArtilleryIndex >= numArtillery))
  597. STOP(("Artillery Strikes are out of range in ObjectManager %d",currentArtilleryIndex));
  598. currentArtilleryIndex++;
  599. if (currentArtilleryIndex >= numArtillery)
  600. currentArtilleryIndex = 0;
  601. //OK to return NULL now. Lets Multiplayer know that there are no more strikes available.
  602. if (artillery[currentArtilleryIndex]->getExists())
  603. return NULL;
  604. artillery[currentArtilleryIndex]->init(false);
  605. artillery[currentArtilleryIndex]->setExists(true);
  606. return(artillery[currentArtilleryIndex]);
  607. }
  608. //---------------------------------------------------------------------------
  609. #define MAX_TERRAIN_OBJECTS 3000
  610. #define OLD_FILE_SIZE 2200
  611. void GameObjectManager::countTerrainObjects (PacketFile* terrainFile, long firstHandle)
  612. {
  613. int packet = terrainFile->getCurrentPacket();
  614. int size = terrainFile->getPacketSize();
  615. MemoryPtr pBuffer = new unsigned char[size];
  616. #ifdef _DEBUG
  617. int bytesRead =
  618. #endif
  619. terrainFile->readPacket( packet, pBuffer );
  620. gosASSERT( bytesRead == size );
  621. File* terrainObjectFile = new File;
  622. terrainObjectFile->open( (char*)pBuffer, size );
  623. totalObjCount = terrainObjectFile->readLong();
  624. if (totalObjCount)
  625. {
  626. objData = (ObjDataLoader *)systemHeap->Malloc(sizeof(ObjDataLoader) * totalObjCount);
  627. memset(objData,0,sizeof(ObjDataLoader) * totalObjCount);
  628. }
  629. else
  630. {
  631. objData = NULL;
  632. }
  633. ObjDataLoader *data = objData;
  634. for ( int i = 0; i < totalObjCount; ++i )
  635. {
  636. data->objTypeNum = terrainObjectFile->readLong();
  637. data->vector.x = terrainObjectFile->readFloat();
  638. data->vector.y = terrainObjectFile->readFloat();
  639. data->vector.z = terrainObjectFile->readFloat();
  640. data->rotation = terrainObjectFile->readFloat();
  641. data->damage = terrainObjectFile->readLong();
  642. data->teamId = terrainObjectFile->readLong();
  643. data->parentId = terrainObjectFile->readLong();
  644. // padding
  645. terrainObjectFile->readLong();
  646. terrainObjectFile->readLong();
  647. // convert to block and vertex
  648. long tileCol;
  649. long tileRow;
  650. land->worldToTile( data->vector, tileRow, tileCol );
  651. int blockI = tileCol/20;
  652. int blockJ = tileRow/20;
  653. data->blockNumber = blockJ * land->blocksMapSide + blockI;
  654. tileCol -= blockI * 20;
  655. tileRow -= blockJ * 20;
  656. data->vertexNumber = tileRow * 20 + tileRow;
  657. countObject(data);
  658. data++;
  659. }
  660. // fix up handles
  661. long curHandle = firstHandle;
  662. for ( i = 0; i < Terrain::numObjBlocks; ++i )
  663. {
  664. Terrain::objBlockInfo[i].firstHandle = curHandle;
  665. curHandle += Terrain::objBlockInfo[i].numObjects;
  666. }
  667. delete terrainObjectFile;
  668. delete pBuffer;
  669. }
  670. void GameObjectManager::countObject( ObjDataLoader *data)
  671. {
  672. ObjectTypePtr objType = objTypeManager->get(data->objTypeNum);
  673. if (!objType)
  674. objType = objTypeManager->load(data->objTypeNum);
  675. if (!objType)
  676. return;
  677. //Fatal(objDataBlock[i].objTypeNum, " GameObjectManager.countTerrainObjects: bad objType ");
  678. switch (objType->getObjectClass())
  679. {
  680. case TERRAINOBJECT:
  681. case TREE:
  682. Terrain::objBlockInfo[data->blockNumber].numCollidableObjects++;
  683. numTerrainObjects++;
  684. break;
  685. case TURRET:
  686. Terrain::objBlockInfo[data->blockNumber].numCollidableObjects++;
  687. numTurrets++;
  688. break;
  689. case GATE:
  690. Terrain::objBlockInfo[data->blockNumber].numCollidableObjects++;
  691. numGates++;
  692. break;
  693. case BUILDING:
  694. case TREEBUILDING:
  695. if (((((BuildingTypePtr)objType)->perimeterAlarmRange > 0.0f) &&
  696. (((BuildingTypePtr)objType)->perimeterAlarmTimer > 0.0f)) ||
  697. (((BuildingTypePtr)objType)->lookoutTowerRange > 0.0f) ||
  698. (((BuildingTypePtr)objType)->sensorRange > 0.0f))
  699. {
  700. Terrain::objBlockInfo[data->blockNumber].numCollidableObjects++;
  701. }
  702. numBuildings++;
  703. break;
  704. case BRIDGE:
  705. numTerrainObjects++;
  706. break;
  707. default:
  708. Fatal(objType->getObjectClass(), " GameObjectManager.countTerrainObjects: bad object type ");
  709. }
  710. Terrain::objBlockInfo[data->blockNumber].numObjects++;
  711. }
  712. //---------------------------------------------------------------------------
  713. inline bool isLandMine (long objTypeNum)
  714. {
  715. return false;
  716. }
  717. //---------------------------------------------------------------------------
  718. long GameObjectManager::getSpecificObjects (long objClass, long objSubType, GameObjectPtr* objects, long maxObjects) {
  719. long numValidObjects = 0;
  720. for (long i = 0; i < getNumObjects(); i++) {
  721. GameObjectPtr obj = objList[i];
  722. if (obj && (obj->getObjectClass() == objClass) && (obj->getObjectType()->getSubType() == objSubType)) {
  723. if (numValidObjects == maxObjects)
  724. Fatal(objClass, " GameObjectManager.getSpecificObjects: too many ");
  725. objects[numValidObjects++] = obj;
  726. }
  727. }
  728. return(numValidObjects);
  729. }
  730. //---------------------------------------------------------------------------
  731. void GameObjectManager::loadTerrainObjects (PacketFile* terrainFile,
  732. volatile float& progress, float progressRange )
  733. {
  734. long curTerrainObjectIndex = 0;
  735. long curBuildingIndex = 0;
  736. long curTurretIndex = 0;
  737. long curGateIndex = 0;
  738. //------------------------------------------------------------------
  739. long* handles = new long[2 * Terrain::numObjBlocks];
  740. for ( int i = 0; i < Terrain::numObjBlocks; ++i )
  741. {
  742. handles[2 * i] = Terrain::objBlockInfo[i].firstHandle;
  743. handles[(2 * i) + 1] = Terrain::objBlockInfo[i].firstHandle + Terrain::objBlockInfo[i].numCollidableObjects;
  744. }
  745. ObjDataLoader *data = objData;
  746. float increment = 0.0f;
  747. if (totalObjCount)
  748. increment = progressRange/totalObjCount;
  749. for ( i = 0; i < totalObjCount; ++i )
  750. {
  751. addObject( data,
  752. curTerrainObjectIndex, curBuildingIndex,
  753. curTurretIndex, curGateIndex, handles[2 * data->blockNumber],
  754. handles[(2 * data->blockNumber) + 1]
  755. );
  756. data++;
  757. progress += increment;
  758. }
  759. delete handles;
  760. handles = NULL;
  761. //Done loading the objects, free the memory holding them!!
  762. systemHeap->Free(objData);
  763. objData = NULL;
  764. //---------------------------------------------------
  765. // Finally, let's build the control building lists...
  766. for (i = 0; i < numTurrets; i++)
  767. {
  768. if ((turrets[i]->parentId != 0xffffffff) && (turrets[i]->parentId != 0))
  769. {
  770. BuildingPtr controlBuilding = (BuildingPtr)ObjectManager->findByCellPosition((turrets[i]->parentId>>16),(turrets[i]->parentId & 0x0000ffff));
  771. if (controlBuilding && !controlBuilding->getFlag(OBJECT_FLAG_CONTROLBUILDING))
  772. {
  773. controlBuilding->setFlag(OBJECT_FLAG_CAPTURABLE, true);
  774. controlBuilding->setFlag(OBJECT_FLAG_CONTROLBUILDING, true);
  775. controlBuilding->listID = numTurretControls;
  776. turretControls[numTurretControls++] = controlBuilding;
  777. }
  778. else if (!controlBuilding)
  779. {
  780. Stuff::Vector3D worldPos;
  781. if (land)
  782. land->cellToWorld((turrets[i]->parentId>>16),(turrets[i]->parentId & 0x0000ffff),worldPos);
  783. PAUSE(("Turret linked to bldg @ R %d, C %d X:%f Y:%f No Bldg there!",(turrets[i]->parentId>>16),(turrets[i]->parentId & 0x0000ffff),worldPos.x,worldPos.y));
  784. turrets[i]->parentId = 0xffffffff;
  785. }
  786. }
  787. }
  788. for (i = 0; i < numGates; i++)
  789. {
  790. if ((gates[i]->parentId != 0xffffffff) && (gates[i]->parentId != 0))
  791. {
  792. BuildingPtr controlBuilding = (BuildingPtr)ObjectManager->findByCellPosition((gates[i]->parentId>>16),(gates[i]->parentId & 0x0000ffff));
  793. if (controlBuilding && !controlBuilding->getFlag(OBJECT_FLAG_CONTROLBUILDING))
  794. {
  795. controlBuilding->setFlag(OBJECT_FLAG_CONTROLBUILDING, true);
  796. controlBuilding->listID = numGateControls;
  797. gateControls[numGateControls++] = controlBuilding;
  798. }
  799. else if (!controlBuilding)
  800. {
  801. PAUSE(("Gate tried to link to building at Row %d, Col %d. No Bldg there!",(gates[i]->parentId>>16),(gates[i]->parentId & 0x0000ffff)));
  802. gates[i]->parentId = 0xffffffff;
  803. }
  804. }
  805. }
  806. //-----------------------------------------------------------------------------------
  807. // Create list of special buildings. These buildings will be updated at least once
  808. // every frame regardless of where they are on the terrain and what is visible.
  809. // This is because perimeter alarms and lookout buildings and ????? must work even
  810. // if the player is NOT looking at them!!
  811. for (i=0;i<numBuildings;i++)
  812. {
  813. if (buildings[i]->isSpecialBuilding())
  814. {
  815. specialBuildings[numSpecialBuildings++] = buildings[i];
  816. }
  817. }
  818. //--------------------------------------------------------------------
  819. //Now, lets point every lit building to at least one power generator.
  820. for (i=0;i<numBuildings;i++)
  821. {
  822. if (buildings[i]->isPowerSource())
  823. {
  824. powerGenerators[numPowerGenerators++] = buildings[i];
  825. }
  826. }
  827. if (numPowerGenerators)
  828. {
  829. for (i=0;i<numBuildings;i++)
  830. {
  831. Stuff::Vector3D maxDist;
  832. long generatorIndex = 0;
  833. maxDist.Subtract(buildings[i]->getPosition(),powerGenerators[0]->getPosition());
  834. float minDistance = maxDist.GetApproximateLength();
  835. for (long j=1;j<numPowerGenerators;j++)
  836. {
  837. maxDist.Subtract(buildings[i]->getPosition(),powerGenerators[j]->getPosition());
  838. float newDistance = maxDist.GetApproximateLength();
  839. if (newDistance < minDistance)
  840. {
  841. generatorIndex = j;
  842. minDistance = newDistance;
  843. }
  844. }
  845. buildings[i]->setPowerSupply(powerGenerators[generatorIndex]);
  846. }
  847. for (i=0;i<numTerrainObjects;i++)
  848. {
  849. Stuff::Vector3D maxDist;
  850. long generatorIndex = 0;
  851. maxDist.Subtract(terrainObjects[i]->getPosition(),powerGenerators[0]->getPosition());
  852. float minDistance = maxDist.GetApproximateLength();
  853. for (long j=1;j<numPowerGenerators;j++)
  854. {
  855. maxDist.Subtract(terrainObjects[i]->getPosition(),powerGenerators[j]->getPosition());
  856. float newDistance = maxDist.GetApproximateLength();
  857. if (newDistance < minDistance)
  858. {
  859. generatorIndex = j;
  860. minDistance = newDistance;
  861. }
  862. }
  863. terrainObjects[i]->setPowerSupply(powerGenerators[generatorIndex]);
  864. }
  865. }
  866. }
  867. extern GameObjectFootPrint* tempSpecialAreaFootPrints;
  868. extern long tempNumSpecialAreas;
  869. void GameObjectManager::addObject (ObjDataLoader *objData, long& curTerrainObjectIndex,
  870. long& curBuildingIndex, long& curTurretIndex, long &curGateIndex,
  871. long& curCollidableHandle, long& curNonCollidableHandle )
  872. {
  873. // THIS IS NOT COMPLETELY DONE! MAKE SURE ALL TERRAIN OBJ TYPES
  874. // ARE ACCOUNTED FOR HERE!
  875. long objTypeNum = objData->objTypeNum;
  876. if (!isLandMine(objTypeNum)) {
  877. ObjectTypePtr objType = getObjectType(objTypeNum);
  878. GameObjectPtr obj = NULL;
  879. if (!objType)
  880. return;
  881. //Fatal();
  882. Stuff::Vector2DOf<long> numbers;
  883. numbers.x = objData->vertexNumber;
  884. numbers.y = objData->blockNumber;
  885. unsigned char realDmg = objData->damage & 0x0f;
  886. switch (objType->getObjectClass()) {
  887. case TERRAINOBJECT:
  888. case TREE:
  889. obj = getTerrainObject(curTerrainObjectIndex++);
  890. if (obj)
  891. {
  892. ((TerrainObjectPtr)obj)->init(true, objType);
  893. if (realDmg)
  894. ((TerrainObjectPtr)obj)->setDamage(((TerrainObjectTypePtr)objType)->getDamageLevel());
  895. objList[curCollidableHandle] = obj;
  896. obj->setHandle(curCollidableHandle++);
  897. obj->setExists(true);
  898. }
  899. else
  900. {
  901. Fatal(curBuildingIndex," No More Trees ");
  902. }
  903. break;
  904. case TURRET:
  905. obj = getTurret(curTurretIndex++);
  906. if (obj)
  907. {
  908. ((TurretPtr)obj)->init(true, objType);
  909. if (realDmg)
  910. obj->setDamage(((TurretTypePtr)objType)->getDamageLevel());
  911. objList[curCollidableHandle] = obj;
  912. obj->setHandle(curCollidableHandle++);
  913. obj->setExists(true);
  914. obj->setParentId(objData->parentId);
  915. obj->setTeamId(objData->teamId,true);
  916. }
  917. else
  918. {
  919. Fatal(curTurretIndex," No More Turrets ");
  920. }
  921. break;
  922. case GATE:
  923. obj = getGate(curGateIndex++);
  924. if (obj)
  925. {
  926. ((GatePtr)obj)->init(true, objType);
  927. if (realDmg)
  928. obj->setDamage(((GateTypePtr)objType)->getDamageLvl());
  929. objList[curCollidableHandle] = obj;
  930. obj->setHandle(curCollidableHandle++);
  931. obj->setExists(true);
  932. obj->setParentId(objData->parentId);
  933. obj->setTeamId(objData->teamId,true);
  934. }
  935. else
  936. {
  937. Fatal(curGateIndex," No More Gates ");
  938. }
  939. break;
  940. case BUILDING:
  941. case TREEBUILDING:
  942. obj = getBuilding(curBuildingIndex++);
  943. if (obj)
  944. {
  945. ((BuildingPtr)obj)->init(true, objType);
  946. if (realDmg)
  947. obj->setDamage(((BuildingTypePtr)objType)->getDamageLevel());
  948. ((BuildingPtr)obj)->baseTileId = (objData->damage >> 4);
  949. if (obj->isSpecialBuilding())
  950. {
  951. objList[curCollidableHandle] = obj;
  952. obj->setHandle(curCollidableHandle++);
  953. }
  954. else
  955. {
  956. objList[curNonCollidableHandle] = obj;
  957. obj->setHandle(curNonCollidableHandle++);
  958. }
  959. obj->setExists(true);
  960. obj->setParentId(objData->parentId);
  961. obj->setTeamId(objData->teamId,true);
  962. }
  963. else
  964. {
  965. Fatal(curBuildingIndex," No More Buildings ");
  966. }
  967. break;
  968. case BRIDGE:
  969. break;
  970. default:
  971. Fatal(objType->getObjectClass(), " GameObjectManager.countTerrainObjects: bad object type ");
  972. }
  973. if (obj) {
  974. obj->setTerrainPosition(objData->vector, numbers);
  975. long cellRow, cellCol;
  976. obj->getCellPosition(cellRow, cellCol);
  977. setPartId(obj, cellRow, cellCol);
  978. //Just keep the designers from hurting themselves
  979. if (objType->getObjectClass() != TURRET)
  980. obj->setRotation(objData->rotation);
  981. if (obj->isTerrainObject()) {
  982. Stuff::Vector3D pos = objData->vector;
  983. ((TerrainObjectPtr)obj)->calcCellFootprint(pos);
  984. if (obj->getObjectClass() == BUILDING) {
  985. if (objType->getSubType() == BUILDING_SUBTYPE_WALL) {
  986. for (long i = 0; i < tempNumSpecialAreas; i++)
  987. if (tempSpecialAreaFootPrints[i].cellPositionRow == cellRow)
  988. if (tempSpecialAreaFootPrints[i].cellPositionCol == cellCol) {
  989. ((BuildingPtr)obj)->calcSubAreas(tempSpecialAreaFootPrints[i].numCells, tempSpecialAreaFootPrints[i].cells);
  990. break;
  991. }
  992. ((BuildingPtr)obj)->closeSubAreas();
  993. }
  994. else if (objType->getSubType() == BUILDING_SUBTYPE_LANDBRIDGE) {
  995. for (long i = 0; i < tempNumSpecialAreas; i++)
  996. if (tempSpecialAreaFootPrints[i].cellPositionRow == cellRow)
  997. if (tempSpecialAreaFootPrints[i].cellPositionCol == cellCol) {
  998. ((BuildingPtr)obj)->calcSubAreas(tempSpecialAreaFootPrints[i].numCells, tempSpecialAreaFootPrints[i].cells);
  999. break;
  1000. }
  1001. ((BuildingPtr)obj)->openSubAreas();
  1002. }
  1003. }
  1004. else if (obj->getObjectClass() == GATE) {
  1005. for (long i = 0; i < tempNumSpecialAreas; i++)
  1006. if (tempSpecialAreaFootPrints[i].cellPositionRow == cellRow)
  1007. if (tempSpecialAreaFootPrints[i].cellPositionCol == cellCol) {
  1008. ((BuildingPtr)obj)->calcSubAreas(tempSpecialAreaFootPrints[i].numCells, tempSpecialAreaFootPrints[i].cells);
  1009. break;
  1010. }
  1011. ((GatePtr)obj)->openSubAreas();
  1012. for (i = 0; i < ((GatePtr)obj)->numSubAreas0; i++) {
  1013. GlobalMoveMap[0]->setAreaOwnerWID(((GatePtr)obj)->subAreas0[i], ((GatePtr)obj)->getWatchID());
  1014. GlobalMoveMap[1]->setAreaOwnerWID(((GatePtr)obj)->subAreas1[i], ((GatePtr)obj)->getWatchID());
  1015. if (((GatePtr)obj)->status == OBJECT_STATUS_DESTROYED) {
  1016. GlobalMoveMap[0]->setAreaTeamID(((GatePtr)obj)->subAreas0[i], -1);
  1017. GlobalMoveMap[1]->setAreaTeamID(((GatePtr)obj)->subAreas1[i], -1);
  1018. }
  1019. else {
  1020. GlobalMoveMap[0]->setAreaTeamID(((GatePtr)obj)->subAreas0[i], ((GatePtr)obj)->teamId);
  1021. GlobalMoveMap[1]->setAreaTeamID(((GatePtr)obj)->subAreas1[i], -1);
  1022. }
  1023. }
  1024. ((GatePtr)obj)->setTeamId(obj->getTeamId(), true);
  1025. short* curCoord = ((GatePtr)obj)->cellsCovered;
  1026. for (i = 0; i < ((GatePtr)obj)->numCellsCovered; i++) {
  1027. long r = *curCoord++;
  1028. long c = *curCoord++;
  1029. GameMap->setGate(r, c, true);
  1030. }
  1031. }
  1032. }
  1033. }
  1034. }
  1035. }
  1036. //---------------------------------------------------------------------------
  1037. void GameObjectManager::destroy (void)
  1038. {
  1039. //--------------------------------------------------------------
  1040. // Free 'em all up!!
  1041. long i=0;
  1042. if (mechs && maxMechs > 0)
  1043. {
  1044. for (i = 0; i < maxMechs; i++)
  1045. {
  1046. delete mechs[i];
  1047. mechs[i] = NULL;
  1048. }
  1049. }
  1050. mechs = NULL;
  1051. //--------------------------------------------------------------
  1052. if (vehicles && maxVehicles > 0)
  1053. {
  1054. for (i = 0; i < maxVehicles; i++)
  1055. {
  1056. delete vehicles[i];
  1057. vehicles[i] = NULL;
  1058. }
  1059. }
  1060. vehicles = NULL;
  1061. //--------------------------------------------------------------
  1062. if (terrainObjects && numTerrainObjects > 0)
  1063. {
  1064. for (i = 0; i < numTerrainObjects; i++)
  1065. {
  1066. delete terrainObjects[i];
  1067. terrainObjects[i] = NULL;
  1068. }
  1069. }
  1070. terrainObjects = NULL;
  1071. //--------------------------------------------------------------
  1072. if (buildings && numBuildings > 0)
  1073. {
  1074. for (i = 0; i < numBuildings; i++)
  1075. {
  1076. delete buildings[i];
  1077. buildings[i] = NULL;
  1078. }
  1079. }
  1080. buildings = NULL;
  1081. //--------------------------------------------------------------
  1082. if (turrets && numTurrets > 0)
  1083. {
  1084. for (i = 0; i < numTurrets; i++)
  1085. {
  1086. delete turrets[i];
  1087. turrets[i] = NULL;
  1088. }
  1089. }
  1090. turrets = NULL;
  1091. //--------------------------------------------------------------
  1092. if (gates && numGates > 0)
  1093. {
  1094. for (i = 0; i < numGates; i++)
  1095. {
  1096. delete gates[i];
  1097. gates[i] = NULL;
  1098. }
  1099. }
  1100. gates = NULL;
  1101. //--------------------------------------------------------------
  1102. if (weapons && numWeapons > 0)
  1103. {
  1104. for (i = 0; i < numWeapons; i++)
  1105. {
  1106. delete weapons[i];
  1107. weapons[i] = NULL;
  1108. }
  1109. }
  1110. weapons = NULL;
  1111. //--------------------------------------------------------------
  1112. if (carnage && numCarnage > 0)
  1113. {
  1114. for (i = 0; i < numCarnage; i++)
  1115. {
  1116. delete carnage[i];
  1117. carnage[i] = NULL;
  1118. }
  1119. }
  1120. carnage = NULL;
  1121. //--------------------------------------------------------------
  1122. if (lights && numLights > 0)
  1123. {
  1124. for (i = 0; i < numLights; i++)
  1125. {
  1126. delete lights[i];
  1127. lights[i] = NULL;
  1128. }
  1129. }
  1130. lights = NULL;
  1131. //--------------------------------------------------------------
  1132. if (artillery && numArtillery > 0)
  1133. {
  1134. for (i = 0; i < numArtillery; i++)
  1135. {
  1136. delete artillery[i];
  1137. artillery[i] = NULL;
  1138. }
  1139. }
  1140. artillery = NULL;
  1141. //--------------------------------------------------------------
  1142. if (objTypeManager)
  1143. {
  1144. delete objTypeManager;
  1145. objTypeManager = NULL;
  1146. }
  1147. delete collisionSystem;
  1148. collisionSystem = NULL;
  1149. systemHeap->Free(moverLineOfSightTable);
  1150. moverLineOfSightTable = NULL;
  1151. }
  1152. //---------------------------------------------------------------------------
  1153. void GameObjectManager::render (bool terrain, bool movers, bool other) {
  1154. //-----------------------------------------------------
  1155. //Set render states as few times as possible.
  1156. if (drawOldWay)
  1157. {
  1158. //--------------------------------
  1159. //Set States for Software Renderer
  1160. if (Environment.Renderer == 3)
  1161. {
  1162. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero);
  1163. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
  1164. gos_SetRenderState( gos_State_MonoEnable, 1);
  1165. gos_SetRenderState( gos_State_Perspective, 0);
  1166. gos_SetRenderState( gos_State_Clipping, 1);
  1167. gos_SetRenderState( gos_State_Specular, 0);
  1168. gos_SetRenderState( gos_State_Dither, 0);
  1169. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate);
  1170. gos_SetRenderState( gos_State_Filter, gos_FilterNone);
  1171. gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap );
  1172. gos_SetRenderState( gos_State_ZCompare, 1);
  1173. gos_SetRenderState( gos_State_ZWrite, 1);
  1174. }
  1175. //--------------------------------
  1176. //Set States for Hardware Renderer
  1177. else
  1178. {
  1179. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero);
  1180. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
  1181. gos_SetRenderState( gos_State_MonoEnable, 0);
  1182. gos_SetRenderState( gos_State_Perspective, 1);
  1183. gos_SetRenderState( gos_State_Clipping, 1);
  1184. gos_SetRenderState( gos_State_Specular, 1);
  1185. gos_SetRenderState( gos_State_Dither, 1);
  1186. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate);
  1187. gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap );
  1188. gos_SetRenderState( gos_State_ZCompare, 1);
  1189. gos_SetRenderState( gos_State_ZWrite, 1);
  1190. }
  1191. }
  1192. if (terrain && renderObjects)
  1193. {
  1194. for (long terrainBlock = 0; terrainBlock < Terrain::numObjBlocks; terrainBlock++)
  1195. {
  1196. if (Terrain::objBlockInfo[terrainBlock].active)
  1197. {
  1198. long numObjs = Terrain::objBlockInfo[terrainBlock].numObjects;
  1199. long objIndex = Terrain::objBlockInfo[terrainBlock].firstHandle;
  1200. for (long terrainObj = 0; terrainObj < numObjs; terrainObj++, objIndex++)
  1201. {
  1202. if (objList[objIndex] &&
  1203. Terrain::objVertexActive[objList[objIndex]->getVertexNum()])
  1204. {
  1205. objList[objIndex]->render();
  1206. if (MaxObjectsDrawn)
  1207. {
  1208. //-----------------------------------------
  1209. // No more element groups, so stop drawing.
  1210. return;
  1211. }
  1212. }
  1213. }
  1214. }
  1215. }
  1216. }
  1217. if (movers) {
  1218. if (mechs && (numMechs < maxMechs))
  1219. {
  1220. for (long i = 0; i < numMechs; i++)
  1221. {
  1222. if (mechs[i] && mechs[i]->getExists())
  1223. mechs[i]->render();
  1224. }
  1225. }
  1226. if (vehicles) {
  1227. for (long i = 0; i < maxVehicles; i++)
  1228. if (vehicles[i] && vehicles[i]->getExists())
  1229. vehicles[i]->render();
  1230. }
  1231. #ifdef USE_ELEMENTALS
  1232. if (elementals) {
  1233. for (long i = 0; i < numElementals; i++)
  1234. if (elementals[i] && elementals[i]->getExists())
  1235. elementals[i]->render();
  1236. }
  1237. #endif
  1238. }
  1239. if (other) {
  1240. //----------------------------------------
  1241. // All other objects should be rendered...
  1242. if (weapons) {
  1243. for (long i = 0; i < numWeapons; i++) {
  1244. if (weapons[i] && weapons[i]->getExists())
  1245. weapons[i]->render();
  1246. }
  1247. }
  1248. if (carnage) {
  1249. for (long i = 0; i < numCarnage; i++) {
  1250. if (carnage[i] && carnage[i]->getExists())
  1251. {
  1252. carnage[i]->render();
  1253. }
  1254. }
  1255. }
  1256. if (lights) {
  1257. for (long i = 0; i < numLights; i++) {
  1258. if (lights[i] && lights[i]->getExists())
  1259. lights[i]->render();
  1260. }
  1261. }
  1262. if (artillery) {
  1263. for (long i = 0; i < numArtillery; i++) {
  1264. if (artillery[i] && artillery[i]->getExists())
  1265. artillery[i]->render();
  1266. }
  1267. }
  1268. }
  1269. gos_SetRenderState( gos_State_Fog, 0);
  1270. }
  1271. //---------------------------------------------------------------------------
  1272. void GameObjectManager::renderShadows (bool terrain, bool movers, bool other) {
  1273. //-----------------------------------------------------
  1274. //Set render states as few times as possible.
  1275. //--------------------------------
  1276. //Set States for Software Renderer
  1277. if (Environment.Renderer == 3)
  1278. {
  1279. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero);
  1280. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeFlat);
  1281. gos_SetRenderState( gos_State_MonoEnable, 1);
  1282. gos_SetRenderState( gos_State_Perspective, 0);
  1283. gos_SetRenderState( gos_State_Clipping, 1);
  1284. gos_SetRenderState( gos_State_AlphaTest, 0);
  1285. gos_SetRenderState( gos_State_Specular, 0);
  1286. gos_SetRenderState( gos_State_Dither, 0);
  1287. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendDecal);
  1288. gos_SetRenderState( gos_State_Filter, gos_FilterNone);
  1289. gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap );
  1290. gos_SetRenderState( gos_State_ZCompare, 0);
  1291. gos_SetRenderState( gos_State_ZWrite, 0);
  1292. }
  1293. //--------------------------------
  1294. //Set States for Hardware Renderer
  1295. else
  1296. {
  1297. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha);
  1298. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeFlat);
  1299. gos_SetRenderState( gos_State_MonoEnable, 1);
  1300. gos_SetRenderState( gos_State_Perspective, 0);
  1301. gos_SetRenderState( gos_State_Clipping, 1);
  1302. gos_SetRenderState( gos_State_AlphaTest, 1);
  1303. gos_SetRenderState( gos_State_Specular, 0);
  1304. gos_SetRenderState( gos_State_Dither, 1);
  1305. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate);
  1306. gos_SetRenderState( gos_State_Filter, gos_FilterNone);
  1307. gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap );
  1308. gos_SetRenderState( gos_State_ZCompare, 2);
  1309. gos_SetRenderState( gos_State_ZWrite, 1);
  1310. }
  1311. if (terrain && renderObjects)
  1312. {
  1313. for (long terrainBlock = 0; terrainBlock < Terrain::numObjBlocks; terrainBlock++)
  1314. {
  1315. if (Terrain::objBlockInfo[terrainBlock].active)
  1316. {
  1317. long numObjs = Terrain::objBlockInfo[terrainBlock].numObjects;
  1318. long objIndex = Terrain::objBlockInfo[terrainBlock].firstHandle;
  1319. for (long terrainObj = 0; terrainObj < numObjs; terrainObj++, objIndex++)
  1320. {
  1321. if (objList[objIndex] &&
  1322. Terrain::objVertexActive[objList[objIndex]->getVertexNum()])
  1323. {
  1324. objList[objIndex]->renderShadows();
  1325. if (MaxObjectsDrawn) {
  1326. //-----------------------------------------
  1327. // No more element groups, so stop drawing.
  1328. return;
  1329. }
  1330. }
  1331. }
  1332. }
  1333. }
  1334. }
  1335. if (movers) {
  1336. if (mechs) {
  1337. for (long i = 0; i < numMechs; i++)
  1338. if (mechs[i] && mechs[i]->getExists())
  1339. mechs[i]->renderShadows();
  1340. }
  1341. if (vehicles) {
  1342. for (long i = 0; i < numVehicles; i++)
  1343. if (vehicles[i] && vehicles[i]->getExists())
  1344. vehicles[i]->renderShadows();
  1345. }
  1346. #ifdef USE_ELEMENTALS
  1347. if (elementals) {
  1348. for (long i = 0; i < numElementals; i++)
  1349. if (elementals[i] && elementals[i]->getExists())
  1350. elementals[i]->renderShadows();
  1351. }
  1352. #endif
  1353. }
  1354. if (other) {
  1355. if (carnage) {
  1356. for (long i = 0; i < numCarnage; i++) {
  1357. if (carnage[i] && carnage[i]->getExists())
  1358. carnage[i]->renderShadows();
  1359. }
  1360. }
  1361. }
  1362. gos_SetRenderState( gos_State_Fog, 0);
  1363. }
  1364. //---------------------------------------------------------------------------
  1365. #ifdef LAB_ONLY
  1366. __int64 MCTimeTerrainObjectsUpdate = 0;
  1367. __int64 MCTimeMechsUpdate = 0;
  1368. __int64 MCTimeVehiclesUpdate = 0;
  1369. __int64 MCTimeTurretsUpdate = 0;
  1370. __int64 MCTimeTerrainObjectsTL = 0;
  1371. __int64 MCTimeMechsTL = 0;
  1372. __int64 MCTimeVehiclesTL = 0;
  1373. __int64 MCTimeTurretsTL = 0;
  1374. __int64 MCTimeAllElseUpdate = 0;
  1375. __int64 MCTimeCaptureListUpdate = 0;
  1376. extern __int64 MCTimeTransformandLight;
  1377. extern __int64 MCTimeAnimationandMatrix;
  1378. extern __int64 MCTimePerShapeTransform;
  1379. unsigned long bldgCount = 0;
  1380. #endif
  1381. void GameObjectManager::update (bool terrain, bool movers, bool other)
  1382. {
  1383. //----------------------------
  1384. // Now, update game objects...
  1385. #ifdef LAB_ONLY
  1386. __int64 x;
  1387. x=GetCycles();
  1388. #endif
  1389. updateCaptureList();
  1390. #ifdef LAB_ONLY
  1391. x=GetCycles()-x;
  1392. MCTimeCaptureListUpdate = x;
  1393. x=GetCycles();
  1394. #endif
  1395. if (terrain && renderObjects)
  1396. {
  1397. #ifdef LAB_ONLY
  1398. bldgCount = 0;
  1399. #endif
  1400. //First Update all of the Special Buildings.
  1401. // They will mark themselves updated and not re-update below.
  1402. for (long spBuilding = 0; spBuilding < numSpecialBuildings;spBuilding++)
  1403. {
  1404. if (specialBuildings[spBuilding] && specialBuildings[spBuilding]->getExists())
  1405. {
  1406. #ifdef LAB_ONLY
  1407. bldgCount++;
  1408. MCTimeAnimationandMatrix =
  1409. MCTimePerShapeTransform =
  1410. MCTimeTransformandLight = 0;
  1411. #endif
  1412. if (!specialBuildings[spBuilding]->update())
  1413. {
  1414. //-----------------------------------------
  1415. // Update failed, so it no longer exists...
  1416. specialBuildings[spBuilding]->setExists(false);
  1417. }
  1418. #ifdef LAB_ONLY
  1419. MCTimeTerrainObjectsTL += MCTimeTransformandLight;
  1420. #endif
  1421. }
  1422. }
  1423. //Then update all of the gates.
  1424. // They too will mark themselves and not re-update.
  1425. // MUST update every frame or they don't open!!
  1426. for (long nGates = 0;nGates < numGates;nGates++)
  1427. {
  1428. if (gates[nGates] && gates[nGates]->getExists())
  1429. {
  1430. #ifdef LAB_ONLY
  1431. bldgCount++;
  1432. MCTimeAnimationandMatrix =
  1433. MCTimePerShapeTransform =
  1434. MCTimeTransformandLight = 0;
  1435. #endif
  1436. if (!gates[nGates]->update())
  1437. {
  1438. //-----------------------------------------
  1439. // Update failed, so it no longer exists...
  1440. gates[nGates]->setExists(false);
  1441. }
  1442. #ifdef LAB_ONLY
  1443. MCTimeTerrainObjectsTL += MCTimeTransformandLight;
  1444. #endif
  1445. }
  1446. }
  1447. for (long terrainBlock = 0; terrainBlock < Terrain::numObjBlocks; terrainBlock++)
  1448. {
  1449. if (Terrain::objBlockInfo[terrainBlock].active || (turn < 3))
  1450. {
  1451. long numObjs = Terrain::objBlockInfo[terrainBlock].numObjects;
  1452. long objIndex = Terrain::objBlockInfo[terrainBlock].firstHandle;
  1453. for (long terrainObj = 0; terrainObj < numObjs; terrainObj++,objIndex++)
  1454. {
  1455. if (objList[objIndex] &&
  1456. (Terrain::objVertexActive[objList[objIndex]->getVertexNum()] || (turn < 3)) &&
  1457. objList[objIndex]->getExists())
  1458. {
  1459. #ifdef LAB_ONLY
  1460. bldgCount++;
  1461. MCTimeAnimationandMatrix =
  1462. MCTimePerShapeTransform =
  1463. MCTimeTransformandLight = 0;
  1464. #endif
  1465. if (!objList[objIndex]->update())
  1466. {
  1467. //-----------------------------------------
  1468. // Update failed, so it no longer exists...
  1469. objList[objIndex]->setExists(false);
  1470. }
  1471. #ifdef LAB_ONLY
  1472. MCTimeTerrainObjectsTL += MCTimeTransformandLight;
  1473. #endif
  1474. }
  1475. }
  1476. }
  1477. }
  1478. }
  1479. #ifdef LAB_ONLY
  1480. x=GetCycles()-x;
  1481. MCTimeTerrainObjectsUpdate = x;
  1482. #endif
  1483. if (movers) {
  1484. static MoverPtr removeList[MAX_MOVERS];
  1485. long numRemoved = 0;
  1486. #ifdef LAB_ONLY
  1487. x=GetCycles();
  1488. #endif
  1489. if (mechs)
  1490. {
  1491. for (long i = 0; i < numMechs; i++)
  1492. {
  1493. MoverPtr mover = mechs[i];
  1494. if (mover && mover->getExists())
  1495. {
  1496. #ifdef LAB_ONLY
  1497. MCTimeAnimationandMatrix =
  1498. MCTimePerShapeTransform =
  1499. MCTimeTransformandLight = 0;
  1500. #endif
  1501. if (!mover->update())
  1502. mover->setExists(false);
  1503. #ifdef LAB_ONLY
  1504. MCTimeMechsTL += MCTimeTransformandLight;
  1505. #endif
  1506. if (mover->getFlag(OBJECT_FLAG_REMOVED))
  1507. removeList[numRemoved++] = mover;
  1508. }
  1509. }
  1510. }
  1511. #ifdef LAB_ONLY
  1512. x=GetCycles()-x;
  1513. MCTimeMechsUpdate = x;
  1514. x=GetCycles();
  1515. #endif
  1516. if (vehicles)
  1517. {
  1518. for (long i = 0; i < maxVehicles; i++)
  1519. {
  1520. MoverPtr mover = vehicles[i];
  1521. if (mover && mover->getExists())
  1522. {
  1523. #ifdef LAB_ONLY
  1524. MCTimeAnimationandMatrix =
  1525. MCTimePerShapeTransform =
  1526. MCTimeTransformandLight = 0;
  1527. #endif
  1528. if (!mover->update())
  1529. mover->setExists(false);
  1530. #ifdef LAB_ONLY
  1531. MCTimeVehiclesTL += MCTimeTransformandLight;
  1532. #endif
  1533. if (mover->getFlag(OBJECT_FLAG_REMOVED))
  1534. removeList[numRemoved++] = mover;
  1535. }
  1536. }
  1537. }
  1538. #ifdef LAB_ONLY
  1539. x=GetCycles()-x;
  1540. MCTimeVehiclesUpdate = x;
  1541. #endif
  1542. for (long i = 0; i < numRemoved; i++)
  1543. mission->removeMover(removeList[i]);
  1544. }
  1545. if (other) {
  1546. //---------------------------------------
  1547. // All other objects should be updated...
  1548. #ifdef LAB_ONLY
  1549. __int64 x;
  1550. x=GetCycles();
  1551. #endif
  1552. if (turrets)
  1553. {
  1554. for (long i=0;i<numTurrets;i++)
  1555. {
  1556. if (turrets[i] && turrets[i]->getExists())
  1557. {
  1558. #ifdef LAB_ONLY
  1559. MCTimeAnimationandMatrix =
  1560. MCTimePerShapeTransform =
  1561. MCTimeTransformandLight = 0;
  1562. #endif
  1563. if (!turrets[i]->update())
  1564. turrets[i]->setExists(false);
  1565. #ifdef LAB_ONLY
  1566. MCTimeTurretsTL += MCTimeTransformandLight;
  1567. #endif
  1568. }
  1569. }
  1570. }
  1571. #ifdef LAB_ONLY
  1572. x=GetCycles()-x;
  1573. MCTimeTurretsUpdate = x;
  1574. x=GetCycles();
  1575. #endif
  1576. if (weapons) {
  1577. for (long i=0;i<numWeapons;i++) {
  1578. if (weapons[i] && weapons[i]->getExists()) {
  1579. if (!weapons[i]->update())
  1580. weapons[i]->setExists(false);
  1581. }
  1582. }
  1583. }
  1584. if (carnage) {
  1585. for (long i = 0; i < numCarnage; i++) {
  1586. if (carnage[i] && carnage[i]->getExists()) {
  1587. if (!carnage[i]->update())
  1588. carnage[i]->setExists(false);
  1589. }
  1590. }
  1591. }
  1592. if (lights) {
  1593. for (long i = 0; i < numLights; i++) {
  1594. if (lights[i] && lights[i]->getExists()) {
  1595. if (!lights[i]->update())
  1596. lights[i]->setExists(false);
  1597. }
  1598. }
  1599. }
  1600. if (artillery) {
  1601. for (long i = 0; i < numArtillery; i++) {
  1602. if (artillery[i] && artillery[i]->getExists()) {
  1603. if (!artillery[i]->update())
  1604. artillery[i]->setExists(false);
  1605. }
  1606. }
  1607. }
  1608. #ifdef LAB_ONLY
  1609. x=GetCycles()-x;
  1610. MCTimeAllElseUpdate = x;
  1611. #endif
  1612. }
  1613. }
  1614. //---------------------------------------------------------------------------
  1615. GameObjectPtr GameObjectManager::get (GameObjectHandle handle) {
  1616. if ((handle < 1) || (handle > getMaxObjects()))
  1617. return(NULL);
  1618. return(objList[handle]);
  1619. }
  1620. //---------------------------------------------------------------------------
  1621. long GameObjectManager::buildMoverLists (void) {
  1622. numMovers = 0;
  1623. numGoodMovers = 0;
  1624. numBadMovers = 0;
  1625. for (long i = 0; i < numMechs; i++) {
  1626. MoverPtr mover = dynamic_cast<MoverPtr>(mechs[i]);
  1627. if (!mover->getTeam())
  1628. continue;
  1629. moverList[numMovers++] = mover;
  1630. if (mover->getTeam()->isFriendly(Team::home))
  1631. goodMoverList[numGoodMovers++] = mover;
  1632. else if (mover->getTeam()->isEnemy(Team::home))
  1633. badMoverList[numBadMovers++] = mover;
  1634. }
  1635. for (i = 0; i < numVehicles; i++) {
  1636. MoverPtr mover = dynamic_cast<MoverPtr>(vehicles[i]);
  1637. if (!mover->getTeam())
  1638. continue;
  1639. moverList[numMovers++] = mover;
  1640. if (mover->getTeam()->isFriendly(Team::home))
  1641. goodMoverList[numGoodMovers++] = mover;
  1642. else if (mover->getTeam()->isEnemy(Team::home))
  1643. badMoverList[numBadMovers++] = mover;
  1644. }
  1645. return(NO_ERR);
  1646. }
  1647. //---------------------------------------------------------------------------
  1648. bool GameObjectManager::modifyMoverLists (MoverPtr mover, long action) {
  1649. switch (action) {
  1650. case MOVERLIST_DELETE: {
  1651. bool foundIt = false;
  1652. if (mover->getObjectClass() == BATTLEMECH) {
  1653. long i = 0;
  1654. for (i = 0; i < numMechs; i++) {
  1655. if (mechs[i] == mover)
  1656. break;
  1657. }
  1658. if (i < numMechs) {
  1659. foundIt = true;
  1660. BattleMechPtr mech = mechs[i];
  1661. memmove(&mechs[i], &mechs[i + 1], (maxMechs - i - 1) * sizeof(BattleMechPtr));
  1662. mechs[maxMechs - 1] = mech;
  1663. numMechs--;
  1664. }
  1665. }
  1666. else if (mover->getObjectClass() == GROUNDVEHICLE) {
  1667. long i = 0;
  1668. for (i = 0; i < numVehicles; i++) {
  1669. if (vehicles[i] == mover)
  1670. break;
  1671. }
  1672. if (i < numVehicles) {
  1673. foundIt = true;
  1674. GroundVehiclePtr vehicle = vehicles[i];
  1675. memmove(&vehicles[i], &vehicles[i + 1], (maxVehicles - i - 1) * sizeof(GroundVehiclePtr));
  1676. vehicles[maxVehicles - 1] = vehicle;
  1677. numVehicles--;
  1678. }
  1679. }
  1680. for (long i = 0; i < numMovers; i++)
  1681. if (moverList[i] == mover) {
  1682. moverList[i] = moverList[--numMovers];
  1683. break;
  1684. }
  1685. if (foundIt && mover->getTeam()) {
  1686. if (mover->getTeam()->isFriendly(Team::home)) {
  1687. long i = 0;
  1688. for (i = 0; i < numGoodMovers; i++)
  1689. if (mover == goodMoverList[i])
  1690. break;
  1691. if (i < numGoodMovers)
  1692. goodMoverList[i] = goodMoverList[--numGoodMovers];
  1693. }
  1694. else if (mover->getTeam()->isEnemy(Team::home)) {
  1695. long i = 0;
  1696. for (i = 0; i < numBadMovers; i++)
  1697. if (mover == badMoverList[i])
  1698. break;
  1699. if (i < numBadMovers)
  1700. badMoverList[i] = badMoverList[--numBadMovers];
  1701. }
  1702. }
  1703. return(foundIt);
  1704. }
  1705. case MOVERLIST_ADD:
  1706. moverList[numMovers++] = mover;
  1707. if (mover->getTeam()) {
  1708. if (mover->getTeam()->isFriendly(Team::home))
  1709. goodMoverList[numGoodMovers++] = mover;
  1710. else if (mover->getTeam()->isEnemy(Team::home))
  1711. badMoverList[numBadMovers++] = mover;
  1712. }
  1713. break;
  1714. case MOVERLIST_TRADE:
  1715. //-----------------------------------------------
  1716. // First, remove it from whatever list it's on...
  1717. long i = 0;
  1718. for (i = 0; i < numGoodMovers; i++)
  1719. if (mover == goodMoverList[i])
  1720. break;
  1721. if (i < numGoodMovers)
  1722. goodMoverList[i] = goodMoverList[--numGoodMovers];
  1723. else {
  1724. long i = 0;
  1725. for (i = 0; i < numBadMovers; i++)
  1726. if (mover == badMoverList[i])
  1727. break;
  1728. if (i < numBadMovers)
  1729. badMoverList[i] = badMoverList[--numBadMovers];
  1730. }
  1731. //----------------------------------
  1732. // Now, add it to the proper list...
  1733. if (mover->getTeam()) {
  1734. if (mover->getTeam()->isFriendly(Team::home))
  1735. goodMoverList[numGoodMovers++] = mover;
  1736. else if (mover->getTeam()->isEnemy(Team::home))
  1737. badMoverList[numBadMovers++] = mover;
  1738. }
  1739. }
  1740. return(true);
  1741. }
  1742. //---------------------------------------------------------------------------
  1743. GameObjectPtr GameObjectManager::findObject (Stuff::Vector3D position) {
  1744. float closestDistance = 10000.0;
  1745. GameObjectPtr closestObj = NULL;
  1746. long numObjects = getMaxObjects();
  1747. for (long objIndex = 1; objIndex <= numObjects; objIndex++) {
  1748. GameObjectPtr obj = objList[objIndex];
  1749. Assert(obj != NULL, objIndex, " GameObjectManager.findObject: NULL obj ");
  1750. if (obj->getExists() && !obj->inTransport()) {
  1751. float distanceFromObject = obj->distanceFrom(position);
  1752. if (distanceFromObject < closestDistance)
  1753. if (distanceFromObject < obj->getExtentRadius()) {
  1754. closestObj = obj;
  1755. closestDistance = distanceFromObject;
  1756. }
  1757. }
  1758. }
  1759. return(closestObj);
  1760. }
  1761. //---------------------------------------------------------------------------
  1762. GameObjectPtr GameObjectManager::findObjectByTypeHandle (long typeHandle) {
  1763. //-------------------------------------------------
  1764. // This function was called findObjectId() in MC...
  1765. long numObjects = getMaxObjects();
  1766. for (long objIndex = 1; objIndex <= numObjects; objIndex++) {
  1767. GameObjectPtr obj = objList[objIndex];
  1768. if (obj->getExists() && (obj->getTypeHandle() == typeHandle))
  1769. return(obj);
  1770. }
  1771. return(NULL);
  1772. }
  1773. //---------------------------------------------------------------------------
  1774. GameObjectPtr GameObjectManager::findByPartId (long partId) {
  1775. if (partId == 0)
  1776. return(NULL);
  1777. long numObjects = getMaxObjects();
  1778. for (long objIndex = 1; objIndex <= numObjects; objIndex++)
  1779. {
  1780. GameObjectPtr obj = objList[objIndex];
  1781. if (obj && obj->getExists() && (obj->getPartId() == partId))
  1782. return(obj);
  1783. }
  1784. return(NULL);
  1785. }
  1786. //---------------------------------------------------------------------------
  1787. GameObjectPtr GameObjectManager::findByBlockVertex (long blockNum, long vertex) {
  1788. //----------------------------------------
  1789. // SLOW compared to using object handle...
  1790. long partId = calcPartId(TERRAINOBJECT, blockNum, vertex);
  1791. return(findByPartId(partId));
  1792. }
  1793. //---------------------------------------------------------------------------
  1794. GameObjectPtr GameObjectManager::findByCellPosition (long row, long col)
  1795. {
  1796. //-------------------------------------------------------------------------------------
  1797. // Must implement for Linkage code. 10/20/99 -fs
  1798. // PLEASE DO NOT CALL EVERY FRAME. THIS ONE WILL BE SLOWER THEN CHRISTMAS!!!!!!!!!!!!
  1799. // Store the pointer if at all possible. YOU HAVE BEEN WARNED!
  1800. long numObjects = getMaxObjects();
  1801. for (long objIndex = 1; objIndex <= numObjects; objIndex++)
  1802. {
  1803. GameObjectPtr obj = objList[objIndex];
  1804. if (obj->getExists())
  1805. {
  1806. long cellR, cellC;
  1807. objList[objIndex]->getCellPosition(cellR,cellC);
  1808. if ((cellR == row) && (cellC == col))
  1809. return objList[objIndex];
  1810. }
  1811. }
  1812. return(NULL);
  1813. }
  1814. //---------------------------------------------------------------------------
  1815. GameObjectPtr GameObjectManager::findByUnitInfo (long commander, long group, long mate) {
  1816. //----------------------------------------
  1817. // SLOW compared to using object handle...
  1818. long partId = calcPartId(MOVER, commander, group, mate);
  1819. return(findByPartId(partId));
  1820. }
  1821. //---------------------------------------------------------------------------
  1822. GameObjectPtr GameObjectManager::findObjectByMouse (long mouseX,
  1823. long mouseY,
  1824. GameObjectPtr* searchList,
  1825. long listSize,
  1826. bool skipDisabled) {
  1827. if (!searchList)
  1828. Fatal(0, " GameObjectManager.findObjectByMouse: NULL searchList ");
  1829. for (long objIndex = 0; objIndex < listSize; objIndex++)
  1830. {
  1831. if (searchList[objIndex] && searchList[objIndex]->getExists())
  1832. {
  1833. GameObjectPtr obj = searchList[objIndex];
  1834. Assert(obj != NULL, objIndex, " GameObjectManager.findObjectByMouse: NULL obj ");
  1835. AppearancePtr objAppearance = obj->getAppearance();
  1836. if (objAppearance && objAppearance->canBeSeen())
  1837. {
  1838. if (obj->getWindowsVisible() == (turn - VISIBLE_THRESHOLD))
  1839. {
  1840. //-----------------------------------------------------
  1841. float tlx = objAppearance->upperLeft.x;
  1842. float tly = objAppearance->upperLeft.y;
  1843. float brx = objAppearance->lowerRight.x;
  1844. float bry = objAppearance->lowerRight.y;
  1845. if ((mouseX >= tlx) &&
  1846. (mouseX <= brx) &&
  1847. (mouseY >= tly) &&
  1848. (mouseY <= bry))
  1849. {
  1850. //---------------------------
  1851. // We're on it, so save it...
  1852. if (!obj->isMover() || (obj->isMover() && obj->isOnGUI() && Terrain::IsGameSelectTerrainPosition(obj->getPosition())))
  1853. {
  1854. if (skipDisabled)
  1855. {
  1856. if (!obj->isDisabled() &&
  1857. (obj->getObjectClass() != TREE) &&
  1858. (obj->getDamageLevel() != 36000000) && //We are a rock clump
  1859. objAppearance->PerPolySelect(mouseX, mouseY))
  1860. return(obj);
  1861. }
  1862. else
  1863. {
  1864. //Do not target trees or artillery strikes!!
  1865. if ((obj->getObjectClass() != TREE) &&
  1866. (obj->getObjectClass() != ARTILLERY) && (obj->getDamageLevel() != 36000000) && //We are a rock clump
  1867. (obj->getDamageLevel() != 36000000) && //We are a rock clump
  1868. objAppearance->PerPolySelect(mouseX, mouseY))
  1869. return(obj);
  1870. }
  1871. }
  1872. }
  1873. }
  1874. }
  1875. }
  1876. }
  1877. return(NULL);
  1878. }
  1879. //---------------------------------------------------------------------------
  1880. GameObjectPtr GameObjectManager::findMoverByMouse (long mouseX,
  1881. long mouseY,
  1882. long commanderId,
  1883. bool skipDisabled) {
  1884. GameObjectPtr* searchList = NULL;
  1885. long numMovers = getMaxMovers();
  1886. if (objList)
  1887. searchList = &objList[1];
  1888. if (!searchList)
  1889. return(NULL);
  1890. if (commanderId == -1)
  1891. for (long objIndex = 0; objIndex < numMovers; objIndex++)
  1892. {
  1893. if (searchList[objIndex] && searchList[objIndex]->getExists())
  1894. {
  1895. GameObjectPtr obj = searchList[objIndex];
  1896. Assert(obj != NULL, objIndex, " GameObjectManager.findObjectByMouse: NULL obj ");
  1897. AppearancePtr objAppearance = obj->getAppearance();
  1898. if (objAppearance && objAppearance->canBeSeen())
  1899. {
  1900. if (obj->getWindowsVisible() == (turn - VISIBLE_THRESHOLD))
  1901. {
  1902. //-----------------------------------------------------
  1903. float tlx = objAppearance->upperLeft.x;
  1904. float tly = objAppearance->upperLeft.y;
  1905. float brx = objAppearance->lowerRight.x;
  1906. float bry = objAppearance->lowerRight.y;
  1907. if ((mouseX >= tlx) &&
  1908. (mouseX <= brx) &&
  1909. (mouseY >= tly) &&
  1910. (mouseY <= bry))
  1911. {
  1912. //---------------------------
  1913. // We're on it, so save it...
  1914. // Movers are NOT per poly!!
  1915. if (!obj->isMover() || (obj->isMover() && obj->isOnGUI() && Terrain::IsGameSelectTerrainPosition(obj->getPosition())))
  1916. {
  1917. if (skipDisabled)
  1918. {
  1919. if (!obj->isDisabled())
  1920. return(obj);
  1921. }
  1922. else
  1923. return(obj);
  1924. }
  1925. }
  1926. }
  1927. }
  1928. }
  1929. }
  1930. else
  1931. for (long objIndex = 0; objIndex < numMovers; objIndex++)
  1932. {
  1933. if (searchList[objIndex] && searchList[objIndex]->getExists())
  1934. {
  1935. GameObjectPtr obj = searchList[objIndex];
  1936. Assert(obj != NULL, objIndex, " GameObjectManager.findObjectByMouse: NULL obj ");
  1937. if (obj->getCommanderId() == commanderId)
  1938. continue;
  1939. AppearancePtr objAppearance = obj->getAppearance();
  1940. if (objAppearance && objAppearance->canBeSeen())
  1941. {
  1942. if (obj->getWindowsVisible() == (turn - VISIBLE_THRESHOLD))
  1943. {
  1944. //-----------------------------------------------------
  1945. float tlx = objAppearance->upperLeft.x;
  1946. float tly = objAppearance->upperLeft.y;
  1947. float brx = objAppearance->lowerRight.x;
  1948. float bry = objAppearance->lowerRight.y;
  1949. if ((mouseX >= tlx) &&
  1950. (mouseX <= brx) &&
  1951. (mouseY >= tly) &&
  1952. (mouseY <= bry))
  1953. {
  1954. if (!obj->isMover() || (obj->isMover() && obj->isOnGUI() && Terrain::IsGameSelectTerrainPosition(obj->getPosition())))
  1955. {
  1956. //---------------------------
  1957. // We're on it, so save it...
  1958. if (skipDisabled)
  1959. {
  1960. if (!obj->isDisabled())
  1961. return(obj);
  1962. }
  1963. else
  1964. return(obj);
  1965. }
  1966. }
  1967. }
  1968. }
  1969. }
  1970. }
  1971. return(NULL);
  1972. }
  1973. //---------------------------------------------------------------------------
  1974. GameObjectPtr GameObjectManager::findTerrainObjectByMouse (long mouseX,
  1975. long mouseY,
  1976. bool skipDisabled)
  1977. {
  1978. for (long terrainBlock = 0; terrainBlock < Terrain::numObjBlocks; terrainBlock++)
  1979. {
  1980. if (Terrain::objBlockInfo[terrainBlock].active)
  1981. {
  1982. long numObjs = Terrain::objBlockInfo[terrainBlock].numObjects;
  1983. long objIndex = Terrain::objBlockInfo[terrainBlock].firstHandle;
  1984. GameObjectPtr obj = findObjectByMouse(mouseX, mouseY, &objList[objIndex], numObjs, skipDisabled);
  1985. if (obj)
  1986. return(obj);
  1987. }
  1988. }
  1989. return(NULL);
  1990. }
  1991. //---------------------------------------------------------------------------
  1992. GameObjectPtr GameObjectManager::findObjectByMouse (long mouseX, long mouseY) {
  1993. GameObjectPtr obj = NULL;
  1994. //-------------------------------------------------------------
  1995. // This function will search movers first. If we find an object
  1996. // near the mouse, we're done...
  1997. // Mitch wants to find live ones before dead ones
  1998. long homeCommanderId = Commander::home->getId();
  1999. obj = findMoverByMouse(mouseX, mouseY, homeCommanderId, true);
  2000. if (obj)
  2001. return(obj);
  2002. obj = findMoverByMouse(mouseX, mouseY, homeCommanderId, false);
  2003. if (obj)
  2004. return(obj);
  2005. obj = findMoverByMouse(mouseX, mouseY, -1, true);
  2006. if (obj)
  2007. return(obj);
  2008. obj = findMoverByMouse(mouseX, mouseY, -1, false);
  2009. if (obj)
  2010. return(obj);
  2011. //-------------------------------------------------------------------------
  2012. // If we still haven't found anything, check everything (including terrain)
  2013. // with disregard to disabled status...
  2014. // Skip disabled should be on. I have Spoken! -fs
  2015. // Frank -- I need to find the nav markers so I can get their little highlight text.... HKG
  2016. obj = findObjectByMouse(mouseX, mouseY, &objList[1], getMaxObjects(),false);
  2017. if (obj)
  2018. return(obj);
  2019. return(findTerrainObjectByMouse(mouseX, mouseY,true));
  2020. }
  2021. //---------------------------------------------------------------------------
  2022. bool GameObjectManager::moverInRect(long index, Stuff::Vector3D &dStart, Stuff::Vector3D &dEnd)
  2023. {
  2024. //------------------------------------------------------------------------------
  2025. // This function checks the mover passed in to see if it
  2026. // is within the magic rectangle. It assumes we are looking for our alignment.
  2027. // This is because we are drag selecting in the GUI!
  2028. if ((index < 0) || (index >= getMaxMovers()))
  2029. return(false);
  2030. MoverPtr checkMover = getMover(index);
  2031. if (checkMover && checkMover->getExists() && (checkMover->getTeam() == Team::home))
  2032. {
  2033. AppearancePtr objAppearance = checkMover->getAppearance();
  2034. if (objAppearance /*&& objAppearance->canBeSeen() */)
  2035. {
  2036. // if (checkMover->getWindowsVisible() > (turn - VISIBLE_THRESHOLD))
  2037. {
  2038. //-----------------------------------------------------
  2039. // Note that this effectively tests inTransport, since
  2040. // windowsVisible only gets set when not inTransport...
  2041. //objAppearance->recalcBounds(); //Shouldn't need to do this. They should already be correct!
  2042. long left = fmin(dStart.x, dEnd.x);
  2043. long right = fmax(dStart.x, dEnd.x);
  2044. long top = fmin(dStart.y, dEnd.y);
  2045. long bottom = fmax(dStart.y, dEnd.y);
  2046. if ((left <= objAppearance->getScreenPos().x) &&
  2047. (right >= objAppearance->getScreenPos().x) &&
  2048. (top <= objAppearance->getScreenPos().y) &&
  2049. (bottom >= objAppearance->getScreenPos().y))
  2050. {
  2051. return(true);
  2052. }
  2053. }
  2054. }
  2055. }
  2056. return(false);
  2057. }
  2058. //---------------------------------------------------------------------------
  2059. ObjectTypePtr GameObjectManager::loadObjectType (ObjectTypeNumber typeHandle) {
  2060. return(objTypeManager->load(typeHandle));
  2061. }
  2062. //---------------------------------------------------------------------------
  2063. ObjectTypePtr GameObjectManager::getObjectType (ObjectTypeNumber typeHandle) {
  2064. return(objTypeManager->get(typeHandle));
  2065. }
  2066. //---------------------------------------------------------------------------
  2067. void GameObjectManager::removeObjectType (ObjectTypeNumber typeHandle) {
  2068. objTypeManager->remove(typeHandle);
  2069. }
  2070. //---------------------------------------------------------------------------
  2071. GameObjectHandle GameObjectManager::getHandle (GameObjectPtr obj) {
  2072. for (long i = 1; i <= getMaxObjects(); i++)
  2073. if (objList[i] == obj)
  2074. return(i);
  2075. return(0);
  2076. }
  2077. //---------------------------------------------------------------------------
  2078. long GameObjectManager::calcPartId (long objectClass, long param1, long param2, long param3) {
  2079. //-------------------------------------------------------------------
  2080. // This should be the only function used to calc partIds for objects.
  2081. // This will allow easy modification of the formulas without making
  2082. // changes everywhere...
  2083. long partId = 0;
  2084. switch (objectClass) {
  2085. case MOVER:
  2086. case BATTLEMECH:
  2087. case GROUNDVEHICLE:
  2088. case ELEMENTAL:
  2089. if (param1 == -1) {
  2090. if (nextReinforcementPartId == (MAX_REINFORCEMENT_PART_ID + 1))
  2091. return(0);
  2092. partId = nextReinforcementPartId++;
  2093. }
  2094. else
  2095. partId = MIN_MOVER_PART_ID +
  2096. param1 * MAX_MOVERGROUPS * MAX_MOVERGROUP_COUNT_START +
  2097. param2 * MAX_MOVERGROUP_COUNT_START +
  2098. param3;
  2099. break;
  2100. case TERRAINOBJECT:
  2101. case TREE:
  2102. case BUILDING:
  2103. case TREEBUILDING:
  2104. case TURRET:
  2105. case GATE:
  2106. partId = MIN_TERRAIN_PART_ID + param1 * MAX_MAP_CELL_WIDTH + param2;
  2107. break;
  2108. case TRAINCAR:
  2109. Fatal(0, " TRAINS NEED PART IDS ");
  2110. break;
  2111. }
  2112. return(partId);
  2113. }
  2114. //---------------------------------------------------------------------------
  2115. void GameObjectManager::setPartId (GameObjectPtr obj, long param1, long param2, long param3) {
  2116. //------------------------------------------------------------------------
  2117. // ALL game objects should have their partIds set through this function.
  2118. // This simply allows easier modification and monitoring of the partIds,
  2119. // should we have any reason to modify or test 'em as missions are loaded.
  2120. long partId = calcPartId(obj->getObjectClass(), param1, param2, param3);
  2121. obj->setPartId(partId);
  2122. }
  2123. //---------------------------------------------------------------------------
  2124. long GameObjectManager::initCollisionSystem (FitIniFile* missionFile) {
  2125. collisionSystem = new CollisionSystem;
  2126. gosASSERT(collisionSystem != NULL);
  2127. collisionSystem->init(missionFile);
  2128. return(0);
  2129. }
  2130. //---------------------------------------------------------------------------
  2131. long GameObjectManager::buildCollidableList (void)
  2132. {
  2133. rebuildCollidableList = false;
  2134. if (collidableList)
  2135. {
  2136. ObjectTypeManager::objectCache->Free(collidableList);
  2137. collidableList = NULL;
  2138. }
  2139. // First, how many collidables are there?
  2140. numCollidables = numMechs + numVehicles + numElementals + numTurrets + numGates + numCarnage + numArtillery;
  2141. collidableList = (GameObjectPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GameObjectPtr) * numCollidables);
  2142. long curIndex = 0;
  2143. for (long i = 0; i < numMechs; i++)
  2144. collidableList[curIndex++] = mechs[i];
  2145. for (i = 0; i < numVehicles; i++)
  2146. collidableList[curIndex++] = vehicles[i];
  2147. for (i = 0; i < numElementals; i++)
  2148. collidableList[curIndex++] = (GameObjectPtr)elementals[i];
  2149. for (i=0;i<numTurrets;i++)
  2150. collidableList[curIndex++] = turrets[i];
  2151. for (i=0;i<numGates;i++)
  2152. collidableList[curIndex++] = gates[i];
  2153. for (i=0;i<numCarnage;i++)
  2154. collidableList[curIndex++] = carnage[i];
  2155. for (i=0;i<numArtillery;i++)
  2156. collidableList[curIndex++] = artillery[i];
  2157. Assert(curIndex == numCollidables, curIndex, " GameObjectManager.buildCollidableList: oof ");
  2158. return(0);
  2159. }
  2160. //---------------------------------------------------------------------------
  2161. long GameObjectManager::getCollidableList (GameObjectPtr*& objList)
  2162. {
  2163. if (rebuildCollidableList)
  2164. buildCollidableList();
  2165. objList = collidableList;
  2166. return(numCollidables);
  2167. }
  2168. //---------------------------------------------------------------------------
  2169. long GameObjectManager::updateCollisions (void) {
  2170. if (!collidableList)
  2171. buildCollidableList();
  2172. collisionSystem->checkObjects();
  2173. return(0);
  2174. }
  2175. //---------------------------------------------------------------------------
  2176. void GameObjectManager::detectStaticCollision (GameObjectPtr obj1, GameObjectPtr obj2) {
  2177. collisionSystem->detectStaticCollision(obj1, obj2);
  2178. }
  2179. //---------------------------------------------------------------------------
  2180. void GameObjectManager::updateCaptureList (void) {
  2181. for (long i = 0; i < MAX_TEAMS; i++)
  2182. numCaptures[i] = 0;
  2183. for (i = 0; i < getNumMovers(); i++) {
  2184. MoverPtr mover = getMover(i);
  2185. if (mover->isDisabled())
  2186. continue;
  2187. MechWarriorPtr pilot = mover->getPilot();
  2188. if (pilot) {
  2189. TacticalOrderPtr tacOrder;
  2190. tacOrder = pilot->getCurTacOrder();
  2191. if (tacOrder->code == TACTICAL_ORDER_CAPTURE) {
  2192. captureList[mover->getTeamId()][numCaptures[mover->getTeamId()]++] = tacOrder->targetWID;
  2193. }
  2194. }
  2195. }
  2196. }
  2197. //---------------------------------------------------------------------------
  2198. bool GameObjectManager::isTeamCapturing (TeamPtr team, GameObjectWatchID targetWID) {
  2199. if (team) {
  2200. long teamID = team->getId();
  2201. for (long i = 0; i < numCaptures[teamID]; i++)
  2202. if (targetWID == captureList[teamID][i])
  2203. return(true);
  2204. }
  2205. else {
  2206. for (long teamID = 0; teamID < MAX_TEAMS; teamID++)
  2207. for (long i = 0; i < numCaptures[teamID]; i++)
  2208. if (targetWID == captureList[teamID][i])
  2209. return(true);
  2210. }
  2211. return(false);
  2212. }
  2213. //---------------------------------------------------------------------------
  2214. CarnagePtr GameObjectManager::createFire (ObjectTypeNumber fireObjTypeHandle,
  2215. GameObjectPtr owner,
  2216. Stuff::Vector3D& position,
  2217. float tonnage) {
  2218. CarnagePtr fire = getCarnage(CARNAGE_FIRE);
  2219. if (fire) {
  2220. ObjectTypePtr objectType = getObjectType(fireObjTypeHandle);
  2221. if (objectType) {
  2222. //------------------------------------------------------------
  2223. // Make sure the object type we loaded is really a fire object
  2224. // type. If not, NULL out of here...
  2225. if (objectType->getObjectClass() != FIRE)
  2226. return(NULL);
  2227. fire->init(false, objectType);
  2228. fire->setOwner(owner);
  2229. fire->setTonnage(tonnage);
  2230. fire->setPosition(position);
  2231. fire->setExists(true);
  2232. }
  2233. }
  2234. return(fire);
  2235. }
  2236. //---------------------------------------------------------------------------
  2237. CarnagePtr GameObjectManager::createExplosion (long effectId,
  2238. GameObjectPtr owner,
  2239. Stuff::Vector3D& position,
  2240. float damage,
  2241. float radius)
  2242. {
  2243. long explosionObjTypeHandle = weaponEffects->GetEffectObjNum(effectId);
  2244. if (explosionObjTypeHandle != INVALID_OBJECT)
  2245. {
  2246. CarnagePtr explosion = getCarnage(CARNAGE_EXPLOSION);
  2247. if (explosion)
  2248. {
  2249. ObjectTypePtr objectType = getObjectType(explosionObjTypeHandle);
  2250. if (objectType && (objectType->getObjectClass() == EXPLOSION))
  2251. {
  2252. //Call in this order or badness.
  2253. explosion->init(effectId);
  2254. explosion->init(false, objectType);
  2255. explosion->setPosition(position);
  2256. explosion->setExtentRadius(radius);
  2257. explosion->setExplDmg(damage);
  2258. explosion->setExists(true);
  2259. explosion->setOwner(owner);
  2260. return(explosion);
  2261. }
  2262. else if (objectType && (objectType->getObjectClass() == FIRE))
  2263. {
  2264. //Call in this order or badness.
  2265. explosion->init(effectId);
  2266. explosion->init(false, objectType);
  2267. explosion->setPosition(position);
  2268. explosion->setExtentRadius(radius);
  2269. explosion->setExplDmg(damage);
  2270. explosion->setExists(true);
  2271. explosion->setOwner(owner);
  2272. return(explosion);
  2273. }
  2274. else
  2275. {
  2276. //Turn on when effects are officially working!
  2277. // Don't really care if nothing happens. Should be a bug not a crash!
  2278. // -fs
  2279. }
  2280. }
  2281. else
  2282. {
  2283. //Should we warn if we are out of explosions or just go on?
  2284. //-fs
  2285. }
  2286. }
  2287. return(NULL);
  2288. }
  2289. //---------------------------------------------------------------------------
  2290. LightPtr GameObjectManager::createLight (ObjectTypeNumber lightObjTypeHandle) {
  2291. LightPtr light = getLight();
  2292. if (light) {
  2293. ObjectTypePtr objectType = getObjectType(lightObjTypeHandle);
  2294. light->init(false, objectType);
  2295. // light->setOwner(owner);
  2296. // light->setTonnage(tonnage);
  2297. Stuff::Vector3D startPosition;
  2298. startPosition.Zero();
  2299. light->setPosition(startPosition);
  2300. light->setExists(true);
  2301. }
  2302. return(light);
  2303. }
  2304. //---------------------------------------------------------------------------
  2305. WeaponBoltPtr GameObjectManager::createWeaponBolt (long effectId)
  2306. {
  2307. WeaponBoltPtr weaponBolt = getWeapon();
  2308. if (weaponBolt)
  2309. {
  2310. ObjectTypeNumber weaponBoltObjTypeHandle = weaponEffects->GetEffectObjNum(effectId);
  2311. ObjectTypePtr objectType = getObjectType(weaponBoltObjTypeHandle);
  2312. if (!objectType)
  2313. STOP(("Object Type for a weapon Bolt was NULL. EffectId: %d ObjType: %d",effectId, weaponBoltObjTypeHandle));
  2314. if (objectType->getObjectClass() != WEAPONBOLT)
  2315. return(NULL);
  2316. //ALWAYS CALL IN THIS ORDER OR NO EFFECT!!!!!!!!!!!!!!!!!!!!
  2317. weaponBolt->init(effectId);
  2318. weaponBolt->init(false, objectType);
  2319. weaponBolt->setExists(true);
  2320. }
  2321. return(weaponBolt);
  2322. }
  2323. //---------------------------------------------------------------------------
  2324. ArtilleryPtr GameObjectManager::createArtillery (long artilleryType, Stuff::Vector3D& position)
  2325. {
  2326. ArtilleryPtr artillery = getArtillery();
  2327. if (artillery)
  2328. {
  2329. static long strikeObjectId[NUM_ARTILLERY_TYPES] =
  2330. {
  2331. SMALL_ARTLRY, BIG_ARTLRY, SENSOR_ARTLRY
  2332. };
  2333. ObjectTypePtr objectType = getObjectType(strikeObjectId[artilleryType]);
  2334. artillery->init(false, objectType);
  2335. artillery->setPosition(position);
  2336. artillery->setExists(true);
  2337. }
  2338. return(artillery);
  2339. }
  2340. void GameObjectManager::updateAppearancesOnly( bool terrain, bool movers, bool other)
  2341. {
  2342. if (terrain && renderObjects)
  2343. {
  2344. for (long terrainBlock = 0; terrainBlock < Terrain::numObjBlocks; terrainBlock++)
  2345. {
  2346. if (Terrain::objBlockInfo[terrainBlock].active)
  2347. {
  2348. long numObjs = Terrain::objBlockInfo[terrainBlock].numObjects;
  2349. long objIndex = Terrain::objBlockInfo[terrainBlock].firstHandle;
  2350. for (long terrainObj = 0; terrainObj < numObjs; terrainObj++, objIndex++)
  2351. {
  2352. if (objList[objIndex] &&
  2353. (Terrain::objVertexActive[objList[objIndex]->getVertexNum()] || (turn < 3)) &&
  2354. objList[objIndex]->getExists())
  2355. {
  2356. if (objList[objIndex]->getAppearance()->recalcBounds())
  2357. {
  2358. // Must force here as well.
  2359. Stuff::Vector3D pos = objList[objIndex]->getPosition();
  2360. float rot = objList[objIndex]->getRotation();
  2361. pos.z = land->getTerrainElevation(pos);
  2362. long drawFlags = objList[objIndex]->drawFlags;
  2363. int teamID = objList[objIndex]->getTeamId();
  2364. objList[objIndex]->getAppearance()->setObjectParameters(pos,rot,drawFlags,teamID,Team::getRelation(teamID, Team::home->getId()));
  2365. objList[objIndex]->getAppearance()->update( false );
  2366. objList[objIndex]->getAppearance()->setVisibility(true, true);
  2367. }
  2368. }
  2369. }
  2370. }
  2371. }
  2372. }
  2373. if (movers)
  2374. {
  2375. if (mechs)
  2376. {
  2377. for (long i = 0; i < numMechs; i++)
  2378. if (mechs[i] && mechs[i]->getExists())
  2379. {
  2380. bool inView = mechs[i]->getAppearance()->recalcBounds();
  2381. if (inView)
  2382. mechs[i]->windowsVisible = turn;
  2383. // Must force here as well.
  2384. Stuff::Vector3D pos = mechs[i]->getPosition();
  2385. float rot = mechs[i]->getRotation();
  2386. pos.z = land->getTerrainElevation(pos);
  2387. bool selected = mechs[i]->isSelected();
  2388. int teamID = mechs[i]->getTeamId();
  2389. mechs[i]->getAppearance()->setObjectParameters(pos,rot,mechs[i]->drawFlags,teamID,Team::getRelation(teamID, Team::home->getId()));
  2390. mechs[i]->getAppearance()->update( false );
  2391. mechs[i]->getAppearance()->setVisibility(inView,true);
  2392. }
  2393. }
  2394. if (vehicles)
  2395. {
  2396. for (long i = 0; i < numVehicles; i++)
  2397. if (vehicles[i] && vehicles[i]->getExists())
  2398. {
  2399. bool inView = vehicles[i]->getAppearance()->recalcBounds();
  2400. vehicles[i]->windowsVisible = turn;
  2401. // Must force here as well.
  2402. Stuff::Vector3D pos = vehicles[i]->getPosition();
  2403. float rot = vehicles[i]->getRotation();
  2404. pos.z = land->getTerrainElevation(pos);
  2405. if ((pos.z < MapData::waterDepth))
  2406. pos.z = MapData::waterDepth;
  2407. bool selected = vehicles[i]->isSelected();
  2408. int teamID = vehicles[i]->getTeamId();
  2409. vehicles[i]->getAppearance()->setObjectParameters(pos, rot, vehicles[i]->drawFlags, teamID, Team::getRelation(teamID, Team::home->getId()));
  2410. vehicles[i]->getAppearance()->update( false );
  2411. vehicles[i]->getAppearance()->setInView( inView );
  2412. }
  2413. }
  2414. }
  2415. if (other) {
  2416. //---------------------------------------
  2417. // All other objects should be updated...
  2418. if (turrets)
  2419. {
  2420. for (long i=0;i<numTurrets;i++)
  2421. {
  2422. if (turrets[i] && turrets[i]->getExists())
  2423. {
  2424. if (turrets[i]->getAppearance()->recalcBounds())
  2425. {
  2426. // Must force here as well.
  2427. Stuff::Vector3D pos = turrets[i]->getPosition();
  2428. float rot = turrets[i]->getRotation();
  2429. pos.z = land->getTerrainElevation(pos);
  2430. bool selected = turrets[i]->isSelected();
  2431. int teamID = turrets[i]->getTeamId();
  2432. turrets[i]->getAppearance()->setObjectParameters(pos,rot,selected,teamID,Team::getRelation(teamID, Team::home->getId()));
  2433. turrets[i]->getAppearance()->update( false );
  2434. turrets[i]->getAppearance()->setInView( 1 );
  2435. }
  2436. else
  2437. turrets[i]->getAppearance()->setInView( 0 );
  2438. }
  2439. }
  2440. }
  2441. /* if (weapons) {
  2442. for (long i=0;i<numWeapons;i++) {
  2443. if (weapons[i] && weapons[i]->getExists()) {
  2444. if (!weapons[i]->update())
  2445. weapons[i]->setExists(false);
  2446. }
  2447. }
  2448. }*/
  2449. /*if (carnage) {
  2450. for (long i = 0; i < numCarnage; i++) {
  2451. if (carnage[i] && carnage[i]->getExists()) {
  2452. if (!carnage[i]->update())
  2453. carnage[i]->setExists(false);
  2454. }
  2455. }
  2456. }*/
  2457. if (lights)
  2458. {
  2459. for (long i = 0; i < numLights; i++)
  2460. {
  2461. if (lights[i] && lights[i]->getExists())
  2462. {
  2463. if (lights[i]->getAppearance()->recalcBounds() )
  2464. {
  2465. lights[i]->getAppearance()->update( false );
  2466. lights[i]->getAppearance()->setInView( 1 );
  2467. }
  2468. else
  2469. lights[i]->getAppearance()->setInView(0);
  2470. }
  2471. }
  2472. }
  2473. if (artillery)
  2474. {
  2475. for (long i = 0; i < numArtillery; i++)
  2476. {
  2477. if (artillery[i] && artillery[i]->getExists())
  2478. {
  2479. if (artillery[i]->getAppearance()->recalcBounds() )
  2480. {
  2481. artillery[i]->getAppearance()->update( false );
  2482. artillery[i]->getAppearance()->setInView( 1 );
  2483. }
  2484. else
  2485. artillery[i]->getAppearance()->setInView( 0 );
  2486. }
  2487. }
  2488. }
  2489. }
  2490. }
  2491. //-------------------------------------------------------------------
  2492. void GameObjectManager::CopyTo (ObjectManagerData *data)
  2493. {
  2494. data->maxObjects = getMaxObjects();
  2495. data->numElementals = numElementals;
  2496. data->numTerrainObjects = numTerrainObjects;
  2497. data->numBuildings = numBuildings;
  2498. data->numTurrets = numTurrets;
  2499. data->numWeapons = numWeapons;
  2500. data->numCarnage = numCarnage;
  2501. data->numLights = numLights;
  2502. data->numArtillery = numArtillery;
  2503. data->numGates = numGates;
  2504. data->maxMechs = maxMechs;
  2505. data->maxVehicles = maxVehicles;
  2506. data->numMechs = numMechs;
  2507. data->numVehicles = numVehicles;
  2508. data->nextWatchId = nextWatchID;
  2509. }
  2510. //-------------------------------------------------------------------
  2511. void GameObjectManager::CopyFrom (ObjectManagerData *data)
  2512. {
  2513. numElementals = data->numElementals;
  2514. numTerrainObjects = data->numTerrainObjects;
  2515. numBuildings = data->numBuildings;
  2516. numTurrets = data->numTurrets;
  2517. numWeapons = data->numWeapons;
  2518. numCarnage = data->numCarnage;
  2519. numLights = data->numLights;
  2520. numArtillery = data->numArtillery;
  2521. numGates = data->numGates;
  2522. maxMechs = data->maxMechs;
  2523. maxVehicles = data->maxVehicles;
  2524. numMechs = data->numMechs;
  2525. numVehicles = data->numVehicles;
  2526. nextWatchID = data->nextWatchId;
  2527. }
  2528. //-------------------------------------------------------------------
  2529. long GameObjectManager::Save (PacketFilePtr file, long packetNum)
  2530. {
  2531. long *watchSave = (long *)malloc(sizeof(long) * (getMaxObjects() + 1));
  2532. memset(watchSave,0,sizeof(long) * (getMaxObjects() + 1));
  2533. ObjectManagerData data;
  2534. CopyTo(&data);
  2535. file->writePacket(packetNum,(MemoryPtr)&data,sizeof(ObjectManagerData),STORAGE_TYPE_RAW);
  2536. packetNum++;
  2537. for (long i=0;i<=getMaxObjects();i++)
  2538. {
  2539. if (objList[i])
  2540. {
  2541. objList[i]->Save(file,packetNum);
  2542. packetNum++;
  2543. //Find the watchID from the watchlist for this object.
  2544. // If none, let it be. It'll be zero already
  2545. // DO NOT CALL getWatchID!!!!!!!
  2546. // That will assign them to objects which don't have them!!!!
  2547. for (long j=0;j<=nextWatchID;j++)
  2548. {
  2549. if (watchList[j] == objList[i])
  2550. {
  2551. watchSave[j] = i;
  2552. }
  2553. }
  2554. }
  2555. else
  2556. {
  2557. packetNum++;
  2558. }
  2559. }
  2560. file->writePacket(packetNum,(MemoryPtr)watchSave,sizeof(long) * (getMaxObjects() + 1),STORAGE_TYPE_ZLIB);
  2561. packetNum++;
  2562. free(watchSave);
  2563. watchSave = NULL;
  2564. return packetNum;
  2565. }
  2566. //-------------------------------------------------------------------
  2567. long GameObjectManager::Load (PacketFilePtr file, long packetNum)
  2568. {
  2569. ObjectManagerData data;
  2570. file->readPacket(packetNum,(MemoryPtr)&data);
  2571. packetNum++;
  2572. CopyFrom(&data);
  2573. //------------------------------------------------------------------
  2574. //Create the ObjList and WatchList EXACTLY like we normally do.
  2575. GameObject::setInitialize(true);
  2576. //-----------------------------------------------------------
  2577. // First element in list is NULL (handle of 0 is always NULL)
  2578. objList = (GameObjectPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  2579. memset(objList,0,sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  2580. watchList = (GameObjectPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  2581. memset(watchList,0,sizeof(GameObjectPtr) * (getMaxObjects() + 1));
  2582. long i = 0;
  2583. long curHandle = 1;
  2584. maxMovers = maxMechs + maxVehicles + numElementals;
  2585. //--------------------------------------------------------------
  2586. // For now, we'll use an array of pointers due to the irritating
  2587. // 'new' for arrays problem...
  2588. if (maxMechs > 0)
  2589. {
  2590. mechs = (BattleMechPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(BattleMechPtr) * maxMechs);
  2591. if (!mechs)
  2592. Fatal(maxMechs, " GameObjectManager.setNumObjects: cannot malloc mechs ");
  2593. }
  2594. //--------------------------------------------------------------
  2595. // For now, we'll use an array of pointers due to the irritating
  2596. // 'new' for arrays problem...
  2597. if (maxVehicles > 0)
  2598. {
  2599. vehicles = (GroundVehiclePtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GroundVehiclePtr) * maxVehicles);
  2600. if (!vehicles)
  2601. Fatal(maxVehicles, " GameObjectManager.setNumObjects: cannot malloc vehicles ");
  2602. }
  2603. //--------------------------------------------------------------
  2604. // For now, we'll use an array of pointers due to the irritating
  2605. // 'new' for arrays problem...
  2606. if (numTerrainObjects > 0)
  2607. {
  2608. terrainObjects = (TerrainObjectPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(TerrainObjectPtr) * numTerrainObjects);
  2609. if (!terrainObjects)
  2610. Fatal(numTerrainObjects, " GameObjectManager.setNumObjects: cannot malloc terrain objects ");
  2611. }
  2612. //--------------------------------------------------------------
  2613. // For now, we'll use an array of pointers due to the irritating
  2614. // 'new' for arrays problem...
  2615. if (numBuildings > 0)
  2616. {
  2617. buildings = (BuildingPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(BuildingPtr) * numBuildings);
  2618. if (!buildings)
  2619. Fatal(numBuildings, " GameObjectManager.setNumObjects: cannot malloc buildings ");
  2620. }
  2621. if (numTurrets > 0)
  2622. {
  2623. turrets = (TurretPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(TurretPtr) * numTurrets);
  2624. if ( !turrets )
  2625. Fatal(numTurrets, " GameObjectManager.setNumObjects: cannot malloc Turrets ");
  2626. }
  2627. if (numGates > 0)
  2628. {
  2629. gates = (GatePtr*)ObjectTypeManager::objectCache->Malloc(sizeof(GatePtr) * numGates);
  2630. if ( !gates )
  2631. Fatal(numGates, " GameObjectManager.setNumObjects: cannot malloc Gates ");
  2632. }
  2633. //--------------------------------------------------------------
  2634. // For now, we'll use an array of pointers due to the irritating
  2635. // 'new' for arrays problem...
  2636. if (numWeapons > 0)
  2637. {
  2638. weapons = (WeaponBoltPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(WeaponBoltPtr) * numWeapons);
  2639. if (!weapons)
  2640. Fatal(numWeapons, " GameObjectManager.setNumObjects: cannot malloc weapons ");
  2641. }
  2642. if (numCarnage > 0)
  2643. {
  2644. carnage = (CarnagePtr*)ObjectTypeManager::objectCache->Malloc(sizeof(CarnagePtr) * numCarnage);
  2645. if (!carnage)
  2646. Fatal(numCarnage, " GameObjectManager.setNumObjects: cannot malloc carnage ");
  2647. }
  2648. if (numArtillery > 0)
  2649. {
  2650. artillery = (ArtilleryPtr*)ObjectTypeManager::objectCache->Malloc(sizeof(ArtilleryPtr) * numArtillery);
  2651. if (!artillery)
  2652. Fatal(numArtillery, " GameObjectManager.setNumObjects: cannot malloc artillery ");
  2653. }
  2654. useMoverLineOfSightTable = true;
  2655. moverLineOfSightTable = (char*)systemHeap->Malloc(maxMovers * maxMovers);
  2656. if (!moverLineOfSightTable)
  2657. Fatal(numGates, " GameObjectManager.setNumObjects: cannot malloc moverLineOfSightTable ");
  2658. long curTerrObjNum = 0;
  2659. long curBuildingNum = 0;
  2660. long curTurretNum = 0;
  2661. long curGateNum = 0;
  2662. long curArtilleryNum = 0;
  2663. long curCarnageNum = 0;
  2664. long curMechNum = 0;
  2665. long curVehicleNum = 0;
  2666. long curBoltNum = 0;
  2667. long oldBlockNum = -1;
  2668. for (i=0;i<=getMaxObjects();i++)
  2669. {
  2670. //OK.
  2671. // For each object that was saved, Load the data.
  2672. // If objectTypeNum != 0, create the object from the type EXACTLY like we do above.
  2673. // then init from the savedData.
  2674. // Next Object.
  2675. //First, get the size of the packet saved.
  2676. // This will tell me what kind of object it was!
  2677. file->seekPacket(packetNum);
  2678. DWORD packetSize = file->getPacketSize();
  2679. if (packetSize == 0)
  2680. {
  2681. //NO Object stored here.
  2682. // Increment Packet and move on
  2683. // First object in ObjList, for example!!
  2684. packetNum++;
  2685. }
  2686. else if ((packetSize == sizeof(GameObjectData)) ||
  2687. (packetSize == sizeof(MoverData)))
  2688. {
  2689. STOP(("We saved a pure GameObject or Pure Mover in slot %d, packet %d",i,packetNum));
  2690. }
  2691. else if (packetSize == sizeof(TerrainObjectData))
  2692. {
  2693. //We have a TerrainObject.
  2694. // Get its data.
  2695. TerrainObjectData data;
  2696. file->readPacket(packetNum,(MemoryPtr)(&data));
  2697. packetNum++;
  2698. TerrainObjectPtr obj = new TerrainObject;
  2699. objList[i] = terrainObjects[curTerrObjNum] = obj;
  2700. objList[i]->setHandle(i);
  2701. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2702. {
  2703. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2704. if (!objType)
  2705. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2706. obj->init(true, objType);
  2707. obj->setExists(true);
  2708. obj->Load(&data);
  2709. obj->setDamage(data.damage);
  2710. obj->setRotation(data.rotation);
  2711. if (data.blockNumber != oldBlockNum)
  2712. {
  2713. oldBlockNum = data.blockNumber;
  2714. Terrain::objBlockInfo[data.blockNumber].firstHandle = i;
  2715. }
  2716. Terrain::objBlockInfo[data.blockNumber].numCollidableObjects++;
  2717. Terrain::objBlockInfo[data.blockNumber].numObjects++;
  2718. }
  2719. else
  2720. {
  2721. obj->setExists(false);
  2722. }
  2723. curTerrObjNum++;
  2724. }
  2725. else if (packetSize == sizeof(BuildingData))
  2726. {
  2727. //We have a Building.
  2728. BuildingData data;
  2729. file->readPacket(packetNum,(MemoryPtr)(&data));
  2730. packetNum++;
  2731. BuildingPtr obj = new Building;
  2732. objList[i] = buildings[curBuildingNum] = obj;
  2733. objList[i]->setHandle(i);
  2734. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2735. {
  2736. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2737. if (!objType)
  2738. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2739. obj->init(true, objType);
  2740. obj->setExists(true);
  2741. obj->Load(&data);
  2742. obj->setDamage(data.damage);
  2743. obj->setRotation(data.rotation);
  2744. if (data.blockNumber != oldBlockNum)
  2745. {
  2746. oldBlockNum = data.blockNumber;
  2747. Terrain::objBlockInfo[data.blockNumber].firstHandle = i;
  2748. }
  2749. if (((((BuildingTypePtr)objType)->perimeterAlarmRange > 0.0f) &&
  2750. (((BuildingTypePtr)objType)->perimeterAlarmTimer > 0.0f)) ||
  2751. (((BuildingTypePtr)objType)->lookoutTowerRange > 0.0f) ||
  2752. (((BuildingTypePtr)objType)->sensorRange > 0.0f))
  2753. {
  2754. Terrain::objBlockInfo[data.blockNumber].numCollidableObjects++;
  2755. }
  2756. Terrain::objBlockInfo[data.blockNumber].numObjects++;
  2757. }
  2758. else
  2759. {
  2760. obj->setExists(false);
  2761. }
  2762. curBuildingNum++;
  2763. }
  2764. else if (packetSize == sizeof(TurretData))
  2765. {
  2766. //We have a Turret.
  2767. TurretData data;
  2768. file->readPacket(packetNum,(MemoryPtr)(&data));
  2769. packetNum++;
  2770. TurretPtr obj = new Turret;
  2771. objList[i] = turrets[curTurretNum] = obj;
  2772. objList[i]->setHandle(i);
  2773. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2774. {
  2775. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2776. if (!objType)
  2777. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2778. obj->init(true, objType);
  2779. obj->setExists(true);
  2780. obj->Load(&data);
  2781. obj->setDamage(data.damage);
  2782. obj->setRotation(data.rotation);
  2783. if (data.blockNumber != oldBlockNum)
  2784. {
  2785. oldBlockNum = data.blockNumber;
  2786. Terrain::objBlockInfo[data.blockNumber].firstHandle = i;
  2787. }
  2788. Terrain::objBlockInfo[data.blockNumber].numCollidableObjects++;
  2789. Terrain::objBlockInfo[data.blockNumber].numObjects++;
  2790. }
  2791. else
  2792. {
  2793. obj->setExists(false);
  2794. }
  2795. curTurretNum++;
  2796. }
  2797. else if (packetSize == sizeof(GateData))
  2798. {
  2799. //We have a Gate.
  2800. GateData data;
  2801. file->readPacket(packetNum,(MemoryPtr)(&data));
  2802. packetNum++;
  2803. GatePtr obj = new Gate;
  2804. objList[i] = gates[curGateNum] = obj;
  2805. objList[i]->setHandle(i);
  2806. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2807. {
  2808. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2809. if (!objType)
  2810. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2811. obj->init(true, objType);
  2812. obj->setExists(true);
  2813. obj->Load(&data);
  2814. obj->setDamage(data.damage);
  2815. obj->setRotation(data.rotation);
  2816. if (data.blockNumber != oldBlockNum)
  2817. {
  2818. oldBlockNum = data.blockNumber;
  2819. Terrain::objBlockInfo[data.blockNumber].firstHandle = i;
  2820. }
  2821. Terrain::objBlockInfo[data.blockNumber].numCollidableObjects++;
  2822. Terrain::objBlockInfo[data.blockNumber].numObjects++;
  2823. }
  2824. else
  2825. {
  2826. obj->setExists(false);
  2827. }
  2828. curGateNum++;
  2829. }
  2830. else if (packetSize == sizeof(ArtilleryData))
  2831. {
  2832. //We have an Artillery.
  2833. ArtilleryData data;
  2834. file->readPacket(packetNum,(MemoryPtr)(&data));
  2835. packetNum++;
  2836. ArtilleryPtr obj = new Artillery;
  2837. objList[i] = artillery[curArtilleryNum] = obj;
  2838. objList[i]->setHandle(i);
  2839. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2840. {
  2841. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2842. if (!objType)
  2843. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2844. obj->init(true, objType);
  2845. obj->setExists(true);
  2846. obj->Load(&data);
  2847. }
  2848. else
  2849. {
  2850. obj->setExists(false);
  2851. }
  2852. curArtilleryNum++;
  2853. }
  2854. else if (packetSize == sizeof(CarnageData))
  2855. {
  2856. //We have a Carnage.
  2857. CarnageData data;
  2858. file->readPacket(packetNum,(MemoryPtr)(&data));
  2859. packetNum++;
  2860. CarnagePtr obj = new Carnage;
  2861. objList[i] = carnage[curCarnageNum] = obj;
  2862. objList[i]->setHandle(i);
  2863. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2864. {
  2865. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2866. if (!objType)
  2867. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2868. obj->init(true, objType);
  2869. obj->setExists(true);
  2870. obj->Load(&data);
  2871. }
  2872. else
  2873. {
  2874. obj->setExists(false);
  2875. }
  2876. curCarnageNum++;
  2877. }
  2878. else if (packetSize == sizeof(MechData))
  2879. {
  2880. //We have a BattleMech.
  2881. MechData data;
  2882. file->readPacket(packetNum,(MemoryPtr)(&data));
  2883. packetNum++;
  2884. BattleMechPtr obj = new BattleMech;
  2885. objList[i] = mechs[curMechNum] = obj;
  2886. objList[i]->setHandle(i);
  2887. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2888. {
  2889. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2890. if (!objType)
  2891. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2892. obj->init(true, objType);
  2893. obj->setExists(true);
  2894. obj->Load(&data);
  2895. }
  2896. else
  2897. {
  2898. obj->setExists(false);
  2899. }
  2900. curMechNum++;
  2901. }
  2902. else if (packetSize == sizeof(GroundVehicleData))
  2903. {
  2904. //We have a groundVehicle.
  2905. GroundVehicleData data;
  2906. file->readPacket(packetNum,(MemoryPtr)(&data));
  2907. packetNum++;
  2908. GroundVehiclePtr obj = new GroundVehicle;
  2909. objList[i] = vehicles[curVehicleNum] = obj;
  2910. objList[i]->setHandle(i);
  2911. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2912. {
  2913. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2914. if (!objType)
  2915. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2916. obj->init(true, objType);
  2917. obj->setExists(true);
  2918. obj->Load(&data);
  2919. }
  2920. else
  2921. {
  2922. obj->setExists(false);
  2923. }
  2924. curVehicleNum++;
  2925. }
  2926. else if (packetSize == sizeof(WeaponBoltData))
  2927. {
  2928. //We have a WeaponBolt.
  2929. WeaponBoltData data;
  2930. file->readPacket(packetNum,(MemoryPtr)(&data));
  2931. packetNum++;
  2932. WeaponBoltPtr obj = new WeaponBolt;
  2933. objList[i] = weapons[curBoltNum] = obj;
  2934. objList[i]->setHandle(i);
  2935. if (data.objectTypeNum > 0) //We have an object type to copy from!!
  2936. {
  2937. ObjectTypePtr objType = getObjectType(data.objectTypeNum);
  2938. if (!objType)
  2939. STOP(("We saved an Object we don't know how to re-create %d",data.objectTypeNum));
  2940. obj->init(true, objType);
  2941. obj->setExists(true);
  2942. obj->Load(&data);
  2943. }
  2944. else
  2945. {
  2946. obj->setExists(false);
  2947. }
  2948. curBoltNum++;
  2949. }
  2950. }
  2951. if (curTerrObjNum != numTerrainObjects)
  2952. STOP(("Didn't load %d but instead %d TerrainObjects",numTerrainObjects,curTerrObjNum));
  2953. if (curBuildingNum != numBuildings)
  2954. STOP(("Didn't load %d but instead %d Buildings",numBuildings,curBuildingNum));
  2955. if (curTurretNum != numTurrets)
  2956. STOP(("Didn't load %d but instead %d Turrets",numTurrets,curTurretNum));
  2957. if (curGateNum != numGates)
  2958. STOP(("Didn't load %d but instead %d Gates",numGates,curGateNum));
  2959. if (curArtilleryNum != numArtillery)
  2960. STOP(("Didn't load %d but instead %d Artillery",numArtillery,curArtilleryNum));
  2961. if (curCarnageNum != numCarnage)
  2962. STOP(("Didn't load %d but instead %d Carnage",numCarnage,curCarnageNum));
  2963. if (curMechNum != maxMechs)
  2964. STOP(("Didn't load %d but instead %d Mechs",maxMechs,curMechNum));
  2965. if (curVehicleNum != maxVehicles)
  2966. STOP(("Didn't load %d but instead %d Vehicles",maxVehicles,curVehicleNum));
  2967. if (curBoltNum != numWeapons)
  2968. STOP(("Didn't load %d but instead %d WeaponBolts",numWeapons,curBoltNum));
  2969. rebuildCollidableList = true;
  2970. //---------------------------------------------------
  2971. // Finally, let's build the control building lists...
  2972. for (i = 0; i < numTurrets; i++)
  2973. {
  2974. if ((turrets[i]->parentId != 0xffffffff) && (turrets[i]->parentId != 0))
  2975. {
  2976. BuildingPtr controlBuilding = (BuildingPtr)ObjectManager->findByCellPosition((turrets[i]->parentId>>16),(turrets[i]->parentId & 0x0000ffff));
  2977. if (controlBuilding && !controlBuilding->getFlag(OBJECT_FLAG_CONTROLBUILDING))
  2978. {
  2979. controlBuilding->setFlag(OBJECT_FLAG_CAPTURABLE, true);
  2980. controlBuilding->setFlag(OBJECT_FLAG_CONTROLBUILDING, true);
  2981. controlBuilding->listID = numTurretControls;
  2982. turretControls[numTurretControls++] = controlBuilding;
  2983. }
  2984. else if (!controlBuilding)
  2985. {
  2986. Stuff::Vector3D worldPos;
  2987. if (land)
  2988. land->cellToWorld((turrets[i]->parentId>>16),(turrets[i]->parentId & 0x0000ffff),worldPos);
  2989. PAUSE(("Turret linked to bldg @ R %d, C %d X:%f Y:%f No Bldg there!",(turrets[i]->parentId>>16),(turrets[i]->parentId & 0x0000ffff),worldPos.x,worldPos.y));
  2990. turrets[i]->parentId = 0xffffffff;
  2991. }
  2992. }
  2993. }
  2994. for (i = 0; i < numGates; i++)
  2995. {
  2996. if ((gates[i]->parentId != 0xffffffff) && (gates[i]->parentId != 0))
  2997. {
  2998. BuildingPtr controlBuilding = (BuildingPtr)ObjectManager->findByCellPosition((gates[i]->parentId>>16),(gates[i]->parentId & 0x0000ffff));
  2999. if (controlBuilding && !controlBuilding->getFlag(OBJECT_FLAG_CONTROLBUILDING))
  3000. {
  3001. controlBuilding->setFlag(OBJECT_FLAG_CONTROLBUILDING, true);
  3002. controlBuilding->listID = numGateControls;
  3003. gateControls[numGateControls++] = controlBuilding;
  3004. }
  3005. else if (!controlBuilding)
  3006. {
  3007. PAUSE(("Gate tried to link to building at Row %d, Col %d. No Bldg there!",(gates[i]->parentId>>16),(gates[i]->parentId & 0x0000ffff)));
  3008. gates[i]->parentId = 0xffffffff;
  3009. }
  3010. }
  3011. }
  3012. //-----------------------------------------------------------------------------------
  3013. // Create list of special buildings. These buildings will be updated at least once
  3014. // every frame regardless of where they are on the terrain and what is visible.
  3015. // This is because perimeter alarms and lookout buildings and ????? must work even
  3016. // if the player is NOT looking at them!!
  3017. for (i=0;i<numBuildings;i++)
  3018. {
  3019. if (buildings[i]->isSpecialBuilding())
  3020. {
  3021. specialBuildings[numSpecialBuildings++] = buildings[i];
  3022. }
  3023. }
  3024. //--------------------------------------------------------------------
  3025. //Now, lets point every lit building to at least one power generator.
  3026. for (i=0;i<numBuildings;i++)
  3027. {
  3028. if (buildings[i]->isPowerSource())
  3029. {
  3030. powerGenerators[numPowerGenerators++] = buildings[i];
  3031. }
  3032. }
  3033. if (numPowerGenerators)
  3034. {
  3035. for (i=0;i<numBuildings;i++)
  3036. {
  3037. Stuff::Vector3D maxDist;
  3038. long generatorIndex = 0;
  3039. maxDist.Subtract(buildings[i]->getPosition(),powerGenerators[0]->getPosition());
  3040. float minDistance = maxDist.GetApproximateLength();
  3041. for (long j=1;j<numPowerGenerators;j++)
  3042. {
  3043. maxDist.Subtract(buildings[i]->getPosition(),powerGenerators[j]->getPosition());
  3044. float newDistance = maxDist.GetApproximateLength();
  3045. if (newDistance < minDistance)
  3046. {
  3047. generatorIndex = j;
  3048. minDistance = newDistance;
  3049. }
  3050. }
  3051. buildings[i]->setPowerSupply(powerGenerators[generatorIndex]);
  3052. }
  3053. for (i=0;i<numTerrainObjects;i++)
  3054. {
  3055. Stuff::Vector3D maxDist;
  3056. long generatorIndex = 0;
  3057. maxDist.Subtract(terrainObjects[i]->getPosition(),powerGenerators[0]->getPosition());
  3058. float minDistance = maxDist.GetApproximateLength();
  3059. for (long j=1;j<numPowerGenerators;j++)
  3060. {
  3061. maxDist.Subtract(terrainObjects[i]->getPosition(),powerGenerators[j]->getPosition());
  3062. float newDistance = maxDist.GetApproximateLength();
  3063. if (newDistance < minDistance)
  3064. {
  3065. generatorIndex = j;
  3066. minDistance = newDistance;
  3067. }
  3068. }
  3069. terrainObjects[i]->setPowerSupply(powerGenerators[generatorIndex]);
  3070. }
  3071. }
  3072. GameObject::setInitialize(false);
  3073. //Reload the Object Watchers
  3074. long *watchSave = (long *)malloc(sizeof(long) * (getMaxObjects() + 1));
  3075. memset(watchSave,0,sizeof(long) * (getMaxObjects() + 1));
  3076. file->readPacket(packetNum,(MemoryPtr)watchSave);
  3077. packetNum++;
  3078. //Find the watchID from the watchlist for this object.
  3079. // If none, let it be. It'll be zero already
  3080. // DO NOT CALL getWatchID!!!!!!!
  3081. // That will assign them to objects which don't have them!!!!
  3082. for (long j=0;j<getMaxObjects();j++)
  3083. {
  3084. watchList[j] = objList[watchSave[j]];
  3085. }
  3086. free(watchSave);
  3087. watchSave = NULL;
  3088. return packetNum;
  3089. }
  3090. //***************************************************************************