djcev.com

//

Git Repos / fte_dogmode / qc / items / weapons.qc

Last update to this file was on 2025-08-13 at 05:20.

Show weapons.qc

//==============================================================================
// items/weapons.qc -- weapons
//==============================================================================

//======================================================================
// constants
//======================================================================

#ifdef SSQC
//----------------------------------------------------------------------
// default inventory slots for weapons
//----------------------------------------------------------------------
typedef enum
{
ITEM_WEAPON_SLOT_AXE = 1, // id1 weapons first
ITEM_WEAPON_SLOT_SHOTGUN = 2,
ITEM_WEAPON_SLOT_SUPERSHOTGUN = 3,
ITEM_WEAPON_SLOT_NAILGUN = 4,
ITEM_WEAPON_SLOT_SUPERNAILGUN = 5,
ITEM_WEAPON_SLOT_GRENADELAUNCHER = 6,
ITEM_WEAPON_SLOT_ROCKETLAUNCHER = 7,
ITEM_WEAPON_SLOT_LIGHTNINGGUN = 8
} item_info_weapon_defaultslots;

const float AMMO_SHELLS_WP = 5; // shells on weapon pickup; id1 5
const float AMMO_NAILS_WP = 30; // nails on weapon pickup; id1 30
const float AMMO_ROCKETS_WP = 5; // rockets on weapon pickup; id1 5
const float AMMO_CELLS_WP = 15; // cells on weapon pickup; id1 15

const float WEAPON_RESPAWN_TIME = 30; // as the name suggests; id1 30
#endif

//======================================================================
// forward declarations
//======================================================================

// base_item_weapon
#ifdef CSQC
void(float isnew) base_item_weapon_netreceive;
#endif
#ifdef SSQC
void(vector p1, vector p2, entity from, float damage) fire_lightning;
#endif
#ifdef SSQC
// BASE_ITEM_WEAPON_HAVEWEAPON(p, w)
// BASE_ITEM_WEAPON_SLOTEMPTY(slot, p)
// BASE_ITEM_WEAPON_ADDAMMO(p, w, i)
// BASE_ITEM_WEAPON_ADDWEAPON(p, w, slot)
void(entity grabber, entity wep) base_item_weapon_grab;
void() base_item_weapon_touch;
void(string key, string value) base_item_weapon_init_field;
#endif
#if defined(CSQC) || defined(SSQC)
void(entity e) base_item_weapon_init;
#endif
#ifdef SSQC
strip void() base_item_weapon;
#endif

#ifdef SSQC
//----------------------------------------------------------------------
// original id1 & pd3 spawn functions -- CEV
//----------------------------------------------------------------------
void() weapon_axe;
void() weapon_shotgun;
void() weapon_supershotgun;
void() weapon_nailgun;
void() weapon_supernailgun;
void() weapon_grenadelauncher;
void() weapon_rocketlauncher;
void() weapon_lightning;
#endif

//------------------------------------------------------------------------------

//----------------------------------------------------------------------
// class base_item_weapon: base_item
// {
#ifdef CSQC
//--------------------------------------------------------------
void(float isnew) base_item_weapon_netreceive =
{
// creates a number of variables, including netflags -- CEV
BASE_ITEM_NETRECEIVE (base_item_weapon_init)
};
#endif

#ifdef SSQC
//--------------------------------------------------------------
// this is here 'cause LG doesn't create a projectile... -- CEV
// TODO CEV
//--------------------------------------------------------------
void(vector p1, vector p2, entity from, float damage) fire_lightning =
{
local entity e1, e2;
local vector f;

f = p2 - p1;
normalize (f);
f_x = 0 - f_y;
f_y = f_x;
f_z = 0;
f = f * 16;

e1 = e2 = world;

traceline (p1, p2, FALSE, from);
if (trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage * 4);
t_damage2 (trace_ent, from, from, damage);
if (from.classtype == CT_PLAYER)
{
if (other.classtype == CT_PLAYER)
// fly me to the moon
trace_ent.velocity_z += 400;
}
}
e1 = trace_ent;

traceline (p1 + f, p2 + f, FALSE, from);
if (trace_ent != e1 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage * 4);
t_damage2 (trace_ent, from, from, damage);
}
e2 = trace_ent;

traceline (p1 - f, p2 - f, FALSE, from);
if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage * 4);
t_damage2 (trace_ent, from, from, damage);
}
};
#endif

#ifdef SSQC
//--------------------------------------------------------------
#define BASE_ITEM_WEAPON_HAVEWEAPON(p, w) \
{ \
local float haveweapon = FALSE; \
if (p.item[0] == w.weapon) haveweapon = TRUE; \
else if (p.item[1] == w.weapon) haveweapon = TRUE; \
else if (p.item[2] == w.weapon) haveweapon = TRUE; \
else if (p.item[3] == w.weapon) haveweapon = TRUE; \
else if (p.item[4] == w.weapon) haveweapon = TRUE; \
else if (p.item[5] == w.weapon) haveweapon = TRUE; \
else if (p.item[6] == w.weapon) haveweapon = TRUE; \
else if (p.item[7] == w.weapon) haveweapon = TRUE; \
local item_info_t iit = item_info[w.weapon]; \
}

//--------------------------------------------------------------
#define BASE_ITEM_WEAPON_SLOTEMPTY(xin, p) \
{ \
local float slotempty = FALSE; \
switch (xin) \
{ \
case 1: \
if (p.item[0] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
case 2: \
if (p.item[1] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
case 3: \
if (p.item[2] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
case 4: \
if (p.item[3] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
case 5: \
if (p.item[4] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
case 6: \
if (p.item[5] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
case 7: \
if (p.item[6] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
case 8: \
if (p.item[7] == ITEM_SEQ_HANDS) \
slotempty = TRUE; \
break; \
} \
}

//--------------------------------------------------------------
#define BASE_ITEM_WEAPON_ADDAMMO(p, w, i) \
{ \
switch (i.option) \
{ \
case ITEM_AMMO_SHELLS: \
p.ammo_shells += w.ammo_shells; \
break; \
case ITEM_AMMO_NAILS: \
p.ammo_nails += w.ammo_nails; \
break; \
case ITEM_AMMO_ROCKETS: \
p.ammo_rockets += w.ammo_rockets; \
break; \
case ITEM_AMMO_CELLS: \
p.ammo_cells += w.ammo_cells; \
break; \
} \
}

//--------------------------------------------------------------
#define BASE_ITEM_WEAPON_ADDWEAPON(p, w, slot) \
{ \
if (haveweapon == FALSE) \
{ \
/* assign to the currently selected slot -- CEV */ \
switch (slot) \
{ \
case 1: p.item[0] = w.weapon; break; \
case 2: p.item[1] = w.weapon; break; \
case 3: p.item[2] = w.weapon; break; \
case 4: p.item[3] = w.weapon; break; \
case 5: p.item[4] = w.weapon; break; \
case 6: p.item[5] = w.weapon; break; \
case 7: p.item[6] = w.weapon; break; \
case 8: p.item[7] = w.weapon; break; \
} \
} \
}

//--------------------------------------------------------------
void(entity pl, entity wep) base_item_weapon_grab =
{
// don't let the owner re-grab within a set time -- CEV
if (wep.owner)
if (pl == wep.owner)
if (time < wep.attack_finished)
return;

// creates the variables haveweapon, item -- CEV
BASE_ITEM_WEAPON_HAVEWEAPON (pl, wep)

// add ammo first -- CEV
BASE_ITEM_WEAPON_ADDAMMO (pl, wep, iit)

// now add the weapon -- CEV
BASE_ITEM_WEAPON_ADDWEAPON (pl, wep, pl.weapon)

// let the player know -- CEV
BASE_ITEM_PICKUPMESSAGE (pl, iit)

// restrict ammo to game maximums -- CEV
base_entity_boundammo (pl);

// don't re-grab / immediately throw the item -- CEV
if (pl.button4)
pl.flags |= FL_THROW_HELD;

if (pl.classtype == CT_PLAYER && pl.SendEntity)
pl.SendFlags |= NETFLAG_PLAYER_AMMO |
NETFLAG_PLAYER_INVENTORY;

// fire all targets / killtargets
local entity stemp = self;
local entity otemp = other;
other = pl;
self = wep;
activator = other;
sub_usetargets ();
self = stemp;
other = otemp;

// remove the grabbed item or set up for respawning -- CEV
BASE_ITEM_CHECKREMOVE (wep,
WEAPON_RESPAWN_TIME, WEAPON_RESPAWN_TIME)
};

//--------------------------------------------------------------
// weapon_touch
//--------------------------------------------------------------
void() base_item_weapon_touch =
{
if (sub_checkvalidtouch(other) == FALSE)
return;

if (!(other.flags & FL_CLIENT))
return;

// this macro creates the float 'item_index' -- CEV
BASE_ENTITY_WEAPONLOOKUP (other)

// don't touch() if other is holding a non-weapon -- CEV
if (item_index > ITEM_SEQ_W_END)
return;

// creates the variables haveweapon, item -- CEV
BASE_ITEM_WEAPON_HAVEWEAPON (other, self)

// creates the variable slotempty -- CEV
BASE_ITEM_WEAPON_SLOTEMPTY (self.weapon, other)

// behavior is different if player is holding grab -- CEV
if (other.button4 && !(other.flags & FL_THROW_HELD))
{
// when player is holding grab, don't touch if
// A. they aren't already holding the same weapon or
// B. they don't have their hands out -- CEV
if (item_index != ITEM_SEQ_HANDS)
// if (item_index != self.weapon)
return;
}
else
{
// when player isn't holding grab, don't touch if
// A. their hands aren't out and
// B. they don't already have the weapon -- CEV
if (item_index == ITEM_SEQ_HANDS)
return;
if (slotempty == FALSE)
if (haveweapon == FALSE)
return;
}

// add ammo from the pickup -- CEV
BASE_ITEM_WEAPON_ADDAMMO (other, self, iit)

// only add the weapon if the player's hands are empty -- CEV
local float destslot = 0;
if (item_index == ITEM_SEQ_HANDS)
destslot = other.weapon;
else if (slotempty)
destslot = self.weapon;

if (destslot)
{
BASE_ITEM_WEAPON_ADDWEAPON (other, self, destslot)
}

// let the player know -- CEV
BASE_ITEM_PICKUPMESSAGE (other, iit)

// restrict ammo to game maximums -- CEV
base_entity_boundammo (other);

if (other.classtype == CT_PLAYER && other.SendEntity)
other.SendFlags |= NETFLAG_PLAYER_AMMO |
NETFLAG_PLAYER_INVENTORY;

// fire all targets / killtargets
activator = other;
sub_usetargets ();

// remove the touched item or set up for respawning -- CEV
BASE_ITEM_CHECKREMOVE (self,
WEAPON_RESPAWN_TIME, WEAPON_RESPAWN_TIME)
};

//--------------------------------------------------------------
void(string key, string value) base_item_weapon_init_field =
{
base_item_init_field (key, value);
};
#endif

#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
void(entity e) base_item_weapon_init =
{
local item_info_t iit = item_info[e.weapon];

e.classgroup |= CG_ITEM_WEAPON;
e.netname = iit.name;

#ifdef CSQC
setmodelindex (e, e.modelindex);
e.modelflags |= MF_ROTATE;
#endif

#ifdef SSQC
e.classname = iit.classname;
e.classtype = iit.classtype;
e.touch = base_item_weapon_touch;
precache_model (iit.world_model);
precache_sound (iit.pickup_sound.wav);
setmodel (e, iit.world_model);

if (!e.dmg && iit.dmg)
e.dmg = iit.dmg;

if (!e.skin && iit.world_skin)
e.skin = iit.world_skin;

// if we have an owner pull from that entity's ammo pool -- CEV
if (e.spawnflags & SPAWNFLAG_ITEM_THROWN && e.owner)
{
local float ammo = 0;
switch (iit.option)
{
case ITEM_AMMO_SHELLS:
ammo = AMMO_SHELLS_WP;
if (e.owner.ammo_shells >= ammo)
{
e.owner.ammo_shells -= ammo;
}
else
{
ammo = e.owner.ammo_shells;
e.owner.ammo_shells = 0;
}
e.ammo_shells = ammo;
break;
case ITEM_AMMO_NAILS:
ammo = AMMO_NAILS_WP;
if (e.owner.ammo_nails >= ammo)
{
e.owner.ammo_nails -= ammo;
}
else
{
ammo = e.owner.ammo_nails;
e.owner.ammo_nails = 0;
}
e.ammo_nails = ammo;
break;
case ITEM_AMMO_ROCKETS:
ammo = AMMO_ROCKETS_WP;
if (e.owner.ammo_rockets >= ammo)
{
e.owner.ammo_rockets -= ammo;
}
else
{
ammo = e.owner.ammo_rockets;
e.owner.ammo_rockets = 0;
}
e.ammo_rockets = ammo;
break;
case ITEM_AMMO_CELLS:
ammo = AMMO_CELLS_WP;
if (e.owner.ammo_cells >= ammo)
{
e.owner.ammo_cells -= ammo;
}
else
{
ammo = e.owner.ammo_cells;
e.owner.ammo_cells = 0;
}
e.ammo_cells = ammo;
break;
default:
dprint (sprintf("base_item_weapon_"
"init: unknown ammo type %g "
"for entity type %s!\n",
iit.option, e.classname));
break;
}

// update any CSQC clients listening in -- CEV
if (e.owner.classtype == CT_PLAYER)
if (e.owner.SendEntity) {
{
e.owner.SendFlags |= NETFLAG_PLAYER_WEAPON |
NETFLAG_PLAYER_AMMO;
} }
}
else
{
// no owner, default ammo for weapon pickup -- CEV
switch (iit.option)
{
case ITEM_AMMO_SHELLS:
if (!e.ammo_shells)
e.ammo_shells = AMMO_SHELLS_WP;
break;
case ITEM_AMMO_NAILS:
if (!e.ammo_nails)
e.ammo_nails = AMMO_NAILS_WP;
break;
case ITEM_AMMO_ROCKETS:
if (!e.ammo_rockets)
e.ammo_rockets = AMMO_ROCKETS_WP;
break;
case ITEM_AMMO_CELLS:
if (!e.ammo_cells)
e.ammo_cells = AMMO_CELLS_WP;
break;
}
}

// particle offset
switch (e.weapon)
{
case ITEM_SEQ_SUPERSHOTGUN:
e.view_ofs = '0 0 33'; break;
case ITEM_SEQ_NAILGUN:
e.view_ofs = '0 0 31'; break;
case ITEM_SEQ_SUPERNAILGUN:
e.view_ofs = '0 0 34'; break;
case ITEM_SEQ_GRENADELAUNCHER:
e.view_ofs = '0 0 28'; break;
case ITEM_SEQ_ROCKETLAUNCHER:
e.view_ofs = '0 0 32'; break;
case ITEM_SEQ_LIGHTNINGGUN:
e.view_ofs = '0 0 31'; break;
}
#endif

// StartItem -- CEV
base_item_init (e);
};
#endif

#ifdef SSQC
//--------------------------------------------------------------
strip void() base_item_weapon =
{
base_item_weapon_init (self);
};
#endif
// };

//----------------------------------------------------------------------
// id1 & pd3 spawn functions -- CEV
//----------------------------------------------------------------------

#ifdef SSQC
//----------------------------------------------------------------------
#define ITEM_WEP(idx) \
/* { */ \
BASE_ITEM_PREINIT (base_item_weapon_init_field) \
self.weapon = idx; \
base_item_weapon_init (self);
/* } */

/*QUAKED weapon_axe (0 .5 .8) (-16 -16 0) (16 16 32)
Axe
*/
//----------------------------------------------------------------------
// Weapon 1: Ranger's Axe -- johnfitz -- dumptruck_ds from RRP and rubicon2
//----------------------------------------------------------------------
// class weapon_axe: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_axe = { ITEM_WEP (ITEM_SEQ_AXE) };
// };

/*QUAKED weapon_shotgun (0 .5 .8) (-16 -16 0) (16 16 32) X STYLE_1 STYLE_2 X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/g_shotgn.mdl"); }
This is a pickup model that should be used when you want a player to spawn with only an axe and then later get the shotgun: (trigger_take_weapon or reset_items 2 in worldspawn). There are two models to choose from. Spawnflag 2 (the default) selects an unused “classic look” model from Rubicon 2 by metlslime. Spawnflag 4 is an alternate from Slapmap and has been used in a few mods.
Single-barrelled Shotgun
Shotgun
*/
//----------------------------------------------------------------------
// Weapon 2: Shotgun -- johnfitz -- dumptruck_ds from RRP and rubicon2
// new shotgun model by Starshipwaters
// removed 2 older shotguns that used spawnflags -- dumptruck_ds
//----------------------------------------------------------------------
// class weapon_shotgun: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_shotgun = { ITEM_WEP (ITEM_SEQ_SHOTGUN) };
// };

/*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/g_shot.mdl"); }
Double-barrelled Shotgun
*/
//----------------------------------------------------------------------
// Weapon 3: Super Shotgun
//----------------------------------------------------------------------
// class weapon_supershotgun: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_supershotgun = { ITEM_WEP (ITEM_SEQ_SUPERSHOTGUN) };
// };

/*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/g_nail.mdl"); }
Nailgun
*/
//----------------------------------------------------------------------
// Weapon 4: Nailgun
//----------------------------------------------------------------------
// class weapon_nailgun: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_nailgun = { ITEM_WEP (ITEM_SEQ_NAILGUN) };
// };

/*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/g_nail2.mdl"); }
Perforator
*/
//----------------------------------------------------------------------
// Weapon 5: Super Nailgun
//----------------------------------------------------------------------
// class weapon_supernailgun: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_supernailgun = { ITEM_WEP (ITEM_SEQ_SUPERNAILGUN) };
// };

/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/g_rock.mdl"); }
Grenade Launcher
*/
//----------------------------------------------------------------------
// Weapon 6: Grenade Launcher
//----------------------------------------------------------------------
// class weapon_grenadelauncher: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_grenadelauncher = { ITEM_WEP (ITEM_SEQ_GRENADELAUNCHER) };
// };

/*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/g_rock2.mdl"); }
Rocket Launcher
*/
//----------------------------------------------------------------------
// Weapon 7: Rocket Launcher
//----------------------------------------------------------------------
// class weapon_rocketlauncher: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_rocketlauncher = { ITEM_WEP (ITEM_SEQ_ROCKETLAUNCHER) };
// };

/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/g_light.mdl"); }
Thunderbolt
*/
//----------------------------------------------------------------------
// Weapon 8: Lightning Gun
//----------------------------------------------------------------------
// class weapon_lightning: base_item_weapon
// {
//--------------------------------------------------------------
void() weapon_lightning = { ITEM_WEP (ITEM_SEQ_LIGHTNINGGUN) };
// };

#undef ITEM_WEP
#endif

Return to the top of this page or return to the overview of this repo.

Log weapons.qc

Return to the top of this page or return to the overview of this repo.