djcev.com

//

Git Repos / fte_dogmode / qc / base_gore.qc

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

Show base_gore.qc

//==============================================================================
// base_gore.qc -- corpses, gibs, heads. the meaty bits. -- CEV
//==============================================================================

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds
//
// deadstuff version 1.0 - tony collen - manero@canweb.net -
// EfNet IRC #QuakeEd or #Trinity
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

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

const float GIB_SOLID = 1; // spawnflags: solid
const float GIB_DYNAMIC = 2; // non-static, moveable gibs

const vector GIB_1_MINS = '-3.57 -8.06 -3.34';
const vector GIB_1_MAXS = '3.69 8.31 30';
const vector GIB_2_MINS = '-12.68 -14.83 -6.19';
const vector GIB_2_MAXS = '13.53 14.57 30';
const vector GIB_3_MINS = '-18.95 -15.92 -3.13';
const vector GIB_3_MAXS = '13.17 15.66 30';

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

void(vector org, vector vel, float damage) spawn_blood;
void(float damage) spawn_touchblood;
void(vector org, vector vel) spawn_chunk;
entity(vector org, vector vel) spawn_meatspray;
vector(vector dir, float dmg) velocity_for_damage;

// base_corpse
strip void() base_corpse;

// base_gib
void() base_gib_touch;
entity(entity src, vector org, vector vel, float sflags, .string gibfield,
void(entity) initfn) spawn_base_gib;
void(entity e) base_gib_init;
strip void() base_gib;

// gib_misc_1
void(entity src, vector dir, float dmg) throw_gib_1;
entity(entity src, vector org, vector vel, float sflags) spawn_gib_misc_1;
void(entity e) gib_misc_1_init;
void() gib_misc_1;

// gib_misc_2
void(entity src, vector dir, float dmg) throw_gib_2;
entity(entity src, vector org, vector vel, float sflags) spawn_gib_misc_2;
void(entity e) gib_misc_2_init;
void() gib_misc_2;

// gib_misc_3
void(entity src, vector dir, float dmg) throw_gib_3;
entity(entity src, vector org, vector vel, float sflags) spawn_gib_misc_3;
void(entity e) gib_misc_3_init;
void() gib_misc_3;

// base_gib_head
void(entity act, vector dir, float dmg, void(entity e) initfn)
base_gib_head_throw;
void(entity e) base_gib_head_init;
strip void() base_gib_head;

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

//----------------------------------------------------------------------
// SpawnBlood
//----------------------------------------------------------------------
void(vector org, vector vel, float damage) spawn_blood =
{
particle (org, vel * 0.1, 73, damage * 2);
};

//----------------------------------------------------------------------
// spawn_touchblood
//----------------------------------------------------------------------
void(float damage) spawn_touchblood =
{
// wall_velocity
local vector vel;

vel = normalize (self.velocity);
vel = normalize (vel + v_up * (random() - 0.5) +
v_right * (random() - 0.5));
// TODO CEV when was the last time a trace was called?
vel = vel + 2 * trace_plane_normal;
vel = (vel * 200) * 0.2;

spawn_blood (self.origin + vel * 0.01, vel, damage);
};

//----------------------------------------------------------------------
// SpawnChunk
//----------------------------------------------------------------------
void(vector org, vector vel) spawn_chunk =
{
particle (org, vel * 0.02, 0, 10);
};

//----------------------------------------------------------------------
// SpawnMeatSpray
//----------------------------------------------------------------------
entity(vector org, vector vel) spawn_meatspray =
{
// reusing the "zombiechunk" projectile -- CEV
local entity e = spawn_projectile_zombiechunk (self, org, vel);
// override some defaults, notably solid and force damage to 0 -- CEV
e.solid = SOLID_NOT;
e.direct_damage = 0;
e.velocity_z += 250 + 50 * random ();
e.nextthink = time + 1;
return e;
};

//----------------------------------------------------------------------
vector(vector dir, float dmg) velocity_for_damage =
{
local vector startdir = dir;

if (dmg == 0 || dir == '0 0 0')
{
// original id1 behavior -- CEV
dir_x = 100 * crandom ();
dir_y = 100 * crandom ();
dir_z = 200 + 100 * random ();

if (dmg > -50)
dir = dir * 0.7;
else if (dmg > -200)
dir = dir * 2;
else
dir = dir * 10;
}
else
{
// I'm sure there's a better way to do this -- CEV
dir_x = dir_x * (4 * fabs(dmg) * random());
dir_y = dir_y * (4 * fabs(dmg) * random());
if (dir_z > 0)
dir_z = 250 + 2 * ((fabs(dmg) * fabs(dir_z)));
else
dir_z = 250 + 2 * ((fabs(dmg) * (random() * 0.5)));
}

dprint (sprintf("velocity_for_damage: damage is %g, startdir is %v, "
"dir is %v\n", dmg, startdir, dir));

return dir;
};

