]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Turrets: factor out attacks
authorTimePath <andrew.hardaker1995@gmail.com>
Wed, 30 Sep 2015 23:10:37 +0000 (09:10 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Wed, 30 Sep 2015 23:10:37 +0000 (09:10 +1000)
22 files changed:
qcsrc/common/turrets/turret/ewheel.qc
qcsrc/common/turrets/turret/ewheel_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/flac.qc
qcsrc/common/turrets/turret/flac_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/fusionreactor.qc
qcsrc/common/turrets/turret/hellion.qc
qcsrc/common/turrets/turret/hellion_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/hk.qc
qcsrc/common/turrets/turret/hk_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/machinegun.qc
qcsrc/common/turrets/turret/machinegun_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/mlrs.qc
qcsrc/common/turrets/turret/mlrs_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/phaser.qc
qcsrc/common/turrets/turret/phaser_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/plasma.qc
qcsrc/common/turrets/turret/plasma_dual.qc
qcsrc/common/turrets/turret/plasma_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/tesla.qc
qcsrc/common/turrets/turret/tesla_weapon.qc [new file with mode: 0644]
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/turrets/turret/walker_weapon.qc [new file with mode: 0644]

index b725c029f861b53bd907a41b2c7722cbdcb7f99b..6dab6172758f869fd12b9236d92bd3b6ee143281 100644 (file)
@@ -1,16 +1,10 @@
-#ifndef TUR_EWHEEL_H
-#define TUR_EWHEEL_H
-
-CLASS(EWheelAttack, PortoLaunch)
-/* flags     */ ATTRIB(EWheelAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(EWheelAttack, impulse, int, 5);
-/* refname   */ ATTRIB(EWheelAttack, netname, string, "turret_ewheel");
-/* wepname   */ ATTRIB(EWheelAttack, message, string, _("eWheel"));
-ENDCLASS(EWheelAttack)
-REGISTER_WEAPON(EWHEEL, NEW(EWheelAttack));
+#ifndef TURRET_EWHEEL_H
+#define TURRET_EWHEEL_H
 
 //#define EWHEEL_FANCYPATH
 
+#include "ewheel_weapon.qc"
+
 CLASS(EWheel, Turret)
 /* spawnflags */ ATTRIB(EWheel, spawnflags, int, TUR_FLAG_PLAYER | TUR_FLAG_MOVE | TUR_FLAG_ROAM);
 /* mins       */ ATTRIB(EWheel, mins, vector, '-32 -32 0');
@@ -27,38 +21,10 @@ REGISTER_TURRET(EWHEEL, NEW(EWheel));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
-void turret_initparams(entity);
-METHOD(EWheelAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       bool isPlayer = IS_PLAYER(self);
-       if (fire1)
-       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-               if (isPlayer) {
-            turret_initparams(self);
-            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;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-
-        turret_do_updates(self);
 
-        entity missile = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, true, true);
-        missile.missile_flags = MIF_SPLASH;
+#include "ewheel_weapon.qc"
 
-        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
-        if (!isPlayer) {
-            self.tur_head.frame += 2;
-
-            if (self.tur_head.frame > 3)
-                self.tur_head.frame = 0;
-        }
-       }
-       return true;
-}
+#ifdef SVQC
 
 float autocvar_g_turrets_unit_ewheel_speed_fast;
 float autocvar_g_turrets_unit_ewheel_speed_slow;
diff --git a/qcsrc/common/turrets/turret/ewheel_weapon.qc b/qcsrc/common/turrets/turret/ewheel_weapon.qc
new file mode 100644 (file)
index 0000000..64b7357
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef TURRET_EWHEEL_WEAPON_H
+#define TURRET_EWHEEL_WEAPON_H
+
+CLASS(EWheelAttack, PortoLaunch)
+/* flags     */ ATTRIB(EWheelAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(EWheelAttack, impulse, int, 5);
+/* refname   */ ATTRIB(EWheelAttack, netname, string, "turret_ewheel");
+/* wepname   */ ATTRIB(EWheelAttack, message, string, _("eWheel"));
+ENDCLASS(EWheelAttack)
+REGISTER_WEAPON(EWHEEL, NEW(EWheelAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+void turret_initparams(entity);
+METHOD(EWheelAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+
+        turret_do_updates(self);
+
+        entity missile = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, true, true);
+        missile.missile_flags = MIF_SPLASH;
+
+        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+        if (!isPlayer) {
+            self.tur_head.frame += 2;
+
+            if (self.tur_head.frame > 3)
+                self.tur_head.frame = 0;
+        }
+    }
+    return true;
+}
+
+#endif
+
+#endif
index c600c4fa92305b158df2434c81b1c69f5dc05398..a2de5cac4bb7289fe05eb8f341100f9528329c16 100644 (file)
@@ -1,13 +1,7 @@
-#ifndef TUR_FLAC_H
-#define TUR_FLAC_H
+#ifndef TURRET_FLAC_H
+#define TURRET_FLAC_H
 
-CLASS(FlacAttack, PortoLaunch)
-/* flags     */ ATTRIB(FlacAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(FlacAttack, impulse, int, 5);
-/* refname   */ ATTRIB(FlacAttack, netname, string, "turret_flac");
-/* wepname   */ ATTRIB(FlacAttack, message, string, _("FLAC"));
-ENDCLASS(FlacAttack)
-REGISTER_WEAPON(FLAC, NEW(FlacAttack));
+#include "flac_weapon.qc"
 
 CLASS(Flac, Turret)
 /* spawnflags */ ATTRIB(Flac, spawnflags, int, TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_MISSILE);
@@ -25,66 +19,21 @@ REGISTER_TURRET(FLAC, NEW(Flac));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
-void turret_flac_projectile_think_explode();
-METHOD(FlacAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       bool isPlayer = IS_PLAYER(self);
-       if (fire1)
-       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-               if (isPlayer) {
-            turret_initparams(self);
-            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.tur_impacttime = 10;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-
-        turret_tag_fire_update();
 
-        entity proj = turret_projectile(SND(HAGAR_FIRE), 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, true, true);
-        proj.missile_flags = MIF_SPLASH | MIF_PROXY;
-        proj.think       = turret_flac_projectile_think_explode;
-        proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
-        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+#include "flac_weapon.qc"
 
-        if (!isPlayer) {
-            self.tur_head.frame = self.tur_head.frame + 1;
-            if (self.tur_head.frame >= 4)
-                self.tur_head.frame = 0;
-        }
-       }
-       return true;
-}
+#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);
+void spawnfunc_turret_flac() { SELFPARAM(); if (!turret_initialize(TUR_FLAC)) remove(self); }
 
-#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);
+METHOD(Flac, tr_setup, void(Flac this, entity it))
+{
+    it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+    it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+    it.damage_flags |= TFL_DMG_HEADSHAKE;
+    it.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
 }
 
-void spawnfunc_turret_flac() { SELFPARAM(); if(!turret_initialize(TUR_FLAC)) remove(self); }
-
-        METHOD(Flac, tr_setup, void(Flac this, entity it))
-        {
-            it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-            it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-            it.damage_flags |= TFL_DMG_HEADSHAKE;
-            it.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
-        }
+#endif
 
-#endif // SVQC
 #endif
diff --git a/qcsrc/common/turrets/turret/flac_weapon.qc b/qcsrc/common/turrets/turret/flac_weapon.qc
new file mode 100644 (file)
index 0000000..d0de057
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef TURRET_FLAC_WEAPON_H
+#define TURRET_FLAC_WEAPON_H
+
+CLASS(FlacAttack, PortoLaunch)
+/* flags     */ ATTRIB(FlacAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(FlacAttack, impulse, int, 5);
+/* refname   */ ATTRIB(FlacAttack, netname, string, "turret_flac");
+/* wepname   */ ATTRIB(FlacAttack, message, string, _("FLAC"));
+ENDCLASS(FlacAttack)
+REGISTER_WEAPON(FLAC, NEW(FlacAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+void turret_flac_projectile_think_explode();
+METHOD(FlacAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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.tur_impacttime = 10;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+
+        turret_tag_fire_update();
+
+        entity proj = turret_projectile(SND(HAGAR_FIRE), 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, true, true);
+        proj.missile_flags = MIF_SPLASH | MIF_PROXY;
+        proj.think       = turret_flac_projectile_think_explode;
+        proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
+        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+        if (!isPlayer) {
+            self.tur_head.frame = self.tur_head.frame + 1;
+            if (self.tur_head.frame >= 4)
+                self.tur_head.frame = 0;
+        }
+    }
+    return true;
+}
+
+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 = 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);
+}
+
+#endif
+
+#endif
index 671d9a67299859640b171800048bfdb3586a9426..fcd6113779d986a66184d11834e7863a53c533f9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef TUR_FUSIONREACTOR_H
-#define TUR_FUSIONREACTOR_H
+#ifndef TURRET_FUSIONREACTOR_H
+#define TURRET_FUSIONREACTOR_H
 
 CLASS(FusionReactor, Turret)
 /* spawnflags */ ATTRIB(FusionReactor, spawnflags, int, TUR_FLAG_SUPPORT | TUR_FLAG_AMMOSOURCE);
@@ -46,32 +46,32 @@ bool turret_fusionreactor_firecheck()
     return true;
 }
 
-void spawnfunc_turret_fusionreactor() { SELFPARAM(); if(!turret_initialize(TUR_FUSIONREACTOR)) remove(self); }
-
-        METHOD(FusionReactor, tr_attack, void(FusionReactor this))
-        {
-            self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
-            vector fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
-            te_smallflash(fl_org);
-        }
-        METHOD(FusionReactor, tr_think, void(FusionReactor thistur))
-        {
-            self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
-        }
-        METHOD(FusionReactor, tr_setup, void(FusionReactor this, entity it))
-        {
-            it.ammo_flags                              = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
-            it.target_select_flags     = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
-            it.firecheck_flags         = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
-            it.shoot_flags                     = TFL_SHOOT_HITALLVALID;
-            it.aim_flags                               = TFL_AIM_NO;
-            it.track_flags                     = TFL_TRACK_NO;
-
-            it.tur_head.scale = 0.75;
-            it.tur_head.avelocity = '0 50 0';
-
-            it.turret_firecheckfunc = turret_fusionreactor_firecheck;
-        }
-
-#endif // SVQC
+void spawnfunc_turret_fusionreactor() { SELFPARAM(); if (!turret_initialize(TUR_FUSIONREACTOR)) remove(self); }
+
+METHOD(FusionReactor, tr_attack, void(FusionReactor this))
+{
+    self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
+    vector fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
+    te_smallflash(fl_org);
+}
+METHOD(FusionReactor, tr_think, void(FusionReactor thistur))
+{
+    self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
+}
+METHOD(FusionReactor, tr_setup, void(FusionReactor this, entity it))
+{
+    it.ammo_flags                              = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
+    it.target_select_flags     = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
+    it.firecheck_flags         = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
+    it.shoot_flags                     = TFL_SHOOT_HITALLVALID;
+    it.aim_flags                               = TFL_AIM_NO;
+    it.track_flags                     = TFL_TRACK_NO;
+
+    it.tur_head.scale = 0.75;
+    it.tur_head.avelocity = '0 50 0';
+
+    it.turret_firecheckfunc = turret_fusionreactor_firecheck;
+}
+
+#endif
 #endif
index e2661442cfa008e089ec66f909094531bd65a4c4..f2c6f7fc914061d214d86adfe5d6d17fd07d3b55 100644 (file)
@@ -1,13 +1,7 @@
-#ifndef TUR_HELLION_H
-#define TUR_HELLION_H
+#ifndef TURRET_HELLION_H
+#define TURRET_HELLION_H
 
-CLASS(HellionAttack, PortoLaunch)
-/* flags     */ ATTRIB(HellionAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(HellionAttack, impulse, int, 9);
-/* refname   */ ATTRIB(HellionAttack, netname, string, "turret_hellion");
-/* wepname   */ ATTRIB(HellionAttack, message, string, _("Hellion"));
-ENDCLASS(HellionAttack)
-REGISTER_WEAPON(HELLION, NEW(HellionAttack));
+#include "hellion_weapon.qc"
 
 CLASS(Hellion, Turret)
 /* spawnflags */ ATTRIB(Hellion, spawnflags, int, TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE);
@@ -25,124 +19,28 @@ REGISTER_TURRET(HELLION, NEW(Hellion));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
-void turret_hellion_missile_think();
-METHOD(HellionAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       bool isPlayer = IS_PLAYER(self);
-       if (fire1)
-       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-               if (isPlayer) {
-            turret_initparams(self);
-            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_radius = 500;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-        if (!isPlayer) {
-            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"));
-        }
-
-        entity 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;
-        if (!isPlayer) self.tur_head.frame += 1;
-       }
-       return true;
-}
-
-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);
+#include "hellion_weapon.qc"
 
-        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);
+#ifdef SVQC
 
-    // Accelerate
-    self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
+void spawnfunc_turret_hellion() { SELFPARAM(); if (!turret_initialize(TUR_HELLION)) remove(self); }
 
-    if (itime < 0.05)
-        self.think = turret_projectile_explode;
+METHOD(Hellion, tr_think, void(Hellion thistur))
+{
+    if (self.tur_head.frame != 0)
+        self.tur_head.frame += 1;
 
-    UpdateCSQCProjectile(self);
+    if (self.tur_head.frame >= 7)
+        self.tur_head.frame = 0;
+}
+METHOD(Hellion, tr_setup, void(Hellion this, entity it))
+{
+    it.aim_flags = TFL_AIM_SIMPLE;
+    it.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
+    it.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
+    it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
 }
 
-void spawnfunc_turret_hellion() { SELFPARAM(); if(!turret_initialize(TUR_HELLION)) remove(self); }
-
-        METHOD(Hellion, tr_think, void(Hellion thistur))
-        {
-            if (self.tur_head.frame != 0)
-                self.tur_head.frame += 1;
-
-            if (self.tur_head.frame >= 7)
-                self.tur_head.frame = 0;
-        }
-        METHOD(Hellion, tr_setup, void(Hellion this, entity it))
-        {
-            it.aim_flags = TFL_AIM_SIMPLE;
-            it.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
-            it.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
-            it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-        }
-
-#endif // SVQC
+#endif
 #endif
diff --git a/qcsrc/common/turrets/turret/hellion_weapon.qc b/qcsrc/common/turrets/turret/hellion_weapon.qc
new file mode 100644 (file)
index 0000000..c3fe8bc
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef TURRET_HELLION_WEAPON_H
+#define TURRET_HELLION_WEAPON_H
+
+CLASS(HellionAttack, PortoLaunch)
+/* flags     */ ATTRIB(HellionAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(HellionAttack, impulse, int, 9);
+/* refname   */ ATTRIB(HellionAttack, netname, string, "turret_hellion");
+/* wepname   */ ATTRIB(HellionAttack, message, string, _("Hellion"));
+ENDCLASS(HellionAttack)
+REGISTER_WEAPON(HELLION, NEW(HellionAttack));
+
+#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();
+METHOD(HellionAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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_radius = 500;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+        if (!isPlayer) {
+            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"));
+        }
+
+        entity 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;
+        if (!isPlayer) self.tur_head.frame += 1;
+    }
+    return true;
+}
+
+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);
+}
+
+#endif
+
+#endif
index f659b5e212014dd85b2d566798ffcaea143862c3..0d7dc6dd0af8103632f35d0741e1ba1e838f2778 100644 (file)
@@ -1,13 +1,9 @@
-#ifndef TUR_HK_H
-#define TUR_HK_H
+#ifndef TURRET_HK_H
+#define TURRET_HK_H
 
