Added sv_voxannounce, which will advertise the time remaining

Added support for c4bombs to align to walls
Fixed the infamous crouch-defusal bug
Reworked the way the Glock does Burst-Fire
Added support for voice overlays when pressing the Voice Communication key
Fixed some bad grammar I must have written while either drunk or lazily copy/pasting things
This commit is contained in:
Marco Cawthorne 2017-11-18 15:21:39 -06:00
parent 7770b250d5
commit 2ec9213437
20 changed files with 168 additions and 21 deletions

View file

@ -245,6 +245,7 @@ void CSQC_UpdateView( float fWinWidth, float fWinHeight, float fGameFocus ) {
}
HUD_DrawOrbituaries();
HUD_DrawVoice();
CSQC_DrawChat();
// Don't even try to draw centerprints and VGUI menus when scores are shown

View file

@ -442,3 +442,30 @@ void HUD_Draw( void ) {
HUD_DrawProgressBar();
HUD_DrawWeaponSelect();
}
/*
=================
HUD_DrawVoice
Draws a little notification for anyone using voice chat
=================
*/
void HUD_DrawVoice( void ) {
vector vVoicePos = vVideoMins + [ vVideoResolution_x - 160, vVideoResolution_y - 136 ];
for ( int i = -1; i > -32; i-- ) {
if ( getplayerkeyvalue( i, INFOKEY_P_VOIPSPEAKING ) == "1" ) {
drawfill( vVoicePos, '144 24', VGUI_WINDOW_BGCOLOR, VGUI_WINDOW_BGALPHA );
drawfill( vVoicePos, [144, 1], vVGUIColor, VGUI_WINDOW_FGALPHA );
drawfill( [vVoicePos_x, vVoicePos_y + 23], [144, 1], vVGUIColor, VGUI_WINDOW_FGALPHA );
drawfill( vVoicePos, [1, 24], vVGUIColor, VGUI_WINDOW_FGALPHA );
drawfill( [vVoicePos_x + 143, vVoicePos_y], [1, 24], vVGUIColor, VGUI_WINDOW_FGALPHA );
CSQC_DrawText( [ vVoicePos_x + 16, vVoicePos_y + 8 ], sprintf( " %.13s", getplayerkeyvalue( i, "name" ) ), '8 8', vVGUIColor, VGUI_WINDOW_FGALPHA, DRAWFLAG_NORMAL, FONT_DEFAULT );
drawpic( vVoicePos + '2 0', "gfx/vgui/icntlk_sv.tga", '24 24', vVGUIColor, 1, DRAWFLAG_NORMAL );
vVoicePos_y -= 32;
}
}
}

View file

@ -70,6 +70,8 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
precache_sound( "debris/bustconcrete2.wav" );
precache_sound( "debris/bustceiling.wav" );
precache_pic( "gfx/vgui/icntlk_sv" );
for ( int i = 0; i < ( CS_WEAPON_COUNT - 1 ); i++ ) {
precache_model( sViewModels[ i ] );
}

View file

