]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_particles.c
relocated the CL_SendMove call to put it at the end of network parsing (and only...
[xonotic/darkplaces.git] / cl_particles.c
index 88ed49274f05219f29edcf02c90132fae5a1a205..8683c08afb133ebe0dbec439328fd2d404fdfb8a 100644 (file)
@@ -152,7 +152,7 @@ void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
 #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)
+trace_t CL_TraceBox (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hitbmodels, int *hitent, int hitsupercontentsmask, qboolean hitplayers)
 {
 #if QW
        pmtrace_t trace;
@@ -167,9 +167,7 @@ float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int
 #else
        RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
 #endif
-       VectorCopy(trace.endpos, impact);
-       VectorCopy(trace.plane.normal, normal);
-       return trace.fraction;
+       return trace;
 }
 #else
 #include "cl_collision.h"
@@ -200,30 +198,31 @@ typedef struct particletype_s
 {
        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
@@ -241,7 +240,7 @@ 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
@@ -324,10 +323,6 @@ cvar_t cl_decals = {CVAR_SAVE, "cl_decals", "0"};
 cvar_t cl_decals_time = {CVAR_SAVE, "cl_decals_time", "0"};
 cvar_t cl_decals_fadetime = {CVAR_SAVE, "cl_decals_fadetime", "20"};
 
-#ifndef WORKINGLQUAKE
-static mempool_t *cl_part_mempool;
-#endif
-
 void CL_Particles_Clear(void)
 {
        cl_numparticles = 0;
@@ -383,8 +378,7 @@ void CL_Particles_Init (void)
 #ifdef WORKINGLQUAKE
        particles = (particle_t *) Hunk_AllocName(cl_maxparticles * sizeof(particle_t), "particles");
 #else
-       cl_part_mempool = Mem_AllocPool("CL_Part", 0, NULL);
-       particles = (particle_t *) Mem_Alloc(cl_part_mempool, cl_maxparticles * sizeof(particle_t));
+       particles = (particle_t *) Mem_Alloc(cl_mempool, cl_maxparticles * sizeof(particle_t));
 #endif
        CL_Particles_Clear();
 }
@@ -393,8 +387,6 @@ void CL_Particles_Shutdown (void)
 {
 #ifdef WORKINGLQUAKE
        // No clue what to do here...
-#else
-       Mem_FreePool (&cl_part_mempool);
 #endif
 }
 
@@ -459,7 +451,7 @@ particle_t *particle(particletype_t *ptype, int pcolor1, int pcolor2, int ptex,
        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)
@@ -470,9 +462,9 @@ void CL_SpawnDecalParticleForSurface(void *hitent, const vec3_t org, const vec3_
                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
        }
@@ -482,24 +474,21 @@ void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size,
 {
        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
+       float org2[3];
+       int besthitent = 0, hitent;
+       trace_t trace;
        bestfrac = 10;
        for (i = 0;i < 32;i++)
        {
                VectorRandom(org2);
                VectorMA(org, maxdist, org2, org2);
-               frac = CL_TraceLine(org, org2, v, normal, true, &hitent, SUPERCONTENTS_SOLID);
-               if (bestfrac > frac)
+               trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, &hitent, SUPERCONTENTS_SOLID, false);
+               if (bestfrac > trace.fraction)
                {
-                       bestfrac = frac;
+                       bestfrac = trace.fraction;
                        besthitent = hitent;
-                       VectorCopy(v, bestorg);
-                       VectorCopy(normal, bestnormal);
+                       VectorCopy(trace.endpos, bestorg);
+                       VectorCopy(trace.plane.normal, bestnormal);
                }
        }
        if (bestfrac < 1)
@@ -665,6 +654,7 @@ CL_ParticleExplosion
 void CL_ParticleExplosion (vec3_t org)
 {
        int i;
+       trace_t trace;
        //vec3_t v;
        //vec3_t v2;
        if (cl_stainmaps.integer)
@@ -698,13 +688,14 @@ void CL_ParticleExplosion (vec3_t org)
                                        v[0] = org[0] + lhrandom(-48, 48);
                                        v[1] = org[1] + lhrandom(-48, 48);
                                        v[2] = org[2] + lhrandom(-48, 48);
-                                       if (CL_TraceLine(org, v, v2, NULL, true, NULL, SUPERCONTENTS_SOLID) >= 0.1)
+                                       trace = CL_TraceBox(org, vec3_origin, vec3_origin, v, true, NULL, SUPERCONTENTS_SOLID, false);
+                                       if (trace.fraction >= 0.1)
                                                break;
                                }
-                               VectorSubtract(v2, org, v2);
+                               VectorSubtract(trace.endpos, 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);
                        }
                }
 
@@ -806,8 +797,9 @@ void CL_SparkShower (vec3_t org, vec3_t dir, int count, vec_t gravityscale)
 
 void CL_Smoke (vec3_t org, vec3_t dir, int count)
 {
-       vec3_t org2, org3;
+       vec3_t org2;
        int k;
+       trace_t trace;
 
        if (!cl_particles.integer) return;
 
@@ -820,8 +812,8 @@ void CL_Smoke (vec3_t org, vec3_t dir, int count)
                        org2[0] = org[0] + 0.125f * lhrandom(-count, count);
                        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);
+                       trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, NULL, SUPERCONTENTS_SOLID, false);
+                       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, trace.endpos[0], trace.endpos[1], trace.endpos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 0);
                }
        }
 }
@@ -844,7 +836,8 @@ static float bloodcount = 0;
 void CL_BloodPuff (vec3_t org, vec3_t vel, int count)
 {
        float s;
-       vec3_t org2, org3;
+       vec3_t org2;
+       trace_t trace;
        // bloodcount is used to accumulate counts too small to cause a blood particle
        if (!cl_particles.integer) return;
        if (!cl_particles_blood.integer) return;
@@ -859,8 +852,8 @@ void CL_BloodPuff (vec3_t org, vec3_t vel, int count)
                org2[0] = org[0] + 0.125f * lhrandom(-bloodcount, bloodcount);
                org2[1] = org[1] + 0.125f * lhrandom(-bloodcount, bloodcount);
                org2[2] = org[2] + 0.125f * lhrandom(-bloodcount, bloodcount);
-               CL_TraceLine(org, org2, org3, NULL, true, NULL, SUPERCONTENTS_SOLID);
-               particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768 / cl_particles_quality.value, cl_particles_blood_alpha.value * 384 / cl_particles_quality.value, 0, -1, org3[0], org3[1], org3[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 1);
+               trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, NULL, SUPERCONTENTS_SOLID, false);
+               particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768 / cl_particles_quality.value, cl_particles_blood_alpha.value * 384 / cl_particles_quality.value, 0, -1, trace.endpos[0], trace.endpos[1], trace.endpos[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 1);
                bloodcount -= 16 / cl_particles_quality.value;
        }
 }
@@ -1147,7 +1140,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en
                                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)
@@ -1158,7 +1151,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en
                                // 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;
 
 
@@ -1244,7 +1237,7 @@ void CL_Tei_Smoke(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) * 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)
@@ -1259,7 +1252,7 @@ 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)
@@ -1276,12 +1269,9 @@ void CL_MoveParticles (void)
 {
        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
+       float gravity, dvel, bloodwaterfade, frametime, f, dist, org[3], oldorg[3];
+       int hitent;
+       trace_t trace;
 
        // LordHavoc: early out condition
        if (!cl_numparticles)
@@ -1326,17 +1316,17 @@ void CL_MoveParticles (void)
                                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)
+                                       trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK, false);
+                                       if (trace.fraction < 1)
                                        {
-                                               VectorCopy(v, p->org);
-                                               // splash
-                                               p->type = particletype + pt_raindecal;
                                                // convert from a raindrop particle to a rainsplash decal
+                                               VectorCopy(trace.endpos, p->org);
+                                               VectorCopy(trace.plane.normal, p->vel);
+                                               VectorAdd(p->org, p->vel, p->org);
+                                               p->type = particletype + pt_raindecal;
                                                p->texnum = tex_rainsplash[0];
                                                p->time2 = cl.time;
                                                p->alphafade = p->alpha / 0.4;
-                                               VectorCopy(normal, p->vel);
-                                               VectorAdd(p->org, normal, p->org);
                                                p->bounce = 0;
                                                p->friction = 0;
                                                p->gravity = 0;
@@ -1346,12 +1336,16 @@ void CL_MoveParticles (void)
                                else if (p->type == particletype + pt_blood)
                                {
                                        // blood - splash on solid
-                                       if (CL_TraceLine(oldorg, p->org, v, normal, true, &hitent, SUPERCONTENTS_SOLID) < 1)
+                                       trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, &hitent, SUPERCONTENTS_SOLID, false);
+                                       if (trace.fraction < 1)
                                        {
-                                               VectorCopy(v, p->org);
+                                               // convert from a blood particle to a blood decal
+                                               VectorCopy(trace.endpos, p->org);
+                                               VectorCopy(trace.plane.normal, p->vel);
+                                               VectorAdd(p->org, p->vel, p->org);
 #ifndef WORKINGLQUAKE
                                                if (cl_stainmaps.integer)
-                                                       R_Stain(v, 32, 32, 16, 16, p->alpha * p->size * (1.0f / 40.0f), 192, 48, 48, p->alpha * p->size * (1.0f / 40.0f));
+                                                       R_Stain(p->org, 32, 32, 16, 16, p->alpha * p->size * (1.0f / 40.0f), 192, 48, 48, p->alpha * p->size * (1.0f / 40.0f));
 #endif
                                                if (!cl_decals.integer)
                                                {
@@ -1360,19 +1354,15 @@ void CL_MoveParticles (void)
                                                }
 
                                                p->type = particletype + pt_decal;
-                                               // convert from a blood particle to a blood decal
                                                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);
-                                               VectorAdd(p->relativeorigin, p->relativedirection, p->relativeorigin);
+                                               p->ownermodel = cl_entities[hitent].render.model;
+                                               Matrix4x4_Transform(&cl_entities[hitent].render.inversematrix, p->org, p->relativeorigin);
+                                               Matrix4x4_Transform3x3(&cl_entities[hitent].render.inversematrix, p->vel, p->relativedirection);
 #endif
                                                p->time2 = cl.time;
                                                p->alphafade = 0;
-                                               VectorCopy(normal, p->vel);
-                                               VectorAdd(p->org, normal, p->org);
                                                p->bounce = 0;
                                                p->friction = 0;
                                                p->gravity = 0;
@@ -1381,9 +1371,10 @@ void CL_MoveParticles (void)
                                }
                                else
                                {
-                                       if (CL_TraceLine(oldorg, p->org, v, normal, true, &hitent, SUPERCONTENTS_SOLID) < 1)
+                                       trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, NULL, SUPERCONTENTS_SOLID, false);
+                                       if (trace.fraction < 1)
                                        {
-                                               VectorCopy(v, p->org);
+                                               VectorCopy(trace.endpos, p->org);
                                                if (p->bounce < 0)
                                                {
                                                        p->type = NULL;
@@ -1391,8 +1382,8 @@ void CL_MoveParticles (void)
                                                }
                                                else
                                                {
-                                                       dist = DotProduct(p->vel, normal) * -p->bounce;
-                                                       VectorMA(p->vel, dist, normal, p->vel);
+                                                       dist = DotProduct(p->vel, trace.plane.normal) * -p->bounce;
+                                                       VectorMA(p->vel, dist, trace.plane.normal, p->vel);
                                                        if (DotProduct(p->vel, p->vel) < 0.03)
                                                                VectorClear(p->vel);
                                                }
@@ -1488,17 +1479,17 @@ void CL_MoveParticles (void)
 #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;
@@ -1924,6 +1915,14 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2)
                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);
@@ -1932,7 +1931,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2)
                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;
@@ -2037,7 +2036,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2)
        glTexCoord2f(particle_texcoord2f[6], particle_texcoord2f[7]);glVertex3f(particle_vertex3f[ 9], particle_vertex3f[10], particle_vertex3f[11]);
        glEnd();
 #else
-       R_Mesh_Draw(4, 2, polygonelements);
+       R_Mesh_Draw(0, 4, 2, polygonelements);
 #endif
 }