//----------------------------------------------------------------------
// class base_corpse: base_mapentity
// {
// https://www.insideqc.com/qctut/qctut-33.shtml
// TODO CEV
//--------------------------------------------------------------
strip void() base_corpse =
{
base_corpse_init (self);
};
// };

//----------------------------------------------------------------------
// class base_gib: base_mapentity
// {
//--------------------------------------------------------------
// Inspired by Ivana Gibson's kickable gibs [1] and similar
// functions found in other mods (Scarlet, etc) -- CEV
// [1]: https://www.insideqc.com/qctut/lesson-52.shtml
//--------------------------------------------------------------
void() base_gib_touch =
{
// only run if the object has come to rest -- CEV
if (self.velocity)
return;

// only run if touched by a player or monster -- CEV
if (other.classtype != CT_PLAYER && !(other.flags & FL_MONSTER))
return;

local float other_spd;
other_spd = vlen ([other.velocity_x, other.velocity_y, 0]);

// only run if other is moving fast enough to disturb
// stationary objects -- CEV
if (other_spd < 200)
return;

// clamp speed to PM_MAXSPEED (320) -- CEV
other_spd = min (other_spd, PM_MAXSPEED);

// this is the same method t_damage uses to find damage
// knockback direction -- CEV
local vector dir;
dir = self.origin - (other.absmin + other.absmax) * 0.5;
dir = normalize (dir);

self.flags &= ~FL_ONGROUND;

if (self.avelocity_y == 0)
// a little spin, as a treat. Rotating in the other
// axes seem to cause gibs to move into the floor -- CEV
self.avelocity_y = 100 * crandom ();

// move in direction at half of other's speed (so this will
// usually be 160) -- CEV
self.velocity += dir * (other_spd * 0.5);

// MOVETYPE_BOUNCE entities stop when impacting the ground if
// Z velocity is 60 or less. I don't want moveable gibs to
// be flying around, so set a fixed Z velocity a little above
// that 60 threshold -- CEV
self.velocity_z = 75;
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel, float sflags,
.string gibfield, void(entity) initfn) spawn_base_gib =
{
local entity e = spawn ();
e.owner = src;
e.spawnflags = sflags;
e.origin = org;
e.velocity = vel;
if (src.gibfield && src.gibfield != "")
e.gibfield = src.gibfield;
initfn (e);
return e;
};

//--------------------------------------------------------------
void(entity e) base_gib_init =
{
if (!(e.flags & FL_CLIENT))
base_mapentity_init (e);

if (e.spawnflags & GIB_SOLID)
{
e.solid = SOLID_BBOX;
}
else if (e.spawnflags & GIB_DYNAMIC)
{
e.movetype = MOVETYPE_BOUNCE;
e.takedamage = DAMAGE_NO;
e.solid = SOLID_TRIGGER;
e.touch = base_gib_touch;
if (e.flags & FL_CLIENT)
e.flags = e.flags - (e.flags & FL_ONGROUND);
else
e.flags = 0;
}
else
{
e.solid = SOLID_NOT;
}
};

strip void() base_gib =
{
base_gib_init (self);
};
// };

/*QUAKED gib_misc_1 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/gib1.mdl");
}*/
//----------------------------------------------------------------------
// class gib_misc_1: base_gib
// {
//--------------------------------------------------------------
// 'self' in this context is the thing being gibbed -- CEV
//--------------------------------------------------------------
void(entity src, vector dir, float dmg) throw_gib_1 =
{
local entity e = spawn_gib_misc_1 (src, src.origin + '0 0 24',
velocity_for_damage(dir, dmg), GIB_DYNAMIC);
e.avelocity_x = random() * 600;
e.avelocity_y = random() * 600;
e.avelocity_z = random() * 600;
e.alpha = 1.0;
e.think = sub_remove_fade;
e.ltime = time;
e.nextthink = time + 10 + random() * 10;
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel, float sflags)
spawn_gib_misc_1 =
{
return spawn_base_gib (src, org, vel, sflags, mdl_gib2,
gib_misc_1_init);
};


//--------------------------------------------------------------
void(entity e) gib_misc_1_init =
{
e.classname = "gib_misc_1";
e.classtype = CT_GORE_GIB1;

// this will set e.solid
base_gib_init (e);

if (e.mdl_gib1 != "")
{
precache_model (e.mdl_gib1);
setmodel (e, e.mdl_gib1);
}
else
{
precache_model ("progs/gib1.mdl");
setmodel (e, "progs/gib1.mdl");
if (e.solid == SOLID_BBOX || e.solid == SOLID_TRIGGER)
setsize (e, GIB_1_MINS, GIB_1_MAXS);
}

e.frame = 0;
};

