mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Added support for *Team Assault* and *Team Tactics*
This commit is contained in:
parent
238e94b4d5
commit
ab2a26a14e
12 changed files with 1353 additions and 264 deletions
|
@ -300,16 +300,7 @@ void CG_ProcessConfigString(int num)
|
|||
cg.matchStartTime = atoi(str);
|
||||
return;
|
||||
case CS_FOGINFO:
|
||||
sscanf
|
||||
(
|
||||
str,
|
||||
"%d %f %f %f %f",
|
||||
&cg.farplane_cull,
|
||||
&cg.farplane_distance,
|
||||
&cg.farplane_color[0],
|
||||
&cg.farplane_color[1],
|
||||
&cg.farplane_color[2]
|
||||
);
|
||||
CG_ParseFogInfo(str);
|
||||
return;
|
||||
case CS_SKYINFO:
|
||||
sscanf
|
||||
|
@ -776,4 +767,45 @@ void Com_Printf( const char *msg, ... ) {
|
|||
|
||||
#endif
|
||||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
|
||||
void CG_ParseFogInfo(const char* str) {
|
||||
sscanf(
|
||||
str,
|
||||
"%d %f %f %f %f %f %f %f %d %f %f %f %f",
|
||||
&cg.farplane_cull,
|
||||
&cg.farplane_distance,
|
||||
&cg.farplane_bias,
|
||||
&cg.skyboxFarplane,
|
||||
&cg.skyboxSpeed,
|
||||
&cg.farplane_color[0],
|
||||
&cg.farplane_color[1],
|
||||
&cg.farplane_color[2],
|
||||
&cg.renderTerrain,
|
||||
&cg.farclipOverride,
|
||||
&cg.farplaneColorOverride[0],
|
||||
&cg.farplaneColorOverride[1],
|
||||
&cg.farplaneColorOverride[2]
|
||||
);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void CG_ParseFogInfo(const char* str) {
|
||||
cg.farclipOverride = 0.0;
|
||||
cg.farplaneColorOverride[0] = -1.0;
|
||||
cg.farplaneColorOverride[1] = -1.0;
|
||||
cg.farplaneColorOverride[2] = -1.0;
|
||||
sscanf
|
||||
(
|
||||
str,
|
||||
"%d %f %f %f %f",
|
||||
&cg.farplane_cull,
|
||||
&cg.farplane_distance,
|
||||
&cg.farplane_color[0],
|
||||
&cg.farplane_color[1],
|
||||
&cg.farplane_color[2]
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -64,7 +64,7 @@ static void CG_MakeBulletHole(vec3_t i_vPos, vec3_t i_vNorm, int iLarge, trace_t
|
|||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void CG_MakeBubbleTrail(vec3_t i_vStart, vec3_t i_vEnd, int iLarge)
|
||||
static void CG_MakeBubbleTrail(vec3_t i_vStart, vec3_t i_vEnd, int iLarge, float alpha = 1.0f)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ static void CG_MakeBulletTracerInternal(vec3_t i_vBarrel, vec3_t i_vStart, vec3_
|
|||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void CG_MakeBulletTracer(vec3_t i_vBarrel, vec3_t i_vStart, vec3_t* i_vEnd, int i_iNumBullets, qboolean iLarge, int iTracerVisible, qboolean bIgnoreEntities) {
|
||||
static void CG_MakeBulletTracer(vec3_t i_vBarrel, vec3_t i_vStart, vec3_t* i_vEnd, int i_iNumBullets, qboolean iLarge, int iTracerVisible, qboolean bIgnoreEntities, float alpha) {
|
||||
bullet_tracer_t* bullet_tracer;
|
||||
int i;
|
||||
|
||||
|
@ -306,6 +306,463 @@ void CG_MakeVehicleEffect(vec3_t i_vStart, vec3_t i_vEnd , vec3_t i_vDir) {
|
|||
cgi.R_DebugLine(vFrom, trace.endpos, 1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
|
||||
void CG_ParseCGMessage()
|
||||
{
|
||||
int i;
|
||||
int iType;
|
||||
int iLarge;
|
||||
int iInfo;
|
||||
int iCount;
|
||||
char* szTmp;
|
||||
vec3_t vStart, vEnd, vTmp;
|
||||
vec3_t vEndArray[MAX_IMPACTS];
|
||||
float alpha;
|
||||
int value;
|
||||
|
||||
qboolean bMoreCGameMessages = qtrue;
|
||||
while (bMoreCGameMessages) {
|
||||
iType = cgi.MSG_ReadBits(6);
|
||||
|
||||
switch (iType)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
if (iType == 1)
|
||||
{
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
}
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
|
||||
if (iType != 1)
|
||||
{
|
||||
vTmp[0] = vStart[0];
|
||||
vTmp[1] = vStart[1];
|
||||
vTmp[2] = vStart[2];
|
||||
}
|
||||
|
||||
vEndArray[0][0] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][1] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(2);
|
||||
if (cgi.MSG_ReadBits(1)) {
|
||||
int iAlpha = cgi.MSG_ReadBits(10);
|
||||
alpha = (float)iAlpha / 512.0;
|
||||
if (alpha < 0.002) {
|
||||
alpha = 0.002;
|
||||
}
|
||||
} else {
|
||||
alpha = 1.0f;
|
||||
}
|
||||
|
||||
if (iType == 1) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
|
||||
}
|
||||
else if (iType == 2) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
|
||||
}
|
||||
else {
|
||||
CG_MakeBubbleTrail(vStart, vEndArray[0], iLarge, alpha);
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if (iType == 3)
|
||||
{
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
iInfo = cgi.MSG_ReadBits(6);
|
||||
}
|
||||
else
|
||||
{
|
||||
iInfo = 0;
|
||||
}
|
||||
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(2);
|
||||
if (cgi.MSG_ReadBits(1)) {
|
||||
int iAlpha = cgi.MSG_ReadBits(10);
|
||||
alpha = (float)iAlpha / 512.0;
|
||||
if (alpha < 0.002) {
|
||||
alpha = 0.002;
|
||||
}
|
||||
} else {
|
||||
alpha = 1.0f;
|
||||
}
|
||||
|
||||
iCount = cgi.MSG_ReadBits(6);
|
||||
for (i = 0; i < iCount; ++i)
|
||||
{
|
||||
vEndArray[i][0] = cgi.MSG_ReadCoord();
|
||||
vEndArray[i][1] = cgi.MSG_ReadCoord();
|
||||
vEndArray[i][2] = cgi.MSG_ReadCoord();
|
||||
}
|
||||
|
||||
if (iCount) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, iCount, iLarge, iInfo, qtrue, alpha);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadDir(vEnd);
|
||||
iLarge = cgi.MSG_ReadBits(2);
|
||||
|
||||
switch (iType)
|
||||
{
|
||||
case 6:
|
||||
if (wall_impact_count < MAX_IMPACTS)
|
||||
{
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = -1;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (wall_impact_count < MAX_IMPACTS)
|
||||
{
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = 6;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (flesh_impact_count < MAX_IMPACTS)
|
||||
{
|
||||
// negative
|
||||
VectorNegate(vEnd, vEnd);
|
||||
VectorCopy(vStart, flesh_impact_pos[flesh_impact_count]);
|
||||
VectorCopy(vEnd, flesh_impact_norm[flesh_impact_count]);
|
||||
flesh_impact_large[flesh_impact_count] = iLarge;
|
||||
flesh_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (flesh_impact_count < MAX_IMPACTS)
|
||||
{
|
||||
// negative
|
||||
VectorNegate(vEnd, vEnd);
|
||||
VectorCopy(vStart, flesh_impact_pos[flesh_impact_count]);
|
||||
VectorCopy(vEnd, flesh_impact_norm[flesh_impact_count]);
|
||||
flesh_impact_large[flesh_impact_count] = iLarge;
|
||||
flesh_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (wall_impact_count < MAX_IMPACTS)
|
||||
{
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = 2;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (wall_impact_count < MAX_IMPACTS)
|
||||
{
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = 4;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 12:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
vEnd[0] = cgi.MSG_ReadCoord();
|
||||
vEnd[1] = cgi.MSG_ReadCoord();
|
||||
vEnd[2] = cgi.MSG_ReadCoord();
|
||||
CG_MeleeImpact(vStart, vEnd);
|
||||
break;
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
CG_MakeExplosionEffect(vStart, iType);
|
||||
break;
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadDir(vEnd);
|
||||
|
||||
sfxManager.MakeEffect_Normal(iType + 67, vStart, vEnd);
|
||||
break;
|
||||
|
||||
case 26:
|
||||
case 27:
|
||||
{
|
||||
str sEffect;
|
||||
char cTmp[8];
|
||||
vec3_t axis[3];
|
||||
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadByte();
|
||||
// get the integer as string
|
||||
snprintf(cTmp, sizeof(cTmp), "%d", iLarge);
|
||||
|
||||
if (iType == 23) {
|
||||
sEffect = "models/fx/crates/debris_";
|
||||
}
|
||||
else {
|
||||
sEffect = "models/fx/windows/debris_";
|
||||
}
|
||||
|
||||
sEffect += cTmp;
|
||||
sEffect += ".tik";
|
||||
|
||||
VectorSet(axis[0], 0, 0, 1);
|
||||
VectorSet(axis[1], 0, 1, 0);
|
||||
VectorSet(axis[2], 1, 0, 0);
|
||||
|
||||
cgi.R_SpawnEffectModel(sEffect.c_str(), vStart, axis);
|
||||
}
|
||||
break;
|
||||
|
||||
case 28:
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][0] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][1] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(2);
|
||||
if (cgi.MSG_ReadBits(1)) {
|
||||
int iAlpha = cgi.MSG_ReadBits(10);
|
||||
alpha = (float)iAlpha / 512.0;
|
||||
if (alpha < 0.002) {
|
||||
alpha = 0.002;
|
||||
}
|
||||
} else {
|
||||
alpha = 1.0f;
|
||||
}
|
||||
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue, alpha);
|
||||
break;
|
||||
|
||||
case 29:
|
||||
memset(vTmp, 0, sizeof(vTmp));
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][0] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][1] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(1);
|
||||
if (cgi.MSG_ReadBits(1)) {
|
||||
int iAlpha = cgi.MSG_ReadBits(10);
|
||||
alpha = (float)iAlpha / 512.0;
|
||||
if (alpha < 0.002) {
|
||||
alpha = 0.002;
|
||||
}
|
||||
} else {
|
||||
alpha = 1.0f;
|
||||
}
|
||||
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
|
||||
break;
|
||||
|
||||
case 30:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
|
||||
cgi.HudDrawElements[iInfo].string[0] = 0;
|
||||
cgi.HudDrawElements[iInfo].pFont = NULL;
|
||||
cgi.HudDrawElements[iInfo].fontName[0] = 0;
|
||||
// set the shader
|
||||
CG_HudDrawShader(iInfo);
|
||||
break;
|
||||
|
||||
case 31:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].iHorizontalAlign = cgi.MSG_ReadBits(2);
|
||||
cgi.HudDrawElements[iInfo].iVerticalAlign = cgi.MSG_ReadBits(2);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].iX = cgi.MSG_ReadShort();
|
||||
cgi.HudDrawElements[iInfo].iY = cgi.MSG_ReadShort();
|
||||
cgi.HudDrawElements[iInfo].iWidth = cgi.MSG_ReadShort();
|
||||
cgi.HudDrawElements[iInfo].iHeight = cgi.MSG_ReadShort();
|
||||
break;
|
||||
|
||||
case 33:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
|
||||
break;
|
||||
|
||||
case 34:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
case 35:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
case 36:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
|
||||
break;
|
||||
|
||||
case 37:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
cgi.HudDrawElements[iInfo].shaderName[0] = 0;
|
||||
// load the font
|
||||
CG_HudDrawFont(iInfo);
|
||||
break;
|
||||
|
||||
case 38:
|
||||
case 39:
|
||||
{
|
||||
int iOldEnt;
|
||||
|
||||
iOldEnt = current_entity_number;
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
if (iType == 36) {
|
||||
commandManager.PlaySound(
|
||||
"dm_kill_notify",
|
||||
NULL,
|
||||
CHAN_LOCAL,
|
||||
2.0,
|
||||
-1,
|
||||
-1,
|
||||
1
|
||||
);
|
||||
}
|
||||
else {
|
||||
commandManager.PlaySound(
|
||||
"dm_hit_notify",
|
||||
NULL,
|
||||
CHAN_LOCAL,
|
||||
2.0,
|
||||
-1,
|
||||
-1,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
current_entity_number = iOldEnt;
|
||||
}
|
||||
break;
|
||||
|
||||
case 40:
|
||||
{
|
||||
int iOldEnt;
|
||||
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(1);
|
||||
iInfo = cgi.MSG_ReadBits(6);
|
||||
szTmp = cgi.MSG_ReadString();
|
||||
|
||||
iOldEnt = current_entity_number;
|
||||
|
||||
if (iLarge) {
|
||||
current_entity_number = iInfo;
|
||||
|
||||
commandManager.PlaySound(
|
||||
szTmp,
|
||||
vStart,
|
||||
CHAN_LOCAL,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0
|
||||
);
|
||||
}
|
||||
else {
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
|
||||
commandManager.PlaySound(
|
||||
szTmp,
|
||||
vStart,
|
||||
CHAN_AUTO,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
current_entity_number = iOldEnt;
|
||||
}
|
||||
break;
|
||||
case 41:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
vEnd[0] = cgi.MSG_ReadCoord();
|
||||
vEnd[1] = cgi.MSG_ReadCoord();
|
||||
vEnd[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadByte();
|
||||
cgi.MSG_ReadByte();
|
||||
VectorSubtract(vEnd, vStart, vTmp);
|
||||
|
||||
// FIXME: unimplemented
|
||||
// ?? can't figure out what is this
|
||||
break;
|
||||
default:
|
||||
cgi.Error(ERR_DROP, "CG_ParseCGMessage: Unknown CGM message type");
|
||||
break;
|
||||
}
|
||||
|
||||
bMoreCGameMessages = cgi.MSG_ReadBits(1);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void CG_ParseCGMessage()
|
||||
{
|
||||
int i;
|
||||
|
@ -684,10 +1141,12 @@ void CG_ParseCGMessage()
|
|||
current_entity_number = iOldEnt;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cgi.Error(ERR_DROP, "CG_ParseCGMessage: Unknown CGM message type");
|
||||
break;
|
||||
}
|
||||
|
||||
bMoreCGameMessages = cgi.MSG_ReadBits(1);
|
||||
}
|
||||
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,58 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "cg_local.h"
|
||||
|
||||
static const char* IsWeaponAllowed(int dmFlags, int flags) {
|
||||
return (dmFlags & flags) ? "0" : "1";
|
||||
}
|
||||
|
||||
static qboolean QueryLandminesAllowed2(const char* mapname, int dmflags) {
|
||||
if (dmflags & DF_WEAPON_NO_LANDMINE) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (dmflags & DF_WEAPON_LANDMINE_ALWAYS) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if (!Q_stricmpn(mapname, "obj/obj_", 8u))
|
||||
return qfalse;
|
||||
if (!Q_stricmpn(mapname, "dm/mohdm", 8u))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Bahnhof_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "obj/MP_Ardennes_TOW"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Bazaar_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "obj/MP_Berlin_TOW"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Brest_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "obj/MP_Druckkammern_TOW"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Gewitter_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "obj/MP_Flughafen_TOW"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Holland_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Malta_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Stadt_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Unterseite_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Verschneit_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "lib/mp_ship_lib"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "DM/MP_Verschneit_DM"))
|
||||
return qfalse;
|
||||
if (!Q_stricmp(mapname, "lib/mp_ship_lib"))
|
||||
return qfalse;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_ParseServerinfo
|
||||
|
@ -39,6 +91,7 @@ void CG_ParseServerinfo(void)
|
|||
const char* mapname;
|
||||
char map[MAX_QPATH];
|
||||
char* spawnpos;
|
||||
const char* version;
|
||||
|
||||
info = CG_ConfigString(CS_SERVERINFO);
|
||||
cgs.gametype = atoi(Info_ValueForKey(info, "g_gametype"));
|
||||
|
@ -48,6 +101,13 @@ void CG_ParseServerinfo(void)
|
|||
cgs.timelimit = atoi(Info_ValueForKey(info, "timelimit"));
|
||||
cgs.maxclients = atoi(Info_ValueForKey(info, "sv_maxclients"));
|
||||
|
||||
version = Info_ValueForKey(info, "version");
|
||||
if (strstr(version, "Spearhead")) {
|
||||
cgi.Cvar_Set("g_servertype", "1");
|
||||
} else {
|
||||
cgi.Cvar_Set("g_servertype", "2");
|
||||
}
|
||||
|
||||
cgi.Cvar_Set("cg_gametype", Info_ValueForKey(info, "g_gametype"));
|
||||
cgi.Cvar_Set("cg_fraglimit", Info_ValueForKey(info, "fraglimit"));
|
||||
cgi.Cvar_Set("cg_timelimit", Info_ValueForKey(info, "timelimit"));
|
||||
|
@ -60,9 +120,18 @@ void CG_ParseServerinfo(void)
|
|||
cgi.Cvar_Set("cg_obj_axistext3", Info_ValueForKey(info, "cg_obj_axistext3"));
|
||||
cgi.Cvar_Set("cg_scoreboardpic", Info_ValueForKey(info, "g_scoreboardpic"));
|
||||
cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover"));
|
||||
cgs.mapChecksum = Info_ValueForKey(info, "sv_mapChecksum");
|
||||
|
||||
mapname = Info_ValueForKey(info, "mapname");
|
||||
|
||||
cgi.Cvar_Set("cg_weapon_rifle", IsWeaponAllowed(cgs.dmflags, DF_WEAPON_NO_RIFLE));
|
||||
cgi.Cvar_Set("cg_weapon_sniper", IsWeaponAllowed(cgs.dmflags, DF_WEAPON_NO_SNIPER));
|
||||
cgi.Cvar_Set("cg_weapon_mg", IsWeaponAllowed(cgs.dmflags, DF_WEAPON_NO_MG));
|
||||
cgi.Cvar_Set("cg_weapon_smg", IsWeaponAllowed(cgs.dmflags, DF_WEAPON_NO_SMG));
|
||||
cgi.Cvar_Set("cg_weapon_rocket", IsWeaponAllowed(cgs.dmflags, DF_WEAPON_NO_ROCKET));
|
||||
cgi.Cvar_Set("cg_weapon_shotgun", IsWeaponAllowed(cgs.dmflags, DF_WEAPON_NO_SHOTGUN));
|
||||
cgi.Cvar_Set("cg_weapon_landmine", QueryLandminesAllowed2(mapname, cgs.dmflags) ? "1" : "0");
|
||||
|
||||
spawnpos = strchr(mapname, '$');
|
||||
if (spawnpos) {
|
||||
Q_strncpyz(map, mapname, spawnpos - mapname + 1);
|
||||
|
@ -152,7 +221,7 @@ CG_Stopwatch_f
|
|||
*/
|
||||
static void CG_Stopwatch_f()
|
||||
{
|
||||
if (cgi.Argc() != 3) {
|
||||
if (cgi.Argc() < 3) {
|
||||
Com_Error(1, "stopwatch didn't have 2 parameters");
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,40 @@ static const char* AnimPrefixList[] =
|
|||
"bazooka",
|
||||
"panzerschreck",
|
||||
"shotgun",
|
||||
"unarmed"
|
||||
"unarmed",
|
||||
//
|
||||
// Team Assault and Team Tactics weapons
|
||||
"mg42portable",
|
||||
"webley",
|
||||
"nagantrev",
|
||||
"beretta",
|
||||
"enfield",
|
||||
"svt",
|
||||
"mosin",
|
||||
"g43",
|
||||
"enfieldl42a1",
|
||||
"carcano",
|
||||
"delisle",
|
||||
"thompson",
|
||||
"sten",
|
||||
"ppsh",
|
||||
"moschetto",
|
||||
"fg42",
|
||||
"vickers",
|
||||
"breda",
|
||||
"f1grenade",
|
||||
"millsgrenade",
|
||||
"nebelhandgranate",
|
||||
"m18smokegrenade",
|
||||
"rdg1smokegrenade",
|
||||
"bomba",
|
||||
"bombabreda",
|
||||
"mine",
|
||||
"minedetector",
|
||||
"minedetectoraxis",
|
||||
"detonator",
|
||||
"kar98mortar",
|
||||
"PIAT"
|
||||
};
|
||||
|
||||
enum animPrefix_e
|
||||
|
@ -69,7 +102,39 @@ enum animPrefix_e
|
|||
WPREFIX_BAZOOKA,
|
||||
WPREFIX_PANZERSCHRECK,
|
||||
WPREFIX_SHOTGUN,
|
||||
WPREFIX_UNARMED
|
||||
WPREFIX_UNARMED,
|
||||
//
|
||||
// Team Assault and Team Tactics weapons
|
||||
WPREFIX_MG42_PORTABLE,
|
||||
WPREFIX_WEBLEY,
|
||||
WPREFIX_NAGANTREV,
|
||||
WPREFIX_BERETTA,
|
||||
WPREFIX_ENFIELD,
|
||||
WPREFIX_SVT,
|
||||
WPREFIX_MOSIN,
|
||||
WPREFIX_G43,
|
||||
WPREFIX_ENFIELDL42A,
|
||||
WPREFIX_CARCANO,
|
||||
WPREFIX_DELISLE,
|
||||
WPREFIX_STEN,
|
||||
WPREFIX_PPSH,
|
||||
WPREFIX_MOSCHETTO,
|
||||
WPREFIX_FG42,
|
||||
WPREFIX_VICKERS,
|
||||
WPREFIX_BREDA,
|
||||
WPREFIX_F1_GRENADE,
|
||||
WPREFIX_MILLS_GRENADE,
|
||||
WPREFIX_NEBELHANDGRANATE,
|
||||
WPREFIX_M18_SMOKE_GRENADE,
|
||||
WPREFIX_RDG1_SMOKE_GRENADE,
|
||||
WPREFIX_BOMBA,
|
||||
WPREFIX_BOMBA_BREDA,
|
||||
WPREFIX_MINE,
|
||||
WPREFIX_MINE_DETECTOR,
|
||||
WPREFIX_MINE_DETECTOR_AXIS,
|
||||
WPREFIX_DETONATOR,
|
||||
WPREFIX_KAR98_MORTAR,
|
||||
WPREFIX_PIAT
|
||||
};
|
||||
|
||||
int CG_GetVMAnimPrefixIndex()
|
||||
|
@ -83,7 +148,9 @@ int CG_GetVMAnimPrefixIndex()
|
|||
if (iWeaponClass & WEAPON_CLASS_ANY_ITEM)
|
||||
{
|
||||
if (!Q_stricmp(szWeaponName, "Papers"))
|
||||
return WPREFIX_PAPERS;
|
||||
return WPREFIX_PAPERS;
|
||||
if (!Q_stricmp(szWeaponName, "Packed MG42 Turret"))
|
||||
return WPREFIX_MG42_PORTABLE;
|
||||
}
|
||||
else if (iWeaponClass & WEAPON_CLASS_PISTOL)
|
||||
{
|
||||
|
@ -92,7 +159,19 @@ int CG_GetVMAnimPrefixIndex()
|
|||
if (!Q_stricmp(szWeaponName, "Walther P38"))
|
||||
return WPREFIX_P38;
|
||||
if (!Q_stricmp(szWeaponName, "Hi-Standard Silenced"))
|
||||
return WPREFIX_HISTANDARD;
|
||||
return WPREFIX_HISTANDARD;
|
||||
|
||||
//
|
||||
// Team Assault and Team Tactics
|
||||
//
|
||||
if (!Q_stricmp(szWeaponName, "Webley Revolver"))
|
||||
return WPREFIX_WEBLEY;
|
||||
if (!Q_stricmp(szWeaponName, "Nagant Revolver"))
|
||||
return WPREFIX_NAGANTREV;
|
||||
if (!Q_stricmp(szWeaponName, "Beretta"))
|
||||
return WPREFIX_BERETTA;
|
||||
|
||||
return WPREFIX_COLT45;
|
||||
}
|
||||
else if (iWeaponClass & WEAPON_CLASS_RIFLE)
|
||||
{
|
||||
|
@ -103,28 +182,97 @@ int CG_GetVMAnimPrefixIndex()
|
|||
if (!Q_stricmp(szWeaponName, "KAR98 - Sniper"))
|
||||
return WPREFIX_KAR98SNIPER;
|
||||
if (!Q_stricmp(szWeaponName, "Springfield '03 Sniper"))
|
||||
return WPREFIX_SPRINGFIELD;
|
||||
return WPREFIX_SPRINGFIELD;
|
||||
|
||||
//
|
||||
// Team Assault and Team Tactics
|
||||
//
|
||||
if (!Q_stricmp(szWeaponName, "Lee-Enfield"))
|
||||
return WPREFIX_SPRINGFIELD;
|
||||
if (!Q_stricmp(szWeaponName, "SVT 40"))
|
||||
return WPREFIX_SVT;
|
||||
if (!Q_stricmp(szWeaponName, "Mosin Nagant Rifle"))
|
||||
return WPREFIX_MOSIN;
|
||||
if (!Q_stricmp(szWeaponName, "G 43"))
|
||||
return WPREFIX_G43;
|
||||
if (!Q_stricmp(szWeaponName, "Enfield L42A1"))
|
||||
return WPREFIX_ENFIELD;
|
||||
if (!Q_stricmp(szWeaponName, "Carcano"))
|
||||
return WPREFIX_CARCANO;
|
||||
if (!Q_stricmp(szWeaponName, "DeLisle"))
|
||||
return WPREFIX_DELISLE;
|
||||
|
||||
return WPREFIX_GARAND;
|
||||
}
|
||||
else if (iWeaponClass & WEAPON_CLASS_SMG)
|
||||
{
|
||||
if (!Q_stricmp(szWeaponName, "Thompson"))
|
||||
return WPREFIX_THOMPSON;
|
||||
if (!Q_stricmp(szWeaponName, "MP40"))
|
||||
return WPREFIX_MP40;
|
||||
return WPREFIX_MP40;
|
||||
//
|
||||
// Team Assault and Team Tactics
|
||||
//
|
||||
if (!Q_stricmp(szWeaponName, "Sten Mark II"))
|
||||
return WPREFIX_STEN;
|
||||
if (!Q_stricmp(szWeaponName, "PPSH SMG"))
|
||||
return WPREFIX_PPSH;
|
||||
if (!Q_stricmp(szWeaponName, "Moschetto"))
|
||||
return WPREFIX_MOSCHETTO;
|
||||
|
||||
return WPREFIX_THOMPSON;
|
||||
}
|
||||
else if (iWeaponClass & WEAPON_CLASS_MG)
|
||||
{
|
||||
if (!Q_stricmp(szWeaponName, "BAR"))
|
||||
return WPREFIX_BAR;
|
||||
if (!Q_stricmp(szWeaponName, "StG 44"))
|
||||
return WPREFIX_MP44;
|
||||
return WPREFIX_MP44;
|
||||
//
|
||||
// Team Assault and Team Tactics
|
||||
//
|
||||
if (!Q_stricmp(szWeaponName, "FG 42"))
|
||||
return WPREFIX_MP44;
|
||||
if (!Q_stricmp(szWeaponName, "Vickers-Berthier"))
|
||||
return WPREFIX_MP44;
|
||||
if (!Q_stricmp(szWeaponName, "Breda"))
|
||||
return WPREFIX_MP44;
|
||||
|
||||
return WPREFIX_BAR;
|
||||
}
|
||||
else if (iWeaponClass & WEAPON_CLASS_GRENADE)
|
||||
{
|
||||
if (!Q_stricmp(szWeaponName, "Frag Grenade"))
|
||||
return WPREFIX_FRAGGRENADE;
|
||||
if (!Q_stricmp(szWeaponName, "Stielhandgranate"))
|
||||
return WPREFIX_STIELHANDGRANATE;
|
||||
return WPREFIX_STIELHANDGRANATE;
|
||||
//
|
||||
// Team Assault and Team Tactics
|
||||
//
|
||||
if (!Q_stricmp(szWeaponName, "F1 Grenade"))
|
||||
return WPREFIX_F1_GRENADE;
|
||||
if (!Q_stricmp(szWeaponName, "Mills Grenade"))
|
||||
return WPREFIX_MILLS_GRENADE;
|
||||
if (!Q_stricmp(szWeaponName, "Nebelhandgranate"))
|
||||
return WPREFIX_NEBELHANDGRANATE;
|
||||
if (!Q_stricmp(szWeaponName, "M18 Smoke Grenade"))
|
||||
return WPREFIX_M18_SMOKE_GRENADE;
|
||||
if (!Q_stricmp(szWeaponName, "RDG-1 Smoke Grenade"))
|
||||
return WPREFIX_RDG1_SMOKE_GRENADE;
|
||||
if (!Q_stricmp(szWeaponName, "Bomba A Mano"))
|
||||
return WPREFIX_BOMBA;
|
||||
if (!Q_stricmp(szWeaponName, "Bomba A Mano Breda"))
|
||||
return WPREFIX_BOMBA_BREDA;
|
||||
if (!Q_stricmp(szWeaponName, "LandmineAllies"))
|
||||
return WPREFIX_MINE;
|
||||
if (!Q_stricmp(szWeaponName, "LandmineAxis"))
|
||||
return WPREFIX_MINE;
|
||||
if (!Q_stricmp(szWeaponName, "Minensuchgerat"))
|
||||
return WPREFIX_MINE_DETECTOR_AXIS;
|
||||
if (!Q_stricmp(szWeaponName, "Minedetector"))
|
||||
return WPREFIX_MINE_DETECTOR;
|
||||
|
||||
return WPREFIX_FRAGGRENADE;
|
||||
}
|
||||
else if (iWeaponClass & WEAPON_CLASS_HEAVY)
|
||||
{
|
||||
|
@ -133,7 +281,14 @@ int CG_GetVMAnimPrefixIndex()
|
|||
if (!Q_stricmp(szWeaponName, "Panzerschreck"))
|
||||
return WPREFIX_PANZERSCHRECK;
|
||||
if (!Q_stricmp(szWeaponName, "Shotgun"))
|
||||
return WPREFIX_SHOTGUN;
|
||||
return WPREFIX_SHOTGUN;
|
||||
//
|
||||
// Team Assault and Team Tactics
|
||||
//
|
||||
if (!Q_stricmp(szWeaponName, "PIAT"))
|
||||
return WPREFIX_PIAT;
|
||||
|
||||
return WPREFIX_BAZOOKA;
|
||||
}
|
||||
|
||||
return WPREFIX_UNARMED;
|
||||
|
@ -226,10 +381,22 @@ void CG_ViewModelAnimation(refEntity_t* pModel)
|
|||
case VM_ANIM_LADDERSTEP:
|
||||
pszAnimSuffix = "ladderstep";
|
||||
break;
|
||||
case VM_ANIM_IDLE:
|
||||
case VM_ANIM_IDLE_0:
|
||||
pszAnimSuffix = "idle0";
|
||||
break;
|
||||
case VM_ANIM_IDLE_1:
|
||||
pszAnimSuffix = "idle1";
|
||||
break;
|
||||
case VM_ANIM_IDLE_2:
|
||||
pszAnimSuffix = "idle2";
|
||||
break;
|
||||
case VM_ANIM_DISABLED:
|
||||
pszAnimSuffix = "disabled";
|
||||
break;
|
||||
default:
|
||||
pszAnimSuffix = "idle";
|
||||
break;
|
||||
case VM_ANIM_IDLE:
|
||||
pszAnimSuffix = "idle";
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(szAnimName, "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
|
||||
|
|
|
@ -865,7 +865,7 @@ void CL_WritePacket( void ) {
|
|||
for ( i = clc.reliableAcknowledge + 1 ; i <= clc.reliableSequence ; i++ ) {
|
||||
MSG_WriteByte( &buf, clc_clientCommand );
|
||||
MSG_WriteLong( &buf, i );
|
||||
MSG_WriteString( &buf, clc.reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
|
||||
MSG_WriteScrambledString( &buf, clc.reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
|
||||
}
|
||||
|
||||
// we want to send all the usercmds that were generated in the last
|
||||
|
|
|
@ -1820,7 +1820,11 @@ wombat: sending conect here: an example connect string from MOHAA looks like thi
|
|||
Q_strncpyz( info, Cvar_InfoString( CVAR_USERINFO ), sizeof( info ) );
|
||||
Info_SetValueForKey( info, "protocol", va("%i", PROTOCOL_VERSION ) );
|
||||
Info_SetValueForKey( info, "qport", va("%i", port ) );
|
||||
Info_SetValueForKey( info, "challenge", va("%i", clc.challenge ) );
|
||||
Info_SetValueForKey(info, "challenge", va("%i", clc.challenge));
|
||||
Info_SetValueForKey(info, "version", TARGET_GAME_VERSION);
|
||||
#if TARGET_GAME_TYPE == 2
|
||||
Info_SetValueForKey(info, "clientType", "Breakthrough");
|
||||
#endif
|
||||
|
||||
strcpy(data, "connect ");
|
||||
// TTimo adding " " around the userinfo string to avoid truncated userinfo on the server
|
||||
|
|
|
@ -75,8 +75,7 @@ void CL_DeltaEntity (msg_t *msg, clSnapshot_t *frame, int newnum, entityState_t
|
|||
if ( unchanged ) {
|
||||
*state = *old;
|
||||
} else {
|
||||
// FIXME: frametime
|
||||
MSG_ReadDeltaEntity( msg, old, state, newnum, 0.0);
|
||||
MSG_ReadDeltaEntity( msg, old, state, newnum, cls.serverFrameTime);
|
||||
}
|
||||
|
||||
if ( state->number == (MAX_GENTITIES-1) ) {
|
||||
|
@ -117,7 +116,7 @@ void CL_ParsePacketEntities( msg_t *msg, clSnapshot_t *oldframe, clSnapshot_t *n
|
|||
|
||||
while ( 1 ) {
|
||||
// read the entity index number
|
||||
newnum = MSG_ReadBits( msg, GENTITYNUM_BITS );
|
||||
newnum = MSG_ReadEntityNum(msg);
|
||||
|
||||
if ( newnum == (MAX_GENTITIES-1) ) {
|
||||
break;
|
||||
|
@ -274,11 +273,10 @@ void CL_ParseSnapshot( msg_t *msg ) {
|
|||
|
||||
// read playerinfo
|
||||
SHOWNET(msg, "playerstate");
|
||||
// FIXME: frametime
|
||||
if ( old ) {
|
||||
MSG_ReadDeltaPlayerstate( msg, &old->ps, &newSnap.ps, 0.0 );
|
||||
MSG_ReadDeltaPlayerstate( msg, &old->ps, &newSnap.ps, cls.serverFrameTime );
|
||||
} else {
|
||||
MSG_ReadDeltaPlayerstate( msg, NULL, &newSnap.ps, 0.0);
|
||||
MSG_ReadDeltaPlayerstate( msg, NULL, &newSnap.ps, cls.serverFrameTime);
|
||||
}
|
||||
|
||||
// read packet entities
|
||||
|
@ -446,6 +444,28 @@ static void CL_ParseServerInfo(void)
|
|||
sizeof(clc.sv_dlURL));
|
||||
}
|
||||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
|
||||
char* MSG_ReadGameStateChar(msg_t* msg) {
|
||||
return MSG_ReadScrambledBigString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime(msg_t* msg) {
|
||||
return MSG_ReadFloat(msg);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char* MSG_ReadGameStateChar(msg_t* msg) {
|
||||
return MSG_ReadString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime(msg_t* msg) {
|
||||
return 1.f / atof(Info_ValueForKey(cl.gameState.stringData + cl.gameState.stringOffsets[CS_SYSTEMINFO], "sv_fps"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseGamestate
|
||||
|
@ -488,7 +508,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
if ( i < 0 || i >= MAX_CONFIGSTRINGS ) {
|
||||
Com_Error( ERR_DROP, "configstring > MAX_CONFIGSTRINGS" );
|
||||
}
|
||||
s = MSG_ReadString( msg );
|
||||
s = MSG_ReadGameStateChar( msg );
|
||||
len = strlen( s );
|
||||
|
||||
if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) {
|
||||
|
@ -499,7 +519,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
Com_Memcpy( cl.gameState.stringData + cl.gameState.dataCount, s, len + 1 );
|
||||
cl.gameState.dataCount += len + 1;
|
||||
} else if ( cmd == svc_baseline ) {
|
||||
newnum = MSG_ReadBits( msg, GENTITYNUM_BITS );
|
||||
newnum = MSG_ReadEntityNum(msg);
|
||||
if ( newnum < 0 || newnum >= MAX_GENTITIES ) {
|
||||
Com_Error( ERR_DROP, "Baseline number out of range: %i", newnum );
|
||||
}
|
||||
|
@ -516,6 +536,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
clc.clientNum = MSG_ReadLong(msg);
|
||||
// read the checksum feed
|
||||
clc.checksumFeed = MSG_ReadLong( msg );
|
||||
cls.serverFrameTime = MSG_ReadServerFrameTime(msg);
|
||||
|
||||
// parse serverId and other cvars
|
||||
CL_SystemInfoChanged();
|
||||
|
@ -727,7 +748,7 @@ void CL_ParseCommandString( msg_t *msg ) {
|
|||
int index;
|
||||
|
||||
seq = MSG_ReadLong( msg );
|
||||
s = MSG_ReadString( msg );
|
||||
s = MSG_ReadScrambledString( msg );
|
||||
|
||||
// see if we have already executed stored it off
|
||||
if ( clc.serverCommandSequence >= seq ) {
|
||||
|
@ -764,10 +785,9 @@ void CL_ParseLocationprint( msg_t *msg ) {
|
|||
|
||||
x = MSG_ReadShort( msg );
|
||||
y = MSG_ReadShort( msg );
|
||||
string = MSG_ReadString(msg);
|
||||
string = MSG_ReadScrambledString(msg);
|
||||
|
||||
// FIXME
|
||||
//UI_UpdateLocationPrint( x, y, string, 1.0 );
|
||||
UI_UpdateLocationPrint( x, y, string, 1.0 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -778,10 +798,10 @@ CL_ParseCenterprint
|
|||
void CL_ParseCenterprint( msg_t *msg ) {
|
||||
char *string;
|
||||
|
||||
string = MSG_ReadString( msg );
|
||||
string = MSG_ReadScrambledString( msg );
|
||||
|
||||
// FIXME
|
||||
//UI_UpdateCenterPrintf( string, 1.0 );
|
||||
UI_UpdateCenterPrint( string, 1.0 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -882,9 +882,9 @@ void CM_LoadMap( const char *name, qboolean clientload, int *checksum ) {
|
|||
((int *)&header)[i] = LittleLong ( ((int *)&header)[i]);
|
||||
}
|
||||
|
||||
if ( header.version != BSP_VERSION ) {
|
||||
Com_Error (ERR_DROP, "CM_LoadMap: %s has wrong version number (%i should be %i)"
|
||||
, name, header.version, BSP_VERSION );
|
||||
if ( header.version < BSP_MIN_VERSION || header.version > BSP_MAX_VERSION ) {
|
||||
Com_Error (ERR_DROP, "CM_LoadMap: %s has wrong version number (%i should be between %i and %i)"
|
||||
, name, header.version, BSP_MIN_VERSION, BSP_MAX_VERSION );
|
||||
}
|
||||
|
||||
cmod_base = ( byte * )&header;
|
||||
|
|
|
@ -3068,7 +3068,7 @@ static void FS_ReorderPurePaks( void )
|
|||
FS_Startup
|
||||
================
|
||||
*/
|
||||
static void FS_Startup( const char *gameName )
|
||||
static void FS_Startup(const char* gameName, const char* extensionName)
|
||||
{
|
||||
const char* homePath;
|
||||
|
||||
|
@ -3087,10 +3087,16 @@ static void FS_Startup( const char *gameName )
|
|||
fs_gamedirvar = Cvar_Get( "fs_game", "", CVAR_INIT | CVAR_SYSTEMINFO );
|
||||
fs_restrict = Cvar_Get( "fs_restrict", "", CVAR_INIT );
|
||||
|
||||
FS_AddGameDirectory( fs_basepath->string, gameName );
|
||||
if (gameName) {
|
||||
FS_AddGameDirectory(fs_basepath->string, gameName);
|
||||
}
|
||||
|
||||
if( *fs_gamedirvar->string && !Q_stricmp( gameName, "main" ) && Q_stricmp( fs_gamedirvar->string, gameName ) ) {
|
||||
FS_AddGameDirectory( fs_basepath->string, fs_gamedirvar->string );
|
||||
if (Q_stricmp(gameName, extensionName)) {
|
||||
FS_AddGameDirectory(fs_basepath->string, extensionName);
|
||||
}
|
||||
|
||||
if (*fs_gamedirvar->string && !Q_stricmp(gameName, GAME_EXTENSION_BASE) && Q_stricmp(fs_gamedirvar->string, gameName)) {
|
||||
FS_AddGameDirectory(fs_basepath->string, fs_gamedirvar->string);
|
||||
}
|
||||
|
||||
fs_mapdir = Cvar_Get( "mapdir", "", 0 );
|
||||
|
@ -3594,7 +3600,7 @@ void FS_InitFilesystem( void ) {
|
|||
Com_StartupVariable( "fs_homepath" );
|
||||
|
||||
// try to start up normally
|
||||
FS_Startup( BASEGAME );
|
||||
FS_Startup( BASEGAME, GAME_EXTENSION_BASE);
|
||||
FS_SetRestrictions();
|
||||
|
||||
if( !silentStart ) {
|
||||
|
@ -3640,7 +3646,7 @@ void FS_Restart( int checksumFeed ) {
|
|||
FS_ClearPakReferences(0);
|
||||
|
||||
// try to start up normally
|
||||
FS_Startup( BASEGAME );
|
||||
FS_Startup(BASEGAME, GAME_EXTENSION_BASE);
|
||||
|
||||
FS_CheckPak0( );
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@ int oldsize = 0;
|
|||
// TA stuff
|
||||
//===================
|
||||
|
||||
static constexpr unsigned int MAX_PACKED_COORD = 65536;
|
||||
static constexpr unsigned int MAX_PACKED_COORD_HALF = MAX_PACKED_COORD / 2;
|
||||
static constexpr unsigned int MAX_PACKED_COORD_EXTRA = 262144;
|
||||
static constexpr unsigned int MAX_PACKED_COORD_EXTRA_HALF = MAX_PACKED_COORD_EXTRA / 2;
|
||||
static constexpr int MAX_PACKED_COORD = 65536;
|
||||
static constexpr int MAX_PACKED_COORD_HALF = MAX_PACKED_COORD / 2;
|
||||
static constexpr int MAX_PACKED_COORD_EXTRA = 262144;
|
||||
static constexpr int MAX_PACKED_COORD_EXTRA_HALF = MAX_PACKED_COORD_EXTRA / 2;
|
||||
|
||||
//===
|
||||
// Statistics for changes reporting
|
||||
|
@ -327,8 +327,10 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
|
|||
msg->readcount = (msg->bit>>3)+1;
|
||||
}
|
||||
if (sgn) {
|
||||
if (value & (1 << (bits - 1))) {
|
||||
value |= -1 ^ ((1 << bits) - 1);
|
||||
if (value & 1) {
|
||||
value = ~(value >> 1);
|
||||
} else {
|
||||
value >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,6 +419,32 @@ void MSG_WriteString( msg_t *sb, const char *s ) {
|
|||
}
|
||||
}
|
||||
|
||||
void MSG_WriteBigString( msg_t *sb, const char *s ) {
|
||||
if ( !s ) {
|
||||
MSG_WriteByte(sb, 0);
|
||||
} else {
|
||||
size_t l;
|
||||
int i;
|
||||
char string[BIG_INFO_STRING];
|
||||
|
||||
l = strlen( s );
|
||||
if ( l >= BIG_INFO_STRING ) {
|
||||
Com_Printf("MSG_WriteString: BIG_INFO_STRING");
|
||||
MSG_WriteByte(sb, 0);
|
||||
return;
|
||||
}
|
||||
Q_strncpyz( string, s, sizeof( string ) );
|
||||
|
||||
for ( i = 0 ; i <= l ; i++ ) {
|
||||
MSG_WriteByte(sb, string[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
|
||||
void MSG_WriteScrambledString(msg_t* sb, const char* s) {
|
||||
if (!s) {
|
||||
strstats[0]++;
|
||||
|
@ -444,28 +472,6 @@ void MSG_WriteScrambledString(msg_t* sb, const char* s) {
|
|||
}
|
||||
}
|
||||
|
||||
void MSG_WriteBigString( msg_t *sb, const char *s ) {
|
||||
if ( !s ) {
|
||||
MSG_WriteByte(sb, 0);
|
||||
} else {
|
||||
size_t l;
|
||||
int i;
|
||||
char string[BIG_INFO_STRING];
|
||||
|
||||
l = strlen( s );
|
||||
if ( l >= BIG_INFO_STRING ) {
|
||||
Com_Printf("MSG_WriteString: BIG_INFO_STRING");
|
||||
MSG_WriteByte(sb, 0);
|
||||
return;
|
||||
}
|
||||
Q_strncpyz( string, s, sizeof( string ) );
|
||||
|
||||
for ( i = 0 ; i <= l ; i++ ) {
|
||||
MSG_WriteByte(sb, string[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MSG_WriteScrambledBigString(msg_t* sb, const char* s) {
|
||||
if (!s) {
|
||||
strstats[0]++;
|
||||
|
@ -493,6 +499,18 @@ void MSG_WriteScrambledBigString(msg_t* sb, const char* s) {
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void MSG_WriteScrambledString(msg_t* sb, const char* s) {
|
||||
return MSG_WriteString(sb, s);
|
||||
}
|
||||
|
||||
void MSG_WriteScrambledBigString(msg_t* sb, const char* s) {
|
||||
return MSG_WriteBigString(sb, s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void MSG_WriteAngle( msg_t *sb, float f ) {
|
||||
MSG_WriteByte (sb, (int)(f*256/360) & 255);
|
||||
}
|
||||
|
@ -598,6 +616,8 @@ float MSG_ReadFloat( msg_t *msg ) {
|
|||
return dat.f;
|
||||
}
|
||||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
|
||||
char* MSG_ReadScrambledString(msg_t* msg) {
|
||||
static char string[MAX_STRING_CHARS];
|
||||
int l, c;
|
||||
|
@ -610,6 +630,9 @@ char* MSG_ReadScrambledString(msg_t* msg) {
|
|||
}
|
||||
|
||||
c = NetByteToStrChar[c];
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
// translate all fmt spec to avoid crash bugs
|
||||
if (c == '%') {
|
||||
c = '.';
|
||||
|
@ -629,6 +652,52 @@ char* MSG_ReadScrambledString(msg_t* msg) {
|
|||
return string;
|
||||
}
|
||||
|
||||
char* MSG_ReadScrambledBigString(msg_t* msg) {
|
||||
static char string[BIG_INFO_STRING];
|
||||
int l, c;
|
||||
|
||||
l = 0;
|
||||
do {
|
||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
c = NetByteToStrChar[c];
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
// translate all fmt spec to avoid crash bugs
|
||||
if (c == '%') {
|
||||
c = '.';
|
||||
}
|
||||
// don't allow higher ascii values
|
||||
// (su44: this check is missing in MoHAA)
|
||||
if (c > 127) {
|
||||
c = '.';
|
||||
}
|
||||
|
||||
string[l] = c;
|
||||
l++;
|
||||
} while (l < sizeof(string) - 1);
|
||||
|
||||
string[l] = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char* MSG_ReadScrambledString(msg_t* msg) {
|
||||
return MSG_ReadString(msg);
|
||||
}
|
||||
|
||||
char* MSG_ReadScrambledBigString(msg_t* msg) {
|
||||
return MSG_ReadBigString(msg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *MSG_ReadString( msg_t *msg ) {
|
||||
static char string[MAX_STRING_CHARS];
|
||||
int l,c;
|
||||
|
@ -1171,6 +1240,157 @@ typedef struct {
|
|||
// using the stringizing operator to save typing...
|
||||
#define NETF(x) #x,(size_t)&((entityState_t*)0)->x
|
||||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
netField_t entityStateFields[] =
|
||||
{
|
||||
{ NETF(netorigin[0]), 0, netFieldType_t::coord },
|
||||
{ NETF(netorigin[1]), 0, netFieldType_t::coord },
|
||||
{ NETF(netangles[1]), 12, netFieldType_t::angle },
|
||||
{ NETF(frameInfo[0].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[1].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(bone_angles[0][0]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[3][0]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[1][0]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[2][0]), -13, netFieldType_t::angle },
|
||||
{ NETF(netorigin[2]), 0, netFieldType_t::coord },
|
||||
{ NETF(frameInfo[0].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[1].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[2].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[3].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[0].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[1].index), 12, netFieldType_t::regular },
|
||||
{ NETF(actionWeight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[2].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[3].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[2].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[3].index), 12, netFieldType_t::regular },
|
||||
{ NETF(eType), 8, netFieldType_t::regular },
|
||||
{ NETF(modelindex), 16, netFieldType_t::regular },
|
||||
{ NETF(parent), 16, netFieldType_t::regular },
|
||||
{ NETF(constantLight), 32, netFieldType_t::regular },
|
||||
{ NETF(renderfx), 32, netFieldType_t::regular },
|
||||
{ NETF(bone_tag[0]), -8, netFieldType_t::regular },
|
||||
{ NETF(bone_tag[1]), -8, netFieldType_t::regular },
|
||||
{ NETF(bone_tag[2]), -8, netFieldType_t::regular },
|
||||
{ NETF(bone_tag[3]), -8, netFieldType_t::regular },
|
||||
{ NETF(bone_tag[4]), -8, netFieldType_t::regular },
|
||||
{ NETF(scale), 10, netFieldType_t::scale },
|
||||
{ NETF(alpha), 8, netFieldType_t::alpha },
|
||||
{ NETF(usageIndex), 16, netFieldType_t::regular },
|
||||
{ NETF(eFlags), 16, netFieldType_t::regular },
|
||||
{ NETF(solid), 32, netFieldType_t::regular },
|
||||
{ NETF(netangles[2]), 12, netFieldType_t::angle },
|
||||
{ NETF(netangles[0]), 12, netFieldType_t::angle },
|
||||
{ NETF(tag_num), 10, netFieldType_t::regular },
|
||||
{ NETF(bone_angles[1][2]), -13, netFieldType_t::angle },
|
||||
{ NETF(attach_use_angles), 1, netFieldType_t::regular },
|
||||
{ NETF(origin2[1]), 0, netFieldType_t::coord },
|
||||
{ NETF(origin2[0]), 0, netFieldType_t::coord },
|
||||
{ NETF(origin2[2]), 0, netFieldType_t::coord },
|
||||
{ NETF(bone_angles[0][2]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[2][2]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[3][2]), -13, netFieldType_t::angle },
|
||||
{ NETF(surfaces[0]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[1]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[2]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[3]), 8, netFieldType_t::regular },
|
||||
{ NETF(bone_angles[0][1]), -13, netFieldType_t::angle },
|
||||
{ NETF(surfaces[4]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[5]), 8, netFieldType_t::regular },
|
||||
{ NETF(pos.trTime), 32, netFieldType_t::regular },
|
||||
{ NETF(pos.trDelta[0]), 0, netFieldType_t::velocity },
|
||||
{ NETF(pos.trDelta[1]), 0, netFieldType_t::velocity },
|
||||
{ NETF(pos.trDelta[2]), 0, netFieldType_t::velocity },
|
||||
{ NETF(loopSound), 16, netFieldType_t::regular },
|
||||
{ NETF(loopSoundVolume), 0, netFieldType_t::regular },
|
||||
{ NETF(loopSoundMinDist), 0, netFieldType_t::regular },
|
||||
{ NETF(loopSoundMaxDist), 0, netFieldType_t::regular },
|
||||
{ NETF(loopSoundPitch), 0, netFieldType_t::regular },
|
||||
{ NETF(loopSoundFlags), 8, netFieldType_t::regular },
|
||||
{ NETF(attach_offset[0]), 0, netFieldType_t::regular },
|
||||
{ NETF(attach_offset[1]), 0, netFieldType_t::regular },
|
||||
{ NETF(attach_offset[2]), 0, netFieldType_t::regular },
|
||||
{ NETF(beam_entnum), 16, netFieldType_t::regular },
|
||||
{ NETF(skinNum), 16, netFieldType_t::regular },
|
||||
{ NETF(wasframe), 10, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[4].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[5].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[6].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[7].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[8].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[9].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[10].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[11].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[12].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[13].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[14].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[15].index), 12, netFieldType_t::regular },
|
||||
{ NETF(frameInfo[4].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[5].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[6].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[7].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[8].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[9].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[10].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[11].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[12].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[13].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[14].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[15].time), 15, netFieldType_t::animTime },
|
||||
{ NETF(frameInfo[4].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[5].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[6].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[7].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[8].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[9].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[10].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[11].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[12].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[13].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[14].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(frameInfo[15].weight), 8, netFieldType_t::animWeight },
|
||||
{ NETF(bone_angles[1][1]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[2][1]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[3][1]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[4][0]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[4][1]), -13, netFieldType_t::angle },
|
||||
{ NETF(bone_angles[4][2]), -13, netFieldType_t::angle },
|
||||
{ NETF(clientNum), 8, netFieldType_t::regular },
|
||||
{ NETF(groundEntityNum), GENTITYNUM_BITS, netFieldType_t::regular },
|
||||
{ NETF(shader_data[0]), 0, netFieldType_t::regular },
|
||||
{ NETF(shader_data[1]), 0, netFieldType_t::regular },
|
||||
{ NETF(shader_time), 0, netFieldType_t::regular },
|
||||
{ NETF(eyeVector[0]), 0, netFieldType_t::regular },
|
||||
{ NETF(eyeVector[1]), 0, netFieldType_t::regular },
|
||||
{ NETF(eyeVector[2]), 0, netFieldType_t::regular },
|
||||
{ NETF(surfaces[6]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[7]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[8]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[9]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[10]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[11]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[12]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[13]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[14]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[15]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[16]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[17]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[18]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[19]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[20]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[21]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[22]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[23]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[24]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[25]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[26]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[27]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[28]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[29]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[30]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[31]), 8, netFieldType_t::regular }
|
||||
};
|
||||
#else
|
||||
netField_t entityStateFields[] =
|
||||
{
|
||||
{ NETF(netorigin[0]), 0, netFieldType_t::coord },
|
||||
|
@ -1320,6 +1540,7 @@ netField_t entityStateFields[] =
|
|||
{ NETF(surfaces[30]), 8, netFieldType_t::regular },
|
||||
{ NETF(surfaces[31]), 8, netFieldType_t::regular }
|
||||
};
|
||||
#endif
|
||||
static constexpr unsigned long numEntityFields = sizeof(entityStateFields) / sizeof(entityStateFields[0]);
|
||||
|
||||
// if (int)f == f and (int)f + ( 1<<(FLOAT_INT_BITS-1) ) < ( 1 << FLOAT_INT_BITS )
|
||||
|
@ -1343,22 +1564,25 @@ void MSG_ReadRegular(msg_t* sb, int bits, void* toF)
|
|||
if (!MSG_ReadBits(sb, 1))
|
||||
{
|
||||
// integral float
|
||||
int32_t truncFloat = MSG_ReadBits(sb, -FLOAT_INT_BITS);
|
||||
// bias to allow equal parts positive and negative
|
||||
truncFloat -= FLOAT_INT_BIAS;
|
||||
*(float*)toF = (float)truncFloat;
|
||||
*(float*)toF = MSG_ReadBits(sb, -FLOAT_INT_BITS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// full floating point value
|
||||
*(float*)toF = MSG_ReadFloat(sb);
|
||||
unsigned int v = MSG_ReadBits(sb, 32);
|
||||
if (v & 1) {
|
||||
*(int*)toF = ((v + 0x7A000000) >> 1) | 0x80000000;
|
||||
}
|
||||
else {
|
||||
*(int*)toF = (v + 0x7A000000) >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MSG_ReadBits(msg, 1)) {
|
||||
*(int*)toF = MSG_ReadBits(msg, bits);
|
||||
if (MSG_ReadBits(sb, 1)) {
|
||||
*(int*)toF = MSG_ReadBits(sb, bits);
|
||||
}
|
||||
else {
|
||||
*(int*)toF = 0;
|
||||
|
@ -1366,6 +1590,11 @@ void MSG_ReadRegular(msg_t* sb, int bits, void* toF)
|
|||
}
|
||||
}
|
||||
|
||||
void MSG_ReadRegularSimple(msg_t* sb, int bits, void* toF)
|
||||
{
|
||||
MSG_ReadRegular(sb, bits, toF);
|
||||
}
|
||||
|
||||
void MSG_WriteRegular(msg_t* sb, int bits, const void* toF)
|
||||
{
|
||||
float fullFloat;
|
||||
|
@ -1418,9 +1647,9 @@ void MSG_WriteEntityNum(msg_t* sb, short number)
|
|||
MSG_WriteBits(sb, (number + 1) % MAX_GENTITIES, GENTITYNUM_BITS);
|
||||
}
|
||||
|
||||
short MSG_ReadEntityNum(msg_t* sb)
|
||||
unsigned short MSG_ReadEntityNum(msg_t* sb)
|
||||
{
|
||||
return (MSG_ReadBits(sb, GENTITYNUM_BITS) - 1) % MAX_GENTITIES;
|
||||
return (unsigned short)(MSG_ReadBits(sb, GENTITYNUM_BITS) - 1) % MAX_GENTITIES;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -1436,7 +1665,7 @@ void MSG_ReadRegular(msg_t* sb, int bits, void* toF)
|
|||
else
|
||||
{
|
||||
if (!MSG_ReadBits(sb, 1)) {
|
||||
*(float*)toF = (float)MSG_ReadBits(sb, FLOAT_INT_BITS);
|
||||
*(float*)toF = (int)MSG_ReadBits(sb, FLOAT_INT_BITS) - FLOAT_INT_BIAS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1456,6 +1685,28 @@ void MSG_ReadRegular(msg_t* sb, int bits, void* toF)
|
|||
}
|
||||
}
|
||||
|
||||
void MSG_ReadRegularSimple(msg_t* sb, int bits, void* toF)
|
||||
{
|
||||
if (bits == 0) {
|
||||
// float
|
||||
if (MSG_ReadBits(sb, 1) == 0) {
|
||||
// integral float
|
||||
int trunc = MSG_ReadBits(sb, FLOAT_INT_BITS);
|
||||
// bias to allow equal parts positive and negative
|
||||
trunc -= FLOAT_INT_BIAS;
|
||||
*(float*)toF = trunc;
|
||||
}
|
||||
else {
|
||||
// full floating point value
|
||||
*(int*)toF = MSG_ReadBits(sb, 32);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// integer
|
||||
*(int*)toF = MSG_ReadBits(sb, bits);
|
||||
}
|
||||
}
|
||||
|
||||
void MSG_WriteRegular(msg_t* sb, int bits, const void* toF)
|
||||
{
|
||||
float fullFloat;
|
||||
|
@ -1530,7 +1781,7 @@ void MSG_WriteEntityNum(msg_t* sb, short number)
|
|||
MSG_WriteBits(sb, number % MAX_GENTITIES, GENTITYNUM_BITS);
|
||||
}
|
||||
|
||||
short MSG_ReadEntityNum(msg_t* sb)
|
||||
unsigned short MSG_ReadEntityNum(msg_t* sb)
|
||||
{
|
||||
return MSG_ReadBits(sb, GENTITYNUM_BITS) % MAX_GENTITIES;
|
||||
}
|
||||
|
@ -1568,7 +1819,7 @@ void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entity
|
|||
if ( from == NULL ) {
|
||||
return;
|
||||
}
|
||||
MSG_WriteBits( msg, from->number, GENTITYNUM_BITS );
|
||||
MSG_WriteEntityNum(msg, to->number);
|
||||
MSG_WriteBits( msg, 1, 1 );
|
||||
return;
|
||||
}
|
||||
|
@ -1813,6 +2064,55 @@ int MSG_PackCoordExtra(float coord)
|
|||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
|
||||
float MSG_ReadPackedAngle(msg_t* msg, int bits)
|
||||
{
|
||||
int packed = MSG_ReadBits(msg, bits);
|
||||
return MSG_UnpackAngle(packed, bits);
|
||||
}
|
||||
|
||||
float MSG_ReadPackedAnimTime(msg_t* msg, int bits, float fromValue, float frameTime)
|
||||
{
|
||||
int packed;
|
||||
if (!MSG_ReadBits(msg, 1)) {
|
||||
return fromValue + frameTime;
|
||||
}
|
||||
|
||||
packed = MSG_ReadBits(msg, bits);
|
||||
return MSG_UnpackAnimTime(packed);
|
||||
}
|
||||
|
||||
float MSG_ReadPackedAnimWeight(msg_t* msg, int bits)
|
||||
{
|
||||
int packed = MSG_ReadBits(msg, bits);
|
||||
return MSG_UnpackAnimWeight(packed, bits);
|
||||
}
|
||||
|
||||
float MSG_ReadPackedScale(msg_t* msg, int bits)
|
||||
{
|
||||
int packed = MSG_ReadBits(msg, bits);
|
||||
return MSG_UnpackScale(packed);
|
||||
}
|
||||
|
||||
float MSG_ReadPackedAlpha(msg_t* msg, int bits)
|
||||
{
|
||||
int packed = MSG_ReadBits(msg, bits);
|
||||
return MSG_UnpackAlpha(packed, bits);
|
||||
}
|
||||
|
||||
float MSG_ReadPackedCoord(msg_t* msg, float fromValue, int bits)
|
||||
{
|
||||
int packedFrom = MSG_PackCoord(fromValue);
|
||||
int packedTo = MSG_ReadDeltaCoord(msg, packedFrom);
|
||||
return MSG_UnpackCoord(packedTo, bits);
|
||||
}
|
||||
|
||||
float MSG_ReadPackedCoordExtra(msg_t* msg, float fromValue, int bits)
|
||||
{
|
||||
int packedFrom = MSG_PackCoordExtra(fromValue);
|
||||
int packedTo = MSG_ReadDeltaCoordExtra(msg, packedFrom);
|
||||
return MSG_UnpackCoordExtra(packedTo, bits);
|
||||
}
|
||||
|
||||
void MSG_WritePackedAngle(msg_t* msg, float value, int bits)
|
||||
{
|
||||
int packed = MSG_PackAngle(value, bits);
|
||||
|
@ -1823,7 +2123,7 @@ void MSG_WritePackedAnimTime(msg_t* msg, float fromValue, float toValue, float f
|
|||
{
|
||||
int packed;
|
||||
|
||||
if (abs(fromValue - toValue) < frameTime) {
|
||||
if (fabs(fromValue - toValue) < frameTime) {
|
||||
// below the frame time, don't send
|
||||
MSG_WriteBits(msg, 0, 1);
|
||||
}
|
||||
|
@ -1923,6 +2223,80 @@ qboolean MSG_DeltaNeeded(const void* fromField, const void* toField, int fieldTy
|
|||
|
||||
#else
|
||||
|
||||
float MSG_ReadPackedAngle(msg_t* msg, int bits)
|
||||
{
|
||||
int result;
|
||||
float tmp = 1.0f;
|
||||
if (bits < 0) {
|
||||
if (MSG_ReadBits(msg, 1))
|
||||
tmp = -1.0f;
|
||||
bits = ~bits;
|
||||
}
|
||||
|
||||
result = MSG_ReadBits(msg, bits);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
return tmp * 360.f / 256.f;
|
||||
case 12:
|
||||
return tmp * result * 360.f / 4096.f;
|
||||
case 16:
|
||||
return tmp * result * 360.f / 65536.f;
|
||||
default:
|
||||
return tmp * 360.f / (1 << bits) * result;
|
||||
}
|
||||
}
|
||||
|
||||
float MSG_ReadPackedAnimTime(msg_t* msg, int bits, float fromValue, float frameTime)
|
||||
{
|
||||
return MSG_ReadBits(msg, 15) / 100.0f;
|
||||
}
|
||||
|
||||
float MSG_ReadPackedAnimWeight(msg_t* msg, int bits)
|
||||
{
|
||||
float tmp = MSG_ReadBits(msg, 8) / 255.0f;
|
||||
if (tmp < 0.0f)
|
||||
return 0.0f;
|
||||
else if (tmp > 1.0f)
|
||||
return 1.0f;
|
||||
else
|
||||
return tmp;
|
||||
}
|
||||
|
||||
float MSG_ReadPackedScale(msg_t* msg, int bits)
|
||||
{
|
||||
return MSG_ReadBits(msg, 10) / 100.0f;
|
||||
}
|
||||
|
||||
float MSG_ReadPackedAlpha(msg_t* msg, int bits)
|
||||
{
|
||||
float tmp = MSG_ReadBits(msg, 8) / 255.0f;
|
||||
if (tmp < 0.0f)
|
||||
return 0.0f;
|
||||
else if (tmp > 1.0f)
|
||||
return 1.0f;
|
||||
else
|
||||
return tmp;
|
||||
}
|
||||
|
||||
float MSG_ReadPackedCoord(msg_t* msg, float fromValue, int bits)
|
||||
{
|
||||
float tmp = 1.0f;
|
||||
int value = MSG_ReadBits(msg, 19);
|
||||
if (value & 262144) // test for 19th bit
|
||||
tmp = -1.0f;
|
||||
value &= ~262144; // remove that bit
|
||||
return tmp * value / 16.0f;
|
||||
}
|
||||
|
||||
float MSG_ReadPackedCoordExtra(msg_t* msg, float fromValue, int bits)
|
||||
{
|
||||
int packedFrom = MSG_PackCoordExtra(fromValue);
|
||||
int packedTo = MSG_ReadDeltaCoordExtra(msg, packedFrom);
|
||||
return MSG_UnpackCoordExtra(packedTo, bits);
|
||||
}
|
||||
|
||||
|
||||
void MSG_WritePackedAngle(msg_t* msg, float value, int bits)
|
||||
{
|
||||
// angles, what a mess! it wouldnt surprise me if something goes wrong here ;)
|
||||
|
@ -2044,6 +2418,25 @@ qboolean MSG_DeltaNeeded(const void* fromField, const void* toField, int fieldTy
|
|||
|
||||
#endif
|
||||
|
||||
float MSG_ReadPackedVelocity(msg_t* msg, int bits)
|
||||
{
|
||||
float tmp = 1.0f;
|
||||
int value = MSG_ReadBits(msg, 17);
|
||||
if (value & 65536) // test for 17th bit
|
||||
tmp = -1.0f;
|
||||
value &= ~65536; // remove that bit
|
||||
return tmp * value / 8.0f;
|
||||
}
|
||||
|
||||
int MSG_ReadPackedSimple(msg_t* msg, int fromValue, int bits)
|
||||
{
|
||||
if (!MSG_ReadBits(msg, 1)) {
|
||||
return fromValue;
|
||||
}
|
||||
|
||||
return MSG_ReadBits(msg, bits);
|
||||
}
|
||||
|
||||
void MSG_WritePackedVelocity(msg_t* msg, float value, int bits)
|
||||
{
|
||||
int32_t packed = (uint32_t)(value * 8.0f);
|
||||
|
@ -2159,106 +2552,34 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
|
|||
} else {
|
||||
switch (field->type) {
|
||||
case netFieldType_e::regular:
|
||||
if ( field->bits == 0 ) {
|
||||
// float
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 ) {
|
||||
*(float *)toF = 0.0f;
|
||||
} else {
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 ) {
|
||||
// integral float
|
||||
trunc = MSG_ReadBits( msg, FLOAT_INT_BITS );
|
||||
// bias to allow equal parts positive and negative
|
||||
trunc -= FLOAT_INT_BIAS;
|
||||
*(float *)toF = trunc;
|
||||
if ( print ) {
|
||||
Com_Printf( "%s:%i ", field->name, trunc );
|
||||
}
|
||||
} else {
|
||||
// full floating point value
|
||||
*toF = MSG_ReadBits( msg, 32 );
|
||||
if ( print ) {
|
||||
Com_Printf( "%s:%f ", field->name, *(float *)toF );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 ) {
|
||||
*toF = 0;
|
||||
} else {
|
||||
// integer
|
||||
*toF = MSG_ReadBits( msg, field->bits );
|
||||
if ( print ) {
|
||||
Com_Printf( "%s:%i ", field->name, *toF );
|
||||
}
|
||||
}
|
||||
}
|
||||
MSG_ReadRegular(msg, field->bits, toF);
|
||||
break;
|
||||
case netFieldType_e::angle: // angles, what a mess! it wouldnt surprise me if something goes wrong here ;)
|
||||
tmp = 1.0f;
|
||||
if ( field->bits < 0 ) {
|
||||
if ( MSG_ReadBits( msg, 1 ) )
|
||||
tmp = -1.0f;
|
||||
bits = ~field->bits;
|
||||
}
|
||||
else bits = field->bits;
|
||||
|
||||
result = MSG_ReadBits(msg, bits);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
*(float*)toF = tmp * 360.f / 256.f;
|
||||
break;
|
||||
case 12:
|
||||
*(float*)toF = tmp * result * 360.f / 4096.f;
|
||||
break;
|
||||
case 16:
|
||||
*(float*)toF = tmp * result * 360.f / 65536.f;
|
||||
break;
|
||||
default:
|
||||
*(float*)toF = tmp * 360.f / (1 << bits) * result;
|
||||
break;
|
||||
}
|
||||
*(float*)toF = MSG_ReadPackedAngle(msg, field->bits);
|
||||
break;
|
||||
case netFieldType_e::animTime: // time
|
||||
*(float *)toF = MSG_ReadBits( msg, 15 ) * 0.0099999998f;
|
||||
*(float*)toF = MSG_ReadPackedAnimTime(msg, field->bits, *(float*)fromF, frameTime);
|
||||
break;
|
||||
case netFieldType_e::animWeight: // nasty!
|
||||
tmp = MSG_ReadBits( msg, 8 ) / 255.0f;
|
||||
if ( tmp < 0.0f )
|
||||
*(float *)toF = 0.0f;
|
||||
else if ( tmp > 1.0f )
|
||||
*(float *)toF = 1.0f;
|
||||
else
|
||||
*(float *)toF = tmp;
|
||||
// FPU instructions yay
|
||||
*(float*)toF = MSG_ReadPackedAnimWeight(msg, field->bits);
|
||||
break;
|
||||
case netFieldType_e::scale:
|
||||
*(float *)toF = MSG_ReadBits( msg, 10 ) *0.0099999998f;
|
||||
*(float*)toF = MSG_ReadPackedScale(msg, field->bits);
|
||||
break;
|
||||
case netFieldType_e::alpha:
|
||||
tmp = MSG_ReadBits( msg, 8 ) / 255.0f;
|
||||
if ( tmp < 0.0f )
|
||||
*(float *)toF = 0.0f;
|
||||
else if ( tmp > 1.0f )
|
||||
*(float *)toF = 1.0f;
|
||||
else
|
||||
*(float *)toF = tmp;
|
||||
*(float*)toF = MSG_ReadPackedAlpha(msg, field->bits);
|
||||
break;
|
||||
case netFieldType_e::coord:
|
||||
tmp = 1.0f;
|
||||
bits = MSG_ReadBits( msg, 19 );
|
||||
if ( bits & 262144 ) // test for 19th bit
|
||||
tmp = -1.0f;
|
||||
bits &= ~262144; // remove that bit
|
||||
*(float *)toF = tmp * bits / 16.0f;
|
||||
*(float*)toF = MSG_ReadPackedCoord(msg, *(float*)fromF, field->bits);
|
||||
break;
|
||||
case netFieldType_e::coordExtra:
|
||||
*(float*)toF = MSG_ReadPackedCoordExtra(msg, *(float*)fromF, field->bits);
|
||||
break;
|
||||
case netFieldType_e::velocity:
|
||||
tmp = 1.0f;
|
||||
bits = MSG_ReadBits( msg, 17 );
|
||||
if ( bits & 65536 ) // test for 17th bit
|
||||
tmp = -1.0f;
|
||||
bits &= ~65536; // remove that bit
|
||||
*(float *)toF = tmp * bits / 8.0f;
|
||||
*(float*)toF = MSG_ReadPackedVelocity(msg, field->bits);
|
||||
break;
|
||||
case netFieldType_e::simple:
|
||||
*(int*)toF = MSG_ReadPackedSimple(msg, *(int*)fromF, field->bits);
|
||||
break;
|
||||
default:
|
||||
Com_Error( ERR_DROP, "MSG_ReadDeltaEntity: unrecognized entity field type %i for field\n", i );
|
||||
|
@ -2336,6 +2657,16 @@ float MSG_UnpackAnimTime(int packed)
|
|||
return packed / 100.f;
|
||||
}
|
||||
|
||||
float MSG_UnpackAnimWeight(int result, int bits)
|
||||
{
|
||||
const int32_t max = (1 << bits) - 1;
|
||||
const float tmp = (float)result / (float)max;
|
||||
|
||||
if (tmp < 0.0f) return 0.f;
|
||||
else if (tmp > 1.0f) return 1.f;
|
||||
else return tmp;
|
||||
}
|
||||
|
||||
float MSG_UnpackScale(int packed)
|
||||
{
|
||||
return packed / 100.f;
|
||||
|
@ -2508,6 +2839,66 @@ plyer_state_t communication
|
|||
// using the stringizing operator to save typing...
|
||||
#define PSF(x) #x,(size_t)&((playerState_t*)0)->x
|
||||
|
||||
#if TARGET_GAME_PROTOCOL >= 15
|
||||
netField_t playerStateFields[] =
|
||||
{
|
||||
{ PSF(commandTime), 32, netFieldType_t::regular },
|
||||
{ PSF(origin[0]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(origin[1]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(viewangles[1]), 0, netFieldType_t::regular },
|
||||
{ PSF(velocity[1]), 0, netFieldType_t::velocity },
|
||||
{ PSF(velocity[0]), 0, netFieldType_t::velocity },
|
||||
{ PSF(viewangles[0]), 0, netFieldType_t::regular },
|
||||
{ PSF(origin[2]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(velocity[2]), 0, netFieldType_t::velocity },
|
||||
{ PSF(iViewModelAnimChanged), 2, netFieldType_t::regular },
|
||||
{ PSF(damage_angles[0]), -13, netFieldType_t::angle },
|
||||
{ PSF(damage_angles[1]), -13, netFieldType_t::angle },
|
||||
{ PSF(damage_angles[2]), -13, netFieldType_t::angle },
|
||||
{ PSF(speed), 16, netFieldType_t::regular },
|
||||
{ PSF(delta_angles[1]), 16, netFieldType_t::regular },
|
||||
{ PSF(viewheight), -8, netFieldType_t::regular },
|
||||
{ PSF(groundEntityNum), GENTITYNUM_BITS, netFieldType_t::regular },
|
||||
{ PSF(delta_angles[0]), 16, netFieldType_t::regular },
|
||||
{ PSF(iViewModelAnim), 4, netFieldType_t::regular },
|
||||
{ PSF(fov), 0, netFieldType_t::regular },
|
||||
{ PSF(current_music_mood), 8, netFieldType_t::regular },
|
||||
{ PSF(gravity), 16, netFieldType_t::regular },
|
||||
{ PSF(fallback_music_mood), 8, netFieldType_t::regular },
|
||||
{ PSF(music_volume), 0, netFieldType_t::regular },
|
||||
{ PSF(pm_flags), 16, netFieldType_t::regular },
|
||||
{ PSF(clientNum), 8, netFieldType_t::regular },
|
||||
{ PSF(fLeanAngle), 0, netFieldType_t::regular },
|
||||
{ PSF(blend[3]), 0, netFieldType_t::regular },
|
||||
{ PSF(blend[0]), 0, netFieldType_t::regular },
|
||||
{ PSF(pm_type), 8, netFieldType_t::regular },
|
||||
{ PSF(feetfalling), 8, netFieldType_t::regular },
|
||||
{ PSF(radarInfo), 26, netFieldType_t::regular },
|
||||
{ PSF(camera_angles[0]), 16, netFieldType_t::angle },
|
||||
{ PSF(camera_angles[1]), 16, netFieldType_t::angle },
|
||||
{ PSF(camera_angles[2]), 16, netFieldType_t::angle },
|
||||
{ PSF(camera_origin[0]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(camera_origin[1]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(camera_origin[2]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(camera_posofs[0]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(camera_posofs[2]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(camera_time), 0, netFieldType_t::regular },
|
||||
{ PSF(voted), 1, netFieldType_t::regular },
|
||||
{ PSF(bobCycle), 8, netFieldType_t::regular },
|
||||
{ PSF(delta_angles[2]), 16, netFieldType_t::regular },
|
||||
{ PSF(viewangles[2]), 0, netFieldType_t::regular },
|
||||
{ PSF(music_volume_fade_time), 0, netFieldType_t::regular },
|
||||
{ PSF(reverb_type), 6, netFieldType_t::regular },
|
||||
{ PSF(reverb_level), 0, netFieldType_t::regular },
|
||||
{ PSF(blend[1]), 0, netFieldType_t::regular },
|
||||
{ PSF(blend[2]), 0, netFieldType_t::regular },
|
||||
{ PSF(camera_offset[0]), 0, netFieldType_t::regular },
|
||||
{ PSF(camera_offset[1]), 0, netFieldType_t::regular },
|
||||
{ PSF(camera_offset[2]), 0, netFieldType_t::regular },
|
||||
{ PSF(camera_posofs[1]), 0, netFieldType_t::coordExtra },
|
||||
{ PSF(camera_flags), 16, netFieldType_t::regular }
|
||||
};
|
||||
#else
|
||||
netField_t playerStateFields[] =
|
||||
{
|
||||
{ PSF(commandTime), 32, netFieldType_t::regular },
|
||||
|
@ -2566,6 +2957,7 @@ netField_t playerStateFields[] =
|
|||
{ PSF(camera_posofs[1]), 0, netFieldType_t::coord },
|
||||
{ PSF(camera_flags), 16, netFieldType_t::regular }
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
=============
|
||||
|
@ -2800,88 +3192,29 @@ void MSG_ReadDeltaPlayerstate(msg_t *msg, playerState_t *from, playerState_t *to
|
|||
|
||||
numFields = sizeof( playerStateFields ) / sizeof( playerStateFields[0] );
|
||||
lc = MSG_ReadByte(msg);
|
||||
//Com_DPrintf( "===\nMSG_ReadDeltaPlayerstate: count %i\n===\n", lc );
|
||||
assert(lc <= numFields);
|
||||
for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) {
|
||||
fromF = (int *)( (byte *)from + field->offset );
|
||||
toF = (int *)( (byte *)to + field->offset );
|
||||
//Com_DPrintf( "field %s ", field->name );
|
||||
if ( ! MSG_ReadBits( msg, 1 ) ) {
|
||||
// no change
|
||||
*toF = *fromF;
|
||||
//Com_DPrintf( "NO CHANGE " );
|
||||
//Com_DPrintf( "value int %i, float %f\n", *toF, *(float *)toF );
|
||||
} else {
|
||||
//Com_DPrintf( "type %i, ", field->type );
|
||||
switch ( field->type ) {
|
||||
case netFieldType_e::regular:
|
||||
if ( field->bits == 0 ) {
|
||||
// float
|
||||
if ( MSG_ReadBits( msg, 1 ) == 0 ) {
|
||||
// integral float
|
||||
trunc = MSG_ReadBits( msg, FLOAT_INT_BITS );
|
||||
// bias to allow equal parts positive and negative
|
||||
trunc -= FLOAT_INT_BIAS;
|
||||
*(float *)toF = trunc;
|
||||
if ( print ) {
|
||||
Com_Printf( "%s:%i ", field->name, trunc );
|
||||
}
|
||||
} else {
|
||||
// full floating point value
|
||||
*toF = MSG_ReadBits( msg, 32 );
|
||||
if ( print ) {
|
||||
Com_Printf( "%s:%f ", field->name, *(float *)toF );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// integer
|
||||
*toF = MSG_ReadBits( msg, field->bits );
|
||||
if ( print ) {
|
||||
Com_Printf( "%s:%i ", field->name, *toF );
|
||||
}
|
||||
}
|
||||
MSG_ReadRegularSimple(msg, field->bits, toF);
|
||||
break;
|
||||
case netFieldType_e::angle:
|
||||
tmp = 1.0f;
|
||||
if ( field->bits < 0 ) {
|
||||
if ( MSG_ReadBits( msg, 1 ) )
|
||||
tmp = -1.0f;
|
||||
bits = - field->bits -1;
|
||||
}
|
||||
else bits = field->bits;
|
||||
|
||||
result = MSG_ReadBits(msg, bits);
|
||||
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
*(float*)toF = tmp * 360.f / 256.f;
|
||||
break;
|
||||
case 12:
|
||||
*(float*)toF = tmp * result * 360.f / 4096.f;
|
||||
break;
|
||||
case 16:
|
||||
*(float*)toF = tmp * result * 360.f / 65536.f;
|
||||
break;
|
||||
default:
|
||||
*(float*)toF = tmp * 360.f / (1 << bits) * result;
|
||||
break;
|
||||
}
|
||||
*(float*)toF = MSG_ReadPackedAngle(msg, field->bits);
|
||||
break;
|
||||
case netFieldType_e::coord:
|
||||
tmp = 1.0f;
|
||||
bits = MSG_ReadBits( msg, 19 );
|
||||
if ( bits & 262144 ) // test for 19th bit
|
||||
tmp = -1.0f;
|
||||
bits &= ~262144; // 4294705151; // remove that bit
|
||||
*(float *)toF = tmp * bits / 16.0f;
|
||||
*(float*)toF = MSG_ReadPackedCoord(msg, *(float*)fromF, field->bits);
|
||||
break;
|
||||
case netFieldType_e::coordExtra:
|
||||
*(float*)toF = MSG_ReadPackedCoordExtra(msg, *(float*)fromF, field->bits);
|
||||
break;
|
||||
case netFieldType_e::velocity:
|
||||
tmp = 1.0f;
|
||||
bits = MSG_ReadBits( msg, 17 );
|
||||
if ( bits & 65536 ) // test for 17th bit
|
||||
tmp = -1.0f;
|
||||
bits &= ~65536; // 4294901759; // remove that bit
|
||||
*(float *)toF = tmp * bits / 8.0f;
|
||||
*(float*)toF = MSG_ReadPackedVelocity(msg, field->bits);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -47,6 +47,8 @@ extern "C" {
|
|||
#define PRODUCT_VERSION PRODUCT_VERSION_NUMBER_STRING "-" PRODUCT_VERSION_STAGE
|
||||
#define PRODUCT_DATE __DATE__
|
||||
|
||||
#define BASEGAME "main"
|
||||
|
||||
//
|
||||
// The target type specifies which content pack the engine targets.
|
||||
//
|
||||
|
@ -57,7 +59,7 @@ extern "C" {
|
|||
//
|
||||
// Team Assault
|
||||
//
|
||||
#define BASEGAME "mainta"
|
||||
#define GAME_EXTENSION_BASE "mainta"
|
||||
#define PRODUCT_EXTENSION "spearhead"
|
||||
// The version string must be equal or above 2.0 to be able to connect to spearhead servers
|
||||
#define TARGET_GAME_VERSION "2.16"
|
||||
|
@ -71,7 +73,7 @@ extern "C" {
|
|||
//
|
||||
// Team Tactics
|
||||
//
|
||||
#define BASEGAME "maintt"
|
||||
#define GAME_EXTENSION_BASE "maintt"
|
||||
#define PRODUCT_EXTENSION "breakthrough"
|
||||
// The version string must be equal or above 2.0 to be able to connect to breakthrough servers
|
||||
#define TARGET_GAME_VERSION "2.41"
|
||||
|
@ -85,8 +87,8 @@ extern "C" {
|
|||
//
|
||||
// Base game
|
||||
//
|
||||
|
||||
#define BASEGAME "main"
|
||||
|
||||
#define GAME_EXTENSION_BASE "main"
|
||||
#define PRODUCT_EXTENSION "base"
|
||||
// The version string must be 1.1x or below, otherwise it's not possible to connect
|
||||
#define TARGET_GAME_VERSION "1.12"
|
||||
|
@ -1729,6 +1731,11 @@ typedef struct playerState_s {
|
|||
float camera_posofs[3];
|
||||
int camera_flags;
|
||||
float damage_angles[3];
|
||||
// --
|
||||
// Team Assault
|
||||
int radarInfo;
|
||||
qboolean voted;
|
||||
// --
|
||||
|
||||
// not communicated over the net at all
|
||||
int ping; // server to game info for scoreboard
|
||||
|
@ -2056,20 +2063,6 @@ typedef struct hdelement_s {
|
|||
struct fontheader_s *pFont;
|
||||
} hdelement_t;
|
||||
|
||||
enum vmAnim_e {
|
||||
VM_ANIM_IDLE,
|
||||
VM_ANIM_CHARGE,
|
||||
VM_ANIM_FIRE,
|
||||
VM_ANIM_FIRE_SECONDARY,
|
||||
VM_ANIM_RECHAMBER,
|
||||
VM_ANIM_RELOAD,
|
||||
VM_ANIM_RELOAD_SINGLE,
|
||||
VM_ANIM_RELOAD_END,
|
||||
VM_ANIM_PULLOUT,
|
||||
VM_ANIM_PUTAWAY,
|
||||
VM_ANIM_LADDERSTEP
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
frameInfo_t g_VMFrameInfo[MAX_FRAMEINFOS];
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ void MSG_WriteLong (msg_t *sb, int c);
|
|||
void MSG_WriteFloat (msg_t *sb, float f);
|
||||
void MSG_WriteString (msg_t *sb, const char *s);
|
||||
void MSG_WriteBigString (msg_t *sb, const char *s);
|
||||
void MSG_WriteScrambledString(msg_t* sb, const char* s);
|
||||
void MSG_WriteScrambledBigString(msg_t* sb, const char* s);
|
||||
void MSG_WriteAngle16 (msg_t *sb, float f);
|
||||
|
||||
void MSG_BeginReading (msg_t *sb);
|
||||
|
@ -104,9 +106,12 @@ float MSG_ReadFloat (msg_t *sb);
|
|||
char *MSG_ReadString (msg_t *sb);
|
||||
char *MSG_ReadBigString (msg_t *sb);
|
||||
char *MSG_ReadStringLine( msg_t *sb );
|
||||
char* MSG_ReadScrambledString(msg_t* msg);
|
||||
char* MSG_ReadScrambledBigString(msg_t* msg);
|
||||
float MSG_ReadAngle8( msg_t *sb );
|
||||
float MSG_ReadAngle16 (msg_t *sb);
|
||||
void MSG_ReadData (msg_t *sb, void *buffer, int size);
|
||||
unsigned short MSG_ReadEntityNum(msg_t* sb);
|
||||
|
||||
|
||||
void MSG_WriteDeltaUsercmd( msg_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||
|
@ -158,6 +163,7 @@ void MSG_WritePackedSimple(msg_t* msg, int value, int bits);
|
|||
|
||||
float MSG_UnpackAngle(int value, int bits);
|
||||
float MSG_UnpackAnimTime(int packed);
|
||||
float MSG_UnpackAnimWeight(int result, int bits);
|
||||
float MSG_UnpackScale(int packed);
|
||||
float MSG_UnpackAlpha(int packed, int bits);
|
||||
float MSG_UnpackCoord(int packed, int bits);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue