djcev.com

//

Git Repos / fte_dogmode / qc / projectiles / multigrenade.qc

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

Show multigrenade.qc

//==============================================================================
// Multi Grenade Code from doe progs MULT_WPN.QC -- dumptruck_ds
//==============================================================================

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

const float MININADE_SPLASH_DAMAGE = 35;// PD3 is 90 for player, 60 other
const float MULTINADE_SPLASH_DAMAGE = 35;// 35 is the tribolt from QC
const float MULTINADE_HEALTH = 50; //

const vector MININADE_MINS = '0 0 0'; // zero size for mininades
const vector MININADE_MAXS = '0 0 0';
const vector MULTINADE_MINS = '-8 -8 -8';// a generous grenade size -- CEV
const vector MULTINADE_MAXS = '8 8 8';

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

// base_doegrenade
void() projectile_minigrenade_explode;

// projectile_minigrenade
void() projectile_minigrenade_think;
void() projectile_minigrenade_touch;
entity(entity src, vector org, vector vel) spawn_projectile_minigrenade;
void(entity e) projectile_minigrenade_init;
strip void() projectile_minigrenade;

// projectile_multigrenade
void(vector dir) projectile_multigrenade_destroy;
void(float offset_angle) projectile_multigrenade_fire;
void() projectile_multigrenade_think;
void() projectile_multigrenade_touch;
entity(entity src, vector org, vector vel) spawn_projectile_multigrenade;
void(entity e) projectile_multigrenade_init;
strip void() projectile_multigrenade;

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

//----------------------------------------------------------------------
// class base_doegrenade: base_projectile
// {
//--------------------------------------------------------------
// MiniGrenadeExplode
//--------------------------------------------------------------
void() projectile_minigrenade_explode =
{
if (self.takedamage)
self.takedamage = DAMAGE_NO;

// removed distinction between player and monster-fired
// minigrenades in favor of a fixed common damage -- CEV
t_radiusdamage2 (self, self.owner, self.dmg_splash, world);

// BecomeExplosion
write_explosion2 (self.origin);
// TODO CEV what are the following two writes doing?
WriteByte (MSG_BROADCAST, 230);
WriteByte (MSG_BROADCAST, 5);
become_base_explosion (self);
};
// };

//----------------------------------------------------------------------
// class projectile_minigrenade: base_doegrenade
// {
//--------------------------------------------------------------
void() projectile_minigrenade_think =
{
projectile_minigrenade_explode ();
};

//--------------------------------------------------------------
// MultiGrenadeTouch (modified)
//--------------------------------------------------------------
void() projectile_minigrenade_touch =
{
if (base_projectile_check_touch())
return;

if (other.takedamage == DAMAGE_AIM)
{
projectile_minigrenade_explode ();
return;
}

// bounce sound
SOUND (self, snd_weapon_grenade_bounce)
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel)
spawn_projectile_minigrenade =
{
local entity e = spawn ();
e.owner = src;
e.origin = org;
e.velocity = vel;
// damage
e.dmg_splash = MININADE_SPLASH_DAMAGE;

projectile_minigrenade_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) projectile_minigrenade_init =
{
base_projectile_init (e);

e.classname = "MiniGrenade";
e.classtype = CT_PROJECTILE_MINIGRENADE;
e.movetype = MOVETYPE_BOUNCE;
e.solid = SOLID_BBOX;
e.think = projectile_minigrenade_think;
e.touch = projectile_minigrenade_touch;
e.aflag |= PROJECTILE_EXPLOSIVE;
e.angles = vectoangles (e.velocity);

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

if (!e.dmg_splash)
e.dmg_splash = MININADE_SPLASH_DAMAGE;

setmodel (e, "progs/mervup.mdl");
e.skin = 0;

setsize (e, MININADE_MINS, MININADE_MAXS);
setorigin (e, e.origin);

// set missile duration
e.nextthink = time + 1 + (crandom() * 0.5);
};

//--------------------------------------------------------------
strip void() projectile_minigrenade =
{
projectile_minigrenade_init (self);
};
// };

//----------------------------------------------------------------------
// class projectile_multigrenade: base_doegrenade
// {
//--------------------------------------------------------------
void(vector dir) projectile_multigrenade_destroy =
{
if (self.aflag & PROJECTILE_DESTROYED)
return;

self.aflag |= PROJECTILE_DESTROYED;
self.th_destroy = sub_nulldestroy;
self.think = sub_null;
self.touch = sub_null;
projectile_minigrenade_explode ();
};

//--------------------------------------------------------------
// MiniGrenadeLaunch
//--------------------------------------------------------------
void(float offset_angle) projectile_multigrenade_fire =
{
local float temp_rand;
local vector mis_angle, mis_vel;

// figure out missile speed
mis_angle = self.v_angle;
mis_angle_y = mis_angle_y + offset_angle;
makevectors (mis_angle);

// TODO CEV some suspicious fixed values here
mis_vel = v_forward * 100 + v_up * 400;
temp_rand = (crandom() * 60) - 30;
mis_vel += temp_rand * v_forward;
temp_rand = (crandom() * 40) - 20;
mis_vel += temp_rand * v_right;
temp_rand = (crandom() * 60) - 30;
mis_vel += temp_rand * v_up;

spawn_projectile_minigrenade (self, self.origin, mis_vel);
};

//--------------------------------------------------------------
// MultiGrenadeExplode
//--------------------------------------------------------------
void() projectile_multigrenade_think =
{
projectile_multigrenade_fire (0);
projectile_multigrenade_fire (72);
projectile_multigrenade_fire (144);
projectile_multigrenade_fire (216);
projectile_multigrenade_fire (288);

remove (self);
};

//--------------------------------------------------------------
// MultiGrenadeTouch (modified)
//--------------------------------------------------------------
void() projectile_multigrenade_touch =
{
if (base_projectile_check_touch())
return;

if (other.takedamage == DAMAGE_AIM)
{
// this previously called GrenadeExplode if fired
// by the player or MiniGrenadeExplode if fired
// by anything else. I've changed that. -- CEV
projectile_minigrenade_explode ();
return;
}

// bounce sound
SOUND (self, snd_weapon_grenade_bounce)
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel)
spawn_projectile_multigrenade =
{
local entity e = spawn ();
e.owner = src;
e.origin = org;
e.velocity = vel;
// damage
e.dmg_splash = MULTINADE_SPLASH_DAMAGE;

projectile_multigrenade_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) projectile_multigrenade_init =
{
base_projectile_init (e);

e.classname = "MultiGrenade";
e.classtype = CT_PROJECTILE_MULTIGRENADE;
e.movetype = MOVETYPE_BOUNCE;
e.solid = SOLID_BBOX;
// e.th_destroy = projectile_multigrenade_destroy;
e.think = projectile_multigrenade_think;
e.touch = projectile_multigrenade_touch;
e.stateflags |= STATE_PUSHABLE | STATE_TELEPORTABLE;
e.aflag |= PROJECTILE_EXPLOSIVE;
// e.health = MULTINADE_HEALTH;
// e.takedamage = DAMAGE_YES;
e.angles = vectoangles (e.velocity);

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

if (!e.dmg_splash)
e.dmg_splash = MULTINADE_SPLASH_DAMAGE;

setmodel (e, "progs/mervup.mdl");
e.skin = 0;

// setsize (e, MULTINADE_MINS, MULTINADE_MAXS);
setsize (e, '0 0 0', '0 0 0');
setorigin (e, e.origin);

// set missile duration
e.nextthink = time + 1;
};

//--------------------------------------------------------------
strip void() projectile_multigrenade =
{
projectile_multigrenade_init (self);
};
// };

//----------------------------------------------------------------------
// end doe qc -- dumptruck_ds
//----------------------------------------------------------------------

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

Log multigrenade.qc

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