From 926d01ccd0012ae5c3fbfcdb71c29c40fe44f260 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 21 Apr 2020 08:13:22 +1000 Subject: [PATCH] Implement accurate-aiming CVAR in 3zb2 game code. --- src/g_ctf.c | 4 ++-- src/g_main.c | 2 ++ src/g_save.c | 3 +++ src/header/local.h | 4 +++- src/player/weapon.c | 49 ++++++++++++++++++++++++++++++--------------- 5 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/g_ctf.c b/src/g_ctf.c index aa958eb..18c1f81 100644 --- a/src/g_ctf.c +++ b/src/g_ctf.c @@ -1290,7 +1290,7 @@ void CTFGrappleDrawCable(edict_t *self) { AngleVectors (self->owner->client->v_angle, f, r, NULL); VectorSet(offset, 16, 16, self->owner->viewheight-8); - P_ProjectSource (self->owner->client, self->owner->s.origin, offset, f, r, start); + P_ProjectSource (self->owner, offset, f, r, start); } else { @@ -1519,7 +1519,7 @@ void CTFGrappleFire (edict_t *ent, vec3_t g_offset, int damage, int effect) // VectorSet(offset, 24, 16, ent->viewheight-8+2); VectorSet(offset, 24, 8, ent->viewheight-8+2); VectorAdd (offset, g_offset, offset); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); VectorScale (forward, -2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; diff --git a/src/g_main.c b/src/g_main.c index f660f81..103c347 100644 --- a/src/g_main.c +++ b/src/g_main.c @@ -51,6 +51,8 @@ cvar_t *bob_roll; cvar_t *sv_cheats; +cvar_t *aimfix; + //ponpoko cvar_t *gamepath; cvar_t *chedit; diff --git a/src/g_save.c b/src/g_save.c index 9530ccd..284b27e 100644 --- a/src/g_save.c +++ b/src/g_save.c @@ -203,6 +203,9 @@ void InitGame (void) bob_pitch = gi.cvar ("bob_pitch", "0.002", 0); bob_roll = gi.cvar ("bob_roll", "0.002", 0); + /* others */ + aimfix = gi.cvar("aimfix", "0", CVAR_ARCHIVE); + // items InitItems (); diff --git a/src/header/local.h b/src/header/local.h index 9aff669..3d5d543 100644 --- a/src/header/local.h +++ b/src/header/local.h @@ -576,6 +576,8 @@ extern cvar_t *maxspectators; extern cvar_t *filterban; +extern cvar_t *aimfix; + //ponpoko extern cvar_t *gamepath; extern cvar_t *chedit; @@ -834,7 +836,7 @@ void DeathmatchScoreboardMessage (edict_t *client, edict_t *killer); // g_pweapon.c // void PlayerNoise(edict_t *who, vec3_t where, int type); -void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result); +void P_ProjectSource (edict_t *ent, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result); void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent)); diff --git a/src/player/weapon.c b/src/player/weapon.c index d430584..567fc9f 100644 --- a/src/player/weapon.c +++ b/src/player/weapon.c @@ -14,9 +14,11 @@ void weapon_grenade_fire (edict_t *ent, qboolean held); // RAFAEL void weapon_trap_fire (edict_t *ent, qboolean held); -void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result) +void P_ProjectSource (edict_t *ent, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result) { - vec3_t _distance; + gclient_t *client = ent->client; + float *point = ent->s.origin; + vec3_t _distance; VectorCopy (distance, _distance); if (client->pers.hand == LEFT_HANDED) @@ -24,6 +26,21 @@ void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t f else if (client->pers.hand == CENTER_HANDED) _distance[1] = 0; G_ProjectSource (point, _distance, forward, right, result); + + // Berserker: fix - now the projectile hits exactly where the scope is pointing. + if (aimfix->value) + { + vec3_t start, end; + VectorSet(start, ent->s.origin[0], ent->s.origin[1], ent->s.origin[2] + ent->viewheight); + VectorMA(start, 8192, forward, end); + + trace_t tr = gi.trace(start, NULL, NULL, end, ent, MASK_SHOT); + if (tr.fraction < 1) + { + VectorSubtract(tr.endpos, result, forward); + VectorNormalize(forward); + } + } } @@ -748,7 +765,7 @@ void weapon_grenade_fire (edict_t *ent, qboolean held) VectorSet(offset, 8, 8, ent->viewheight-8); AngleVectors (ent->client->v_angle, forward, right, NULL); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); timer = ent->client->grenade_time - level.time; speed = GRENADE_MINSPEED + (GRENADE_TIMER - timer) * ((GRENADE_MAXSPEED - GRENADE_MINSPEED) / GRENADE_TIMER); @@ -925,7 +942,7 @@ void weapon_grenadelauncher_fire (edict_t *ent) VectorSet(offset, 8, 8, ent->viewheight-8); AngleVectors (ent->client->v_angle, forward, right, NULL); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); VectorScale (forward, -2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; @@ -990,7 +1007,7 @@ void Weapon_RocketLauncher_Fire (edict_t *ent) ent->client->kick_angles[0] = -1; VectorSet(offset, 8, 8, ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); if(ent->client->zc.aiming != 4) fire_rocket (ent, start, forward, damage, 650, damage_radius, radius_damage); else { @@ -1146,7 +1163,7 @@ void Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, in if(!(ent->svflags & SVF_MONSTER)) { VectorAdd (offset, g_offset, offset); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); VectorScale (forward, -2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; @@ -1352,7 +1369,7 @@ void Machinegun_Fire (edict_t *ent) VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles); AngleVectors (angles, forward, right, NULL); VectorSet(offset, 0, 8, ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_MACHINEGUN); gi.WriteByte (svc_muzzleflash); @@ -1481,7 +1498,7 @@ void Chaingun_Fire (edict_t *ent) r = 7 + crandom()*4; u = crandom()*4; VectorSet(offset, 0, r, u + ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN); } @@ -1607,7 +1624,7 @@ void Gatringgun_Fire (edict_t *ent) r = 7 + crandom()*4; u = crandom()*4; VectorSet(offset, 0, r, u + ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN); } @@ -1691,7 +1708,7 @@ void weapon_shotgun_fire (edict_t *ent) ent->client->kick_angles[0] = -2; VectorSet(offset, 0, 8, ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); if (is_quad) { @@ -1744,7 +1761,7 @@ void weapon_supershotgun_fire (edict_t *ent) ent->client->kick_angles[0] = -2; VectorSet(offset, 0, 8, ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); if (is_quad) { @@ -1886,7 +1903,7 @@ void weapon_railgun_fire (edict_t *ent) VectorSet(offset, 0, 7, ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); if(ent->client->zc.aiming == 0) fire_rail (ent, start, forward, damage, kick); else @@ -2030,7 +2047,7 @@ void weapon_bfg_fire (edict_t *ent) ent->client->v_dmg_time = level.time + DAMAGE_TIME; VectorSet(offset, 8, 8, ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); fire_bfg (ent, start, forward, damage, 400, damage_radius); ent->client->ps.gunframe++; @@ -2097,7 +2114,7 @@ void weapon_ionripper_fire (edict_t *ent) // VectorSet (offset, 0, 7, ent->viewheight - 8); VectorSet (offset, 16, 7, ent->viewheight - 8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); fire_ionripper (ent, start, forward, damage, 500, EF_IONRIPPER); @@ -2160,7 +2177,7 @@ void weapon_phalanx_fire (edict_t *ent) ent->client->kick_angles[0] = -2; VectorSet(offset, 0, 8, ent->viewheight-8); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); if (ent->client->ps.gunframe == 8) { @@ -2238,7 +2255,7 @@ void weapon_trap_fire (edict_t *ent, qboolean held) VectorSet(offset, 8, 8, ent->viewheight-8); AngleVectors (ent->client->v_angle, forward, right, NULL); - P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); + P_ProjectSource (ent, offset, forward, right, start); timer = ent->client->grenade_time - level.time; speed = GRENADE_MINSPEED + (GRENADE_TIMER - timer) * ((GRENADE_MAXSPEED - GRENADE_MINSPEED) / GRENADE_TIMER);