From f8a1902187c8e7514a622d46d84954d300d2909f Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Sun, 11 Dec 2016 11:10:03 +0100 Subject: [PATCH] Added bomb-defusing Added progressbar on bomb defusing Added seperators on the timer and the ammo display Fixed some USE bugs related to doors and other ents +use (+button6) is now something that can be toggled, whereas before it was a one-time thing Added various sounds when buying things Added various messages when trying to buy things you already have Added proper radio sounds to the bombing mission type More work done on the equipment --- Source/Client/Event.c | 9 -- Source/Client/HUD.c | 82 ++++++++++++++++--- Source/Client/VGUI.h | 8 +- Source/Client/VGUIBuyMenu.c | 131 ++++++++++++++++++++---------- Source/Client/progs.src | 1 + Source/Globals.h | 15 ++++ Source/Menu/progs.src | 9 ++ Source/Server/Ammo.c | 3 +- Source/Server/Damage.c | 5 +- Source/Server/Defs.h | 8 +- Source/Server/EntHostage.c | 1 - Source/Server/EnvObjects.c | 2 + Source/Server/FuncDoorRotating.c | 10 +++ Source/Server/FuncHostageRescue.c | 2 +- Source/Server/FuncVIPSafetyZone.c | 2 +- Source/Server/Input.c | 28 ++----- Source/Server/Main.c | 6 ++ Source/Server/Player.c | 54 +++++++++++- Source/Server/Rules.c | 24 ++++-- Source/Server/progs.src | 4 +- Source/Shared/Equipment.c | 87 ++++++++++++++++++++ Source/Shared/WeaponBase.c | 1 + Source/Shared/WeaponC4Bomb.c | 73 +++++++++++++++-- Source/Shared/Weapons.c | 13 +-- 24 files changed, 455 insertions(+), 123 deletions(-) create mode 100644 Source/Menu/progs.src create mode 100644 Source/Shared/Equipment.c diff --git a/Source/Client/Event.c b/Source/Client/Event.c index f15dd020..fb2f3c46 100644 --- a/Source/Client/Event.c +++ b/Source/Client/Event.c @@ -28,7 +28,6 @@ Init all the cmds in one place void CSQC_ConsoleCommand_Init( void ) { registercommand( "buy" ); registercommand( "chooseteam" ); - registercommand( "use" ); registercommand( "testobt" ); registercommand( "+showscores" ); registercommand( "-showscores" ); @@ -55,14 +54,6 @@ float CSQC_ConsoleCommand( string sCMD ) { fVGUI_Display = VGUI_TEAMSELECT; return TRUE; break; - case "use": - sendevent( "PlayerUse", "" ); - return TRUE; - break; - case "testobt": - HUD_AddOrbituaries( player_localnum, TEAM_T, player_localnum, TEAM_CT, getstatf( STAT_ACTIVEWEAPON ), FALSE ); - return TRUE; - break; case "+showscores": iShowScores = TRUE; return TRUE; diff --git a/Source/Client/HUD.c b/Source/Client/HUD.c index 9ee1ccc2..71e17c1c 100644 --- a/Source/Client/HUD.c +++ b/Source/Client/HUD.c @@ -107,7 +107,6 @@ void HUD_DrawHealth( void ) { fHealthAlpha = HUD_ALPHA; } - // Health vector vHealthPos = [ 16, vVideoResolution_y - 42 ]; drawsubpic( vHealthPos, '24 24 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 2, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, HUD_ALPHA, DRAWFLAG_ADDITIVE ); HUD_DrawNums( getstatf( STAT_HEALTH ), vHealthPos + '72 0', HUD_ALPHA, VGUI_WINDOW_FGCOLOR ); @@ -133,6 +132,7 @@ void HUD_DrawArmor( void ) { } else { fArmorAlpha = HUD_ALPHA; } + vector vArmorPos = [ 112, vVideoResolution_y - 42 ]; drawsubpic( vArmorPos, '24 24 0', HUD_NUMFILE_LAYER, [ 0, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, fArmorAlpha, DRAWFLAG_ADDITIVE ); HUD_DrawNums( getstatf( STAT_ARMOR ), vArmorPos + '72 0', fArmorAlpha, VGUI_WINDOW_FGCOLOR); @@ -170,8 +170,6 @@ void HUD_DrawIcons( void ) { } else { drawsubpic( vBIconPos, '32 32 0', HUD_NUMFILE_LAYER, [ 0, 0.125 * 5 - 0.046875], [ 0.125, 0.125 ], '0 1 0', 1, DRAWFLAG_ADDITIVE ); } - - } } @@ -186,7 +184,7 @@ int iOldUnits; float fTimerAlpha; void HUD_DrawTimer( void ) { int iMinutes, iSeconds, iTens, iUnits; - vector vTimePos = [ ( vVideoResolution_x / 2 ) - 60, vVideoResolution_y - 42 ]; + vector vTimePos = [ ( vVideoResolution_x / 2 ) - 62, vVideoResolution_y - 42 ]; if( serverkey( "timelimit" ) ) { float fTimeLeft = ( stof(serverkey( "timelimit" )) * 60 ) - getstatf( STAT_GAMETIME ); @@ -217,11 +215,17 @@ void HUD_DrawTimer( void ) { } HUD_DrawNumber( iMinutes, vTimePos + '48 0 0', fAlpha, '1 0 0' ); - HUD_DrawNumber( iTens, vTimePos + '70 0 0', fAlpha, '1 0 0' ); - HUD_DrawNumber( iUnits, vTimePos + '94 0 0',fAlpha, '1 0 0' ); + HUD_DrawNumber( iTens, vTimePos + '75 0 0', fAlpha, '1 0 0' ); + HUD_DrawNumber( iUnits, vTimePos + '99 0 0',fAlpha, '1 0 0' ); HUD_DrawNumber( iMinutes, vTimePos + '48 0 0', 1 - fAlpha, VGUI_WINDOW_FGCOLOR ); - HUD_DrawNumber( iTens, vTimePos + '70 0 0', 1 - fAlpha, VGUI_WINDOW_FGCOLOR ); - HUD_DrawNumber( iUnits, vTimePos + '94 0 0',1 - fAlpha, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNumber( iTens, vTimePos + '75 0 0', 1 - fAlpha, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNumber( iUnits, vTimePos + '99 0 0',1 - fAlpha, VGUI_WINDOW_FGCOLOR ); + + // : symbol + drawsubpic( vTimePos + '70 6 0', '3 3 0', HUD_NUMFILE_LAYER, [0.9375, 0], [ 0.01171875, 0.01171875 ], '1 0 0', fAlpha, DRAWFLAG_ADDITIVE ); + drawsubpic( vTimePos + '70 16 0', '3 3 0', HUD_NUMFILE_LAYER, [0.9375, 0], [ 0.01171875, 0.01171875 ], '1 0 0', fAlpha, DRAWFLAG_ADDITIVE ); + drawsubpic( vTimePos + '70 6 0', '3 3 0', HUD_NUMFILE_LAYER, [0.9375, 0], [ 0.01171875, 0.01171875 ], VGUI_WINDOW_FGCOLOR, 1 - fAlpha, DRAWFLAG_ADDITIVE ); + drawsubpic( vTimePos + '70 16 0', '3 3 0', HUD_NUMFILE_LAYER, [0.9375, 0], [ 0.01171875, 0.01171875 ], VGUI_WINDOW_FGCOLOR, 1 - fAlpha, DRAWFLAG_ADDITIVE ); drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], '1 0 0', fAlpha, DRAWFLAG_ADDITIVE ); drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, 1 - fAlpha, DRAWFLAG_ADDITIVE ); @@ -236,8 +240,12 @@ void HUD_DrawTimer( void ) { fTimerAlpha = HUD_ALPHA; } HUD_DrawNumber( iMinutes, vTimePos + '48 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); - HUD_DrawNumber( iTens, vTimePos + '70 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); - HUD_DrawNumber( iUnits, vTimePos + '94 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNumber( iTens, vTimePos + '75 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); + HUD_DrawNumber( iUnits, vTimePos + '99 0 0', fTimerAlpha, VGUI_WINDOW_FGCOLOR ); + + drawsubpic( vTimePos + '70 6 0', '3 3 0', HUD_NUMFILE_LAYER, [0.9375, 0], [ 0.01171875, 0.01171875 ], VGUI_WINDOW_FGCOLOR, fTimerAlpha, DRAWFLAG_ADDITIVE ); + drawsubpic( vTimePos + '70 16 0', '3 3 0', HUD_NUMFILE_LAYER, [0.9375, 0], [ 0.01171875, 0.01171875 ], VGUI_WINDOW_FGCOLOR, fTimerAlpha, DRAWFLAG_ADDITIVE ); + drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, fTimerAlpha, DRAWFLAG_ADDITIVE ); iOldUnits = iUnits; } @@ -253,28 +261,45 @@ Draws the amount of money (0-16000) with an icon to the screen float fOldMoneyValue; float fMoneyAlphaEffect; vector vMoneyColorEffect; +float fMoneyDifference; void HUD_DrawMoney( void ) { // If the money differs from last frame, paint it appropriately if ( getstatf( STAT_MONEY ) > fOldMoneyValue ) { // Make it green for a short time vMoneyColorEffect = '0 1 0'; fMoneyAlphaEffect = 1.0; + fMoneyDifference = fOldMoneyValue - getstatf( STAT_MONEY ); } else if ( getstatf( STAT_MONEY ) < fOldMoneyValue ) { // Make it red vMoneyColorEffect = '1 0 0'; fMoneyAlphaEffect = 1.0; + fMoneyDifference = fOldMoneyValue - getstatf( STAT_MONEY ); } vector vMoneyPos = [ vVideoResolution_x - 160, vVideoResolution_y - 72 ]; + // If the alpha/color effect is active, draw the money twice in their varying alphas/colors if ( fMoneyAlphaEffect > 0 ) { fMoneyAlphaEffect -= frametime * 0.5; drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], vMoneyColorEffect, fMoneyAlphaEffect, DRAWFLAG_ADDITIVE ); drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, HUD_ALPHA - ( fMoneyAlphaEffect * 0.5 ), DRAWFLAG_ADDITIVE ); + // Draw the +/- symbols depending on whether or not we made or lost money + if ( fMoneyDifference < 0 ) { + drawsubpic( vMoneyPos + '0 -32 0', '18 23 0', HUD_NUMFILE_LAYER, [ 0.8671875, 0.09765625], [ 0.0703125, 0.08984375 ], vMoneyColorEffect, fMoneyAlphaEffect, DRAWFLAG_ADDITIVE ); + } else { + drawsubpic( vMoneyPos + '0 -32 0', '13 23 0', HUD_NUMFILE_LAYER, [ 0.8203125, 0.09765625], [ 0.05078125, 0.08984375 ], vMoneyColorEffect, fMoneyAlphaEffect, DRAWFLAG_ADDITIVE ); + } + + // Shift the numbers for reverse drawing vMoneyPos_x += ( 24 * 5 ); + + // Draw the regular numbers at their normal positions HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos, fMoneyAlphaEffect, vMoneyColorEffect ); HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos, HUD_ALPHA - ( fMoneyAlphaEffect * 0.5 ), VGUI_WINDOW_FGCOLOR ); + + // Draw above how much money we've gotten from all this + HUD_DrawNums( fabs( fMoneyDifference ), vMoneyPos + '0 -32 0', fMoneyAlphaEffect, vMoneyColorEffect ); } else { drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, HUD_ALPHA, DRAWFLAG_ADDITIVE ); vMoneyPos_x += ( 24 * 5 ); @@ -308,8 +333,11 @@ void HUD_DrawAmmo( void ) { fAmmoAlpha = HUD_ALPHA; } - vector vAmmoClipPos = [ vVideoResolution_x - 136, vVideoResolution_y - 42 ]; + vector vAmmoClipPos = [ vVideoResolution_x - 142, vVideoResolution_y - 42 ]; HUD_DrawNums( getstatf( STAT_CURRENT_CLIP ), vAmmoClipPos, fAmmoAlpha, VGUI_WINDOW_FGCOLOR ); + + drawsubpic( [vVideoResolution_x - 118, vVideoResolution_y - 42], '3 25 0', HUD_NUMFILE_LAYER, [0.9375, 0], [ 0.01171875, 0.09765625 ], VGUI_WINDOW_FGCOLOR, fAmmoAlpha, DRAWFLAG_ADDITIVE ); + vector vAmmoCalPos = [ vVideoResolution_x - 64, vVideoResolution_y - 42 ]; HUD_DrawNums( getstatf( STAT_CURRENT_CALIBER ), vAmmoCalPos, fAmmoAlpha, VGUI_WINDOW_FGCOLOR ); @@ -319,6 +347,37 @@ void HUD_DrawAmmo( void ) { fOldCal = getstatf( STAT_CURRENT_CALIBER ); } +void HUD_DrawProgressBar( void ) { + vector vSize = '540 16'; + vector vMainPos; + vector v1, v2, v3; + + if ( getstatf( STAT_PROGRESS ) > 0 ) { + vMainPos_x = ( vVideoResolution_x / 2 ) - (vSize_x / 2); + vMainPos_y = ( vVideoResolution_y / 2 ) - (vSize_y / 2); + + // Draw the background + vector vBar = vSize; + vBar_x = 536 * getstatf( STAT_PROGRESS ); + vBar_y = 13; + drawfill( vMainPos + '1 1 0', vBar, VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + + // Draw the outline START + v1_x = vMainPos_x + vSize_x; + v1_y = vMainPos_y; + drawline( 1.0, vMainPos - '1 0 0', v1, VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + + v2_x = vMainPos_x; + v2_y = vMainPos_y + vSize_y; + drawline( 1.0, vMainPos, v2, VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + + v3 = vMainPos + vSize; + drawline( 1.0, v1, v3, VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + drawline( 1.0, v2, v3, VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE ); + // Draw the outline END + } +} + /* ================= HUD_Draw @@ -340,4 +399,5 @@ void HUD_Draw( void ) { HUD_DrawMoney(); HUD_DrawAmmo(); HUD_DrawOrbituaries(); + HUD_DrawProgressBar(); } diff --git a/Source/Client/VGUI.h b/Source/Client/VGUI.h index 5a054086..e19a6bfd 100644 --- a/Source/Client/VGUI.h +++ b/Source/Client/VGUI.h @@ -52,4 +52,10 @@ typedef struct { typedef struct { string sName; string sImage; -} vguiweapon_t; +} vguiweaponobject_t; + +typedef struct { + float fID; + string sName; + string sImage; +} vguiequipobject_t; diff --git a/Source/Client/VGUIBuyMenu.c b/Source/Client/VGUIBuyMenu.c index dbdf9f58..e177bc82 100644 --- a/Source/Client/VGUIBuyMenu.c +++ b/Source/Client/VGUIBuyMenu.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "VGUI.h" -vguiweapon_t vguiWeaponTable[ CS_WEAPON_COUNT ] = { +vguiweaponobject_t vguiWeaponTable[ CS_WEAPON_COUNT ] = { { "None", "" }, { "Knife", "" }, { "H&K USP .45 Tactical", "gfx/vgui/640_usp" }, @@ -47,6 +47,16 @@ vguiweapon_t vguiWeaponTable[ CS_WEAPON_COUNT ] = { { "FN M249 Para", "gfx/vgui/640_m249" } }; +vguiequipobject_t vguiEquipmentTable[ 7 ] = { + { EQUIPMENT_KEVLAR, "Kevlar", "gfx/vgui/kevlar" }, + { EQUIPMENT_HELMET, "Kevlar & Helmet", "gfx/vgui/kevlar_helmet" }, + { EQUIPMENT_FLASHBANG, "Flashband", "gfx/vgui/640_flashbang" }, + { EQUIPMENT_HEGRENADE, "HE Grenade", "gfx/vgui/640_hegrenade" }, + { EQUIPMENT_SMOKEGRENADE, "Smoke Grenade", "gfx/vgui/640_smokegrenade" }, + { EQUIPMENT_DEFUSALKIT, "Defusal Kit", "gfx/vgui/defuser" }, + { EQUIPMENT_NIGHTVISION, "NightVision", "gfx/vgui/nightvision" }, +}; + // TODO: Clean this up void VGUI_BuyMenu_Main( vector vPos ) { static void BuyMenu_Main_1( void ) { @@ -106,27 +116,37 @@ This is kinda ugly, but it will work for now float iLastSelected; void VGUI_BuyMenu_BuyWeapon( void ) { if( iLastSelected ) { - sendevent( "GamePlayerBuy", "f", iLastSelected ); + sendevent( "PlayerBuyWeapon", "f", iLastSelected ); fVGUI_Display = VGUI_NONE; } } /* ==================== -VGUI_BuyMenu_Button +VGUI_BuyMenu_BuyEquipment +==================== +*/ +void VGUI_BuyMenu_BuyEquipment( void ) { + sendevent( "PlayerBuyEquipment", "f", iLastSelected ); + fVGUI_Display = VGUI_NONE; +} + +/* +==================== +VGUI_BuyMenu_WeaponButton Draws a button that displays whether or not you can purchase said weapon etc. ==================== */ -void VGUI_BuyMenu_Button( float fWeapon ) { +void VGUI_BuyMenu_WeaponButton( float fWeapon ) { iLastSelected = fWeapon; if ( wptTable[ fWeapon ].iPrice <= getstatf( STAT_MONEY ) ) { if ( VGUI_Button( vguiWeaponTable[ fWeapon ].sName, VGUI_BuyMenu_BuyWeapon, vVGUIButtonPos, '180 24 0' ) == TRUE ) { drawpic( vVGUIWindowPos + '290 116', vguiWeaponTable[ fWeapon ].sImage, '256 64', '1 1 1', 1 ); - VGUI_Text( sprintf( "Price: %d", (float)wptTable[ fWeapon ].iPrice ) , vVGUIWindowPos + '256 250', '8 8 0' ); - VGUI_Text( sprintf( "Caliber: %d", (float)wptTable[ fWeapon ].iCaliber ) , vVGUIWindowPos + '256 260', '8 8 0' ); - VGUI_Text( sprintf( "Rounds Per Minute: %d", ( wptTable[ fWeapon ].fAttackFinished) * 3600 ) , vVGUIWindowPos + '256 270', '8 8 0' ); + VGUI_Text( sprintf( "Price: %i", wptTable[ fWeapon ].iPrice ), vVGUIWindowPos + '256 250', '8 8 0' ); + VGUI_Text( sprintf( "Caliber: %i", wptTable[ fWeapon ].iCaliber ), vVGUIWindowPos + '256 260', '8 8 0' ); + VGUI_Text( sprintf( "Rounds Per Minute: %d", ( wptTable[ fWeapon ].fAttackFinished) * 3600 ), vVGUIWindowPos + '256 270', '8 8 0' ); } } else { VGUI_FakeButton( vguiWeaponTable[ fWeapon ].sName, vVGUIButtonPos, '180 24 0' ); @@ -135,6 +155,28 @@ void VGUI_BuyMenu_Button( float fWeapon ) { vVGUIButtonPos_y += 32; } +/* +==================== +VGUI_BuyMenu_EquipmentButton + +Draws a button that displays whether or not you can purchase said equipment +==================== +*/ +void VGUI_BuyMenu_EquipmentButton( float fID ) { + iLastSelected = fID; + + if ( eqptTable[ fID ].iPrice <= getstatf( STAT_MONEY ) ) { + if ( VGUI_Button( vguiEquipmentTable[ fID ].sName, VGUI_BuyMenu_BuyEquipment, vVGUIButtonPos, '180 24 0' ) == TRUE ) { + drawpic( vVGUIWindowPos + '290 116', vguiEquipmentTable[ fID ].sImage, '256 64', '1 1 1', 1 ); + VGUI_Text( sprintf( "Price: %i", eqptTable[ fID ].iPrice ) , vVGUIWindowPos + '256 250', '8 8 0' ); + } + } else { + VGUI_FakeButton( vguiEquipmentTable[ fID ].sName, vVGUIButtonPos, '180 24 0' ); + } + + vVGUIButtonPos_y += 32; +} + /* ==================== VGUI_BuyMenu_Handguns @@ -143,20 +185,19 @@ VGUI_BuyMenu_Handguns void VGUI_BuyMenu_Handguns( vector vPos ) { vVGUIButtonPos = vPos + '16 116 0'; - VGUI_BuyMenu_Button( WEAPON_USP45 ); - VGUI_BuyMenu_Button( WEAPON_GLOCK18 ); - VGUI_BuyMenu_Button( WEAPON_DEAGLE ); - VGUI_BuyMenu_Button( WEAPON_P228 ); + VGUI_BuyMenu_WeaponButton( WEAPON_USP45 ); + VGUI_BuyMenu_WeaponButton( WEAPON_GLOCK18 ); + VGUI_BuyMenu_WeaponButton( WEAPON_DEAGLE ); + VGUI_BuyMenu_WeaponButton( WEAPON_P228 ); vVGUIButtonPos_y += 32; if ( stof( getplayerkeyvalue( player_localnum, "*team" ) ) == TEAM_T ) { - VGUI_BuyMenu_Button( WEAPON_ELITES ); + VGUI_BuyMenu_WeaponButton( WEAPON_ELITES ); + } else if ( stof( getplayerkeyvalue( player_localnum, "*team" ) ) == TEAM_CT ) { + VGUI_BuyMenu_WeaponButton( WEAPON_FIVESEVEN ); } - if ( stof( getplayerkeyvalue( player_localnum, "*team" ) ) == TEAM_CT ) { - VGUI_BuyMenu_Button( WEAPON_FIVESEVEN ); - } VGUI_Button( "Back", VGUI_BuyMenu_Back, vPos + '16 440 0', '180 24 0' ); } @@ -168,8 +209,8 @@ VGUI_BuyMenu_Shotguns void VGUI_BuyMenu_Shotguns( vector vPos ) { vVGUIButtonPos = vPos + '16 116 0'; - VGUI_BuyMenu_Button( WEAPON_M3 ); - VGUI_BuyMenu_Button( WEAPON_XM1014 ); + VGUI_BuyMenu_WeaponButton( WEAPON_M3 ); + VGUI_BuyMenu_WeaponButton( WEAPON_XM1014 ); VGUI_Button( "Back", VGUI_BuyMenu_Back, vPos + '16 440 0', '180 24 0' ); } @@ -183,18 +224,16 @@ void VGUI_BuyMenu_SMGs( vector vPos ) { vVGUIButtonPos = vPos + '16 116 0'; - VGUI_BuyMenu_Button( WEAPON_MP5 ); - VGUI_BuyMenu_Button( WEAPON_P90 ); - VGUI_BuyMenu_Button( WEAPON_UMP45 ); + VGUI_BuyMenu_WeaponButton( WEAPON_MP5 ); + VGUI_BuyMenu_WeaponButton( WEAPON_P90 ); + VGUI_BuyMenu_WeaponButton( WEAPON_UMP45 ); vVGUIButtonPos_y += 32; if ( stof( getplayerkeyvalue( player_localnum, "*team" ) ) == TEAM_T ) { - VGUI_BuyMenu_Button( WEAPON_MAC10 ); - } - - if ( stof( getplayerkeyvalue( player_localnum, "*team" ) ) == TEAM_CT ) { - VGUI_BuyMenu_Button( WEAPON_TMP ); + VGUI_BuyMenu_WeaponButton( WEAPON_MAC10 ); + } else if ( stof( getplayerkeyvalue( player_localnum, "*team" ) ) == TEAM_CT ) { + VGUI_BuyMenu_WeaponButton( WEAPON_TMP ); } VGUI_Button( "Back", VGUI_BuyMenu_Back, vPos + '16 440 0', '180 24 0' ); @@ -209,23 +248,23 @@ void VGUI_BuyMenu_Rifles( vector vPos ) { vVGUIButtonPos = vPos + '16 116 0'; if ( getstati( STAT_TEAM ) == TEAM_T ) { - VGUI_BuyMenu_Button( WEAPON_AK47 ); - VGUI_BuyMenu_Button( WEAPON_SG552 ); + VGUI_BuyMenu_WeaponButton( WEAPON_AK47 ); + VGUI_BuyMenu_WeaponButton( WEAPON_SG552 ); - VGUI_BuyMenu_Button( WEAPON_SCOUT ); - VGUI_BuyMenu_Button( WEAPON_AWP ); + VGUI_BuyMenu_WeaponButton( WEAPON_SCOUT ); + VGUI_BuyMenu_WeaponButton( WEAPON_AWP ); - VGUI_BuyMenu_Button( WEAPON_G3SG1 ); + VGUI_BuyMenu_WeaponButton( WEAPON_G3SG1 ); } if ( getstati( STAT_TEAM ) == TEAM_CT ) { - VGUI_BuyMenu_Button( WEAPON_M4A1 ); - VGUI_BuyMenu_Button( WEAPON_AUG ); + VGUI_BuyMenu_WeaponButton( WEAPON_M4A1 ); + VGUI_BuyMenu_WeaponButton( WEAPON_AUG ); - VGUI_BuyMenu_Button( WEAPON_SCOUT ); - VGUI_BuyMenu_Button( WEAPON_AWP ); + VGUI_BuyMenu_WeaponButton( WEAPON_SCOUT ); + VGUI_BuyMenu_WeaponButton( WEAPON_AWP ); - VGUI_BuyMenu_Button( WEAPON_SG550 ); + VGUI_BuyMenu_WeaponButton( WEAPON_SG550 ); } VGUI_Button( "Back", VGUI_BuyMenu_Back, vPos + '16 440 0', '180 24 0' ); @@ -239,7 +278,7 @@ VGUI_BuyMenu_Machineguns void VGUI_BuyMenu_Machineguns( vector vPos ) { vVGUIButtonPos = vPos + '16 116 0'; - VGUI_BuyMenu_Button( WEAPON_PARA ); + VGUI_BuyMenu_WeaponButton( WEAPON_PARA ); VGUI_Button( "Back", VGUI_BuyMenu_Back, vPos + '16 440 0', '180 24 0' ); } @@ -250,17 +289,19 @@ VGUI_BuyMenu_Equipment ==================== */ void VGUI_BuyMenu_Equipment( vector vPos ) { + vVGUIButtonPos = vPos + '16 116 0'; - /*VGUI_BuyMenu_Button( "Kevlar Vest", "", BuyMenu_Equipment_1, vPos + '16 116 0', '180 24 0' ); - VGUI_BuyMenu_Button( "Kevlar Vest & Helmet", "", BuyMenu_Equipment_1, vPos + '16 148 0', '180 24 0' ); - VGUI_BuyMenu_Button( "Flashbang", "gfx/vgui/640_flashbang", BuyMenu_Equipment_1, vPos + '16 180 0', '180 24 0' ); - VGUI_BuyMenu_Button( "HE Grenade", "gfx/vgui/640_hegrenade", BuyMenu_Equipment_1, vPos + '16 212 0', '180 24 0' ); - VGUI_BuyMenu_Button( "Smoke Grenade", "gfx/vgui/640_smokegrenade", BuyMenu_Equipment_1, vPos + '16 244 0', '180 24 0' ); - VGUI_BuyMenu_Button( "NightVision Goggles", "", BuyMenu_Equipment_1, vPos + '16 276 0', '180 24 0' );*/ - - if ( getplayerkeyvalue( player_localnum, "team" ) == "ct" ) { - //VGUI_BuyMenu_Button( "Defuse Kit", "", BuyMenu_Equipment_1, vPos + '16 308 0', '180 24 0' ); + VGUI_BuyMenu_EquipmentButton( 0 ); + VGUI_BuyMenu_EquipmentButton( 1 ); + VGUI_BuyMenu_EquipmentButton( 2 ); + VGUI_BuyMenu_EquipmentButton( 3 ); + VGUI_BuyMenu_EquipmentButton( 4 ); + + if ( stof( getplayerkeyvalue( player_localnum, "*team" ) ) == TEAM_CT ) { + VGUI_BuyMenu_EquipmentButton( 5 ); } + VGUI_BuyMenu_EquipmentButton( 6 ); + VGUI_Button( "Back", VGUI_BuyMenu_Back, vPos + '16 440 0', '180 24 0' ); } diff --git a/Source/Client/progs.src b/Source/Client/progs.src index b07bbd6d..67dbf6e8 100644 --- a/Source/Client/progs.src +++ b/Source/Client/progs.src @@ -37,6 +37,7 @@ Defs.h ../Shared/Weapons.c ../Shared/Effects.c ../Shared/Radio.c +../Shared/Equipment.c ../Server/AmbientSound.c diff --git a/Source/Globals.h b/Source/Globals.h index 94a8a2cc..19c005a5 100644 --- a/Source/Globals.h +++ b/Source/Globals.h @@ -38,6 +38,7 @@ enum { STAT_SLOT_GRENADE, STAT_CURRENT_CLIP, STAT_CURRENT_CALIBER, + STAT_PROGRESS, STAT_TEAM, STAT_WON_T, STAT_WON_CT @@ -85,6 +86,15 @@ enum { WEAPON_C4BOMB }; +#define CS_EQUIPMENT_COUNT 7 +#define EQUIPMENT_KEVLAR 1 +#define EQUIPMENT_HELMET 2 +#define EQUIPMENT_FLASHBANG 4 +#define EQUIPMENT_HEGRENADE 8 +#define EQUIPMENT_SMOKEGRENADE 16 +#define EQUIPMENT_DEFUSALKIT 32 +#define EQUIPMENT_NIGHTVISION 64 + enum { CALIBER_50AE = 1, CALIBER_762MM, @@ -152,6 +162,11 @@ typedef struct { float fMaxInaccuracy; } weaponinfo_t; +typedef struct { + int iID; + int iPrice; +} equipmentinfo_t; + typedef struct { int iSize; int iMaxAmount; diff --git a/Source/Menu/progs.src b/Source/Menu/progs.src new file mode 100644 index 00000000..09afed6a --- /dev/null +++ b/Source/Menu/progs.src @@ -0,0 +1,9 @@ +#pragma target fte + +#pragma progs_dat "../../opencs/menu.dat" + +#includelist +../Builtins.h +../Globals.h +../Math.h +#endlist diff --git a/Source/Server/Ammo.c b/Source/Server/Ammo.c index 54411337..2889c0c9 100644 --- a/Source/Server/Ammo.c +++ b/Source/Server/Ammo.c @@ -65,6 +65,7 @@ void Ammo_BuySecondary( void ) { self.(wptTable[ self.iSlotSecondary ].iCaliberfld) += ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iSize; Money_AddMoney( self, -ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iPrice ); + sound( self, CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_IDLE ); if ( self.(wptTable[ self.iSlotSecondary ].iCaliberfld) > ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iMaxAmount ) { self.(wptTable[ self.iSlotSecondary ].iCaliberfld) = ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iMaxAmount; @@ -83,8 +84,6 @@ void CSEv_GamePlayerBuyAmmo_f( float fType ) { Ammo_BuySecondary(); } - sound( self, CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM ); Weapon_UpdateCurrents(); self.fAttackFinished = time + 1.0; } - diff --git a/Source/Server/Damage.c b/Source/Server/Damage.c index 83eee6ce..0c76ea76 100644 --- a/Source/Server/Damage.c +++ b/Source/Server/Damage.c @@ -85,11 +85,8 @@ void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadi float fDiff = vlen( vOrigin - eDChain.origin ); fDiff = ( fRadius - fDiff ) / fRadius; - fDamage = fDamage * fDiff; - - bprint( sprintf("[DEBUG] EXPLOSION! Hit Radius: %d, Damage Multiplier: %f\n", vlen( vOrigin - eDChain.origin ), fDiff ) ); - + if ( fDiff > 0 ) { Damage_Apply( eDChain, eAttacker, fDamage, eDChain.origin ); } diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index 5cd77573..d92ca39e 100644 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -43,6 +43,11 @@ float EFFECT_BLOOD; .int iCrouchAttempt; .int iHasBomb; .float fDeaths; +.int iEquipment; +.float armor; +.float fProgressBar; + +#define FL_USERELEASED 8192 // Match specific fields int iWon_T; @@ -77,6 +82,7 @@ int iBombPlanted; .void() vPain; .void() vDeath; .float fRespawns; +.entity eUser; // All about +use entity eActivator; @@ -101,7 +107,7 @@ string sCSPlayers[9] = { "models/player/gign/gign.mdl" }; -void Rules_RoundOver( int iTeamWon, int iMoneyReward ); +void Rules_RoundOver( int iTeamWon, int iMoneyReward, float fSilent ); float Rules_BuyingPossible( void ); void Timer_Begin( float fTime, float fMode); void Spawn_RespawnClient( float fTeam ); diff --git a/Source/Server/EntHostage.c b/Source/Server/EntHostage.c index ae6ccc61..c4684098 100644 --- a/Source/Server/EntHostage.c +++ b/Source/Server/EntHostage.c @@ -18,7 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -.entity eUser; .entity eTargetPoint; .entity eLastCreated; .int iHasBeenUsed; diff --git a/Source/Server/EnvObjects.c b/Source/Server/EnvObjects.c index 8a57a425..3827f47a 100644 --- a/Source/Server/EnvObjects.c +++ b/Source/Server/EnvObjects.c @@ -80,8 +80,10 @@ void env_sprite( void ) { } precache_model( self.model ); + setmodel( self, self.model ); setorigin( self, self.origin ); Entities_RenderSetup(); + self.pvsflags = PVSF_NOREMOVE | PVSF_IGNOREPVS; self.SendEntity = env_sprite_send; self.vUse = env_sprite_use; } diff --git a/Source/Server/FuncDoorRotating.c b/Source/Server/FuncDoorRotating.c index 5573715c..3162675e 100644 --- a/Source/Server/FuncDoorRotating.c +++ b/Source/Server/FuncDoorRotating.c @@ -146,6 +146,11 @@ brush_rotate_trigger - What happens when you +use the brush or trigger it ================= */ void FuncDoorRotate_Trigger( void ) { + if ( self.fAttackFinished > time ) { + return; + } + self.fAttackFinished = self.ltime + self.wait; + if ( ( self.state == STATE_UP ) || ( self.state == STATE_RAISED ) ) { FuncDoorRotate_RotateBack(); return; @@ -167,6 +172,7 @@ FuncDoorRotate_Touch */ void FuncDoorRotate_Touch( void ) { if ( other.classname == "player" ) { + eActivator = other; FuncDoorRotate_Trigger(); if( !( self.spawnflags & SF_ROT_USE ) ) { @@ -218,6 +224,10 @@ void func_door_rotating( void ) { if ( !self.speed ) { self.speed = 100; } + + if( self.wait == 0 ) { + self.wait = 4; + } self.pos1 = self.angles; diff --git a/Source/Server/FuncHostageRescue.c b/Source/Server/FuncHostageRescue.c index 1069934f..d79735d8 100644 --- a/Source/Server/FuncHostageRescue.c +++ b/Source/Server/FuncHostageRescue.c @@ -44,7 +44,7 @@ void func_hostage_rescue_touch( void ) { if ( iHostagesRescued >= iHostagesMax ) { // TODO: Broadcast_Print: All Hostages have been rescued! - Rules_RoundOver( TEAM_CT, 0 ); + Rules_RoundOver( TEAM_CT, 0, FALSE ); } } } diff --git a/Source/Server/FuncVIPSafetyZone.c b/Source/Server/FuncVIPSafetyZone.c index 3bd598c8..814b2b63 100644 --- a/Source/Server/FuncVIPSafetyZone.c +++ b/Source/Server/FuncVIPSafetyZone.c @@ -25,7 +25,7 @@ func_vip_safetyzone_touch */ void func_vip_safetyzone_touch( void ) { if ( ( other.classname == "player" ) && ( other.team == TEAM_VIP ) ) { - Rules_RoundOver( TEAM_CT, 2500 ); + Rules_RoundOver( TEAM_CT, 2500, FALSE ); entity eOld = self; self = other; diff --git a/Source/Server/Input.c b/Source/Server/Input.c index c3cc5431..4429df94 100644 --- a/Source/Server/Input.c +++ b/Source/Server/Input.c @@ -44,27 +44,11 @@ void Input_Handle( void ) { Weapon_SecondaryAttack( self.weapon ); } + if ( self.button6 ) { + Player_UseDown(); + } else { + Player_UseUp(); + } + self.impulse = 0; } - -/* -==================== -CSEv_PlayerUse -==================== -*/ -void CSEv_PlayerUse( void ) { - vector vSource; - entity eOriginalSelf; - - makevectors(self.v_angle); - vSource = self.origin + self.view_ofs; - traceline ( vSource, vSource + ( v_forward * 64 ), FALSE, self); - - if ( trace_ent.iUsable ) { - eActivator = self; - eOriginalSelf = self; - self = trace_ent; - self.vUse(); - self = eOriginalSelf; - } -} diff --git a/Source/Server/Main.c b/Source/Server/Main.c index caa16a23..a659c979 100644 --- a/Source/Server/Main.c +++ b/Source/Server/Main.c @@ -90,6 +90,10 @@ void worldspawn( void ) { precache_sound( "player/pl_step4.wav" ); precache_sound( "items/9mmclip1.wav" ); + precache_sound( "items/tr_kevlar.wav" ); + precache_sound( "items/gunpickup2.wav" ); + precache_sound( "common/wpn_select.wav" ); + precache_sound( "common/wpn_denyselect.wav" ); precache_sound( "weapons/ak47-1.wav" ); precache_sound( "weapons/ak47-2.wav" ); @@ -267,6 +271,7 @@ void worldspawn( void ) { clientstat( STAT_HOSTAGEZONE, EV_FLOAT, fInHostageZone ); clientstat( STAT_BOMBZONE, EV_FLOAT, fInBombZone ); + clientstat( 4, EV_FLOAT, armor ); clientstat( STAT_MONEY, EV_FLOAT, fMoney ); clientstat( STAT_SLOT_MELEE, EV_INTEGER, iSlotMelee ); clientstat( STAT_SLOT_PRIMARY, EV_INTEGER, iSlotPrimary ); @@ -275,6 +280,7 @@ void worldspawn( void ) { clientstat( STAT_CURRENT_CLIP, EV_INTEGER, iCurrentClip ); clientstat( STAT_CURRENT_CALIBER, EV_INTEGER, iCurrentCaliber ); clientstat( STAT_TEAM, EV_INTEGER, team ); + clientstat( STAT_PROGRESS, EV_FLOAT, fProgressBar ); pointerstat( STAT_GAMETIME, EV_FLOAT, &fGameTime ); pointerstat( STAT_WON_T, EV_INTEGER, &iWon_T ); pointerstat( STAT_WON_CT, EV_INTEGER, &iWon_CT ); diff --git a/Source/Server/Player.c b/Source/Server/Player.c index 56065f90..5bd5b8dc 100644 --- a/Source/Server/Player.c +++ b/Source/Server/Player.c @@ -43,17 +43,17 @@ void Player_Death( void ) { // If the bomb has been planted, T deaths don't matter anymore if ( iAlivePlayers_T == 0 && iBombPlanted == FALSE ) { - Rules_RoundOver( TEAM_CT, 3600 ); + Rules_RoundOver( TEAM_CT, 3600, FALSE ); } } else if ( self.team == TEAM_CT ) { iAlivePlayers_CT--; if ( iAlivePlayers_CT == 0 ) { - Rules_RoundOver( TEAM_T, 3600 ); + Rules_RoundOver( TEAM_T, 3600, FALSE ); } } else if ( self.team == TEAM_VIP ) { iAlivePlayers_CT--; // For consistency - Rules_RoundOver( TEAM_T, 2500 ); + Rules_RoundOver( TEAM_T, 2500, FALSE ); } } @@ -116,7 +116,7 @@ void Player_CrouchUp( void ) { return; } - if ( self.iCrouching && ( !self.velocity_z ) && (Player_CrouchCheck( self ) ) ) { + if ( self.iCrouching && ( !self.velocity_z ) && ( Player_CrouchCheck( self ) ) ) { setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); setorigin( self, self.origin + '0 0 18'); @@ -130,3 +130,49 @@ void Player_CrouchUp( void ) { self.iCrouchAttempt = TRUE; } + +/* +==================== +Player_UseDown +==================== +*/ +void Player_UseDown( void ) { + if ( !( self.flags & FL_USERELEASED ) ) { + return; + } + + vector vSource; + entity eOriginalSelf; + + makevectors(self.v_angle); + vSource = self.origin + self.view_ofs; + traceline ( vSource, vSource + ( v_forward * 64 ), FALSE, self); + + if ( trace_ent.iUsable ) { + sound( self, CHAN_WEAPON, "common/wpn_select.wav", 0.25, ATTN_IDLE ); + if ( trace_ent.classname != "c4bomb" ) { + self.flags = ( self.flags - FL_USERELEASED ); + } + + eActivator = self; + eOriginalSelf = self; + self = trace_ent; + self.vUse(); + self = eOriginalSelf; + } else { + sound( self, CHAN_WEAPON, "common/wpn_denyselect.wav", 0.25, ATTN_IDLE ); + self.flags = ( self.flags - FL_USERELEASED ); + } +} + +/* +==================== +Player_UseUp +==================== +*/ +void Player_UseUp( void ) { + if ( !( self.frags & FL_USERELEASED ) ) { + self.flags = self.flags | FL_USERELEASED; + self.fProgressBar = 0; + } +} diff --git a/Source/Server/Rules.c b/Source/Server/Rules.c index 76b52b55..f0be6f7f 100644 --- a/Source/Server/Rules.c +++ b/Source/Server/Rules.c @@ -92,6 +92,7 @@ void Rules_Restart( void ) { if ( iPickT == iRandomT ) { self = eFind; Weapon_AddItem( WEAPON_C4BOMB ); + centerprint( self, "You have the bomb!\nFind the target zone or DROP\nthe bomb for another Terrorist." ); } } } @@ -109,6 +110,7 @@ void Rules_Restart( void ) { self = eFind; self.team = TEAM_VIP; Spawn_RespawnClient( self.team ); + centerprint( self, "You are the VIP\nMake your way to the safety zones!" ); forceinfokey( self, "*dead", "2" ); } } @@ -130,20 +132,26 @@ void Rules_Restart( void ) { } // This can happen whenever an objective is complete or time is up -void Rules_RoundOver( int iTeamWon, int iMoneyReward ) { +void Rules_RoundOver( int iTeamWon, int iMoneyReward, float fSilent ) { if ( fGameState != GAME_ACTIVE ) { return; } if ( iTeamWon == TEAM_T ) { - Radio_BroadcastMessage( RADIO_TERWIN ); + if ( fSilent == TRUE ) { + Radio_BroadcastMessage( RADIO_TERWIN ); + } iWon_T++; } else if ( iTeamWon == TEAM_CT ) { - Radio_BroadcastMessage( RADIO_CTWIN ); + if ( fSilent == TRUE ) { + Radio_BroadcastMessage( RADIO_CTWIN ); + } iWon_CT++; } else { - Radio_BroadcastMessage( RADIO_ROUNDDRAW ); + if ( fSilent == TRUE ) { + Radio_BroadcastMessage( RADIO_ROUNDDRAW ); + } } Money_QueTeamReward( iTeamWon, iMoneyReward ); Timer_Begin( 5, GAME_END); // Round is over, 5 seconds til a new round starts @@ -152,14 +160,14 @@ void Rules_RoundOver( int iTeamWon, int iMoneyReward ) { // Whenever mp_roundtime was being counted down to 0 void Rules_TimeOver( void ) { if ( iVIPZones > 0 ) { - Rules_RoundOver( TEAM_T, 3250 ); + Rules_RoundOver( TEAM_T, 3250, FALSE ); } else if ( iBombZones > 0 ) { - Rules_RoundOver( TEAM_CT, 3250 ); + Rules_RoundOver( TEAM_CT, 3250, FALSE ); } else if ( iHostagesMax > 0 ) { // TODO: Broadcast_Print: Hostages have not been rescued! - Rules_RoundOver( TEAM_T, 3250 ); + Rules_RoundOver( TEAM_T, 3250, FALSE ); } else { - Rules_RoundOver( 0, 0 ); + Rules_RoundOver( 0, 0, FALSE ); } } diff --git a/Source/Server/progs.src b/Source/Server/progs.src index fcb96ffd..c1622a93 100644 --- a/Source/Server/progs.src +++ b/Source/Server/progs.src @@ -8,6 +8,8 @@ ../Math.h Defs.h +Money.c + ../Shared/Radio.c ../Shared/WeaponAK47.c ../Shared/WeaponAUG.c @@ -36,8 +38,8 @@ Defs.h ../Shared/WeaponBase.c ../Shared/Weapons.c ../Shared/Effects.c +../Shared/Equipment.c -Money.c Ammo.c Damage.c TraceAttack.c diff --git a/Source/Shared/Equipment.c b/Source/Shared/Equipment.c new file mode 100644 index 00000000..ed3faafd --- /dev/null +++ b/Source/Shared/Equipment.c @@ -0,0 +1,87 @@ +/* +OpenCS Project +Copyright (C) 2015 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. +*/ + +equipmentinfo_t eqptTable [ CS_EQUIPMENT_COUNT ] = { + { EQUIPMENT_KEVLAR, 650 }, + { EQUIPMENT_HELMET, 1000 }, + { EQUIPMENT_FLASHBANG, 300 }, + { EQUIPMENT_HEGRENADE, 300 }, + { EQUIPMENT_SMOKEGRENADE, 300 }, + { EQUIPMENT_DEFUSALKIT, 200 }, + { EQUIPMENT_NIGHTVISION, 1250 }, +}; + +#ifdef SSQC +void CSEv_PlayerBuyEquipment_f( float fID ) { + if ( Rules_BuyingPossible() == FALSE ) { + return; + } + + if ( ( self.fMoney - eqptTable[ fID ].iPrice ) >= 0 ) { + if ( eqptTable[ fID ].iID == EQUIPMENT_KEVLAR ) { + if ( self.armor == 100 ) { + // You already own armor etc. + centerprint( self, "You already have kevlar!" ); + } else { + self.armor = 100; + Money_AddMoney( self, -650 ); + } + + sound( self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE ); + self.fAttackFinished = time + 1.0; + return; + } else if ( eqptTable[ fID ].iID == EQUIPMENT_HELMET ) { + if ( self.armor == 100 ) { + if ( self.iEquipment & EQUIPMENT_HELMET ) { + // You already have full armor and a helmet + centerprint( self, "You already have kevlar and a helmet!" ); + } else { + // You have full armor, but no helmet + centerprint( self, "You already have some kevlar,\nand now you've bought a helmet!" ); + Money_AddMoney( self, -350 ); + sound( self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE ); + } + } else { + if ( self.iEquipment & EQUIPMENT_HELMET ) { + // Only get armor + centerprint( self, "You already have a helmet,\nand now you're bought some kevlar!" ); + self.armor = 100; + Money_AddMoney( self, -650 ); + sound( self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE ); + } else { + // Get both + self.armor = 100; + self.iEquipment = self.iEquipment | EQUIPMENT_HELMET; + Money_AddMoney( self, -1000 ); + sound( self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE ); + } + } + + self.fAttackFinished = time + 1.0; + return; + } + + self.iEquipment = self.iEquipment | ( eqptTable[ fID ].iID ); + Money_AddMoney( self, -eqptTable[ fID ].iPrice ); + } + + self.fAttackFinished = time + 1.0; +} +#endif diff --git a/Source/Shared/WeaponBase.c b/Source/Shared/WeaponBase.c index 39fb0b25..255ef3f0 100644 --- a/Source/Shared/WeaponBase.c +++ b/Source/Shared/WeaponBase.c @@ -74,6 +74,7 @@ float OpenCSGunBase_PrimaryFire( void ) { self.fAttackFinished = time + wptTable[ self.weapon ].fAttackFinished; Client_SendEvent( self, EV_WEAPON_PRIMARYATTACK ); + self.effects = self.effects | EF_MUZZLEFLASH; return TRUE; } diff --git a/Source/Shared/WeaponC4Bomb.c b/Source/Shared/WeaponC4Bomb.c index 35b60a57..932ef5ee 100644 --- a/Source/Shared/WeaponC4Bomb.c +++ b/Source/Shared/WeaponC4Bomb.c @@ -57,10 +57,20 @@ enum { #ifdef SSQC void WeaponC4BOMB_Drop( vector vBombPos ) { - static void c4bomb_think( void ) { + static float fBeepTime; // Used for the beeping sounds that last 1.5 seconds + static float fDefuseProgress; // Used to track... the progress + + static void C4BombThink( void ) { + // If the guy who started using us stopped using us, reset the defuser counter + if ( ( self.eUser != world ) && ( self.eUser.button6 == FALSE ) ) { + self.eUser.fProgressBar = 0; + self.eUser = world; + fDefuseProgress = 0; + } + + // If our time has passed, explode if ( self.fAttackFinished < time ) { - Rules_RoundOver( TEAM_T, 3500 ); - // EXPLODE! + Rules_RoundOver( TEAM_T, 3500, FALSE ); sound( self, CHAN_VOICE, "weapons/c4_explode1.wav", 1.0, ATTN_NONE ); Damage_Radius( self.origin, self.owner, 500, 1024 ); remove( self ); @@ -68,7 +78,15 @@ void WeaponC4BOMB_Drop( vector vBombPos ) { return; } - if ( self.fAttackFinished - time < 5 ) { + // Only play sounds every once in a while + if ( fBeepTime > time ) { + return; + } + fBeepTime = time + 1.5; + + if ( self.fAttackFinished - time < 2 ) { + sound( self, CHAN_VOICE, "weapons/c4_beep5.wav", 1.0, ATTN_NONE ); + } else if ( self.fAttackFinished - time < 5 ) { sound( self, CHAN_VOICE, "weapons/c4_beep5.wav", 1.0, ATTN_NORM ); } else if ( self.fAttackFinished - time < 10 ) { sound( self, CHAN_VOICE, "weapons/c4_beep4.wav", 1.0, ATTN_NORM ); @@ -79,19 +97,59 @@ void WeaponC4BOMB_Drop( vector vBombPos ) { } else { sound( self, CHAN_VOICE, "weapons/c4_beep1.wav", 1.0, ATTN_NORM ); } - self.nextthink = time + 1.5; + } + static void C4BombUse( void ) { + /*if ( eActivator.team != TEAM_CT ) { + return; + }*/ + + // On first use, play defusing sound + if ( self.eUser == world ) { + sound( self, CHAN_VOICE, "weapons/c4_disarm.wav", 1.0, ATTN_NORM ); + } + + // Takes 10 seconds to defuse that thing! + if ( fDefuseProgress > 10 ) { + sound( self, CHAN_VOICE, "weapons/c4_disarmed.wav", 1.0, ATTN_NORM ); + Rules_RoundOver( TEAM_CT, 3500, TRUE ); + Radio_BroadcastMessage( RADIO_BOMBDEF ); + eActivator.fProgressBar = 0; + iBombPlanted = FALSE; + remove( self ); + return; + } + + // If the user has for the right equipment, make 10 seconds pass twice as fast + if ( eActivator.iEquipment & EQUIPMENT_DEFUSALKIT ) { + fDefuseProgress += ( frametime * 2 ); + } else { + fDefuseProgress += frametime; + } + + eActivator.fProgressBar = (fDefuseProgress * 0.1); + + // Makesure C4BombThink knows who the user is + self.eUser = eActivator; } + // Do all the dirty entspawning stuff entity eBomb = spawn(); + eBomb.classname = "c4bomb"; setorigin( eBomb, vBombPos ); setmodel( eBomb, "models/w_c4.mdl" ); - eBomb.think = c4bomb_think; - eBomb.nextthink = time + 1.5; + eBomb.solid = SOLID_BBOX; + eBomb.customphysics = C4BombThink; eBomb.fAttackFinished = time + cvar( "mp_c4timer" ); + eBomb.vUse = C4BombUse; + eBomb.iUsable = TRUE; + sound( eBomb, CHAN_WEAPON, "weapons/c4_plant.wav", 1.0, ATTN_IDLE ); + // Broadcast the bomb state Radio_BroadcastMessage( RADIO_BOMBPL ); iBombPlanted = TRUE; + + // Tell the bomb-planter to get rid of the weapon! self.iSlotGrenade = self.iSlotGrenade - WEAPON_C4BOMB; Weapon_SwitchBest(); } @@ -119,6 +177,7 @@ void WeaponC4BOMB_PrimaryFire( void ) { makevectors( self.v_angle ); traceline( self.origin + self.view_ofs, self.origin + self.view_ofs + ( v_forward * 64 ), FALSE, self ); + // If we aren't aiming at a place or look in the wrong location... stop it if ( trace_fraction == 1 || self.fInBombZone == FALSE ) { WeaponC4BOMB_Release(); self.fAttackFinished = time + 1.0; diff --git a/Source/Shared/Weapons.c b/Source/Shared/Weapons.c index b420f0e3..6ee3821d 100644 --- a/Source/Shared/Weapons.c +++ b/Source/Shared/Weapons.c @@ -129,6 +129,7 @@ void Weapon_UpdateCurrents( void ) { } // We get a weapon for the first time essentially +// TODO: Drop the current slot weapon upon buying a new one void Weapon_AddItem( float fWeapon ) { // Add the gun to the appropriate slot @@ -164,15 +165,17 @@ void Weapon_SwitchBest( void ) { } } -void CSEv_GamePlayerBuy_f( float fWeapon ) { +void CSEv_PlayerBuyWeapon_f( float fWeapon ) { if ( Rules_BuyingPossible() == FALSE ) { return; } - Weapon_AddItem( fWeapon ); - Weapon_Draw( fWeapon ); - - self.fMoney -= wptTable[ fWeapon ].iPrice; + if ( ( self.fMoney - wptTable[ fWeapon ].iPrice ) >= 0 ) { + Weapon_AddItem( fWeapon ); + Weapon_Draw( fWeapon ); + Money_AddMoney( self, -wptTable[ fWeapon ].iPrice ); + sound( self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE ); + } self.fAttackFinished = time + 1.0; } #endif