For VM 0-03-00
Lots of little bug-fixes and stuff
This commit is contained in:
Victor Chow 2001-07-09 00:32:10 +00:00
parent a772993171
commit bb4f35017c
21 changed files with 461 additions and 125 deletions

View file

@ -2689,6 +2689,59 @@ static void CG_DrawTourneyScoreboard() {
#endif
}
/*
=====================
CG_DrawDamageBlend
Elder: Does a fullscreen alpha blend like Quake 2 when hurt
=====================
*/
#define MAX_DAMAGE_ALPHA 0.75
#define MAX_BLEND_TIME 1500
static void CG_DrawDamageBlend()
{
float dmg;
vec4_t damageColor;
//Leave if no true damage, disabled, or ragepro
if ( !cg.rq3_trueDamage || !rxn_painblend.integer ||
cgs.glconfig.hardwareType == GLHW_RAGEPRO)
{
return;
}
//Clamp blend time
if (cg.rq3_blendTime > MAX_BLEND_TIME)
cg.rq3_blendTime = MAX_BLEND_TIME;
//Reset if we've gone past our blendTime
if (cg.time - cg.damageTime > cg.rq3_blendTime) {
//cg.rq3_trueDamage = 0;
cg.rq3_blendTime = 0;
return;
}
VectorCopy(colorRed, damageColor);
dmg = cg.rq3_trueDamage;
//clamp at 100 health
if (dmg > 100)
dmg = 100;
damageColor[3] = MAX_DAMAGE_ALPHA * (dmg / 100.0) * (1.0 - (cg.time - cg.damageTime) / cg.rq3_blendTime);
if (damageColor[3] > MAX_DAMAGE_ALPHA)
damageColor[3] = MAX_DAMAGE_ALPHA;
else if (damageColor[3] < 0)
damageColor[3] = 0;
CG_FillRect(0,0, SCREEN_WIDTH, SCREEN_HEIGHT, damageColor);
}
/*
=====================
CG_DrawActive
@ -2746,6 +2799,9 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
VectorCopy( baseOrg, cg.refdef.vieworg );
}
// Elder: draw damage blend
CG_DrawDamageBlend();
// draw status bar and other floating elements
CG_Draw2D();
}

View file

@ -525,7 +525,18 @@ static void CG_Missile( centity_t *cent ) {
// spin as it moves
if ( s1->pos.trType != TR_STATIONARY ) {
RotateAroundDirection( ent.axis, cg.time / 4 );
//Spin knife like a wheel
if ( s1->weapon == WP_KNIFE ) {
vec3_t knifeVelocity;
BG_EvaluateTrajectoryDelta(&s1->pos, cg.time, knifeVelocity);
vectoangles(knifeVelocity, cent->lerpAngles);
cent->lerpAngles[0] += cg.time / 6;
AnglesToAxis( cent->lerpAngles, ent.axis );
}
else
RotateAroundDirection( ent.axis, cg.time / 4 );
} else {
#ifdef MISSIONPACK
if ( s1->weapon == WP_PROX_LAUNCHER ) {

View file

@ -1764,18 +1764,20 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
#ifdef MISSIONPACK
case EV_PROXIMITY_MINE_STICK:
DEBUGNAME("EV_PROXIMITY_MINE_STICK");
//Elder: removed
if( es->eventParm & SURF_FLESH ) {
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound );
//trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound );
} else if( es->eventParm & SURF_METALSTEPS ) {
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound );
//trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound );
} else {
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound );
//trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound );
}
break;
case EV_PROXIMITY_MINE_TRIGGER:
DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER");
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound );
//Elder: removed
//trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound );
break;
case EV_KAMIKAZE:
DEBUGNAME("EV_KAMIKAZE");

View file

@ -189,21 +189,21 @@ void CG_DrawInformation( void ) {
//Elder: Initial y-position
y = 96;
// don't print server lines if playing a local game
trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
if ( !atoi( buf ) ) {
// map-specific message (long map name)
s = CG_ConfigString( CS_MESSAGE );
if ( s[0] ) {
// map-specific message (long map name)
s = CG_ConfigString( CS_MESSAGE );
if ( s[0] ) {
//UI_DrawProportionalString( 4, y, s,
//UI_LEFT|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
//Q_strncpyz(buf, s, 1024);
//Q_CleanStr(buf);
CG_DrawSmallStringColor(x, y, s, colorWhite);
y += SMALLCHAR_HEIGHT;
}
}
// don't print server lines if playing a local game
trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
if ( !atoi( buf ) ) {
// server hostname
Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024);
Q_CleanStr(buf);

View file

@ -368,7 +368,7 @@ typedef struct weaponInfo_s {
qhandle_t barrelModel;
qhandle_t flashModel;
//Elder: added third person model to weaponInfo structure
qhandle_t thirdModel;
qhandle_t firstModel;
vec3_t weaponMidpoint; // so it will rotate centered instead of by tag
@ -593,6 +593,11 @@ typedef struct {
float damageTime;
float damageX, damageY, damageValue;
//Elder: added for alpha pain blend
int rq3_trueDamage; //Q3 doesn't hold the actual damage amount in cg.damageValue
//float rq3_lastPainAlpha;
float rq3_blendTime; //How long we take to fade out
// status bar head
float headYaw;
float headEndPitch;
@ -711,7 +716,7 @@ typedef struct {
//Elder: akimbo stuff - since it's valid every game
qhandle_t akimboModel;
qhandle_t akimboFlashModel;
qhandle_t akimbo3rdModel;
qhandle_t akimbo1stModel;
qhandle_t akimboHandModel;
@ -788,6 +793,14 @@ typedef struct {
qhandle_t dishFlashModel;
qhandle_t lightningExplosionModel;
// Elder: RQ3 item models
qhandle_t rq3_kevlarModel;
qhandle_t rq3_bandolierModel;
qhandle_t rq3_silencerModel;
qhandle_t rq3_laserModel;
qhandle_t rq3_slippersModel;
// weapon effect shaders
qhandle_t railExplosionShader;
qhandle_t plasmaExplosionShader;
@ -988,10 +1001,11 @@ typedef struct {
sfxHandle_t n_healthSound;
sfxHandle_t hgrenb1aSound;
sfxHandle_t hgrenb2aSound;
sfxHandle_t wstbimplSound;
sfxHandle_t wstbimpmSound;
sfxHandle_t wstbimpdSound;
sfxHandle_t wstbactvSound;
//Elder: removed
//sfxHandle_t wstbimplSound;
//sfxHandle_t wstbimpmSound;
//sfxHandle_t wstbimpdSound;
//sfxHandle_t wstbactvSound;
} cgMedia_t;
@ -1168,6 +1182,8 @@ extern vmCvar_t rxn_drawWeapon;
extern vmCvar_t rxn_glasstime;
//Elder: muzzle flash toggle
extern vmCvar_t rxn_flash;
//Elder: turn on or off alpha blending
extern vmCvar_t rxn_painblend;
extern vmCvar_t cg_drawFriend;
extern vmCvar_t cg_teamChatsOnly;
extern vmCvar_t cg_noVoiceChats;

View file

@ -142,6 +142,8 @@ vmCvar_t rxn_drawWeapon;
vmCvar_t rxn_glasstime;
//Elder: muzzle flash toggle
vmCvar_t rxn_flash;
//Elder: turn on or off alpha blending
vmCvar_t rxn_painblend;
vmCvar_t cg_drawFriend;
vmCvar_t cg_teamChatsOnly;
vmCvar_t cg_noVoiceChats;
@ -295,7 +297,8 @@ cvarTable_t cvarTable[] = {
{ &rxn_drawWeapon, "rxn_drawWeapon", "2", CVAR_ARCHIVE },
{ &rxn_glasstime, "rxn_glasstime", "0", CVAR_ARCHIVE },
//Elder: added
{ &rxn_flash, "rxn_flash", "1", CVAR_ARCHIVE }
{ &rxn_flash, "rxn_flash", "1", CVAR_ARCHIVE },
{ &rxn_painblend, "rxn_painblend", "1", CVAR_ARCHIVE }
// { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
};
@ -754,10 +757,11 @@ static void CG_RegisterSounds( void ) {
cgs.media.n_healthSound = trap_S_RegisterSound("sound/items/n_health.wav", qfalse );
cgs.media.hgrenb1aSound = trap_S_RegisterSound("sound/weapons/grenade/hgrenb1a.wav", qfalse);
cgs.media.hgrenb2aSound = trap_S_RegisterSound("sound/weapons/grenade/hgrenb2a.wav", qfalse);
cgs.media.wstbimplSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpl.wav", qfalse);
cgs.media.wstbimpmSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpm.wav", qfalse);
cgs.media.wstbimpdSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpd.wav", qfalse);
cgs.media.wstbactvSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbactv.wav", qfalse);
//Elder: removed
//cgs.media.wstbimplSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpl.wav", qfalse);
//cgs.media.wstbimpmSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpm.wav", qfalse);
//cgs.media.wstbimpdSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpd.wav", qfalse);
//cgs.media.wstbactvSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbactv.wav", qfalse);
}
@ -975,9 +979,16 @@ static void CG_RegisterGraphics( void ) {
//Elder: akimbos - some of the stuff isn't in yet :p
cgs.media.akimboModel = trap_R_RegisterModel( "models/weapons2/akimbo/akimbo.md3" );
cgs.media.akimboFlashModel = trap_R_RegisterModel( "models/weapons2/akimbo/akimbo_flash.md3" );
cgs.media.akimbo3rdModel = trap_R_RegisterModel( "models/weapons2/akimbo_3rd.md3" );
cgs.media.akimbo1stModel = trap_R_RegisterModel( "models/weapons2/akimbo_1st.md3" );
cgs.media.akimboHandModel = trap_R_RegisterModel( "models/weapons2/akimbo/akimbo_hand.md3" );
//Elder: item cache
cgs.media.rq3_bandolierModel = trap_R_RegisterModel( "models/items/bandolier.md3" );
cgs.media.rq3_kevlarModel = trap_R_RegisterModel( "models/items/kevlar.md3" );
cgs.media.rq3_silencerModel = trap_R_RegisterModel( "models/items/silencer.md3" );
cgs.media.rq3_laserModel = trap_R_RegisterModel( "models/items/laser.md3" );
cgs.media.rq3_slippersModel = trap_R_RegisterModel( "models/items/slippers.md3" );
cgs.media.smoke2 = trap_R_RegisterModel( "models/weapons2/shells/s_shell.md3" );
cgs.media.balloonShader = trap_R_RegisterShader( "sprites/balloon3" );
@ -1975,6 +1986,8 @@ void CG_EventHandling(int type) {
void CG_KeyEvent(int key, qboolean down) {
//Elder: Let's see what we're pressing
//CG_Printf("Key: %i, isDown: %d\n", key, down);
}
void CG_MouseEvent(int x, int y) {

View file

@ -57,7 +57,8 @@ void CG_CheckAmmo( void ) {
if ( total == 0 ) {
cg.lowAmmoWarning = 2;
} else {
cg.lowAmmoWarning = 1;
//Elder: only allow completely empty ammo warning sounds
//cg.lowAmmoWarning = 1;
}
// play a sound on transitions
@ -81,8 +82,17 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
float dist;
float yaw, pitch;
//Elder: removed
// show the attacking player's head and name in corner
cg.attackerTime = cg.time;
//cg.attackerTime = cg.time;
//Elder: added
cg.rq3_trueDamage = damage;
//Elder: memset in cg_main.c should let us increment safely
if (damage * 10 < 100)
cg.rq3_blendTime += 100;
else
cg.rq3_blendTime += damage * 10;
// the lower on health you are, the greater the view kick will be
health = cg.snap->ps.stats[STAT_HEALTH];

View file

@ -606,7 +606,7 @@ static void CG_DamageBlendBlob( void ) {
int t;
int maxTime;
refEntity_t ent;
if ( !cg.damageValue ) {
return;
}
@ -622,7 +622,6 @@ static void CG_DamageBlendBlob( void ) {
return;
}
memset( &ent, 0, sizeof( ent ) );
ent.reType = RT_SPRITE;
ent.renderfx = RF_FIRST_PERSON;

View file

@ -515,17 +515,18 @@ void CG_RegisterWeapon( int weaponNum ) {
//Elder: added to cache 3rd-person models (hopefully)
strcpy( path, item->world_model[0] );
COM_StripExtension( path, path );
strcat( path, "_3rd.md3" );
weaponInfo->thirdModel = trap_R_RegisterModel( path );
//Elder: changed from _3rd to _1st
strcat( path, "_1st.md3" );
weaponInfo->firstModel = trap_R_RegisterModel( path );
if ( !weaponInfo->handsModel ) {
//Elder: WTF!?
weaponInfo->handsModel = trap_R_RegisterModel( "models/weapons2/m3/m3_hand.md3" );
}
//Elder: if no _3rd model, point to the weaponModel... this may get funky :)
if ( !weaponInfo->thirdModel ) {
weaponInfo->thirdModel = weaponInfo->weaponModel;
//Elder: if no _1st model, point to the weaponModel... this may get funky :)
if ( !weaponInfo->firstModel ) {
weaponInfo->firstModel = weaponInfo->weaponModel;
}
weaponInfo->loopFireSound = qfalse;
@ -737,7 +738,8 @@ void CG_RegisterWeapon( int weaponNum ) {
break;
case WP_GRENADE:
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/grenade/grenade_3rd.md3" );
//Changed from _3rd
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/grenade/grenade.md3" );
weaponInfo->missileTrailFunc = CG_GrenadeTrail;
weaponInfo->wiTrailTime = 700;
weaponInfo->trailRadius = 32;
@ -1099,8 +1101,8 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
//}
if (ps == NULL)
{
//Elder: We are in third person, use the third-person model
gun.hModel = weapon->thirdModel;
//Elder: We are in third person, use the third-person model (DEFAULT)
gun.hModel = weapon->weaponModel;
/* Elder: use the cached model above
switch (weaponNum)//Blaze: Used to make the third person weapon models different then 1st person
@ -1140,8 +1142,8 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
*/
}
else {
//Elder: we are in first-person, use the first-person (default) model
gun.hModel = weapon->weaponModel;
//Elder: we are in first-person, use the first-person (NOT default) model
gun.hModel = weapon->firstModel;
}
if (!gun.hModel) {
@ -1289,11 +1291,11 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
if ( rxn_flash.integer ) {
if (ps) {
//Elder: draw flash based on first-person view
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->firstModel, "tag_flash");
}
else {
//Elder: draw flash based on 3rd-person view
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->thirdModel, "tag_flash");
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
}
trap_R_AddRefEntityToScene( &flash );

View file

@ -185,13 +185,15 @@ gitem_t bg_itemlist[] =
/* precache */ "",
/* sounds */ ""
},
//Blaze: 3rd Person Models
//Elder: 07/06/2001: Now known as 1st-person models!
//Knife
{
"knife_3rd",
"knife_1st",
NULL,
{"models/weapons2/knife/knife_3rd.md3",0,0,0},
{"models/weapons2/knife/knife_1st.md3",0,0,0},
"icons/iconw_knife",
RQ3_KNIFE_NAME,
1,
@ -203,9 +205,9 @@ gitem_t bg_itemlist[] =
//Pistol
{
"pistol_3rd",
"pistol_1st",
NULL,
{ "models/weapons2/mk23/mk23_3rd.md3",
{ "models/weapons2/mk23/mk23_1st.md3",
0, 0, 0},
"icons/iconw_mk23",
RQ3_PISTOL_NAME,
@ -218,9 +220,9 @@ gitem_t bg_itemlist[] =
//M4
{
"m4_3rd",
"m4_1st",
NULL,
{ "models/weapons2/m4/m4_3rd.md3",
{ "models/weapons2/m4/m4_1st.md3",
0, 0, 0},
"icons/iconw_m4",
RQ3_M4_NAME,
@ -233,9 +235,9 @@ gitem_t bg_itemlist[] =
//SSG3000
{
"ssg3000_3rd",
"ssg3000_1st",
NULL,
{ "models/weapons2/ssg3000/ssg3000_3rd.md3",
{ "models/weapons2/ssg3000/ssg3000_1st.md3",
0, 0, 0},
"icons/iconw_ssg",
RQ3_SSG3000_NAME,
@ -248,9 +250,9 @@ gitem_t bg_itemlist[] =
//MP5
{
"mp5_3rd",
"mp5_1st",
NULL,
{ "models/weapons2/mp5/mp5_3rd.md3",
{ "models/weapons2/mp5/mp5_1st.md3",
0, 0, 0},
"icons/iconw_mp5",
RQ3_MP5_NAME,
@ -263,9 +265,9 @@ gitem_t bg_itemlist[] =
//Handcannon
{
"handcannon_3rd",
"handcannon_1st",
NULL,
{ "models/weapons2/handcannon/handcannon_3rd.md3",
{ "models/weapons2/handcannon/handcannon_1st.md3",
0, 0, 0},
"icons/iconw_sawedoff",
RQ3_HANDCANNON_NAME,
@ -278,9 +280,9 @@ gitem_t bg_itemlist[] =
//Shotgun
{
"m3_3rd",
"m3_1st",
NULL,
{ "models/weapons2/m3/m3_3rd.md3",
{ "models/weapons2/m3/m3_1st.md3",
0, 0, 0},
"icons/iconw_m3",
RQ3_M3_NAME,
@ -293,9 +295,9 @@ gitem_t bg_itemlist[] =
//Akimbo Placeholder
{
"akimbo_3rd",
"akimbo_1st",
NULL,
{ "models/weapons2/akimbo/akimbo_3rd.md3",
{ "models/weapons2/akimbo/akimbo_1st.md3",
0, 0, 0},
"icons/iconw_akimbo",
RQ3_AKIMBO_NAME,
@ -309,9 +311,9 @@ gitem_t bg_itemlist[] =
//Grenade
{
"grenade_3rd",
"grenade_1st",
NULL,
{ "models/weapons2/grenade/grenade_3rd.md3",
{ "models/weapons2/grenade/grenade_1st.md3",
0, 0, 0},
"icons/iconw_gren",
RQ3_GRENADE_NAME,
@ -466,13 +468,14 @@ Only in CTF games
/* sounds */ ""
},
//Elder: RQ3 Items
{
"item_kevlar",
"sound/items/kevlar.wav",
{ "models/items/kevlar.md3",
0, 0, 0},
"icons/kevlar",
"Kevlar Vest",
"icons/iconi_kevlar",
RQ3_KEVLAR_NAME,
0,
IT_HOLDABLE,
HI_KEVLAR,
@ -480,6 +483,62 @@ Only in CTF games
""
},
{
"item_silencer",
"sound/items/silencer.wav",
{ "models/items/silencer.md3",
0, 0, 0},
"icons/iconi_silencer",
RQ3_SILENCER_NAME,
0,
IT_HOLDABLE,
HI_SILENCER,
"",
""
},
{
"item_laser",
"sound/items/laser.wav",
{ "models/items/laser.md3",
0, 0, 0},
"icons/iconi_laser",
RQ3_LASER_NAME,
0,
IT_HOLDABLE,
HI_LASER,
"",
""
},
{
"item_bandolier",
"sound/items/bandolier.wav",
{ "models/items/bandolier.md3",
0, 0, 0},
"icons/iconi_bandolier",
RQ3_BANDOLIER_NAME,
0,
IT_HOLDABLE,
HI_BANDOLIER,
"",
""
},
{
"item_slippers",
"sound/items/slippers.wav",
{ "models/items/slippers.md3",
0, 0, 0},
"icons/iconi_slippers",
RQ3_SLIPPERS_NAME,
0,
IT_HOLDABLE,
HI_SLIPPERS,
"",
""
},
#ifdef MISSIONPACK
/*QUAKED holdable_kamikaze (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
@ -718,12 +777,13 @@ Only in One Flag CTF games
IT_WEAPON,
WP_PROX_LAUNCHER,
/* precache */ "",
/* sounds */ "sound/weapons/proxmine/wstbtick.wav "
//Elder: removing so we get rid of those error messages
/* sounds */ /*"sound/weapons/proxmine/wstbtick.wav "
"sound/weapons/proxmine/wstbactv.wav "
"sound/weapons/proxmine/wstbimpl.wav "
"sound/weapons/proxmine/wstbimpm.wav "
"sound/weapons/proxmine/wstbimpd.wav "
"sound/weapons/proxmine/wstbactv.wav"
"sound/weapons/proxmine/wstbactv.wav"*/
},
/*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended

View file

@ -1185,6 +1185,8 @@ static void PM_CrashLand( void ) {
}
else {
PM_AddEvent( PM_FootstepForSurface() );
//Elder: added? useful?
pm->ps->stats[STAT_FALLDAMAGE] = 0;
}
}
@ -1997,11 +1999,24 @@ static void PM_Weapon( void ) {
//G_Printf("Taking away ammo\n");
pm->ps->ammo[ pm->ps->weapon ]--;
}
//Elder: special weapon case handling
//Elder: remove knives from inventory if out of ammo
if (pm->ps->weapon == WP_KNIFE && pm->ps->ammo[ WP_KNIFE ] == 0)
{
pm->ps->stats[STAT_WEAPONS] &= ~( 1 << WP_KNIFE);
}
//Elder: remove grenade from inventory if out of ammo
else if (pm->ps->weapon == WP_GRENADE && pm->ps->ammo[ WP_GRENADE ] == 0)
{
pm->ps->stats[STAT_WEAPONS] &= ~( 1 << WP_GRENADE);
}
//Elder: remove one more bullet/shell if handcannon/akimbo
if (pm->ps->weapon == WP_HANDCANNON) {
else if (pm->ps->weapon == WP_HANDCANNON)
{
pm->ps->ammo[ pm->ps->weapon ]--;
}
//Elder: take away an extra bullet if available - handled in g_weapon.c as well
else if (pm->ps->weapon == WP_AKIMBO && pm->ps->ammo[ WP_AKIMBO ] > 0) {
pm->ps->ammo[ WP_AKIMBO ] --;

View file

@ -520,7 +520,7 @@ typedef enum {
} powerup_t;
//Elder: swapped around
//Elder: swapped around + full Bando name and typo fix on "slipers"
typedef enum {
HI_NONE,
@ -532,8 +532,8 @@ typedef enum {
HI_KEVLAR,
HI_LASER,
HI_SILENCER,
HI_BANDO,
HI_SLIPERS,
HI_BANDOLIER,
HI_SLIPPERS,
HI_NUM_HOLDABLE
} holdable_t;

View file

@ -57,6 +57,8 @@ qboolean JumpKick( gentity_t *ent )
gentity_t *tent;
gentity_t *traceEnt;
int damage;
//Elder: for kick sound
qboolean kickSuccess;
// set aiming directions
AngleVectors (ent->client->ps.viewangles, forward, right, up);
@ -75,17 +77,9 @@ qboolean JumpKick( gentity_t *ent )
return qfalse;
}
DoorKick( &tr, ent, muzzle, forward );
kickSuccess = DoorKick( &tr, ent, muzzle, forward );
traceEnt = &g_entities[ tr.entityNum ];
// send blood impact
if ( traceEnt->takedamage && traceEnt->client ) {
tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT );
tent->s.otherEntityNum = traceEnt->s.number;
tent->s.eventParm = DirToByte( tr.plane.normal );
tent->s.weapon = ent->s.weapon;
}
if ( !traceEnt->takedamage) {
return qfalse;
}
@ -98,8 +92,39 @@ qboolean JumpKick( gentity_t *ent )
}
damage = 20;
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
damage, DAMAGE_NO_LOCATIONAL, MOD_KICK );
//Elder: can't hit if crouching but can still hit "dead" bodies :)
if (traceEnt->client && traceEnt->health > 0 && traceEnt->r.maxs[2] < 20)
{
return qfalse;
}
else {
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
damage, DAMAGE_NO_LOCATIONAL, MOD_KICK );
}
// send blood impact
if ( traceEnt->takedamage && traceEnt->client ) {
tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT );
tent->s.otherEntityNum = traceEnt->s.number;
tent->s.eventParm = DirToByte( tr.plane.normal );
tent->s.weapon = ent->s.weapon;
kickSuccess = qtrue;
}
if (traceEnt->client && traceEnt->client->ps.stats[STAT_UNIQUEWEAPONS] > 0)
{
//Elder: toss a unique weapon if kicked
//Todo: Need to make sure to cancel any reload attempts
//Todo: need to send a message to attacker and target about weapon kick
ThrowWeapon(traceEnt);
//trap_SendServerCommand( ent-g_entities, va("print \"You kicked %s's %s from his hands!\n\"", traceEnt->client->pers.netname, (traceEnt->client->ps.weapon)->pickup_name);
//trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\""));
}
//Elder: for the kick
// do our special form of knockback here
@ -111,8 +136,29 @@ qboolean JumpKick( gentity_t *ent )
if (self->enemy->velocity[2] > 0)
self->enemy->groundentity = NULL;
*/
//Elder: kick knockback for AQ2 -- recall variable kick = 400
if (traceEnt->client)
{
//Elder: for kick knockback
vec3_t size, vTemp;
//Make the "size" vector - hopefully this is right
VectorSubtract(traceEnt->r.maxs, traceEnt->r.mins, size);
G_Printf("Size: %s\n", vtos(size));
VectorMA(traceEnt->r.absmin, 0.5, size, vTemp);
VectorSubtract(vTemp, tr.endpos, vTemp);
VectorNormalize(vTemp);
VectorMA(traceEnt->client->ps.velocity, 400, vTemp, traceEnt->client->ps.velocity);
if (traceEnt->client->ps.velocity[2] > 0)
traceEnt->s.groundEntityNum = ENTITYNUM_NONE;
}
//Elder: Our set of locally called sounds
G_AddEvent ( ent, EV_RQ3_SOUND, RQ3_SOUND_KICK);
if (kickSuccess)
G_AddEvent ( ent, EV_RQ3_SOUND, RQ3_SOUND_KICK);
return qtrue;
}
@ -137,6 +183,9 @@ void P_DamageFeedback( gentity_t *player ) {
}
// total points of damage shot at the player this frame
if (client->damage_blood > 0)
G_Printf("(%i) Damage_blood: %i\n", player->s.clientNum, client->damage_blood);
count = client->damage_blood + client->damage_armor;
if ( count == 0 ) {
return; // didn't take any damage
@ -221,7 +270,9 @@ void P_DamageFeedback( gentity_t *player ) {
//Elder: headshot sound
case LOCATION_HEAD:
case LOCATION_FACE:
G_AddEvent ( player, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT);
//Elder: takes more bandwidth but guarantees a headshot sound
G_Sound(player, CHAN_AUTO, G_SoundIndex("sound/misc/headshot.wav"));
//G_AddEvent ( player, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT);
break;
default:
G_AddEvent( player, EV_PAIN, player->health );
@ -338,7 +389,8 @@ G_SetClientSound
void G_SetClientSound( gentity_t *ent ) {
#ifdef MISSIONPACK
if( ent->s.eFlags & EF_TICKING ) {
ent->client->ps.loopSound = G_SoundIndex( "sound/weapons/proxmine/wstbtick.wav");
//Elder: removed
//ent->client->ps.loopSound = G_SoundIndex( "sound/weapons/proxmine/wstbtick.wav");
}
else
#endif
@ -621,6 +673,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
if ( client->ps.stats[STAT_ARMOR] > 100) {// max is 100 client->ps.stats[STAT_MAX_HEALTH] ) {
client->ps.stats[STAT_ARMOR]--;
}
//Blaze: Do bandaging stuff
if (ent->client->bleedtick > 1)
{
@ -632,6 +685,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
ent->client->bleed_remain = 0;
ent->client->bleeding = 0;
ent->client->bleedtick = 0;
ent->client->bleedBandageCount = 0;
//Elder: added
//ent->client->isBandaging = qfalse;
//Elder: remove bandage work
@ -750,8 +804,10 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
damage = ent->client->ps.stats[STAT_FALLDAMAGE];
VectorSet (dir, 0, 0, 1);
ent->pain_debounce_time = level.time + 200; // no normal pain sound
//Elder: added so we can trigger AQ2 pain blends
ent->client->ps.damageEvent++;
G_Damage (ent, NULL, NULL, NULL, NULL, damage, 0, MOD_FALLING);
break;
case EV_FIRE_WEAPON:
@ -1475,7 +1531,8 @@ void ClientEndFrame( gentity_t *ent ) {
if (level.time % 30000 < 1)
{
G_Printf("Spawn an Item\n");
rq3_item = BG_FindItem( "Kevlar Vest" );
//rq3_item = BG_FindItem( "Kevlar Vest" );
rq3_item = BG_FindItemForHoldable( HI_KEVLAR );
rq3_temp = SelectSpawnPoint(ent->client->ps.origin,spawn_origin, spawn_angles);
Drop_Item (rq3_temp, rq3_item, 0);
}

View file

@ -1647,9 +1647,11 @@ void Cmd_Bandage (gentity_t *ent)
ent->client->ps.weaponTime += 6000;
ent->client->bleedtick = 4;
//Elder: added to track health to bleed off
ent->client->bleedBandageCount = BLEED_BANDAGE;
//Elder: added
//ent->client->isBandaging = qtrue;
ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_WORK;
ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_WORK;
//Elder: moved to g_active where it will be unset after 2 bleedticks
//ent->client->ps.stats[STAT_RQ3] &= !RQ3_LEGDAMAGE;
}

View file

@ -97,7 +97,7 @@ void TossClientItems( gentity_t *self ) {
*/
//Elder: run through player STAT_WEAPONS and drop any unique weapons
//That way, we can also account for the bandolier automatically
//That way, we can also account for servers with extra weapons
//BTW, that means no cheating to get all weapons or it'll spawn mad!!
weaponInventory = self->client->ps.stats[STAT_WEAPONS];
@ -113,6 +113,7 @@ void TossClientItems( gentity_t *self ) {
item = BG_FindItemForWeapon( WP_M3 );
Drop_Item( self, item, angle);
self->client->pers.hadUniqueWeapon[ WP_M3 ] = qfalse;
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
angle += 30;
}
@ -120,6 +121,7 @@ void TossClientItems( gentity_t *self ) {
item = BG_FindItemForWeapon( WP_M4 );
Drop_Item( self, item, angle);
self->client->pers.hadUniqueWeapon[ WP_M4 ] = qfalse;
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
angle += 30;
}
@ -127,6 +129,7 @@ void TossClientItems( gentity_t *self ) {
item = BG_FindItemForWeapon( WP_MP5 );
Drop_Item( self, item, angle);
self->client->pers.hadUniqueWeapon[ WP_MP5 ] = qfalse;
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
angle += 30;
}
@ -134,6 +137,7 @@ void TossClientItems( gentity_t *self ) {
item = BG_FindItemForWeapon( WP_HANDCANNON );
Drop_Item( self, item, angle);
self->client->pers.hadUniqueWeapon[ WP_HANDCANNON ] = qfalse;
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
angle += 30;
}
@ -141,6 +145,7 @@ void TossClientItems( gentity_t *self ) {
item = BG_FindItemForWeapon( WP_SSG3000 );
Drop_Item( self, item, angle);
self->client->pers.hadUniqueWeapon[ WP_SSG3000 ] = qfalse;
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
angle += 30;
}
@ -1372,9 +1377,12 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
targ->health, take, asave );
}
// Elder: moved below location damage
// 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
/*
if ( client ) {
if ( attacker ) {
client->ps.persistant[PERS_ATTACKER] = attacker->s.number;
@ -1392,6 +1400,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
client->damage_fromWorld = qtrue;
}
}
*/
// See if it's the player hurting the emeny flag carrier
#ifdef MISSIONPACK
@ -1440,8 +1449,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
tookShellHit[playernum] = 1;
}
else {
//Grenade stuff
trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname));
//Grenade stuff - don't print if you hurt yourself
if (targ != attacker)
trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname));
}
}
@ -1626,6 +1636,29 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
// End Duffman
}
// 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
if ( client ) {
if ( attacker ) {
client->ps.persistant[PERS_ATTACKER] = attacker->s.number;
} else {
client->ps.persistant[PERS_ATTACKER] = ENTITYNUM_WORLD;
}
client->damage_armor += asave;
client->damage_blood += take;
client->damage_knockback += knockback;
if ( dir ) {
VectorCopy ( dir, client->damage_from );
client->damage_fromWorld = qfalse;
} else {
VectorCopy ( targ->r.currentOrigin, client->damage_from );
client->damage_fromWorld = qtrue;
}
}
// do the damage
if (take) {
// G_Printf("(%d) taken as damage\n",take);

View file

@ -12,8 +12,11 @@
#define GAMEVERSION "reaction"
#define BODY_QUEUE_SIZE 8
//Blaze: How long someone bleads for
//Blaze: How long someone bleeds for
#define BLEED_TIME 10 // 10 = 1 second is time for losing 1 health at slowest bleed rate
//Elder: Everyone knows you lose 6 health from the moment you start bandaging
//Let's enforce that in-code because it's sometimes 7 or even 8
#define BLEED_BANDAGE 6
// types of locations that can be hit
#define LOC_HDAM 1 // head
@ -339,7 +342,8 @@ struct gclient_s {
//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.
int bleedBandageCount; //Elder: hack to restrict amount of bleeding to 6 points
//Elder: server only needs to know for sniper spread - ARGH
// int zoomed; // Hawkins (SSG zoom)
//qboolean semi; // hawkins (semiauto mode for m4, mp5, pistol)

View file

@ -155,7 +155,8 @@ static void ProximityMine_Activate( gentity_t *ent ) {
ent->health = 1;
ent->die = ProximityMine_Die;
ent->s.loopSound = G_SoundIndex( "sound/weapons/proxmine/wstbtick.wav" );
//Elder: removed
//ent->s.loopSound = G_SoundIndex( "sound/weapons/proxmine/wstbtick.wav" );
// build the proximity trigger
trigger = G_Spawn ();
@ -433,13 +434,15 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
//missed throw or hit func_breakable;
//spawn a knife at its trajectory end-point
xr_item = BG_FindItemForWeapon( WP_KNIFE );
BG_EvaluateTrajectoryDelta(&ent->s.pos, level.time, knifeVelocity);
if (other->s.eType == ET_BREAKABLE) {
VectorScale(trace->plane.normal, 10, knifeVelocity);
knifeVelocity[1] -= 50;
VectorScale(knifeVelocity, -0.25, knifeVelocity);
//breakable "hit"; make it fall to the ground
xr_drop = LaunchItem(xr_item, trace->endpos, knifeVelocity, FL_DROPPED_ITEM);
//but still set it as a thrown knife
//xr_drop->flags |= FL_THROWN_KNIFE;
@ -447,8 +450,10 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
//and transfer into shared entityState
VectorScale(trace->plane.normal, 16, temp);
VectorAdd(trace->endpos, temp, knifeOffset);
VectorCopy(xr_drop->s.origin, temp);
VectorAdd(temp, knifeOffset, xr_drop->s.origin);
//VectorCopy(xr_drop->s.origin, temp);
VectorAdd(xr_drop->s.origin, knifeOffset, xr_drop->s.origin);
VectorCopy(xr_drop->s.origin, xr_drop->r.currentOrigin);
}
else {
@ -458,28 +463,24 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
//Elder: make the knife stick out a bit more
//and transfer into shared entityState
VectorCopy(ent->s.pos.trDelta, temp);
VectorCopy(knifeVelocity, temp);
VectorNormalize(temp);
VectorScale(temp, -4, temp);
VectorAdd(trace->endpos, temp, knifeOffset);
VectorCopy(xr_drop->s.origin, temp);
VectorAdd(temp, knifeOffset, xr_drop->s.origin);
//VectorCopy(xr_drop->s.origin, temp);
VectorAdd(xr_drop->s.origin, knifeOffset, xr_drop->s.origin);
}
//Elder: make the knife stick out a bit more
//and transfer into shared entityState
//VectorScale(trace->plane.normal, 4, temp);
//VectorAdd(trace->endpos, temp, knifeOffset);
//VectorCopy(xr_drop->s.origin, temp);
//VectorAdd(temp, knifeOffset, xr_drop->s.origin);
//Elder: transfer entity data into the shared entityState
//They are rotated on the client side in cg_ents.c
//G_Printf("movedir: %s\n", vtos(ent->s.pos.trDelta));
xr_drop->s.eFlags = xr_drop->flags;
//vectoangles( trace->plane.normal, xr_drop->s.angles );
vectoangles( ent->s.pos.trDelta, xr_drop->s.angles );
vectoangles( knifeVelocity, xr_drop->s.angles);
xr_drop->s.angles[0] += 90;
}
}
@ -599,6 +600,19 @@ void G_RunMissile( gentity_t *ent ) {
return; // exploded
}
}
//Elder: make knife follow the trajectory - not real but oh well...
/* Done in CG_Missile locally to save bandwidth
if (ent->classname == "weapon_knife")
{
vec3_t knifeVelocity;
BG_EvaluateTrajectoryDelta(&ent->s.pos, level.time, knifeVelocity);
vectoangles(knifeVelocity, ent->s.angles);
ent->s.angles[0] += level.time % 360;
}
*/
#ifdef MISSIONPACK
// if the prox mine wasn't yet outside the player body
if (ent->s.weapon == WP_PROX_LAUNCHER && !ent->count) {
@ -732,6 +746,12 @@ gentity_t *fire_knife (gentity_t *self, vec3_t start, vec3_t dir)
gentity_t *bolt;
// vec3_t gVec;
// gVec[0] = 0;
// gVec[1] = g_gravity.value;
// gVec[2] = 0;
VectorNormalize (dir);
bolt = G_Spawn();
@ -757,6 +777,13 @@ gentity_t *fire_knife (gentity_t *self, vec3_t start, vec3_t dir)
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin);
VectorCopy (dir, bolt->s.apos.trBase);
VectorCopy (dir, bolt->r.currentAngles);
//Saving stuff for Makro's knife equations
VectorCopy( start, bolt->s.origin2);
VectorCopy( dir, bolt->s.angles2);
return bolt;
}

View file

@ -611,7 +611,6 @@ void Reached_BinaryMover( gentity_t *ent ) {
// return to pos1 after a delay
ent->think = ReturnToPos1;
ent->nextthink = level.time + ent->wait;
;
}
// fire targets
@ -630,7 +629,7 @@ void Reached_BinaryMover( gentity_t *ent ) {
}
// close areaportals
if ( ent->teammaster == ent || !ent->teammaster ) {
if ( ent->teammaster == ent || !ent->teammaster) {
trap_AdjustAreaPortalState( ent, qfalse );
}
@ -727,7 +726,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
MatchTeam( ent, MOVER_2TO1, level.time + 50);
if ( ent->sound1to2 ) {
G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 );
}
}
}
else {
//Elder: normal Q3 door
@ -1178,7 +1177,7 @@ void SP_func_door (gentity_t *ent) {
char *sSndStart;
//Elder: can set sounds from here
G_SpawnString( "soundstart", "sound/movers/doors/dr1_strt.wav", &sSndStart );
G_SpawnString( "soundstart", "sound/movers/doors/dr1_end.wav", &sSndStart );
G_SpawnString( "soundstop", "sound/movers/doors/dr1_end.wav", &sSndStop );
G_SpawnString( "soundmove", "sound/movers/doors/dr1_strt.wav", &sSndMove );
@ -1259,6 +1258,10 @@ void SP_func_door (gentity_t *ent) {
}
}
//Elder: open areaportals for start_open doors
if ( (ent->spawnflags & 1) == 1 && (ent->teammaster == ent || !ent->teammaster) ) {
trap_AdjustAreaPortalState( ent, qtrue );
}
}
@ -1293,7 +1296,7 @@ void SP_func_door_rotating ( gentity_t *ent ) {
char *sSndStart;
//Elder: can set sounds from here
G_SpawnString( "soundstart", "sound/movers/doors/dr1_strt.wav", &sSndStart );
G_SpawnString( "soundstart", "sound/movers/doors/dr1_end.wav", &sSndStart );
G_SpawnString( "soundstop", "sound/movers/doors/dr1_end.wav", &sSndStop );
G_SpawnString( "soundmove", "sound/movers/doors/dr1_strt.wav", &sSndMove );

View file

@ -783,7 +783,8 @@ KNIFE ATTACKS
========================================================================
*/
int Knife_Attack ( gentity_t *self, int damage)
//Elder: changed to void function
void Knife_Attack ( gentity_t *self, int damage)
{
trace_t tr;
vec3_t end;
@ -806,14 +807,18 @@ int Knife_Attack ( gentity_t *self, int damage)
{
if (hitent->takedamage)
{
G_Damage (hitent, self, self, forward, tr.endpos, damage, 0, MOD_KNIFE );
return -2;
//Elder: no knock-back on knife slashes
G_Damage (hitent, self, self, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_KNIFE );
return;
//return -2;
}
}
else
return 0;
//return 0;
return;
}
return 0; // we hit the sky, call it a miss
return;
//return 0; // we hit the sky, call it a miss
}
static int knives = 0;

View file

@ -1,22 +1,43 @@
#include "g_local.h"
//Elder: someone should comment this b/c it's hard to follow
//Makes the damage "non-instant" like AQ2
void CheckBleeding(gentity_t *targ)
{
int damage;
int temp;
if (!(targ->client->bleeding) || (targ->health <=0)) return;
temp = (int)(targ->client->bleeding * .2);
targ->client->bleeding -= temp;
if (temp <= 0) temp=1;
if (temp <= 0) temp = 1;
targ->client->bleed_remain += temp;
damage = (int)(targ->client->bleed_remain/BLEED_TIME);
if (targ->client->bleed_remain >= BLEED_TIME)
{
targ->health -= damage;
if (targ->health <=0)
if ( (targ->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK &&
targ->client->bleedBandageCount < 1)
{
player_die(targ,&g_entities[targ->client->lasthurt_client],&g_entities[targ->client->lasthurt_client],damage,targ->client->lasthurt_mod);
//Elder: skip damage being dealt
}
else
{
targ->health -= damage;
}
//Elder: hack to count off health so we only lose 6 health on a bandage
if ( (targ->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK)
{
targ->client->bleedBandageCount--;
}
if (targ->health <= 0)
{
player_die(targ, &g_entities[targ->client->lasthurt_client], &g_entities[targ->client->lasthurt_client], damage, targ->client->lasthurt_mod);
}
else
{
@ -25,7 +46,7 @@ void CheckBleeding(gentity_t *targ)
}
}
//Elder: apparently does nothing
//Elder: apparently does nothing and is unused
void StartBandage(gentity_t *ent)
{
ent->client->bleeding = 0;

View file

@ -166,12 +166,12 @@ void UI_DrawConnectScreen( qboolean overlay ) {
//UI_DrawProportionalString( 320, 96, "Press Esc to abort", UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color );
// display global MOTD at bottom
UI_DrawProportionalString( x, 384,
UI_DrawProportionalString( x, 352,
Info_ValueForKey( cstate.updateInfoString, "motd" ), UI_LEFT|UI_SMALLFONT, menu_text_color );
// print any server info (server full, bad version, etc)
if ( cstate.connState < CA_CONNECTED ) {
UI_DrawProportionalString( x, 400, cstate.messageString, UI_LEFT|UI_SMALLFONT, menu_text_color );
UI_DrawProportionalString( x, 384, cstate.messageString, UI_LEFT|UI_SMALLFONT, menu_text_color );
}
#if 0