@ -100,6 +100,8 @@ void Player_Draw( void ) {
self.baseframe2time += frametime;
self.frame2time += frametime;
self.bonecontrol5 = stof( getplayerkeyvalue( player_localnum, INFOKEY_P_VOIPLOUDNESS ) );
}
/*

View file

@ -44,6 +44,9 @@ void Sound_PlayVOX( string sMessage ) {
}
void Sound_ProcessWordQue( void ) {
if ( cltime < 2 ) {
return;
}
if ( iVOXCount ) {
if ( fSampleTime < time ) {
localcmd( sprintf( "play %s\n", sndVOX[ iVOXPos ].sSample ) );

View file

@ -1,5 +1,5 @@
<project version="Crimson Editor 3.60">
<category name="Client" expanded="no">
<category name="Client" expanded="yes">
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Defs.h" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Draw.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Client\Entities.c" />
@ -60,6 +60,7 @@
<localfile path="C:\cygwin\home\User\FreeCS\Source\Server\Timer.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Server\TraceAttack.c" />
<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">
<localfile path="C:\cygwin\home\User\FreeCS\Source\Menu\Defs.h" />
@ -73,7 +74,7 @@
<localfile path="C:\cygwin\home\User\FreeCS\Source\Menu\Objects.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Menu\progs.src" />
</category>
<category name="Shared" expanded="no">
<category name="Shared" expanded="yes">
<localfile path="C:\cygwin\home\User\FreeCS\Source\Shared\Animations.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Shared\BaseGun.c" />
<localfile path="C:\cygwin\home\User\FreeCS\Source\Shared\BaseMelee.c" />

View file

@ -55,7 +55,12 @@ void Menu_Configuration_Init( void ) {
while ( ( sTemp = fgets( fileSettings ) ) ) {
// Tokenize and just parse this stuff in
if ( tokenize_console( sTemp ) == 2 ) {
strActBind[ iCount ] = argv( 0 );
// FTE uses +voip, so replace the GoldSrc bind with that
if ( argv( 0 ) != "+voicerecord" ) {
strActBind[ iCount ] = argv( 0 );
} else {
strActBind[ iCount ] = "+voip";
}
strActDescr[ iCount ] = argv( 1 );
//print( sprintf( "%s %s\n", strActBind[ iCount ], strActDescr[ iCount ] ) );
iCount++;

View file

@ -113,6 +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 ) ) );
}
self.team = 0;
forceinfokey( self, "*team", "0" );
}

View file

@ -27,12 +27,12 @@ var float autocvar_mp_buytime = 90;
var float autocvar_mp_freezetime = 6;
var float autocvar_mp_c4timer = 45;
var float autocvar_mp_roundtime = 5;
var float autocvar_mp_fillweapons = 0;
var float autocvar_mp_timelimit = 60;
var string autocvar_motdfile = "motd.txt";
var int autocvar_mp_fillweapons = FALSE;
var int autocvar_mp_autoreload = FALSE;
var int autocvar_sv_voxannounce = TRUE;
// Mapcycle features
var string autocvar_mapcyclefile = "mapcycle.txt";

View file

@ -86,11 +86,7 @@ float ConsoleCmd( string sCommand ) {
if ( argv( 0 ) == "vox" ) {
localcmd( sprintf( "echo [VOX] Sending: %s\n", argv( 1 ) ) );
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_CHAT_VOX );
WriteString( MSG_MULTICAST, argv( 1 ) );
msg_entity = world;
multicast( '0 0 0', MULTICAST_ALL );
Vox_Broadcast( argv( 1 ) );
return TRUE;
}

View file

@ -47,6 +47,23 @@ 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 ( time >= ( cvar( "mp_timelimit" ) * 60 ) ) {
for ( int i = 0; i < iMapCycleCount; i++ ) {

76
Source/Server/Vox.c Executable file
View file

@ -0,0 +1,76 @@
/*
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.
*/
/*
=================
Vox_TimeToString
Assumes time in minutes.
TODO: Actually output proper, tokenized strings for not just 1-10 minutes
=================
*/
string Vox_TimeToString( float fTime ) {
fTime = rint( fTime );
switch ( fTime ) {
case 0: return "no";
case 1: return "one";
case 2: return "two";
case 3: return "three";
case 4: return "four";
case 5: return "five";
case 6: return "six";
case 7: return "seven";
case 8: return "eight";
case 9: return "nine";
case 10: return "ten";
default: return "over ten";
}
}
/*
=================
Vox_Broadcast
Broadcasts a VOX message to all players
=================
*/
void Vox_Broadcast( string sMessage ) {
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_CHAT_VOX );
WriteString( MSG_MULTICAST, sMessage );
msg_entity = world;
multicast( '0 0 0', MULTICAST_ALL );
}
/*
=================
Vox_Singlecast
Broadcasts a VOX message to one player
=================
*/
void Vox_Singlecast( entity eClient, string sMessage ) {
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_CHAT_VOX );
WriteString( MSG_MULTICAST, sMessage );
msg_entity = eClient;
multicast( '0 0 0', MULTICAST_ONE_R );
}

