Code for 0-14-00 VMs
Server-side
This commit is contained in:
Victor Chow 2001-10-11 22:52:43 +00:00
parent 9839e288a6
commit 0d6cebd40c
12 changed files with 192 additions and 42 deletions

View file

@ -1333,6 +1333,7 @@ char *eventnames[] = {
"EV_BULLET_HIT_WALL",
"EV_BULLET_HIT_METAL", // Elder: sparks
"EV_BULLET_HIT_KEVLAR", // Elder: sparks
"EV_BULLET_HIT_GLASS", // Elder: glass mark
"EV_SSG3000_HIT_FLESH", // Elder: SSG3000 blood spray
"EV_JUMPKICK", // Elder: sound + jumpkick message
"EV_EJECTBLOOD", // Elder: when bleeding, every 2s release blood

View file

@ -1257,9 +1257,11 @@ static void PM_CrashLand( void ) {
*/
//delta = vel + t * acc;
//Blaze: added to make it more like aq2
delta = pm->ps->velocity[2] - pml.previous_velocity[2];
//delta = pm->ps->velocity[2] - pml.previous_velocity[2];
// Elder: 300/320 factor included
delta = 0.9375f * (pm->ps->velocity[2] - pml.previous_velocity[2]);
delta = delta*delta * 0.0001;
// ducking while falling doubles damage
// if ( pm->ps->pm_flags & PMF_DUCKED ) {
// delta *= 2;
@ -1319,19 +1321,23 @@ static void PM_CrashLand( void ) {
}
else if (delta > 20)
{ if (bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_SLIPPERS)
{ PM_AddEvent( EV_FALL_SHORT_NOSOUND );
{
PM_AddEvent( EV_FALL_SHORT_NOSOUND );
//Elder: added? useful?
pm->ps->stats[STAT_FALLDAMAGE] = 0;
}
else
{ PM_AddEvent( EV_FALL_SHORT );
{
PM_AddEvent( EV_FALL_SHORT );
//Elder: added? useful?
pm->ps->stats[STAT_FALLDAMAGE] = 0;
}
}
else if (!(bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_SLIPPERS))
{
PM_AddEvent( PM_FootstepForSurface() );
// Elder: don't spam sound events going up -- more like Q2 ladders as well
if (!pml.ladder || pm->ps->velocity[2] < 0)
PM_AddEvent( PM_FootstepForSurface() );
//Elder: added? useful?
pm->ps->stats[STAT_FALLDAMAGE] = 0;
}
@ -1463,7 +1469,9 @@ static void PM_GroundTrace( void ) {
}
// if the trace didn't hit anything, we are in free fall
if ( trace.fraction == 1.0 ) {
// Elder: added ladder check
if ( trace.fraction == 1.0 && !pml.ladder) {
//if ( trace.fraction == 1.0 ) {
PM_GroundTraceMissed();
pml.groundPlane = qfalse;
pml.walking = qfalse;
@ -1491,7 +1499,8 @@ static void PM_GroundTrace( void ) {
}
// slopes that are too steep will not be considered onground
if ( trace.plane.normal[2] < MIN_WALK_NORMAL ) {
// Elder: added ladder check
if ( trace.plane.normal[2] < MIN_WALK_NORMAL && !pml.ladder) {
if ( pm->debugLevel ) {
Com_Printf("%i:steep\n", c_pmove);
}
@ -1521,8 +1530,17 @@ static void PM_GroundTrace( void ) {
PM_CrashLand();
// Elder: added ladder check
if (pml.ladder)
{
pml.groundPlane = qfalse;
pml.walking = qfalse;
return;
}
// don't do landing time if we were just going down a slope
if ( pml.previous_velocity[2] < -200 ) {
// Elder: maybe this is keeping the strafe jumping too tight?
// don't allow another jump for a little while
pm->ps->pm_flags |= PMF_TIME_LAND;
pm->ps->pm_time = 250;
@ -1888,6 +1906,7 @@ static void PM_BeginWeaponChange( int weapon ) {
pm->ps->stats[STAT_RELOADATTEMPTS] = 0;
pm->ps->stats[STAT_RQ3] &= ~RQ3_FASTRELOADS;
pm->ps->stats[STAT_RQ3] &= ~RQ3_LOCKRELOADS;
pm->ps->stats[STAT_RQ3] &= ~RQ3_QUEUERELOAD;
pm->ps->weaponstate = WEAPON_DROPPING;
@ -2033,10 +2052,10 @@ PM_WeaponAnimation
==============
*/
static void PM_WeaponAnimation( void ) {
if (pm->ps->weaponstate == WEAPON_RELOADING)
{
PM_ContinueWeaponAnim( WP_ANIM_RELOAD );
}
//if (pm->ps->weaponstate == WEAPON_RELOADING)
//{
//PM_ContinueWeaponAnim( WP_ANIM_RELOAD );
//}
//else if (pm->ps->weaponstate == WEAPON_READY)
//PM_ContinueWeaponAnim( WP_ANIM_IDLE );
//else if (pm->ps->weaponstate == WEAPON_DROPPING)
@ -2065,6 +2084,7 @@ It is triggered by BUTTON_AFFIRMATIVE (bind +button5)
static void PM_Reload( void )
{
// int weapon = pm->ps->weapon;
int truePress = 0;
// only normal/noclip players can reload
if (pm->ps->pm_type > PM_NOCLIP)
@ -2074,9 +2094,21 @@ static void PM_Reload( void )
pm->ps->stats[STAT_RELOADATTEMPTS] = 0;
pm->ps->stats[STAT_RQ3] &= ~RQ3_FASTRELOADS;
pm->ps->stats[STAT_RQ3] &= ~RQ3_LOCKRELOADS;
pm->ps->stats[STAT_RQ3] &= ~RQ3_QUEUERELOAD;
return;
}
// try to reload since it's queued
if ( pm->ps->stats[STAT_RQ3] & RQ3_QUEUERELOAD )
{
if ( (pm->cmd.buttons & BUTTON_AFFIRMATIVE) && !(pm->ps->pm_flags & PMF_RELOAD_HELD))
truePress = 1;
pm->ps->stats[STAT_RQ3] &= ~RQ3_QUEUERELOAD;
pm->ps->pm_flags &= ~PMF_RELOAD_HELD;
pm->cmd.buttons |= BUTTON_AFFIRMATIVE;
}
if ( pm->cmd.buttons & BUTTON_AFFIRMATIVE ) {
if ( !(pm->ps->pm_flags & PMF_RELOAD_HELD) )
{
@ -2085,7 +2117,16 @@ static void PM_Reload( void )
// check for bursting or weapon delay
if (pm->ps->stats[STAT_BURST] > 0 || pm->ps->weaponTime > 0)
{
if (truePress && (pm->ps->weapon == WP_SSG3000 || pm->ps->weapon == WP_M3))
{
pm->ps->stats[STAT_RQ3] |= RQ3_FASTRELOADS;
pm->ps->stats[STAT_RELOADATTEMPTS]++;
}
pm->ps->stats[STAT_RQ3] |= RQ3_QUEUERELOAD;
return;
}
// check for bandaging
if (pm->ps->stats[STAT_RQ3] & RQ3_BANDAGE_WORK)
@ -2172,7 +2213,12 @@ static void PM_Reload( void )
break;
}
// start the animation off
if (pm->ps->weaponstate != WEAPON_RELOADING)
PM_StartWeaponAnim(WP_ANIM_RELOAD);
pm->ps->weaponstate = WEAPON_RELOADING;
PM_AddEvent(EV_RELOAD_WEAPON0);
//Com_Printf("Starting reload\n");
return;
@ -2270,8 +2316,11 @@ static void PM_Reload( void )
if (pm->ps->stats[STAT_RELOADATTEMPTS] > 0)
PM_StartWeaponAnim(WP_ANIM_RELOAD);
//PM_StartWeaponAnim(WP_ANIM_EXTRA1);
{
PM_StartWeaponAnim(WP_ANIM_EXTRA1);
//PM_StartWeaponAnim(WP_ANIM_RELOAD);
}
if (pm->ps->stats[STAT_CLIPS] > 0)
{
@ -2304,6 +2353,7 @@ static void PM_Reload( void )
// lock fast-reloads during finish delay
pm->ps->stats[STAT_RQ3] |= RQ3_LOCKRELOADS;
//Com_Printf("<<<<<<<<<<<<< Locking\n");
PM_StartWeaponAnim( WP_ANIM_EXTRA2 );
}
return;
@ -3114,13 +3164,14 @@ void CheckLadder( void )
pml.ladder = qtrue;
// Elder: does this work?
/*
if (pml.ladder && pml.previous_ladder == qfalse)
{
if (pm->debugLevel)
Com_Printf("Hit ladder hard\n");
PM_CrashLand();
}
*/
}
@ -3291,7 +3342,8 @@ void PmoveSingle (pmove_t *pmove) {
} else if ( pm->waterlevel > 1 && !pml.ladder) { //Blaze: wtf, need to add a comment to make it a big enough change for cvs to notice
// swimming
PM_WaterMove();
} else if (pml.ladder) {
// Elder: Added !(...) check below to prevent crouch spasms at bottom of ladders
} else if (pml.ladder && !(pm->ps->viewheight == CROUCH_VIEWHEIGHT && pm->ps->groundEntityNum != ENTITYNUM_NONE)) {
PM_LadderMove();
} else if ( pml.walking ) {
// walking on ground

View file

@ -66,6 +66,11 @@
#define RQ3_DEBRIS_CONCRETE 0x00000400
#define RQ3_DEBRIS_POPCAN 0x00000800
// Elder: dynamic light switches
#define DLIGHT_ADDITIVE 1
#define DLIGHT_FLICKER 2
#define DLIGHT_PULSE 4
#define DLIGHT_STROBE 8
//Old debris definitions
//Elder: debris bit parms to pass to break_glass - maybe I should enum this?
@ -136,10 +141,6 @@
//Elder: confused?
//Elder: used for STAT_KNIFE ... obsolete now
//#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"
@ -169,11 +170,6 @@ typedef enum {
RQ3_SOUND_TOTAL
} rq3_sounds_t;
//#define RQ3_SOUND_KICK 0
//#define RQ3_SOUND_HEADSHOT 1
//#define RQ3_SOUND_KNIFEDEATH 2
//#define RQ3_SOUND_LCA 3 //lights, camera, action!
//Elder: Weapon damage and spread stats
#define PISTOL_DAMAGE 90
#define MP5_DAMAGE 55
@ -498,9 +494,7 @@ typedef enum {
#define RQ3_THROWWEAPON 32 // Present if dropping weapon via cmd or kicked away
#define RQ3_FASTRELOADS 64 // Fast-reloads flag
#define RQ3_LOCKRELOADS 128 // Lock-reloads at end of fast-reload cycle
// Elder: reload status; 0 + 1 = stage 2
//#define RQ3_RELOADSTAGE0 256
//#define RQ3_RELOADSTAGE1 512
#define RQ3_QUEUERELOAD 256 // auto-reload if set
// player_state->persistant[] indexes
@ -828,6 +822,7 @@ typedef enum {
EV_BULLET_HIT_WALL,
EV_BULLET_HIT_METAL, // Elder: sparks
EV_BULLET_HIT_KEVLAR, // Elder: sparks
EV_BULLET_HIT_GLASS, // Elder: glass mark
EV_SSG3000_HIT_FLESH,
EV_JUMPKICK, // Elder: sound + jumpkick message
EV_EJECTBLOOD, // Elder: when bleeding, every 2s release blood
@ -1159,6 +1154,7 @@ typedef enum {
ET_GRAPPLE, // grapple hooked on wall
ET_TEAM,
ET_LASER, // lasersight entity type
ET_DLIGHT, // Elder: dynamic light entity
ET_EVENTS // any of the EV_* events can be added freestanding
// by setting eType to ET_EVENTS + eventNum

View file

@ -242,21 +242,31 @@ void P_WorldEffects( gentity_t *ent ) {
//
if (waterlevel &&
(ent->watertype&(CONTENTS_LAVA|CONTENTS_SLIME)) ) {
/*
if (ent->health > 0
&& ent->pain_debounce_time <= level.time ) {
*/
// Elder: changed around a bit -- using timestamp variable
if ( ent->health > 0 && level.time > ent->timestamp)
{
if ( envirosuit ) {
G_AddEvent( ent, EV_POWERUP_BATTLESUIT, 0 );
} else {
if (ent->watertype & CONTENTS_LAVA) {
//G_Damage (ent, NULL, NULL, NULL, NULL,
//30*waterlevel, 0, MOD_LAVA);
G_Damage (ent, NULL, NULL, NULL, NULL,
30*waterlevel, 0, MOD_LAVA);
3*waterlevel, 0, MOD_LAVA);
}
if (ent->watertype & CONTENTS_SLIME) {
//G_Damage (ent, NULL, NULL, NULL, NULL,
//10*waterlevel, 0, MOD_SLIME);
G_Damage (ent, NULL, NULL, NULL, NULL,
10*waterlevel, 0, MOD_SLIME);
waterlevel, 0, MOD_SLIME);
}
// Elder: added
ent->timestamp = level.time + FRAMETIME;
}
}
}

View file

@ -1332,6 +1332,11 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
}
}
#endif
// Elder: respawn protection -- only for gunfire though!
// No safety from falling!
if ( targ->client && inflictor &&
level.time - targ->client->respawnTime < g_RQ3_respawnProtectTime.integer * 1000)
return;
if ( !inflictor ) {
inflictor = &g_entities[ENTITYNUM_WORLD];

View file

@ -723,6 +723,7 @@ void DropPortalDestination( gentity_t *ent );
#endif
void G_BreakGlass( gentity_t *ent, vec3_t point, int mod );//Blaze: Breakable glass
void G_RunDlight ( gentity_t *ent ); // Elder: dlight running
//
// g_weapon.c
@ -953,6 +954,8 @@ extern vmCvar_t g_proxMineTimeout;
extern vmCvar_t g_rxn_knifelimit;
extern vmCvar_t g_RQ3_maxWeapons;
extern vmCvar_t g_RQ3_statLog;
extern vmCvar_t g_RQ3_ejectBlood;
extern vmCvar_t g_RQ3_respawnProtectTime;
//Elder: spam protection cvars
extern vmCvar_t g_RQ3_messageMaxCount; // Max messages in interval
extern vmCvar_t g_RQ3_messageInterval; // Time interval for spam check

View file

@ -65,6 +65,8 @@ vmCvar_t g_listEntity;
vmCvar_t g_rxn_knifelimit;
vmCvar_t g_RQ3_maxWeapons;
vmCvar_t g_RQ3_statLog;
vmCvar_t g_RQ3_ejectBlood;
vmCvar_t g_RQ3_respawnProtectTime;
//Elder: spam protection cvars
vmCvar_t g_RQ3_messageMaxCount;
vmCvar_t g_RQ3_messageInterval;
@ -171,14 +173,17 @@ static cvarTable_t gameCvarTable[] = {
{ &g_rankings, "g_rankings", "0", 0, 0, qfalse},
//Blaze: Reaction stuff
// Elder: these are explicit values set every time the game initializes
{ &g_RQ3_ejectBlood, "g_RQ3_ejectBlood", "0", CVAR_ARCHIVE | CVAR_NORESTART,0, qfalse},
{ &g_RQ3_maxWeapons, "g_RQ3_maxWeapons", "1",0,0, qtrue},
{ &g_RQ3_respawnProtectTime, "g_RQ3_respawnProtectTime", "2", CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue},
{ &g_RQ3_statLog, "sv_RQ3_statLog", "1", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse},
{ &g_RQ3_messageMaxCount, "sv_RQ3_messageMaxCount", SAY_MAX_NUMBER, CVAR_ARCHIVE, 0, qfalse },
{ &g_RQ3_messageInterval, "sv_RQ3_messageInterval", SAY_PERIOD_TIME, CVAR_ARCHIVE, 0, qfalse },
{ &g_RQ3_messageMaxWarnings, "sv_RQ3_messageMaxWarnings", SAY_MAX_WARNINGS, CVAR_ARCHIVE, 0, qfalse },
{ &g_RQ3_messageWarnTime, "sv_RQ3_messageWarnTime", SAY_WARNING_TIME, CVAR_ARCHIVE, 0, qfalse },
{ &g_RQ3_messageBanTime, "sv_RQ3_messageBanTime", SAY_BAN_TIME, CVAR_ARCHIVE, 0, qfalse },
{ &g_RQ3_messageProtect, "sv_RQ3_messageProtect", "1", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qtrue}
{ &g_RQ3_messageMaxCount, "sv_RQ3_messageMaxCount", SAY_MAX_NUMBER, 0, 0, qfalse },
{ &g_RQ3_messageInterval, "sv_RQ3_messageInterval", SAY_PERIOD_TIME, 0, 0, qfalse },
{ &g_RQ3_messageMaxWarnings, "sv_RQ3_messageMaxWarnings", SAY_MAX_WARNINGS, 0, 0, qfalse },
{ &g_RQ3_messageWarnTime, "sv_RQ3_messageWarnTime", SAY_WARNING_TIME, 0, 0, qfalse },
{ &g_RQ3_messageBanTime, "sv_RQ3_messageBanTime", SAY_BAN_TIME, 0, 0, qfalse },
{ &g_RQ3_messageProtect, "sv_RQ3_messageProtect", "1", CVAR_SERVERINFO, 0, qtrue}
};
@ -1802,6 +1807,7 @@ start = trap_Milliseconds();
// clear events that are too old
if ( level.time - ent->eventTime > EVENT_VALID_MSEC ) {
if ( ent->s.event ) {
//G_Printf("Discarded: %i\n", ent->s.event & ~EV_EVENT_BITS);
ent->s.event = 0; // &= EV_EVENT_BITS;
if ( ent->client ) {
ent->client->ps.externalEvent = 0;
@ -1861,6 +1867,12 @@ start = trap_Milliseconds();
continue;
}
// Elder: run dynamic lights
if ( ent->s.eType == ET_DLIGHT ) {
G_RunDlight( ent );
continue;
}
if ( i < MAX_CLIENTS ) {
G_RunClient( ent );
continue;

View file

@ -46,6 +46,63 @@ void SP_light( gentity_t *self ) {
G_FreeEntity( self );
}
/*QUAKED dlight (0 1 0) (-8 -8 -8) (8 8 8)
Dynamic light entity. Use sparingly.
Q3 does not allow for manual light radius setup.
Set the color key for the intended color
"light" overrides the default 100 intensity.
*/
void SP_dlight( gentity_t *ent ) {
vec3_t color;
float light;
int r, g, b, i;
int style;
G_SpawnFloat( "light", "300", &light );
G_SpawnVector( "_color", "1 1 1", color );
// - set style bits in eventParm
if ( ent->spawnflags & 1 )
ent->s.eventParm |= DLIGHT_ADDITIVE;
if ( ent->spawnflags & 2 )
ent->s.eventParm |= DLIGHT_FLICKER;
if ( ent->spawnflags & 4 )
ent->s.eventParm |= DLIGHT_PULSE;
if ( ent->spawnflags & 8 )
ent->s.eventParm |= DLIGHT_STROBE;
r = color[0] * 255;
if ( r > 255 ) {
r = 255;
}
g = color[1] * 255;
if ( g > 255 ) {
g = 255;
}
b = color[2] * 255;
if ( b > 255 ) {
b = 255;
}
i = light / 4;
if ( i > 255 ) {
i = 255;
}
ent->s.constantLight = r | ( g << 8 ) | ( b << 16 ) | ( i << 24 );
ent->s.eType = ET_DLIGHT;
ent->classname = "dlight";
ent->s.pos.trType = TR_STATIONARY;
VectorCopy( ent->s.origin, ent->r.currentOrigin);
trap_LinkEntity( ent );
}
// Nothing significant to do
void G_RunDlight ( gentity_t *ent ) {
trap_LinkEntity( ent );
}
/*
@ -444,6 +501,7 @@ void SP_func_breakable( gentity_t *ent ) {
trap_LinkEntity (ent);
}
/*
=================
G_BreakGlass
@ -513,8 +571,8 @@ void G_BreakGlass( gentity_t *ent, vec3_t point, int mod )
break;
}
G_Printf("(%f) (%f) (%f)\n", impactPoint[0], impactPoint[1], impactPoint[2]);
G_FreeEntity( ent );
G_Printf("%s shift: %i\n", vtos(impactPoint), shiftCount);
switch ( shiftCount )
{
case 0:
@ -530,10 +588,10 @@ void G_BreakGlass( gentity_t *ent, vec3_t point, int mod )
G_Error("G_BreakGlass: shiftCount > 2\n");
break;
}
//G_Printf("eType: %i\n", tent->s.event & ~EV_EVENT_BITS);
//Elder: use TempEntity2 to stuff params
//tent = G_TempEntity( center, EV_BREAK_GLASS );
tent->s.eventParm = eParm;
//tent->s.eventParm = eParm;
}
}

View file

@ -147,6 +147,7 @@ void SP_target_location (gentity_t *ent);
void SP_target_push (gentity_t *ent);
void SP_light (gentity_t *self);
void SP_dlight (gentity_t *self); // Elder: dlight entity
void SP_info_null (gentity_t *self);
void SP_info_notnull (gentity_t *self);
void SP_info_camp (gentity_t *self);
@ -226,6 +227,7 @@ spawn_t spawns[] = {
{"target_push", SP_target_push},
{"light", SP_light},
{"dlight", SP_dlight}, // Elder: dlight entity
{"path_corner", SP_path_corner},
{"misc_teleporter_dest", SP_misc_teleporter_dest},

View file

@ -455,6 +455,10 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_METAL );
tent->s.eventParm = DirToByte( tr.plane.normal );
tent->s.otherEntityNum = ent->s.number;
} else if ( tr.surfaceFlags & SURF_GLASS) {
tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_GLASS );
tent->s.eventParm = DirToByte( tr.plane.normal );
tent->s.otherEntityNum = ent->s.number;
} else {
tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_WALL );
tent->s.eventParm = DirToByte( tr.plane.normal );
@ -1231,7 +1235,10 @@ int RQ3_Spread (gentity_t *ent, int spread)
float xyspeed = (ent->client->ps.velocity[0]*ent->client->ps.velocity[0] + ent->client->ps.velocity[1]*ent->client->ps.velocity[1]);
//crouching
if (ent->client->ps.pm_flags & PMF_DUCKED)
//if (ent->client->ps.pm_flags & PMF_DUCKED)
// make sure player is actually on the ground
if (ent->client->ps.groundEntityNum != ENTITYNUM_NONE &&
ent->client->ps.pm_flags & PMF_DUCKED)
return (spread * 0.65);
//running
@ -1257,7 +1264,6 @@ int RQ3_Spread (gentity_t *ent, int spread)
stage = 1;
}
return (int)(spread * factor[stage]);
/*
@ -1541,6 +1547,8 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
if ( (trace.surfaceFlags & SURF_METALSTEPS) ||
(trace.surfaceFlags & SURF_METAL2) )
tent[unlinked] = G_TempEntity( trace.endpos, EV_BULLET_HIT_METAL );
else if (trace.surfaceFlags & SURF_GLASS)
tent[unlinked] = G_TempEntity( trace.endpos, EV_BULLET_HIT_GLASS );
else
tent[unlinked] = G_TempEntity( trace.endpos, EV_BULLET_HIT_WALL );
@ -1602,6 +1610,8 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
if ( (trace.surfaceFlags & SURF_METALSTEPS) ||
(trace.surfaceFlags & SURF_METAL2) )
tentWall = G_TempEntity( trace.endpos, EV_BULLET_HIT_METAL );
else if (trace.surfaceFlags & SURF_GLASS)
tentWall = G_TempEntity( trace.endpos, EV_BULLET_HIT_GLASS );
else
{
tentWall = G_TempEntity( trace.endpos, EV_BULLET_HIT_WALL );

View file

@ -59,7 +59,7 @@ void CheckBleeding(gentity_t *targ)
targ->client->bleed_remain %= realBleedTime;
}
if (targ->client->bleed_delay <= level.time)
if (g_RQ3_ejectBlood.integer && targ->client->bleed_delay <= level.time)
{
vec3_t bleedOrigin;

View file

@ -63,4 +63,5 @@
#define SURF_WOOD 0x100000
#define SURF_CARPET 0x200000
#define SURF_METAL2 0x400000
#define SURF_GLASS 0x800000 // not really a surface; more for marks