Reworking the sniper zoom and bandage required extensive server changes
to fit the new model.  Also made various fixes.
This commit is contained in:
Victor Chow 2001-06-18 01:59:58 +00:00
parent 3fe61cd477
commit b37c00c9d0
12 changed files with 411 additions and 115 deletions

View file

@ -939,8 +939,12 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
switch( item->giType ) { switch( item->giType ) {
case IT_WEAPON: case IT_WEAPON:
return qtrue; // weapons are always picked up //Elder: gotta check before we can pick it up
//if (item->giTag == WP_KNIFE && ps->ammo[WP_KNIFE] >= RQ3_KNIFE_MAXCLIP)
//return qfalse;
//else
return qtrue; // weapons are always picked up
case IT_AMMO: case IT_AMMO:
//Blaze: pick up all ammo //Blaze: pick up all ammo

View file

@ -882,7 +882,7 @@ static void PM_WalkMove( void ) {
return; return;
} }
*/ */
//Blaze: Cant jump while someone has leg damage //Blaze: Cant jump while someone has leg damage
if ( !((pm->ps->stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE) && PM_CheckJump () ) { if ( !((pm->ps->stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE) && PM_CheckJump () ) {
// jumped away // jumped away
if ( pm->waterlevel > 1 ) { if ( pm->waterlevel > 1 ) {
@ -1810,7 +1810,14 @@ static void PM_Weapon( void ) {
pm->ps->weaponTime = 0; pm->ps->weaponTime = 0;
pm->ps->weaponstate = WEAPON_READY; pm->ps->weaponstate = WEAPON_READY;
// Homer: not firing, reset burst value (cheaper than a non-zero check) // Homer: not firing, reset burst value (cheaper than a non-zero check)
pm->ps->stats[STAT_BURST] = 0; //Elder: reset only if the max amount has been shot
//if ( pm->ps->weapon == WP_PISTOL) {
pm->ps->stats[STAT_BURST] = 0;
//}
//else if ( ( pm->ps->weapon == WP_M4 && pm->ps->stats[STAT_BURST] > 2 ) ||
//( pm->ps->weapon == WP_MP5 && pm->ps->stats[STAT_BURST] > 2 ) ) {
//pm->ps->stats[STAT_BURST] = 0;
//}
return; return;
} }
@ -1880,41 +1887,40 @@ static void PM_Weapon( void ) {
switch( pm->ps->weapon ) { switch( pm->ps->weapon ) {
default: default:
//Blaze: Reaction Sniper Rifle delay //Elder: weapon delay times using constants
case WP_SSG3000: case WP_SSG3000:
addTime = 1500; addTime = RQ3_SSG3000_DELAY;
break; break;
//Blaze: Reaction Pistol delay
case WP_PISTOL: case WP_PISTOL:
addTime = 500; addTime = RQ3_PISTOL_DELAY;
break; break;
//Blaze: Reaction M4 fire delay
case WP_M4: case WP_M4:
addTime = 80;//refire time addTime = RQ3_M4_DELAY;
break; break;
//Blaze: Reaction MP5 fire delay
case WP_MP5: case WP_MP5:
addTime = 100;//refire time addTime = RQ3_MP5_DELAY;
break; break;
//Blaze: Reaction Knife fire delay
case WP_KNIFE: case WP_KNIFE:
addTime = 1000;//refire time if ( (pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) == RQ3_KNIFEMODE) {
//knife slash
addTime = RQ3_KNIFE_DELAY;
}
else {
//knife throw
addTime = RQ3_THROW_DELAY;
}
break; break;
//Blaze: Reaction HandCannon fire delay
case WP_HANDCANNON: case WP_HANDCANNON:
addTime = 1500;//refire time addTime = RQ3_HANDCANNON_DELAY;
break; break;
//Blaze: Reaction Shotgun fire delay
case WP_M3: case WP_M3:
addTime = 1000;//refire time addTime = RQ3_M3_DELAY;
break; break;
//Blaze: Reaction Akimbo fire delay
case WP_AKIMBO: case WP_AKIMBO:
addTime = 1000;//refire time addTime = RQ3_AKIMBO_DELAY;
break; break;
//Blaze: Reaction Grenade fire delay
case WP_GRENADE: case WP_GRENADE:
addTime = 1000;//refire time addTime = RQ3_GRENADE_DELAY;
break; break;
#ifdef MISSIONPACK #ifdef MISSIONPACK
case WP_NAILGUN: case WP_NAILGUN:

View file

@ -16,10 +16,12 @@
#define RANK_TIED_FLAG 0x4000 #define RANK_TIED_FLAG 0x4000
//Elder: this are uncertified
#define DEFAULT_SHOTGUN_SPREAD 700 #define DEFAULT_SHOTGUN_SPREAD 700
#define DEFAULT_HANDCANNON_SPREAD 1400 #define DEFAULT_HANDCANNON_SPREAD 1400
#define DEFAULT_SHOTGUN_COUNT 11 #define DEFAULT_SHOTGUN_COUNT 11
//Elder: changed this will affect the cgame entity placement
#define ITEM_RADIUS 15 // item sizes are needed for client side pickup detection #define ITEM_RADIUS 15 // item sizes are needed for client side pickup detection
#define LIGHTNING_RANGE 768 #define LIGHTNING_RANGE 768
@ -96,7 +98,7 @@
//Elder: confused? //Elder: confused?
//Elder: used for STAT_KNIFE ... //Elder: used for STAT_KNIFE ... obsolete now
#define RQ3_KNIFE_SLASH 0 #define RQ3_KNIFE_SLASH 0
#define RQ3_KNIFE_THROW 1 #define RQ3_KNIFE_THROW 1
@ -135,6 +137,9 @@
#define AKIMBO_DAMAGE 90 #define AKIMBO_DAMAGE 90
#define SLASH_DAMAGE 200 //Shashing knife damage #define SLASH_DAMAGE 200 //Shashing knife damage
#define THROW_DAMAGE 250 //Throwing Knife damage #define THROW_DAMAGE 250 //Throwing Knife damage
#define GRENADE_DAMAGE 170
#define GRENADE_SPLASH_DAMAGE 170
#define GRENADE_SPLASH_RADIUS 340 //Splash damage * 2
#define PISTOL_SPREAD 140 #define PISTOL_SPREAD 140
#define MP5_SPREAD 250 #define MP5_SPREAD 250
@ -142,6 +147,44 @@
#define SNIPER_SPREAD 425 #define SNIPER_SPREAD 425
#define AKIMBO_SPREAD 300 #define AKIMBO_SPREAD 300
//Elder: weapon kicks - I think this is against whoever got hit?
#define RQ3_PISTOL_KICK 150
#define RQ3_M3_KICK 20
#define RQ3_M4_KICK 90
#define RQ3_MP5_KICK 90
#define RQ3_HANDCANNON_KICK 40
#define RQ3_SNIPER_KICK 200 // but it seems to get multiplied by zero in the source
#define RQ3_AKIMBO_KICK 90
#define RQ3_KNIFE_KICK 0
#define RQ3_THROW_KICK 50
#define RQ3_GRENADE_KICK 0 // Elder: assumed
//Elder: weaponTime constants (delay in milliseconds)
//Kinda "derived" from the AQ2 source
//Recall that Q2 animations run at 10Hz and the fire
//rate is derived from the number of animation frames
#define RQ3_PISTOL_DELAY 400
#define RQ3_M3_DELAY 900
#define RQ3_M4_DELAY 100
#define RQ3_MP5_DELAY 100
#define RQ3_HANDCANNON_DELAY 1200
#define RQ3_SSG3000_DELAY 1400
#define RQ3_SSG3000_BOLT_DELAY 1300// Elder: delay before zooming back in
#define RQ3_AKIMBO_DELAY 500 // Elder: two delays: one for the total delay
#define RQ3_AKIMBO_DELAY2 200 // one for the time to start the second shot
#define RQ3_KNIFE_DELAY 800
#define RQ3_THROW_DELAY 800
#define RQ3_GRENADE_DELAY 750 // Elder: I made this up
//Elder: special for grenade: speeds depending on distance select
#define GRENADE_SHORT_SPEED 400
#define GRENADE_MEDIUM_SPEED 720
#define GRENADE_LONG_SPEED 920
//Elder: knife throw speed - from the AQ2 source
#define THROW_SPEED 1200
//Elder: special flag needed in both games //Elder: special flag needed in both games
#define FL_THROWN_KNIFE 0x00040000 // Elder: thrown knife special case #define FL_THROWN_KNIFE 0x00040000 // Elder: thrown knife special case
@ -314,13 +357,22 @@ typedef enum {
STAT_JUMPTIME, //Blaze RE: Double jump STAT_JUMPTIME, //Blaze RE: Double jump
STAT_UNIQUEWEAPONS, STAT_UNIQUEWEAPONS,
STAT_FALLDAMAGE, STAT_FALLDAMAGE,
STAT_BANDAGE, //Elder: holds bandage need // STAT_BANDAGE, //Elder: holds bandage need - moved to STAT_RQ3
STAT_RQ3, //Blaze: Will hold a few flags for bandage, etc info STAT_RQ3, //Blaze: Will hold a few flags for bandage, etc info
// STAT_KNIFE, //Elder: knife throwing -- wasteful? then later rename STAT_RQ3 or something and use bits // STAT_KNIFE, //Elder: knife throwing -- wasteful? then later rename STAT_RQ3 or something and use bits
} statIndex_t; } statIndex_t;
//STAT_RQ3 stat info //STAT_RQ3 stat info
#define RQ3_LEGDAMAGE 1 //If this bit is set, the player has leg damage #define RQ3_LEGDAMAGE 1 //If this bit is set, the player has leg damage
//Elder: bandage states to pass to cgame - should remove STAT_BANDAGE
//and integrate with STAT_RQ3
#define RQ3_BANDAGE_NEED 2
#define RQ3_BANDAGE_WORK 4
//Elder: zoom stat - 1x = 0, 2x = zoom low, 4x = zoom_med, 6x = zoom_low + zoom_med
#define RQ3_ZOOM_LOW 8
#define RQ3_ZOOM_MED 16
// player_state->persistant[] indexes // player_state->persistant[] indexes
// these fields are the only part of player_state that isn't // these fields are the only part of player_state that isn't

View file

@ -590,7 +590,9 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
ent->client->bleeding = 0; ent->client->bleeding = 0;
ent->client->bleedtick = 0; ent->client->bleedtick = 0;
//Elder: added //Elder: added
ent->client->isBandaging = qfalse; //ent->client->isBandaging = qfalse;
//Elder: remove bandage work
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK;
//Elder: moved from somewhere - err, g_cmds.c I think //Elder: moved from somewhere - err, g_cmds.c I think
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_LEGDAMAGE; ent->client->ps.stats[STAT_RQ3] &= ~RQ3_LEGDAMAGE;
@ -883,7 +885,8 @@ void ThrowWeapon( gentity_t *ent )
return; return;
} }
//Elder: Bandaging case //Elder: Bandaging case
else if (client->isBandaging) { //else if (client->isBandaging) {
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\"")); trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\""));
return; return;
} }
@ -1177,8 +1180,52 @@ void ClientThink_real( gentity_t *ent ) {
// touch other objects // touch other objects
ClientImpacts( ent, &pm ); ClientImpacts( ent, &pm );
//Elder: someone added
if ( bJumping ) JumpKick( ent ); if ( bJumping ) JumpKick( ent );
//Elder: added for akimbos and 3rb and sniper zoom
switch( ent->client->ps.weapon ) {
case WP_AKIMBO:
if ( ent->client->weaponfireNextTime != 0 &&
level.time >= ent->client->weaponfireNextTime) {
FireWeapon( ent );
}
break;
case WP_SSG3000:
if ( ent->client->weaponfireNextTime != 0 &&
level.time >= ent->client->weaponfireNextTime) {
//Elder: restore last zoom and clear the variable
ent->client->ps.stats[STAT_RQ3] |= ent->client->lastzoom;
ent->client->lastzoom = 0;
ent->client->weaponfireNextTime = 0;
}
else if (level.time < ent->client->weaponfireNextTime) {
//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;
}
break;
//case WP_MP5:
case WP_M4:
/*
if (ent->client->weaponfireNextTime != 0 &&
level.time >= ent->client->weaponfireNextTime) {
//Burst three shots and subtract ammo accordingly
FireWeapon(ent);
ent->client->ps.ammo[WP_M4]--;
}*/
break;
default:
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 // save results of triggers and client events
if (ent->client->ps.eventSequence != oldEventSequence) { if (ent->client->ps.eventSequence != oldEventSequence) {
ent->eventTime = level.time; ent->eventTime = level.time;
@ -1376,15 +1423,15 @@ void ClientEndFrame( gentity_t *ent ) {
// End Duffman // End Duffman
ent->client->ps.stats[STAT_HEALTH] = ent->health; // FIXME: get rid of ent->health... ent->client->ps.stats[STAT_HEALTH] = ent->health; // FIXME: get rid of ent->health...
//Elder: bleeding //Elder: bleeding notification
//TODO: add in when you get leg damage
//ent->client->ps.stats[STAT_RQ3] &= RQ3_LEGDAMAGE; //ent->client->ps.stats[STAT_RQ3] &= RQ3_LEGDAMAGE;
if (ent->client->bleeding || if (ent->client->bleeding ||
(ent->client->ps.stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE) { (ent->client->ps.stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE) {
ent->client->ps.stats[STAT_BANDAGE] = 1; ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_NEED;
} }
else { else {
ent->client->ps.stats[STAT_BANDAGE] = 0; ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_NEED;
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK;
} }
G_SetClientSound (ent); G_SetClientSound (ent);

View file

@ -1240,14 +1240,21 @@ void ClientSpawn(gentity_t *ent) {
client->latched_buttons = 0; client->latched_buttons = 0;
// Hawkins reset zoomed flag // Hawkins reset zoomed flag
client->zoomed=0; //Elder: using new stat - it's cleared anyways below
//client->zoomed=0;
//Elder: knife reset/initialize //Elder: knife reset/initialize
//Elder: removed - set in ClientBegin //Elder: removed - set in ClientBegin
//client->ps.persistant[PERS_WEAPONMODES] &= !RQ3_KNIFEMODE; //client->ps.persistant[PERS_WEAPONMODES] &= !RQ3_KNIFEMODE;
//Elder: reset isBandaging flag //Elder: reset isBandaging flag
client->isBandaging = qfalse; //client->isBandaging = qfalse;
//Elder: reset all RQ3 non-persistent stats
ent->client->ps.stats[STAT_RQ3] = 0;
//Elder: set weaponfireNextTime amount
client->weaponfireNextTime = 0;
// set default animations // set default animations
client->ps.torsoAnim = TORSO_STAND; client->ps.torsoAnim = TORSO_STAND;

View file

@ -1595,21 +1595,29 @@ void Cmd_Stats_f( gentity_t *ent ) {
void Cmd_Bandage (gentity_t *ent) void Cmd_Bandage (gentity_t *ent)
{ {
// Zoom out when bandaging. // Zoom out when bandaging.
if( ent->client->zoomed ){ //if( ent->client->zoomed ){
ent->client->zoomed = 0; //ent->client->zoomed = 0;
} //}
//Elder: can't use events //Elder: can't use events
//G_AddEvent(ent,EV_ZOOM,0); //G_AddEvent(ent,EV_ZOOM,0);
//} //}
//Elder: added so you can't "rebandage" //Elder: added so you can't "rebandage"
if (ent->client->isBandaging == qtrue) { if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
//if (ent->client->isBandaging == qtrue) {
trap_SendServerCommand( ent-g_entities, va("print \"You are already bandaging!\n\"")); trap_SendServerCommand( ent-g_entities, va("print \"You are already bandaging!\n\""));
return; return;
} }
if (ent->client->bleeding || (ent->client->ps.stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE) //if (ent->client->bleeding || (ent->client->ps.stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE)
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_NEED) == RQ3_BANDAGE_NEED ||
(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;
ent->client->ps.weaponstate = WEAPON_DROPPING; ent->client->ps.weaponstate = WEAPON_DROPPING;
ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT )
^ ANIM_TOGGLEBIT ) | TORSO_DROP; ^ ANIM_TOGGLEBIT ) | TORSO_DROP;
@ -1617,7 +1625,8 @@ void Cmd_Bandage (gentity_t *ent)
ent->client->ps.weaponTime += 6000; ent->client->ps.weaponTime += 6000;
ent->client->bleedtick = 4; ent->client->bleedtick = 4;
//Elder: added //Elder: added
ent->client->isBandaging = qtrue; //ent->client->isBandaging = qtrue;
ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_WORK;
//Elder: moved to g_active where it will be unset after 2 bleedticks //Elder: moved to g_active where it will be unset after 2 bleedticks
//ent->client->ps.stats[STAT_RQ3] &= !RQ3_LEGDAMAGE; //ent->client->ps.stats[STAT_RQ3] &= !RQ3_LEGDAMAGE;
} }
@ -1643,8 +1652,9 @@ void Cmd_Reload( gentity_t *ent ) {
int ammotoadd; int ammotoadd;
int delay; int delay;
//Elder: added //Elder: added for redundant check but shouldn't need to come here - handled in cgame
if (ent->client->isBandaging) { //if (ent->client->isBandaging == qtrue) {
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\"")); trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\""));
return; return;
} }
@ -1662,9 +1672,12 @@ void Cmd_Reload( gentity_t *ent ) {
// Hawkins: Zoom out when reloading. // Hawkins: Zoom out when reloading.
//Elder: shouldn't need to know about it //Elder: shouldn't need to know about it
// To Do: Must remember to zoom back in // To Do: Must remember to zoom back in
if( ent->client->zoomed ){ //if( ent->client->zoomed ){
ent->client->zoomed=0; //ent->client->zoomed=0;
} //}
//Elder: remove zoom bits
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
//Elder: can't use events //Elder: can't use events
//G_AddEvent(ent,EV_ZOOM,0); //G_AddEvent(ent,EV_ZOOM,0);
@ -1689,7 +1702,7 @@ void Cmd_Reload( gentity_t *ent ) {
break; break;
//Elder: was missing? //Elder: was missing?
case WP_M4: case WP_M4:
delay = 2500; delay = 2000;
if (ent->client->ps.ammo[weapon] >= RQ3_M4_AMMO) if (ent->client->ps.ammo[weapon] >= RQ3_M4_AMMO)
{ {
trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\"")); trap_SendServerCommand( ent-g_entities, va("print \"No need to reload.\n\""));
@ -1875,18 +1888,51 @@ void Cmd_Weapon(gentity_t *ent)
{ {
//Elder: debug code //Elder: debug code
//G_Printf("PERS_WEAPONMODES: %d\n", ent->client->ps.persistant[PERS_WEAPONMODES]); //G_Printf("PERS_WEAPONMODES: %d\n", ent->client->ps.persistant[PERS_WEAPONMODES]);
//Elder: added since cgame doesn't actually know if its bandaging
//if (ent->client->isBandaging == qtrue) {
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;
}
//Elder: added brackets, and-ops and not-ops instead of logical ops //Elder: added brackets, and-ops and not-ops instead of logical ops
switch(ent->s.weapon){ switch(ent->s.weapon){
case WP_SSG3000: case WP_SSG3000:
// zoom is done by client. zoom 3 levels, then zoom out // zoom is done by client. zoom 3 levels, then zoom out
//Elder: This is just for the server to track when calcing the spread //Elder: This is just for the server to track when calcing the spread
if(ent->client->zoomed == 3) { /*
if (ent->client->zoomed == 3) {
ent->client->zoomed = 0; ent->client->zoomed = 0;
} }
else { else {
ent->client->zoomed++; ent->client->zoomed++;
} }
*/
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 ) {
//Elder: zoom 1x
//G_Printf("Server: 1x\n");
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
}
else if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_MED) == RQ3_ZOOM_MED) {
//Elder: zoom 6x
//G_Printf("Server: 6x\n");
ent->client->ps.stats[STAT_RQ3] |= RQ3_ZOOM_LOW;
}
else if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW) {
//Elder: zoom 4x
//G_Printf("Server: 4x\n");
ent->client->ps.stats[STAT_RQ3] |= RQ3_ZOOM_MED;
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
}
else {
//Elder: zoom 2x
//G_Printf("Server: 2x\n");
ent->client->ps.stats[STAT_RQ3] |= RQ3_ZOOM_LOW;
}
//Elder: don't print - will broadcast to server //Elder: don't print - will broadcast to server
//G_Printf("zoomlevel = %d\n",ent->client->zoomed); //G_Printf("zoomlevel = %d\n",ent->client->zoomed);
@ -2000,7 +2046,18 @@ void Cmd_Weapon(gentity_t *ent)
// Hawkins make sure spread comes back // 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"); //G_Printf("Got to Cmd_Unzoom\n");
ent->client->zoomed = 0; //Elder: added
//if (ent->client->isBandaging == qtrue) {
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 {
//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;
}
} }
@ -2010,9 +2067,21 @@ Cmd_Drop_f XRAY FMJ
================= =================
*/ */
void Cmd_Drop_f( gentity_t *ent ) { void Cmd_Drop_f( gentity_t *ent ) {
ent->client->zoomed=0;
//G_AddEvent(ent,EV_ZOOM,0); //Elder: added
ThrowWeapon( ent ); //if (ent->client->isBandaging == qtrue) {
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging!\n\""));
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;
//G_AddEvent(ent,EV_ZOOM,0);
ThrowWeapon( ent );
}
} }

View file

@ -100,46 +100,58 @@ void TossClientItems( gentity_t *self ) {
//That way, we can also account for the bandolier automatically //That way, we can also account for the bandolier automatically
//BTW, that means no cheating to get all weapons or it'll spawn mad!! //BTW, that means no cheating to get all weapons or it'll spawn mad!!
weaponInventory = self->client->ps.stats[STAT_WEAPONS]; weaponInventory = self->client->ps.stats[STAT_WEAPONS];
//Elder: throw items in a "circle" starting at a random angle
i = level.time;
angle = Q_random(&i) * 30;
//Elder: added hadUniqueWeapons check - returns to qfalse if died with the gun //Elder: added hadUniqueWeapons check - returns to qfalse if died with the gun
//as opposed to dropping it, then died //as opposed to dropping it, then died
if ( (weaponInventory & (1 << WP_M3) ) == (1 << WP_M3) ) { if ( (weaponInventory & (1 << WP_M3) ) == (1 << WP_M3) ) {
item = BG_FindItemForWeapon( WP_M3 ); item = BG_FindItemForWeapon( WP_M3 );
Drop_Item( self, item, 0); Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_M3 ] = qfalse; self->client->hadUniqueWeapon[ WP_M3 ] = qfalse;
angle += 30;
} }
if ( (weaponInventory & (1 << WP_M4) ) == (1 << WP_M4) ) { if ( (weaponInventory & (1 << WP_M4) ) == (1 << WP_M4) ) {
item = BG_FindItemForWeapon( WP_M4 ); item = BG_FindItemForWeapon( WP_M4 );
Drop_Item( self, item, 0); Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_M4 ] = qfalse; self->client->hadUniqueWeapon[ WP_M4 ] = qfalse;
angle += 30;
} }
if ( (weaponInventory & (1 << WP_MP5) ) == (1 << WP_MP5) ) { if ( (weaponInventory & (1 << WP_MP5) ) == (1 << WP_MP5) ) {
item = BG_FindItemForWeapon( WP_MP5 ); item = BG_FindItemForWeapon( WP_MP5 );
Drop_Item( self, item, 0); Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_MP5 ] = qfalse; self->client->hadUniqueWeapon[ WP_MP5 ] = qfalse;
angle += 30;
} }
if ( (weaponInventory & (1 << WP_HANDCANNON) ) == (1 << WP_HANDCANNON) ) { if ( (weaponInventory & (1 << WP_HANDCANNON) ) == (1 << WP_HANDCANNON) ) {
item = BG_FindItemForWeapon( WP_HANDCANNON ); item = BG_FindItemForWeapon( WP_HANDCANNON );
Drop_Item( self, item, 0); Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_HANDCANNON ] = qfalse; self->client->hadUniqueWeapon[ WP_HANDCANNON ] = qfalse;
angle += 30;
} }
if ( (weaponInventory & (1 << WP_SSG3000) ) == (1 << WP_SSG3000) ) { if ( (weaponInventory & (1 << WP_SSG3000) ) == (1 << WP_SSG3000) ) {
item = BG_FindItemForWeapon( WP_SSG3000 ); item = BG_FindItemForWeapon( WP_SSG3000 );
Drop_Item( self, item, 0); Drop_Item( self, item, angle);
self->client->hadUniqueWeapon[ WP_SSG3000 ] = qfalse; self->client->hadUniqueWeapon[ WP_SSG3000 ] = qfalse;
angle += 30;
} }
//Elder: Always drop the pistol //Elder: Always drop the pistol
item = BG_FindItemForWeapon( WP_PISTOL ); item = BG_FindItemForWeapon( WP_PISTOL );
Drop_Item (self, item, 0); Drop_Item (self, item, angle);
angle += 30;
//Elder: drop a knife if player has at least one //Elder: drop a knife if player has at least one
if ( self->client->ps.ammo[ WP_KNIFE ] > 0) { if ( self->client->ps.ammo[ WP_KNIFE ] > 0) {
item = BG_FindItemForWeapon( WP_KNIFE ); item = BG_FindItemForWeapon( WP_KNIFE );
Drop_Item (self, item, 0); Drop_Item (self, item, angle);
} }
// drop all the powerups if not in teamplay // drop all the powerups if not in teamplay
@ -500,12 +512,17 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if ( self->client ) if ( self->client )
{ {
// Hawkins put spread back and zoom out // Hawkins put spread back and zoom out
self->client->zoomed = 0; //Elder: remove zoom bits
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_LOW;
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_ZOOM_MED;
//self->client->zoomed = 0;
self->client->bleeding = 0; self->client->bleeding = 0;
//targ->client->bleedcount = 0; //targ->client->bleedcount = 0;
self->client->bleed_remain = 0; self->client->bleed_remain = 0;
//Elder: added; //Elder: added;
self->client->isBandaging = qfalse; //self->client->isBandaging = qfalse;
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK;
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_NEED;
} }
if ( self->client->ps.pm_type == PM_DEAD ) { if ( self->client->ps.pm_type == PM_DEAD ) {
return; return;

View file

@ -281,7 +281,6 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
quantity = 0; // None for you, sir! quantity = 0; // None for you, sir!
} else { } else {
if ( ent->count ) { if ( ent->count ) {
//Elder: place to put gun's chamber ammo?
quantity = ent->count; quantity = ent->count;
} else { } else {
quantity = ent->item->quantity; quantity = ent->item->quantity;
@ -299,18 +298,19 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
} */ } */
} }
// add the weapon // add the weapon if not knife or pistol
other->client->ps.stats[STAT_WEAPONS] |= ( 1 << ent->item->giTag ); if (ent->item->giTag != WP_KNIFE || ent->item->giTag != WP_PISTOL)
other->client->ps.stats[STAT_WEAPONS] |= ( 1 << ent->item->giTag );
// Begin Duffman - Adds a clip for each weapon picked up, will want to edit this later // Begin Duffman - Adds a clip for each weapon picked up, will want to edit this later
/*Add_Ammo( other, ent->item->giTag, quantity );*/ /*Add_Ammo( other, ent->item->giTag, quantity );*/
switch (ent->item->giTag) switch (ent->item->giTag)
{ {
case WP_KNIFE: case WP_KNIFE:
if (other->client->ps.ammo[ent->item->giTag] < RQ3_KNIFE_MAXCLIP) if (other->client->ps.ammo[WP_KNIFE] < RQ3_KNIFE_MAXCLIP)
{ {
//G_Printf("(%d)\n",other->client->ps.ammo[ent->item->giTag]); //G_Printf("(%d)\n",other->client->ps.ammo[ent->item->giTag]);
ammotoadd=other->client->ps.ammo[ent->item->giTag]+1; ammotoadd = other->client->ps.ammo[WP_KNIFE] + 1;
} }
else else
{ {
@ -384,14 +384,19 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
break; break;
default: default:
//Blaze: Should never hit here //Blaze: Should never hit here
G_Printf("Pickup_Weapon given bad giTag: %d\n", ent->item->giTag); G_Printf("Pickup_Weapon: Given bad giTag: %d\n", ent->item->giTag);
ammotoadd=30; ammotoadd=0;
break; break;
} }
//Elder: conditional added to "restore" weapons //Elder: conditional added to "restore" weapons
if ( other->client->hadUniqueWeapon[ent->item->giTag] == qfalse || if ( other->client->hadUniqueWeapon[ent->item->giTag] == qfalse ||
!((ent->flags & FL_THROWN_ITEM) == FL_THROWN_ITEM) ) { !((ent->flags & FL_THROWN_ITEM) == FL_THROWN_ITEM) ) {
other->client->ps.ammo[ent->item->giTag]= ammotoadd; 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;
}
} }
// End Duffman // End Duffman
@ -589,7 +594,7 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
//Akimbos: shouldn't pick them up b/c they shouldn't be dropped //Akimbos: shouldn't pick them up b/c they shouldn't be dropped
//Specials: if you have more than/equal to limit (remember bando later), leave //Specials: if you have more than/equal to limit (remember bando later), leave
case WP_KNIFE: case WP_KNIFE:
if ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_KNIFE) == (1 << WP_KNIFE) ) && if ( ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_KNIFE) ) == (1 << WP_KNIFE) ) &&
(other->client->ps.ammo[ent->item->giTag] >= RQ3_KNIFE_MAXCLIP) ) (other->client->ps.ammo[ent->item->giTag] >= RQ3_KNIFE_MAXCLIP) )
return; return;
break; break;
@ -600,10 +605,11 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
break; break;
case WP_PISTOL: case WP_PISTOL:
//Elder: always have pistol - but extra ones give akimbo or clips //Elder: always have pistol - but extra ones give akimbo or clips
if ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_AKIMBO) == (1 << WP_AKIMBO) ) && if ( ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_AKIMBO) ) == (1 << WP_AKIMBO) ) &&
other->client->ps.stats[ent->item->giTag] >= RQ3_PISTOL_MAXCLIP) other->client->numClips[WP_PISTOL] >= RQ3_PISTOL_MAXCLIP ) {
//leave if we have max clips and akimbos //leave if we have max clips and akimbos
return; return;
}
break; break;
case WP_M3: case WP_M3:
case WP_HANDCANNON: case WP_HANDCANNON:
@ -682,14 +688,18 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
*/ */
respawn = Pickup_Weapon(ent, other); respawn = Pickup_Weapon(ent, other);
respawn = -1; //Dont respawn weapons
//Elder: added pistol condition
if (ent->item->giTag == WP_GRENADE || ent->item->giTag == WP_PISTOL) //Elder: added pistol and knife condition
{ if (ent->item->giTag == WP_GRENADE || ent->item->giTag == WP_PISTOL ||
// G_Printf("Grenade Pickedup (%d)\n",respawn); ent->item->giTag == WP_KNIFE) {
// G_Printf("Grenade Picked up (%d)\n",respawn);
respawn = 30; respawn = 30;
} }
else {
//Elder: moved here
respawn = -1; //Dont respawn weapons
}
// predict = qfalse; // predict = qfalse;
break; break;
@ -912,7 +922,7 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity, int xr_fla
if( xr_flags & FL_THROWN_ITEM) { if( xr_flags & FL_THROWN_ITEM) {
dropped->clipmask = MASK_SHOT; // XRAY FMJ dropped->clipmask = MASK_SHOT; // XRAY FMJ
dropped->s.pos.trTime = level.time - 50; // move a bit on the very first frame dropped->s.pos.trTime = level.time - 50; // move a bit on the very first frame
VectorScale( velocity, 400, dropped->s.pos.trDelta ); // 700 500 VectorScale( velocity, 200, dropped->s.pos.trDelta ); // 700 500 400
SnapVector( dropped->s.pos.trDelta ); // save net bandwidth SnapVector( dropped->s.pos.trDelta ); // save net bandwidth
dropped->physicsBounce= 0; dropped->physicsBounce= 0;
} }
@ -929,22 +939,33 @@ dropWeapon XRAY FMJ
*/ */
gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags ) { // XRAY FMJ gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags ) { // XRAY FMJ
vec3_t velocity; vec3_t velocity;
vec3_t angles;
vec3_t origin; vec3_t origin;
VectorCopy( ent->s.pos.trBase, origin ); VectorCopy( ent->s.pos.trBase, origin );
VectorCopy( ent->s.apos.trBase, angles );
angles[YAW] += angle;
angles[PITCH] = 0; // always forward
AngleVectors( angles, velocity, NULL, NULL);
//VectorScale( velocity, 150, velocity);
// set aiming directions // set aiming directions
AngleVectors (ent->client->ps.viewangles, velocity, NULL, NULL); //AngleVectors (ent->client->ps.viewangles, velocity, NULL, NULL);
origin[2] += ent->client->ps.viewheight; origin[2] += ent->client->ps.viewheight;
VectorMA( origin, 34, velocity, origin ); // 14 VectorMA( origin, 10, velocity, origin ); // 14 34
// snap to integer coordinates for more efficient network bandwidth usage // snap to integer coordinates for more efficient network bandwidth usage
SnapVector( origin); SnapVector( origin);
// less vertical velocity // less vertical velocity
velocity[2] += 0.2f; //velocity[2] += 0.2f;
//velocity[2] = 20;
//G_Printf("Velocity: %s\n", vtos(velocity));
VectorNormalize( velocity ); VectorNormalize( velocity );
VectorScale( velocity, 5, velocity);
return LaunchItem( item, origin, velocity, xr_flags ); return LaunchItem( item, origin, velocity, xr_flags );
//return LaunchItem( item, ent->s.pos.trBase, velocity, xr_flags );
} }
/* /*

View file

@ -65,7 +65,7 @@ typedef enum {
#define RQ3_RESPAWNTIME_DEFAULT 60000 // Elder: time for weapons to respawn - up to 60s #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_AUTOOPEN 128 // Elder: revert to Q3 behaviour
#define SP_NODOORTOGGLE 256 // Elder: added to disable mover toggling #define SP_DOORTOGGLE 256 // Elder: added to enable mover toggling
//============================================================================ //============================================================================
@ -181,6 +181,7 @@ struct gentity_s {
gitem_t *item; // for bonus items gitem_t *item; // for bonus items
float distance; // VALKYRIE: for rotating door float distance; // VALKYRIE: for rotating door
}; };
@ -339,7 +340,7 @@ struct gclient_s {
int bleedtick; //Blaze: Holds # of seconds till bleeding stops. int bleedtick; //Blaze: Holds # of seconds till bleeding stops.
//Elder: server only needs to know for sniper spread - ARGH //Elder: server only needs to know for sniper spread - ARGH
int zoomed; // Hawkins (SSG zoom) // int zoomed; // Hawkins (SSG zoom)
//qboolean semi; // hawkins (semiauto mode for m4, mp5, pistol) //qboolean semi; // hawkins (semiauto mode for m4, mp5, pistol)
int shots; //Blaze: Number of shots fired so far with this weapon int shots; //Blaze: Number of shots fired so far with this weapon
@ -352,12 +353,16 @@ struct gclient_s {
int grenRange; // range to throw grenade (short/medium/long) int grenRange; // range to throw grenade (short/medium/long)
int throwKnife; // knife to throwing int throwKnife; // knife to throwing
*/ */
qboolean isBandaging; //Elder: player in the process of bandaging //qboolean isBandaging; //Elder: player in the process of bandaging
// end Homer // end Homer
//Elder: prep for "ammo" in last gun //Elder: prep for "ammo" in last gun
//Only the server needs to know this //Only the server needs to know this
qboolean hadUniqueWeapon[MAX_WEAPONS]; 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
#ifdef MISSIONPACK #ifdef MISSIONPACK
gentity_t *persistantPowerup; gentity_t *persistantPowerup;

