added Nexiuz TE_ effects (prefixed TE_TEI_) and Nexiuz plasma trail (an override...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 10 Nov 2002 05:03:42 +0000 (05:03 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 10 Nov 2002 05:03:42 +0000 (05:03 +0000)
Nexiuz mode disables fullbrights
reshaped some of the particle structure (flags is gone, broken apart into separate fields again)
added tex_beam (which uses a separate texture instead of the particle font because it needs to repeat)
simplified some of the texture font generation (tex_ variables now indicate where to put the images in the texture)
now resets trail positions if entity was not active in previous frame
now gives packet dump when Host_Error is called during client message parsing code
now frees the model(s) being loaded when Host_Error is called during model loading code
removed modelflush command because it crashes the realtime lighting code (which points to leafs and surfaces in the world model, a problem which does not exist with r_restart and vid_restart)
R_Stain and R_CalcBeamVerts now use const where appropriate

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2618 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
cl_parse.c
cl_particles.c
client.h
gl_rmain.c
gl_rsurf.c
host.c
model_shared.c
model_shared.h
protocol.h
render.h

index 3a238c3..ad2f92c 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -541,7 +541,7 @@ static void CL_RelinkNetworkEntities(void)
 
                VectorCopy (neworg, ent->persistent.trail_origin);
                // persistent.modelindex will be updated by CL_LerpUpdate
-               if (ent->state_current.modelindex != ent->persistent.modelindex)
+               if (ent->state_current.modelindex != ent->persistent.modelindex || !ent->state_previous.active)
                        VectorCopy(neworg, oldorg);
 
                VectorCopy (neworg, ent->render.origin);
@@ -571,7 +571,19 @@ static void CL_RelinkNetworkEntities(void)
                if (effects)
                {
                        if (effects & EF_BRIGHTFIELD)
-                               CL_EntityParticles (ent);
+                       {
+                               if (gamemode == GAME_NEXIUZ)
+                               {
+                                       dlightcolor[0] += 100.0f;
+                                       dlightcolor[1] += 200.0f;
+                                       dlightcolor[2] += 400.0f;
+                                       // don't do trail if we have no previous location
+                                       if (ent->state_previous.active)
+                                               CL_RocketTrail (oldorg, neworg, 8, ent);
+                               }
+                               else
+                                       CL_EntityParticles (ent);
+                       }
                        if (effects & EF_MUZZLEFLASH)
                                ent->persistent.muzzleflash = 100.0f;
                        if (effects & EF_DIMLIGHT)
index 44e04c8..b63a017 100644 (file)
@@ -1309,8 +1309,41 @@ void CL_ParseTempEntity (void)
                S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
+       case TE_TEI_G3:
+               MSG_ReadVector(pos);
+               MSG_ReadVector(pos2);
+               MSG_ReadVector(dir);
+               CL_BeamParticle(pos, pos2, 12, 1, 0.3, 0.1, 1, 1);
+               CL_BeamParticle(pos, pos2, 5, 1, 0.9, 0.3, 1, 1);
+               break;
+
+       case TE_TEI_SMOKE:
+               MSG_ReadVector(pos);
+               MSG_ReadVector(dir);
+               count = MSG_ReadByte ();
+               Mod_FindNonSolidLocation(pos, cl.worldmodel);
+               CL_Tei_Smoke(pos, dir, count);
+               break;
+
+       case TE_TEI_BIGEXPLOSION:
+               MSG_ReadVector(pos);
+               Mod_FindNonSolidLocation(pos, cl.worldmodel);
+               CL_ParticleExplosion (pos);
+               CL_AllocDlight (NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
+               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               break;
+
+       case TE_TEI_PLASMAHIT:
+               MSG_ReadVector(pos);
+               MSG_ReadVector(dir);
+               count = MSG_ReadByte ();
+               Mod_FindNonSolidLocation(pos, cl.worldmodel);
+               CL_Tei_PlasmaHit(pos, dir, count);
+               CL_AllocDlight (NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
+               break;
+
        default:
-               Host_Error ("CL_ParseTempEntity: bad type %d", type);
+               Host_Error ("CL_ParseTempEntity: bad type %d (hex %02X)", type, type);
        }
 }
 
@@ -1323,6 +1356,7 @@ static qbyte cgamenetbuffer[65536];
 CL_ParseServerMessage
 =====================
 */
+int parsingerror = false;
 void CL_ParseServerMessage (void)
 {
        int                     cmd;
@@ -1347,6 +1381,8 @@ void CL_ParseServerMessage (void)
 
        entitiesupdated = false;
 
+       parsingerror = true;
+
        while (1)
        {
                if (msg_badread)
@@ -1667,6 +1703,17 @@ void CL_ParseServerMessage (void)
 
        if (entitiesupdated)
                CL_EntityUpdateEnd();
+
+       parsingerror = false;
+}
+
+void CL_Parse_DumpPacket(void)
+{
+       if (!parsingerror)
+               return;
+       Con_Printf("Packet dump:\n");
+       SZ_HexDumpToConsole(&net_message);
+       parsingerror = false;
 }
 
 void CL_Parse_Init(void)
index 1409edc..22a3851 100644 (file)
@@ -163,21 +163,16 @@ ptype_t;
 
 #define PARTICLE_INVALID 0
 #define PARTICLE_BILLBOARD 1
-#define PARTICLE_BEAM 2
+#define PARTICLE_SPARK 2
 #define PARTICLE_ORIENTED_DOUBLESIDED 3
-
-#define P_TEXNUM_FIRSTBIT 0
-#define P_TEXNUM_BITS 6
-#define P_ORIENTATION_FIRSTBIT (P_TEXNUM_FIRSTBIT + P_TEXNUM_BITS)
-#define P_ORIENTATION_BITS 2
-#define P_FLAGS_FIRSTBIT (P_ORIENTATION_FIRSTBIT + P_ORIENTATION_BITS)
-//#define P_DYNLIGHT (1 << (P_FLAGS_FIRSTBIT + 0))
-#define P_ADDITIVE (1 << (P_FLAGS_FIRSTBIT + 1))
+#define PARTICLE_BEAM 4
 
 typedef struct particle_s
 {
        ptype_t         type;
-       unsigned int    flags; // dynamically lit, orientation, additive blending, texnum
+       int                     orientation;
+       int                     texnum;
+       int                     additive;
        vec3_t          org;
        vec3_t          vel;
        float           die;
@@ -234,12 +229,13 @@ static int particlepalette[256] =
 
 //static int explosparkramp[8] = {0x4b0700, 0x6f0f00, 0x931f07, 0xb7330f, 0xcf632b, 0xe3974f, 0xffe7b5, 0xffffff};
 
-// these must match r_part.c's textures
+// texture numbers in particle font
 static const int tex_smoke[8] = {0, 1, 2, 3, 4, 5, 6, 7};
-//static const int tex_rainsplash[16] = {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
+static const int tex_rainsplash[16] = {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
 static const int tex_particle = 24;
-//static const int tex_rain = 25;
+static const int tex_raindrop = 25;
 static const int tex_bubble = 26;
+static const int tex_beam = 27;
 
 static int                     cl_maxparticles;
 static int                     cl_numparticles;
@@ -317,35 +313,31 @@ void CL_Particles_Init (void)
                return;\
        {\
                particle_t      *part;\
-               int tempcolor, tempcolor2, cr1, cg1, cb1, cr2, cg2, cb2;\
-               unsigned int partflags;\
-               partflags = ((porientation) << P_ORIENTATION_FIRSTBIT) | ((ptex) << P_TEXNUM_FIRSTBIT);\
-               if (padditive)\
-                       partflags |= P_ADDITIVE;\
-               /*if (plight)*/\
-               /*      partflags |= P_DYNLIGHT;*/\
-               tempcolor = (pcolor1);\
-               tempcolor2 = (pcolor2);\
-               cr2 = ((tempcolor2) >> 16) & 0xFF;\
-               cg2 = ((tempcolor2) >> 8) & 0xFF;\
-               cb2 = (tempcolor2) & 0xFF;\
-               if (tempcolor != tempcolor2)\
+               int ptempcolor, ptempcolor2, pcr1, pcg1, pcb1, pcr2, pcg2, pcb2;\
+               ptempcolor = (pcolor1);\
+               ptempcolor2 = (pcolor2);\
+               pcr2 = ((ptempcolor2) >> 16) & 0xFF;\
+               pcg2 = ((ptempcolor2) >> 8) & 0xFF;\
+               pcb2 = (ptempcolor2) & 0xFF;\
+               if (ptempcolor != ptempcolor2)\
                {\
-                       cr1 = ((tempcolor) >> 16) & 0xFF;\
-                       cg1 = ((tempcolor) >> 8) & 0xFF;\
-                       cb1 = (tempcolor) & 0xFF;\
-                       tempcolor = rand() & 0xFF;\
-                       cr2 = (((cr2 - cr1) * tempcolor) >> 8) + cr1;\
-                       cg2 = (((cg2 - cg1) * tempcolor) >> 8) + cg1;\
-                       cb2 = (((cb2 - cb1) * tempcolor) >> 8) + cb1;\
+                       pcr1 = ((ptempcolor) >> 16) & 0xFF;\
+                       pcg1 = ((ptempcolor) >> 8) & 0xFF;\
+                       pcb1 = (ptempcolor) & 0xFF;\
+                       ptempcolor = rand() & 0xFF;\
+                       pcr2 = (((pcr2 - pcr1) * ptempcolor) >> 8) + pcr1;\
+                       pcg2 = (((pcg2 - pcg1) * ptempcolor) >> 8) + pcg1;\
+                       pcb2 = (((pcb2 - pcb1) * ptempcolor) >> 8) + pcb1;\
                }\
                part = &particles[cl_numparticles++];\
                part->type = (ptype);\
-               part->color[0] = cr2;\
-               part->color[1] = cg2;\
-               part->color[2] = cb2;\
+               part->color[0] = pcr2;\
+               part->color[1] = pcg2;\
+               part->color[2] = pcb2;\
                part->color[3] = 0xFF;\
-               part->flags = partflags;\
+               part->orientation = porientation;\
+               part->texnum = ptex;\
+               part->additive = padditive;\
                part->scalex = (pscalex);\
                part->scaley = (pscaley);\
                part->alpha = (palpha);\
@@ -565,7 +557,7 @@ void CL_ParticleExplosion (vec3_t org)
                        for (i = 0;i < 256;i++)
                        {
                                k = particlepalette[0x68 + (rand() & 7)];
-                               particle(pt_static, PARTICLE_BEAM, k, k, tex_particle, false, true, 1.5f, 0.05f, lhrandom(0, 255), 512, 9999, 1, 0, org[0], org[1], org[2], lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(-192, 192) + 160, 0, 0, 0, 0, 0, 0);
+                               particle(pt_static, PARTICLE_SPARK, k, k, tex_particle, false, true, 1.5f, 0.05f, lhrandom(0, 255), 512, 9999, 1, 0, org[0], org[1], org[2], lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(-192, 192) + 160, 0, 0, 0, 0, 0, 0);
                        }
                }
        }
@@ -662,7 +654,7 @@ void CL_SparkShower (vec3_t org, vec3_t dir, int count)
                        while(count--)
                        {
                                k = particlepalette[0x68 + (rand() & 7)];
-                               particle(pt_static, PARTICLE_BEAM, k, k, tex_particle, false, true, 0.4f, 0.015f, lhrandom(64, 255), 512, 9999, 1, 0, org[0], org[1], org[2], lhrandom(-64, 64) + dir[0], lhrandom(-64, 64) + dir[1], lhrandom(0, 128) + dir[2], 0, 0, 0, 0, 0, 0);
+                               particle(pt_static, PARTICLE_SPARK, k, k, tex_particle, false, true, 0.4f, 0.015f, lhrandom(64, 255), 512, 9999, 1, 0, org[0], org[1], org[2], lhrandom(-64, 64) + dir[0], lhrandom(-64, 64) + dir[1], lhrandom(0, 128) + dir[2], 0, 0, 0, 0, 0, 0);
                        }
                }
        }
@@ -781,7 +773,7 @@ void CL_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color
                while(count--)
                {
                        k = particlepalette[colorbase + (rand()&3)];
-                       particle(pt_rain, PARTICLE_BEAM, k, k, tex_particle, true, true, 0.5, 0.02, lhrandom(8, 16), 0, t, 0, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], cl.time + 9999, dir[0], dir[1], dir[2], 0, 0);
+                       particle(pt_rain, PARTICLE_SPARK, k, k, tex_particle, true, true, 0.5, 0.02, lhrandom(8, 16), 0, t, 0, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], cl.time + 9999, dir[0], dir[1], dir[2], 0, 0);
                }
                break;
        case 1:
@@ -1020,6 +1012,13 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
                                        particle(pt_static, PARTICLE_BILLBOARD, 0x303030, 0x606060, tex_smoke[rand()&7], true, false, dec, dec, 64, 320, 9999, 0, 0, pos[0], pos[1], pos[2], lhrandom(-4, 4), lhrandom(-4, 4), lhrandom(0, 16), 0, 0, 0, 0, 0, 0);
                                }
                                break;
+                       case 8: // Nexiuz plasma trail
+                               dec = 4;
+                               if (smoke)
+                               {
+                                       //particle(pt_static, PARTICLE_BILLBOARD, 0x2030FF, 0x80C0FF, tex_particle, false, true, 3.0f, 3.0f, lhrandom(64, 255), 512, 9999, 0, 0, pos[0], pos[1], pos[2], lhrandom(-32, 32) + dir[0] * -64.0f, lhrandom(-32, 32) + dir[1] * -64.0f, lhrandom(-32, 32) + dir[2] * -64.0f, 0, 0, 0, 0, 0, 0);
+                                       particle(pt_static, PARTICLE_BILLBOARD, 0x283880, 0x283880, tex_particle, false, true, dec, dec, 255, 1024, 9999, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0);
+                               }
                }
 
                // advance to next time and position
@@ -1054,6 +1053,59 @@ void CL_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent)
        }
 }
 
+void CL_BeamParticle (const vec3_t start, const vec3_t end, vec_t radius, float red, float green, float blue, float alpha, float lifetime)
+{
+       int tempcolor2, cr, cg, cb;
+       cr = red * 255;
+       cg = green * 255;
+       cb = blue * 255;
+       tempcolor2 = (bound(0, cr, 255) << 16) | (bound(0, cg, 255) << 8) | bound(0, cb, 255);
+       particle(pt_static, PARTICLE_BEAM, tempcolor2, tempcolor2, tex_beam, false, true, radius, radius, alpha * 255, alpha * 255 / lifetime, 9999, 0, 0, start[0], start[1], start[2], 0, 0, 0, 0, end[0], end[1], end[2], 0, 0);
+}
+
+void CL_Tei_Smoke(const vec3_t org, const vec3_t dir, int count)
+{
+       int k;
+       if (!cl_particles.integer) return;
+
+       // smoke puff
+       if (cl_particles_smoke.integer)
+       {
+               k = count / 4;
+               while(k--)
+               {
+                       particle(pt_grow, PARTICLE_BILLBOARD, 0x202020, 0x404040, tex_smoke[rand()&7], true, true, 5, 5, 255, 512, 9999, 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, 15, 0, 0, 0, 0, 0);
+               }
+       }
+}
+
+void CL_Tei_PlasmaHit(const vec3_t org, const vec3_t dir, int count)
+{
+       int k;
+       if (!cl_particles.integer) return;
+
+       if (cl_stainmaps.integer)
+               R_Stain(org, 40, 96, 96, 96, 40, 128, 128, 128, 40);
+
+       // smoke puff
+       if (cl_particles_smoke.integer)
+       {
+               k = count / 4;
+               while(k--)
+               {
+                       particle(pt_grow, PARTICLE_BILLBOARD, 0x202020, 0x404040, tex_smoke[rand()&7], true, true, 5, 5, 255, 512, 9999, 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), 15, 0, 0, 0, 0, 0);
+               }
+       }
+
+       if (cl_particles_sparks.integer)
+       {
+               // sparks
+               while(count--)
+               {
+                       particle(pt_static, PARTICLE_SPARK, 0x2030FF, 0x80C0FF, tex_particle, false, true, 2.0f, 0.1f, lhrandom(64, 255), 512, 9999, 0, 0, org[0], org[1], org[2], lhrandom(-count, count) * 3.0f + dir[0], lhrandom(-count, count) * 3.0f + dir[1], lhrandom(-count, count) * 3.0f + dir[2], 0, 0, 0, 0, 0, 0);
+               }
+       }
+}
 
 /*
 ===============
@@ -1238,6 +1290,7 @@ void CL_MoveParticles (void)
 // particletexture_t is a rectangle in the particlefonttexture
 typedef struct
 {
+       rtexture_t *texture;
        float s1, t1, s2, t2;
 }
 particletexture_t;
@@ -1285,15 +1338,15 @@ static qbyte shadebubble(float dx, float dy, vec3_t light)
                return 0;
 }
 
-static void setuptex(int cltexnum, int rtexnum, qbyte *data, qbyte *particletexturedata)
+static void setuptex(int texnum, qbyte *data, qbyte *particletexturedata)
 {
        int basex, basey, y;
-       basex = ((rtexnum >> 0) & 7) * 32;
-       basey = ((rtexnum >> 3) & 7) * 32;
-       particletexture[cltexnum].s1 = (basex + 1) / 256.0f;
-       particletexture[cltexnum].t1 = (basey + 1) / 256.0f;
-       particletexture[cltexnum].s2 = (basex + 31) / 256.0f;
-       particletexture[cltexnum].t2 = (basey + 31) / 256.0f;
+       basex = ((texnum >> 0) & 7) * 32;
+       basey = ((texnum >> 3) & 7) * 32;
+       particletexture[texnum].s1 = (basex + 1) / 256.0f;
+       particletexture[texnum].t1 = (basey + 1) / 256.0f;
+       particletexture[texnum].s2 = (basex + 31) / 256.0f;
+       particletexture[texnum].t2 = (basey + 31) / 256.0f;
        for (y = 0;y < 32;y++)
                memcpy(particletexturedata + ((basey + y) * 256 + basex) * 4, data + y * 32 * 4, 32 * 4);
 }
@@ -1302,13 +1355,13 @@ static void R_InitParticleTexture (void)
 {
        int x,y,d,i,m;
        float dx, dy, radius, f, f2;
-       qbyte data[32][32][4], noise1[64][64], noise2[64][64];
+       qbyte data[32][32][4], noise1[64][64], noise2[64][64], data2[64][16][4];
        vec3_t light;
        qbyte particletexturedata[256*256*4];
 
        memset(particletexturedata, 255, sizeof(particletexturedata));
 
-       // the particletexture[][] array numbers must match the cl_part.c textures
+       // the second setuptex parameter must match the tex_ numbers
        // smoke/blood
        for (i = 0;i < 8;i++)
        {
@@ -1337,7 +1390,7 @@ static void R_InitParticleTexture (void)
                }
                while (m < 224);
 
-               setuptex(i + 0, i + 0, &data[0][0][0], particletexturedata);
+               setuptex(tex_smoke[i], &data[0][0][0], particletexturedata);
        }
 
        // rain splash
@@ -1357,7 +1410,7 @@ static void R_InitParticleTexture (void)
                                data[y][x][3] = (int) f;
                        }
                }
-               setuptex(i + 8, i + 16, &data[0][0][0], particletexturedata);
+               setuptex(tex_rainsplash[i], &data[0][0][0], particletexturedata);
        }
 
        // normal particle
@@ -1373,7 +1426,7 @@ static void R_InitParticleTexture (void)
                        data[y][x][3] = (qbyte) d;
                }
        }
-       setuptex(24, 32, &data[0][0][0], particletexturedata);
+       setuptex(tex_particle, &data[0][0][0], particletexturedata);
 
        // rain
        light[0] = 1;light[1] = 1;light[2] = 1;
@@ -1386,7 +1439,7 @@ static void R_InitParticleTexture (void)
                        data[y][x][3] = shadebubble((x - 16) * (1.0 / 8.0), y < 24 ? (y - 24) * (1.0 / 24.0) : (y - 24) * (1.0 / 8.0), light);
                }
        }
-       setuptex(25, 33, &data[0][0][0], particletexturedata);
+       setuptex(tex_raindrop, &data[0][0][0], particletexturedata);
 
        // bubble
        light[0] = 1;light[1] = 1;light[2] = 1;
@@ -1399,7 +1452,7 @@ static void R_InitParticleTexture (void)
                        data[y][x][3] = shadebubble((x - 16) * (1.0 / 16.0), (y - 16) * (1.0 / 16.0), light);
                }
        }
-       setuptex(26, 34, &data[0][0][0], particletexturedata);
+       setuptex(tex_bubble, &data[0][0][0], particletexturedata);
 
 #if WORKINGLQUAKE
        glBindTexture(GL_TEXTURE_2D, (particlefonttexture = gl_extension_number++));
@@ -1407,6 +1460,31 @@ static void R_InitParticleTexture (void)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 #else
        particlefonttexture = R_LoadTexture2D(particletexturepool, "particlefont", 256, 256, particletexturedata, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
+       for (i = 0;i < MAX_PARTICLETEXTURES;i++)
+               particletexture[i].texture = particlefonttexture;
+
+       // beam
+       fractalnoise(&noise1[0][0], 64, 4);
+       m = 0;
+       for (y = 0;y < 64;y++)
+       {
+               for (x = 0;x < 16;x++)
+               {
+                       if (x < 8)
+                               d = x;
+                       else
+                               d = (15 - x);
+                       d = d * d * noise1[y][x] / (7 * 7);
+                       data2[y][x][0] = data2[y][x][1] = data2[y][x][2] = (qbyte) bound(0, d, 255);
+                       data2[y][x][3] = 255;
+               }
+       }
+
+       particletexture[tex_beam].texture = R_LoadTexture2D(particletexturepool, "beam", 16, 64, &data2[0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
+       particletexture[tex_beam].s1 = 0;
+       particletexture[tex_beam].t1 = 0;
+       particletexture[tex_beam].s2 = 1;
+       particletexture[tex_beam].t2 = 1;
 #endif
 }
 
@@ -1448,7 +1526,6 @@ float varray_vertex[16];
 
 void R_DrawParticleCallback(const void *calldata1, int calldata2)
 {
-       int additive, texnum, orientation;
        float org[3], up2[3], v[3], right[3], up[3], fog, ifog, fogvec[3], cr, cg, cb, ca;
        particletexture_t *tex;
 #ifndef WORKINGLQUAKE
@@ -1457,66 +1534,8 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2)
        const particle_t *p = calldata1;
 
        VectorCopy(p->org, org);
-       orientation = (p->flags >> P_ORIENTATION_FIRSTBIT) & ((1 << P_ORIENTATION_BITS) - 1);
-       texnum = (p->flags >> P_TEXNUM_FIRSTBIT) & ((1 << P_TEXNUM_BITS) - 1);
-       //dynlight = p->flags & P_DYNLIGHT;
-       additive = p->flags & P_ADDITIVE;
 
-#ifdef WORKINGLQUAKE
-       if (additive)
-               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-       else
-               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-#else
-       memset(&m, 0, sizeof(m));
-       m.blendfunc1 = GL_SRC_ALPHA;
-       if (additive)
-               m.blendfunc2 = GL_ONE;
-       else
-               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-       m.tex[0] = R_GetTexture(particlefonttexture);
-       R_Mesh_Matrix(&r_identitymatrix);
-       R_Mesh_State(&m);
-#endif
-
-       tex = &particletexture[texnum];
-       cr = p->color[0] * (1.0f / 255.0f);
-       cg = p->color[1] * (1.0f / 255.0f);
-       cb = p->color[2] * (1.0f / 255.0f);
-       ca = p->alpha * (1.0f / 255.0f);
-#ifndef WORKINGLQUAKE
-       if (fogenabled)
-       {
-               VectorSubtract(org, r_origin, fogvec);
-               fog = exp(fogdensity/DotProduct(fogvec,fogvec));
-               ifog = 1 - fog;
-               cr = cr * ifog;
-               cg = cg * ifog;
-               cb = cb * ifog;
-               if (!additive)
-               {
-                       cr += fogcolor[0] * fog;
-                       cg += fogcolor[1] * fog;
-                       cb += fogcolor[2] * fog;
-               }
-       }
-       cr *= r_colorscale;
-       cg *= r_colorscale;
-       cb *= r_colorscale;
-
-       varray_texcoord[0][0] = tex->s2;varray_texcoord[0][1] = tex->t1;
-       varray_texcoord[0][4] = tex->s1;varray_texcoord[0][5] = tex->t1;
-       varray_texcoord[0][8] = tex->s1;varray_texcoord[0][9] = tex->t2;
-       varray_texcoord[0][12] = tex->s2;varray_texcoord[0][13] = tex->t2;
-#endif
-
-       if (orientation == PARTICLE_BEAM)
-       {
-               VectorMA(p->org, -p->scaley, p->vel, v);
-               VectorMA(p->org, p->scaley, p->vel, up2);
-               R_CalcBeamVerts(varray_vertex, v, up2, p->scalex);
-       }
-       else if (orientation == PARTICLE_BILLBOARD)
+       if (p->orientation == PARTICLE_BILLBOARD)
        {
                VectorScale(vright, p->scalex, right);
                VectorScale(vup, p->scaley, up);
@@ -1533,7 +1552,15 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2)
                varray_vertex[13] = org[1] + right[1] + up[1];
                varray_vertex[14] = org[2] + right[2] + up[2];
        }
-       else if (orientation == PARTICLE_ORIENTED_DOUBLESIDED)
+       else if (p->orientation == PARTICLE_SPARK)
+       {
+               VectorMA(p->org, -p->scaley, p->vel, v);
+               VectorMA(p->org, p->scaley, p->vel, up2);
+               R_CalcBeamVerts(varray_vertex, v, up2, p->scalex);
+       }
+       else if (p->orientation == PARTICLE_BEAM)
+               R_CalcBeamVerts(varray_vertex, p->org, p->vel2, p->scalex);
+       else if (p->orientation == PARTICLE_ORIENTED_DOUBLESIDED)
        {
                // double-sided
                if (DotProduct(p->vel2, r_origin) > DotProduct(p->vel2, org))
@@ -1559,8 +1586,19 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2)
                varray_vertex[14] = org[2] + right[2] + up[2];
        }
        else
-               Host_Error("R_DrawParticles: unknown particle orientation %i\n", orientation);
+               Host_Error("R_DrawParticles: unknown particle orientation %i\n", p->orientation);
+
+       tex = &particletexture[p->texnum];
+       cr = p->color[0] * (1.0f / 255.0f);
+       cg = p->color[1] * (1.0f / 255.0f);
+       cb = p->color[2] * (1.0f / 255.0f);
+       ca = p->alpha * (1.0f / 255.0f);
+
 #if WORKINGLQUAKE
+       if (p->additive)
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+       else
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBegin(GL_QUADS);
        glColor4f(cr, cg, cb, ca);
        glTexCoord2f(tex->s2, tex->t1);glVertex3f(varray_vertex[ 0], varray_vertex[ 1], varray_vertex[ 2]);
@@ -1569,6 +1607,54 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2)
        glTexCoord2f(tex->s2, tex->t2);glVertex3f(varray_vertex[12], varray_vertex[13], varray_vertex[14]);
        glEnd();
 #else
+       memset(&m, 0, sizeof(m));
+       m.blendfunc1 = GL_SRC_ALPHA;
+       if (p->additive)
+               m.blendfunc2 = GL_ONE;
+       else
+               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       m.tex[0] = R_GetTexture(tex->texture);
+       R_Mesh_Matrix(&r_identitymatrix);
+       R_Mesh_State(&m);
+
+       if (fogenabled)
+       {
+               VectorSubtract(org, r_origin, fogvec);
+               fog = exp(fogdensity/DotProduct(fogvec,fogvec));
+               ifog = 1 - fog;
+               cr = cr * ifog;
+               cg = cg * ifog;
+               cb = cb * ifog;
+               if (!p->additive)
+               {
+                       cr += fogcolor[0] * fog;
+                       cg += fogcolor[1] * fog;
+                       cb += fogcolor[2] * fog;
+               }
+       }
+       cr *= r_colorscale;
+       cg *= r_colorscale;
+       cb *= r_colorscale;
+
+       if (p->orientation == PARTICLE_BEAM)
+       {
+               VectorSubtract(p->vel2, p->org, up);
+               VectorNormalizeFast(up);
+               v[0] = DotProduct(p->org, up) * (1.0f / 64.0f) - cl.time * 0.25;
+               v[1] = DotProduct(p->vel2, up) * (1.0f / 64.0f) - cl.time * 0.25;
+               varray_texcoord[0][0] = 1;varray_texcoord[0][1] = v[0];
+               varray_texcoord[0][4] = 0;varray_texcoord[0][5] = v[0];
+               varray_texcoord[0][8] = 0;varray_texcoord[0][9] = v[1];
+               varray_texcoord[0][12] = 1;varray_texcoord[0][13] = v[1];
+       }
+       else
+       {
+               varray_texcoord[0][0] = tex->s2;varray_texcoord[0][1] = tex->t1;
+               varray_texcoord[0][4] = tex->s1;varray_texcoord[0][5] = tex->t1;
+               varray_texcoord[0][8] = tex->s1;varray_texcoord[0][9] = tex->t2;
+               varray_texcoord[0][12] = tex->s2;varray_texcoord[0][13] = tex->t2;
+       }
+
        GL_Color(cr, cg, cb, ca);
        R_Mesh_Draw(4, 2, polygonelements);
 #endif
@@ -1606,7 +1692,7 @@ void R_DrawParticles (void)
        // LordHavoc: only render if not too close
        c_particles += cl_numparticles;
        for (i = 0, p = particles;i < cl_numparticles;i++, p++)
-               if (DotProduct(p->org, vpn) >= minparticledist)
+               if (DotProduct(p->org, vpn) >= minparticledist || p->orientation == PARTICLE_BEAM)
                        R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0);
 #endif
 }
index 71e0b43..1168ba8 100644 (file)
--- a/client.h
+++ b/client.h
@@ -569,6 +569,7 @@ void CL_TimeDemo_f (void);
 //
 void CL_Parse_Init(void);
 void CL_ParseServerMessage(void);
+void CL_Parse_DumpPacket(void);
 
 //
 // view
@@ -613,6 +614,9 @@ void CL_ParticleExplosion (vec3_t org);
 void CL_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength);
 void CL_LavaSplash (vec3_t org);
 void CL_TeleportSplash (vec3_t org);
+void CL_BeamParticle (const vec3_t start, const vec3_t end, vec_t radius, float red, float green, float blue, float alpha, float lifetime);
+void CL_Tei_Smoke(const vec3_t pos, const vec3_t dir, int count);
+void CL_Tei_PlasmaHit(const vec3_t pos, const vec3_t dir, int count);
 void CL_MoveParticles(void);
 void R_MoveExplosions(void);
 void R_NewExplosion(vec3_t org);
index bcf5c25..2cf0486 100644 (file)
@@ -228,7 +228,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable (&r_dynamic);
        Cvar_RegisterVariable (&r_fullbright);
        Cvar_RegisterVariable (&r_textureunits);
-       if (gamemode == GAME_NEHAHRA)
+       if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXIUZ)
                Cvar_SetValue("r_fullbrights", 0);
        R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
 }
@@ -1396,7 +1396,7 @@ void R_DrawNoModel(entity_render_t *ent)
        //      R_DrawNoModelCallback(ent, 0);
 }
 
-void R_CalcBeamVerts (float *vert, vec3_t org1, vec3_t org2, float width)
+void R_CalcBeamVerts (float *vert, const vec3_t org1, const vec3_t org2, float width)
 {
        vec3_t right1, right2, diff, normal;
 
index 97589a2..add2b1a 100644 (file)
@@ -419,7 +419,7 @@ static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surf, int d
        }
 }
 
-void R_StainNode (mnode_t *node, model_t *model, vec3_t origin, float radius, float fcolor[8])
+void R_StainNode (mnode_t *node, model_t *model, const vec3_t origin, float radius, const float fcolor[8])
 {
        float ndist, a, ratio, maxdist, maxdist2, maxdist3, invradius, sdtable[256], td, dist2;
        msurface_t *surf, *endsurf;
@@ -541,7 +541,7 @@ loc0:
        }
 }
 
-void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2)
+void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2)
 {
        int n;
        float fcolor[8];
diff --git a/host.c b/host.c
index 7233970..455d0be 100644 (file)
--- a/host.c
+++ b/host.c
@@ -133,11 +133,17 @@ This shuts down both the client and server
 ================
 */
 char hosterrorstring[4096];
+extern char sv_spawnmap[MAX_QPATH];
+extern char sv_loadgame[MAX_OSPATH];
 void Host_Error (const char *error, ...)
 {
        va_list argptr;
        static qboolean inerror = false;
 
+       // make sure we don't get in a loading loop
+       sv_loadgame[0] = 0;
+       sv_spawnmap[0] = 0;
+
        // LordHavoc: if first frame has not been shown, or currently shutting
        // down, do Sys_Error instead
        if (!host_loopactive || host_shuttingdown)
@@ -164,6 +170,8 @@ void Host_Error (const char *error, ...)
        va_end (argptr);
        Con_Printf ("Host_Error: %s\n",hosterrorstring);
 
+       CL_Parse_DumpPacket();
+
        PR_Crash();
 
        if (sv.active)
@@ -175,6 +183,9 @@ void Host_Error (const char *error, ...)
        CL_Disconnect ();
        cls.demonum = -1;
 
+       // unload any partially loaded models
+       Mod_ClearErrorModels();
+
        inerror = false;
 
        longjmp (host_abortserver, 1);
index 4c75ef0..591d8ac 100644 (file)
@@ -102,7 +102,6 @@ Mod_Init
 ===============
 */
 static void Mod_Print (void);
-static void Mod_Flush (void);
 void Mod_Init (void)
 {
        Mod_BrushInit();
@@ -110,7 +109,6 @@ void Mod_Init (void)
        Mod_SpriteInit();
 
        Cmd_AddCommand ("modellist", Mod_Print);
-       Cmd_AddCommand ("modelflush", Mod_Flush);
 }
 
 void Mod_RenderInit(void)
@@ -206,6 +204,8 @@ static model_t *Mod_LoadModel (model_t *mod, qboolean crash, qboolean checkdisk,
        mod->needload = false;
        mod->used = true;
        mod->crc = crc;
+       // errors can prevent the corresponding mod->error = false;
+       mod->error = true;
 
        // all models use memory, so allocate a memory pool
        mod->mempool = Mem_AllocPool(mod->name);
@@ -222,6 +222,8 @@ static model_t *Mod_LoadModel (model_t *mod, qboolean crash, qboolean checkdisk,
 
        Mem_Free(buf);
 
+       // no errors occurred
+       mod->error = false;
        return mod;
 }
 
@@ -250,6 +252,16 @@ void Mod_ClearAll (void)
 {
 }
 
+void Mod_ClearErrorModels (void)
+{
+       int i;
+       model_t *mod;
+
+       for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
+               if (mod->error)
+                       Mod_FreeModel(mod);
+}
+
 void Mod_ClearUsed(void)
 {
        int i;
@@ -372,17 +384,6 @@ static void Mod_Print (void)
                        Con_Printf ("%4iK %s\n", mod->mempool ? (mod->mempool->totalsize + 1023) / 1024 : 0, mod->name);
 }
 
-static void Mod_Flush (void)
-{
-       int             i;
-
-       Con_Printf ("Unloading models\n");
-       for (i = 0;i < MAX_MOD_KNOWN;i++)
-               if (mod_known[i].name[0])
-                       Mod_UnloadModel(&mod_known[i]);
-       Mod_LoadModels();
-}
-
 int Mod_FindTriangleWithEdge(const int *elements, int numtriangles, int start, int end)
 {
        int i;
index 83d981f..745f2ce 100644 (file)
@@ -99,6 +99,8 @@ typedef struct model_s
        qboolean                isworldmodel;
        // true if this model is a HalfLife .bsp file
        qboolean                ishlbsp;
+       // true if this model was not successfully loaded and should be purged
+       qboolean                error;
 
        // mod_brush, mod_alias, mod_sprite
        modtype_t               type;
@@ -286,6 +288,7 @@ extern cvar_t r_fullbrights;
 void Mod_Init (void);
 void Mod_CheckLoaded (model_t *mod);
 void Mod_ClearAll (void);
+void Mod_ClearErrorModels (void);
 model_t *Mod_FindName (const char *name);
 model_t *Mod_ForName (const char *name, qboolean crash, qboolean checkdisk, qboolean isworldmodel);
 void Mod_TouchModel (const char *name);
index da37e37..951b6a8 100644 (file)
@@ -286,6 +286,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define TE_CUSTOMFLASH         73 // [vector] origin [byte] radius / 8 - 1 [byte] lifetime / 256 - 1 [byte] red [byte] green [byte] blue
 #define TE_FLAMEJET                    74 // [vector] origin [vector] velocity [byte] count
 #define TE_PLASMABURN          75 // [vector] origin
+// LordHavoc: Tei grabbed these codes
+#define TE_TEI_G3                      76 // [vector] start [vector] end [vector] angles
+#define TE_TEI_SMOKE           77 // [vector] origin [vector] dir [byte] count
+#define TE_TEI_BIGEXPLOSION    78 // [vector] origin
+#define TE_TEI_PLASMAHIT       79 // [vector} origin [vector] dir [byte] count
+
 
 // these are bits for the 'flags' field of the entity_state_t
 #define RENDER_STEP 1
index 52afb74..5b951cb 100644 (file)
--- a/render.h
+++ b/render.h
@@ -165,12 +165,12 @@ void R_TimeReport_Start(void);
 void R_TimeReport_End(void);
 
 // r_stain
-void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2);
+void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2);
 
 void R_DrawWorldCrosshair(void);
 void R_Draw2DCrosshair(void);
 
-void R_CalcBeamVerts (float *vert, vec3_t org1, vec3_t org2, float width);
+void R_CalcBeamVerts (float *vert, const vec3_t org1, const vec3_t org2, float width);
 
 #endif