Shuffled a lot of Decal code around so gibs can now spawn blood, etc.

This commit is contained in:
Marco Cawthorne 2020-04-01 20:55:05 +02:00
parent 479048bda8
commit ec819cf4e4
7 changed files with 132 additions and 60 deletions

View File

@ -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
View 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;
}
}
}

View File

@ -4,6 +4,7 @@
#includelist
baseentity.h
decals.h
materials.h
server/defs.h
server/baseentity.cpp

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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
}