djcev.com

//

Git Repos / fte_dogmode / qc / projectiles / grenade.qc

Last update to this file was on 2024-04-12 at 18:56.

Show grenade.qc

//==============================================================================
// Grenades
//==============================================================================

//======================================================================
// constants
//======================================================================
const float GRENADE_DIRECT_DAMAGE = 100;// direct damage; 100 is id1
const float GRENADE_SPLASH_DAMAGE = 120;// splash damage; 120 is id1
const float GRENADE_SPEED = 600; // id1 grenade speed is 600
const float GRENADE_HEALTH = 50; // explodes when dead

// found using FTE's sv_gameplayfix_setmodelrealbox
// const vector GRENADE_MINS = '-8.57384 -3.71142 -3.94197';
// const vector GRENADE_MAXS = '10.2459 3.68095 4.05187';
const vector GRENADE_MINS = '-8 -8 -8'; // a little more generous -- CEV
const vector GRENADE_MAXS = '8 8 8';

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

// projectile_grenade
void(vector dir) projectile_grenade_destroy;
void() projectile_grenade_think;
entity(entity src, vector org, vector vel) spawn_projectile_grenade;
void(entity e) projectile_grenade_init;
strip void() projectile_grenade;

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

//----------------------------------------------------------------------
// class projectile_grenade: base_projectile_qcphys
// {
//--------------------------------------------------------------
void(vector dir) projectile_grenade_destroy =
{
if (self.aflag & PROJECTILE_DESTROYED)
return;

self.aflag |= PROJECTILE_DESTROYED;
self.destroy = sub_nulldestroy;
self.think = sub_null;
self.touch = sub_null;
projectile_grenade_think ();
};

//--------------------------------------------------------------
void() projectile_grenade_think =
{
if (self.takedamage)
self.takedamage = DAMAGE_NO;

t_radiusdamage2 (self, self.owner, self.splash_damage, other);

// BecomeExplosion
write_explosion (self.origin);
become_base_explosion (self);
};

//--------------------------------------------------------------
// GrenadeTouch
//
// This has been modified to fix a bug in the original code, which
// is that an entity with a very large bounding box (e.g. the size
// of monster_boss or monster_oldone) would receive little or no
// damage from a grenade impact. (In the original game, this bug
// didn't really matter because the largest DAMAGE_AIM entities
// were Shambler-sized.)
//
// In the original code, this function simply called GrenadeExplode,
// which called T_RadiusDamage, which deals an amount of damage
// based on the distance to the center of the victim's bounding box.
// Therefore, the larger the victim's bounding box, the lower the
// amount of damage that a grenade impact could deal.
//
// This modified version of GrenadeTouch adds a hack so that an
// entity which is larger than Shambler-size is treated differently:
// damage will be dealt to it using the same logic as a rocket
// impact, i.e. T_Damage will be called to deal damage to the
// impacted entity, and then radius damage will be dealt to any
// other entities in the vicinity. Grenades and rockets have
// always dealt the same amount of radius damage, so making the
// impact damage the same seemed a reasonable solution.
//
// The reason this logic is only used for very large entities is
// because I didn't want to affect the amount of damage that
// grenades deal to any of the original monsters under any
// circumstances. -- iw
//--------------------------------------------------------------
void() projectile_grenade_touch =
{
// standard touch check
if (base_projectile_check_touch())
return;

if (other.takedamage == DAMAGE_AIM)
{
// see the explanation above -- iw
if (other.size_x > VEC_HULL2_SIZE_x ||
other.size_y > VEC_HULL2_SIZE_y ||
other.size_z > VEC_HULL2_SIZE_z)
{
// note that the logic for monster_shambler's
// partial immunity to explosions is not
// required because this is only for entities
// which are larger than monster_shambler -- iw
// dmg = this.direct_dmg + random() * 20;
t_damage2 (other, self, self.owner,
self.direct_damage);
projectile_grenade_think ();
return;
}
other = world;
projectile_grenade_think ();
return;
}

if (self.count < time)
{
// bounce sound
sound (self, CHAN_WEAPON, "weapons/bounce.wav",
1, ATTN_NORM);
}

self.count = time + 0.02;
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel) spawn_projectile_grenade =
{
local entity e = spawn ();
e.owner = src;
e.origin = org;
e.velocity = vel;
// damage
e.direct_damage = GRENADE_DIRECT_DAMAGE;
e.splash_damage = GRENADE_SPLASH_DAMAGE;
// model, skin, & sounds
e.mdl_proj = src.mdl_proj;
e.skin_proj = src.skin_proj;
e.snd_hit = src.snd_hit;

projectile_grenade_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) projectile_grenade_init =
{
base_projectile_qcphys_init (e);

e.classname = "grenade";
e.classtype = CT_PROJECTILE_GRENADE;
e.movetype = MOVETYPE_BOUNCE;
e.solid = SOLID_BBOX;
e.destroy = projectile_grenade_destroy;
e.touch = projectile_grenade_touch;
e.aflag |= PROJECTILE_EXPLOSIVE;
e.health = GRENADE_HEALTH;
e.takedamage = DAMAGE_YES;
e.angles = vectoangles (e.velocity);

if (!e.avelocity)
e.avelocity = '300 300 300';

if (!e.proj_basespeed)
e.proj_basespeed = GRENADE_SPEED;

// default damage for player grenades -- CEV
if (!e.direct_damage)
e.direct_damage = GRENADE_DIRECT_DAMAGE;

if (!e.splash_damage)
e.splash_damage = GRENADE_SPLASH_DAMAGE;

if (e.mdl_proj && e.mdl_proj != "")
setmodel (e, e.mdl_proj);
else
setmodel (e, "progs/grenade.mdl");

if (e.skin_proj)
e.skin = e.skin_proj;
else
e.skin = 0;

setsize (e, GRENADE_MINS, GRENADE_MAXS);
setorigin (e, e.origin);

// schedule next think (explosion time)
e.think = projectile_grenade_think;
e.nextthink = time + 2.5;
};

//--------------------------------------------------------------
strip void() projectile_grenade =
{
projectile_grenade_init (self);
};
// };

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

Log grenade.qc

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