New code for upcoming VM 0-09-00
Server-side
This commit is contained in:
Victor Chow 2001-08-17 20:48:18 +00:00
parent 7b3547e2b5
commit 2a5aacc346
10 changed files with 270 additions and 77 deletions

View file

@ -1279,6 +1279,9 @@ char *eventnames[] = {
"EV_FOOTSTEP",
"EV_FOOTSTEP_METAL",
"EV_FOOTSTEP_GRASS", // Elder: grass stuff
"EV_FOOTSTEP_WOOD",
"EV_FOOTSTEP_CARPET",
"EV_FOOTSTEP_METAL2",
"EV_FOOTSPLASH",
"EV_FOOTWADE",
"EV_SWIM",

View file

@ -1148,6 +1148,19 @@ static int PM_FootstepForSurface( void ) {
if ( pml.groundTrace.surfaceFlags & SURF_GRASS ) {
return EV_FOOTSTEP_GRASS;
}
if ( pml.groundTrace.surfaceFlags & SURF_WOOD ) {
return EV_FOOTSTEP_WOOD;
}
if ( pml.groundTrace.surfaceFlags & SURF_CARPET ) {
return EV_FOOTSTEP_CARPET;
}
if ( pml.groundTrace.surfaceFlags & SURF_METAL2 ) {
return EV_FOOTSTEP_METAL2;
}
return EV_FOOTSTEP;
}
@ -1758,7 +1771,16 @@ static void PM_BeginWeaponChange( int weapon ) {
}
PM_AddEvent( EV_CHANGE_WEAPON );
pm->ps->weaponstate = WEAPON_DROPPING;
//Elder: ignore disarm delays when throwing a weapon
if (pm->ps->stats[STAT_RQ3] & RQ3_THROWWEAPON)
{
//Com_Printf("Got to throw skip\n");
pm->ps->stats[STAT_RQ3] &= ~RQ3_THROWWEAPON;
pm->ps->weaponTime = 0;
}
else
{
//pm->ps->weaponTime += 200;
//Elder: dependent time for each weapon
switch (pm->ps->weapon) {
@ -1797,11 +1819,20 @@ static void PM_BeginWeaponChange( int weapon ) {
}
//Elder: temp hack
if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_HANDCANNON)
if (pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON)
PM_StartWeaponAnim(WP_ANIM_DISARM);
}
pm->ps->weaponstate = WEAPON_DROPPING;
//Elder: temp hack
if (pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON)
PM_StartWeaponAnim(WP_ANIM_DISARM);
PM_StartTorsoAnim( TORSO_DROP );
}
@ -1870,7 +1901,9 @@ static void PM_FinishWeaponChange( void ) {
}
//Elder: temp hack
if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_HANDCANNON)
if (pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON)
PM_StartWeaponAnim(WP_ANIM_ACTIVATE);
PM_StartTorsoAnim( TORSO_RAISE );
@ -1894,7 +1927,9 @@ static void PM_TorsoAnimation( void ) {
// QUARANTINE - Weapon Animation
// Should always draw the weapon when it is just ready
//Elder: temp hack
if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_HANDCANNON)
if (pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON)
PM_ContinueWeaponAnim( WP_ANIM_IDLE );
// PM_ContinueWeaponAnim( WP_ANIM_READY );
@ -1913,12 +1948,12 @@ static void PM_WeaponAnimation( void ) {
{
PM_ContinueWeaponAnim( WP_ANIM_RELOAD );
}
else if (pm->ps->weaponstate == WEAPON_READY)
PM_ContinueWeaponAnim( WP_ANIM_IDLE );
else if (pm->ps->weaponstate == WEAPON_DROPPING)
PM_ContinueWeaponAnim( WP_ANIM_DISARM );
else if (pm->ps->weaponstate == WEAPON_RAISING)
PM_ContinueWeaponAnim( WP_ANIM_ACTIVATE );
//else if (pm->ps->weaponstate == WEAPON_READY)
//PM_ContinueWeaponAnim( WP_ANIM_IDLE );
//else if (pm->ps->weaponstate == WEAPON_DROPPING)
//PM_ContinueWeaponAnim( WP_ANIM_DISARM );
//else if (pm->ps->weaponstate == WEAPON_RAISING)
//PM_ContinueWeaponAnim( WP_ANIM_ACTIVATE );
return;
}
@ -2049,9 +2084,11 @@ static void PM_Weapon( void ) {
}
else
{
//Elder: added
//Elder: temp hack
if (pm->ps->weaponstate == WEAPON_READY &&
(pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_HANDCANNON))
(pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON))
PM_ContinueWeaponAnim(WP_ANIM_IDLE);
}
}
@ -2093,7 +2130,10 @@ static void PM_Weapon( void ) {
// QUARANTINE - Weapon Animation
// Should always draw the weapon when it is just ready
// PM_StartWeaponAnim( WP_ANIM_READY );
if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_HANDCANNON)
// temp hack
if (pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON)
PM_StartWeaponAnim( WP_ANIM_IDLE );
return;
}
@ -2178,7 +2218,9 @@ static void PM_Weapon( void ) {
// QUARANTINE - Weapon animations
// This should change pm->ps->generic1 so we can animate
// Elder: don't repeat if on semi-auto
if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_HANDCANNON)
if (pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON)
PM_StartWeaponAnim( WP_ANIM_FIRE );
}
}
@ -2741,8 +2783,10 @@ void PmoveSingle (pmove_t *pmove) {
PM_Weapon();
//weapon animations(rq3 specific)
//Elder: hack to avoid messing up fast-reloads
if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3 || pm->ps->weapon == WP_HANDCANNON)
//Elder: temp hack to avoid messing up fast-reloads
if (pm->ps->weapon == WP_PISTOL ||
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON )
PM_WeaponAnimation();
// torso animation

View file

@ -374,7 +374,7 @@ typedef enum {
WEAPON_RAISING, //sync with WP_ANIM_ACTIVATE
WEAPON_DROPPING, //sync with WP_ANIM_DISARM
WEAPON_FIRING, //sync with WP_ANIM_FIRE
WEAPON_RELOADING //sync with WP_ANIM_RELOAD
WEAPON_RELOADING, //sync with WP_ANIM_RELOAD
} weaponstate_t;
//Blaze: for the weapon animation states
@ -385,7 +385,7 @@ typedef enum {
WP_ANIM_IDLE,
WP_ANIM_DISARM,
WP_ANIM_ACTIVATE,
//WP_ANIM_FIRE2,
//WP_ANIM_EMPTY,
MAX_WEAPON_ANIMATIONS
} wpAnimNumber_t;
@ -463,7 +463,7 @@ typedef enum {
STAT_CLIENTS_READY, // bit mask of clients wishing to exit the intermission (FIXME: configstring?)
// STAT_MAX_HEALTH, // health / armor limit, changable by handicap
//STAT_MAX_HEALTH, // health / armor limit, changable by handicap
//These are RQ3-related specific stats
STAT_CLIPS, // Num Clips player currently has
@ -482,7 +482,7 @@ typedef enum {
//Elder: zoom stat - 1x = 0, 2x = zoom low, 4x = zoom_med, 6x = zoom_low + zoom_med
#define RQ3_ZOOM_LOW 8
#define RQ3_ZOOM_MED 16
#define RQ3_THROWWEAPON 32 //Present if dropping weapon via cmd or kicked away
// player_state->persistant[] indexes
@ -610,6 +610,22 @@ typedef enum {
WP_NUM_WEAPONS
} weapon_t;
// Elder: for our end-level awards later on
typedef enum {
RECORD_HEADSHOTS,
RECORD_CHESTSHOTS,
RECORD_STOMACHSHOTS,
RECORD_LEGSHOTS,
RECORD_FALLINGDEATHS,
RECORD_CAMPCOUNT,
RECORD_JUMPCOUNT, // e.g. rabbit or monkey award
RECORD_SUICIDES, // e.g. for MPELP award
RECORD_STEALTHKILLS,
RECORD_FRAGSTEALS,
RECORD_TOTAL
} rq3record_t;
//Elder: added
//
@ -645,6 +661,9 @@ typedef enum {
EV_FOOTSTEP,
EV_FOOTSTEP_METAL,
EV_FOOTSTEP_GRASS, // Elder: new surfaces
EV_FOOTSTEP_WOOD,
EV_FOOTSTEP_CARPET,
EV_FOOTSTEP_METAL2,
EV_FOOTSPLASH,
EV_FOOTWADE,
EV_SWIM,

View file

@ -906,7 +906,14 @@ int ThrowWeapon( gentity_t *ent, qboolean forceThrow )
//Elder: Don't reset the weapon ammo
//client->ps.ammo[ weap ] = 0;
client->pers.hadUniqueWeapon[weap] = qtrue;
//Elder: for immediate weapon drops
if (client->ps.weapon == weap)
{
client->ps.stats[STAT_RQ3] |= RQ3_THROWWEAPON;
trap_SendServerCommand( ent-g_entities, va("selectpistol"));
}
client->ps.stats[STAT_WEAPONS] &= ~( 1 << weap);
xr_drop= dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM );

View file

@ -1279,6 +1279,9 @@ void ClientSpawn(gentity_t *ent) {
// set default animations
client->ps.torsoAnim = TORSO_STAND;
client->ps.legsAnim = LEGS_IDLE;
// weapon animations
client->ps.generic1 = ( ( client->ps.generic1 & ANIM_TOGGLEBIT )
^ ANIM_TOGGLEBIT ) | WP_ANIM_IDLE;
if ( level.intermissiontime ) {
MoveClientToIntermission( ent );

View file

@ -451,6 +451,9 @@ void Cmd_LevelShot_f( gentity_t *ent ) {
/*
==================
Elder: WTF... this is the wrong description, but it was
like this in the 1.29h source
Cmd_LevelShot_f
This is just to help generate the level pictures
@ -876,15 +879,20 @@ void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText )
if (validation != SAY_OK)
{
// Only send one message for the initial offense
if (ent->client->pers.sayMuteTime == level.time)
if (ent->client->pers.sayMuteTime == level.time && ent->client->pers.sayModerated == qfalse)
{
ent->client->pers.sayModerated = qtrue;
if (validation == SAY_WARNING)
{
trap_SendServerCommand( ent-g_entities, va("print \"Exceeded message limit - ^3WARNING ^7(%i seconds).\n\"", SAY_WARNING_TIME));
trap_SendServerCommand( ent-g_entities, va("print \"Exceeded message limit - ^3WARNING ^7(%i seconds).\n\"", g_RQ3_messageWarnTime.integer));
G_LogPrintf( "Server: %s received a message protect warning (offense %i)\n", ent->client->pers.netname, ent->client->pers.sayWarnings);
}
else if (validation == SAY_BAN)
{
trap_SendServerCommand( ent-g_entities, va("print \"Exceeded message limit - ^1BAN ^7(%i seconds).\n\"", SAY_BAN_TIME));
// Don't bother printing if kicked
if (g_RQ3_messageBanTime.integer > 0)
trap_SendServerCommand( ent-g_entities, va("print \"Exceeded message limit - ^1BAN ^7(%i seconds).\n\"", g_RQ3_messageBanTime.integer));
G_LogPrintf( "Server: %s received a message protect ban (offense %i)\n", ent->client->pers.netname, ent->client->pers.sayBans);
}
}
@ -1669,7 +1677,9 @@ void Cmd_Bandage (gentity_t *ent)
ent->client->ps.weaponstate = WEAPON_DROPPING;
//Elder: temp hack
if (ent->client->ps.weapon == WP_PISTOL || ent->client->ps.weapon == WP_M3)
if (ent->client->ps.weapon == WP_PISTOL ||
ent->client->ps.weapon == WP_M3 ||
ent->client->ps.weapon == WP_HANDCANNON)
{
ent->client->ps.generic1 = ( ( ent->client->ps.generic1 & ANIM_TOGGLEBIT )
^ ANIM_TOGGLEBIT ) | WP_ANIM_DISARM;
@ -2549,11 +2559,73 @@ spam from reaching other clients.
int RQ3_ValidateSay ( gentity_t *ent )
{
int timeCheck;
int warnTime;
int banTime;
int intervalTime;
int maxWarnings;
int maxMessages;
if (ent->client->pers.sayWarnings)
timeCheck = SAY_WARNING_TIME * 1000;
if (g_RQ3_messageProtect.integer == 0)
return SAY_OK;
// Check for good cvar values and set them to defaults if bad
// We use local vars because the cvars may not update in time for use
// message count
if (g_RQ3_messageMaxCount.integer < 0)
{
maxMessages = atoi(SAY_MAX_NUMBER);
trap_Cvar_Set( "sv_RQ3_messageMaxCount", SAY_MAX_NUMBER);
}
else
timeCheck = SAY_BAN_TIME * 1000;
maxMessages = g_RQ3_messageMaxCount.integer;
// warning time
if (g_RQ3_messageWarnTime.integer < 0)
{
warnTime = atoi(SAY_WARNING_TIME);
trap_Cvar_Set( "sv_RQ3_messageWarnTime", SAY_WARNING_TIME);
}
else
warnTime = g_RQ3_messageWarnTime.integer;
// max warnings
if (g_RQ3_messageMaxWarnings.integer < 0)
{
maxWarnings = atoi(SAY_MAX_WARNINGS);
trap_Cvar_Set( "sv_RQ3_messageMaxWarnings", SAY_MAX_WARNINGS);
}
else
maxWarnings = g_RQ3_messageMaxWarnings.integer;
// ban time
if (g_RQ3_messageBanTime.integer < 0)
{
banTime = atoi(SAY_BAN_TIME);
trap_Cvar_Set( "sv_RQ3_messageBanTime", SAY_BAN_TIME);
}
else
banTime = g_RQ3_messageBanTime.integer;
// interval time
if (g_RQ3_messageInterval.integer < 0)
{
intervalTime = atoi(SAY_PERIOD_TIME);
trap_Cvar_Set( "sv_RQ3_messageInterval", SAY_PERIOD_TIME);
}
else
intervalTime = g_RQ3_messageInterval.integer;
// seconds to milliseconds
if (ent->client->pers.sayWarnings)
{
timeCheck = warnTime * 1000;
}
else
{
timeCheck = banTime * 1000;
}
// check if already warned/banned
if (ent->client->pers.sayMuteTime &&
@ -2566,17 +2638,22 @@ int RQ3_ValidateSay ( gentity_t *ent )
}
// check if a flooder
if (ent->client->pers.sayCount >= SAY_MAX_NUMBER &&
level.time - ent->client->pers.sayTime < SAY_PERIOD_TIME * 1000)
if (ent->client->pers.sayCount >= maxMessages &&
level.time - ent->client->pers.sayTime < intervalTime * 1000)
{
ent->client->pers.sayMuteTime = level.time;
// determine penalty level
if (ent->client->pers.sayWarnings >= SAY_MAX_WARNINGS)
if (ent->client->pers.sayWarnings >= maxWarnings)
{
// bans never reset, but warnings do
ent->client->pers.sayBans++;
ent->client->pers.sayWarnings = 0;
// kick if no ban time is set
if (banTime == 0)
trap_DropClient(ent->s.clientNum, "Dropped due to chat abuse");
return SAY_BAN;
}
else
@ -2587,11 +2664,12 @@ int RQ3_ValidateSay ( gentity_t *ent )
}
// regular say check
if (level.time - ent->client->pers.sayTime > SAY_PERIOD_TIME * 1000)
if (level.time - ent->client->pers.sayTime > intervalTime * 1000)
{
ent->client->pers.sayCount = 0;
ent->client->pers.sayTime = level.time;
ent->client->pers.sayMuteTime = 0;
ent->client->pers.sayModerated = qfalse;
}
ent->client->pers.sayCount++;

View file

@ -818,8 +818,11 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
// Elder: only do death sounds if not hit in the head
if ((self->client->lasthurt_location & LOCATION_HEAD) != LOCATION_HEAD &&
(self->client->lasthurt_location & LOCATION_FACE) != LOCATION_FACE )
//G_Printf("Shot Diff: %i\n", level.time - self->client->headShotTime);
//if ((self->client->lasthurt_location & LOCATION_HEAD) != LOCATION_HEAD &&
//(self->client->lasthurt_location & LOCATION_FACE) != LOCATION_FACE &&
if (level.time - self->client->headShotTime > 400)
G_AddEvent( self, EV_DEATH1 + i, killer );
// the body can still be gibbed
@ -1631,6 +1634,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{
case LOCATION_HEAD:
case LOCATION_FACE:
//save headshot time for player_die
targ->client->headShotTime = level.time;
//Elder: reusing line so we don't have to declare more variables
line[0] = 0;
line[1] = 0;

View file

@ -269,17 +269,24 @@ typedef struct {
int sayWarnings;
int sayBans;
int sayMuteTime;
qboolean sayModerated; // so warnings are not repeated for multi-line, same-frame messages
} clientPersistant_t;
// Elder: spam prevention defaults
/*
#define SAY_MAX_NUMBER 6
#define SAY_MAX_WARNINGS 3
#define SAY_PERIOD_TIME 3 // Elder: in seconds
#define SAY_WARNING_TIME 15
#define SAY_BAN_TIME 60 // Technically should drop client
*/
#define SAY_MAX_NUMBER "6"
#define SAY_MAX_WARNINGS "3"
#define SAY_PERIOD_TIME "3" // Elder: in seconds
#define SAY_WARNING_TIME "15"
#define SAY_BAN_TIME "60" // Technically should drop client
typedef enum
{
SAY_BAN,
@ -393,6 +400,7 @@ struct gclient_s {
// 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
int headShotTime; // Elder: got headshot?
//Elder: server only needs to know for sniper spread - ARGH
// int zoomed; // Hawkins (SSG zoom)
@ -410,6 +418,8 @@ struct gclient_s {
int consecutiveShots; // Elder: for M4 ride-up/kick
int uniqueWeapons; // Elder: formerly a stat, now just a server var
int uniqueItems;
//int records[RECORD_TOTAL]; // Elder: for our awards when we implement it
#ifdef MISSIONPACK
gentity_t *persistantPowerup;
@ -920,6 +930,13 @@ extern vmCvar_t g_proxMineTimeout;
//Blaze: Reaction cvars
extern vmCvar_t g_rxn_knifelimit;
extern vmCvar_t g_RQ3_maxWeapons;
//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
extern vmCvar_t g_RQ3_messageMaxWarnings; // Max warning count
extern vmCvar_t g_RQ3_messageWarnTime; // Time for warning; 0 for no-penalty warning
extern vmCvar_t g_RQ3_messageBanTime; // Time for ban; 0 to kick
extern vmCvar_t g_RQ3_messageProtect; // Elder: 0 disable, non-zero enable
void trap_Printf( const char *fmt );
void trap_Error( const char *fmt );

View file

@ -64,6 +64,13 @@ vmCvar_t g_listEntity;
//Blaze: Reaction cvars
vmCvar_t g_rxn_knifelimit;
vmCvar_t g_RQ3_maxWeapons;
//Elder: spam protection cvars
vmCvar_t g_RQ3_messageMaxCount;
vmCvar_t g_RQ3_messageInterval;
vmCvar_t g_RQ3_messageMaxWarnings;
vmCvar_t g_RQ3_messageWarnTime;
vmCvar_t g_RQ3_messageBanTime;
vmCvar_t g_RQ3_messageProtect;
#ifdef MISSIONPACK
vmCvar_t g_obeliskHealth;
vmCvar_t g_obeliskRegenPeriod;
@ -163,7 +170,13 @@ static cvarTable_t gameCvarTable[] = {
{ &g_rankings, "g_rankings", "0", 0, 0, qfalse},
//Blaze: Reaction stuff
{ &g_RQ3_maxWeapons, "g_RQ3_maxWeapons", "1",0,0,qtrue}
{ &g_RQ3_maxWeapons, "g_RQ3_maxWeapons", "1",0,0, qtrue},
{ &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}
};

View file

@ -59,5 +59,8 @@
#define SURF_NODLIGHT 0x20000 // don't dlight even if solid (solid lava, skies)
#define SURF_DUST 0x40000 // leave a dust trail when walking on this surface
//Elder: new surfaces
#define SURF_GRASS 0x80000 // grass footsteps and turf hits later
//#define SURF_CERAMIC 0x100000
#define SURF_GRASS 0x80000
#define SURF_WOOD 0x100000
#define SURF_CARPET 0x200000
#define SURF_METAL2 0x400000