diff --git a/Source/Client/Draw.c b/Source/Client/Draw.c index f0e3cfb2..85517da3 100644 --- a/Source/Client/Draw.c +++ b/Source/Client/Draw.c @@ -49,6 +49,8 @@ void CSQC_Parse_Print(string sMessage, float fLevel ) { } fChatTime = time + CHAT_TIME; + } else { + print( sMessage ); } } diff --git a/Source/Client/Entities.c b/Source/Client/Entities.c index 5b3ef946..4b37cb2b 100644 --- a/Source/Client/Entities.c +++ b/Source/Client/Entities.c @@ -28,18 +28,20 @@ Called whenever an entity is sent manually via .SendFlags and so on void CSQC_Ent_Update( float fIsNew ) { float fEntType = readbyte(); - if ( fEntType == 1 ) { + if ( fEntType == ENT_AMBIENTSOUND ) { self.origin_x = readcoord(); self.origin_y = readcoord(); self.origin_z = readcoord(); setorigin( self, self.origin ); + + CSQC_ambient_generic( readstring(), readfloat(), readbyte() ); + } else if ( fEntType == ENT_SPRITE ) { + self.origin_x = readcoord(); + self.origin_y = readcoord(); + self.origin_z = readcoord(); - string sSample = readstring(); // WriteString( MSG_ENTITY, self.message ); - float fVolume = readfloat(); // WriteFloat( MSG_ENTITY, self.health ); - float fAttennuation = readbyte(); // WriteByte( MSG_ENTITY, self.style ); - CSQC_ambient_generic( sSample, fVolume, fAttennuation ); - //print( sprintf( "[DEV] Ambientsound (%s), ATTN %d \n", sSample, fAttennuation ) ); + Effect_AnimatedSprite( self.origin, readfloat(), readfloat(), readfloat(), readfloat(), readfloat() ); } } diff --git a/Source/Client/HUD.c b/Source/Client/HUD.c index 72a0d505..9ee1ccc2 100644 --- a/Source/Client/HUD.c +++ b/Source/Client/HUD.c @@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define NUMSIZE_X 0.09375 #define NUMSIZE_Y 0.09765625 +#define HUD_ALPHA 0.6 + // Instead of calculating them on demand, just read the offsets here float vHUDNumPos[10] = { 0, @@ -92,12 +94,24 @@ HUD_DrawHealth Draw the current amount of health ================= */ +float fOldHealth; +float fHealthAlpha; void HUD_DrawHealth( void ) { + if ( getstatf( STAT_HEALTH ) != fOldHealth ) { + fHealthAlpha = 1.0; + } + + if ( fHealthAlpha >= HUD_ALPHA ) { + fHealthAlpha -= frametime * 0.5; + } else { + fHealthAlpha = HUD_ALPHA; + } // Health vector vHealthPos = [ 16, vVideoResolution_y - 42 ]; - drawsubpic( vHealthPos, '24 24 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 2, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); - HUD_DrawNums( getstatf( STAT_HEALTH ), vHealthPos + '72 0', 1, VGUI_WINDOW_FGCOLOR ); + drawsubpic( vHealthPos, '24 24 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 2, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, HUD_ALPHA, DRAWFLAG_ADDITIVE ); + HUD_DrawNums( getstatf( STAT_HEALTH ), vHealthPos + '72 0', HUD_ALPHA, VGUI_WINDOW_FGCOLOR ); + fOldHealth = getstatf( STAT_HEALTH ); } /* @@ -107,11 +121,22 @@ HUD_DrawArmor Draw the current amount of Kevlar ================= */ +float fOldArmor; +float fArmorAlpha; void HUD_DrawArmor( void ) { - + if ( getstatf( STAT_ARMOR ) != fOldArmor ) { + fArmorAlpha = 1.0; + } + + if ( fArmorAlpha >= HUD_ALPHA ) { + fArmorAlpha -= frametime * 0.5; + } else { + fArmorAlpha = HUD_ALPHA; + } vector vArmorPos = [ 112, vVideoResolution_y - 42 ]; - drawsubpic( vArmorPos, '24 24 0', HUD_NUMFILE_LAYER, [ 0, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); - HUD_DrawNums( getstatf( STAT_ARMOR ), vArmorPos + '72 0', 1, VGUI_WINDOW_FGCOLOR); + drawsubpic( vArmorPos, '24 24 0', HUD_NUMFILE_LAYER, [ 0, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, fArmorAlpha, DRAWFLAG_ADDITIVE ); + HUD_DrawNums( getstatf( STAT_ARMOR ), vArmorPos + '72 0', fArmorAlpha, VGUI_WINDOW_FGCOLOR); + fOldArmor = getstatf( STAT_ARMOR ); } /* @@ -157,6 +182,8 @@ HUD_DrawTimer Draws the roundtime at the bottom of the screen (always visible) ================= */ +int iOldUnits; +float fTimerAlpha; void HUD_DrawTimer( void ) { int iMinutes, iSeconds, iTens, iUnits; vector vTimePos = [ ( vVideoResolution_x / 2 ) - 60, vVideoResolution_y - 42 ]; @@ -199,10 +226,20 @@ void HUD_DrawTimer( void ) { drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], '1 0 0', fAlpha, DRAWFLAG_ADDITIVE ); drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, 1 - fAlpha, DRAWFLAG_ADDITIVE ); } else { - HUD_DrawNumber( iMinutes, vTimePos + '48 0 0', 1, VGUI_WINDOW_FGCOLOR ); - HUD_DrawNumber( iTens, vTimePos + '70 0 0', 1, VGUI_WINDOW_FGCOLOR ); - HUD_DrawNumber( iUnits, vTimePos + '94 0 0', 1, VGUI_WINDOW_FGCOLOR ); - drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + if ( iUnits != iOldUnits ) { + fTimerAlpha = 1.0; + } + + if ( fTimerAlpha >= HUD_ALPHA ) { + fTimerAlpha -= frametime * 0.5; + } else { + fTimerAlpha = HUD_ALPHA; + } + HUD_DrawNumber( iMinutes, vTimePos + '48 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNumber( iTens, vTimePos + '70 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNumber( iUnits, vTimePos + '94 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); + drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, fTimerAlpha, DRAWFLAG_ADDITIVE ); + iOldUnits = iUnits; } } @@ -233,15 +270,15 @@ void HUD_DrawMoney( void ) { if ( fMoneyAlphaEffect > 0 ) { fMoneyAlphaEffect -= frametime * 0.5; drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], vMoneyColorEffect, fMoneyAlphaEffect, DRAWFLAG_ADDITIVE ); - drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, 1 - fMoneyAlphaEffect, DRAWFLAG_ADDITIVE ); + drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, HUD_ALPHA - ( fMoneyAlphaEffect * 0.5 ), DRAWFLAG_ADDITIVE ); vMoneyPos_x += ( 24 * 5 ); HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos, fMoneyAlphaEffect, vMoneyColorEffect ); - HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos, 1 - fMoneyAlphaEffect, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos, HUD_ALPHA - ( fMoneyAlphaEffect * 0.5 ), VGUI_WINDOW_FGCOLOR ); } else { - drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, HUD_ALPHA, DRAWFLAG_ADDITIVE ); vMoneyPos_x += ( 24 * 5 ); - HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos, 1, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos, HUD_ALPHA, VGUI_WINDOW_FGCOLOR ); } fOldMoneyValue = getstatf( STAT_MONEY ); @@ -254,18 +291,32 @@ HUD_DrawAmmo Draws the current clip, the amount of ammo for the caliber and a matching caliber icon ================= */ +float fOldClip, fOldCal; +float fAmmoAlpha; void HUD_DrawAmmo( void ) { if ( getstatf( STAT_ACTIVEWEAPON ) == WEAPON_KNIFE || getstatf( STAT_ACTIVEWEAPON ) == WEAPON_C4BOMB ) { return; } + if ( getstatf( STAT_CURRENT_CLIP ) != fOldClip || getstatf( STAT_CURRENT_CALIBER ) != fOldCal ) { + fAmmoAlpha = 1.0; + } + + if ( fAmmoAlpha >= HUD_ALPHA ) { + fAmmoAlpha -= frametime * 0.5; + } else { + fAmmoAlpha = HUD_ALPHA; + } + vector vAmmoClipPos = [ vVideoResolution_x - 136, vVideoResolution_y - 42 ]; - HUD_DrawNums( getstatf( STAT_CURRENT_CLIP ), vAmmoClipPos, 1, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNums( getstatf( STAT_CURRENT_CLIP ), vAmmoClipPos, fAmmoAlpha, VGUI_WINDOW_FGCOLOR ); vector vAmmoCalPos = [ vVideoResolution_x - 64, vVideoResolution_y - 42 ]; - HUD_DrawNums( getstatf( STAT_CURRENT_CALIBER ), vAmmoCalPos, 1, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNums( getstatf( STAT_CURRENT_CALIBER ), vAmmoCalPos, fAmmoAlpha, VGUI_WINDOW_FGCOLOR ); // Caliber icon - drawsubpic( vVideoResolution - '42 42 0', '24 24 0', HUD_NUMFILE_LAYER, vHUDCalPos[ wptTable[ getstatf( STAT_ACTIVEWEAPON ) ].iCaliber ], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + drawsubpic( vVideoResolution - '42 42 0', '24 24 0', HUD_NUMFILE_LAYER, vHUDCalPos[ wptTable[ getstatf( STAT_ACTIVEWEAPON ) ].iCaliber ], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, fAmmoAlpha, DRAWFLAG_ADDITIVE ); + fOldClip = getstatf( STAT_CURRENT_CLIP ); + fOldCal = getstatf( STAT_CURRENT_CALIBER ); } /* diff --git a/Source/Client/VGUIScoreboard.c b/Source/Client/VGUIScoreboard.c index be3eb3b8..f692a011 100644 --- a/Source/Client/VGUIScoreboard.c +++ b/Source/Client/VGUIScoreboard.c @@ -49,15 +49,17 @@ vector VGUI_Scores_DrawTeam( vector vPos, float fTeam ) { for ( int i = -1; i > -32; i-- ) { if ( stof( getplayerkeyvalue( i, "*team" ) ) == fTeam ) { if ( getplayerkeyvalue( i, "name" ) ) { + vColor = HUD_GetChatColor( fTeam ); if ( getplayerkeyvalue( i, "name" ) == getplayerkeyvalue( player_localnum, "name" ) ) { - vColor = HUD_GetChatColor( fTeam ); drawfill( vNewPos + '19 -2', '493 14', vColor, VGUI_WINDOW_BGALPHA, DRAWFLAG_ADDITIVE ); vColor = '1 1 1'; } if ( getplayerkeyvalue( i, "*dead" ) == "1" ) { drawstring( vNewPos + '38 0', sprintf( "%s [DEAD]", getplayerkeyvalue( i, "name" ) ), '8 8 0', vColor, 1, 0 ); + } else if ( getplayerkeyvalue( i, "*dead" ) == "2" ) { + drawstring( vNewPos + '38 0', sprintf( "%s [VIP]", getplayerkeyvalue( i, "name" ) ), '8 8 0', vColor, 1, 0 ); } else { drawstring( vNewPos + '38 0', getplayerkeyvalue( i, "name" ), '8 8 0', vColor, 1, 0 ); } @@ -65,7 +67,7 @@ vector VGUI_Scores_DrawTeam( vector vPos, float fTeam ) { // Spectators don't have stats worth caring about if ( fTeam != TEAM_SPECTATOR ) { - VGUI_Scores_AlignedText( vNewPos + '320 0', getplayerkeyvalue( i, "*score" ), '8 8 0', vColor ); + VGUI_Scores_AlignedText( vNewPos + '320 0', getplayerkeyvalue( i, INFOKEY_P_FRAGS ), '8 8 0', vColor ); VGUI_Scores_AlignedText( vNewPos + '384 0', getplayerkeyvalue( i, "*deaths" ), '8 8 0', vColor ); } VGUI_Scores_AlignedText( vNewPos + '456 0', getplayerkeyvalue( i, INFOKEY_P_PING ), '8 8 0', vColor ); diff --git a/Source/Globals.h b/Source/Globals.h index 0741d45a..94a8a2cc 100644 --- a/Source/Globals.h +++ b/Source/Globals.h @@ -43,6 +43,11 @@ enum { STAT_WON_CT }; +enum { + ENT_AMBIENTSOUND = 1, + ENT_SPRITE +}; + enum { GAME_INACTIVE, GAME_COMMENCING, diff --git a/Source/Server/AmbientSound.c b/Source/Server/AmbientSound.c index 8db8483f..a14e0d78 100644 --- a/Source/Server/AmbientSound.c +++ b/Source/Server/AmbientSound.c @@ -41,9 +41,10 @@ Not Toggled (32) - Older FGDs show this as Not Looped. Note that actual looping depends purely on cue points defined in the .wav file (see notes). */ #ifdef SSQC +.float pitch; void ambient_generic( void ) { static float ambient_generic_send( entity ePEnt, float fChanged ) { - WriteByte( MSG_ENTITY, 1 ); // Identifier + WriteByte( MSG_ENTITY, ENT_AMBIENTSOUND ); // Identifier WriteCoord( MSG_ENTITY, self.origin_x ); WriteCoord( MSG_ENTITY, self.origin_y ); WriteCoord( MSG_ENTITY, self.origin_z ); @@ -53,7 +54,7 @@ void ambient_generic( void ) { return TRUE; } static void ambient_generic_use( void ) { - sound( self, CHAN_VOICE, self.message, self.health, self.style ); + sound( self, CHAN_VOICE, self.message, self.health, self.style, self.pitch ); } static void ambient_generic_useloop( void ) { if ( self.state == TRUE ) { diff --git a/Source/Server/Damage.c b/Source/Server/Damage.c index 01db46d0..83eee6ce 100644 --- a/Source/Server/Damage.c +++ b/Source/Server/Damage.c @@ -35,18 +35,28 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos eTarget.health = eTarget.health - iDamage; // TODO: Body part multipliers + // Special monetary punishment for hostage murderers + if ( eTarget.classname == "hostage_entity" ) { + if ( eTarget.health > 0 ) { + Money_AddMoney( eAttacker, -150 ); // Pain + } else { + Money_AddMoney( eAttacker, -1500 ); // Death + } + } + + // Don't be like Q1 and make everything bleed. if ( eTarget.iBleeds == TRUE ) { makevectors( eAttacker.angles ); pointparticles( EFFECT_BLOOD, vHitPos, v_forward * -1, 1 ); } + // Target is dead and a client.... if ( eTarget.health <= 0 ) { - if ( eTarget.flags & FL_CLIENT && eAttacker.flags & FL_CLIENT ) { + if ( ( eTarget.flags & FL_CLIENT ) && ( eAttacker.flags & FL_CLIENT ) ) { Damage_CastOrbituary( eAttacker, eTarget, eAttacker.weapon, FALSE ); - eAttacker.fKills++; + eAttacker.frags++; eTarget.fDeaths++; - forceinfokey( eAttacker, "*score", ftos( eAttacker.fKills ) ); forceinfokey( eTarget, "*deaths", ftos( eTarget.fDeaths ) ); Money_AddMoney( eAttacker, 300 ); diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index 0390831e..5cd77573 100644 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -42,7 +42,7 @@ float EFFECT_BLOOD; .int iCrouching; .int iCrouchAttempt; .int iHasBomb; -.float fKills, fDeaths; +.float fDeaths; // Match specific fields int iWon_T; diff --git a/Source/Server/EntHostage.c b/Source/Server/EntHostage.c index 227a6594..ae6ccc61 100644 --- a/Source/Server/EntHostage.c +++ b/Source/Server/EntHostage.c @@ -38,18 +38,18 @@ entity hostage_waypoint( void ) { // Called whenver a hostage is shot void hostage_pain( void ) { - self.frame = 13 - ceil( random() * 5); + self.frame = 13 - floor( random( 1, 6 ) ); } // hosdown.wav void hostage_die( void ) { Radio_BroadcastMessage( RADIO_HOSDOWN ); - self.frame = 30 + ceil( random() * 5); + self.frame = 30 + floor( random( 1, 6 ) ); self.solid = SOLID_NOT; self.takedamage = DAMAGE_NO; if ( other.eTargetPoint != other.eUser ) { - remove( other.eTargetPoint ); + remove( other.eTargetPoint ); } } @@ -57,10 +57,10 @@ void hostage_die( void ) { void hostage_use( void ) { if ( eActivator.team == TEAM_CT ) { if ( ( self.eUser == world ) ) { - + // Only give cash to the CT for using it for the first time if ( self.iHasBeenUsed == FALSE ) { Money_AddMoney( eActivator, 150 ); - sound( self, CHAN_VOICE, sprintf( "hostage/hos%d.wav", ceil( random() * 5 ) ), 1.0, ATTN_IDLE ); + sound( self, CHAN_VOICE, sprintf( "hostage/hos%d.wav", random( 1, 6 ) ), 1.0, ATTN_IDLE ); self.iHasBeenUsed = TRUE; } diff --git a/Source/Server/EnvObjects.c b/Source/Server/EnvObjects.c index d7ba4829..8a57a425 100644 --- a/Source/Server/EnvObjects.c +++ b/Source/Server/EnvObjects.c @@ -42,12 +42,50 @@ void cycler_sprite( void ) { Entities_RenderSetup(); Entities_InitRespawnable( cycler_sprite_respawn ); + self.vUse = cycler_sprite_respawn; } void env_glow( void ) { cycler_sprite(); } +/* +================= +env_sprite + +This entity lets you display and cycle through the animation of a sprite. + +Attributes: +Name (targetname) - Property used to identify entities. +Pitch Yaw Roll (angles) - Sets the pitch (up / down), yaw (left / right) and roll (bank) respectively. The compass in WorldCraft / Hammer corresponds to Yaw. The settings are not always (or not all) used. +Sprite (model) - A sprite must be specified here (sprites/spritename.spr). +Frames per second (framerate) - Framerate the sprite will run at if animated. +================= +*/ +.float framerate; +void env_sprite( void ) { + static float env_sprite_send( entity ePEnt, float fChanged ) { + WriteByte( MSG_ENTITY, ENT_SPRITE ); // Identifier + WriteCoord( MSG_ENTITY, self.origin_x ); + WriteCoord( MSG_ENTITY, self.origin_y ); + WriteCoord( MSG_ENTITY, self.origin_z ); + WriteFloat( MSG_ENTITY, self.modelindex ); + WriteFloat( MSG_ENTITY, self.framerate ); + WriteFloat( MSG_ENTITY, self.scale ); + WriteFloat( MSG_ENTITY, self.alpha ); + WriteFloat( MSG_ENTITY, self.effects ); + return TRUE; + } + static void env_sprite_use( void ) { + } + + precache_model( self.model ); + setorigin( self, self.origin ); + Entities_RenderSetup(); + self.SendEntity = env_sprite_send; + self.vUse = env_sprite_use; +} + /* ================= env_render diff --git a/Source/Server/Footsteps.c b/Source/Server/Footsteps.c index 8dc678ac..e1d979df 100644 --- a/Source/Server/Footsteps.c +++ b/Source/Server/Footsteps.c @@ -44,7 +44,7 @@ void Footsteps_Update( void ) { dDelay = clamp( 0.1, 1 / ( fForce / 90 ), 1 ); traceline( self.origin + self.view_ofs, self.origin + '0 0 -48', FALSE, self ); - sound( self, CHAN_BODY, sprintf( "player/pl_step%d.wav", ceil( random() * 4) ), 0.5, ATTN_IDLE ); + sound( self, CHAN_BODY, sprintf( "player/pl_step%d.wav", random( 1, 5 ) ), 0.5, ATTN_IDLE ); self.fSteptime = time + dDelay; } diff --git a/Source/Server/FuncBreakable.c b/Source/Server/FuncBreakable.c index 870e43c4..9c0a53b8 100644 --- a/Source/Server/FuncBreakable.c +++ b/Source/Server/FuncBreakable.c @@ -68,7 +68,7 @@ void func_breakable_pain( void ) { } if ( iTypeCount >= 1 ) { - sound( self, CHAN_VOICE, sprintf( "%s%d.wav", sTypeSample, ceil( random() * iTypeCount ) ), 1.0, ATTN_NORM ); + sound( self, CHAN_VOICE, sprintf( "%s%d.wav", sTypeSample, random( 1, (float)iTypeCount + 1 ) ), 1.0, ATTN_NORM ); } } @@ -108,7 +108,7 @@ void func_breakable_die( void ) { } if ( iTypeCount >= 1 ) { - sound( self, CHAN_VOICE, sprintf( "%s%d.wav", sTypeSample, ceil( random() * iTypeCount ) ), 1.0, ATTN_NORM ); + sound( self, CHAN_VOICE, sprintf( "%s%d.wav", sTypeSample, random( 1, (float)iTypeCount + 1 ) ), 1.0, ATTN_NORM ); } Effect_BreakModel( self.absmin, self.absmax, self.velocity, self.material ); diff --git a/Source/Server/FuncButton.c b/Source/Server/FuncButton.c index 28a6a74e..30f2cfeb 100644 --- a/Source/Server/FuncButton.c +++ b/Source/Server/FuncButton.c @@ -195,6 +195,11 @@ FuncButton_Trigger ==================== */ void FuncButton_Trigger( void ) { + if ( self.fAttackFinished > self.ltime ) { + return; + } + self.fAttackFinished = self.ltime + self.wait; + if ( ( self.state == STATE_UP ) || ( self.state == STATE_RAISED ) ){ FuncButton_MoveBack(); return; diff --git a/Source/Server/FuncDoor.c b/Source/Server/FuncDoor.c index f599c79a..f8ac39d7 100644 --- a/Source/Server/FuncDoor.c +++ b/Source/Server/FuncDoor.c @@ -175,6 +175,11 @@ FuncDoor_Trigger ==================== */ void FuncDoor_Trigger( void ) { + if ( self.fAttackFinished > self.ltime ) { + return; + } + self.fAttackFinished = self.ltime + self.wait; + // Only trigger stuff when we are done moving if ( ( self.state == STATE_RAISED ) || ( self.state == STATE_LOWERED ) ) { if ( self.delay > 0 ) { diff --git a/Source/Server/FuncVIPSafetyZone.c b/Source/Server/FuncVIPSafetyZone.c index cdaf1c2a..3bd598c8 100644 --- a/Source/Server/FuncVIPSafetyZone.c +++ b/Source/Server/FuncVIPSafetyZone.c @@ -29,10 +29,13 @@ void func_vip_safetyzone_touch( void ) { entity eOld = self; self = other; - self.team = TEAM_CT; + Spawn_MakeSpectator(); self.classname = "player"; - + self.team = TEAM_CT; + forceinfokey( self, "*dead", "0" ); + iAlivePlayers_CT--; + self = eOld; } } diff --git a/Source/Server/Rules.c b/Source/Server/Rules.c index 04063c92..1d509f97 100644 --- a/Source/Server/Rules.c +++ b/Source/Server/Rules.c @@ -64,14 +64,11 @@ float Rules_BuyingPossible( void ) { // Loop through all players and respawn them void Rules_Restart( void ) { - iHostagesRescued = 0; - entity eFind = findchain( classname, "player" ); entity eOld = self; - while ( eFind ) { - + for ( entity eFind = world; eFind = find( eFind, classname, "player" ); ) { self = eFind; if ( self.health > 0 ) { @@ -81,69 +78,51 @@ void Rules_Restart( void ) { } Money_GiveTeamReward(); - - eFind = eFind.chain; } - self = eOld; - // Select a random Terrorist for the bomb thing if ( iBombZones > 0 ) { - int iRandomT = ceil( random() * iAlivePlayers_T ); + int iRandomT = floor( random( 1, (float)iAlivePlayers_T + 1 ) ); int iPickT = 0; - eFind = findchain( classname, "player" ); - while ( eFind ) { - - if ( eFind.classname == "player" && eFind.team == TEAM_T ) { + for ( entity eFind = world; eFind = find( eFind, classname, "player" ); ) { + if ( eFind.team == TEAM_T ) { iPickT++; if ( iPickT == iRandomT ) { - eOld = self; self = eFind; Weapon_AddItem( WEAPON_C4BOMB ); - self = eOld; } } - - eFind = eFind.chain; } } // If there is a VIP, select a random CT to be it if ( iVIPZones > 0 ) { - int iRandomCT = ceil( random() * iAlivePlayers_CT ); + int iRandomCT = floor( random( 1, (float)iAlivePlayers_CT + 1 ) ); int iPickCT = 0; - eFind = findchain( classname, "player" ); - while ( eFind ) { - - if ( eFind.classname == "player" && eFind.team == TEAM_CT ) { + for ( entity eFind = world; eFind = find( eFind, classname, "player" ); ) { + if ( eFind.team == TEAM_CT ) { iPickCT++; - if ( iPickCT == iRandomCT ) { - eOld = self; self = eFind; self.team = TEAM_VIP; Spawn_RespawnClient( self.team ); - self = eOld; + forceinfokey( self, "*dead", "2" ); } } - - eFind = eFind.chain; } + } // Respawn all the entities - eFind = findchainfloat( fRespawns , TRUE ); - eOld = self; - while ( eFind ) { - + + for ( entity eFind = world; eFind = findfloat( eFind, fRespawns, TRUE ); ) { self = eFind; Entities_Respawn(); - - eFind = eFind.chain; } + self = eOld; Timer_Begin( cvar( "mp_freezetime" ), GAME_FREEZE ); diff --git a/Source/Server/Spawn.c b/Source/Server/Spawn.c index 87b3cbfe..a7d9c09e 100644 --- a/Source/Server/Spawn.c +++ b/Source/Server/Spawn.c @@ -211,9 +211,8 @@ void CSEv_GamePlayerSpawn_f( float fChar ) { } - self.fKills = 0; + self.frags = 0; self.fDeaths = 0; - forceinfokey( self, "*score", "0" ); forceinfokey( self, "*deaths", "0" ); } diff --git a/Source/Server/Timer.c b/Source/Server/Timer.c index 92e47934..6b717727 100644 --- a/Source/Server/Timer.c +++ b/Source/Server/Timer.c @@ -59,7 +59,7 @@ void Timer_Update( void ) { } else { Timer_Begin( cvar( "mp_roundtime" ) * 60, GAME_ACTIVE ); // Unfreeze - float fRand = ceil( random() * 3 ); + float fRand = floor( random( 1, 4 ) ); if ( fRand == 1 ) { Radio_BroadcastMessage( RADIO_MOVEOUT ); } else if ( fRand == 2 ) { diff --git a/Source/Server/TraceAttack.c b/Source/Server/TraceAttack.c index 879246c1..628e0b09 100644 --- a/Source/Server/TraceAttack.c +++ b/Source/Server/TraceAttack.c @@ -33,7 +33,7 @@ void TraceAttack_FireBullets( int iShots ) { if ( trace_ent.takedamage == DAMAGE_YES ) { Damage_Apply( trace_ent, self, wptTable[ self.weapon ].iDamage, trace_endpos ); } else { - pointparticles( EFFECT_GUNSHOT, trace_endpos, '0 0 0', 1 ); + pointparticles( EFFECT_GUNSHOT, trace_endpos, trace_plane_normal, 1 ); } } iShots--; diff --git a/Source/Shared/Effects.c b/Source/Shared/Effects.c index 645d0701..dcd34799 100644 --- a/Source/Shared/Effects.c +++ b/Source/Shared/Effects.c @@ -18,6 +18,33 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifdef CSQC +.float framerate; +.float maxframe; +void Effect_AnimatedSprite( vector vPos, float fIndex, float fFPS, float fScale, float fAlpha, float fEffects ) { + + static void Effect_AnimatedSprite_Animate( void ) { + if( self.frame >= self.maxframe ) { + self.frame = 0; + } else { + self.frame += 1; + } + + self.nextthink = time + ( 1 / self.framerate ); + } + self.modelindex = fIndex; + setorigin( self, vPos ); + self.scale = fScale; + self.alpha = fAlpha; + self.effects = fEffects; + self.framerate = fFPS; + self.think = Effect_AnimatedSprite_Animate; + self.drawmask = MASK_ENGINE; + self.nextthink = time + ( 1 / self.framerate ); + //self.maxframe = modelframecount( self.modelindex ); +} +#endif + void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle ) { #ifdef SSQC WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET ); @@ -31,11 +58,12 @@ void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle ) WriteByte( MSG_MULTICAST, fStyle ); msg_entity = self; - multicast( '0 0 0', MULTICAST_PVS ); + multicast( '0 0 0', MULTICAST_ALL ); #else static void Effect_BreakModel_Remove( void ) { remove( self ) ; } - float fCount = 20; // TODO: Generate gibcount based around size. + float fCount = 20; // TODO: Generate gibcount based around size + float fModelCount; vector vPos; string sModel = ""; @@ -43,30 +71,37 @@ void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle ) case MATERIAL_GLASS: case MATERIAL_GLASS_UNBREAKABLE: sModel = "models/glassgibs.mdl"; + fModelCount = 8; break; case MATERIAL_WOOD: sModel = "models/woodgibs.mdl"; + fModelCount = 3; break; case MATERIAL_METAL: sModel = "models/metalplategibs.mdl"; + fModelCount = 13; break; case MATERIAL_FLESH: sModel = "models/fleshgibs.mdl"; - break; - case MATERIAL_CINDER: - sModel = "models/cindergibs.mdl"; + fModelCount = 4; break; case MATERIAL_TILE: sModel = "models/ceilinggibs.mdl"; + fModelCount = 4; break; case MATERIAL_COMPUTER: sModel = "models/computergibs.mdl"; + fModelCount = 15; break; case MATERIAL_ROCK: sModel = "models/rockgibs.mdl"; + fModelCount = 3; break; default: + case MATERIAL_CINDER: sModel = "models/cindergibs.mdl"; + fModelCount = 9; + break; } while ( fCount > 0 ) { @@ -77,7 +112,8 @@ void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle ) vPos_z = vMins_z + ( random() * ( vMaxs_z - vMins_z ) ); setorigin( eGib, vPos ); - setmodel( eGib, sModel ); // Placeholder + setmodel( eGib, sModel ); + setcustomskin( eGib, "", sprintf( "geomset 0 %f\n", random( 1, fModelCount + 1 ) ) ); eGib.movetype = MOVETYPE_BOUNCE; eGib.solid = SOLID_NOT; diff --git a/Source/Shared/WeaponAK47.c b/Source/Shared/WeaponAK47.c index c229eeae..9a5ce1a8 100644 --- a/Source/Shared/WeaponAK47.c +++ b/Source/Shared/WeaponAK47.c @@ -72,7 +72,7 @@ void WeaponAK47_PrimaryFire( void ) { } } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_AK47_SHOOT1 ); } else if ( iRand == 2 ) { diff --git a/Source/Shared/WeaponAUG.c b/Source/Shared/WeaponAUG.c index 34932cc7..64cf1d1b 100644 --- a/Source/Shared/WeaponAUG.c +++ b/Source/Shared/WeaponAUG.c @@ -68,7 +68,7 @@ void WeaponAUG_PrimaryFire( void ) { sound( self, CHAN_WEAPON, "weapons/aug-1.wav", 1, ATTN_NORM ); } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_AUG_SHOOT1 ); } else if ( iRand == 2 ) { diff --git a/Source/Shared/WeaponAWP.c b/Source/Shared/WeaponAWP.c index 0fb1452e..7ff77f56 100644 --- a/Source/Shared/WeaponAWP.c +++ b/Source/Shared/WeaponAWP.c @@ -69,7 +69,7 @@ void WeaponAWP_PrimaryFire( void ) { sound( self, CHAN_WEAPON, "weapons/awp1.wav", 1, ATTN_NORM ); } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_AWP_SHOOT1 ); } else if ( iRand == 2 ) { diff --git a/Source/Shared/WeaponC4Bomb.c b/Source/Shared/WeaponC4Bomb.c index f2f894e8..35b60a57 100644 --- a/Source/Shared/WeaponC4Bomb.c +++ b/Source/Shared/WeaponC4Bomb.c @@ -92,6 +92,7 @@ void WeaponC4BOMB_Drop( vector vBombPos ) { Radio_BroadcastMessage( RADIO_BOMBPL ); iBombPlanted = TRUE; + self.iSlotGrenade = self.iSlotGrenade - WEAPON_C4BOMB; Weapon_SwitchBest(); } #endif diff --git a/Source/Shared/WeaponElites.c b/Source/Shared/WeaponElites.c index b5768996..00611bf6 100644 --- a/Source/Shared/WeaponElites.c +++ b/Source/Shared/WeaponElites.c @@ -85,7 +85,7 @@ void WeaponELITES_PrimaryFire( void ) { sound( self, CHAN_WEAPON, "weapons/elite_fire.wav", 1, ATTN_NORM ); } #else - int iRand = ceil( random() * 5 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iWeaponMode_ELITES == 0 ) { if ( getstatf( STAT_CURRENT_CLIP ) == 1 ) { View_PlayAnimation( ANIM_ELITES_SHOOT_LEFTLAST ); diff --git a/Source/Shared/WeaponKnife.c b/Source/Shared/WeaponKnife.c index 226c089c..623ad493 100644 --- a/Source/Shared/WeaponKnife.c +++ b/Source/Shared/WeaponKnife.c @@ -56,6 +56,8 @@ enum { void WeaponKNIFE_Draw( void ) { #ifdef SSQC Client_SendEvent( self, EV_WEAPON_DRAW ); + self.iCurrentClip = 0; + self.iCurrentCaliber = 0; #else View_PlayAnimation( ANIM_KNIFE_DRAW ); #endif diff --git a/Source/Shared/WeaponM4A1.c b/Source/Shared/WeaponM4A1.c index 28121f8b..e922d1b5 100644 --- a/Source/Shared/WeaponM4A1.c +++ b/Source/Shared/WeaponM4A1.c @@ -94,7 +94,7 @@ void WeaponM4A1_PrimaryFire( void ) { } } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { if ( iWeaponMode_M4A1 == TRUE ) { diff --git a/Source/Shared/WeaponMP5.c b/Source/Shared/WeaponMP5.c index 358b1357..d22fd57c 100644 --- a/Source/Shared/WeaponMP5.c +++ b/Source/Shared/WeaponMP5.c @@ -72,7 +72,7 @@ void WeaponMP5_PrimaryFire( void ) { } } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_MP5_SHOOT1 ); } else if ( iRand == 2 ) { diff --git a/Source/Shared/WeaponMac10.c b/Source/Shared/WeaponMac10.c index 3c7a1a09..301afdd1 100644 --- a/Source/Shared/WeaponMac10.c +++ b/Source/Shared/WeaponMac10.c @@ -67,7 +67,7 @@ void WeaponMAC10_PrimaryFire( void ) { sound( self, CHAN_WEAPON, "weapons/mac10-1.wav", 1, ATTN_NORM ); } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_MAC10_SHOOT1 ); diff --git a/Source/Shared/WeaponP228.c b/Source/Shared/WeaponP228.c index 004eadb2..c93bde91 100644 --- a/Source/Shared/WeaponP228.c +++ b/Source/Shared/WeaponP228.c @@ -74,7 +74,7 @@ void WeaponP228_PrimaryFire( void ) { View_PlayAnimation( ANIM_P228_SHOOT_EMPTY ); } else { - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_P228_SHOOT1 ); diff --git a/Source/Shared/WeaponP90.c b/Source/Shared/WeaponP90.c index 33f1f675..f8d5165f 100644 --- a/Source/Shared/WeaponP90.c +++ b/Source/Shared/WeaponP90.c @@ -68,7 +68,7 @@ void WeaponP90_PrimaryFire( void ) { sound( self, CHAN_WEAPON, "weapons/p90-1.wav", 1, ATTN_NORM ); } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_P90_SHOOT1 ); diff --git a/Source/Shared/WeaponSG552.c b/Source/Shared/WeaponSG552.c index b05be6ec..ad2269c8 100644 --- a/Source/Shared/WeaponSG552.c +++ b/Source/Shared/WeaponSG552.c @@ -72,7 +72,7 @@ void WeaponSG552_PrimaryFire( void ) { } } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_SG552_SHOOT1 ); } else if ( iRand == 2 ) { diff --git a/Source/Shared/WeaponTMP.c b/Source/Shared/WeaponTMP.c index 5020b08c..c4b64c59 100644 --- a/Source/Shared/WeaponTMP.c +++ b/Source/Shared/WeaponTMP.c @@ -71,7 +71,7 @@ void WeaponTMP_PrimaryFire( void ) { } } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_TMP_SHOOT1 ); } else if ( iRand == 2 ) { diff --git a/Source/Shared/WeaponUMP45.c b/Source/Shared/WeaponUMP45.c index 632d068e..766b73e3 100644 --- a/Source/Shared/WeaponUMP45.c +++ b/Source/Shared/WeaponUMP45.c @@ -68,7 +68,7 @@ void WeaponUMP45_PrimaryFire( void ) { sound( self, CHAN_WEAPON, "weapons/ump45-1.wav", 1, ATTN_NORM ); } #else - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { View_PlayAnimation( ANIM_UMP45_SHOOT1 ); diff --git a/Source/Shared/WeaponUSP45.c b/Source/Shared/WeaponUSP45.c index 0ec0e6e5..acd51435 100644 --- a/Source/Shared/WeaponUSP45.c +++ b/Source/Shared/WeaponUSP45.c @@ -103,7 +103,7 @@ void WeaponUSP45_PrimaryFire( void ) { View_PlayAnimation( ANIM_USP45_SHOOTLAST ); } } else { - int iRand = ceil( random() * 3 ); + int iRand = (int)floor( random( 1, 4 ) ); if ( iRand == 1 ) { if ( iWeaponMode_USP45 == TRUE ) { diff --git a/opencs/csprogs.dat b/opencs/csprogs.dat index a3cdb393..d3c2a849 100644 Binary files a/opencs/csprogs.dat and b/opencs/csprogs.dat differ diff --git a/opencs/particles/default.cfg b/opencs/particles/default.cfg index 471be568..b346effb 100644 --- a/opencs/particles/default.cfg +++ b/opencs/particles/default.cfg @@ -4,7 +4,7 @@ r_part te_gunshot texture ball tcoords 1 65 31 95 256 8 32 scale 1 - count 12 + count 8 scalefactor 1 alpha 0.5 die 0.8 @@ -13,7 +13,7 @@ r_part te_gunshot spawnmode ball spawnorg 1 spawnvel 100 - veladd -100 + veladd 100 friction 0.3 gravity 800 } @@ -32,7 +32,26 @@ r_part +te_gunshot spawnmode ball spawnorg 2 spawnvel 20 - veladd -20 + veladd 20 +} + +r_part +te_gunshot +{ + type ball + texture ball + tcoords 1 65 31 95 256 8 32 + scale 2 + count 18 + scalefactor 1 + alpha 1 + die 0.8 + rgb 25 25 25 + spawnmode ball + spawnorg 1 + spawnvel 100 + veladd 100 + friction 0.3 + gravity 800 } r_part te_blood diff --git a/opencs/progs.dat b/opencs/progs.dat index 02793749..52ea9aaa 100644 Binary files a/opencs/progs.dat and b/opencs/progs.dat differ