r5587 - in trunk/data/qcsrc: client common menu/nexuiz server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sat Jan 17 12:53:55 EST 2009


Author: div0
Date: 2009-01-17 12:53:48 -0500 (Sat, 17 Jan 2009)
New Revision: 5587

Added:
   trunk/data/qcsrc/client/damage.qc
   trunk/data/qcsrc/client/gibs.qc
Modified:
   trunk/data/qcsrc/client/Defs.qc
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/csqc_builtins.qc
   trunk/data/qcsrc/client/movetypes.qc
   trunk/data/qcsrc/client/movetypes.qh
   trunk/data/qcsrc/client/progs.src
   trunk/data/qcsrc/client/projectile.qc
   trunk/data/qcsrc/common/constants.qh
   trunk/data/qcsrc/common/util.qc
   trunk/data/qcsrc/common/util.qh
   trunk/data/qcsrc/menu/nexuiz/dialog_settings_audio.c
   trunk/data/qcsrc/server/cl_player.qc
   trunk/data/qcsrc/server/cl_weaponsystem.qc
   trunk/data/qcsrc/server/g_damage.qc
   trunk/data/qcsrc/server/g_violence.qc
   trunk/data/qcsrc/server/miscfunctions.qc
   trunk/data/qcsrc/server/w_hook.qc
Log:
moved gibbing from server to client

SavageX: please reimplement sv_gentle as client cvar in client/gibs.qc


Modified: trunk/data/qcsrc/client/Defs.qc
===================================================================
--- trunk/data/qcsrc/client/Defs.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/client/Defs.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -218,3 +218,6 @@
 float servertime, serverprevtime, serverdeltatime;
 
 float ticrate;
+
+.float damageforcescale;
+.void(float thisdmg, float hittype, vector org, vector thisforce) event_damage;

Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/client/Main.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -133,6 +133,7 @@
 	WaypointSprite_Load();
 
 	Projectile_Precache();
+	GibSplash_Precache();
 }
 
 // CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
@@ -517,6 +518,10 @@
 		Ent_RadarLink();
 	else if(self.enttype == ENT_CLIENT_PROJECTILE)
 		Ent_Projectile();
+	else if(self.enttype == ENT_CLIENT_GIBSPLASH)
+		Ent_GibSplash();
+	else if(self.enttype == ENT_CLIENT_DAMAGEINFO)
+		Ent_DamageInfo();
 	else
 		error(strcat("unknown entity type in CSQC_Ent_Update: ", ftos(self.enttype), "\n"));
 	

Modified: trunk/data/qcsrc/client/csqc_builtins.qc
===================================================================
--- trunk/data/qcsrc/client/csqc_builtins.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/client/csqc_builtins.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -275,3 +275,5 @@
 
 string(float ccase, float calpha, float cnum, string s, ...) strconv = #224;
 float(entity ent) wasfreed = #353;
+
+entity(vector org, float rad) findradius = #22;

Added: trunk/data/qcsrc/client/damage.qc
===================================================================
--- trunk/data/qcsrc/client/damage.qc	                        (rev 0)
+++ trunk/data/qcsrc/client/damage.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -0,0 +1,52 @@
+void Ent_DamageInfo()
+{
+	float hittype, dmg, rad, edge, thisdmg;
+	vector force, org, thisforce;
+	entity oldself;
+
+	oldself = self;
+
+	hittype = ReadShort();
+	org_x = ReadCoord();
+	org_y = ReadCoord();
+	org_z = ReadCoord();
+
+	dmg = ReadByte();
+	rad = ReadByte();
+	edge = ReadByte();
+	force = decompressShortVector(ReadShort());
+
+	for(self = findradius(org, rad); self; self = self.chain)
+	{
+		print("findradius found something\n");
+
+		if(rad)
+		{
+			thisdmg = vlen(self.origin - org) / rad;
+			print("thisdmg = ", ftos(thisdmg), "\n");
+			if(thisdmg >= 1)
+				continue;
+			thisdmg = dmg + (edge - dmg) * thisdmg;
+			thisforce = force_z * normalize(self.origin - org);
+		}
+		else
+		{
+			thisdmg = dmg;
+			thisforce = force;
+		}
+
+		if(self.damageforcescale)
+			if(vlen(thisforce))
+			{
+				self.move_velocity = self.move_velocity + self.damageforcescale * thisforce;
+				self.move_flags &~= FL_ONGROUND;
+			}
+
+		if(self.event_damage)
+			self.event_damage(thisdmg, hittype, org, thisforce);
+	}
+
+	self = oldself;
+
+	// TODO spawn particle effects and sounds based on hittype
+}

Added: trunk/data/qcsrc/client/gibs.qc
===================================================================
--- trunk/data/qcsrc/client/gibs.qc	                        (rev 0)
+++ trunk/data/qcsrc/client/gibs.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -0,0 +1,141 @@
+void Gib_Touch()
+{
+	// TODO maybe bounce of walls, make more gibs, etc.
+	
+	sound(self, CHAN_PAIN, strcat("misc/gib_splat0", ftos(floor(random() * 4 + 1)), ".wav"), VOL_BASE, ATTN_NORM);
+	pointparticles(particleeffectnum("blood"), self.origin + '0 0 1', '0 0 30', 10);
+
+	remove(self);
+}
+
+void Gib_Draw()
+{
+	vector oldorg;
+	oldorg = self.origin;
+
+	Movetype_Physics(FALSE);
+	
+	trailparticles(self, particleeffectnum("TR_BLOOD"), oldorg, self.origin);
+
+	self.renderflags = 0;
+	self.alpha = bound(0, self.nextthink - time, 1);
+
+	if(self.alpha == 0)
+		remove(self);
+	else
+		R_AddEntity(self);
+}
+
+void TossGib (string mdlname, vector org, vector v, float destroyontouch)
+{
+	entity gib;
+
+	// TODO remove some gibs according to cl_nogibs
+	
+	gib = spawn();
+	gib.classname = "gib";
+	gib.move_movetype = MOVETYPE_BOUNCE;
+	gib.gravity = 1;
+	gib.solid = SOLID_CORPSE;
+
+	setmodel (gib, mdlname); // precision set above
+
+	setsize (gib, '-8 -8 -8', '8 8 8');
+
+	gib.draw = Gib_Draw;
+	if(destroyontouch)
+		gib.move_touch = Gib_Touch;
+
+	gib.move_origin = org;
+	gib.move_velocity = v + randomvec();
+	gib.move_avelocity = randomvec() * vlen(gib.move_velocity);
+	gib.move_time = time;
+	gib.damageforcescale = 3.5;
+
+	gib.nextthink = time + 12 + random () * 4;
+}
+
+void Ent_GibSplash()
+{
+	float amount, type;
+	vector org, vel, mi, ma;
+
+	float c, gibfactor, randomvalue;
+
+	amount = ReadByte() / 16.0; // gibbage amount
+	type = ReadByte(); // gibbage type
+	org_x = ReadShort() * 4 + 2;
+	org_y = ReadShort() * 4 + 2;
+	org_z = ReadShort() * 4 + 2;
+	vel = decompressShortVector(ReadShort());
+	mi = decompressShortVector(ReadShort());
+	ma = decompressShortVector(ReadShort());
+
+	gibfactor = 1 - cvar("cl_nogibs");
+	if(gibfactor <= 0)
+		return;
+	
+	amount *= gibfactor;
+
+	if(cvar("ekg"))
+		amount *= 5;
+
+	if(type == 1) // full gibbage
+	{
+		sound (self, CHAN_PAIN, "misc/gib.wav", VOL_BASE, ATTN_NORM);
+
+		if(random() < amount)
+			TossGib("models/gibs/eye.md3", org, vel + randomvec() * 150, 0);
+		te_bloodshower(org + mi, org + ma, 1200, 1000 * amount);
+		if(random() < amount)
+			TossGib("models/gibs/bloodyskull.md3", org, vel, 0);
+
+		for(c = 0; c < amount; ++c)
+		{
+			randomvalue = amount - c;
+				
+			if(random() < randomvalue)
+				TossGib ("models/gibs/arm.md3", org, vel + randomvec() * (random() * 120 + 90),0);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/arm.md3", org, vel + randomvec() * (random() * 120 + 90),0);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/chest.md3", org + '0 0 -12', vel + randomvec() * (random() * 120 + 80),0);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/smallchest.md3", org, vel + randomvec() * (random() * 120 + 80),0);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/leg1.md3", org + '0 0 -5', vel + randomvec() * (random() * 120 + 85),0);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/leg2.md3", org + '0 0 -9', vel + randomvec() * (random() * 120 + 85),0);
+
+			// these splat on impact
+			if(random() < randomvalue)
+				TossGib ("models/gibs/chunk.mdl", org, vel + randomvec() * 450,1);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/chunk.mdl", org, vel + randomvec() * 450,1);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/chunk.mdl", org, vel + randomvec() * 450,1);
+			if(random() < randomvalue)
+				TossGib ("models/gibs/chunk.mdl", org, vel + randomvec() * 450,1);
+		}
+	}
+	else if(type == 2) // just blood
+	{
+		pointparticles(particleeffectnum("blood"), org, vel, amount);
+	}
+	else if(type == 3) // single gib
+	{
+		TossGib ("models/gibs/chunk.mdl", org, vel, 1);
+	}
+}
+
+void GibSplash_Precache()
+{
+	precache_model("models/gibs/chunk.mdl");
+	precache_model("models/gibs/leg1.mdl");
+	precache_model("models/gibs/leg2.mdl");
+	precache_model("models/gibs/chest.mdl");
+	precache_model("models/gibs/smallchest.mdl");
+	precache_model("models/gibs/arm.mdl");
+	precache_model("models/gibs/bloodyskull.mdl");
+	precache_model("models/gibs/eye.mdl");
+}

Modified: trunk/data/qcsrc/client/movetypes.qc
===================================================================
--- trunk/data/qcsrc/client/movetypes.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/client/movetypes.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -17,16 +17,106 @@
 
 void _Movetype_Impact(entity oth) // SV_Impact
 {
-	if(self.move_moveflags & MOVEFLAG_STOPONIMPACT)
+	entity oldother, oldself;
+
+	oldself = self;
+	oldother = other;
+
+	if(self.move_touch)
 	{
-		// don't CLIP the velocity, but stop ENTIRELY
-		self.velocity = '0 0 0';
-		self.avelocity = '0 0 0';
+		other = oth;
+
+		self.move_touch();
+
+		other = oldother;
 	}
+
+	if(oth.move_touch)
+	{
+		other = self;
+		self = oth;
+
+		self.move_touch();
+
+		self = oldself;
+		other = oldother;
+	}
 }
 
+void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid
+{
+	entity e, oldself, oldother;
+
+	oldself = self;
+	oldother = other;
+
+	for(e = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); e; e = e.chain)
+	{
+		if(e.move_touch)
+		if(boxesoverlap(e.absmin, e.absmax, oldself.absmin, oldself.absmax))
+		{
+			self = e;
+			other = oldself;
+
+			trace_allsolid = FALSE;
+			trace_startsolid = FALSE;
+			trace_fraction = 1;
+			trace_inwater = FALSE;
+			trace_inopen = TRUE;
+			trace_endpos = e.origin;
+			trace_plane_normal = '0 0 1';
+			trace_plane_dist = 0;
+			trace_ent = oldself;
+
+			e.move_touch();
+		}
+	}
+
+	other = oldother;
+	self = oldself;
+}
+
 void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
 {
+	vector mi, ma;
+	if(self.solid == SOLID_BSP)
+	{
+		// TODO set the absolute bbox
+		mi = self.mins;
+		ma = self.maxs;
+	}
+	else
+	{
+		mi = self.mins;
+		ma = self.maxs;
+	}
+	mi = mi + self.origin;
+	ma = ma + self.origin;
+
+	if(self.move_flags & FL_ITEM)
+	{
+		mi_x -= 15;
+		mi_y -= 15;
+		mi_z -= 1;
+		ma_x += 15;
+		ma_y += 15;
+		ma_z += 1;
+	}
+	else
+	{
+		mi_x -= 1;
+		mi_y -= 1;
+		mi_z -= 1;
+		ma_x += 1;
+		ma_y += 1;
+		ma_z += 1;
+	}
+
+	self.absmin = mi;
+	self.absmax = ma;
+
+	if(touch_triggers)
+		_Movetype_LinkEdict_TouchAreaGrid();
 }
 
 float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
@@ -111,8 +201,9 @@
 
 	self.move_origin = trace_endpos;
 
-	if(self.solid >= SOLID_TRIGGER && trace_ent && (!(self.move_flags & FL_ONGROUND) || (self.move_groundentity != trace_ent)))
-		_Movetype_Impact(trace_ent);
+	if(trace_fraction < 1)
+		if(self.solid >= SOLID_TRIGGER && (!(self.move_flags & FL_ONGROUND) || (self.move_groundentity != trace_ent)))
+			_Movetype_Impact(trace_ent);
 
 	return trace_fraction;
 }
@@ -139,7 +230,10 @@
 	if(self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS)
 	{
 		self.move_didgravity = TRUE;
-		self.move_velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+		if(self.gravity)
+			self.move_velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+		else
+			self.move_velocity_z -= dt * getstatf(STAT_MOVEVARS_GRAVITY);
 	}
 
 	self.move_angles = self.move_angles + self.move_avelocity * dt;
@@ -168,11 +262,15 @@
 		}
 		else if(self.move_movetype == MOVETYPE_BOUNCE)
 		{
-			self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.5);
+			float d, bouncefac, bouncestop;
 
-			float d;
+			bouncefac = self.move_bounce_factor;     if(!bouncefac)  bouncefac = 0.5;
+			bouncestop = self.move_bounce_stopspeed; if(!bouncestop) bouncestop = 60;
+
+			self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1 + bouncefac);
+
 			d = trace_plane_normal * self.move_velocity;
-			if(trace_plane_normal_z > 0.7 && d < 60 && d > -60)
+			if(trace_plane_normal_z > 0.7 && d < bouncestop && d > -bouncestop)
 			{
 				self.move_flags |= FL_ONGROUND;
 				self.move_groundentity = trace_ent;
@@ -269,7 +367,12 @@
 		// now continue the move from move_time to time
 		self.velocity = self.move_velocity;
 		if(self.move_didgravity)
-			self.velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+		{
+			if(self.gravity)
+				self.velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+			else
+				self.velocity_z -= dt * getstatf(STAT_MOVEVARS_GRAVITY);
+		}
 
 		self.angles = self.move_angles + dt * self.avelocity;
 
@@ -288,4 +391,7 @@
 		self.angles = self.move_angles;
 		self.origin = self.move_origin;
 	}
+
+	if(!wasfreed(self))
+		setorigin(self, self.origin);
 }

Modified: trunk/data/qcsrc/client/movetypes.qh
===================================================================
--- trunk/data/qcsrc/client/movetypes.qh	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/client/movetypes.qh	2009-01-17 17:53:48 UTC (rev 5587)
@@ -1,11 +1,13 @@
-.float move_flags;
 .float move_movetype;
 .float move_time;
 .vector move_origin;
 .vector move_angles;
 .vector move_velocity;
 .vector move_avelocity;
-.float move_moveflags;
+.float move_flags;
+.void(void) move_touch;
+.float move_bounce_factor;
+.float move_bounce_stopspeed;
 
 void Movetype_Physics(float matchserver);
 
@@ -24,6 +26,5 @@
 float MOVETYPE_FOLLOW = 12;
 float MOVETYPE_FAKEPUSH = 13;
 
+float   FL_ITEM                 = 256;
 float	FL_ONGROUND				= 512;
-
-float MOVEFLAG_STOPONIMPACT = 1;

Modified: trunk/data/qcsrc/client/progs.src
===================================================================
--- trunk/data/qcsrc/client/progs.src	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/client/progs.src	2009-01-17 17:53:48 UTC (rev 5587)
@@ -30,6 +30,8 @@
 particles.qc
 laser.qc
 projectile.qc
+gibs.qc
+damage.qc
 
 Main.qc
 View.qc

Modified: trunk/data/qcsrc/client/projectile.qc
===================================================================
--- trunk/data/qcsrc/client/projectile.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/client/projectile.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -1,3 +1,13 @@
+void SUB_Null()
+{
+}
+
+void SUB_Stop()
+{
+	self.move_velocity = self.move_avelocity = '0 0 0';
+	self.move_movetype = MOVETYPE_NONE;
+}
+
 .float count; // set if clientside projectile
 .float cnt; // sound index
 .float gravity;
@@ -82,7 +92,7 @@
 void Ent_RemoveProjectile()
 {
 	if(self.cnt)
-		loopsound(self, CHAN_PAIN, "misc/null.wav", VOL_BASE, ATTN_NORM);
+		loopsound(self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM);
 }
 
 void Ent_Projectile()
@@ -170,26 +180,26 @@
 		self.mins = '0 0 0';
 		self.maxs = '0 0 0';
 		self.colormod = '0 0 0';
+		self.move_touch = SUB_Stop;
 		self.move_movetype = MOVETYPE_TOSS;
-		self.move_moveflags = MOVEFLAG_STOPONIMPACT;
 
 		switch(self.cnt)
 		{
 			case PROJECTILE_ELECTRO:
 				// only new engines support sound moving with object
-				loopsound(self, CHAN_PAIN, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
+				loopsound(self, CHAN_PROJECTILE, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
 				self.mins = '0 0 -3';
 				self.maxs = '0 0 -3';
 				self.move_movetype = MOVETYPE_BOUNCE;
-				self.move_moveflags = 0;
+				self.move_touch = SUB_Null;
 				break;
 			case PROJECTILE_ROCKET:
-				loopsound(self, CHAN_PAIN, "weapons/rocket_fly.wav", VOL_BASE, ATTN_NORM);
+				loopsound(self, CHAN_PROJECTILE, "weapons/rocket_fly.wav", VOL_BASE, ATTN_NORM);
 				self.mins = '-3 -3 -3';
 				self.maxs = '3 3 3';
 				break;
 			case PROJECTILE_TAG:
-				loopsound(self, CHAN_PAIN, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
+				loopsound(self, CHAN_PROJECTILE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
 				self.mins = '-2 -2 -2';
 				self.maxs = '2 2 2';
 				break;
@@ -197,7 +207,7 @@
 				self.mins = '0 0 -3';
 				self.maxs = '0 0 -3';
 				self.move_movetype = MOVETYPE_BOUNCE;
-				self.move_moveflags = 0;
+				self.move_touch = SUB_Null;
 				break;
 			case PROJECTILE_SEEKER:
 				self.mins = '-2 -2 -2';
@@ -211,13 +221,28 @@
 				break;
 			case PROJECTILE_HAGAR_BOUNCING:
 				self.move_movetype = MOVETYPE_BOUNCE;
-				self.move_moveflags = 0;
+				self.move_touch = SUB_Null;
 				break;
 			default:
 				break;
 		}
 	}
 
+	if(self.gravity)
+	{
+		if(self.move_movetype == MOVETYPE_FLY)
+			self.movetype = MOVETYPE_TOSS;
+		if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
+			self.movetype = MOVETYPE_BOUNCE;
+	}
+	else
+	{
+		if(self.move_movetype == MOVETYPE_TOSS)
+			self.movetype = MOVETYPE_FLY;
+		if(self.move_movetype == MOVETYPE_BOUNCE)
+			self.movetype = MOVETYPE_BOUNCEMISSILE;
+	}
+
 	if(!(self.count & 0x80))
 		InterpolateOrigin_Note();
 	

Modified: trunk/data/qcsrc/common/constants.qh
===================================================================
--- trunk/data/qcsrc/common/constants.qh	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/common/constants.qh	2009-01-17 17:53:48 UTC (rev 5587)
@@ -55,6 +55,8 @@
 const float ENT_CLIENT_WAYPOINT = 10; // flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable]
 const float ENT_CLIENT_RADARLINK = 11; // flags [startorigin] [endorigin] [startcolor+16*endcolor]
 const float ENT_CLIENT_PROJECTILE = 12;
+const float ENT_CLIENT_GIBSPLASH = 13;
+const float ENT_CLIENT_DAMAGEINFO = 14;
 
 const float SPRITERULE_DEFAULT = 0;
 const float SPRITERULE_TEAMPLAY = 1;
@@ -326,7 +328,7 @@
 	// on world: UNUSED
 	// on players: projectiles hitting player        SHOTS
 	// on entities: projectiles                      SHOTS
-	// on csqc: UNUSED
+	// on csqc: projectile sounds                    SHOTS
 float	CHAN_WEAPON2			= 5; // Nex fire (separated as it is a very long sound)
 	// on world: UNUSED
 	// on players: weapon firing                     WEAPONS
@@ -336,7 +338,7 @@
 	// on world: UNUSED
 	// on players: pain                              PAIN
 	// on entities: projectiles flying               SHOTS
-	// on csqc: projectiles flying                   SHOTS
+	// on csqc: player pain                          PAIN
 float	CHAN_PLAYER				= 7; // Player body
 	// on world: UNUSED
 	// on players: player sounds                     PLAYER

Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/common/util.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -1301,3 +1301,9 @@
 			DEC_TO_HEXDIGIT(floor(rgb_z * 15 + 0.5))
 		);
 }
+
+// requires that m2>m1 in all coordinates, and that m4>m3
+float boxesoverlap(vector m1, vector m2, vector m3, vector m4) {return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z;};
+
+// requires the same, but is a stronger condition
+float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins_x >= bmins_x && smaxs_x <= bmaxs_x && smins_y >= bmins_y && smaxs_y <= bmaxs_y && smins_z >= bmins_z && smaxs_z <= bmaxs_z;};

Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/common/util.qh	2009-01-17 17:53:48 UTC (rev 5587)
@@ -132,3 +132,6 @@
 vector rgb_to_hsv(vector rgb);
 vector hsv_to_rgb(vector hsv);
 string rgb_to_hexcolor(vector rgb);
+
+float boxesoverlap(vector m1, vector m2, vector m3, vector m4);
+float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs);

Modified: trunk/data/qcsrc/menu/nexuiz/dialog_settings_audio.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/dialog_settings_audio.c	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/menu/nexuiz/dialog_settings_audio.c	2009-01-17 17:53:48 UTC (rev 5587)
@@ -56,7 +56,7 @@
 		setDependentStringNotEqual(s, "volume", "0");
 	me.TR(me);
 		me.TDempty(me, 0.2);
-		s = makeNexuizDecibelsSlider(-20, 0, 0.5, "snd_playerchannel6volume");
+		s = makeNexuizDecibelsSlider(-20, 0, 0.5, "snd_playerchannel6volume snd_csqcchannel6volume");
 		me.TD(me, 1, 0.8, e = makeNexuizSliderCheckBox(-1000000, 1, s, "Pain:"));
 		me.TD(me, 1, 2, s);
 		setDependentStringNotEqual(e, "volume", "0");
@@ -72,7 +72,7 @@
 	me.TR(me);
 		me.TDempty(me, 0.2);
 		s = makeNexuizDecibelsSlider(-20, 0, 0.5, "snd_entchannel4volume");
-		makeMulti(s, "snd_playerchannel4volume snd_entchannel6volume snd_csqcchannel6volume");
+		makeMulti(s, "snd_playerchannel4volume snd_entchannel6volume snd_csqcchannel4volume");
 		me.TD(me, 1, 0.8, e = makeNexuizSliderCheckBox(-1000000, 1, s, "Shots:"));
 		me.TD(me, 1, 2, s);
 		setDependentStringNotEqual(e, "volume", "0");

Modified: trunk/data/qcsrc/server/cl_player.qc
===================================================================
--- trunk/data/qcsrc/server/cl_player.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/server/cl_player.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -51,7 +51,6 @@
 	self.solid = oldself.solid;
 	self.takedamage = oldself.takedamage;
 	self.think = oldself.think;
-	self.gibrandom = oldself.gibrandom;
 	self.customizeentityforclient = oldself.customizeentityforclient;
 	if (keepvelocity == 1)
 		self.velocity = oldself.velocity;
@@ -258,8 +257,8 @@
 void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
 	local float take, save;
-	if(sv_gentle < 1)	
-		pointparticles(particleeffectnum("blood"), hitloc, force, bound(0, damage, 200));
+	Violence_GibSplash_At(hitloc, '0 0 0', '0 0 0', force, 2, bound(0, damage, 200) / 16);
+
 	// damage resistance (ignore most of the damage from a bullet or similar)
 	damage = max(damage - 5, 1);
 
@@ -273,13 +272,10 @@
 	else if (take > 10)
 		sound (self, CHAN_PROJECTILE, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM);
 
-	if(independent_players)
-	if(sv_gentle < 1) {	
-		if (take > 50)
-			TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.1,1);
-		if (take > 100)
-			TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.2,1);
-	}
+	if (take > 50)
+		Violence_GibSplash_At(hitloc, '0 0 0', '0 0 0', force * -0.1, 3, 1);
+	if (take > 100)
+		Violence_GibSplash_At(hitloc, '0 0 0', '0 0 0', force * -0.2, 3, 1);
 
 	if (!(self.flags & FL_GODMODE))
 	{
@@ -292,7 +288,7 @@
 	self.dmg_take = self.dmg_take + take;//max(take - 10, 0);
 	self.dmg_inflictor = inflictor;
 
-	if (self.health <= -75)
+	if (self.health <= -75 && self.modelindex != 0)
 	{
 		// don't use any animations as a gib
 		self.frame = 0;
@@ -300,61 +296,9 @@
 		// view just above the floor
 		self.view_ofs = '0 0 4';
 
-		// make a juicy mess
-		local float multiplier;
-		multiplier = 1;
-		if (cvar("ekg"))
-			multiplier = 5;
-
-
-		// make a meaty mess
-		if(independent_players)
-		{
-			TossGib (self, "models/gibs/eye.md3", self.origin + self.view_ofs, self.velocity + randomvec() * 150,0);
-			self.solid = SOLID_TRIGGER; // undo SOLID_CORPSE
-			self.takedamage = DAMAGE_NO; // can't damage this gib, to prevent better jumps from it
-		}
-		else
-			TossGib (self, "models/gibs/eye.md3", self.origin + self.view_ofs, self.velocity + randomvec() * 150,0);
-		
-		if not(independent_players)
-		if(sv_gentle < 1) {
-			te_bloodshower (self.origin + self.mins, self.origin + self.maxs, 1200 * multiplier, 1000);
-			TossGib (world, "models/gibs/bloodyskull.md3", self.origin + self.view_ofs, self.velocity,0);
-
-			local float c;
-			c = 0;
-
-			while (c < multiplier)
-			{
-				c = c + 1;
-				//TossGib (world, "models/gibs/gib1.md3", self.origin, self.velocity + randomvec() * 450,0);
-				//TossGib (world, "models/gibs/gib2.md3", self.origin, self.velocity + randomvec() * 450,0);
-				//TossGib (world, "models/gibs/gib3.md3", self.origin, self.velocity + randomvec() * 450,0);
-				//TossGib (world, "models/gibs/gib4.md3", self.origin, self.velocity + randomvec() * 450,0);
-				//TossGib (world, "models/gibs/gib5.md3", self.origin, self.velocity + randomvec() * 450,0);
-				//TossGib (world, "models/gibs/gib6.md3", self.origin, self.velocity + randomvec() * 450,0);
-
-				TossGib (world, "models/gibs/arm.md3", self.origin + self.view_ofs, self.velocity + randomvec() * (random() * 120 + 90),0);
-				TossGib (world, "models/gibs/arm.md3", self.origin + self.view_ofs, self.velocity + randomvec() * (random() * 120 + 90),0);
-				//TossGib (world, "models/gibs/arm.md3", self.origin + self.view_ofs, self.velocity + randomvec() * 150,0);
-				//TossGib (world, "models/gibs/arm.md3", self.origin + self.view_ofs, self.velocity + randomvec() * 150,0);
-				TossGib (world, "models/gibs/chest.md3", self.origin + self.view_ofs * 0.5, self.velocity + randomvec() * (random() * 120 + 80),0);
-				//TossGib (world, "models/gibs/smallchest.md3", self.origin + self.view_ofs, self.velocity + randomvec() * 150,0);
-				TossGib (world, "models/gibs/smallchest.md3", self.origin + self.view_ofs, self.velocity + randomvec() * (random() * 120 + 80),0);
-				TossGib (world, "models/gibs/leg1.md3", self.origin + self.view_ofs * -0.2, self.velocity + randomvec() * (random() * 120 + 85),0);
-				TossGib (world, "models/gibs/leg2.md3", self.origin + self.view_ofs * -0.4, self.velocity + randomvec() * (random() * 120 + 85),0);
-				//TossGib (world, "models/gibs/leg1.md3", self.origin + self.view_ofs * -0.2, self.velocity + randomvec() * 150,0);
-				//TossGib (world, "models/gibs/leg2.md3", self.origin + self.view_ofs * -0.4, self.velocity + randomvec() * 150,0);
-
-				// these splat on impact
-				TossGib (world, "models/gibs/chunk.mdl", self.origin, self.velocity + randomvec() * 450,1);
-				TossGib (world, "models/gibs/chunk.mdl", self.origin, self.velocity + randomvec() * 450,1);
-				TossGib (world, "models/gibs/chunk.mdl", self.origin, self.velocity + randomvec() * 450,1);
-				TossGib (world, "models/gibs/chunk.mdl", self.origin, self.velocity + randomvec() * 450,1);
-			}
-			sound (self, CHAN_PLAYER, "misc/gib.wav", VOL_BASE, ATTN_NORM);
-		}
+		Violence_GibSplash(self, 1, 1);
+		self.modelindex = 0; // restore later
+		self.solid = SOLID_NOT; // restore later
 	}
 }
 
@@ -371,11 +315,7 @@
 			damage /= sqrt(bound(1.0, attacker.cvar_cl_handicap, 100.0));
 	}
 
-	if(sv_gentle > 0) {
-		pointparticles(particleeffectnum("damage_hit"), hitloc, force, bound(0, damage, 200));
-	} else {
-		pointparticles(particleeffectnum("blood"), hitloc, force, bound(0, damage, 200));
-	}
+	Violence_GibSplash_At(hitloc, '0 0 0', '0 0 0', force, 2, bound(0, damage, 200) / 16);
 
 	if(g_arena)
 	if(numspawned < 2)
@@ -399,14 +339,10 @@
 	else if (take > 10)
 		sound (self, CHAN_PROJECTILE, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM); // FIXME possibly remove them?
 
-	if(sv_gentle < 1)
-	if not(independent_players)
-	{
-		if (take > 50)
-			TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.1,1);
-		if (take > 100)
-			TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.2,1);
-	}
+	if (take > 50)
+		Violence_GibSplash_At(hitloc, '0 0 0', '0 0 0', force * -0.1, 3, 1);
+	if (take > 100)
+		Violence_GibSplash_At(hitloc, '0 0 0', '0 0 0', force * -0.2, 3, 1);
 
 	if (time > self.spawnshieldtime)
 	{

Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -351,6 +351,7 @@
 void CL_SpawnWeaponentity()
 {
 	self.weaponentity = spawn();
+	self.weaponentity.classname = "weaponentity";
 	self.weaponentity.solid = SOLID_NOT;
 	self.weaponentity.owner = self;
 	self.weaponentity.weaponentity = self.weaponentity;
@@ -365,6 +366,7 @@
 	self.weaponentity.scale = 0.61;
 
 	self.exteriorweaponentity = spawn();
+	self.exteriorweaponentity.classname = "exteriorweaponentity";
 	self.exteriorweaponentity.solid = SOLID_NOT;
 	self.exteriorweaponentity.exteriorweaponentity = self.exteriorweaponentity;
 	self.exteriorweaponentity.owner = self;

Modified: trunk/data/qcsrc/server/g_damage.qc
===================================================================
--- trunk/data/qcsrc/server/g_damage.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/server/g_damage.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -1,3 +1,47 @@
+.float dmg;
+.float dmg_edge;
+.float dmg_force;
+.float dmg_radius;
+
+float Damage_DamageInfo_SendEntity(entity to, float sf)
+{
+	WriteByte(MSG_ENTITY, ENT_CLIENT_DAMAGEINFO);
+	WriteShort(MSG_ENTITY, self.projectiledeathtype);
+	WriteCoord(MSG_ENTITY, floor(self.origin_x));
+	WriteCoord(MSG_ENTITY, floor(self.origin_y));
+	WriteCoord(MSG_ENTITY, floor(self.origin_z));
+	WriteByte(MSG_ENTITY, bound(1, self.dmg, 255));
+	WriteByte(MSG_ENTITY, bound(0, self.dmg_radius, 255));
+	WriteByte(MSG_ENTITY, bound(1, self.dmg_edge, 255));
+	WriteShort(MSG_ENTITY, self.oldorigin_x);
+	return TRUE;
+}
+
+void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype)
+{
+	// TODO maybe call this from non-edgedamage too?
+	// TODO maybe make the client do the particle effects for the weapons and the impact sounds using this info?
+
+	entity e;
+
+	e = spawn();
+	e.classname = "damageinfo";
+	setorigin(e, org);
+	setmodel(e, "null");
+	e.think = SUB_Remove;
+	e.nextthink = time + 0.2;
+	e.projectiledeathtype = deathtype;
+	e.dmg = coredamage;
+	e.dmg_edge = edgedamage;
+	e.dmg_radius = rad;
+	e.dmg_force = vlen(force);
+	e.velocity = force;
+
+	e.oldorigin_x = compressShortVector(e.velocity);
+
+	e.SendEntity = Damage_DamageInfo_SendEntity;
+}
+
 #define DAMAGE_CENTERPRINT_SPACER NEWLINES
 
 float checkrules_firstblood;
@@ -898,11 +942,15 @@
 		return 0;
 	}
 
+
 	RadiusDamage_running = 1;
 
 	blastorigin = (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5);
 	total_damage_to_creatures = 0;
 
+	if(deathtype == WEP_HOOK | HITTYPE_SECONDARY | HITTYPE_BOUNCE) // only send gravity bomb damage once
+		Damage_DamageInfo(blastorigin, coredamage, edgedamage, rad, forceintensity * '0 0 1', deathtype);
+
 	targ = findradius (blastorigin, rad);
 	while (targ)
 	{

Modified: trunk/data/qcsrc/server/g_violence.qc
===================================================================
--- trunk/data/qcsrc/server/g_violence.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/server/g_violence.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -1,98 +1,42 @@
-void GibDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+float Violence_GibSplash_SendEntity(entity to, float sf)
 {
-	float r;
-	r = random ();
-	if (r < 0.60)
-		sound (self, CHAN_PROJECTILE, "misc/gib_splat01.wav", VOL_BASE, ATTN_NORM);
-	else if (r < 0.65)
-		sound (self, CHAN_PROJECTILE, "misc/gib_splat02.wav", VOL_BASE, ATTN_NORM);
-	else if (r < 0.70)
-		sound (self, CHAN_PROJECTILE, "misc/gib_splat03.wav", VOL_BASE, ATTN_NORM);
-	else if (r < 0.75)
-		sound (self, CHAN_PROJECTILE, "misc/gib_splat04.wav", VOL_BASE, ATTN_NORM);
-	
-	if(sv_gentle < 1)
-		pointparticles(particleeffectnum("blood"), self.origin + '0 0 1', '0 0 30', 10);
-	self.health = self.health - damage;
-	if (self.health <= -1000)
-	{
-		self.event_damage = SUB_Null;
-		SUB_VanishOrRemove (self);
-	}
+	WriteByte(MSG_ENTITY, ENT_CLIENT_GIBSPLASH);
+	WriteByte(MSG_ENTITY, bound(1, self.cnt * 16, 255)); // gibbage amount multiplier
+	WriteByte(MSG_ENTITY, self.state); // actually type
+	WriteShort(MSG_ENTITY, floor(self.origin_x / 4)); // not using a coord here, as gibs don't need this accuracy
+	WriteShort(MSG_ENTITY, floor(self.origin_y / 4)); // not using a coord here, as gibs don't need this accuracy
+	WriteShort(MSG_ENTITY, floor(self.origin_z / 4)); // not using a coord here, as gibs don't need this accuracy
+	WriteShort(MSG_ENTITY, self.oldorigin_x); // acrually compressed velocity
+	WriteShort(MSG_ENTITY, self.oldorigin_y); // acrually compressed mins
+	WriteShort(MSG_ENTITY, self.oldorigin_z); // acrually compressed maxs
+	return TRUE;
 }
 
-
-void GibTouch ()
+// TODO maybe convert this to a TE?
+void Violence_GibSplash_At(vector org, vector mi, vector ma, vector dir, float type, float amount)
 {
-	if(SUB_NoImpactCheck())
-	{
-		SUB_VanishOrRemove(self);
-		return;
-	}
-	GibDamage (other, other, 1000, 0, self.origin, '0 0 0');
-}
+	entity e;
 
+	e = spawn();
+	e.classname = "gibsplash";
+	e.cnt = amount;
+	e.state = type;
+	e.SendEntity = Violence_GibSplash_SendEntity;
+	e.nextthink = time + 0.2;
+	e.think = SUB_Remove;
+		// 0.2s should be enough time for all clients to receive this ent once, do the gibbage and be done with it
+	setmodel(e, "null");
+	e.effects = EF_NODEPTHTEST; // show gibs from around the corner
+	setorigin(e, org);
+	setsize(e, mi, ma);
+	e.velocity = dir;
 
-.float gibrandom;
-.float gibmodelindex;
-float Gib_customizeentityforclient()
-{
-	if(self.classname == "player") // the eye
-	{
-		if(sv_gentle > 0) {
-			self.model = "";
-			return TRUE;
-		}
-		if(self.gibrandom > other.cvar_cl_nogibs)
-			self.model = self.mdl;
-		else
-			self.model = "";
-		return TRUE;
-	}
-	else // other gibs - don't even need to send them
-		return (self.gibrandom > other.cvar_cl_nogibs);
-};
+	e.oldorigin_x = compressShortVector(e.velocity);
+	e.oldorigin_y = compressShortVector(e.mins);
+	e.oldorigin_z = compressShortVector(e.maxs);
+}
 
