]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Turrets: cleanup
authorTimePath <andrew.hardaker1995@gmail.com>
Mon, 28 Sep 2015 05:29:21 +0000 (15:29 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Mon, 28 Sep 2015 05:33:20 +0000 (15:33 +1000)
37 files changed:
qcsrc/client/main.qc
qcsrc/client/progs.inc
qcsrc/common/nades.qc
qcsrc/common/turrets/all.inc
qcsrc/common/turrets/all.qc
qcsrc/common/turrets/all.qh
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/cl_turrets.qh
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/sv_turrets.qh
qcsrc/common/turrets/turret.qh [new file with mode: 0644]
qcsrc/common/turrets/turret/ewheel.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/flac.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/fusionreactor.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/hellion.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/hk.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/machinegun.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/mlrs.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/phaser.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/plasma.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/plasma_dual.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/tesla.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/walker.qc [new file with mode: 0644]
qcsrc/common/turrets/unit/ewheel.qc [deleted file]
qcsrc/common/turrets/unit/flac.qc [deleted file]
qcsrc/common/turrets/unit/fusionreactor.qc [deleted file]
qcsrc/common/turrets/unit/hellion.qc [deleted file]
qcsrc/common/turrets/unit/hk.qc [deleted file]
qcsrc/common/turrets/unit/machinegun.qc [deleted file]
qcsrc/common/turrets/unit/mlrs.qc [deleted file]
qcsrc/common/turrets/unit/phaser.qc [deleted file]
qcsrc/common/turrets/unit/plasma.qc [deleted file]
qcsrc/common/turrets/unit/plasma_dual.qc [deleted file]
qcsrc/common/turrets/unit/tesla.qc [deleted file]
qcsrc/common/turrets/unit/walker.qc [deleted file]
qcsrc/server/g_world.qc
qcsrc/server/progs.inc

index ca31f32f71bf7b5afb82bb487a650653d1da108d..8bb66c874c1f2efd7f222ae3773e6b067a03bed3 100644 (file)
@@ -146,7 +146,6 @@ void CSQC_Init(void)
 
        // needs to be done so early because of the constants they create
        static_init();
-       CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
        CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
index 1b9c587abb613355193505564e30ddbff4a3cada..449692d5f2fd1401c91b621a8d6027c4f79a7cff 100644 (file)
 #include "../common/items/all.qc"
 #include "../common/monsters/all.qc"
 #include "../common/mutators/all.qc"
+#include "../common/turrets/all.qc"
 #include "../common/vehicles/all.qc"
 #include "../common/weapons/all.qc"
 
 #include "../common/turrets/cl_turrets.qc"
-#include "../common/turrets/all.qc"
 
 #include "../common/triggers/include.qc"
 
index f361730ba16b29f5a9fe150e6272586e74afe0b3..d750871257ab2c4ef5b8ed0d0cbd239b8a154d54 100644 (file)
@@ -78,7 +78,7 @@ void ent_healer()
 {SELFPARAM();
        int sf = ReadByte();
 
-       if(sf & TNSF_SETUP)
+       if(sf & 1)
        {
                self.origin_x = ReadCoord();
                self.origin_y = ReadCoord();
index 04bb10f6a548e67da5fba28ed487c71a1300f52c..5c9f1e16f0a73bee0bfc91e061e4f205896aebda 100644 (file)
@@ -1,12 +1,12 @@
-#include "unit/ewheel.qc"
-#include "unit/flac.qc"
-#include "unit/fusionreactor.qc"
-#include "unit/hellion.qc"
-#include "unit/hk.qc"
-#include "unit/machinegun.qc"
-#include "unit/mlrs.qc"
-#include "unit/phaser.qc"
-#include "unit/plasma.qc"
-#include "unit/plasma_dual.qc"
-#include "unit/tesla.qc"
-#include "unit/walker.qc"
+#include "turret/ewheel.qc"
+#include "turret/flac.qc"
+#include "turret/fusionreactor.qc"
+#include "turret/hellion.qc"
+#include "turret/hk.qc"
+#include "turret/machinegun.qc"
+#include "turret/mlrs.qc"
+#include "turret/phaser.qc"
+#include "turret/plasma.qc"
+#include "turret/plasma_dual.qc"
+#include "turret/tesla.qc"
+#include "turret/walker.qc"
index f0fc7195a84b244c691a67a2830b093d9a374618..c23a13861ecc9a182e11d16abb516b440cb1908e 100644 (file)
@@ -1,5 +1,22 @@
 #include "all.qh"
 
+Turret get_turretinfo(int id)
+{
+    if (id < 1 || id > TUR_COUNT - 1)
+        return TUR_Null;
+    Turret m = turret_info[id];
+    if (m) return m;
+    return TUR_Null;
+}
+
+#ifdef SVQC
+#include "sv_turrets.qh"
+#endif
+
+#ifdef CSQC
+#include "cl_turrets.qh"
+#endif
+
 #define IMPLEMENTATION
 #include "all.inc"
 #undef IMPLEMENTATION
index 4f8a728028074f31aabfc02b9ae586532d77ca2a..3e4af08f63931d40b8de1868bb39fb595c4bfe75 100644 (file)
@@ -1,147 +1,8 @@
-#ifndef TURRETS_H
-#define TURRETS_H
+#ifndef TURRETS_ALL_H
+#define TURRETS_ALL_H
 
-// turret requests
-#define TR_SETUP          1 // (BOTH) setup turret data
-#define TR_THINK                 2 // (SERVER) logic to run every frame
-#define TR_DEATH          3 // (SERVER) called when turret dies
-#define TR_PRECACHE       4 // (BOTH) precaches models/sounds used by this turret
-#define TR_ATTACK         5 // (SERVER) called when turret attacks
-#define TR_CONFIG         6 // (ALL)
+#include "turret.qh"
 
-// functions:
-entity get_turretinfo(int id);
-
-// fields:
-.entity tur_head;
-
-// target selection flags
-.int target_select_flags;
-.int target_validate_flags;
-const int TFL_TARGETSELECT_NO = 2; // don't automatically find targets
-const int TFL_TARGETSELECT_LOS = 4; // require line of sight to find targets
-const int TFL_TARGETSELECT_PLAYERS = 8; // target players
-const int TFL_TARGETSELECT_MISSILES = 16; // target projectiles
-const int TFL_TARGETSELECT_TRIGGERTARGET = 32; // respond to turret_trigger_target events
-const int TFL_TARGETSELECT_ANGLELIMITS = 64; // apply extra angular limits to target selection
-const int TFL_TARGETSELECT_RANGELIMITS = 128; // limit target selection range
-const int TFL_TARGETSELECT_TEAMCHECK = 256; // don't attack teammates
-const int TFL_TARGETSELECT_NOBUILTIN = 512; // only attack targets when triggered
-const int TFL_TARGETSELECT_OWNTEAM = 1024; // only attack teammates
-const int TFL_TARGETSELECT_NOTURRETS = 2048; // don't attack other turrets
-const int TFL_TARGETSELECT_FOV = 4096; // extra limits to attack range
-const int TFL_TARGETSELECT_MISSILESONLY = 8192; // only attack missiles
-
-// aim flags
-.int aim_flags;
-const int TFL_AIM_NO = 1; // no aiming
-const int TFL_AIM_SPLASH = 2; // aim for ground around the target's feet
-const int TFL_AIM_LEAD = 4; // try to predict target movement
-const int TFL_AIM_SHOTTIMECOMPENSATE = 8; // compensate for shot traveltime when leading
-const int TFL_AIM_ZPREDICT = 16; // predict target's z position at impact
-const int TFL_AIM_SIMPLE = 32; // aim at player's current location
-
-// tracking flags
-.int track_flags;
-const int TFL_TRACK_NO = 2; // don't move head
-const int TFL_TRACK_PITCH = 4; // pitch head
-const int TFL_TRACK_ROTATE = 8; // rotate head
-
-// prefire checks
-.int firecheck_flags;
-const int TFL_FIRECHECK_DEAD = 4; // don't attack dead targets (zombies?)
-const int TFL_FIRECHECK_DISTANCES = 8; // another range check
-const int TFL_FIRECHECK_LOS = 16; // line of sight
-const int TFL_FIRECHECK_AIMDIST = 32; // consider distance impactpoint<->aimspot
-const int TFL_FIRECHECK_REALDIST = 64; // consider enemy origin<->impactpoint
-const int TFL_FIRECHECK_ANGLEDIST = 128; // consider angular diff head<->aimspot
-const int TFL_FIRECHECK_TEAMCHECK = 256; // don't attack teammates
-const int TFL_FIRECHECK_AFF = 512; // try to avoid any friendly fire
-const int TFL_FIRECHECK_AMMO_OWN = 1024; // own ammo needs to be larger than damage dealt
-const int TFL_FIRECHECK_AMMO_OTHER = 2048; // target's ammo needs to be less than max
-const int TFL_FIRECHECK_REFIRE = 4096; // check single attack finished delays
-const int TFL_FIRECHECK_NO = 16384; // no prefire checks
-
-// attack flags
-.int shoot_flags;
-const int TFL_SHOOT_NO = 64; // no attacking
-const int TFL_SHOOT_VOLLY = 2; // fire in vollies
-const int TFL_SHOOT_VOLLYALWAYS = 4; // always do a full volly, even if target is lost
-const int TFL_SHOOT_HITALLVALID = 8; // loop through all valid targets
-const int TFL_SHOOT_CLEARTARGET = 16; // lose target after attack (after volly is done if in volly mode)
-const int TFL_SHOOT_CUSTOM = 32; // custom attacking
-
-// turret capabilities
-.int turret_flags;
-const int TUR_FLAG_NONE = 0; // no abilities
-const int TUR_FLAG_SNIPER = 2; // sniping turret
-const int TUR_FLAG_SPLASH = 4; // can deal splash damage
-const int TUR_FLAG_HITSCAN = 8; // hit scan
-const int TUR_FLAG_MULTIGUN = 16; // multiple guns
-const int TUR_FLAG_GUIDED = 32; // laser guided projectiles
-const int TUR_FLAG_SLOWPROJ = 64; // turret fires slow projectiles
-const int TUR_FLAG_MEDPROJ = 128; // turret fires medium projectiles
-const int TUR_FLAG_FASTPROJ = 256; // turret fires fast projectiles
-const int TUR_FLAG_PLAYER = 512; // can damage players
-const int TUR_FLAG_MISSILE = 1024; // can damage missiles
-const int TUR_FLAG_SUPPORT = 2048; // supports other units
-const int TUR_FLAG_AMMOSOURCE = 4096; // can provide ammunition
-const int TUR_FLAG_RECIEVETARGETS = 8192; // can recieve targets from external sources
-const int TUR_FLAG_MOVE = 16384; // can move
-const int TUR_FLAG_ROAM = 32768; // roams around if not attacking
-const int TUR_FLAG_ISTURRET = 65536; // identifies this unit as a turret
-
-// ammo types
-#define ammo_flags currentammo
-const int TFL_AMMO_NONE = 64; // doesn't use ammo
-const int TFL_AMMO_ENERGY = 2; // uses power
-const int TFL_AMMO_BULLETS = 4; // uses bullets
-const int TFL_AMMO_ROCKETS = 8; // uses explosives
-const int TFL_AMMO_RECHARGE = 16; // regenerates ammo
-const int TFL_AMMO_RECIEVE = 32; // can recieve ammo from support units
-
-// damage flags
-.int damage_flags;
-const int TFL_DMG_NO = 256; // doesn't take damage
-const int TFL_DMG_YES = 2; // can be damaged
-const int TFL_DMG_TEAM = 4; // can be damaged by teammates
-const int TFL_DMG_RETALIATE = 8; // target attackers
-const int TFL_DMG_RETALIATE_TEAM = 16; // target attackers, even if on same team
-const int TFL_DMG_TARGETLOSS = 32; // loses target when damaged
-const int TFL_DMG_AIMSHAKE = 64; // damage throws off aim
-const int TFL_DMG_HEADSHAKE = 128; // damage shakes head
-const int TFL_DMG_DEATH_NORESPAWN = 256; // no re-spawning
-
-// spawn flags
-const int TSF_SUSPENDED = 1;
-const int TSF_TERRAINBASE = 2; // currently unused
-const int TSF_NO_AMMO_REGEN = 4; // disable builtin ammo regeneration
-const int TSF_NO_PATHBREAK = 8; // don't break path to chase enemies, will still fire at them if possible
-const int TSL_NO_RESPAWN = 16; // don't re-spawn
-const int TSL_ROAM = 32; // roam while idle
-
-// send flags
-const int TNSF_UPDATE       = 2;
-const int TNSF_STATUS       = 4;
-const int TNSF_SETUP        = 8;
-const int TNSF_ANG          = 16;
-const int TNSF_AVEL         = 32;
-const int TNSF_MOVE         = 64;
-.float anim_start_time;
-const int TNSF_ANIM         = 128;
-
-const int TNSF_FULL_UPDATE  = 16777215;
-
-
-// other useful macros
-#define TUR_ACTION(turrettype,mrequest) (get_turretinfo(turrettype)).turret_func(mrequest)
-#define TUR_NAME(turrettype) (get_turretinfo(turrettype)).turret_name
-
-// =====================
-//  Turret Registration
-// =====================
-
-float t_null(float dummy);
 void register_turret(entity e, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname);
 
 const int TUR_MAXCOUNT = 24;
@@ -164,37 +25,6 @@ REGISTER_REGISTRY(RegisterTurrets)
        _REGISTER_TURRET(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname)
 #endif
 
-float t_null(float dummy) { return 0; }
-
-CLASS(Turret, Object)
-    ATTRIB(Turret, m_id, int, 0)
-
-    ATTRIB(Turret, turretid, int, 0)
-    /** short name */
-    ATTRIB(Turret, netname, string, string_null)
-    /** human readable name */
-    ATTRIB(Turret, turret_name, string, string_null)
-    /** t_... */
-    ATTRIB(Turret, turret_func, float(float), t_null)
-    /** currently a copy of the model */
-    ATTRIB(Turret, mdl, string, string_null)
-    /** full name of model */
-    ATTRIB(Turret, model, string, string_null)
-    /** full name of tur_head model */
-    ATTRIB(Turret, head_model, string, string_null)
-    /** TODO: deprecate! */
-    ATTRIB(Turret, cvar_basename, string, string_null)
-
-    ATTRIB(Turret, spawnflags, int, 0)
-    /** turret hitbox size */
-    ATTRIB(Turret, mins, vector, '0 0 0')
-    /** turret hitbox size */
-    ATTRIB(Turret, maxs, vector, '0 0 0')
-
-    METHOD(Turret, display, void(entity this, void(string name, string icon) returns)) {
-        returns(this.turret_name, string_null);
-    }
-
 void register_turret(Turret e, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname)
 {
        e.classname = "turret_info";
@@ -210,8 +40,8 @@ void register_turret(Turret e, float(float) func, float turretflags, vector min_
        e.model = strzone(strcat("models/turrets/", modelname));
        e.head_model = strzone(strcat("models/turrets/", headmodelname));
 }
-ENDCLASS(Turret)
 
+entity get_turretinfo(int id);
 
 REGISTER_TURRET(Null,
        t_null,
@@ -224,17 +54,6 @@ REGISTER_TURRET(Null,
        "Turret"
 );
 
-entity get_turretinfo(float id)
-{
-       entity m;
-       if(id < 1 || id > TUR_COUNT - 1)
-               return TUR_Null;
-       m = turret_info[id];
-       if(m)
-               return m;
-       return TUR_Null;
-}
-
 #include "all.inc"
 
 #endif
index b2a0fe1b53bcc798b1421299487f63a619dbe835..94fb4ae3f4f7c64289f42975cb0aed56dc417624 100644 (file)
@@ -1,5 +1,3 @@
-#include "all.qh"
-
 void turret_remove()
 {SELFPARAM();
        remove(self.tur_head);
index f8ea64ad1151ce6bc873ca6a4feac7aba6a78d55..0f8ff9485117807a5f7e752a54b17eba6e3f3d42 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef CL_TURRETS_H
 #define CL_TURRETS_H
 
-#include "all.qh"
-
 void ent_turret();
 
 #endif
index c17061b22f0211422b48619fc1da96849e0ff222..337b2789ac8e0211edb9e6e1b090f116607025b4 100644 (file)
@@ -1,5 +1,4 @@
 #ifdef SVQC
-#include "all.qh"
 #include "../../server/autocvars.qh"
 
 // Generic aiming
index 1a4ade6806b29e0a713fdb63bb0c0b2da2a6e9ce..4eca2c6fb1f9d0ac864d58881c4174a9b0b9081d 100644 (file)
@@ -1,7 +1,11 @@
 #ifndef SV_TURRETS_H
 #define SV_TURRETS_H
 
-#include "all.qh"
+entity turret_projectile(string _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim);
+void turret_projectile_explode();
+float turret_validate_target(entity e_turret, entity e_target, float validate_flags);
+float turret_firecheck();
+entity turret_select_target();
 
 // turret fields
 .float ticrate; // interal ai think rate
diff --git a/qcsrc/common/turrets/turret.qh b/qcsrc/common/turrets/turret.qh
new file mode 100644 (file)
index 0000000..e31d93f
--- /dev/null
@@ -0,0 +1,173 @@
+#ifndef TURRET_H
+#define TURRET_H
+
+// turret requests
+const int TR_SETUP = 1; // (BOTH) setup turret data
+const int TR_THINK = 2; // (SERVER) logic to run every frame
+const int TR_DEATH = 3; // (SERVER) called when turret dies
+const int TR_PRECACHE = 4; // (BOTH) precaches models/sounds used by this turret
+const int TR_ATTACK = 5; // (SERVER) called when turret attacks
+const int TR_CONFIG = 6; // (ALL)
+
+// functions:
+entity get_turretinfo(int id);
+
+// fields:
+.entity tur_head;
+
+// target selection flags
+.int target_select_flags;
+.int target_validate_flags;
+const int TFL_TARGETSELECT_NO = 2; // don't automatically find targets
+const int TFL_TARGETSELECT_LOS = 4; // require line of sight to find targets
+const int TFL_TARGETSELECT_PLAYERS = 8; // target players
+const int TFL_TARGETSELECT_MISSILES = 16; // target projectiles
+const int TFL_TARGETSELECT_TRIGGERTARGET = 32; // respond to turret_trigger_target events
+const int TFL_TARGETSELECT_ANGLELIMITS = 64; // apply extra angular limits to target selection
+const int TFL_TARGETSELECT_RANGELIMITS = 128; // limit target selection range
+const int TFL_TARGETSELECT_TEAMCHECK = 256; // don't attack teammates
+const int TFL_TARGETSELECT_NOBUILTIN = 512; // only attack targets when triggered
+const int TFL_TARGETSELECT_OWNTEAM = 1024; // only attack teammates
+const int TFL_TARGETSELECT_NOTURRETS = 2048; // don't attack other turrets
+const int TFL_TARGETSELECT_FOV = 4096; // extra limits to attack range
+const int TFL_TARGETSELECT_MISSILESONLY = 8192; // only attack missiles
+
+// aim flags
+.int aim_flags;
+const int TFL_AIM_NO = 1; // no aiming
+const int TFL_AIM_SPLASH = 2; // aim for ground around the target's feet
+const int TFL_AIM_LEAD = 4; // try to predict target movement
+const int TFL_AIM_SHOTTIMECOMPENSATE = 8; // compensate for shot traveltime when leading
+const int TFL_AIM_ZPREDICT = 16; // predict target's z position at impact
+const int TFL_AIM_SIMPLE = 32; // aim at player's current location
+
+// tracking flags
+.int track_flags;
+const int TFL_TRACK_NO = 2; // don't move head
+const int TFL_TRACK_PITCH = 4; // pitch head
+const int TFL_TRACK_ROTATE = 8; // rotate head
+
+// prefire checks
+.int firecheck_flags;
+const int TFL_FIRECHECK_DEAD = 4; // don't attack dead targets (zombies?)
+const int TFL_FIRECHECK_DISTANCES = 8; // another range check
+const int TFL_FIRECHECK_LOS = 16; // line of sight
+const int TFL_FIRECHECK_AIMDIST = 32; // consider distance impactpoint<->aimspot
+const int TFL_FIRECHECK_REALDIST = 64; // consider enemy origin<->impactpoint
+const int TFL_FIRECHECK_ANGLEDIST = 128; // consider angular diff head<->aimspot
+const int TFL_FIRECHECK_TEAMCHECK = 256; // don't attack teammates
+const int TFL_FIRECHECK_AFF = 512; // try to avoid any friendly fire
+const int TFL_FIRECHECK_AMMO_OWN = 1024; // own ammo needs to be larger than damage dealt
+const int TFL_FIRECHECK_AMMO_OTHER = 2048; // target's ammo needs to be less than max
+const int TFL_FIRECHECK_REFIRE = 4096; // check single attack finished delays
+const int TFL_FIRECHECK_NO = 16384; // no prefire checks
+
+// attack flags
+.int shoot_flags;
+const int TFL_SHOOT_NO = 64; // no attacking
+const int TFL_SHOOT_VOLLY = 2; // fire in vollies
+const int TFL_SHOOT_VOLLYALWAYS = 4; // always do a full volly, even if target is lost
+const int TFL_SHOOT_HITALLVALID = 8; // loop through all valid targets
+const int TFL_SHOOT_CLEARTARGET = 16; // lose target after attack (after volly is done if in volly mode)
+const int TFL_SHOOT_CUSTOM = 32; // custom attacking
+
+// turret capabilities
+.int turret_flags;
+const int TUR_FLAG_NONE = 0; // no abilities
+const int TUR_FLAG_SNIPER = 2; // sniping turret
+const int TUR_FLAG_SPLASH = 4; // can deal splash damage
+const int TUR_FLAG_HITSCAN = 8; // hit scan
+const int TUR_FLAG_MULTIGUN = 16; // multiple guns
+const int TUR_FLAG_GUIDED = 32; // laser guided projectiles
+const int TUR_FLAG_SLOWPROJ = 64; // turret fires slow projectiles
+const int TUR_FLAG_MEDPROJ = 128; // turret fires medium projectiles
+const int TUR_FLAG_FASTPROJ = 256; // turret fires fast projectiles
+const int TUR_FLAG_PLAYER = 512; // can damage players
+const int TUR_FLAG_MISSILE = 1024; // can damage missiles
+const int TUR_FLAG_SUPPORT = 2048; // supports other units
+const int TUR_FLAG_AMMOSOURCE = 4096; // can provide ammunition
+const int TUR_FLAG_RECIEVETARGETS = 8192; // can recieve targets from external sources
+const int TUR_FLAG_MOVE = 16384; // can move
+const int TUR_FLAG_ROAM = 32768; // roams around if not attacking
+const int TUR_FLAG_ISTURRET = 65536; // identifies this unit as a turret
+
+// ammo types
+#define ammo_flags currentammo
+const int TFL_AMMO_NONE = 64; // doesn't use ammo
+const int TFL_AMMO_ENERGY = 2; // uses power
+const int TFL_AMMO_BULLETS = 4; // uses bullets
+const int TFL_AMMO_ROCKETS = 8; // uses explosives
+const int TFL_AMMO_RECHARGE = 16; // regenerates ammo
+const int TFL_AMMO_RECIEVE = 32; // can recieve ammo from support units
+
+// damage flags
+.int damage_flags;
+const int TFL_DMG_NO = 256; // doesn't take damage
+const int TFL_DMG_YES = 2; // can be damaged
+const int TFL_DMG_TEAM = 4; // can be damaged by teammates
+const int TFL_DMG_RETALIATE = 8; // target attackers
+const int TFL_DMG_RETALIATE_TEAM = 16; // target attackers, even if on same team
+const int TFL_DMG_TARGETLOSS = 32; // loses target when damaged
+const int TFL_DMG_AIMSHAKE = 64; // damage throws off aim
+const int TFL_DMG_HEADSHAKE = 128; // damage shakes head
+const int TFL_DMG_DEATH_NORESPAWN = 256; // no re-spawning
+
+// spawn flags
+const int TSF_SUSPENDED = 1;
+const int TSF_TERRAINBASE = 2; // currently unused
+const int TSF_NO_AMMO_REGEN = 4; // disable builtin ammo regeneration
+const int TSF_NO_PATHBREAK = 8; // don't break path to chase enemies, will still fire at them if possible
+const int TSL_NO_RESPAWN = 16; // don't re-spawn
+const int TSL_ROAM = 32; // roam while idle
+
+// send flags
+const int TNSF_UPDATE       = 2;
+const int TNSF_STATUS       = 4;
+const int TNSF_SETUP        = 8;
+const int TNSF_ANG          = 16;
+const int TNSF_AVEL         = 32;
+const int TNSF_MOVE         = 64;
+.float anim_start_time;
+const int TNSF_ANIM         = 128;
+
+const int TNSF_FULL_UPDATE  = 16777215;
+
+
+// other useful macros
+#define TUR_ACTION(turrettype,mrequest) (get_turretinfo(turrettype)).turret_func(mrequest)
+#define TUR_NAME(turrettype) (get_turretinfo(turrettype)).turret_name
+
+float t_null(float dummy) { return 0; }
+
+CLASS(Turret, Object)
+    ATTRIB(Turret, m_id, int, 0)
+
+    ATTRIB(Turret, turretid, int, 0)
+    /** short name */
+    ATTRIB(Turret, netname, string, string_null)
+    /** human readable name */
+    ATTRIB(Turret, turret_name, string, string_null)
+    /** t_... */
+    ATTRIB(Turret, turret_func, float(float), t_null)
+    /** currently a copy of the model */
+    ATTRIB(Turret, mdl, string, string_null)
+    /** full name of model */
+    ATTRIB(Turret, model, string, string_null)
+    /** full name of tur_head model */
+    ATTRIB(Turret, head_model, string, string_null)
+    /** TODO: deprecate! */
+    ATTRIB(Turret, cvar_basename, string, string_null)
+
+    ATTRIB(Turret, spawnflags, int, 0)
+    /** turret hitbox size */
+    ATTRIB(Turret, mins, vector, '-0 -0 -0')
+    /** turret hitbox size */
+    ATTRIB(Turret, maxs, vector, '0 0 0')
+
+    METHOD(Turret, display, void(entity this, void(string name, string icon) returns)) {
+        returns(this.turret_name, string_null);
+    }
+
+ENDCLASS(Turret)
+
+#endif
diff --git a/qcsrc/common/turrets/turret/ewheel.qc b/qcsrc/common/turrets/turret/ewheel.qc
new file mode 100644 (file)
index 0000000..a27860b
--- /dev/null
@@ -0,0 +1,312 @@
+#ifndef TUR_EWHEEL_H
+#define TUR_EWHEEL_H
+REGISTER_TURRET(
+/* TUR_##id   */ EWHEEL,
+/* function   */ t_ewheel,
+/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE | TUR_FLAG_ROAM,
+/* mins,maxs  */ '-32 -32 0', '32 32 48',
+/* model      */ "ewheel-base2.md3",
+/* head_model */ "ewheel-gun1.md3",
+/* netname    */ "ewheel",
+/* fullname   */ _("eWheel Turret")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+float autocvar_g_turrets_unit_ewheel_speed_fast;
+float autocvar_g_turrets_unit_ewheel_speed_slow;
+float autocvar_g_turrets_unit_ewheel_speed_slower;
+float autocvar_g_turrets_unit_ewheel_speed_stop;
+float autocvar_g_turrets_unit_ewheel_turnrate;
+
+const float ewheel_anim_stop = 0;
+const float ewheel_anim_fwd_slow = 1;
+const float ewheel_anim_fwd_fast = 2;
+const float ewheel_anim_bck_slow = 3;
+const float ewheel_anim_bck_fast = 4;
+
+//#define EWHEEL_FANCYPATH
+void ewheel_move_path()
+{SELFPARAM();
+#ifdef EWHEEL_FANCYPATH
+    // Are we close enougth to a path node to switch to the next?
+    if (vlen(self.origin  - self.pathcurrent.origin) < 64)
+        if (self.pathcurrent.path_next == world)
+        {
+            // Path endpoint reached
+            pathlib_deletepath(self.pathcurrent.owner);
+            self.pathcurrent = world;
+
+            if (self.pathgoal)
+            {
+                if (self.pathgoal.use)
+                    self.pathgoal.use();
+
+                if (self.pathgoal.enemy)
+                {
+                    self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
+                    self.pathgoal = self.pathgoal.enemy;
+                }
+            }
+            else
+                self.pathgoal = world;
+        }
+        else
+            self.pathcurrent = self.pathcurrent.path_next;
+
+#else
+    if (vlen(self.origin - self.pathcurrent.origin) < 64)
+        self.pathcurrent = self.pathcurrent.enemy;
+#endif
+
+    if (self.pathcurrent)
+    {
+
+        self.moveto = self.pathcurrent.origin;
+        self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
+
+        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
+    }
+}
+
+void ewheel_move_enemy()
+{SELFPARAM();
+    float newframe;
+
+    self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
+
+    self.moveto  = self.origin + self.steerto * 128;
+
+    if (self.tur_dist_enemy > self.target_range_optimal)
+    {
+        if ( self.tur_head.spawnshieldtime < 1 )
+        {
+            newframe = ewheel_anim_fwd_fast;
+            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
+        }
+        else if (self.tur_head.spawnshieldtime < 2)
+        {
+
+            newframe = ewheel_anim_fwd_slow;
+            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
+       }
+        else
+        {
+            newframe = ewheel_anim_fwd_slow;
+            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
+        }
+    }
+    else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
+    {
+        newframe = ewheel_anim_bck_slow;
+        movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
+    }
+    else
+    {
+        newframe = ewheel_anim_stop;
+        movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
+    }
+
+    turrets_setframe(newframe, false);
+}
+
+void ewheel_move_idle()
+{SELFPARAM();
+    if(self.frame != 0)
+    {
+        self.SendFlags |= TNSF_ANIM;
+        self.anim_start_time = time;
+    }
+
+    self.frame = 0;
+    if (vlen(self.velocity))
+        movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
+}
+
+void spawnfunc_turret_ewheel() { SELFPARAM(); if(!turret_initialize(TUR_EWHEEL.m_id)) remove(self); }
+
+float t_ewheel(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            float i;
+            entity _mis;
+
+            for (i = 0; i < 1; ++i)
+            {
+                turret_do_updates(self);
+
+                _mis = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
+                _mis.missile_flags = MIF_SPLASH;
+
+                Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+                self.tur_head.frame += 2;
+
+                if (self.tur_head.frame > 3)
+                    self.tur_head.frame = 0;
+            }
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            float vz;
+            vector wish_angle, real_angle;
+
+            vz = self.velocity_z;
+
+            self.angles_x = anglemods(self.angles_x);
+            self.angles_y = anglemods(self.angles_y);
+
+            fixedmakevectors(self.angles);
+
+            wish_angle = normalize(self.steerto);
+            wish_angle = vectoangles(wish_angle);
+            real_angle = wish_angle - self.angles;
+            real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
+
+            self.tur_head.spawnshieldtime = fabs(real_angle_y);
+            real_angle_y  = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
+            self.angles_y = (self.angles_y + real_angle_y);
+
+            if(self.enemy)
+                ewheel_move_enemy();
+            else if(self.pathcurrent)
+                ewheel_move_path();
+            else
+                ewheel_move_idle();
+
+            self.velocity_z = vz;
+
+            if(vlen(self.velocity))
+                self.SendFlags |= TNSF_MOVE;
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            self.velocity = '0 0 0';
+
+#ifdef EWHEEL_FANCYPATH
+            if (self.pathcurrent)
+                pathlib_deletepath(self.pathcurrent.owner);
+#endif
+            self.pathcurrent = world;
+
+            return true;
+        }
+        case TR_SETUP:
+        {
+            entity e;
+
+            if(self.movetype == MOVETYPE_WALK)
+            {
+                self.velocity = '0 0 0';
+                self.enemy = world;
+
+                setorigin(self, self.pos1);
+
+                if (self.target != "")
+                {
+                    e = find(world, targetname, self.target);
+                    if (!e)
+                    {
+                        LOG_TRACE("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
+                        self.target = "";
+                    }
+
+                    if (e.classname != "turret_checkpoint")
+                        LOG_TRACE("Warning: not a turrret path\n");
+                    else
+                    {
+
+#ifdef EWHEEL_FANCYPATH
+                        self.pathcurrent = WALKER_PATH(self.origin,e.origin);
+                        self.pathgoal = e;
+#else
+                        self.pathcurrent  = e;
+#endif
+                    }
+                }
+            }
+
+            self.iscreature                            = true;
+            self.teleportable                  = TELEPORT_NORMAL;
+            self.damagedbycontents             = true;
+            self.movetype                              = MOVETYPE_WALK;
+            self.solid                                 = SOLID_SLIDEBOX;
+            self.takedamage                            = DAMAGE_AIM;
+            self.idle_aim                              = '0 0 0';
+            self.pos1                                  = self.origin;
+            self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+            self.frame                                 = self.tur_head.frame = 1;
+            self.ammo_flags                            = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+
+            // Convert from dgr / sec to dgr / tic
+            self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
+            self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+
+void ewheel_draw()
+{SELFPARAM();
+    float dt;
+
+    dt = time - self.move_time;
+    self.move_time = time;
+    if(dt <= 0)
+        return;
+
+    fixedmakevectors(self.angles);
+    setorigin(self, self.origin + self.velocity * dt);
+    self.tur_head.angles += dt * self.tur_head.move_avelocity;
+    self.angles_y = self.move_angles_y;
+
+    if (self.health < 127)
+    if(random() < 0.05)
+        te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
+}
+
+float t_ewheel(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            self.gravity               = 1;
+            self.movetype              = MOVETYPE_BOUNCE;
+            self.move_movetype = MOVETYPE_BOUNCE;
+            self.move_origin   = self.origin;
+            self.move_time             = time;
+            self.draw                  = ewheel_draw;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/flac.qc b/qcsrc/common/turrets/turret/flac.qc
new file mode 100644 (file)
index 0000000..aacefd1
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef TUR_FLAC_H
+#define TUR_FLAC_H
+REGISTER_TURRET(
+/* TUR_##id   */ FLAC,
+/* function   */ t_flac,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_MISSILE,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "flac.md3",
+/* netname       */ "flac",
+/* fullname   */ _("FLAC Cannon")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+void turret_flac_projectile_think_explode()
+{SELFPARAM();
+    if(self.enemy != world)
+    if(vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3)
+        setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
+
+#ifdef TURRET_DEBUG
+    float d;
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
+    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
+    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+    RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
+#endif
+    remove(self);
+}
+
+void spawnfunc_turret_flac() { SELFPARAM(); if(!turret_initialize(TUR_FLAC.m_id)) remove(self); }
+
+float t_flac(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            entity proj;
+
+            turret_tag_fire_update();
+
+            proj = turret_projectile(SND(HAGAR_FIRE), 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
+            Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+            proj.think   = turret_flac_projectile_think_explode;
+            proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
+            proj.missile_flags = MIF_SPLASH | MIF_PROXY;
+
+            self.tur_head.frame = self.tur_head.frame + 1;
+            if (self.tur_head.frame >= 4)
+                self.tur_head.frame = 0;
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+            self.damage_flags |= TFL_DMG_HEADSHAKE;
+            self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_flac(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/fusionreactor.qc b/qcsrc/common/turrets/turret/fusionreactor.qc
new file mode 100644 (file)
index 0000000..7d2f4f0
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef TUR_FUSIONREACTOR_H
+#define TUR_FUSIONREACTOR_H
+REGISTER_TURRET(
+/* TUR_##id   */ FUSIONREACTOR,
+/* function   */ t_fusionreactor,
+/* spawnflags */ TUR_FLAG_SUPPORT | TUR_FLAG_AMMOSOURCE,
+/* mins,maxs  */ '-34 -34 0', '34 34 90',
+/* model         */ "base.md3",
+/* head_model */ "reactor.md3",
+/* netname       */ "fusionreactor",
+/* fullname   */ _("Fusion Reactor")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+bool turret_fusionreactor_firecheck()
+{SELFPARAM();
+    if (self.attack_finished_single > time)
+        return false;
+
+    if (self.enemy.deadflag != DEAD_NO)
+        return false;
+
+    if (self.enemy == world)
+        return false;
+
+    if (self.ammo < self.shot_dmg)
+        return false;
+
+    if (self.enemy.ammo >= self.enemy.ammo_max)
+        return false;
+
+    if (vlen(self.enemy.origin - self.origin) > self.target_range)
+        return false;
+
+    if(self.team != self.enemy.team)
+        return false;
+
+    if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
+        return false;
+
+    return true;
+}
+
+void spawnfunc_turret_fusionreactor() { SELFPARAM(); if(!turret_initialize(TUR_FUSIONREACTOR.m_id)) remove(self); }
+
+float t_fusionreactor(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            vector fl_org;
+
+            self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
+            fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
+            te_smallflash(fl_org);
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ammo_flags                            = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
+            self.target_select_flags   = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
+            self.firecheck_flags               = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
+            self.shoot_flags                   = TFL_SHOOT_HITALLVALID;
+            self.aim_flags                             = TFL_AIM_NO;
+            self.track_flags                   = TFL_TRACK_NO;
+
+            self.tur_head.scale = 0.75;
+            self.tur_head.avelocity = '0 50 0';
+
+            self.turret_firecheckfunc = turret_fusionreactor_firecheck;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_fusionreactor(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/hellion.qc b/qcsrc/common/turrets/turret/hellion.qc
new file mode 100644 (file)
index 0000000..9efae2d
--- /dev/null
@@ -0,0 +1,161 @@
+#ifndef TUR_HELLION_H
+#define TUR_HELLION_H
+REGISTER_TURRET(
+/* TUR_##id   */ HELLION,
+/* function   */ t_hellion,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "hellion.md3",
+/* netname       */ "hellion",
+/* fullname   */ _("Hellion Missile Turret")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+float autocvar_g_turrets_unit_hellion_shot_speed_gain;
+float autocvar_g_turrets_unit_hellion_shot_speed_max;
+
+void turret_hellion_missile_think()
+{SELFPARAM();
+    vector olddir,newdir;
+    vector pre_pos;
+    float itime;
+
+    self.nextthink = time + 0.05;
+
+    olddir = normalize(self.velocity);
+
+    if(self.max_health < time)
+        turret_projectile_explode();
+
+    // Enemy dead? just keep on the current heading then.
+    if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
+    {
+
+        // Make sure we dont return to tracking a respawned player
+        self.enemy = world;
+
+        // Turn model
+        self.angles = vectoangles(self.velocity);
+
+        if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
+            turret_projectile_explode();
+
+        // Accelerate
+        self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
+
+        UpdateCSQCProjectile(self);
+
+        return;
+    }
+
+    // Enemy in range?
+    if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
+        turret_projectile_explode();
+
+    // Predict enemy position
+    itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
+    pre_pos = self.enemy.origin + self.enemy.velocity * itime;
+
+    pre_pos = (pre_pos + self.enemy.origin) * 0.5;
+
+    // Find out the direction to that place
+    newdir = normalize(pre_pos - self.origin);
+
+    // Turn
+    newdir = normalize(olddir + newdir * 0.35);
+
+    // Turn model
+    self.angles = vectoangles(self.velocity);
+
+    // Accelerate
+    self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
+
+    if (itime < 0.05)
+        self.think = turret_projectile_explode;
+
+    UpdateCSQCProjectile(self);
+}
+
+void spawnfunc_turret_hellion() { SELFPARAM(); if(!turret_initialize(TUR_HELLION.m_id)) remove(self); }
+
+float t_hellion(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            entity missile;
+
+            if(self.tur_head.frame != 0)
+                self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
+            else
+                self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
+
+            missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
+            te_explosion (missile.origin);
+            missile.think              = turret_hellion_missile_think;
+            missile.nextthink  = time;
+            missile.flags              = FL_PROJECTILE;
+            missile.max_health   = time + 9;
+            missile.tur_aimpos   = randomvec() * 128;
+            missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
+            self.tur_head.frame += 1;
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            if (self.tur_head.frame != 0)
+                self.tur_head.frame += 1;
+
+            if (self.tur_head.frame >= 7)
+                self.tur_head.frame = 0;
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.aim_flags = TFL_AIM_SIMPLE;
+            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
+            self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
+            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_hellion(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/hk.qc b/qcsrc/common/turrets/turret/hk.qc
new file mode 100644 (file)
index 0000000..8ec6f16
--- /dev/null
@@ -0,0 +1,362 @@
+#ifndef TUR_HK_H
+#define TUR_HK_H
+REGISTER_TURRET(
+/* TUR_##id   */ HK,
+/* function   */ t_hk,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER | TUR_FLAG_RECIEVETARGETS,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "hk.md3",
+/* netname       */ "hk",
+/* fullname   */ _("Hunter-Killer Turret")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+float autocvar_g_turrets_unit_hk_shot_speed;
+float autocvar_g_turrets_unit_hk_shot_speed_accel;
+float autocvar_g_turrets_unit_hk_shot_speed_accel2;
+float autocvar_g_turrets_unit_hk_shot_speed_decel;
+float autocvar_g_turrets_unit_hk_shot_speed_max;
+float autocvar_g_turrets_unit_hk_shot_speed_turnrate;
+
+//#define TURRET_DEBUG_HK
+
+#ifdef TURRET_DEBUG_HK
+.float atime;
+#endif
+
+float hk_is_valid_target(entity e_target)
+{SELFPARAM();
+    if (e_target == world)
+        return 0;
+
+    // If only this was used more..
+    if (e_target.flags & FL_NOTARGET)
+        return 0;
+
+    // Cant touch this
+    if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
+        return 0;
+
+    // player
+    if (IS_CLIENT(e_target))
+    {
+        if (self.owner.target_select_playerbias < 0)
+            return 0;
+
+        if (e_target.deadflag != DEAD_NO)
+            return 0;
+    }
+
+    // Missile
+    if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
+        return 0;
+
+    // Team check
+    if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
+        return 0;
+
+    return 1;
+}
+
+void turret_hk_missile_think()
+{SELFPARAM();
+    vector vu, vd, vf, vl, vr, ve;  // Vector (direction)
+    float  fu, fd, ff, fl, fr, fe;  // Fraction to solid
+    vector olddir,wishdir,newdir;   // Final direction
+    float lt_for;   // Length of Trace FORwrad
+    float lt_seek;  // Length of Trace SEEK (left, right, up down)
+    float pt_seek;  // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
+    vector pre_pos;
+    float myspeed;
+    entity e;
+    float ad,edist;
+
+    self.nextthink = time + self.ticrate;
+
+    //if (self.cnt < time)
+    // turret_hk_missile_explode();
+
+    if (self.enemy.deadflag != DEAD_NO)
+        self.enemy = world;
+
+    // Pick the closest valid target.
+    if (!self.enemy)
+    {
+        e = findradius(self.origin, 5000);
+        while (e)
+        {
+            if (hk_is_valid_target(e))
+            {
+                if (!self.enemy)
+                    self.enemy = e;
+                else
+                    if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
+                        self.enemy = e;
+            }
+            e = e.chain;
+        }
+    }
+
+    self.angles = vectoangles(self.velocity);
+    self.angles_x = self.angles_x * -1;
+    makevectors(self.angles);
+    self.angles_x = self.angles_x * -1;
+
+    if (self.enemy)
+    {
+        edist = vlen(self.origin - self.enemy.origin);
+        // Close enougth to do decent damage?
+        if ( edist <= (self.owner.shot_radius * 0.25) )
+        {
+            turret_projectile_explode();
+            return;
+        }
+
+        // Get data on enemy position
+        pre_pos = self.enemy.origin +
+                  self.enemy.velocity *
+                  min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
+
+        traceline(self.origin, pre_pos,true,self.enemy);
+        ve = normalize(pre_pos - self.origin);
+        fe = trace_fraction;
+
+    }
+    else
+    {
+    edist = 0;
+    ve = '0 0 0';
+        fe = 0;
+    }
+
+    if ((fe != 1) || (self.enemy == world) || (edist > 1000))
+    {
+        myspeed = vlen(self.velocity);
+
+        lt_for  = myspeed * 3;
+        lt_seek = myspeed * 2.95;
+
+        // Trace forward
+        traceline(self.origin, self.origin + v_forward * lt_for,false,self);
+        vf = trace_endpos;
+        ff = trace_fraction;
+
+        // Find angular offset
+        ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
+
+        // To close to something, Slow down!
+        if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) )
+            myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed));
+
+        // Failry clear, accelerate.
+        if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) )
+            myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max));
+
+        // Setup trace pitch
+        pt_seek = 1 - ff;
+        pt_seek = bound(0.15,pt_seek,0.8);
+        if (ff < 0.5) pt_seek = 1;
+
+        // Trace left
+        traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self);
+        vl = trace_endpos;
+        fl = trace_fraction;
+
+        // Trace right
+        traceline(self.origin,  self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
+        vr = trace_endpos;
+        fr = trace_fraction;
+
+        // Trace up
+        traceline(self.origin,  self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
+        vu = trace_endpos;
+        fu = trace_fraction;
+
+        // Trace down
+        traceline(self.origin,  self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
+        vd = trace_endpos;
+        fd = trace_fraction;
+
+        vl = normalize(vl - self.origin);
+        vr = normalize(vr - self.origin);
+        vu = normalize(vu - self.origin);
+        vd = normalize(vd - self.origin);
+
+        // Panic tresh passed, find a single direction and turn as hard as we can
+        if (pt_seek == 1)
+        {
+            wishdir = v_right;
+            if (fl > fr) wishdir = -1 * v_right;
+            if (fu > fl) wishdir = v_up;
+            if (fd > fu) wishdir = -1 * v_up;
+        }
+        else
+        {
+            // Normalize our trace vectors to make a smooth path
+            wishdir = normalize( (vl * fl) + (vr * fr) +  (vu * fu) +  (vd * fd) );
+        }
+
+        if (self.enemy)
+        {
+            if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
+            wishdir = (wishdir * (1 - fe)) + (ve * fe);
+        }
+    }
+    else
+    {
+        // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
+        myspeed = vlen(self.velocity);
+        if (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max))
+            myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
+
+        wishdir = ve;
+    }
+
+    if ((myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) && (self.cnt > time))
+        myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
+
+    // Ranoutagazfish?
+    if (self.cnt < time)
+    {
+        self.cnt = time + 0.25;
+        self.nextthink = 0;
+        self.movetype           = MOVETYPE_BOUNCE;
+        return;
+    }
+
+    // Calculate new heading
+    olddir = normalize(self.velocity);
+    newdir = normalize(olddir + wishdir * (autocvar_g_turrets_unit_hk_shot_speed_turnrate));
+
+    // Set heading & speed
+    self.velocity = newdir * myspeed;
+
+    // Align model with new heading
+    self.angles = vectoangles(self.velocity);
+
+
+#ifdef TURRET_DEBUG_HK
+    //if(self.atime < time) {
+    if ((fe <= 0.99)||(edist > 1000))
+    {
+        te_lightning2(world,self.origin, self.origin + vr * lt_seek);
+        te_lightning2(world,self.origin, self.origin + vl * lt_seek);
+        te_lightning2(world,self.origin, self.origin + vu * lt_seek);
+        te_lightning2(world,self.origin, self.origin + vd * lt_seek);
+        te_lightning2(world,self.origin, vf);
+    }
+    else
+    {
+        te_lightning2(world,self.origin, self.enemy.origin);
+    }
+    bprint("Speed: ", ftos(rint(myspeed)), "\n");
+    bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
+    bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
+    self.atime = time + 0.2;
+    //}
+#endif
+
+    UpdateCSQCProjectile(self);
+}
+
+float turret_hk_addtarget(entity e_target,entity e_sender)
+{SELFPARAM();
+    if (e_target)
+    {
+        if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
+        {
+            self.enemy = e_target;
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+void spawnfunc_turret_hk() { SELFPARAM(); if(!turret_initialize(TUR_HK.m_id)) remove(self); }
+
+float t_hk(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            entity missile;
+
+            missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
+            te_explosion (missile.origin);
+
+            missile.think                      = turret_hk_missile_think;
+            missile.nextthink          = time + 0.25;
+            missile.movetype            = MOVETYPE_BOUNCEMISSILE;
+            missile.velocity            = self.tur_shotdir_updated * (self.shot_speed * 0.75);
+            missile.angles                = vectoangles(missile.velocity);
+            missile.cnt                          = time + 30;
+            missile.ticrate              = max(autocvar_sys_ticrate, 0.05);
+            missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_AI;
+
+            if (self.tur_head.frame == 0)
+                self.tur_head.frame = self.tur_head.frame + 1;
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            if (self.tur_head.frame != 0)
+                self.tur_head.frame = self.tur_head.frame + 1;
+
+            if (self.tur_head.frame > 5)
+                self.tur_head.frame = 0;
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+            self.aim_flags = TFL_AIM_SIMPLE;
+            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+            self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
+            self.shoot_flags = TFL_SHOOT_CLEARTARGET;
+            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
+
+            self.turret_addtarget = turret_hk_addtarget;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_hk(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/machinegun.qc b/qcsrc/common/turrets/turret/machinegun.qc
new file mode 100644 (file)
index 0000000..48a200c
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef TUR_MACHINEGUN_H
+#define TUR_MACHINEGUN_H
+REGISTER_TURRET(
+/* TUR_##id   */ MACHINEGUN,
+/* function   */ t_machinegun,
+/* spawnflags */ TUR_FLAG_PLAYER,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "machinegun.md3",
+/* netname       */ "machinegun",
+/* fullname   */ _("Machinegun Turret")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+void spawnfunc_turret_machinegun() { SELFPARAM(); if(!turret_initialize(TUR_MACHINEGUN.m_id)) remove(self); }
+
+void W_MachineGun_MuzzleFlash(void);
+
+float t_machinegun(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
+
+            W_MachineGun_MuzzleFlash();
+            setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.damage_flags |= TFL_DMG_HEADSHAKE;
+            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+            self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+            self.turret_flags |= TUR_FLAG_HITSCAN;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_machinegun(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/mlrs.qc b/qcsrc/common/turrets/turret/mlrs.qc
new file mode 100644 (file)
index 0000000..fe3775b
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef TUR_MLRS_H
+#define TUR_MLRS_H
+REGISTER_TURRET(
+/* TUR_##id   */ MLRS,
+/* function   */ t_mlrs,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "mlrs.md3",
+/* netname       */ "mlrs",
+/* fullname   */ _("MLRS Turret")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+void spawnfunc_turret_mlrs() { SELFPARAM(); if(!turret_initialize(TUR_MLRS.m_id)) remove(self); }
+
+float t_mlrs(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            entity missile;
+
+            turret_tag_fire_update();
+            missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
+            missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
+            missile.missile_flags = MIF_SPLASH;
+            te_explosion (missile.origin);
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            // 0 = full, 6 = empty
+            self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
+            if(self.tur_head.frame < 0)
+            {
+                LOG_TRACE("ammo:",ftos(self.ammo),"\n");
+                LOG_TRACE("shot_dmg:",ftos(self.shot_dmg),"\n");
+            }
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+
+            self.damage_flags |= TFL_DMG_HEADSHAKE;
+            self.shoot_flags  |= TFL_SHOOT_VOLLYALWAYS;
+            self.volly_counter = self.shot_volly;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_mlrs(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/phaser.qc b/qcsrc/common/turrets/turret/phaser.qc
new file mode 100644 (file)
index 0000000..9e16249
--- /dev/null
@@ -0,0 +1,170 @@
+#ifndef TUR_PHASER_H
+#define TUR_PHASER_H
+REGISTER_TURRET(
+/* TUR_##id   */ PHASER,
+/* function   */ t_phaser,
+/* spawnflags */ TUR_FLAG_SNIPER | TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "phaser.md3",
+/* netname       */ "phaser",
+/* fullname   */ _("Phaser Cannon")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+.float fireflag;
+
+float turret_phaser_firecheck()
+{SELFPARAM();
+    if (self.fireflag != 0) return 0;
+    return turret_firecheck();
+}
+
+void beam_think()
+{SELFPARAM();
+    if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
+    {
+        self.owner.attack_finished_single = time + self.owner.shot_refire;
+        self.owner.fireflag = 2;
+        self.owner.tur_head.frame = 10;
+        sound (self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
+        remove(self);
+        return;
+    }
+
+    turret_do_updates(self.owner);
+
+    if (time - self.shot_spread > 0)
+    {
+        self.shot_spread = time + 2;
+        sound (self, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
+    }
+
+
+    self.nextthink = time + self.ticrate;
+
+    self.owner.attack_finished_single = time + frametime;
+    setself(self.owner);
+    FireImoBeam (   self.tur_shotorg,
+                    self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
+                    '-1 -1 -1' * self.shot_radius,
+                    '1 1 1' * self.shot_radius,
+                    self.shot_force,
+                    this.shot_dmg,
+                    0.75,
+                    DEATH_TURRET_PHASER);
+    setself(this);
+    self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
+
+}
+
+void spawnfunc_turret_phaser() { SELFPARAM(); if(!turret_initialize(TUR_PHASER.m_id)) remove(self); }
+
+float t_phaser(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            entity beam;
+
+            beam = spawn();
+            beam.ticrate = 0.1; //autocvar_sys_ticrate;
+            setmodel(beam, MDL_TUR_PHASER_BEAM);
+            beam.effects = EF_LOWPRECISION;
+            beam.solid = SOLID_NOT;
+            beam.think = beam_think;
+            beam.cnt = time + self.shot_speed;
+            beam.shot_spread = time + 2;
+            beam.nextthink = time;
+            beam.owner = self;
+            beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
+            beam.scale = self.target_range / 256;
+            beam.movetype = MOVETYPE_NONE;
+            beam.enemy = self.enemy;
+            beam.bot_dodge = true;
+            beam.bot_dodgerating = beam.shot_dmg;
+            sound (beam, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
+            self.fireflag = 1;
+
+            beam.attack_finished_single = self.attack_finished_single;
+            self.attack_finished_single = time; // + autocvar_sys_ticrate;
+
+            setattachment(beam,self.tur_head,"tag_fire");
+
+            soundat (self, trace_endpos, CH_SHOTS, SND(NEXIMPACT), VOL_BASE, ATTEN_NORM);
+
+            if (self.tur_head.frame == 0)
+                self.tur_head.frame = 1;
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            if (self.tur_head.frame != 0)
+            {
+                if (self.fireflag == 1)
+                {
+                    if (self.tur_head.frame == 10)
+                        self.tur_head.frame = 1;
+                    else
+                        self.tur_head.frame = self.tur_head.frame +1;
+                }
+                else if (self.fireflag == 2 )
+                {
+                    self.tur_head.frame = self.tur_head.frame +1;
+                    if (self.tur_head.frame == 15)
+                    {
+                        self.tur_head.frame = 0;
+                        self.fireflag = 0;
+                    }
+                }
+            }
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+            self.aim_flags = TFL_AIM_LEAD;
+
+            self.turret_firecheckfunc = turret_phaser_firecheck;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_phaser(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/plasma.qc b/qcsrc/common/turrets/turret/plasma.qc
new file mode 100644 (file)
index 0000000..0cfe13c
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef TUR_PLASMA_H
+#define TUR_PLASMA_H
+REGISTER_TURRET(
+/* TUR_##id   */ PLASMA,
+/* function   */ t_plasma,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "plasma.md3",
+/* netname       */ "plasma",
+/* fullname   */ _("Plasma Cannon")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+void spawnfunc_turret_plasma() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA.m_id)) remove(self); }
+
+float t_plasma(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            if(g_instagib)
+            {
+                float flying;
+                flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
+
+                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
+                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
+
+                Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+                // teamcolor / hit beam effect
+                vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+                WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
+                if (self.tur_head.frame == 0)
+                    self.tur_head.frame = 1;
+            }
+            else
+            {
+                entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
+                missile.missile_flags = MIF_SPLASH;
+
+                Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+                if (self.tur_head.frame == 0)
+                    self.tur_head.frame = 1;
+            }
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            if (self.tur_head.frame != 0)
+                self.tur_head.frame = self.tur_head.frame + 1;
+
+            if (self.tur_head.frame > 5)
+                self.tur_head.frame = 0;
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+            self.damage_flags |= TFL_DMG_HEADSHAKE;
+            self.firecheck_flags |= TFL_FIRECHECK_AFF;
+            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
+
+            turret_do_updates(self);
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_plasma(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/plasma_dual.qc b/qcsrc/common/turrets/turret/plasma_dual.qc
new file mode 100644 (file)
index 0000000..74713ea
--- /dev/null
@@ -0,0 +1,134 @@
+#ifndef TUR_PLASMA_DUAL_H
+#define TUR_PLASMA_DUAL_H
+REGISTER_TURRET(
+/* TUR_##id   */ PLASMA_DUAL,
+/* function   */ t_plasma_dual,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
+/* mins,maxs  */ '-32 -32 0', '32 32 64',
+/* model         */ "base.md3",
+/* head_model */ "plasmad.md3",
+/* netname       */ "plasma_dual",
+/* fullname   */ _("Dual Plasma Cannon")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../weapons/all.qh"
+
+CLASS(PlasmaDualAttack, PortoLaunch)
+/* flags     */ ATTRIB(PlasmaDualAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(PlasmaDualAttack, impulse, int, 5);
+/* refname   */ ATTRIB(PlasmaDualAttack, netname, string, "plasmadual");
+/* wepname   */ ATTRIB(PlasmaDualAttack, message, string, _("Dual plasma"));
+ENDCLASS(PlasmaDualAttack)
+REGISTER_WEAPON(PLASMA_DUAL, NEW(PlasmaDualAttack));
+
+#ifdef SVQC
+
+float t_plasma_dual(float req);
+METHOD(PlasmaDualAttack, wr_think, bool(entity thiswep)) {
+       SELFPARAM();
+       if (self.BUTTON_ATCK)
+       if (weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire))) {
+               W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0);
+               self.tur_shotdir_updated = w_shotdir;
+               self.tur_shotorg = w_shotorg;
+               self.tur_head = self;
+        self.shot_speed = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed));
+        self.shot_spread = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500);
+               t_plasma_dual(TR_ATTACK);
+               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+       }
+       return true;
+}
+
+void spawnfunc_turret_plasma_dual() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA_DUAL.m_id)) remove(self); }
+
+float t_plasma_dual(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            if(g_instagib)
+            {
+                float flying;
+                flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
+
+                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
+                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
+
+
+                Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+                // teamcolor / hit beam effect
+                vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+                WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
+                self.tur_head.frame += 1;
+            }
+            else
+            {
+                entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
+                missile.missile_flags = MIF_SPLASH;
+                Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+                self.tur_head.frame += 1;
+            }
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
+                self.tur_head.frame = self.tur_head.frame + 1;
+
+            if (self.tur_head.frame > 6)
+                self.tur_head.frame = 0;
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+            self.damage_flags |= TFL_DMG_HEADSHAKE;
+            self.firecheck_flags |= TFL_FIRECHECK_AFF;
+            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
+
+            turret_do_updates(self);
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_plasma_dual(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/tesla.qc b/qcsrc/common/turrets/turret/tesla.qc
new file mode 100644 (file)
index 0000000..66c6751
--- /dev/null
@@ -0,0 +1,218 @@
+#ifndef TUR_TESLA_H
+#define TUR_TESLA_H
+REGISTER_TURRET(
+/* TUR_##id   */ TESLA,
+/* function   */ t_tesla,
+/* spawnflags */ TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
+/* mins,maxs  */ '-60 -60 0', '60 60 128',
+/* model         */ "tesla_base.md3",
+/* head_model */ "tesla_head.md3",
+/* netname       */ "tesla",
+/* fullname   */ _("Tesla Coil")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+entity toast(entity from, float range, float damage)
+{SELFPARAM();
+    entity e;
+    entity etarget = world;
+    float d,dd;
+    float r;
+
+    dd = range + 1;
+
+    e = findradius(from.origin,range);
+    while (e)
+    {
+        if ((e.railgunhit != 1) && (e != from))
+        {
+            r = turret_validate_target(self,e,self.target_validate_flags);
+            if (r > 0)
+            {
+                traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
+                if (trace_fraction == 1.0)
+                {
+                    d = vlen(e.origin - from.origin);
+                    if (d < dd)
+                    {
+                        dd = d;
+                        etarget = e;
+                    }
+                }
+            }
+        }
+        e = e.chain;
+    }
+
+    if (etarget)
+    {
+        te_csqc_lightningarc(from.origin,etarget.origin);
+        Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
+        etarget.railgunhit = 1;
+    }
+
+    return etarget;
+}
+
+float turret_tesla_firecheck()
+{SELFPARAM();
+    // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
+    float do_target_scan = 0;
+
+    if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
+        do_target_scan = 1;
+
+    // Old target (if any) invalid?
+    if(self.target_validate_time < time)
+    if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
+    {
+        self.enemy = world;
+        self.target_validate_time = time + 0.5;
+        do_target_scan = 1;
+    }
+
+    // But never more often then g_turrets_targetscan_mindelay!
+    if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
+        do_target_scan = 0;
+
+    if(do_target_scan)
+    {
+        self.enemy = turret_select_target();
+        self.target_select_time = time;
+    }
+
+    if(!turret_firecheck())
+        return 0;
+
+    if(self.enemy)
+        return 1;
+
+    return 0;
+}
+
+void spawnfunc_turret_tesla() { SELFPARAM(); if(!turret_initialize(TUR_TESLA.m_id)) remove(self); }
+
+float t_tesla(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            entity e, t;
+            float d, r, i;
+
+            d = self.shot_dmg;
+            r = self.target_range;
+            e = spawn();
+            setorigin(e,self.tur_shotorg);
+
+            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+
+            t = toast(e,r,d);
+            remove(e);
+
+            if (t == world) return true;
+
+            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
+
+            self.attack_finished_single = time + self.shot_refire;
+            for (i = 0; i < 10; ++i)
+            {
+                d *= 0.75;
+                r *= 0.85;
+                t = toast(t, r, d);
+                if (t == world) break;
+
+            }
+
+            e = findchainfloat(railgunhit, 1);
+            while (e)
+            {
+                e.railgunhit = 0;
+                e = e.chain;
+            }
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            if(!self.active)
+            {
+                self.tur_head.avelocity = '0 0 0';
+                return true;
+            }
+
+            if(self.ammo < self.shot_dmg)
+            {
+                self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
+            }
+            else
+            {
+                self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
+
+                if(self.attack_finished_single > time)
+                    return true;
+
+                float f;
+                f = (self.ammo / self.ammo_max);
+                f = f * f;
+                if(f > random())
+                    if(random() < 0.1)
+                        te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
+            }
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                                 TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+
+            self.turret_firecheckfunc = turret_tesla_firecheck;
+            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                               TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+
+            self.firecheck_flags       = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
+            self.shoot_flags           = TFL_SHOOT_CUSTOM;
+            self.ammo_flags                    = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+            self.aim_flags                     = TFL_AIM_NO;
+            self.track_flags           = TFL_TRACK_NO;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_tesla(float req)
+{
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/turret/walker.qc b/qcsrc/common/turrets/turret/walker.qc
new file mode 100644 (file)
index 0000000..82fb622
--- /dev/null
@@ -0,0 +1,697 @@
+#ifndef TUR_WALKER_H
+#define TUR_WALKER_H
+REGISTER_TURRET(
+/* TUR_##id   */ WALKER,
+/* function   */ t_walker,
+/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE,
+/* mins,maxs  */ '-70 -70 0', '70 70 95',
+/* model         */ "walker_body.md3",
+/* head_model */ "walker_head_minigun.md3",
+/* netname       */ "walker",
+/* fullname   */ _("Walker Turret")
+);
+#endif
+
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+float autocvar_g_turrets_unit_walker_melee_damage;
+float autocvar_g_turrets_unit_walker_melee_force;
+float autocvar_g_turrets_unit_walker_melee_range;
+float autocvar_g_turrets_unit_walker_rocket_damage;
+float autocvar_g_turrets_unit_walker_rocket_radius;
+float autocvar_g_turrets_unit_walker_rocket_force;
+float autocvar_g_turrets_unit_walker_rocket_speed;
+float autocvar_g_turrets_unit_walker_rocket_range;
+float autocvar_g_turrets_unit_walker_rocket_range_min;
+float autocvar_g_turrets_unit_walker_rocket_refire;
+float autocvar_g_turrets_unit_walker_rocket_turnrate;
+float autocvar_g_turrets_unit_walker_speed_stop;
+float autocvar_g_turrets_unit_walker_speed_walk;
+float autocvar_g_turrets_unit_walker_speed_run;
+float autocvar_g_turrets_unit_walker_speed_jump;
+float autocvar_g_turrets_unit_walker_speed_swim;
+float autocvar_g_turrets_unit_walker_speed_roam;
+float autocvar_g_turrets_unit_walker_turn;
+float autocvar_g_turrets_unit_walker_turn_walk;
+float autocvar_g_turrets_unit_walker_turn_strafe;
+float autocvar_g_turrets_unit_walker_turn_swim;
+float autocvar_g_turrets_unit_walker_turn_run;
+
+#define ANIM_NO         0
+#define ANIM_TURN       1
+#define ANIM_WALK       2
+#define ANIM_RUN        3
+#define ANIM_STRAFE_L   4
+#define ANIM_STRAFE_R   5
+#define ANIM_JUMP       6
+#define ANIM_LAND       7
+#define ANIM_PAIN       8
+#define ANIM_MELEE      9
+#define ANIM_SWIM       10
+#define ANIM_ROAM       11
+
+.float animflag;
+.float idletime;
+
+#define WALKER_PATH(s,e) pathlib_astar(s,e)
+
+float walker_firecheck()
+{SELFPARAM();
+    if (self.animflag == ANIM_MELEE)
+        return 0;
+
+    return turret_firecheck();
+}
+
+void walker_melee_do_dmg()
+{SELFPARAM();
+    vector where;
+    entity e;
+
+    makevectors(self.angles);
+    where = self.origin + v_forward * 128;
+
+    e = findradius(where,32);
+    while (e)
+    {
+        if (turret_validate_target(self, e, self.target_validate_flags))
+            if (e != self && e.owner != self)
+                Damage(e, self, self, (autocvar_g_turrets_unit_walker_melee_damage), DEATH_TURRET_WALK_MELEE, '0 0 0', v_forward * (autocvar_g_turrets_unit_walker_melee_force));
+
+        e = e.chain;
+    }
+}
+
+void walker_setnoanim()
+{SELFPARAM();
+    turrets_setframe(ANIM_NO, false);
+    self.animflag = self.frame;
+}
+void walker_rocket_explode()
+{SELFPARAM();
+    RadiusDamage (self, self.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), self, world, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET, world);
+    remove (self);
+}
+
+void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{SELFPARAM();
+    self.health = self.health - damage;
+    self.velocity = self.velocity + vforce;
+
+    if (self.health <= 0)
+        W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
+}
+
+#define WALKER_ROCKET_MOVE movelib_move_simple(newdir, (autocvar_g_turrets_unit_walker_rocket_speed), (autocvar_g_turrets_unit_walker_rocket_turnrate)); UpdateCSQCProjectile(self)
+void walker_rocket_loop();
+void walker_rocket_think()
+{SELFPARAM();
+    vector newdir;
+    float edist;
+    float itime;
+    float m_speed;
+
+    self.nextthink = time;
+
+    edist = vlen(self.enemy.origin - self.origin);
+
+    // Simulate crude guidance
+    if (self.cnt < time)
+    {
+        if (edist < 1000)
+            self.tur_shotorg = randomvec() * min(edist, 64);
+        else
+            self.tur_shotorg = randomvec() * min(edist, 256);
+
+        self.cnt = time + 0.5;
+    }
+
+    if (edist < 128)
+        self.tur_shotorg = '0 0 0';
+
+    if (self.max_health < time)
+    {
+        self.think       = walker_rocket_explode;
+        self.nextthink  = time;
+        return;
+    }
+
+    if (self.shot_dmg != 1337 && random() < 0.01)
+    {
+        walker_rocket_loop();
+        return;
+    }
+
+    m_speed = vlen(self.velocity);
+
+    // Enemy dead? just keep on the current heading then.
+    if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
+        self.enemy = world;
+
+    if (self.enemy)
+    {
+        itime = max(edist / m_speed, 1);
+        newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
+    }
+    else
+        newdir  = normalize(self.velocity);
+
+    WALKER_ROCKET_MOVE;
+}
+
+void walker_rocket_loop3()
+{SELFPARAM();
+    vector newdir;
+    self.nextthink = time;
+
+    if (self.max_health < time)
+    {
+        self.think = walker_rocket_explode;
+        return;
+    }
+
+    if (vlen(self.origin - self.tur_shotorg) < 100 )
+    {
+        self.think = walker_rocket_think;
+        return;
+    }
+
+    newdir = steerlib_pull(self.tur_shotorg);
+    WALKER_ROCKET_MOVE;
+
+    self.angles = vectoangles(self.velocity);
+}
+
+void walker_rocket_loop2()
+{SELFPARAM();
+    vector newdir;
+
+    self.nextthink = time;
+
+    if (self.max_health < time)
+    {
+        self.think = walker_rocket_explode;
+        return;
+    }
+
+    if (vlen(self.origin - self.tur_shotorg) < 100 )
+    {
+        self.tur_shotorg = self.origin - '0 0 200';
+        self.think = walker_rocket_loop3;
+        return;
+    }
+
+    newdir = steerlib_pull(self.tur_shotorg);
+    WALKER_ROCKET_MOVE;
+}
+
+void walker_rocket_loop()
+{SELFPARAM();
+    self.nextthink = time;
+    self.tur_shotorg = self.origin + '0 0 300';
+    self.think = walker_rocket_loop2;
+    self.shot_dmg = 1337;
+}
+
+void walker_fire_rocket(vector org)
+{SELFPARAM();
+    entity rocket;
+
+    fixedmakevectors(self.angles);
+
+    te_explosion (org);
+
+    rocket = spawn ();
+    setorigin(rocket, org);
+
+    sound (self, CH_WEAPON_A, SND_HAGAR_FIRE, VOL_BASE, ATTEN_NORM);
+    setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+
+    rocket.classname             = "walker_rocket";
+    rocket.owner                         = self;
+    rocket.bot_dodge             = true;
+    rocket.bot_dodgerating     = 50;
+    rocket.takedamage           = DAMAGE_YES;
+    rocket.damageforcescale   = 2;
+    rocket.health                       = 25;
+    rocket.tur_shotorg         = randomvec() * 512;
+    rocket.cnt                         = time + 1;
+    rocket.enemy                         = self.enemy;
+
+    if (random() < 0.01)
+        rocket.think             = walker_rocket_loop;
+    else
+        rocket.think             = walker_rocket_think;
+
+    rocket.event_damage           = walker_rocket_damage;
+
+    rocket.nextthink             = time;
+    rocket.movetype               = MOVETYPE_FLY;
+    rocket.velocity               = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
+    rocket.angles                       = vectoangles(rocket.velocity);
+    rocket.touch                         = walker_rocket_explode;
+    rocket.flags                         = FL_PROJECTILE;
+    rocket.solid                         = SOLID_BBOX;
+    rocket.max_health           = time + 9;
+    rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
+
+    CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound
+}
+
+.vector enemy_last_loc;
+.float enemy_last_time;
+void walker_move_to(vector _target, float _dist)
+{SELFPARAM();
+    switch (self.waterlevel)
+    {
+        case WATERLEVEL_NONE:
+            if (_dist > 500)
+                self.animflag = ANIM_RUN;
+            else
+                self.animflag = ANIM_WALK;
+        case WATERLEVEL_WETFEET:
+        case WATERLEVEL_SWIMMING:
+            if (self.animflag != ANIM_SWIM)
+                self.animflag = ANIM_WALK;
+            else
+                self.animflag = ANIM_SWIM;
+            break;
+        case WATERLEVEL_SUBMERGED:
+            self.animflag = ANIM_SWIM;
+    }
+
+    self.moveto = _target;
+    self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
+
+    if(self.enemy)
+    {
+        self.enemy_last_loc = _target;
+        self.enemy_last_time = time;
+    }
+}
+
+//#define WALKER_FANCYPATHING
+
+void walker_move_path()
+{SELFPARAM();
+#ifdef WALKER_FANCYPATHING
+    // Are we close enougth to a path node to switch to the next?
+    if (vlen(self.origin  - self.pathcurrent.origin) < 64)
+        if (self.pathcurrent.path_next == world)
+        {
+            // Path endpoint reached
+            pathlib_deletepath(self.pathcurrent.owner);
+            self.pathcurrent = world;
+
+            if (self.pathgoal)
+            {
+                if (self.pathgoal.use)
+                    self.pathgoal.use();
+
+                if (self.pathgoal.enemy)
+                {
+                    self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
+                    self.pathgoal = self.pathgoal.enemy;
+                }
+            }
+            else
+                self.pathgoal = world;
+        }
+        else
+            self.pathcurrent = self.pathcurrent.path_next;
+
+    self.moveto = self.pathcurrent.origin;
+    self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
+    walker_move_to(self.moveto, 0);
+
+#else
+    if (vlen(self.origin - self.pathcurrent.origin) < 64)
+        self.pathcurrent = self.pathcurrent.enemy;
+
+    if(!self.pathcurrent)
+        return;
+
+    self.moveto = self.pathcurrent.origin;
+    self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
+    walker_move_to(self.moveto, 0);
+#endif
+}
+
+void spawnfunc_turret_walker() { SELFPARAM(); if(!turret_initialize(TUR_WALKER.m_id)) remove(self); }
+
+float t_walker(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_ATTACK:
+        {
+            sound (self, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
+            fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
+            Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+            return true;
+        }
+        case TR_THINK:
+        {
+            fixedmakevectors(self.angles);
+
+            if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
+                walker_move_path();
+            else if (self.enemy == world)
+            {
+                if(self.pathcurrent)
+                    walker_move_path();
+                else
+                {
+                    if(self.enemy_last_time != 0)
+                    {
+                        if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
+                            self.enemy_last_time = 0;
+                        else
+                            walker_move_to(self.enemy_last_loc, 0);
+                    }
+                    else
+                    {
+                        if(self.animflag != ANIM_NO)
+                        {
+                            traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
+
+                            if(trace_fraction != 1.0)
+                                self.tur_head.idletime = -1337;
+                            else
+                            {
+                                traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
+                                if(trace_fraction == 1.0)
+                                    self.tur_head.idletime = -1337;
+                            }
+
+                            if(self.tur_head.idletime == -1337)
+                            {
+                                self.moveto = self.origin + randomvec() * 256;
+                                self.tur_head.idletime = 0;
+                            }
+
+                            self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
+                            self.moveto_z = self.origin_z + 64;
+                            walker_move_to(self.moveto, 0);
+                        }
+
+                        if(self.idletime < time)
+                        {
+                            if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
+                            {
+                                self.idletime = time + 1 + random() * 5;
+                                self.moveto = self.origin;
+                                self.animflag = ANIM_NO;
+                            }
+                            else
+                            {
+                                self.animflag = ANIM_WALK;
+                                self.idletime = time + 4 + random() * 2;
+                                self.moveto = self.origin + randomvec() * 256;
+                                self.tur_head.moveto = self.moveto;
+                                self.tur_head.idletime = 0;
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE)
+                {
+                    vector wish_angle;
+
+                    wish_angle = angleofs(self, self.enemy);
+                    if (self.animflag != ANIM_SWIM)
+                    if (fabs(wish_angle_y) < 15)
+                    {
+                        self.moveto   = self.enemy.origin;
+                        self.steerto  = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
+                        self.animflag = ANIM_MELEE;
+                    }
+                }
+                else if (self.tur_head.attack_finished_single < time)
+                {
+                    if(self.tur_head.shot_volly)
+                    {
+                        self.animflag = ANIM_NO;
+
+                        self.tur_head.shot_volly = self.tur_head.shot_volly -1;
+                        if(self.tur_head.shot_volly == 0)
+                            self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire);
+                        else
+                            self.tur_head.attack_finished_single = time + 0.2;
+
+                        if(self.tur_head.shot_volly > 1)
+                            walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
+                        else
+                            walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02")));
+                    }
+                    else
+                    {
+                        if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min))
+                        if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range))
+                            self.tur_head.shot_volly = 4;
+                    }
+                }
+                else
+                {
+                    if (self.animflag != ANIM_MELEE)
+                        walker_move_to(self.enemy.origin, self.tur_dist_enemy);
+                }
+            }
+
+            {
+                vector real_angle;
+                float turny = 0, turnx = 0;
+                float vz;
+
+                real_angle = vectoangles(self.steerto) - self.angles;
+                vz = self.velocity_z;
+
+                switch (self.animflag)
+                {
+                    case ANIM_NO:
+                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
+                        break;
+
+                    case ANIM_TURN:
+                        turny = (autocvar_g_turrets_unit_walker_turn);
+                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
+                        break;
+
+                    case ANIM_WALK:
+                        turny = (autocvar_g_turrets_unit_walker_turn_walk);
+                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6);
+                        break;
+
+                    case ANIM_RUN:
+                        turny = (autocvar_g_turrets_unit_walker_turn_run);
+                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6);
+                        break;
+
+                    case ANIM_STRAFE_L:
+                        turny = (autocvar_g_turrets_unit_walker_turn_strafe);
+                        movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
+                        break;
+
+                    case ANIM_STRAFE_R:
+                        turny = (autocvar_g_turrets_unit_walker_turn_strafe);
+                        movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
+                        break;
+
+                    case ANIM_JUMP:
+                        self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump);
+                        break;
+
+                    case ANIM_LAND:
+                        break;
+
+                    case ANIM_PAIN:
+                        if(self.frame != ANIM_PAIN)
+                            defer(0.25, walker_setnoanim);
+
+                        break;
+
+                    case ANIM_MELEE:
+                        if(self.frame != ANIM_MELEE)
+                        {
+                            defer(0.41, walker_setnoanim);
+                            defer(0.21, walker_melee_do_dmg);
+                        }
+
+                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
+                        break;
+
+                    case ANIM_SWIM:
+                        turny = (autocvar_g_turrets_unit_walker_turn_swim);
+                        turnx = (autocvar_g_turrets_unit_walker_turn_swim);
+
+                        self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
+                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3);
+                        vz = self.velocity_z + sin(time * 4) * 8;
+                        break;
+
+                    case ANIM_ROAM:
+                        turny = (autocvar_g_turrets_unit_walker_turn_walk);
+                        movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5);
+                        break;
+                }
+
+                if(turny)
+                {
+                    turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
+                    self.angles_y += turny;
+                }
+
+                if(turnx)
+                {
+                    turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
+                    self.angles_x += turnx;
+                }
+
+                self.velocity_z = vz;
+            }
+
+
+            if(self.origin != self.oldorigin)
+                self.SendFlags |= TNSF_MOVE;
+
+            self.oldorigin = self.origin;
+            turrets_setframe(self.animflag, false);
+
+            return true;
+        }
+        case TR_DEATH:
+        {
+#ifdef WALKER_FANCYPATHING
+            if (self.pathcurrent)
+                pathlib_deletepath(self.pathcurrent.owner);
+#endif
+            self.pathcurrent = world;
+
+            return true;
+        }
+        case TR_SETUP:
+        {
+            self.ticrate = 0.05;
+
+            entity e;
+
+            // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
+            if(self.movetype == MOVETYPE_WALK)
+            {
+                if(self.pos1)
+                    setorigin(self, self.pos1);
+                if(self.pos2)
+                    self.angles = self.pos2;
+            }
+
+            self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+            self.aim_flags = TFL_AIM_LEAD;
+            self.turret_flags |= TUR_FLAG_HITSCAN;
+
+            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+            self.iscreature = true;
+            self.teleportable = TELEPORT_NORMAL;
+            self.damagedbycontents = true;
+            self.solid = SOLID_SLIDEBOX;
+            self.takedamage = DAMAGE_AIM;
+            if(self.movetype != MOVETYPE_WALK)
+            {
+                setorigin(self, self.origin);
+                tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self);
+                setorigin(self, trace_endpos + '0 0 4');
+                self.pos1 = self.origin;
+                self.pos2 = self.angles;
+            }
+            self.movetype = MOVETYPE_WALK;
+            self.idle_aim = '0 0 0';
+            self.turret_firecheckfunc = walker_firecheck;
+
+            if (self.target != "")
+            {
+                e = find(world, targetname, self.target);
+                if (!e)
+                {
+                    LOG_TRACE("Initital waypoint for walker does NOT exsist, fix your map!\n");
+                    self.target = "";
+                }
+
+                if (e.classname != "turret_checkpoint")
+                    LOG_TRACE("Warning: not a turrret path\n");
+                else
+                {
+#ifdef WALKER_FANCYPATHING
+                    self.pathcurrent = WALKER_PATH(self.origin, e.origin);
+                    self.pathgoal = e;
+#else
+                    self.pathcurrent = e;
+#endif
+                }
+            }
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+
+#include "../../../client/movelib.qh"
+
+void walker_draw()
+{SELFPARAM();
+    float dt;
+
+    dt = time - self.move_time;
+    self.move_time = time;
+    if(dt <= 0)
+        return;
+
+    fixedmakevectors(self.angles);
+    movelib_groundalign4point(300, 100, 0.25, 45);
+    setorigin(self, self.origin + self.velocity * dt);
+    self.tur_head.angles += dt * self.tur_head.move_avelocity;
+    self.angles_y = self.move_angles_y;
+
+    if (self.health < 127)
+    if(random() < 0.15)
+        te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
+}
+
+float t_walker(float req)
+{SELFPARAM();
+    switch(req)
+    {
+        case TR_SETUP:
+        {
+            self.gravity               = 1;
+            self.movetype              = MOVETYPE_BOUNCE;
+            self.move_movetype = MOVETYPE_BOUNCE;
+            self.move_origin   = self.origin;
+            self.move_time             = time;
+            self.draw                  = walker_draw;
+
+            return true;
+        }
+        case TR_PRECACHE:
+        {
+            return true;
+        }
+    }
+
+    return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/ewheel.qc b/qcsrc/common/turrets/unit/ewheel.qc
deleted file mode 100644 (file)
index cd111b2..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ EWHEEL,
-/* function   */ t_ewheel,
-/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE | TUR_FLAG_ROAM,
-/* mins,maxs  */ '-32 -32 0', '32 32 48',
-/* model      */ "ewheel-base2.md3",
-/* head_model */ "ewheel-gun1.md3",
-/* netname    */ "ewheel",
-/* fullname   */ _("eWheel Turret")
-);
-#else
-#ifdef SVQC
-float autocvar_g_turrets_unit_ewheel_speed_fast;
-float autocvar_g_turrets_unit_ewheel_speed_slow;
-float autocvar_g_turrets_unit_ewheel_speed_slower;
-float autocvar_g_turrets_unit_ewheel_speed_stop;
-float autocvar_g_turrets_unit_ewheel_turnrate;
-
-const float ewheel_anim_stop = 0;
-const float ewheel_anim_fwd_slow = 1;
-const float ewheel_anim_fwd_fast = 2;
-const float ewheel_anim_bck_slow = 3;
-const float ewheel_anim_bck_fast = 4;
-
-//#define EWHEEL_FANCYPATH
-void ewheel_move_path()
-{SELFPARAM();
-#ifdef EWHEEL_FANCYPATH
-    // Are we close enougth to a path node to switch to the next?
-    if (vlen(self.origin  - self.pathcurrent.origin) < 64)
-        if (self.pathcurrent.path_next == world)
-        {
-            // Path endpoint reached
-            pathlib_deletepath(self.pathcurrent.owner);
-            self.pathcurrent = world;
-
-            if (self.pathgoal)
-            {
-                if (self.pathgoal.use)
-                    self.pathgoal.use();
-
-                if (self.pathgoal.enemy)
-                {
-                    self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
-                    self.pathgoal = self.pathgoal.enemy;
-                }
-            }
-            else
-                self.pathgoal = world;
-        }
-        else
-            self.pathcurrent = self.pathcurrent.path_next;
-
-#else
-    if (vlen(self.origin - self.pathcurrent.origin) < 64)
-        self.pathcurrent = self.pathcurrent.enemy;
-#endif
-
-    if (self.pathcurrent)
-    {
-
-        self.moveto = self.pathcurrent.origin;
-        self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-
-        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
-    }
-}
-
-void ewheel_move_enemy()
-{SELFPARAM();
-    float newframe;
-
-    self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
-
-    self.moveto  = self.origin + self.steerto * 128;
-
-    if (self.tur_dist_enemy > self.target_range_optimal)
-    {
-        if ( self.tur_head.spawnshieldtime < 1 )
-        {
-            newframe = ewheel_anim_fwd_fast;
-            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
-        }
-        else if (self.tur_head.spawnshieldtime < 2)
-        {
-
-            newframe = ewheel_anim_fwd_slow;
-            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
-       }
-        else
-        {
-            newframe = ewheel_anim_fwd_slow;
-            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
-        }
-    }
-    else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
-    {
-        newframe = ewheel_anim_bck_slow;
-        movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
-    }
-    else
-    {
-        newframe = ewheel_anim_stop;
-        movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
-    }
-
-    turrets_setframe(newframe, false);
-}
-
-void ewheel_move_idle()
-{SELFPARAM();
-    if(self.frame != 0)
-    {
-        self.SendFlags |= TNSF_ANIM;
-        self.anim_start_time = time;
-    }
-
-    self.frame = 0;
-    if (vlen(self.velocity))
-        movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
-}
-
-void spawnfunc_turret_ewheel() { SELFPARAM(); if(!turret_initialize(TUR_EWHEEL.m_id)) remove(self); }
-
-float t_ewheel(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            float i;
-            entity _mis;
-
-            for (i = 0; i < 1; ++i)
-            {
-                turret_do_updates(self);
-
-                _mis = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
-                _mis.missile_flags = MIF_SPLASH;
-
-                Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
-                self.tur_head.frame += 2;
-
-                if (self.tur_head.frame > 3)
-                    self.tur_head.frame = 0;
-            }
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            float vz;
-            vector wish_angle, real_angle;
-
-            vz = self.velocity_z;
-
-            self.angles_x = anglemods(self.angles_x);
-            self.angles_y = anglemods(self.angles_y);
-
-            fixedmakevectors(self.angles);
-
-            wish_angle = normalize(self.steerto);
-            wish_angle = vectoangles(wish_angle);
-            real_angle = wish_angle - self.angles;
-            real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
-
-            self.tur_head.spawnshieldtime = fabs(real_angle_y);
-            real_angle_y  = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
-            self.angles_y = (self.angles_y + real_angle_y);
-
-            if(self.enemy)
-                ewheel_move_enemy();
-            else if(self.pathcurrent)
-                ewheel_move_path();
-            else
-                ewheel_move_idle();
-
-            self.velocity_z = vz;
-
-            if(vlen(self.velocity))
-                self.SendFlags |= TNSF_MOVE;
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            self.velocity = '0 0 0';
-
-#ifdef EWHEEL_FANCYPATH
-            if (self.pathcurrent)
-                pathlib_deletepath(self.pathcurrent.owner);
-#endif
-            self.pathcurrent = world;
-
-            return true;
-        }
-        case TR_SETUP:
-        {
-            entity e;
-
-            if(self.movetype == MOVETYPE_WALK)
-            {
-                self.velocity = '0 0 0';
-                self.enemy = world;
-
-                setorigin(self, self.pos1);
-
-                if (self.target != "")
-                {
-                    e = find(world, targetname, self.target);
-                    if (!e)
-                    {
-                        LOG_TRACE("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
-                        self.target = "";
-                    }
-
-                    if (e.classname != "turret_checkpoint")
-                        LOG_TRACE("Warning: not a turrret path\n");
-                    else
-                    {
-
-#ifdef EWHEEL_FANCYPATH
-                        self.pathcurrent = WALKER_PATH(self.origin,e.origin);
-                        self.pathgoal = e;
-#else
-                        self.pathcurrent  = e;
-#endif
-                    }
-                }
-            }
-
-            self.iscreature                            = true;
-            self.teleportable                  = TELEPORT_NORMAL;
-            self.damagedbycontents             = true;
-            self.movetype                              = MOVETYPE_WALK;
-            self.solid                                 = SOLID_SLIDEBOX;
-            self.takedamage                            = DAMAGE_AIM;
-            self.idle_aim                              = '0 0 0';
-            self.pos1                                  = self.origin;
-            self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-            self.frame                                 = self.tur_head.frame = 1;
-            self.ammo_flags                            = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-
-            // Convert from dgr / sec to dgr / tic
-            self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
-            self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-
-void ewheel_draw()
-{SELFPARAM();
-    float dt;
-
-    dt = time - self.move_time;
-    self.move_time = time;
-    if(dt <= 0)
-        return;
-
-    fixedmakevectors(self.angles);
-    setorigin(self, self.origin + self.velocity * dt);
-    self.tur_head.angles += dt * self.tur_head.move_avelocity;
-    self.angles_y = self.move_angles_y;
-
-    if (self.health < 127)
-    if(random() < 0.05)
-        te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
-}
-
-float t_ewheel(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            self.gravity               = 1;
-            self.movetype              = MOVETYPE_BOUNCE;
-            self.move_movetype = MOVETYPE_BOUNCE;
-            self.move_origin   = self.origin;
-            self.move_time             = time;
-            self.draw                  = ewheel_draw;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/flac.qc b/qcsrc/common/turrets/unit/flac.qc
deleted file mode 100644 (file)
index e191160..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ FLAC,
-/* function   */ t_flac,
-/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_MISSILE,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "flac.md3",
-/* netname       */ "flac",
-/* fullname   */ _("FLAC Cannon")
-);
-#else
-#ifdef SVQC
-void turret_flac_projectile_think_explode()
-{SELFPARAM();
-    if(self.enemy != world)
-    if(vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3)
-        setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
-
-#ifdef TURRET_DEBUG
-    float d;
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
-    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
-    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
-    RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
-#endif
-    remove(self);
-}
-
-void spawnfunc_turret_flac() { SELFPARAM(); if(!turret_initialize(TUR_FLAC.m_id)) remove(self); }
-
-float t_flac(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            entity proj;
-
-            turret_tag_fire_update();
-
-            proj = turret_projectile(SND(HAGAR_FIRE), 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
-            Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-            proj.think   = turret_flac_projectile_think_explode;
-            proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
-            proj.missile_flags = MIF_SPLASH | MIF_PROXY;
-
-            self.tur_head.frame = self.tur_head.frame + 1;
-            if (self.tur_head.frame >= 4)
-                self.tur_head.frame = 0;
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-            self.damage_flags |= TFL_DMG_HEADSHAKE;
-            self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_flac(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/fusionreactor.qc b/qcsrc/common/turrets/unit/fusionreactor.qc
deleted file mode 100644 (file)
index 5a8df2a..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ FUSIONREACTOR,
-/* function   */ t_fusionreactor,
-/* spawnflags */ TUR_FLAG_SUPPORT | TUR_FLAG_AMMOSOURCE,
-/* mins,maxs  */ '-34 -34 0', '34 34 90',
-/* model         */ "base.md3",
-/* head_model */ "reactor.md3",
-/* netname       */ "fusionreactor",
-/* fullname   */ _("Fusion Reactor")
-);
-#else
-#ifdef SVQC
-bool turret_fusionreactor_firecheck()
-{SELFPARAM();
-    if (self.attack_finished_single > time)
-        return false;
-
-    if (self.enemy.deadflag != DEAD_NO)
-        return false;
-
-    if (self.enemy == world)
-        return false;
-
-    if (self.ammo < self.shot_dmg)
-        return false;
-
-    if (self.enemy.ammo >= self.enemy.ammo_max)
-        return false;
-
-    if (vlen(self.enemy.origin - self.origin) > self.target_range)
-        return false;
-
-    if(self.team != self.enemy.team)
-        return false;
-
-    if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
-        return false;
-
-    return true;
-}
-
-void spawnfunc_turret_fusionreactor() { SELFPARAM(); if(!turret_initialize(TUR_FUSIONREACTOR.m_id)) remove(self); }
-
-float t_fusionreactor(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            vector fl_org;
-
-            self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
-            fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
-            te_smallflash(fl_org);
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ammo_flags                            = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
-            self.target_select_flags   = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
-            self.firecheck_flags               = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
-            self.shoot_flags                   = TFL_SHOOT_HITALLVALID;
-            self.aim_flags                             = TFL_AIM_NO;
-            self.track_flags                   = TFL_TRACK_NO;
-
-            self.tur_head.scale = 0.75;
-            self.tur_head.avelocity = '0 50 0';
-
-            self.turret_firecheckfunc = turret_fusionreactor_firecheck;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_fusionreactor(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/hellion.qc b/qcsrc/common/turrets/unit/hellion.qc
deleted file mode 100644 (file)
index 56f5da9..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ HELLION,
-/* function   */ t_hellion,
-/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "hellion.md3",
-/* netname       */ "hellion",
-/* fullname   */ _("Hellion Missile Turret")
-);
-#else
-#ifdef SVQC
-float autocvar_g_turrets_unit_hellion_shot_speed_gain;
-float autocvar_g_turrets_unit_hellion_shot_speed_max;
-
-void turret_hellion_missile_think()
-{SELFPARAM();
-    vector olddir,newdir;
-    vector pre_pos;
-    float itime;
-
-    self.nextthink = time + 0.05;
-
-    olddir = normalize(self.velocity);
-
-    if(self.max_health < time)
-        turret_projectile_explode();
-
-    // Enemy dead? just keep on the current heading then.
-    if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
-    {
-
-        // Make sure we dont return to tracking a respawned player
-        self.enemy = world;
-
-        // Turn model
-        self.angles = vectoangles(self.velocity);
-
-        if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
-            turret_projectile_explode();
-
-        // Accelerate
-        self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
-
-        UpdateCSQCProjectile(self);
-
-        return;
-    }
-
-    // Enemy in range?
-    if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
-        turret_projectile_explode();
-
-    // Predict enemy position
-    itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
-    pre_pos = self.enemy.origin + self.enemy.velocity * itime;
-
-    pre_pos = (pre_pos + self.enemy.origin) * 0.5;
-
-    // Find out the direction to that place
-    newdir = normalize(pre_pos - self.origin);
-
-    // Turn
-    newdir = normalize(olddir + newdir * 0.35);
-
-    // Turn model
-    self.angles = vectoangles(self.velocity);
-
-    // Accelerate
-    self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
-
-    if (itime < 0.05)
-        self.think = turret_projectile_explode;
-
-    UpdateCSQCProjectile(self);
-}
-
-void spawnfunc_turret_hellion() { SELFPARAM(); if(!turret_initialize(TUR_HELLION.m_id)) remove(self); }
-
-float t_hellion(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            entity missile;
-
-            if(self.tur_head.frame != 0)
-                self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
-            else
-                self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
-
-            missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
-            te_explosion (missile.origin);
-            missile.think              = turret_hellion_missile_think;
-            missile.nextthink  = time;
-            missile.flags              = FL_PROJECTILE;
-            missile.max_health   = time + 9;
-            missile.tur_aimpos   = randomvec() * 128;
-            missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
-            self.tur_head.frame += 1;
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            if (self.tur_head.frame != 0)
-                self.tur_head.frame += 1;
-
-            if (self.tur_head.frame >= 7)
-                self.tur_head.frame = 0;
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.aim_flags = TFL_AIM_SIMPLE;
-            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
-            self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
-            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_hellion(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/hk.qc b/qcsrc/common/turrets/unit/hk.qc
deleted file mode 100644 (file)
index 106c982..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ HK,
-/* function   */ t_hk,
-/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER | TUR_FLAG_RECIEVETARGETS,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "hk.md3",
-/* netname       */ "hk",
-/* fullname   */ _("Hunter-Killer Turret")
-);
-#else
-#ifdef SVQC
-float autocvar_g_turrets_unit_hk_shot_speed;
-float autocvar_g_turrets_unit_hk_shot_speed_accel;
-float autocvar_g_turrets_unit_hk_shot_speed_accel2;
-float autocvar_g_turrets_unit_hk_shot_speed_decel;
-float autocvar_g_turrets_unit_hk_shot_speed_max;
-float autocvar_g_turrets_unit_hk_shot_speed_turnrate;
-
-//#define TURRET_DEBUG_HK
-
-#ifdef TURRET_DEBUG_HK
-.float atime;
-#endif
-
-float hk_is_valid_target(entity e_target)
-{SELFPARAM();
-    if (e_target == world)
-        return 0;
-
-    // If only this was used more..
-    if (e_target.flags & FL_NOTARGET)
-        return 0;
-
-    // Cant touch this
-    if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
-        return 0;
-
-    // player
-    if (IS_CLIENT(e_target))
-    {
-        if (self.owner.target_select_playerbias < 0)
-            return 0;
-
-        if (e_target.deadflag != DEAD_NO)
-            return 0;
-    }
-
-    // Missile
-    if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
-        return 0;
-
-    // Team check
-    if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
-        return 0;
-
-    return 1;
-}
-
-void turret_hk_missile_think()
-{SELFPARAM();
-    vector vu, vd, vf, vl, vr, ve;  // Vector (direction)
-    float  fu, fd, ff, fl, fr, fe;  // Fraction to solid
-    vector olddir,wishdir,newdir;   // Final direction
-    float lt_for;   // Length of Trace FORwrad
-    float lt_seek;  // Length of Trace SEEK (left, right, up down)
-    float pt_seek;  // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
-    vector pre_pos;
-    float myspeed;
-    entity e;
-    float ad,edist;
-
-    self.nextthink = time + self.ticrate;
-
-    //if (self.cnt < time)
-    // turret_hk_missile_explode();
-
-    if (self.enemy.deadflag != DEAD_NO)
-        self.enemy = world;
-
-    // Pick the closest valid target.
-    if (!self.enemy)
-    {
-        e = findradius(self.origin, 5000);
-        while (e)
-        {
-            if (hk_is_valid_target(e))
-            {
-                if (!self.enemy)
-                    self.enemy = e;
-                else
-                    if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
-                        self.enemy = e;
-            }
-            e = e.chain;
-        }
-    }
-
-    self.angles = vectoangles(self.velocity);
-    self.angles_x = self.angles_x * -1;
-    makevectors(self.angles);
-    self.angles_x = self.angles_x * -1;
-
-    if (self.enemy)
-    {
-        edist = vlen(self.origin - self.enemy.origin);
-        // Close enougth to do decent damage?
-        if ( edist <= (self.owner.shot_radius * 0.25) )
-        {
-            turret_projectile_explode();
-            return;
-        }
-
-        // Get data on enemy position
-        pre_pos = self.enemy.origin +
-                  self.enemy.velocity *
-                  min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
-
-        traceline(self.origin, pre_pos,true,self.enemy);
-        ve = normalize(pre_pos - self.origin);
-        fe = trace_fraction;
-
-    }
-    else
-    {
-    edist = 0;
-    ve = '0 0 0';
-        fe = 0;
-    }
-
-    if ((fe != 1) || (self.enemy == world) || (edist > 1000))
-    {
-        myspeed = vlen(self.velocity);
-
-        lt_for  = myspeed * 3;
-        lt_seek = myspeed * 2.95;
-
-        // Trace forward
-        traceline(self.origin, self.origin + v_forward * lt_for,false,self);
-        vf = trace_endpos;
-        ff = trace_fraction;
-
-        // Find angular offset
-        ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
-
-        // To close to something, Slow down!
-        if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) )
-            myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed));
-
-        // Failry clear, accelerate.
-        if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) )
-            myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max));
-
-        // Setup trace pitch
-        pt_seek = 1 - ff;
-        pt_seek = bound(0.15,pt_seek,0.8);
-        if (ff < 0.5) pt_seek = 1;
-
-        // Trace left
-        traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self);
-        vl = trace_endpos;
-        fl = trace_fraction;
-
-        // Trace right
-        traceline(self.origin,  self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
-        vr = trace_endpos;
-        fr = trace_fraction;
-
-        // Trace up
-        traceline(self.origin,  self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
-        vu = trace_endpos;
-        fu = trace_fraction;
-
-        // Trace down
-        traceline(self.origin,  self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
-        vd = trace_endpos;
-        fd = trace_fraction;
-
-        vl = normalize(vl - self.origin);
-        vr = normalize(vr - self.origin);
-        vu = normalize(vu - self.origin);
-        vd = normalize(vd - self.origin);
-
-        // Panic tresh passed, find a single direction and turn as hard as we can
-        if (pt_seek == 1)
-        {
-            wishdir = v_right;
-            if (fl > fr) wishdir = -1 * v_right;
-            if (fu > fl) wishdir = v_up;
-            if (fd > fu) wishdir = -1 * v_up;
-        }
-        else
-        {
-            // Normalize our trace vectors to make a smooth path
-            wishdir = normalize( (vl * fl) + (vr * fr) +  (vu * fu) +  (vd * fd) );
-        }
-
-        if (self.enemy)
-        {
-            if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
-            wishdir = (wishdir * (1 - fe)) + (ve * fe);
-        }
-    }
-    else
-    {
-        // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
-        myspeed = vlen(self.velocity);
-        if (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max))
-            myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
-
-        wishdir = ve;
-    }
-
-    if ((myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) && (self.cnt > time))
-        myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
-
-    // Ranoutagazfish?
-    if (self.cnt < time)
-    {
-        self.cnt = time + 0.25;
-        self.nextthink = 0;
-        self.movetype           = MOVETYPE_BOUNCE;
-        return;
-    }
-
-    // Calculate new heading
-    olddir = normalize(self.velocity);
-    newdir = normalize(olddir + wishdir * (autocvar_g_turrets_unit_hk_shot_speed_turnrate));
-
-    // Set heading & speed
-    self.velocity = newdir * myspeed;
-
-    // Align model with new heading
-    self.angles = vectoangles(self.velocity);
-
-
-#ifdef TURRET_DEBUG_HK
-    //if(self.atime < time) {
-    if ((fe <= 0.99)||(edist > 1000))
-    {
-        te_lightning2(world,self.origin, self.origin + vr * lt_seek);
-        te_lightning2(world,self.origin, self.origin + vl * lt_seek);
-        te_lightning2(world,self.origin, self.origin + vu * lt_seek);
-        te_lightning2(world,self.origin, self.origin + vd * lt_seek);
-        te_lightning2(world,self.origin, vf);
-    }
-    else
-    {
-        te_lightning2(world,self.origin, self.enemy.origin);
-    }
-    bprint("Speed: ", ftos(rint(myspeed)), "\n");
-    bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
-    bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
-    self.atime = time + 0.2;
-    //}
-#endif
-
-    UpdateCSQCProjectile(self);
-}
-
-float turret_hk_addtarget(entity e_target,entity e_sender)
-{SELFPARAM();
-    if (e_target)
-    {
-        if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
-        {
-            self.enemy = e_target;
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
-void spawnfunc_turret_hk() { SELFPARAM(); if(!turret_initialize(TUR_HK.m_id)) remove(self); }
-
-float t_hk(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            entity missile;
-
-            missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
-            te_explosion (missile.origin);
-
-            missile.think                      = turret_hk_missile_think;
-            missile.nextthink          = time + 0.25;
-            missile.movetype            = MOVETYPE_BOUNCEMISSILE;
-            missile.velocity            = self.tur_shotdir_updated * (self.shot_speed * 0.75);
-            missile.angles                = vectoangles(missile.velocity);
-            missile.cnt                          = time + 30;
-            missile.ticrate              = max(autocvar_sys_ticrate, 0.05);
-            missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_AI;
-
-            if (self.tur_head.frame == 0)
-                self.tur_head.frame = self.tur_head.frame + 1;
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            if (self.tur_head.frame != 0)
-                self.tur_head.frame = self.tur_head.frame + 1;
-
-            if (self.tur_head.frame > 5)
-                self.tur_head.frame = 0;
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-            self.aim_flags = TFL_AIM_SIMPLE;
-            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-            self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
-            self.shoot_flags = TFL_SHOOT_CLEARTARGET;
-            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
-
-            self.turret_addtarget = turret_hk_addtarget;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_hk(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/machinegun.qc b/qcsrc/common/turrets/unit/machinegun.qc
deleted file mode 100644 (file)
index 35f1921..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ MACHINEGUN,
-/* function   */ t_machinegun,
-/* spawnflags */ TUR_FLAG_PLAYER,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "machinegun.md3",
-/* netname       */ "machinegun",
-/* fullname   */ _("Machinegun Turret")
-);
-#else
-#ifdef SVQC
-void spawnfunc_turret_machinegun() { SELFPARAM(); if(!turret_initialize(TUR_MACHINEGUN.m_id)) remove(self); }
-
-void W_MachineGun_MuzzleFlash(void);
-
-float t_machinegun(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
-
-            W_MachineGun_MuzzleFlash();
-            setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.damage_flags |= TFL_DMG_HEADSHAKE;
-            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-            self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-            self.turret_flags |= TUR_FLAG_HITSCAN;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_machinegun(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/mlrs.qc b/qcsrc/common/turrets/unit/mlrs.qc
deleted file mode 100644 (file)
index 21e0a43..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ MLRS,
-/* function   */ t_mlrs,
-/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "mlrs.md3",
-/* netname       */ "mlrs",
-/* fullname   */ _("MLRS Turret")
-);
-#else
-#ifdef SVQC
-void spawnfunc_turret_mlrs() { SELFPARAM(); if(!turret_initialize(TUR_MLRS.m_id)) remove(self); }
-
-float t_mlrs(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            entity missile;
-
-            turret_tag_fire_update();
-            missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
-            missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
-            missile.missile_flags = MIF_SPLASH;
-            te_explosion (missile.origin);
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            // 0 = full, 6 = empty
-            self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
-            if(self.tur_head.frame < 0)
-            {
-                LOG_TRACE("ammo:",ftos(self.ammo),"\n");
-                LOG_TRACE("shot_dmg:",ftos(self.shot_dmg),"\n");
-            }
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-
-            self.damage_flags |= TFL_DMG_HEADSHAKE;
-            self.shoot_flags  |= TFL_SHOOT_VOLLYALWAYS;
-            self.volly_counter = self.shot_volly;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_mlrs(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/phaser.qc b/qcsrc/common/turrets/unit/phaser.qc
deleted file mode 100644 (file)
index 04e2264..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ PHASER,
-/* function   */ t_phaser,
-/* spawnflags */ TUR_FLAG_SNIPER | TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "phaser.md3",
-/* netname       */ "phaser",
-/* fullname   */ _("Phaser Cannon")
-);
-#else
-#ifdef SVQC
-.float fireflag;
-
-float turret_phaser_firecheck()
-{SELFPARAM();
-    if (self.fireflag != 0) return 0;
-    return turret_firecheck();
-}
-
-void beam_think()
-{SELFPARAM();
-    if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
-    {
-        self.owner.attack_finished_single = time + self.owner.shot_refire;
-        self.owner.fireflag = 2;
-        self.owner.tur_head.frame = 10;
-        sound (self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
-        remove(self);
-        return;
-    }
-
-    turret_do_updates(self.owner);
-
-    if (time - self.shot_spread > 0)
-    {
-        self.shot_spread = time + 2;
-        sound (self, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
-    }
-
-
-    self.nextthink = time + self.ticrate;
-
-    self.owner.attack_finished_single = time + frametime;
-    setself(self.owner);
-    FireImoBeam (   self.tur_shotorg,
-                    self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
-                    '-1 -1 -1' * self.shot_radius,
-                    '1 1 1' * self.shot_radius,
-                    self.shot_force,
-                    this.shot_dmg,
-                    0.75,
-                    DEATH_TURRET_PHASER);
-    setself(this);
-    self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
-
-}
-
-void spawnfunc_turret_phaser() { SELFPARAM(); if(!turret_initialize(TUR_PHASER.m_id)) remove(self); }
-
-float t_phaser(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            entity beam;
-
-            beam = spawn();
-            beam.ticrate = 0.1; //autocvar_sys_ticrate;
-            setmodel(beam, MDL_TUR_PHASER_BEAM);
-            beam.effects = EF_LOWPRECISION;
-            beam.solid = SOLID_NOT;
-            beam.think = beam_think;
-            beam.cnt = time + self.shot_speed;
-            beam.shot_spread = time + 2;
-            beam.nextthink = time;
-            beam.owner = self;
-            beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
-            beam.scale = self.target_range / 256;
-            beam.movetype = MOVETYPE_NONE;
-            beam.enemy = self.enemy;
-            beam.bot_dodge = true;
-            beam.bot_dodgerating = beam.shot_dmg;
-            sound (beam, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
-            self.fireflag = 1;
-
-            beam.attack_finished_single = self.attack_finished_single;
-            self.attack_finished_single = time; // + autocvar_sys_ticrate;
-
-            setattachment(beam,self.tur_head,"tag_fire");
-
-            soundat (self, trace_endpos, CH_SHOTS, SND(NEXIMPACT), VOL_BASE, ATTEN_NORM);
-
-            if (self.tur_head.frame == 0)
-                self.tur_head.frame = 1;
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            if (self.tur_head.frame != 0)
-            {
-                if (self.fireflag == 1)
-                {
-                    if (self.tur_head.frame == 10)
-                        self.tur_head.frame = 1;
-                    else
-                        self.tur_head.frame = self.tur_head.frame +1;
-                }
-                else if (self.fireflag == 2 )
-                {
-                    self.tur_head.frame = self.tur_head.frame +1;
-                    if (self.tur_head.frame == 15)
-                    {
-                        self.tur_head.frame = 0;
-                        self.fireflag = 0;
-                    }
-                }
-            }
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            self.aim_flags = TFL_AIM_LEAD;
-
-            self.turret_firecheckfunc = turret_phaser_firecheck;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_phaser(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/plasma.qc b/qcsrc/common/turrets/unit/plasma.qc
deleted file mode 100644 (file)
index baafa51..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ PLASMA,
-/* function   */ t_plasma,
-/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "plasma.md3",
-/* netname       */ "plasma",
-/* fullname   */ _("Plasma Cannon")
-);
-#else
-#ifdef SVQC
-void spawnfunc_turret_plasma() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA.m_id)) remove(self); }
-
-float t_plasma(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            if(g_instagib)
-            {
-                float flying;
-                flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-
-                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
-                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
-
-                Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
-                // teamcolor / hit beam effect
-                vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-                WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
-                if (self.tur_head.frame == 0)
-                    self.tur_head.frame = 1;
-            }
-            else
-            {
-                entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
-                missile.missile_flags = MIF_SPLASH;
-
-                Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                if (self.tur_head.frame == 0)
-                    self.tur_head.frame = 1;
-            }
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            if (self.tur_head.frame != 0)
-                self.tur_head.frame = self.tur_head.frame + 1;
-
-            if (self.tur_head.frame > 5)
-                self.tur_head.frame = 0;
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            self.damage_flags |= TFL_DMG_HEADSHAKE;
-            self.firecheck_flags |= TFL_FIRECHECK_AFF;
-            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
-
-            turret_do_updates(self);
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_plasma(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/plasma_dual.qc b/qcsrc/common/turrets/unit/plasma_dual.qc
deleted file mode 100644 (file)
index 8b2bc25..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ PLASMA_DUAL,
-/* function   */ t_plasma_dual,
-/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
-/* mins,maxs  */ '-32 -32 0', '32 32 64',
-/* model         */ "base.md3",
-/* head_model */ "plasmad.md3",
-/* netname       */ "plasma_dual",
-/* fullname   */ _("Dual Plasma Cannon")
-);
-#else
-
-#include "../../weapons/all.qh"
-
-CLASS(PlasmaDualAttack, PortoLaunch)
-/* flags     */ ATTRIB(PlasmaDualAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(PlasmaDualAttack, impulse, int, 5);
-/* refname   */ ATTRIB(PlasmaDualAttack, netname, string, "plasmadual");
-/* wepname   */ ATTRIB(PlasmaDualAttack, message, string, _("Dual plasma"));
-ENDCLASS(PlasmaDualAttack)
-REGISTER_WEAPON(PLASMA_DUAL, NEW(PlasmaDualAttack));
-
-#ifdef SVQC
-
-float t_plasma_dual(float req);
-METHOD(PlasmaDualAttack, wr_think, bool(entity thiswep)) {
-       SELFPARAM();
-       if (self.BUTTON_ATCK)
-       if (weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire))) {
-               W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0);
-               self.tur_shotdir_updated = w_shotdir;
-               self.tur_shotorg = w_shotorg;
-               self.tur_head = self;
-        self.shot_speed = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed));
-        self.shot_spread = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500);
-               t_plasma_dual(TR_ATTACK);
-               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-       }
-       return true;
-}
-
-void spawnfunc_turret_plasma_dual() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA_DUAL.m_id)) remove(self); }
-
-float t_plasma_dual(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            if(g_instagib)
-            {
-                float flying;
-                flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-
-                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
-                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
-
-
-                Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
-                // teamcolor / hit beam effect
-                vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-                WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
-                self.tur_head.frame += 1;
-            }
-            else
-            {
-                entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
-                missile.missile_flags = MIF_SPLASH;
-                Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                self.tur_head.frame += 1;
-            }
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
-                self.tur_head.frame = self.tur_head.frame + 1;
-
-            if (self.tur_head.frame > 6)
-                self.tur_head.frame = 0;
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            self.damage_flags |= TFL_DMG_HEADSHAKE;
-            self.firecheck_flags |= TFL_FIRECHECK_AFF;
-            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
-
-            turret_do_updates(self);
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_plasma_dual(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/tesla.qc b/qcsrc/common/turrets/unit/tesla.qc
deleted file mode 100644 (file)
index d3c894b..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ TESLA,
-/* function   */ t_tesla,
-/* spawnflags */ TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
-/* mins,maxs  */ '-60 -60 0', '60 60 128',
-/* model         */ "tesla_base.md3",
-/* head_model */ "tesla_head.md3",
-/* netname       */ "tesla",
-/* fullname   */ _("Tesla Coil")
-);
-#else
-#ifdef SVQC
-entity toast(entity from, float range, float damage)
-{SELFPARAM();
-    entity e;
-    entity etarget = world;
-    float d,dd;
-    float r;
-
-    dd = range + 1;
-
-    e = findradius(from.origin,range);
-    while (e)
-    {
-        if ((e.railgunhit != 1) && (e != from))
-        {
-            r = turret_validate_target(self,e,self.target_validate_flags);
-            if (r > 0)
-            {
-                traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
-                if (trace_fraction == 1.0)
-                {
-                    d = vlen(e.origin - from.origin);
-                    if (d < dd)
-                    {
-                        dd = d;
-                        etarget = e;
-                    }
-                }
-            }
-        }
-        e = e.chain;
-    }
-
-    if (etarget)
-    {
-        te_csqc_lightningarc(from.origin,etarget.origin);
-        Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
-        etarget.railgunhit = 1;
-    }
-
-    return etarget;
-}
-
-float turret_tesla_firecheck()
-{SELFPARAM();
-    // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
-    float do_target_scan = 0;
-
-    if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
-        do_target_scan = 1;
-
-    // Old target (if any) invalid?
-    if(self.target_validate_time < time)
-    if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
-    {
-        self.enemy = world;
-        self.target_validate_time = time + 0.5;
-        do_target_scan = 1;
-    }
-
-    // But never more often then g_turrets_targetscan_mindelay!
-    if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
-        do_target_scan = 0;
-
-    if(do_target_scan)
-    {
-        self.enemy = turret_select_target();
-        self.target_select_time = time;
-    }
-
-    if(!turret_firecheck())
-        return 0;
-
-    if(self.enemy)
-        return 1;
-
-    return 0;
-}
-
-void spawnfunc_turret_tesla() { SELFPARAM(); if(!turret_initialize(TUR_TESLA.m_id)) remove(self); }
-
-float t_tesla(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            entity e, t;
-            float d, r, i;
-
-            d = self.shot_dmg;
-            r = self.target_range;
-            e = spawn();
-            setorigin(e,self.tur_shotorg);
-
-            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
-            t = toast(e,r,d);
-            remove(e);
-
-            if (t == world) return true;
-
-            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
-
-            self.attack_finished_single = time + self.shot_refire;
-            for (i = 0; i < 10; ++i)
-            {
-                d *= 0.75;
-                r *= 0.85;
-                t = toast(t, r, d);
-                if (t == world) break;
-
-            }
-
-            e = findchainfloat(railgunhit, 1);
-            while (e)
-            {
-                e.railgunhit = 0;
-                e = e.chain;
-            }
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            if(!self.active)
-            {
-                self.tur_head.avelocity = '0 0 0';
-                return true;
-            }
-
-            if(self.ammo < self.shot_dmg)
-            {
-                self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
-            }
-            else
-            {
-                self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
-
-                if(self.attack_finished_single > time)
-                    return true;
-
-                float f;
-                f = (self.ammo / self.ammo_max);
-                f = f * f;
-                if(f > random())
-                    if(random() < 0.1)
-                        te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
-            }
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                 TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
-            self.turret_firecheckfunc = turret_tesla_firecheck;
-            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                               TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
-            self.firecheck_flags       = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
-            self.shoot_flags           = TFL_SHOOT_CUSTOM;
-            self.ammo_flags                    = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            self.aim_flags                     = TFL_AIM_NO;
-            self.track_flags           = TFL_TRACK_NO;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-float t_tesla(float req)
-{
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
diff --git a/qcsrc/common/turrets/unit/walker.qc b/qcsrc/common/turrets/unit/walker.qc
deleted file mode 100644 (file)
index 792e7a3..0000000
+++ /dev/null
@@ -1,694 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_TURRET(
-/* TUR_##id   */ WALKER,
-/* function   */ t_walker,
-/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE,
-/* mins,maxs  */ '-70 -70 0', '70 70 95',
-/* model         */ "walker_body.md3",
-/* head_model */ "walker_head_minigun.md3",
-/* netname       */ "walker",
-/* fullname   */ _("Walker Turret")
-);
-#else
-#ifdef SVQC
-float autocvar_g_turrets_unit_walker_melee_damage;
-float autocvar_g_turrets_unit_walker_melee_force;
-float autocvar_g_turrets_unit_walker_melee_range;
-float autocvar_g_turrets_unit_walker_rocket_damage;
-float autocvar_g_turrets_unit_walker_rocket_radius;
-float autocvar_g_turrets_unit_walker_rocket_force;
-float autocvar_g_turrets_unit_walker_rocket_speed;
-float autocvar_g_turrets_unit_walker_rocket_range;
-float autocvar_g_turrets_unit_walker_rocket_range_min;
-float autocvar_g_turrets_unit_walker_rocket_refire;
-float autocvar_g_turrets_unit_walker_rocket_turnrate;
-float autocvar_g_turrets_unit_walker_speed_stop;
-float autocvar_g_turrets_unit_walker_speed_walk;
-float autocvar_g_turrets_unit_walker_speed_run;
-float autocvar_g_turrets_unit_walker_speed_jump;
-float autocvar_g_turrets_unit_walker_speed_swim;
-float autocvar_g_turrets_unit_walker_speed_roam;
-float autocvar_g_turrets_unit_walker_turn;
-float autocvar_g_turrets_unit_walker_turn_walk;
-float autocvar_g_turrets_unit_walker_turn_strafe;
-float autocvar_g_turrets_unit_walker_turn_swim;
-float autocvar_g_turrets_unit_walker_turn_run;
-
-#define ANIM_NO         0
-#define ANIM_TURN       1
-#define ANIM_WALK       2
-#define ANIM_RUN        3
-#define ANIM_STRAFE_L   4
-#define ANIM_STRAFE_R   5
-#define ANIM_JUMP       6
-#define ANIM_LAND       7
-#define ANIM_PAIN       8
-#define ANIM_MELEE      9
-#define ANIM_SWIM       10
-#define ANIM_ROAM       11
-
-.float animflag;
-.float idletime;
-
-#define WALKER_PATH(s,e) pathlib_astar(s,e)
-
-float walker_firecheck()
-{SELFPARAM();
-    if (self.animflag == ANIM_MELEE)
-        return 0;
-
-    return turret_firecheck();
-}
-
-void walker_melee_do_dmg()
-{SELFPARAM();
-    vector where;
-    entity e;
-
-    makevectors(self.angles);
-    where = self.origin + v_forward * 128;
-
-    e = findradius(where,32);
-    while (e)
-    {
-        if (turret_validate_target(self, e, self.target_validate_flags))
-            if (e != self && e.owner != self)
-                Damage(e, self, self, (autocvar_g_turrets_unit_walker_melee_damage), DEATH_TURRET_WALK_MELEE, '0 0 0', v_forward * (autocvar_g_turrets_unit_walker_melee_force));
-
-        e = e.chain;
-    }
-}
-
-void walker_setnoanim()
-{SELFPARAM();
-    turrets_setframe(ANIM_NO, false);
-    self.animflag = self.frame;
-}
-void walker_rocket_explode()
-{SELFPARAM();
-    RadiusDamage (self, self.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), self, world, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET, world);
-    remove (self);
-}
-
-void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-{SELFPARAM();
-    self.health = self.health - damage;
-    self.velocity = self.velocity + vforce;
-
-    if (self.health <= 0)
-        W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
-}
-
-#define WALKER_ROCKET_MOVE movelib_move_simple(newdir, (autocvar_g_turrets_unit_walker_rocket_speed), (autocvar_g_turrets_unit_walker_rocket_turnrate)); UpdateCSQCProjectile(self)
-void walker_rocket_loop();
-void walker_rocket_think()
-{SELFPARAM();
-    vector newdir;
-    float edist;
-    float itime;
-    float m_speed;
-
-    self.nextthink = time;
-
-    edist = vlen(self.enemy.origin - self.origin);
-
-    // Simulate crude guidance
-    if (self.cnt < time)
-    {
-        if (edist < 1000)
-            self.tur_shotorg = randomvec() * min(edist, 64);
-        else
-            self.tur_shotorg = randomvec() * min(edist, 256);
-
-        self.cnt = time + 0.5;
-    }
-
-    if (edist < 128)
-        self.tur_shotorg = '0 0 0';
-
-    if (self.max_health < time)
-    {
-        self.think       = walker_rocket_explode;
-        self.nextthink  = time;
-        return;
-    }
-
-    if (self.shot_dmg != 1337 && random() < 0.01)
-    {
-        walker_rocket_loop();
-        return;
-    }
-
-    m_speed = vlen(self.velocity);
-
-    // Enemy dead? just keep on the current heading then.
-    if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
-        self.enemy = world;
-
-    if (self.enemy)
-    {
-        itime = max(edist / m_speed, 1);
-        newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
-    }
-    else
-        newdir  = normalize(self.velocity);
-
-    WALKER_ROCKET_MOVE;
-}
-
-void walker_rocket_loop3()
-{SELFPARAM();
-    vector newdir;
-    self.nextthink = time;
-
-    if (self.max_health < time)
-    {
-        self.think = walker_rocket_explode;
-        return;
-    }
-
-    if (vlen(self.origin - self.tur_shotorg) < 100 )
-    {
-        self.think = walker_rocket_think;
-        return;
-    }
-
-    newdir = steerlib_pull(self.tur_shotorg);
-    WALKER_ROCKET_MOVE;
-
-    self.angles = vectoangles(self.velocity);
-}
-
-void walker_rocket_loop2()
-{SELFPARAM();
-    vector newdir;
-
-    self.nextthink = time;
-
-    if (self.max_health < time)
-    {
-        self.think = walker_rocket_explode;
-        return;
-    }
-
-    if (vlen(self.origin - self.tur_shotorg) < 100 )
-    {
-        self.tur_shotorg = self.origin - '0 0 200';
-        self.think = walker_rocket_loop3;
-        return;
-    }
-
-    newdir = steerlib_pull(self.tur_shotorg);
-    WALKER_ROCKET_MOVE;
-}
-
-void walker_rocket_loop()
-{SELFPARAM();
-    self.nextthink = time;
-    self.tur_shotorg = self.origin + '0 0 300';
-    self.think = walker_rocket_loop2;
-    self.shot_dmg = 1337;
-}
-
-void walker_fire_rocket(vector org)
-{SELFPARAM();
-    entity rocket;
-
-    fixedmakevectors(self.angles);
-
-    te_explosion (org);
-
-    rocket = spawn ();
-    setorigin(rocket, org);
-
-    sound (self, CH_WEAPON_A, SND_HAGAR_FIRE, VOL_BASE, ATTEN_NORM);
-    setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
-    rocket.classname             = "walker_rocket";
-    rocket.owner                         = self;
-    rocket.bot_dodge             = true;
-    rocket.bot_dodgerating     = 50;
-    rocket.takedamage           = DAMAGE_YES;
-    rocket.damageforcescale   = 2;
-    rocket.health                       = 25;
-    rocket.tur_shotorg         = randomvec() * 512;
-    rocket.cnt                         = time + 1;
-    rocket.enemy                         = self.enemy;
-
-    if (random() < 0.01)
-        rocket.think             = walker_rocket_loop;
-    else
-        rocket.think             = walker_rocket_think;
-
-    rocket.event_damage           = walker_rocket_damage;
-
-    rocket.nextthink             = time;
-    rocket.movetype               = MOVETYPE_FLY;
-    rocket.velocity               = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
-    rocket.angles                       = vectoangles(rocket.velocity);
-    rocket.touch                         = walker_rocket_explode;
-    rocket.flags                         = FL_PROJECTILE;
-    rocket.solid                         = SOLID_BBOX;
-    rocket.max_health           = time + 9;
-    rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
-
-    CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound
-}
-
-.vector enemy_last_loc;
-.float enemy_last_time;
-void walker_move_to(vector _target, float _dist)
-{SELFPARAM();
-    switch (self.waterlevel)
-    {
-        case WATERLEVEL_NONE:
-            if (_dist > 500)
-                self.animflag = ANIM_RUN;
-            else
-                self.animflag = ANIM_WALK;
-        case WATERLEVEL_WETFEET:
-        case WATERLEVEL_SWIMMING:
-            if (self.animflag != ANIM_SWIM)
-                self.animflag = ANIM_WALK;
-            else
-                self.animflag = ANIM_SWIM;
-            break;
-        case WATERLEVEL_SUBMERGED:
-            self.animflag = ANIM_SWIM;
-    }
-
-    self.moveto = _target;
-    self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-
-    if(self.enemy)
-    {
-        self.enemy_last_loc = _target;
-        self.enemy_last_time = time;
-    }
-}
-
-//#define WALKER_FANCYPATHING
-
-void walker_move_path()
-{SELFPARAM();
-#ifdef WALKER_FANCYPATHING
-    // Are we close enougth to a path node to switch to the next?
-    if (vlen(self.origin  - self.pathcurrent.origin) < 64)
-        if (self.pathcurrent.path_next == world)
-        {
-            // Path endpoint reached
-            pathlib_deletepath(self.pathcurrent.owner);
-            self.pathcurrent = world;
-
-            if (self.pathgoal)
-            {
-                if (self.pathgoal.use)
-                    self.pathgoal.use();
-
-                if (self.pathgoal.enemy)
-                {
-                    self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
-                    self.pathgoal = self.pathgoal.enemy;
-                }
-            }
-            else
-                self.pathgoal = world;
-        }
-        else
-            self.pathcurrent = self.pathcurrent.path_next;
-
-    self.moveto = self.pathcurrent.origin;
-    self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
-    walker_move_to(self.moveto, 0);
-
-#else
-    if (vlen(self.origin - self.pathcurrent.origin) < 64)
-        self.pathcurrent = self.pathcurrent.enemy;
-
-    if(!self.pathcurrent)
-        return;
-
-    self.moveto = self.pathcurrent.origin;
-    self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-    walker_move_to(self.moveto, 0);
-#endif
-}
-
-void spawnfunc_turret_walker() { SELFPARAM(); if(!turret_initialize(TUR_WALKER.m_id)) remove(self); }
-
-float t_walker(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_ATTACK:
-        {
-            sound (self, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
-            fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
-            Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
-            return true;
-        }
-        case TR_THINK:
-        {
-            fixedmakevectors(self.angles);
-
-            if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
-                walker_move_path();
-            else if (self.enemy == world)
-            {
-                if(self.pathcurrent)
-                    walker_move_path();
-                else
-                {
-                    if(self.enemy_last_time != 0)
-                    {
-                        if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
-                            self.enemy_last_time = 0;
-                        else
-                            walker_move_to(self.enemy_last_loc, 0);
-                    }
-                    else
-                    {
-                        if(self.animflag != ANIM_NO)
-                        {
-                            traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
-
-                            if(trace_fraction != 1.0)
-                                self.tur_head.idletime = -1337;
-                            else
-                            {
-                                traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
-                                if(trace_fraction == 1.0)
-                                    self.tur_head.idletime = -1337;
-                            }
-
-                            if(self.tur_head.idletime == -1337)
-                            {
-                                self.moveto = self.origin + randomvec() * 256;
-                                self.tur_head.idletime = 0;
-                            }
-
-                            self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
-                            self.moveto_z = self.origin_z + 64;
-                            walker_move_to(self.moveto, 0);
-                        }
-
-                        if(self.idletime < time)
-                        {
-                            if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
-                            {
-                                self.idletime = time + 1 + random() * 5;
-                                self.moveto = self.origin;
-                                self.animflag = ANIM_NO;
-                            }
-                            else
-                            {
-                                self.animflag = ANIM_WALK;
-                                self.idletime = time + 4 + random() * 2;
-                                self.moveto = self.origin + randomvec() * 256;
-                                self.tur_head.moveto = self.moveto;
-                                self.tur_head.idletime = 0;
-                            }
-                        }
-                    }
-                }
-            }
-            else
-            {
-                if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE)
-                {
-                    vector wish_angle;
-
-                    wish_angle = angleofs(self, self.enemy);
-                    if (self.animflag != ANIM_SWIM)
-                    if (fabs(wish_angle_y) < 15)
-                    {
-                        self.moveto   = self.enemy.origin;
-                        self.steerto  = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-                        self.animflag = ANIM_MELEE;
-                    }
-                }
-                else if (self.tur_head.attack_finished_single < time)
-                {
-                    if(self.tur_head.shot_volly)
-                    {
-                        self.animflag = ANIM_NO;
-
-                        self.tur_head.shot_volly = self.tur_head.shot_volly -1;
-                        if(self.tur_head.shot_volly == 0)
-                            self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire);
-                        else
-                            self.tur_head.attack_finished_single = time + 0.2;
-
-                        if(self.tur_head.shot_volly > 1)
-                            walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
-                        else
-                            walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02")));
-                    }
-                    else
-                    {
-                        if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min))
-                        if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range))
-                            self.tur_head.shot_volly = 4;
-                    }
-                }
-                else
-                {
-                    if (self.animflag != ANIM_MELEE)
-                        walker_move_to(self.enemy.origin, self.tur_dist_enemy);
-                }
-            }
-
-            {
-                vector real_angle;
-                float turny = 0, turnx = 0;
-                float vz;
-
-                real_angle = vectoangles(self.steerto) - self.angles;
-                vz = self.velocity_z;
-
-                switch (self.animflag)
-                {
-                    case ANIM_NO:
-                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
-                        break;
-
-                    case ANIM_TURN:
-                        turny = (autocvar_g_turrets_unit_walker_turn);
-                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
-                        break;
-
-                    case ANIM_WALK:
-                        turny = (autocvar_g_turrets_unit_walker_turn_walk);
-                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6);
-                        break;
-
-                    case ANIM_RUN:
-                        turny = (autocvar_g_turrets_unit_walker_turn_run);
-                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6);
-                        break;
-
-                    case ANIM_STRAFE_L:
-                        turny = (autocvar_g_turrets_unit_walker_turn_strafe);
-                        movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
-                        break;
-
-                    case ANIM_STRAFE_R:
-                        turny = (autocvar_g_turrets_unit_walker_turn_strafe);
-                        movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
-                        break;
-
-                    case ANIM_JUMP:
-                        self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump);
-                        break;
-
-                    case ANIM_LAND:
-                        break;
-
-                    case ANIM_PAIN:
-                        if(self.frame != ANIM_PAIN)
-                            defer(0.25, walker_setnoanim);
-
-                        break;
-
-                    case ANIM_MELEE:
-                        if(self.frame != ANIM_MELEE)
-                        {
-                            defer(0.41, walker_setnoanim);
-                            defer(0.21, walker_melee_do_dmg);
-                        }
-
-                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
-                        break;
-
-                    case ANIM_SWIM:
-                        turny = (autocvar_g_turrets_unit_walker_turn_swim);
-                        turnx = (autocvar_g_turrets_unit_walker_turn_swim);
-
-                        self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
-                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3);
-                        vz = self.velocity_z + sin(time * 4) * 8;
-                        break;
-
-                    case ANIM_ROAM:
-                        turny = (autocvar_g_turrets_unit_walker_turn_walk);
-                        movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5);
-                        break;
-                }
-
-                if(turny)
-                {
-                    turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
-                    self.angles_y += turny;
-                }
-
-                if(turnx)
-                {
-                    turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
-                    self.angles_x += turnx;
-                }
-
-                self.velocity_z = vz;
-            }
-
-
-            if(self.origin != self.oldorigin)
-                self.SendFlags |= TNSF_MOVE;
-
-            self.oldorigin = self.origin;
-            turrets_setframe(self.animflag, false);
-
-            return true;
-        }
-        case TR_DEATH:
-        {
-#ifdef WALKER_FANCYPATHING
-            if (self.pathcurrent)
-                pathlib_deletepath(self.pathcurrent.owner);
-#endif
-            self.pathcurrent = world;
-
-            return true;
-        }
-        case TR_SETUP:
-        {
-            self.ticrate = 0.05;
-
-            entity e;
-
-            // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
-            if(self.movetype == MOVETYPE_WALK)
-            {
-                if(self.pos1)
-                    setorigin(self, self.pos1);
-                if(self.pos2)
-                    self.angles = self.pos2;
-            }
-
-            self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            self.aim_flags = TFL_AIM_LEAD;
-            self.turret_flags |= TUR_FLAG_HITSCAN;
-
-            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-            self.iscreature = true;
-            self.teleportable = TELEPORT_NORMAL;
-            self.damagedbycontents = true;
-            self.solid = SOLID_SLIDEBOX;
-            self.takedamage = DAMAGE_AIM;
-            if(self.movetype != MOVETYPE_WALK)
-            {
-                setorigin(self, self.origin);
-                tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self);
-                setorigin(self, trace_endpos + '0 0 4');
-                self.pos1 = self.origin;
-                self.pos2 = self.angles;
-            }
-            self.movetype = MOVETYPE_WALK;
-            self.idle_aim = '0 0 0';
-            self.turret_firecheckfunc = walker_firecheck;
-
-            if (self.target != "")
-            {
-                e = find(world, targetname, self.target);
-                if (!e)
-                {
-                    LOG_TRACE("Initital waypoint for walker does NOT exsist, fix your map!\n");
-                    self.target = "";
-                }
-
-                if (e.classname != "turret_checkpoint")
-                    LOG_TRACE("Warning: not a turrret path\n");
-                else
-                {
-#ifdef WALKER_FANCYPATHING
-                    self.pathcurrent = WALKER_PATH(self.origin, e.origin);
-                    self.pathgoal = e;
-#else
-                    self.pathcurrent = e;
-#endif
-                }
-            }
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // SVQC
-#ifdef CSQC
-
-#include "../../../client/movelib.qh"
-
-void walker_draw()
-{SELFPARAM();
-    float dt;
-
-    dt = time - self.move_time;
-    self.move_time = time;
-    if(dt <= 0)
-        return;
-
-    fixedmakevectors(self.angles);
-    movelib_groundalign4point(300, 100, 0.25, 45);
-    setorigin(self, self.origin + self.velocity * dt);
-    self.tur_head.angles += dt * self.tur_head.move_avelocity;
-    self.angles_y = self.move_angles_y;
-
-    if (self.health < 127)
-    if(random() < 0.15)
-        te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
-}
-
-float t_walker(float req)
-{SELFPARAM();
-    switch(req)
-    {
-        case TR_SETUP:
-        {
-            self.gravity               = 1;
-            self.movetype              = MOVETYPE_BOUNCE;
-            self.move_movetype = MOVETYPE_BOUNCE;
-            self.move_origin   = self.origin;
-            self.move_time             = time;
-            self.draw                  = walker_draw;
-
-            return true;
-        }
-        case TR_PRECACHE:
-        {
-            return true;
-        }
-    }
-
-    return true;
-}
-
-#endif // CSQC
-#endif // REGISTER_TURRET
index e17e7adbcff7dd162f345a89a84e2b0b4e9bf8ad..2c889c09e977a9853dd7efde05578f08040e5786 100644 (file)
@@ -557,7 +557,6 @@ void spawnfunc___init_dedicated_server(void)
 
        // needs to be done so early because of the constants they create
        static_init();
-       CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
 
@@ -604,7 +603,6 @@ void spawnfunc_worldspawn (void)
 
        // needs to be done so early because of the constants they create
        static_init();
-       CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
 
index 4eceb36b98584c25035c9447ac24e40266c83934..86ede635042427fc3e36a60d565794120fcf2bfd 100644 (file)
 #include "../common/items/all.qc"
 #include "../common/monsters/all.qc"
 #include "../common/mutators/all.qc"
+#include "../common/turrets/all.qc"
 #include "../common/vehicles/all.qc"
-#include "../common/weapons/all.qc" // TODO
+#include "../common/weapons/all.qc"
 
 #include "../common/turrets/sv_turrets.qc"
 #include "../common/turrets/config.qc"
 #include "../common/turrets/util.qc"
-#include "../common/turrets/all.qc"
 #include "../common/turrets/checkpoint.qc"
 #include "../common/turrets/targettrigger.qc"
 #include "../common/weapons/config.qc"