-#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');
#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;
--- /dev/null
+#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
-#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);
#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
--- /dev/null
+#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
-#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);
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
-#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);
#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
--- /dev/null
+#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
-#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);
#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)
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
--- /dev/null
+#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
-#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);
#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
--- /dev/null
+#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
-#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);
#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
--- /dev/null
+#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
-#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);
#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
--- /dev/null
+#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
-#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);
#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
-#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");
#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
--- /dev/null
+#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
-#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);
#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()
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
--- /dev/null
+#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
-#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');
#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;
--- /dev/null
+#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