Fixed #79 by updating the spectator check

Fixed the smoke-grenade smoke not clearing upon next round
Changed in_rawinput to 0 for now, since it was causing problems
Fixed the RadiusDamage function in regards to regular explosions
Deleted the unnecessary lines trying to respect 'timelimit', which is deprecated afaik
Changed the sizes of individual grenades so that they'll be thrown more easily across crates and corners
Added an early preview of loading map overviews. They are not really usable and merely a work in progress on my end. They will be finished soon though.
This commit is contained in:
Marco Cawthorne 2017-11-19 20:03:30 -06:00
parent 2ec9213437
commit cd6263299e
26 changed files with 379 additions and 163 deletions

View file

@ -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;

View file

@ -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 ) {

View file

@ -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;

View file

@ -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 ) ) {

View file

@ -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;
}
/*

View file

@ -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;
}

143
Source/Client/Overview.c Executable file
View file

@ -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 ) ) ;
}

View file

@ -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 );

View file

@ -44,6 +44,7 @@ Defs.h
../Shared/Equipment.c
../Shared/Animations.c
Overview.c
Player.c
View.c
VGUIObjects.c

View file

@ -11,6 +11,7 @@
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\HUDWeaponSelect.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Init.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Nightvision.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Overview.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Player.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\progs.src" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Sound.c" />
@ -25,7 +26,7 @@
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\VGUITeamSelect.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\View.c" />
</category>
<category name="Server" expanded="yes">
<category name="Server" expanded="no">
<localfile path="C:\cygwin\home\User\FreeCS\Source\Server\AmbientSound.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Server\Ammo.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Server\ArmouryEntity.c" />
@ -62,7 +63,7 @@
<localfile path="C:\cygwin\home\User\FreeCS\Source\Server\Triggers.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Server\Vox.c" />
</category>
<category name="Menu" expanded="yes">
<category name="Menu" expanded="no">
<localfile path="C:\cygwin\home\User\FreeCS\Source\Menu\Defs.h" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Menu\Draw.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Menu\Header.c" />

View file

@ -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 );

View file

@ -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;

View file

@ -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;

View file

@ -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";

View file

@ -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

View file

@ -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 ] ) );
}
}
}
}

View file

@ -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 );

View file

@ -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
}

View file

@ -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";

View file

@ -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 ) {

View file

@ -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;

View file

@ -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";

Binary file not shown.

View file

@ -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"
seta cfg_save_auto "1"

Binary file not shown.

Binary file not shown.