diff --git a/Source/Client/Defs.h b/Source/Client/Defs.h
index 7406eb96..4b1f0e5e 100755
--- a/Source/Client/Defs.h
+++ b/Source/Client/Defs.h
@@ -90,6 +90,9 @@ struct
float fVGUI_Display; // The VGUI menu currently being drawn
int iShowScores; // This is seperated from the other VGUI stuff so we can check scores while buying and whatnot
+ // Testing
+ int iOverview;
+
//crosshair
int iOldShotMultiplier;
float fCrosshairDistance;
diff --git a/Source/Client/Draw.c b/Source/Client/Draw.c
index 67c6a84d..d86a3566 100755
--- a/Source/Client/Draw.c
+++ b/Source/Client/Draw.c
@@ -179,59 +179,69 @@ void CSQC_UpdateView( float fWinWidth, float fWinHeight, float fGameFocus ) {
}
}
- addentities( MASK_ENGINE );
- Nightvision_PreDraw();
for ( s = 0; s < numclientseats; s++ ) {
pSeat = &seats[ s ];
setproperty( VF_ACTIVESEAT, (float)s );
-
- if ( autocvar_cl_thirdperson == TRUE && getstatf( STAT_HEALTH ) ) {
- setproperty( VF_VIEWENTITY, (float)0 );
- } else {
- setproperty( VF_VIEWENTITY, (float)player_localentnum );
+
+ if ( pSeat.iOverview == FALSE ) {
+ addentities( MASK_ENGINE );
}
+ Nightvision_PreDraw();
- setproperty( VF_AFOV, cvar( "fov" ) * ( getstatf( STAT_VIEWZOOM ) / 255 ) );
- setsensitivityscaler( ( getstatf( STAT_VIEWZOOM ) / 255 ) );
-
- // When Cameratime is active, draw on the forced coords instead
- if ( pSeat->fCameraTime > time ) {
- setproperty( VF_ORIGIN, pSeat->vCameraPos ) ;
- } else {
- setproperty( VF_ORIGIN, pSeat->vPlayerOrigin + [ 0, 0, getstatf( STAT_VIEWHEIGHT ) ] );
- View_DrawViewModel();
- }
-
- //FIXME: this is awkward. renderscene internally rounds to pixels.
- //on the other hand, drawpic uses linear filtering and multisample and stuff.
- //this means that there can be a pixel or so difference between scene and 2d.
- //as a general rule, you won't notice unless there's some big drawfills.
- switch ( numclientseats ) {
- case 3:
- if (!s)
- {
- case 2:
- vVideoResolution = [ fWinWidth, fWinHeight * 0.5 ];
- vVideoMins = [ 0, ( s & 1 ) * vVideoResolution_y ];
+ if ( pSeat.iOverview == FALSE ) {
+ if ( autocvar_cl_thirdperson == TRUE && getstatf( STAT_HEALTH ) ) {
+ setproperty( VF_VIEWENTITY, (float)0 );
+ } else {
+ setproperty( VF_VIEWENTITY, (float)player_localentnum );
+ }
+
+ setproperty( VF_AFOV, cvar( "fov" ) * ( getstatf( STAT_VIEWZOOM ) / 255 ) );
+ setsensitivityscaler( ( getstatf( STAT_VIEWZOOM ) / 255 ) );
+
+ // When Cameratime is active, draw on the forced coords instead
+ if ( pSeat->fCameraTime > time ) {
+ setproperty( VF_ORIGIN, pSeat->vCameraPos ) ;
+ } else {
+ setproperty( VF_ORIGIN, pSeat->vPlayerOrigin + [ 0, 0, getstatf( STAT_VIEWHEIGHT ) ] );
+ View_DrawViewModel();
+ }
+
+ //FIXME: this is awkward. renderscene internally rounds to pixels.
+ //on the other hand, drawpic uses linear filtering and multisample and stuff.
+ //this means that there can be a pixel or so difference between scene and 2d.
+ //as a general rule, you won't notice unless there's some big drawfills.
+ switch ( numclientseats ) {
+ case 3:
+ if (!s)
+ {
+ case 2:
+ vVideoResolution = [ fWinWidth, fWinHeight * 0.5 ];
+ vVideoMins = [ 0, ( s & 1 ) * vVideoResolution_y ];
+ break;
+ }
+ s++;
+ case 4:
+ vVideoResolution = [ fWinWidth, fWinHeight ] * 0.5;
+ vVideoMins = [ (s&1) * vVideoResolution_x, ( s / 2i ) * vVideoResolution_y ];
+ break;
+ default:
+ vVideoResolution = [ fWinWidth, fWinHeight ];
+ vVideoMins = [ 0, 0 ];
break;
}
- s++;
- case 4:
- vVideoResolution = [ fWinWidth, fWinHeight ] * 0.5;
- vVideoMins = [ (s&1) * vVideoResolution_x, ( s / 2i ) * vVideoResolution_y ];
- break;
- default:
- vVideoResolution = [ fWinWidth, fWinHeight ];
- vVideoMins = [ 0, 0 ];
- break;
+ setproperty( VF_MIN, vVideoMins );
+ setproperty( VF_SIZE, vVideoResolution );
+ setproperty( VF_ANGLES, view_angles + pSeat->vPunchAngle );
+ setproperty( VF_DRAWWORLD, 1 );
+ } else {
+ setproperty( VF_DRAWWORLD, 0 );
+ Overview_Draw();
}
- setproperty( VF_MIN, vVideoMins );
- setproperty( VF_SIZE, vVideoResolution );
- setproperty( VF_ANGLES, view_angles + pSeat->vPunchAngle );
+
renderscene();
-
+
View_DropPunchAngle();
Nightvision_PostDraw();
@@ -257,6 +267,7 @@ void CSQC_UpdateView( float fWinWidth, float fWinHeight, float fGameFocus ) {
}
}
}
+
pSeat = (void*)0x70000000i;
if ( needcursor ) {
diff --git a/Source/Client/Event.c b/Source/Client/Event.c
index 16b10c53..3bb4f265 100755
--- a/Source/Client/Event.c
+++ b/Source/Client/Event.c
@@ -26,6 +26,7 @@ Init all the cmds in one place
=================
*/
void CSQC_ConsoleCommand_Init( void ) {
+ registercommand( "overview_test" );
registercommand( "vox_test" );
registercommand( "+attack2" );
registercommand( "-attack2" );
@@ -119,6 +120,10 @@ float CSQC_ConsoleCommand( string sCMD ) {
tokenize( sCMD );
switch ( argv(0) ) {
+ case "overview_test":
+ pSeat.iOverview = 1 - pSeat.iOverview;
+ return TRUE;
+ break;
case "vox_test":
Sound_PlayVOX( sCMD );
return TRUE;
diff --git a/Source/Client/HUD.c b/Source/Client/HUD.c
index 1c3677ec..afc396a0 100755
--- a/Source/Client/HUD.c
+++ b/Source/Client/HUD.c
@@ -190,22 +190,10 @@ void HUD_DrawTimer( void ) {
int iMinutes, iSeconds, iTens, iUnits;
vector vTimePos = vVideoMins+[ ( vVideoResolution_x / 2 ) - 62, vVideoResolution_y - 42 ];
- if( serverkey( "timelimit" ) ) {
- float fTimeLeft = ( stof( serverkey( "timelimit" ) ) * 60 ) - getstatf( STAT_GAMETIME );
- if ( fTimeLeft < 0 ) {
- iMinutes = iSeconds = iTens = iUnits = 0;
- } else {
- iMinutes = fTimeLeft / 60;
- iSeconds = fTimeLeft - 60 * iMinutes;
- iTens = iSeconds / 10;
- iUnits = iSeconds - 10 * iTens;
- }
- } else {
- iMinutes = getstatf( STAT_GAMETIME ) / 60;
- iSeconds = getstatf( STAT_GAMETIME ) - 60 * iMinutes;
- iTens = iSeconds / 10;
- iUnits = iSeconds - 10 * iTens;
- }
+ iMinutes = getstatf( STAT_GAMETIME ) / 60;
+ iSeconds = getstatf( STAT_GAMETIME ) - 60 * iMinutes;
+ iTens = iSeconds / 10;
+ iUnits = iSeconds - 10 * iTens;
// Flashing red numbers
if ( ( iMinutes == 0 ) && ( iTens <= 1 ) ) {
diff --git a/Source/Client/Init.c b/Source/Client/Init.c
index 6e754659..be8f7708 100755
--- a/Source/Client/Init.c
+++ b/Source/Client/Init.c
@@ -71,6 +71,7 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
precache_sound( "debris/bustceiling.wav" );
precache_pic( "gfx/vgui/icntlk_sv" );
+ precache_pic( sprintf( "overviews/%s.bmp", mapname ) );
for ( int i = 0; i < ( CS_WEAPON_COUNT - 1 ); i++ ) {
precache_model( sViewModels[ i ] );
@@ -93,6 +94,10 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
CSQC_ConsoleCommand_Init();
CSQC_VGUI_Init();
+
+ Overview_Init();
+
+ pSeat.iOverview = FALSE;
}
/*
diff --git a/Source/Client/Nightvision.c b/Source/Client/Nightvision.c
index 8888165a..8d507b07 100755
--- a/Source/Client/Nightvision.c
+++ b/Source/Client/Nightvision.c
@@ -53,7 +53,7 @@ Called before rendering the frame in Draw.c
=================
*/
void Nightvision_PreDraw( void ) {
- if( getplayerkeyvalue( player_localnum, "*spec" ) == "1" ) {
+ if( getplayerkeyvalue( player_localnum, "*spec" ) != "0" ) {
iNightVision = FALSE;
return;
}
diff --git a/Source/Client/Overview.c b/Source/Client/Overview.c
new file mode 100755
index 00000000..27029751
--- /dev/null
+++ b/Source/Client/Overview.c
@@ -0,0 +1,143 @@
+/*
+FreeCS Project
+Copyright (C) 2016, 2017 Marco "eukara" Hladik
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+The overview system was meant to support
+more layers and so on. Never actually used.
+Probably seemed impractical, feel free to make this
+parse layers etc. properly though.
+*/
+
+typedef struct {
+ float fZoom;
+ vector vOrigin;
+ int iRotated;
+ float fHeight;
+ string sImagePath;
+} overview_t;
+
+overview_t ovMap;
+
+/*
+=================
+Overview_Init
+
+Initializes the globals and whatnot
+=================
+*/
+void Overview_Init( void ) {
+ int iImageCount = 0;
+ string sTemp;
+
+ ovMap.fZoom = 1.0f;
+ ovMap.vOrigin = '0 0 0';
+ ovMap.iRotated = FALSE;
+
+ filestream fOverview = fopen( sprintf( "overviews/%s.txt", mapname ), FILE_READ );
+ if ( fOverview != -1 ) {
+ for ( int i = 0;; i++ ) {
+ sTemp = fgets( fOverview );
+ if not ( sTemp ) {
+ break;
+ }
+
+ tokenize( sTemp );
+ if ( strtolower( argv( 0 ) ) == "zoom" ) {
+ ovMap.fZoom = stof( argv( 1 ) );
+ } else if ( strtolower( argv( 0 ) ) == "origin" ) {
+ ovMap.vOrigin = [ stof( argv( 1 ) ), stof( argv( 2 ) ), stof( argv( 3 ) ) ];
+ } else if ( strtolower( argv( 0 ) ) == "rotated" ) {
+ ovMap.iRotated = (int)stof( argv( 1 ) );
+ } else if ( strtolower( argv( 0 ) ) == "height" ) {
+ ovMap.fHeight = stof( argv( 1 ) );
+ }
+ }
+ fclose( fOverview );
+ ovMap.sImagePath = sprintf( "overviews/%s.bmp", mapname );
+ } else {
+ error( sprintf( "[OVERVIEW] Couldn't load overviews/%s.txt", mapname ) );
+ ovMap.sImagePath = __NULL__;
+ }
+}
+
+
+/*
+=================
+Overview_Draw
+
+Draw one of two types of overviews.
+This is for spectators.
+=================
+*/
+void Overview_Draw( void ) {
+ float fCameraHeight;
+ vector vVert1, vVert2, vVert3, vVert4;
+
+ if ( ovMap.sImagePath == __NULL__ ) {
+ return;
+ }
+
+ drawfill( vVideoMins, vVideoResolution, '0 0 0', 1.0f, 0 );
+ if ( ovMap.iRotated == TRUE ) {
+
+ vVert1 = ovMap.vOrigin -( ( 4096/ovMap.fZoom ) * '1 0.75 0' );
+ vVert4 = ovMap.vOrigin + ( 4096/ovMap.fZoom ) * '1 0.75 0';
+
+ vVert2 = [ vVert1_x, vVert4_y ] ;
+ vVert3 = [ vVert4_x, vVert1_y ] ;
+
+ R_BeginPolygon( ovMap.sImagePath );
+ R_PolygonVertex( [ vVert4_x, vVert4_y, ovMap.fHeight ], '1 0', '1 1 1', 1.0f ); // Top Left
+ R_PolygonVertex( [ vVert3_x, vVert3_y, ovMap.fHeight ], '1 1', '1 1 1', 1.0f ); // Top Right
+ R_PolygonVertex( [ vVert2_x, vVert2_y, ovMap.fHeight ], '0 0', '1 1 1', 1.0f ); // Bottom left
+ R_EndPolygon();
+
+ R_BeginPolygon( ovMap.sImagePath );
+ R_PolygonVertex( [ vVert1_x, vVert1_y, ovMap.fHeight ], '0 1', '1 1 1', 1.0f ); // Bottom right
+ R_PolygonVertex( [ vVert2_x, vVert2_y, ovMap.fHeight ], '0 0', '1 1 1', 1.0f ); // Bottom left
+ R_PolygonVertex( [ vVert3_x, vVert3_y, ovMap.fHeight ], '1 1', '1 1 1', 1.0f ); // Top Right
+ R_EndPolygon();
+
+ fCameraHeight = fabs( 4096/ovMap.fZoom );
+ } else {
+
+ vVert1 = ovMap.vOrigin -( ( 4096/ovMap.fZoom ) * '0.75 1 0' );
+ vVert4 = ovMap.vOrigin + ( 4096/ovMap.fZoom ) * '0.75 1 0';
+
+ vVert2 = [ vVert1_x, vVert4_y ] ;
+ vVert3 = [ vVert4_x, vVert1_y ] ;
+ R_BeginPolygon( ovMap.sImagePath );
+ R_PolygonVertex( [ vVert4_x, vVert4_y, ovMap.fHeight ], '0 0', '1 1 1', 1.0f ); // Top Left
+ R_PolygonVertex( [ vVert3_x, vVert3_y, ovMap.fHeight ], '1 0', '1 1 1', 1.0f ); // Top Right
+ R_PolygonVertex( [ vVert2_x, vVert2_y, ovMap.fHeight ], '0 1', '1 1 1', 1.0f ); // Bottom left
+ R_EndPolygon();
+
+ R_BeginPolygon( ovMap.sImagePath );
+ R_PolygonVertex( [ vVert1_x, vVert1_y, ovMap.fHeight ], '1 1', '1 1 1', 1.0f ); // Bottom right
+ R_PolygonVertex( [ vVert2_x, vVert2_y, ovMap.fHeight ], '0 1', '1 1 1', 1.0f ); // Bottom left
+ R_PolygonVertex( [ vVert3_x, vVert3_y, ovMap.fHeight ], '1 0', '1 1 1', 1.0f ); // Top Right
+ R_EndPolygon();
+
+ fCameraHeight = fabs( 4096/ovMap.fZoom );
+ }
+
+ makevectors( view_angles );
+ setproperty( VF_ORIGIN, ovMap.vOrigin + ( v_forward * -fCameraHeight ) ) ;
+}
\ No newline at end of file
diff --git a/Source/Client/VGUISpectator.c b/Source/Client/VGUISpectator.c
index 6581af32..cc9b5803 100755
--- a/Source/Client/VGUISpectator.c
+++ b/Source/Client/VGUISpectator.c
@@ -34,22 +34,11 @@ void VGUI_DrawSpectatorHUD( void ) {
// Draw the timer
int iMinutes, iSeconds, iTens, iUnits;
- if( serverkey( "timelimit" ) ) {
- float fTimeLeft = ( stof( serverkey( "timelimit" ) ) * 60 ) - getstatf( STAT_GAMETIME );
- if ( fTimeLeft < 0 ) {
- iMinutes = iSeconds = iTens = iUnits = 0;
- } else {
- iMinutes = fTimeLeft / 60;
- iSeconds = fTimeLeft - 60 * iMinutes;
- iTens = iSeconds / 10;
- iUnits = iSeconds - 10 * iTens;
- }
- } else {
- iMinutes = getstatf( STAT_GAMETIME ) / 60;
- iSeconds = getstatf( STAT_GAMETIME ) - 60 * iMinutes;
- iTens = iSeconds / 10;
- iUnits = iSeconds - 10 * iTens;
- }
+ iMinutes = getstatf( STAT_GAMETIME ) / 60;
+ iSeconds = getstatf( STAT_GAMETIME ) - 60 * iMinutes;
+ iTens = iSeconds / 10;
+ iUnits = iSeconds - 10 * iTens;
+
drawpic( vVideoMins + [ vVideoResolution_x - 70, 20 ], "gfx/vgui/640_timer", '14 14', '1 1 1', 1 );
VGUI_RightText( vVideoMins + [ vVideoResolution_x - 16, 23 ], sprintf( "%i:%i%i", iMinutes, iTens, iUnits ), '8 8', '0.56 0.56 0.21', FONT_DEFAULT );
diff --git a/Source/Client/progs.src b/Source/Client/progs.src
index 113eca83..8595d4cd 100755
--- a/Source/Client/progs.src
+++ b/Source/Client/progs.src
@@ -44,6 +44,7 @@ Defs.h
../Shared/Equipment.c
../Shared/Animations.c
+Overview.c
Player.c
View.c
VGUIObjects.c
diff --git a/Source/FreeCS-CE.prj b/Source/FreeCS-CE.prj
index 6368a8b8..162415a1 100644
--- a/Source/FreeCS-CE.prj
+++ b/Source/FreeCS-CE.prj
@@ -11,6 +11,7 @@
+
@@ -25,7 +26,7 @@
-
+
@@ -62,7 +63,7 @@
-
+
diff --git a/Source/Menu/MenuMultiplayer.c b/Source/Menu/MenuMultiplayer.c
index 554be45f..6ebcf6c5 100755
--- a/Source/Menu/MenuMultiplayer.c
+++ b/Source/Menu/MenuMultiplayer.c
@@ -25,8 +25,6 @@ float fldPing;
float fldPlayers;
float fldMaxplayers;
float fldMap;
-float fldTimelimit;
-float fldFraglimit;
float fServerClickTime;
/*
@@ -144,8 +142,6 @@ void Menu_Multiplayer( void ) {
fldPlayers = gethostcacheindexforkey("numhumans");
fldMaxplayers = gethostcacheindexforkey("maxplayers");
fldMap = gethostcacheindexforkey("map");
- fldTimelimit = gethostcacheindexforkey("timelimit");
- fldFraglimit = gethostcacheindexforkey("fraglimit");
iServersTotal = gethostcachevalue( SLIST_HOSTCACHEVIEWCOUNT );
diff --git a/Source/Server/Client.c b/Source/Server/Client.c
index 9605f0a7..f32d074f 100755
--- a/Source/Server/Client.c
+++ b/Source/Server/Client.c
@@ -113,9 +113,11 @@ void PutClientInServer( void ) {
// Because we don't want to reset these when we die
Money_AddMoney( self, autocvar_mp_startmoney );
- if ( autocvar_sv_voxannounce == TRUE ) {
- float fTimeLeft = cvar( "mp_timelimit" ) - ( time / 60 );
- Vox_Singlecast( self, sprintf( "%s minutes remaining", Vox_TimeToString( fTimeLeft ) ) );
+ if ( cvar( "mp_timelimit" ) > 0 ) {
+ if ( autocvar_sv_voxannounce == TRUE ) {
+ float fTimeLeft = cvar( "mp_timelimit" ) - ( time / 60 );
+ Vox_Singlecast( self, sprintf( "we have %s minutes remaining", Vox_TimeToString( fTimeLeft ) ) );
+ }
}
self.team = 0;
diff --git a/Source/Server/Damage.c b/Source/Server/Damage.c
index 47f97b72..5f27b2e6 100755
--- a/Source/Server/Damage.c
+++ b/Source/Server/Damage.c
@@ -191,6 +191,51 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos
self = eOld;
}
+/*
+=================
+Damage_CheckAttack
+
+This verifies that the entity is actually able to receive some damage,
+from a plain geographical standpoint
+=================
+*/
+float Damage_CheckAttack( entity eTarget, vector vAttackPos ) {
+ if ( eTarget.movetype == MOVETYPE_PUSH ) {
+ traceline( vAttackPos, 0.5 * ( eTarget.absmin + eTarget.absmax ), TRUE, self );
+
+ if ( trace_fraction == 1 ) {
+ return TRUE;
+ }
+ if ( trace_ent == eTarget ) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ traceline( vAttackPos, eTarget.origin, TRUE, self );
+ if ( trace_fraction == 1 ) {
+ return TRUE;
+ }
+ traceline( vAttackPos, eTarget.origin + '15 15 0', TRUE, self );
+ if ( trace_fraction == 1 ) {
+ return TRUE;
+ }
+ traceline( vAttackPos, eTarget.origin + '-15 -15 0', TRUE, self );
+ if ( trace_fraction == 1 ) {
+ return TRUE;
+ }
+ traceline( vAttackPos, eTarget.origin + '-15 15 0', TRUE, self );
+ if ( trace_fraction == 1 ) {
+ return TRUE;
+ }
+ traceline( vAttackPos, eTarget.origin + '15 -15 0', TRUE, self );
+ if ( trace_fraction == 1 ) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/*
=================
Damage_Radius
@@ -203,13 +248,15 @@ void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadi
while( eDChain ) {
if ( eDChain.takedamage == DAMAGE_YES ) {
- float fDiff = vlen( vOrigin - eDChain.origin );
+ if ( Damage_CheckAttack( eDChain, vOrigin ) ) {
+ float fDiff = vlen( vOrigin - eDChain.origin );
- fDiff = ( fRadius - fDiff ) / fRadius;
- fDamage = fDamage * fDiff;
+ fDiff = ( fRadius - fDiff ) / fRadius;
+ fDamage = fDamage * fDiff;
- if ( fDamage > 0 ) {
- Damage_Apply( eDChain, eAttacker, fDamage, eDChain.origin, FALSE );
+ if ( fDiff > 0 ) {
+ Damage_Apply( eDChain, eAttacker, fDamage, eDChain.origin, TRUE );
+ }
}
}
eDChain = eDChain.chain;
diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h
index b9eb139c..ad24e1a9 100755
--- a/Source/Server/Defs.h
+++ b/Source/Server/Defs.h
@@ -32,7 +32,7 @@ var string autocvar_motdfile = "motd.txt";
var int autocvar_mp_fillweapons = FALSE;
var int autocvar_mp_autoreload = FALSE;
-var int autocvar_sv_voxannounce = TRUE;
+var int autocvar_sv_voxannounce = FALSE;
// Mapcycle features
var string autocvar_mapcyclefile = "mapcycle.txt";
diff --git a/Source/Server/Main.c b/Source/Server/Main.c
index 171233e6..75978098 100755
--- a/Source/Server/Main.c
+++ b/Source/Server/Main.c
@@ -30,13 +30,12 @@ void SV_SendChat( entity eSender, string sMessage, entity eEnt, float fType ) {
WriteByte( MSG_MULTICAST, num_for_edict( eSender ) - 1 );
WriteByte( MSG_MULTICAST, eSender.team );
WriteString( MSG_MULTICAST, sMessage );
- if (eEnt)
- {
+ if (eEnt) {
msg_entity = eEnt;
multicast( '0 0 0', MULTICAST_ONE );
- }
- else
+ } else {
multicast( '0 0 0', MULTICAST_ALL );
+ }
}
/*
@@ -49,6 +48,12 @@ chat messages and handle distribution ourselves.
*/
void SV_ParseClientCommand( string sCommand ) {
tokenize( sCommand );
+
+ if ( argv( 1 ) == "timeleft" ) {
+ float fTimeLeft = cvar( "mp_timelimit" ) - ( time / 60 );
+ Vox_Singlecast( self, sprintf( "we have %s minutes remaining", Vox_TimeToString( fTimeLeft ) ) );
+ return;
+ }
// Players talk to players, spectators to spectators.
if ( self.health ) {
@@ -85,7 +90,6 @@ float ConsoleCmd( string sCommand ) {
tokenize( sCommand );
if ( argv( 0 ) == "vox" ) {
- localcmd( sprintf( "echo [VOX] Sending: %s\n", argv( 1 ) ) );
Vox_Broadcast( argv( 1 ) );
return TRUE;
}
@@ -157,57 +161,70 @@ void worldspawn( void ) {
}
}
fclose( fileMaterial );
+ } else {
+ error( "Failed to load sound/materials.txt!\n" );
}
// The message of the day.
localcmd( sprintf( "echo [MOTD] Loading %s.\n", autocvar_motdfile ) );
filestream fmMOTD = fopen( autocvar_motdfile, FILE_READ );
- for ( int i = 0; i < 25; i++ ) {
- sTemp = fgets( fmMOTD );
- if not ( sTemp ) {
- break;
- }
-
- if ( sTemp == __NULL__ ) {
- localcmd( sprintf( "serverinfo motdline%i /\n", iMOTDLines ) );
- } else {
- localcmd( sprintf( "serverinfo motdline%i %s\n", iMOTDLines, sTemp ) );
+
+ if ( fmMOTD >= 0 ) {
+ for ( int i = 0; i < 25; i++ ) {
+ sTemp = fgets( fmMOTD );
+ if not ( sTemp ) {
+ break;
+ }
+
+ if ( sTemp == __NULL__ ) {
+ localcmd( sprintf( "serverinfo motdline%i /\n", iMOTDLines ) );
+ } else {
+ localcmd( sprintf( "serverinfo motdline%i %s\n", iMOTDLines, sTemp ) );
+ }
+ iMOTDLines++;
}
- iMOTDLines++;
+ localcmd( sprintf( "serverinfo motdlength %i\n", iMOTDLines ) );
+ fclose( fmMOTD );
+ } else {
+ error( "[MOTD] Loading failed.\n" );
}
- localcmd( sprintf( "serverinfo motdlength %i\n", iMOTDLines ) );
- fclose( fmMOTD );
// The mapcycle information.
localcmd( sprintf( "echo [MAPCYCLE] Loading %s.\n", autocvar_mapcyclefile ) );
filestream fmMapcycle = fopen( autocvar_mapcyclefile, FILE_READ );
- for ( int i = 0;; i++ ) {
- sTemp = fgets( fmMapcycle );
- if not ( sTemp ) {
- break;
- }
-
- if ( sTemp != __NULL__ ) {
- iMapCycleCount++;
- }
- }
- fseek( fmMapcycle, 0 );
- localcmd( sprintf( "echo [MAPCYCLE] List has %i maps.\n", iMapCycleCount ) );
- sMapCycle = memalloc( sizeof( string ) * iMapCycleCount );
- for ( int i = 0; i < iMapCycleCount; i++ ) {
- sMapCycle[ i ] = fgets( fmMapcycle );
- }
- fclose( fmMapcycle );
-
- for ( int i = 0; i < iMapCycleCount; i++ ) {
- if ( sMapCycle[ i ] == mapname ) {
- if ( ( i + 1 ) < iMapCycleCount ) {
- localcmd( sprintf( "echo [MAPCYCLE] Next map: %s\n", sMapCycle[ i + 1 ] ) );
- } else {
+ if ( fmMapcycle >= 0 ) {
+ for ( int i = 0;; i++ ) {
+ sTemp = fgets( fmMapcycle );
+ if not ( sTemp ) {
break;
+ }
+
+ if ( sTemp != __NULL__ ) {
+ iMapCycleCount++;
}
}
+
+ fseek( fmMapcycle, 0 );
+ localcmd( sprintf( "echo [MAPCYCLE] List has %i maps.\n", iMapCycleCount ) );
+ sMapCycle = memalloc( sizeof( string ) * iMapCycleCount );
+ for ( int i = 0; i < iMapCycleCount; i++ ) {
+ sMapCycle[ i ] = fgets( fmMapcycle );
+ }
+ fclose( fmMapcycle );
+
+ for ( int i = 0; i < iMapCycleCount; i++ ) {
+ if ( sMapCycle[ i ] == mapname ) {
+ if ( ( i + 1 ) < iMapCycleCount ) {
+ localcmd( sprintf( "echo [MAPCYCLE] Next map: %s\n", sMapCycle[ i + 1 ] ) );
+ } else {
+ break;
+ }
+ }
+ }
+ } else {
+ iMapCycleCount = 0;
+ error( "[MAPCYCLE] Loading failed.\n" );
}
// Let's make our version information clear
diff --git a/Source/Server/Timer.c b/Source/Server/Timer.c
index 82716a65..ee9e8c09 100755
--- a/Source/Server/Timer.c
+++ b/Source/Server/Timer.c
@@ -49,30 +49,31 @@ Called once every frame to check the status of things
void Timer_Update( void ) {
static float fVoxTimer;
- // Not happy with this, but it'll do
- if ( autocvar_sv_voxannounce == TRUE ) {
- if ( fVoxTimer > time ) {
- return;
- }
-
- float fTimeLeft = ( cvar( "mp_timelimit" ) * 60 ) - time;
- for ( int i = 0; i <= 10; i++ ) {
- if ( rint( fTimeLeft ) == ( i * 60 ) ) {
- Vox_Broadcast( sprintf( "%s minutes remaining", Vox_TimeToString( fTimeLeft / 60 ) ) );
- fVoxTimer = time + 10.0f;
+ // This map has been played enough we think
+ if ( cvar( "mp_timelimit" ) > 0 ) {
+ if ( autocvar_sv_voxannounce == TRUE ) {
+ if ( fVoxTimer > time ) {
+ return;
+ }
+
+ float fTimeLeft = ( cvar( "mp_timelimit" ) * 60 ) - time;
+ for ( int i = 0; i <= 10; i++ ) {
+ if ( rint( fTimeLeft ) == ( i * 60 ) ) {
+ Vox_Broadcast( sprintf( "%s minutes remaining", Vox_TimeToString( fTimeLeft / 60 ) ) );
+ fVoxTimer = time + 10.0f;
+ }
}
}
- }
- // This map has been played enough we think
- if ( time >= ( cvar( "mp_timelimit" ) * 60 ) ) {
- for ( int i = 0; i < iMapCycleCount; i++ ) {
- if ( sMapCycle[ i ] == mapname ) {
- if ( ( i + 1 ) < iMapCycleCount ) {
- localcmd( sprintf( "changelevel %s\n", sMapCycle[ i + 1 ] ) );
- return;
- } else {
- localcmd( sprintf( "changelevel %s\n", sMapCycle[ 0 ] ) );
+ if ( time >= ( cvar( "mp_timelimit" ) * 60 ) ) {
+ for ( int i = 0; i < iMapCycleCount; i++ ) {
+ if ( sMapCycle[ i ] == mapname ) {
+ if ( ( i + 1 ) < iMapCycleCount ) {
+ localcmd( sprintf( "changelevel %s\n", sMapCycle[ i + 1 ] ) );
+ return;
+ } else {
+ localcmd( sprintf( "changelevel %s\n", sMapCycle[ 0 ] ) );
+ }
}
}
}
diff --git a/Source/Server/Vox.c b/Source/Server/Vox.c
index 41a56b29..a3416550 100755
--- a/Source/Server/Vox.c
+++ b/Source/Server/Vox.c
@@ -53,6 +53,7 @@ Broadcasts a VOX message to all players
=================
*/
void Vox_Broadcast( string sMessage ) {
+ localcmd( sprintf( "echo [VOX] Broadcast: %s\n", sMessage ) );
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_CHAT_VOX );
WriteString( MSG_MULTICAST, sMessage );
@@ -68,6 +69,7 @@ Broadcasts a VOX message to one player
=================
*/
void Vox_Singlecast( entity eClient, string sMessage ) {
+ localcmd( sprintf( "echo [VOX] Singlecast to %s: %s\n", eClient.netname, sMessage ) );
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_CHAT_VOX );
WriteString( MSG_MULTICAST, sMessage );
diff --git a/Source/Shared/Effects.c b/Source/Shared/Effects.c
index a7e584ce..30106cc9 100755
--- a/Source/Shared/Effects.c
+++ b/Source/Shared/Effects.c
@@ -92,6 +92,11 @@ void Effect_CreateSmoke( vector vPos ) {
multicast( '0 0 0', MULTICAST_ALL );
#else
static void Effect_CreateSmoke_Think( void ) {
+ // HACK: This should only ever happen when rounds restart!
+ // Any way this can go wrong?
+ if ( self.skin < getstatf( STAT_GAMETIME ) ) {
+ remove( self );
+ }
if ( self.frame <= 0 ) {
remove( self );
return;
@@ -100,6 +105,7 @@ void Effect_CreateSmoke( vector vPos ) {
pointparticles( PARTICLE_SMOKEGRENADE, self.origin, '0 0 0', 1 );
self.frame--;
self.nextthink = time + 0.2f;
+ self.skin = getstatf( STAT_GAMETIME );
}
entity eSmoke = spawn();
@@ -107,6 +113,7 @@ void Effect_CreateSmoke( vector vPos ) {
eSmoke.think = Effect_CreateSmoke_Think;
eSmoke.nextthink = time;
eSmoke.frame = 200;
+ eSmoke.skin = getstatf( STAT_GAMETIME );
#endif
}
diff --git a/Source/Shared/WeaponFlashbang.c b/Source/Shared/WeaponFlashbang.c
index 24d681cc..23a4b149 100755
--- a/Source/Shared/WeaponFlashbang.c
+++ b/Source/Shared/WeaponFlashbang.c
@@ -105,7 +105,7 @@ void WeaponFLASHBANG_Throw( void ) {
vNorm = normalize ( self.origin - eFind.origin );
fDot = vNorm * v_forward;
- if ( fDot > 0.3 ) {
+ if ( fDot > 0.5 ) {
Effect_CreateFlash( eFind );
}
}
@@ -135,7 +135,7 @@ void WeaponFLASHBANG_Throw( void ) {
entity eNade = spawn();
setorigin( eNade, ( self.origin + self.view_ofs ) + ( v_forward * 16 ) );
setmodel( eNade, "models/w_flashbang.mdl" );
- setsize( eNade, '-4 -4 -4', '4 4 4' );
+ setsize( eNade, '-1 -1 -1', '1 1 1' );
vector vDir = aim ( self, 100000 );
eNade.classname = "remove_me";
diff --git a/Source/Shared/WeaponGlock18.c b/Source/Shared/WeaponGlock18.c
index 1ca06233..83578dd1 100755
--- a/Source/Shared/WeaponGlock18.c
+++ b/Source/Shared/WeaponGlock18.c
@@ -104,7 +104,6 @@ void WeaponGLOCK18_PrimaryFire( void ) {
self.fAttackFinished = time + 0.5;
sound( self, CHAN_WEAPON, "weapons/glock18-1.wav", 1, ATTN_NORM );
Client_SendEvent( self, EV_WEAPON_PRIMARYATTACK );
- BaseGun_ShotMultiplierHandle( 3 );
}
#else
if ( iWeaponMode_GLOCK18 == FALSE ) {
diff --git a/Source/Shared/WeaponHEGrenade.c b/Source/Shared/WeaponHEGrenade.c
index a60f0600..1cc51e70 100755
--- a/Source/Shared/WeaponHEGrenade.c
+++ b/Source/Shared/WeaponHEGrenade.c
@@ -107,8 +107,8 @@ void WeaponHEGRENADE_Throw( void ) {
if ( other == self.owner ) {
return;
}
- if ( other.classname == "func_breakable" && other.material == MATERIAL_GLASS ) {
- Damage_Apply( other, self, 50, self.origin, FALSE );
+ if ( ( other.classname == "func_breakable" ) && ( other.material == MATERIAL_GLASS ) ) {
+ Damage_Apply( other, self, other.health, self.origin, FALSE );
}
sound( self, CHAN_WEAPON, "weapons/he_bounce-1.wav", 1, ATTN_NORM );
@@ -118,15 +118,15 @@ void WeaponHEGRENADE_Throw( void ) {
entity eNade = spawn();
setorigin( eNade, ( self.origin + self.view_ofs ) + ( v_forward * 16 ) );
setmodel( eNade, "models/w_hegrenade.mdl" );
- setsize( eNade, '-4 -4 -4', '4 4 4' );
+ setsize( eNade, '-1 -1 -1', '1 1 1' );
vector vDir = aim ( self, 100000 );
eNade.owner = self;
eNade.classname = "remove_me";
eNade.solid = SOLID_TRIGGER; // This is so grenades will not get slowed down by windows they touch
eNade.angles = vectoangles( vDir );
- eNade.velocity = ( vDir * 800 );
- eNade.avelocity = ( v_forward * 600 );
+ eNade.velocity = ( vDir * 1000 );
+ eNade.avelocity = ( v_forward * 1000 );
eNade.movetype = MOVETYPE_BOUNCE;
eNade.touch = Weapon_HEGRENADE_Touch;
diff --git a/Source/Shared/WeaponSmokeGrenade.c b/Source/Shared/WeaponSmokeGrenade.c
index 013adb5e..615e7130 100755
--- a/Source/Shared/WeaponSmokeGrenade.c
+++ b/Source/Shared/WeaponSmokeGrenade.c
@@ -127,7 +127,7 @@ void WeaponSMOKEGRENADE_Throw( void ) {
entity eNade = spawn();
setorigin( eNade, ( self.origin + self.view_ofs ) + ( v_forward * 16 ) );
setmodel( eNade, "models/w_smokegrenade.mdl" );
- setsize( eNade, '-4 -4 -4', '4 4 4' );
+ setsize( eNade, '-1 -1 -1', '1 1 1' );
vector vDir = aim ( self, 100000 );
eNade.classname = "remove_me";
diff --git a/freecs/csprogs.dat b/freecs/csprogs.dat
index b6ede5f6..95caaa90 100644
Binary files a/freecs/csprogs.dat and b/freecs/csprogs.dat differ
diff --git a/freecs/default.cfg b/freecs/default.cfg
index 590cf08c..86fd9dd4 100644
--- a/freecs/default.cfg
+++ b/freecs/default.cfg
@@ -76,5 +76,4 @@ seta scr_conalpha "1"
seta con_notifylines "0"
seta maxplayers "8"
seta lang "en_us"
-seta cfg_save_auto "1"
-seta in_rawinput "1"
\ No newline at end of file
+seta cfg_save_auto "1"
\ No newline at end of file
diff --git a/freecs/menu.dat b/freecs/menu.dat
index 475cce81..ac57ed18 100755
Binary files a/freecs/menu.dat and b/freecs/menu.dat differ
diff --git a/freecs/progs.dat b/freecs/progs.dat
index a7dacf2d..ab06f2f4 100644
Binary files a/freecs/progs.dat and b/freecs/progs.dat differ