Bood Splats
Author: MaNiAcSource: https://www.insideqc.com/qctut/qctut-47.shtml
Remember the blood that would "splat" on the walls in Duke Nukem 3D? This tutorial contains instructions on how to add the Quake "equivalent" of this effect. I have only provided direct instructions for the Shotgun, Super Shotgun, Nailgun, and Super Nailgun, but it can be added to other weapons with relative ease.Step 1 -
We must first add the main functions for this effect. Create splat.qc and paste the following code into it:
The code has been commented in many places to make it more easily readable.float() crandom; //function prototype for crandom //SplatThink: Controls behavior of splats after they have hit the wall void() SplatThink = { 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 = { 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 = { 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.avelocity = '3000 1000 2000'; //spin fast! splat.touch = SplatTouch; splat.nextthink = time + 2; splat.think = SUB_Remove; setmodel (splat, "progs/zom_gib.mdl"); setsize (splat, '0 0 0', '0 0 0'); setorigin (splat, org); //start splat at point of damage };
Step 2 -
Add the following above "weapons.qc" in progs.src:
This is needed for the compiler to compile the new QC file.splat.qc
Step 3 -
Add the following to the bottom of W_Precache in weapons.qc:
This loads the model used for blood splats into memory when the level starts.precache_model ("progs/zom_gib.mdl");
Step 4 -
Now we need to make some of the weapons create blood splats when they damage enemies...
In weapons.qc, add the following after the line "if (trace_ent.takedamage)" in TraceAttack:
Also in weapons.qc, add the following after the line "if (other.takedamage)" in spike_touch AND superspike_touch:if(random() < 0.4) //only 2 in 5 times to prevent overflows ThrowBloodSplat(dir, trace_endpos, trace_ent); //throw blood splat in direction of shot
If added to both functions, this will affect the Nailgun and Super Nailgun.if (random() < 0.8) //only 4 in 5 times to prevent overflows { self.angles_x = self.angles_x*-1; //account for error in makevectors with non-player entities makevectors(self.angles); //find direction nail is facing ThrowBloodSplat(v_forward, self.origin, other); //throw blood splat in direction nail is facing }
Use this technique to add blood splats to any other weapon you wish to. The important thing to remember is that you need to have the angle of impact. This will usually be either the direction the shot was fired (for instant hit weapons) or the direction the projectile is facing for projectile weapons.
Step 5 -
Compile and run! The Super Shotgun is definitely an 'interesting' weapon with this modification!
Tags: tutorial, quakec, qc, insideqc, monster, ai