From c531db636d778dbf537feee8d77910d019c4e160 Mon Sep 17 00:00:00 2001 From: Knightmare66 Date: Wed, 4 Aug 2021 02:15:24 -0400 Subject: [PATCH] Changed protocol version to 57. Fixed an old protocol bug in how extended HUD stats were sent to the client. Changed protocol for svc_sound servercommand to separate channel and entity values from a merged short to a byte and a short. More improvements to Tactician Gunner prox aiming safety in missionpack DLL. Fixed SV_CheckVelocity() sv_velocity cap in missionpack, 3ZB2, and Zaero game DLLs. --- 3zb2/g_phys.c | 7 ++++- awaken2/g_phys.c | 4 +-- client/cl_ents.c | 15 ++++++--- client/cl_parse.c | 35 ++++++++++++--------- client/cl_utils.c | 4 +-- kmquake2_changelog.txt | 3 ++ missionpack/g_local.h | 2 +- missionpack/g_phys.c | 14 +++++++-- missionpack/m_gunner.c | 70 +++++++++++++++++++++++++++++++++--------- missionpack/m_turret.c | 2 +- qcommon/qcommon.h | 2 +- server/sv_ents.c | 22 ++++++++++--- server/sv_send.c | 15 ++++++--- zaero/g_phys.c | 7 ++++- 14 files changed, 148 insertions(+), 54 deletions(-) diff --git a/3zb2/g_phys.c b/3zb2/g_phys.c index 2075302..663c439 100644 --- a/3zb2/g_phys.c +++ b/3zb2/g_phys.c @@ -52,12 +52,17 @@ void SV_CheckVelocity (edict_t *ent) // // bound velocity // - for (i=0 ; i<3 ; i++) +/* for (i=0 ; i<3 ; i++) { if (ent->velocity[i] > sv_maxvelocity->value) ent->velocity[i] = sv_maxvelocity->value; else if (ent->velocity[i] < -sv_maxvelocity->value) ent->velocity[i] = -sv_maxvelocity->value; + } */ + if (VectorLength(ent->velocity) > sv_maxvelocity->value) + { + VectorNormalize (ent->velocity); + VectorScale (ent->velocity, sv_maxvelocity->value, ent->velocity); } } diff --git a/awaken2/g_phys.c b/awaken2/g_phys.c index e3401ea..1448310 100644 --- a/awaken2/g_phys.c +++ b/awaken2/g_phys.c @@ -55,8 +55,8 @@ void SV_CheckVelocity(edict_t *ent) if (VectorLength(ent->velocity) > sv_maxvelocity->value) { - VectorNormalize(ent->velocity); - VectorScale(ent->velocity, sv_maxvelocity->value, ent->velocity); + VectorNormalize (ent->velocity); + VectorScale (ent->velocity, sv_maxvelocity->value, ent->velocity); } //DH-- } diff --git a/client/cl_ents.c b/client/cl_ents.c index f057509..3b19937 100644 --- a/client/cl_ents.c +++ b/client/cl_ents.c @@ -630,8 +630,9 @@ void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe) { int flags; player_state_t *state; - int i; - int statbits; + int i, j; + int statbits; // still used by legacy protocol + int statbitarray[(MAX_STATS+31)>>5]; // derived from MAX_STATS state = &newframe->playerstate; @@ -747,7 +748,7 @@ void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe) if (statbits & (1<stats[i] = MSG_ReadShort(&net_message); } // end old CL_ParsePlayerstate code - else //new CL_ParsePlayerstate code + else // new CL_ParsePlayerstate code { // Knightmare 4/5/2002- read as long flags = MSG_ReadLong (&net_message); @@ -897,10 +898,16 @@ void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe) state->rdflags = MSG_ReadByte (&net_message); // parse stats - statbits = MSG_ReadLong (&net_message); + /* statbits = MSG_ReadLong (&net_message); for (i = 0; i < MAX_STATS; i++) if (statbits & (1<stats[i] = MSG_ReadShort(&net_message); + */ + for (j = 0; j < (MAX_STATS+31)>>5; j++) + statbitarray[j] = MSG_ReadLong (&net_message); + for (i = 0; i < MAX_STATS; i++) + if ( statbitarray[i>>5] & (1<<(i&31)) ) + state->stats[i] = MSG_ReadShort(&net_message); } // end new CL_ParsePlayerstate code } diff --git a/client/cl_parse.c b/client/cl_parse.c index 3280843..5157eba 100644 --- a/client/cl_parse.c +++ b/client/cl_parse.c @@ -126,15 +126,10 @@ void CL_ParseServerData (void) // BIG HACK to let demos from release work with the 3.0x patch!!! // Knightmare- also allow connectivity with servers using the old protocol -// if (Com_ServerState() && (i < PROTOCOL_VERSION) /*== 35*/) - if ( LegacyProtocol() ) {} // do nothing -/* else if (i == OLD_PROTOCOL_VERSION) - Cvar_ForceSet ("cl_servertrick", "1"); - else if (i == PROTOCOL_VERSION) - Cvar_ForceSet ("cl_servertrick", "0"); // force this off for local games - else if (i != PROTOCOL_VERSION) */ - else if ( (i != PROTOCOL_VERSION) && (i != OLD_PROTOCOL_VERSION) ) + if ( LegacyProtocol() ) { } // do nothing + else if ( (i != PROTOCOL_VERSION) && (i != OLD_PROTOCOL_VERSION) ) { Com_Error (ERR_DROP, "Server returned version %i, not %i or %i", i, PROTOCOL_VERSION, OLD_PROTOCOL_VERSION); + } cl.servercount = MSG_ReadLong (&net_message); cl.attractloop = MSG_ReadByte (&net_message); @@ -582,7 +577,7 @@ void CL_ParseStartSoundPacket(void) sound_num = MSG_ReadByte (&net_message); else sound_num = MSG_ReadShort (&net_message); - //end Knightmare + // end Knightmare if (flags & SND_VOLUME) volume = MSG_ReadByte (&net_message) / 255.0; @@ -599,14 +594,24 @@ void CL_ParseStartSoundPacket(void) else ofs = 0; - if (flags & SND_ENT) - { // entity reletive - channel = MSG_ReadShort(&net_message); - ent = channel>>3; + if (flags & SND_ENT) // entity relative + { + // Knightmare 8/2/21- read channel and ent as a combined short only if playing old demos or + // connected to server using old protocol; otherwise, read as a byte and a short + if ( LegacyProtocol() ) + { + channel = MSG_ReadShort(&net_message); + ent = channel >> 3; + channel &= 7; + } + else + { + channel = MSG_ReadByte(&net_message); + ent = (unsigned short)MSG_ReadShort(&net_message); // make sure this doesn't turn negative! + } if (ent > MAX_EDICTS) Com_Error (ERR_DROP,"CL_ParseStartSoundPacket: ent = %i", ent); - - channel &= 7; + // end Knightmare } else { diff --git a/client/cl_utils.c b/client/cl_utils.c index ad0307c..b2e97d0 100644 --- a/client/cl_utils.c +++ b/client/cl_utils.c @@ -450,8 +450,8 @@ if parsing of old protocol should be used. */ qboolean LegacyProtocol (void) { - //if (dedicated->integer) // Server always uses new protocol - // return false; +// if (dedicated->integer) // Server always uses new protocol +// return false; if ( (Com_ServerState() && cls.serverProtocol <= OLD_PROTOCOL_VERSION) || (cls.serverProtocol == OLD_PROTOCOL_VERSION) ) return true; diff --git a/kmquake2_changelog.txt b/kmquake2_changelog.txt index a576a0f..6812716 100644 --- a/kmquake2_changelog.txt +++ b/kmquake2_changelog.txt @@ -38,6 +38,9 @@ Changes as of v0.20 update 8: - Added client detection of server protocol from challenge message. Client also auto-reconnects with cl_servertrick set correspondingly when a "wrong version" rejection message is received. +- Changed protocol version to 57. This was necessitated by fixing an old protocol bug in how extended HUD stats were sent to the client. + Also changed protocol for svc_sound servercommand to separate channel and entity values from a merged short to a byte and a short. + - Added cel shading support. Uses cvars r_celshading to enable, and r_celshading_width for line width (1-10). - Added Z-Pass shadow mode due to patent issues w/ commercial games. Set the cvar r_shadow_zfail to 0 to enable this. diff --git a/missionpack/g_local.h b/missionpack/g_local.h index 9c34c5c..484a342 100644 --- a/missionpack/g_local.h +++ b/missionpack/g_local.h @@ -2629,7 +2629,7 @@ struct edict_s char *datafile; // Mappack- for the camera to backup the players position, ammo, powerups, etc - backup_t backup; //this holds the client data + backup_t backup; // this holds the client data vec3_t fog_color; int fog_model; diff --git a/missionpack/g_phys.c b/missionpack/g_phys.c index 5d2968e..0c96f0b 100644 --- a/missionpack/g_phys.c +++ b/missionpack/g_phys.c @@ -165,12 +165,12 @@ SV_CheckVelocity */ void SV_CheckVelocity (edict_t *ent) { - int i; +// int i; // // bound velocity // - for (i=0 ; i<3 ; i++) +/* for (i=0 ; i<3 ; i++) { if (ent->velocity[i] > sv_maxvelocity->value) ent->velocity[i] = sv_maxvelocity->value; @@ -181,6 +181,16 @@ void SV_CheckVelocity (edict_t *ent) ent->relative_velocity[i] = sv_maxvelocity->value; else if (ent->relative_velocity[i] < -sv_maxvelocity->value) ent->relative_velocity[i] = -sv_maxvelocity->value; + } */ + if (VectorLength(ent->velocity) > sv_maxvelocity->value) + { + VectorNormalize (ent->velocity); + VectorScale (ent->velocity, sv_maxvelocity->value, ent->velocity); + } + if (VectorLength(ent->relative_velocity) > sv_maxvelocity->value) + { + VectorNormalize (ent->relative_velocity); + VectorScale (ent->relative_velocity, sv_maxvelocity->value, ent->relative_velocity); } } diff --git a/missionpack/m_gunner.c b/missionpack/m_gunner.c index dc6fdfc..276dc4a 100644 --- a/missionpack/m_gunner.c +++ b/missionpack/m_gunner.c @@ -41,7 +41,7 @@ static int tactician_sound_sight; #define GRENADE_VELOCITY 632.4555320337f #define GRENADE_VELOCITY_SQUARED 400000.0f // Knightmare- placement spread for Tactician Gunner prox mines -#define GUNNER_PROX_SPREAD 40.0f +#define GUNNER_PROX_SPREAD 48.0f #define HALF_GUNNER_PROX_SPREAD (GUNNER_PROX_SPREAD * 0.5f) void gunner_idlesound (edict_t *self) @@ -535,6 +535,7 @@ qboolean gunner_grenade_check (edict_t *self) if (tr.ent == self->enemy || tr.fraction == 1) { // Knightmare- added close-range prox safety check if (isProx) { + VectorCopy (target, self->aim_point); // save this aim location in case later safety check fails if (gunner_prox_safety_check(self, start, target)) return true; } @@ -548,6 +549,7 @@ qboolean gunner_grenade_check (edict_t *self) if (tr.ent == self->enemy || tr.fraction == 1) { // Knightmare- added close-range prox safety check if (isProx) { + VectorCopy (target, self->aim_point); // save this aim location in case later safety check fails if (gunner_prox_safety_check(self, start, target)) return true; } @@ -685,8 +687,12 @@ void GunnerGrenade (edict_t *self) float spread; // float pitch; // PMM - vec3_t target; + vec3_t target, leadTarget; qboolean blindfire = false; + qboolean leadingTarget = false; + qboolean targetSafe = false; + qboolean leadSafe = false; + qboolean isProx = (self->moreflags & FL2_COMMANDER); //PGM if (!self->enemy || !self->enemy->inuse) @@ -750,8 +756,52 @@ void GunnerGrenade (edict_t *self) if (self->enemy->absmin[2] <= self->absmax[2]) target[2] = self->enemy->absmin[2]; + // lead target... 20, 35, 50, 65 chance of leading + if ( random() < (0.2 + skill->value * 0.15) ) + { + float dist, time; + + VectorSubtract (target, start, aim); + dist = VectorLength (aim); + time = dist / GRENADE_VELOCITY; // Not correct, but better than nothin' + VectorMA (target, time, self->enemy->velocity, leadTarget); + if (!isProx) // delay copying for prox safety check + VectorCopy (leadTarget, target); + leadingTarget = true; + } + + if (isProx) // Knightmare- run another safety check before firing, so players can't trick us into self-damage + { + if ( gunner_prox_safety_check(self, start, target) ) { + VectorCopy (target, self->aim_point); // save this target point + targetSafe = true; + } + if ( leadingTarget && gunner_prox_safety_check(self, start, leadTarget) ) { + VectorCopy (leadTarget, target); // copy lead point over target + leadSafe = true; + } + if ( !targetSafe && !leadSafe ) { + VectorCopy (self->aim_point, target); // revert to prev target point + } + /* if ((g_showlogic) && (g_showlogic->value)) + { + if ( targetSafe && leadSafe ) + gi.dprintf ("GunnerGrenade: safe to fire at and lead target, saving target point.\n"); + else if ( targetSafe && leadingTarget && !leadSafe ) + gi.dprintf ("GunnerGrenade: safe to fire at but not lead target, saving target point.\n"); + else if ( targetSafe && !leadingTarget ) + gi.dprintf ("GunnerGrenade: safe to fire at target, saving target point.\n"); + else if ( !targetSafe && leadSafe ) + gi.dprintf ("GunnerGrenade: safe to lead target only, not saving target point.\n"); + else if ( !targetSafe && !leadSafe && leadingTarget ) + gi.dprintf ("GunnerGrenade: NOT safe to fire at or lead target, reverting to prev target point.\n"); + else if ( !targetSafe && !leadSafe && !leadingTarget ) + gi.dprintf ("GunnerGrenade: NOT safe to fire at target, reverting to prev target point.\n"); + } */ + } + // Knightmare- spread out Tactician Gunner's prox mines so they don't collide - if (self->moreflags & FL2_COMMANDER) + if (isProx) { target[0] += crandom() * GUNNER_PROX_SPREAD; target[1] += crandom() * GUNNER_PROX_SPREAD; @@ -765,16 +815,7 @@ void GunnerGrenade (edict_t *self) target[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); } - // lead target... 20, 35, 50, 65 chance of leading - if ( random() < (0.2 + skill->value * 0.15) ) - { - float dist, time; - - VectorSubtract (target, start, aim); - dist = VectorLength (aim); - time = dist / GRENADE_VELOCITY; // Not correct, but better than nothin' - VectorMA (target, time, self->enemy->velocity, target); - } + // Leading code was here // aim up if they're on the same level as me and far away. // if ((range > 512) && (aim[2] < 64) && (aim[2] > -64)) @@ -810,8 +851,7 @@ void GunnerGrenade (edict_t *self) // VectorMA (forward, spread, right, aim); // VectorMA (aim, pitch, up, aim); - // Knightmare- Tactician Gunner fires prox mines - if (self->moreflags & FL2_COMMANDER) + if (isProx) // Knightmare- Tactician Gunner fires prox mines { float prox_timer = (blindfire) ? 60.0f : 30.0f; monster_fire_prox (self, start, aim, 90, 1, GRENADE_VELOCITY, 20, prox_timer, 192, flash_number); diff --git a/missionpack/m_turret.c b/missionpack/m_turret.c index 1ab97aa..0ce889c 100644 --- a/missionpack/m_turret.c +++ b/missionpack/m_turret.c @@ -363,7 +363,7 @@ void Turret_Railgun_Aim (edict_t *self) end[2]+=self->enemy->viewheight; else end[2]+=22; - VectorCopy (end, self->aim_point); //save for aiming the shot + VectorCopy (end, self->aim_point); // save for aiming the shot self->think = Turret_Railgun_Fire; self->nextthink = level.time + 2 * FRAMETIME; diff --git a/qcommon/qcommon.h b/qcommon/qcommon.h index 6b5a746..05e6c7f 100644 --- a/qcommon/qcommon.h +++ b/qcommon/qcommon.h @@ -239,7 +239,7 @@ PROTOCOL // protocol.h -- communications protocols -#define PROTOCOL_VERSION 56 // changed from 0.19, was 35 +#define PROTOCOL_VERSION 57 // changed from 0.19, was 35 #define R1Q2_PROTOCOL_VERSION 35 #define OLD_PROTOCOL_VERSION 34 diff --git a/server/sv_ents.c b/server/sv_ents.c index 5123fd2..0d50e0d 100644 --- a/server/sv_ents.c +++ b/server/sv_ents.c @@ -223,11 +223,12 @@ SV_WritePlayerstateToClient */ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg) { - int i; + int i, j; int pflags; player_state_t *ps, *ops; player_state_t dummy; - int statbits; +// int statbits; + int statbitarray[(MAX_STATS+31)>>5]; // derived from MAX_STATS ps = &to->ps; if (!from) @@ -432,7 +433,7 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size MSG_WriteChar (msg, ps->gunangles[2]*4); } -#ifdef NEW_PLAYER_STATE_MEMBERS //Knightmare added +#ifdef NEW_PLAYER_STATE_MEMBERS // Knightmare added if (pflags & PS_WEAPONSKIN) MSG_WriteShort (msg, ps->gunskin); @@ -454,7 +455,7 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size if (pflags & PS_STOPSPEED) MSG_WriteShort (msg, ps->stopspeed); -#endif //end Knightmare +#endif // end Knightmare if (pflags & PS_BLEND) { @@ -469,7 +470,7 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size MSG_WriteByte (msg, ps->rdflags); // send stats - statbits = 0; +/* statbits = 0; for (i=0 ; istats[i] != ops->stats[i]) statbits |= 1<stats[i]); +*/ + for (j = 0; j < (MAX_STATS+31)>>5; j++) + statbitarray[j] = 0; + for (i=0; istats[i] != ops->stats[i]) + statbitarray[i>>5] |= 1<<(i&31); + for (j = 0; j < (MAX_STATS+31)>>5; j++) + MSG_WriteLong (msg, statbitarray[j]); + for (i=0; i>5] & (1<<(i&31)) ) + MSG_WriteShort (msg, ps->stats[i]); } diff --git a/server/sv_send.c b/server/sv_send.c index 936274f..6aa043c 100644 --- a/server/sv_send.c +++ b/server/sv_send.c @@ -311,7 +311,9 @@ void SV_StartSound (vec3_t origin, edict_t *entity, int channel, else use_phs = true; - sendchan = (ent<<3) | (channel&7); + // Knightmare 8/2/21- changed to a full byte instead of 3 bits +// sendchan = (ent<<3) | (channel&7); + sendchan = (channel & 255); flags = 0; if (volume != DEFAULT_SOUND_PACKET_VOLUME) @@ -350,7 +352,7 @@ void SV_StartSound (vec3_t origin, edict_t *entity, int channel, MSG_WriteByte (&sv.multicast, svc_sound); MSG_WriteByte (&sv.multicast, flags); - //Knightmare- 12/23/2001- changed to short + // Knightmare- 12/23/2001- changed to short MSG_WriteShort (&sv.multicast, soundindex); if (flags & SND_VOLUME) @@ -361,12 +363,17 @@ void SV_StartSound (vec3_t origin, edict_t *entity, int channel, MSG_WriteByte (&sv.multicast, timeofs*1000); if (flags & SND_ENT) - MSG_WriteShort (&sv.multicast, sendchan); + { + // Knightmare 8/2/21- changed ent and channel to byte and a short + // MSG_WriteShort (&sv.multicast, sendchan); + MSG_WriteByte (&sv.multicast, sendchan); + MSG_WriteShort (&sv.multicast, ent); + } if (flags & SND_POS) MSG_WritePos (&sv.multicast, origin); - // if the sound doesn't attenuate,send it to everyone + // if the sound doesn't attenuate, send it to everyone // (global radio chatter, voiceovers, etc) if (attenuation == ATTN_NONE) use_phs = false; diff --git a/zaero/g_phys.c b/zaero/g_phys.c index ab09a97..0fd66ee 100644 --- a/zaero/g_phys.c +++ b/zaero/g_phys.c @@ -57,12 +57,17 @@ void SV_CheckVelocity (edict_t *ent) // // bound velocity // - for (i=0 ; i<3 ; i++) +/* for (i=0 ; i<3 ; i++) { if (ent->velocity[i] > sv_maxvelocity->value) ent->velocity[i] = sv_maxvelocity->value; else if (ent->velocity[i] < -sv_maxvelocity->value) ent->velocity[i] = -sv_maxvelocity->value; + } */ + if (VectorLength(ent->velocity) > sv_maxvelocity->value) + { + VectorNormalize (ent->velocity); + VectorScale (ent->velocity, sv_maxvelocity->value, ent->velocity); } }