Shuffled a lot of Decal code around so gibs can now spawn blood, etc.
This commit is contained in:
parent
479048bda8
commit
ec819cf4e4
7 changed files with 132 additions and 60 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
#includelist
|
||||
baseentity.h
|
||||
decals.h
|
||||
materials.h
|
||||
client/baseentity.cpp
|
||||
client/env_cubemap.cpp
|
||||
|
|
55
src/gs-entbase/decals.h
Normal file
55
src/gs-entbase/decals.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
typedef struct {
|
||||
float fraction;
|
||||
vector normal;
|
||||
vector endpos;
|
||||
} traced_t;
|
||||
|
||||
traced_t g_tracedDecal;
|
||||
|
||||
void
|
||||
decal_pickwall(entity dself, vector vpos)
|
||||
{
|
||||
traced_t tmp[6];
|
||||
float frac = 1.0f;
|
||||
|
||||
g_tracedDecal.fraction = 1.0f;
|
||||
g_tracedDecal.endpos = [0,0,0];
|
||||
g_tracedDecal.normal = [0,0,0];
|
||||
|
||||
/* unrolled, trace against walls in all 6 directions */
|
||||
makevectors([0, 0, 0]);
|
||||
traceline(vpos + (v_forward * -1), vpos + (v_forward * 128), 1, dself);
|
||||
tmp[0].fraction = trace_fraction;
|
||||
tmp[0].normal = trace_plane_normal;
|
||||
tmp[0].endpos = trace_endpos;
|
||||
traceline(vpos + (v_forward * 1), vpos + (v_forward * -128), 1, dself);
|
||||
tmp[1].fraction = trace_fraction;
|
||||
tmp[1].normal = trace_plane_normal;
|
||||
tmp[1].endpos = trace_endpos;
|
||||
traceline(vpos + (v_right * -1), vpos + (v_right * 128), 1, dself);
|
||||
tmp[2].fraction = trace_fraction;
|
||||
tmp[2].normal = trace_plane_normal;
|
||||
tmp[2].endpos = trace_endpos;
|
||||
traceline(vpos + (v_right * 1), vpos + (v_right * -128), 1, dself);
|
||||
tmp[3].fraction = trace_fraction;
|
||||
tmp[3].normal = trace_plane_normal;
|
||||
tmp[3].endpos = trace_endpos;
|
||||
traceline(vpos + (v_up * -1), vpos + (v_up * 128), 1, dself);
|
||||
tmp[4].fraction = trace_fraction;
|
||||
tmp[4].normal = trace_plane_normal;
|
||||
tmp[4].endpos = trace_endpos;
|
||||
traceline(vpos + (v_up * 1), vpos + (v_up * -128), 1, dself);
|
||||
tmp[5].fraction = trace_fraction;
|
||||
tmp[5].normal = trace_plane_normal;
|
||||
tmp[5].endpos = trace_endpos;
|
||||
|
||||
/* pick whatever wall is closest */
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ( tmp[i].fraction < frac ) {
|
||||
frac = tmp[i].fraction;
|
||||
g_tracedDecal.fraction = tmp[i].fraction;
|
||||
g_tracedDecal.endpos = tmp[i].endpos;
|
||||
g_tracedDecal.normal = tmp[i].normal;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#includelist
|
||||
baseentity.h
|
||||
decals.h
|
||||
materials.h
|
||||
server/defs.h
|
||||
server/baseentity.cpp
|
||||
|
|
|
@ -28,12 +28,6 @@ The texture will be aligned along the surface texture normals.
|
|||
* but not angles. So we have to figure them out ourselves. */
|
||||
.string texture;
|
||||
|
||||
typedef struct {
|
||||
float fraction;
|
||||
vector normal;
|
||||
vector endpos;
|
||||
} traced_t;
|
||||
|
||||
float infodecal_send(entity pvsent, float cflags)
|
||||
{
|
||||
WriteByte(MSG_ENTITY, ENT_DECAL);
|
||||
|
@ -49,13 +43,6 @@ float infodecal_send(entity pvsent, float cflags)
|
|||
|
||||
void infodecal(void)
|
||||
{
|
||||
traced_t tmp[6];
|
||||
int i = 0;
|
||||
int b = 0;
|
||||
float frac = 1.0f;
|
||||
vector endpos = [0,0,0];
|
||||
vector vpos = self.origin;
|
||||
|
||||
#ifdef WASTES
|
||||
remove(self);
|
||||
return;
|
||||
|
@ -84,47 +71,9 @@ void infodecal(void)
|
|||
|
||||
/* Some maps have everything set to full-on uppercase */
|
||||
self.texture = strtolower(self.texture);
|
||||
|
||||
/*self.origin[0] = rint(self.origin[0]);
|
||||
self.origin[1] = rint(self.origin[1]);
|
||||
self.origin[2] = rint(self.origin[2]);*/
|
||||
decal_pickwall(self, self.origin);
|
||||
|
||||
/* Unrolled because I'm lazy */
|
||||
makevectors([0, 0, 0]);
|
||||
traceline(vpos + (v_forward * -1), vpos + (v_forward * 128), 1, self);
|
||||
tmp[0].fraction = trace_fraction;
|
||||
tmp[0].normal = trace_plane_normal;
|
||||
tmp[0].endpos = trace_endpos;
|
||||
traceline(vpos + (v_forward * 1), vpos + (v_forward * -128), 1, self);
|
||||
tmp[1].fraction = trace_fraction;
|
||||
tmp[1].normal = trace_plane_normal;
|
||||
tmp[1].endpos = trace_endpos;
|
||||
traceline(vpos + (v_right * -1), vpos + (v_right * 128), 1, self);
|
||||
tmp[2].fraction = trace_fraction;
|
||||
tmp[2].normal = trace_plane_normal;
|
||||
tmp[2].endpos = trace_endpos;
|
||||
traceline(vpos + (v_right * 1), vpos + (v_right * -128), 1, self);
|
||||
tmp[3].fraction = trace_fraction;
|
||||
tmp[3].normal = trace_plane_normal;
|
||||
tmp[3].endpos = trace_endpos;
|
||||
traceline(vpos + (v_up * -1), vpos + (v_up * 128), 1, self);
|
||||
tmp[4].fraction = trace_fraction;
|
||||
tmp[4].normal = trace_plane_normal;
|
||||
tmp[4].endpos = trace_endpos;
|
||||
traceline(vpos + (v_up * 1), vpos + (v_up * -128), 1, self);
|
||||
tmp[5].fraction = trace_fraction;
|
||||
tmp[5].normal = trace_plane_normal;
|
||||
tmp[5].endpos = trace_endpos;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if ( tmp[i].fraction < frac ) {
|
||||
frac = tmp[i].fraction;
|
||||
endpos = tmp[i].endpos;
|
||||
b = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (frac == 1.0f) {
|
||||
if (g_tracedDecal.fraction == 1.0f) {
|
||||
dprint(sprintf("infodecal tracing failed at %v\n", self.origin));
|
||||
|
||||
if (self.classname != "tempdecal") {
|
||||
|
@ -133,19 +82,21 @@ void infodecal(void)
|
|||
return;
|
||||
}
|
||||
|
||||
self.origin = g_tracedDecal.endpos;
|
||||
|
||||
/* FIXME: more universal check? */
|
||||
if (getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, endpos)) == "sky") {
|
||||
if (getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, g_tracedDecal.endpos)) == "sky") {
|
||||
return;
|
||||
}
|
||||
|
||||
makevectors(vectoangles(tmp[b].endpos - self.origin ));
|
||||
vector cpl = v_forward - (v_forward * tmp[b].normal) * tmp[b].normal;
|
||||
makevectors(vectoangles(g_tracedDecal.endpos - self.origin ));
|
||||
vector cpl = v_forward - (v_forward * g_tracedDecal.normal) * g_tracedDecal.normal;
|
||||
|
||||
if (tmp[b].normal[2] == 0) {
|
||||
if (g_tracedDecal.normal[2] == 0) {
|
||||
cpl = [0, 0, 1];
|
||||
}
|
||||
|
||||
self.angles = vectoangles(cpl, tmp[b].normal);
|
||||
self.angles = vectoangles(cpl, g_tracedDecal.normal);
|
||||
self.solid = SOLID_NOT;
|
||||
self.pvsflags = PVSF_NOREMOVE | PVSF_IGNOREPVS;
|
||||
self.SendEntity = infodecal_send;
|
||||
|
|
|
@ -116,7 +116,7 @@ monstermaker::Spawner(void)
|
|||
}
|
||||
|
||||
/* too many alive at a time */
|
||||
if ((m_iMaxChildren > 0) && c >= m_iMaxChildren) || (m_flDelay == 0 && c >= 1)) {
|
||||
if ((m_iMaxChildren > 0 && c >= m_iMaxChildren) || (m_flDelay == 0 && c >= 1)) {
|
||||
nextthink = time + m_flDelay;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -151,7 +151,6 @@ void Decals_PlaceGauss(vector pos)
|
|||
decal.nextthink = time /*+ 0.1f*/;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CSQC
|
||||
|
||||
class decal
|
||||
|
@ -231,4 +230,54 @@ void Decal_Parse(void)
|
|||
new.predraw = Decal_PreDraw;
|
||||
new.drawmask = MASK_ENGINE;
|
||||
}
|
||||
|
||||
/* this is like Decal_Parse, but better */
|
||||
void
|
||||
Decals_Place(vector org, string dname)
|
||||
{
|
||||
decal new;
|
||||
|
||||
new = spawn(decal);
|
||||
decal_pickwall(new, org);
|
||||
|
||||
/* we never hit any wall. */
|
||||
if (g_tracedDecal.fraction == 1.0f) {
|
||||
dprint(sprintf("infodecal tracing failed at %v\n", org));
|
||||
remove(new);
|
||||
return;
|
||||
}
|
||||
|
||||
new.origin = g_tracedDecal.endpos;
|
||||
|
||||
/* FIXME: more universal check? */
|
||||
if (getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, g_tracedDecal.endpos)) == "sky") {
|
||||
return;
|
||||
}
|
||||
|
||||
makevectors(vectoangles(g_tracedDecal.endpos - self.origin ));
|
||||
vector cpl = v_forward - (v_forward * g_tracedDecal.normal) * g_tracedDecal.normal;
|
||||
|
||||
if (g_tracedDecal.normal[2] == 0) {
|
||||
cpl = [0, 0, 1];
|
||||
}
|
||||
|
||||
new.angles = vectoangles(cpl, g_tracedDecal.normal);
|
||||
new.m_strTexture = dname;
|
||||
|
||||
new.size = drawgetimagesize(new.m_strTexture);
|
||||
|
||||
if (serverkeyfloat("*bspversion") == 30) {
|
||||
Decal_MakeShader(new);
|
||||
}
|
||||
|
||||
makevectors(new.angles);
|
||||
float surf = getsurfacenearpoint(world, new.origin);
|
||||
vector s_dir = getsurfacepointattribute(world, surf, 0, SPA_S_AXIS);
|
||||
vector t_dir = getsurfacepointattribute(world, surf, 0, SPA_T_AXIS);
|
||||
new.mins = v_up / new.size[0];
|
||||
new.maxs = t_dir / new.size[1];
|
||||
new.color = getlight(new.origin) / 255;
|
||||
new.predraw = Decal_PreDraw;
|
||||
new.drawmask = MASK_ENGINE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -99,6 +99,10 @@ Effect_GibHuman(vector pos)
|
|||
static void Gib_Remove(void) {
|
||||
remove(self);
|
||||
}
|
||||
static void Gib_Touch(void)
|
||||
{
|
||||
Decals_Place(self.origin, sprintf("{blood%d", floor(random(1,9))));
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
|
||||
vector vel;
|
||||
|
@ -110,9 +114,12 @@ Effect_GibHuman(vector pos)
|
|||
setmodel(gibb, g_hgibs[i]);
|
||||
setorigin(gibb, pos);
|
||||
gibb.movetype = MOVETYPE_BOUNCE;
|
||||
gibb.solid = SOLID_BBOX;
|
||||
setsize(gibb, [0,0,0], [0,0,0]);
|
||||
gibb.velocity = vel;
|
||||
gibb.avelocity = vectoangles(gibb.velocity);
|
||||
gibb.think = Gib_Remove;
|
||||
gibb.touch = Gib_Touch;
|
||||
gibb.nextthink = time + 5.0f;
|
||||
gibb.drawmask = MASK_ENGINE;
|
||||
}
|
||||
|
@ -164,6 +171,11 @@ void Effect_CreateBlood(vector pos, vector color) {
|
|||
msg_entity = self;
|
||||
multicast(pos, MULTICAST_PVS);
|
||||
#else
|
||||
static void Blood_Touch(void)
|
||||
{
|
||||
Decals_Place(self.origin, sprintf("{blood%d", floor(random(1,9))));
|
||||
}
|
||||
|
||||
env_sprite eBlood = spawn(env_sprite);
|
||||
setorigin(eBlood, pos);
|
||||
setmodel(eBlood, "sprites/bloodspray.spr");
|
||||
|
@ -192,6 +204,9 @@ void Effect_CreateBlood(vector pos, vector color) {
|
|||
ePart.framerate = 15;
|
||||
ePart.nextthink = time + 0.1f;
|
||||
ePart.velocity = randomvec() * 64;
|
||||
ePart.touch = Blood_Touch;
|
||||
ePart.solid = SOLID_BBOX;
|
||||
setsize(ePart, [0,0,0], [0,0,0]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue