Adding unlagged. Still needs work.

This commit is contained in:
Richard Allen 2003-03-09 21:30:39 +00:00
parent 04de609254
commit 8963c6a49f
24 changed files with 751 additions and 489 deletions

View file

@ -48,6 +48,7 @@ GOBJ = \
$(GDIRNAME)/rxn_game.o \
$(GDIRNAME)/g_teamplay.o \
$(GDIRNAME)/g_matchmode.o \
$(GDIRNAME)/g_unlagged.o \
$(GDIRNAME)/zcam.o \
$(GDIRNAME)/zcam_target.o
@ -75,6 +76,7 @@ CGOBJ = \
$(CGDIRNAME)/cg_snapshot.o \
$(CGDIRNAME)/cg_view.o \
$(CGDIRNAME)/cg_atmospheric.o \
$(CGDIRNAME)/cg_unlagged.o \
$(CGDIRNAME)/cg_weapons.o
UIOBJ = \

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.70 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.69 2002/10/30 21:24:47 jbravo
// Minor helmet tweaking
//
@ -1568,7 +1571,8 @@ static void CG_DrawLagometer(void)
int color;
float vscale;
if (!cg_lagometer.integer || cgs.localServer) {
// JBravo: unlagged
if (!cg_lagometer.integer /*|| cgs.localServer*/) {
CG_DrawDisconnect();
return;
}

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.39 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.38 2003/03/08 09:58:08 niceass
// Changes to make my "position on tag with offset" work correctly with orientation matrices crap for CTB tag_weapon2
//
@ -876,16 +879,20 @@ CG_CalcEntityLerpPositions
*/
static void CG_CalcEntityLerpPositions(centity_t * cent)
{
// JBravo: unlagged
int timeshift = 0;
// this is done server-side now - cg_smoothClients is undefined
// players will always be TR_INTERPOLATE
// if this player does not want to see extrapolated players
if (!cg_smoothClients.integer) {
/* if (!cg_smoothClients.integer) {
// make sure the clients use TR_INTERPOLATE
if (cent->currentState.number < MAX_CLIENTS) {
cent->currentState.pos.trType = TR_INTERPOLATE;
cent->nextState.pos.trType = TR_INTERPOLATE;
}
}
*/
if (cent->interpolate && cent->currentState.pos.trType == TR_INTERPOLATE) {
CG_InterpolateEntityPosition(cent);
return;
@ -897,9 +904,40 @@ static void CG_CalcEntityLerpPositions(centity_t * cent)
CG_InterpolateEntityPosition(cent);
return;
}
if (cent->currentState.number < MAX_CLIENTS &&
cent->currentState.clientNum != cg.predictedPlayerState.clientNum) {
cent->currentState.pos.trType = TR_LINEAR_STOP;
cent->currentState.pos.trTime = cg.snap->serverTime;
cent->currentState.pos.trDuration = 1000 / sv_fps.integer;
}
if (cent->currentState.eType == ET_MISSILE) {
// if it's one of ours
if (cent->currentState.otherEntityNum == cg.clientNum) {
timeshift = 1000 / sv_fps.integer;
}
}
// just use the current frame and evaluate as best we can
CG_EvaluateTrajectory(&cent->currentState.pos, cg.time, cent->lerpOrigin);
CG_EvaluateTrajectory(&cent->currentState.apos, cg.time, cent->lerpAngles);
// CG_EvaluateTrajectory(&cent->currentState.pos, cg.time, cent->lerpOrigin);
// CG_EvaluateTrajectory(&cent->currentState.apos, cg.time, cent->lerpAngles);
BG_EvaluateTrajectory(&cent->currentState.pos, cg.time + timeshift, cent->lerpOrigin);
BG_EvaluateTrajectory(&cent->currentState.apos, cg.time + timeshift, cent->lerpAngles);
if (timeshift != 0) {
trace_t tr;
vec3_t lastOrigin;
BG_EvaluateTrajectory (&cent->currentState.pos, cg.time, lastOrigin);
CG_Trace(&tr, lastOrigin, vec3_origin, vec3_origin, cent->lerpOrigin, cent->currentState.number, MASK_SHOT);
// don't let the projectile go through the floor
if (tr.fraction < 1.0f) {
cent->lerpOrigin[0] = lastOrigin[0] + tr.fraction * (cent->lerpOrigin[0] - lastOrigin[0]);
cent->lerpOrigin[1] = lastOrigin[1] + tr.fraction * (cent->lerpOrigin[1] - lastOrigin[1]);
cent->lerpOrigin[2] = lastOrigin[2] + tr.fraction * (cent->lerpOrigin[2] - lastOrigin[2]);
}
}
// adjust for riding a mover if it wasn't rolled into the predicted
// player state
@ -1071,7 +1109,7 @@ void CG_AddPacketEntities(int mode)
}
} else {
cg.frameInterpolation = 0; // actually, it should never be used, because
// no entities7 should be marked as interpolating
// no entities should be marked as interpolating
}
// the auto-rotating items will all have the same axis
@ -1094,6 +1132,17 @@ void CG_AddPacketEntities(int mode)
// lerp the non-predicted value for lightning gun origins
CG_CalcEntityLerpPositions(&cg_entities[cg.snap->ps.clientNum]);
// JBravo: unlagged
if (cg.nextSnap) {
for (num = 0 ; num < cg.nextSnap->numEntities ; num++) {
cent = &cg_entities[cg.nextSnap->entities[num].number];
if (cent->nextState.eType == ET_MISSILE || cent->nextState.eType == ET_GENERAL) {
CG_TransitionEntity(cent);
cent->interpolate = qtrue;
CG_AddCEntity(cent);
}
}
}
}
if (mode != -1) {
@ -1114,7 +1163,9 @@ void CG_AddPacketEntities(int mode)
} else {
for (num = 0; num < cg.snap->numEntities; num++) {
cent = &cg_entities[cg.snap->entities[num].number];
CG_AddCEntity(cent);
if (!cg.nextSnap || (cent->nextState.eType != ET_MISSILE && cent->nextState.eType != ET_GENERAL)) {
CG_AddCEntity(cent);
}
}
}
}

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.71 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.70 2002/11/09 14:13:32 makro
// Added tdmMode info to the loading screen
//
@ -1003,85 +1006,122 @@ void CG_EntityEvent(centity_t * cent, vec3_t position)
case EV_BULLET_HIT_WALL:
DEBUGNAME("EV_BULLET_HIT_WALL");
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_DEFAULT);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
// do nothing, because it was already predicted
// Com_Printf("Ignoring bullet event\n");
} else {
// do the bullet, because it wasn't predicted
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_DEFAULT);
//Com_Printf("Non-predicted bullet\n");
}
break;
case EV_BULLET_HIT_METAL:
DEBUGNAME("EV_BULLET_HIT_METAL");
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_METAL);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_METAL);
}
break;
case EV_BULLET_HIT_GLASS:
DEBUGNAME("EV_BULLET_HIT_GLASS");
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_GLASS);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_GLASS);
}
break;
//Makro - added
case EV_BULLET_HIT_WOOD:
DEBUGNAME("EV_BULLET_HIT_WOOD");
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_WOOD);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_WOOD);
}
break;
//Makro - added
case EV_BULLET_HIT_BRICK:
DEBUGNAME("EV_BULLET_HIT_BRICK");
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_BRICK);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_BRICK);
}
break;
//Makro - added
case EV_BULLET_HIT_CERAMIC:
DEBUGNAME("EV_BULLET_HIT_CERAMIC");
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_CERAMIC);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
ByteToDir(es->eventParm, dir);
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_CERAMIC);
}
break;
case EV_BULLET_HIT_KEVLAR:
DEBUGNAME("EV_BULLET_HIT_KEVLAR");
ByteToDir(es->eventParm, dir);
VectorScale(dir, -1, dir);
trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.kevlarHitSound);
if (cg_RQ3_impactEffects.integer) {
vec3_t velocity;
vec3_t origin;
int sparkCount;
int i;
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
ByteToDir(es->eventParm, dir);
VectorScale(dir, -1, dir);
trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.kevlarHitSound);
if (cg_RQ3_impactEffects.integer) {
vec3_t velocity, origin;
int sparkCount, i;
sparkCount = 20 + rand() % 15;
VectorCopy(es->pos.trBase, origin);
origin[2] += 12;
// Generate the particles
for (i = 0; i < sparkCount; i++) {
VectorScale(dir, 150 + rand() % 30, velocity);
//random upwards sparks
if (rand() % 5 < 1)
velocity[2] += 120 + rand() % 30;
sparkCount = 20 + rand() % 15;
VectorCopy(es->pos.trBase, origin);
origin[2] += 12;
// Generate the particles
for (i = 0; i < sparkCount; i++) {
VectorScale(dir, 150 + rand() % 30, velocity);
//random upwards sparks
if (rand() % 5 < 1)
velocity[2] += 120 + rand() % 30;
velocity[0] += rand() % 80 - 40;
velocity[1] += rand() % 80 - 40;
CG_ParticleSparks(origin, velocity, 150 + rand() % 120, 2, 2, -4, 1);
velocity[0] += rand() % 80 - 40;
velocity[1] += rand() % 80 - 40;
CG_ParticleSparks(origin, velocity, 150 + rand() % 120, 2, 2, -4, 1);
}
}
}
break;
case EV_BULLET_HIT_FLESH:
DEBUGNAME("EV_BULLET_HIT_FLESH");
//ByteToDir( es->eventParm, dir );
//Elder: added additional param
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
//ByteToDir( es->eventParm, dir );
//Elder: added additional param
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH);
}
break;
case EV_SSG3000_HIT_FLESH:
DEBUGNAME("EV_SSG3000_HIT_FLESH");
ByteToDir(es->eventParm, dir);
//Elder: added additional param
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH);
VectorAdd(es->pos.trBase, dir, dir);
CG_BleedSpray(es->pos.trBase, dir, es->otherEntityNum2, 10);
if (es->clientNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2)) {
} else {
ByteToDir(es->eventParm, dir);
//Elder: added additional param
CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH);
VectorAdd(es->pos.trBase, dir, dir);
CG_BleedSpray(es->pos.trBase, dir, es->otherEntityNum2, 10);
}
break;
case EV_JUMPKICK:
@ -1105,12 +1145,20 @@ void CG_EntityEvent(centity_t * cent, vec3_t position)
case EV_SHOTGUN:
DEBUGNAME("EV_SHOTGUN");
CG_ShotgunFire(es, qtrue);
if (es->otherEntityNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 4)) {
} else {
CG_ShotgunFire(es, qtrue);
}
break;
case EV_HANDCANNON:
DEBUGNAME("EV_SHOTGUN");
CG_ShotgunFire(es, qfalse);
DEBUGNAME("EV_HANDCANNON");
if (es->otherEntityNum == cg.predictedPlayerState.clientNum &&
cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 4)) {
} else {
CG_ShotgunFire(es, qfalse);
}
break;
case EV_GENERAL_SOUND:
@ -1141,16 +1189,6 @@ void CG_EntityEvent(centity_t * cent, vec3_t position)
case RQ3_SOUND_KICK:
trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.kickSound);
break;
//Elder: handled in EV_HEADSHOT now
/*
case RQ3_SOUND_HEADSHOT:
//CG_Printf("EV_RQ3_SOUND: Headshot\n");
//Elder: extra blood - synched with sound
//CG_Bleed( position, es->number );
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.headshotSound);
break;
*/
case RQ3_SOUND_LCA:
//Global sound
//trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.media.lcaSound);

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.137 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.136 2003/02/27 08:10:20 jbravo
// Added replacement model functionality for ammo
//
@ -829,6 +832,9 @@ typedef struct {
#define MAX_PREDICTED_EVENTS 16
// JBravo: unlagged
#define NUM_SAVED_STATES (CMD_BACKUP + 2)
typedef struct {
int clientFrame; // incremented each frame
@ -1073,6 +1079,11 @@ typedef struct {
int refready;
int CTBcountdowntime;
// JBravo: unlagged
int lastPredictedCommand;
int lastServerTime;
playerState_t savedPmoveStates[NUM_SAVED_STATES];
int stateHead, stateTail;
} cg_t;
//Blaze: struct to hold the func_breakable stuff
@ -1620,7 +1631,8 @@ typedef struct {
// media
cgMedia_t media;
// JBravo: unlagged
int delagHitscan;
} cgs_t;
//==============================================================================
@ -1815,7 +1827,7 @@ extern vmCvar_t cg_teamChatsOnly;
extern vmCvar_t cg_noVoiceChats;
extern vmCvar_t cg_noVoiceText;
extern vmCvar_t cg_scorePlum;
extern vmCvar_t cg_smoothClients;
//extern vmCvar_t cg_smoothClients;
extern vmCvar_t pmove_fixed;
extern vmCvar_t pmove_msec;
@ -1835,6 +1847,19 @@ extern vmCvar_t cg_oldRocket;
extern vmCvar_t cg_oldPlasma;
extern vmCvar_t cg_trueLightning;
// JBravo: unlagged
extern vmCvar_t cg_delag;
extern vmCvar_t cg_debugDelag;
extern vmCvar_t cg_drawBBox;
extern vmCvar_t cg_cmdTimeNudge;
extern vmCvar_t sv_fps;
extern vmCvar_t cg_projectileNudge;
extern vmCvar_t cg_optimizePrediction;
extern vmCvar_t cl_timeNudge;
extern vmCvar_t cg_latentSnaps;
extern vmCvar_t cg_latentCmds;
extern vmCvar_t cg_plOut;
// NiceAss: No longer part of the MissionPack
extern vmCvar_t cg_enableBreath;
extern vmCvar_t cg_enableLaserFog;
@ -1891,6 +1916,10 @@ extern vmCvar_t cg_RQ3_matchmode;
extern vmCvar_t cg_atmosphericEffects;
extern vmCvar_t cg_lowEffects;
void CG_PredictWeaponEffects(centity_t *cent);
void CG_AddBoundingBox(centity_t *cent);
qboolean CG_Cvar_ClampInt(const char *name, vmCvar_t *vmCvar, int min, int max);
//
// cg_main.c
//
@ -2161,6 +2190,7 @@ void CG_Pressure(vec3_t origin, vec3_t dir, int type, int speed, int life);
// cg_snapshot.c
//
void CG_ProcessSnapshots(void);
void CG_TransitionEntity(centity_t *cent);
//
// cg_info.c

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.123 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.122 2003/02/27 08:10:20 jbravo
// Added replacement model functionality for ammo
//
@ -555,7 +558,7 @@ vmCvar_t cg_noVoiceChats;
vmCvar_t cg_noVoiceText;
vmCvar_t cg_hudFiles;
vmCvar_t cg_scorePlum;
vmCvar_t cg_smoothClients;
//vmCvar_t cg_smoothClients;
vmCvar_t pmove_fixed;
//vmCvar_t cg_pmove_fixed;
@ -577,6 +580,19 @@ vmCvar_t cg_oldRocket;
vmCvar_t cg_oldPlasma;
vmCvar_t cg_trueLightning;
// JBravo: unlagged
vmCvar_t cg_delag;
vmCvar_t cg_debugDelag;
vmCvar_t cg_drawBBox;
vmCvar_t cg_cmdTimeNudge;
vmCvar_t sv_fps;
vmCvar_t cg_projectileNudge;
vmCvar_t cg_optimizePrediction;
vmCvar_t cl_timeNudge;
vmCvar_t cg_latentSnaps;
vmCvar_t cg_latentCmds;
vmCvar_t cg_plOut;
//Blaze: cheat struct
cheat_cvar cheats[30];
@ -769,7 +785,7 @@ static cvarTable_t cvarTable[] = { // bk001129
{&cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0},
{&cg_timescale, "timescale", "1", 0},
{&cg_scorePlum, "cg_scorePlums", "1", CVAR_USERINFO | CVAR_ARCHIVE},
{&cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE},
// {&cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE},
{&cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT},
{&pmove_fixed, "pmove_fixed", "0", 0},
@ -863,8 +879,20 @@ static cvarTable_t cvarTable[] = { // bk001129
{&cg_RQ3_bot_minplayers, "bot_minplayers", "0", CVAR_ROM},
{&cg_RQ3_showOwnKills, "g_RQ3_showOwnKills", "0", CVAR_ROM},
// q3f atmospheric stuff:
{ &cg_atmosphericEffects, "cg_atmosphericEffects", "1", CVAR_ARCHIVE },
{ &cg_lowEffects, "cg_lowEffects", "0", CVAR_ARCHIVE },
{&cg_atmosphericEffects, "cg_atmosphericEffects", "1", CVAR_ARCHIVE},
{&cg_lowEffects, "cg_lowEffects", "0", CVAR_ARCHIVE},
// JBravo: unlagged
{&cg_delag, "cg_delag", "1", CVAR_ARCHIVE | CVAR_USERINFO},
{&cg_debugDelag, "cg_debugDelag", "0", CVAR_USERINFO | CVAR_CHEAT},
{&cg_drawBBox, "cg_drawBBox", "0", CVAR_CHEAT},
{&cg_cmdTimeNudge, "cg_cmdTimeNudge", "0", CVAR_ARCHIVE | CVAR_USERINFO},
{&sv_fps, "sv_fps", "20", 0},
{&cg_projectileNudge, "cg_projectileNudge", "0", CVAR_ARCHIVE},
{&cg_optimizePrediction, "cg_optimizePrediction", "1", CVAR_ARCHIVE},
{&cl_timeNudge, "cl_timeNudge", "0", CVAR_ARCHIVE},
{&cg_latentSnaps, "cg_latentSnaps", "0", CVAR_USERINFO | CVAR_CHEAT},
{&cg_latentCmds, "cg_latentCmds", "0", CVAR_USERINFO | CVAR_CHEAT},
{&cg_plOut, "cg_plOut", "0", CVAR_USERINFO | CVAR_CHEAT},
//{ &cg_RQ3_RefID, "g_RQ3_RefID", "0", 0}
//{ &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
@ -930,6 +958,18 @@ void CG_UpdateCvars(void)
cvarTable_t *cv;
for (i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++) {
// JBravo: unlagged
if (cv->vmCvar == &cg_cmdTimeNudge) {
CG_Cvar_ClampInt(cv->cvarName, cv->vmCvar, 0, 999);
} else if (cv->vmCvar == &cl_timeNudge) {
CG_Cvar_ClampInt( cv->cvarName, cv->vmCvar, -50, 50);
} else if (cv->vmCvar == &cg_latentSnaps) {
CG_Cvar_ClampInt( cv->cvarName, cv->vmCvar, 0, 10);
} else if (cv->vmCvar == &cg_latentCmds) {
CG_Cvar_ClampInt( cv->cvarName, cv->vmCvar, 0, MAX_LATENT_CMDS - 1);
} else if (cv->vmCvar == &cg_plOut) {
CG_Cvar_ClampInt( cv->cvarName, cv->vmCvar, 0, 100);
}
trap_Cvar_Update(cv->vmCvar);
}

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.57 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.56 2003/03/08 10:02:23 niceass
// CTB briefcases in 3rd person now utilize tag_weapon2
//
@ -2640,6 +2643,8 @@ void CG_Player(centity_t * cent)
if (cent->currentState.eFlags & EF_HANDCANNON_SMOKED) {
CG_HCSmokeTrail(cent);
}
// JBravo: unlagged
CG_AddBoundingBox(cent);
}
//=====================================================================

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.26 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.25 2002/07/21 18:47:27 niceass
// weaponprediction cvar added
//
@ -415,6 +418,135 @@ static void CG_TouchTriggerPrediction(void)
}
}
// JBravo: unlagged
#define ABS(x) ((x) < 0 ? (-(x)) : (x))
static int IsUnacceptableError( playerState_t *ps, playerState_t *pps ) {
vec3_t delta;
int i;
if (pps->pm_type != ps->pm_type ||
pps->pm_flags != ps->pm_flags ||
pps->pm_time != ps->pm_time) {
return 1;
}
VectorSubtract(pps->origin, ps->origin, delta);
if (VectorLengthSquared( delta ) > 0.1f * 0.1f) {
if (cg_showmiss.integer) {
CG_Printf("delta: %.2f ", VectorLength(delta));
}
return 2;
}
VectorSubtract(pps->velocity, ps->velocity, delta);
if (VectorLengthSquared( delta ) > 0.1f * 0.1f) {
if (cg_showmiss.integer) {
CG_Printf("delta: %.2f ", VectorLength(delta));
}
return 3;
}
if (pps->weaponTime != ps->weaponTime ||
pps->gravity != ps->gravity ||
pps->speed != ps->speed ||
pps->delta_angles[0] != ps->delta_angles[0] ||
pps->delta_angles[1] != ps->delta_angles[1] ||
pps->delta_angles[2] != ps->delta_angles[2] ||
pps->groundEntityNum != ps->groundEntityNum) {
return 4;
}
if (pps->legsTimer != ps->legsTimer ||
pps->legsAnim != ps->legsAnim ||
pps->torsoTimer != ps->torsoTimer ||
pps->torsoAnim != ps->torsoAnim ||
pps->movementDir != ps->movementDir) {
return 5;
}
VectorSubtract(pps->grapplePoint, ps->grapplePoint, delta);
if (VectorLengthSquared(delta) > 0.1f * 0.1f) {
return 6;
}
if (pps->eFlags != ps->eFlags) {
return 7;
}
if (pps->eventSequence != ps->eventSequence) {
return 8;
}
for (i = 0; i < MAX_PS_EVENTS; i++) {
if (pps->events[i] != ps->events[i] ||
pps->eventParms[i] != ps->eventParms[i]) {
return 9;
}
}
if (pps->externalEvent != ps->externalEvent ||
pps->externalEventParm != ps->externalEventParm ||
pps->externalEventTime != ps->externalEventTime) {
return 10;
}
if (pps->clientNum != ps->clientNum ||
pps->weapon != ps->weapon ||
pps->weaponstate != ps->weaponstate) {
return 11;
}
if (ABS(pps->viewangles[0] - ps->viewangles[0]) > 1.0f ||
ABS(pps->viewangles[1] - ps->viewangles[1]) > 1.0f ||
ABS(pps->viewangles[2] - ps->viewangles[2]) > 1.0f) {
return 12;
}
if (pps->viewheight != ps->viewheight) {
return 13;
}
if (pps->damageEvent != ps->damageEvent ||
pps->damageYaw != ps->damageYaw ||
pps->damagePitch != ps->damagePitch ||
pps->damageCount != ps->damageCount) {
return 14;
}
for (i = 0; i < MAX_STATS; i++) {
if (pps->stats[i] != ps->stats[i]) {
return 15;
}
}
for (i = 0; i < MAX_PERSISTANT; i++) {
if (pps->persistant[i] != ps->persistant[i]) {
return 16;
}
}
for (i = 0; i < MAX_POWERUPS; i++) {
if (pps->powerups[i] != ps->powerups[i]) {
return 17;
}
}
for (i = 0; i < MAX_WEAPONS; i++) {
if (pps->ammo[i] != ps->ammo[i]) {
return 18;
}
}
if (pps->generic1 != ps->generic1 ||
pps->loopSound != ps->loopSound ||
pps->jumppad_ent != ps->jumppad_ent) {
return 19;
}
return 0;
}
/*
=================
CG_PredictPlayerState
@ -448,6 +580,9 @@ void CG_PredictPlayerState(void)
qboolean moved;
usercmd_t oldestCmd;
usercmd_t latestCmd;
// JBravo: unlagged
int stateIndex, predictCmd;
int numPredicted = 0, numPlayedBack = 0;
cg.hyperspace = qfalse; // will be set if touching a trigger_teleport
@ -529,6 +664,44 @@ void CG_PredictPlayerState(void)
cg_pmove.pmove_fixed = pmove_fixed.integer; // | cg_pmove_fixed.integer;
cg_pmove.pmove_msec = pmove_msec.integer;
// JBravo: unlagged
if (cg_optimizePrediction.integer && !cg_latentCmds.integer) {
if (cg.nextFrameTeleport || cg.thisFrameTeleport) {
cg.lastPredictedCommand = 0;
cg.stateTail = cg.stateHead;
predictCmd = current - CMD_BACKUP + 1;
} else if (cg.physicsTime == cg.lastServerTime) {
predictCmd = cg.lastPredictedCommand + 1;
} else {
int i;
qboolean error = qtrue;
for (i = cg.stateHead; i != cg.stateTail; i = (i + 1) % NUM_SAVED_STATES) {
if (cg.savedPmoveStates[i].commandTime == cg.predictedPlayerState.commandTime) {
int errorcode = IsUnacceptableError(&cg.predictedPlayerState, &cg.savedPmoveStates[i]);
if (errorcode) {
if (cg_showmiss.integer) {
CG_Printf("errorcode %d at %d\n", errorcode, cg.time);
}
break;
}
*cg_pmove.ps = cg.savedPmoveStates[i];
cg.stateHead = (i + 1) % NUM_SAVED_STATES;
predictCmd = cg.lastPredictedCommand + 1;
error = qfalse;
break;
}
}
if (error) {
cg.lastPredictedCommand = 0;
cg.stateTail = cg.stateHead;
predictCmd = current - CMD_BACKUP + 1;
}
}
cg.lastServerTime = cg.physicsTime;
stateIndex = cg.stateHead;
}
// run cmds
moved = qfalse;
for (cmdNum = current - CMD_BACKUP + 1; cmdNum <= current; cmdNum++) {
@ -610,28 +783,6 @@ void CG_PredictPlayerState(void)
((cg_pmove.cmd.serverTime + pmove_msec.integer -
1) / pmove_msec.integer) * pmove_msec.integer;
}
//Elder: predict bursting here
/*
if ( (cg.snap->ps.weapon == WP_M4 &&
(cg.snap->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE) ||
(cg.snap->ps.weapon == WP_MP5 &&
(cg.snap->ps.persistant[PERS_WEAPONMODES] & RQ3_MP5MODE) == RQ3_MP5MODE))
{
if (cg_pmove.cmd.buttons & BUTTON_ATTACK)// && client->ps.stats[STAT_BURST] > 0)
{
if ( cg.snap->ps.stats[STAT_BURST] >= 0 && cg.snap->ps.stats[STAT_BURST] < 3)
cg_pmove.cmd.buttons |= BUTTON_ATTACK;
else
cg_pmove.cmd.buttons &= ~BUTTON_ATTACK;
}
else if (cg.snap->ps.stats[STAT_BURST] > 2)
{
cg.snap->ps.stats[STAT_BURST] = 0;
cg.snap->ps.weaponTime += 500;
}
else if (cg.snap->ps.stats[STAT_BURST] > 0)
cg_pmove.cmd.buttons |= BUTTON_ATTACK;
} */
// JBravo: setting lca in pm if needed
//if (cg_RQ3_lca.integer == 1)
@ -646,7 +797,30 @@ void CG_PredictPlayerState(void)
else
cg_pmove.predict = qfalse;
Pmove(&cg_pmove);
// JBravo: unlagged
if (cg_optimizePrediction.integer && !cg_latentCmds.integer) {
if (cmdNum >= predictCmd || (stateIndex + 1) % NUM_SAVED_STATES == cg.stateHead) {
Pmove (&cg_pmove);
numPredicted++;
cg.lastPredictedCommand = cmdNum;
if ((stateIndex + 1) % NUM_SAVED_STATES != cg.stateHead) {
cg.savedPmoveStates[stateIndex] = *cg_pmove.ps;
stateIndex = (stateIndex + 1) % NUM_SAVED_STATES;
cg.stateTail = stateIndex;
}
} else {
numPlayedBack++;
if (cg_showmiss.integer &&
cg.savedPmoveStates[stateIndex].commandTime != cg_pmove.cmd.serverTime) {
CG_Printf("saved state miss\n");
}
*cg_pmove.ps = cg.savedPmoveStates[stateIndex];
stateIndex = (stateIndex + 1) % NUM_SAVED_STATES;
}
} else {
Pmove (&cg_pmove);
numPredicted++;
}
moved = qtrue;

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.71 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.70 2002/10/26 22:03:43 jbravo
// Made TeamDM work RQ3 style.
//
@ -397,6 +400,9 @@ void CG_ParseServerinfo(void)
trap_Cvar_Set("g_redTeam", cgs.redTeam);
Q_strncpyz(cgs.blueTeam, Info_ValueForKey(info, "g_blueTeam"), sizeof(cgs.blueTeam));
trap_Cvar_Set("g_blueTeam", cgs.blueTeam);
// JBravo: unlagged
cgs.delagHitscan = atoi(Info_ValueForKey(info, "g_delagHitscan"));
trap_Cvar_Set("g_delagHitscan", va("%i", cgs.delagHitscan));
}
/*

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.7 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.6 2002/06/16 20:06:13 jbravo
// Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap"
//
@ -52,7 +55,7 @@ CG_TransitionEntity
cent->nextState is moved to cent->currentState and events are fired
===============
*/
static void CG_TransitionEntity(centity_t * cent)
void CG_TransitionEntity(centity_t * cent)
{
cent->currentState = cent->nextState;
cent->currentValid = qtrue;
@ -269,6 +272,17 @@ static snapshot_t *CG_ReadNextSnapshot(void)
cgs.processedSnapshotNum++;
r = trap_GetSnapshot(cgs.processedSnapshotNum, dest);
// JBravo: unlagged
if (cg_latentSnaps.integer && r) {
int i = 0, time = dest->serverTime;
while (dest->serverTime > time - cg_latentSnaps.integer * (1000 / sv_fps.integer)) {
if (!(r = trap_GetSnapshot(cgs.processedSnapshotNum - i, dest))) {
break;
}
i++;
}
}
// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
if (cg.snap && r && dest->serverTime == cg.snap->serverTime) {
//continue;
@ -323,7 +337,11 @@ void CG_ProcessSnapshots(void)
if (n != cg.latestSnapshotNum) {
if (n < cg.latestSnapshotNum) {
// this should never happen
CG_Error("CG_ProcessSnapshots: n < cg.latestSnapshotNum");
if (cg_latentSnaps.integer) {
CG_Printf("WARNING: CG_ProcessSnapshots: n < cg.latestSnapshotNum\n");
} else {
CG_Error("CG_ProcessSnapshots: n < cg.latestSnapshotNum");
}
}
cg.latestSnapshotNum = n;
}
@ -361,7 +379,11 @@ void CG_ProcessSnapshots(void)
// if time went backwards, we have a level restart
if (cg.nextSnap->serverTime < cg.snap->serverTime) {
CG_Error("CG_ProcessSnapshots: Server time went backwards");
if (cg_latentSnaps.integer) {
CG_Printf("WARNING: CG_ProcessSnapshots: Server time went backwards\n");
} else {
CG_Error("CG_ProcessSnapshots: Server time went backwards");
}
}
}
// if our time is < nextFrame's, we have a nice interpolating state

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.30 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.29 2002/09/01 21:14:37 makro
// Sky portal tweaks
//
@ -1139,6 +1142,9 @@ void CG_DrawActiveFrame(int serverTime, stereoFrame_t stereoView, qboolean demoP
//end Blaze
cg.time = serverTime;
// JBravo: unlagged
cg.time -= cg_latentSnaps.integer * (1000 / sv_fps.integer);
cg.demoPlayback = demoPlayback;
// update cvars

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.106 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.105 2003/03/08 10:04:12 niceass
// small code change. should make no difference
//
@ -2254,6 +2257,8 @@ void CG_FireWeapon(centity_t * cent, int weapModification)
break;
}
}
// JBravo: unlagged
CG_PredictWeaponEffects(cent);
}
/*
@ -2768,7 +2773,7 @@ Perform the same traces the server did to locate the
hit splashes
================
*/
static void CG_ShotgunPattern(vec3_t origin, vec3_t origin2, int otherEntNum, int shotType, int seed)
void CG_ShotgunPattern(vec3_t origin, vec3_t origin2, int otherEntNum, int shotType, int seed)
{
int i, count;
float r, u;

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.55 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.54 2003/02/27 07:33:58 jbravo
// Bots stfy about flags. Its cases. Teamname fixes. TP style TP fixes.
//
@ -2918,6 +2921,11 @@ int BotFindEnemy(bot_state_t * bs, int curenemy)
if (EntityIsInvisible(&entinfo) && !EntityIsShooting(&entinfo)) {
continue;
}
// JBravo: unlagged
if (g_entities[i].flags & FL_NOTARGET) {
continue;
}
//if not an easy fragger don't shoot at chatting players
if (easyfragger < 0.5 && EntityIsChatting(&entinfo))
continue;

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.96 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.95 2002/11/13 00:50:38 jbravo
// Fixed item dropping, specmode selection on death and helmet probs.
//
@ -1099,6 +1102,49 @@ void ClientThink_real(gentity_t * ent)
if (ucmd->serverTime < level.time - 1000) {
ucmd->serverTime = level.time - 1000;
}
// JBravo: unlagged
client->frameOffset = trap_Milliseconds() - level.frameStartTime;
if (client->pers.plOut) {
float thresh = (float)client->pers.plOut / 100.0f;
if (random() < thresh) {
return;
}
}
client->pers.pingsamples[client->pers.samplehead] = level.previousTime + client->frameOffset - ucmd->serverTime;
client->pers.samplehead++;
if ( client->pers.samplehead >= NUM_PING_SAMPLES ) {
client->pers.samplehead -= NUM_PING_SAMPLES;
}
if (g_truePing.integer) {
int i, sum = 0;
for (i = 0; i < NUM_PING_SAMPLES; i++) {
sum += client->pers.pingsamples[i];
}
client->pers.realPing = sum / NUM_PING_SAMPLES;
} else {
client->pers.realPing = client->ps.ping;
}
if (client->pers.latentCmds) {
int time = ucmd->serverTime;
int cmdindex = client->pers.cmdhead - client->pers.latentCmds - 1;
while (cmdindex < 0) {
cmdindex += MAX_LATENT_CMDS;
}
client->pers.cmd = client->pers.cmdqueue[cmdindex];
client->pers.realPing += time - ucmd->serverTime;
}
client->attackTime = ucmd->serverTime;
client->lastUpdateFrame = level.framenum;
if (client->pers.latentSnaps) {
client->pers.realPing += client->pers.latentSnaps * (1000 / sv_fps.integer);
client->attackTime -= client->pers.latentSnaps * (1000 / sv_fps.integer);
}
if (client->pers.realPing < 0) {
client->pers.realPing = 0;
}
msec = ucmd->serverTime - client->ps.commandTime;
// following others may result in bad times, but we still want
@ -1220,11 +1266,12 @@ void ClientThink_real(gentity_t * ent)
if (ent->client->ps.eventSequence != oldEventSequence) {
ent->eventTime = level.time;
}
if (g_smoothClients.integer) {
/* if (g_smoothClients.integer) {
BG_PlayerStateToEntityStateExtraPolate(&ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue);
} else {
BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, qtrue);
}
} */
BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, qtrue);
SendPendingPredictableEvents(&ent->client->ps);
if (!(ent->client->ps.eFlags & EF_FIRING)) {
@ -1344,7 +1391,7 @@ void ClientThink(int clientNum)
// mark the time we got info, so we can display the
// phone jack if they don't get any for a while
ent->client->lastCmdTime = level.time;
// ent->client->lastCmdTime = level.time;
/* camera jitter fix (server side) */
// JBravo: Take SPECTATOR_ZCAM into account
@ -1450,6 +1497,7 @@ void ClientEndFrame(gentity_t * ent)
{
int i;
clientPersistant_t *pers;
int frames;
if (ent->client->sess.sessionTeam == TEAM_SPECTATOR) {
SpectatorClientEndFrame(ent);
@ -1491,11 +1539,11 @@ void ClientEndFrame(gentity_t * ent)
P_DamageFeedback(ent);
// add the EF_CONNECTION flag if we haven't gotten commands recently
if (level.time - ent->client->lastCmdTime > 1000) {
/* if (level.time - ent->client->lastCmdTime > 1000) {
ent->s.eFlags |= EF_CONNECTION;
} else {
ent->s.eFlags &= ~EF_CONNECTION;
}
} */
// Begin Duffman
// Update the clips Amount in weapon for the client
@ -1540,10 +1588,25 @@ void ClientEndFrame(gentity_t * ent)
G_SetClientSound(ent);
// set the latest infor
if (g_smoothClients.integer) {
/* if (g_smoothClients.integer) {
BG_PlayerStateToEntityStateExtraPolate(&ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue);
} else {
BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, qtrue);
}
} */
BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, qtrue);
SendPendingPredictableEvents(&ent->client->ps);
// JBravo: unlagged
ent->client->ps.eFlags &= ~EF_CONNECTION;
frames = level.framenum - ent->client->lastUpdateFrame - 1;
if (frames > 2) {
frames = 2;
ent->client->ps.eFlags |= EF_CONNECTION;
ent->s.eFlags |= EF_CONNECTION;
}
if (frames > 0 && g_smoothClients.integer) {
G_PredictPlayerMove(ent, (float)frames / sv_fps.integer);
SnapVector(ent->s.pos.trBase);
}
G_StoreHistory(ent);
}

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.125 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.124 2003/02/27 03:58:35 jbravo
// Fixed the FF system after adding TDM broke it. Added color to error messages
//
@ -1020,6 +1023,28 @@ void ClientUserinfoChanged(int clientNum)
client->pers.predictItemPickup = qtrue;
}
// JBravo: unlagged
s = Info_ValueForKey(userinfo, "cg_delag");
if (!atoi(s)) {
client->pers.delag = 0;
} else {
client->pers.delag = atoi(s);
}
s = Info_ValueForKey(userinfo, "cg_cmdTimeNudge");
client->pers.cmdTimeNudge = atoi(s);
s = Info_ValueForKey(userinfo, "cg_debugDelag");
if (!atoi(s)) {
client->pers.debugDelag = qfalse;
} else {
client->pers.debugDelag = qtrue;
}
s = Info_ValueForKey(userinfo, "cg_latentSnaps");
client->pers.latentSnaps = atoi(s);
s = Info_ValueForKey(userinfo, "cg_latentCmds");
client->pers.latentCmds = atoi(s);
s = Info_ValueForKey(userinfo, "cg_plOut");
client->pers.plOut = atoi(s);
// set name
Q_strncpyz(oldname, client->pers.netname, sizeof(oldname));
s = Info_ValueForKey(userinfo, "name");
@ -1364,6 +1389,12 @@ char *ClientConnect(int clientNum, qboolean firstTime, qboolean isBot)
}
// JBravo: moved from ClientBegin
client->pers.enterTime = level.time;
// JBravo: unlagged
if (g_delagHitscan.integer) {
trap_SendServerCommand(clientNum, "print \"^1This server is Unlagged: full lag compensation is ON!\n\"");
} else {
trap_SendServerCommand(clientNum, "print \"^1This server is Unlagged: full lag compensation is OFF!\n\"");
}
return NULL;
}
@ -1646,6 +1677,10 @@ void ClientSpawn(gentity_t * ent)
flags = ent->client->ps.eFlags & (EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED);
flags ^= EF_TELEPORT_BIT;
// JBravo: unlagged
G_ResetHistory(ent);
ent->client->saved.leveltime = 0;
// clear everything but the persistant data
saved = client->pers;

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.178 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.177 2003/02/27 03:58:35 jbravo
// Fixed the FF system after adding TDM broke it. Added color to error messages
//
@ -477,7 +480,8 @@ void DeathmatchScoreboardMessage(gentity_t * ent)
if (cl->pers.connected == CON_CONNECTING) {
ping = -1;
} else {
ping = cl->ps.ping < 999 ? cl->ps.ping : 999;
//ping = cl->ps.ping < 999 ? cl->ps.ping : 999;
ping = cl->pers.realPing < 999 ? cl->pers.realPing : 999;
}
if (cl->accuracy_shots) {

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.133 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.132 2003/02/27 03:58:35 jbravo
// Fixed the FF system after adding TDM broke it. Added color to error messages
//
@ -1177,6 +1180,9 @@ void player_die(gentity_t * self, gentity_t * inflictor, gentity_t * attacker, i
if (level.intermissiontime) {
return;
}
// JBravo: unlagged
G_UnTimeShiftClient(self);
// JBravo: lets not bother with those CTF functions in Teamplay
if (g_gametype.integer == GT_CTF) {
// check for an almost capture

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.135 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.134 2003/01/06 00:23:29 makro
// no message
//
@ -595,6 +598,7 @@ typedef struct {
//
#define MAX_NETNAME 36
#define MAX_VOTE_COUNT 3
#define NUM_PING_SAMPLES 64
// client data that stays across multiple respawns, but is cleared
// on each level change or team change at ClientBegin()
@ -625,8 +629,28 @@ typedef struct {
int sayMuteTime;
qboolean sayModerated; // so warnings are not repeated for multi-line, same-frame messages
int records[REC_NUM_RECORDS]; // Elder: for our statistics tracking
// JBravo: unlagged
int delag;
int debugDelag;
int cmdTimeNudge;
int latentSnaps;
int latentCmds;
int plOut;
usercmd_t cmdqueue[MAX_LATENT_CMDS];
int cmdhead;
int realPing;
int pingsamples[NUM_PING_SAMPLES];
int samplehead;
} clientPersistant_t;
// JBravo: unlagged
#define NUM_CLIENT_HISTORY 17
typedef struct {
vec3_t mins, maxs;
vec3_t currentOrigin;
int leveltime;
} clientHistory_t;
struct camera_s;
// Elder: spam prevention defaults
@ -660,7 +684,7 @@ struct gclient_s {
clientSession_t sess;
qboolean readyToExit; // wishes to leave the intermission
qboolean noclip;
int lastCmdTime; // level.time of last usercmd_t, for EF_CONNECTION
// int lastCmdTime; // level.time of last usercmd_t, for EF_CONNECTION
// we can't just use pers.lastCommand.time, because
// of the g_sycronousclients case
int buttons;
@ -773,6 +797,13 @@ struct gclient_s {
// JBravo: time of death for delayed CTB respawns
int time_of_death;
int flagMessageTime;// NiceAss: Newb message for pistol/knife w/ enemy case
// JBravo: unlagged
int attackTime;
int historyHead;
clientHistory_t history[NUM_CLIENT_HISTORY];
clientHistory_t saved;
int frameOffset;
int lastUpdateFrame;
};
// JBravo: for model loading
@ -910,7 +941,7 @@ typedef struct {
qboolean teams_assigned[MAX_TEAMS];
gentity_t *potential_spawns[MAX_TEAMS][MAX_SPAWN_POINTS];
gentity_t *used_farteamplay_spawns[MAX_TEAMS][MAX_SPAWN_POINTS];
int frameStartTime;
} level_locals_t;
//
@ -1111,9 +1142,19 @@ qboolean G_FileExists(char *filename);
//
qboolean LogAccuracyHit(gentity_t * target, gentity_t * attacker);
void CalcMuzzlePoint(gentity_t * ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint);
void SnapVectorTowards(vec3_t v, vec3_t to);
//void SnapVectorTowards(vec3_t v, vec3_t to);
qboolean CheckGauntletAttack(gentity_t * ent);
// JBrabo: unlagged - g_unlagged.c
void G_ResetHistory(gentity_t *ent);
void G_StoreHistory(gentity_t *ent);
void G_TimeShiftAllClients(int time, gentity_t *skip);
void G_UnTimeShiftAllClients(gentity_t *skip);
void G_DoTimeShiftFor(gentity_t *ent);
void G_UndoTimeShiftFor(gentity_t *ent);
void G_UnTimeShiftClient(gentity_t *client);
void G_PredictPlayerMove(gentity_t *ent, float frametime);
//void Knife_Touch (gentity_t *ent, gentity_t *other,trace_t *trace);
//Blaze: No need for these because no gauntlet
//void Weapon_HookFree (gentity_t *ent);
@ -1356,6 +1397,13 @@ extern vmCvar_t g_enableFogLaser;
extern vmCvar_t g_singlePlayer;
extern vmCvar_t g_proxMineTimeout;
// JBravo: unlagged
extern vmCvar_t g_delagHitscan;
extern vmCvar_t g_unlaggedVersion;
extern vmCvar_t g_truePing;
extern vmCvar_t g_lightningDamage;
extern vmCvar_t sv_fps;
//Slicer: Matchmode
extern vmCvar_t g_RQ3_matchmode;
extern vmCvar_t g_RQ3_forceteamtalk;

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.135 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.134 2003/03/02 21:12:46 jbravo
// Version bumped to 3.0. Lets try and keep it list this.
//
@ -517,6 +520,13 @@ vmCvar_t g_enableFogLaser;
// JBravo: ditto
vmCvar_t g_enableDust;
// JBravo: unlagged
vmCvar_t g_delagHitscan;
vmCvar_t g_unlaggedVersion;
vmCvar_t g_truePing;
vmCvar_t g_lightningDamage;
vmCvar_t sv_fps;
//Blaze let cvar.cfg be set by server admins
vmCvar_t g_RQ3_cvarfile;
@ -587,6 +597,11 @@ static cvarTable_t gameCvarTable[] = {
{&g_smoothClients, "g_smoothClients", "1", 0, 0, qfalse},
{&pmove_fixed, "pmove_fixed", "0", CVAR_SYSTEMINFO, 0, qfalse},
{&pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO, 0, qfalse},
{&g_delagHitscan, "g_delagHitscan", "1", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qtrue},
{&g_unlaggedVersion, "g_unlaggedVersion", "2.0", CVAR_ROM | CVAR_SERVERINFO, 0, qfalse},
{&g_truePing, "g_truePing", "1", CVAR_ARCHIVE, 0, qtrue},
{&g_lightningDamage, "g_lightningDamage", "8", 0, 0, qtrue},
{&sv_fps, "sv_fps", "20", CVAR_SYSTEMINFO | CVAR_ARCHIVE, 0, qfalse},
{&g_rankings, "g_rankings", "0", 0, 0, qfalse},
//Slicer: Matchmode
{&g_RQ3_matchmode, "g_RQ3_matchmode", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_SYSTEMINFO, 0, qfalse},
@ -2530,10 +2545,10 @@ void G_RunFrame(int levelTime)
continue;
}
if (ent->s.eType == ET_MISSILE) {
/* if (ent->s.eType == ET_MISSILE) {
G_RunMissile(ent);
continue;
}
} */
if (ent->s.eType == ET_ITEM || ent->physicsObject) {
G_RunItem(ent);
@ -2552,6 +2567,22 @@ void G_RunFrame(int levelTime)
G_RunThink(ent);
}
// JBravo: unlagged
G_TimeShiftAllClients(level.previousTime, NULL);
ent = &g_entities[0];
for (i=0 ; i<level.num_entities ; i++, ent++) {
if (!ent->inuse) {
continue;
}
if (ent->freeAfterEvent) {
continue;
}
if (ent->s.eType == ET_MISSILE) {
G_RunMissile(ent);
}
}
G_UnTimeShiftAllClients(NULL);
end = trap_Milliseconds();
start = trap_Milliseconds();
@ -2613,6 +2644,7 @@ void G_RunFrame(int levelTime)
}
trap_Cvar_Set("g_listEntity", "0");
}
level.frameStartTime = trap_Milliseconds();
}
/*

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.66 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.65 2003/02/27 19:52:34 makro
// dlights
//
@ -343,6 +346,9 @@ void TeleportPlayer(gentity_t * player, vec3_t origin, vec3_t angles)
// toggle the teleport bit so the client knows to not lerp
player->client->ps.eFlags ^= EF_TELEPORT_BIT;
// JBravo: unlagged
G_ResetHistory(player);
// set angles
// SetClientViewAngle( player, angles );

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.32 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.31 2002/09/29 16:06:45 jbravo
// Work done at the HPWorld expo
//
@ -127,11 +130,9 @@ void G_ExplodeMissile(gentity_t * ent)
if (ent->s.weapon == WP_KNIFE &&
((g_gametype.integer == GT_TEAMPLAY && level.team_round_going) || g_gametype.integer != GT_TEAMPLAY))
g_entities[ent->r.ownerNum].client->pers.records[REC_KNIFETHROWHITS]++;
//g_entities[ent->r.ownerNum].client->knifeHits++;
if (ent->s.weapon == WP_GRENADE &&
((g_gametype.integer == GT_TEAMPLAY && level.team_round_going) || g_gametype.integer != GT_TEAMPLAY))
g_entities[ent->r.ownerNum].client->pers.records[REC_GRENADEHITS]++;
//g_entities[ent->r.ownerNum].client->grenHits++;
}
}
//Elder: huhh?
@ -162,16 +163,6 @@ void G_MissileImpact(gentity_t * ent, trace_t * trace)
G_AddEvent(ent, EV_GRENADE_BOUNCE, 0);
return;
}
//Elder: regular Q3 grenades
// check for bounce
/*
if ( !other->takedamage &&
( ent->s.eFlags & ( EF_BOUNCE | EF_BOUNCE_HALF ) ) ) {
G_BounceMissile( ent, trace );
G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 );
return;
}
*/
// impact damage
if (other->takedamage) {
@ -194,12 +185,6 @@ void G_MissileImpact(gentity_t * ent, trace_t * trace)
if (VectorLength(velocity) == 0) {
velocity[2] = 1; // stepped on a grenade
}
//Elder: added
//Blaze: Moved down into the section where it actually hits the glass, otherwise the breakable entity is gone when it checks for it
/*if ( ent->s.weapon == WP_KNIFE && other->s.eType == ET_BREAKABLE ) {
G_Damage (other, ent, &g_entities[ent->r.ownerNum], velocity,
ent->s.origin, ent->damage, 0, ent->methodOfDeath);
} */
}
}
@ -295,23 +280,6 @@ void G_MissileImpact(gentity_t * ent, trace_t * trace)
// And cut the velocity down.
VectorScale(ent->s.pos.trDelta, .2, ent->s.pos.trDelta);
return;
/* OLD METHOD
//breakable "hit"; make it fall to the ground
xr_drop = LaunchItem(xr_item, trace->endpos, velocity, FL_DROPPED_ITEM);
//but still set it as a thrown knife
//xr_drop->flags |= FL_THROWN_KNIFE;
//Elder: move the knife back a bit more
//and transfer into shared entityState
VectorScale(trace->plane.normal, 16, temp);
VectorAdd(trace->endpos, temp, knifeOffset);
//VectorCopy(xr_drop->s.origin, temp);
VectorAdd(xr_drop->s.origin, knifeOffset, xr_drop->s.origin);
VectorCopy(xr_drop->s.origin, xr_drop->r.currentOrigin);
*/
} else {
//leave embedded in the wall
xr_drop = LaunchItem(xr_item, trace->endpos, 0, FL_THROWN_KNIFE | FL_DROPPED_ITEM);
@ -383,43 +351,6 @@ void G_MissileImpact(gentity_t * ent, trace_t * trace)
trap_LinkEntity(ent);
}
/*
================
G_ExplodeMissile
Explode a missile without an impact
================
*/
/*
void G_ExplodeMissile( gentity_t *ent ) {
vec3_t dir;
vec3_t origin;
G_EvaluateTrajectory( &ent->s.pos, level.time, origin );
SnapVector( origin );
G_SetOrigin( ent, origin );
// we don't have a valid direction, so just point straight up
dir[0] = dir[1] = 0;
dir[2] = 1;
ent->s.eType = ET_GENERAL;
G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) );
ent->freeAfterEvent = qtrue;
// splash damage
if ( ent->splashDamage ) {
if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, NULL
, ent->splashMethodOfDeath ) ) {
g_entities[ent->r.ownerNum].client->ps.persistant[PERS_ACCURACY_HITS]++;
}
}
trap_LinkEntity( ent );
}
*/
/*
================
G_RunMissile
@ -470,17 +401,6 @@ void G_RunMissile(gentity_t * ent)
return; // exploded
}
}
//Elder: make knife follow the trajectory - not real but oh well...
/* Done in CG_Missile locally to save bandwidth
if (ent->classname == "weapon_knife")
{
vec3_t knifeVelocity;
G_EvaluateTrajectoryDelta(&ent->s.pos, level.time, knifeVelocity);
vectoangles(knifeVelocity, ent->s.angles);
ent->s.angles[0] += level.time % 360;
}
*/
// check think function after bouncing
G_RunThink(ent);
@ -488,49 +408,6 @@ void G_RunMissile(gentity_t * ent)
//=============================================================================
/*
=================
fire_plasma
=================
*/
//Blaze: No plasma gun so no need for this function
/*
gentity_t *fire_plasma (gentity_t *self, vec3_t start, vec3_t dir) {
gentity_t *bolt;
VectorNormalize (dir);
bolt = G_Spawn();
bolt->classname = "plasma";
bolt->nextthink = level.time + 10000;
bolt->think = G_ExplodeMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
bolt->s.weapon = WP_PLASMAGUN;
bolt->r.ownerNum = self->s.number;
bolt->parent = self;
bolt->damage = 20;
bolt->splashDamage = 15;
bolt->splashRadius = 20;
bolt->methodOfDeath = MOD_PLASMA;
bolt->splashMethodOfDeath = MOD_PLASMA_SPLASH;
bolt->clipmask = MASK_SHOT;
bolt->target_ent = NULL;
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, 2000, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin);
return bolt;
}
*/
//=============================================================================
/*
=================
fire_grenade
@ -561,6 +438,7 @@ gentity_t *fire_grenade(gentity_t * self, vec3_t start, vec3_t dir)
bolt->s.weapon = WP_GRENADE;
bolt->s.eFlags = EF_BOUNCE_HALF;
bolt->r.ownerNum = self->s.number;
bolt->s.otherEntityNum = self->s.number;
bolt->parent = self;
bolt->damage = GRENADE_DAMAGE; //probably only used on a direct hit
bolt->splashDamage = GRENADE_SPLASH_DAMAGE; //Blaze: Reaction Grenade Damage
@ -627,6 +505,7 @@ gentity_t *fire_knife(gentity_t * self, vec3_t start, vec3_t dir)
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
bolt->s.weapon = WP_KNIFE;
bolt->r.ownerNum = self->s.number;
bolt->s.otherEntityNum = self->s.number;
bolt->parent = self;
bolt->damage = THROW_DAMAGE;
bolt->splashDamage = 0;
@ -649,133 +528,6 @@ gentity_t *fire_knife(gentity_t * self, vec3_t start, vec3_t dir)
// Elder: Statistics tracking
self->client->pers.records[REC_KNIFETHROWSHOTS]++;
}
// bolt->s.pos.trDelta[2] *= .85;
//Elder: not needed anymore
//Saving stuff for Makro's knife equations
//VectorCopy( start, bolt->s.origin2);
//VectorCopy( dir, bolt->s.angles2);
return bolt;
}
//=============================================================================
/*
=================
fire_bfg
=================
*/
//Blaze: no bfg
/*
gentity_t *fire_bfg (gentity_t *self, vec3_t start, vec3_t dir) {
gentity_t *bolt;
VectorNormalize (dir);
bolt = G_Spawn();
bolt->classname = "bfg";
bolt->nextthink = level.time + 10000;
bolt->think = G_ExplodeMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
bolt->s.weapon = WP_BFG;
bolt->r.ownerNum = self->s.number;
bolt->parent = self;
bolt->damage = 100;
bolt->splashDamage = 100;
bolt->splashRadius = 120;
bolt->methodOfDeath = MOD_BFG;
bolt->splashMethodOfDeath = MOD_BFG_SPLASH;
bolt->clipmask = MASK_SHOT;
bolt->target_ent = NULL;
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, 2000, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin);
return bolt;
}
*/
//=============================================================================
/*
=================
fire_rocket
=================
*/
//Blaze: No need for this since there are no rockets
/*
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir) {
gentity_t *bolt;
VectorNormalize (dir);
bolt = G_Spawn();
bolt->classname = "rocket";
bolt->nextthink = level.time + 15000;
bolt->think = G_ExplodeMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
bolt->s.weapon = WP_ROCKET_LAUNCHER;
bolt->r.ownerNum = self->s.number;
bolt->parent = self;
bolt->damage = 100;
bolt->splashDamage = 100;
bolt->splashRadius = 120;
bolt->methodOfDeath = MOD_ROCKET;
bolt->splashMethodOfDeath = MOD_ROCKET_SPLASH;
bolt->clipmask = MASK_SHOT;
bolt->target_ent = NULL;
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, 900, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin);
return bolt;
}
*/
/*
=================
fire_grapple
=================
*/
//Blaze: no need for this since no grapple
/*
gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir) {
gentity_t *hook;
VectorNormalize (dir);
hook = G_Spawn();
hook->classname = "hook";
hook->nextthink = level.time + 10000;
hook->think = Weapon_HookFree;
hook->s.eType = ET_MISSILE;
hook->r.svFlags = SVF_USE_CURRENT_ORIGIN;
hook->s.weapon = WP_GRAPPLING_HOOK;
hook->r.ownerNum = self->s.number;
hook->methodOfDeath = MOD_GRAPPLE;
hook->clipmask = MASK_SHOT;
hook->parent = self;
hook->target_ent = NULL;
hook->s.pos.trType = TR_LINEAR;
hook->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
hook->s.otherEntityNum = self->s.number; // use to match beam in client
VectorCopy( start, hook->s.pos.trBase );
VectorScale( dir, 800, hook->s.pos.trDelta );
SnapVector( hook->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, hook->r.currentOrigin);
self->client->hook = hook;
return hook;
}
*/

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.86 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.85 2002/12/20 14:29:47 jbravo
// Activated the second barrel on the HC
//
@ -456,6 +459,8 @@ rather than blindly truncating. This prevents it from truncating
into a wall.
======================
*/
// JBravo: unlagged. moved to q_shared.c
/*
void SnapVectorTowards(vec3_t v, vec3_t to)
{
int i;
@ -467,7 +472,7 @@ void SnapVectorTowards(vec3_t v, vec3_t to)
v[i] = (int) v[i] + 1;
}
}
}
} */
#define MACHINEGUN_SPREAD 200
#define MACHINEGUN_DAMAGE 7
@ -483,6 +488,7 @@ void Bullet_Fire(gentity_t * ent, float spread, int damage, int MOD)
gentity_t *tent2;
gentity_t *traceEnt;
int i, passent;
// int seed = ent->client->attackTime % 256;
//Makro
int Material;
@ -506,33 +512,6 @@ void Bullet_Fire(gentity_t * ent, float spread, int damage, int MOD)
break;
}
}
/* Original AQ2 code
vectoangles (aimdir, dir);
AngleVectors (dir, forward, right, up);
r = crandom()*hspread;
u = crandom()*vspread;
VectorMA (start, 8192, forward, end);
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
*/
/* More AQ2 code to implement
// change bullet's course when it enters water
VectorSubtract (end, start, dir);
vectoangles (dir, dir);
AngleVectors (dir, forward, right, up);
r = crandom()*hspread*2;
u = crandom()*vspread*2;
VectorMA (water_start, 8192, forward, end);
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
*/
//Elder: original Q3 code -- note the first line and its use to reduce spread
//r = random() * M_PI * 2.0f;
//u = sin(r) * crandom() * spread * 16;
//r = cos(r) * crandom() * spread * 16;
u = crandom() * spread;
r = crandom() * spread;
@ -542,8 +521,11 @@ void Bullet_Fire(gentity_t * ent, float spread, int damage, int MOD)
passent = ent->s.number;
for (i = 0; i < 10; i++) {
// JBravo: unlagged
G_DoTimeShiftFor(ent);
trap_Trace(&tr, muzzle, NULL, NULL, end, passent, MASK_SHOT);
G_UndoTimeShiftFor(ent);
//Makro - saving the material flag to avoid useless calls to the GetMaterialFromFlag function
Material = GetMaterialFromFlag(tr.surfaceFlags);
@ -556,24 +538,7 @@ void Bullet_Fire(gentity_t * ent, float spread, int damage, int MOD)
// snap the endpos to integers, but nudged towards the line
SnapVectorTowards(tr.endpos, muzzle);
// NiceAss: Special hit-detection stuff for the head
/*
if (traceEnt->takedamage && traceEnt->client && G_HitPlayer(traceEnt, forward, tr.endpos) == qfalse) {
VectorCopy(tr.endpos, muzzle);
passent = tr.entityNum;
continue;
}
*/
if (traceEnt->takedamage && traceEnt->client) {
/*if (bg_itemlist[traceEnt->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag != HI_KEVLAR &&
!OnSameTeam(traceEnt, ent) || (g_friendlyFire.integer > 0 && OnSameTeam(traceEnt, ent)) ) {
tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_FLESH);
//tent->s.eventParm = traceEnt->s.number;
tent->s.eventParm = DirToByte(forward);
tent->s.otherEntityNum2 = traceEnt->s.number;
tent->s.otherEntityNum = ent->s.number;
}*/
if (LogAccuracyHit(traceEnt, ent)) {
ent->client->accuracy_hits++;
// Elder: Statistics tracking
@ -581,64 +546,53 @@ void Bullet_Fire(gentity_t * ent, float spread, int damage, int MOD)
switch (MOD) {
case MOD_PISTOL:
ent->client->pers.records[REC_MK23HITS]++;
//ent->client->mk23Hits++;
break;
case MOD_M4:
ent->client->pers.records[REC_M4HITS]++;
//ent->client->m4Hits++;
break;
case MOD_MP5:
ent->client->pers.records[REC_MP5HITS]++;
//ent->client->mp5Hits++;
break;
case MOD_AKIMBO:
ent->client->pers.records[REC_AKIMBOHITS]++;
//ent->client->akimboHits++;
break;
}
}
}
//Elder: *******************TEST CODE *****************
//} else if ( tr.surfaceFlags & SURF_GRASS ) {
//tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_FLESH);
//tent->s.eventParm = DirToByte( tr.plane.normal );
//Makro - new surfaceparm system
//} else if ((tr.surfaceFlags & SURF_METALSTEPS) || (tr.surfaceFlags & SURF_METAL2) || (tr.surfaceFlags & SURF_HARDMETAL)) {
} else if (IsMetalMat(Material)) {
tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_METAL);
tent->s.eventParm = ReflectVectorByte(forward, tr.plane.normal);
tent->s.otherEntityNum = ent->s.number;
//} else if ( tr.surfaceFlags & SURF_GLASS) {
tent->s.clientNum = ent->s.clientNum;
} else if (Material == MAT_GLASS) {
tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_GLASS);
tent->s.eventParm = DirToByte(tr.plane.normal);
tent->s.otherEntityNum = ent->s.number;
//Makro - moved the pressure code out of these if's
//} else if ( traceEnt->s.eType == ET_PRESSURE ) {
// // Pressure entities
// G_CreatePressure(tr.endpos, tr.plane.normal, traceEnt);
tent->s.clientNum = ent->s.clientNum;
//Makro - new sounds
} else if (IsWoodMat(Material)) {
tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_WOOD);
tent->s.eventParm = DirToByte(tr.plane.normal);
tent->s.otherEntityNum = ent->s.number;
tent->s.clientNum = ent->s.clientNum;
//Makro - new sounds
} else if (Material == MAT_BRICK) {
tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_BRICK);
tent->s.eventParm = DirToByte(tr.plane.normal);
tent->s.otherEntityNum = ent->s.number;
tent->s.clientNum = ent->s.clientNum;
//Makro - new sounds
} else if (Material == MAT_CERAMIC) {
tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_CERAMIC);
tent->s.eventParm = DirToByte(tr.plane.normal);
tent->s.otherEntityNum = ent->s.number;
tent->s.clientNum = ent->s.clientNum;
} else {
tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_WALL);
tent->s.eventParm = DirToByte(tr.plane.normal);
tent->s.otherEntityNum = ent->s.number;
tent->s.clientNum = ent->s.clientNum;
}
//tent->s.otherEntityNum = ent->s.number;
//G_Printf("Surfaceflags: %d\n", tr.surfaceFlags);
//Makro - moved the pressure code out of these if's
if (traceEnt->s.eType == ET_PRESSURE) {
@ -667,10 +621,10 @@ void Bullet_Fire(gentity_t * ent, float spread, int damage, int MOD)
}
// NiceAss: Added so the M4 will shoot through bodies
// Makro - changed from || to &&. Q3 crashed before
if ( traceEnt->client && ent->client) {
if ( (MOD == MOD_M4 && traceEnt->client->kevlarHit == qfalse) ||
if (traceEnt->client && ent->client) {
if ((MOD == MOD_M4 && traceEnt->client->kevlarHit == qfalse) ||
// NiceAss: And you can shoot through teammates
OnSameTeam(traceEnt, ent) ) {
OnSameTeam(traceEnt, ent)) {
VectorCopy(tr.endpos, muzzle);
passent = tr.entityNum;
continue;
@ -784,6 +738,7 @@ void ShotgunPattern(vec3_t origin, vec3_t origin2, int seed, gentity_t * ent, in
hc_multipler = 5;
}
G_DoTimeShiftFor(ent);
// generate the "random" spread pattern
for (i = 0; i < count; i++) {
if (shotType == WP_M3) {
@ -815,6 +770,7 @@ void ShotgunPattern(vec3_t origin, vec3_t origin2, int seed, gentity_t * ent, in
}
}
}
G_UndoTimeShiftFor(ent);
}
void weapon_supershotgun_fire(gentity_t * ent)
@ -864,6 +820,7 @@ void weapon_railgun_fire(gentity_t * ent)
VectorMA(muzzle, 8192, forward, end);
// trace only against the solids, so the railgun will go through people
G_DoTimeShiftFor(ent);
unlinked = 0;
hits = 0;
passent = ent->s.number;
@ -887,6 +844,7 @@ void weapon_railgun_fire(gentity_t * ent)
unlinkedEntities[unlinked] = traceEnt;
unlinked++;
} while (unlinked < MAX_RAIL_HITS);
G_UndoTimeShiftFor(ent);
// link back in any entities we unlinked
for (i = 0; i < unlinked; i++) {
@ -1212,7 +1170,6 @@ void Weapon_M4_Fire(gentity_t * ent)
// Homer: increment burst if needed
if ((ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE) {
//ent->client->ps.stats[STAT_BURST]++;
spread = M4_SPREAD * 0.7;
} else {
spread = M4_SPREAD;
@ -1232,19 +1189,8 @@ void Weapon_M4_Fire(gentity_t * ent)
// JBravo: ff
if (g_gametype.integer >= GT_TEAM)
setFFState(ent);
Bullet_Fire(ent, RQ3_Spread(ent, M4_SPREAD), M4_DAMAGE, MOD_M4);
/*
if ( (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE) {
//Elder: burst three shots
if (ent->client->weaponfireNextTime > 0 && ent->client->ps.stats[STAT_BURST] > 2) {
ent->client->weaponfireNextTime = 0;
}
else {
ent->client->weaponfireNextTime = level.time + RQ3_M4_DELAY;
}
} */
}
/*
@ -1309,23 +1255,11 @@ void Weapon_SSG3000_Fire(gentity_t * ent)
{
vec3_t end;
trace_t trace;
gentity_t *tent;//[MAX_SSG3000_HITS];
gentity_t *tentWall;
gentity_t *traceEnt = NULL;
int damage;
int i;
int hits;
int unlinked;
int passent;
gentity_t *tent, *tentWall, *traceEnt = NULL;
gentity_t *unlinkedEntities[MAX_SSG3000_HITS];
int damage, i, hits, unlinked, passent, Material;
qboolean hitBreakable;
float r;
float u;
float spread;
//Makro
int Material;
float r, u, spread;
// Elder: Statistics tracking
if (ent->client && ((g_gametype.integer == GT_TEAMPLAY && level.team_round_going) || g_gametype.integer != GT_TEAMPLAY))
@ -1344,6 +1278,8 @@ void Weapon_SSG3000_Fire(gentity_t * ent)
damage = SNIPER_DAMAGE;
// JBravo: unlagged NEW
G_DoTimeShiftFor(ent);
// trace only against the solids, so the SSG3000 will go through people
unlinked = 0;
hits = 0;
@ -1383,17 +1319,6 @@ void Weapon_SSG3000_Fire(gentity_t * ent)
return;
}
// NiceAss: Special hit-detection stuff for the head
/*
if (traceEnt->takedamage && traceEnt->client && G_HitPlayer(traceEnt, forward, trace.endpos) == qfalse) {
// It actually didn't hit anything...
trap_UnlinkEntity(traceEnt);
unlinkedEntities[unlinked] = traceEnt;
unlinked++;
continue;
}
*/
if (traceEnt->takedamage) {
//flag hitBreakable - bullets go through even
//if it doesn't "shatter" - but that's usually
@ -1450,6 +1375,7 @@ void Weapon_SSG3000_Fire(gentity_t * ent)
unlinked++;
}
} while (unlinked < MAX_SSG3000_HITS);
G_UndoTimeShiftFor(ent);
// link back in any entities we unlinked
for (i = 0; i < unlinked; i++) {
@ -1534,6 +1460,7 @@ void Weapon_MP5_Fire(gentity_t * ent)
// JBravo: ff
if (g_gametype.integer >= GT_TEAM)
setFFState(ent);
Bullet_Fire(ent, RQ3_Spread(ent, MP5_SPREAD), MP5_DAMAGE, MOD_MP5);
}
@ -1718,9 +1645,6 @@ void Weapon_Grenade_Fire(gentity_t * ent)
setFFState(ent);
m = fire_grenade(ent, muzzle, forward);
// VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics
}
/*
@ -1956,7 +1880,6 @@ void Laser_Think(gentity_t * self)
//Trace Position
trap_Trace(&tr, start, NULL, NULL, end, passent, MASK_SHOT);
//trap_Trace (&tr2, start, NULL, NULL, end, passent, MASK_SHOT|CONTENTS_FOG);
traceEnt = &g_entities[tr.entityNum];
//Did you not hit anything?
@ -1965,28 +1888,10 @@ void Laser_Think(gentity_t * self)
trap_UnlinkEntity(self);
return;
}
// It "hit" a player, but actually missed (thanks to new headshot code!)
/*
if ((traceEnt->takedamage && traceEnt->client && G_HitPlayer(traceEnt, forward, tr.endpos) == qfalse)) {
passent = tr.entityNum;
continue;
}
*/
//Makro - new surfaceparm system
//if (!(tr.surfaceFlags & SURF_GLASS)) break;
if (!(GetMaterialFromFlag(tr.surfaceFlags) == MAT_GLASS))
break;
/*
//Makro - don't go through brushes that aren't detail/trans
//contents = trap_PointContents(tr.endpos, -1);
contents = tr.contents;
if (contents & CONTENTS_SOLID) {
if ( !(contents & (CONTENTS_TRANSLUCENT | CONTENTS_DETAIL)) ) {
break;
}
}
*/
VectorMA(tr.endpos, 10, forward, start); // Nudge it forward a little bit
}
@ -2018,12 +1923,10 @@ void ReloadWeapon(gentity_t * ent, int stage)
{
if (stage == 1 && (ent->client->ps.weapon == WP_SSG3000 || ent->client->ps.weapon == WP_M3)) {
//G_Printf("Hit server-side reload stage 1\n");
if (ent->client->ps.weapon == WP_M3)
ent->client->numClips[WP_HANDCANNON] = ent->client->numClips[WP_M3];
ent->client->numClips[ent->client->ps.weapon]--;
} else if (stage == 2) {
//G_Printf("Hit server-side reload stage 2\n");
ent->client->numClips[ent->client->ps.weapon]--;
// remove an extra clip if using HC or Akimbos
if (ent->client->ps.weapon == WP_HANDCANNON || ent->client->ps.weapon == WP_AKIMBO)

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.8 2003/03/09 21:30:39 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.7 2002/08/21 03:42:20 niceass
// move of some vector functions outside of just game
//
@ -1270,3 +1273,16 @@ void Info_SetValueForKey_Big(char *s, const char *key, const char *value)
}
//====================================================================
// JBravo: moved from g_weapon.c
void SnapVectorTowards( vec3_t v, vec3_t to )
{
int i;
for (i = 0 ; i < 3 ; i++) {
if ( to[i] <= v[i] ) {
v[i] = (int)v[i];
} else {
v[i] = (int)v[i] + 1;
}
}
}

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.12 2003/03/09 21:30:39 jbravo
// Adding unlagged. Still needs work.
//
// Revision 1.11 2002/08/27 04:46:33 niceass
// ref say added
//
@ -34,6 +37,7 @@
// A user mod should never modify this file
#define Q3_VERSION "Q3 1.29h"
#define MAX_LATENT_CMDS 64
#define MAX_TEAMNAME 32
@ -695,6 +699,8 @@ typedef struct {
#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
#define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));}
void SnapVectorTowards(vec3_t v, vec3_t to);
// just in case you do't want to use the macros
vec_t _DotProduct(const vec3_t v1, const vec3_t v2);
void _VectorSubtract(const vec3_t veca, const vec3_t vecb, vec3_t out);