//--------------------------------------------------------------
void() gib_misc_1 =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

gib_misc_1_init (self);
};
// };

/*QUAKED gib_misc_2 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/gib2.mdl");
}*/
//----------------------------------------------------------------------
// class gib_misc_2: base_gib
// {
//--------------------------------------------------------------
// 'self' in this context is the thing being gibbed -- CEV
//--------------------------------------------------------------
void(entity src, vector dir, float dmg) throw_gib_2 =
{
local entity e = spawn_gib_misc_2 (src, src.origin + '0 0 24',
velocity_for_damage(dir, dmg), GIB_DYNAMIC);
e.avelocity_x = random() * 600;
e.avelocity_y = random() * 600;
e.avelocity_z = random() * 600;
e.alpha = 1.0;
e.think = sub_remove_fade;
e.ltime = time;
e.nextthink = time + 10 + random() * 10;
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel, float sflags)
spawn_gib_misc_2 =
{
return spawn_base_gib (src, org, vel, sflags, mdl_gib2,
gib_misc_2_init);
};

//--------------------------------------------------------------
void(entity e) gib_misc_2_init =
{
e.classname = "gib_misc_2";
e.classtype = CT_GORE_GIB2;

// this will set e.solid
base_gib_init (e);

if (e.mdl_gib2 != "")
{
precache_model (e.mdl_gib2);
setmodel (e, e.mdl_gib2);
}
else
{
precache_model ("progs/gib2.mdl");
setmodel (e, "progs/gib2.mdl");
if (e.solid == SOLID_BBOX || e.solid == SOLID_TRIGGER)
setsize (e, GIB_2_MINS, GIB_2_MAXS);
}

e.frame = 0;
};

//--------------------------------------------------------------
void() gib_misc_2 =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

gib_misc_2_init (self);
};
// };

/*QUAKED gib_misc_3 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/gib3.mdl");
}*/
//----------------------------------------------------------------------
// class gib_misc_3: base_gib
// {
//--------------------------------------------------------------
// 'self' in this context is the thing being gibbed -- CEV
//--------------------------------------------------------------
void(entity src, vector dir, float dmg) throw_gib_3 =
{
local entity e = spawn_gib_misc_3 (src, src.origin + '0 0 24',
velocity_for_damage(dir, dmg), GIB_DYNAMIC);
e.avelocity_x = random() * 600;
e.avelocity_y = random() * 600;
e.avelocity_z = random() * 600;
e.alpha = 1.0;
e.think = sub_remove_fade;
e.ltime = time;
e.nextthink = time + 10 + random() * 10;
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel, float sflags)
spawn_gib_misc_3 =
{
return spawn_base_gib (src, org, vel, sflags, mdl_gib3,
gib_misc_3_init);
};

//--------------------------------------------------------------
void(entity e) gib_misc_3_init =
{
e.classname = "gib_misc_3";
e.classtype = CT_GORE_GIB3;

// this will set e.solid
base_gib_init (e);

if (e.mdl_gib3 != "")
{
precache_model (e.mdl_gib3);
setmodel (e, e.mdl_gib3);
}
else
{
precache_model ("progs/gib3.mdl");
setmodel (e, "progs/gib3.mdl");
if (e.solid == SOLID_BBOX || e.solid == SOLID_TRIGGER)
setsize (e, GIB_3_MINS, GIB_3_MAXS);
}

e.frame = 0;
};

//--------------------------------------------------------------
void() gib_misc_3 =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

gib_misc_3_init (self);
};
// };

//----------------------------------------------------------------------
// class base_gib_head: base_gib
// {
//--------------------------------------------------------------
// ThrowHead
//--------------------------------------------------------------
void(entity act, vector dir, float dmg, void(entity e) initfn)
base_gib_head_throw =
{
act.skin = act.skin_head;
act.nextthink = -1;
act.spawnflags = GIB_DYNAMIC;
act.view_ofs = '0 0 8';

act.origin_z = act.origin_z - 24;
act.avelocity = crandom() * '0 600 0';
act.velocity = velocity_for_damage (dir, dmg);

if (initfn)
initfn (act);
};

//--------------------------------------------------------------
void(entity e) base_gib_head_init =
{
base_gib_init (e);
};

//--------------------------------------------------------------
strip void() base_gib_head =
{
base_gib_head_init (self);
};
// };

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

Log base_gore.qc

Date Commit Message Author + -
2024-04-12 Moveable gibs, heads, some bugfixes cev +505  

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