mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2025-03-27 12:51:13 +00:00
Elder:
Bunch of changes related to VM 0-01-xx series (server side)
This commit is contained in:
parent
942c397d3a
commit
c11637d248
13 changed files with 628 additions and 203 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue