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