Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 47.88 KB | None | 0 0
  1. /*=======================================================//
  2. // field.QC - CustomTF 3.2.OfN - 30/1/2001 - //
  3. // by Sergio Fumaña Grunwaldt - OfteN [cp] //
  4. =========================================================//
  5. Field generator stuff - Written all by myself! :)
  6. I took the model and some sounds from deadlode mod
  7. One sound is from megaTF
  8. =========================================================*/
  9.  
  10. // field generator status flags, DO NOT MODIFY
  11.  
  12. #define FIELDGEN_ISOFF 0 // no field, not linked, and its not trying to link (several possible reasons)
  13. #define FIELDGEN_ISIDLE 1 // no field, not linked, trying to link with other generator
  14. #define FIELDGEN_ISDISABLED 2 // no field, linked, its disabled temporary (teammate passing thru field)
  15. #define FIELDGEN_ISENABLED 3 // field, linked, and cells enough, waiting for shock, only hum sound
  16. #define FIELDGEN_ISWORKING 4 // field, linked, glowing and all the field visual/sound effects are on
  17.  
  18. // field generator settings
  19.  
  20. #define FIELDGEN_WORKTIME 3 // seconds the generators remain "working", glowing and doing lightning after a shock
  21. #define FIELDGEN_WORKING_RATE 1 // interval in seconds for fieldgens to use cells
  22. #define FIELDGEN_LINKTIME 3.5 // seconds between tries to link with other generator (only visual)
  23. #define FIELDGEN_TIMEDISABLED 1.5 // time fieldgens remain disabled
  24. #define FIELDGEN_CELLSCOST 2 // cells cost for each "FIELDGEN_ISWORKING" pass
  25.  
  26. // force field settings
  27.  
  28. #define FIELD_DMG 250//160 //was 80 - normal damag when touching
  29. #define FIELD_DMGINSIDE 500//420 //was 120 - damage when trapped inside field
  30. #define FIELD_SOUNDSRATE 1 // Rate in seconds at which hum/shield sound is played
  31. #define FIELD_VISUALFACTOR 0.5 // 1 = always generate lightning for visuals, when working. 0 = never
  32.  
  33. /*===============================================================================================
  34.  
  35. EXPLANATION OF HOW THE ENTITY FIELDS ARE USED (thnx? np.. :P)
  36. ---------------------------------------------
  37.  
  38. For field generator entity:
  39. ---------------------------
  40.  
  41. .has_holo - Holds current status of every field generator, FIELDGEN_ISXXXX determines
  42. .has_sensor - Boolean value, determines if field generator is currently supporting a force field
  43. .martyr_enemy - This points to the force field, if none its always 'world'
  44. .no_grenades_1 - Controls delay between tries to link (only affects sound/flash, it tries to link every frame)
  45. .no_grenades_2 - Controls delay for field to go up again after beeing disabled
  46. .tp_grenades_1 - Controls delay of the WORKING status
  47. .has_teleporter - Used to flash generators when field is activated
  48. .has_camera - Controls delay between cells take
  49. .has_tesla - Boolean, forced status.
  50.  
  51. For force field entity:
  52. -----------------------
  53.  
  54. .demon_one - Points to the first field generator
  55. .demon_two - Points to the 2nd generator
  56. .has_holo - Hum sound running, boolean
  57. .has_sensor - Shield sound running, boolean
  58. .has_tesla - Controls delay between hums
  59. .has_sentry - Controls delay between shield sounds
  60. .cnt - Orientation of field (x or y)
  61. .dmg - Next damage the field will do
  62. .has_camera - Used to control the rate at which the field touch sound/visual effects are done (4hz)
  63.  
  64. ================================================================================================*/
  65.  
  66. void() CheckDistance;
  67. entity(entity fieldgen) Find_OtherGen;
  68. float(entity fieldgen1, entity fieldgen2) FieldGens_CanLink;
  69. float(entity fieldgen) FieldGen_CanIdle;
  70. float(entity fieldgen) IsValidFieldGen;
  71. float (vector targ, vector check) vis2orig;
  72. float(entity field) IsValidField;
  73. void(entity tfield, entity gen1) Field_UpdateSounds;
  74. void(entity tfield) Field_StopSounds;
  75. void(entity tfield) Field_MakeVisual;
  76. float(entity tfield) FieldIsImproved;
  77. float(entity tfield) FieldIsMalfunctioning;
  78. void() Field_touch;
  79. void() Field_touch_SUB;
  80. float(entity e1, entity e2) EntsTouching2;
  81. void(entity tfield, vector where, entity thing) FieldExplosion;
  82. void(entity field) PutFieldWork;
  83. float(entity tfield, entity who) Field_ItCanPass;
  84. float(entity tfield, entity who) Field_ShouldDamage;
  85.  
  86. #ifdef FIELD_FORCEMODE
  87. entity(entity myself) GetMyFieldGen;
  88. float(entity tfield) Field_GetForcedStatus;
  89. void(float value) SetFieldForcedStatus; // player function (self = player) cuts disabled time also
  90. float() GetFieldForcedStatus; // player
  91. #endif
  92.  
  93. //=========================================================================================
  94. // field generator model and sounds
  95.  
  96. void() Field_Precache =
  97. {
  98. precache_sound ("misc/null.wav");
  99. precache_sound2("misc/ffhum.wav");
  100. precache_sound2("misc/ffbeep.wav");
  101. precache_sound2("misc/ffield.wav");
  102. precache_sound2("misc/ffact.wav");
  103. precache_sound2("misc/fffail.wav");
  104. precache_model2("progs/ffgen2.mdl");
  105. };
  106.  
  107. //==================================================================================================
  108. // checks for field generators and removes itself if needed, checks for stuck entities inside field
  109.  
  110. void() Field_think =
  111. {
  112.  
  113. /* NOT NEEDED - if (self.classname != "force_field")
  114. {
  115. RPrint("BUG: Not a force field entity was in 'FieldThink()'!\n");
  116. return;
  117. }*/
  118.  
  119. self.has_camera = #FALSE; // resets flag for visuals
  120.  
  121. // check field generators, removal of this field if needed... (for safety only)
  122. if (!IsValidFieldGen(self.demon_one) || !IsValidFieldGen(self.demon_two))
  123. {
  124. #ifdef OMC_DEBUG
  125. // this doesnt get printed
  126. dprint("In Field_think one of the FGs arent working\n" );
  127.  
  128. #endif
  129. if (IsValidFieldGen(self.demon_one))
  130. {
  131. self.demon_one.has_sensor = #FALSE;
  132. self.demon_one.martyr_enemy = world;
  133. }
  134.  
  135. if (IsValidFieldGen(self.demon_two))
  136. {
  137. self.demon_two.has_sensor = #FALSE;
  138. self.demon_two.martyr_enemy = world;
  139. }
  140.  
  141. self.demon_one = world;
  142. self.demon_two = world;
  143.  
  144. dremove(self);
  145.  
  146. // report this, as it shouldnt happen
  147. RPrint("Debug: Field entity removed in Field_think()\n");
  148. return;
  149. }
  150. else
  151. self.nextthink = time + 0.25; // 4hz rate
  152.  
  153. // Make visuals if needed
  154. if (self.demon_one.has_holo == #FIELDGEN_ISWORKING)
  155. Field_MakeVisual(self);
  156.  
  157. // checks for anything stuck in field :)
  158. local entity te;
  159. local float frange;
  160.  
  161. frange = #FIELDGEN_RANGE;
  162.  
  163. if (FieldIsImproved(self) & #IMPROVED_FOUR)
  164. {
  165. #ifdef OMC_DEBUG
  166. dprint("In Field_think (self) & IMPROVED_FOUR\n" );
  167.  
  168. #endif
  169. frange = #FIELDGEN_HACKEDRANGE; // at least 1 hacked for range
  170.  
  171. if (self.demon_one.all_active & #IMPROVED_FOUR && self.demon_two.all_active & #IMPROVED_FOUR)
  172. frange = #FIELDGEN_HACKEDRANGE2; // both field generators hacked
  173.  
  174.  
  175. }
  176.  
  177. te = findradius(self.origin,frange);
  178. while (te)
  179. {
  180. if (te != self)
  181. if (te != self.demon_one)
  182. if (te != self.demon_two)
  183. if (te.velocity == '0 0 0')
  184. if (te.classname != "force_field")
  185. if (EntsTouching2(te,self))
  186. {
  187. #ifdef OMC_DEBUG
  188. // OMC doesnt ever get printed
  189. dprint("In Field_think somethings stuck in the field\n" );
  190.  
  191. #endif
  192. other = te;
  193. deathmsg = #DMSG_STUCK_FORCEFIELD;
  194. self.dmg = #FIELD_DMGINSIDE; // this gonna hurt
  195. Field_touch_SUB();
  196. }
  197.  
  198. te = te.chain;
  199. }
  200. };
  201.  
  202. //=============================================================================================
  203. // is one entity actually intersecting the other one? (this avoids using a stupid trigger)
  204.  
  205. float(entity e1, entity e2) EntsTouching2 =
  206. {
  207. #ifdef OMC_DEBUG
  208. dprint("In EntsTouching2\n" );
  209.  
  210. #endif
  211. if (e1.absmin_x > e2.absmax_x)
  212. return #FALSE;
  213. if (e1.absmin_y > e2.absmax_y)
  214. return #FALSE;
  215. if (e1.absmin_z > e2.absmax_z)
  216. return #FALSE;
  217.  
  218. if (e1.absmax_x < e2.absmin_x)
  219. return #FALSE;
  220. if (e1.absmax_y < e2.absmin_y)
  221. return #FALSE;
  222. if (e1.absmax_z < e2.absmin_z)
  223. return #FALSE;
  224.  
  225. return #TRUE;
  226. };
  227.  
  228. //=================================================================================
  229. // these 2 functions return the current hacks that should apply to the field
  230.  
  231. float(entity tfield) FieldIsImproved =
  232. {
  233.  
  234. #ifdef OMC_DEBUG
  235. dprint("In FieldIsImproved (checking any hacks)\n" );
  236.  
  237. #endif
  238.  
  239. if (IsValidFieldGen(tfield.demon_one) && IsValidFieldGen(tfield.demon_two))
  240. return tfield.demon_one.all_active | tfield.demon_two.all_active;
  241.  
  242. if (IsValidFieldGen(tfield.demon_one))
  243. return tfield.demon_one.all_active;
  244.  
  245. if (IsValidFieldGen(tfield.demon_two))
  246. return tfield.demon_two.all_active;
  247.  
  248. return 0;
  249. };
  250.  
  251. float(entity tfield) FieldIsMalfunctioning =
  252. {
  253.  
  254. #ifdef OMC_DEBUG
  255. dprint("In FieldIsMalfunctioning \n" );
  256.  
  257. #endif
  258.  
  259. if (IsValidFieldGen(tfield.demon_one) && IsValidFieldGen(tfield.demon_two))
  260. return tfield.demon_one.is_malfunctioning | tfield.demon_two.is_malfunctioning;
  261.  
  262. if (IsValidFieldGen(tfield.demon_one))
  263. return tfield.demon_one.is_malfunctioning;
  264.  
  265. if (IsValidFieldGen(tfield.demon_two))
  266. return tfield.demon_two.is_malfunctioning;
  267.  
  268. return 0;
  269. };
  270.  
  271. //=================================================================
  272. // disables force field
  273.  
  274. void(entity tfield, float timedisable) DisableField =
  275. {
  276. if (IsValidFieldGen(tfield.demon_one))
  277. {
  278. tfield.demon_one.has_holo = #FIELDGEN_ISDISABLED;
  279.  
  280. #ifdef OMC_DEBUG
  281. local string Str;
  282. Str = ftos(tfield.demon_one.no_grenades_2);
  283. dprint("In DisableField_1, before 1st field gen restart delay = " );
  284. dprint(Str);
  285. dprint("\n");
  286. #endif
  287.  
  288. if (tfield.demon_one.no_grenades_2 < time + timedisable)
  289. tfield.demon_one.no_grenades_2 = time + timedisable;
  290.  
  291. #ifdef OMC_DEBUG
  292. Str = ftos(tfield.demon_one.no_grenades_2);
  293. dprint("In DisableField_2, after 1st field gen restart delay = " );
  294. dprint(Str);
  295. dprint(", ");
  296. Str = ftos(timedisable);
  297. dprint("timedisable = " );
  298. dprint(Str);
  299. dprint("\n");
  300. #endif
  301. }
  302.  
  303. if (IsValidFieldGen(tfield.demon_two))
  304. {
  305. #ifdef OMC_DEBUG
  306. Str = ftos(tfield.demon_two.no_grenades_2);
  307. dprint("In DisableField_3, before 2nd field gen restart delay = " );
  308. dprint(Str);
  309. dprint("\n");
  310. #endif
  311. tfield.demon_two.has_holo = #FIELDGEN_ISDISABLED;
  312.  
  313. if (tfield.demon_two.no_grenades_2 < time + timedisable)
  314. tfield.demon_two.no_grenades_2 = time + timedisable;
  315.  
  316. #ifdef OMC_DEBUG
  317. Str = ftos(tfield.demon_two.no_grenades_2);
  318. dprint("In DisableField_4, after the 2nd field gen restart delay = " );
  319. dprint(Str);
  320. dprint("\n");
  321. #endif
  322. }
  323.  
  324. sound (tfield, #CHAN_VOICE, "misc/ffbeep.wav", 0.4, #ATTN_IDLE);
  325. };
  326.  
  327. //=========================================================================================
  328. // applies damage and makes the sound and visual effect for the forcefield shock
  329.  
  330. void() Field_touch_SUB =
  331. {
  332.  
  333.  
  334. #ifdef OMC_DEBUG
  335. /* The path for a friendlt teammate entering the fg is: SUB_1 SUB_5 SUB_6 */
  336. dprint("In Field_touch_SUB_1\n" );
  337.  
  338. #endif
  339. if (FieldIsMalfunctioning(self) & #SCREWUP_THREE) // reduce output
  340. self.dmg = 1;
  341.  
  342. #ifdef GIBABLE_CORPSES
  343. if (other.#corpseflag == #STRFLAG_CORPSE) // Corpses
  344. {
  345. #ifdef OMC_DEBUG
  346. dprint("In Field_touch_SUB_2\n" );
  347.  
  348. #endif
  349. if (Field_ItCanPass(self, other))
  350. {
  351. #ifdef OMC_DEBUG
  352. dprint("In Field_touch_SUB_3\n" );
  353.  
  354. #endif
  355. DisableField(self,#FIELDGEN_TIMEDISABLED);
  356. return;
  357. }
  358. else
  359. {
  360. #ifdef OMC_DEBUG
  361. dprint("In Field_touch_SUB_4\n" );
  362.  
  363. #endif
  364. if (Field_ShouldDamage(self,other))
  365. TF_T_Damage (other, self, self.real_owner, self.dmg, 0, #TF_TD_ELECTRICITY);
  366. }
  367. }
  368. else
  369. #endif
  370. if (other.classname == "player" && other.health > 0) // PLAYERS (alive)
  371. {
  372. #ifdef OMC_DEBUG
  373. dprint("In Field_touch_SUB_5 player is alive\n" );
  374.  
  375. #endif
  376. if (other.playerclass == #PC_UNDEFINED) // Observers (they have 1 hp)
  377. return;
  378.  
  379. if (Field_ItCanPass(self, other))
  380. {
  381. #ifdef OMC_DEBUG
  382. dprint("In Field_touch_SUB_6 it can pass \n" );
  383.  
  384. #endif
  385. DisableField(self,#FIELDGEN_TIMEDISABLED);
  386. return;
  387. }
  388. else
  389. {
  390. #ifdef OMC_DEBUG
  391. dprint("In Field_touch_SUB_7\n" );
  392.  
  393. #endif
  394. if (Field_ShouldDamage(self,other))
  395. TF_T_Damage (other, self, self.real_owner, self.dmg, #TF_TD_NOTTEAM, #TF_TD_ELECTRICITY);
  396. }
  397. }
  398. else // non player entities (or player heads)
  399. {
  400. if (IsMonster(other))
  401. {
  402. if (Field_ItCanPass(self, other))
  403. {
  404. DisableField(self,#FIELDGEN_TIMEDISABLED);
  405. return;
  406. }
  407. else if (Field_ShouldDamage(self,other))
  408. TF_T_Damage (other, self, self.real_owner, self.dmg, #TF_TD_NOTTEAM, #TF_TD_ELECTRICITY);
  409. }
  410. else // non-monsters non-alive-players entities (EVERYTHING ELSE)
  411. {
  412. #ifdef OMC_DEBUG
  413. dprint("In Field_touch_SUB_8\n" );
  414.  
  415. #endif
  416. // excludes entities that shouldnt be moved, doors plats etc..
  417. if(other.movetype == #MOVETYPE_NONE
  418. || other.movetype == #MOVETYPE_PUSH
  419. || other == world)
  420. return;
  421.  
  422. if (other.flags & #FL_ONGROUND)
  423. other.velocity_z = other.velocity_z + 100 + 160*random();
  424.  
  425. other.flags = other.flags - (other.flags & #FL_ONGROUND);
  426.  
  427. if (self.cnt) // Y Alignment
  428. {
  429. if (other.origin_x < self.origin_x)
  430. other.velocity_x = (0 - other.velocity_x) - (80 + 100 * random());
  431. else
  432. other.velocity_x = (0 - other.velocity_x) + (80 + 100 * random());
  433. }
  434. else // X Alignment
  435. {
  436. if (other.origin_y < self.origin_y)
  437. other.velocity_y = (0 - other.velocity_y) - (80 + 100 * random());
  438. else
  439. other.velocity_y = (0 - other.velocity_y) + (80 + 100 * random());
  440. }
  441. }
  442. }
  443.  
  444. // Do the effects for shock
  445. FieldExplosion(self,other.origin,other);
  446. PutFieldWork(self);
  447. };
  448.  
  449. #ifdef FIELD_FORCEMODE
  450.  
  451. //==========================================================================
  452. // gets one of our field generators
  453.  
  454. entity(entity myself) GetMyFieldGen =
  455. {
  456. #ifdef OMC_DEBUG
  457. dprint("In GetMyFieldGen \n" );
  458.  
  459. #endif
  460. local entity te;
  461. local float foundit;
  462. te = world;
  463. foundit = #FALSE;
  464.  
  465. te = find(world, classname, "building_fieldgen");
  466. while (te != world && foundit == #FALSE)
  467. {
  468. if (te.real_owner == myself) // is it ours?
  469. foundit = #TRUE; // yeah, found it
  470.  
  471. if (foundit == #FALSE) // our search must continue...
  472. te = find(te, classname, "building_fieldgen");
  473. }
  474.  
  475. return te;
  476. };
  477.  
  478. //=========================================================================
  479. // these functions retrieve and set the current 'forced status' on a field
  480.  
  481. float(entity tfield) Field_GetForcedStatus =
  482. {
  483. #ifdef OMC_DEBUG
  484. dprint("In Field_GetForcedStatus \n" );
  485.  
  486. #endif
  487. if (IsValidFieldGen(tfield.demon_one) && IsValidFieldGen(tfield.demon_two))
  488. {
  489. if (tfield.demon_two.has_tesla || tfield.demon_one.has_tesla)
  490. return #TRUE;
  491. }
  492. else if (IsValidFieldGen(tfield.demon_one))
  493. {
  494. if (tfield.demon_one.has_tesla)
  495. return #TRUE;
  496. }
  497. else if (IsValidFieldGen(tfield.demon_two))
  498. {
  499. if (tfield.demon_two.has_tesla)
  500. return #TRUE;
  501. }
  502.  
  503. return #FALSE;
  504. };
  505.  
  506. //==============================================================================
  507. // player functions called on menu.qc to disable/enable forced status on field
  508.  
  509. void(float value) SetFieldForcedStatus =
  510. {
  511. #ifdef OMC_DEBUG
  512. dprint("In SetFieldForcedStatus\n" );
  513.  
  514. #endif
  515. local entity gen1, gen2;
  516. gen1 = GetMyFieldGen(self);
  517. gen2 = Find_OtherGen(gen1);
  518.  
  519. if (IsValidFieldGen(gen1))
  520. {
  521. gen1.has_tesla = value;
  522. if (value)
  523. gen1.no_grenades_2 = time;
  524. }
  525.  
  526. if (IsValidFieldGen(gen2))
  527. {
  528. gen2.has_tesla = value;
  529. if (value)
  530. gen2.no_grenades_2 = time;
  531. }
  532. };
  533.  
  534. float() GetFieldForcedStatus =
  535. {
  536. local entity gen1, gen2;
  537. gen1 = GetMyFieldGen(self);
  538. gen2 = Find_OtherGen(gen1);
  539.  
  540. if (IsValidFieldGen(gen1) && IsValidFieldGen(gen2))
  541. {
  542. if (gen1.has_tesla || gen2.has_tesla)
  543. return #TRUE;
  544. }
  545. else if (IsValidFieldGen(gen1))
  546. return gen1.has_tesla;
  547. else if (IsValidFieldGen(gen2))
  548. return gen2.has_tesla;
  549.  
  550. return #FALSE;
  551.  
  552. };
  553.  
  554. #endif
  555.  
  556. //=========================================================================
  557. // returns TRUE if 'who' entity should be able to pass thru the field
  558.  
  559. float(entity tfield, entity who) Field_ItCanPass =
  560. {
  561. #ifdef OMC_DEBUG
  562. dprint("In Field_ItCanPass\n" );
  563.  
  564. #endif
  565.  
  566. #ifdef FIELD_TEST
  567. return #FALSE;
  568. #endif
  569.  
  570. if (FieldIsMalfunctioning(tfield) & #SCREWUP_ONE) // Malfunctioning, always block
  571. return #FALSE;
  572.  
  573. if (who == tfield.real_owner) // field owner - always pass
  574. return #TRUE;
  575.  
  576. #ifdef FIELD_FORCEMODE
  577.  
  578. if (Field_GetForcedStatus(tfield))
  579. return #FALSE;
  580.  
  581. #endif
  582.  
  583. if (who.classname == "player") // PLAYERS
  584. {
  585. if (Teammate(who.team_no, tfield.real_owner.team_no)) // teammate
  586. return #TRUE;
  587.  
  588. if (Teammate(who.undercover_team, tfield.real_owner.team_no)) // spies disguised as our team
  589. return #TRUE;
  590. }
  591. else if (IsMonster(who)) // MONSTERS/ARMY
  592. {
  593. if (Teammate(who.real_owner.team_no, tfield.real_owner.team_no)) // team monster
  594. return #TRUE;
  595. }
  596. #ifdef GIBABLE_CORPSES
  597. else if (who.#corpseflag == #STRFLAG_CORPSE) // CORPSES
  598. {
  599. if (Teammate(who.team_no, tfield.real_owner.team_no)) // team corpse
  600. return #TRUE;
  601. }
  602. #endif
  603.  
  604. return #FALSE;
  605. };
  606.  
  607. //=========================================================================
  608. // returns TRUE if 'who' entity should be damaged by the field
  609.  
  610. float(entity tfield, entity who) Field_ShouldDamage =
  611. {
  612.  
  613. #ifdef OMC_DEBUG
  614. dprint("In Field_ShouldDamage\n" );
  615.  
  616. #endif
  617.  
  618.  
  619.  
  620. #ifdef FIELD_TEST
  621. return #TRUE;
  622. #endif
  623.  
  624. if (FieldIsMalfunctioning(tfield) & #SCREWUP_ONE) // Malfunctioning, hurts always
  625. return #TRUE;
  626.  
  627. if (who.classname == "player") // PLAYERS
  628. {
  629. if (who == tfield.real_owner) // field owner
  630. return #FALSE;
  631.  
  632. if (Teammate(who.team_no, tfield.real_owner.team_no)) // teammate
  633. return #FALSE;
  634.  
  635. if (Teammate(who.undercover_team, tfield.real_owner.team_no)) // spies disguised as our team
  636. return #FALSE;
  637. }
  638. else if (IsMonster(who)) // MONSTERS/ARMY
  639. {
  640. if (Teammate(who.real_owner.team_no, tfield.real_owner.team_no)) // team monster
  641. return #FALSE;
  642. }
  643. #ifdef GIBABLE_CORPSES
  644. else if (who.#corpseflag == #STRFLAG_CORPSE) // CORPSES
  645. {
  646. if (Teammate(who.team_no, tfield.real_owner.team_no)) // team corpse
  647. return #FALSE;
  648. }
  649. #endif
  650.  
  651. return #TRUE;
  652. };
  653.  
  654. //=============================================================================
  655. // applies the particle effect and electric sound (at max 4hz rate)
  656.  
  657. void(entity tfield, vector where, entity thing) FieldExplosion =
  658. {
  659. if (!tfield.has_camera)
  660. {
  661. if (thing == world || thing.is_removed) return;
  662.  
  663. local vector whereFX;
  664. whereFX = where;
  665. whereFX_z = tfield.origin_z;
  666.  
  667. spawnFOG(whereFX);
  668. sound(tfield,#CHAN_BODY,"effects/crunch.wav",0.5,#ATTN_NORM);
  669.  
  670. tfield.has_camera = #TRUE; // cya soon (this gets reset on every field think)
  671. }
  672. };
  673.  
  674. //================================================================
  675. // Refresh working time for the force field
  676.  
  677. void(entity field) PutFieldWork =
  678. {
  679. #ifdef OMC_DEBUG
  680. dprint("In PutFieldWork \n" );
  681.  
  682. #endif
  683. if (IsValidFieldGen(field.demon_one))
  684. field.demon_one.tp_grenades_1 = time + #FIELDGEN_WORKTIME;
  685. if (IsValidFieldGen(field.demon_two))
  686. field.demon_two.tp_grenades_1 = time + #FIELDGEN_WORKTIME;
  687. };
  688.  
  689. //==============================================================
  690. // Force field touch function
  691.  
  692. void() Field_touch =
  693. {
  694. #ifdef OMC_DEBUG
  695. dprint("In Field_touch\n" );
  696.  
  697. #endif
  698. if (other.classname == "force_field") return; //avoid weird loops with other fields
  699.  
  700. self.dmg = #FIELD_DMG;
  701.  
  702. deathmsg = #DMSG_FORCEFIELD;
  703. Field_touch_SUB();
  704. };
  705.  
  706. //===================================================================================
  707. // creates the force field between the 2 generators (only if none currently on)
  708.  
  709. void(entity gen1, entity gen2) Create_Field =
  710. {
  711. #ifdef OMC_DEBUG
  712. dprint("In Create_Field\n" );
  713.  
  714. #endif
  715. // Check for existing force field, and abort if any
  716. if (gen1.has_sensor || gen2.has_sensor)
  717. {
  718. #ifdef OMC_DEBUG
  719.  
  720. dprint("In Create_Field FTE thinks forcefield is up\n" );
  721.  
  722. #endif
  723. return;
  724. }
  725.  
  726. if (gen1.martyr_enemy != world || gen2.martyr_enemy != world) // 2nd CHECK
  727. {
  728. #ifdef OMC_DEBUG
  729.  
  730. \
  731. // ======== GROUND ZERO =================
  732.  
  733. // THIS is the place where CPQWSV and the FTE dprints differ.
  734. // In FTE the line (gen1.martyr_enemy != world || gen2.martyr_enemy != world) is TRUE and the following gets printed.
  735. // In cpqwsv the following line doesnt execute, and the program flow goes straight to FieldGen_think_5
  736.  
  737. dprint("In Create_Field FTE thinks forcefield isnt set to world\n" );
  738. #endif
  739. return;
  740. }
  741.  
  742. // already checked b4 on CanLink -> CanIdle
  743. /*if (!IsValidFieldGen(gen1) || !IsValidFieldGen(gen2))
  744. return;*/
  745.  
  746. gen1.has_holo = #FIELDGEN_ISENABLED;
  747. gen2.has_holo = #FIELDGEN_ISENABLED;
  748.  
  749. gen1.has_sensor = #TRUE;
  750. gen2.has_sensor = #TRUE;
  751.  
  752. local entity tfield;
  753.  
  754. // generate field
  755. tfield = spawn();
  756. tfield.classname = "force_field";
  757. tfield.owner = world;
  758. tfield.real_owner = gen1.real_owner; // --> player
  759.  
  760. tfield.think = Field_think;
  761. tfield.touch = Field_touch;
  762. tfield.nextthink = time + 0.25;
  763.  
  764. // set pos and size
  765. tfield.origin = gen1.origin + '0 0 32';
  766. tfield.absmin_z = gen1.origin_z - 32;
  767. tfield.absmax_z = gen1.origin_z + 32;
  768.  
  769. tfield.mins_z = 0 - 32;
  770. tfield.maxs_z = 32;
  771. tfield.size_z = 64;
  772.  
  773. local float diff;
  774.  
  775. if (gen1.origin_x == gen2.origin_x)
  776. {
  777. tfield.cnt = 0;
  778.  
  779. tfield.origin_x = gen1.origin_x;
  780. tfield.absmin_x = gen1.origin_x - 2;
  781. tfield.absmax_x = gen1.origin_x + 2;
  782.  
  783. tfield.maxs_x = 2;
  784. tfield.mins_x = 0 - 2;
  785. tfield.size_x = 4;
  786.  
  787. if (gen1.origin_y > gen2.origin_y)
  788. {
  789. diff = (gen1.origin_y - gen2.origin_y)/2;
  790.  
  791. tfield.origin_y = gen1.origin_y - diff;
  792. tfield.absmin_y = gen2.origin_y;
  793. tfield.absmax_y = gen1.origin_y;
  794.  
  795. tfield.maxs_y = diff;
  796. tfield.mins_y = 0 - diff;
  797. tfield.size_y = diff * 2;
  798. }
  799. else
  800. {
  801. diff = (gen2.origin_y - gen1.origin_y)/2;
  802.  
  803. tfield.origin_y = gen2.origin_y - diff;
  804. tfield.absmin_y = gen1.origin_y;
  805. tfield.absmax_y = gen2.origin_y;
  806.  
  807. tfield.maxs_y = diff;
  808. tfield.mins_y = 0 - diff;
  809. tfield.size_y = diff * 2;
  810. }
  811. }
  812. else
  813. {
  814. tfield.cnt = 1;
  815.  
  816. tfield.origin_y = gen1.origin_y;
  817. tfield.absmin_y = gen1.origin_y - 2;
  818. tfield.absmax_y = gen1.origin_y + 2;
  819.  
  820. tfield.maxs_y = 2;
  821. tfield.mins_y = 0 - 2;
  822. tfield.size_y = 4;
  823.  
  824. if (gen1.origin_x > gen2.origin_x)
  825. {
  826. diff = (gen1.origin_x - gen2.origin_x)/2;
  827.  
  828. tfield.origin_x = gen1.origin_x - diff;
  829. tfield.absmin_x = gen2.origin_x;
  830. tfield.absmax_x = gen1.origin_x;
  831.  
  832. tfield.maxs_x = diff;
  833. tfield.mins_x = 0 - diff;
  834. tfield.size_x = diff * 2;
  835.  
  836. }
  837. else
  838. {
  839. diff = (gen2.origin_x - gen1.origin_x)/2;
  840.  
  841. tfield.origin_x = gen2.origin_x - diff;
  842. tfield.absmin_x = gen1.origin_x;
  843. tfield.absmax_x = gen2.origin_x;
  844.  
  845. tfield.maxs_x = diff;
  846. tfield.mins_x = 0 - diff;
  847. tfield.size_x = diff * 2;
  848. }
  849. }
  850. //============================= !!!!!!!!!! ===================
  851. // OMC_FG I think the problem is here ->
  852. // apply stuff
  853. tfield.movetype = #MOVETYPE_NONE;
  854. tfield.solid = #SOLID_BBOX;
  855. setsize(tfield, tfield.mins, tfield.maxs);
  856. setorigin(tfield, tfield.origin);
  857.  
  858. // assign the pointers on the field generators
  859. gen1.martyr_enemy = tfield;
  860. gen2.martyr_enemy = tfield;
  861.  
  862. // assign the pointers to generators on ourselves
  863. tfield.demon_one = gen1;
  864. tfield.demon_two = gen2;
  865.  
  866. // make activation sound
  867. sound (tfield, #CHAN_VOICE, "misc/ffact.wav", 0.2, #ATTN_NORM);
  868.  
  869. // initialize sound flags on field
  870. tfield.has_sensor = #FALSE;
  871. tfield.has_holo = #FALSE;
  872.  
  873. // flash generators
  874. gen1.effects = #EF_DIMLIGHT | #EF_RED;
  875. gen1.has_teleporter = #TRUE;
  876. gen1.skin = 2;
  877. gen2.effects = #EF_DIMLIGHT | #EF_RED;
  878. gen2.has_teleporter = #TRUE;
  879. gen2.skin = 2;
  880. };
  881.  
  882. //=================================================================
  883. // removes the force field (if any)
  884.  
  885. void(entity gen1, entity gen2) Remove_Field =
  886. {
  887. #ifdef OMC_DEBUG
  888. dprint("In Remove_Field\n" );
  889.  
  890. #endif
  891. local float soundsoff;
  892. soundsoff = #FALSE;
  893.  
  894. if (IsValidFieldGen(gen1))
  895. {
  896. gen1.has_sensor = #FALSE;
  897.  
  898. if (IsValidField(gen1.martyr_enemy))
  899. {
  900. Field_StopSounds(gen1.martyr_enemy); // Stops sounds on force field
  901. soundsoff = #TRUE;
  902.  
  903. dremove(gen1.martyr_enemy);
  904. gen1.martyr_enemy = world;
  905. }
  906. }
  907.  
  908. if (IsValidFieldGen(gen2))
  909. {
  910. gen2.has_sensor = #FALSE;
  911.  
  912. if (IsValidField(gen2.martyr_enemy))
  913. {
  914. if (!soundsoff)
  915. Field_StopSounds(gen2.martyr_enemy); // Stops sounds on force field if not done
  916.  
  917. dremove(gen2.martyr_enemy);
  918. gen2.martyr_enemy = world;
  919. }
  920. }
  921. };
  922.  
  923. //======================================================================
  924. // The following 2 functions are used for safety everywhere
  925.  
  926. float(entity field) IsValidField =
  927. {
  928. if (field == world)
  929. return #FALSE;
  930.  
  931. if (field.classname != "force_field")
  932. return #FALSE;
  933.  
  934. return #TRUE;
  935. };
  936.  
  937. float(entity fieldgen) IsValidFieldGen =
  938. {
  939. if (fieldgen == world)
  940. return #FALSE;
  941.  
  942. if (fieldgen.classname != "building_fieldgen")
  943. return #FALSE;
  944.  
  945. return #TRUE;
  946. };
  947.  
  948. //========================================================
  949. // starts or removes sounds on the field
  950.  
  951. void(entity tfield, entity gen1) Field_UpdateSounds =
  952. {
  953. #ifdef OMC_DEBUG
  954. dprint("In Field_UpdateSounds\n" );
  955.  
  956. #endif
  957. //.has_holo : hum
  958. //.has_sensor : shield
  959.  
  960. if (IsValidField(tfield)) // only if there is a field currently
  961. {
  962. local float playhum, playshield;
  963.  
  964. playhum = #FALSE;
  965. playshield = #FALSE;
  966.  
  967. /*if (gen1.has_holo == #FIELDGEN_ISOFF) // for some reason we r not working
  968. {
  969. playhum = #FALSE;
  970. playshield = #FALSE;
  971. }
  972. else if (gen1.has_holo == #FIELDGEN_ISIDLE) // awaiting for link
  973. {
  974. playhum = #FALSE;
  975. playshield = #FALSE;
  976. }
  977. else if (gen1.has_holo == #FIELDGEN_ISDISABLED) // teammate passing thru the field?
  978. {
  979. playhum = #FALSE;
  980. playshield = #FALSE;
  981. }
  982. else*/
  983.  
  984. if (gen1.has_holo == #FIELDGEN_ISENABLED)
  985. {
  986. playhum = #TRUE;
  987. playshield = #FALSE;
  988. }
  989. else if (gen1.has_holo == #FIELDGEN_ISWORKING)
  990. {
  991. playhum = #TRUE;
  992. playshield = #TRUE;
  993. }
  994.  
  995. // ok, lets update the sounds if needed..
  996. if (!playhum)
  997. {
  998. if (tfield.has_holo)
  999. {
  1000. sound(tfield,#CHAN_MISC,"misc/null.wav",0.5,#ATTN_NORM);
  1001. tfield.has_holo = #FALSE;
  1002. }
  1003. }
  1004. else
  1005. {
  1006. if (!tfield.has_holo || tfield.has_tesla < time)
  1007. {
  1008. sound(tfield,#CHAN_MISC,"misc/ffhum.wav",0.4,#ATTN_NORM);
  1009. tfield.has_tesla = time + #FIELD_SOUNDSRATE;
  1010. tfield.has_holo = #TRUE;
  1011. }
  1012. }
  1013.  
  1014. if (!playshield)
  1015. {
  1016. if (tfield.has_sensor)
  1017. {
  1018. sound(tfield,#CHAN_ITEM,"misc/null.wav",0.5,#ATTN_NORM);
  1019. tfield.has_sensor = #FALSE;
  1020. }
  1021. }
  1022. else
  1023. {
  1024. if (!tfield.has_sensor || tfield.has_sentry < time)
  1025. {
  1026. //TODO?: lower volume as (FIELDGEN_WORKTIME - time) decreases
  1027.  
  1028. sound(tfield,#CHAN_ITEM,"misc/ffield.wav",0.5,#ATTN_NORM);
  1029. tfield.has_sentry = time + #FIELD_SOUNDSRATE;
  1030. tfield.has_sensor = #TRUE;
  1031. }
  1032. }
  1033. }
  1034. };
  1035.  
  1036. //====================================================================
  1037. // Called on each force field removal to stop any sounds from it
  1038.  
  1039. void(entity tfield) Field_StopSounds =
  1040. {
  1041. // We dont do any check because this function is called with everything already checked
  1042. sound(tfield,#CHAN_ITEM,"misc/null.wav",0.5,#ATTN_NORM);
  1043. sound(tfield,#CHAN_MISC,"misc/null.wav",0.5,#ATTN_NORM);
  1044. tfield.has_sensor = #FALSE;
  1045. tfield.has_holo = #FALSE;
  1046. };
  1047.  
  1048. //====================================================================
  1049. // do the lightning stuff while field is FIELDGEN_ISWORKING
  1050.  
  1051. void(entity tfield) Field_MakeVisual =
  1052. {
  1053. // To avoid some overhead, only do visual lightning effect sometimes
  1054. if (random() < #FIELD_VISUALFACTOR)
  1055. return;
  1056.  
  1057. if (IsValidField(tfield))
  1058. {
  1059. local float fx, fy;
  1060. local vector tmpvec;
  1061.  
  1062. if (tfield.cnt)
  1063. {
  1064. fy = tfield.origin_y;
  1065. fx = tfield.origin_x + (tfield.size_x/2 - tfield.size_x * random());
  1066. }
  1067. else
  1068. {
  1069. fx = tfield.origin_x;
  1070. fy = tfield.origin_y + (tfield.size_y/2 - tfield.size_y * random());
  1071. }
  1072.  
  1073. tmpvec_x = fx;
  1074. tmpvec_y = fy;
  1075. tmpvec_z = tfield.origin_z - 12;
  1076.  
  1077. WriteByte (#MSG_BROADCAST, #SVC_TEMPENTITY);
  1078.  
  1079. if (random() > 0.5)
  1080. WriteByte (#MSG_BROADCAST, #TE_LIGHTNING2);
  1081. else
  1082. WriteByte (#MSG_BROADCAST, #TE_LIGHTNING1);
  1083.  
  1084. WriteEntity (#MSG_BROADCAST, tfield);
  1085.  
  1086. if (random() > 0.5)
  1087. {
  1088. WriteCoord (#MSG_BROADCAST, fx);
  1089. WriteCoord (#MSG_BROADCAST, fy);
  1090. WriteCoord (#MSG_BROADCAST, tfield.origin_z - 12);
  1091. WriteCoord (#MSG_BROADCAST, fx);
  1092. WriteCoord (#MSG_BROADCAST, fy);
  1093. WriteCoord (#MSG_BROADCAST, tfield.origin_z + 12);
  1094. }
  1095. else
  1096. {
  1097. WriteCoord (#MSG_BROADCAST, fx);
  1098. WriteCoord (#MSG_BROADCAST, fy);
  1099. WriteCoord (#MSG_BROADCAST, tfield.origin_z + 22);
  1100. WriteCoord (#MSG_BROADCAST, fx);
  1101. WriteCoord (#MSG_BROADCAST, fy);
  1102. WriteCoord (#MSG_BROADCAST, tfield.origin_z - 2);
  1103. }
  1104.  
  1105. #ifdef QUAKE_WORLD
  1106. multicast (tmpvec, #MULTICAST_PHS);
  1107. #endif
  1108. }
  1109. };
  1110.  
  1111. //==================================================
  1112. // called every frame by the field generators
  1113.  
  1114. void() FieldGen_think =
  1115. {
  1116. local entity othergen;
  1117. othergen = Find_OtherGen(self); // get our brother
  1118.  
  1119.  
  1120. #ifdef OMC_DEBUG
  1121. local string Str;
  1122.  
  1123. #endif
  1124.  
  1125.  
  1126.  
  1127. // Create the force field if it's possible, or remove it if not and exists
  1128. if (FieldGens_CanLink(self,othergen))
  1129. {
  1130. #ifdef OMC_DEBUG
  1131.  
  1132. dprint("FieldGen_think FieldGens_CAN Link\n" );
  1133.  
  1134. #endif
  1135. // OMC_GROUND minus 1
  1136. Create_Field(self,othergen); // checks redundancy itself
  1137. }
  1138.  
  1139. else
  1140. {
  1141. #ifdef OMC_DEBUG
  1142. dprint("FieldGen_think FieldGens_CANT Link\n" );
  1143.  
  1144. #endif
  1145.  
  1146. Remove_Field(self,othergen); // checks redundancy itself
  1147. }
  1148.  
  1149.  
  1150. // field gens main loop (ai? heh.. my cat is smarter than these force fields)
  1151. if (self.has_holo == #FIELDGEN_ISOFF) // for some reason we r not working
  1152. {
  1153. #ifdef OMC_DEBUG
  1154. dprint("FieldGen_think_1 (FIELDGEN_ISOFF) \n" );
  1155.  
  1156. #endif
  1157. self.effects = 0;
  1158. self.skin = 0;
  1159.  
  1160. if (FieldGen_CanIdle(self)) // can we go idle?
  1161. {
  1162. #ifdef OMC_DEBUG
  1163. dprint("FieldGen_think_1 fieldgen can idle\n" );
  1164.  
  1165. #endif
  1166. self.has_holo = #FIELDGEN_ISIDLE;
  1167. }
  1168. }
  1169. else if (self.has_holo == #FIELDGEN_ISIDLE) // trying to link
  1170. {
  1171. #ifdef OMC_DEBUG
  1172. dprint("FieldGen_think_2 (trying to link)\n" );
  1173.  
  1174. #endif
  1175. self.effects = 0;
  1176. self.skin = 0;
  1177.  
  1178. if (self.no_grenades_1 < time) // trying to link sound/flash time
  1179. {
  1180. #ifdef OMC_DEBUG
  1181. Str=ftos(self.no_grenades_1);
  1182. dprint("FieldGen_think_2.5 self.no_grenades_1: " );
  1183. dprint(Str);
  1184. dprint(", time = " );
  1185. Str=ftos(time);
  1186. dprint(Str);
  1187. dprint("\n" );
  1188.  
  1189. #endif
  1190. sound (self, #CHAN_WEAPON, "misc/fffail.wav", 0.5, #ATTN_IDLE);
  1191. self.skin = 1;
  1192. self.effects = #EF_DIMLIGHT;
  1193. self.no_grenades_1 = time + #FIELDGEN_LINKTIME;
  1194. }
  1195. }
  1196. else if (self.has_holo == #FIELDGEN_ISDISABLED) // teammate passing thru the field?
  1197. {
  1198. #ifdef OMC_DEBUG
  1199. dprint("FieldGen_think_3 - teammate passing thru the field\n" );
  1200.  
  1201. #endif
  1202. self.effects = 0;
  1203. self.skin = 0;
  1204.  
  1205.  
  1206. // OMC_THIS IS WHERE THE PROBLEM IS
  1207. // time check
  1208. if (self.no_grenades_2 < time) // can we go idle?
  1209. {
  1210. #ifdef OMC_DEBUG
  1211. dprint("FieldGen_think_4 (fieldgen is idle)\n" );
  1212.  
  1213. #endif
  1214. self.has_holo = #FIELDGEN_ISIDLE;
  1215. self.tp_grenades_1 = 0;
  1216. }
  1217. }
  1218. else if (self.has_holo == #FIELDGEN_ISENABLED) // we r ready and linked
  1219. {
  1220. #ifdef OMC_DEBUG
  1221. dprint("FieldGen_think_5\n" );
  1222.  
  1223. #endif
  1224. if (!self.has_teleporter)
  1225. {
  1226. self.effects = 0;
  1227. self.skin = 1;
  1228. }
  1229.  
  1230. // omc_FTE THIS IS THERE THE PROBLEM MIGHT BE
  1231. if (self.has_sensor == #FALSE)
  1232. {
  1233. #ifdef OMC_DEBUG
  1234. dprint("FieldGen_think 5.5 self.has_sensor is FALSE, self.has_holo just got set to FIELDGEN_ISIDLE \n" );
  1235.  
  1236. #endif
  1237. self.has_holo = #FIELDGEN_ISIDLE;
  1238. }
  1239.  
  1240. if (self.tp_grenades_1 >= time)
  1241. self.has_holo = #FIELDGEN_ISWORKING;
  1242. }
  1243. else if (self.has_holo == #FIELDGEN_ISWORKING) // hopefully after killing some1..
  1244. {
  1245. #ifdef OMC_DEBUG
  1246. dprint("FieldGen_think_6\n" );
  1247.  
  1248. #endif
  1249. self.effects = #EF_DIMLIGHT;
  1250. self.skin = 2;
  1251.  
  1252. if (self.has_camera <= time)
  1253. {
  1254. self.ammo_cells = self.ammo_cells - #FIELDGEN_CELLSCOST;
  1255.  
  1256. if (self.ammo_cells <= 24 && self.ammo_cells > 24 - #FIELDGEN_CELLSCOST)
  1257. sprint(self.real_owner,#PRINT_HIGH,"Your field generator is low on cells\n");
  1258. else if (self.ammo_cells < #FIELDGEN_CELLSCOST)
  1259. sprint(self.real_owner,#PRINT_HIGH,"Your field generator has run out of cells\n");
  1260.  
  1261. self.has_camera = time + #FIELDGEN_WORKING_RATE;
  1262. }
  1263.  
  1264. if (self.has_sensor == #FALSE)
  1265. {
  1266. #ifdef OMC_DEBUG
  1267. dprint("FieldGen_think_6.5 .has_sensor == FALSE\n" );
  1268.  
  1269. #endif
  1270.  
  1271. self.has_holo = #FIELDGEN_ISIDLE;
  1272. }
  1273. else if (self.tp_grenades_1 <= time)
  1274. self.has_holo = #FIELDGEN_ISENABLED;
  1275. }
  1276.  
  1277. if (!FieldGen_CanIdle(self)) // turn us off if needed
  1278. self.has_holo = #FIELDGEN_ISOFF;
  1279.  
  1280. Field_UpdateSounds(self.martyr_enemy,self); // update force field sounds
  1281.  
  1282. self.has_teleporter = #FALSE; // resets 'flash' status bypass
  1283. self.nextthink = time + 0.1;
  1284. };
  1285.  
  1286. //=======================================================================
  1287. // returns TRUE if the generator could currently go to idle status
  1288.  
  1289. float(entity fieldgen) FieldGen_CanIdle =
  1290. {
  1291.  
  1292. if (!(IsValidFieldGen(fieldgen)))
  1293. {
  1294. #ifdef OMC_DEBUG
  1295. dprint("FieldGen_CanIdle IsValidFieldGen returning false\n" );
  1296.  
  1297. #endif
  1298.  
  1299. return #FALSE;
  1300. }
  1301.  
  1302. if (fieldgen.ammo_cells >= #FIELDGEN_CELLSCOST &&
  1303. !(fieldgen.is_malfunctioning & #SCREWUP_FOUR)
  1304. && fieldgen.health > 0)
  1305. {
  1306. #ifdef OMC_DEBUG
  1307. dprint("FieldGen_CanIdle returning TRUE\n" );
  1308.  
  1309. #endif
  1310. return #TRUE;
  1311. }
  1312.  
  1313. #ifdef OMC_DEBUG
  1314. dprint("FieldGen_CanIdle returning (default) false\n" );
  1315.  
  1316. #endif
  1317.  
  1318. return #FALSE;
  1319. };
  1320.  
  1321. //=======================================================================
  1322. // returns TRUE if both generators could currently generate the field
  1323.  
  1324. float(entity fieldgen1, entity fieldgen2) FieldGens_CanLink =
  1325. {
  1326.  
  1327. //!!!!!!!!!!!!!!!
  1328. // OMC bug 25 oct 2010 ok this returns false if teammate walks through!!
  1329. //!!!!!!!!!!!!!!!!!!
  1330.  
  1331.  
  1332.  
  1333. if (!(IsValidFieldGen(fieldgen1)) || !(IsValidFieldGen(fieldgen2)))
  1334. {
  1335. #ifdef OMC_DEBUG
  1336. dprint("FieldGens_CanLink_1\n" );
  1337.  
  1338. #endif
  1339. return #FALSE;
  1340. }
  1341.  
  1342. if (!visible2(fieldgen1,fieldgen2))
  1343. {
  1344. #ifdef OMC_DEBUG
  1345. dprint("FieldGens_CanLink_2 can't see them\n" );
  1346.  
  1347. #endif
  1348. return #FALSE;
  1349. }
  1350.  
  1351. local float r;
  1352. r = vlen(fieldgen1.origin - fieldgen2.origin); // get distance between generators
  1353.  
  1354. // Both fieldgens hacked
  1355. if ((fieldgen1.all_active & #IMPROVED_FOUR && fieldgen2.all_active & #IMPROVED_FOUR) && r > #FIELDGEN_HACKEDRANGE2)
  1356. {
  1357. #ifdef OMC_DEBUG
  1358. dprint("FieldGens_CanLink_3 both FGs hacked\n" );
  1359.  
  1360. #endif
  1361. return #FALSE;
  1362. }
  1363.  
  1364. // Only 1 fieldgen hacked
  1365. if ( ((fieldgen1.all_active & #IMPROVED_FOUR && !(fieldgen2.all_active & #IMPROVED_FOUR)) || (fieldgen2.all_active & #IMPROVED_FOUR && !(fieldgen1.all_active & #IMPROVED_FOUR))) && r > #FIELDGEN_HACKEDRANGE)
  1366. {
  1367. #ifdef OMC_DEBUG
  1368. dprint("FieldGens_CanLink_4\n" );
  1369.  
  1370. #endif
  1371. return #FALSE;
  1372. }
  1373.  
  1374. // None hacked for range
  1375. if (r > #FIELDGEN_RANGE && !(fieldgen1.all_active & #IMPROVED_FOUR || fieldgen2.all_active & #IMPROVED_FOUR))
  1376. {
  1377. #ifdef OMC_DEBUG
  1378. dprint("FieldGens_CanLink_5 none hacked\n" );
  1379.  
  1380. #endif
  1381. return #FALSE;
  1382. }
  1383.  
  1384. if (fieldgen1.origin_z != fieldgen2.origin_z) // Different heights?
  1385. {
  1386. #ifdef OMC_DEBUG
  1387. dprint("FieldGens_CanLink_6 different heights\n" );
  1388.  
  1389. #endif
  1390. return #FALSE;
  1391. }
  1392.  
  1393. if (fieldgen1.origin_x != fieldgen2.origin_x && fieldgen1.origin_y != fieldgen2.origin_y) // Unaligned?
  1394. {
  1395. #ifdef OMC_DEBUG
  1396. dprint("FieldGens_CanLink_7 not aligned\n" );
  1397.  
  1398. #endif
  1399. return #FALSE;
  1400. }
  1401.  
  1402. if (fieldgen1.has_holo == #FIELDGEN_ISDISABLED || fieldgen2.has_holo == #FIELDGEN_ISDISABLED)
  1403. {
  1404. #ifdef OMC_DEBUG
  1405. dprint("FieldGens_CanLink_8 FGs are disabled\n" );
  1406.  
  1407. #endif
  1408. return #FALSE;
  1409. }
  1410.  
  1411. if (fieldgen1.has_holo == #FIELDGEN_ISOFF || fieldgen2.has_holo == #FIELDGEN_ISOFF)
  1412. {
  1413. #ifdef OMC_DEBUG
  1414. dprint("FieldGens_CanLink_9 FGs are off\n" );
  1415.  
  1416. #endif
  1417. return #FALSE;
  1418. }
  1419.  
  1420. // Return TRUE only if basic conditions on CanIdle() are meet
  1421. if (FieldGen_CanIdle(fieldgen1) && FieldGen_CanIdle(fieldgen2))
  1422. {
  1423. #ifdef OMC_DEBUG
  1424. dprint("FieldGens_CanLink_10 -basic conditions on CanIdle() are met\n" );
  1425.  
  1426. #endif
  1427. return #TRUE;
  1428. }
  1429.  
  1430. return #FALSE;
  1431. };
  1432.  
  1433. //=============================================================================================
  1434. // initialize field generator stuff just after beeing built, called on engineer.qc
  1435.  
  1436. void(entity fieldgen) FieldGen_Built =
  1437. {
  1438. fieldgen.touch = SUB_Null;
  1439. fieldgen.think = FieldGen_think;
  1440. fieldgen.nextthink = time + 0.1;
  1441. fieldgen.has_holo = #FIELDGEN_ISIDLE; // we start on IDLE status (searching for other gen to link)
  1442. fieldgen.has_sensor = #FALSE;
  1443. fieldgen.no_grenades_1 = time + 3;
  1444. fieldgen.martyr_enemy = world;
  1445. };
  1446.  
  1447. //==============================================================
  1448. // returns our other generator (if any)
  1449.  
  1450. entity(entity fieldgen) Find_OtherGen =
  1451. {
  1452. local entity te;
  1453. local float foundit;
  1454. te = world;
  1455. foundit = #FALSE;
  1456.  
  1457. te = find(world, classname, "building_fieldgen");
  1458. while (te != world && foundit == #FALSE)
  1459. {
  1460. if (te.real_owner == fieldgen.real_owner) // is it ours?
  1461. if (te != fieldgen) // and not the same generator..
  1462. foundit = #TRUE; // yeah, found it
  1463.  
  1464. if (foundit == #FALSE) // our search must continue...
  1465. te = find(te, classname, "building_fieldgen");
  1466. }
  1467.  
  1468. return te;
  1469. };
  1470.  
  1471. //=========================================================================================
  1472. // returns the place where field gen will be built related to player current pos and yaw
  1473. // called on engineer.qc, place is the origin passed where other kind of buildings are placed
  1474.  
  1475. vector(vector place) WhereGen =
  1476. {
  1477. // if we have no field generator currently, it can be placed anywhere
  1478. if (self.has_fieldgen == 0) return place;
  1479.  
  1480. local vector retval;
  1481. local float r, distx, disty, foundit;
  1482. local entity te;
  1483.  
  1484. foundit = #FALSE;
  1485.  
  1486. // find the other generator
  1487. te = find(world, classname, "building_fieldgen");
  1488. while (te != world && foundit == #FALSE)
  1489. {
  1490. if (te.real_owner == self) // is it ours?
  1491. foundit = #TRUE; // yeah, found it
  1492.  
  1493. if (foundit == #FALSE) // our search must continue...
  1494. te = find(te, classname, "building_fieldgen");
  1495. }
  1496.  
  1497. // check for error getting the other gen
  1498. if (te == world || te.classname != "building_fieldgen" || foundit == #FALSE)
  1499. {
  1500. RPrint("BUG: Error in field generator placement routine. 'WhereGen()'\n");
  1501. return place;
  1502. }
  1503.  
  1504. // calculate the new generator pos
  1505. distx = fabs(place_x - te.origin_x);
  1506. disty = fabs(place_y - te.origin_y);
  1507. retval = place;
  1508.  
  1509. if (distx < disty)
  1510. {
  1511. retval_x = te.origin_x; // adjust it in line
  1512.  
  1513. r = vlen(self.origin - retval); // get distance from us (player)
  1514. if (r > 200) // we r too far away?
  1515. retval = place; // then bypass the calc
  1516. }
  1517. else
  1518. {
  1519. retval_y = te.origin_y; // adjust line up
  1520.  
  1521. r = vlen(self.origin - retval); // get distance from us (player)
  1522. if (r > 200) // we r too far away?
  1523. retval = place; // then bypass the calc
  1524. }
  1525.  
  1526. // print message if they wont link
  1527. if (!vis2orig(te.origin,retval))
  1528. sprint(self, #PRINT_HIGH, "Your field generators won't link, there are obstacles between them!\n");
  1529.  
  1530. r = vlen(te.origin - retval); // get distance between generators
  1531. if (te.all_active & #IMPROVED_FOUR && r > #FIELDGEN_HACKEDRANGE)
  1532. sprint(self, #PRINT_HIGH, "Your field generators are too far away to link, even hacked\n");
  1533.  
  1534. if (r > #FIELDGEN_RANGE && !(te.all_active & #IMPROVED_FOUR))
  1535. sprint(self, #PRINT_HIGH, "Your field generators are too far away to link\n");
  1536.  
  1537. /*if (retval_z != te.origin_z)
  1538. sprint(self, #PRINT_HIGH, "Your field generators are at different heights, they won't link\n");*/
  1539.  
  1540. if (retval_x != te.origin_x && retval_y != te.origin_y)
  1541. sprint(self, #PRINT_HIGH, "Your field generators are not lined up, they won't link\n");
  1542.  
  1543. // return the final building place
  1544. return retval;
  1545. };
  1546.  
  1547. //======================================================================
  1548. // damn! our field generator was destroyed. Force field must go down..
  1549.  
  1550. void() FieldGen_Die =
  1551. {
  1552. self.real_owner.has_fieldgen = self.real_owner.has_fieldgen - 1;
  1553. if (self.real_owner.has_fieldgen < 0) self.real_owner.has_fieldgen = 0;
  1554.  
  1555. WriteByte (#MSG_BROADCAST, #SVC_TEMPENTITY);
  1556. WriteByte (#MSG_BROADCAST, #TE_EXPLOSION);
  1557. WriteCoord (#MSG_BROADCAST, self.origin_x);
  1558. WriteCoord (#MSG_BROADCAST, self.origin_y);
  1559. WriteCoord (#MSG_BROADCAST, self.origin_z);
  1560. #ifdef QUAKE_WORLD
  1561. multicast (self.origin, #MULTICAST_PHS);
  1562. #endif
  1563.  
  1564. // check if field should be removed..
  1565. local entity othergen;
  1566. othergen = Find_OtherGen(self);
  1567.  
  1568. if (IsValidFieldGen(othergen))
  1569. Remove_Field(self, othergen);
  1570. else
  1571. Remove_Field(self, world); // extra removal, not needed i think...
  1572.  
  1573. sprint(self.real_owner, #PRINT_HIGH, "Your field generator was destroyed.\n");
  1574.  
  1575. local entity sprite;
  1576.  
  1577. sprite = SpawnSprite(1,#SPRITE_AIRBURST,self.origin,'0 0 0',#SPRITEMOVE_UPSLOW,0.1);
  1578.  
  1579. if (sprite)
  1580. {
  1581. sprite.effects = #EF_DIMLIGHT;
  1582.  
  1583. if (self.real_owner.team_no == 1)
  1584. sprite.effects = #EF_DIMLIGHT | #EF_BLUE;
  1585. else if (self.real_owner.team_no == 2)
  1586. sprite.effects = #EF_DIMLIGHT | #EF_RED;
  1587. }
  1588.  
  1589. ThrowGib("progs/tesgib3.mdl", -70,#TRUE,0,0, #FALSE);
  1590.  
  1591. dremove(self);
  1592. };
  1593.  
  1594. //=========================================================================
  1595. // Engineer has used a Spanner on the field generator
  1596.  
  1597. void(entity field) Engineer_UseFieldGen =
  1598. {
  1599. self.building = field;
  1600.  
  1601. if (Teammate(self.building.real_owner.team_no,self.team_no) && self.building.is_malfunctioning & #SCREWUP_THREE)
  1602. {
  1603. sprint(self,#PRINT_HIGH,"Trapped field generator, have a nice day!\n");
  1604.  
  1605. deathmsg = #DMSG_FGTRAP;
  1606. sound (self, #CHAN_MISC, "effects/crunch.wav", 1, #ATTN_NONE);
  1607. TF_T_Damage(self, self, self, self.health + 60, 0, #TF_TD_OTHER);
  1608. return;
  1609. }
  1610.  
  1611. local entity dist_checker;
  1612. local string st;
  1613.  
  1614. sprint(self, #PRINT_HIGH, "Field Generator has ");
  1615. st = ftos(field.health);
  1616. sprint(self, #PRINT_HIGH, st);
  1617. sprint(self, #PRINT_HIGH, "¯");
  1618. st = ftos(field.max_health);
  1619. sprint(self, #PRINT_HIGH, st);
  1620. sprint(self, #PRINT_HIGH, " èåáìôè, ");
  1621. st = ftos(field.ammo_cells);
  1622. sprint(self, #PRINT_HIGH, st);
  1623. sprint(self, #PRINT_HIGH, "¯");
  1624. st = ftos(field.maxammo_cells);
  1625. sprint(self, #PRINT_HIGH, st);
  1626. sprint(self, #PRINT_HIGH, " ãåììó\n");
  1627.  
  1628. // Pop up the menu
  1629. self.current_menu = #MENU_ENGINEER_FIX_FIELDGEN;
  1630. self.menu_count = #MENU_REFRESH_RATE;
  1631.  
  1632. //dodgy
  1633. if (teamplay != 0 && !Teammate(self.building.real_owner.team_no,self.team_no)) {
  1634. Menu_EngineerFix_FieldGen_Input(4);
  1635. return;
  1636. }
  1637.  
  1638. // Start a Distance checker, which removes the menu if the player
  1639. // gets too far away from the field generator.
  1640. dist_checker = spawn();
  1641. dist_checker.classname = "timer";
  1642. dist_checker.owner = self;
  1643. dist_checker.enemy = field;
  1644. dist_checker.think = CheckDistance;
  1645. dist_checker.nextthink = time + 0.3;
  1646. };
  1647.  
  1648. //===========================================================================
  1649. // Any external code should use this function, where needed
  1650.  
  1651. void(entity tfield, vector where, entity thing) FieldEvent =
  1652. {
  1653. FieldExplosion(tfield, where, thing);
  1654. PutFieldWork(tfield);
  1655. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement