*/
void CL_ParseStartSoundPacket(int largesoundindex)
{
- vec3_t pos;
- int channel, ent;
- int sound_num;
- int volume;
- int field_mask;
- float attenuation;
- int i;
+ vec3_t pos;
+ int channel, ent;
+ int sound_num;
+ int volume;
+ int field_mask;
+ float attenuation;
+ int i;
- field_mask = MSG_ReadByte();
+ field_mask = MSG_ReadByte();
- if (field_mask & SND_VOLUME)
+ if (field_mask & SND_VOLUME)
volume = MSG_ReadByte ();
else
volume = DEFAULT_SOUND_PACKET_VOLUME;
- if (field_mask & SND_ATTENUATION)
+ if (field_mask & SND_ATTENUATION)
attenuation = MSG_ReadByte () / 64.0;
else
attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
for (i = 0;i < 3;i++)
pos[i] = MSG_ReadCoord ();
- S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
+ S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
}
/*
case TE_WIZSPIKE:
// spike hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+ CL_AllocDlight (NULL, pos, 50, 0.25f, 1.00f, 0.25f, 250, 0.2);
CL_RunParticleEffect (pos, vec3_origin, 20, 30);
S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
break;
case TE_KNIGHTSPIKE:
// spike hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+ CL_AllocDlight (NULL, pos, 50, 1.0f, 0.60f, 0.20f, 250, 0.2);
CL_RunParticleEffect (pos, vec3_origin, 226, 20);
S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
break;
case TE_SPIKE:
// spike hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
// LordHavoc: changed to spark shower
CL_SparkShower(pos, vec3_origin, 15);
if ( rand() % 5 )
case TE_SPIKEQUAD:
// quad spike hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
// LordHavoc: changed to spark shower
CL_SparkShower(pos, vec3_origin, 15);
CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
case TE_SUPERSPIKE:
// super spike hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
// LordHavoc: changed to dust shower
CL_SparkShower(pos, vec3_origin, 30);
if ( rand() % 5 )
case TE_SUPERSPIKEQUAD:
// quad super spike hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
// LordHavoc: changed to dust shower
CL_SparkShower(pos, vec3_origin, 30);
CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
case TE_BLOOD:
// blood puff
MSG_ReadVector(pos);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
dir[0] = MSG_ReadChar ();
dir[1] = MSG_ReadChar ();
dir[2] = MSG_ReadChar ();
case TE_BLOOD2:
// blood puff
MSG_ReadVector(pos);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
CL_BloodPuff(pos, vec3_origin, 10);
break;
case TE_SPARK:
// spark shower
MSG_ReadVector(pos);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
dir[0] = MSG_ReadChar ();
dir[1] = MSG_ReadChar ();
dir[2] = MSG_ReadChar ();
count = MSG_ReadByte ();
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
CL_SparkShower(pos, dir, count);
break;
case TE_PLASMABURN:
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
CL_PlasmaBurn(pos);
break;
case TE_GUNSHOT:
// bullet hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
// LordHavoc: changed to dust shower
CL_SparkShower(pos, vec3_origin, 15);
break;
case TE_GUNSHOTQUAD:
// quad bullet hitting wall
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
CL_SparkShower(pos, vec3_origin, 15);
CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
break;
case TE_EXPLOSION:
// rocket explosion
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
CL_ParticleExplosion (pos);
// LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
CL_AllocDlight (NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
case TE_EXPLOSIONQUAD:
// quad rocket explosion
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
CL_ParticleExplosion (pos);
CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
case TE_EXPLOSION3:
// Nehahra movie colored lighting explosion
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
CL_ParticleExplosion (pos);
CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
case TE_EXPLOSIONRGB:
// colored lighting explosion
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
CL_ParticleExplosion (pos);
color[0] = MSG_ReadByte() * (1.0 / 255.0);
color[1] = MSG_ReadByte() * (1.0 / 255.0);
case TE_TAREXPLOSION:
// tarbaby explosion
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
CL_BlobExplosion (pos);
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
case TE_SMALLFLASH:
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
break;
case TE_CUSTOMFLASH:
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
radius = MSG_ReadByte() * 8;
velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
color[0] = MSG_ReadByte() * (1.0 / 255.0);
case TE_EXPLOSION2:
// color mapped explosion
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
colorStart = MSG_ReadByte ();
colorLength = MSG_ReadByte ();
CL_ParticleExplosion2 (pos, colorStart, colorLength);
MSG_ReadVector(pos);
MSG_ReadVector(dir);
count = MSG_ReadByte ();
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
CL_Tei_Smoke(pos, dir, count);
break;
case TE_TEI_BIGEXPLOSION:
MSG_ReadVector(pos);
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
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);
MSG_ReadVector(pos);
MSG_ReadVector(dir);
count = MSG_ReadByte ();
- Mod_FindNonSolidLocation(pos, cl.worldmodel);
+ Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 5);
CL_Tei_PlasmaHit(pos, dir, count);
CL_AllocDlight (NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
break;
return ((mleaf_t *)node)->contents;
}
-void Mod_FindNonSolidLocation(vec3_t pos, model_t *mod)
+typedef struct findnonsolidlocationinfo_s
{
- if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]-=1;
- pos[1]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[1]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[1]-=1;
- pos[2]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[2]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[2]-=1;
+ vec3_t center;
+ vec_t radius;
+ vec3_t nudge;
+ vec_t bestdist;
+ model_t *model;
}
+findnonsolidlocationinfo_t;
+#if 0
+extern cvar_t samelevel;
+#endif
+void Mod_FindNonSolidLocation_r_Leaf(findnonsolidlocationinfo_t *info, mleaf_t *leaf)
+{
+ int i, surfnum, k, *tri, *mark;
+ float dist, f, vert[3][3], edge[3][3], facenormal[3], edgenormal[3][3], point[3];
+#if 0
+ float surfnormal[3];
+#endif
+ msurface_t *surf;
+ surfmesh_t *mesh;
+ for (surfnum = 0, mark = leaf->firstmarksurface;surfnum < leaf->nummarksurfaces;surfnum++, mark++)
+ {
+ surf = info->model->surfaces + *mark;
+ if (surf->flags & SURF_SOLIDCLIP)
+ {
+#if 0
+ VectorCopy(surf->plane->normal, surfnormal);
+ if (surf->flags & SURF_PLANEBACK)
+ VectorNegate(surfnormal, surfnormal);
+#endif
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ for (k = 0;k < mesh->numtriangles;k++)
+ {
+ tri = mesh->index + k * 3;
+ VectorCopy((mesh->verts + tri[0] * 4), vert[0]);
+ VectorCopy((mesh->verts + tri[1] * 4), vert[1]);
+ VectorCopy((mesh->verts + tri[2] * 4), vert[2]);
+ VectorSubtract(vert[1], vert[0], edge[0]);
+ VectorSubtract(vert[2], vert[1], edge[1]);
+ CrossProduct(edge[1], edge[0], facenormal);
+ if (facenormal[0] || facenormal[1] || facenormal[2])
+ {
+ VectorNormalize(facenormal);
+#if 0
+ if (VectorDistance(facenormal, surfnormal) > 0.01f)
+ Con_Printf("a2! %f %f %f != %f %f %f\n", facenormal[0], facenormal[1], facenormal[2], surfnormal[0], surfnormal[1], surfnormal[2]);
+#endif
+ f = DotProduct(info->center, facenormal) - DotProduct(vert[0], facenormal);
+ if (f <= info->bestdist && f >= -info->bestdist)
+ {
+ VectorSubtract(vert[0], vert[2], edge[2]);
+ VectorNormalize(edge[0]);
+ VectorNormalize(edge[1]);
+ VectorNormalize(edge[2]);
+ CrossProduct(facenormal, edge[0], edgenormal[0]);
+ CrossProduct(facenormal, edge[1], edgenormal[1]);
+ CrossProduct(facenormal, edge[2], edgenormal[2]);
+#if 0
+ if (samelevel.integer & 1)
+ VectorNegate(edgenormal[0], edgenormal[0]);
+ if (samelevel.integer & 2)
+ VectorNegate(edgenormal[1], edgenormal[1]);
+ if (samelevel.integer & 4)
+ VectorNegate(edgenormal[2], edgenormal[2]);
+ for (i = 0;i < 3;i++)
+ if (DotProduct(vert[0], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f
+ || DotProduct(vert[1], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f
+ || DotProduct(vert[2], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f)
+ Con_Printf("a! %i : %f %f %f (%f %f %f)\n", i, edgenormal[i][0], edgenormal[i][1], edgenormal[i][2], facenormal[0], facenormal[1], facenormal[2]);
+#endif
+ // face distance
+ if (DotProduct(info->center, edgenormal[0]) < DotProduct(vert[0], edgenormal[0])
+ && DotProduct(info->center, edgenormal[1]) < DotProduct(vert[1], edgenormal[1])
+ && DotProduct(info->center, edgenormal[2]) < DotProduct(vert[2], edgenormal[2]))
+ {
+ // we got lucky, the center is within the face
+ dist = DotProduct(info->center, facenormal) - DotProduct(vert[0], facenormal);
+ if (dist < 0)
+ {
+ dist = -dist;
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(facenormal, (info->radius - -dist), info->nudge);
+ }
+ }
+ else
+ {
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(facenormal, (info->radius - dist), info->nudge);
+ }
+ }
+ }
+ else
+ {
+ // check which edge or vertex the center is nearest
+ for (i = 0;i < 3;i++)
+ {
+ f = DotProduct(info->center, edge[i]);
+ if (f >= DotProduct(vert[0], edge[i])
+ && f <= DotProduct(vert[1], edge[i]))
+ {
+ // on edge
+ VectorMA(info->center, -f, edge[i], point);
+ dist = sqrt(DotProduct(point, point));
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(point, (info->radius / dist), info->nudge);
+ }
+ // skip both vertex checks
+ // (both are further away than this edge)
+ i++;
+ }
+ else
+ {
+ // not on edge, check first vertex of edge
+ VectorSubtract(info->center, vert[i], point);
+ dist = sqrt(DotProduct(point, point));
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(point, (info->radius / dist), info->nudge);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void Mod_FindNonSolidLocation_r(findnonsolidlocationinfo_t *info, mnode_t *node)
+{
+ if (node->contents)
+ {
+ if (((mleaf_t *)node)->nummarksurfaces)
+ Mod_FindNonSolidLocation_r_Leaf(info, (mleaf_t *)node);
+ }
+ else
+ {
+ float f = PlaneDiff(info->center, node->plane);
+ if (f >= -info->bestdist)
+ Mod_FindNonSolidLocation_r(info, node->children[0]);
+ if (f <= info->bestdist)
+ Mod_FindNonSolidLocation_r(info, node->children[1]);
+ }
+}
+
+void Mod_FindNonSolidLocation(vec3_t in, vec3_t out, model_t *model, float radius)
+{
+ int i;
+ findnonsolidlocationinfo_t info;
+ VectorCopy(in, info.center);
+ info.radius = radius;
+ info.model = model;
+ i = 0;
+ do
+ {
+ VectorClear(info.nudge);
+ info.bestdist = radius;
+ Mod_FindNonSolidLocation_r(&info, model->nodes + model->hulls[0].firstclipnode);
+ VectorAdd(info.center, info.nudge, info.center);
+ }
+ while(info.bestdist < radius && ++i < 10);
+ VectorCopy(info.center, out);
+}
/*
===================