mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-26 22:21:16 +00:00
Release 25 Game
This commit is contained in:
parent
1520497f0b
commit
7568fda611
15 changed files with 537 additions and 285 deletions
|
@ -21,7 +21,6 @@ An item fires all of its targets when it is picked up. If the toucher can't car
|
|||
"count" override quantity or duration on most items.
|
||||
*/
|
||||
|
||||
|
||||
gitem_t bg_itemlist[] =
|
||||
{
|
||||
{
|
||||
|
@ -1440,6 +1439,7 @@ void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad ) {
|
|||
// then don't play the event sound again if we are in a fat trigger
|
||||
if ( ps->jumppad_ent != jumppad->number ) {
|
||||
|
||||
/*
|
||||
vectoangles( jumppad->origin2, angles);
|
||||
p = fabs( AngleNormalize180( angles[PITCH] ) );
|
||||
if( p < 45 ) {
|
||||
|
@ -1447,6 +1447,9 @@ void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad ) {
|
|||
} else {
|
||||
effectNum = 1;
|
||||
}
|
||||
*/
|
||||
// NiceAss: For cutsom sounds...
|
||||
effectNum = jumppad->generic1;
|
||||
BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, effectNum, ps );
|
||||
}
|
||||
// remember hitting this jumppad this frame
|
||||
|
|
|
@ -1922,7 +1922,7 @@ static void PM_BeginWeaponChange( int weapon ) {
|
|||
PM_StartWeaponAnim(WP_ANIM_DISARM);
|
||||
else
|
||||
*/
|
||||
if (pm->ps->weapon == WP_KNIFE && !(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE))
|
||||
if ( pm->ps->weapon == WP_KNIFE && !(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) )
|
||||
PM_StartWeaponAnim(WP_ANIM_THROWDISARM);
|
||||
else {
|
||||
PM_StartWeaponAnim(WP_ANIM_DISARM);
|
||||
|
@ -1939,14 +1939,18 @@ static void PM_BeginWeaponChange( int weapon ) {
|
|||
// Elder: cancel burst shots
|
||||
pm->ps->stats[STAT_BURST] = 0;
|
||||
|
||||
// NiceAss: Added this as a fix for knifes and grenades when you throw the last one.
|
||||
if ( ( (pm->ps->weapon == WP_GRENADE || pm->ps->weapon == WP_KNIFE) && pm->ps->ammo[pm->ps->weapon] == 0) &&
|
||||
pm->ps->weaponstate != WEAPON_FIRING )
|
||||
{
|
||||
pm->ps->weaponstate = WEAPON_DROPPING;
|
||||
|
||||
// NiceAss: Added this. Is it a hack?
|
||||
if (pm->ps->weapon == WP_GRENADE && pm->ps->ammo[pm->ps->weapon] == 0) {
|
||||
pm->ps->weaponTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
pm->ps->weaponstate = WEAPON_DROPPING;
|
||||
|
||||
|
||||
//Elder: temp hack
|
||||
/*
|
||||
if (pm->ps->weapon == WP_PISTOL ||
|
||||
|
@ -1989,10 +1993,11 @@ static void PM_FinishWeaponChange( void ) {
|
|||
weapon = WP_NONE;
|
||||
}
|
||||
|
||||
//Remove grenade if out of ammo
|
||||
if (weapon == WP_GRENADE && pm->ps->ammo[WP_GRENADE] == 0)
|
||||
//Remove grenade/knife if out of ammo
|
||||
if ( (weapon == WP_GRENADE || weapon == WP_KNIFE) && pm->ps->ammo[weapon] == 0)
|
||||
{
|
||||
pm->ps->stats[STAT_WEAPONS] &= ~(1 << WP_GRENADE);
|
||||
if (weapon == WP_GRENADE) pm->ps->stats[STAT_WEAPONS] &= ~(1 << WP_GRENADE);
|
||||
if (weapon == WP_KNIFE) pm->ps->stats[STAT_WEAPONS] &= ~(1 << WP_KNIFE);
|
||||
weapon = WP_PISTOL;
|
||||
}
|
||||
|
||||
|
@ -2049,14 +2054,12 @@ static void PM_FinishWeaponChange( void ) {
|
|||
PM_StartWeaponAnim(WP_ANIM_ACTIVATE);
|
||||
*/
|
||||
/*else*/
|
||||
|
||||
if (pm->ps->weapon == WP_KNIFE && !(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE))
|
||||
PM_StartWeaponAnim(WP_ANIM_THROWACTIVATE);
|
||||
else
|
||||
PM_StartWeaponAnim(WP_ANIM_ACTIVATE);
|
||||
|
||||
PM_StartTorsoAnim( TORSO_RAISE );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2360,8 +2363,9 @@ static void PM_Reload( void )
|
|||
pm->ps->ammo[WP_AKIMBO] = RQ3_AKIMBO_AMMO;
|
||||
}
|
||||
|
||||
if ( !(pm->ps->stats[STAT_RQ3] & RQ3_LOCKRELOADS) )
|
||||
if ( !(pm->ps->stats[STAT_RQ3] & RQ3_LOCKRELOADS) ) {
|
||||
pm->ps->ammo[pm->ps->weapon] = ammotoadd;
|
||||
}
|
||||
|
||||
// handle continuous fast-reloads
|
||||
if ((pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_SSG3000) &&
|
||||
|
@ -2516,6 +2520,23 @@ static void PM_Weapon( void ) {
|
|||
pm->cmd.buttons |= BUTTON_ATTACK;
|
||||
}
|
||||
|
||||
//agt: Knife stupidity
|
||||
//I'll hijack STAT_BURST for this one
|
||||
if( pm->ps->weapon == WP_KNIFE && (pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) ) {
|
||||
if (pm->cmd.buttons & BUTTON_ATTACK &&
|
||||
pm->ps->stats[STAT_BURST] >= 0 && pm->ps->stats[STAT_BURST] < 5)
|
||||
{
|
||||
pm->cmd.buttons |= BUTTON_ATTACK;
|
||||
}
|
||||
else if (pm->ps->stats[STAT_BURST] > 4) {
|
||||
pm->ps->stats[STAT_BURST] = 0;
|
||||
pm->ps->weaponTime += 650; // NiceAss note: 30ms * 5 attacks = 150 ms + 650ms = 800ms.
|
||||
}
|
||||
else if (pm->ps->stats[STAT_BURST] > 0) {
|
||||
pm->cmd.buttons |= BUTTON_ATTACK;
|
||||
}
|
||||
}
|
||||
|
||||
//Elder: New semi-auto code
|
||||
if ( pm->ps->weapon == WP_PISTOL &&
|
||||
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_MK23MODE) == RQ3_MK23MODE)
|
||||
|
@ -2581,6 +2602,11 @@ static void PM_Weapon( void ) {
|
|||
}
|
||||
*/
|
||||
|
||||
// NiceAss: Sorta a hack, but it looks better.
|
||||
/* if ( pm->ps->weapon == WP_PISTOL && pm->ps->ammo[WP_PISTOL] == 0 && pm->ps->weaponTime < RQ3_PISTOL_DELAY*.3 ) {
|
||||
PM_StartWeaponAnim( WP_ANIM_EMPTY );
|
||||
}*/
|
||||
|
||||
// make weapon function
|
||||
if ( pm->ps->weaponTime > 0 ) {
|
||||
pm->ps->weaponTime -= pml.msec;
|
||||
|
@ -2605,7 +2631,7 @@ static void PM_Weapon( void ) {
|
|||
if ( pm->ps->weapon == WP_GRENADE && pm->ps->weaponstate == WEAPON_COCKED) {
|
||||
pm->ps->weaponstate = WEAPON_FIRING;
|
||||
pm->cmd.buttons &= ~BUTTON_ATTACK;
|
||||
PM_AddEvent( EV_FIRE_WEAPON );
|
||||
PM_AddEvent2( EV_FIRE_WEAPON, RQ3_WPMOD_GRENADEDROP );
|
||||
pm->ps->ammo[WP_GRENADE]--;
|
||||
}
|
||||
PM_BeginWeaponChange( pm->cmd.weapon );
|
||||
|
@ -2669,7 +2695,30 @@ static void PM_Weapon( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( pm->ps->weaponstate == WEAPON_RAISING ) {
|
||||
//NiceAss: Attempt to have the knife/grenade "activate" after a throw if you have another one of them
|
||||
if ( pm->ps->weaponstate == WEAPON_FIRING && pm->ps->ammo[pm->ps->weapon] > 0 &&
|
||||
(pm->ps->weapon == WP_KNIFE || pm->ps->weapon == WP_GRENADE) ) {
|
||||
|
||||
if (pm->ps->weapon == WP_KNIFE && !(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE))
|
||||
{
|
||||
pm->ps->weaponTime = RQ3_KNIFE_ACTIVATE_DELAY;
|
||||
PM_StartWeaponAnim(WP_ANIM_THROWACTIVATE);
|
||||
pm->ps->weaponstate = WEAPON_RAISING;
|
||||
PM_StartTorsoAnim( TORSO_RAISE );
|
||||
return;
|
||||
}
|
||||
if (pm->ps->weapon == WP_GRENADE)
|
||||
{
|
||||
pm->ps->weaponTime = RQ3_GRENADE_DELAY;
|
||||
PM_StartWeaponAnim(WP_ANIM_ACTIVATE);
|
||||
pm->ps->weaponstate = WEAPON_RAISING;
|
||||
PM_StartTorsoAnim( TORSO_RAISE );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pm->ps->weaponstate == WEAPON_RAISING &&
|
||||
!( ( pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) && pm->ps->stats[STAT_BURST]) ) {
|
||||
pm->ps->weaponstate = WEAPON_READY;
|
||||
if ( pm->ps->weapon == WP_KNIFE ) {
|
||||
PM_StartTorsoAnim( TORSO_STAND2 );
|
||||
|
@ -2699,9 +2748,15 @@ static void PM_Weapon( void ) {
|
|||
PM_StartWeaponAnim( WP_ANIM_THROWIDLE );
|
||||
else
|
||||
PM_StartWeaponAnim( WP_ANIM_IDLE );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// NiceAss: Added for knife animation switch.
|
||||
// At the moment, this is only used for changing knife-throw modes.
|
||||
if ( pm->ps->weaponstate == WEAPON_MODECHANGE ) {
|
||||
if ( pm->ps->weapon == WP_KNIFE) pm->ps->weaponstate = WEAPON_READY;
|
||||
}
|
||||
|
||||
// Elder: fire on release - based on code from inolen
|
||||
// check for fire
|
||||
|
@ -2719,15 +2774,15 @@ static void PM_Weapon( void ) {
|
|||
PM_ContinueWeaponAnim(WP_ANIM_EXTRA1);
|
||||
return;
|
||||
}
|
||||
// NiceAss: Fix for the double-grenade bug (pm->ps->weaponstate == WEAPON_FIRING)
|
||||
else if ( pm->ps->weaponstate == WEAPON_COCKED || pm->ps->weaponstate == WEAPON_FIRING)
|
||||
else if ( pm->ps->weaponstate == WEAPON_COCKED )
|
||||
return;
|
||||
}
|
||||
// Elder: stall the thrown knife action
|
||||
|
||||
else if ( pm->ps->weapon == WP_KNIFE && pm->ps->weaponstate != WEAPON_STALL &&
|
||||
pm->ps->stats[STAT_WEAPONSTALLTIME] <= 0 &&
|
||||
!(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) )
|
||||
!(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) &&
|
||||
pm->ps->ammo[pm->ps->weapon])
|
||||
{
|
||||
pm->ps->weaponstate = WEAPON_STALL;
|
||||
pm->ps->stats[STAT_WEAPONSTALLTIME] = 200;
|
||||
|
@ -2829,7 +2884,13 @@ static void PM_Weapon( void ) {
|
|||
// check for out of ammo
|
||||
if ( ! pm->ps->ammo[ pm->ps->weapon ]) {
|
||||
PM_AddEvent( EV_NOAMMO );
|
||||
//NiceAss: Dirty hack:
|
||||
if (pm->ps->weapon == WP_KNIFE || pm->ps->weapon == WP_GRENADE)
|
||||
//PM_FinishWeaponChange();
|
||||
pm->ps->weaponstate = WEAPON_DROPPING;
|
||||
else
|
||||
pm->ps->weaponTime += 500;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2856,7 +2917,8 @@ static void PM_Weapon( void ) {
|
|||
*/
|
||||
if ( pm->ps->weapon == WP_KNIFE &&
|
||||
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) )
|
||||
PM_StartWeaponAnim( WP_ANIM_FIRE );
|
||||
// Modified by agt for slash "bursting"
|
||||
if(!pm->ps->stats[STAT_BURST]) PM_StartWeaponAnim( WP_ANIM_FIRE );
|
||||
|
||||
PM_StartTorsoAnim( TORSO_ATTACK2 );
|
||||
} else {
|
||||
|
@ -2885,10 +2947,15 @@ static void PM_Weapon( void ) {
|
|||
pm->ps->weapon == WP_M4 ||
|
||||
pm->ps->weapon == WP_MP5 ||
|
||||
pm->ps->weapon == WP_GRENADE) */
|
||||
//if ( pm->ps->ammo[pm->ps->weapon] > 1 )
|
||||
PM_StartWeaponAnim( WP_ANIM_FIRE );
|
||||
//else
|
||||
// PM_StartWeaponAnim( WP_ANIM_EMPTY );
|
||||
}
|
||||
}
|
||||
|
||||
//NiceAss: Hack of the week!!!!
|
||||
if (pm->ps->weaponstate == WEAPON_FIRING && pm->ps->weapon == WP_GRENADE) return;
|
||||
|
||||
pm->ps->weaponstate = WEAPON_FIRING;
|
||||
|
||||
|
@ -2902,7 +2969,9 @@ static void PM_Weapon( void ) {
|
|||
(pm->ps->weapon == WP_MP5 &&
|
||||
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_MP5MODE) == RQ3_MP5MODE) ||
|
||||
(pm->ps->weapon == WP_PISTOL &&
|
||||
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_MK23MODE) == RQ3_MK23MODE))
|
||||
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_MK23MODE) == RQ3_MK23MODE) ||
|
||||
(pm->ps->weapon == WP_KNIFE &&
|
||||
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) == RQ3_KNIFEMODE) )
|
||||
{
|
||||
pm->ps->stats[STAT_BURST]++;
|
||||
}
|
||||
|
@ -2970,10 +3039,15 @@ static void PM_Weapon( void ) {
|
|||
if (bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_SILENCER &&
|
||||
(pm->ps->weapon == WP_PISTOL ||
|
||||
pm->ps->weapon == WP_MP5 ||
|
||||
pm->ps->weapon == WP_SSG3000))
|
||||
{
|
||||
pm->ps->weapon == WP_SSG3000)) {
|
||||
PM_AddEvent2( EV_FIRE_WEAPON, RQ3_WPMOD_SILENCER );
|
||||
}
|
||||
else if (pm->ps->stats[STAT_BURST] > 1 && pm->ps->weapon == WP_KNIFE &&
|
||||
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) == RQ3_KNIFEMODE)
|
||||
{
|
||||
// NiceAss: Prevent the client from doing stuff after the first "slash".
|
||||
PM_AddEvent2( EV_FIRE_WEAPON, RQ3_WPMOD_KNIFENOMARK);
|
||||
}
|
||||
else
|
||||
PM_AddEvent( EV_FIRE_WEAPON );
|
||||
|
||||
|
@ -2995,8 +3069,15 @@ static void PM_Weapon( void ) {
|
|||
case WP_KNIFE:
|
||||
if ( (pm->ps->persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) == RQ3_KNIFEMODE) {
|
||||
//knife slash
|
||||
//agt: hacking it up a little. The alternate time value should be
|
||||
//a constant, but I have a headache and I'm tired of screwing around
|
||||
//with the knives. [NiceAss: I'll do it for you!]
|
||||
if(pm->ps->stats[STAT_BURST]) {
|
||||
addTime = RQ3_KNIFE_SLASH_BURST; //NiceAss: Not really a burst, but it fits with everything else =D
|
||||
} else {
|
||||
addTime = RQ3_KNIFE_DELAY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//knife throw
|
||||
addTime = RQ3_THROW_DELAY;
|
||||
|
|
|
@ -222,8 +222,9 @@ typedef enum {
|
|||
#define RQ3_AKIMBO_DELAY 100
|
||||
#define RQ3_AKIMBO_DELAY2 300
|
||||
#define RQ3_KNIFE_DELAY 800
|
||||
#define RQ3_THROW_DELAY 800
|
||||
#define RQ3_GRENADE_DELAY 750 // Elder: I made this up
|
||||
#define RQ3_THROW_DELAY 300 // NiceAss: Was 800, but much too slow.
|
||||
#define RQ3_KNIFE_SLASH_BURST 30 // NiceAss: For slashing every 30 ms. (Agt's arbitrary number of the day =))
|
||||
#define RQ3_GRENADE_DELAY 300 // NiceAss: Was 750, but much too slow.
|
||||
|
||||
//Elder: reload delays
|
||||
//Also kinda "derived" from the AQ2 source
|
||||
|
@ -251,7 +252,7 @@ typedef enum {
|
|||
//Elder: each weapon also has a different weapon switch up delay... ugh bloody hell
|
||||
#define RQ3_PISTOL_ACTIVATE_DELAY 900
|
||||
#define RQ3_M3_ACTIVATE_DELAY 700
|
||||
#define RQ3_M4_ACTIVATE_DELAY 1000
|
||||
#define RQ3_M4_ACTIVATE_DELAY 700 // 1000
|
||||
#define RQ3_MP5_ACTIVATE_DELAY 1000
|
||||
#define RQ3_HANDCANNON_ACTIVATE_DELAY 600
|
||||
#define RQ3_SSG3000_ACTIVATE_DELAY 800
|
||||
|
@ -287,6 +288,11 @@ typedef enum {
|
|||
//Elder: weapon modifications
|
||||
#define RQ3_WPMOD_SILENCER 1
|
||||
#define RQ3_WPMOD_KNIFESLASH 2
|
||||
// NiceAss: Used after the first "slash" of the knife.
|
||||
// A bit misleading in its name. It also means there will be no sound.
|
||||
#define RQ3_WPMOD_KNIFENOMARK 3
|
||||
// Niceass: If you are switching weapons, the grenade is dropped rather than thrown.
|
||||
#define RQ3_WPMOD_GRENADEDROP 4
|
||||
|
||||
//
|
||||
// config strings are a general means of communicating variable length strings
|
||||
|
@ -376,7 +382,9 @@ typedef enum {
|
|||
WEAPON_DROPPING, //sync with WP_ANIM_DISARM
|
||||
WEAPON_FIRING, //sync with WP_ANIM_FIRE
|
||||
WEAPON_RELOADING, //sync with WP_ANIM_RELOAD
|
||||
WEAPON_STALL //for delaying weapon fires (knife, grenade)
|
||||
WEAPON_STALL, //for delaying weapon fires (knife, grenade)
|
||||
WEAPON_MODECHANGE, // NiceAss: sync with WP_ANIM_EXTRA1 & WP_ANIM_EXTRA2 for knife.
|
||||
WEAPON_BANDAGING // NiceAss: Added to follow AQ2 and fix a bug.
|
||||
} weaponstate_t;
|
||||
|
||||
//Blaze: for the weapon animation states
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
//
|
||||
|
||||
#include "g_local.h"
|
||||
#ifdef __ZCAM__
|
||||
#include "zcam.h"
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
|
||||
//Elder: got rid of these
|
||||
//extern float s_quadFactor;
|
||||
|
@ -339,7 +343,7 @@ void ClientImpacts( gentity_t *ent, pmove_t *pm ) {
|
|||
G_TouchTriggers
|
||||
|
||||
Find all trigger entities that ent's current position touches.
|
||||
Spectators will only interact with teleporters.
|
||||
Spectators will only interact with teleporters (and door triggers for spectators)
|
||||
============
|
||||
*/
|
||||
void G_TouchTriggers( gentity_t *ent ) {
|
||||
|
@ -417,11 +421,17 @@ void G_TouchTriggers( gentity_t *ent ) {
|
|||
ent->client->ps.jumppad_frame = 0;
|
||||
ent->client->ps.jumppad_ent = 0;
|
||||
}
|
||||
|
||||
if (ent->client->openDoor == 2) {
|
||||
ent->client->openDoor = qfalse;
|
||||
ent->client->openDoorTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SpectatorThink
|
||||
NiceAss: Heavy modifications will be here for AQ2-like spectator mode and zcam!?
|
||||
=================
|
||||
*/
|
||||
void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) {
|
||||
|
@ -430,6 +440,24 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) {
|
|||
|
||||
client = ent->client;
|
||||
|
||||
|
||||
client->oldbuttons = client->buttons;
|
||||
client->buttons = ucmd->buttons;
|
||||
|
||||
// attack button cycles through spectators
|
||||
if ( ( client->buttons & BUTTON_ATTACK ) && ! ( client->oldbuttons & BUTTON_ATTACK ) ) {
|
||||
Cmd_FollowCycle_f( ent, 1 );
|
||||
}
|
||||
|
||||
#ifdef __ZCAM__
|
||||
if ( client->sess.spectatorState == SPECTATOR_CAMERA_FLIC &&
|
||||
client->sess.spectatorState == SPECTATOR_CAMERA_SWING )
|
||||
{
|
||||
camera_think(ent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( client->sess.spectatorState != SPECTATOR_FOLLOW ) {
|
||||
client->ps.pm_type = PM_SPECTATOR;
|
||||
client->ps.speed = 400; // faster than normal
|
||||
|
@ -450,14 +478,6 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) {
|
|||
G_TouchTriggers( ent );
|
||||
trap_UnlinkEntity( ent );
|
||||
}
|
||||
|
||||
client->oldbuttons = client->buttons;
|
||||
client->buttons = ucmd->buttons;
|
||||
|
||||
// attack button cycles through spectators
|
||||
if ( ( client->buttons & BUTTON_ATTACK ) && ! ( client->oldbuttons & BUTTON_ATTACK ) ) {
|
||||
Cmd_FollowCycle_f( ent, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -585,7 +605,6 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
|
|||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK;
|
||||
//Elder: moved from somewhere - err, g_cmds.c I think
|
||||
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_LEGDAMAGE;
|
||||
|
||||
// ent->client->ps.weaponstate = WEAPON_RAISING;
|
||||
// ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | TORSO_RAISE;
|
||||
// NiceAss: clear last player to hit you.
|
||||
|
@ -1397,14 +1416,29 @@ void ClientThink( int clientNum ) {
|
|||
// phone jack if they don't get any for a while
|
||||
ent->client->lastCmdTime = level.time;
|
||||
|
||||
if ( !(ent->r.svFlags & SVF_BOT) && !g_synchronousClients.integer ) {
|
||||
if ( !(ent->r.svFlags & SVF_BOT) && !g_synchronousClients.integer
|
||||
#ifdef __ZCAM__
|
||||
/* camera jitter fix (server side) */
|
||||
&& (ent->client->sess.sessionTeam != TEAM_SPECTATOR
|
||||
|| (ent->client->sess.sessionTeam == TEAM_SPECTATOR
|
||||
&& ent->client->sess.spectatorState == SPECTATOR_FOLLOW))
|
||||
#endif /* __ZCAM__ */
|
||||
) {
|
||||
ClientThink_real( ent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G_RunClient( gentity_t *ent ) {
|
||||
if ( !(ent->r.svFlags & SVF_BOT) && !g_synchronousClients.integer ) {
|
||||
if ( !(ent->r.svFlags & SVF_BOT) && !g_synchronousClients.integer
|
||||
#ifdef __ZCAM__
|
||||
/* camera jitter fix (server side) */
|
||||
&& (ent->client->sess.sessionTeam != TEAM_SPECTATOR
|
||||
|| (ent->client->sess.sessionTeam == TEAM_SPECTATOR
|
||||
&& ent->client->sess.spectatorState == SPECTATOR_FOLLOW))
|
||||
#endif /* __ZCAM__ */
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ent->client->pers.cmd.serverTime = level.time;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Copyright (C) 1999-2000 Id Software, Inc.
|
||||
//
|
||||
#include "g_local.h"
|
||||
#ifdef __ZCAM__
|
||||
#include "zcam.h"
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
#define RQ3_NONAMEPLAYER "Nameless"
|
||||
|
||||
|
@ -693,6 +696,8 @@ void ClientUserinfoChanged( int clientNum ) {
|
|||
char redTeam[MAX_INFO_STRING];
|
||||
char blueTeam[MAX_INFO_STRING];
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
// NiceAss: Added the following. Needed to prevent all models but "grunt"
|
||||
char *skin2, model2[MAX_STRING_CHARS];
|
||||
|
||||
ent = g_entities + clientNum;
|
||||
client = ent->client;
|
||||
|
@ -765,6 +770,22 @@ void ClientUserinfoChanged( int clientNum ) {
|
|||
Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) );
|
||||
}
|
||||
|
||||
// NiceAss: temporary hack to prevent non-grunt models:
|
||||
Q_strncpyz(model2, model, sizeof(model));
|
||||
skin2 = Q_strrchr( model2, '/' );
|
||||
if ( skin2 ) {
|
||||
*skin2++ = '\0';
|
||||
} else {
|
||||
skin2 = "default";
|
||||
}
|
||||
|
||||
if ( Q_stricmpn(model2, "grunt", sizeof(model2) ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Illegal player model. Forcing change on server.\n\""));
|
||||
Q_strncpyz(model, "grunt/resdog", sizeof("grunt/resdog"));
|
||||
Q_strncpyz(headModel, "grunt/resdog", sizeof("grunt/resdog"));
|
||||
}
|
||||
// End of temporary hack.
|
||||
|
||||
// bots set their team a few frames later
|
||||
if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) {
|
||||
s = Info_ValueForKey( userinfo, "team" );
|
||||
|
@ -881,6 +902,8 @@ int G_SendCheatVars(int clientNum)
|
|||
char cheatVar[40], cl_cheatvar[128];
|
||||
float lowval, highval;
|
||||
|
||||
//NiceAss: Added so /devmap will not have the client check cvars. Lie to the server that it loaded fine =)
|
||||
if (g_cheats.integer) return qtrue;
|
||||
|
||||
// load the file
|
||||
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
||||
|
@ -1262,6 +1285,11 @@ void ClientSpawn(gentity_t *ent) {
|
|||
VectorCopy (playerMaxs, ent->r.maxs);
|
||||
|
||||
client->ps.clientNum = index;
|
||||
|
||||
#ifdef __ZCAM__
|
||||
camera_begin (ent);
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
//Blaze: changed WP_MACHINEGUN to WP_PISTOL, makes the base weapon you start with the pistol
|
||||
client->ps.stats[STAT_WEAPONS] = ( 1 << WP_PISTOL );
|
||||
//Blaze: Set starting amo for the machine gun, different in teamplay and dm, we can remove this
|
||||
|
@ -1431,6 +1459,10 @@ void ClientDisconnect( int clientNum ) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __ZCAM__
|
||||
camera_disconnect (ent);
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
// send effect if they were completely connected
|
||||
if ( ent->client->pers.connected == CON_CONNECTED
|
||||
&& ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Copyright (C) 1999-2000 Id Software, Inc.
|
||||
//
|
||||
#include "g_local.h"
|
||||
#ifdef __ZCAM__
|
||||
#include "zcam.h"
|
||||
#endif /* __ZACM__ */
|
||||
|
||||
//Blaze: was there a extra ../ here?
|
||||
#include "../ui/menudef.h" // for the voice chats
|
||||
|
@ -1695,7 +1698,7 @@ void Cmd_Bandage (gentity_t *ent)
|
|||
^ ANIM_TOGGLEBIT ) | WP_ANIM_DISARM;
|
||||
}
|
||||
else */
|
||||
if (ent->client->ps.weapon == WP_KNIFE && (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE))
|
||||
if (ent->client->ps.weapon == WP_KNIFE && !(ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE))
|
||||
{
|
||||
ent->client->ps.generic1 = ( ( ent->client->ps.generic1 & ANIM_TOGGLEBIT )
|
||||
^ ANIM_TOGGLEBIT ) | WP_ANIM_THROWDISARM;
|
||||
|
@ -2257,18 +2260,29 @@ void Cmd_Weapon(gentity_t *ent)
|
|||
}
|
||||
break;
|
||||
case WP_KNIFE:
|
||||
// NiceAss: weapon animation/state check before the mode switch.
|
||||
if ( ent->client->ps.weaponstate != WEAPON_READY ) break;
|
||||
|
||||
// toggle throwing/slashing
|
||||
if ((ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) == RQ3_KNIFEMODE)
|
||||
if ( (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE) == RQ3_KNIFEMODE)
|
||||
{
|
||||
//Elder: added
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] &= ~RQ3_KNIFEMODE;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Switched to throwing.\n\""));
|
||||
// Niceass: Animations added
|
||||
ent->client->ps.weaponstate = WEAPON_MODECHANGE;
|
||||
ent->client->ps.weaponTime = 550;
|
||||
ent->client->ps.generic1 = ( ( ent->client->ps.generic1 & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | WP_ANIM_EXTRA1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Elder: we're gonna use this to flag throw or slash with the knife
|
||||
ent->client->ps.persistant[PERS_WEAPONMODES] |= RQ3_KNIFEMODE;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"Switched to slashing.\n\""));
|
||||
// Niceass: Animations added
|
||||
ent->client->ps.weaponstate = WEAPON_MODECHANGE;
|
||||
ent->client->ps.weaponTime = 550;
|
||||
ent->client->ps.generic1 = ( ( ent->client->ps.generic1 & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | WP_ANIM_EXTRA2;
|
||||
}
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
|
@ -2563,6 +2577,11 @@ void ClientCommand( int clientNum ) {
|
|||
//Elder: stuff for dropping items
|
||||
else if (Q_stricmp (cmd, "dropitem") == 0)
|
||||
Cmd_DropItem_f( ent );
|
||||
#ifdef __ZCAM__
|
||||
// NiceAss: removed
|
||||
//else if (Q_stricmp (cmd, "camera") == 0)
|
||||
// camera_cmd ( ent );
|
||||
#endif /* __ZCAM__ */
|
||||
else if (Q_stricmp (cmd, "playerstats") == 0)
|
||||
{
|
||||
Cmd_PlayerStats_f( ent );
|
||||
|
|
|
@ -16,6 +16,7 @@ void ScorePlum( gentity_t *ent, vec3_t origin, int score ) {
|
|||
plum = G_TempEntity( origin, EV_SCOREPLUM );
|
||||
// only send this temp entity to a single client
|
||||
plum->r.svFlags |= SVF_SINGLECLIENT;
|
||||
|
||||
plum->r.singleClient = ent->s.number;
|
||||
//
|
||||
plum->s.otherEntityNum = ent->s.number;
|
||||
|
@ -1496,6 +1497,66 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
}
|
||||
|
||||
// NiceAss: Make sure it hit the player before doing this stuff.
|
||||
// This was added when the possibility of missing was added from spherical head detection.
|
||||
// We don't want someone flying back from a sniper to the head when it actually missed!
|
||||
if ( G_HitPlayer ( targ, dir, point ) ) {
|
||||
// figure momentum add, even if the damage won't be taken
|
||||
if ( knockback && targ->client ) {
|
||||
vec3_t kvel, flydir;
|
||||
float mass;
|
||||
|
||||
if ( mod != MOD_FALLING )
|
||||
{
|
||||
VectorCopy(dir, flydir);
|
||||
flydir[2] += 0.4f;
|
||||
}
|
||||
|
||||
mass = 200;
|
||||
|
||||
//Elder: Q2 uses a hardcoded value of 500 for non-rocket jumps
|
||||
//Q3 uses g_knockback.value ... default 1000
|
||||
//AQ2:
|
||||
//VectorScale (flydir, 500.0 * (float)knockback / mass, kvel);
|
||||
//RQ3:
|
||||
//VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
|
||||
if (targ->client && attacker == targ)
|
||||
VectorScale (flydir, 1600.0 * (float)knockback / mass, kvel);
|
||||
else
|
||||
VectorScale (flydir, 500.0 * (float)knockback / mass, kvel);
|
||||
VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);
|
||||
|
||||
// set the timer so that the other client can't cancel
|
||||
// out the movement immediately
|
||||
if ( !targ->client->ps.pm_time ) {
|
||||
int t;
|
||||
|
||||
t = knockback * 2;
|
||||
if ( t < 50 ) {
|
||||
t = 50;
|
||||
}
|
||||
if ( t > 200 ) {
|
||||
t = 200;
|
||||
}
|
||||
targ->client->ps.pm_time = t;
|
||||
targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
|
||||
}
|
||||
}
|
||||
|
||||
// NiceAss: This was moved too
|
||||
// add to the attacker's hit counter (if the target isn't a general entity like a prox mine)
|
||||
if ( attacker->client && targ != attacker && targ->health > 0
|
||||
&& targ->s.eType != ET_MISSILE
|
||||
&& targ->s.eType != ET_GENERAL)
|
||||
{
|
||||
if ( OnSameTeam( targ, attacker ) ) {
|
||||
attacker->client->ps.persistant[PERS_HITS]--;
|
||||
} else {
|
||||
attacker->client->ps.persistant[PERS_HITS]++;
|
||||
}
|
||||
attacker->client->ps.persistant[PERS_ATTACKEE_ARMOR] = (targ->health<<8)|(client->ps.stats[STAT_ARMOR]);
|
||||
}
|
||||
}
|
||||
|
||||
// check for completely getting out of the damage
|
||||
if ( !(dflags & DAMAGE_NO_PROTECTION) ) {
|
||||
|
@ -1865,62 +1926,6 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
// End Duffman
|
||||
}
|
||||
|
||||
// NiceAss: This whole "if" statement was moved down so it wouldn't happen if you missed the head. (spherical hit detection stuff)
|
||||
// figure momentum add, even if the damage won't be taken
|
||||
if ( knockback && targ->client ) {
|
||||
vec3_t kvel, flydir;
|
||||
float mass;
|
||||
|
||||
if ( mod != MOD_FALLING )
|
||||
{
|
||||
VectorCopy(dir, flydir);
|
||||
flydir[2] += 0.4f;
|
||||
}
|
||||
|
||||
mass = 200;
|
||||
|
||||
//Elder: Q2 uses a hardcoded value of 500 for non-rocket jumps
|
||||
//Q3 uses g_knockback.value ... default 1000
|
||||
//AQ2:
|
||||
//VectorScale (flydir, 500.0 * (float)knockback / mass, kvel);
|
||||
//RQ3:
|
||||
//VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
|
||||
if (targ->client && attacker == targ)
|
||||
VectorScale (flydir, 1600.0 * (float)knockback / mass, kvel);
|
||||
else
|
||||
VectorScale (flydir, 500.0 * (float)knockback / mass, kvel);
|
||||
VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);
|
||||
|
||||
// set the timer so that the other client can't cancel
|
||||
// out the movement immediately
|
||||
if ( !targ->client->ps.pm_time ) {
|
||||
int t;
|
||||
|
||||
t = knockback * 2;
|
||||
if ( t < 50 ) {
|
||||
t = 50;
|
||||
}
|
||||
if ( t > 200 ) {
|
||||
t = 200;
|
||||
}
|
||||
targ->client->ps.pm_time = t;
|
||||
targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
|
||||
}
|
||||
}
|
||||
|
||||
// NiceAss: This was moved too
|
||||
// add to the attacker's hit counter (if the target isn't a general entity like a prox mine)
|
||||
if ( attacker->client && targ != attacker && targ->health > 0
|
||||
&& targ->s.eType != ET_MISSILE
|
||||
&& targ->s.eType != ET_GENERAL) {
|
||||
if ( OnSameTeam( targ, attacker ) ) {
|
||||
attacker->client->ps.persistant[PERS_HITS]--;
|
||||
} else {
|
||||
attacker->client->ps.persistant[PERS_HITS]++;
|
||||
}
|
||||
attacker->client->ps.persistant[PERS_ATTACKEE_ARMOR] = (targ->health<<8)|(client->ps.stats[STAT_ARMOR]);
|
||||
}
|
||||
|
||||
// add to the damage inflicted on a player this frame
|
||||
// the total will be turned into screen blends and view angle kicks
|
||||
// at the end of the frame
|
||||
|
@ -1948,7 +1953,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
// G_Printf("(%d) taken as damage\n",take);
|
||||
if (instant_dam)
|
||||
{
|
||||
//G_Printf("(%d) instant damage\n",take);
|
||||
// G_Printf("(%d) instant damage\n",take);
|
||||
targ->health = targ->health - take;
|
||||
}
|
||||
if ( targ->client ) {
|
||||
|
@ -2060,6 +2065,8 @@ CanDamage
|
|||
|
||||
Returns qtrue if the inflictor can directly damage the target. Used for
|
||||
explosions and melee attacks.
|
||||
|
||||
NICEASS TODO: Impliment G_HitPlayer in this func for clients.
|
||||
============
|
||||
*/
|
||||
qboolean CanDamage (gentity_t *targ, vec3_t origin) {
|
||||
|
@ -2074,6 +2081,7 @@ qboolean CanDamage (gentity_t *targ, vec3_t origin) {
|
|||
|
||||
VectorCopy (midpoint, dest);
|
||||
trap_Trace ( &tr, origin, vec3_origin, vec3_origin, dest, ENTITYNUM_NONE, MASK_SOLID);
|
||||
|
||||
if (tr.fraction == 1.0 || tr.entityNum == targ->s.number)
|
||||
return qtrue;
|
||||
|
||||
|
|
|
@ -1031,6 +1031,7 @@ gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags
|
|||
VectorSet (maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS);
|
||||
|
||||
// NiceAss: Check if the new location starts in a solid.
|
||||
// FIXME: Use trap_point or whatever?
|
||||
trap_Trace( &tr, origin, mins, maxs, origin, ent->s.number, MASK_SOLID );
|
||||
if (tr.startsolid == qtrue)
|
||||
VectorMA( origin, -7, velocity, origin ); // -5 won't work (hint: it should work). Only -7 or less will..
|
||||
|
@ -1381,7 +1382,9 @@ void G_BounceItem( gentity_t *ent, trace_t *trace ) {
|
|||
VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta );
|
||||
|
||||
// check for stop
|
||||
if ( trace->plane.normal[2] > 0 && ent->s.pos.trDelta[2] < 40 ) {
|
||||
|
||||
if ( ( trace->plane.normal[2] > 0 && ent->s.pos.trDelta[2] < 40 ) ||
|
||||
( trace->plane.normal[2] > .7 ) ) {
|
||||
trace->endpos[2] += 1.0; // make sure it is off ground
|
||||
SnapVector( trace->endpos );
|
||||
G_SetOrigin( ent, trace->endpos );
|
||||
|
@ -1389,6 +1392,7 @@ void G_BounceItem( gentity_t *ent, trace_t *trace ) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin);
|
||||
VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
|
||||
ent->s.pos.trTime = level.time;
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
// the "gameversion" client command will print this plus compile date
|
||||
#define GAMEVERSION "reaction"
|
||||
|
||||
// NiceAss: Took it out until later.
|
||||
// #define __ZCAM__
|
||||
|
||||
#define BODY_QUEUE_SIZE 8
|
||||
|
||||
// Blaze: How long someone bleeds for
|
||||
|
@ -207,6 +210,10 @@ typedef enum {
|
|||
SPECTATOR_NOT,
|
||||
SPECTATOR_FREE,
|
||||
SPECTATOR_FOLLOW,
|
||||
#ifdef __ZCAM__
|
||||
SPECTATOR_CAMERA_FLIC,
|
||||
SPECTATOR_CAMERA_SWING,
|
||||
#endif
|
||||
SPECTATOR_SCOREBOARD
|
||||
} spectatorState_t;
|
||||
|
||||
|
@ -284,6 +291,9 @@ typedef struct {
|
|||
int records[REC_NUM_RECORDS]; // Elder: for our statistics tracking
|
||||
} clientPersistant_t;
|
||||
|
||||
#ifdef __ZCAM__
|
||||
struct camera_s;
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
// Elder: spam prevention defaults
|
||||
/*
|
||||
|
@ -395,7 +405,7 @@ struct gclient_s {
|
|||
// End Duffman
|
||||
int weaponCount[WP_NUM_WEAPONS]; // Elder: for duplicate unique weapon tracking
|
||||
|
||||
qboolean openDoor; //Blaze: used to hold if someone has hit opendoor key
|
||||
int openDoor; //Blaze: used to hold if someone has hit opendoor key
|
||||
int openDoorTime;
|
||||
|
||||
// timeResidual is used to handle events that happen every second
|
||||
|
@ -437,7 +447,7 @@ struct gclient_s {
|
|||
int uniqueItems;
|
||||
int killStreak; // Elder: replaces the old STAT_STREAK
|
||||
qboolean kevlarHit; // Elder: kevlar hit -- FIXME: poor implementation
|
||||
|
||||
int knife_sound; // NiceAss: What did the player hit while slashing?
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
gentity_t *persistantPowerup;
|
||||
|
@ -447,6 +457,9 @@ struct gclient_s {
|
|||
#endif
|
||||
|
||||
char *areabits;
|
||||
#ifdef __ZCAM__
|
||||
struct camera_s *camera;
|
||||
#endif /* __ZCAM__ */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
//
|
||||
|
||||
#include "g_local.h"
|
||||
#ifdef __ZCAM__
|
||||
#include "zcam.h"
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
level_locals_t level;
|
||||
|
||||
|
@ -469,6 +472,10 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) {
|
|||
g_entities[i].client = level.clients + i;
|
||||
}
|
||||
|
||||
#ifdef __ZCAM__
|
||||
camera_init ();
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
// always leave room for the max number of clients,
|
||||
// even if they aren't all used, so numbers inside that
|
||||
// range are NEVER anything but clients
|
||||
|
@ -542,6 +549,10 @@ void G_ShutdownGame( int restart ) {
|
|||
trap_FS_FCloseFile( level.logFile );
|
||||
}
|
||||
|
||||
#ifdef __ZCAM__
|
||||
camera_shutdown ();
|
||||
#endif /* __ZCAM__ */
|
||||
|
||||
// write all the client session data so we can get it back
|
||||
G_WriteSessionData();
|
||||
|
||||
|
|
|
@ -424,7 +424,6 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
|||
// one, rather than changing the missile into the explosion?
|
||||
|
||||
//Elder: I don't know but that's what we did for the knife
|
||||
|
||||
if ( other->takedamage && other->client ) {
|
||||
G_AddEvent( ent, EV_MISSILE_HIT, DirToByte( trace->plane.normal ) );
|
||||
ent->s.otherEntityNum = other->s.number;
|
||||
|
@ -454,17 +453,19 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
|||
BG_EvaluateTrajectoryDelta(&ent->s.pos, level.time, knifeVelocity);
|
||||
|
||||
if (other->s.eType == ET_BREAKABLE) {
|
||||
VectorScale(knifeVelocity, -0.25, knifeVelocity);
|
||||
//VectorScale(knifeVelocity, -0.25, knifeVelocity);
|
||||
//Blaze: Moved from above, now deal the damage to the glass, and let the knife drop
|
||||
if ( ent->s.weapon == WP_KNIFE && other->s.eType == ET_BREAKABLE ) {
|
||||
BG_EvaluateTrajectory( &ent->s.pos, level.time, origin);
|
||||
velocity[0] = 0;
|
||||
velocity[1] = 0;
|
||||
velocity[2] = 0;
|
||||
//velocity[0] = 0;
|
||||
//velocity[1] = 0;
|
||||
//velocity[2] = 0;
|
||||
G_Damage (other, ent, &g_entities[ent->r.ownerNum], velocity, origin, THROW_DAMAGE, 0, MOD_KNIFE_THROWN);
|
||||
}
|
||||
|
||||
|
||||
// NiceAss: Cut its velocity in half.
|
||||
VectorScale( ent->s.pos.trDelta, .6, ent->s.pos.trDelta);
|
||||
return;
|
||||
/*
|
||||
//breakable "hit"; make it fall to the ground
|
||||
xr_drop = LaunchItem(xr_item, trace->endpos, velocity, FL_DROPPED_ITEM);
|
||||
|
||||
|
@ -480,6 +481,7 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
|||
VectorAdd(xr_drop->s.origin, knifeOffset, xr_drop->s.origin);
|
||||
|
||||
VectorCopy(xr_drop->s.origin, xr_drop->r.currentOrigin);
|
||||
*/
|
||||
}
|
||||
else {
|
||||
//leave embedded in the wall
|
||||
|
@ -753,9 +755,10 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
|
|||
if ( self->client) {
|
||||
// Elder: Statistics tracking
|
||||
self->client->pers.records[REC_GRENADESHOTS]++;
|
||||
|
||||
if ( self->client->ps.stats[STAT_HEALTH] <= 0 ||
|
||||
(self->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
|
||||
(self->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK ||
|
||||
// NiceAss: Should catch any case of switching weapons with a grenade "cocked"
|
||||
self->client->ps.weaponstate == WEAPON_DROPPING ) {
|
||||
//Always drop close range if dead or about to bandage
|
||||
speed = GRENADE_SHORT_SPEED / 2;
|
||||
}
|
||||
|
@ -829,7 +832,7 @@ gentity_t *fire_knife (gentity_t *self, vec3_t start, vec3_t dir)
|
|||
self->client->pers.records[REC_KNIFETHROWSHOTS]++;
|
||||
}
|
||||
|
||||
bolt->s.pos.trDelta[2] *= .85;
|
||||
// bolt->s.pos.trDelta[2] *= .85;
|
||||
|
||||
//Elder: not needed anymore
|
||||
//Saving stuff for Makro's knife equations
|
||||
|
|
|
@ -1151,12 +1151,12 @@ void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) {
|
|||
//else {
|
||||
//Blaze's broken open door code
|
||||
//Elder: not as broken as you think :)
|
||||
if (other->client->openDoor == qtrue ||
|
||||
if (other->client->openDoor ||
|
||||
(ent->parent->spawnflags & SP_AUTOOPEN) == SP_AUTOOPEN) {
|
||||
//G_Printf("Using a door\n");
|
||||
Use_BinaryMover( ent->parent, ent, other );
|
||||
other->client->openDoor = qfalse;
|
||||
other->client->openDoorTime = 0;
|
||||
// NiceAss: Hackish, but oh well. Done so you can trigger multipul doors in an area.
|
||||
other->client->openDoor = 2;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
@ -1196,8 +1196,18 @@ void Think_SpawnNewDoorTrigger( gentity_t *ent ) {
|
|||
best = i;
|
||||
}
|
||||
}
|
||||
maxs[best] += 120;
|
||||
mins[best] -= 120;
|
||||
// expand
|
||||
maxs[best] += 60;
|
||||
mins[best] -= 60;
|
||||
// NiceAss: AQ2 Style. Above is Q3 style.
|
||||
if (best != 0) {
|
||||
maxs[0] += 60;
|
||||
mins[0] -= 60;
|
||||
}
|
||||
if (best != 1) {
|
||||
maxs[1] += 60;
|
||||
mins[1] -= 60;
|
||||
}
|
||||
|
||||
// NiceAss: This trigger will be for players
|
||||
// create a trigger with this size
|
||||
|
@ -1213,9 +1223,20 @@ void Think_SpawnNewDoorTrigger( gentity_t *ent ) {
|
|||
trap_LinkEntity (other);
|
||||
|
||||
// NiceAss: This trigger will be for spectators
|
||||
// NiceAss: Undo most of the stretched box size so it is only a little bigger than the door
|
||||
maxs[best] -= 110;
|
||||
mins[best] += 110;
|
||||
// NiceAss: Undo the stretched box size
|
||||
// expand
|
||||
maxs[best] -= 60;
|
||||
mins[best] += 60;
|
||||
// NiceAss: AQ2 Style. Above is Q3 style.
|
||||
if (best != 0) {
|
||||
maxs[0] -= 60;
|
||||
mins[0] += 60;
|
||||
}
|
||||
if (best != 1) {
|
||||
maxs[1] -= 60;
|
||||
mins[1] += 60;
|
||||
}
|
||||
|
||||
other = G_Spawn ();
|
||||
other->classname = "door_trigger_spectator";
|
||||
VectorCopy (mins, other->r.mins);
|
||||
|
|
|
@ -177,15 +177,16 @@ Must point at a target_position, which will be the apex of the leap.
|
|||
This will be client side predicted, unlike target_push
|
||||
*/
|
||||
void SP_trigger_push( gentity_t *self ) {
|
||||
char *sound;
|
||||
InitTrigger (self);
|
||||
|
||||
// unlike other triggers, we need to send this one to the client
|
||||
// NiceAss: Added for custom push sounds. Default is none. Q3 is "sounds/world/bouncepad.wav"
|
||||
if (G_SpawnString( "noise", "", &sound )) {;
|
||||
self->s.generic1 = G_SoundIndex( sound );
|
||||
}
|
||||
|
||||
self->r.svFlags &= ~SVF_NOCLIENT;
|
||||
|
||||
// make sure the client precaches this sound
|
||||
//Elder: edited for now TODO: let mappers use a key pair
|
||||
//G_SoundIndex("sound/world/jumppad.wav");
|
||||
|
||||
self->s.eType = ET_PUSH_TRIGGER;
|
||||
self->touch = trigger_push_touch;
|
||||
self->think = AimAtTarget;
|
||||
|
|
|
@ -459,8 +459,7 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
|
|||
//} else if ( tr.surfaceFlags & SURF_GRASS ) {
|
||||
//tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_FLESH);
|
||||
//tent->s.eventParm = DirToByte( tr.plane.normal );
|
||||
} else if ( (tr.surfaceFlags & SURF_METALSTEPS) ||
|
||||
(tr.surfaceFlags & SURF_METAL2) ) {
|
||||
} else if ( (tr.surfaceFlags & SURF_METALSTEPS) || (tr.surfaceFlags & SURF_METAL2) ) {
|
||||
tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_METAL );
|
||||
tent->s.eventParm = DirToByte( tr.plane.normal );
|
||||
tent->s.otherEntityNum = ent->s.number;
|
||||
|
@ -477,22 +476,6 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
|
|||
//G_Printf("Surfaceflags: %d\n", tr.surfaceFlags);
|
||||
|
||||
if ( traceEnt->takedamage) {
|
||||
#ifdef MISSIONPACK
|
||||
if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
|
||||
if (G_InvulnerabilityEffect( traceEnt, forward, tr.endpos, impactpoint, bouncedir )) {
|
||||
G_BounceProjectile( muzzle, impactpoint, bouncedir, end );
|
||||
VectorCopy( impactpoint, muzzle );
|
||||
// the player can hit him/herself with the bounced rail
|
||||
passent = ENTITYNUM_NONE;
|
||||
}
|
||||
else {
|
||||
VectorCopy( tr.endpos, muzzle );
|
||||
passent = traceEnt->s.number;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD);
|
||||
|
||||
// FIXME: poor implementation
|
||||
|
@ -505,13 +488,17 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
|
|||
// Need this?
|
||||
tent2->s.otherEntityNum = ent->s.number;
|
||||
}
|
||||
else
|
||||
traceEnt->client->kevlarHit = qfalse;
|
||||
}
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
// NiceAss: Added so the M4 will shoot through bodies
|
||||
if (MOD == MOD_M4 && traceEnt->client &&
|
||||
traceEnt->client->kevlarHit == qfalse)
|
||||
{
|
||||
VectorCopy (tr.endpos, muzzle);
|
||||
passent = tr.entityNum;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (traceEnt->client) traceEnt->client->kevlarHit = qfalse;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1129,22 +1116,31 @@ void Knife_Attack ( gentity_t *self, int damage)
|
|||
{
|
||||
//Elder: no knock-back on knife slashes
|
||||
G_Damage (hitent, self, self, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_KNIFE );
|
||||
if (hitent->client)
|
||||
{
|
||||
tent = G_TempEntity(tr.endpos, EV_RQ3_SOUND);
|
||||
tent->s.eventParm = RQ3_SOUND_KNIFEHIT;
|
||||
if (self->client)
|
||||
self->client->pers.records[REC_KNIFESLASHHITS]++;
|
||||
}
|
||||
if (hitent->client) self->client->knife_sound = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->client->knife_sound = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// NiceAss: Play appropriate sound on 5th slash
|
||||
if (self->client->ps.stats[STAT_BURST] > 4) {
|
||||
if (self->client->knife_sound == 0) { // Missed
|
||||
// TODO: Miss sound should be here, like in AQ2
|
||||
}
|
||||
else if (self->client->knife_sound == -1) { // Hit wall
|
||||
//Elder TODO: take into account surface flags for clank
|
||||
tent = G_TempEntity(tr.endpos, EV_KNIFE_MISS);
|
||||
tent->s.eventParm = DirToByte(tr.plane.normal);
|
||||
tent->s.weapon = WP_KNIFE;
|
||||
}
|
||||
else if (self->client->knife_sound == -2) { // Hit player
|
||||
tent = G_TempEntity(tr.endpos, EV_RQ3_SOUND);
|
||||
tent->s.eventParm = RQ3_SOUND_KNIFEHIT;
|
||||
if (self->client)
|
||||
self->client->pers.records[REC_KNIFESLASHHITS]++;
|
||||
}
|
||||
self->client->knife_sound = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1438,6 +1434,8 @@ void Weapon_SSG3000_FireOld(gentity_t *ent)
|
|||
RQ3_SaveZoomLevel(ent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Elder:
|
||||
|
@ -2365,9 +2363,12 @@ void Laser_Gen( gentity_t *ent, qboolean enabled ) {
|
|||
void Laser_Think( gentity_t *self )
|
||||
{
|
||||
vec3_t end, start, forward, up;
|
||||
trace_t tr;
|
||||
trace_t tr, tr2;
|
||||
int l=0, passent;
|
||||
gentity_t *traceEnt;
|
||||
// NiceAss: For fog:
|
||||
gentity_t *tent;
|
||||
vec3_t fogStart;
|
||||
|
||||
//If the player dies, is spectator, or wrong weapon, kill the dot
|
||||
if (self->parent->client->ps.pm_type == PM_DEAD ||
|
||||
|
@ -2387,6 +2388,9 @@ void Laser_Think( gentity_t *self )
|
|||
CalcMuzzlePoint(self->parent, forward, right, up, start);
|
||||
|
||||
passent = self->parent->s.number;
|
||||
|
||||
self->s.eFlags &= ~EF_FIRING;
|
||||
|
||||
// Keep tracing if it hits glass.
|
||||
for (l = 0; l < 10; l++)
|
||||
{
|
||||
|
@ -2394,6 +2398,7 @@ void Laser_Think( gentity_t *self )
|
|||
|
||||
//Trace Position
|
||||
trap_Trace (&tr, start, NULL, NULL, end, passent, MASK_SHOT);
|
||||
//trap_Trace (&tr2, start, NULL, NULL, end, passent, MASK_SHOT|CONTENTS_FOG);
|
||||
traceEnt = &g_entities[ tr.entityNum ];
|
||||
|
||||
//Did you not hit anything?
|
||||
|
@ -2403,14 +2408,23 @@ void Laser_Think( gentity_t *self )
|
|||
return;
|
||||
}
|
||||
|
||||
VectorMA(tr.endpos, 10, forward, start); // Nudge it forward a little bit
|
||||
|
||||
// It "hit" a player, but actually missed (thanks to new headshot code!)
|
||||
if ( traceEnt->takedamage && traceEnt->client && G_HitPlayer(traceEnt, forward, tr.endpos) == qfalse ) {
|
||||
if ( ( traceEnt->takedamage && traceEnt->client && G_HitPlayer(traceEnt, forward, tr.endpos) == qfalse ) ) {
|
||||
passent = tr.entityNum;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We hit fog...
|
||||
/*
|
||||
if (!VectorCompare(tr.endpos, tr2.endpos)) {
|
||||
VectorCopy(tr2.endpos, tr.endpos);
|
||||
self->s.eFlags |= EF_FIRING;
|
||||
self->s.otherEntityNum = self->parent->client->ps.clientNum;//self->parent->s.number; // ->s.clientNum ???
|
||||
break;
|
||||
}
|
||||
*/
|
||||
if (!(tr.surfaceFlags & SURF_GLASS)) break;
|
||||
VectorMA(tr.endpos, 10, forward, start); // Nudge it forward a little bit
|
||||
}
|
||||
|
||||
//Move you forward to keep you visible
|
||||
|
|
Loading…
Reference in a new issue