Bunch of changes related to VM 0-01-xx series (server side)
This commit is contained in:
Victor Chow 2001-06-24 02:08:15 +00:00
parent 942c397d3a
commit c11637d248
13 changed files with 628 additions and 203 deletions

View file

@ -1673,7 +1673,44 @@ static void PM_BeginWeaponChange( int weapon ) {
PM_AddEvent( EV_CHANGE_WEAPON );
pm->ps->weaponstate = WEAPON_DROPPING;
pm->ps->weaponTime += 200;
//pm->ps->weaponTime += 200;
//Elder: dependent time for each weapon
switch (pm->ps->weapon) {
case WP_PISTOL:
pm->ps->weaponTime += RQ3_PISTOL_SWITCH1_DELAY;
break;
case WP_M3:
pm->ps->weaponTime += RQ3_M3_SWITCH1_DELAY;
break;
case WP_M4:
pm->ps->weaponTime += RQ3_M4_SWITCH1_DELAY;
break;
case WP_MP5:
pm->ps->weaponTime += RQ3_MP5_SWITCH1_DELAY;
break;
case WP_HANDCANNON:
pm->ps->weaponTime += RQ3_HANDCANNON_SWITCH1_DELAY;
break;
case WP_SSG3000:
pm->ps->weaponTime += RQ3_SSG3000_SWITCH1_DELAY;
break;
case WP_AKIMBO:
pm->ps->weaponTime += RQ3_AKIMBO_SWITCH1_DELAY;
break;
case WP_KNIFE:
pm->ps->weaponTime += RQ3_KNIFE_SWITCH1_DELAY;
break;
case WP_GRENADE:
pm->ps->weaponTime += RQ3_GRENADE_SWITCH1_DELAY;
break;
default:
//Elder: shouldn't be here
//G_Printf("PM_BeginWeaponChange: received bad weapon %d\n", pm->ps->weapon);
pm->ps->weaponTime += 600;
break;
}
PM_StartTorsoAnim( TORSO_DROP );
}
@ -1699,7 +1736,43 @@ static void PM_FinishWeaponChange( void ) {
pm->ps->weapon = weapon;
pm->ps->weaponstate = WEAPON_RAISING;
pm->ps->weaponTime += 250;
//pm->ps->weaponTime += 250;
//Elder: weapon-dependent timing
switch (pm->ps->weapon) {
case WP_PISTOL:
pm->ps->weaponTime += RQ3_PISTOL_SWITCH2_DELAY;
break;
case WP_M3:
pm->ps->weaponTime += RQ3_M3_SWITCH2_DELAY;
break;
case WP_M4:
pm->ps->weaponTime += RQ3_M4_SWITCH2_DELAY;
break;
case WP_MP5:
pm->ps->weaponTime += RQ3_MP5_SWITCH2_DELAY;
break;
case WP_HANDCANNON:
pm->ps->weaponTime += RQ3_HANDCANNON_SWITCH2_DELAY;
break;
case WP_SSG3000:
pm->ps->weaponTime += RQ3_SSG3000_SWITCH2_DELAY;
break;
case WP_AKIMBO:
pm->ps->weaponTime += RQ3_AKIMBO_SWITCH2_DELAY;
break;
case WP_KNIFE:
pm->ps->weaponTime += RQ3_KNIFE_SWITCH2_DELAY;
break;
case WP_GRENADE:
pm->ps->weaponTime += RQ3_GRENADE_SWITCH2_DELAY;
break;
default:
//Elder: shouldn't be here
//G_Printf("PM_FinishWeaponChange: received bad weapon %d\n", pm->ps->weapon);
pm->ps->weaponTime += 750;
break;
}
PM_StartTorsoAnim( TORSO_RAISE );
}
@ -2239,6 +2312,7 @@ void PmoveSingle (pmove_t *pmove) {
pml.frametime = pml.msec * 0.001;
// update the viewangles
PM_UpdateViewAngles( pm->ps, &pm->cmd );
AngleVectors (pm->ps->viewangles, pml.forward, pml.right, pml.up);

View file

@ -16,12 +16,20 @@
#define RANK_TIED_FLAG 0x4000
//Elder: this are uncertified
#define DEFAULT_SHOTGUN_SPREAD 700
#define DEFAULT_HANDCANNON_SPREAD 1400
#define DEFAULT_SHOTGUN_COUNT 11
//Elder: Q2 shotgun spreads for handcannon
#define DEFAULT_SHOTGUN_HSPREAD 1000
#define DEFAULT_SHOTGUN_VSPREAD 500
#define DEFAULT_M3_HSPREAD 800
#define DEFAULT_M3_VSPREAD 800
//Elder: changed this will affect the cgame entity placement
//Elder: this are uncertified
//#define DEFAULT_SHOTGUN_SPREAD 700
//#define DEFAULT_HANDCANNON_SPREAD 1400
//#define DEFAULT_SHOTGUN_COUNT 11
#define DEFAULT_M3_COUNT 12
#define DEFAULT_HANDCANNON_COUNT 17 //Elder: 17 per blast = 34 per shot
//Elder: changing this will affect the cgame entity placement
#define ITEM_RADIUS 15 // item sizes are needed for client side pickup detection
#define LIGHTNING_RANGE 768
@ -180,28 +188,50 @@
//Elder: reload delays
//Also kinda "derived" from the AQ2 source
#define RQ3_PISTOL_RELOAD_DELAY 1100
#define RQ3_M3_RELOAD_DELAY 1100
#define RQ3_M3_ALLOW_FAST_RELOAD_DELAY 800 // Time into reload to enable fast-reloads
//#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_FAST_RELOAD_DELAY 500 // Fast reload time
#define RQ3_M4_RELOAD_DELAY 1900
#define RQ3_MP5_RELOAD_DELAY 1800
#define RQ3_HANDCANNON_RELOAD_DELAY 2100
#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_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_SSG3000_RELOAD_DELAY 3100
#define RQ3_SSG3000_ALLOW_RELOAD_DELAY 2300 // Time into reload to enable fast-reloads
//#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_ALLOW_FAST_RELOAD_DELAY 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_AKIMBO_RELOAD_DELAY 2500
#define RQ3_KNIFE_RELOAD_DELAY 0 // Elder: shouldn't need
#define RQ3_GRENADE_RELOAD_DELAY 0 // Elder: shouldn't need
//Elder: each weapon also has a different weapon switch delay... ugh
//Elder: each weapon also has a different weapon switch down delay and...
#define RQ3_PISTOL_SWITCH1_DELAY 900 //300
#define RQ3_M3_SWITCH1_DELAY 700 //600
#define RQ3_M4_SWITCH1_DELAY 1000 //500
#define RQ3_MP5_SWITCH1_DELAY 1000 //400
#define RQ3_HANDCANNON_SWITCH1_DELAY 600 //400
#define RQ3_SSG3000_SWITCH1_DELAY 800 //900
#define RQ3_AKIMBO_SWITCH1_DELAY 600 //800
#define RQ3_KNIFE_SWITCH1_DELAY 500 //700
#define RQ3_THROW_SWITCH1_DELAY 500 //700
#define RQ3_GRENADE_SWITCH1_DELAY 500 //300 Elder: I made this up
//Elder: each weapon also has a different weapon switch up delay... ugh bloody hell
#define RQ3_PISTOL_SWITCH2_DELAY 300
#define RQ3_M3_SWITCH2_DELAY 600
#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_AKIMBO_SWITCH2_DELAY 800
#define RQ3_KNIFE_SWITCH2_DELAY 700
#define RQ3_THROW_SWITCH2_DELAY 700
#define RQ3_GRENADE_SWITCH2_DELAY 300 //Elder: I made this up
//Elder: special for grenade: speeds depending on distance select
#define GRENADE_SHORT_SPEED 400

View file

@ -881,7 +881,7 @@ void ThrowWeapon( gentity_t *ent )
//Elder: TODO: have to add a reloading case:
//weaponTime > 0 or weaponState == weapon_dropping? Or both?
//Still firing
if (ucmd->buttons & BUTTON_ATTACK || client->ps.weaponTime > 0) {
if ( (ucmd->buttons & BUTTON_ATTACK) == BUTTON_ATTACK || client->ps.weaponTime > 0) {
return;
}
//Elder: Bandaging case
@ -913,7 +913,7 @@ void ThrowWeapon( gentity_t *ent )
//client->ps.weapon = WP_PISTOL;
//Elder: Don't reset the weapon ammo
//client->ps.ammo[ weap ] = 0;
client->hadUniqueWeapon[weap] = qtrue;
client->pers.hadUniqueWeapon[weap] = qtrue;
trap_SendServerCommand( ent-g_entities, va("selectpistol"));
client->ps.stats[STAT_WEAPONS] &= ~( 1 << weap);
@ -1204,6 +1204,17 @@ void ClientThink_real( gentity_t *ent ) {
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)
ent->client->fastReloads = 0;
if (!ent->client->fastReloads) {
//Elder: For reloading
ent->client->ps.stats[STAT_RQ3] |= ent->client->lastzoom;
ent->client->lastzoom = 0;
}
} */
break;
//case WP_MP5:
case WP_M4:
@ -1434,6 +1445,21 @@ void ClientEndFrame( gentity_t *ent ) {
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK;
}
//Elder: M4 ride-up/kick -- condition for non-burst and ammo only
if ( ent->client->ps.weapon == WP_M4 && ent->client->ps.ammo[WP_M4] > 0 &&
(ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) != RQ3_M4MODE &&
(ent->client->buttons & BUTTON_ATTACK) == BUTTON_ATTACK)
{
//G_Printf("bullets: %d, viewangle: %f\n", ent->client->consecutiveShots, ent->client->ps.viewangles[0]);
ent->client->ps.delta_angles[0] = ANGLE2SHORT(ent->client->consecutiveShots * -0.7);
}
else
{
ent->client->ps.delta_angles[0] = 0;
ent->client->consecutiveShots = 0;
}
G_SetClientSound (ent);
// set the latest infor

View file

@ -1041,7 +1041,7 @@ void ClientSpawn(gentity_t *ent) {
char userinfo[MAX_INFO_STRING];
//To save the ammo stuff
qboolean hadUniqueWeapon[MAX_WEAPONS];
//qboolean hadUniqueWeapon[MAX_WEAPONS];
index = ent - g_entities;
client = ent->client;
@ -1105,9 +1105,9 @@ void ClientSpawn(gentity_t *ent) {
accuracy_shots = client->accuracy_shots;
//Elder: save unique weapon info
for ( i = 0 ; i < MAX_WEAPONS ; i++ ) {
hadUniqueWeapon[i] = client->hadUniqueWeapon[i];
}
//for ( i = 0 ; i < MAX_WEAPONS ; i++ ) {
//hadUniqueWeapon[i] = client->hadUniqueWeapon[i];
//}
for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
persistant[i] = client->ps.persistant[i];
@ -1129,9 +1129,9 @@ void ClientSpawn(gentity_t *ent) {
client->lastkilled_client = -1;
//Elder: restore unique weapon info
for ( i = 0 ; i < MAX_WEAPONS ; i++ ) {
client->hadUniqueWeapon[i] = hadUniqueWeapon[i];
}
//for ( i = 0 ; i < MAX_WEAPONS ; i++ ) {
//client->hadUniqueWeapon[i] = hadUniqueWeapon[i];
//}
for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
client->ps.persistant[i] = persistant[i];
@ -1249,12 +1249,17 @@ void ClientSpawn(gentity_t *ent) {
//Elder: reset isBandaging flag
//client->isBandaging = qfalse;
//Elder: reset all RQ3 non-persistent stats
ent->client->ps.stats[STAT_RQ3] = 0;
//Elder: set weaponfireNextTime amount
client->weaponfireNextTime = 0;
//Elder: Initialize fast reloads stuff
client->fastReloads = 0;
client->lastReloadTime = 0;
//Elder: initialize consecutive shots for M4 ride-up
client->consecutiveShots = 0;
// set default animations
client->ps.torsoAnim = TORSO_STAND;

View file

@ -49,6 +49,29 @@ void DeathmatchScoreboardMessage( gentity_t *ent ) {
}
perfect = ( cl->ps.persistant[PERS_RANK] == 0 && cl->ps.persistant[PERS_KILLED] == 0 ) ? 1 : 0;
//Blaze: Removed because it uses the persistant stats stuff
//Elder: played around with it...
//G_Printf("Clientnum: %d\n", level.sortedClients[i]);
Com_sprintf (entry, sizeof(entry),
" %i %i %i %i %i %i %i %i %i %i %i %i %i %i", level.sortedClients[i],
cl->ps.persistant[PERS_SCORE], ping, (level.time - cl->pers.enterTime)/60000,
scoreFlags, g_entities[level.sortedClients[i]].s.powerups, accuracy,
0,
0,
0,
0,
0,
0,
0);
//cl->ps.persistant[PERS_IMPRESSIVE_COUNT],
//cl->ps.persistant[PERS_EXCELLENT_COUNT],
//cl->ps.persistant[PERS_GAUNTLET_FRAG_COUNT],
//cl->ps.persistant[PERS_DEFEND_COUNT],
//cl->ps.persistant[PERS_ASSIST_COUNT],
//perfect,
//cl->ps.persistant[PERS_CAPTURES]);
/* Com_sprintf (entry, sizeof(entry),
" %i %i %i %i %i %i %i %i %i %i %i %i %i %i", level.sortedClients[i],
cl->ps.persistant[PERS_SCORE], ping, (level.time - cl->pers.enterTime)/60000,
@ -1685,138 +1708,288 @@ void Cmd_Reload( gentity_t *ent ) {
ent->client->ps.stats[STAT_WEAPONS], WP_KNIFE, WP_PISTOL, WP_M4, WP_SSG3000,
WP_MP5, WP_M3, WP_HANDCANNON, WP_AKIMBO, WP_GRENADE);
*/
switch(weapon) {
case WP_KNIFE:
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
break;
case WP_PISTOL:
delay = RQ3_PISTOL_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_PISTOL_AMMO)
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
//Elder: was missing?
case WP_M4:
delay = RQ3_M4_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_M4_AMMO)
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
case WP_M3:
ammotoadd += ent->client->ps.ammo[weapon];
//Elder: temporarily using fast-loads
delay = RQ3_M3_FAST_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_M3_AMMO)
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
case WP_HANDCANNON:
delay = RQ3_HANDCANNON_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_HANDCANNON_AMMO) {
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
case WP_SSG3000:
//Elder: temporarily using fast-loads
delay = RQ3_SSG3000_FAST_RELOAD_DELAY;
ammotoadd += ent->client->ps.ammo[weapon];
if (ent->client->ps.ammo[weapon] >= RQ3_SSG3000_AMMO) {
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
case WP_AKIMBO:
delay = RQ3_AKIMBO_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_AKIMBO_AMMO) {
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
case WP_MP5:
delay = RQ3_MP5_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_MP5_AMMO)
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
default:
//Elder: shouldn't be here
delay = 2500;
//Elder: changed function
if (ent->client->ps.ammo[weapon] >= ClipAmountForAmmo(weapon))
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
}
//Elder: added handcannon and akimbo conditional
if (ent->client->numClips[weapon] == 0) {
trap_SendServerCommand( ent-g_entities, va("print \"Out of ammo\n\""));
switch(weapon) {
case WP_KNIFE:
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
break;
case WP_PISTOL:
if (ent->client->ps.ammo[weapon] >= RQ3_PISTOL_AMMO)
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
delay = RQ3_PISTOL_RELOAD_DELAY;
break;
//Elder: was missing?
case WP_M4:
if (ent->client->ps.ammo[weapon] >= RQ3_M4_AMMO)
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
delay = RQ3_M4_RELOAD_DELAY;
break;
case WP_M3:
ammotoadd += ent->client->ps.ammo[weapon];
//Check to see if fastReloads is stale
if (level.time - ent->client->lastReloadTime > RQ3_M3_RELOAD_DELAY)
ent->client->fastReloads = 0;
if (ent->client->ps.ammo[weapon] >= RQ3_M3_AMMO)
{
//reset fast reloads
ent->client->fastReloads = 0;
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
//Check if it's already reloading
//ent->client->ps.weaponstate == WEAPON_RELOADING
if (ent->client->ps.weaponstate == WEAPON_DROPPING && ent->client->numClips[WP_M3] > 0)
{
/*
G_Printf("Time index: %d, FastReload- VirginStart: %d, WindowStart: %d, WindowEnd: %d\n",
level.time - ent->client->lastReloadTime,
RQ3_M3_ALLOW_FAST_RELOAD_DELAY,
RQ3_M3_FAST_RELOAD_DELAY,
RQ3_M3_RELOAD_DELAY);
*/
//Have we fast reloaded before?
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
//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)
{
//gotcha
ent->client->fastReloads = 1;
}
else
{
//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;
}
else
{
//not enough time has passed for a fast reload attempt
//so discard the attempt
//G_Printf("Too soon: Discarded fast-reload attempt\n");
return;
}
}
//check for fast reloads
if (ent->client->fastReloads) {
//Fast reload
G_Printf("Using fast reloads\n");
delay = RQ3_M3_FAST_RELOAD_DELAY;
ent->client->fastReloads = 1;
}
else {
//Regular reload
G_Printf("Using regular reloads\n");
delay = RQ3_M3_RELOAD_DELAY;
ent->client->fastReloads = 0;
}
ent->client->lastReloadTime = level.time;
break;
case WP_HANDCANNON:
delay = RQ3_HANDCANNON_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_HANDCANNON_AMMO) {
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
case WP_SSG3000:
ammotoadd += ent->client->ps.ammo[weapon];
//Check to see if fastReloads is stale
if (level.time - ent->client->lastReloadTime > RQ3_SSG3000_RELOAD_DELAY)
ent->client->fastReloads = 0;
if (ent->client->ps.ammo[weapon] >= RQ3_SSG3000_AMMO)
{
//reset fast reloads
ent->client->fastReloads = 0;
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
//Check if it's already reloading
//ent->client->ps.weaponstate == WEAPON_RELOADING
if (ent->client->ps.weaponstate == WEAPON_DROPPING && ent->client->numClips[WP_SSG3000] > 0)
{
/*
G_Printf("Time index: %d, FastReload- VirginStart: %d, WindowStart: %d, WindowEnd: %d\n",
level.time - ent->client->lastReloadTime,
RQ3_SSG3000_ALLOW_FAST_RELOAD_DELAY,
RQ3_SSG3000_FAST_RELOAD_DELAY,
RQ3_SSG3000_RELOAD_DELAY);
*/
//Have we fast reloaded before?
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
//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)
{
//gotcha
ent->client->fastReloads = 1;
}
else
{
//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;
}
else
{
//not enough time has passed for a fast reload attempt
//so discard the attempt
//G_Printf("Too soon: Discarded fast-reload attempt\n");
return;
}
}
//check for fast reloads
if (ent->client->fastReloads) {
//Fast reload
G_Printf("Using fast reloads\n");
delay = RQ3_SSG3000_FAST_RELOAD_DELAY;
ent->client->fastReloads = 1;
}
else {
//Regular reload
G_Printf("Using regular reloads\n");
delay = RQ3_SSG3000_RELOAD_DELAY;
ent->client->fastReloads = 0;
}
ent->client->lastReloadTime = level.time;
break;
case WP_AKIMBO:
delay = RQ3_AKIMBO_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_AKIMBO_AMMO) {
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
case WP_MP5:
delay = RQ3_MP5_RELOAD_DELAY;
if (ent->client->ps.ammo[weapon] >= RQ3_MP5_AMMO)
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
default:
//Elder: shouldn't be here
delay = 2500;
//Elder: changed function
if (ent->client->ps.ammo[weapon] >= ClipAmountForAmmo(weapon))
{
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
return;
}
break;
}
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\""));
return;
}
//Elder: added handcannon and akimbo conditional
if (ent->client->numClips[weapon] == 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\""));
return;
}
//Save once only
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.weaponstate = WEAPON_RELOADING;
ent->client->ps.weaponstate = WEAPON_DROPPING;
ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT )
^ ANIM_TOGGLEBIT ) | TORSO_DROP;
ent->client->ps.weaponTime += delay;
//ent->client->ps.weaponstate = WEAPON_RELOADING;
ent->client->ps.weaponstate = WEAPON_DROPPING;
ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT )
^ ANIM_TOGGLEBIT ) | TORSO_DROP;
ent->client->ps.weaponTime += delay;
// add ammo to weapon
//Elder: at this point there should be sufficient ammo requirements to reload
if (ent->client->numClips[weapon] > 0) {
//Elder: more attempts to synchronize the mk23 and akimbos
if (weapon == WP_PISTOL && (ent->client->ps.stats[STAT_WEAPONS] & (1 << WP_AKIMBO) ) ) {
ent->client->ps.ammo[WP_AKIMBO] = ent->client->ps.ammo[WP_AKIMBO] - ent->client->ps.ammo[WP_PISTOL] + ammotoadd;
if (ent->client->ps.ammo[WP_AKIMBO] > RQ3_AKIMBO_AMMO) {
ent->client->ps.ammo[WP_AKIMBO] = RQ3_AKIMBO_AMMO;
}
}
else if (weapon == WP_AKIMBO) {
//Elder: refill the MK23 as well
ent->client->ps.ammo[WP_PISTOL] = RQ3_PISTOL_AMMO;
}
ent->client->ps.ammo[weapon] = ammotoadd;
ent->client->numClips[weapon]--;
//Elder: remove an extra "clip" if it's the handcannon or akimbo
if (weapon == WP_HANDCANNON || weapon == WP_AKIMBO)
ent->client->numClips[weapon]--;
//Elder: sync hc and m3 ammo + mk23 and akimbo ammo - a switch might look nicer
if (weapon == WP_M3) {
ent->client->numClips[WP_HANDCANNON] = ent->client->numClips[WP_M3];
}
else if (weapon == WP_HANDCANNON) {
ent->client->numClips[WP_M3] = ent->client->numClips[WP_HANDCANNON];
}
else if(weapon == WP_PISTOL) {
ent->client->numClips[WP_AKIMBO] = ent->client->numClips[WP_PISTOL];
}
else if (weapon == WP_AKIMBO) {
ent->client->numClips[WP_PISTOL] = ent->client->numClips[WP_AKIMBO];
//Elder: at this point there should be sufficient ammo requirements to reload
if (ent->client->numClips[weapon] > 0) {
//Elder: more attempts to synchronize the mk23 and akimbos
if (weapon == WP_PISTOL && (ent->client->ps.stats[STAT_WEAPONS] & (1 << WP_AKIMBO) ) ) {
ent->client->ps.ammo[WP_AKIMBO] = ent->client->ps.ammo[WP_AKIMBO] - ent->client->ps.ammo[WP_PISTOL] + ammotoadd;
if (ent->client->ps.ammo[WP_AKIMBO] > RQ3_AKIMBO_AMMO) {
ent->client->ps.ammo[WP_AKIMBO] = RQ3_AKIMBO_AMMO;
}
}
else if (weapon == WP_AKIMBO) {
//Elder: refill the MK23 as well
ent->client->ps.ammo[WP_PISTOL] = RQ3_PISTOL_AMMO;
}
// add ammo to weapon
ent->client->ps.ammo[weapon] = ammotoadd;
ent->client->numClips[weapon]--;
//Elder: remove an extra "clip" if it's the handcannon or akimbo
if (weapon == WP_HANDCANNON || weapon == WP_AKIMBO)
ent->client->numClips[weapon]--;
//Elder: sync hc and m3 ammo + mk23 and akimbo ammo - a switch might look nicer
if (weapon == WP_M3) {
ent->client->numClips[WP_HANDCANNON] = ent->client->numClips[WP_M3];
}
else if (weapon == WP_HANDCANNON) {
ent->client->numClips[WP_M3] = ent->client->numClips[WP_HANDCANNON];
}
else if(weapon == WP_PISTOL) {
ent->client->numClips[WP_AKIMBO] = ent->client->numClips[WP_PISTOL];
}
else if (weapon == WP_AKIMBO) {
ent->client->numClips[WP_PISTOL] = ent->client->numClips[WP_AKIMBO];
}
}
}
/*
==================
ClipAmountForWeapon for Cmd_Reload
@ -1900,6 +2073,10 @@ void Cmd_Weapon(gentity_t *ent)
return;
}
//Can't reload while firing
if ( ent->client->ps.weaponTime > 0)
return;
//Elder: added brackets, and-ops and not-ops instead of logical ops
switch(ent->s.weapon){
case WP_SSG3000:

View file

@ -112,35 +112,35 @@ void TossClientItems( gentity_t *self ) {
if ( (weaponInventory & (1 << WP_M3) ) == (1 << WP_M3) ) {
item = BG_FindItemForWeapon( WP_M3 );
Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_M3 ] = qfalse;
self->client->pers.hadUniqueWeapon[ WP_M3 ] = qfalse;
angle += 30;
}
if ( (weaponInventory & (1 << WP_M4) ) == (1 << WP_M4) ) {
item = BG_FindItemForWeapon( WP_M4 );
Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_M4 ] = qfalse;
self->client->pers.hadUniqueWeapon[ WP_M4 ] = qfalse;
angle += 30;
}
if ( (weaponInventory & (1 << WP_MP5) ) == (1 << WP_MP5) ) {
item = BG_FindItemForWeapon( WP_MP5 );
Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_MP5 ] = qfalse;
self->client->pers.hadUniqueWeapon[ WP_MP5 ] = qfalse;
angle += 30;
}
if ( (weaponInventory & (1 << WP_HANDCANNON) ) == (1 << WP_HANDCANNON) ) {
item = BG_FindItemForWeapon( WP_HANDCANNON );
Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_HANDCANNON ] = qfalse;
self->client->pers.hadUniqueWeapon[ WP_HANDCANNON ] = qfalse;
angle += 30;
}
if ( (weaponInventory & (1 << WP_SSG3000) ) == (1 << WP_SSG3000) ) {
item = BG_FindItemForWeapon( WP_SSG3000 );
Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_SSG3000 ] = qfalse;
self->client->pers.hadUniqueWeapon[ WP_SSG3000 ] = qfalse;
angle += 30;
}

View file

@ -389,13 +389,17 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
break;
}
//Elder: conditional added to "restore" weapons
if ( other->client->hadUniqueWeapon[ent->item->giTag] == qfalse ||
if ( other->client->pers.hadUniqueWeapon[ent->item->giTag] == qfalse ||
!((ent->flags & FL_THROWN_ITEM) == FL_THROWN_ITEM) ) {
other->client->ps.ammo[ent->item->giTag]= ammotoadd;
//Elder: add extra handcannon clips if it's "fresh"
if (ent->item->giTag == WP_HANDCANNON) {
other->client->numClips[ WP_HANDCANNON ] += 5;
other->client->numClips[ WP_M3 ] += 5;
if (other->client->numClips[ WP_HANDCANNON ] > 13) {
other->client->numClips[ WP_HANDCANNON ] = 14;
other->client->numClips[ WP_M3 ] = 14;
}
}
}
@ -880,7 +884,7 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity, int xr_fla
G_SetOrigin( dropped, origin );
//reset back the dropped item case
dropped->flags = FL_DROPPED_ITEM;
//dropped->flags = FL_DROPPED_ITEM;
//dropped->s.eFlags |= EF_BOUNCE_HALF;
}
else {

View file

@ -64,8 +64,8 @@ typedef enum {
#define RQ3_RESPAWNTIME_DEFAULT 60000 // Elder: time for weapons to respawn - up to 60s
#define SP_AUTOOPEN 128 // Elder: revert to Q3 behaviour
#define SP_DOORTOGGLE 256 // Elder: added to enable mover toggling
#define SP_AUTOOPEN 4 // Elder: revert to Q3 behaviour
#define SP_DOORTOGGLE 8 // Elder: added to enable mover toggling
//============================================================================
@ -259,6 +259,7 @@ typedef struct {
int voteCount; // to prevent people from constantly calling votes
int teamVoteCount; // to prevent people from constantly calling votes
qboolean teamInfo; // send team overlay updates?
qboolean hadUniqueWeapon[MAX_WEAPONS]; //Elder: for "ammo" in last gun
} clientPersistant_t;
@ -356,14 +357,15 @@ struct gclient_s {
//qboolean isBandaging; //Elder: player in the process of bandaging
// end Homer
//Elder: prep for "ammo" in last gun
//Only the server needs to know this
qboolean hadUniqueWeapon[MAX_WEAPONS];
//Elder: added for 3rb and akimbos
int weaponfireNextTime; //for akimbos and burst modes
int lastzoom; // Elder: save last zoom state when firing
int fastReloads; //Elder: for queuing M3/SSG reloads
int lastReloadTime; //Elder: for queuing M3/SSG reloads
int consecutiveShots; //Elder: for M4 ride-up/kick
#ifdef MISSIONPACK
gentity_t *persistantPowerup;
int portalID;
@ -550,6 +552,9 @@ gentity_t *G_TempEntity( vec3_t origin, int event );
gentity_t *G_TempEntity2( vec3_t origin, int event, int eParm );
void G_Sound( gentity_t *ent, int channel, int soundIndex );
void G_FreeEntity( gentity_t *e );
//Elder: added
void RQ3_SaveZoomLevel ( gentity_t *ent );
int RQ3_isZoomed ( gentity_t *ent );
qboolean G_EntitiesFree( void );

View file

@ -453,7 +453,7 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
}
else {
//leave embedded in the wall
xr_drop = LaunchItem(xr_item, trace->endpos, 0, FL_THROWN_KNIFE);
xr_drop = LaunchItem(xr_item, trace->endpos, 0, FL_THROWN_KNIFE|FL_DROPPED_ITEM);
VectorClear( xr_drop->s.pos.trDelta );
//Elder: make the knife stick out a bit more

View file

@ -994,7 +994,9 @@ void Blocked_Door( gentity_t *ent, gentity_t *other ) {
if ( ent->damage ) {
G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH );
}
if ( ent->spawnflags & 4 ) {
//if ( ent->spawnflags & 4 ) {
//Elder: new crusher flag
if ( ent->spawnflags & 2 ) {
return; // crushers don't reverse
}
@ -1137,7 +1139,7 @@ NOMONSTER monsters will not trigger this door
//Elder: new one from GTKRadiant's entity.def plus Reaction stuff
/*QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER x x x x AUTOOPEN TOGGLE
/*QUAKED func_door (0 .5 .8) ? START_OPEN CRUSHER AUTO_OPEN TOGGLE
Normal sliding door entity. By default, the door will activate when player walks close to it or when damage is inflicted to it.
-------- KEYS --------
angle : determines the opening direction of door (up = -1, down = -2).
@ -1155,14 +1157,14 @@ origin : alternate method of setting XYZ origin of .md3 model included with enti
notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
soundstart : path to sound file to play when door starts to open
soundstop : path to sound file to play when door comes to a stop
soundmove : path to sound file to play when door is moving
-------- SPAWNFLAGS --------
START_OPEN : the door will spawn in the open state and operate in reverse.
CRUSHER : door will not reverse direction when blocked and will keep damaging player until he dies or gets out of the way.
TOGGLE : door requires an opendoor toggle to work
TOGGLE : door requires an opendoor toggle to open or close
AUTOOPEN : door will open like traditional Q3 doors (like a motion sensor)
Setting AUTOOPEN will make the doors act like traditional Q3A doors
-------- NOTES --------
Unlike in Quake 2, doors that touch are NOT automatically teamed. If you want doors to operate together, you have to team them manually by assigning the same team name to all of them. Setting the origin key is simply an alternate method to using an origin brush. When using the model2 key, the origin point of the model will correspond to the origin point defined by either the origin brush or the origin coordinate value.*/
void SP_func_door (gentity_t *ent) {
@ -1173,22 +1175,33 @@ void SP_func_door (gentity_t *ent) {
//Elder: added
char *sSndMove;
char *sSndStop;
char *sSndStart;
//Elder: can set sounds from here?
//G_SpawnString( "soundmove", "sound/movers/doors/dr1_strt.wav", &sSndMove );
//G_SpawnString( "soundstop", "sound/movers/doors/dr1_end.wav", &sSndStop );
ent->sound1to2 = ent->sound2to1 = G_SoundIndex("sound/movers/doors/dr1_strt.wav");
ent->soundPos1 = ent->soundPos2 = G_SoundIndex("sound/movers/doors/dr1_end.wav");
//Elder: can set sounds from here
G_SpawnString( "soundstart", "sound/movers/doors/dr1_strt.wav", &sSndStart );
G_SpawnString( "soundstop", "sound/movers/doors/dr1_end.wav", &sSndStop );
G_SpawnString( "soundmove", "sound/movers/doors/dr1_strt.wav", &sSndMove );
ent->sound1to2 = ent->sound2to1 = G_SoundIndex(sSndMove);
ent->soundPos1 = G_SoundIndex(sSndStart);
ent->soundPos2 = G_SoundIndex(sSndStop);
//ent->sound1to2 = ent->sound2to1 = G_SoundIndex("sound/movers/doors/dr1_strt.wav");
//ent->soundPos1 = ent->soundPos2 = G_SoundIndex("sound/movers/doors/dr1_end.wav");
ent->blocked = Blocked_Door;
//Elder: added for debugging purposes but doesn't show up (DOH)
/*
if ( (ent->spawnflags & 1) == 1)
G_Printf("func_door Starting Open\n");
if ( (ent->spawnflags & 4) == 4)
if ( (ent->spawnflags & 2) == 2)
G_Printf("func_door CRUSHER\n");
if ( (ent->spawnflags & SP_DOORTOGGLE) == SP_DOORTOGGLE)
G_Printf("func_door is a Toggle\n");
if ( (ent->spawnflags & SP_AUTOOPEN) == SP_AUTOOPEN)
G_Printf("func_door is an auto-open\n");
*/
// default speed of 400
if (!ent->speed)
@ -1251,7 +1264,7 @@ void SP_func_door (gentity_t *ent) {
// REACTION
/*QUAKED func_door_rotating (0 .5 .8) START_OPEN REVERSE TOGGLE X_AXIS Y_AXIS
/*QUAKED func_door_rotating (0 .5 .8) START_OPEN CRUSHER AUTO_OPEN TOGGLE X_AXIS Y_AXIS
This is the rotating door... just as the name suggests it's a door that rotates
START_OPEN the door to moves to its destination when spawned, and operate in reverse.
REVERSE if you want the door to open in the other direction, use this switch.
@ -1268,18 +1281,36 @@ check either the X_AXIS or Y_AXIS box to change that.
"speed" how fast the door will open (degrees/second)
"color" constantLight color
"light" constantLight radius
soundstart : path to sound file to play when door starts to open
soundstop : path to sound file to play when door comes to a stop
soundmove : path to sound file to play when door is moving
*/
void SP_func_door_rotating ( gentity_t *ent ) {
ent->sound1to2 = ent->sound2to1 = G_SoundIndex("sound/movers/doors/dr1_strt.wav");
ent->soundPos1 = ent->soundPos2 = G_SoundIndex("sound/movers/doors/dr1_end.wav");
//Elder: added
char *sSndMove;
char *sSndStop;
char *sSndStart;
//Elder: can set sounds from here
G_SpawnString( "soundstart", "sound/movers/doors/dr1_strt.wav", &sSndStart );
G_SpawnString( "soundstop", "sound/movers/doors/dr1_end.wav", &sSndStop );
G_SpawnString( "soundmove", "sound/movers/doors/dr1_strt.wav", &sSndMove );
ent->sound1to2 = ent->sound2to1 = G_SoundIndex(sSndMove);
ent->soundPos1 = G_SoundIndex(sSndStart);
ent->soundPos2 = G_SoundIndex(sSndStop);
//ent->sound1to2 = ent->sound2to1 = G_SoundIndex("sound/movers/doors/dr1_strt.wav");
//ent->soundPos1 = ent->soundPos2 = G_SoundIndex("sound/movers/doors/dr1_end.wav");
ent->blocked = Blocked_Door;
// default speed of 120
if (!ent->speed)
ent->speed = 120;
/*
if ( ent->spawnflags & 1)
G_Printf("rotating door Starting Open\n");
if ( ent->spawnflags & 2)
@ -1290,13 +1321,15 @@ void SP_func_door_rotating ( gentity_t *ent ) {
G_Printf("rotating door on X_AXIS\n");
if ( ent->spawnflags & 16)
G_Printf("rotating door on Y_AXIS\n");
*/
// if speed is negative, positize it and add reverse flag
// Elder: handled below in reverse direction
/*
if ( ent->speed < 0 ) {
ent->speed *= -1;
ent->spawnflags |= 2;
}
}*/
// default of 2 seconds
if (!ent->wait)
@ -1307,17 +1340,21 @@ void SP_func_door_rotating ( gentity_t *ent ) {
VectorClear( ent->movedir );
VectorClear( ent->s.angles );
if ( ent->spawnflags & 8 ) {
//Elder: changed from 8 - 16 and 16 - 32 respectively
if ( ent->spawnflags & 16 ) {
ent->movedir[2] = 1.0;
} else if ( ent->spawnflags & 16 ) {
} else if ( ent->spawnflags & 32 ) {
ent->movedir[0] = 1.0;
} else {
ent->movedir[1] = 1.0;
}
// reverse direction if necessary
if ( ent->spawnflags & 2 )
//if ( ent->spawnflags & 2 )
if (ent->speed < 0) {
ent->speed *= -1;
VectorNegate ( ent->movedir, ent->movedir );
}
// default distance of 90 degrees. This is something the mapper should not
// leave out, so we'll tell him if he does.

View file

@ -211,7 +211,9 @@ void Use_target_push( gentity_t *self, gentity_t *other, gentity_t *activator )
// play fly sound every 1.5 seconds
if ( activator->fly_sound_debounce_time < level.time ) {
activator->fly_sound_debounce_time = level.time + 1500;
G_Sound( activator, CHAN_AUTO, self->noise_index );
//Elder: added to check noise_index
if (self->noise_index)
G_Sound( activator, CHAN_AUTO, self->noise_index );
}
}

View file

@ -699,3 +699,42 @@ gentity_t *findradius (gentity_t *from, vec3_t org, float rad)
return NULL;
}
/*
================
Added by Elder
RQ3_SaveZoomLevel
Quick function to save the last zoom setting
================
*/
void RQ3_SaveZoomLevel( gentity_t *ent ) {
if (ent->client) {
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW)
ent->client->lastzoom |= RQ3_ZOOM_LOW;
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_MED) == RQ3_ZOOM_MED)
ent->client->lastzoom |= RQ3_ZOOM_MED;
}
}
/*
================
Added by Elder
RQ3_isZoomed
Quick function to determine if player is zoomed in
================
*/
int RQ3_isZoomed( gentity_t *ent ) {
if (!ent->client) {
G_Error( "RQ3_isZoomed: passed non-client entity" );
return -1;
}
else {
return ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW ||
(ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_MED) == RQ3_ZOOM_MED);
}
}

View file

@ -318,7 +318,7 @@ qboolean ShotgunPellet( vec3_t start, vec3_t end, gentity_t *ent ) {
}
// this should match CG_ShotgunPattern
void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent, qboolean ism3 ) {
void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent, int shotType ) {
int i;
float r, u;
vec3_t end;
@ -326,6 +326,10 @@ void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent, qb
int oldScore;
qboolean hitClient = qfalse;
//Elder: added
int count;
int hc_multipler;
// derive the right and up vectors from the forward vector, because
// the client won't have any other information
VectorNormalize2( origin2, forward );
@ -334,17 +338,34 @@ void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent, qb
oldScore = ent->client->ps.persistant[PERS_SCORE];
//Elder: added
if (shotType == WP_M3)
count = DEFAULT_M3_COUNT;
else if (shotType == WP_HANDCANNON) {
count = DEFAULT_HANDCANNON_COUNT;
hc_multipler = 4;
}
else {
count = DEFAULT_HANDCANNON_COUNT;
hc_multipler = 5;
}
// generate the "random" spread pattern
for ( i = 0 ; i < DEFAULT_SHOTGUN_COUNT ; i++ ) {
if (ism3)
for ( i = 0 ; i < count ; i++ ) {
if (shotType == WP_M3)
{
r = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
u = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
r = Q_crandom( &seed ) * DEFAULT_M3_HSPREAD * 16;
u = Q_crandom( &seed ) * DEFAULT_M3_VSPREAD * 16;
//r = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
//u = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
}
else
{
r = Q_crandom( &seed ) * DEFAULT_HANDCANNON_SPREAD * 16 * 4;
u = Q_crandom( &seed ) * DEFAULT_HANDCANNON_SPREAD * 16 * 4;
r = Q_crandom( &seed ) * DEFAULT_SHOTGUN_HSPREAD * 16 * 4;
u = Q_crandom( &seed ) * DEFAULT_SHOTGUN_VSPREAD * 16 * hc_multipler;
//r = Q_crandom( &seed ) * DEFAULT_HANDCANNON_SPREAD * 16 * 4;
//u = Q_crandom( &seed ) * DEFAULT_HANDCANNON_SPREAD * 16 * 4;
}
VectorMA( origin, 8192 * 16, forward, end);
@ -368,7 +389,8 @@ void weapon_supershotgun_fire (gentity_t *ent) {
tent->s.eventParm = rand() & 255; // seed for spread pattern
tent->s.otherEntityNum = ent->s.number;
ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent, qtrue );
//Elder: removed for now
//ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent, qtrue );
}
@ -944,7 +966,13 @@ void Weapon_M4_Fire(gentity_t *ent)
else
{
spread = M4_SPREAD;
//M4-kick stuff
ent->client->consecutiveShots++;
if (ent->client->consecutiveShots > 23)
ent->client->consecutiveShots = 23;
}
Bullet_Fire( ent, RQ3Spread(ent, M4_SPREAD), M4_DAMAGE, MOD_M4);
/*
@ -994,8 +1022,9 @@ void Weapon_SSG3000_Fire(gentity_t *ent)
//G_Printf("Zoom Level: %d\n", ent->client->zoomed);
//Elder: changed to use RQ3Spread 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) {
//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) {
if (RQ3_isZoomed(ent)) {
spread = 0;
}
else {
@ -1005,11 +1034,7 @@ void Weapon_SSG3000_Fire(gentity_t *ent)
//Elder: bolt action plus save last zoom
ent->client->weaponfireNextTime = level.time + RQ3_SSG3000_BOLT_DELAY;
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW)
ent->client->lastzoom |= RQ3_ZOOM_LOW;
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_MED) == RQ3_ZOOM_MED)
ent->client->lastzoom |= RQ3_ZOOM_MED;
RQ3_SaveZoomLevel(ent);
}
/*
@ -1049,7 +1074,7 @@ void Weapon_HandCannon_Fire(gentity_t *ent)
SnapVector( tent->s.origin2 );
tent->s.eventParm = rand() & 255; // seed for spread pattern
tent->s.otherEntityNum = ent->s.number;
ShotgunPattern(tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent,qfalse );
ShotgunPattern(tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent, WP_HANDCANNON );
// send shotgun blast
tent2 = G_TempEntity( muzzle, EV_HANDCANNON );
@ -1058,7 +1083,8 @@ void Weapon_HandCannon_Fire(gentity_t *ent)
tent2->s.eventParm = rand() & 255; // seed for spread pattern
tent2->s.otherEntityNum = ent->s.number;
tent2->s.angles2[1] += 20;
ShotgunPattern(tent2->s.pos.trBase, tent2->s.origin2, tent2->s.eventParm, ent,qfalse );
//Elder: note negative one
ShotgunPattern(tent2->s.pos.trBase, tent2->s.origin2, tent2->s.eventParm, ent, -1 );
}
/*
@ -1078,7 +1104,7 @@ void Weapon_M3_Fire(gentity_t *ent)
tent->s.eventParm = rand() & 255; // seed for spread pattern
tent->s.otherEntityNum = ent->s.number;
ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent, qtrue );
ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent, WP_M3 );
}
/*