328 lines
No EOL
7.6 KiB
C++
328 lines
No EOL
7.6 KiB
C++
/*
|
|
=============================
|
|
ewgore.qc
|
|
coded by
|
|
Michael Rogers a.k.a Xsniper
|
|
ssj_xsniper@yahoo.com
|
|
http://www.xsniper.net/
|
|
|
|
Description:
|
|
This file contains functions that create various
|
|
levels of blood and gore in EW.
|
|
|
|
ALL BLOOD AND GORE IS DISABLED FOR THE TIME BEING!
|
|
=============================
|
|
*/
|
|
|
|
vector(float dm) VelocityForDamage =
|
|
{
|
|
local vector v;
|
|
|
|
v_x = 100 * crandom();
|
|
v_y = 100 * crandom();
|
|
v_z = 200 + 100 * random();
|
|
|
|
if (dm > -50)
|
|
{
|
|
// dprint ("level 1\n");
|
|
v = v * 0.7;
|
|
}
|
|
else if (dm > -200)
|
|
{
|
|
// dprint ("level 3\n");
|
|
v = v * 2;
|
|
}
|
|
else
|
|
v = v * 10;
|
|
|
|
return v;
|
|
};
|
|
|
|
/*
|
|
================
|
|
SpawnMeatSpray
|
|
================
|
|
*/
|
|
void(vector org, vector vel) SpawnMeatSpray =
|
|
{
|
|
local entity missile, mpuff;
|
|
local vector org;
|
|
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
missile = spawn ();
|
|
missile.owner = self;
|
|
missile.movetype = MOVETYPE_BOUNCE;
|
|
missile.solid = SOLID_NOT;
|
|
|
|
makevectors (self.angles);
|
|
|
|
missile.velocity = vel;
|
|
missile.velocity_z = missile.velocity_z + 250 + 50*random();
|
|
|
|
missile.avelocity = '3000 1000 2000';
|
|
|
|
// set missile duration
|
|
missile.nextthink = time + 1;
|
|
missile.think = SUB_Remove;
|
|
|
|
setmodel (missile, "models/gibs/clod1.md2");
|
|
setsize (missile, '0 0 0', '0 0 0');
|
|
setorigin (missile, org);
|
|
};
|
|
|
|
/*
|
|
================
|
|
SpawnBlood
|
|
================
|
|
*/
|
|
void(vector org, vector vel, float damage) SpawnBlood =
|
|
{
|
|
local float bcolor;
|
|
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
//set up blood color
|
|
bcolor = 33;
|
|
|
|
if (cvar("blood_level") > 0)
|
|
{
|
|
//different levels of blood based on blood level
|
|
if (cvar("blood_level") < 2)
|
|
{
|
|
particle (org, vel*0.1, bcolor, damage*2);
|
|
particle (org, vel*0.15, bcolor, damage*3);
|
|
}
|
|
else if (cvar("blood_level") < 3)
|
|
{
|
|
particle (org, vel*0.1, bcolor, damage*2);
|
|
particle (org, vel*0.15, bcolor, damage*3);
|
|
particle (org, vel*0.25, bcolor, damage*4);
|
|
}
|
|
else if (cvar("blood_level") >= 3)
|
|
{
|
|
particle (org, vel*0.1, bcolor, damage*1);
|
|
particle (org, vel*0.1, bcolor, damage*2);
|
|
particle (org, vel*0.15, bcolor, damage*3);
|
|
particle (org, vel*0.25, bcolor, damage*5);
|
|
}
|
|
}
|
|
};
|
|
|
|
/*
|
|
================
|
|
spawn_touchblood
|
|
================
|
|
*/
|
|
void(float damage) spawn_touchblood =
|
|
{
|
|
local vector vel;
|
|
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
vel = wall_velocity () * 0.05;
|
|
SpawnBlood (self.origin + vel*0.01, vel, damage);
|
|
};
|
|
|
|
|
|
/*
|
|
================
|
|
SpawnChunk
|
|
================
|
|
*/
|
|
void(vector org, vector vel) SpawnChunk =
|
|
{
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
//even older yet reliable particle system
|
|
particle (org, vel*0.02, 33, 2);
|
|
};
|
|
|
|
/*
|
|
=================
|
|
GibThink
|
|
|
|
Lets bleed for awhile and then remove ourself.
|
|
=================
|
|
*/
|
|
void() GibThink =
|
|
{
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
//see if we can stop bleeding now
|
|
if (time > self.ltime)
|
|
{
|
|
self.think = SUB_Remove;
|
|
self.nextthink = time + 0.1 + random();
|
|
}
|
|
else
|
|
{
|
|
self.think = GibThink;
|
|
self.nextthink = time + 0.05;
|
|
}
|
|
|
|
//if we are airborne then lets drip blood
|
|
if (!(self.flags & FL_ONGROUND))
|
|
{
|
|
//leave a blood trail
|
|
SpawnChunk(self.origin,'0 0 0');
|
|
SpawnChunk(self.origin,'50 0 0');
|
|
SpawnChunk(self.origin,'0 50 0');
|
|
SpawnChunk(self.origin,'25 25 50');
|
|
}
|
|
};
|
|
|
|
void(string gibname, float dm) ThrowGib =
|
|
{
|
|
local entity new;
|
|
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
new = spawn();
|
|
new.origin = self.origin;
|
|
setmodel (new, gibname);
|
|
setsize (new, '0 0 0', '0 0 0');
|
|
new.velocity = VelocityForDamage (dm);
|
|
new.movetype = MOVETYPE_BOUNCE;
|
|
new.solid = SOLID_NOT;
|
|
new.avelocity_x = random()*600;
|
|
new.avelocity_y = random()*600;
|
|
new.avelocity_z = random()*600;
|
|
new.think = GibThink;
|
|
new.ltime = time + 4 + random();
|
|
new.nextthink = time + 0.05;
|
|
new.frame = 0;
|
|
};
|
|
|
|
void(string gibname, float dm) ThrowHead =
|
|
{
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
setmodel (self, gibname);
|
|
self.skin = 0;
|
|
self.frame = 0;
|
|
self.think = GibThink;
|
|
self.ltime = time + 4 + random();
|
|
self.nextthink = time + 0.05;
|
|
self.movetype = MOVETYPE_BOUNCE;
|
|
self.takedamage = DAMAGE_NO;
|
|
self.solid = SOLID_NOT;
|
|
self.view_ofs = '0 0 8';
|
|
setsize (self, '-16 -16 0', '16 16 56');
|
|
self.velocity = VelocityForDamage (dm);
|
|
self.origin_z = self.origin_z - 24;
|
|
self.flags = self.flags - (self.flags & FL_ONGROUND);
|
|
self.avelocity = crandom() * '0 600 0';
|
|
};
|
|
|
|
|
|
void() GibPlayer =
|
|
{
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
ThrowHead ("models/gibs/skull.md2", self.health);
|
|
ThrowGib ("models/gibs/clod1.md2", self.health);
|
|
ThrowGib ("models/gibs/clod2.md2", self.health);
|
|
ThrowGib ("models/gibs/leaf.md2", self.health);
|
|
|
|
self.deadflag = DEAD_DEAD;
|
|
|
|
if (damage_attacker.classname == "teledeath")
|
|
{
|
|
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
|
|
return;
|
|
}
|
|
|
|
if (damage_attacker.classname == "teledeath2")
|
|
{
|
|
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
|
|
return;
|
|
}
|
|
|
|
if (random() < 0.5)
|
|
sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE);
|
|
else
|
|
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE);
|
|
};
|
|
|
|
//SplatThink: Controls behavior of splats after they have hit the wall
|
|
void() SplatThink =
|
|
{
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
if ( (self.attack_finished <= time) || (self.flags & FL_ONGROUND) )
|
|
{
|
|
remove(self); //remove if: time "runs out" or on ground
|
|
return;
|
|
}
|
|
self.velocity_z = random()*-10; //splat slowly slides down walls, changing speed
|
|
self.angles = vectoangles(self.velocity); //point in direction of movement
|
|
self.nextthink = time + 0.2;
|
|
};
|
|
|
|
//SplatTouch: Called(by the engine) when splats touch the world or an entity
|
|
//after being spawned
|
|
void() SplatTouch =
|
|
{
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
if ( (other != world) || (pointcontents(self.origin) <= -3) || (self.flags & FL_ONGROUND) )
|
|
{
|
|
remove(self); //remove if: didn't hit wall, in liquid, or on ground
|
|
return;
|
|
}
|
|
|
|
self.velocity = self.avelocity = '0 0 0'; //stop moving and spinning
|
|
self.movetype = MOVETYPE_FLY; //changed to remove effect of gravity
|
|
self.touch = SUB_Null; //don't call this (touch) function again
|
|
self.attack_finished = time + 4 + (2*random()); //set random "time limit"
|
|
|
|
self.think = SplatThink;
|
|
self.nextthink = time + 0.2;
|
|
};
|
|
|
|
//ThrowBloodSplat: This will create a blood splat at "org", moving in
|
|
//direction "dir", and owned by "own"
|
|
void(vector dir, vector org, entity own) ThrowBloodSplat =
|
|
{
|
|
//all blood and gore is disabled
|
|
return;
|
|
|
|
local entity splat;
|
|
local vector dir;
|
|
|
|
if ( !((own.flags & FL_MONSTER) || (own.classname == "player")) )
|
|
return; //only monsters and players should create splats!
|
|
|
|
splat = spawn();
|
|
splat.owner = own; //move through hit monster/player
|
|
splat.movetype = MOVETYPE_TOSS; //gravity with no bouncing
|
|
splat.solid = SOLID_BBOX; //does not move through other entities (besides owner)
|
|
|
|
dir = normalize(dir); //make sure "dir" has length 1
|
|
splat.velocity = dir * (450 + 50*random()); //random velocity in direction of shot
|
|
splat.velocity_x = splat.velocity_x + crandom()*40; //randomize x velocity (+/- 40)
|
|
splat.velocity_y = splat.velocity_y + crandom()*40; //randomize y velocity (+/- 40)
|
|
splat.velocity_z = splat.velocity_z + 120 + 50*random(); //randomize z velocity (+ 120-170)
|
|
splat.touch = SplatTouch;
|
|
|
|
splat.think = GibThink;
|
|
splat.ltime = time + 4 + random();
|
|
splat.nextthink = time + 0.05;
|
|
|
|
setmodel (splat, "progs/spike.mdl");
|
|
splat.scale = 0.1;
|
|
splat.alpha = 0.1;
|
|
setsize (splat, '0 0 0', '0 0 0');
|
|
setorigin (splat, org); //start splat at point of damage
|
|
}; |