-CLASS(HunterKillerAttack, PortoLaunch)
-/* flags     */ ATTRIB(HunterKillerAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(HunterKillerAttack, impulse, int, 9);
-/* refname   */ ATTRIB(HunterKillerAttack, netname, string, "turret_hk");
-/* wepname   */ ATTRIB(HunterKillerAttack, message, string, _("Hunter-Killer"));
-ENDCLASS(HunterKillerAttack)
-REGISTER_WEAPON(HK, NEW(HunterKillerAttack));
+//#define TURRET_DEBUG_HK
+
+#include "hk_weapon.qc"
 
 CLASS(HunterKiller, Turret)
 /* spawnflags */ ATTRIB(HunterKiller, spawnflags, int, TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER | TUR_FLAG_RECIEVETARGETS);
@@ -25,286 +21,37 @@ REGISTER_TURRET(HK, NEW(HunterKiller));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
-void turret_hk_missile_think();
-METHOD(HunterKillerAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       bool isPlayer = IS_PLAYER(self);
-       if (fire1)
-       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-               if (isPlayer) {
-            turret_initparams(self);
-            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;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-        entity 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 (!isPlayer)
-        if (self.tur_head.frame == 0)
-            self.tur_head.frame = self.tur_head.frame + 1;
-       }
-       return true;
-}
+#include "hk_weapon.qc"
 
-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 SVQC
 
 #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;
+void spawnfunc_turret_hk() { SELFPARAM(); if(!turret_initialize(TUR_HK)) remove(self); }
 
-    // Team check
-    if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
-        return 0;
+METHOD(HunterKiller, tr_think, void(HunterKiller thistur))
+{
+    if (self.tur_head.frame != 0)
+        self.tur_head.frame = self.tur_head.frame + 1;
 
-    return 1;
+    if (self.tur_head.frame > 5)
+        self.tur_head.frame = 0;
 }
 
-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);
+METHOD(HunterKiller, tr_setup, void(HunterKiller this, entity it))
+{
+    it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+    it.aim_flags = TFL_AIM_SIMPLE;
+    it.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+    it.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
+    it.shoot_flags = TFL_SHOOT_CLEARTARGET;
+    it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
+
+    it.turret_addtarget = turret_hk_addtarget;
 }
 
 float turret_hk_addtarget(entity e_target,entity e_sender)
@@ -321,27 +68,5 @@ float turret_hk_addtarget(entity e_target,entity e_sender)
     return 0;
 }
 
-void spawnfunc_turret_hk() { SELFPARAM(); if(!turret_initialize(TUR_HK)) remove(self); }
-
-        METHOD(HunterKiller, tr_think, void(HunterKiller thistur))
-        {
-            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;
-        }
-        METHOD(HunterKiller, tr_setup, void(HunterKiller this, entity it))
-        {
-            it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-            it.aim_flags = TFL_AIM_SIMPLE;
-            it.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-            it.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
-            it.shoot_flags = TFL_SHOOT_CLEARTARGET;
-            it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
-
-            it.turret_addtarget = turret_hk_addtarget;
-        }
-
 #endif // SVQC
 #endif
diff --git a/qcsrc/common/turrets/turret/hk_weapon.qc b/qcsrc/common/turrets/turret/hk_weapon.qc
new file mode 100644 (file)
index 0000000..e3f838f
--- /dev/null
@@ -0,0 +1,297 @@
+#ifndef TURRET_HK_WEAPON_H
+#define TURRET_HK_WEAPON_H
+
+CLASS(HunterKillerAttack, PortoLaunch)
+/* flags     */ ATTRIB(HunterKillerAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(HunterKillerAttack, impulse, int, 9);
+/* refname   */ ATTRIB(HunterKillerAttack, netname, string, "turret_hk");
+/* wepname   */ ATTRIB(HunterKillerAttack, message, string, _("Hunter-Killer"));
+ENDCLASS(HunterKillerAttack)
+REGISTER_WEAPON(HK, NEW(HunterKillerAttack));
+
+#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;
+
+void turret_hk_missile_think();
+METHOD(HunterKillerAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2))
+{
+       SELFPARAM();
+       bool isPlayer = IS_PLAYER(self);
+       if (fire1)
+       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+               if (isPlayer) {
+            turret_initparams(self);
+            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;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+        entity 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 (!isPlayer)
+        if (self.tur_head.frame == 0)
+            self.tur_head.frame = self.tur_head.frame + 1;
+       }
+       return true;
+}
+
+bool hk_is_valid_target(entity e_target);
+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);
+}
+
+bool 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;
+}
+
+#endif
+
+#endif
index 336a0f7c8c200a312e999a9430a96e304247b800..8fc1f4251c78f9b1f6096f7afc27c2f4fe4840c5 100644 (file)
@@ -1,13 +1,7 @@
-#ifndef TUR_MACHINEGUN_H
-#define TUR_MACHINEGUN_H
+#ifndef TURRET_MACHINEGUN_H
+#define TURRET_MACHINEGUN_H
 
