mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2025-03-13 22:22:13 +00:00
Elder:
Major changes from the the alpha pak release on June 8th I have it documented in my worklog
This commit is contained in:
parent
85a0dece4b
commit
9092878c49
15 changed files with 535 additions and 142 deletions
|
@ -462,6 +462,7 @@ localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
|
|||
}
|
||||
|
||||
|
||||
//Elder: we need one that sprays blood
|
||||
/*
|
||||
=================
|
||||
CG_Bleed
|
||||
|
@ -692,13 +693,16 @@ void CG_BigExplode( vec3_t playerOrigin ) {
|
|||
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
|
||||
}
|
||||
|
||||
#define GLASS_VELOCITY 175
|
||||
#define GLASS_JUMP 125
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_LaunchGlass
|
||||
==================
|
||||
*/
|
||||
//Elder: might want to rotate the model randomly or do it in break glass
|
||||
void CG_LaunchGlass( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
|
||||
void CG_LaunchGlass( vec3_t origin, vec3_t velocity, vec3_t rotation, qhandle_t hModel ) {
|
||||
localEntity_t *le;
|
||||
refEntity_t *re;
|
||||
|
||||
|
@ -719,6 +723,13 @@ void CG_BigExplode( vec3_t playerOrigin ) {
|
|||
VectorCopy( velocity, le->pos.trDelta );
|
||||
le->pos.trTime = cg.time;
|
||||
|
||||
//Elder: added
|
||||
//VectorCopy( origin, le->angles.trBase );
|
||||
VectorCopy( velocity, le->angles.trBase );
|
||||
le->angles.trBase[2] = le->angles.trBase[2] - GLASS_JUMP;
|
||||
VectorCopy( rotation, le->angles.trDelta );
|
||||
le->angles.trTime = cg.time;
|
||||
|
||||
le->bounceFactor = 0.3f;
|
||||
|
||||
le->leFlags = LEF_TUMBLE;
|
||||
|
@ -733,10 +744,9 @@ void CG_BigExplode( vec3_t playerOrigin ) {
|
|||
Generated a bunch of glass shards launching out from the glass location
|
||||
===================
|
||||
*/
|
||||
#define GLASS_VELOCITY 175
|
||||
#define GLASS_JUMP 125
|
||||
|
||||
void CG_BreakGlass( vec3_t playerOrigin, int glassParm ) {
|
||||
vec3_t origin, velocity;
|
||||
vec3_t origin, velocity, rotation;
|
||||
int value;
|
||||
int count = 40; // How many shards to generate
|
||||
int states[] = {1,2,3}; // The array of possible numbers
|
||||
|
@ -801,20 +811,23 @@ void CG_BreakGlass( vec3_t playerOrigin, int glassParm ) {
|
|||
// number every time a piece of glass is broken.
|
||||
value = states[rand()%numstates];
|
||||
VectorCopy( playerOrigin, origin );
|
||||
velocity[0] = crandom()*GLASS_VELOCITY;
|
||||
velocity[1] = crandom()*GLASS_VELOCITY;
|
||||
velocity[2] = GLASS_JUMP + crandom()*GLASS_VELOCITY;
|
||||
|
||||
velocity[0] = crandom() * GLASS_VELOCITY;
|
||||
velocity[1] = crandom() * GLASS_VELOCITY;
|
||||
velocity[2] = GLASS_JUMP + crandom() * GLASS_VELOCITY;
|
||||
//Elder: added
|
||||
rotation[0] = crandom() * GLASS_VELOCITY;
|
||||
rotation[1] = crandom() * GLASS_VELOCITY;
|
||||
rotation[2] = crandom() * GLASS_VELOCITY;
|
||||
switch (value) {
|
||||
case 1:
|
||||
// If our random number was 1, generate the 1st shard piece
|
||||
CG_LaunchGlass( origin, velocity, debris1 );
|
||||
CG_LaunchGlass( origin, velocity, rotation, debris1 );
|
||||
break;
|
||||
case 2:
|
||||
CG_LaunchGlass( origin, velocity, debris2 );
|
||||
CG_LaunchGlass( origin, velocity, rotation, debris2 );
|
||||
break;
|
||||
case 3:
|
||||
CG_LaunchGlass( origin, velocity, debris3 );
|
||||
CG_LaunchGlass( origin, velocity, rotation, debris3 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1002,10 +1002,25 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
|
||||
case EV_RQ3_SOUND:
|
||||
DEBUGNAME("EV_RQ3_SOUND");
|
||||
//CG_Printf("EV_RQ3_SOUND\n");
|
||||
if (es->eventParm == 0) {
|
||||
//CG_Printf("EV_RQ3_SOUND: Kick\n");
|
||||
trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.kickSound);
|
||||
//CG_Printf("EV_RQ3_SOUND: %d\n", es->eventParm);
|
||||
switch (es->eventParm) {
|
||||
case RQ3_SOUND_KICK:
|
||||
//CG_Printf("EV_RQ3_SOUND: Kick\n");
|
||||
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.kickSound);
|
||||
break;
|
||||
case RQ3_SOUND_HEADSHOT:
|
||||
//CG_Printf("EV_RQ3_SOUND: Headshot\n");
|
||||
//Elder: extra blood - synched with sound
|
||||
//CG_Bleed( position, es->number );
|
||||
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.headshotSound);
|
||||
break;
|
||||
case RQ3_SOUND_LCA:
|
||||
//CG_Printf("EV_RQ3_SOUND: Lights, Camera, Action\n");
|
||||
//Global sound
|
||||
trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.media.lcaSound);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1128,7 +1143,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
case EV_PAIN:
|
||||
// local player sounds are triggered in CG_CheckLocalSounds,
|
||||
// so ignore events on the player
|
||||
DEBUGNAME("EV_PAIN");
|
||||
DEBUGNAME("EV_PAIN");/*
|
||||
if ( es->eventParm == -99999 ) {
|
||||
CG_Printf("EV_PAIN: Headshot\n");
|
||||
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.headshotSound);
|
||||
}*/
|
||||
if ( cent->currentState.number != cg.snap->ps.clientNum ) {
|
||||
CG_PainEvent( cent, es->eventParm );
|
||||
}
|
||||
|
|
|
@ -826,6 +826,9 @@ typedef struct {
|
|||
|
||||
// sounds
|
||||
sfxHandle_t kickSound; //Elder: kick sound
|
||||
sfxHandle_t headshotSound; //Elder: splat
|
||||
sfxHandle_t lcaSound; //Elder: lights, camera, action!
|
||||
sfxHandle_t lensSound; //Elder: sniper lens zoom
|
||||
sfxHandle_t quadSound;
|
||||
sfxHandle_t tracerSound;
|
||||
sfxHandle_t selectSound;
|
||||
|
|
|
@ -612,8 +612,12 @@ static void CG_RegisterSounds( void ) {
|
|||
cgs.media.gibBounce2Sound = trap_S_RegisterSound( "sound/player/gibimp2.wav", qfalse );
|
||||
cgs.media.gibBounce3Sound = trap_S_RegisterSound( "sound/player/gibimp3.wav", qfalse );
|
||||
|
||||
//Elder: kick sound
|
||||
//Elder: RQ3 sounds
|
||||
cgs.media.kickSound = trap_S_RegisterSound( "sound/misc/kick.wav", qfalse);
|
||||
cgs.media.lensSound = trap_S_RegisterSound( "sound/misc/lens.wav", qfalse);
|
||||
cgs.media.headshotSound = trap_S_RegisterSound( "sound/misc/headshot.wav", qfalse);
|
||||
cgs.media.lcaSound = trap_S_RegisterSound( "sound/misc/lca.wav", qfalse);
|
||||
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
cgs.media.useInvulnerabilitySound = trap_S_RegisterSound( "sound/items/invul_activate.wav", qfalse );
|
||||
|
|
|
@ -433,7 +433,8 @@ CG_GrenadeTrail
|
|||
==========================
|
||||
*/
|
||||
static void CG_GrenadeTrail( centity_t *ent, const weaponInfo_t *wi ) {
|
||||
CG_RocketTrail( ent, wi );
|
||||
//Elder: removed smoke trail
|
||||
//CG_RocketTrail( ent, wi );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1724,6 +1725,8 @@ void CG_Weapon_f( void ) {
|
|||
if ( trap_Argc() == 1 ) {
|
||||
//Elder: if SSG, use local zooming THEN forward to server for stats
|
||||
if (cg.snap->ps.weapon == WP_SSG3000) {
|
||||
//trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_ITEM, cgs.media.lensSound);
|
||||
trap_S_StartLocalSound( cgs.media.lensSound, CHAN_ITEM);
|
||||
CG_RXN_Zoom();
|
||||
}
|
||||
|
||||
|
|
|
@ -1548,6 +1548,7 @@ static void PM_FinishWeaponChange( void ) {
|
|||
int weapon;
|
||||
|
||||
weapon = pm->cmd.weapon;
|
||||
|
||||
if ( weapon < WP_NONE || weapon >= WP_NUM_WEAPONS ) {
|
||||
weapon = WP_NONE;
|
||||
}
|
||||
|
@ -1688,7 +1689,7 @@ static void PM_Weapon( void ) {
|
|||
PM_StartTorsoAnim( TORSO_ATTACK );
|
||||
}
|
||||
|
||||
//Elder: works great server side, but client needs to predict it
|
||||
// Elder: the client side portion is in
|
||||
// Homer: if weapon can set to be burst mode, check for burst value
|
||||
// M4
|
||||
if ( pm->ps->weapon == WP_M4 && pm->ps->stats[STAT_BURST] > 2 ) {
|
||||
|
@ -1717,10 +1718,11 @@ static void PM_Weapon( void ) {
|
|||
// take an ammo away if not infinite
|
||||
if ( pm->ps->ammo[ pm->ps->weapon ] != -1 ) {
|
||||
//Blaze: Dont remove ammo for knife
|
||||
//Elder: can't access throwKnife?
|
||||
//if ( pm->ps->weapon != WP_KNIFE)
|
||||
//Elder: don't remove ammo if slashing knife
|
||||
if ( !(pm->ps->weapon == WP_KNIFE && pm->ps->stats[STAT_KNIFE] == RQ3_KNIFE_SLASH) ) {
|
||||
//G_Printf("Taking away ammo\n");
|
||||
pm->ps->ammo[ pm->ps->weapon ]--;
|
||||
|
||||
}
|
||||
//Elder: remove one more bullet/shell if handcannon/akimbo
|
||||
if (pm->ps->weapon == WP_HANDCANNON || pm->ps->weapon == WP_AKIMBO) {
|
||||
pm->ps->ammo[ pm->ps->weapon ]--;
|
||||
|
|
|
@ -94,6 +94,34 @@
|
|||
|
||||
//Elder: confused?
|
||||
|
||||
//Elder: used for STAT_KNIFE ...
|
||||
#define RQ3_KNIFE_SLASH 0
|
||||
#define RQ3_KNIFE_THROW 1
|
||||
|
||||
//Elder: from Action source, but changed defined names a bit
|
||||
#define RQ3_PISTOL_NAME "MK23 Pistol"
|
||||
#define RQ3_MP5_NAME "MP5/10 Submachinegun"
|
||||
#define RQ3_M4_NAME "M4 Assault Rifle"
|
||||
#define RQ3_M3_NAME "M3 Super 90 Assault Shotgun"
|
||||
#define RQ3_HANDCANNON_NAME "Handcannon"
|
||||
#define RQ3_SSG3000_NAME "Sniper Rifle"
|
||||
#define RQ3_AKIMBO_NAME "Dual MK23 Pistols"
|
||||
#define RQ3_KNIFE_NAME "Combat Knife"
|
||||
#define RQ3_GRENADE_NAME "M26 Fragmentation Grenade"
|
||||
|
||||
#define RQ3_SILENCER_NAME "Silencer"
|
||||
#define RQ3_SLIPPERS_NAME "Stealth Slippers"
|
||||
#define RQ3_BANDOLIER_NAME "Bandolier"
|
||||
#define RQ3_KEVLAR_NAME "Kevlar Vest"
|
||||
#define RQ3_LASER_NAME "Lasersight"
|
||||
|
||||
//Elder: sound events for EV_RQ3_SOUND
|
||||
#define RQ3_SOUND_KICK 0
|
||||
#define RQ3_SOUND_HEADSHOT 1
|
||||
#define RQ3_SOUND_KNIFEDEATH 2
|
||||
#define RQ3_SOUND_LCA 3 //lights, camera, action!
|
||||
|
||||
|
||||
|
||||
//
|
||||
// config strings are a general means of communicating variable length strings
|
||||
|
@ -251,7 +279,7 @@ typedef enum {
|
|||
STAT_PERSISTANT_POWERUP,
|
||||
#endif
|
||||
STAT_WEAPONS, // 16 bit fields
|
||||
STAT_ARMOR,
|
||||
STAT_ARMOR, // Elder: technically we don't need this anymore - maybe for vest
|
||||
STAT_DEAD_YAW, // look this direction when dead (FIXME: get rid of?)
|
||||
// Begin Duffman
|
||||
STAT_CLIPS, // Num Clips player currently has
|
||||
|
@ -264,6 +292,7 @@ typedef enum {
|
|||
STAT_UNIQUEWEAPONS,
|
||||
STAT_FALLDAMAGE,
|
||||
STAT_BANDAGE, //Elder: holds bandage need
|
||||
STAT_KNIFE, //Elder: knife throwing -- wasteful? then later rename STAT_RQ3 or something and use bits
|
||||
} statIndex_t;
|
||||
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ qboolean JumpKick( gentity_t *ent )
|
|||
damage, DAMAGE_NO_LOCATIONAL, MOD_KICK );
|
||||
|
||||
//Elder: Our set of locally called sounds
|
||||
G_AddEvent ( ent, EV_RQ3_SOUND, 0);
|
||||
G_AddEvent ( ent, EV_RQ3_SOUND, RQ3_SOUND_KICK);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
@ -151,10 +151,30 @@ void P_DamageFeedback( gentity_t *player ) {
|
|||
client->ps.damageYaw = angles[YAW]/360.0 * 256;
|
||||
}
|
||||
|
||||
// play an apropriate pain sound
|
||||
|
||||
/*
|
||||
G_Printf("Lasthurt: %d, Head: %d, Face: %d, And-Op: %d\n",
|
||||
client->lasthurt_location,
|
||||
LOCATION_HEAD, LOCATION_FACE,
|
||||
client->lasthurt_location & ~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT) );
|
||||
*/
|
||||
|
||||
// play an appropriate pain sound
|
||||
if ( (level.time > player->pain_debounce_time) && !(player->flags & FL_GODMODE) ) {
|
||||
player->pain_debounce_time = level.time + 700;
|
||||
G_AddEvent( player, EV_PAIN, player->health );
|
||||
|
||||
switch ( client->lasthurt_location &
|
||||
~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT) ) {
|
||||
//Elder: headshot sound
|
||||
case LOCATION_HEAD:
|
||||
case LOCATION_FACE:
|
||||
G_AddEvent ( player, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT);
|
||||
break;
|
||||
default:
|
||||
G_AddEvent( player, EV_PAIN, player->health );
|
||||
break;
|
||||
}
|
||||
|
||||
client->ps.damageEvent++;
|
||||
}
|
||||
|
||||
|
@ -559,6 +579,8 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
|
|||
ent->client->bleed_remain = 0;
|
||||
ent->client->bleeding = 0;
|
||||
ent->client->bleedtick = 0;
|
||||
//Elder: added
|
||||
ent->client->isBandaging = qfalse;
|
||||
// ent->client->ps.weaponTime += 2500;
|
||||
// ent->client->ps.weaponstate = WEAPON_RAISING;
|
||||
// ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | TORSO_RAISE;
|
||||
|
@ -840,25 +862,40 @@ void ThrowWeapon( gentity_t *ent )
|
|||
|
||||
//if( client->ps.weapon == WP_KNIFE || client->ps.weapon == WP_PISTOL || client->ps.weapon == WP_GRENADE || ( ucmd->buttons & BUTTON_ATTACK ))
|
||||
// return;
|
||||
//Elder: better change conditional to include bandaging case... re: "You are too busy bandaging..."
|
||||
if (ucmd->buttons & BUTTON_ATTACK) return;
|
||||
weap=0;
|
||||
|
||||
//Still firing
|
||||
if (ucmd->buttons & BUTTON_ATTACK) {
|
||||
return;
|
||||
}
|
||||
//Elder: Bandaging case
|
||||
else if (client->isBandaging) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\""));
|
||||
return;
|
||||
}
|
||||
|
||||
weap = 0;
|
||||
if (client->ps.stats[STAT_UNIQUEWEAPONS] > 0)
|
||||
{
|
||||
weap = client->ps.stats[STAT_WEAPONS];
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_M4) )== (1 << WP_M4)) weap = WP_M4;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_M3) )== (1 << WP_M3)) weap = WP_M3;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_MP5) )== (1 << WP_MP5)) weap = WP_MP5;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_HANDCANNON) )== (1 << WP_HANDCANNON)) weap = WP_HANDCANNON;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_SSG3000) )== (1 << WP_SSG3000)) weap = WP_SSG3000;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_M4) ) == (1 << WP_M4))
|
||||
weap = WP_M4;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_M3) ) == (1 << WP_M3))
|
||||
weap = WP_M3;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_MP5) ) == (1 << WP_MP5))
|
||||
weap = WP_MP5;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_HANDCANNON) ) == (1 << WP_HANDCANNON))
|
||||
weap = WP_HANDCANNON;
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_SSG3000) ) == (1 << WP_SSG3000))
|
||||
weap = WP_SSG3000;
|
||||
if (weap == 0 ) return;
|
||||
xr_item = BG_FindItemForWeapon( weap );
|
||||
|
||||
//Elder: do you really want to do this?
|
||||
client->ps.ammo[ weap ] = 0;
|
||||
|
||||
client->ps.stats[STAT_WEAPONS] &= ~( 1 << weap);
|
||||
//Elder: moved up
|
||||
client->ps.weapon = WP_PISTOL;
|
||||
client->ps.ammo[ weap ] = 0;
|
||||
|
||||
client->ps.stats[STAT_WEAPONS] &= ~( 1 << weap);
|
||||
//client->ps.weapon = WP_PISTOL;
|
||||
xr_drop= dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM );
|
||||
xr_drop->count= -1; // XRAY FMJ 0 is already taken, -1 means no ammo
|
||||
client->ps.stats[STAT_UNIQUEWEAPONS]--;
|
||||
|
|
|
@ -1222,6 +1222,11 @@ void ClientSpawn(gentity_t *ent) {
|
|||
// Hawkins reset zoomed flag
|
||||
client->zoomed=0;
|
||||
|
||||
//Elder: knife reset/initialize
|
||||
client->ps.stats[STAT_KNIFE] = RQ3_KNIFE_SLASH;
|
||||
|
||||
//Elder: reset isBandaging flag
|
||||
client->isBandaging = qfalse;
|
||||
|
||||
// set default animations
|
||||
client->ps.torsoAnim = TORSO_STAND;
|
||||
|
|
|
@ -1603,6 +1603,8 @@ void Cmd_Bandage (gentity_t *ent)
|
|||
|
||||
ent->client->ps.weaponTime += 6000;
|
||||
ent->client->bleedtick = 4;
|
||||
//Elder: added
|
||||
ent->client->isBandaging = qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1625,6 +1627,12 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
int weapon;
|
||||
int ammotoadd;
|
||||
int delay;
|
||||
|
||||
//Elder: added
|
||||
if (ent->client->isBandaging) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\""));
|
||||
return;
|
||||
}
|
||||
|
||||
weapon = ent->client->ps.weapon;
|
||||
//Elder: changed to new function
|
||||
|
@ -1892,10 +1900,16 @@ void Cmd_Weapon(gentity_t *ent)
|
|||
case WP_KNIFE:
|
||||
// toggle throwing/slashing
|
||||
ent->client->throwKnife = !(ent->client->throwKnife);
|
||||
if (ent->client->throwKnife)
|
||||
if (ent->client->throwKnife) {
|
||||
//Elder: added
|
||||
ent->client->ps.stats[STAT_KNIFE] = RQ3_KNIFE_THROW;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Switched to throwing.\n\""));
|
||||
else
|
||||
}
|
||||
else {
|
||||
//Elder: we're gonna use this to flag throw or slash with the knife
|
||||
ent->client->ps.stats[STAT_KNIFE] = RQ3_KNIFE_SLASH;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Switched to slashing.\n\""));
|
||||
}
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
// nothing
|
||||
|
|
|
@ -59,6 +59,8 @@ void TossClientItems( gentity_t *self ) {
|
|||
float angle;
|
||||
int i;
|
||||
gentity_t *drop;
|
||||
//Elder: added
|
||||
int weaponInventory;
|
||||
|
||||
// drop the weapon if not a gauntlet or machinegun
|
||||
weapon = self->s.weapon;
|
||||
|
@ -78,14 +80,60 @@ void TossClientItems( gentity_t *self ) {
|
|||
}
|
||||
}
|
||||
*/
|
||||
//Blaze: dont need this check as we will be droping everyhing, but just changed WP_MACHINEGUN to WP_PISTOL just in case, also removed grappling hook check
|
||||
if ( weapon > WP_PISTOL && self->client->ps.ammo[ weapon ] ) {
|
||||
//Blaze: dont need this check as we will be dropping everyhing, but just changed WP_MACHINEGUN to WP_PISTOL just in case, also removed grappling hook check
|
||||
//Elder:
|
||||
//don't drop akimbos (maybe drop another pistol), knives, or grenades
|
||||
//and don't drop knife - that's handled later
|
||||
//Maybe we should check the player's weapon inventory instead
|
||||
/*
|
||||
if ( weapon != WP_GRENADE && weapon != WP_AKIMBO &&
|
||||
weapon != WP_KNIFE && weapon > WP_PISTOL && self->client->ps.ammo[ weapon ] ) {
|
||||
// find the item type for this weapon
|
||||
item = BG_FindItemForWeapon( weapon );
|
||||
|
||||
// spawn the item
|
||||
Drop_Item( self, item, 0 );
|
||||
}
|
||||
*/
|
||||
|
||||
//Elder: run through player STAT_WEAPONS and drop any unique weapons
|
||||
//That way, we can also account for the bandolier automatically
|
||||
//BTW, that means no cheating to get all weapons or it'll spawn mad!!
|
||||
weaponInventory = self->client->ps.stats[STAT_WEAPONS];
|
||||
|
||||
if ( (weaponInventory & (1 << WP_M3) ) == (1 << WP_M3) ) {
|
||||
item = BG_FindItemForWeapon( WP_M3 );
|
||||
Drop_Item( self, item, 0);
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_M4) ) == (1 << WP_M4) ) {
|
||||
item = BG_FindItemForWeapon( WP_M4 );
|
||||
Drop_Item( self, item, 0);
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_MP5) ) == (1 << WP_MP5) ) {
|
||||
item = BG_FindItemForWeapon( WP_MP5 );
|
||||
Drop_Item( self, item, 0);
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_HANDCANNON) ) == (1 << WP_HANDCANNON) ) {
|
||||
item = BG_FindItemForWeapon( WP_HANDCANNON );
|
||||
Drop_Item( self, item, 0);
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_SSG3000) ) == (1 << WP_SSG3000) ) {
|
||||
item = BG_FindItemForWeapon( WP_SSG3000 );
|
||||
Drop_Item( self, item, 0);
|
||||
}
|
||||
|
||||
//Elder: Always drop the pistol
|
||||
item = BG_FindItemForWeapon( WP_PISTOL );
|
||||
Drop_Item (self, item, 0);
|
||||
//Elder: drop a knife if player has at least one
|
||||
if ( self->client->ps.ammo[ WP_KNIFE ] > 0) {
|
||||
item = BG_FindItemForWeapon( WP_KNIFE );
|
||||
Drop_Item (self, item, 0);
|
||||
}
|
||||
|
||||
// drop all the powerups if not in teamplay
|
||||
if ( g_gametype.integer != GT_TEAM ) {
|
||||
|
@ -450,6 +498,8 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
self->client->bleeding = 0;
|
||||
//targ->client->bleedcount = 0;
|
||||
self->client->bleed_remain = 0;
|
||||
//Elder: added;
|
||||
self->client->isBandaging = qfalse;
|
||||
}
|
||||
if ( self->client->ps.pm_type == PM_DEAD ) {
|
||||
return;
|
||||
|
@ -991,6 +1041,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
|
||||
vec3_t bulletAngle;
|
||||
|
||||
//Elder: added for M3 and Pistols
|
||||
vec_t dist;
|
||||
vec3_t line;
|
||||
|
||||
int clientHeight;
|
||||
int clientFeetZ;
|
||||
|
@ -1021,6 +1074,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !inflictor ) {
|
||||
inflictor = &g_entities[ENTITYNUM_WORLD];
|
||||
}
|
||||
|
@ -1043,6 +1097,34 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
return;
|
||||
}
|
||||
|
||||
//Elder: from action source
|
||||
// damage reduction for shotgun and mk23/akimbo
|
||||
// if far away, reduce it to original action levels
|
||||
//Note: doesn't handle shots on non-clients (e.g. breakables)
|
||||
if (targ->client && inflictor->client) {
|
||||
if ( mod == MOD_M3) {
|
||||
VectorSubtract(targ->client->ps.origin, inflictor->client->ps.origin, line );
|
||||
dist = VectorLength( line );
|
||||
if ( dist > 450.0 ) {
|
||||
damage = damage - 2;
|
||||
}
|
||||
}
|
||||
else if ( mod == MOD_PISTOL || mod == MOD_AKIMBO ) {
|
||||
VectorSubtract(targ->client->ps.origin, inflictor->client->ps.origin, line );
|
||||
dist = VectorLength( line );
|
||||
// G_Printf("Distance from target: %f\n", dist);
|
||||
if ( dist > 600.0 && dist < 1400.0 ) {
|
||||
// G_Printf("Damage reduced to 2/3\n");
|
||||
damage = (int)(damage * 2/3);
|
||||
}
|
||||
//Elder: added >= ... 1400.0 is a magic number for perfect shots if not in :)
|
||||
else if ( dist >= 1400.0 ) {
|
||||
// G_Printf("Damage reduced to 1/2\n");
|
||||
damage = (int)(damage * 1/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Blaze: If we shot a breakable item subtract the damage from its health and try to break it
|
||||
if ( targ->s.eType == ET_BREAKABLE ) {
|
||||
targ->health -= damage;
|
||||
|
@ -1080,6 +1162,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
VectorNormalize(dir);
|
||||
}
|
||||
|
||||
//Elder: this is a simplifed knockback calc - Action has a radically different one.
|
||||
knockback = damage;
|
||||
if ( knockback > 200 ) {
|
||||
knockback = 200;
|
||||
|
@ -1104,6 +1187,8 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
|
||||
mass = 200;
|
||||
|
||||
//Elder: Q2 uses a hardcoded value of 500 for non-rocket jumps
|
||||
//Q3 uses g_knockback.value ... default 1000
|
||||
VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
|
||||
VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);
|
||||
|
||||
|
@ -1330,6 +1415,11 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
{
|
||||
trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the head.\n\"", targ->client->pers.netname));
|
||||
trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\""));
|
||||
//Elder: headshot sound moved to g_active.c
|
||||
//if ( mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN ) {
|
||||
//G_Printf("play headshot sound\n");
|
||||
//G_AddEvent ( targ, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT);
|
||||
//}
|
||||
take *= 1.8; //+ 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1337,6 +1427,11 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
{
|
||||
trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the head.\n\"", targ->client->pers.netname));
|
||||
trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\""));
|
||||
//Elder: headshot sound - no events here
|
||||
//if ( mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN ) {
|
||||
//G_Printf("play headshot sound\n");
|
||||
//G_AddEvent ( targ, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT);
|
||||
//}
|
||||
take *= 1.8; //+ 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1409,12 +1504,13 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
|
||||
if ( targ->health <= 0 ) {
|
||||
if ( client )
|
||||
targ->flags |= FL_NO_KNOCKBACK;
|
||||
|
||||
if (targ->health < -999)
|
||||
//Elder: removed so we can play with bodies :)
|
||||
//if ( client ) {
|
||||
//targ->flags |= FL_NO_KNOCKBACK;
|
||||
//}
|
||||
if (targ->health < -999) {
|
||||
targ->health = -999;
|
||||
|
||||
}
|
||||
targ->enemy = attacker;
|
||||
targ->die (targ, inflictor, attacker, take, mod);
|
||||
return;
|
||||
|
|
|
@ -321,7 +321,8 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
|
|||
//Someone can optimize this code later, but for now, it works.
|
||||
if ( !(other->client->ps.stats[STAT_WEAPONS] & (1 << WP_AKIMBO) ) ) {
|
||||
//give akimbo
|
||||
G_Printf("Dual MK23 pistols\n");
|
||||
//G_Printf("Dual MK23 pistols\n");
|
||||
trap_SendServerCommand( other-g_entities, va("print \"%s^7\n\"", RQ3_AKIMBO_NAME) );
|
||||
other->client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_AKIMBO );
|
||||
other->client->ps.ammo[WP_AKIMBO] = other->client->ps.ammo[WP_PISTOL] + RQ3_PISTOL_AMMO;
|
||||
ammotoadd = other->client->ps.ammo[WP_PISTOL];
|
||||
|
@ -329,7 +330,8 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
|
|||
//Elder: Already have akimbo - technically should have pistol
|
||||
else if (other->client->numClips[ WP_PISTOL ] < 2) {
|
||||
//give an extra clip - make < 2 + 2 * hasBandolier(0/1) or something for bando when it's in
|
||||
G_Printf("Picked up an extra clip\n");
|
||||
//G_Printf("Picked up an extra clip\n");
|
||||
trap_SendServerCommand( other-g_entities, va("print \"Picked up an extra clip^7\n\"" ) );
|
||||
other->client->numClips[ WP_PISTOL ]++;
|
||||
other->client->numClips[ WP_AKIMBO ]++;
|
||||
ammotoadd = other->client->ps.ammo[WP_PISTOL];
|
||||
|
@ -565,6 +567,9 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
|
||||
predict = other->client->pers.predictItemPickup;
|
||||
|
||||
//Elder: should check if the item was recently thrown ... if it was, then
|
||||
//don't allow it to be picked up ... or something like that
|
||||
|
||||
// call the item-specific pickup function
|
||||
switch( ent->item->giType ) {
|
||||
case IT_WEAPON:
|
||||
|
@ -623,10 +628,10 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
break;
|
||||
}
|
||||
//Blaze: Check and see if it's a unique weapon, and if so make sure they dont have too many already
|
||||
if (ent->item->giTag == WP_MP5 || ent->item->giTag == WP_M4 || ent->item->giTag == WP_M3 || ent->item->giTag == WP_HANDCANNON || ent->item->giTag == WP_SSG3000)
|
||||
{
|
||||
if (other->client->ps.stats[STAT_UNIQUEWEAPONS] >= g_rxn_maxweapons.integer)
|
||||
{
|
||||
if (ent->item->giTag == WP_MP5 || ent->item->giTag == WP_M4 ||
|
||||
ent->item->giTag == WP_M3 || ent->item->giTag == WP_HANDCANNON ||
|
||||
ent->item->giTag == WP_SSG3000) {
|
||||
if (other->client->ps.stats[STAT_UNIQUEWEAPONS] >= g_rxn_maxweapons.integer) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -634,7 +639,8 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
respawn = Pickup_Weapon(ent, other);
|
||||
respawn = -1; //Dont respawn weapons
|
||||
|
||||
if (ent->item->giTag == WP_GRENADE)
|
||||
//Elder: added pistol condition
|
||||
if (ent->item->giTag == WP_GRENADE || ent->item->giTag == WP_PISTOL)
|
||||
{
|
||||
// G_Printf("Grenade Pickedup (%d)\n",respawn);
|
||||
respawn = 30;
|
||||
|
@ -814,6 +820,7 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity, int xr_fla
|
|||
G_SetOrigin( dropped, origin );
|
||||
dropped->s.pos.trType = TR_GRAVITY;
|
||||
dropped->s.pos.trTime = level.time;
|
||||
//Elder: should change to a constant velocity for weapons
|
||||
VectorCopy( velocity, dropped->s.pos.trDelta );
|
||||
|
||||
dropped->s.eFlags |= EF_BOUNCE_HALF;
|
||||
|
@ -825,7 +832,19 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity, int xr_fla
|
|||
dropped->think = Team_DroppedFlagThink;
|
||||
dropped->nextthink = level.time + 30000;
|
||||
Team_CheckDroppedItem( dropped );
|
||||
} else { // auto-remove after 30 seconds
|
||||
}
|
||||
|
||||
//Elder: Reaction Unique Weapons in deathmatch - respawn in 30 seconds
|
||||
//Don't forget to condition it when we get teamplay in
|
||||
else if ( item->giType == IT_WEAPON &&
|
||||
item->giTag != WP_GRENADE && item->giTag != WP_PISTOL &&
|
||||
item->giTag != WP_AKIMBO && item->giTag != WP_KNIFE ) {
|
||||
dropped->think = RQ3_DroppedWeaponThink;
|
||||
//Elder: don't want to wait forever while testing :)
|
||||
dropped->nextthink = level.time + RQ3_RESPAWNTIME_DEFAULT;
|
||||
}
|
||||
|
||||
else { // auto-remove after 30 seconds
|
||||
dropped->think = G_FreeEntity;
|
||||
dropped->nextthink = level.time + 30000;
|
||||
}
|
||||
|
@ -1275,3 +1294,115 @@ void G_RunItem( gentity_t *ent ) {
|
|||
G_BounceItem( ent, &tr );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Added by Elder
|
||||
|
||||
RQ3_DroppedWeaponThink
|
||||
Get the item name from the entity and forward
|
||||
it to RQ3_ResetWeapon to find and respawn
|
||||
|
||||
This is like respawning CTF flags in baseq3
|
||||
==============
|
||||
*/
|
||||
void RQ3_DroppedWeaponThink(gentity_t *ent) {
|
||||
int weaponNum = WP_NONE;
|
||||
|
||||
switch (ent->item->giTag) {
|
||||
case WP_MP5:
|
||||
case WP_M4:
|
||||
case WP_M3:
|
||||
case WP_HANDCANNON:
|
||||
case WP_SSG3000:
|
||||
weaponNum = ent->item->giTag;
|
||||
break;
|
||||
|
||||
case WP_PISTOL:
|
||||
case WP_KNIFE:
|
||||
case WP_AKIMBO:
|
||||
case WP_GRENADE:
|
||||
default:
|
||||
//Elder: shouldn't have to come here
|
||||
G_Printf("DroppedWeaponThink: Out of range weapon %d\n", ent->item->giTag);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
//Elder: flag the item we want to remove
|
||||
ent->flags |= FL_RQ3_JUNKITEM;
|
||||
RQ3_ResetWeapon( weaponNum );
|
||||
// Reset Weapon will delete this entity
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Added by Elder
|
||||
|
||||
RQ3_ResetWeapon
|
||||
Respawn a unique weapon
|
||||
|
||||
Similar to CTF Flag reset
|
||||
A little quirky - maybe someone can fine-tune this!
|
||||
Bugs:
|
||||
The weapon may not return to its original location if there is
|
||||
more than one of the type. It just finds the closest empty spot
|
||||
and respawns it.
|
||||
==============
|
||||
*/
|
||||
void RQ3_ResetWeapon( int weapon ) {
|
||||
char *c;
|
||||
gentity_t *ent; //, *rent = NULL;
|
||||
int numRespawned = 0;
|
||||
int numRemoved = 0;
|
||||
|
||||
switch (weapon) {
|
||||
case WP_M3:
|
||||
c = "weapon_m3";
|
||||
break;
|
||||
case WP_M4:
|
||||
c = "weapon_m4";
|
||||
break;
|
||||
case WP_MP5:
|
||||
c = "weapon_mp5";
|
||||
break;
|
||||
case WP_SSG3000:
|
||||
c = "weapon_ssg3000";
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
c = "weapon_handcannon";
|
||||
break;
|
||||
default:
|
||||
//Elder: shouldn't be here
|
||||
G_Printf("RQ3_ResetWeapon: Received bad weapon: %d\n", weapon);
|
||||
break;
|
||||
}
|
||||
|
||||
ent = NULL;
|
||||
//Elder: here's the solution and another problem to RQ3 weapon respawns
|
||||
while ((ent = G_Find (ent, FOFS(classname), c)) != NULL) {
|
||||
//if it's a dropped copy, free it
|
||||
//if (ent->flags & FL_DROPPED_ITEM) {
|
||||
//Elder: only release if it's past the
|
||||
//default respawn time and is flagged
|
||||
if (numRemoved < 1 &&
|
||||
(ent->flags & FL_DROPPED_ITEM) == FL_DROPPED_ITEM &&
|
||||
(ent->flags & FL_RQ3_JUNKITEM) == FL_RQ3_JUNKITEM &&
|
||||
level.time - ent->timestamp >= RQ3_RESPAWNTIME_DEFAULT) {
|
||||
G_FreeEntity(ent);
|
||||
numRemoved++;
|
||||
}
|
||||
else {
|
||||
//rent = ent;
|
||||
//Elder: only respawn if it's a "taken" item
|
||||
//It won't necessarily respawn the gun in its original spot if there's
|
||||
//more than one, but it will put it in an empty location... good enough?
|
||||
if ( (ent->r.svFlags & SVF_NOCLIENT) == SVF_NOCLIENT &&
|
||||
(ent->s.eFlags & EF_NODRAW) == EF_NODRAW &&
|
||||
ent->r.contents == 0 && numRespawned < 1) {
|
||||
RespawnItem(ent);
|
||||
numRespawned++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return rent;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
//Elder: err - this looks funny... should it be 0x00010000 ?
|
||||
//#define FL_THROWN_ITEM 0x00016000 // XRAY FMJ weapon throwing
|
||||
#define FL_THROWN_ITEM 0x00010000 // XRAY FMJ weapon throwing
|
||||
#define FL_RQ3_JUNKITEM 0x00020000 // Elder: the item we want to remove
|
||||
|
||||
// movers are things like doors, plats, buttons, etc
|
||||
typedef enum {
|
||||
|
@ -60,6 +61,8 @@ typedef enum {
|
|||
|
||||
#define SP_PODIUM_MODEL "models/mapobjects/podium/podium4.md3"
|
||||
|
||||
#define RQ3_RESPAWNTIME_DEFAULT 30000 // Elder: time for weapons to respawn
|
||||
|
||||
//============================================================================
|
||||
|
||||
typedef struct gentity_s gentity_t;
|
||||
|
@ -327,8 +330,8 @@ struct gclient_s {
|
|||
int bleedloc; //Blaze: Where are we bleeding
|
||||
vec3_t bleedloc_offset;// Blaze: location of bleeding (from origin)
|
||||
vec3_t bleednorm;
|
||||
//qboolean isbleeding;//Blaze: is client bleeding
|
||||
int legDamage;//Blaze: Client has leg damage
|
||||
//qboolean isBleeding;//Blaze: is client bleeding
|
||||
int legDamage;//Blaze: Client has leg damage - holds number of hits too
|
||||
int bleedtick;//Blaze: Holds # of seconds till bleeding stops.
|
||||
//Elder: server only needs to know for sniper spread - ARGH
|
||||
int zoomed; // Hawkins (SSG zoom)
|
||||
|
@ -341,6 +344,7 @@ struct gclient_s {
|
|||
int m4_3rb; // M4 to 3rb
|
||||
int grenRange; // range to throw grenade (short/medium/long)
|
||||
int throwKnife; // knife to throwing
|
||||
qboolean isBandaging; //Elder: player in the process of bandaging
|
||||
// end Homer
|
||||
#ifdef MISSIONPACK
|
||||
gentity_t *persistantPowerup;
|
||||
|
@ -503,6 +507,11 @@ void ClearRegisteredItems( void );
|
|||
void RegisterItem( gitem_t *item );
|
||||
void SaveRegisteredItems( void );
|
||||
|
||||
//Elder: added
|
||||
void RQ3_DroppedWeaponThink(gentity_t *ent);
|
||||
void RQ3_ResetWeapon( int weapon );
|
||||
|
||||
|
||||
//
|
||||
// g_utils.c
|
||||
//
|
||||
|
|
|
@ -67,7 +67,8 @@ void G_ExplodeMissile( gentity_t *ent ) {
|
|||
g_entities[ent->r.ownerNum].client->accuracy_hits++;
|
||||
}
|
||||
}
|
||||
G_Printf("exploding knife\n");
|
||||
//Elder: huhh?
|
||||
//G_Printf("exploding knife\n");
|
||||
trap_LinkEntity( ent );
|
||||
}
|
||||
|
||||
|
@ -255,14 +256,25 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
|||
#endif
|
||||
other = &g_entities[trace->entityNum];
|
||||
|
||||
// check for bounce
|
||||
if ( !other->takedamage &&
|
||||
//Elder: no grenade explosion on impact
|
||||
if ( ent->s.weapon == WP_GRENADE &&
|
||||
( ent->s.eFlags & ( EF_BOUNCE | EF_BOUNCE_HALF ) ) ) {
|
||||
G_BounceMissile( ent, trace );
|
||||
G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
//Elder: regular Q3 grenades
|
||||
// check for bounce
|
||||
/*
|
||||
if ( !other->takedamage &&
|
||||
( ent->s.eFlags & ( EF_BOUNCE | EF_BOUNCE_HALF ) ) ) {
|
||||
G_BounceMissile( ent, trace );
|
||||
G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 );
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
if ( other->takedamage ) {
|
||||
if ( ent->s.weapon != WP_PROX_LAUNCHER ) {
|
||||
|
|
|
@ -5,6 +5,27 @@
|
|||
|
||||
#include "g_local.h"
|
||||
|
||||
//Blaze: reaction weapon damage ratings & weapon spreads
|
||||
//Elder: moved to the top
|
||||
#define PISTOL_DAMAGE 90
|
||||
#define MP5_DAMAGE 55
|
||||
#define M4_DAMAGE 90
|
||||
#define M3_DAMAGE 17
|
||||
//Elder: wrong name
|
||||
//#define SHOTGUN_DAMAGE 17
|
||||
#define HANDCANNON_DAMAGE 20
|
||||
#define SNIPER_DAMAGE 250
|
||||
#define AKIMBO_DAMAGE 90
|
||||
#define SLASH_DAMAGE 200//Shashing knife damage
|
||||
#define THROW_DAMAGE 250//Throwing Knife damage
|
||||
|
||||
#define PISTOL_SPREAD 140
|
||||
#define MP5_SPREAD 250
|
||||
#define M4_SPREAD 300
|
||||
#define SNIPER_SPREAD 425
|
||||
#define AKIMBO_SPREAD 300
|
||||
|
||||
|
||||
static float s_quadFactor;
|
||||
static vec3_t forward, right, up;
|
||||
static vec3_t muzzle;
|
||||
|
@ -135,23 +156,7 @@ void SnapVectorTowards( vec3_t v, vec3_t to ) {
|
|||
#define MACHINEGUN_SPREAD 200
|
||||
#define MACHINEGUN_DAMAGE 7
|
||||
#define MACHINEGUN_TEAM_DAMAGE 5 // wimpier MG in teamplay
|
||||
//Blaze: reaction weapon damage ratings & weapon spreads
|
||||
|
||||
#define PISTOL_DAMAGE 90
|
||||
#define MP5_DAMAGE 55
|
||||
#define M4_DAMAGE 90
|
||||
#define SHOTGUN_DAMAGE 17
|
||||
#define HANDCANNON_DAMAGE 20
|
||||
#define SNIPER_DAMAGE 250
|
||||
#define AKIMBO_DAMAGE 90
|
||||
#define SLASH_DAMAGE 200//Shashing knife damage
|
||||
#define THROW_DAMAGE 250//Throwing Knife damage
|
||||
|
||||
#define PISTOL_SPREAD 140
|
||||
#define MP5_SPREAD 250
|
||||
#define M4_SPREAD 300
|
||||
#define SNIPER_SPREAD 425
|
||||
#define AKIMBO_SPREAD 300
|
||||
|
||||
void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
|
||||
trace_t tr;
|
||||
|
@ -283,7 +288,18 @@ qboolean ShotgunPellet( vec3_t start, vec3_t end, gentity_t *ent ) {
|
|||
}
|
||||
|
||||
if ( traceEnt->takedamage) {
|
||||
damage = DEFAULT_SHOTGUN_DAMAGE; // * s_quadFactor;
|
||||
//Elder: added to discern handcannon and m3 damage
|
||||
if (ent->client && ent->client->ps.weapon == WP_HANDCANNON ) {
|
||||
//G_Printf("Firing handcannon\n");
|
||||
damage = HANDCANNON_DAMAGE;
|
||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_HANDCANNON);
|
||||
}
|
||||
else {
|
||||
//G_Printf("Firing M3\n");
|
||||
damage = M3_DAMAGE;
|
||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_M3);
|
||||
}
|
||||
//damage = DEFAULT_SHOTGUN_DAMAGE; // * s_quadFactor;
|
||||
#ifdef MISSIONPACK
|
||||
if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
|
||||
if (G_InvulnerabilityEffect( traceEnt, forward, tr.endpos, impactpoint, bouncedir )) {
|
||||
|
@ -306,7 +322,8 @@ qboolean ShotgunPellet( vec3_t start, vec3_t end, gentity_t *ent ) {
|
|||
}
|
||||
}
|
||||
#else
|
||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_SHOTGUN);
|
||||
//Elder: moved into if conditional above
|
||||
//G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_SHOTGUN);
|
||||
if( LogAccuracyHit( traceEnt, ent ) ) {
|
||||
return qtrue;
|
||||
}
|
||||
|
@ -793,80 +810,77 @@ static int knives = 0;
|
|||
|
||||
void knife_touch (gentity_t *ent, gentity_t *other,trace_t *trace)
|
||||
{
|
||||
vec3_t origin;
|
||||
gitem_t *xr_item;
|
||||
gentity_t *xr_drop;
|
||||
vec3_t origin;
|
||||
gitem_t *xr_item;
|
||||
gentity_t *xr_drop;
|
||||
|
||||
G_Printf("Knife Touched Something\n");
|
||||
|
||||
|
||||
if (other == ent->parent)
|
||||
return;
|
||||
if (other == ent->parent)
|
||||
return;
|
||||
|
||||
if (trace && (trace->surfaceFlags & SURF_SKY))
|
||||
{
|
||||
//Blaze: Get rid of the knife if it hits the sky
|
||||
if (trace && (trace->surfaceFlags & SURF_SKY)) {
|
||||
//Blaze: Get rid of the knife if it hits the sky
|
||||
// G_FreeEdict (ent);
|
||||
return;
|
||||
}
|
||||
//Elder: I think you want this
|
||||
G_FreeEntity(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->parent->client)
|
||||
{
|
||||
//Blaze: Play the clank hit noise
|
||||
// gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/clank.wav"), 1, ATTN_NORM, 0);
|
||||
// PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
if (ent->parent->client) {
|
||||
//Blaze: Play the clank hit noise
|
||||
// gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/clank.wav"), 1, ATTN_NORM, 0);
|
||||
// PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
||||
// calculate position for the explosion entity
|
||||
// calculate position for the explosion entity
|
||||
|
||||
VectorMA (ent->s.origin, -0.02, ent->s.origin2, origin);
|
||||
VectorMA (ent->s.origin, -0.02, ent->s.origin2, origin);
|
||||
|
||||
//glass fx
|
||||
if (0 == Q_stricmp(other->classname, "func_explosive"))
|
||||
{
|
||||
// ignore it, so it can bounce
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (0 == Q_stricmp(other->classname, "func_explosive")) {
|
||||
// ignore it, so it can bounce
|
||||
return;
|
||||
}
|
||||
else
|
||||
// ---
|
||||
if (other->takedamage)
|
||||
{
|
||||
G_Damage (other, ent, ent, ent->s.origin2, ent->s.origin, THROW_DAMAGE, 0, MOD_KNIFE_THROWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (other->takedamage) {
|
||||
G_Damage (other, ent, ent, ent->s.origin2, ent->s.origin, THROW_DAMAGE, 0, MOD_KNIFE_THROWN);
|
||||
}
|
||||
else {
|
||||
|
||||
// code to manage excess knives in the game, guarantees that
|
||||
// no more than knifelimit knives will be stuck in walls.
|
||||
// if knifelimit == 0 then it won't be in effect and it can
|
||||
// start removing knives even when less than the limit are
|
||||
// out there.
|
||||
/* if ( g_rxn_knifelimit.value != 0 )
|
||||
{
|
||||
knives++;
|
||||
|
||||
if (knives > g_rxn_knifelimit.value)
|
||||
knives = 1;
|
||||
|
||||
knife = FindEdictByClassnum ("weapon_Knife", knives);
|
||||
|
||||
if (knife)
|
||||
{
|
||||
knife->nextthink = level.time + .1;
|
||||
}
|
||||
|
||||
} */
|
||||
// code to manage excess knives in the game, guarantees that
|
||||
// no more than knifelimit knives will be stuck in walls.
|
||||
// if knifelimit == 0 then it won't be in effect and it can
|
||||
// start removing knives even when less than the limit are
|
||||
// out there.
|
||||
/* if ( g_rxn_knifelimit.value != 0 )
|
||||
{
|
||||
knives++;
|
||||
|
||||
if (knives > g_rxn_knifelimit.value)
|
||||
knives = 1;
|
||||
|
||||
knife = FindEdictByClassnum ("weapon_Knife", knives);
|
||||
|
||||
if (knife)
|
||||
{
|
||||
knife->nextthink = level.time + .1;
|
||||
}
|
||||
|
||||
} */
|
||||
|
||||
xr_item = BG_FindItemForWeapon( WP_KNIFE );
|
||||
|
||||
//spawn a knife in the object
|
||||
//Elder: todo - rotate the knife model so it's collinear with trajectory
|
||||
//and eliminate the jittering
|
||||
xr_item = BG_FindItemForWeapon( WP_KNIFE );
|
||||
//xr_drop = dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM );
|
||||
xr_drop = dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM);
|
||||
xr_drop->count = 1;
|
||||
}
|
||||
|
||||
xr_drop= dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM );
|
||||
xr_drop->count =1;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
G_FreeEntity (ent);
|
||||
G_FreeEntity (ent);
|
||||
}
|
||||
|
||||
//gentity_t *Knife_Throw (gentity_t *self,vec3_t start, vec3_t dir, int damage, int speed )
|
||||
|
@ -933,12 +947,16 @@ void Weapon_Knife_Fire(gentity_t *ent)
|
|||
gentity_t *m;
|
||||
|
||||
// Homer: if client is supposed to be slashing, go to that function instead
|
||||
if ( !ent->client->throwKnife )
|
||||
{
|
||||
if ( !ent->client->throwKnife ) {
|
||||
//Elder: added
|
||||
ent->client->ps.stats[STAT_KNIFE] = RQ3_KNIFE_SLASH;
|
||||
Knife_Attack(ent,SLASH_DAMAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
//Elder: added
|
||||
ent->client->ps.stats[STAT_KNIFE] = RQ3_KNIFE_THROW;
|
||||
|
||||
// extra vertical velocity
|
||||
forward[2] += 0.2f;
|
||||
|
||||
|
@ -950,8 +968,6 @@ void Weapon_Knife_Fire(gentity_t *ent)
|
|||
// m->splashDamage *= s_quadFactor;
|
||||
// ^^^^ Homer: got quad?
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue