Git Repos / fte_dogmode / qc / hazards / shooter.qc
Last update to this file was on 2025-08-13 at 05:20.
Show shooter.qc
//==============================================================================
// trap_spikeshooter from Hipnotic -- with additions by dumptruck_ds
//==============================================================================
// MED 11/09/96 added new spawnflags -- taken from hipdefs.qc - dumptruck_ds
//======================================================================
// constants
//======================================================================
#ifdef SSQC
//----------------------------------------------------------------------
// shooter hazard spawnflags -- CEV
//----------------------------------------------------------------------
typedef enumflags
{
        SPAWNFLAG_HAZARD_SHOOTER_SUPERSPIKE = 1,
        SPAWNFLAG_HAZARD_SHOOTER_LASER = 2,
        SPAWNFLAG_HAZARD_SHOOTER_LAVABALL = 4,
        SPAWNFLAG_HAZARD_SHOOTER_ROCKET = 8,
        SPAWNFLAG_HAZARD_SHOOTER_VOREBALL = 16,
        SPAWNFLAG_HAZARD_SHOOTER_GRENADE = 32,
        SPAWNFLAG_HAZARD_SHOOTER_GIBS = 64,
        SPAWNFLAG_HAZARD_SHOOTER_SILENT = 128
        // SPAWNFLAG_NOT_ON_EASY = 256, // see base_entities.qc -- CEV
        // SPAWNFLAG_NOT_ON_NORMAL = 512,
        // SPAWNFLAG_NOT_ON_HARD_OR_NIGHTMARE = 1024,
        // SPAWNFLAG_NOT_IN_DEATHMATCH = 2048,
        // SPAWNFLAG_NOT_IN_COOP = 4096,
        // SPAWNFLAG_NOT_IN_SP = 8192,
        // SPAWNFLAG_NOT_ON_SKILL2 = 32768, // see base_entities.qc -- CEV
        // SPAWNFLAG_NOT_ON_SKILL3 = 65536, // see base_entities.qc -- CEV
        // SPAWNFLAG_CENTERPRINTALL = 131072 // see base_entities.qc -- CEV
} base_hazard_shooter_spawnflags;
#endif
//======================================================================
// forward declarations
//======================================================================
// base_hazard_shooter
#ifdef SSQC
void() base_hazard_shooter_think;
void() base_hazard_shooter_use;
void(string key, string value) base_hazard_shooter_init_field;
void(entity e) base_hazard_shooter_init;
strip void() base_hazard_shooter;
#endif
// trap_spikeshooter
#ifdef SSQC
void(entity e) trap_spikeshooter_init;
void() trap_spikeshooter;
#endif
// trap_shooter
#ifdef SSQC
void(entity e) trap_shooter_init;
void() trap_shooter;
#endif
// trap_switched_shooter
#ifdef SSQC
void() trap_switched_shooter_use;
void(entity e) trap_switched_shooter_init;
void() trap_switched_shooter;
#endif
//------------------------------------------------------------------------------
//----------------------------------------------------------------------
// class base_hazard_shooter: base_mapentity
// {
#ifdef SSQC
        //--------------------------------------------------------------
        // shooter_think -- MED 11/01/96 added state capability
        //--------------------------------------------------------------
        void() base_hazard_shooter_think =
        {
                if (!(self.stateflags & STATE_INACTIVE))
                        // call the use/firing function directly -- CEV
                        base_hazard_shooter_use ();
                self.nextthink = time + self.wait;
        };
        //--------------------------------------------------------------
        // spikeshooter_use
        // MED 11/09/96 added lava ball and rocket
        // dumptruck_ds added voreball and grenades
        //--------------------------------------------------------------
        void() base_hazard_shooter_use =
        {
                local sound_info_t snd = snd_empty;
                if (self.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_LASER)
                {
                        snd = snd_enforcer_fire;
                        local vector l_v = normalize (self.movedir);
                        // SetSpeed
                        l_v *= LASER_SPEED;
                        spawn_projectile_laser (self, self.origin, l_v);
                }
                else if (self.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_LAVABALL)
                {
                        snd = snd_boss_throw;
                        spawn_projectile_lavaball (self, self.origin,
                                self.movedir * 600);
                }
                else if (self.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_ROCKET)
                {
                        snd = snd_weapon_rocketlauncher;
                        spawn_projectile_rocket (self, self.origin,
                                self.movedir * ROCKET_SPEED);
                }
                else if (self.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_VOREBALL)
                {
                        snd = snd_shalrath_attack_02;
                        local float basespeed;
                        if (skill == 3)
                                basespeed = 350;
                        else
                                basespeed = 250;
                        spawn_projectile_voreball (self, self.origin,
                                self.movedir * VOREBALL_SPEED, basespeed);
                }
                else if (self.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_GRENADE)
                {
                        snd = snd_weapon_grenadelauncher;
                        local vector g_v = self.movedir * 600 +
                                v_up * 200 + crandom() * v_right * 10 +
                                crandom() * v_up * 10;
                        spawn_projectile_grenade (self, self.origin, g_v);
                }
                else if (self.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_GIBS)
                {
                        snd = snd_zombie_shot;
                        local vector z_v = self.movedir * 600 +
                                v_up * 200 + crandom() * v_right * 10 +
                                crandom() * v_up * 10;
                        spawn_projectile_zombiechunk (self, self.origin, z_v);
                }
                else
                {
                        snd = snd_weapon_supernailgun;
                        local float damage;
                        if (self.spawnflags &
                                SPAWNFLAG_HAZARD_SHOOTER_SUPERSPIKE)
                        {
                                damage = SPIKE_SUPER_DAMAGE;
                        }
                        else
                        {
                                damage = SPIKE_NORMAL_DAMAGE;
                        }
                        // shooter spikes move at half the speed of
                        // player spikes -- CEV
                        spawn_projectile_spike (self, self.origin,
                                self.movedir * 500, damage);
                }
                if (!(self.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_SILENT)) {
                if (snd.wav != snd_empty.wav)
                {
                        // random small delay to start (to prevent loud
                        // stacking of shooter sounds) -- CEV
                        sound (self, CHAN_VOICE, snd.wav, VOL_MHI, ATTN_NORM,
                                0, 0, random() * -1);
                } }
        };
        //==============================================================
        // Initialization
        //==============================================================
        //--------------------------------------------------------------
        void(string key, string value) base_hazard_shooter_init_field =
        {
                switch (key)
                {
                        case "state":
                                if (value == "1")
                                        self.stateflags &= ~STATE_INACTIVE;
                                else
                                        self.stateflags |= STATE_INACTIVE;
                                break;
                }
        };
        //--------------------------------------------------------------
        void(entity e) base_hazard_shooter_init =
        {
                base_mapentity_init (e);
                e.think = base_hazard_shooter_think;
                e.use = base_hazard_shooter_use;
                sub_setmovedir (e);
                if (e.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_LASER)
                {
                        precache_model2 ("progs/laser.mdl");
                        precache_sound2 (snd_enforcer_fire.wav);
                        precache_sound2 (snd_enforcer_fire_hit.wav);
                }
                else if (e.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_LAVABALL)
                {
                        precache_model ("progs/lavaball.mdl");
                        precache_sound2 (snd_boss_throw.wav); // dms
                }
                else if (e.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_ROCKET)
                {
                        precache_model ("progs/missile.mdl");
                        precache_sound (snd_weapon_rocketlauncher.wav);
                }
                else if (e.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_VOREBALL)
                {
                        precache_model ("progs/v_spike.mdl");
                        precache_sound (snd_shalrath_attack_02.wav);
                }
                else if (e.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_GRENADE)
                {
                        precache_model ("progs/grenade.mdl");
                        // grenade launcher
                        precache_sound (snd_weapon_grenadelauncher.wav);
                }
                else if (e.spawnflags & SPAWNFLAG_HAZARD_SHOOTER_GIBS)
                {
                        precache_model ("progs/zom_gib.mdl");
                        // Zombie gibs
                        precache_sound (snd_zombie_shot.wav);
                        precache_sound (snd_zombie_miss.wav);
                        precache_sound (snd_zombie_hit.wav);
                }
                else
                {
                        precache_sound (snd_weapon_supernailgun.wav);
                }
        };
        //--------------------------------------------------------------
        strip void() base_hazard_shooter =
        {
                base_hazard_shooter_init (self);
        };
#endif
// };
/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
When triggered, fires a spike in the direction set in QuakeEd.
Laser is only for REGISTERED.
*/
//----------------------------------------------------------------------
// class trap_spikeshooter: base_hazard_shooter
// {
#ifdef SSQC
        //--------------------------------------------------------------
        void(entity e) trap_spikeshooter_init =
        {
                e.classname = "trap_spikeshooter";
                e.classtype = CT_HAZARD_SPIKESHOOTER;
                base_hazard_shooter_init (e);
        };
        //--------------------------------------------------------------
        void() trap_spikeshooter =
        {
                base_mapentity_init_spawndata (base_hazard_shooter_init_field);
                // new spawnflags for all entities -- iw
                if (SUB_Inhibit())
                        return;
                trap_spikeshooter_init (self);
        };
#endif
// };
/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Continuously fires spikes.
"wait" time between spike (1.0 default)
"nextthink" delay before firing first spike, so multiple shooters can be stagered.
*/
//----------------------------------------------------------------------
// class trap_shooter: base_hazard_shooter
// {
#ifdef SSQC
        //--------------------------------------------------------------
        void(entity e) trap_shooter_init =
        {
                e.classname = "trap_shooter";
                e.classtype = CT_HAZARD_SHOOTER;
                base_hazard_shooter_init (e);
                if (e.wait == 0)
                        e.wait = 1;
                // MED 11/01/96 added state capability
                // trap_shooter is always active (apparently) -- CEV
                e.stateflags &= ~STATE_INACTIVE;
                e.nextthink = e.nextthink + e.wait + e.ltime;
        };
        //--------------------------------------------------------------
        void() trap_shooter =
        {
                base_mapentity_init_spawndata (base_hazard_shooter_init_field);
                // new spawnflags for all entities -- iw
                if (SUB_Inhibit())
                        return;
                trap_shooter_init (self);
        };
#endif
// };
//MED 11/01/96 added new function
/*QUAKED trap_switched_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Continuously fires spikes.
"wait" time between spike (1.0 default)
"nextthink" delay before firing first spike, so multiple shooters can be stagered.
"state" 0 initially off, 1 initially on. (0 default)
*/
//----------------------------------------------------------------------
// class trap_switched_shooter: base_hazard_shooter
// {
#ifdef SSQC
        //--------------------------------------------------------------
        // trap_shooter_use -- MED 11/01/96 added new use function
        //--------------------------------------------------------------
        void() trap_switched_shooter_use =
        {
                if (self.stateflags & STATE_INACTIVE)
                        self.stateflags &= ~STATE_INACTIVE;
                else
                        self.stateflags |= STATE_INACTIVE;
        };
        //--------------------------------------------------------------
        void(entity e) trap_switched_shooter_init =
        {
                e.classname = "trap_switched_shooter";
                e.classtype = CT_HAZARD_SWITCHED_SHOOTER;
                base_hazard_shooter_init (e);
                e.use = trap_switched_shooter_use;
                if (e.wait == 0)
                        e.wait = 1;
                // MED 11/01/96 added state capability
                e.nextthink = e.nextthink + e.wait + e.ltime;
        };
        //--------------------------------------------------------------
        void() trap_switched_shooter =
        {
                // this is needed because 0 is default off/INACTIVE -- CEV
                self.stateflags |= STATE_INACTIVE;
                base_mapentity_init_spawndata (base_hazard_shooter_init_field);
                // new spawnflags for all entities -- iw
                if (SUB_Inhibit())
                        return;
                trap_switched_shooter_init (self);
        };
#endif
// };
Return to the top of this page or return to the overview of this repo.
Log shooter.qc
| Date | Commit Message | Author | + | - | 
|---|---|---|---|---|
| 2025-08-13 | Another big commit. Item changes, field rework, etc. | cev | +69 | -39 | 
| 2025-03-30 | Big commit. Entity networking, etc. | cev | +68 | -64 | 
| 2024-11-20 | pmove refactor into prepoc macros, view bobbing | cev | +2 | -3 | 
| 2024-06-15 | Major update, committing as-is, will have bugs | cev | +25 | -8 | 
| 2024-03-24 | 2nd pass refactor, rework QC class structure | cev | +159 | -139 | 
| 2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +90 | -141 | 
| 2024-01-31 | Class based monster refactor & start projectiles | cev | +15 | -10 | 
| 2024-01-09 | Continue OO / Class-based refactor | cev | +251 | -235 | 
| 2023-12-02 | More refactoring & moving, begin adding mdls & snd | cev | +335 | 
Return to the top of this page or return to the overview of this repo.