if(MUTATOR_CALLHOOK(TurretFire, self))
return;
- TUR_ACTION(self.m_id, TR_ATTACK);
+ Turret info = get_turretinfo(self.m_id);
+ info.tr_attack(info);
self.attack_finished_single = time + self.shot_refire;
self.ammo -= self.shot_dmg;
}
}
+void turret_initparams(entity tur)
+{
+ #define TRY(x) (x) ? (x)
+ tur.respawntime = max (-1, (TRY(tur.respawntime) : 60 ));
+ tur.shot_refire = bound(0.01, (TRY(tur.shot_refire) : 1 ), 9999);
+ tur.shot_dmg = max (1, (TRY(tur.shot_dmg) : tur.shot_refire * 50 ));
+ tur.shot_radius = max (1, (TRY(tur.shot_radius) : tur.shot_dmg * 0.5 ));
+ tur.shot_speed = max (1, (TRY(tur.shot_speed) : 2500 ));
+ tur.shot_spread = bound(0.0001, (TRY(tur.shot_spread) : 0.0125 ), 500);
+ tur.shot_force = bound(0.001, (TRY(tur.shot_force) : tur.shot_dmg * 0.5 + tur.shot_radius * 0.5 ), 5000);
+ tur.shot_volly = bound(1, (TRY(tur.shot_volly) : 1 ), floor(tur.ammo_max / tur.shot_dmg));
+ tur.shot_volly_refire = bound(tur.shot_refire, (TRY(tur.shot_volly_refire) : tur.shot_refire * tur.shot_volly ), 60);
+ tur.target_range = bound(0, (TRY(tur.target_range) : tur.shot_speed * 0.5 ), MAX_SHOT_DISTANCE);
+ tur.target_range_min = bound(0, (TRY(tur.target_range_min) : tur.shot_radius * 2 ), MAX_SHOT_DISTANCE);
+ tur.target_range_optimal = bound(0, (TRY(tur.target_range_optimal) : tur.target_range * 0.5 ), MAX_SHOT_DISTANCE);
+ tur.aim_maxrotate = bound(0, (TRY(tur.aim_maxrotate) : 90 ), 360);
+ tur.aim_maxpitch = bound(0, (TRY(tur.aim_maxpitch) : 20 ), 90);
+ tur.aim_speed = bound(0.1, (TRY(tur.aim_speed) : 36 ), 1000);
+ tur.aim_firetolerance_dist = bound(0.1, (TRY(tur.aim_firetolerance_dist) : 5 + (tur.shot_radius * 2) ), MAX_SHOT_DISTANCE);
+ tur.target_select_rangebias = bound(-10, (TRY(tur.target_select_rangebias) : 1 ), 10);
+ tur.target_select_samebias = bound(-10, (TRY(tur.target_select_samebias) : 1 ), 10);
+ tur.target_select_anglebias = bound(-10, (TRY(tur.target_select_anglebias) : 1 ), 10);
+ tur.target_select_missilebias = bound(-10, (TRY(tur.target_select_missilebias) : 1 ), 10);
+ tur.target_select_playerbias = bound(-10, (TRY(tur.target_select_playerbias) : 1 ), 10);
+ tur.ammo_max = max (tur.shot_dmg, (TRY(tur.ammo_max) : tur.shot_dmg * 10 ));
+ tur.ammo_recharge = max (0, (TRY(tur.ammo_recharge) : tur.shot_dmg * 0.5 ));
+ #undef TRY
+}
+
float turret_initialize(float tur_id)
{SELFPARAM();
if(!autocvar_g_turrets)
if(!self.track_blendrate) { self.track_blendrate = 0.35; }
}
- self.respawntime = max(-1, ((!self.respawntime) ? 60 : self.respawntime));
- self.shot_refire = bound(0.01, ((!self.shot_refire) ? 1 : self.shot_refire), 9999);
- self.shot_dmg = max(1, ((!self.shot_dmg) ? self.shot_refire * 50 : self.shot_dmg));
- self.shot_radius = max(1, ((!self.shot_radius) ? self.shot_dmg * 0.5 : self.shot_radius));
- self.shot_speed = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed));
- self.shot_spread = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500);
- self.shot_force = bound(0.001, ((!self.shot_force) ? self.shot_dmg * 0.5 + self.shot_radius * 0.5 : self.shot_force), 5000);
- self.shot_volly = bound(1, ((!self.shot_volly) ? 1 : self.shot_volly), floor(self.ammo_max / self.shot_dmg));
- self.shot_volly_refire = bound(self.shot_refire, ((!self.shot_volly_refire) ? self.shot_refire * self.shot_volly : self.shot_volly_refire), 60);
- self.target_range = bound(0, ((!self.target_range) ? self.shot_speed * 0.5 : self.target_range), MAX_SHOT_DISTANCE);
- self.target_range_min = bound(0, ((!self.target_range_min) ? self.shot_radius * 2 : self.target_range_min), MAX_SHOT_DISTANCE);
- self.target_range_optimal = bound(0, ((!self.target_range_optimal) ? self.target_range * 0.5 : self.target_range_optimal), MAX_SHOT_DISTANCE);
- self.aim_maxrotate = bound(0, ((!self.aim_maxrotate) ? 90 : self.aim_maxrotate), 360);
- self.aim_maxpitch = bound(0, ((!self.aim_maxpitch) ? 20 : self.aim_maxpitch), 90);
- self.aim_speed = bound(0.1, ((!self.aim_speed) ? 36 : self.aim_speed), 1000);
- self.aim_firetolerance_dist = bound(0.1, ((!self.aim_firetolerance_dist) ? 5 + (self.shot_radius * 2) : self.aim_firetolerance_dist), MAX_SHOT_DISTANCE);
- self.target_select_rangebias = bound(-10, ((!self.target_select_rangebias) ? 1 : self.target_select_rangebias), 10);
- self.target_select_samebias = bound(-10, ((!self.target_select_samebias) ? 1 : self.target_select_samebias), 10);
- self.target_select_anglebias = bound(-10, ((!self.target_select_anglebias) ? 1 : self.target_select_anglebias), 10);
- self.target_select_missilebias = bound(-10, ((!self.target_select_missilebias) ? 1 : self.target_select_missilebias), 10);
- self.target_select_playerbias = bound(-10, ((!self.target_select_playerbias) ? 1 : self.target_select_playerbias), 10);
- self.ammo_max = max(self.shot_dmg, ((!self.ammo_max) ? self.shot_dmg * 10 : self.ammo_max));
- self.ammo_recharge = max(0, ((!self.ammo_recharge) ? self.shot_dmg * 0.5 : self.ammo_recharge));
+ turret_initparams(self);
self.turret_flags = TUR_FLAG_ISTURRET | (tur.spawnflags);
.bool(Turret) tr_death;
const int TR_PRECACHE = 4; // (BOTH) precaches models/sounds used by this turret
.bool(Turret) tr_precache;
-const int TR_ATTACK = 5; // (SERVER) called when turret attacks
-.bool(Turret) tr_attack;
+/** (SERVER) called when turret attacks */
+.void(Turret) tr_attack;
const int TR_CONFIG = 6; // (ALL)
.bool(Turret) tr_config;
if (req == TR_THINK) return this.tr_think ? this.tr_think(this) : false;
if (req == TR_DEATH) return this.tr_death ? this.tr_death(this) : false;
if (req == TR_PRECACHE) return this.tr_precache ? this.tr_precache(this) : false;
- if (req == TR_ATTACK) return this.tr_attack ? this.tr_attack(this) : false;
if (req == TR_CONFIG) return this.tr_config ? this.tr_config(this) : false;
return false;
}
void spawnfunc_turret_ewheel() { SELFPARAM(); if(!turret_initialize(TUR_EWHEEL.m_id)) remove(self); }
- METHOD(EWheel, tr_attack, bool(EWheel thistur))
+ METHOD(EWheel, tr_attack, void(EWheel thistur))
{
SELFPARAM();
float i;
if (self.tur_head.frame > 3)
self.tur_head.frame = 0;
}
-
- return true;
}
METHOD(EWheel, tr_think, bool(EWheel thistur))
{
void spawnfunc_turret_flac() { SELFPARAM(); if(!turret_initialize(TUR_FLAC.m_id)) remove(self); }
- METHOD(Flac, tr_attack, bool(Flac thistur))
+ METHOD(Flac, tr_attack, void(Flac thistur))
{
entity proj;
self.tur_head.frame = self.tur_head.frame + 1;
if (self.tur_head.frame >= 4)
self.tur_head.frame = 0;
-
- return true;
}
METHOD(Flac, tr_think, bool(Flac thistur))
{
void spawnfunc_turret_fusionreactor() { SELFPARAM(); if(!turret_initialize(TUR_FUSIONREACTOR.m_id)) remove(self); }
- METHOD(FusionReactor, tr_attack, bool(FusionReactor thistur))
+ METHOD(FusionReactor, tr_attack, void(FusionReactor thistur))
{
vector fl_org;
self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
te_smallflash(fl_org);
-
- return true;
}
METHOD(FusionReactor, tr_think, bool(FusionReactor thistur))
{
void spawnfunc_turret_hellion() { SELFPARAM(); if(!turret_initialize(TUR_HELLION.m_id)) remove(self); }
- METHOD(Hellion, tr_attack, bool(Hellion thistur))
+ METHOD(Hellion, tr_attack, void(Hellion thistur))
{
entity missile;
missile.tur_aimpos = randomvec() * 128;
missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
self.tur_head.frame += 1;
-
- return true;
}
METHOD(Hellion, tr_think, bool(Hellion thistur))
{
void spawnfunc_turret_hk() { SELFPARAM(); if(!turret_initialize(TUR_HK.m_id)) remove(self); }
- METHOD(HunterKiller, tr_attack, bool(HunterKiller thistur))
+ METHOD(HunterKiller, tr_attack, void(HunterKiller thistur))
{
entity missile;
if (self.tur_head.frame == 0)
self.tur_head.frame = self.tur_head.frame + 1;
-
- return true;
}
METHOD(HunterKiller, tr_think, bool(HunterKiller thistur))
{
void W_MachineGun_MuzzleFlash(void);
- METHOD(MachineGunTurret, tr_attack, bool(MachineGunTurret thistur))
+ METHOD(MachineGunTurret, tr_attack, void(MachineGunTurret thistur))
{
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;
}
METHOD(MachineGunTurret, tr_think, bool(MachineGunTurret thistur))
{
#ifdef SVQC
void spawnfunc_turret_mlrs() { SELFPARAM(); if(!turret_initialize(TUR_MLRS.m_id)) remove(self); }
- METHOD(MLRSTurret, tr_attack, bool(MLRSTurret thistur))
+ METHOD(MLRSTurret, tr_attack, void(MLRSTurret thistur))
{
entity missile;
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;
}
METHOD(MLRSTurret, tr_think, bool(MLRSTurret thistur))
{
void spawnfunc_turret_phaser() { SELFPARAM(); if(!turret_initialize(TUR_PHASER.m_id)) remove(self); }
- METHOD(PhaserTurret, tr_attack, bool(PhaserTurret thistur))
+ METHOD(PhaserTurret, tr_attack, void(PhaserTurret thistur))
{
entity beam;
if (self.tur_head.frame == 0)
self.tur_head.frame = 1;
-
- return true;
}
METHOD(PhaserTurret, tr_think, bool(PhaserTurret thistur))
{
#endif
#ifdef IMPLEMENTATION
+
+CLASS(PlasmaAttack, PortoLaunch)
+/* flags */ ATTRIB(PlasmaAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(PlasmaAttack, impulse, int, 5);
+/* refname */ ATTRIB(PlasmaAttack, netname, string, "plasma");
+/* wepname */ ATTRIB(PlasmaAttack, message, string, _("Plasma"));
+ENDCLASS(PlasmaAttack)
+REGISTER_WEAPON(PLASMA, NEW(PlasmaAttack));
+
#ifdef SVQC
+
+void turret_initparams(entity tur);
+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;
+}
+
void spawnfunc_turret_plasma() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA.m_id)) remove(self); }
- METHOD(PlasmaTurret, tr_attack, bool(PlasmaTurret thistur))
+ METHOD(PlasmaTurret, tr_attack, void(PlasmaTurret thistur))
{
if(g_instagib)
{
- float flying;
- flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-
FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
// teamcolor / hit beam effect
vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
}
else
{
- entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
- missile.missile_flags = MIF_SPLASH;
-
- Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
+ Weapon wep = WEP_PLASMA;
+ wep.wr_think(wep, true, false);
}
-
- return true;
+ if (self.tur_head.frame == 0)
+ self.tur_head.frame = 1;
}
METHOD(PlasmaTurret, tr_think, bool(PlasmaTurret thistur))
{
#ifdef SVQC
+void turret_initparams(entity tur);
METHOD(PlasmaDualAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
SELFPARAM();
+ bool isPlayer = IS_PLAYER(self);
if (fire1)
- if (weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
- W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0);
- self.tur_shotdir_updated = w_shotdir;
- self.tur_shotorg = w_shotorg;
- self.tur_head = self;
- self.shot_refire = bound(0.01, ((!self.shot_refire) ? 1 : self.shot_refire), 9999);
- self.shot_dmg = max(1, ((!self.shot_dmg) ? self.shot_refire * 50 : self.shot_dmg));
- self.shot_radius = max(1, ((!self.shot_radius) ? self.shot_dmg * 0.5 : self.shot_radius));
- self.shot_speed = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed));
- self.shot_spread = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500);
- self.shot_force = bound(0.001, ((!self.shot_force) ? self.shot_dmg * 0.5 + self.shot_radius * 0.5 : self.shot_force), 5000);
- TUR_ACTION(TUR_PLASMA_DUAL.m_id, TR_ATTACK);
- weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+ 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;
}
void spawnfunc_turret_plasma_dual() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA_DUAL.m_id)) remove(self); }
- METHOD(DualPlasmaTurret, tr_attack, bool(DualPlasmaTurret thistur))
+ METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret thistur))
{
- if(g_instagib)
- {
- float flying;
- flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-
+ 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);
// teamcolor / hit beam effect
vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
- self.tur_head.frame += 1;
- }
- else
- {
- entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
- missile.missile_flags = MIF_SPLASH;
- Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
- self.tur_head.frame += 1;
+ } else {
+ Weapon wep = WEP_PLASMA_DUAL;
+ wep.wr_think(wep, true, false);
}
-
- return true;
+ self.tur_head.frame += 1;
}
METHOD(DualPlasmaTurret, tr_think, bool(DualPlasmaTurret thistur))
{
void spawnfunc_turret_tesla() { SELFPARAM(); if(!turret_initialize(TUR_TESLA.m_id)) remove(self); }
- METHOD(TeslaCoil, tr_attack, bool(TeslaCoil thistur))
+ METHOD(TeslaCoil, tr_attack, void(TeslaCoil thistur))
{
entity e, t;
float d, r, i;
t = toast(e,r,d);
remove(e);
- if (t == world) return true;
+ if (t == world) return;
self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
e.railgunhit = 0;
e = e.chain;
}
-
- return true;
}
METHOD(TeslaCoil, tr_think, bool(TeslaCoil thistur))
{
void spawnfunc_turret_walker() { SELFPARAM(); if(!turret_initialize(TUR_WALKER.m_id)) remove(self); }
- METHOD(WalkerTurret, tr_attack, bool(WalkerTurret thistur))
+ METHOD(WalkerTurret, tr_attack, void(WalkerTurret thistur))
{
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;
}
METHOD(WalkerTurret, tr_think, bool(WalkerTurret thistur))
{