-CLASS(MachineGunTurretAttack, PortoLaunch)
-/* flags     */ ATTRIB(MachineGunTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(MachineGunTurretAttack, impulse, int, 9);
-/* refname   */ ATTRIB(MachineGunTurretAttack, netname, string, "turret_machinegun");
-/* wepname   */ ATTRIB(MachineGunTurretAttack, message, string, _("Machinegun"));
-ENDCLASS(MachineGunTurretAttack)
-REGISTER_WEAPON(TUR_MACHINEGUN, NEW(MachineGunTurretAttack));
+#include "machinegun_weapon.qc"
 
 CLASS(MachineGunTurret, Turret)
 /* spawnflags */ ATTRIB(MachineGunTurret, spawnflags, int, TUR_FLAG_PLAYER);
@@ -25,39 +19,21 @@ REGISTER_TURRET(MACHINEGUN, NEW(MachineGunTurret));
 #endif
 
 #ifdef IMPLEMENTATION
+
+#include "machinegun_weapon.qc"
+
 #ifdef SVQC
-void W_MachineGun_MuzzleFlash();
-
-METHOD(MachineGunTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       bool isPlayer = IS_PLAYER(self);
-       if (fire1)
-       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR(machinegun, sustained_refire))) {
-               if (isPlayer) {
-            turret_initparams(self);
-            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;
-            weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
-        }
-        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;
-}
 
-void spawnfunc_turret_machinegun() { SELFPARAM(); if(!turret_initialize(TUR_MACHINEGUN)) remove(self); }
+void spawnfunc_turret_machinegun() { SELFPARAM(); if (!turret_initialize(TUR_MACHINEGUN)) remove(self); }
 
-        METHOD(MachineGunTurret, tr_setup, void(MachineGunTurret this, entity it))
-        {
-            it.damage_flags |= TFL_DMG_HEADSHAKE;
-            it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-            it.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-            it.turret_flags |= TUR_FLAG_HITSCAN;
-        }
+METHOD(MachineGunTurret, tr_setup, void(MachineGunTurret this, entity it))
+{
+    it.damage_flags |= TFL_DMG_HEADSHAKE;
+    it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+    it.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+    it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+    it.turret_flags |= TUR_FLAG_HITSCAN;
+}
 
 #endif // SVQC
 #endif