View file

@ -46,6 +46,7 @@ PhysicsMove.c
../Shared/Effects.c
../Shared/Equipment.c
Vox.c
Ammo.c
Damage.c
TraceAttack.c

View file

@ -104,7 +104,7 @@ void CSEv_PlayerBuyEquipment_f( float fID ) {
self.armor = 100;
Money_AddMoney( self, -650 );
sound( self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE );
centerprint( self, "You already have a helmet,\nand now you're bought some kevlar!" );
centerprint( self, "You already have a helmet,\nand now you've bought some kevlar!" );
} else {
// Get both
self.armor = 100;

View file

@ -103,7 +103,7 @@ static void WeaponC4BOMB_Use( void ) {
static void WeaponC4BOMB_Think( void ) {
// If the guy who started using us stopped using us, reset the defuser counter
if ( ( self.eUser != world ) && ( self.eUser.button6 == FALSE ) ) {
if ( ( self.eUser != world ) && ( self.eUser.button3 == FALSE ) ) {
self.eUser.fProgressBar = 0;
self.eUser = world;
fDefuseProgress = 0;
@ -159,7 +159,7 @@ static void WeaponC4BOMB_Think( void ) {
}
}
void WeaponC4BOMB_Drop( vector vBombPos ) {
void WeaponC4BOMB_Drop( vector vBombPos, vector vNormal ) {
// Do all the dirty entspawning stuff
entity eBomb = spawn();
eBomb.classname = "c4bomb";
@ -173,7 +173,14 @@ void WeaponC4BOMB_Drop( vector vBombPos ) {
eBomb.fAttackFinished = time + autocvar_mp_c4timer;
eBomb.vUse = WeaponC4BOMB_Use;
eBomb.iUsable = TRUE;
eBomb.owner = world;
eBomb.owner = self;
// Align the bomb to the wall
vector vBombAngles = self.angles + '0 90 0';
vBombAngles_x *= -1;
makevectors( vBombAngles );
vector vCoplanar = v_forward - ( v_forward * vNormal ) * vNormal;
eBomb.angles = vectoangles( vCoplanar, vNormal );
sound( eBomb, CHAN_WEAPON, "weapons/c4_plant.wav", 1.0, ATTN_IDLE );

View file

@ -89,15 +89,19 @@ void WeaponGLOCK18_PrimaryFire( void ) {
sound( self, CHAN_WEAPON, "weapons/glock18-2.wav", 1, ATTN_NORM );
}
} else {
if ( (self.iMag_GLOCK18 - 3 ) < 0 ) {
return FALSE;
if ( self.iMag_GLOCK18 <= 0 ) {
return;
}
BaseGun_AccuracyCalc();
TraceAttack_FireBullets( 3, ( self.origin + self.view_ofs ) );
self.iMag_GLOCK18 -= 3;
for ( int i = 0; i < 3; i++ ) {
if ( self.iMag_GLOCK18 ) {
BaseGun_ShotMultiplierHandle( 1 );
BaseGun_AccuracyCalc();
TraceAttack_FireBullets( 1, ( self.origin + self.view_ofs ) );
self.iMag_GLOCK18 -= 1;
}
}
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 );

View file

@ -46,7 +46,7 @@ string sWeaponModels[ CS_WEAPON_COUNT ] = {
"models/w_g3sg1.mdl",
"models/w_sg550.mdl",
"models/w_m249.mdl",
"models/w_c4.mdl",
"models/w_backpack.mdl",
"models/w_flashbang.mdl",
"models/w_hegrenade.mdl",
"models/w_smokegrenade.mdl"

Binary file not shown.

Binary file not shown.

Binary file not shown.