Git Repos / fte_dogmode / qc / projectiles / grenade.qc
Last update to this file was on 2024-06-15 at 19:50.
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
// {
//--------------------------------------------------------------
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",
VOL_HIGH, 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_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);
setsize (e, '0 0 0', '0 0 0');
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
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-06-15 | Major update, committing as-is, will have bugs | cev | +8 | -7 |
2024-04-12 | Moveable gibs, heads, some bugfixes | cev | +3 | -3 |
2024-04-08 | Registered monsters, projectile bugfixes | cev | +9 | -4 |
2024-04-05 | Player footsteps, shareware monsters, misc? | cev | +1 | |
2024-03-24 | 2nd pass refactor, rework QC class structure | cev | +98 | -54 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +63 | -87 |
2024-01-31 | Class based monster refactor & start projectiles | cev | +176 |
Return to the top of this page or return to the overview of this repo.