diff --git a/qcsrc/common/turrets/turret/machinegun_weapon.qc b/qcsrc/common/turrets/turret/machinegun_weapon.qc
new file mode 100644 (file)
index 0000000..6612ecb
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef TURRET_MACHINEGUN_WEAPON_H
+#define TURRET_MACHINEGUN_WEAPON_H
+
+CLASS(MachineGunTurretAttack, PortoLaunch)
+/* flags     */ ATTRIB(MachineGunTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(MachineGunTurretAttack, impulse, int, 9);
+/* refname   */ ATTRIB(MachineGunTurretAttack, netname, string, "turret_machinegun");
+/* wepname   */ ATTRIB(MachineGunTurretAttack, message, string, _("Machinegun"));
+ENDCLASS(MachineGunTurretAttack)
+REGISTER_WEAPON(TUR_MACHINEGUN, NEW(MachineGunTurretAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+void W_MachineGun_MuzzleFlash();
+
+METHOD(MachineGunTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2))
+{
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR(machinegun, sustained_refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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;
+            weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
+        }
+        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;
+}
+
+#endif
+
+#endif
index 93fd49e1a5a8ea38dcca9b988d60abfd28de24b4..7920c1a02d3da2a25130cd79cc0335579abb122f 100644 (file)
@@ -1,13 +1,7 @@
-#ifndef TUR_MLRS_H
-#define TUR_MLRS_H
+#ifndef TURRET_MLRS_H
+#define TURRET_MLRS_H
 
-CLASS(MLRSTurretAttack, PortoLaunch)
-/* flags     */ ATTRIB(MLRSTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(MLRSTurretAttack, impulse, int, 9);
-/* refname   */ ATTRIB(MLRSTurretAttack, netname, string, "turret_mlrs");
-/* wepname   */ ATTRIB(MLRSTurretAttack, message, string, _("MLRS"));
-ENDCLASS(MLRSTurretAttack)
-REGISTER_WEAPON(TUR_MLRS, NEW(MLRSTurretAttack));
+#include "mlrs_weapon.qc"
 
 CLASS(MLRSTurret, Turret)
 /* spawnflags */ ATTRIB(MLRSTurret, spawnflags, int, TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER);
@@ -25,51 +19,32 @@ REGISTER_TURRET(MLRS, NEW(MLRSTurret));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
-METHOD(MLRSTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       bool isPlayer = IS_PLAYER(self);
-       if (fire1)
-       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR(machinegun, sustained_refire))) {
-               if (isPlayer) {
-            turret_initparams(self);
-            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_radius = 500;
-            weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
-        }
-        turret_tag_fire_update();
-        entity 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;
-}
 
-void spawnfunc_turret_mlrs() { SELFPARAM(); if(!turret_initialize(TUR_MLRS)) remove(self); }
+#include "mlrs_weapon.qc"
 
-        METHOD(MLRSTurret, tr_think, void(MLRSTurret thistur))
-        {
-            // 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");
-            }
-        }
-        METHOD(MLRSTurret, tr_setup, void(MLRSTurret this, entity it))
-        {
-            it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-            it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+#ifdef SVQC
 
-            it.damage_flags |= TFL_DMG_HEADSHAKE;
-            it.shoot_flags  |= TFL_SHOOT_VOLLYALWAYS;
-            it.volly_counter = it.shot_volly;
-        }
+void spawnfunc_turret_mlrs() { SELFPARAM(); if (!turret_initialize(TUR_MLRS)) remove(self); }
+
+METHOD(MLRSTurret, tr_think, void(MLRSTurret thistur))
+{
+    // 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");
+    }
+}
+METHOD(MLRSTurret, tr_setup, void(MLRSTurret this, entity it))
+{
+    it.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+    it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+
+    it.damage_flags |= TFL_DMG_HEADSHAKE;
+    it.shoot_flags  |= TFL_SHOOT_VOLLYALWAYS;
+    it.volly_counter = it.shot_volly;
+}
 
 #endif // SVQC
 #endif
diff --git a/qcsrc/common/turrets/turret/mlrs_weapon.qc b/qcsrc/common/turrets/turret/mlrs_weapon.qc
new file mode 100644 (file)
index 0000000..70d7f8d
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef TURRET_MLRS_WEAPON_H
+#define TURRET_MLRS_WEAPON_H
+
+CLASS(MLRSTurretAttack, PortoLaunch)
+/* flags     */ ATTRIB(MLRSTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(MLRSTurretAttack, impulse, int, 9);
+/* refname   */ ATTRIB(MLRSTurretAttack, netname, string, "turret_mlrs");
+/* wepname   */ ATTRIB(MLRSTurretAttack, message, string, _("MLRS"));
+ENDCLASS(MLRSTurretAttack)
+REGISTER_WEAPON(TUR_MLRS, NEW(MLRSTurretAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+METHOD(MLRSTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2))
+{
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR(machinegun, sustained_refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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_radius = 500;
+            weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
+        }
+        turret_tag_fire_update();
+        entity 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;
+}
+
+#endif
+
+#endif
index c7b11cba962b6917c9379416b6e095e787238aa4..7fcb0131f6fa7f41e3697be632aeccb5e9e61180 100644 (file)
@@ -1,13 +1,7 @@
-#ifndef TUR_PHASER_H
-#define TUR_PHASER_H
+#ifndef TURRET_PHASER_H
+#define TURRET_PHASER_H
 
-CLASS(PhaserTurretAttack, PortoLaunch)
-/* flags     */ ATTRIB(PhaserTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(PhaserTurretAttack, impulse, int, 9);
-/* refname   */ ATTRIB(PhaserTurretAttack, netname, string, "turret_phaser");
-/* wepname   */ ATTRIB(PhaserTurretAttack, message, string, _("Phaser"));
-ENDCLASS(PhaserTurretAttack)
-REGISTER_WEAPON(PHASER, NEW(PhaserTurretAttack));
+#include "phaser_weapon.qc"
 
 CLASS(PhaserTurret, Turret)
 /* spawnflags */ ATTRIB(PhaserTurret, spawnflags, int, TUR_FLAG_SNIPER | TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER);
@@ -25,130 +19,49 @@ REGISTER_TURRET(PHASER, NEW(PhaserTurret));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
-void beam_think();
-.int fireflag;
-METHOD(PhaserTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-    SELFPARAM();
-    bool isPlayer = IS_PLAYER(self);
-    if (fire1)
-    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-        if (isPlayer) {
-            turret_initparams(self);
-            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 = 1;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-        entity 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 (!isPlayer)
-        if (self.tur_head.frame == 0)
-            self.tur_head.frame = 1;
-    }
-    return true;
-}
-
-float turret_phaser_firecheck()
-{SELFPARAM();
-    if (self.fireflag != 0) return 0;
-    return turret_firecheck();
-}
+#include "phaser_weapon.qc"
 
-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;
-    }
+#ifdef SVQC
 
-    turret_do_updates(self.owner);
+void spawnfunc_turret_phaser() { SELFPARAM(); if (!turret_initialize(TUR_PHASER)) remove(self); }
 
-    if (time - self.shot_spread > 0)
+METHOD(PhaserTurret, tr_think, void(PhaserTurret thistur))
+{
+    if (self.tur_head.frame != 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)) remove(self); }
-
-        METHOD(PhaserTurret, tr_think, void(PhaserTurret thistur))
+        if (self.fireflag == 1)
         {
-            if (self.tur_head.frame != 0)
+            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)
             {
-                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;
-                    }
-                }
+                self.tur_head.frame = 0;
+                self.fireflag = 0;
             }
         }
-        METHOD(PhaserTurret, tr_setup, void(PhaserTurret this, entity it))
-        {
-            it.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            it.aim_flags = TFL_AIM_LEAD;
+    }
+}
+float turret_phaser_firecheck();
+METHOD(PhaserTurret, tr_setup, void(PhaserTurret this, entity it))
+{
+    it.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+    it.aim_flags = TFL_AIM_LEAD;
 
-            it.turret_firecheckfunc = turret_phaser_firecheck;
-        }
+    it.turret_firecheckfunc = turret_phaser_firecheck;
+}
+float turret_phaser_firecheck()
+{
+    SELFPARAM();
+    if (self.fireflag != 0) return 0;
+    return turret_firecheck();
+}
 
-#endif // SVQC
+#endif
 #endif
diff --git a/qcsrc/common/turrets/turret/phaser_weapon.qc b/qcsrc/common/turrets/turret/phaser_weapon.qc
new file mode 100644 (file)
index 0000000..ac81770
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef TURRET_PHASER_WEAPON_H
+#define TURRET_PHASER_WEAPON_H
+
+CLASS(PhaserTurretAttack, PortoLaunch)
+/* flags     */ ATTRIB(PhaserTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(PhaserTurretAttack, impulse, int, 9);
+/* refname   */ ATTRIB(PhaserTurretAttack, netname, string, "turret_phaser");
+/* wepname   */ ATTRIB(PhaserTurretAttack, message, string, _("Phaser"));
+ENDCLASS(PhaserTurretAttack)
+REGISTER_WEAPON(PHASER, NEW(PhaserTurretAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+void beam_think();
+
+.int fireflag;
+
+METHOD(PhaserTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2))
+{
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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 = 1;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+        entity 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 (!isPlayer)
+        if (self.tur_head.frame == 0)
+            self.tur_head.frame = 1;
+    }
+    return true;
+}
+
+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;
+
+}
+
+#endif
+
+#endif
index 1adb45623053010a01c80efa9331710c50e4d714..04f81cbc0d2851db5c15042312bf90111f990e0b 100644 (file)
@@ -1,13 +1,7 @@
-#ifndef TUR_PLASMA_H
-#define TUR_PLASMA_H
+#ifndef TURRET_PLASMA_H
+#define TURRET_PLASMA_H
 
-CLASS(PlasmaAttack, PortoLaunch)
-/* flags     */ ATTRIB(PlasmaAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(PlasmaAttack, impulse, int, 5);
-/* refname   */ ATTRIB(PlasmaAttack, netname, string, "turret_plasma");
-/* wepname   */ ATTRIB(PlasmaAttack, message, string, _("Plasma"));
-ENDCLASS(PlasmaAttack)
-REGISTER_WEAPON(PLASMA, NEW(PlasmaAttack));
+#include "plasma_weapon.qc"
 
 CLASS(PlasmaTurret, Turret)
 /* spawnflags */ ATTRIB(PlasmaTurret, spawnflags, int, TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER);
@@ -25,67 +19,50 @@ REGISTER_TURRET(PLASMA, NEW(PlasmaTurret));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
 
-METHOD(PlasmaAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       bool isPlayer = IS_PLAYER(self);
-       if (fire1)
-       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-               if (isPlayer) {
-            turret_initparams(self);
-            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;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-        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);
-       }
-       return true;
-}
+#include "plasma_weapon.qc"
+
+#ifdef SVQC
 
-void spawnfunc_turret_plasma() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA)) remove(self); }
+void spawnfunc_turret_plasma() { SELFPARAM(); if (!turret_initialize(TUR_PLASMA)) remove(self); }
 
-        METHOD(PlasmaTurret, tr_attack, void(PlasmaTurret this))
-        {
-            if(g_instagib)
-            {
-                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
-                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
+METHOD(PlasmaTurret, tr_attack, void(PlasmaTurret this))
+{
+    if(g_instagib)
+    {
+        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);
+        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);
-            }
-            else
-            {
-                super.tr_attack(this);
-            }
-            if (self.tur_head.frame == 0)
-                self.tur_head.frame = 1;
-        }
-        METHOD(PlasmaTurret, tr_think, void(PlasmaTurret thistur))
-        {
-            if (self.tur_head.frame != 0)
-                self.tur_head.frame = self.tur_head.frame + 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);
+    }
+    else
+    {
+        super.tr_attack(this);
+    }
+    if (self.tur_head.frame == 0)
+        self.tur_head.frame = 1;
+}
+METHOD(PlasmaTurret, tr_think, void(PlasmaTurret thistur))
+{
+    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;
-        }
-        METHOD(PlasmaTurret, tr_setup, void(PlasmaTurret this, entity it))
-        {
-            it.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            it.damage_flags |= TFL_DMG_HEADSHAKE;
-            it.firecheck_flags |= TFL_FIRECHECK_AFF;
-            it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
+    if (self.tur_head.frame > 5)
+        self.tur_head.frame = 0;
+}
+METHOD(PlasmaTurret, tr_setup, void(PlasmaTurret this, entity it))
+{
+    it.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+    it.damage_flags |= TFL_DMG_HEADSHAKE;
+    it.firecheck_flags |= TFL_FIRECHECK_AFF;
+    it.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
 
-            turret_do_updates(it);
-        }
+    turret_do_updates(it);
+}
 