-// changes by LordHavoc on 03/30/04
-// TossGib now takes a gib entity so it can be used for tossing heads
-// gib.velocity now uses randomvec() instead of a bunch of manual random calls
-// merged Gib() into PlayerGib()
-void TossGib (entity gib, string mdlname, vector org, vector v, float destroyontouch)
+void Violence_GibSplash(entity source, float type, float amount)
 {
-	if (gib == world)
-	{
-		gib = spawn ();
-		gib.deadflag = DEAD_DEAD;
-	}
-
-	// don't set his classname to something else or it'll screw up a lot of stuff
-	if(gib.classname != "player")
-		gib.classname = "gib";
-	gib.iscreature = FALSE; // not a creature, because lava sounds on gibs are annoying
-	gib.movetype = MOVETYPE_BOUNCE;
-	gib.solid = SOLID_CORPSE;
-	gib.skin = 0;
-	gib.effects = 0;
-	gib.gibrandom = random(); // used for customize function to reduce gibs
-	gib.customizeentityforclient = Gib_customizeentityforclient;
-	gib.effects = EF_LOWPRECISION; // use less bandwidth
-
-	gib.mdl = mdlname;
-	setmodel (gib, mdlname); // precision set above
-	gib.gibmodelindex = gib.modelindex;
-	setsize (gib, '-8 -8 -8', '8 8 8');
-	setorigin (gib, org);
-
-	gib.health = -1;
-	gib.takedamage = DAMAGE_YES;
-	gib.damageforcescale = 3.5;
-	gib.event_damage = GibDamage;
-	if (destroyontouch == 1)
-		gib.touch = GibTouch;
-
-	gib.velocity = v + randomvec();
-	gib.avelocity = randomvec() * vlen(gib.velocity);
-	gib.oldvelocity = gib.velocity;
-
-	SUB_SetFade (gib, time + 12 + random () * 4, 1);
+	Violence_GibSplash_At(source.origin + source.view_ofs, source.mins - source.view_ofs, source.maxs - source.view_ofs, source.velocity, type, amount);
 }

Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/server/miscfunctions.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -689,12 +689,6 @@
 	return  v;
 };
 
-// requires that m2>m1 in all coordinates, and that m4>m3
-float boxesoverlap(vector m1, vector m2, vector m3, vector m4) {return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z;};
-
-// requires the same, but is a stronger condition
-float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins_x >= bmins_x && smaxs_x <= bmaxs_x && smins_y >= bmins_y && smaxs_y <= bmaxs_y && smins_z >= bmins_z && smaxs_z <= bmaxs_z;};
-
 float g_pickup_shells;
 float g_pickup_shells_max;
 float g_pickup_nails;

Modified: trunk/data/qcsrc/server/w_hook.qc
===================================================================
--- trunk/data/qcsrc/server/w_hook.qc	2009-01-17 10:53:45 UTC (rev 5586)
+++ trunk/data/qcsrc/server/w_hook.qc	2009-01-17 17:53:48 UTC (rev 5587)
@@ -20,6 +20,7 @@
 	self.dmg_last = dmg_remaining_next;
 
 	RadiusDamage (self, self.owner, self.dmg * f, self.dmg_edge * f, self.dmg_radius, self.owner, self.dmg_force * f, self.projectiledeathtype, world);
+	self.projectiledeathtype |= HITTYPE_BOUNCE;
 	//RadiusDamage (self, world, self.dmg * f, self.dmg_edge * f, self.dmg_radius, world, self.dmg_force * f, self.projectiledeathtype, world);
 
 	if(dt < self.dmg_duration)




More information about the nexuiz-commits mailing list