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