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:
parent
2ec9213437
commit
cd6263299e
26 changed files with 379 additions and 163 deletions
|
@ -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;
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ) ) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
143
Source/Client/Overview.c
Executable 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 ) ) ;
|
||||
}
|
|
@ -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 );
|
||||
|
|
|
@ -44,6 +44,7 @@ Defs.h
|
|||
../Shared/Equipment.c
|
||||
../Shared/Animations.c
|
||||
|
||||
Overview.c
|
||||
Player.c
|
||||
View.c
|
||||
VGUIObjects.c
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
@ -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"
|
BIN
freecs/menu.dat
BIN
freecs/menu.dat
Binary file not shown.
BIN
freecs/progs.dat
BIN
freecs/progs.dat
Binary file not shown.
Loading…
Reference in a new issue