Git Repos / fte_dogmode / qc / items / armor.qc
Last update to this file was on 2025-08-13 at 05:20.
Show armor.qc
//==============================================================================
// armor.qc
//==============================================================================
//======================================================================
// constants
//======================================================================
#ifdef SSQC
const float ARMOR_GREEN_ABSORB = 0.3; // absorb percent; id1 0.3
const float ARMOR_GREEN_AMOUNT = 100; // amount per pickup; id1 100
const float ARMOR_GREEN_MAX = 125; // id1 125
const float ARMOR_YELLOW_ABSORB = 0.6; // id1 0.6
const float ARMOR_YELLOW_AMOUNT = 150; // id1 150
const float ARMOR_YELLOW_MAX = 175; // id1 175
const float ARMOR_RED_ABSORB = 0.8; // id1 0.8
const float ARMOR_RED_AMOUNT = 200; // id1 200
const float ARMOR_RED_MAX = 225; // id1 225
const float ARMOR_SHARD_AMOUNT = 5; // Q3 5
const float ARMOR_RESPAWN_SP = 30; // id1 30s
const float ARMOR_RESPAWN_DM = 20; // id1 20s
#endif
//======================================================================
// forward declarations
//======================================================================
// base_item_armor
#ifdef SSQC
// BASE_ITEM_ARMOR_ADDARMOR(p, idx)
#endif
#ifdef CSQC
void(float isnew) base_item_armor_netreceive;
#endif
#ifdef SSQC
entity(entity src) item_armor_shard_drop;
void(entity grabber, entity armor) base_item_armor_grab;
void(entity attacker, float item_index) base_item_armor_fire;
void() base_item_armor_touch;
void(string key, string value) base_item_armor_init_field;
#endif
#if defined(CSQC) || defined(SSQC)
void(entity e) base_item_armor_init;
#endif
#ifdef SSQC
strip void() base_item_armor;
#endif
#ifdef SSQC
//----------------------------------------------------------------------
// original id1 & pd3 spawn functions -- CEV
//----------------------------------------------------------------------
void() item_armor1;
void() item_armor2;
void() item_armorInv;
void() item_armor_shard;
#endif
//------------------------------------------------------------------------------
//----------------------------------------------------------------------
// class base_item_armor: base_item
// {
#ifdef SSQC
//--------------------------------------------------------------
#define BASE_ITEM_ARMOR_ADDARMOR(p, idx) \
{ \
local float a_type = 0, a_value = 0, a_bit = 0; \
switch (idx) \
{ \
case ITEM_SEQ_ARMOR_GREEN: \
/* green armor */ \
a_type = ARMOR_GREEN_ABSORB; \
a_value = ARMOR_GREEN_AMOUNT; \
a_bit = IT_ARMOR1; \
break; \
case ITEM_SEQ_ARMOR_YELLOW: \
/* yellow armor */ \
a_type = ARMOR_YELLOW_ABSORB; \
a_value = ARMOR_YELLOW_AMOUNT; \
a_bit = IT_ARMOR2; \
break; \
case ITEM_SEQ_ARMOR_RED: \
/* red armor */ \
a_type = ARMOR_RED_ABSORB; \
a_value = ARMOR_RED_AMOUNT; \
a_bit = IT_ARMOR3; \
break; \
case ITEM_SEQ_ARMOR_SHARD: \
a_value = p.armorvalue + ARMOR_SHARD_AMOUNT; \
if (p.items & IT_ARMOR2) \
{ \
if (p.armorvalue >= ARMOR_YELLOW_MAX) \
return; \
if (a_value > ARMOR_YELLOW_MAX) \
a_value = ARMOR_YELLOW_MAX; \
a_type = ARMOR_YELLOW_ABSORB; \
a_bit = IT_ARMOR2; \
} \
else if (p.items & IT_ARMOR3) \
{ \
if (p.armorvalue >= ARMOR_RED_MAX) \
return; \
if (a_value > ARMOR_RED_MAX) \
a_value = ARMOR_RED_MAX; \
a_type = ARMOR_RED_ABSORB; \
a_bit = IT_ARMOR3; \
} \
else \
{ \
if (p.armorvalue >= ARMOR_GREEN_MAX) \
return; \
if (a_value > ARMOR_GREEN_MAX) \
a_value = ARMOR_GREEN_MAX; \
a_type = ARMOR_GREEN_ABSORB; \
a_bit = IT_ARMOR1; \
} \
break; \
default: \
dprint (sprintf("base_item_armor_touch: " \
"unknown armor type! seq %g, class " \
"%s!\n", idx, self.classname)); \
return; \
} \
if (p.armortype * p.armorvalue >= a_type * a_value) \
return; \
p.armortype = a_type; \
p.armorvalue = a_value; \
p.items = p.items - (p.items & \
(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + a_bit; \
}
#endif
#ifdef CSQC
//--------------------------------------------------------------
void(float isnew) base_item_armor_netreceive =
{
// creates a number of variables, including netflags -- CEV
BASE_ITEM_NETRECEIVE (base_item_armor_init)
};
#endif
#ifdef SSQC
//--------------------------------------------------------------
// TODO CEV
//--------------------------------------------------------------
entity(entity src) item_armor_shard_drop =
{
local vector vel;
vel_x = -100 + (random() * 200);
vel_y = -100 + (random() * 200);
vel_z = 300;
local entity oself = self;
self = src;
local entity e = spawn_base_item (ITEM_SEQ_ARMOR_SHARD,
src.origin - '0 0 24', vel, SPAWNFLAG_ITEM_THROWN);
self = oself;
return e;
};
//--------------------------------------------------------------
void(entity grabber, entity armor) base_item_armor_grab =
{
BASE_ITEM_INVENTORY_ADD (armor, grabber)
sprint (grabber, sprintf("%s grabbed the %s\n",
grabber.netname, armor.netname));
// don't re-grab / immediately throw the item -- CEV
if (grabber.button4)
grabber.flags |= FL_THROW_HELD;
if (grabber.classtype == CT_PLAYER && grabber.SendEntity)
grabber.SendFlags |= NETFLAG_PLAYER_WEAPON;
// fire all targets / killtargets
local entity stemp = self;
local entity otemp = other;
other = grabber;
self = armor;
activator = other;
sub_usetargets ();
self = stemp;
other = otemp;
// remove or respawn -- CEV
BASE_ITEM_CHECKREMOVE (armor,
ARMOR_RESPAWN_SP, ARMOR_RESPAWN_DM)
};
//--------------------------------------------------------------
void(entity attacker, float item_index) base_item_armor_fire =
{
// add the armor -- CEV
BASE_ITEM_ARMOR_ADDARMOR (attacker, item_index)
// now remove the armor from inventory -- CEV
BASE_ITEM_INVENTORY_REMOVE (attacker)
// make sure the client knows -- CEV
if (attacker.classtype == CT_PLAYER && attacker.SendEntity)
attacker.SendFlags |= NETFLAG_PLAYER_ITEMS |
NETFLAG_PLAYER_HEALTH | NETFLAG_PLAYER_WEAPON;
// let the player know -- CEV
local item_info_t iit = item_info[item_index];
BASE_ITEM_PICKUPMESSAGE (attacker, iit)
};
//--------------------------------------------------------------
// was armor_touch -- CEV
//--------------------------------------------------------------
void() base_item_armor_touch =
{
// thrown item check -- CEV
if (base_item_touch_projectile())
return;
if (sub_checkvalidtouch(other) == FALSE)
return;
// don't touch() if the player isn't holding a weapon -- CEV
BASE_ENTITY_WEAPONLOOKUP (other)
if (item_index < ITEM_SEQ_W_START||item_index > ITEM_SEQ_W_END)
{
if (item_index == ITEM_SEQ_HANDS && other.button4)
{
// self.attack_finished = time + 0.5;
base_item_armor_grab (other, self);
return;
}
else if (!other.button0)
{
return;
}
}
// add the armor -- CEV
BASE_ITEM_ARMOR_ADDARMOR (other, self.weapon)
// let the client (CSQC) know -- CEV
if (other.classtype == CT_PLAYER && other.SendEntity)
other.SendFlags |= NETFLAG_PLAYER_ITEMS |
NETFLAG_PLAYER_HEALTH;
// let the player know -- CEV
local item_info_t iit = item_info[self.weapon];
BASE_ITEM_PICKUPMESSAGE (other, iit)
// fire all targets / killtargets
activator = other;
sub_usetargets ();
// either remove the item or set up for respawning -- CEV
BASE_ITEM_CHECKREMOVE (self,
ARMOR_RESPAWN_SP, ARMOR_RESPAWN_DM)
};
//--------------------------------------------------------------
void(string key, string value) base_item_armor_init_field =
{
base_item_init_field (key, value);
};
#endif
#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
void(entity e) base_item_armor_init =
{
local item_info_t iit = item_info[e.weapon];
e.netname = iit.name;
e.classgroup |= CG_ITEM_ARMOR;
#ifdef SSQC
e.classname = iit.classname;
e.classtype = iit.classtype;
e.touch = base_item_armor_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;
#endif
#ifdef CSQC
setmodelindex (e, e.modelindex);
e.modelflags |= MF_ROTATE;
#endif
// next function will take care of setsize -- CEV
base_item_init (e);
};
#endif
#ifdef SSQC
//--------------------------------------------------------------
strip void() base_item_armor =
{
base_item_armor_init (self);
};
#endif
// };
//----------------------------------------------------------------------
// id1 & pd3 spawn functions -- CEV
//----------------------------------------------------------------------
#ifdef SSQC
//----------------------------------------------------------------------
#define ITEM_ARMOR(idx) \
/* { */ \
BASE_ITEM_PREINIT (base_item_armor_init_field) \
self.weapon = idx; \
base_item_armor_init (self);
/* } */
/*QUAKED item_armor1 (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/armor.mdl");
}
*/
void() item_armor1 = { ITEM_ARMOR (ITEM_SEQ_ARMOR_GREEN) };
/*QUAKED item_armor2 (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({ "path": ":progs/armor.mdl", "skin": 1 }); }
*/
void() item_armor2 = { ITEM_ARMOR (ITEM_SEQ_ARMOR_YELLOW) };
/*QUAKED item_armorInv (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({ "path": ":progs/armor.mdl", "skin": 2 });
}
*/
void() item_armorInv = { ITEM_ARMOR (ITEM_SEQ_ARMOR_RED) };
//------------------------------------------------------------------------------
// item_armor_shard
//------------------------------------------------------------------------------
void() item_armor_shard = { ITEM_ARMOR (ITEM_SEQ_ARMOR_SHARD) };
#undef ITEM_ARMOR
#endif
Return to the top of this page or return to the overview of this repo.
Log armor.qc
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2025-08-13 | Another big commit. Item changes, field rework, etc. | cev | +75 | -305 |
2025-03-30 | Big commit. Entity networking, etc. | cev | +330 | -223 |
2024-06-15 | Major update, committing as-is, will have bugs | cev | +26 | -4 |
2024-03-24 | 2nd pass refactor, rework QC class structure | cev | +247 | -125 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +27 | -27 |
2024-01-13 | Refactored items into classes, fix teleporttrain | cev | +269 | -254 |
2024-01-09 | Continue OO / Class-based refactor | cev | -4 | |
2023-12-09 | Start OO / class-based refactor, work on items | cev | +63 | -23 |
2023-12-02 | More refactoring & moving, begin adding mdls & snd | cev | +278 |
Return to the top of this page or return to the overview of this repo.