From: TimePath Date: Wed, 30 Sep 2015 09:54:24 +0000 (+1000) Subject: Turrets: make usable as weapons X-Git-Tag: xonotic-v0.8.2~1874^2~30 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=ab7c517aad9d96d37b3080af38e07fb394dada50 Turrets: make usable as weapons --- diff --git a/qcsrc/common/turrets/turret/ewheel.qc b/qcsrc/common/turrets/turret/ewheel.qc index be562a828b..81336a4951 100644 --- a/qcsrc/common/turrets/turret/ewheel.qc +++ b/qcsrc/common/turrets/turret/ewheel.qc @@ -14,10 +14,50 @@ ENDCLASS(EWheel) REGISTER_TURRET(EWHEEL, NEW(EWheel)); +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; +} + float autocvar_g_turrets_unit_ewheel_speed_fast; float autocvar_g_turrets_unit_ewheel_speed_slow; float autocvar_g_turrets_unit_ewheel_speed_slower; @@ -133,23 +173,8 @@ void spawnfunc_turret_ewheel() { SELFPARAM(); if(!turret_initialize(TUR_EWHEEL.m METHOD(EWheel, tr_attack, void(EWheel thistur)) { SELFPARAM(); - float i; - entity _mis; - - for (i = 0; i < 1; ++i) - { - turret_do_updates(self); - - _mis = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE); - _mis.missile_flags = MIF_SPLASH; - - Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); - - self.tur_head.frame += 2; - - if (self.tur_head.frame > 3) - self.tur_head.frame = 0; - } + Weapon wep = WEP_EWHEEL; + wep.wr_think(wep, true, false); } METHOD(EWheel, tr_think, bool(EWheel thistur)) { diff --git a/qcsrc/common/turrets/turret/flac.qc b/qcsrc/common/turrets/turret/flac.qc index d917e27f2f..f2554ad541 100644 --- a/qcsrc/common/turrets/turret/flac.qc +++ b/qcsrc/common/turrets/turret/flac.qc @@ -14,10 +14,52 @@ ENDCLASS(Flac) REGISTER_TURRET(FLAC, NEW(Flac)); +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_initparams(entity); +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) @@ -39,19 +81,8 @@ void spawnfunc_turret_flac() { SELFPARAM(); if(!turret_initialize(TUR_FLAC.m_id) METHOD(Flac, tr_attack, void(Flac thistur)) { - entity proj; - - turret_tag_fire_update(); - - proj = turret_projectile(SND(HAGAR_FIRE), 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE); - Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); - proj.think = turret_flac_projectile_think_explode; - proj.nextthink = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01); - proj.missile_flags = MIF_SPLASH | MIF_PROXY; - - self.tur_head.frame = self.tur_head.frame + 1; - if (self.tur_head.frame >= 4) - self.tur_head.frame = 0; + Weapon wep = WEP_FLAC; + wep.wr_think(wep, true, false); } METHOD(Flac, tr_think, bool(Flac thistur)) { diff --git a/qcsrc/common/turrets/turret/hellion.qc b/qcsrc/common/turrets/turret/hellion.qc index 60cf6e0c69..d0622bf859 100644 --- a/qcsrc/common/turrets/turret/hellion.qc +++ b/qcsrc/common/turrets/turret/hellion.qc @@ -14,10 +14,54 @@ ENDCLASS(Hellion) REGISTER_TURRET(HELLION, NEW(Hellion)); +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 +void turret_initparams(entity); +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; @@ -87,22 +131,8 @@ void spawnfunc_turret_hellion() { SELFPARAM(); if(!turret_initialize(TUR_HELLION METHOD(Hellion, tr_attack, void(Hellion thistur)) { - entity missile; - - if(self.tur_head.frame != 0) - self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire")); - else - self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2")); - - missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE); - te_explosion (missile.origin); - missile.think = turret_hellion_missile_think; - missile.nextthink = time; - missile.flags = FL_PROJECTILE; - missile.max_health = time + 9; - missile.tur_aimpos = randomvec() * 128; - missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT; - self.tur_head.frame += 1; + Weapon wep = WEP_HELLION; + wep.wr_think(wep, true, false); } METHOD(Hellion, tr_think, bool(Hellion thistur)) { diff --git a/qcsrc/common/turrets/turret/hk.qc b/qcsrc/common/turrets/turret/hk.qc index 240143e573..8fedee421c 100644 --- a/qcsrc/common/turrets/turret/hk.qc +++ b/qcsrc/common/turrets/turret/hk.qc @@ -14,10 +14,52 @@ ENDCLASS(HunterKiller) REGISTER_TURRET(HK, NEW(HunterKiller)); +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 +void turret_initparams(entity); +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; +} + 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; @@ -284,22 +326,8 @@ void spawnfunc_turret_hk() { SELFPARAM(); if(!turret_initialize(TUR_HK.m_id)) re METHOD(HunterKiller, tr_attack, void(HunterKiller thistur)) { - entity missile; - - missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE); - te_explosion (missile.origin); - - missile.think = turret_hk_missile_think; - missile.nextthink = time + 0.25; - missile.movetype = MOVETYPE_BOUNCEMISSILE; - missile.velocity = self.tur_shotdir_updated * (self.shot_speed * 0.75); - missile.angles = vectoangles(missile.velocity); - missile.cnt = time + 30; - missile.ticrate = max(autocvar_sys_ticrate, 0.05); - missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_AI; - - if (self.tur_head.frame == 0) - self.tur_head.frame = self.tur_head.frame + 1; + Weapon wep = WEP_HK; + wep.wr_think(wep, true, false); } METHOD(HunterKiller, tr_think, bool(HunterKiller thistur)) { diff --git a/qcsrc/common/turrets/turret/machinegun.qc b/qcsrc/common/turrets/turret/machinegun.qc index 8ca679a053..43dc1750d7 100644 --- a/qcsrc/common/turrets/turret/machinegun.qc +++ b/qcsrc/common/turrets/turret/machinegun.qc @@ -14,20 +14,47 @@ ENDCLASS(MachineGunTurret) REGISTER_TURRET(MACHINEGUN, NEW(MachineGunTurret)); +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 spawnfunc_turret_machinegun() { SELFPARAM(); if(!turret_initialize(TUR_MACHINEGUN.m_id)) remove(self); } +void turret_initparams(entity); +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 W_MachineGun_MuzzleFlash(void); +void spawnfunc_turret_machinegun() { SELFPARAM(); if(!turret_initialize(TUR_MACHINEGUN.m_id)) remove(self); } 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"); + Weapon wep = WEP_TUR_MACHINEGUN; + wep.wr_think(wep, true, false); } METHOD(MachineGunTurret, tr_think, bool(MachineGunTurret thistur)) { diff --git a/qcsrc/common/turrets/turret/mlrs.qc b/qcsrc/common/turrets/turret/mlrs.qc index 35fe1e3c72..08a1edcfae 100644 --- a/qcsrc/common/turrets/turret/mlrs.qc +++ b/qcsrc/common/turrets/turret/mlrs.qc @@ -14,21 +14,48 @@ ENDCLASS(MLRSTurret) REGISTER_TURRET(MLRS, NEW(MLRSTurret)); +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 +void turret_initparams(entity); +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.m_id)) remove(self); } METHOD(MLRSTurret, tr_attack, void(MLRSTurret thistur)) { - entity missile; - - turret_tag_fire_update(); - missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE); - missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed); - missile.missile_flags = MIF_SPLASH; - te_explosion (missile.origin); + Weapon wep = WEP_TUR_MLRS; + wep.wr_think(wep, true, false); } METHOD(MLRSTurret, tr_think, bool(MLRSTurret thistur)) { diff --git a/qcsrc/common/turrets/turret/phaser.qc b/qcsrc/common/turrets/turret/phaser.qc index 8689ebd262..7cef889095 100644 --- a/qcsrc/common/turrets/turret/phaser.qc +++ b/qcsrc/common/turrets/turret/phaser.qc @@ -14,11 +14,65 @@ ENDCLASS(PhaserTurret) REGISTER_TURRET(PHASER, NEW(PhaserTurret)); +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 -.float fireflag; +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(); @@ -68,36 +122,8 @@ void spawnfunc_turret_phaser() { SELFPARAM(); if(!turret_initialize(TUR_PHASER.m METHOD(PhaserTurret, tr_attack, void(PhaserTurret thistur)) { - entity beam; - - beam = spawn(); - beam.ticrate = 0.1; //autocvar_sys_ticrate; - setmodel(beam, MDL_TUR_PHASER_BEAM); - beam.effects = EF_LOWPRECISION; - beam.solid = SOLID_NOT; - beam.think = beam_think; - beam.cnt = time + self.shot_speed; - beam.shot_spread = time + 2; - beam.nextthink = time; - beam.owner = self; - beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate); - beam.scale = self.target_range / 256; - beam.movetype = MOVETYPE_NONE; - beam.enemy = self.enemy; - beam.bot_dodge = true; - beam.bot_dodgerating = beam.shot_dmg; - sound (beam, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM); - self.fireflag = 1; - - beam.attack_finished_single = self.attack_finished_single; - self.attack_finished_single = time; // + autocvar_sys_ticrate; - - setattachment(beam,self.tur_head,"tag_fire"); - - soundat (self, trace_endpos, CH_SHOTS, SND(NEXIMPACT), VOL_BASE, ATTEN_NORM); - - if (self.tur_head.frame == 0) - self.tur_head.frame = 1; + Weapon wep = WEP_PHASER; + wep.wr_think(wep, true, false); } METHOD(PhaserTurret, tr_think, bool(PhaserTurret thistur)) { diff --git a/qcsrc/common/turrets/turret/plasma.qc b/qcsrc/common/turrets/turret/plasma.qc index d5c8ea42a1..3197400063 100644 --- a/qcsrc/common/turrets/turret/plasma.qc +++ b/qcsrc/common/turrets/turret/plasma.qc @@ -14,18 +14,18 @@ ENDCLASS(PlasmaTurret) REGISTER_TURRET(PLASMA, NEW(PlasmaTurret)); -#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"); +/* 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 void turret_initparams(entity tur); diff --git a/qcsrc/common/turrets/turret/plasma_dual.qc b/qcsrc/common/turrets/turret/plasma_dual.qc index a7e064b35d..a8885c0404 100644 --- a/qcsrc/common/turrets/turret/plasma_dual.qc +++ b/qcsrc/common/turrets/turret/plasma_dual.qc @@ -14,20 +14,20 @@ ENDCLASS(DualPlasmaTurret) REGISTER_TURRET(PLASMA_DUAL, NEW(DualPlasmaTurret)); -#endif - -#ifdef IMPLEMENTATION - #include "../../weapons/all.qh" CLASS(PlasmaDualAttack, PortoLaunch) /* flags */ ATTRIB(PlasmaDualAttack, spawnflags, int, WEP_TYPE_OTHER); /* impulse */ ATTRIB(PlasmaDualAttack, impulse, int, 5); -/* refname */ ATTRIB(PlasmaDualAttack, netname, string, "plasmadual"); +/* refname */ ATTRIB(PlasmaDualAttack, netname, string, "turret_plasmadual"); /* wepname */ ATTRIB(PlasmaDualAttack, message, string, _("Dual plasma")); ENDCLASS(PlasmaDualAttack) REGISTER_WEAPON(PLASMA_DUAL, NEW(PlasmaDualAttack)); +#endif + +#ifdef IMPLEMENTATION + #ifdef SVQC void turret_initparams(entity tur); diff --git a/qcsrc/common/turrets/turret/tesla.qc b/qcsrc/common/turrets/turret/tesla.qc index 80b2d1e7f3..84d9598038 100644 --- a/qcsrc/common/turrets/turret/tesla.qc +++ b/qcsrc/common/turrets/turret/tesla.qc @@ -14,10 +14,66 @@ ENDCLASS(TeslaCoil) REGISTER_TURRET(TESLA, NEW(TeslaCoil)); +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; @@ -100,39 +156,8 @@ void spawnfunc_turret_tesla() { SELFPARAM(); if(!turret_initialize(TUR_TESLA.m_i METHOD(TeslaCoil, tr_attack, void(TeslaCoil thistur)) { - entity e, t; - float d, r, i; - - d = self.shot_dmg; - r = self.target_range; - e = spawn(); - setorigin(e,self.tur_shotorg); - - self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK; - - t = toast(e,r,d); - remove(e); - - if (t == world) return; - - self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK; - - self.attack_finished_single = time + self.shot_refire; - for (i = 0; i < 10; ++i) - { - d *= 0.75; - r *= 0.85; - t = toast(t, r, d); - if (t == world) break; - - } - - e = findchainfloat(railgunhit, 1); - while (e) - { - e.railgunhit = 0; - e = e.chain; - } + Weapon wep = WEP_TESLA; + wep.wr_think(wep, true, false); } METHOD(TeslaCoil, tr_think, bool(TeslaCoil thistur)) { diff --git a/qcsrc/common/turrets/turret/walker.qc b/qcsrc/common/turrets/turret/walker.qc index 36582d4281..d223bf4877 100644 --- a/qcsrc/common/turrets/turret/walker.qc +++ b/qcsrc/common/turrets/turret/walker.qc @@ -14,10 +14,38 @@ ENDCLASS(WalkerTurret) REGISTER_TURRET(WALKER, NEW(WalkerTurret)); +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; +} + float autocvar_g_turrets_unit_walker_melee_damage; float autocvar_g_turrets_unit_walker_melee_force; float autocvar_g_turrets_unit_walker_melee_range; @@ -345,9 +373,8 @@ void spawnfunc_turret_walker() { SELFPARAM(); if(!turret_initialize(TUR_WALKER.m 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); + Weapon wep = WEP_WALKER; + wep.wr_think(wep, true, false); } METHOD(WalkerTurret, tr_think, bool(WalkerTurret thistur)) { diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh index 7f7e34dda6..cf15dd6bc4 100644 --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@ -107,7 +107,7 @@ WepSet ReadWepSet(); // weapon name macros const int WEP_FIRST = 1; -#define WEP_MAXCOUNT 32 // Increase as needed. Can be up to 72. +#define WEP_MAXCOUNT 72 // Increase as needed. Can be up to 72. int WEP_COUNT; #define WEP_LAST (WEP_FIRST + WEP_COUNT - 1) WepSet WEPSET_ALL; diff --git a/qcsrc/server/mutators/gamemode_nexball_weapon.qc b/qcsrc/server/mutators/gamemode_nexball_weapon.qc index a8822f897b..d0b8bee092 100644 --- a/qcsrc/server/mutators/gamemode_nexball_weapon.qc +++ b/qcsrc/server/mutators/gamemode_nexball_weapon.qc @@ -1,4 +1,5 @@ -#ifndef IMPLEMENTATION +#ifndef GAMEMODE_NEXBALL_WEAPON_H +#define GAMEMODE_NEXBALL_WEAPON_H CLASS(BallStealer, PortoLaunch) /* flags */ ATTRIB(BallStealer, spawnflags, int, WEP_TYPE_OTHER);