Spawn decals on csqc's bmodels, not just engine-deltaed ents.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6089 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-10-23 10:05:26 +00:00
parent 442d23f226
commit eb157e09b8
5 changed files with 139 additions and 73 deletions

View file

@ -54,6 +54,9 @@ static int rand(void)
#define R_PARTSET_BUILTINS
#endif
#include "pr_common.h"
extern world_t csqc_world;
struct
{
char *name;
@ -122,7 +125,7 @@ typedef struct clippeddecal_s
float die;
int entity; //>0 is a lerpentity, <0 is a csqc ent. 0 is world. woot.
model_t *model; //just for paranoia
// model_t *model; //just for paranoia
vec3_t vertex[3];
vec2_t texcoords[3];
@ -4610,7 +4613,7 @@ static void PScript_AddDecals(void *vctx, vec3_t *fte_restrict points, size_t nu
points += 3;
d->entity = ctx->entity;
d->model = ctx->model;
// d->model = ctx->model;
d->die = ptype->randdie*frandom();
if (ptype->die)
@ -4788,17 +4791,34 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
VectorMA(org, -16, dir, ctx.tangent1);
CL_TraceLine(ctx.tangent2, ctx.tangent1, ctx.center, bestdir, &ctx.entity);
}
if (ctx.entity && (unsigned)ctx.entity < (unsigned)cl.maxlerpents)
if (ctx.entity)
{
lerpents_t *le = cl.lerpents+ctx.entity;
ctx.model = cl.model_precache[le->entstate->modelindex];
if (le->entstate)
VectorSubtract(ctx.center, le->origin, ctx.center);
if (ctx.entity>0 && (unsigned)ctx.entity < (unsigned)cl.maxlerpents)
{
lerpents_t *le = cl.lerpents+ctx.entity;
ctx.model = cl.model_precache[le->entstate->modelindex];
if (le->entstate)
VectorSubtract(ctx.center, le->origin, ctx.center);
else
ctx.entity = 0;
}
else if (ctx.entity<0 && (unsigned)-ctx.entity < (unsigned)csqc_world.num_edicts)
{
wedict_t *e = WEDICT_NUM_UB(csqc_world.progs, -ctx.entity);
if (e)
{
ctx.model = csqc_world.Get_CModel(&csqc_world, e->v->modelindex);
if (!ctx.model)
continue;
VectorSubtract(ctx.center, e->v->origin, ctx.center);
}
else
continue;
}
else
ctx.entity = 0;
}
else
ctx.entity = 0;
VectorNegate(dir, ctx.normal);
VectorNormalize(ctx.normal);
@ -6625,6 +6645,21 @@ static void R_AddClippedDecal(scenetris_t *t, clippeddecal_t *d, plooks_t *type)
VectorAdd(d->vertex[1], le->origin, cl_strisvertv[cl_numstrisvert+1]);
VectorAdd(d->vertex[2], le->origin, cl_strisvertv[cl_numstrisvert+2]);
}
else if (d->entity < 0)
{
wedict_t *e = WEDICT_NUM_UB(csqc_world.progs, -d->entity);
if (!e)
return;
if (e->ereftype!=ER_ENTITY || //kill decals attached to removed ents.
e->v->angles[0] || e->v->angles[1] || e->v->angles[2]) //FIXME: deal with rotated entities.
{
d->die = -1;
return;
}
VectorAdd(d->vertex[0], e->v->origin, cl_strisvertv[cl_numstrisvert+0]);
VectorAdd(d->vertex[1], e->v->origin, cl_strisvertv[cl_numstrisvert+1]);
VectorAdd(d->vertex[2], e->v->origin, cl_strisvertv[cl_numstrisvert+2]);
}
else
{
VectorCopy(d->vertex[0], cl_strisvertv[cl_numstrisvert+0]);

View file

@ -884,77 +884,99 @@ entity_t *TraceLineR (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
return result;
}
#include "pr_common.h"
//traces against networked entities only.
//0 says hit nothing.
//1 says hit world
//>1 says hit some entity
float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int *ent)
{
trace_t trace;
float bestfrac=1;
int i;
vec3_t ts, te;
physent_t *pe;
model_t *mod;
int result=0;
vec3_t axis[3];
memset (&trace, 0, sizeof(trace));
VectorCopy (end, impact);
if (normal)
VectorClear(normal);
for (i=0 ; i < pmove.numphysent ; i++)
#ifdef CSQC_DAT
extern world_t csqc_world;
if (csqc_world.progs)
{
pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
mod = pe->model;
if (mod && mod->loadstate == MLS_LOADED && mod->funcs.NativeTrace)
trace = World_Move(&csqc_world, start, vec3_origin, vec3_origin, end, MOVE_NOMONSTERS, csqc_world.edicts);
VectorCopy(trace.endpos, impact);
if (normal)
VectorCopy(trace.plane.normal, normal);
if (ent)
{
VectorSubtract(start, pe->origin, ts);
VectorSubtract(end, pe->origin, te);
if (pe->angles[0] || pe->angles[1] || pe->angles[2])
{
AngleVectors(pe->angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
mod->funcs.NativeTrace(mod, 0, PE_FRAMESTATE, axis, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace);
}
if (trace.entnum) //ssqc numbers...
*ent = trace.entnum; //aka: trace_networkentity
else if (trace.ent) //csqc numbers are negative...
*ent = -((wedict_t*)trace.ent)->entnum;
//else makestatic, though those are assumed non-solid so won't be returned anyway.
else
mod->funcs.NativeTrace(mod, 0, PE_FRAMESTATE, NULL, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace);
if (trace.fraction<1)
{
if (bestfrac > trace.fraction)
{
bestfrac = trace.fraction;
if (normal)
VectorCopy (trace.plane.normal, normal);
VectorAdd (pe->origin, trace.endpos, impact);
result = pe->info;
}
}
if (trace.startsolid)
{
if (normal)
{
VectorSubtract(start, end, normal);
VectorNormalize(normal);
}
VectorCopy (end, impact);
//hit nothing
if (ent)
*ent = 0;
return 1;
}
*ent = 0;
}
return trace.fraction;
}
else
#endif
{
float bestfrac=1;
int i;
vec3_t ts, te;
physent_t *pe;
model_t *mod;
int result=0;
vec3_t axis[3];
if (ent)
*ent = result;
return bestfrac;
memset (&trace, 0, sizeof(trace));
VectorCopy (end, impact);
if (normal)
VectorClear(normal);
for (i=0 ; i < pmove.numphysent ; i++)
{
pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
mod = pe->model;
if (mod && mod->loadstate == MLS_LOADED && mod->funcs.NativeTrace)
{
VectorSubtract(start, pe->origin, ts);
VectorSubtract(end, pe->origin, te);
if (pe->angles[0] || pe->angles[1] || pe->angles[2])
{
AngleVectors(pe->angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
mod->funcs.NativeTrace(mod, 0, PE_FRAMESTATE, axis, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace);
}
else
mod->funcs.NativeTrace(mod, 0, PE_FRAMESTATE, NULL, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace);
if (trace.fraction<1)
{
if (bestfrac > trace.fraction)
{
bestfrac = trace.fraction;
if (normal)
VectorCopy (trace.plane.normal, normal);
VectorAdd (pe->origin, trace.endpos, impact);
result = pe->info;
}
}
if (trace.startsolid)
{
if (normal)
{
VectorSubtract(start, end, normal);
VectorNormalize(normal);
}
VectorCopy (end, impact);
//hit nothing
if (ent)
*ent = 0;
return 1;
}
}
}
if (ent)
*ent = result;
return bestfrac;
}
}
//handy utility...

View file

@ -2067,6 +2067,7 @@ void R_DrawNameTags(void)
vec3_t org;
vec3_t screenspace;
vec3_t diff;
int scale=1;
if (!cls.allow_cheats)
{
vec2_t scale = {8,8};
@ -2086,6 +2087,7 @@ void R_DrawNameTags(void)
#ifdef CSQC_DAT
extern world_t csqc_world;
w = &csqc_world;
scale = -1;
#endif
}
else if ((r_showfields.ival & 3) == 3)
@ -2194,7 +2196,7 @@ void R_DrawNameTags(void)
{
int hitent;
vec3_t imp;
if (CL_TraceLine(r_refdef.vieworg, org, imp, NULL, &hitent)>=1 || hitent == i)
if (CL_TraceLine(r_refdef.vieworg, org, imp, NULL, &hitent)>=1 || hitent*scale == i)
{
best = i;
bestscore = score;

View file

@ -194,6 +194,13 @@ qboolean HTTP_ServerInit(int epfd, int port)
setsockopt(httpserversocket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6only, sizeof(v6only));
}
#ifdef SO_REUSEADDR
{ //bypass TIME_WAIT (this is supposed to still fail if another process still has it bound)
int reuse = true;
setsockopt(httpserversocket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
}
#endif
if (ioctlsocket (httpserversocket, FIONBIO, &_true) == -1)
{
IWebPrintf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(neterrno()));

View file

@ -2671,7 +2671,7 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
memset ( &clip, 0, sizeof ( moveclip_t ) );
if (passedict && passedict->xv->hull && !(type & MOVE_IGNOREHULL))
if (passedict->xv->hull && !(type & MOVE_IGNOREHULL))
hullnum = passedict->xv->hull;
#ifdef CLIENTONLY
else
@ -2800,7 +2800,7 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
clip.mins = mins;
clip.maxs = maxs;
clip.type = type;
clip.passedict = passedict;
clip.passedict = (passedict!=w->edicts)?passedict:NULL;
clip.hullnum = 0;//hullnum; //BUG: hexen2's SV_ClipMoveToEntity's move_ent argument is set inconsistantly. This has the effect that the SOLID_BSP's .hull field is used instead of the SOLID_BBOX entity. We can't fix this because hexen2 depends upon it - this is the 'tibet5' bug.
#ifdef Q2SERVER
clip.q2passedict = NULL;