mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-10 07:11:36 +00:00
Elder:
Sync with VM 0-04-00 release Fixes a ton of stuff, adds some new goodies
This commit is contained in:
parent
05b8566b24
commit
732f73a910
11 changed files with 517 additions and 271 deletions
|
@ -1105,10 +1105,10 @@ Check for hard landings that generate sound events
|
|||
*/
|
||||
static void PM_CrashLand( void ) {
|
||||
float delta;
|
||||
float dist;
|
||||
float vel, acc;
|
||||
float t;
|
||||
float a, b, c, den;
|
||||
//float dist;
|
||||
//float vel, acc;
|
||||
//float t;
|
||||
//float a, b, c, den;
|
||||
int damage;
|
||||
|
||||
// decide which landing animation to use
|
||||
|
@ -1190,6 +1190,18 @@ static void PM_CrashLand( void ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (delta > 20)
|
||||
{
|
||||
PM_AddEvent( EV_FALL_SHORT );
|
||||
//Elder: added? useful?
|
||||
pm->ps->stats[STAT_FALLDAMAGE] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_AddEvent( PM_FootstepForSurface() );
|
||||
//Elder: added? useful?
|
||||
pm->ps->stats[STAT_FALLDAMAGE] = 0;
|
||||
}
|
||||
|
||||
// start footstep cycle over
|
||||
pm->ps->bobCycle = 0;
|
||||
|
@ -1738,6 +1750,13 @@ static void PM_FinishWeaponChange( void ) {
|
|||
weapon = WP_NONE;
|
||||
}
|
||||
|
||||
//Remove grenade if out of ammo
|
||||
if (weapon == WP_GRENADE && pm->ps->ammo[WP_GRENADE] == 0)
|
||||
{
|
||||
pm->ps->stats[STAT_WEAPONS] &= ~(1 << WP_GRENADE);
|
||||
weapon = WP_PISTOL;
|
||||
}
|
||||
|
||||
pm->ps->weapon = weapon;
|
||||
pm->ps->weaponstate = WEAPON_RAISING;
|
||||
//pm->ps->weaponTime += 250;
|
||||
|
@ -1873,6 +1892,22 @@ static void PM_Weapon( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
//Elder: drop the primed grenade if bandaging
|
||||
/*
|
||||
if ( pm->ps->weapon == WP_GRENADE &&
|
||||
pm->ps->ammo[WP_GRENADE] > 0 &&
|
||||
//
|
||||
//pm->ps->weaponstate == WEAPON_DROPPING &&
|
||||
(pm->cmd.buttons & 1) &&
|
||||
(pm->ps->stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK)
|
||||
{
|
||||
PM_AddEvent( EV_FIRE_WEAPON );
|
||||
pm->ps->ammo[WP_GRENADE]--;
|
||||
if (pm->ps->ammo[WP_GRENADE] == 0)
|
||||
pm->ps->stats[STAT_WEAPONS] &= ~( 1 << WP_GRENADE);
|
||||
}*/
|
||||
|
||||
|
||||
if ( pm->ps->weaponTime > 0 ) {
|
||||
return;
|
||||
}
|
||||
|
@ -2263,8 +2298,9 @@ static void PM_LadderMove( void ) {
|
|||
for (i=0 ; i<3 ; i++)
|
||||
wishvel[i] = scale * pml.forward[i]*pm->cmd.forwardmove +
|
||||
scale * pml.right[i]*pm->cmd.rightmove;
|
||||
wishvel[0] /= 2;
|
||||
wishvel[1] /= 2;
|
||||
//Elder: changed from a factor of 2 to 10
|
||||
wishvel[0] /= 10;
|
||||
wishvel[1] /= 10;
|
||||
wishvel[2] += scale * pm->cmd.upmove;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@
|
|||
#define RQ3_AKIMBO_KICK 90
|
||||
#define RQ3_KNIFE_KICK 0
|
||||
#define RQ3_THROW_KICK 50
|
||||
#define RQ3_GRENADE_KICK 0 // Elder: assumed
|
||||
#define RQ3_GRENADE_KICK 200 // Elder: assumed
|
||||
|
||||
|
||||
//Elder: weaponTime constants (delay in milliseconds)
|
||||
|
@ -200,16 +200,16 @@
|
|||
#define RQ3_AKIMBO_RELOAD_DELAY 2500
|
||||
|
||||
#define RQ3_M3_RELOAD_DELAY 1100
|
||||
#define RQ3_M3_ALLOW_FAST_RELOAD_DELAY 700 // Time into reload to enable fast-reloads
|
||||
#define RQ3_M3_ALLOW_FAST_RELOAD_DELAY 200 // 700 Time into reload to enable fast-reloads
|
||||
#define RQ3_M3_FAST_RELOAD_DELAY 500 // Fast reload time
|
||||
//#define RQ3_M3_START_RELOAD_DELAY 300 // Start index point of fast reload
|
||||
//#define RQ3_M3_FINISH_RELOAD_DELAY 300 // Amount of time after all fast reloads
|
||||
#define RQ3_M3_FINISH_RELOAD_DELAY 300 // Amount of time after all fast reloads
|
||||
|
||||
#define RQ3_SSG3000_RELOAD_DELAY 3100
|
||||
#define RQ3_SSG3000_ALLOW_FAST_RELOAD_DELAY 2200 // Time into reload to enable fast-reloads
|
||||
#define RQ3_SSG3000_ALLOW_FAST_RELOAD_DELAY 1400 //2200 Time into reload to enable fast-reloads
|
||||
#define RQ3_SSG3000_FAST_RELOAD_DELAY 600 // Fast reload time
|
||||
//#define RQ3_SSG3000_START_RELOAD_DELAY 1700 // Start index point of fast reload
|
||||
//#define RQ3_SSG3000_FINISH_RELOAD_DELAY 800 // Amount of time after all fast reloads
|
||||
#define RQ3_SSG3000_FINISH_RELOAD_DELAY 800 // Amount of time after all fast reloads
|
||||
|
||||
#define RQ3_KNIFE_RELOAD_DELAY 0 // Elder: shouldn't need
|
||||
#define RQ3_GRENADE_RELOAD_DELAY 0 // Elder: shouldn't need
|
||||
|
@ -232,7 +232,7 @@
|
|||
#define RQ3_M4_SWITCH2_DELAY 500
|
||||
#define RQ3_MP5_SWITCH2_DELAY 400
|
||||
#define RQ3_HANDCANNON_SWITCH2_DELAY 400
|
||||
#define RQ3_SSG3000_SWITCH2_DELAY 900
|
||||
#define RQ3_SSG3000_SWITCH2_DELAY 150 //900 For some reason it's auto-used with WEAPON_RAISING
|
||||
#define RQ3_AKIMBO_SWITCH2_DELAY 800
|
||||
#define RQ3_KNIFE_SWITCH2_DELAY 700
|
||||
#define RQ3_THROW_SWITCH2_DELAY 700
|
||||
|
|
|
@ -3,164 +3,13 @@
|
|||
|
||||
#include "g_local.h"
|
||||
|
||||
extern float s_quadFactor;
|
||||
extern vec3_t forward, right, up;
|
||||
extern vec3_t muzzle;
|
||||
extern void Cmd_OpenDoor( gentity_t * );
|
||||
//Elder: got rid of these
|
||||
//extern float s_quadFactor;
|
||||
//extern vec3_t forward, right, up;
|
||||
//extern vec3_t muzzle;
|
||||
//extern void Cmd_OpenDoor( gentity_t * );
|
||||
|
||||
qboolean DoorKick( trace_t *trIn, gentity_t *ent, vec3_t origin, vec3_t forward )
|
||||
{
|
||||
gentity_t *traceEnt;
|
||||
trace_t tr;
|
||||
|
||||
traceEnt = &g_entities[ trIn->entityNum ];
|
||||
if ( Q_stricmp (traceEnt->classname, "func_door_rotating") == 0 )
|
||||
{
|
||||
vec3_t d_right, d_forward;
|
||||
float crossProduct;
|
||||
vec3_t end;
|
||||
|
||||
// Find the hit point and the muzzle point with respect
|
||||
// to the door's origin, then project down to the XY plane
|
||||
// and take the cross product
|
||||
VectorSubtract( trIn->endpos, traceEnt->s.origin, d_right );
|
||||
VectorSubtract( origin, traceEnt->s.origin, d_forward );
|
||||
crossProduct = d_forward[0]*d_right[1]-d_right[0]*d_forward[1];
|
||||
|
||||
// See if we are on the proper side to do it
|
||||
if ( ((traceEnt->pos2[1] > traceEnt->pos1[1]) && crossProduct > 0) ||
|
||||
((traceEnt->pos2[1] < traceEnt->pos1[1]) && crossProduct < 0))
|
||||
{
|
||||
Cmd_OpenDoor( ent );
|
||||
VectorMA( trIn->endpos, 25, forward, end );
|
||||
trap_Trace (&tr, trIn->endpos, NULL, NULL, end, trIn->entityNum, MASK_SHOT);
|
||||
if ( !(tr.surfaceFlags & SURF_NOIMPACT) )
|
||||
{
|
||||
traceEnt = &g_entities[ tr.entityNum ];
|
||||
if ( traceEnt->client )
|
||||
{
|
||||
*trIn = tr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
else
|
||||
return qfalse;
|
||||
|
||||
}
|
||||
|
||||
qboolean JumpKick( gentity_t *ent )
|
||||
{
|
||||
trace_t tr;
|
||||
vec3_t end;
|
||||
gentity_t *tent;
|
||||
gentity_t *traceEnt;
|
||||
int damage;
|
||||
//Elder: for kick sound
|
||||
qboolean kickSuccess;
|
||||
|
||||
// set aiming directions
|
||||
AngleVectors (ent->client->ps.viewangles, forward, right, up);
|
||||
|
||||
CalcMuzzlePoint ( ent, forward, right, up, muzzle );
|
||||
|
||||
VectorMA (muzzle, 32, forward, end);
|
||||
|
||||
//VectorCopy( ent->s.origin, muzzle );
|
||||
//muzzle[2] += 32;
|
||||
// the muzzle really isn't the right point to test the jumpkick from
|
||||
trap_Trace (&tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT);
|
||||
//trap_Trace (&tr, ent->s.origin, ent->r.mins, ent->r.maxs, end, ent->s.number, MASK_SHOT);
|
||||
//trap_Trace (&tr, ent->s.origin, NULL, NULL, end, ent->s.number, MASK_SHOT);
|
||||
if ( tr.surfaceFlags & SURF_NOIMPACT ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
kickSuccess = DoorKick( &tr, ent, muzzle, forward );
|
||||
traceEnt = &g_entities[ tr.entityNum ];
|
||||
|
||||
if ( !traceEnt->takedamage) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (ent->client->ps.powerups[PW_QUAD] ) {
|
||||
G_AddEvent( ent, EV_POWERUP_QUAD, 0 );
|
||||
s_quadFactor = g_quadfactor.value;
|
||||
} else {
|
||||
s_quadFactor = 1;
|
||||
}
|
||||
|
||||
damage = 20;
|
||||
|
||||
//Elder: can't hit if crouching but can still hit "dead" bodies :)
|
||||
if (traceEnt->client && traceEnt->health > 0 && traceEnt->r.maxs[2] < 20)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
else {
|
||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
||||
damage, DAMAGE_NO_LOCATIONAL, MOD_KICK );
|
||||
}
|
||||
|
||||
// send blood impact
|
||||
if ( traceEnt->takedamage && traceEnt->client ) {
|
||||
tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT );
|
||||
tent->s.otherEntityNum = traceEnt->s.number;
|
||||
tent->s.eventParm = DirToByte( tr.plane.normal );
|
||||
tent->s.weapon = ent->s.weapon;
|
||||
kickSuccess = qtrue;
|
||||
}
|
||||
|
||||
if (traceEnt->client && traceEnt->client->ps.stats[STAT_UNIQUEWEAPONS] > 0)
|
||||
{
|
||||
//Elder: toss a unique weapon if kicked
|
||||
//Todo: Need to make sure to cancel any reload attempts
|
||||
//Todo: need to send a message to attacker and target about weapon kick
|
||||
ThrowWeapon(traceEnt);
|
||||
//trap_SendServerCommand( ent-g_entities, va("print \"You kicked %s's %s from his hands!\n\"", traceEnt->client->pers.netname, (traceEnt->client->ps.weapon)->pickup_name);
|
||||
//trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\""));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Elder: for the kick
|
||||
// do our special form of knockback here
|
||||
/*
|
||||
VectorMA (self->enemy->absmin, 0.5, self->enemy->size, v);
|
||||
VectorSubtract (v, point, v);
|
||||
VectorNormalize (v);
|
||||
VectorMA (self->enemy->velocity, kick, v, self->enemy->velocity);
|
||||
if (self->enemy->velocity[2] > 0)
|
||||
self->enemy->groundentity = NULL;
|
||||
*/
|
||||
//Elder: kick knockback for AQ2 -- recall variable kick = 400
|
||||
if (traceEnt->client)
|
||||
{
|
||||
//Elder: for kick knockback
|
||||
vec3_t size, vTemp;
|
||||
|
||||
//Make the "size" vector - hopefully this is right
|
||||
VectorSubtract(traceEnt->r.maxs, traceEnt->r.mins, size);
|
||||
G_Printf("Size: %s\n", vtos(size));
|
||||
|
||||
VectorMA(traceEnt->r.absmin, 0.5, size, vTemp);
|
||||
VectorSubtract(vTemp, tr.endpos, vTemp);
|
||||
VectorNormalize(vTemp);
|
||||
VectorMA(traceEnt->client->ps.velocity, 400, vTemp, traceEnt->client->ps.velocity);
|
||||
if (traceEnt->client->ps.velocity[2] > 0)
|
||||
traceEnt->s.groundEntityNum = ENTITYNUM_NONE;
|
||||
}
|
||||
|
||||
|
||||
//Elder: Our set of locally called sounds
|
||||
if (kickSuccess)
|
||||
G_AddEvent ( ent, EV_RQ3_SOUND, RQ3_SOUND_KICK);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
//Elder: moved kick to g_weapon.c where it belongs
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -176,6 +25,7 @@ void P_DamageFeedback( gentity_t *player ) {
|
|||
gclient_t *client;
|
||||
float count, side;
|
||||
vec3_t angles, v;
|
||||
vec3_t forward, right, up;
|
||||
|
||||
client = player->client;
|
||||
if ( client->ps.pm_type == PM_DEAD ) {
|
||||
|
@ -183,8 +33,11 @@ void P_DamageFeedback( gentity_t *player ) {
|
|||
}
|
||||
|
||||
// total points of damage shot at the player this frame
|
||||
if (client->damage_blood > 0)
|
||||
G_Printf("(%i) Damage_blood: %i\n", player->s.clientNum, client->damage_blood);
|
||||
//if (client->damage_blood > 0)
|
||||
//G_Printf("(%i) Damage_blood: %i\n", player->s.clientNum, client->damage_blood);
|
||||
|
||||
//if (client->damage_knockback > 0)
|
||||
//G_Printf("(%i) Damage_knockback: %i\n", player->s.clientNum, client->damage_knockback);
|
||||
|
||||
count = client->damage_blood + client->damage_armor;
|
||||
if ( count == 0 ) {
|
||||
|
@ -213,6 +66,10 @@ void P_DamageFeedback( gentity_t *player ) {
|
|||
|
||||
// new RQ3 view-kick code, needs more tweaking (the 50 needs to be replaces with that below calcuation
|
||||
// from the AQ2 code.
|
||||
|
||||
// set aiming directions
|
||||
AngleVectors (client->ps.viewangles, forward, right, up);
|
||||
|
||||
VectorSubtract(client->damage_from, player->s.origin , v);
|
||||
VectorNormalize(v);
|
||||
|
||||
|
@ -1139,6 +996,7 @@ void ClientThink_real( gentity_t *ent ) {
|
|||
client->ps.speed *= 1.3;
|
||||
}
|
||||
|
||||
|
||||
// Let go of the hook if we aren't firing
|
||||
//Blaze: No Hook in reaction
|
||||
/*
|
||||
|
@ -1290,7 +1148,26 @@ void ClientThink_real( gentity_t *ent ) {
|
|||
FireWeapon( ent );
|
||||
}
|
||||
break;
|
||||
case WP_M3:
|
||||
//Elder: try to do a fast reload if it's queued
|
||||
if ( ent->client->ps.weaponTime < RQ3_M3_FAST_RELOAD_DELAY &&
|
||||
ent->client->fastReloads &&
|
||||
ent->client->reloadAttempts > 0)
|
||||
{
|
||||
//G_Printf("(%i) ClientThink: attempting fast-reload...\n", ent->s.clientNum);
|
||||
Cmd_Reload( ent );
|
||||
}
|
||||
break;
|
||||
case WP_SSG3000:
|
||||
//Elder: try to do a fast reload if it's queued
|
||||
if ( ent->client->ps.weaponTime < RQ3_SSG3000_FAST_RELOAD_DELAY &&
|
||||
ent->client->fastReloads &&
|
||||
ent->client->reloadAttempts > 0)
|
||||
{
|
||||
//G_Printf("(%i) ClientThink: attempting fast-reload...\n", ent->s.clientNum);
|
||||
Cmd_Reload( ent );
|
||||
}
|
||||
/*
|
||||
if ( ent->client->weaponfireNextTime != 0 &&
|
||||
level.time >= ent->client->weaponfireNextTime) {
|
||||
//Elder: restore last zoom and clear the variable
|
||||
|
@ -1302,7 +1179,7 @@ void ClientThink_real( gentity_t *ent ) {
|
|||
//Elder: stay in 1x until bolt is ready
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
}
|
||||
}*/
|
||||
/* else if (level.time - ent->client->lastReloadTime > ent->client->ps.weaponTime) {
|
||||
//Elder: Too buggy at the moment
|
||||
if (level.time - ent->client->lastReloadTime > RQ3_SSG3000_RELOAD_DELAY)
|
||||
|
@ -1329,13 +1206,6 @@ void ClientThink_real( gentity_t *ent ) {
|
|||
break;
|
||||
}
|
||||
|
||||
//if ( ent->client->ps.weapon == WP_AKIMBO &&
|
||||
//ent->client->weaponfireNextTime != 0 &&
|
||||
//level.time >= ent->client->weaponfireNextTime) {
|
||||
//FireWeapon( ent );
|
||||
//}
|
||||
|
||||
|
||||
// save results of triggers and client events
|
||||
if (ent->client->ps.eventSequence != oldEventSequence) {
|
||||
ent->eventTime = level.time;
|
||||
|
@ -1543,7 +1413,6 @@ void ClientEndFrame( gentity_t *ent ) {
|
|||
ent->client->ps.stats[STAT_HEALTH] = ent->health; // FIXME: get rid of ent->health...
|
||||
|
||||
//Elder: bleeding notification
|
||||
//ent->client->ps.stats[STAT_RQ3] &= RQ3_LEGDAMAGE;
|
||||
if (ent->client->bleeding ||
|
||||
(ent->client->ps.stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE) {
|
||||
ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_NEED;
|
||||
|
|
|
@ -1638,20 +1638,35 @@ void Cmd_Bandage (gentity_t *ent)
|
|||
(ent->client->ps.stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE)
|
||||
{
|
||||
//Elder: remove zoom bits
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
Cmd_Unzoom(ent);
|
||||
|
||||
//Elder: added
|
||||
ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_WORK;
|
||||
|
||||
//Elder: drop the primed grenade
|
||||
//Moved weapon switch to bg_pmove.c
|
||||
if (ent->client->ps.weapon == WP_GRENADE &&
|
||||
ent->client->ps.weaponstate == WEAPON_COCKED) {
|
||||
FireWeapon(ent);
|
||||
ent->client->ps.ammo[WP_GRENADE]--;
|
||||
//if (ent->client->ps.ammo[WP_GRENADE] == 0)
|
||||
//{
|
||||
//ent->client->ps.stats[STAT_WEAPONS] &= ~(1 << WP_GRENADE);
|
||||
//ent->client->ps.weapon = WP_PISTOL;
|
||||
//trap_SendServerCommand( ent-g_entities, "selectpistol" );
|
||||
//}
|
||||
}
|
||||
|
||||
ent->client->ps.weaponstate = WEAPON_DROPPING;
|
||||
ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT )
|
||||
^ ANIM_TOGGLEBIT ) | TORSO_DROP;
|
||||
|
||||
|
||||
ent->client->ps.weaponTime += 6000;
|
||||
ent->client->bleedtick = 4;
|
||||
//Elder: added to track health to bleed off
|
||||
ent->client->bleedBandageCount = BLEED_BANDAGE;
|
||||
|
||||
//Elder: added
|
||||
ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_WORK;
|
||||
//Elder: moved to g_active where it will be unset after 2 bleedticks
|
||||
//ent->client->ps.stats[STAT_RQ3] &= !RQ3_LEGDAMAGE;
|
||||
}
|
||||
|
@ -1675,11 +1690,13 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
|
||||
int weapon;
|
||||
int ammotoadd;
|
||||
int delay;
|
||||
int delay = 0;
|
||||
|
||||
//Elder: added for redundant check but shouldn't need to come here - handled in cgame
|
||||
//if (ent->client->isBandaging == qtrue) {
|
||||
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
|
||||
ent->client->fastReloads = 0;
|
||||
ent->client->reloadAttempts = 0;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\""));
|
||||
return;
|
||||
}
|
||||
|
@ -1692,7 +1709,6 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
//Elder: changed to new function
|
||||
ammotoadd = ClipAmountForReload(weapon);
|
||||
|
||||
delay = 0;
|
||||
/*if (ent->client->ps.ammo[weapon] >= ClipAmountForWeapon(weapon))
|
||||
{ trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
|
||||
return;
|
||||
|
@ -1747,8 +1763,9 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
|
||||
if (ent->client->ps.ammo[weapon] >= RQ3_M3_AMMO)
|
||||
{
|
||||
//reset fast reloads
|
||||
//reset fast reloads and attempts
|
||||
ent->client->fastReloads = 0;
|
||||
ent->client->reloadAttempts = 0;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
|
||||
return;
|
||||
}
|
||||
|
@ -1765,38 +1782,37 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
RQ3_M3_RELOAD_DELAY);
|
||||
*/
|
||||
//Have we fast reloaded before?
|
||||
if (ent->client->fastReloads) {
|
||||
if (ent->client->fastReloads)
|
||||
{
|
||||
if (level.time - ent->client->lastReloadTime < RQ3_M3_FAST_RELOAD_DELAY)
|
||||
{
|
||||
//not enough time has passed for a fast reload attempt
|
||||
//so discard the attempt
|
||||
//not enough time has passed for a fast-reload attempt so ignore it
|
||||
//G_Printf("Too soon: Discarded fast-reload attempt\n");
|
||||
return;
|
||||
}
|
||||
else if (level.time - ent->client->lastReloadTime >= RQ3_M3_FAST_RELOAD_DELAY &&
|
||||
level.time - ent->client->lastReloadTime <= RQ3_M3_RELOAD_DELAY)
|
||||
//else if (level.time - ent->client->lastReloadTime >= RQ3_M3_FAST_RELOAD_DELAY &&
|
||||
//level.time - ent->client->lastReloadTime <= RQ3_M3_RELOAD_DELAY)*/
|
||||
else if (level.time - ent->client->lastReloadTime <= RQ3_M3_RELOAD_DELAY)
|
||||
{
|
||||
//gotcha
|
||||
//Gotcha!
|
||||
ent->client->fastReloads = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Missed the window of opportunity!
|
||||
//Reset fastReloads
|
||||
//Missed the window of opportunity! - Reset fastReloads
|
||||
//G_Printf("Missed Window: disabling fast reloads\n");
|
||||
ent->client->fastReloads = 0;
|
||||
}
|
||||
}
|
||||
//Fast-reload virgin
|
||||
else if (level.time - ent->client->lastReloadTime >= RQ3_M3_ALLOW_FAST_RELOAD_DELAY &&
|
||||
level.time - ent->client->lastReloadTime <= RQ3_M3_RELOAD_DELAY)
|
||||
{
|
||||
ent->client->fastReloads = 1;
|
||||
}
|
||||
level.time - ent->client->lastReloadTime <= RQ3_M3_RELOAD_DELAY)
|
||||
{
|
||||
ent->client->fastReloads = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//not enough time has passed for a fast reload attempt
|
||||
//so discard the attempt
|
||||
//not enough time has passed for a fast-reload attempt so ignore it
|
||||
//G_Printf("Too soon: Discarded fast-reload attempt\n");
|
||||
return;
|
||||
}
|
||||
|
@ -1817,7 +1833,14 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
ent->client->fastReloads = 0;
|
||||
}
|
||||
|
||||
//Elder: finished a full reload cycle - mark the time and discard the attempt
|
||||
ent->client->lastReloadTime = level.time;
|
||||
ent->client->reloadAttempts--;
|
||||
|
||||
//Finish off if no more reload attempts
|
||||
if (ent->client->reloadAttempts < 1 && ent->client->fastReloads)
|
||||
delay += RQ3_M3_FINISH_RELOAD_DELAY;
|
||||
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
delay = RQ3_HANDCANNON_RELOAD_DELAY;
|
||||
|
@ -1835,8 +1858,9 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
|
||||
if (ent->client->ps.ammo[weapon] >= RQ3_SSG3000_AMMO)
|
||||
{
|
||||
//reset fast reloads
|
||||
//reset fast reloads and attempts
|
||||
ent->client->fastReloads = 0;
|
||||
ent->client->reloadAttempts = 0;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
|
||||
return;
|
||||
}
|
||||
|
@ -1853,38 +1877,37 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
RQ3_SSG3000_RELOAD_DELAY);
|
||||
*/
|
||||
//Have we fast reloaded before?
|
||||
if (ent->client->fastReloads) {
|
||||
if (ent->client->fastReloads)
|
||||
{
|
||||
if (level.time - ent->client->lastReloadTime < RQ3_SSG3000_FAST_RELOAD_DELAY)
|
||||
{
|
||||
//not enough time has passed for a fast reload attempt
|
||||
//so discard the attempt
|
||||
//not enough time has passed for a fast-reload attempt so ignore it
|
||||
//G_Printf("Too soon: Discarded fast-reload attempt\n");
|
||||
return;
|
||||
}
|
||||
else if (level.time - ent->client->lastReloadTime >= RQ3_SSG3000_FAST_RELOAD_DELAY &&
|
||||
level.time - ent->client->lastReloadTime <= RQ3_SSG3000_RELOAD_DELAY)
|
||||
//else if (level.time - ent->client->lastReloadTime >= RQ3_SSG3000_FAST_RELOAD_DELAY &&
|
||||
//level.time - ent->client->lastReloadTime <= RQ3_SSG3000_RELOAD_DELAY)*/
|
||||
else if (level.time - ent->client->lastReloadTime <= RQ3_SSG3000_RELOAD_DELAY)
|
||||
{
|
||||
//gotcha
|
||||
//Gotcha!
|
||||
ent->client->fastReloads = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Missed the window of opportunity!
|
||||
//Reset fastReloads
|
||||
//Missed the window of opportunity! - Reset fastReloads
|
||||
//G_Printf("Missed Window: disabling fast reloads\n");
|
||||
ent->client->fastReloads = 0;
|
||||
}
|
||||
}
|
||||
//Fast-reload virgin
|
||||
else if (level.time - ent->client->lastReloadTime >= RQ3_SSG3000_ALLOW_FAST_RELOAD_DELAY &&
|
||||
level.time - ent->client->lastReloadTime <= RQ3_SSG3000_RELOAD_DELAY)
|
||||
{
|
||||
ent->client->fastReloads = 1;
|
||||
}
|
||||
level.time - ent->client->lastReloadTime <= RQ3_SSG3000_RELOAD_DELAY)
|
||||
{
|
||||
ent->client->fastReloads = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//not enough time has passed for a fast reload attempt
|
||||
//so discard the attempt
|
||||
//not enough time has passed for a fast-reload attempt so ignore it
|
||||
//G_Printf("Too soon: Discarded fast-reload attempt\n");
|
||||
return;
|
||||
}
|
||||
|
@ -1904,7 +1927,14 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
ent->client->fastReloads = 0;
|
||||
}
|
||||
|
||||
//Elder: finished a full reload cycle - mark the time and discard the attempt
|
||||
ent->client->lastReloadTime = level.time;
|
||||
ent->client->reloadAttempts--;
|
||||
|
||||
//Finish off if no more reload attempts
|
||||
if (ent->client->reloadAttempts < 1 && ent->client->fastReloads)
|
||||
delay += RQ3_SSG3000_FINISH_RELOAD_DELAY;
|
||||
|
||||
break;
|
||||
case WP_AKIMBO:
|
||||
delay = RQ3_AKIMBO_RELOAD_DELAY;
|
||||
|
@ -1935,11 +1965,13 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
|
||||
//Elder: added handcannon and akimbo conditional
|
||||
if (ent->client->numClips[weapon] == 0) {
|
||||
ent->client->fastReloads = 0;
|
||||
ent->client->reloadAttempts = 0;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Out of ammo\n\""));
|
||||
return;
|
||||
}
|
||||
else if ( (weapon == WP_HANDCANNON || weapon == WP_AKIMBO) && ent->client->numClips[weapon] < 2 ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Not enough of ammo\n\""));
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Not enough ammo\n\""));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1948,8 +1980,8 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
if (RQ3_isZoomed(ent) && weapon == WP_SSG3000) {
|
||||
RQ3_SaveZoomLevel(ent);
|
||||
//Elder: remove zoom bits
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
//ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
//ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
}
|
||||
|
||||
//ent->client->ps.weaponstate = WEAPON_RELOADING;
|
||||
|
@ -2200,20 +2232,19 @@ void Cmd_Weapon(gentity_t *ent)
|
|||
{//Going into Short
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] |= RQ3_GRENSHORT; //Set the short flag
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] &= ~RQ3_GRENMED; //unset the med flag
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Grenade set for short range throw.\n\""));
|
||||
|
||||
//trap_SendServerCommand( ent-g_entities, va("print \"Grenade set for short range throw.\n\""));
|
||||
}
|
||||
else if ( (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_GRENSHORT) == RQ3_GRENSHORT)
|
||||
{//Going into Med
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] &= ~RQ3_GRENSHORT; //unset the short flag
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] |= RQ3_GRENMED; //Set the med flag
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Grenade set for medium range throw.\n\""));
|
||||
//trap_SendServerCommand( ent-g_entities, va("print \"Grenade set for medium range throw.\n\""));
|
||||
}
|
||||
else if ( (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_GRENMED) == RQ3_GRENMED)
|
||||
{//Going into Long
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] |= RQ3_GRENSHORT; //Set the short flag
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] |= RQ3_GRENMED; //Set the med flag
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Grenade set for long range throw.\n\""));
|
||||
//trap_SendServerCommand( ent-g_entities, va("print \"Grenade set for long range throw.\n\""));
|
||||
}
|
||||
//Elder: added
|
||||
else {
|
||||
|
@ -2235,20 +2266,21 @@ void Cmd_Weapon(gentity_t *ent)
|
|||
|
||||
|
||||
// Hawkins make sure spread comes back
|
||||
void Cmd_Unzoom(gentity_t *ent){
|
||||
void Cmd_Unzoom(gentity_t *ent)
|
||||
{
|
||||
//G_Printf("Got to Cmd_Unzoom\n");
|
||||
//Elder: added
|
||||
//if (ent->client->isBandaging == qtrue) {
|
||||
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
|
||||
//if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
|
||||
//trap_SendServerCommand( ent-g_entities, va("print \"You'll get to your weapon when you are finished bandaging!\n\""));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
//return;
|
||||
//}
|
||||
//else {
|
||||
//Elder: remove zoom bits
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
//ent->client->zoomed = 0;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2267,6 +2299,7 @@ void Cmd_Drop_f( gentity_t *ent ) {
|
|||
}
|
||||
else {
|
||||
//Elder: remove zoom bits
|
||||
Cmd_Unzoom(ent);
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
//ent->client->zoomed=0;
|
||||
|
@ -2384,7 +2417,12 @@ void ClientCommand( int clientNum ) {
|
|||
Cmd_Stats_f( ent );
|
||||
// Begin Duffman
|
||||
else if (Q_stricmp (cmd, "reload") == 0)
|
||||
{
|
||||
//Elder: add to reload queue if using fast-reloadable weapons
|
||||
if (ent->client->ps.weapon == WP_M3 || ent->client->ps.weapon == WP_SSG3000)
|
||||
ent->client->reloadAttempts++;
|
||||
Cmd_Reload( ent );
|
||||
}
|
||||
// End Duffman
|
||||
//Blaze's Open door command
|
||||
else if (Q_stricmp (cmd, "opendoor") == 0)
|
||||
|
|
|
@ -530,8 +530,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
//ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
|
||||
//Elder: remove zoom bits
|
||||
self->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
self->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
Cmd_Unzoom(self);
|
||||
//self->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
|
||||
//self->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
|
||||
//self->client->zoomed = 0;
|
||||
self->client->bleeding = 0;
|
||||
//targ->client->bleedcount = 0;
|
||||
|
@ -541,6 +542,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
self->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK;
|
||||
self->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_NEED;
|
||||
self->client->ps.stats[STAT_STREAK] = 0;
|
||||
|
||||
//Elder: stop reload attempts
|
||||
self->client->reloadAttempts = 0;
|
||||
}
|
||||
if ( self->client->ps.pm_type == PM_DEAD ) {
|
||||
return;
|
||||
|
@ -1252,33 +1256,94 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
|
||||
//Elder: this is a simplifed knockback calc - Action has a radically different one.
|
||||
knockback = damage;
|
||||
if ( knockback > 200 ) {
|
||||
knockback = 200;
|
||||
}
|
||||
//knockback = damage;
|
||||
|
||||
if ( mod == MOD_KICK )
|
||||
{
|
||||
knockback = 200;
|
||||
}
|
||||
//if ( knockback > 200 ) {
|
||||
//knockback = 200;
|
||||
//}
|
||||
|
||||
//if ( mod == MOD_KICK )
|
||||
//{
|
||||
//knockback = 200;
|
||||
//}
|
||||
|
||||
if ( targ->flags & FL_NO_KNOCKBACK ) {
|
||||
knockback = 0;
|
||||
}
|
||||
if ( dflags & DAMAGE_NO_KNOCKBACK ) {
|
||||
else if ( dflags & DAMAGE_NO_KNOCKBACK ) {
|
||||
knockback = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Elder: select knockback
|
||||
switch (mod)
|
||||
{
|
||||
case MOD_HANDCANNON:
|
||||
knockback = RQ3_HANDCANNON_KICK;
|
||||
break;
|
||||
case MOD_M3:
|
||||
knockback = RQ3_M3_KICK;
|
||||
break;
|
||||
case MOD_M4:
|
||||
knockback = RQ3_M4_KICK;
|
||||
break;
|
||||
case MOD_MP5:
|
||||
knockback = RQ3_MP5_KICK;
|
||||
break;
|
||||
case MOD_SNIPER:
|
||||
knockback = RQ3_SNIPER_KICK;
|
||||
break;
|
||||
case MOD_PISTOL:
|
||||
knockback = RQ3_PISTOL_KICK;
|
||||
break;
|
||||
case MOD_AKIMBO:
|
||||
knockback = RQ3_AKIMBO_KICK;
|
||||
break;
|
||||
case MOD_GRENADE_SPLASH:
|
||||
case MOD_GRENADE:
|
||||
knockback = (int)(0.75 * damage);
|
||||
break;
|
||||
case MOD_KNIFE:
|
||||
knockback = RQ3_KNIFE_KICK;
|
||||
break;
|
||||
case MOD_KNIFE_THROWN:
|
||||
knockback = RQ3_THROW_KICK;
|
||||
break;
|
||||
case MOD_KICK:
|
||||
//Elder: do some calculation here?
|
||||
knockback = 400;
|
||||
break;
|
||||
default:
|
||||
//G_Printf("Unknown MOD\n");
|
||||
G_Printf("G_Damage: Received unknown MOD - using default knockback\n");
|
||||
knockback = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// figure momentum add, even if the damage won't be taken
|
||||
if ( knockback && targ->client ) {
|
||||
vec3_t kvel;
|
||||
vec3_t kvel, flydir;
|
||||
float mass;
|
||||
|
||||
if ( mod != MOD_FALLING )
|
||||
{
|
||||
VectorCopy(dir, flydir);
|
||||
flydir[2] += 0.4f;
|
||||
}
|
||||
|
||||
mass = 200;
|
||||
|
||||
//Elder: Q2 uses a hardcoded value of 500 for non-rocket jumps
|
||||
//Q3 uses g_knockback.value ... default 1000
|
||||
VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
|
||||
//AQ2:
|
||||
//VectorScale (flydir, 500.0 * (float)knockback / mass, kvel);
|
||||
//RQ3:
|
||||
//VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
|
||||
if (targ->client && attacker == targ)
|
||||
VectorScale (flydir, 1600.0 * (float)knockback / mass, kvel);
|
||||
else
|
||||
VectorScale (flydir, 500.0 * (float)knockback / mass, kvel);
|
||||
VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);
|
||||
|
||||
// set the timer so that the other client can't cancel
|
||||
|
@ -1688,7 +1753,6 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
if (client)
|
||||
{
|
||||
|
||||
if (!(targ->flags & FL_GODMODE) && (take)) targ->pain (targ, attacker, take);
|
||||
}
|
||||
if (take)
|
||||
|
|
|
@ -327,7 +327,9 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
|
|||
trap_SendServerCommand( other-g_entities, va("print \"%s^7\n\"", RQ3_AKIMBO_NAME) );
|
||||
other->client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_AKIMBO );
|
||||
other->client->ps.ammo[WP_AKIMBO] = other->client->ps.ammo[WP_PISTOL] + RQ3_PISTOL_AMMO;
|
||||
ammotoadd = other->client->ps.ammo[WP_PISTOL];
|
||||
//Elder: always reset back to full clip like Action if first pistol picked up
|
||||
ammotoadd = RQ3_PISTOL_AMMO;
|
||||
//ammotoadd = other->client->ps.ammo[WP_PISTOL];
|
||||
}
|
||||
//Elder: Already have akimbo - technically should have pistol
|
||||
else if (other->client->numClips[ WP_PISTOL ] < 2) {
|
||||
|
@ -374,9 +376,9 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
|
|||
other->client->ps.stats[STAT_UNIQUEWEAPONS]++;
|
||||
break;
|
||||
case WP_GRENADE:
|
||||
if (other->client->ps.ammo[ent->item->giTag] < RQ3_GRENADE_MAXCLIP)
|
||||
if (other->client->ps.ammo[WP_GRENADE] < RQ3_GRENADE_MAXCLIP)
|
||||
{
|
||||
ammotoadd=other->client->ps.ammo[ent->item->giTag]+1;
|
||||
ammotoadd=other->client->ps.ammo[WP_GRENADE] + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -606,7 +608,7 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
return;
|
||||
break;
|
||||
case WP_GRENADE:
|
||||
if ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_GRENADE) == (1 << WP_GRENADE) ) &&
|
||||
if ( ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_GRENADE) )== (1 << WP_GRENADE) ) &&
|
||||
(other->client->ps.ammo[ent->item->giTag] >= RQ3_GRENADE_MAXCLIP) )
|
||||
return;
|
||||
break;
|
||||
|
@ -951,7 +953,7 @@ gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags
|
|||
vec3_t velocity;
|
||||
vec3_t angles;
|
||||
vec3_t origin;
|
||||
int throwheight;
|
||||
//int throwheight;
|
||||
|
||||
VectorCopy( ent->s.pos.trBase, origin );
|
||||
VectorCopy( ent->s.apos.trBase, angles );
|
||||
|
|
|
@ -367,6 +367,7 @@ struct gclient_s {
|
|||
|
||||
int fastReloads; //Elder: for queuing M3/SSG reloads
|
||||
int lastReloadTime; //Elder: for queuing M3/SSG reloads
|
||||
int reloadAttempts; //Elder: for queueing M3/SSG reloads
|
||||
|
||||
int consecutiveShots; //Elder: for M4 ride-up/kick
|
||||
|
||||
|
@ -506,6 +507,8 @@ void StopFollowing( gentity_t *ent );
|
|||
void BroadcastTeamChange( gclient_t *client, int oldTeam );
|
||||
void SetTeam( gentity_t *ent, char *s );
|
||||
void Cmd_FollowCycle_f( gentity_t *ent, int dir );
|
||||
void Cmd_Unzoom(gentity_t *ent);
|
||||
void Cmd_OpenDoor(gentity_t *ent);
|
||||
//Elder: commented out for Homer
|
||||
//void toggleSemi(gentity_t *ent);
|
||||
|
||||
|
@ -598,7 +601,8 @@ void TossClientCubes( gentity_t *self );
|
|||
#ifdef MISSIONPACK
|
||||
#define DAMAGE_NO_TEAM_PROTECTION 0x00000010 // armor, shields, invulnerability, and godmode have no effect
|
||||
#endif
|
||||
#define DAMAGE_NO_LOCATIONAL 0x00000016 // Generic damage (shotguns, grenades, kicks)
|
||||
//Elder: Changed from 0x00000016 to 0x00000020
|
||||
#define DAMAGE_NO_LOCATIONAL 0x00000020 // Generic damage (shotguns, grenades, kicks)
|
||||
|
||||
//
|
||||
// g_missile.c
|
||||
|
@ -656,6 +660,8 @@ qboolean CheckGauntletAttack( gentity_t *ent );
|
|||
//Elder: for shotgun damage reports
|
||||
void RQ3_InitShotgunDamageReport( void );
|
||||
void RQ3_ProduceShotgunDamageReport(gentity_t *self);
|
||||
qboolean JumpKick( gentity_t *ent );
|
||||
qboolean DoorKick( trace_t *trIn, gentity_t *ent, vec3_t origin, vec3_t forward );
|
||||
extern int tookShellHit[MAX_CLIENTS];
|
||||
|
||||
|
||||
|
|
|
@ -1695,9 +1695,9 @@ void G_RunFrame( int levelTime ) {
|
|||
int i;
|
||||
gentity_t *ent;
|
||||
//Blaze: Used for droping knifes
|
||||
gitem_t *xr_item;
|
||||
gentity_t *xr_drop;
|
||||
int temp;
|
||||
//gitem_t *xr_item;
|
||||
//gentity_t *xr_drop;
|
||||
//int temp;
|
||||
int msec;
|
||||
int start, end;
|
||||
|
||||
|
|
|
@ -709,8 +709,9 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
|
|||
|
||||
//Elder: grenade toggle distances/speeds
|
||||
if ( self->client) {
|
||||
if (self->client->ps.stats[STAT_HEALTH] <= 0) {
|
||||
//Always drop close range if dead
|
||||
if ( self->client->ps.stats[STAT_HEALTH] <= 0 ||
|
||||
(self->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
|
||||
//Always drop close range if dead or about to bandage
|
||||
speed = GRENADE_SHORT_SPEED / 2;
|
||||
}
|
||||
else if ( (self->client->ps.persistant[PERS_WEAPONMODES] & RQ3_GRENSHORT) == RQ3_GRENSHORT &&
|
||||
|
|
|
@ -36,6 +36,174 @@ void G_BounceProjectile( vec3_t start, vec3_t impact, vec3_t dir, vec3_t endout
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
======================================================================
|
||||
|
||||
RQ3 Jump Kick
|
||||
Moved from g_active.c to g_weapon.c
|
||||
Because it is a weapon!
|
||||
|
||||
======================================================================
|
||||
*/
|
||||
|
||||
qboolean JumpKick( gentity_t *ent )
|
||||
{
|
||||
trace_t tr;
|
||||
vec3_t end;
|
||||
gentity_t *tent;
|
||||
gentity_t *traceEnt;
|
||||
int damage;
|
||||
//Elder: for kick sound
|
||||
qboolean kickSuccess;
|
||||
|
||||
// set aiming directions
|
||||
AngleVectors (ent->client->ps.viewangles, forward, right, up);
|
||||
|
||||
CalcMuzzlePoint ( ent, forward, right, up, muzzle );
|
||||
|
||||
VectorMA (muzzle, 32, forward, end);
|
||||
|
||||
//VectorCopy( ent->s.origin, muzzle );
|
||||
//muzzle[2] += 32;
|
||||
// the muzzle really isn't the right point to test the jumpkick from
|
||||
|
||||
trap_Trace (&tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT);
|
||||
//trap_Trace (&tr, ent->s.origin, ent->r.mins, ent->r.maxs, end, ent->s.number, MASK_SHOT);
|
||||
//trap_Trace (&tr, ent->s.origin, NULL, NULL, end, ent->s.number, MASK_SHOT);
|
||||
if ( tr.surfaceFlags & SURF_NOIMPACT ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
kickSuccess = DoorKick( &tr, ent, muzzle, forward );
|
||||
traceEnt = &g_entities[ tr.entityNum ];
|
||||
|
||||
if ( !traceEnt->takedamage) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (ent->client->ps.powerups[PW_QUAD] ) {
|
||||
G_AddEvent( ent, EV_POWERUP_QUAD, 0 );
|
||||
s_quadFactor = g_quadfactor.value;
|
||||
} else {
|
||||
s_quadFactor = 1;
|
||||
}
|
||||
|
||||
damage = 20;
|
||||
|
||||
if ( traceEnt->s.eType == ET_BREAKABLE || traceEnt->client)
|
||||
kickSuccess = qtrue;
|
||||
|
||||
//Elder: can't hit if crouching but can still hit "dead" bodies :)
|
||||
if (traceEnt->client && traceEnt->health > 0 && traceEnt->r.maxs[2] < 20)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
else {
|
||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
||||
damage, DAMAGE_NO_LOCATIONAL, MOD_KICK );
|
||||
}
|
||||
|
||||
// send blood impact
|
||||
if ( traceEnt->takedamage && traceEnt->client ) {
|
||||
tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT );
|
||||
tent->s.otherEntityNum = traceEnt->s.number;
|
||||
tent->s.eventParm = DirToByte( tr.plane.normal );
|
||||
tent->s.weapon = ent->s.weapon;
|
||||
}
|
||||
|
||||
if (traceEnt->client && traceEnt->client->ps.stats[STAT_UNIQUEWEAPONS] > 0)
|
||||
{
|
||||
//Elder: toss a unique weapon if kicked
|
||||
//Todo: Need to make sure to cancel any reload attempts
|
||||
//Todo: need to send a message to attacker and target about weapon kick
|
||||
ThrowWeapon(traceEnt);
|
||||
//trap_SendServerCommand( ent-g_entities, va("print \"You kicked %s's %s from his hands!\n\"", traceEnt->client->pers.netname, (traceEnt->client->ps.weapon)->pickup_name);
|
||||
//trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\""));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Elder: for the kick
|
||||
// do our special form of knockback here
|
||||
/*
|
||||
VectorMA (self->enemy->absmin, 0.5, self->enemy->size, v);
|
||||
VectorSubtract (v, point, v);
|
||||
VectorNormalize (v);
|
||||
VectorMA (self->enemy->velocity, kick, v, self->enemy->velocity);
|
||||
if (self->enemy->velocity[2] > 0)
|
||||
self->enemy->groundentity = NULL;
|
||||
*/
|
||||
//Elder: kick knockback for AQ2 -- recall variable kick = 400
|
||||
//if (traceEnt->client)
|
||||
//{
|
||||
//Elder: for kick knockback
|
||||
//vec3_t size, vTemp;
|
||||
|
||||
//Make the "size" vector - hopefully this is right
|
||||
//VectorSubtract(traceEnt->r.maxs, traceEnt->r.mins, size);
|
||||
//G_Printf("Size: %s\n", vtos(size));
|
||||
|
||||
//VectorMA(traceEnt->r.absmin, 0.5, size, vTemp);
|
||||
//VectorSubtract(vTemp, tr.endpos, vTemp);
|
||||
//VectorNormalize(vTemp);
|
||||
//VectorMA(traceEnt->client->ps.velocity, 400, vTemp, traceEnt->client->ps.velocity);
|
||||
//if (traceEnt->client->ps.velocity[2] > 0)
|
||||
//traceEnt->s.groundEntityNum = ENTITYNUM_NONE;
|
||||
//}
|
||||
|
||||
|
||||
//Elder: Our set of locally called sounds
|
||||
if (kickSuccess)
|
||||
G_AddEvent ( ent, EV_RQ3_SOUND, RQ3_SOUND_KICK);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
qboolean DoorKick( trace_t *trIn, gentity_t *ent, vec3_t origin, vec3_t forward )
|
||||
{
|
||||
gentity_t *traceEnt;
|
||||
trace_t tr;
|
||||
|
||||
traceEnt = &g_entities[ trIn->entityNum ];
|
||||
if ( Q_stricmp (traceEnt->classname, "func_door_rotating") == 0 )
|
||||
{
|
||||
vec3_t d_right, d_forward;
|
||||
float crossProduct;
|
||||
vec3_t end;
|
||||
|
||||
// Find the hit point and the muzzle point with respect
|
||||
// to the door's origin, then project down to the XY plane
|
||||
// and take the cross product
|
||||
VectorSubtract( trIn->endpos, traceEnt->s.origin, d_right );
|
||||
VectorSubtract( origin, traceEnt->s.origin, d_forward );
|
||||
crossProduct = d_forward[0]*d_right[1]-d_right[0]*d_forward[1];
|
||||
|
||||
// See if we are on the proper side to do it
|
||||
if ( ((traceEnt->pos2[1] > traceEnt->pos1[1]) && crossProduct > 0) ||
|
||||
((traceEnt->pos2[1] < traceEnt->pos1[1]) && crossProduct < 0))
|
||||
{
|
||||
Cmd_OpenDoor( ent );
|
||||
VectorMA( trIn->endpos, 25, forward, end );
|
||||
trap_Trace (&tr, trIn->endpos, NULL, NULL, end, trIn->entityNum, MASK_SHOT);
|
||||
if ( !(tr.surfaceFlags & SURF_NOIMPACT) )
|
||||
{
|
||||
traceEnt = &g_entities[ tr.entityNum ];
|
||||
if ( traceEnt->client )
|
||||
{
|
||||
*trIn = tr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
else
|
||||
return qfalse;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
======================================================================
|
||||
|
||||
|
@ -907,18 +1075,77 @@ void Knife_Touch (gentity_t *ent, gentity_t *other,trace_t *trace)
|
|||
|
||||
|
||||
//======================================================================
|
||||
int RQ3Spread (gentity_t *ent, int spread)
|
||||
//Elder: can probably be static
|
||||
int RQ3_Spread (gentity_t *ent, int spread)
|
||||
{
|
||||
int runspeed = 225;
|
||||
int walkspeed = 10;
|
||||
int stage = 0;
|
||||
float factor[] = {0.7f, 1.0f, 2.0f, 6.0f};
|
||||
float xyspeed = (ent->client->ps.velocity[0]*ent->client->ps.velocity[0] + ent->client->ps.velocity[1]*ent->client->ps.velocity[1]);
|
||||
|
||||
if (ent->client->ps.pm_flags & PMF_DUCKED) return (spread * 0.65);
|
||||
//crouching
|
||||
if (ent->client->ps.pm_flags & PMF_DUCKED)
|
||||
return (spread * 0.65);
|
||||
|
||||
if (xyspeed > runspeed * runspeed) spread *= 3;
|
||||
else if (xyspeed >= walkspeed*walkspeed) spread *= 2;
|
||||
return (int)spread;
|
||||
//running
|
||||
if (xyspeed > runspeed * runspeed)
|
||||
stage = 3;
|
||||
//walking
|
||||
else if (xyspeed >= walkspeed*walkspeed)
|
||||
stage = 2;
|
||||
//standing
|
||||
else
|
||||
stage = 1;
|
||||
|
||||
//TODO: add laser advantage
|
||||
|
||||
|
||||
return (int)(spread * factor[stage]);
|
||||
|
||||
/*
|
||||
//Elder: original AQ2 code
|
||||
int running = 225; // minimum speed for running
|
||||
int walking = 10; // minimum speed for walking
|
||||
int laser = 0;
|
||||
float factor[] = {.7, 1, 2, 6};
|
||||
int stage = 0;
|
||||
|
||||
// 225 is running
|
||||
// < 10 will be standing
|
||||
float xyspeed = (ent->velocity[0]*ent->velocity[0] + ent->velocity[1]*ent->velocity[1]);
|
||||
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) // crouching
|
||||
return( spread * .65);
|
||||
|
||||
if ( (ent->client->pers.inventory[ITEM_INDEX(FindItem(LASER_NAME))])
|
||||
&& (ent->client->curr_weap == MK23_NUM
|
||||
|| ent->client->curr_weap == MP5_NUM
|
||||
|| ent->client->curr_weap == M4_NUM ) )
|
||||
laser = 1;
|
||||
|
||||
|
||||
// running
|
||||
if ( xyspeed > running*running )
|
||||
stage = 3;
|
||||
// walking
|
||||
else if ( xyspeed >= walking*walking )
|
||||
stage = 2;
|
||||
// standing
|
||||
else
|
||||
stage = 1;
|
||||
|
||||
// laser advantage
|
||||
if (laser)
|
||||
{
|
||||
if (stage == 1)
|
||||
stage = 0;
|
||||
else
|
||||
stage = 1;
|
||||
}
|
||||
|
||||
return (int)(spread * factor[stage]);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
@ -981,7 +1208,7 @@ void Weapon_M4_Fire(gentity_t *ent)
|
|||
|
||||
}
|
||||
|
||||
Bullet_Fire( ent, RQ3Spread(ent, M4_SPREAD), M4_DAMAGE, MOD_M4);
|
||||
Bullet_Fire( ent, RQ3_Spread(ent, M4_SPREAD), M4_DAMAGE, MOD_M4);
|
||||
|
||||
/*
|
||||
if ( (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE) {
|
||||
|
@ -1014,7 +1241,7 @@ void Weapon_MK23_Fire(gentity_t *ent)
|
|||
{
|
||||
spread = PISTOL_SPREAD;
|
||||
}
|
||||
Bullet_Fire( ent, RQ3Spread(ent, spread), PISTOL_DAMAGE, MOD_PISTOL);
|
||||
Bullet_Fire( ent, RQ3_Spread(ent, spread), PISTOL_DAMAGE, MOD_PISTOL);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1255,7 @@ void Weapon_SSG3000_FireOld(gentity_t *ent)
|
|||
float spread;
|
||||
//Elder: Don't print - will broadcast to server
|
||||
//G_Printf("Zoom Level: %d\n", ent->client->zoomed);
|
||||
//Elder: changed to use RQ3Spread as well
|
||||
//Elder: changed to use RQ3_Spread as well
|
||||
//Elder: using new stat
|
||||
//if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW ||
|
||||
//(ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_MED) == RQ3_ZOOM_MED) {
|
||||
|
@ -1036,7 +1263,7 @@ void Weapon_SSG3000_FireOld(gentity_t *ent)
|
|||
spread = 0;
|
||||
}
|
||||
else {
|
||||
spread = RQ3Spread(ent, SNIPER_SPREAD);
|
||||
spread = RQ3_Spread(ent, SNIPER_SPREAD);
|
||||
}
|
||||
Bullet_Fire( ent, spread, SNIPER_DAMAGE, MOD_SNIPER);
|
||||
|
||||
|
@ -1054,7 +1281,7 @@ railgun_fire, old SSG, and bullet_fire code
|
|||
weapon_ssg3000_fire
|
||||
=================
|
||||
*/
|
||||
#define MAX_SSG3000_HITS 4
|
||||
#define MAX_SSG3000_HITS 8
|
||||
void Weapon_SSG3000_Fire (gentity_t *ent) {
|
||||
vec3_t end;
|
||||
trace_t trace;
|
||||
|
@ -1081,7 +1308,7 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
|
|||
spread = 0;
|
||||
}
|
||||
else {
|
||||
spread = RQ3Spread(ent, SNIPER_SPREAD);
|
||||
spread = RQ3_Spread(ent, SNIPER_SPREAD);
|
||||
r = random() * M_PI * 2.0f;
|
||||
u = sin(r) * crandom() * spread * 16;
|
||||
r = cos(r) * crandom() * spread * 16;
|
||||
|
@ -1226,7 +1453,7 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
|
|||
}
|
||||
|
||||
//Elder: bolt action plus save last zoom
|
||||
ent->client->weaponfireNextTime = level.time + RQ3_SSG3000_BOLT_DELAY;
|
||||
//ent->client->weaponfireNextTime = level.time + RQ3_SSG3000_BOLT_DELAY;
|
||||
RQ3_SaveZoomLevel(ent);
|
||||
}
|
||||
|
||||
|
@ -1250,7 +1477,7 @@ void Weapon_MP5_Fire(gentity_t *ent)
|
|||
spread = MP5_SPREAD;
|
||||
}
|
||||
|
||||
Bullet_Fire( ent, RQ3Spread(ent, MP5_SPREAD), MP5_DAMAGE, MOD_MP5);
|
||||
Bullet_Fire( ent, RQ3_Spread(ent, MP5_SPREAD), MP5_DAMAGE, MOD_MP5);
|
||||
|
||||
}
|
||||
/*
|
||||
|
@ -1385,7 +1612,7 @@ void Weapon_Akimbo_Fire(gentity_t *ent)
|
|||
float spread;
|
||||
//Blaze: Will need 2 of these
|
||||
spread = AKIMBO_SPREAD;
|
||||
Bullet_Fire( ent, RQ3Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
|
||||
Bullet_Fire( ent, RQ3_Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
|
||||
|
||||
//Elder: reset plus added 1 bullet check
|
||||
if (ent->client->weaponfireNextTime > 0 || ent->client->ps.ammo[WP_AKIMBO] < 2)
|
||||
|
@ -1393,7 +1620,7 @@ void Weapon_Akimbo_Fire(gentity_t *ent)
|
|||
else
|
||||
ent->client->weaponfireNextTime = level.time + RQ3_AKIMBO_DELAY2;
|
||||
|
||||
//Bullet_Fire( ent, RQ3Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
|
||||
//Bullet_Fire( ent, RQ3_Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -19,6 +19,7 @@ void CheckBleeding(gentity_t *targ)
|
|||
|
||||
if (targ->client->bleed_remain >= BLEED_TIME)
|
||||
{
|
||||
//G_Printf("Bleed Remain: %i\n", targ->client->bleed_remain);
|
||||
if ( (targ->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK &&
|
||||
targ->client->bleedBandageCount < 1)
|
||||
{
|
||||
|
@ -32,7 +33,9 @@ void CheckBleeding(gentity_t *targ)
|
|||
//Elder: hack to count off health so we only lose 6 health on a bandage
|
||||
if ( (targ->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK)
|
||||
{
|
||||
targ->client->bleedBandageCount--;
|
||||
//Start hack enforcement once we've ramped down to 1 health/second
|
||||
if (targ->client->bleed_remain <= 10)
|
||||
targ->client->bleedBandageCount--;
|
||||
}
|
||||
|
||||
if (targ->health <= 0)
|
||||
|
|
Loading…
Reference in a new issue