Compare commits

...
19 Commits
Author SHA1 Message Date
OM 5bba5abece Added README note 2023-05-21 22:10:27 +02:00
OM bdcb6c42b6 Parse includes, depending on the server type 2023-05-21 22:07:42 +02:00
OM 0fe01d23d6 Fixed tag_num being -1 and *MSG_ReadPackedAngle* setting the wrong angle value 2023-05-21 22:07:09 +02:00
OM fc675e4064 Fixed authorization stuck 2023-05-21 22:06:42 +02:00
OM a29af7c3f6 Added Screenshot (Spearhead expansion) 2023-05-21 21:22:51 +02:00
OM 732872f433 Updated README 2023-05-21 21:22:02 +02:00
OM 04b5fdb934 Added Spearhead/Breakthrough client support 2023-05-21 21:21:20 +02:00
OM e23ce01d19 Added getKey/authorizeThis 2023-05-21 21:21:07 +02:00
OM 648dc395e7 Fixed compilation errors 2023-05-21 20:07:28 +02:00
OM ab2a26a14e Added support for *Team Assault* and *Team Tactics* 2023-05-21 19:59:36 +02:00
OM 238e94b4d5 Don't assert if *cls* is NULL 2023-05-21 19:59:12 +02:00
OM 0c18e0e26c Exports *UI_UpdateCenterPrint* and *UI_UpdateLocationPrint* 2023-05-21 19:58:59 +02:00
OM 7085d60d02 Added Team Tactics features 2023-05-21 19:58:43 +02:00
OM 3933e63044 Fixed crash in LoopSound when tiki's alias list is NULL 2023-05-21 19:57:45 +02:00
OM 342552c349 Process lightmap coord array on static models 2023-05-21 02:48:57 +02:00
OM 9addff08ce Bind if the texture is a lightmap 2023-05-21 02:48:41 +02:00
OM 2ff1071115 Export *R_PrintInfoWorldtris* 2023-05-21 02:43:07 +02:00
OM 49f4ac66ab Added *R_DrawLensFlares* 2023-05-21 02:40:50 +02:00
OM 7761cbd74c Implemented *RB_SetupStaticModelGridLighting* and *RB_Static_BuildDLights* 2023-05-21 02:40:44 +02:00
35 changed files with 1738 additions and 327 deletions

No files matched your search

+3
View File
@@ -41,6 +41,8 @@ Here is the current working state for each part of the engine:
| Server module (fgame) | | x | | | | | Actor, vehicle, and few gameplay bugs |
| UI | | | | x | | | Has core features only (menu, widgets, console, hud, urc loading) |
NOTE: Both client and server version can be compiled to target **Medal of Honor: Spearhead* and **Medal of Honor: Breakthrough**.
## Running
Backup existing mohaa files, **cgamex86.dll** and **gamex86.dll** (set their extension to **.bak**)
@@ -87,6 +89,7 @@ Visual Studio (2019 or 2022) is generally preferred.
## Screenshots
![](docs/images/opm_53_tt_1.png)
![](docs/images/opm_50b_1.png)
![](docs/images/opm_50b_2.png)
+2 -2
View File
@@ -5139,7 +5139,7 @@ void ClientGameCommandManager::LoopSound(Event* ev)
// Get the real sound to play
if (current_tiki) {
if (current_tiki && current_tiki->a->alias_list) {
name = cgi.Alias_ListFindRandom((AliasList_t*)current_tiki->a->alias_list,
sound_name.c_str(), &soundAlias);
}
@@ -5168,7 +5168,7 @@ void CacheResource(const char* stuff)
{
str real_stuff;
if (!stuff) {
if (!stuff || !stuff[0]) {
return;
}
+13 -5
View File
@@ -297,15 +297,21 @@ typedef struct {
qboolean testGun;
// farplane parameters
float farplane_distance;
float farplane_distance;
float farplane_bias;
vec3_t farplane_color;
qboolean farplane_cull;
qboolean farplane_cull;
int skyboxFarplane;
qboolean renderTerrain;
float farclipOverride;
vec3_t farplaneColorOverride;
// portal sky parameters
qboolean sky_portal;
float sky_alpha;
vec3_t sky_origin;
vec3_t sky_axis[3]; // rotation vectors
vec3_t sky_axis[3]; // rotation vectors
int skyboxSpeed;
// weapon viewkick recoil
float viewkick[2];
@@ -371,8 +377,9 @@ typedef struct {
int fraglimit;
int timelimit;
int maxclients;
int cinematic;
char mapname[MAX_QPATH];
int cinematic;
int mapChecksum;
char mapname[MAX_QPATH];
//
// locally derived information from gamestate
@@ -475,6 +482,7 @@ int CG_LastAttacker( void );
void CG_Init( clientGameImport_t *imported, int serverMessageNum, int serverCommandSequence, int clientNum );
void CG_Shutdown( void );
void CG_ServerRestarted( void );
void CG_ParseFogInfo(const char* str);
//
// cg_modelanim.cpp
+42 -10
View File
@@ -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
+463 -4
View File
@@ -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 = 1.0f) {
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
+70 -1
View File
@@ -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");
}
+179 -12
View File
@@ -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);
+1 -1
View File
@@ -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
+20 -5
View File
@@ -32,6 +32,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../sys/sys_loadlib.h"
#endif
#include "gcdkeyc.h"
cvar_t *cl_nodelta;
cvar_t *cl_debugMove;
@@ -1779,6 +1781,7 @@ void CL_CheckForResend( void ) {
int port, i;
char info[MAX_INFO_STRING];
char data[MAX_INFO_STRING];
char buf[1024];
// don't send anything if playing back a demo
if ( clc.demoplaying ) {
@@ -1807,7 +1810,11 @@ void CL_CheckForResend( void ) {
// }
NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "getchallenge");
break;
case CA_AUTHORIZING:
// resend the cd key authorization
gcd_compute_response(cl_cdkey, Cmd_Argv(1), cls.gcdResponse, CDResponseMethod_REAUTH);
NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "authorizeThis %s", cls.gcdResponse);
break;
case CA_CHALLENGING:
/*
wombat: sending conect here: an example connect string from MOHAA looks like this:
@@ -1820,7 +1827,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_PROTOCOL >= 15
Info_SetValueForKey(info, "clientType", "Breakthrough");
#endif
strcpy(data, "connect ");
// TTimo adding " " around the userinfo string to avoid truncated userinfo on the server
@@ -2079,7 +2090,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
// challenge from the server we are connecting to
if ( !Q_stricmp(c, "challengeResponse") ) {
if ( cls.state != CA_CONNECTING ) {
if ( cls.state != CA_CONNECTING && cls.state != CA_AUTHORIZING ) {
Com_Printf( "Unwanted challenge response received. Ignored.\n" );
} else {
// start sending challenge repsonse instead of challenge request packets
@@ -2144,8 +2155,12 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
}
// cd check
if ( !Q_stricmp(c, "keyAuthorize") ) {
// we don't use these now, so dump them on the floor
if ( !Q_stricmp(c, "getKey") ) {
char buf[1024];
cls.state = CA_AUTHORIZING;
gcd_compute_response(cl_cdkey, Cmd_Argv(1), cls.gcdResponse, CDResponseMethod_NEWAUTH);
NET_OutOfBandPrint(NS_CLIENT, from, "authorizeThis %s", cls.gcdResponse);
return;
}
+34 -14
View File
@@ -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 );
}
/*
+6
View File
@@ -303,6 +303,7 @@ typedef struct {
int framecount;
int frametime; // msec since last frame
float serverFrameTime;
int realtime; // ignores pause
int realFrametime; // ignoring pause, so console always works
@@ -345,6 +346,11 @@ typedef struct {
hdelement_t HudDrawElements[ MAX_HUDDRAW_ELEMENTS ];
clientAnim_t anim;
stopWatch_t stopwatch;
void* savedCgameState;
int savedCgameStateSize;
char gcdResponse[73];
int unknown3_0;
int currentRate;
qhandle_t charSetShader;
qhandle_t whiteShader;
qhandle_t consoleShader;
+87 -6
View File
@@ -66,6 +66,34 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define CS_MOTD 4 // g_motd string for server message of the day
#define CS_WARMUP 5 // server time when the match will be restarted
#if TARGET_GAME_PROTOCOL >= 15
#define CS_MUSIC 6 // MUSIC_NewSoundtrack(cs)
#define CS_FOGINFO 7 // cg.farplane_cull cg.farplane_distance cg.farplane_color[3]
#define CS_SKYINFO 8 // cg.sky_alpha cg.sky_portal
#define CS_GAME_VERSION 9
#define CS_LEVEL_START_TIME 10 // so the timer only shows the current level cgs.levelStartTime
#define CS_CURRENT_OBJECTIVE 11
#define CS_RAIN_DENSITY 12 // cg.rain
#define CS_RAIN_SPEED 13
#define CS_RAIN_SPEEDVARY 14
#define CS_RAIN_SLANT 15
#define CS_RAIN_LENGTH 16
#define CS_RAIN_MINDIST 17
#define CS_RAIN_WIDTH 18
#define CS_RAIN_SHADER 19
#define CS_RAIN_NUMSHADERS 20
#define CS_VOTE_TIME 21
#define CS_VOTE_STRING 22
#define CS_VOTE_YES 23
#define CS_VOTE_NO 24
#define CS_VOTE_UNDECIDED 25
#else
#define CS_MUSIC 8 // MUSIC_NewSoundtrack(cs)
#define CS_FOGINFO 9 // cg.farplane_cull cg.farplane_distance cg.farplane_color[3]
#define CS_SKYINFO 10 // cg.sky_alpha cg.sky_portal
@@ -85,6 +113,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define CS_RAIN_SHADER 21
#define CS_RAIN_NUMSHADERS 22
#endif
#define CS_MATCHEND 26 // cgs.matchEndTime
#define CS_MODELS 32
@@ -98,11 +128,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define CS_PLAYERS (CS_LIGHTSTYLES+MAX_LIGHTSTYLES) // 1684
#define CS_WEAPONS (CS_PLAYERS+MAX_CLIENTS) // su44 was here
#define CS_TEAMS 1876
#define CS_GENERAL_STRINGS 1877
#define CS_SPECTATORS 1878
#define CS_ALLIES 1879
#define CS_AXIS 1880
#define CS_TEAMS 1892
#define CS_GENERAL_STRINGS 1893
#define CS_SPECTATORS 1894
#define CS_ALLIES 1895
#define CS_AXIS 1896
#define CS_SOUNDTRACK 1881
#define CS_TEAMINFO 1
@@ -528,6 +558,15 @@ extern const char *means_of_death_strings[];
#define DF_NO_DROP_WEAPONS (1<<16)
#define DF_NO_FOOTSTEPS (1<<17)
#define DF_WEAPON_LANDMINE_ALWAYS (1<<21)
#define DF_WEAPON_NO_RIFLE (1<<22)
#define DF_WEAPON_NO_SNIPER (1<<23)
#define DF_WEAPON_NO_SMG (1<<24)
#define DF_WEAPON_NO_MG (1<<25)
#define DF_WEAPON_NO_ROCKET (1<<26)
#define DF_WEAPON_NO_SHOTGUN (1<<27)
#define DF_WEAPON_NO_LANDMINE (1<<28)
#define DM_FLAG( flag ) ( g_gametype->integer && ( ( int )dmflags->integer & ( flag ) ) )
// content masks
@@ -612,7 +651,49 @@ typedef enum {
void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result );
void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap );
void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap );
void BG_PlayerStateToEntityStateExtraPolate(playerState_t* ps, entityState_t* s, int time, qboolean snap);
#if TARGET_GAME_PROTOCOL >= 15
enum vmAnim_e {
VM_ANIM_DISABLED,
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,
VM_ANIM_IDLE_0,
VM_ANIM_IDLE_1,
VM_ANIM_IDLE_2,
};
#else
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,
VM_ANIM_IDLE_0,
VM_ANIM_IDLE_1,
VM_ANIM_IDLE_2,
VM_ANIM_DISABLED,
};
#endif
#ifdef __cplusplus
}
+50
View File
@@ -3666,6 +3666,49 @@ qboolean Player::checkimmediateswitch( Conditional &condition )
return ( g_gametype->integer && g_immediateswitch->integer );
}
qboolean Player::checkmovementspeed(Conditional& condition)
{
int speed = atoi(condition.getParm(1));
return client->ps.speed >= speed;
}
qboolean Player::checkabletodefuse(Conditional& condition)
{
// FIXME: unimplemented
return true;
}
qboolean Player::checkonlandmine(Conditional& condition)
{
// FIXME: unimplemented
return false;
}
qboolean Player::checknearlandmine(Conditional& condition)
{
// FIXME: unimplemented
return false;
}
qboolean Player::CondCanPlaceLandmine(Conditional& condition)
{
// FIXME: unimplemented
return false;
}
qboolean Player::CondWeaponCurrentFireAnim(Conditional& condition)
{
// FIXME: unimplemented
return false;
}
qboolean Player::CondVehicleType(Conditional& condition)
{
// FIXME: unimplemented
return false;
}
qboolean Player::CondAnimDoneVM( Conditional &condition )
{
return animDoneVM;
@@ -4024,6 +4067,13 @@ Condition<Player> Player::Conditions[] =
{ "MIN_CHARGE_TIME_MET", &Player::checkminchargetimemet },
{ "MAX_CHARGE_TIME_MET", &Player::checkmaxchargetimemet },
{ "IMMEDIATE_SWITCH", &Player::checkimmediateswitch },
{ "CHECK_MOVEMENT_SPEED", &Player::checkmovementspeed },
{ "ABLE_TO_DEFUSE", &Player::checkabletodefuse },
{ "ON_LANDMINE", &Player::checkonlandmine },
{ "NEAR_LANDMINE", &Player::checknearlandmine },
{ "CAN_PLACE_LANDMINE", &Player::CondCanPlaceLandmine },
{ "WEAPON_CURRENT_FIRE_ANIM", &Player::CondWeaponCurrentFireAnim },
{ "VEHICLE_TYPE", &Player::CondVehicleType },
{ "ANIMDONE_VM", &Player::CondAnimDoneVM },
{ "CLIENT_COMMAND", &Player::CondClientCommand },
{ "IS_VM_ANIM", &Player::CondVMAnim },
+7
View File
@@ -443,6 +443,13 @@ public:
qboolean checkminchargetimemet( Conditional &condition );
qboolean checkmaxchargetimemet( Conditional &condition );
qboolean checkimmediateswitch( Conditional &condition );
qboolean checkmovementspeed( Conditional &condition );
qboolean checkabletodefuse( Conditional &condition );
qboolean checkonlandmine( Conditional &condition );
qboolean checknearlandmine( Conditional &condition );
qboolean CondCanPlaceLandmine( Conditional &condition );
qboolean CondWeaponCurrentFireAnim( Conditional &condition );
qboolean CondVehicleType( Conditional &condition );
qboolean CondAnimDoneVM( Conditional &condition );
qboolean CondClientCommand( Conditional &condition );
qboolean CondVMAnim( Conditional &condition );
+3 -3
View File
@@ -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;
+12 -6
View File
@@ -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( );
+542 -198
View File
@@ -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
@@ -326,11 +326,21 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
}
msg->readcount = (msg->bit>>3)+1;
}
#if TARGET_GAME_PROTOCOL >= 15
if (sgn) {
if (value & 1) {
value = ~(value >> 1);
} else {
value >>= 1;
}
}
#else
if (sgn) {
if (value & (1 << (bits - 1))) {
value |= -1 ^ ((1 << bits) - 1);
}
}
#endif
return value;
}
@@ -417,6 +427,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 +480,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 +507,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 +624,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 +638,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 +660,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;
@@ -721,7 +798,6 @@ void MSG_GetNullEntityState(entityState_t *nullState) {
nullState->alpha = 1.0f;
nullState->scale = 1.0f;
nullState->parent = ENTITYNUM_NONE;
nullState->tag_num = -1; // su44
nullState->constantLight = 0xffffff;
nullState->renderfx = 16;
nullState->bone_tag[4] = -1;
@@ -1171,6 +1247,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 +1547,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 +1571,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 +1597,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;
@@ -1382,16 +1618,19 @@ void MSG_WriteRegular(msg_t* sb, int bits, const void* toF)
}
else {
MSG_WriteBits(sb, 1, 1);
if (trunc == fullFloat && trunc + FLOAT_INT_BIAS >= 0 &&
trunc + FLOAT_INT_BIAS < (1 << FLOAT_INT_BITS)) {
if (trunc == fullFloat && trunc >= -4096 && trunc < 4096) {
// send as small integer
MSG_WriteBits(sb, 0, 1);
MSG_WriteBits(sb, trunc + FLOAT_INT_BIAS, FLOAT_INT_BITS);
MSG_WriteBits(sb, trunc, -FLOAT_INT_BITS);
}
else {
// send as full floating point value
int newvalue = *(int*)toF * 2 - 0x7A000000;
if (*(int*)toF < 0) {
newvalue |= 1;
}
MSG_WriteBits(sb, 1, 1);
MSG_WriteBits(sb, *(int*)toF, 32);
// send as full floating point value
MSG_WriteBits(sb, newvalue, 32);
}
}
}
@@ -1418,9 +1657,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 +1675,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 +1695,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 +1791,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 +1829,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, from->number);
MSG_WriteBits( msg, 1, 1 );
return;
}
@@ -1813,6 +2074,55 @@ int MSG_PackCoordExtra(float coord)
#if TARGET_GAME_PROTOCOL >= 15
float MSG_ReadPackedAngle(msg_t* msg, int bits)
{
int packed = MSG_ReadBits(msg, abs(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,9 +2133,10 @@ 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);
return;
}
MSG_WriteBits(msg, 1, 1);
@@ -1923,6 +2234,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 +2429,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 +2563,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 +2668,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 +2850,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 +2968,7 @@ netField_t playerStateFields[] =
{ PSF(camera_posofs[1]), 0, netFieldType_t::coord },
{ PSF(camera_flags), 16, netFieldType_t::regular }
};
#endif
/*
=============
@@ -2800,88 +3203,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;
+12 -19
View File
@@ -36,7 +36,7 @@ extern "C" {
//
// These values are the only one that must be set for the version
#define PRODUCT_VERSION_MAJOR 0
#define PRODUCT_VERSION_MINOR 52
#define PRODUCT_VERSION_MINOR 53
#define PRODUCT_VERSION_PATCH 0
#define PRODUCT_VERSION_STAGE "alpha"
@@ -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];
+7
View File
@@ -83,7 +83,10 @@ 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_WriteEntityNum(msg_t* sb, short number);
void MSG_BeginReading (msg_t *sb);
void MSG_BeginReadingOOB(msg_t *sb);
@@ -104,9 +107,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 +164,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);
+2 -2
View File
@@ -468,8 +468,8 @@ typedef struct {
// little-endian "2015"
#define BSP_BETA_VERSION 18 // Beta Allied Assault
#define BSP_BASE_VERSION 19 // vanilla Allied Assault
#define BSP_VERSION 19 // current Allied Assault
#define BSP_MIN_VERSION 18 // Beta Allied Assault
#define BSP_MAX_VERSION 21 // Breakthrough
// there shouldn't be any problem with increasing these values at the
+15 -2
View File
@@ -807,7 +807,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
if ( depthRange ) {
qglDepthRange (0, 0.3);
} else {
qglDepthRange (0, 1);
qglDepthRange (0, 1.875);
}
oldDepthRange = depthRange;
}
@@ -872,6 +872,10 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
}
}
if (*drawSurf->surface == SF_SPRITE) {
backEnd.shaderStartTime = ((refSprite_t*)drawSurf->surface)->shaderTime;
}
// add the triangles for this surface
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
}
@@ -886,7 +890,16 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
// go back to the world modelview matrix
qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
if ( depthRange ) {
qglDepthRange (0, 1);
qglDepthRange (0, 1.875);
}
RB_ShadowFinish();
RB_RenderFlares();
R_DrawLensFlares();
if (g_bInfoworldtris)
{
g_bInfoworldtris = 0;
R_PrintInfoWorldtris();
}
#if 0
+2 -2
View File
@@ -2233,9 +2233,9 @@ void RE_LoadWorldMap( const char *name ) {
c_gridVerts = 0;
i = LittleLong(header.version);
if (i < BSP_BASE_VERSION || i > BSP_VERSION) {
if (i < BSP_MIN_VERSION || i > BSP_MAX_VERSION) {
ri.Error(ERR_DROP, "RE_LoadWorldMap: %s has wrong version number (%i should be between %i and %i)",
name, i, BSP_BASE_VERSION, BSP_VERSION);
name, i, BSP_MIN_VERSION, BSP_MAX_VERSION);
}
// load into heap
+57 -1
View File
@@ -350,7 +350,63 @@ void RB_SetupEntityGridLighting()
void RB_SetupStaticModelGridLighting(trRefdef_t* refdef, cStaticModelUnpacked_t* ent, const vec3_t lightOrigin)
{
// FIXME: unimplemented
int iColor;
int i;
dlight_t* dl;
float power;
vec3_t vLight;
vec3_t dir;
float d;
if (ent->bLightGridCalculated) {
return;
}
ent->bLightGridCalculated = qtrue;
if (!(refdef->rdflags & RDF_NOWORLDMODEL) && tr.world->lightGridData) {
R_GetLightingGridValue(backEnd.currentSphere->traceOrigin, vLight);
}
else {
vLight[0] = vLight[1] = vLight[2] = tr.identityLight * 150.0;
}
for (i = 0; i < refdef->num_dlights; i++) {
dl = &refdef->dlights[i];
VectorSubtract(dl->origin, lightOrigin, dir);
d = VectorLengthSquared(dir);
power = dl->radius * dl->radius;
if (power >= d) {
d = dl->radius * 7500.0 / d;
VectorMA(vLight, d, dl->color, vLight);
}
}
if (tr.overbrightShift)
{
vLight[0] = tr.overbrightMult * vLight[0];
vLight[1] = tr.overbrightMult * vLight[1];
vLight[2] = tr.overbrightMult * vLight[2];
}
// normalize
if (vLight[0] < 255.0 || vLight[1] < 255.0 || vLight[2] < 255.0) {
float scale = 255.0 / fmin(vLight[0], fmin(vLight[1], vLight[2]));
VectorScale(vLight, scale, vLight);
}
// clamp ambient
for (i = 0; i < 3; i++) {
if (vLight[i] > tr.identityLightByte) {
vLight[i] = tr.identityLightByte;
}
}
// save out the byte packet version
((byte*)&ent->iGridLighting)[0] = myftol(vLight[0]);
((byte*)&ent->iGridLighting)[1] = myftol(vLight[1]);
((byte*)&ent->iGridLighting)[2] = myftol(vLight[2]);
((byte*)&ent->iGridLighting)[3] = 0xff;
}
/*
+3
View File
@@ -1879,6 +1879,7 @@ void R_GetLightingForDecal(vec3_t vLight, vec3_t vFacing, vec3_t vOrigin);
void R_GetLightingForSmoke(vec3_t vLight, vec3_t vOrigin);
void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent );
void RB_SetupEntityGridLighting();
void RB_SetupStaticModelGridLighting(trRefdef_t* refdef, cStaticModelUnpacked_t* ent, const vec3_t lightOrigin);
void R_TransformDlights( int count, dlight_t *dl, orientationr_t *ori );
void RB_Light_Real(unsigned char* colors);
void RB_Sphere_BuildDLights();
@@ -2037,6 +2038,7 @@ SUN FLARE
=============================================================
*/
void R_InitLensFlare();
void R_DrawLensFlares();
/*
=============================================================
@@ -2091,6 +2093,7 @@ void R_PrintInfoStaticModels();
void R_AddSkelSurfaces(trRefEntity_t* ent);
void R_AddStaticModelSurfaces(void);
float R_CalcLod(const vec3_t origin, float radius);
void R_PrintInfoWorldtris(void);
extern int g_nStaticSurfaces;
extern qboolean g_bInfostaticmodels;
+7 -3
View File
@@ -1387,7 +1387,7 @@ void RB_StageIteratorVertexLitTextureUnfogged( void )
//
// now do any dynamic lighting needed
//
if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
if ( tess.dlightBits && !tess.dlightMap && tess.shader->sort <= SS_OPAQUE ) {
ProjectDlightTexture();
}
@@ -1456,7 +1456,11 @@ void RB_StageIteratorLightmappedMultitextureUnfogged( void ) {
} else {
GL_TexEnv( GL_MODULATE );
}
R_BindAnimatedImage( &tess.xstages[0]->bundle[1] );
if (tess.dlightMap && tess.xstages[0]->bundle[1].isLightmap) {
GL_Bind(&tr.identityLightImage[tess.dlightMap]);
} else {
R_BindAnimatedImage(&tess.xstages[0]->bundle[1]);
}
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][1] );
@@ -1485,7 +1489,7 @@ void RB_StageIteratorLightmappedMultitextureUnfogged( void ) {
//
// now do any dynamic lighting needed
//
if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
if ( tess.dlightBits && !tess.dlightMap && tess.shader->sort <= SS_OPAQUE ) {
ProjectDlightTexture();
}
+1 -1
View File
@@ -204,7 +204,7 @@ void RB_Grid_SetupEntity()
void RB_Grid_SetupStaticModel()
{
// FIXME: unimplemented
RB_SetupStaticModelGridLighting(&tr.refdef, backEnd.currentStaticModel, backEnd.currentStaticModel->origin);
}
void RB_Light_Fullbright(unsigned char* colors)
+31 -2
View File
@@ -390,7 +390,34 @@ void R_AddStaticModelSurfaces(void) {
void RB_Static_BuildDLights()
{
// FIXME: unimplemented
int i;
backEnd.currentStaticModel->useSpecialLighting = backEnd.refdef.num_dlights > 0;
backEnd.currentStaticModel->numdlights = 0;
if (!backEnd.currentStaticModel->useSpecialLighting) {
return;
}
for (i = 0; i < backEnd.refdef.num_dlights && backEnd.currentStaticModel->numdlights != 32; i++) {
vec3_t lightorigin, delta;
VectorCopy(backEnd.refdef.dlights[i].origin, lightorigin);
VectorSubtract(lightorigin, backEnd.currentStaticModel->origin, delta);
if (backEnd.refdef.dlights[i].radius * 2.0 >= VectorLength(delta)) {
MatrixTransformVectorRight(
backEnd.currentStaticModel->axis,
delta,
backEnd.currentStaticModel->dlights[backEnd.currentStaticModel->numdlights].transformed
);
backEnd.currentStaticModel->dlights[backEnd.currentStaticModel->numdlights++].index = i;
}
}
if (!backEnd.currentStaticModel->numdlights) {
backEnd.currentStaticModel->useSpecialLighting = qfalse;
}
}
void R_InfoStaticModels_f()
@@ -476,7 +503,9 @@ void RB_StaticMesh(staticSurface_t* staticSurf) {
Vector4Copy(surf->pStaticXyz[j], tess.xyz[baseVertex + j]);
Vector4Copy(surf->pStaticNormal[j], tess.normal[baseVertex + j]);
tess.texCoords[baseVertex + j][0][0] = surf->pStaticTexCoords[j][0][0];
tess.texCoords[baseVertex + j][0][1] = surf->pStaticTexCoords[j][0][1];
tess.texCoords[baseVertex + j][0][1] = surf->pStaticTexCoords[j][0][1];
tess.texCoords[baseVertex + j][1][0] = surf->pStaticTexCoords[j][1][0];
tess.texCoords[baseVertex + j][1][1] = surf->pStaticTexCoords[j][1][1];
}
if (backEndData[backEnd.smpFrame]->staticModelData) {
+5
View File
@@ -28,3 +28,8 @@ void R_InitLensFlare()
{
// FIXME: unimplemented
}
void R_DrawLensFlares()
{
// FIXME: unimplemented
}
+28 -6
View File
@@ -439,9 +439,15 @@ gotnewcl:
Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name );
newcl->state = CS_CONNECTED;
newcl->nextSnapshotTime = svs.time;
newcl->lastPacketTime = svs.time;
newcl->lastConnectTime = svs.time;
if (sv_maxclients->integer > 1) {
newcl->nextSnapshotTime = svs.time + 800;
newcl->lastPacketTime = svs.time + 800;
newcl->lastConnectTime = svs.time + 800;
} else {
newcl->nextSnapshotTime = svs.time + 300;
newcl->lastPacketTime = svs.time + 300;
newcl->lastConnectTime = svs.time + 300;
}
// when we receive the first packet from the client, we will
// notice that it is from a different serverid and that the
@@ -530,6 +536,19 @@ void SV_DropClient( client_t *drop, const char *reason ) {
}
}
#if TARGET_GAME_PROTOCOL >= 15
void MSG_WriteServerFrameTime(msg_t* msg, float f) {
MSG_WriteFloat(msg, f);
}
#else
void MSG_WriteServerFrameTime(msg_t* msg, float f) {
}
#endif
/*
================
SV_SendClientGameState
@@ -583,7 +602,7 @@ void SV_SendClientGameState( client_t *client ) {
if (sv.configstrings[start][0]) {
MSG_WriteSVC( &msg, svc_configstring );
MSG_WriteShort( &msg, start );
MSG_WriteString( &msg, sv.configstrings[start] );
MSG_WriteScrambledBigString( &msg, sv.configstrings[start] );
}
}
@@ -604,7 +623,10 @@ void SV_SendClientGameState( client_t *client ) {
MSG_WriteLong( &msg, client - svs.clients);
// write the checksum feed
MSG_WriteLong( &msg, sv.checksumFeed);
MSG_WriteLong( &msg, 0);
// write the server frametime to the client (only on TA/TT)
MSG_WriteServerFrameTime(&msg, sv.frameTime);
// deliver this to the client
SV_SendMessageToClient( &msg, client );
@@ -1310,7 +1332,7 @@ static qboolean SV_ClientCommand( client_t *cl, msg_t *msg ) {
qboolean clientOk = qtrue;
seq = MSG_ReadLong( msg );
s = MSG_ReadString( msg );
s = MSG_ReadScrambledString( msg );
// see if we have already executed it
if ( cl->lastClientCommand >= seq ) {
+2 -1
View File
@@ -521,6 +521,7 @@ void SV_ClearServer(void) {
}
}
Com_Memset (&sv, 0, sizeof(sv));
sv.frameTime = 1.0 / sv_fps->value;
}
/*
@@ -1012,7 +1013,7 @@ void SV_Init( void ) {
sv_showloss = Cvar_Get ("sv_showloss", "0", 0);
sv_padPackets = Cvar_Get ("sv_padPackets", "0", 0);
sv_killserver = Cvar_Get ("sv_killserver", "0", 0);
sv_mapChecksum = Cvar_Get ("sv_mapChecksum", "", CVAR_ROM);
sv_mapChecksum = Cvar_Get ("sv_mapChecksum", "", CVAR_ROM | CVAR_SERVERINFO);
sv_drawentities = Cvar_Get( "sv_drawentities", "1", 0 );
sv_deeptracedebug = Cvar_Get( "sv_deeptracedebug", "0", 0 );
sv_chatter = Cvar_Get( "sv_chatter", "0", 0 );
+4 -4
View File
@@ -109,7 +109,7 @@ static void SV_EmitPacketEntities( clientSnapshot_t *from, clientSnapshot_t *to,
}
}
MSG_WriteBits( msg, (MAX_GENTITIES-1), GENTITYNUM_BITS ); // end of packetentities
MSG_WriteEntityNum(msg, (MAX_GENTITIES - 1)); // end of packetentities
}
@@ -217,11 +217,11 @@ static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg ) {
MSG_WriteSVC( msg, svc_locprint );
MSG_WriteShort( msg, client->XOffset );
MSG_WriteShort( msg, client->YOffset );
MSG_WriteString( msg, client->centerprint );
MSG_WriteScrambledString( msg, client->centerprint );
}
else {
MSG_WriteSVC( msg, svc_centerprint );
MSG_WriteString( msg, client->centerprint );
MSG_WriteScrambledString( msg, client->centerprint );
}
}
@@ -248,7 +248,7 @@ void SV_UpdateServerCommandsToClient( client_t *client, msg_t *msg ) {
for ( i = client->reliableAcknowledge + 1 ; i <= client->reliableSequence ; i++ ) {
MSG_WriteSVC( msg, svc_serverCommand );
MSG_WriteLong( msg, i );
MSG_WriteString( msg, client->reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
MSG_WriteScrambledString( msg, client->reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
}
client->reliableSent = client->reliableSequence;
}
+26 -16
View File
@@ -328,13 +328,24 @@ TIKI_ParseIncludes
*/
qboolean TIKI_ParseIncludes( dloaddef_t *ld )
{
const char *token;
const char* token;
qboolean b_incl = false;
const char *mapname;
const char* mapname;
const char* servertype;
int depth = 0;
token = ld->tikiFile.GetToken( true );
if( sv_mapname )
static cvar_t* pServerType = Cvar_Get("g_servertype", "2", 0);
static cvar_t* pGameType = Cvar_Get("cg_gametype", "0", CVAR_SERVERINFO | CVAR_LATCH);
if (pGameType->integer && pServerType->integer == 1) {
servertype = "spearheadserver";
}
else {
servertype = "breakthroughserver";
}
token = ld->tikiFile.GetToken(true);
if (sv_mapname)
{
mapname = sv_mapname->string;
}
@@ -343,38 +354,37 @@ qboolean TIKI_ParseIncludes( dloaddef_t *ld )
mapname = "utils";
}
while( 1 )
while (1)
{
if( !strncmp( token, mapname, strlen( token ) )
|| !strncmp( token, "spearheadserver", strlen( token ) )
|| !strncmp( token, "breakthroughserver", strlen( token ) ) )
if (!strncmp(token, mapname, strlen(token))
|| !strncmp(token, servertype, strlen(token)))
{
b_incl = true;
}
else if( ( !stricmp( token, "{" ) || !ld->tikiFile.TokenAvailable( true ) ) )
else if ((!stricmp(token, "{") || !ld->tikiFile.TokenAvailable(true)))
{
break;
}
token = ld->tikiFile.GetToken( true );
token = ld->tikiFile.GetToken(true);
}
if( b_incl )
if (b_incl)
{
return true;
}
while( ld->tikiFile.TokenAvailable( true ) )
while (ld->tikiFile.TokenAvailable(true))
{
token = ld->tikiFile.GetAndIgnoreLine( false );
if( strstr( token, "{" ) )
token = ld->tikiFile.GetAndIgnoreLine(false);
if (strstr(token, "{"))
{
depth++;
}
if( strstr( token, "}" ) )
if (strstr(token, "}"))
{
if( !depth )
if (!depth)
{
break;
}
+2
View File
@@ -230,5 +230,7 @@ void UI_SetCvarInt( const char *cvar, int value );
void UI_SetCvarFloat( const char *cvar, float value );
void UI_ListFiles( const char *filespec );
const char *UI_ConfigString( int index );
void UI_UpdateCenterPrint(const char* s, float alpha);
void UI_UpdateLocationPrint(int x, int y, const char* s, float alpha);
#endif
-1
View File
@@ -174,7 +174,6 @@ void UILayout::ProcessCommands
cl = "UI";
cl += newname;
cls = getClass( cl );
assert( cls );
if( !cls )
{
Com_Printf( "Failed to find resource type '%s'\n", token );
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB