weaponbolt.cpp 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691
  1. //---------------------------------------------------------------------------
  2. //
  3. // weaponbolt.cpp -- File contains the WeaponBolt Object code
  4. //
  5. // MechCommander 2
  6. //
  7. //---------------------------------------------------------------------------//
  8. // Copyright (C) Microsoft Corporation. All rights reserved. //
  9. //===========================================================================//
  10. //---------------------------------------------------------------------------
  11. // Include Files
  12. #ifndef MCLIB_H
  13. #include "mclib.h"
  14. #endif
  15. #ifndef WEAPONBOLT_H
  16. #include "weaponbolt.h"
  17. #endif
  18. #ifndef GAMESOUND_H
  19. #include "gamesound.h"
  20. #endif
  21. #ifndef OBJMGR_H
  22. #include "objmgr.h"
  23. #endif
  24. #ifndef WEAPONFX_H
  25. #include "weaponfx.h"
  26. #endif
  27. #ifndef MULTPLYR_H
  28. #include "multplyr.h"
  29. #endif
  30. #ifndef MISSION_H
  31. #include "mission.h"
  32. #endif
  33. #include <gameos.hpp>
  34. //---------------------------------------------------------------------------
  35. extern bool hasGuardBand;
  36. extern MidLevelRenderer::MLRClipper * theClipper;
  37. extern bool drawOldWay;
  38. extern float BaseHeadShotElevation;
  39. extern bool useNonWeaponEffects;
  40. extern bool MLRVertexLimitReached;
  41. #define BASE_EFFECT_SCALAR 1.0f
  42. #define EFFECT_LEFT_TIME 1.0f
  43. #define WEAPON_ARC_FACTOR -20.0f
  44. #define WEAPON_ARC_HEIGHT 150.0f
  45. #define ARC_THRESHOLD 0.0f
  46. //---------------------------------------------------------------------------
  47. // class WeaponBoltType
  48. //---------------------------------------------------------------------------
  49. GameObjectPtr WeaponBoltType::createInstance (void)
  50. {
  51. WeaponBoltPtr result = new WeaponBolt;
  52. if (!result)
  53. return NULL;
  54. result->init(true, this);
  55. return(result);
  56. }
  57. //---------------------------------------------------------------------------
  58. void WeaponBoltType::destroy (void)
  59. {
  60. if (textureName)
  61. ObjectTypeManager::objectCache->Free(textureName);
  62. textureName = NULL;
  63. ObjectType::destroy();
  64. }
  65. //---------------------------------------------------------------------------
  66. DWORD bgrTorgb (DWORD frontRGB);
  67. //---------------------------------------------------------------------------
  68. long WeaponBoltType::init (FilePtr objFile, unsigned long fileSize)
  69. {
  70. long result = 0;
  71. FitIniFile bullFile;
  72. result = bullFile.open(objFile,fileSize);
  73. if (result != NO_ERR)
  74. Fatal(result,"WeaponBoltType::init -- Unable to open File");
  75. //------------------------------------------------------------------
  76. result = bullFile.seekBlock("BoltProjectileData");
  77. if (result != NO_ERR)
  78. {
  79. //Check if we are a NEW beam type.
  80. result = bullFile.seekBlock("BeamProjectileData");
  81. if (result != NO_ERR)
  82. {
  83. STOP(("WeaponBoltTYpe::init -- Not a valid weaponBolt"));
  84. }
  85. result = bullFile.readIdBoolean("IsBeam",isBeam);
  86. if (result != NO_ERR)
  87. isBeam = false;
  88. result = bullFile.readIdFloat("BeamDuration",beamDuration);
  89. if (result != NO_ERR)
  90. beamDuration = 0.0f;
  91. result = bullFile.readIdFloat("BeamWiggle",beamWiggle);
  92. if (result != NO_ERR)
  93. beamWiggle = 0.0f;
  94. result = bullFile.readIdBoolean("PointLight",lightSource);
  95. if (result != NO_ERR)
  96. lightSource = false;
  97. char txmName[1024];
  98. result = bullFile.readIdString("TextureName",txmName,1023);
  99. if (result != NO_ERR)
  100. strcpy(txmName,"NONE");
  101. textureName = (char *)ObjectTypeManager::objectCache->Malloc(strlen(txmName)+1);
  102. strcpy(textureName,txmName);
  103. result = bullFile.readIdFloat("UVAnimRate",uvAnimRate);
  104. if (result != NO_ERR)
  105. uvAnimRate = 0.0f;
  106. result = bullFile.readIdFloat("UVRepeat",uvRepeat);
  107. if (result != NO_ERR)
  108. uvRepeat = 1.0f;
  109. result = bullFile.readIdFloat("UnitLength",unitLength);
  110. if (result != NO_ERR)
  111. unitLength = 1.0f;
  112. if (unitLength < Stuff::SMALL)
  113. unitLength = 1.0f;
  114. result = bullFile.readIdBoolean("MipTexture",mipTexture);
  115. if (result != NO_ERR)
  116. mipTexture = false;
  117. result = bullFile.readIdLong("FiringSoundFX",fireSoundFX);
  118. if (result != NO_ERR)
  119. fireSoundFX = 0;
  120. result = bullFile.readIdFloat("BulgeWidth",bulgeWidth);
  121. if (result != NO_ERR)
  122. bulgeWidth = 1.0f;
  123. result = bullFile.readIdULong("MidEdgeRGB",midEdgeRGB);
  124. if (result != NO_ERR)
  125. midEdgeRGB = 0x00ffffff;
  126. result = bullFile.readIdULong("MiddleRGB",middleRGB);
  127. if (result != NO_ERR)
  128. middleRGB = 0x00ffffff;
  129. result = bullFile.readIdUChar("EdgeAlpha",edgeAlpha);
  130. if (result != NO_ERR)
  131. edgeAlpha = 0xff;
  132. result = bullFile.readIdUChar("BoltAlpha",boltAlpha);
  133. if (result != NO_ERR)
  134. boltAlpha = 0xff;
  135. projLength = 1.0f;
  136. velocity = 1.0f;
  137. if (lightSource)
  138. {
  139. result = bullFile.readIdULong("LightRGB",lightRGB);
  140. if (result != NO_ERR)
  141. Fatal(result,"WeaponBoltType::init -- Unable to find lightRGB");
  142. result = bullFile.readIdFloat("MaxRadius",maxRadius);
  143. if (result != NO_ERR)
  144. Fatal(result,"WeaponBoltType::init -- Unable to find maxRadius");
  145. result = bullFile.readIdFloat("OutRadius",outRadius);
  146. if (result != NO_ERR)
  147. Fatal(result,"WeaponBoltType::init -- Unable to find outRadius");
  148. result = bullFile.readIdFloat("Intensity",intensity);
  149. if (result != NO_ERR)
  150. Fatal(result,"WeaponBoltType::init -- Unable to find intensity");
  151. }
  152. }
  153. else
  154. {
  155. result = bullFile.readIdFloat("ProjectileLength",projLength);
  156. if (result != NO_ERR)
  157. Fatal(result,"WeaponBoltType::init -- Unable to find projectileLength");
  158. result = bullFile.readIdFloat("BulgeLength",bulgeLength);
  159. if (result != NO_ERR)
  160. Fatal(result,"WeaponBoltType::init -- Unable to find bulgeLength");
  161. result = bullFile.readIdFloat("BulgeWidth",bulgeWidth);
  162. if (result != NO_ERR)
  163. Fatal(result,"WeaponBoltType::init -- Unable to find bulgeWidth");
  164. result = bullFile.readIdFloat("Velocity",velocity);
  165. if (result != NO_ERR)
  166. Fatal(result,"WeaponBoltType::init -- Unable to find velocity");
  167. result = bullFile.readIdLong("HitEffect",hitEffectObjNum);
  168. if (result != NO_ERR)
  169. Fatal(result,"WeaponBoltType::init -- Unable to find HitEffect");
  170. result = bullFile.readIdLong("MissEffect",missEffectObjNum);
  171. if (result != NO_ERR)
  172. Fatal(result,"WeaponBoltType::init -- Unable to find missEffect");
  173. result = bullFile.readIdLong("FiringSoundFX",fireSoundFX);
  174. if (result != NO_ERR)
  175. Fatal(result,"WeaponBoltType::init -- Unable to find FiringSoundFx");
  176. result = bullFile.readIdULong("FrontRGB",frontRGB);
  177. if (result != NO_ERR)
  178. Fatal(result,"WeaponBoltType::init -- Unable to find FrontRGB");
  179. result = bullFile.readIdULong("MidEdgeRGB",midEdgeRGB);
  180. if (result != NO_ERR)
  181. Fatal(result,"WeaponBoltType::init -- Unable to find MIDEDGERGB");
  182. result = bullFile.readIdULong("MiddleRGB",middleRGB);
  183. if (result != NO_ERR)
  184. Fatal(result,"WeaponBoltType::init -- Unable to find MiddleRGB");
  185. result = bullFile.readIdULong("BackRGB",backRGB);
  186. if (result != NO_ERR)
  187. Fatal(result,"WeaponBoltType::init -- Unable to find backRGB");
  188. result = bullFile.readIdUChar("EdgeAlpha",edgeAlpha);
  189. if (result != NO_ERR)
  190. Fatal(result,"WeaponBoltType::init -- Unable to find edgeAlpha");
  191. result = bullFile.readIdUChar("BoltAlpha",boltAlpha);
  192. if (result != NO_ERR)
  193. Fatal(result,"WeaponBoltType::init -- Unable to find boltAlpha");
  194. result = bullFile.readIdBoolean("IsBeam",isBeam);
  195. if (result != NO_ERR)
  196. isBeam = false;
  197. result = bullFile.readIdFloat("BeamDuration",beamDuration);
  198. if (result != NO_ERR)
  199. beamDuration = 0.0f;
  200. result = bullFile.readIdFloat("BeamWiggle",beamWiggle);
  201. if (result != NO_ERR)
  202. beamWiggle = 0.0f;
  203. result = bullFile.readIdBoolean("PointLight",lightSource);
  204. if (result != NO_ERR)
  205. lightSource = false;
  206. result = bullFile.readIdBoolean("ArcEffect",arcEffect);
  207. if (result != NO_ERR)
  208. arcEffect = false;
  209. result = bullFile.readIdFloat("ArcHeight",arcHeight);
  210. if (result != NO_ERR)
  211. arcHeight = -1.0f;
  212. result = bullFile.readIdFloat("AfterHitTime",afterHitTime);
  213. if (result != NO_ERR)
  214. afterHitTime = 0.0f;
  215. result = bullFile.readIdFloat("AreaEffectDamage",areaEffectDmg);
  216. if (result != NO_ERR)
  217. areaEffectDmg = 0.0f;
  218. result = bullFile.readIdFloat("AreaEffectRadius",areaEffectRad);
  219. if (result != NO_ERR)
  220. areaEffectRad = 0.0f;
  221. if (lightSource)
  222. {
  223. result = bullFile.readIdULong("LightRGB",lightRGB);
  224. if (result != NO_ERR)
  225. Fatal(result,"WeaponBoltType::init -- Unable to find lightRGB");
  226. result = bullFile.readIdFloat("MaxRadius",maxRadius);
  227. if (result != NO_ERR)
  228. Fatal(result,"WeaponBoltType::init -- Unable to find maxRadius");
  229. result = bullFile.readIdFloat("OutRadius",outRadius);
  230. if (result != NO_ERR)
  231. Fatal(result,"WeaponBoltType::init -- Unable to find outRadius");
  232. result = bullFile.readIdFloat("Intensity",intensity);
  233. if (result != NO_ERR)
  234. Fatal(result,"WeaponBoltType::init -- Unable to find intensity");
  235. }
  236. //------------------------------------------------------------------
  237. // Editor writes RGBs as BGRs. Change over here.
  238. frontRGB = bgrTorgb(frontRGB);
  239. backRGB = bgrTorgb(backRGB);
  240. middleRGB = bgrTorgb(middleRGB);
  241. midEdgeRGB = bgrTorgb(midEdgeRGB);
  242. lightRGB = bgrTorgb(lightRGB);
  243. }
  244. //------------------------------------------------------------------
  245. // Initialize the base object Type from the current file.
  246. result = ObjectType::init(&bullFile);
  247. return(result);
  248. }
  249. //---------------------------------------------------------------------------
  250. bool WeaponBoltType::handleCollision (GameObjectPtr collidee, GameObjectPtr collider)
  251. {
  252. //-------------------------------------------------------
  253. // The bolt ceases to exist when its effect is done.
  254. // always return FALSE or the collision will make it
  255. // go away!
  256. return(FALSE);
  257. }
  258. //---------------------------------------------------------------------------
  259. bool WeaponBoltType::handleDestruction (GameObjectPtr collidee, GameObjectPtr collider)
  260. {
  261. //-------------------------------------------------------
  262. // The bolt ceases to exist when its effect is done.
  263. // always return FALSE or the collision will make it
  264. // go away!
  265. return(FALSE);
  266. }
  267. //---------------------------------------------------------------------------
  268. TG_LightPtr WeaponBoltType::getLight (void)
  269. {
  270. TG_LightPtr pointLight = NULL;
  271. if (lightSource)
  272. {
  273. pointLight = (TG_LightPtr)systemHeap->Malloc(sizeof(TG_Light));
  274. pointLight->init(TG_LIGHT_POINT);
  275. pointLight->SetaRGB(lightRGB);
  276. pointLight->SetIntensity(intensity);
  277. pointLight->SetFalloffDistances(maxRadius,outRadius);
  278. }
  279. return(pointLight);
  280. }
  281. //---------------------------------------------------------------------------
  282. // class WeaponBolt
  283. //---------------------------------------------------------------------------
  284. bool WeaponBolt::isVisible (void)
  285. {
  286. //----------------------------------------------------------------------
  287. // This function checks to see if this weaponBolt is visible on screen
  288. bool isVisible = true;
  289. if (isVisible)
  290. {
  291. windowsVisible = turn;
  292. }
  293. return(true);
  294. }
  295. //---------------------------------------------------------------------------
  296. long WeaponBolt::update (void)
  297. {
  298. Stuff::Vector3D laserDirection;
  299. bool moveThisFrame = true;
  300. if (getFlag(OBJECT_FLAG_JUSTCREATED))
  301. {
  302. setFlag(OBJECT_FLAG_JUSTCREATED, false);
  303. setFlag(OBJECT_FLAG_TANGIBLE, false);
  304. hitTarget = false;
  305. moveThisFrame = false;
  306. //-------------------------------------------------------------
  307. // Update position relative to my owner
  308. GameObjectPtr myOwner = ObjectManager->getByWatchID(ownerWID);
  309. if (myOwner)
  310. {
  311. position = myOwner->getPositionFromHS(hotSpotNumber);
  312. }
  313. //-------------------------------------------------------------------
  314. // If we were just Created, play our sound Effect.
  315. if (((WeaponBoltTypePtr)getObjectType())->fireSoundFX != 0)
  316. soundSystem->playDigitalSample(((WeaponBoltTypePtr)getObjectType())->fireSoundFX, position, true);
  317. laserPosition = position;
  318. Stuff::Vector3D ownerPosition = laserPosition;
  319. Stuff::Point3D actualPosition;
  320. actualPosition.x = -laserPosition.x;
  321. actualPosition.y = laserPosition.z;
  322. actualPosition.z = laserPosition.y;
  323. GameObjectPtr target = ObjectManager->getByWatchID(targetWID);
  324. Stuff::Vector3D targetPos;
  325. targetPos.Zero();
  326. if (target)
  327. {
  328. if (!target->isMech())
  329. {
  330. setTargetPosition(target->getPositionFromHS(targetHotSpot));
  331. }
  332. else
  333. {
  334. if (targetHotSpot)
  335. setTargetPosition(target->appearance->getHitNodeLeft());
  336. else
  337. setTargetPosition(target->appearance->getHitNodeRight());
  338. }
  339. }
  340. if (targetPosition)
  341. {
  342. targetPos = *targetPosition;
  343. }
  344. else
  345. {
  346. //Somehow, we are updating a fresh weaponbolt which has not been connected.
  347. // Do not allow it to go on or we will crash for sure.
  348. return false;
  349. }
  350. laserDirection.Subtract(targetPos,ownerPosition);
  351. if (laserDirection.GetLength() != 0.0)
  352. laserDirection.Normalize(laserDirection);
  353. laserDirection *= ((WeaponBoltTypePtr)getObjectType())->projLength;
  354. //laserPosition.Add(laserPosition,laserDirection);
  355. if (((WeaponBoltTypePtr)getObjectType())->isBeam)
  356. {
  357. timeLeft = ((WeaponBoltTypePtr)getObjectType())->beamDuration;
  358. actualPosition.x = -(*targetPosition).x; //Play the beam hitting effect at the hit location
  359. actualPosition.y = (*targetPosition).z;
  360. actualPosition.z = (*targetPosition).y;
  361. }
  362. else
  363. timeLeft = 0.0f;
  364. if (gosEffect && gosEffect->IsExecuted())
  365. {
  366. Stuff::LinearMatrix4D shapeOrigin;
  367. Stuff::LinearMatrix4D localToWorld;
  368. Stuff::LinearMatrix4D localResult;
  369. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  370. shapeOrigin.BuildTranslation(actualPosition);
  371. rotation = -world_angle_between(position, *targetPosition);
  372. Stuff::UnitQuaternion effectRot;
  373. effectRot = Stuff::EulerAngles(0.0f,rotation * DEGREES_TO_RADS,0.0f);
  374. localToWorld.Multiply(gosFX::Effect_Against_Motion,effectRot);
  375. localResult.Multiply(localToWorld,shapeOrigin);
  376. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&localResult,NULL);
  377. gosEffect->Start(&info);
  378. }
  379. if (muzzleEffect && muzzleEffect->IsExecuted())
  380. {
  381. Stuff::Point3D mPosition;
  382. Stuff::LinearMatrix4D shapeOrigin;
  383. Stuff::LinearMatrix4D localToWorld;
  384. Stuff::LinearMatrix4D localResult;
  385. mPosition.x = -position.x;
  386. mPosition.y = position.z;
  387. mPosition.z = position.y;
  388. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  389. shapeOrigin.BuildTranslation(mPosition);
  390. Stuff::UnitQuaternion effectRot;
  391. if (myOwner)
  392. effectRot = Stuff::EulerAngles(0.0f, myOwner->getRotation() * DEGREES_TO_RADS,0.0f);
  393. else
  394. effectRot = Stuff::EulerAngles(0.0f, 0.0f ,0.0f);
  395. localToWorld.Multiply(gosFX::Effect_Into_Motion,effectRot);
  396. localResult.Multiply(localToWorld,shapeOrigin);
  397. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&localResult,NULL);
  398. muzzleEffect->Start(&info);
  399. }
  400. Stuff::Vector3D laserVelocity;
  401. laserVelocity.Subtract(targetPos,ownerPosition);
  402. float distance = laserVelocity.x * laserVelocity.x + laserVelocity.y * laserVelocity.y;
  403. distanceToTarget = distance;
  404. halfDistanceToTarget = distance / 2.0f;
  405. goalHeight = ((WeaponBoltTypePtr)getObjectType())->arcHeight;
  406. goalHeight *= 10.0f;
  407. }
  408. //-------------------------------------------------------------
  409. // Update position relative to my owner
  410. GameObjectPtr myOwner = ObjectManager->getByWatchID(ownerWID);
  411. if (myOwner)
  412. position = myOwner->getPositionFromHS(hotSpotNumber);
  413. bool inView = TRUE;
  414. //---------------------
  415. //Update beamDuration
  416. if (((WeaponBoltTypePtr)getObjectType())->isBeam)
  417. {
  418. timeLeft -= frameLength;
  419. if (timeLeft >= 0.0f)
  420. {
  421. gosTextureHandle = mcTextureManager->get_gosTextureHandle(mcTextureHandle);
  422. mcTextureManager->addTriangle(mcTextureHandle,MC2_ISEFFECTS|MC2_DRAWONEIN);
  423. mcTextureManager->addTriangle(mcTextureHandle,MC2_ISEFFECTS|MC2_DRAWONEIN);
  424. mcTextureManager->addTriangle(mcTextureHandle,MC2_ISEFFECTS|MC2_DRAWONEIN);
  425. mcTextureManager->addTriangle(mcTextureHandle,MC2_ISEFFECTS|MC2_DRAWONEIN);
  426. }
  427. startUV += ((WeaponBoltTypePtr)getObjectType())->uvAnimRate * frameLength;
  428. }
  429. else if (!gosEffect && !((WeaponBoltTypePtr)getObjectType())->isBeam)
  430. {
  431. mcTextureManager->addTriangle(0xffffffff,MC2_DRAWALPHA);
  432. mcTextureManager->addTriangle(0xffffffff,MC2_DRAWALPHA);
  433. mcTextureManager->addTriangle(0xffffffff,MC2_DRAWALPHA);
  434. mcTextureManager->addTriangle(0xffffffff,MC2_DRAWALPHA);
  435. }
  436. //---------------------------------------------------------------
  437. // Keep projectile flying toward target. Even if Target Moves!!
  438. Stuff::Vector3D ownerPosition = laserPosition;
  439. GameObjectPtr target = ObjectManager->getByWatchID(targetWID);
  440. Stuff::Vector3D targetPos;
  441. targetPos.Zero();
  442. if (target && (!hitTarget || ((WeaponBoltTypePtr)getObjectType())->isBeam))
  443. {
  444. if (!target->isMech())
  445. {
  446. setTargetPosition(target->getPositionFromHS(targetHotSpot));
  447. }
  448. else
  449. {
  450. if (targetHotSpot)
  451. setTargetPosition(target->appearance->getHitNodeLeft());
  452. else
  453. setTargetPosition(target->appearance->getHitNodeRight());
  454. }
  455. }
  456. if (targetPosition)
  457. {
  458. targetPos = *targetPosition;
  459. }
  460. Stuff::Vector3D laserVelocity;
  461. float velMag = ((WeaponBoltTypePtr)getObjectType())->velocity;
  462. velMag *= frameLength;
  463. laserVelocity.Subtract(targetPos,ownerPosition);
  464. float distance = laserVelocity.x * laserVelocity.x + laserVelocity.y * laserVelocity.y;
  465. //----------------------------------------------------------------------
  466. // For the first half of the distance, bring weapons up if NOT beam!!!
  467. bool isArcing = false;
  468. if (((WeaponBoltTypePtr)getObjectType())->arcEffect)
  469. {
  470. //GoalHeight is actually the velocity
  471. if ( goalHeight > 0.0f )
  472. {
  473. float accel = -((WeaponBoltTypePtr)getObjectType())->arcHeight * 10.0f;
  474. goalHeight += accel * frameLength;
  475. if (goalHeight >= 0.0f)
  476. {
  477. laserVelocity.z = goalHeight;
  478. isArcing = true;
  479. }
  480. }
  481. }
  482. //-------------------------------------------------------------------
  483. // Make the bullets go away when they get close enough to the target.
  484. // This is determined by checking the distanceToTarget. A soon as it
  485. // starts to get bigger, we have passed the target and "hit" it.
  486. if (!hitTarget)
  487. {
  488. if (!((WeaponBoltTypePtr)getObjectType())->isBeam)
  489. {
  490. float lastDistanceMoved = distanceToTarget - distance;
  491. distanceToTarget = distance;
  492. if (lastDistanceMoved >= distance)
  493. {
  494. hitTarget = TRUE;
  495. hitLeft = ((WeaponBoltTypePtr)getObjectType())->afterHitTime;
  496. if (target)
  497. {
  498. Stuff::Vector3D hotSpot = target->getPositionFromHS(targetHotSpot);
  499. if (target->isMech())
  500. {
  501. if (targetHotSpot)
  502. hotSpot = target->appearance->getHitNodeLeft();
  503. else
  504. hotSpot = target->appearance->getHitNodeRight();
  505. }
  506. if (hitEffect && hitEffect->IsExecuted())
  507. {
  508. Stuff::Point3D tPosition;
  509. Stuff::LinearMatrix4D shapeOrigin;
  510. Stuff::LinearMatrix4D localToWorld;
  511. tPosition.x = -hotSpot.x;
  512. tPosition.y = hotSpot.z;
  513. tPosition.z = hotSpot.y;
  514. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  515. shapeOrigin.BuildTranslation(tPosition);
  516. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,NULL);
  517. hitEffect->Start(&info);
  518. }
  519. if (missEffect)
  520. {
  521. missEffect->Kill();
  522. delete missEffect;
  523. missEffect = NULL;
  524. }
  525. if (waterMissEffect)
  526. {
  527. waterMissEffect->Kill();
  528. delete waterMissEffect;
  529. waterMissEffect = NULL;
  530. }
  531. //Put effect ON the spot!!
  532. laserPosition = hotSpot;
  533. }
  534. else
  535. {
  536. Stuff::Vector3D hotSpot = *targetPosition;
  537. long cellR, cellC;
  538. land->worldToCell(hotSpot,cellR, cellC);
  539. if (GameMap->getDeepWater(cellR, cellC) || GameMap->getShallowWater(cellR, cellC))
  540. {
  541. if (waterMissEffect && waterMissEffect->IsExecuted())
  542. {
  543. Stuff::Point3D tPosition;
  544. Stuff::LinearMatrix4D shapeOrigin;
  545. Stuff::LinearMatrix4D localToWorld;
  546. tPosition.x = -hotSpot.x;
  547. tPosition.y = Terrain::waterElevation;
  548. tPosition.z = hotSpot.y;
  549. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  550. shapeOrigin.BuildTranslation(tPosition);
  551. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,NULL);
  552. waterMissEffect->Start(&info);
  553. }
  554. if (missEffect)
  555. {
  556. missEffect->Kill();
  557. delete missEffect;
  558. missEffect = NULL;
  559. }
  560. }
  561. else
  562. {
  563. if (missEffect && missEffect->IsExecuted())
  564. {
  565. Stuff::Point3D tPosition;
  566. Stuff::LinearMatrix4D shapeOrigin;
  567. Stuff::LinearMatrix4D localToWorld;
  568. tPosition.x = -hotSpot.x;
  569. tPosition.y = hotSpot.z;
  570. tPosition.z = hotSpot.y;
  571. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  572. shapeOrigin.BuildTranslation(tPosition);
  573. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,NULL);
  574. missEffect->Start(&info);
  575. }
  576. if (waterMissEffect)
  577. {
  578. waterMissEffect->Kill();
  579. delete waterMissEffect;
  580. waterMissEffect = NULL;
  581. }
  582. }
  583. if (hitEffect)
  584. {
  585. hitEffect->Kill();
  586. delete hitEffect;
  587. hitEffect = NULL;
  588. }
  589. //Put effect ON the spot!!
  590. laserPosition = hotSpot;
  591. }
  592. //--------------------------------
  593. // Laser has hit target.
  594. if (target)
  595. {
  596. //Figure out angle between target and Shooter if target is BELOW shooter.
  597. // If no shooter, no bonus!!
  598. GameObjectPtr owner = ObjectManager->getByWatchID(ownerWID);
  599. if (owner)
  600. {
  601. if (target->getPosition().z < owner->getPosition().z)
  602. {
  603. Stuff::Vector3D targetPos = target->getPosition();
  604. Stuff::Vector3D ownerPos = owner->getPosition();
  605. float zDistance = ownerPos.z - targetPos.z;
  606. targetPos.z = ownerPos.z = 0.0f;
  607. Stuff::Vector3D distance;
  608. distance.Subtract(ownerPos,targetPos);
  609. float yDistance = distance.GetApproximateLength();
  610. float angle = mc2_atan2(zDistance,yDistance) * RADS_TO_DEGREES;
  611. if (RollDice(angle * BaseHeadShotElevation))
  612. {
  613. weaponShot.hitLocation = 0; //Make it a head shot!
  614. }
  615. }
  616. }
  617. if (((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum &&
  618. (((WeaponBoltTypePtr)getObjectType())->areaEffectDmg > 0.0f) &&
  619. (((WeaponBoltTypePtr)getObjectType())->areaEffectRad > 0.0f))
  620. {
  621. //This is an area effect weapon. Hit or MISS, its the same!
  622. if (hitEffect)
  623. {
  624. hitEffect->Kill();
  625. delete hitEffect;
  626. hitEffect = NULL;
  627. }
  628. if (missEffect)
  629. {
  630. missEffect->Kill();
  631. delete missEffect;
  632. missEffect = NULL;
  633. }
  634. if (waterMissEffect)
  635. {
  636. waterMissEffect->Kill();
  637. delete waterMissEffect;
  638. waterMissEffect = NULL;
  639. }
  640. //Create the explosion here. HIT or MISS, its the same one!!
  641. // Damage is done by explosion NOT by hit!
  642. ObjectManager->createExplosion(((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum,
  643. NULL,*targetPosition,
  644. ((WeaponBoltTypePtr)getObjectType())->areaEffectDmg,
  645. ((WeaponBoltTypePtr)getObjectType())->areaEffectRad);
  646. }
  647. else
  648. {
  649. if (MPlayer)
  650. {
  651. if (MPlayer->isServer())
  652. target->handleWeaponHit(&weaponShot, true);
  653. }
  654. else
  655. target->handleWeaponHit(&weaponShot);
  656. }
  657. }
  658. else if (targetPosition)
  659. {
  660. long randomCrater = 0;
  661. if (weaponShot.damage > 9)
  662. randomCrater = 3;
  663. else if (weaponShot.damage > 6)
  664. randomCrater = 2;
  665. else if (weaponShot.damage > 3)
  666. randomCrater = 1;
  667. if (missEffect) //We missed and hit land. Otherwise, we hit water, do NOT add crater
  668. craterManager->addCrater(CRATER_1+randomCrater,*targetPosition,RandomNumber(180));
  669. //if (MasterComponentList[weaponShot.masterId].getWeaponAmmoType() != WEAPON_AMMO_NONE)
  670. // energy weapons don't set off mines
  671. // Yes, they should DT, 5/30/98
  672. {
  673. long cellRow, cellCol;
  674. land->worldToCell(*targetPosition, cellRow, cellCol);
  675. if (GameMap->getMine(cellRow, cellCol) == 1)
  676. {
  677. ObjectManager->createExplosion(MINE_EXPLOSION_ID, NULL, *targetPosition, MineSplashDamage, MineSplashRange * worldUnitsPerMeter);
  678. GameMap->setMine(cellRow, cellCol, 2);
  679. }
  680. }
  681. if (((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum &&
  682. (((WeaponBoltTypePtr)getObjectType())->areaEffectDmg > 0.0f) &&
  683. (((WeaponBoltTypePtr)getObjectType())->areaEffectRad > 0.0f))
  684. {
  685. //This is an area effect weapon. Hit or MISS, its the same!
  686. if (hitEffect)
  687. {
  688. hitEffect->Kill();
  689. delete hitEffect;
  690. hitEffect = NULL;
  691. }
  692. if (missEffect)
  693. {
  694. missEffect->Kill();
  695. delete missEffect;
  696. missEffect = NULL;
  697. }
  698. if (waterMissEffect)
  699. {
  700. waterMissEffect->Kill();
  701. delete waterMissEffect;
  702. waterMissEffect = NULL;
  703. }
  704. //Create the explosion here. HIT or MISS, its the same one!!
  705. // Damage is done by explosion NOT by hit!
  706. ObjectManager->createExplosion(((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum,
  707. NULL,*targetPosition,
  708. ((WeaponBoltTypePtr)getObjectType())->areaEffectDmg,
  709. ((WeaponBoltTypePtr)getObjectType())->areaEffectRad);
  710. }
  711. }
  712. }
  713. }
  714. else
  715. {
  716. if (timeLeft < 0.0)
  717. {
  718. hitTarget = TRUE;
  719. if (target)
  720. {
  721. Stuff::Vector3D hotSpot = target->getPositionFromHS(targetHotSpot);
  722. if (target->isMech())
  723. {
  724. if (targetHotSpot)
  725. hotSpot = target->appearance->getHitNodeLeft();
  726. else
  727. hotSpot = target->appearance->getHitNodeRight();
  728. }
  729. if (hitEffect && hitEffect->IsExecuted())
  730. {
  731. Stuff::Point3D tPosition;
  732. Stuff::LinearMatrix4D shapeOrigin;
  733. Stuff::LinearMatrix4D localToWorld;
  734. tPosition.x = -hotSpot.x;
  735. tPosition.y = hotSpot.z;
  736. tPosition.z = hotSpot.y;
  737. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  738. shapeOrigin.BuildTranslation(tPosition);
  739. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,NULL);
  740. hitEffect->Start(&info);
  741. }
  742. if (missEffect)
  743. {
  744. missEffect->Kill();
  745. delete missEffect;
  746. missEffect = NULL;
  747. }
  748. if (waterMissEffect)
  749. {
  750. waterMissEffect->Kill();
  751. delete waterMissEffect;
  752. waterMissEffect = NULL;
  753. }
  754. }
  755. else
  756. {
  757. Stuff::Vector3D hotSpot = *targetPosition;
  758. long cellR, cellC;
  759. land->worldToCell(hotSpot,cellR, cellC);
  760. if (GameMap->getDeepWater(cellR, cellC) || GameMap->getShallowWater(cellR, cellC))
  761. {
  762. if (waterMissEffect && waterMissEffect->IsExecuted())
  763. {
  764. Stuff::Point3D tPosition;
  765. Stuff::LinearMatrix4D shapeOrigin;
  766. Stuff::LinearMatrix4D localToWorld;
  767. tPosition.x = -hotSpot.x;
  768. tPosition.y = Terrain::waterElevation;
  769. tPosition.z = hotSpot.y;
  770. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  771. shapeOrigin.BuildTranslation(tPosition);
  772. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,NULL);
  773. waterMissEffect->Start(&info);
  774. }
  775. if (missEffect)
  776. {
  777. missEffect->Kill();
  778. delete missEffect;
  779. missEffect = NULL;
  780. }
  781. }
  782. else
  783. {
  784. if (missEffect && missEffect->IsExecuted())
  785. {
  786. Stuff::Point3D tPosition;
  787. Stuff::LinearMatrix4D shapeOrigin;
  788. Stuff::LinearMatrix4D localToWorld;
  789. tPosition.x = -hotSpot.x;
  790. tPosition.y = hotSpot.z;
  791. tPosition.z = hotSpot.y;
  792. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  793. shapeOrigin.BuildTranslation(tPosition);
  794. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,NULL);
  795. missEffect->Start(&info);
  796. }
  797. if (waterMissEffect)
  798. {
  799. waterMissEffect->Kill();
  800. delete waterMissEffect;
  801. waterMissEffect = NULL;
  802. }
  803. }
  804. if (hitEffect)
  805. {
  806. hitEffect->Kill();
  807. delete hitEffect;
  808. hitEffect = NULL;
  809. }
  810. }
  811. //--------------------------------
  812. // Laser has hit target.
  813. if (target)
  814. {
  815. //Figure out angle between target and Shooter if target is BELOW shooter.
  816. // If no shooter, no bonus!!
  817. GameObjectPtr owner = ObjectManager->getByWatchID(ownerWID);
  818. if (owner)
  819. {
  820. if (target->getPosition().z < owner->getPosition().z)
  821. {
  822. Stuff::Vector3D targetPos = target->getPosition();
  823. Stuff::Vector3D ownerPos = owner->getPosition();
  824. float zDistance = ownerPos.z - targetPos.z;
  825. targetPos.z = ownerPos.z = 0.0f;
  826. Stuff::Vector3D distance;
  827. distance.Subtract(ownerPos,targetPos);
  828. float yDistance = distance.GetApproximateLength();
  829. float angle = mc2_atan2(zDistance,yDistance) * RADS_TO_DEGREES;
  830. if (RollDice(angle * BaseHeadShotElevation))
  831. {
  832. weaponShot.hitLocation = 0; //Make it a head shot!
  833. }
  834. }
  835. }
  836. if (((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum &&
  837. (((WeaponBoltTypePtr)getObjectType())->areaEffectDmg > 0.0f) &&
  838. (((WeaponBoltTypePtr)getObjectType())->areaEffectRad > 0.0f))
  839. {
  840. //This is an area effect weapon. Hit or MISS, its the same!
  841. if (hitEffect)
  842. {
  843. hitEffect->Kill();
  844. delete hitEffect;
  845. hitEffect = NULL;
  846. }
  847. if (missEffect)
  848. {
  849. missEffect->Kill();
  850. delete missEffect;
  851. missEffect = NULL;
  852. }
  853. if (waterMissEffect)
  854. {
  855. waterMissEffect->Kill();
  856. delete waterMissEffect;
  857. waterMissEffect = NULL;
  858. }
  859. //Create the explosion here. HIT or MISS, its the same one!!
  860. // Damage is done by explosion NOT by hit!
  861. ObjectManager->createExplosion(((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum,
  862. NULL,*targetPosition,
  863. ((WeaponBoltTypePtr)getObjectType())->areaEffectDmg,
  864. ((WeaponBoltTypePtr)getObjectType())->areaEffectRad);
  865. }
  866. else
  867. {
  868. if (MPlayer)
  869. {
  870. if (MPlayer->isServer())
  871. target->handleWeaponHit(&weaponShot, true);
  872. }
  873. else
  874. target->handleWeaponHit(&weaponShot);
  875. }
  876. }
  877. else if (targetPosition)
  878. {
  879. long randomCrater = 0;
  880. if (weaponShot.damage > 9)
  881. randomCrater = 3;
  882. else if (weaponShot.damage > 6)
  883. randomCrater = 2;
  884. else if (weaponShot.damage > 3)
  885. randomCrater = 1;
  886. if (missEffect)
  887. craterManager->addCrater(CRATER_1+randomCrater,*targetPosition,RandomNumber(180));
  888. //if (MasterComponentList[weaponShot.masterId].getWeaponAmmoType() != WEAPON_AMMO_NONE)
  889. // energy weapons don't set off mines
  890. // Yes, they should DT, 5/30/98
  891. {
  892. long cellRow, cellCol;
  893. land->worldToCell(*targetPosition, cellRow, cellCol);
  894. if (GameMap->getMine(cellRow, cellCol) == 1)
  895. {
  896. ObjectManager->createExplosion(MINE_EXPLOSION_ID, NULL, *targetPosition, MineSplashDamage, MineSplashRange * worldUnitsPerMeter);
  897. GameMap->setMine(cellRow, cellCol, 2);
  898. }
  899. }
  900. if (((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum &&
  901. (((WeaponBoltTypePtr)getObjectType())->areaEffectDmg > 0.0f) &&
  902. (((WeaponBoltTypePtr)getObjectType())->areaEffectRad > 0.0f))
  903. {
  904. //This is an area effect weapon. Hit or MISS, its the same!
  905. if (hitEffect)
  906. {
  907. hitEffect->Kill();
  908. delete hitEffect;
  909. hitEffect = NULL;
  910. }
  911. if (missEffect)
  912. {
  913. missEffect->Kill();
  914. delete missEffect;
  915. missEffect = NULL;
  916. }
  917. if (waterMissEffect)
  918. {
  919. waterMissEffect->Kill();
  920. delete waterMissEffect;
  921. waterMissEffect = NULL;
  922. }
  923. //Create the explosion here. HIT or MISS, its the same one!!
  924. // Damage is done by explosion NOT by hit!
  925. ObjectManager->createExplosion(((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum,
  926. NULL,*targetPosition,
  927. ((WeaponBoltTypePtr)getObjectType())->areaEffectDmg,
  928. ((WeaponBoltTypePtr)getObjectType())->areaEffectRad);
  929. }
  930. }
  931. }
  932. }
  933. }
  934. //Actually move the effect toward the target
  935. // But only AFTER the first Start for the effect
  936. // Otherwise, weapon moves one time of flight distant
  937. if (!hitTarget)
  938. {
  939. float tmpZ = laserVelocity.z;
  940. if (isArcing)
  941. {
  942. laserVelocity.z = 0.0f;
  943. tmpZ *= frameLength;
  944. }
  945. if (laserVelocity.GetLength() != 0.0)
  946. laserVelocity.Normalize(laserVelocity);
  947. if (moveThisFrame)
  948. {
  949. laserVelocity *= velMag;
  950. if (isArcing)
  951. laserVelocity.z = tmpZ;
  952. }
  953. laserPosition += laserVelocity;
  954. laserDirection.Negate(laserVelocity);
  955. if (laserDirection.GetLength() != 0.0)
  956. laserDirection.Normalize(laserDirection);
  957. }
  958. //------------------------------------------------
  959. // Update GOSFX
  960. if (gosEffect && gosEffect->IsExecuted())
  961. {
  962. Stuff::Point3D actualPosition;
  963. if (((WeaponBoltTypePtr)getObjectType())->isBeam)
  964. {
  965. actualPosition.x = -(*targetPosition).x; //Play the beam hitting effect at the hit location
  966. actualPosition.y = (*targetPosition).z;
  967. actualPosition.z = (*targetPosition).y;
  968. }
  969. else
  970. {
  971. actualPosition.x = -laserPosition.x;
  972. actualPosition.y = laserPosition.z;
  973. actualPosition.z = laserPosition.y;
  974. }
  975. Stuff::LinearMatrix4D shapeOrigin;
  976. Stuff::LinearMatrix4D localToWorld;
  977. Stuff::LinearMatrix4D localResult;
  978. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  979. shapeOrigin.BuildTranslation(actualPosition);
  980. rotation = -world_angle_between(laserPosition, *targetPosition);
  981. Stuff::UnitQuaternion effectRot;
  982. effectRot = Stuff::EulerAngles(0.0f,rotation * DEGREES_TO_RADS,0.0f);
  983. localToWorld.Multiply(gosFX::Effect_Against_Motion,effectRot);
  984. localResult.Multiply(localToWorld,shapeOrigin);
  985. Stuff::OBB boundingBox;
  986. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&localResult,&boundingBox);
  987. bool result = gosEffect->Execute(&info);
  988. if (!result)
  989. {
  990. gosEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  991. delete gosEffect;
  992. gosEffect = NULL;
  993. }
  994. }
  995. if (muzzleEffect && muzzleEffect->IsExecuted())
  996. {
  997. Stuff::Point3D mPosition;
  998. mPosition.x = -position.x;
  999. mPosition.y = position.z;
  1000. mPosition.z = position.y;
  1001. Stuff::LinearMatrix4D shapeOrigin;
  1002. Stuff::LinearMatrix4D localToWorld;
  1003. Stuff::LinearMatrix4D localResult;
  1004. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1005. shapeOrigin.BuildTranslation(mPosition);
  1006. Stuff::UnitQuaternion effectRot;
  1007. if (myOwner)
  1008. effectRot = Stuff::EulerAngles(0.0f, myOwner->getRotation() * DEGREES_TO_RADS,0.0f);
  1009. else
  1010. effectRot = Stuff::EulerAngles(0.0f, 0.0f ,0.0f);
  1011. localToWorld.Multiply(gosFX::Effect_Into_Motion,effectRot);
  1012. localResult.Multiply(localToWorld,shapeOrigin);
  1013. Stuff::OBB boundingBox;
  1014. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&localResult,&boundingBox);
  1015. bool result = muzzleEffect->Execute(&info);
  1016. if (!result)
  1017. {
  1018. muzzleEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  1019. delete muzzleEffect;
  1020. muzzleEffect = NULL;
  1021. }
  1022. }
  1023. if (!hitTarget && !((WeaponBoltTypePtr)getObjectType())->isBeam)
  1024. {
  1025. //--------------------------------------------------------------------------------------
  1026. // LaserPosition is front of projectile, laserVertices[0] is top vertex of bulge.
  1027. // LaserVertices[1] is bottom vertex of bulge, laservertices[2] is back of projectile,
  1028. // and laservertices[3] is the middle of the bulge.
  1029. Stuff::Vector3D lDir(laserDirection);
  1030. lDir *= ((WeaponBoltTypePtr)getObjectType())->bulgeLength;
  1031. laserVertices[0].Add(laserPosition,lDir);
  1032. laserVertices[1] = laserVertices[0];
  1033. laserVertices[3] = laserVertices[0];
  1034. laserVertices[1].x += laserDirection.y * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1035. laserVertices[1].y -= laserDirection.x * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1036. laserVertices[0].x -= laserDirection.y * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1037. laserVertices[0].y += laserDirection.x * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1038. laserDirection *= ((WeaponBoltTypePtr)getObjectType())->projLength;
  1039. laserVertices[2].Add(laserPosition,laserDirection);
  1040. if (((WeaponBoltTypePtr)getObjectType())->lightSource && !pointLight && (lightId != -1))
  1041. {
  1042. pointLight = ((WeaponBoltTypePtr)getObjectType())->getLight();
  1043. lightId = eye->addWorldLight(pointLight);
  1044. if (lightId == -1)
  1045. {
  1046. //NO LIGHT ALLOWED! TOO Many in World!
  1047. // LightId is now -1 which will cause this to NEVER make a light!
  1048. systemHeap->Free(pointLight);
  1049. pointLight = NULL;
  1050. }
  1051. }
  1052. }
  1053. else if (!hitTarget && ((WeaponBoltTypePtr)getObjectType())->isBeam)
  1054. {
  1055. //------------------------------------------------
  1056. // For beam we need 4 vertices for the two faces.
  1057. laserVertices[0] = position;
  1058. laserVertices[1] = position;
  1059. laserSide[0] = position;
  1060. laserSide[1] = position;
  1061. laserVertices[0].x -= laserDirection.y * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1062. laserVertices[0].y += laserDirection.x * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1063. laserVertices[1].x += laserDirection.y * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1064. laserVertices[1].y -= laserDirection.x * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1065. laserSide[0].z += ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1066. laserSide[1].z -= ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1067. hsPos = *targetPosition;
  1068. if (target)
  1069. {
  1070. if (!target->isMech())
  1071. {
  1072. hsPos = target->getPositionFromHS(targetHotSpot);
  1073. }
  1074. else
  1075. {
  1076. if (targetHotSpot)
  1077. hsPos = target->appearance->getHitNodeLeft();
  1078. else
  1079. hsPos = target->appearance->getHitNodeRight();
  1080. }
  1081. }
  1082. //-------------------------------------------
  1083. // Wiggle the hotspot.
  1084. float beamWiggle = ((WeaponBoltTypePtr)getObjectType())->beamWiggle;
  1085. Stuff::Vector3D offset(beamWiggle,beamWiggle,beamWiggle);
  1086. offset.x = RandomNumber(offset.x * 2) - offset.x;
  1087. offset.y = RandomNumber(offset.y * 2) - offset.y;
  1088. offset.z = RandomNumber(offset.z * 2) - offset.z;
  1089. hsPos += offset;
  1090. laserVertices[2] = hsPos;
  1091. laserVertices[3] = hsPos;
  1092. laserSide[2] = hsPos;
  1093. laserSide[3] = hsPos;
  1094. laserVertices[2].x -= laserDirection.y * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1095. laserVertices[2].y += laserDirection.x * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1096. laserVertices[3].x += laserDirection.y * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1097. laserVertices[3].y -= laserDirection.x * ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1098. laserSide[2].z += ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1099. laserSide[3].z -= ((WeaponBoltTypePtr)getObjectType())->bulgeWidth;
  1100. }
  1101. if (pointLight)
  1102. {
  1103. Stuff::Point3D ourPosition;
  1104. ourPosition.x = -laserPosition.x;
  1105. ourPosition.y = laserPosition.z;
  1106. ourPosition.z = laserPosition.y;
  1107. pointLight->direction = ourPosition;
  1108. Stuff::LinearMatrix4D lightToWorldMatrix;
  1109. lightToWorldMatrix.BuildTranslation(ourPosition);
  1110. lightToWorldMatrix.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1111. pointLight->SetLightToWorld(&lightToWorldMatrix);
  1112. pointLight->SetPosition(&laserPosition);
  1113. }
  1114. if (hitTarget)
  1115. {
  1116. hitLeft -= frameLength;
  1117. if (gosEffect && (hitLeft < 0.0f))
  1118. {
  1119. gosEffect->Kill();
  1120. delete gosEffect;
  1121. gosEffect = NULL;
  1122. //Need to kill the light source here too!
  1123. if (pointLight)
  1124. {
  1125. eye->removeWorldLight(lightId,pointLight);
  1126. systemHeap->Free(pointLight);
  1127. pointLight = NULL;
  1128. }
  1129. }
  1130. if (hitEffect && hitEffect->IsExecuted())
  1131. {
  1132. Stuff::Vector3D hotSpot = *targetPosition;
  1133. if (target)
  1134. {
  1135. if (!target->isMech())
  1136. {
  1137. hotSpot = target->getPositionFromHS(targetHotSpot);
  1138. }
  1139. else
  1140. {
  1141. if (targetHotSpot)
  1142. hotSpot = target->appearance->getHitNodeLeft();
  1143. else
  1144. hotSpot = target->appearance->getHitNodeRight();
  1145. }
  1146. }
  1147. Stuff::Point3D tPosition;
  1148. tPosition.x = -hotSpot.x;
  1149. tPosition.y = hotSpot.z;
  1150. tPosition.z = hotSpot.y;
  1151. Stuff::LinearMatrix4D shapeOrigin;
  1152. Stuff::LinearMatrix4D localToWorld;
  1153. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1154. shapeOrigin.BuildTranslation(tPosition);
  1155. Stuff::OBB boundingBox;
  1156. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,&boundingBox);
  1157. bool result = hitEffect->Execute(&info);
  1158. if (!result)
  1159. {
  1160. if (hitEffect)
  1161. {
  1162. hitEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  1163. delete hitEffect;
  1164. hitEffect = NULL;
  1165. }
  1166. inView = FALSE;
  1167. if (pointLight)
  1168. {
  1169. eye->removeWorldLight(lightId,pointLight);
  1170. systemHeap->Free(pointLight);
  1171. pointLight = NULL;
  1172. }
  1173. //Kill later to make Steve Happy!!
  1174. if (muzzleEffect)
  1175. {
  1176. muzzleEffect->Kill();
  1177. delete muzzleEffect;
  1178. muzzleEffect = NULL;
  1179. }
  1180. }
  1181. }
  1182. else
  1183. {
  1184. if (hitEffect)
  1185. {
  1186. hitEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  1187. delete hitEffect;
  1188. hitEffect = NULL;
  1189. }
  1190. if (pointLight)
  1191. {
  1192. eye->removeWorldLight(lightId,pointLight);
  1193. systemHeap->Free(pointLight);
  1194. pointLight = NULL;
  1195. }
  1196. }
  1197. if (missEffect && missEffect->IsExecuted())
  1198. {
  1199. Stuff::Vector3D hotSpot = *targetPosition;
  1200. if (target)
  1201. {
  1202. if (!target->isMech())
  1203. {
  1204. hotSpot = target->getPositionFromHS(targetHotSpot);
  1205. }
  1206. else
  1207. {
  1208. if (targetHotSpot)
  1209. hotSpot = target->appearance->getHitNodeLeft();
  1210. else
  1211. hotSpot = target->appearance->getHitNodeRight();
  1212. }
  1213. }
  1214. Stuff::Point3D tPosition;
  1215. tPosition.x = -hotSpot.x;
  1216. tPosition.y = hotSpot.z;
  1217. tPosition.z = hotSpot.y;
  1218. Stuff::LinearMatrix4D shapeOrigin;
  1219. Stuff::LinearMatrix4D localToWorld;
  1220. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1221. shapeOrigin.BuildTranslation(tPosition);
  1222. Stuff::OBB boundingBox;
  1223. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,&boundingBox);
  1224. bool result = missEffect->Execute(&info);
  1225. if (!result)
  1226. {
  1227. if (missEffect)
  1228. {
  1229. missEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  1230. delete missEffect;
  1231. missEffect = NULL;
  1232. }
  1233. //Kill later to make Steve Happy!!
  1234. if (muzzleEffect)
  1235. {
  1236. muzzleEffect->Kill();
  1237. delete muzzleEffect;
  1238. muzzleEffect = NULL;
  1239. }
  1240. inView = FALSE;
  1241. if (pointLight)
  1242. {
  1243. eye->removeWorldLight(lightId,pointLight);
  1244. systemHeap->Free(pointLight);
  1245. pointLight = NULL;
  1246. }
  1247. }
  1248. }
  1249. else
  1250. {
  1251. if (missEffect)
  1252. {
  1253. missEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  1254. delete missEffect;
  1255. missEffect = NULL;
  1256. }
  1257. if (pointLight)
  1258. {
  1259. eye->removeWorldLight(lightId,pointLight);
  1260. systemHeap->Free(pointLight);
  1261. pointLight = NULL;
  1262. }
  1263. }
  1264. if (waterMissEffect && waterMissEffect->IsExecuted())
  1265. {
  1266. Stuff::Vector3D hotSpot = *targetPosition;
  1267. if (target)
  1268. {
  1269. if (!target->isMech())
  1270. {
  1271. hotSpot = target->getPositionFromHS(targetHotSpot);
  1272. }
  1273. else
  1274. {
  1275. if (targetHotSpot)
  1276. hotSpot = target->appearance->getHitNodeLeft();
  1277. else
  1278. hotSpot = target->appearance->getHitNodeRight();
  1279. }
  1280. }
  1281. Stuff::Point3D tPosition;
  1282. tPosition.x = -hotSpot.x;
  1283. tPosition.y = Terrain::waterElevation;
  1284. tPosition.z = hotSpot.y;
  1285. Stuff::LinearMatrix4D shapeOrigin;
  1286. Stuff::LinearMatrix4D localToWorld;
  1287. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1288. shapeOrigin.BuildTranslation(tPosition);
  1289. Stuff::OBB boundingBox;
  1290. gosFX::Effect::ExecuteInfo info((Stuff::Time)scenarioTime,&shapeOrigin,&boundingBox);
  1291. bool result = waterMissEffect->Execute(&info);
  1292. if (!result)
  1293. {
  1294. if (waterMissEffect)
  1295. {
  1296. waterMissEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  1297. delete waterMissEffect;
  1298. waterMissEffect = NULL;
  1299. }
  1300. //Kill later to make Steve Happy!!
  1301. if (muzzleEffect)
  1302. {
  1303. muzzleEffect->Kill();
  1304. delete muzzleEffect;
  1305. muzzleEffect = NULL;
  1306. }
  1307. inView = FALSE;
  1308. if (pointLight)
  1309. {
  1310. eye->removeWorldLight(lightId,pointLight);
  1311. systemHeap->Free(pointLight);
  1312. pointLight = NULL;
  1313. }
  1314. }
  1315. }
  1316. else
  1317. {
  1318. if (waterMissEffect)
  1319. {
  1320. waterMissEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  1321. delete waterMissEffect;
  1322. waterMissEffect = NULL;
  1323. }
  1324. if (pointLight)
  1325. {
  1326. eye->removeWorldLight(lightId,pointLight);
  1327. systemHeap->Free(pointLight);
  1328. pointLight = NULL;
  1329. }
  1330. }
  1331. if (!waterMissEffect && !hitEffect && !missEffect && !gosEffect)
  1332. inView = false;
  1333. }
  1334. return (inView);
  1335. }
  1336. //---------------------------------------------------------------------------
  1337. void WeaponBolt::render (void)
  1338. {
  1339. if (!getFlag(OBJECT_FLAG_JUSTCREATED) && !isTargeted()) //can we be seen by the enemy?
  1340. {
  1341. gosFX::Effect::DrawInfo drawInfo;
  1342. drawInfo.m_clipper = theClipper;
  1343. MidLevelRenderer::MLRState mlrState;
  1344. //mlrState.SetBackFaceOn();
  1345. mlrState.SetDitherOn();
  1346. mlrState.SetTextureCorrectionOn();
  1347. mlrState.SetZBufferCompareOn();
  1348. mlrState.SetZBufferWriteOn();
  1349. //mlrState.SetFilterMode(MidLevelRenderer::MLRState::BiLinearFilterMode);
  1350. //mlrState.SetAlphaMode(MidLevelRenderer::MLRState::AlphaInvAlphaMode);
  1351. drawInfo.m_state = mlrState;
  1352. drawInfo.m_clippingFlags = 0x0;
  1353. if (!gosEffect && !hitTarget && !((WeaponBoltTypePtr)getObjectType())->isBeam)
  1354. {
  1355. //---------------------------
  1356. // Render the polygons here.
  1357. gos_VERTEX lq1Vertices[3], lq2Vertices[3], lq3Vertices[3], lq4Vertices[3];
  1358. Stuff::Vector4D screenPos;
  1359. DWORD alphaMode = ((WeaponBoltTypePtr)getObjectType())->boltAlpha;
  1360. alphaMode <<= 24;
  1361. DWORD edgeMode = ((WeaponBoltTypePtr)getObjectType())->edgeAlpha;
  1362. edgeMode <<= 24;
  1363. eye->projectZ(laserPosition,screenPos);
  1364. lq1Vertices[0].x = screenPos.x;
  1365. lq1Vertices[0].y = screenPos.y;
  1366. lq1Vertices[0].z = 0.1f;
  1367. lq1Vertices[0].rhw = screenPos.w;
  1368. lq1Vertices[0].u = 0.0f;
  1369. lq1Vertices[0].v = 0.0f;
  1370. lq1Vertices[0].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->frontRGB;
  1371. lq2Vertices[0].x = screenPos.x;
  1372. lq2Vertices[0].y = screenPos.y;
  1373. lq2Vertices[0].z = 0.1f;
  1374. lq2Vertices[0].rhw = screenPos.w;
  1375. lq2Vertices[0].u = 0.0f;
  1376. lq2Vertices[0].v = 0.0f;
  1377. lq2Vertices[0].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->frontRGB;
  1378. eye->projectZ(laserVertices[0],screenPos);
  1379. lq1Vertices[1].x = screenPos.x;
  1380. lq1Vertices[1].y = screenPos.y;
  1381. lq1Vertices[1].z = 0.1f;
  1382. lq1Vertices[1].rhw = screenPos.w;
  1383. lq1Vertices[1].u = 0.0f;
  1384. lq1Vertices[1].v = 0.0f;
  1385. lq1Vertices[1].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1386. lq3Vertices[1].x = screenPos.x;
  1387. lq3Vertices[1].y = screenPos.y;
  1388. lq3Vertices[1].z = 0.1f;
  1389. lq3Vertices[1].rhw = screenPos.w;
  1390. lq3Vertices[1].u = 0.0f;
  1391. lq3Vertices[1].v = 0.0f;
  1392. lq3Vertices[1].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1393. eye->projectZ(laserVertices[3],screenPos);
  1394. lq1Vertices[2].x = screenPos.x;
  1395. lq1Vertices[2].y = screenPos.y;
  1396. lq1Vertices[2].z = 0.1f;
  1397. lq1Vertices[2].rhw = screenPos.w;
  1398. lq1Vertices[2].u = 0.0f;
  1399. lq1Vertices[2].v = 0.0f;
  1400. lq1Vertices[2].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1401. lq2Vertices[2].x = screenPos.x;
  1402. lq2Vertices[2].y = screenPos.y;
  1403. lq2Vertices[2].z = 0.1f;
  1404. lq2Vertices[2].rhw = screenPos.w;
  1405. lq2Vertices[2].u = 0.0f;
  1406. lq2Vertices[2].v = 0.0f;
  1407. lq2Vertices[2].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1408. lq3Vertices[0].x = screenPos.x;
  1409. lq3Vertices[0].y = screenPos.y;
  1410. lq3Vertices[0].z = 0.1f;
  1411. lq3Vertices[0].rhw = screenPos.w;
  1412. lq3Vertices[0].u = 0.0f;
  1413. lq3Vertices[0].v = 0.0f;
  1414. lq3Vertices[0].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1415. lq4Vertices[0].x = screenPos.x;
  1416. lq4Vertices[0].y = screenPos.y;
  1417. lq4Vertices[0].z = 0.1f;
  1418. lq4Vertices[0].rhw = screenPos.w;
  1419. lq4Vertices[0].u = 0.0f;
  1420. lq4Vertices[0].v = 0.0f;
  1421. lq4Vertices[0].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1422. eye->projectZ(laserVertices[2],screenPos);
  1423. lq3Vertices[2].x = screenPos.x;
  1424. lq3Vertices[2].y = screenPos.y;
  1425. lq3Vertices[2].z = 0.1f;
  1426. lq3Vertices[2].rhw = screenPos.w;
  1427. lq3Vertices[2].u = 0.0f;
  1428. lq3Vertices[2].v = 0.0f;
  1429. lq3Vertices[2].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->backRGB;
  1430. lq4Vertices[2].x = screenPos.x;
  1431. lq4Vertices[2].y = screenPos.y;
  1432. lq4Vertices[2].z = 0.1f;
  1433. lq4Vertices[2].rhw = screenPos.w;
  1434. lq4Vertices[2].u = 0.0f;
  1435. lq4Vertices[2].v = 0.0f;
  1436. lq4Vertices[2].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->backRGB;
  1437. eye->projectZ(laserVertices[1],screenPos);
  1438. lq2Vertices[1].x = screenPos.x;
  1439. lq2Vertices[1].y = screenPos.y;
  1440. lq2Vertices[1].z = 0.1f;
  1441. lq2Vertices[1].rhw = screenPos.w;
  1442. lq2Vertices[1].u = 0.0f;
  1443. lq2Vertices[1].v = 0.0f;
  1444. lq2Vertices[1].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1445. lq4Vertices[1].x = screenPos.x;
  1446. lq4Vertices[1].y = screenPos.y;
  1447. lq4Vertices[1].z = 0.1f;
  1448. lq4Vertices[1].rhw = screenPos.w;
  1449. lq4Vertices[1].u = 0.0f;
  1450. lq4Vertices[1].v = 0.0f;
  1451. lq4Vertices[1].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1452. if (((lq1Vertices[0].x > eye->viewMulX) ||
  1453. (lq1Vertices[0].y > eye->viewMulY) ||
  1454. (lq1Vertices[0].x < eye->viewAddX) ||
  1455. (lq1Vertices[0].y < eye->viewAddY) ||
  1456. (lq1Vertices[1].x > eye->viewMulX) ||
  1457. (lq1Vertices[1].y > eye->viewMulY) ||
  1458. (lq1Vertices[1].x < eye->viewAddX) ||
  1459. (lq1Vertices[1].y < eye->viewAddY) ||
  1460. (lq1Vertices[2].x > eye->viewMulX) ||
  1461. (lq1Vertices[2].y > eye->viewMulY) ||
  1462. (lq1Vertices[2].x < eye->viewAddX) ||
  1463. (lq1Vertices[2].y < eye->viewAddY)))
  1464. {
  1465. }
  1466. else
  1467. {
  1468. if (drawOldWay)
  1469. {
  1470. //------------------------
  1471. // Draw em!
  1472. gos_SetRenderState( gos_State_Texture, 0 );
  1473. //--------------------------------
  1474. //Set States for Software Renderer
  1475. if (Environment.Renderer == 3)
  1476. {
  1477. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero);
  1478. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
  1479. gos_SetRenderState( gos_State_MonoEnable, 1);
  1480. gos_SetRenderState( gos_State_Perspective, 0);
  1481. gos_SetRenderState( gos_State_Clipping, 0);
  1482. gos_SetRenderState( gos_State_AlphaTest, 0);
  1483. gos_SetRenderState( gos_State_Specular, 0);
  1484. gos_SetRenderState( gos_State_Dither, 0);
  1485. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulateAlpha);
  1486. gos_SetRenderState( gos_State_Filter, gos_FilterNone);
  1487. gos_SetRenderState( gos_State_TextureAddress, gos_TextureClamp );
  1488. }
  1489. //--------------------------------
  1490. //Set States for Hardware Renderer
  1491. else
  1492. {
  1493. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero);
  1494. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
  1495. gos_SetRenderState( gos_State_MonoEnable, 0);
  1496. gos_SetRenderState( gos_State_Perspective, 1);
  1497. gos_SetRenderState( gos_State_Clipping, 2);
  1498. gos_SetRenderState( gos_State_AlphaTest, 0);
  1499. gos_SetRenderState( gos_State_Specular, 0);
  1500. gos_SetRenderState( gos_State_Dither, 1);
  1501. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulateAlpha);
  1502. gos_SetRenderState( gos_State_Filter, gos_FilterBiLinear);
  1503. gos_SetRenderState( gos_State_TextureAddress, gos_TextureClamp );
  1504. }
  1505. gos_DrawTriangles(lq1Vertices,3);
  1506. }
  1507. else
  1508. {
  1509. mcTextureManager->addVertices(0xffffffff,lq1Vertices,MC2_DRAWALPHA);
  1510. }
  1511. }
  1512. if (((lq2Vertices[0].x > eye->viewMulX) ||
  1513. (lq2Vertices[0].y > eye->viewMulY) ||
  1514. (lq2Vertices[0].x < eye->viewAddX) ||
  1515. (lq2Vertices[0].y < eye->viewAddY) ||
  1516. (lq2Vertices[1].x > eye->viewMulX) ||
  1517. (lq2Vertices[1].y > eye->viewMulY) ||
  1518. (lq2Vertices[1].x < eye->viewAddX) ||
  1519. (lq2Vertices[1].y < eye->viewAddY) ||
  1520. (lq2Vertices[2].x > eye->viewMulX) ||
  1521. (lq2Vertices[2].y > eye->viewMulY) ||
  1522. (lq2Vertices[2].x < eye->viewAddX) ||
  1523. (lq2Vertices[2].y < eye->viewAddY)))
  1524. {
  1525. }
  1526. else
  1527. {
  1528. if (drawOldWay)
  1529. {
  1530. gos_DrawTriangles(lq2Vertices,3);
  1531. }
  1532. else
  1533. {
  1534. mcTextureManager->addVertices(0xffffffff,lq2Vertices,MC2_DRAWALPHA);
  1535. }
  1536. }
  1537. if (((lq3Vertices[0].x > eye->viewMulX) ||
  1538. (lq3Vertices[0].y > eye->viewMulY) ||
  1539. (lq3Vertices[0].x < eye->viewAddX) ||
  1540. (lq3Vertices[0].y < eye->viewAddY) ||
  1541. (lq3Vertices[1].x > eye->viewMulX) ||
  1542. (lq3Vertices[1].y > eye->viewMulY) ||
  1543. (lq3Vertices[1].x < eye->viewAddX) ||
  1544. (lq3Vertices[1].y < eye->viewAddY) ||
  1545. (lq3Vertices[2].x > eye->viewMulX) ||
  1546. (lq3Vertices[2].y > eye->viewMulY) ||
  1547. (lq3Vertices[2].x < eye->viewAddX) ||
  1548. (lq3Vertices[2].y < eye->viewAddY)))
  1549. {
  1550. }
  1551. else
  1552. {
  1553. if (drawOldWay)
  1554. {
  1555. gos_DrawTriangles(lq3Vertices,3);
  1556. }
  1557. else
  1558. {
  1559. mcTextureManager->addVertices(0xffffffff,lq3Vertices,MC2_DRAWALPHA);
  1560. }
  1561. }
  1562. if (((lq4Vertices[0].x > eye->viewMulX) ||
  1563. (lq4Vertices[0].y > eye->viewMulY) ||
  1564. (lq4Vertices[0].x < eye->viewAddX) ||
  1565. (lq4Vertices[0].y < eye->viewAddY) ||
  1566. (lq4Vertices[1].x > eye->viewMulX) ||
  1567. (lq4Vertices[1].y > eye->viewMulY) ||
  1568. (lq4Vertices[1].x < eye->viewAddX) ||
  1569. (lq4Vertices[1].y < eye->viewAddY) ||
  1570. (lq4Vertices[2].x > eye->viewMulX) ||
  1571. (lq4Vertices[2].y > eye->viewMulY) ||
  1572. (lq4Vertices[2].x < eye->viewAddX) ||
  1573. (lq4Vertices[2].y < eye->viewAddY)))
  1574. {
  1575. }
  1576. else
  1577. {
  1578. if (drawOldWay)
  1579. {
  1580. gos_DrawTriangles(lq4Vertices,3);
  1581. }
  1582. else
  1583. {
  1584. mcTextureManager->addVertices(0xffffffff,lq4Vertices,MC2_DRAWALPHA);
  1585. }
  1586. }
  1587. }
  1588. else if (!hitTarget && ((WeaponBoltTypePtr)getObjectType())->isBeam)
  1589. {
  1590. //---------------------------
  1591. // Render the polygons here.
  1592. gos_VERTEX lq1Vertices[3], lq2Vertices[3], lq3Vertices[3], lq4Vertices[3];
  1593. Stuff::Vector4D screenPos;
  1594. DWORD alphaMode = ((WeaponBoltTypePtr)getObjectType())->boltAlpha;
  1595. alphaMode <<= 24;
  1596. DWORD edgeMode = ((WeaponBoltTypePtr)getObjectType())->edgeAlpha;
  1597. edgeMode <<= 24;
  1598. Stuff::Point3D actualPosition;
  1599. Stuff::Vector3D hotSpot = *targetPosition;
  1600. GameObjectPtr target = ObjectManager->getByWatchID(targetWID);
  1601. if (target)
  1602. {
  1603. if (!target->isMech())
  1604. {
  1605. hotSpot = target->getPositionFromHS(targetHotSpot);
  1606. }
  1607. else
  1608. {
  1609. if (targetHotSpot)
  1610. hotSpot = target->appearance->getHitNodeLeft();
  1611. else
  1612. hotSpot = target->appearance->getHitNodeRight();
  1613. }
  1614. }
  1615. Stuff::Vector3D length;
  1616. length.Subtract(hotSpot,position);
  1617. float dist = length.GetApproximateLength();
  1618. float realUVRepeat = ((WeaponBoltTypePtr)getObjectType())->uvRepeat * dist / ((WeaponBoltTypePtr)getObjectType())->unitLength;
  1619. eye->projectZ(laserVertices[0],screenPos);
  1620. lq1Vertices[0].x = screenPos.x;
  1621. lq1Vertices[0].y = screenPos.y;
  1622. lq1Vertices[0].z = screenPos.z;
  1623. lq1Vertices[0].rhw = screenPos.w;
  1624. lq1Vertices[0].u = startUV;
  1625. lq1Vertices[0].v = 0.0f;
  1626. lq1Vertices[0].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1627. lq2Vertices[0].x = screenPos.x;
  1628. lq2Vertices[0].y = screenPos.y;
  1629. lq2Vertices[0].z = screenPos.z;
  1630. lq2Vertices[0].rhw = screenPos.w;
  1631. lq2Vertices[0].u = startUV;
  1632. lq2Vertices[0].v = 0.0f;
  1633. lq2Vertices[0].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1634. eye->projectZ(laserVertices[1],screenPos);
  1635. lq2Vertices[1].x = screenPos.x;
  1636. lq2Vertices[1].y = screenPos.y;
  1637. lq2Vertices[1].z = screenPos.z;
  1638. lq2Vertices[1].rhw = screenPos.w;
  1639. lq2Vertices[1].u = startUV;
  1640. lq2Vertices[1].v = 0.999999f;
  1641. lq2Vertices[1].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1642. eye->projectZ(laserVertices[2],screenPos);
  1643. lq1Vertices[1].x = screenPos.x;
  1644. lq1Vertices[1].y = screenPos.y;
  1645. lq1Vertices[1].z = screenPos.z;
  1646. lq1Vertices[1].rhw = screenPos.w;
  1647. lq1Vertices[1].u = startUV + realUVRepeat;
  1648. lq1Vertices[1].v = 0.0f;
  1649. lq1Vertices[1].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1650. eye->projectZ(laserVertices[3],screenPos);
  1651. lq1Vertices[2].x = screenPos.x;
  1652. lq1Vertices[2].y = screenPos.y;
  1653. lq1Vertices[2].z = screenPos.z;
  1654. lq1Vertices[2].rhw = screenPos.w;
  1655. lq1Vertices[2].u = startUV + realUVRepeat;
  1656. lq1Vertices[2].v = 0.999999f;
  1657. lq1Vertices[2].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1658. lq2Vertices[2].x = screenPos.x;
  1659. lq2Vertices[2].y = screenPos.y;
  1660. lq2Vertices[2].z = screenPos.z;
  1661. lq2Vertices[2].rhw = screenPos.w;
  1662. lq2Vertices[2].u = startUV + realUVRepeat;
  1663. lq2Vertices[2].v = 0.999999f;
  1664. lq2Vertices[2].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1665. eye->projectZ(laserSide[0],screenPos);
  1666. lq3Vertices[0].x = screenPos.x;
  1667. lq3Vertices[0].y = screenPos.y;
  1668. lq3Vertices[0].z = screenPos.z;
  1669. lq3Vertices[0].rhw = screenPos.w;
  1670. lq3Vertices[0].u = startUV;
  1671. lq3Vertices[0].v = 0.0f;
  1672. lq3Vertices[0].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1673. lq4Vertices[0].x = screenPos.x;
  1674. lq4Vertices[0].y = screenPos.y;
  1675. lq4Vertices[0].z = screenPos.z;
  1676. lq4Vertices[0].rhw = screenPos.w;
  1677. lq4Vertices[0].u = startUV;
  1678. lq4Vertices[0].v = 0.0f;
  1679. lq4Vertices[0].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1680. eye->projectZ(laserSide[1],screenPos);
  1681. lq4Vertices[1].x = screenPos.x;
  1682. lq4Vertices[1].y = screenPos.y;
  1683. lq4Vertices[1].z = screenPos.z;
  1684. lq4Vertices[1].rhw = screenPos.w;
  1685. lq4Vertices[1].u = startUV;
  1686. lq4Vertices[1].v = 0.999999f;
  1687. lq4Vertices[1].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->midEdgeRGB;
  1688. eye->projectZ(laserSide[2],screenPos);
  1689. lq3Vertices[1].x = screenPos.x;
  1690. lq3Vertices[1].y = screenPos.y;
  1691. lq3Vertices[1].z = screenPos.z;
  1692. lq3Vertices[1].rhw = screenPos.w;
  1693. lq3Vertices[1].u = startUV + realUVRepeat;
  1694. lq3Vertices[1].v = 0.0f;
  1695. lq3Vertices[1].argb = edgeMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1696. eye->projectZ(laserSide[3],screenPos);
  1697. lq3Vertices[2].x = screenPos.x;
  1698. lq3Vertices[2].y = screenPos.y;
  1699. lq3Vertices[2].z = screenPos.z;
  1700. lq3Vertices[2].rhw = screenPos.w;
  1701. lq3Vertices[2].u = startUV + realUVRepeat;
  1702. lq3Vertices[2].v = 0.999999f;
  1703. lq3Vertices[2].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1704. lq4Vertices[2].x = screenPos.x;
  1705. lq4Vertices[2].y = screenPos.y;
  1706. lq4Vertices[2].z = screenPos.z;
  1707. lq4Vertices[2].rhw = screenPos.w;
  1708. lq4Vertices[2].u = startUV + realUVRepeat;
  1709. lq4Vertices[2].v = 0.999999f;
  1710. lq4Vertices[2].argb = alphaMode + ((WeaponBoltTypePtr)getObjectType())->middleRGB;
  1711. if (drawOldWay)
  1712. {
  1713. //------------------------
  1714. // Draw em!
  1715. gos_SetRenderState( gos_State_Texture, 0 );
  1716. //--------------------------------
  1717. //Set States for Software Renderer
  1718. if (Environment.Renderer == 3)
  1719. {
  1720. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneInvAlpha);
  1721. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
  1722. gos_SetRenderState( gos_State_MonoEnable, 1);
  1723. gos_SetRenderState( gos_State_Perspective, 0);
  1724. gos_SetRenderState( gos_State_Clipping, 1);
  1725. gos_SetRenderState( gos_State_AlphaTest, 0);
  1726. gos_SetRenderState( gos_State_Specular, 0);
  1727. gos_SetRenderState( gos_State_Dither, 0);
  1728. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulateAlpha);
  1729. gos_SetRenderState( gos_State_Filter, gos_FilterNone);
  1730. gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap );
  1731. gos_SetRenderState( gos_State_ZCompare, 1);
  1732. gos_SetRenderState( gos_State_ZWrite, 0);
  1733. }
  1734. //--------------------------------
  1735. //Set States for Hardware Renderer
  1736. else
  1737. {
  1738. gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneInvAlpha);
  1739. gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
  1740. gos_SetRenderState( gos_State_MonoEnable, 0);
  1741. gos_SetRenderState( gos_State_Perspective, 1);
  1742. gos_SetRenderState( gos_State_Clipping, 1);
  1743. gos_SetRenderState( gos_State_AlphaTest, 0);
  1744. gos_SetRenderState( gos_State_Specular, 0);
  1745. gos_SetRenderState( gos_State_Dither, 1);
  1746. gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulateAlpha);
  1747. gos_SetRenderState( gos_State_Filter, gos_FilterBiLinear);
  1748. gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap );
  1749. gos_SetRenderState( gos_State_ZCompare, 1);
  1750. gos_SetRenderState( gos_State_ZWrite, 0);
  1751. }
  1752. if (gosTextureHandle != 0xffffffff)
  1753. gos_SetRenderState( gos_State_Texture,gosTextureHandle);
  1754. else
  1755. gos_SetRenderState( gos_State_Texture,0);
  1756. gos_DrawTriangles(lq1Vertices,3);
  1757. gos_DrawTriangles(lq2Vertices,3);
  1758. gos_DrawTriangles(lq3Vertices,3);
  1759. gos_DrawTriangles(lq4Vertices,3);
  1760. }
  1761. else
  1762. {
  1763. if ((lq1Vertices[0].z >= 0.0f) &&
  1764. (lq1Vertices[0].z < 1.0f) &&
  1765. (lq1Vertices[1].z >= 0.0f) &&
  1766. (lq1Vertices[1].z < 1.0f) &&
  1767. (lq1Vertices[2].z >= 0.0f) &&
  1768. (lq1Vertices[2].z < 1.0f))
  1769. {
  1770. mcTextureManager->addVertices(mcTextureHandle,lq1Vertices,MC2_ISEFFECTS|MC2_DRAWONEIN);
  1771. }
  1772. if ((lq2Vertices[0].z >= 0.0f) &&
  1773. (lq2Vertices[0].z < 1.0f) &&
  1774. (lq2Vertices[1].z >= 0.0f) &&
  1775. (lq2Vertices[1].z < 1.0f) &&
  1776. (lq2Vertices[2].z >= 0.0f) &&
  1777. (lq2Vertices[2].z < 1.0f))
  1778. {
  1779. mcTextureManager->addVertices(mcTextureHandle,lq2Vertices,MC2_ISEFFECTS|MC2_DRAWONEIN);
  1780. }
  1781. if ((lq3Vertices[0].z >= 0.0f) &&
  1782. (lq3Vertices[0].z < 1.0f) &&
  1783. (lq3Vertices[1].z >= 0.0f) &&
  1784. (lq3Vertices[1].z < 1.0f) &&
  1785. (lq3Vertices[2].z >= 0.0f) &&
  1786. (lq3Vertices[2].z < 1.0f))
  1787. {
  1788. mcTextureManager->addVertices(mcTextureHandle,lq3Vertices,MC2_ISEFFECTS|MC2_DRAWONEIN);
  1789. }
  1790. if ((lq4Vertices[0].z >= 0.0f) &&
  1791. (lq4Vertices[0].z < 1.0f) &&
  1792. (lq4Vertices[1].z >= 0.0f) &&
  1793. (lq4Vertices[1].z < 1.0f) &&
  1794. (lq4Vertices[2].z >= 0.0f) &&
  1795. (lq4Vertices[2].z < 1.0f))
  1796. {
  1797. mcTextureManager->addVertices(mcTextureHandle,lq4Vertices,MC2_ISEFFECTS|MC2_DRAWONEIN);
  1798. }
  1799. }
  1800. if (gosEffect)
  1801. {
  1802. Stuff::Point3D actualPosition;
  1803. Stuff::Vector3D hotSpot = *targetPosition;
  1804. GameObjectPtr target = ObjectManager->getByWatchID(targetWID);
  1805. if (target)
  1806. {
  1807. if (!target->isMech())
  1808. {
  1809. hotSpot = target->getPositionFromHS(targetHotSpot);
  1810. }
  1811. else
  1812. {
  1813. if (targetHotSpot)
  1814. hotSpot = target->appearance->getHitNodeLeft();
  1815. else
  1816. hotSpot = target->appearance->getHitNodeRight();
  1817. }
  1818. }
  1819. actualPosition.x = -hotSpot.x; //Play the beam hitting effect at the hit location
  1820. actualPosition.y = hotSpot.z;
  1821. actualPosition.z = hotSpot.y;
  1822. Stuff::LinearMatrix4D shapeOrigin;
  1823. Stuff::LinearMatrix4D localToWorld;
  1824. Stuff::LinearMatrix4D localResult;
  1825. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1826. shapeOrigin.BuildTranslation(actualPosition);
  1827. Stuff::UnitQuaternion effectRot;
  1828. effectRot = Stuff::EulerAngles(0.0f,rotation * DEGREES_TO_RADS,0.0f);
  1829. localToWorld.Multiply(gosFX::Effect_Against_Motion,effectRot);
  1830. localResult.Multiply(localToWorld,shapeOrigin);
  1831. drawInfo.m_parentToWorld = &localResult;
  1832. if (!MLRVertexLimitReached)
  1833. gosEffect->Draw(&drawInfo);
  1834. }
  1835. }
  1836. else if (gosEffect)
  1837. {
  1838. Stuff::Point3D actualPosition;
  1839. actualPosition.x = -laserPosition.x;
  1840. actualPosition.y = laserPosition.z;
  1841. actualPosition.z = laserPosition.y;
  1842. Stuff::LinearMatrix4D shapeOrigin;
  1843. Stuff::LinearMatrix4D localToWorld;
  1844. Stuff::LinearMatrix4D localResult;
  1845. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1846. shapeOrigin.BuildTranslation(actualPosition);
  1847. Stuff::UnitQuaternion effectRot;
  1848. effectRot = Stuff::EulerAngles(0.0f,rotation * DEGREES_TO_RADS,0.0f);
  1849. localToWorld.Multiply(gosFX::Effect_Against_Motion,effectRot);
  1850. localResult.Multiply(localToWorld,shapeOrigin);
  1851. drawInfo.m_parentToWorld = &localResult;
  1852. if (!MLRVertexLimitReached)
  1853. gosEffect->Draw(&drawInfo);
  1854. }
  1855. if (muzzleEffect)
  1856. {
  1857. Stuff::Point3D mPosition;
  1858. mPosition.x = -position.x;
  1859. mPosition.y = position.z;
  1860. mPosition.z = position.y;
  1861. Stuff::LinearMatrix4D shapeOrigin;
  1862. Stuff::LinearMatrix4D localToWorld;
  1863. Stuff::LinearMatrix4D localResult;
  1864. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1865. shapeOrigin.BuildTranslation(mPosition);
  1866. GameObjectPtr myOwner = ObjectManager->getByWatchID(ownerWID);
  1867. Stuff::UnitQuaternion effectRot;
  1868. if (myOwner)
  1869. effectRot = Stuff::EulerAngles(0.0f, myOwner->getRotation() * DEGREES_TO_RADS,0.0f);
  1870. else
  1871. effectRot = Stuff::EulerAngles(0.0f,0.0f,0.0f);
  1872. localToWorld.Multiply(gosFX::Effect_Into_Motion,effectRot);
  1873. localResult.Multiply(localToWorld,shapeOrigin);
  1874. drawInfo.m_parentToWorld = &localResult;
  1875. if (!MLRVertexLimitReached)
  1876. muzzleEffect->Draw(&drawInfo);
  1877. }
  1878. if (hitEffect && hitTarget && hitEffect->IsExecuted())
  1879. {
  1880. Stuff::Vector3D hotSpot = *targetPosition;
  1881. GameObjectPtr target = ObjectManager->getByWatchID(targetWID);
  1882. if (target)
  1883. {
  1884. if (!target->isMech())
  1885. {
  1886. hotSpot = target->getPositionFromHS(targetHotSpot);
  1887. }
  1888. else
  1889. {
  1890. if (targetHotSpot)
  1891. hotSpot = target->appearance->getHitNodeLeft();
  1892. else
  1893. hotSpot = target->appearance->getHitNodeRight();
  1894. }
  1895. }
  1896. Stuff::Point3D tPosition;
  1897. tPosition.x = -hotSpot.x;
  1898. tPosition.y = hotSpot.z;
  1899. tPosition.z = hotSpot.y;
  1900. Stuff::LinearMatrix4D shapeOrigin;
  1901. Stuff::LinearMatrix4D localToWorld;
  1902. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1903. shapeOrigin.BuildTranslation(tPosition);
  1904. drawInfo.m_parentToWorld = &shapeOrigin;
  1905. if (!MLRVertexLimitReached)
  1906. hitEffect->Draw(&drawInfo);
  1907. }
  1908. if (missEffect && hitTarget && missEffect->IsExecuted())
  1909. {
  1910. Stuff::Vector3D hotSpot = *targetPosition;
  1911. Stuff::Point3D tPosition;
  1912. tPosition.x = -hotSpot.x;
  1913. tPosition.y = hotSpot.z;
  1914. tPosition.z = hotSpot.y;
  1915. Stuff::LinearMatrix4D shapeOrigin;
  1916. Stuff::LinearMatrix4D localToWorld;
  1917. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1918. shapeOrigin.BuildTranslation(tPosition);
  1919. drawInfo.m_parentToWorld = &shapeOrigin;
  1920. if (!MLRVertexLimitReached)
  1921. missEffect->Draw(&drawInfo);
  1922. }
  1923. if (waterMissEffect && hitTarget && waterMissEffect->IsExecuted())
  1924. {
  1925. Stuff::Vector3D hotSpot = *targetPosition;
  1926. Stuff::Point3D tPosition;
  1927. tPosition.x = -hotSpot.x;
  1928. tPosition.y = Terrain::waterElevation;
  1929. tPosition.z = hotSpot.y;
  1930. Stuff::LinearMatrix4D shapeOrigin;
  1931. Stuff::LinearMatrix4D localToWorld;
  1932. shapeOrigin.BuildRotation(Stuff::EulerAngles(0.0f,0.0f,0.0f));
  1933. shapeOrigin.BuildTranslation(tPosition);
  1934. drawInfo.m_parentToWorld = &shapeOrigin;
  1935. if (!MLRVertexLimitReached)
  1936. waterMissEffect->Draw(&drawInfo);
  1937. }
  1938. }
  1939. }
  1940. //---------------------------------------------------------------------------
  1941. void WeaponBolt::destroy (void)
  1942. {
  1943. if (targetPosition)
  1944. {
  1945. delete targetPosition;
  1946. targetPosition = NULL;
  1947. }
  1948. //Must toss these here as mission may have ended with effect still playing!!
  1949. if (pointLight)
  1950. {
  1951. if (eye)
  1952. eye->removeWorldLight(lightId,pointLight);
  1953. systemHeap->Free(pointLight);
  1954. pointLight = NULL;
  1955. }
  1956. if (hitEffect)
  1957. {
  1958. hitEffect->Kill();
  1959. delete hitEffect;
  1960. hitEffect = NULL;
  1961. }
  1962. if (muzzleEffect)
  1963. {
  1964. muzzleEffect->Kill();
  1965. delete muzzleEffect;
  1966. muzzleEffect = NULL;
  1967. }
  1968. if (gosEffect)
  1969. {
  1970. gosEffect->Kill();
  1971. delete gosEffect;
  1972. gosEffect = NULL;
  1973. }
  1974. if (missEffect)
  1975. {
  1976. missEffect->Kill();
  1977. delete missEffect;
  1978. missEffect = NULL;
  1979. }
  1980. if (waterMissEffect)
  1981. {
  1982. waterMissEffect->Kill();
  1983. delete waterMissEffect;
  1984. waterMissEffect = NULL;
  1985. }
  1986. }
  1987. //---------------------------------------------------------------------------
  1988. void WeaponBolt::init (bool create, ObjectTypePtr _type)
  1989. {
  1990. GameObject::init(create, _type);
  1991. setFlag(OBJECT_FLAG_JUSTCREATED, true);
  1992. objectClass = WEAPONBOLT;
  1993. lightId = -9; //Tell it to make one!
  1994. //Make SURE all of the old Effects are GONE!!
  1995. destroy();
  1996. //-----------------------------------------
  1997. // Are we a magical new GOSFX(tm)?
  1998. if (effectId >= 0)
  1999. {
  2000. if (strcmp(weaponEffects->GetEffectName(effectId),"NONE") != 0)
  2001. {
  2002. //--------------------------------------------
  2003. // Yes, load it on up.
  2004. unsigned flags = gosFX::Effect::ExecuteFlag|gosFX::Effect::LoopFlag;
  2005. Check_Object(gosFX::EffectLibrary::Instance);
  2006. gosFX::Effect::Specification* gosEffectSpec = gosFX::EffectLibrary::Instance->Find(weaponEffects->GetEffectName(effectId));
  2007. if (gosEffectSpec)
  2008. {
  2009. gosEffect = gosFX::EffectLibrary::Instance->MakeEffect(gosEffectSpec->m_effectID, flags);
  2010. gosASSERT(gosEffect != NULL);
  2011. MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
  2012. //gosEffect->SetScalar(BASE_EFFECT_SCALAR);
  2013. }
  2014. }
  2015. if ((strcmp(weaponEffects->GetEffectMuzzleFlashName(effectId),"NONE") != 0) && useNonWeaponEffects)
  2016. {
  2017. //--------------------------------------------
  2018. // Yes, load it on up.
  2019. unsigned flags = gosFX::Effect::ExecuteFlag;
  2020. Check_Object(gosFX::EffectLibrary::Instance);
  2021. gosFX::Effect::Specification* gosEffectSpec = gosFX::EffectLibrary::Instance->Find(weaponEffects->GetEffectMuzzleFlashName(effectId));
  2022. if (gosEffectSpec)
  2023. {
  2024. muzzleEffect = gosFX::EffectLibrary::Instance->MakeEffect(gosEffectSpec->m_effectID, flags);
  2025. gosASSERT(muzzleEffect != NULL);
  2026. MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
  2027. //muzzleEffect->SetScalar(BASE_EFFECT_SCALAR);
  2028. }
  2029. }
  2030. if (strcmp(weaponEffects->GetEffectHitName(effectId),"NONE") != 0)
  2031. {
  2032. //--------------------------------------------
  2033. // Yes, load it on up.
  2034. unsigned flags = gosFX::Effect::ExecuteFlag;
  2035. Check_Object(gosFX::EffectLibrary::Instance);
  2036. gosFX::Effect::Specification* gosEffectSpec = gosFX::EffectLibrary::Instance->Find(weaponEffects->GetEffectHitName(effectId));
  2037. if (gosEffectSpec)
  2038. {
  2039. hitEffect = gosFX::EffectLibrary::Instance->MakeEffect(gosEffectSpec->m_effectID, flags);
  2040. gosASSERT(hitEffect != NULL);
  2041. MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
  2042. //hitEffect->SetScalar(BASE_EFFECT_SCALAR);
  2043. }
  2044. }
  2045. if ((strcmp(weaponEffects->GetEffectMissName(effectId),"NONE") != 0) && useNonWeaponEffects)
  2046. {
  2047. //--------------------------------------------
  2048. // Yes, load it on up.
  2049. unsigned flags = gosFX::Effect::ExecuteFlag;
  2050. Check_Object(gosFX::EffectLibrary::Instance);
  2051. gosFX::Effect::Specification* gosEffectSpec = gosFX::EffectLibrary::Instance->Find(weaponEffects->GetEffectMissName(effectId));
  2052. if (gosEffectSpec)
  2053. {
  2054. missEffect = gosFX::EffectLibrary::Instance->MakeEffect(gosEffectSpec->m_effectID, flags);
  2055. gosASSERT(missEffect != NULL);
  2056. MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
  2057. //hitEffect->SetScalar(BASE_EFFECT_SCALAR);
  2058. }
  2059. }
  2060. //No water miss for machine guns
  2061. if (useNonWeaponEffects && (effectId != 11) && (strcmp(weaponEffects->GetEffectName(WATER_MISS_FX),"NONE") != 0))
  2062. {
  2063. //--------------------------------------------
  2064. // Yes, load it on up.
  2065. unsigned flags = gosFX::Effect::ExecuteFlag;
  2066. Check_Object(gosFX::EffectLibrary::Instance);
  2067. gosFX::Effect::Specification* gosEffectSpec = gosFX::EffectLibrary::Instance->Find(weaponEffects->GetEffectName(WATER_MISS_FX));
  2068. if (gosEffectSpec)
  2069. {
  2070. waterMissEffect = gosFX::EffectLibrary::Instance->MakeEffect(gosEffectSpec->m_effectID, flags);
  2071. gosASSERT(waterMissEffect != NULL);
  2072. MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
  2073. //hitEffect->SetScalar(BASE_EFFECT_SCALAR);
  2074. }
  2075. }
  2076. else
  2077. {
  2078. waterMissEffect = NULL;
  2079. }
  2080. }
  2081. //----------------------------------------------
  2082. // Get a texture Handle from the textureManager
  2083. // Assume ALPHA!
  2084. if (((WeaponBoltTypePtr)_type)->textureName && stricmp(((WeaponBoltTypePtr)_type)->textureName,"NONE") != 0)
  2085. {
  2086. char tPath[1024];
  2087. sprintf(tPath,"%s128\\",tglPath);
  2088. FullPathFileName textureName;
  2089. textureName.init(tPath,((WeaponBoltTypePtr)_type)->textureName,".tga");
  2090. if (((WeaponBoltTypePtr)_type)->mipTexture)
  2091. mcTextureHandle = mcTextureManager->loadTexture(textureName,gos_Texture_Alpha,0);
  2092. else
  2093. mcTextureHandle = mcTextureManager->loadTexture(textureName,gos_Texture_Alpha,gosHint_DisableMipmap);
  2094. }
  2095. else
  2096. {
  2097. mcTextureHandle = 0;
  2098. gosTextureHandle = 0xffffffff;
  2099. }
  2100. }
  2101. //---------------------------------------------------------------------------
  2102. void WeaponBolt::setOwner (GameObjectPtr who)
  2103. {
  2104. if (who)
  2105. ownerWID = who->getWatchID();
  2106. else
  2107. ownerWID = 0;
  2108. }
  2109. //---------------------------------------------------------------------------
  2110. void WeaponBolt::setTarget (GameObjectPtr who)
  2111. {
  2112. if (who)
  2113. targetWID = who->getWatchID();
  2114. else
  2115. targetWID = 0;
  2116. }
  2117. //---------------------------------------------------------------------------
  2118. void WeaponBolt::setTargetPosition (Stuff::Vector3D pos)
  2119. {
  2120. if (!targetPosition)
  2121. targetPosition = new Stuff::Vector3D;
  2122. *targetPosition = pos;
  2123. }
  2124. //***************************************************************************
  2125. void WeaponBolt::Save (PacketFilePtr file, long packetNum)
  2126. {
  2127. WeaponBoltData data;
  2128. CopyTo(&data);
  2129. //PacketNum incremented in ObjectManager!!
  2130. file->writePacket(packetNum,(MemoryPtr)&data,sizeof(WeaponBoltData),STORAGE_TYPE_ZLIB);
  2131. }
  2132. //***************************************************************************
  2133. void WeaponBolt::CopyTo (WeaponBoltData *data)
  2134. {
  2135. data->ownerWID = ownerWID;
  2136. data->hotSpotNumber = hotSpotNumber;
  2137. data->targetWID = targetWID;
  2138. data->targetHotSpot = targetHotSpot;
  2139. Stuff::Vector3D dmy;
  2140. dmy.Zero();
  2141. if (targetPosition)
  2142. data->targetPosition = *targetPosition;
  2143. else
  2144. data->targetPosition = dmy;
  2145. data->distanceToTarget = distanceToTarget;
  2146. data->halfDistanceToTarget = halfDistanceToTarget;
  2147. data->weaponShot = weaponShot;
  2148. data->laserPosition = laserPosition;
  2149. memcpy(data->laserVertices,laserVertices,sizeof(Stuff::Vector3D) * 4);
  2150. memcpy(data->laserSide,laserSide,sizeof(Stuff::Vector3D) * 4);
  2151. data->effectId = effectId;
  2152. data->hitTarget = hitTarget;
  2153. data->timeLeft = timeLeft;
  2154. data->hsPos = hsPos;
  2155. data->hitLeft = hitLeft;
  2156. data->mcTextureHandle = mcTextureHandle;
  2157. data->gosTextureHandle = gosTextureHandle;
  2158. data->startUV = startUV;
  2159. data->goalHeight = goalHeight;
  2160. GameObject::CopyTo(dynamic_cast<GameObjectData *>(data));
  2161. }
  2162. //---------------------------------------------------------------------------
  2163. void WeaponBolt::Load (WeaponBoltData *data)
  2164. {
  2165. GameObject::Load(dynamic_cast<GameObjectData *>(data));
  2166. ownerWID = data->ownerWID;
  2167. hotSpotNumber = data->hotSpotNumber;
  2168. targetWID = data->targetWID;
  2169. targetHotSpot = data->targetHotSpot;
  2170. if ((data->targetPosition.x == data->targetPosition.y) &&
  2171. (data->targetPosition.x == data->targetPosition.z))
  2172. targetPosition = NULL;
  2173. else
  2174. {
  2175. targetPosition = new Stuff::Vector3D;
  2176. *targetPosition = data->targetPosition;
  2177. }
  2178. distanceToTarget = data->distanceToTarget;
  2179. halfDistanceToTarget = data->halfDistanceToTarget;
  2180. weaponShot = data->weaponShot;
  2181. laserPosition = data->laserPosition;
  2182. memcpy(laserVertices,data->laserVertices,sizeof(Stuff::Vector3D) * 4);
  2183. memcpy(laserSide,data->laserSide,sizeof(Stuff::Vector3D) * 4);
  2184. effectId = data->effectId;
  2185. hitTarget = data->hitTarget;
  2186. timeLeft = data->timeLeft;
  2187. hsPos = data->hsPos;
  2188. hitLeft = data->hitLeft;
  2189. startUV = data->startUV;
  2190. goalHeight = data->goalHeight;
  2191. }
  2192. //---------------------------------------------------------------------------
  2193. void WeaponBolt::finishNow (void)
  2194. {
  2195. if (getExists())
  2196. {
  2197. //This weapon is still enroute or in some other way is not resolved. Resolve it.
  2198. // Then setExists to false!!
  2199. //Toss its effects.
  2200. if (hitEffect)
  2201. {
  2202. hitEffect->Kill();
  2203. delete hitEffect;
  2204. hitEffect = NULL;
  2205. }
  2206. if (muzzleEffect)
  2207. {
  2208. muzzleEffect->Kill();
  2209. delete muzzleEffect;
  2210. muzzleEffect = NULL;
  2211. }
  2212. if (missEffect)
  2213. {
  2214. missEffect->Kill();
  2215. delete missEffect;
  2216. missEffect = NULL;
  2217. }
  2218. if (waterMissEffect)
  2219. {
  2220. waterMissEffect->Kill();
  2221. delete waterMissEffect;
  2222. waterMissEffect = NULL;
  2223. }
  2224. if (gosEffect)
  2225. {
  2226. gosEffect->Kill(); //Effect is over. Otherwise, wait until hit!
  2227. delete gosEffect;
  2228. gosEffect = NULL;
  2229. }
  2230. //Need to kill the light source here too!
  2231. if (pointLight)
  2232. {
  2233. if (eye)
  2234. eye->removeWorldLight(lightId,pointLight);
  2235. systemHeap->Free(pointLight);
  2236. pointLight = NULL;
  2237. }
  2238. GameObjectPtr target = ObjectManager->getByWatchID(targetWID);
  2239. if (target)
  2240. {
  2241. if (MPlayer)
  2242. {
  2243. if (MPlayer->isServer())
  2244. target->handleWeaponHit(&weaponShot, true);
  2245. }
  2246. else
  2247. target->handleWeaponHit(&weaponShot);
  2248. }
  2249. if (((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum &&
  2250. (((WeaponBoltTypePtr)getObjectType())->areaEffectDmg > 0.0f) &&
  2251. (((WeaponBoltTypePtr)getObjectType())->areaEffectRad > 0.0f))
  2252. {
  2253. //Create the explosion here. HIT or MISS, its the same one!!
  2254. // Damage is done by explosion NOT by hit!
  2255. ObjectManager->createExplosion(((WeaponBoltTypePtr)getObjectType())->hitEffectObjNum,
  2256. NULL,*targetPosition,
  2257. ((WeaponBoltTypePtr)getObjectType())->areaEffectDmg,
  2258. ((WeaponBoltTypePtr)getObjectType())->areaEffectRad);
  2259. }
  2260. setExists(false);
  2261. }
  2262. }
  2263. //---------------------------------------------------------------------------