#include "pmove.h"
extern qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace);
#endif
-float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int hitbmodels, void **hitent, int hitsupercontentsmask)
+float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int hitbmodels, int *hitent, int hitsupercontentsmask)
{
#if QW
pmtrace_t trace;
{
pblend_t blendmode;
porientation_t orientation;
+ qboolean lighting;
}
particletype_t;
typedef enum
{
- pt_alphastatic, pt_static, pt_spark, pt_beam, pt_rain, pt_raindecal, pt_snow, pt_bubble, pt_blood, pt_grow, pt_decal, pt_entityparticle, pt_total
+ pt_alphastatic, pt_static, pt_spark, pt_beam, pt_rain, pt_raindecal, pt_snow, pt_bubble, pt_blood, pt_smoke, pt_decal, pt_entityparticle, pt_total
}
ptype_t;
// must match ptype_t values
particletype_t particletype[pt_total] =
{
- {PBLEND_ALPHA, PARTICLE_BILLBOARD}, //pt_alphastatic
- {PBLEND_ADD, PARTICLE_BILLBOARD}, //pt_static
- {PBLEND_ADD, PARTICLE_SPARK}, //pt_spark
- {PBLEND_ADD, PARTICLE_BEAM}, //pt_beam
- {PBLEND_ADD, PARTICLE_SPARK}, //pt_rain
- {PBLEND_ADD, PARTICLE_ORIENTED_DOUBLESIDED}, //pt_raindecal
- {PBLEND_ADD, PARTICLE_BILLBOARD}, //pt_snow
- {PBLEND_ADD, PARTICLE_BILLBOARD}, //pt_bubble
- {PBLEND_MOD, PARTICLE_BILLBOARD}, //pt_blood
- {PBLEND_ADD, PARTICLE_BILLBOARD}, //pt_grow
- {PBLEND_MOD, PARTICLE_ORIENTED_DOUBLESIDED}, //pt_decal
- {PBLEND_ALPHA, PARTICLE_BILLBOARD}, //pt_entityparticle
+ {PBLEND_ALPHA, PARTICLE_BILLBOARD, false}, //pt_alphastatic
+ {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_static
+ {PBLEND_ADD, PARTICLE_SPARK, false}, //pt_spark
+ {PBLEND_ADD, PARTICLE_BEAM, false}, //pt_beam
+ {PBLEND_ADD, PARTICLE_SPARK, false}, //pt_rain
+ {PBLEND_ADD, PARTICLE_ORIENTED_DOUBLESIDED, false}, //pt_raindecal
+ {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_snow
+ {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_bubble
+ {PBLEND_MOD, PARTICLE_BILLBOARD, false}, //pt_blood
+ {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_smoke
+ {PBLEND_MOD, PARTICLE_ORIENTED_DOUBLESIDED, false}, //pt_decal
+ {PBLEND_ALPHA, PARTICLE_BILLBOARD, false}, //pt_entityparticle
};
typedef struct particle_s
float friction; // how much air friction affects this object (objects with a low mass/size ratio tend to get more air friction)
qbyte color[4];
#ifndef WORKINGLQUAKE
- entity_render_t *owner; // decal stuck to this entity
+ unsigned short owner; // decal stuck to this entity
model_t *ownermodel; // model the decal is stuck to (used to make sure the entity is still alive)
vec3_t relativeorigin; // decal at this location in entity's coordinate space
vec3_t relativedirection; // decal oriented this way relative to entity's coordinate space
return part;
}
-void CL_SpawnDecalParticleForSurface(void *hitent, const vec3_t org, const vec3_t normal, int color1, int color2, int texnum, float size, float alpha)
+void CL_SpawnDecalParticleForSurface(int hitent, const vec3_t org, const vec3_t normal, int color1, int color2, int texnum, float size, float alpha)
{
particle_t *p;
if (!cl_decals.integer)
p->time2 = cl.time;
#ifndef WORKINGLQUAKE
p->owner = hitent;
- p->ownermodel = p->owner->model;
- Matrix4x4_Transform(&p->owner->inversematrix, org, p->relativeorigin);
- Matrix4x4_Transform3x3(&p->owner->inversematrix, normal, p->relativedirection);
+ p->ownermodel = cl_entities[p->owner].render.model;
+ Matrix4x4_Transform(&cl_entities[p->owner].render.inversematrix, org, p->relativeorigin);
+ Matrix4x4_Transform3x3(&cl_entities[p->owner].render.inversematrix, normal, p->relativedirection);
VectorAdd(p->relativeorigin, p->relativedirection, p->relativeorigin);
#endif
}
int i;
float bestfrac, bestorg[3], bestnormal[3];
float frac, v[3], normal[3], org2[3];
-#ifdef WORKINGLQUAKE
- void *besthitent = NULL, *hitent;
-#else
- entity_render_t *besthitent = NULL, *hitent;
-#endif
+ int besthitent = 0, hitent;
bestfrac = 10;
for (i = 0;i < 32;i++)
{
VectorSubtract(v2, org, v2);
#endif
VectorScale(v2, 2.0f, v2);
- particle(particletype + pt_static, 0xFFFFFF, 0xFFFFFF, tex_smoke[rand()&7], 12, 32, 64, 0, 0, org[0], org[1], org[2], v2[0], v2[1], v2[2], 0);
+ particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 12, 32, 64, 0, 0, org[0], org[1], org[2], v2[0], v2[1], v2[2], 0);
}
}
org2[1] = org[1] + 0.125f * lhrandom(-count, count);
org2[2] = org[2] + 0.125f * lhrandom(-count, count);
CL_TraceLine(org, org2, org3, NULL, true, NULL, SUPERCONTENTS_SOLID);
- particle(particletype + pt_grow, 0x101010, 0x202020, tex_smoke[rand()&7], 3, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 1024, 0, 0, org3[0], org3[1], org3[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 0);
+ particle(particletype + pt_smoke, 0x101010, 0x202020, tex_smoke[rand()&7], 3, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 1024, 0, 0, org3[0], org3[1], org3[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 0);
}
}
}
dec = qd*3;
if (smoke)
{
- particle(particletype + pt_grow, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*125, qd*cl_particles_smoke_alphafade.value*125, 0, 0, pos[0], pos[1], pos[2], lhrandom(-5, 5), lhrandom(-5, 5), lhrandom(-5, 5), 0);
+ particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*125, qd*cl_particles_smoke_alphafade.value*125, 0, 0, pos[0], pos[1], pos[2], lhrandom(-5, 5), lhrandom(-5, 5), lhrandom(-5, 5), 0);
particle(particletype + pt_static, 0x801010, 0xFFA020, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*288, qd*cl_particles_smoke_alphafade.value*1400, 0, 0, pos[0], pos[1], pos[2], lhrandom(-20, 20), lhrandom(-20, 20), lhrandom(-20, 20), 0);
}
if (bubbles)
// FIXME: make it gradually stop smoking
dec = qd*3;
if (smoke)
- particle(particletype + pt_grow, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*100, qd*cl_particles_smoke_alphafade.value*100, 0, 0, pos[0], pos[1], pos[2], lhrandom(-5, 5), lhrandom(-5, 5), lhrandom(-5, 5), 0);
+ particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*100, qd*cl_particles_smoke_alphafade.value*100, 0, 0, pos[0], pos[1], pos[2], lhrandom(-5, 5), lhrandom(-5, 5), lhrandom(-5, 5), 0);
break;
// smoke puff
if (cl_particles_smoke.integer)
for (f = 0;f < count;f += 4.0f / cl_particles_quality.value)
- particle(particletype + pt_grow, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255 / cl_particles_quality.value, 512 / cl_particles_quality.value, 0, 0, org[0] + 0.125f * lhrandom(-count, count), org[1] + 0.125f * lhrandom (-count, count), org[2] + 0.125f * lhrandom(-count, count), dir[0] + lhrandom(-count, count) * 0.5f, dir[1] + lhrandom(-count, count) * 0.5f, dir[2] + lhrandom(-count, count) * 0.5f, 0);
+ particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255 / cl_particles_quality.value, 512 / cl_particles_quality.value, 0, 0, org[0] + 0.125f * lhrandom(-count, count), org[1] + 0.125f * lhrandom (-count, count), org[2] + 0.125f * lhrandom(-count, count), dir[0] + lhrandom(-count, count) * 0.5f, dir[1] + lhrandom(-count, count) * 0.5f, dir[2] + lhrandom(-count, count) * 0.5f, 0);
}
void CL_Tei_PlasmaHit(const vec3_t org, const vec3_t dir, int count)
// smoke puff
if (cl_particles_smoke.integer)
for (f = 0;f < count;f += 4.0f / cl_particles_quality.value)
- particle(particletype + pt_grow, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255 / cl_particles_quality.value, 512 / cl_particles_quality.value, 0, 0, org[0] + 0.125f * lhrandom(-count, count), org[1] + 0.125f * lhrandom (-count, count), org[2] + 0.125f * lhrandom(-count, count), dir[0] + lhrandom(-count, count), dir[1] + lhrandom(-count, count), dir[2] + lhrandom(-count, count), 0);
+ particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255 / cl_particles_quality.value, 512 / cl_particles_quality.value, 0, 0, org[0] + 0.125f * lhrandom(-count, count), org[1] + 0.125f * lhrandom (-count, count), org[2] + 0.125f * lhrandom(-count, count), dir[0] + lhrandom(-count, count), dir[1] + lhrandom(-count, count), dir[2] + lhrandom(-count, count), 0);
// sparks
if (cl_particles_sparks.integer)
particle_t *p;
int i, maxparticle, j, a, content;
float gravity, dvel, bloodwaterfade, frametime, f, dist, normal[3], v[3], org[3], oldorg[3];
-#ifdef WORKINGLQUAKE
- void *hitent;
-#else
- entity_render_t *hitent;
-#endif
+ int hitent;
// LordHavoc: early out condition
if (!cl_numparticles)
if (p->type == particletype + pt_rain)
{
// raindrop - splash on solid/water/slime/lava
- if (CL_TraceLine(oldorg, p->org, v, normal, true, &hitent, SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK) < 1)
+ if (CL_TraceLine(oldorg, p->org, v, normal, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK) < 1)
{
VectorCopy(v, p->org);
// splash
p->texnum = tex_blooddecal[rand()&7];
#ifndef WORKINGLQUAKE
p->owner = hitent;
- p->ownermodel = hitent->model;
- Matrix4x4_Transform(&hitent->inversematrix, v, p->relativeorigin);
- Matrix4x4_Transform3x3(&hitent->inversematrix, normal, p->relativedirection);
+ p->ownermodel = cl_entities[hitent].render.model;
+ Matrix4x4_Transform(&cl_entities[hitent].render.inversematrix, v, p->relativeorigin);
+ Matrix4x4_Transform3x3(&cl_entities[hitent].render.inversematrix, normal, p->relativedirection);
VectorAdd(p->relativeorigin, p->relativedirection, p->relativeorigin);
#endif
p->time2 = cl.time;
}
else
{
- if (CL_TraceLine(oldorg, p->org, v, normal, true, &hitent, SUPERCONTENTS_SOLID) < 1)
+ if (CL_TraceLine(oldorg, p->org, v, normal, true, NULL, SUPERCONTENTS_SOLID) < 1)
{
VectorCopy(v, p->org);
if (p->bounce < 0)
#endif
p->type = NULL;
break;
- case pt_grow:
- p->size += frametime * 15;
+ case pt_smoke:
+ //p->size += frametime * 15;
break;
case pt_decal:
// FIXME: this has fairly wacky handling of alpha
p->alphafade = cl.time > (p->time2 + cl_decals_time.value) ? (255 / cl_decals_fadetime.value) : 0;
#ifndef WORKINGLQUAKE
- if (p->owner->model == p->ownermodel)
+ if (cl_entities[p->owner].render.model == p->ownermodel)
{
- Matrix4x4_Transform(&p->owner->matrix, p->relativeorigin, p->org);
- Matrix4x4_Transform3x3(&p->owner->matrix, p->relativedirection, p->vel);
+ Matrix4x4_Transform(&cl_entities[p->owner].render.matrix, p->relativeorigin, p->org);
+ Matrix4x4_Transform3x3(&cl_entities[p->owner].render.matrix, p->relativedirection, p->vel);
}
else
p->type = NULL;
ca = 1;
}
#ifndef WORKINGLQUAKE
+ if (p->type->lighting)
+ {
+ float ambient[3], diffuse[3], diffusenormal[3];
+ R_CompleteLightPoint(ambient, diffuse, diffusenormal, org, true);
+ cr *= (ambient[0] + 0.5 * diffuse[0]);
+ cg *= (ambient[1] + 0.5 * diffuse[1]);
+ cb *= (ambient[2] + 0.5 * diffuse[2]);
+ }
if (fogenabled)
{
VectorSubtract(org, r_vieworigin, fogvec);
cr = cr * ifog;
cg = cg * ifog;
cb = cb * ifog;
- if (blendmode == PBLEND_ADD)
+ if (blendmode == PBLEND_ALPHA)
{
cr += fogcolor[0] * fog;
cg += fogcolor[1] * fog;