-#endif // SVQC
+#endif
 #endif
index 98f6243ee0e7be9e2cb1a8737e5339712693226e..faac00d26dce98cfb77b7cbe21e9503e26c6465f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef TUR_PLASMA_DUAL_H
-#define TUR_PLASMA_DUAL_H
+#ifndef TURRET_PLASMA_DUAL_H
+#define TURRET_PLASMA_DUAL_H
 
 CLASS(PlasmaDualAttack, PlasmaAttack)
 /* refname   */ ATTRIB(PlasmaDualAttack, netname, string, "turret_plasma_dual");
@@ -26,33 +26,33 @@ REGISTER_TURRET(PLASMA_DUAL, NEW(DualPlasmaTurret));
 
 #ifdef SVQC
 
-void spawnfunc_turret_plasma_dual() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA_DUAL)) remove(self); }
+void spawnfunc_turret_plasma_dual() { SELFPARAM(); if (!turret_initialize(TUR_PLASMA_DUAL)) remove(self); }
 
-        METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret this))
-        {
-            if (g_instagib) {
-                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
-                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
+METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret this))
+{
+    if (g_instagib) {
+        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);
+        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);
-            } else {
-                super.vtblbase.tr_attack(this);
-            }
-            self.tur_head.frame += 1;
-        }
-        METHOD(DualPlasmaTurret, tr_think, void(DualPlasmaTurret thistur))
-        {
-            if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
-                self.tur_head.frame = self.tur_head.frame + 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);
+    } else {
+        super.vtblbase.tr_attack(this);
+    }
+    self.tur_head.frame += 1;
+}
+METHOD(DualPlasmaTurret, tr_think, void(DualPlasmaTurret thistur))
+{
+    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;
-        }
+    if (self.tur_head.frame > 6)
+        self.tur_head.frame = 0;
+}
 
-#endif // SVQC
+#endif
 #endif
diff --git a/qcsrc/common/turrets/turret/plasma_weapon.qc b/qcsrc/common/turrets/turret/plasma_weapon.qc
new file mode 100644 (file)
index 0000000..4fa0851
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef TURRET_PLASMA_WEAPON_H
+#define TURRET_PLASMA_WEAPON_H
+
+CLASS(PlasmaAttack, PortoLaunch)
+/* flags     */ ATTRIB(PlasmaAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(PlasmaAttack, impulse, int, 5);
+/* refname   */ ATTRIB(PlasmaAttack, netname, string, "turret_plasma");
+/* wepname   */ ATTRIB(PlasmaAttack, message, string, _("Plasma"));
+ENDCLASS(PlasmaAttack)
+REGISTER_WEAPON(PLASMA, NEW(PlasmaAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+METHOD(PlasmaAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+    SELFPARAM();
+       bool isPlayer = IS_PLAYER(self);
+       if (fire1)
+       if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+               if (isPlayer) {
+            turret_initparams(self);
+            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;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+        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);
+       }
+       return true;
+}
+
+#endif
+
+#endif
index 02fcd1f4cce2d805b1869c8212aa9e7c152879e9..65733a8cbe72405fec3418d9228469fa8b46f268 100644 (file)
@@ -1,13 +1,7 @@
-#ifndef TUR_TESLA_H
-#define TUR_TESLA_H
+#ifndef TURRET_TESLA_H
+#define TURRET_TESLA_H
 
-CLASS(TeslaCoilTurretAttack, PortoLaunch)
-/* flags     */ ATTRIB(TeslaCoilTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(TeslaCoilTurretAttack, impulse, int, 9);
-/* refname   */ ATTRIB(TeslaCoilTurretAttack, netname, string, "turret_tesla");
-/* wepname   */ ATTRIB(TeslaCoilTurretAttack, message, string, _("Tesla Coil"));
-ENDCLASS(TeslaCoilTurretAttack)
-REGISTER_WEAPON(TESLA, NEW(TeslaCoilTurretAttack));
+#include "tesla_weapon.qc"
 
 CLASS(TeslaCoil, Turret)
 /* spawnflags */ ATTRIB(TeslaCoil, spawnflags, int, TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE);
@@ -25,95 +19,56 @@ REGISTER_TURRET(TESLA, NEW(TeslaCoil));
 #endif
 
 #ifdef IMPLEMENTATION
-#ifdef SVQC
-entity toast(entity from, float range, float damage);
-METHOD(TeslaCoilTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-    SELFPARAM();
-    bool isPlayer = IS_PLAYER(self);
-    if (fire1)
-    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-        if (isPlayer) {
-            turret_initparams(self);
-            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;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-
-        float d = self.shot_dmg;
-        float r = self.target_range;
-        entity e = spawn();
-        setorigin(e,self.tur_shotorg);
-
-        self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
-        entity t = toast(e,r,d);
-        remove(e);
-
-        if (t == NULL) return true;
-
-        self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
-
-        self.attack_finished_single = time + self.shot_refire;
-        for (int 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;
-}
+#include "tesla_weapon.qc"
 
-entity toast(entity from, float range, float damage)
-{SELFPARAM();
-    entity e;
-    entity etarget = world;
-    float d,dd;
-    float r;
+#ifdef SVQC
 
-    dd = range + 1;
+void spawnfunc_turret_tesla() { SELFPARAM(); if (!turret_initialize(TUR_TESLA)) remove(self); }
 
-    e = findradius(from.origin,range);
-    while (e)
+METHOD(TeslaCoil, tr_think, void(TeslaCoil thistur))
+{
+    if(!self.active)
     {
-        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;
+        self.tur_head.avelocity = '0 0 0';
+        return;
     }
 
-    if (etarget)
+    if(self.ammo < self.shot_dmg)
     {
-        te_csqc_lightningarc(from.origin,etarget.origin);
-        Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
-        etarget.railgunhit = 1;
+        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);
 
-    return etarget;
+        if(self.attack_finished_single > time)
+            return;
+
+        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));
+    }
+}
+
+float turret_tesla_firecheck();
+METHOD(TeslaCoil, tr_setup, void(TeslaCoil this, entity it))
+{
+    it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                         TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+
+    it.turret_firecheckfunc = turret_tesla_firecheck;
+    it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                       TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+
+    it.firecheck_flags = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
+    it.shoot_flags             = TFL_SHOOT_CUSTOM;
+    it.ammo_flags                      = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
+    it.aim_flags                       = TFL_AIM_NO;
+    it.track_flags             = TFL_TRACK_NO;
 }
 
 float turret_tesla_firecheck()
@@ -152,50 +107,5 @@ float turret_tesla_firecheck()
     return 0;
 }
 
-void spawnfunc_turret_tesla() { SELFPARAM(); if(!turret_initialize(TUR_TESLA)) remove(self); }
-
-        METHOD(TeslaCoil, tr_think, void(TeslaCoil thistur))
-        {
-            if(!self.active)
-            {
-                self.tur_head.avelocity = '0 0 0';
-                return;
-            }
-
-            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;
-
-                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));
-            }
-        }
-        METHOD(TeslaCoil, tr_setup, void(TeslaCoil this, entity it))
-        {
-            it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                 TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
-            it.turret_firecheckfunc = turret_tesla_firecheck;
-            it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                               TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
-            it.firecheck_flags = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
-            it.shoot_flags             = TFL_SHOOT_CUSTOM;
-            it.ammo_flags                      = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-            it.aim_flags                       = TFL_AIM_NO;
-            it.track_flags             = TFL_TRACK_NO;
-        }
-
-#endif // SVQC
+#endif
 #endif
diff --git a/qcsrc/common/turrets/turret/tesla_weapon.qc b/qcsrc/common/turrets/turret/tesla_weapon.qc
new file mode 100644 (file)
index 0000000..d8f69df
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef TURRET_TESLA_WEAPON_H
+#define TURRET_TESLA_WEAPON_H
+
+CLASS(TeslaCoilTurretAttack, PortoLaunch)
+/* flags     */ ATTRIB(TeslaCoilTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(TeslaCoilTurretAttack, impulse, int, 9);
+/* refname   */ ATTRIB(TeslaCoilTurretAttack, netname, string, "turret_tesla");
+/* wepname   */ ATTRIB(TeslaCoilTurretAttack, message, string, _("Tesla Coil"));
+ENDCLASS(TeslaCoilTurretAttack)
+REGISTER_WEAPON(TESLA, NEW(TeslaCoilTurretAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+entity toast(entity from, float range, float damage);
+METHOD(TeslaCoilTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+
+        float d = self.shot_dmg;
+        float r = self.target_range;
+        entity e = spawn();
+        setorigin(e,self.tur_shotorg);
+
+        self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
+
+        entity t = toast(e,r,d);
+        remove(e);
+
+        if (t == NULL) return true;
+
+        self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
+
+        self.attack_finished_single = time + self.shot_refire;
+        for (int 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;
+}
+
+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;
+}
+
+#endif
+
+#endif
index 37781fa6733502d9a88bcaa92628ff944796bf04..49e93c09d0ae49de24921ad644d7736fa5a7d64d 100644 (file)
@@ -1,16 +1,10 @@
-#ifndef TUR_WALKER_H
-#define TUR_WALKER_H
-
-CLASS(WalkerTurretAttack, PortoLaunch)
-/* flags     */ ATTRIB(WalkerTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(WalkerTurretAttack, impulse, int, 5);
-/* refname   */ ATTRIB(WalkerTurretAttack, netname, string, "turret_walker");
-/* wepname   */ ATTRIB(WalkerTurretAttack, message, string, _("Walker"));
-ENDCLASS(WalkerTurretAttack)
-REGISTER_WEAPON(WALKER, NEW(WalkerTurretAttack));
+#ifndef TURRET_WALKER_H
+#define TURRET_WALKER_H
 
 //#define WALKER_FANCYPATHING
 
+#include "walker_weapon.qc"
+
 CLASS(WalkerTurret, Turret)
 /* spawnflags */ ATTRIB(WalkerTurret, spawnflags, int, TUR_FLAG_PLAYER | TUR_FLAG_MOVE);
 /* mins       */ ATTRIB(WalkerTurret, mins, vector, '-70 -70 0');
@@ -27,26 +21,10 @@ REGISTER_TURRET(WALKER, NEW(WalkerTurret));
 #endif
 
 #ifdef IMPLEMENTATION
+
+#include "walker_weapon.qc"
+
 #ifdef SVQC
-METHOD(WalkerTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-    SELFPARAM();
-    bool isPlayer = IS_PLAYER(self);
-    if (fire1)
-    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
-        if (isPlayer) {
-            turret_initparams(self);
-            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;
-            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-        }
-        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;
-}
 
 float autocvar_g_turrets_unit_walker_melee_damage;
 float autocvar_g_turrets_unit_walker_melee_force;
diff --git a/qcsrc/common/turrets/turret/walker_weapon.qc b/qcsrc/common/turrets/turret/walker_weapon.qc
new file mode 100644 (file)
index 0000000..eea7a37
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef TURRET_WALKER_WEAPON_H
+#define TURRET_WALKER_WEAPON_H
+
+CLASS(WalkerTurretAttack, PortoLaunch)
+/* flags     */ ATTRIB(WalkerTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse   */ ATTRIB(WalkerTurretAttack, impulse, int, 5);
+/* refname   */ ATTRIB(WalkerTurretAttack, netname, string, "turret_walker");
+/* wepname   */ ATTRIB(WalkerTurretAttack, message, string, _("Walker"));
+ENDCLASS(WalkerTurretAttack)
+REGISTER_WEAPON(WALKER, NEW(WalkerTurretAttack));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+METHOD(WalkerTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+    SELFPARAM();
+    bool isPlayer = IS_PLAYER(self);
+    if (fire1)
+    if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
+        if (isPlayer) {
+            turret_initparams(self);
+            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;
+            weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+        }
+        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;
+}
+
+#endif
+
+#endif