View file

@ -662,6 +662,7 @@ fire_grenade
*/ */
gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) { gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
gentity_t *bolt; gentity_t *bolt;
int speed;
VectorNormalize (dir); VectorNormalize (dir);
@ -675,9 +676,9 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
bolt->s.eFlags = EF_BOUNCE_HALF; bolt->s.eFlags = EF_BOUNCE_HALF;
bolt->r.ownerNum = self->s.number; bolt->r.ownerNum = self->s.number;
bolt->parent = self; bolt->parent = self;
bolt->damage = 100; bolt->damage = GRENADE_DAMAGE; //probably only used on a direct hit
bolt->splashDamage = 340;//Blaze: Reaction Grenade Damage bolt->splashDamage = GRENADE_SPLASH_DAMAGE; //Blaze: Reaction Grenade Damage
bolt->splashRadius = 200;//Blaze: changed from 150 was 170, but I uped it some more bolt->splashRadius = GRENADE_SPLASH_RADIUS; //Blaze: changed from 150 was 170, but I uped it some more
bolt->methodOfDeath = MOD_GRENADE; bolt->methodOfDeath = MOD_GRENADE;
bolt->splashMethodOfDeath = MOD_GRENADE_SPLASH; bolt->splashMethodOfDeath = MOD_GRENADE_SPLASH;
bolt->clipmask = MASK_SHOT; bolt->clipmask = MASK_SHOT;
@ -686,7 +687,30 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
bolt->s.pos.trType = TR_GRAVITY; bolt->s.pos.trType = TR_GRAVITY;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase ); VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, 700, bolt->s.pos.trDelta );
//Elder: grenade toggle distances/speeds
if ( self->client) {
if ( (self->client->ps.persistant[PERS_WEAPONMODES] & RQ3_GRENSHORT) == RQ3_GRENSHORT &&
(self->client->ps.persistant[PERS_WEAPONMODES] & RQ3_GRENMED) == RQ3_GRENMED) {
//Long range throw
speed = GRENADE_LONG_SPEED;
}
else if ( (self->client->ps.persistant[PERS_WEAPONMODES] & RQ3_GRENSHORT) == RQ3_GRENSHORT) {
//Short range throw
speed = GRENADE_SHORT_SPEED;
}
else if ( (self->client->ps.persistant[PERS_WEAPONMODES] & RQ3_GRENMED) == RQ3_GRENMED) {
//Medium range throw
speed = GRENADE_MEDIUM_SPEED;
}
else {
//Elder: shouldn't be here
G_Printf("fire_grenade: Did not receive a grenade parm\n");
speed = GRENADE_MEDIUM_SPEED;
}
}
VectorScale( dir, speed, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin); VectorCopy (start, bolt->r.currentOrigin);
@ -720,7 +744,7 @@ gentity_t *fire_knife (gentity_t *self, vec3_t start, vec3_t dir)
bolt->s.pos.trType = TR_GRAVITY; bolt->s.pos.trType = TR_GRAVITY;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase ); VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, 1100, bolt->s.pos.trDelta ); VectorScale( dir, THROW_SPEED, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin); VectorCopy (start, bolt->r.currentOrigin);

View file

@ -602,13 +602,16 @@ void Reached_BinaryMover( gentity_t *ent ) {
} }
//Elder: added toggle bit //Elder: added toggle bit
if ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE ) { //Also added "touch" and "takedamage" check so we are only abusing doors
if ( (ent->spawnflags & SP_DOORTOGGLE) == SP_DOORTOGGLE ) { //||
//ent->touch || (ent->takedamage == qtrue) ) {
G_Printf("Sliding Toggle Door used\n");
}
else {
// return to pos1 after a delay // return to pos1 after a delay
ent->think = ReturnToPos1; ent->think = ReturnToPos1;
ent->nextthink = level.time + ent->wait; ent->nextthink = level.time + ent->wait;
} ;
else {
//G_Printf("Sliding Toggle Door used\n");
} }
// fire targets // fire targets
@ -641,14 +644,17 @@ void Reached_BinaryMover( gentity_t *ent ) {
} }
//Elder: added toggle bit //Elder: added toggle bit
if ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE ) { //Also added "touch" and "takedamage" check so we are only abusing doors
//if ( ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE ) ||
if ( (ent->spawnflags & SP_DOORTOGGLE) == SP_DOORTOGGLE ) { //||
//ent->touch || (ent->takedamage == qtrue) ) {
G_Printf("Rotating Toggle Door used\n");
}
else {
// return to apos1 after a delay // return to apos1 after a delay
ent->think = ReturnToApos1; ent->think = ReturnToApos1;
ent->nextthink = level.time + ent->wait; ent->nextthink = level.time + ent->wait;
} }
else {
//G_Printf("Rotating Toggle Door used\n");
}
// fire targets // fire targets
if ( !ent->activator ) { if ( !ent->activator ) {
@ -713,16 +719,19 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
// if all the way up, just delay before coming down // if all the way up, just delay before coming down
if ( ent->moverState == MOVER_POS2 ) { if ( ent->moverState == MOVER_POS2 ) {
if ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE) { //Elder: added two additional checks
//Elder: normal Q3 door if ( (ent->spawnflags & SP_DOORTOGGLE) == SP_DOORTOGGLE ) {
ent->nextthink = level.time + ent->wait; //if ( ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE ) ||
} //ent->touch || ent->takedamage) {
else { //Elder: Move back "immediately"
//Elder: Move back "immediately"
MatchTeam( ent, MOVER_2TO1, level.time + 50); MatchTeam( ent, MOVER_2TO1, level.time + 50);
if ( ent->sound1to2 ) { if ( ent->sound1to2 ) {
G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 );
} }
}
else {
//Elder: normal Q3 door
ent->nextthink = level.time + ent->wait;
} }
return; return;
} }
@ -791,16 +800,18 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
// if all the way up, just delay before coming down // if all the way up, just delay before coming down
if ( ent->moverState == ROTATOR_POS2 ) { if ( ent->moverState == ROTATOR_POS2 ) {
if ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE) { //if ( ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE ) ||
//Elder: normal rotating door //ent->touch || ent->takedamage) {
ent->nextthink = level.time + ent->wait; if ( (ent->spawnflags & SP_DOORTOGGLE) == SP_DOORTOGGLE ) {
}
else {
//Elder: Move back "immediately" //Elder: Move back "immediately"
MatchTeam( ent, ROTATOR_2TO1, level.time + 50); MatchTeam( ent, ROTATOR_2TO1, level.time + 50);
if ( ent->sound1to2 ) { if ( ent->sound1to2 ) {
G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 );
} }
}
else {
//Elder: normal rotating door
ent->nextthink = level.time + ent->wait;
} }
return; return;
} }
@ -1126,7 +1137,7 @@ NOMONSTER monsters will not trigger this door
//Elder: new one from GTKRadiant's entity.def plus Reaction stuff //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 NOTOGGLE /*QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER x x x x AUTOOPEN TOGGLE
Normal sliding door entity. By default, the door will activate when player walks close to it or when damage is inflicted to it. Normal sliding door entity. By default, the door will activate when player walks close to it or when damage is inflicted to it.
-------- KEYS -------- -------- KEYS --------
angle : determines the opening direction of door (up = -1, down = -2). angle : determines the opening direction of door (up = -1, down = -2).
@ -1149,9 +1160,9 @@ soundmove : path to sound file to play when door is moving
-------- SPAWNFLAGS -------- -------- SPAWNFLAGS --------
START_OPEN : the door will spawn in the open state and operate in reverse. 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. CRUSHER : door will not reverse direction when blocked and will keep damaging player until he dies or gets out of the way.
NOTOGGLE : door will close like traditional Q3 doors using the wait period TOGGLE : door requires an opendoor toggle to work
AUTOOPEN : door will open like traditional Q3 doors (like a motion sensor) AUTOOPEN : door will open like traditional Q3 doors (like a motion sensor)
Setting NOTOGGLE and AUTOOPEN will make the doors act like traditional Q3A doors Setting AUTOOPEN will make the doors act like traditional Q3A doors
-------- NOTES -------- -------- 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.*/ 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) { void SP_func_door (gentity_t *ent) {
@ -1176,7 +1187,7 @@ void SP_func_door (gentity_t *ent) {
G_Printf("func_door Starting Open\n"); G_Printf("func_door Starting Open\n");
if ( (ent->spawnflags & 4) == 4) if ( (ent->spawnflags & 4) == 4)
G_Printf("func_door CRUSHER\n"); G_Printf("func_door CRUSHER\n");
if ( (ent->spawnflags & SP_NODOORTOGGLE) == SP_NODOORTOGGLE) if ( (ent->spawnflags & SP_DOORTOGGLE) == SP_DOORTOGGLE)
G_Printf("func_door is a Toggle\n"); G_Printf("func_door is a Toggle\n");
// default speed of 400 // default speed of 400

View file

@ -947,6 +947,17 @@ void Weapon_M4_Fire(gentity_t *ent)
} }
Bullet_Fire( ent, RQ3Spread(ent, M4_SPREAD), M4_DAMAGE, MOD_M4); Bullet_Fire( ent, RQ3Spread(ent, M4_SPREAD), M4_DAMAGE, MOD_M4);
/*
if ( (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE) {
//Elder: burst three shots
if (ent->client->weaponfireNextTime > 0 && ent->client->ps.stats[STAT_BURST] > 2) {
ent->client->weaponfireNextTime = 0;
}
else {
ent->client->weaponfireNextTime = level.time + RQ3_M4_DELAY;
}
}*/
} }
/* /*
@ -978,10 +989,26 @@ SSG3000 Attack
*/ */
void Weapon_SSG3000_Fire(gentity_t *ent) void Weapon_SSG3000_Fire(gentity_t *ent)
{ {
float spread;
//Elder: Don't print - will broadcast to server //Elder: Don't print - will broadcast to server
//G_Printf("Zoom Level: %d\n", ent->client->zoomed); //G_Printf("Zoom Level: %d\n", ent->client->zoomed);
//Elder: changed to use RQ3Spread as well //Elder: changed to use RQ3Spread as well
Bullet_Fire( ent, ( ent->client->zoomed? 0:RQ3Spread(ent, SNIPER_SPREAD)), SNIPER_DAMAGE, MOD_SNIPER); //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) {
spread = 0;
}
else {
spread = RQ3Spread(ent, SNIPER_SPREAD);
}
Bullet_Fire( ent, spread, SNIPER_DAMAGE, MOD_SNIPER);
//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;
} }
@ -1065,8 +1092,14 @@ void Weapon_Akimbo_Fire(gentity_t *ent)
//Blaze: Will need 2 of these //Blaze: Will need 2 of these
spread = AKIMBO_SPREAD; spread = AKIMBO_SPREAD;
Bullet_Fire( ent, RQ3Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO); Bullet_Fire( ent, RQ3Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
//Elder: should there be a small delay or is that just the sound effect in AQ2?
Bullet_Fire( ent, RQ3Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO); //Elder: reset
if (ent->client->weaponfireNextTime > 0)
ent->client->weaponfireNextTime = 0;
else
ent->client->weaponfireNextTime = level.time + RQ3_AKIMBO_DELAY2;
//Bullet_Fire( ent, RQ3Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
} }
/* /*