diff --git a/Source/Client/Defs.h b/Source/Client/Defs.h index 838e92d8..d545d5dc 100644 --- a/Source/Client/Defs.h +++ b/Source/Client/Defs.h @@ -51,6 +51,7 @@ vector vVGUIColor; // Defined in HUD_Draw (VGUI.c) vector vCrossColor; // Defined in HUD_Draw (HUDCrosshair.c) float fVGUI_Display; // The VGUI menu currently being drawn +float fInputSendNext; vector vVideoResolution; // Updated every frame diff --git a/Source/Client/Event.c b/Source/Client/Event.c index d3ade8e7..6fa16e98 100644 --- a/Source/Client/Event.c +++ b/Source/Client/Event.c @@ -33,6 +33,7 @@ void CSQC_ConsoleCommand_Init( void ) { registercommand( "+showscores" ); registercommand( "-showscores" ); registercommand( "nightvision" ); + registercommand( "drop" ); registercommand( "radio1" ); registercommand( "radio2" ); @@ -135,6 +136,10 @@ float CSQC_ConsoleCommand( string sCMD ) { Nightvision_Toggle(); return TRUE; break; + case "drop": + sendevent( "WeaponDrop", "" ); + return TRUE; + break; case "glock": sendevent( "PlayerBuyWeapon", "f", WEAPON_GLOCK18 ); return TRUE; @@ -466,14 +471,16 @@ Hijacks and controls what input globals are being sent to the server void CSQC_Input_Frame( void ) { // If we are inside a VGUI, don't let the client do stuff outside if ( ( fVGUI_Display != VGUI_NONE ) ) { - input_angles = '0 0 0'; - input_movevalues = '0 0 0'; - input_buttons = 0; - input_impulse = 0; - } - - if ( ( fHUDWeaponSelected ) && ( input_buttons & INPUT_BUTTON0 ) ) { + fInputSendNext = time + 0.1; + } else if ( ( fHUDWeaponSelected ) && ( input_buttons & INPUT_BUTTON0 ) ) { HUD_DrawWeaponSelect_Trigger(); input_buttons = 0; + fInputSendNext = time + 0.1; + } + + if ( fInputSendNext > time ) { + input_impulse = 0; + input_buttons = 0; + return; } } diff --git a/Source/Client/Init.c b/Source/Client/Init.c index 4bcc5942..9666e541 100644 --- a/Source/Client/Init.c +++ b/Source/Client/Init.c @@ -59,7 +59,7 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) { precache_sound( "debris/bustconcrete2.wav" ); precache_sound( "debris/bustceiling1.wav" ); - for( int i = 0; i < CS_WEAPON_COUNT; i++ ) { + for ( int i = 1; i < CS_WEAPON_COUNT; i++ ) { precache_model( sViewModels[ i ] ); } diff --git a/Source/Client/Sound.c b/Source/Client/Sound.c index 31a74a92..c3ace4e0 100644 --- a/Source/Client/Sound.c +++ b/Source/Client/Sound.c @@ -36,6 +36,7 @@ void Sound_Delayed( string sSample, float fVol, float fDelay ) { remove( self ); } entity eSound = spawn(); + eSound.classname = "event_sound"; eSound.think = Sound_Delayed_PlayBack; eSound.sSoundSample = sSample; eSound.fVolume = fVol; diff --git a/Source/Client/VGUIBuyMenu.c b/Source/Client/VGUIBuyMenu.c index cda7fdb1..8f89b0ea 100644 --- a/Source/Client/VGUIBuyMenu.c +++ b/Source/Client/VGUIBuyMenu.c @@ -142,14 +142,14 @@ 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: %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' ); + if ( VGUI_Button( vguiWeaponTable[ fWeapon ].sName, VGUI_BuyMenu_BuyWeapon, vVGUIButtonPos, '264 24 0' ) == TRUE ) { + drawpic( vVGUIWindowPos + '328 116', vguiWeaponTable[ fWeapon ].sImage, '256 64', '1 1 1', 1 ); + VGUI_Text( sprintf( "Price: %i", wptTable[ fWeapon ].iPrice ), vVGUIWindowPos + '328 250', '8 8 0' ); + VGUI_Text( sprintf( "Caliber: %i", wptTable[ fWeapon ].iCaliber ), vVGUIWindowPos + '328 260', '8 8 0' ); + VGUI_Text( sprintf( "Rounds Per Minute: %d", ( wptTable[ fWeapon ].fAttackFinished) * 3600 ), vVGUIWindowPos + '328 270', '8 8 0' ); } } else { - VGUI_FakeButton( vguiWeaponTable[ fWeapon ].sName, vVGUIButtonPos, '180 24 0' ); + VGUI_FakeButton( vguiWeaponTable[ fWeapon ].sName, vVGUIButtonPos, '264 24 0' ); } vVGUIButtonPos_y += 32; diff --git a/Source/Client/VGUITeamSelect.c b/Source/Client/VGUITeamSelect.c index eb59157d..bd49587a 100644 --- a/Source/Client/VGUITeamSelect.c +++ b/Source/Client/VGUITeamSelect.c @@ -20,46 +20,70 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "VGUI.h" -string sClassInfo[40] = { +string sClassInfo[64] = { "Phoenix Connexion", "gfx/vgui/640_terror", - "The Phoenix Faction was formed shortly after the breakup of the USSR.", - "Having established a reputation for killing anyone that gets in their way,", - "the Phoenix Faction is one of the most feared terrorist groups in Eastern Europe.", + "The Phoenix Faction was formed shortly", + "after the breakup of the USSR. Having", + "established a reputation for killing ", + "anyone that gets in their way, the", + "the Phoenix Faction is one of the most", + "feared terrorist groups in Eastern Europe.", "L337 Krew", "gfx/vgui/640_leet", - "Middle Eastern fundamentalist group bent on world domination and various other evil deeds", + "Middle Eastern fundamentalist group bent", + "on world domination and various other", + "evil deeds", + "", "", "", "Arctic Avengers", "gfx/vgui/640_arctic", "Swedish terrorist faction founded in 1977.", - "Famous for their bombing of the Canadian embassy in 1990.", + "Famous for their bombing of the Canadian", + "embassy in 1990.", + "", + "", "", "Guerilla Warfare", "gfx/vgui/640_guerilla", - "A terrorist faction founded in the Middle East, Guerilla Warfare,", - "has a reputation for ruthlessness. Their disgust for the American lifestyle was", - "demonstrated in their 1982 bombing of a school bus full of Rock and Roll musicians.", + "A terrorist faction founded in the", + "Middle East, Guerilla Warfare, has a", + "reputation for ruthlessness. Their disgust", + "for the American lifestyle was demonstrated", + "in their 1982 bombing of a school bus full", + "of Rock and Roll musicians.", "Seal Team 6", "gfx/vgui/640_urban", - "Seal Team 6 (to be known later as DEVGRU) was founded in 1980 under the command of ", - "Lieutenant-Commander Richard Marcincko. ST-6 was placed on permanent alert to ", - "respond to terrorist attacks against American targets worldwide.", + "Seal Team 6 (to be known later as DEVGRU)", + "was founded in 1980 under the command of", + "Lieutenant-Commander Richard Marcincko.", + "ST-6 was placed on permanent alert to", + "respond to terrorist attacks against ", + "American targets worldwide.", "German GSG9", "gfx/vgui/640_gsg9", - "GSG-9 was born out of the tragic events that led to the death of several", - "Israeli athletes during the 1972 Olympic games in Munich, Germany.", + "GSG-9 was born out of the tragic events", + "that led to the death of several", + "Israeli athletes during the 1972 Olympic", + "games in Munich, Germany.", + "", "", "UK SAS", "gfx/vgui/640_sas", - "The world-renowned British SAS was founded in the Second World War", - "by a man named David Stirling. Their role during WW2 involved gathering intelligence", - "behind enemy lines and executing sabotage strikes and assassinations against key targets.", + "The world-renowned British SAS was founded", + "in the Second World War by a man named", + "David Stirling. Their role during WW2", + "involved gathering intelligence behind enemy", + "lines and executing sabotage strikes and", + "assassinations against key targets.", "French GIGN", "gfx/vgui/640_gign", - "France's elite Counter-Terrorist unit, the GIGN, was designed to be a fast response force ", - "that could decisively react to any large-scale terrorist incident. Consisting of no more", - "than 100 men, the GIGN has earned its reputation through a history of successful ops." + "France's elite Counter-Terrorist unit was", + "designed to be a fast response force", + "that could decisively react to any large-", + "scale terrorist incident. Consisting of no", + "more than 100 men, the GIGN has earned its", + "reputation through a history of successful ops." }; void VGUI_TeamSelect_Main( vector vPos ) { @@ -70,7 +94,22 @@ void VGUI_TeamSelect_Main( vector vPos ) { fVGUI_Display = VGUI_TEAM_CT; } static void TeamSelect_Main_ButtonAuto( void ) { - fVGUI_Display = VGUI_NONE; + int iPlayersT = 0; + int iPlayersCT = 0; + + for ( int i = 0; i < 32; i++ ) { + if ( stof( getplayerkeyvalue( i, "*team" ) ) == TEAM_T ) { + iPlayersT++; + } else if ( stof( getplayerkeyvalue( i, "*team" ) ) == TEAM_CT ) { + iPlayersCT++; + } + } + + if ( iPlayersCT > iPlayersT ) { + fVGUI_Display = VGUI_TEAM_T; + } else { + fVGUI_Display = VGUI_TEAM_CT; + } } static void TeamSelect_Main_ButtonSpectate( void ) { sendevent( "GamePlayerSpawn", "f", 0 ); @@ -102,12 +141,15 @@ void VGUI_TeamSelect_Back( void ) { } void VGUI_TeamSelect_Button( float fNumber, void() vFunc, vector vPos, vector vSize ) { - if( VGUI_Button( sClassInfo[ 5 * fNumber ] , vFunc, vPos, vSize ) == TRUE ) { - drawpic( vVGUIWindowPos + '355 116', sClassInfo[ 5 * fNumber + 1 ], '128 256', '1 1 1', 1 ); + if( VGUI_Button( sClassInfo[ 8 * fNumber ] , vFunc, vPos, vSize ) == TRUE ) { + drawpic( vVGUIWindowPos + '356 64', sClassInfo[ 8 * fNumber + 1 ], '128 256', '1 1 1', 1 ); - VGUI_Text( sClassInfo[ 5 * fNumber + 2 ], vVGUIWindowPos + '16 372', '6 8 0' ); - VGUI_Text( sClassInfo[ 5 * fNumber + 3 ], vVGUIWindowPos + '16 390', '6 8 0' ); - VGUI_Text( sClassInfo[ 5 * fNumber + 4 ], vVGUIWindowPos + '16 406', '6 8 0' ); + VGUI_Text( sClassInfo[ 8 * fNumber + 2 ], vVGUIWindowPos + '232 336', '8 8 0' ); + VGUI_Text( sClassInfo[ 8 * fNumber + 3 ], vVGUIWindowPos + '232 346', '8 8 0' ); + VGUI_Text( sClassInfo[ 8 * fNumber + 4 ], vVGUIWindowPos + '232 356', '8 8 0' ); + VGUI_Text( sClassInfo[ 8 * fNumber + 5 ], vVGUIWindowPos + '232 366', '8 8 0' ); + VGUI_Text( sClassInfo[ 8 * fNumber + 6 ], vVGUIWindowPos + '232 376', '8 8 0' ); + VGUI_Text( sClassInfo[ 8 * fNumber + 7 ], vVGUIWindowPos + '232 386', '8 8 0' ); } } @@ -129,10 +171,10 @@ void VGUI_TeamSelect_T( vector vPos ) { fVGUI_Display = VGUI_NONE; } - VGUI_TeamSelect_Button( 0, TeamSelect_T1, vPos + '16 116 0', '180 24 0' ); - VGUI_TeamSelect_Button( 1, TeamSelect_T2, vPos + '16 148 0', '180 24 0' ); - VGUI_TeamSelect_Button( 2, TeamSelect_T3, vPos + '16 180 0', '180 24 0' ); - VGUI_TeamSelect_Button( 3, TeamSelect_T4, vPos + '16 212 0', '180 24 0' ); + VGUI_TeamSelect_Button( 0, TeamSelect_T1, vPos + '16 160 0', '180 24 0' ); + VGUI_TeamSelect_Button( 1, TeamSelect_T2, vPos + '16 192 0', '180 24 0' ); + VGUI_TeamSelect_Button( 2, TeamSelect_T3, vPos + '16 224 0', '180 24 0' ); + VGUI_TeamSelect_Button( 3, TeamSelect_T4, vPos + '16 256 0', '180 24 0' ); VGUI_Button( "Back", VGUI_TeamSelect_Back, vPos + '16 440 0', '120 24 0' ); } @@ -154,9 +196,9 @@ void VGUI_TeamSelect_CT ( vector vPos ) { fVGUI_Display = VGUI_NONE; } - VGUI_TeamSelect_Button( 4, TeamSelect_CT1, vPos + '16 116 0', '180 24 0' ); - VGUI_TeamSelect_Button( 5, TeamSelect_CT2, vPos + '16 148 0', '180 24 0' ); - VGUI_TeamSelect_Button( 6, TeamSelect_CT3, vPos + '16 180 0', '180 24 0' ); - VGUI_TeamSelect_Button( 7, TeamSelect_CT4, vPos + '16 212 0', '180 24 0' ); + VGUI_TeamSelect_Button( 4, TeamSelect_CT1, vPos + '16 160 0', '180 24 0' ); + VGUI_TeamSelect_Button( 5, TeamSelect_CT2, vPos + '16 192 0', '180 24 0' ); + VGUI_TeamSelect_Button( 6, TeamSelect_CT3, vPos + '16 224 0', '180 24 0' ); + VGUI_TeamSelect_Button( 7, TeamSelect_CT4, vPos + '16 256 0', '180 24 0' ); VGUI_Button( "Back", VGUI_TeamSelect_Back, vPos + '16 440 0', '120 24 0' ); } diff --git a/Source/Server/Ammo.c b/Source/Server/Ammo.c index 62424672..08b2259a 100644 --- a/Source/Server/Ammo.c +++ b/Source/Server/Ammo.c @@ -109,5 +109,4 @@ void CSEv_GamePlayerBuyAmmo_f( float fType ) { } Weapon_UpdateCurrents(); - self.fAttackFinished = time + 1.0; } diff --git a/Source/Server/ArmouryEntity.c b/Source/Server/ArmouryEntity.c index b06c5825..6bc00834 100644 --- a/Source/Server/ArmouryEntity.c +++ b/Source/Server/ArmouryEntity.c @@ -19,25 +19,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ int iArmouryItems[ 19 ] = { - WEAPON_MP5; - WEAPON_TMP; - WEAPON_P90; - WEAPON_MAC10; - WEAPON_AK47; - WEAPON_SG552; - WEAPON_M4A1; - WEAPON_AUG; - WEAPON_SCOUT; - WEAPON_G3SG1; - WEAPON_AWP; - WEAPON_M3; - WEAPON_XM1014; - WEAPON_PARA; - EQUIPMENT_FLASHBANG; - EQUIPMENT_HEGRENADE; - EQUIPMENT_KEVLAR; - EQUIPMENT_HELMET; - EQUIPMENT_SMOKEGRENADE; + WEAPON_MP5, + WEAPON_TMP, + WEAPON_P90, + WEAPON_MAC10, + WEAPON_AK47, + WEAPON_SG552, + WEAPON_M4A1, + WEAPON_AUG, + WEAPON_SCOUT, + WEAPON_G3SG1, + WEAPON_AWP, + WEAPON_M3, + WEAPON_XM1014, + WEAPON_PARA, + EQUIPMENT_FLASHBANG, + EQUIPMENT_HEGRENADE, + EQUIPMENT_KEVLAR, + EQUIPMENT_HELMET, + EQUIPMENT_SMOKEGRENADE, }; string sArmouryModels[ 19 ] = { @@ -62,9 +62,20 @@ string sArmouryModels[ 19 ] = { "models/w_smokegrenade.mdl" }; +.float item; +.float count; + +/* +================= +SPAWN: armoury_entity + +Very old entity that wasn't updated all that much +but is heavily present throughout custom maps, hence the odd item list +================= +*/ void armoury_entity( void ) { static void armoury_entity_touch( void ) { - if ( other.classname == "player" ) { + if ( other.classname != "player" ) { return; } @@ -72,11 +83,16 @@ void armoury_entity( void ) { self = other; if ( iArmouryItems[ eOld.item ] < 32 ) { - Weapon_AddItem( iArmouryItems[ eOld.item ] ); + if ( Weapon_SlotEmpty( Weapon_GetSlot( iArmouryItems[ eOld.item ] ) ) ) { + Weapon_AddItem( iArmouryItems[ eOld.item ] ); + Weapon_Draw( iArmouryItems[ eOld.item ] ); + } else { + self = eOld; + return; + } } else { - self.iEquipment = self.iEquipment | iArmouryItems[ eOld.item ]; + // Equipment } - self = eOld; self.health--; @@ -86,12 +102,16 @@ void armoury_entity( void ) { } } static void armoury_entity_respawn( void ) { - setmodel( self, sArmouryModels[ self.item ] ); - self.solid = SOLID_BBOX; + self.solid = SOLID_TRIGGER; self.health = self.count; self.touch = armoury_entity_touch; + droptofloor(); } + precache_model( sArmouryModels[ self.item ] ); + setmodel( self, sArmouryModels[ self.item ] ); + setsize( self, '-16 -16 0', '16 16 16' ); + armoury_entity_respawn(); Entities_InitRespawnable( armoury_entity_respawn ); } diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index a603c0db..140a60d6 100644 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -119,8 +119,10 @@ void Spawn_CreateClient( float fTeam ); void Spawn_MakeSpectator( void ); void Client_SendEvent( entity eClient, float fEVType ); void Client_TriggerCamera( entity eTarget, vector vPos, vector vEndPos, float fResetTime ); + void Weapon_SwitchBest( void ); void Weapon_UpdateCurrents( void ); +void Weapon_DropWeapon( int iSlot ); float Weapon_GetAnimType( float fWeapon ); float Weapon_GetFireRate( float fWeapon ); float Weapon_GetReloadTime( float fWeapon ); diff --git a/Source/Server/Main.c b/Source/Server/Main.c index 96155dc5..e861a265 100644 --- a/Source/Server/Main.c +++ b/Source/Server/Main.c @@ -86,6 +86,10 @@ void worldspawn( void ) { fclose( fileMaterial ); } + for ( int i = 1; i < CS_WEAPON_COUNT; i++ ) { + precache_model( sWeaponModels[ i ] ); + } + precache_model( sCSPlayers[1] ); precache_model( sCSPlayers[2] ); precache_model( sCSPlayers[3] ); diff --git a/Source/Server/Player.c b/Source/Server/Player.c index 682aa4ab..0cfbbca4 100644 --- a/Source/Server/Player.c +++ b/Source/Server/Player.c @@ -76,7 +76,7 @@ void Player_Death( int iHitBody ) { // Drop a corpse entity eCorpse = spawn(); - eCorpse.classname = "corpse"; + eCorpse.classname = "remove_me"; setorigin( eCorpse, self.origin ); setmodel( eCorpse, self.model ); setsize( eCorpse, self.mins, self.maxs ); diff --git a/Source/Server/Rules.c b/Source/Server/Rules.c index 20f36e7e..123782fb 100644 --- a/Source/Server/Rules.c +++ b/Source/Server/Rules.c @@ -101,8 +101,8 @@ void Rules_Restart( void ) { Money_GiveTeamReward(); } - // Clear the corpses - for ( entity eFind = world; ( eFind = find( eFind, classname, "corpse" ) ); ) { + // Clear the corpses/items + for ( entity eFind = world; ( eFind = find( eFind, classname, "remove_me" ) ); ) { remove( eFind ); } diff --git a/Source/Server/Spawn.c b/Source/Server/Spawn.c index 69628d60..7931d4e7 100644 --- a/Source/Server/Spawn.c +++ b/Source/Server/Spawn.c @@ -168,7 +168,7 @@ void Spawn_CreateClient( float fCharModel ) { Weapon_AddItem( WEAPON_KNIFE ); Weapon_AddItem( WEAPON_USP45 ); Weapon_GiveAmmo( WEAPON_USP45, 24 ); - Weapon_Draw( WEAPON_GLOCK18 ); + Weapon_Draw( WEAPON_USP45 ); } if( self.iInGame == FALSE ) { diff --git a/Source/Server/TraceAttack.c b/Source/Server/TraceAttack.c index 60a55005..4eacd1fc 100644 --- a/Source/Server/TraceAttack.c +++ b/Source/Server/TraceAttack.c @@ -67,8 +67,8 @@ void TraceAttack_FireSingle( vector vPos, vector vAngle ) { Effect_Impact( IMPACT_GLASS, trace_endpos, trace_plane_normal ); break; case 'N': - TraceAttack_Penetrate( trace_endpos + ( v_forward * 2 ), vAngle ); Effect_Impact( IMPACT_DEFAULT, trace_endpos, trace_plane_normal ); + TraceAttack_Penetrate( trace_endpos + ( v_forward * 2 ), vAngle ); break; case 'T': default: diff --git a/Source/Server/progs.src b/Source/Server/progs.src index de9b0b27..988eb88b 100644 --- a/Source/Server/progs.src +++ b/Source/Server/progs.src @@ -63,6 +63,7 @@ FuncBuyZone.c FuncButton.c FuncDoor.c FuncDoorRotating.c +ArmouryEntity.c AmbientSound.c Light.c diff --git a/Source/Shared/Weapons.c b/Source/Shared/Weapons.c index 8b3df395..5122ff82 100644 --- a/Source/Shared/Weapons.c +++ b/Source/Shared/Weapons.c @@ -20,6 +20,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void Temp_Nothing( void ) { } +#ifdef SSQC +string sWeaponModels[ CS_WEAPON_COUNT ] = { + "", + "models/w_knife.mdl", + "models/w_usp.mdl", + "models/w_glock18.mdl", + "models/w_deagle.mdl", + "models/w_p228.mdl", + "models/w_elite.mdl", + "models/w_fiveseven.mdl", + "models/w_m3.mdl", + "models/w_xm1014.mdl", + "models/w_mp5.mdl", + "models/w_p90.mdl", + "models/w_ump45.mdl", + "models/w_mac10.mdl", + "models/w_tmp.mdl", + "models/w_ak47.mdl", + "models/w_sg552.mdl", + "models/w_m4a1.mdl", + "models/w_aug.mdl", + "models/w_scout.mdl", + "models/w_awp.mdl", + "models/w_g3sg1.mdl", + "models/w_sg550.mdl", + "models/w_m249.mdl", + "models/w_c4.mdl" +}; +#endif + weaponfunc_t wpnFuncTable[ CS_WEAPON_COUNT ] = { { Temp_Nothing, Temp_Nothing, Temp_Nothing, Temp_Nothing }, { WeaponKNIFE_Draw, WeaponKNIFE_PrimaryFire, WeaponKNIFE_Secondary, Temp_Nothing }, @@ -29,13 +59,13 @@ weaponfunc_t wpnFuncTable[ CS_WEAPON_COUNT ] = { { WeaponP228_Draw, WeaponP228_PrimaryFire, Temp_Nothing, WeaponP228_Reload }, { WeaponELITES_Draw, WeaponELITES_PrimaryFire, Temp_Nothing, WeaponELITES_Reload }, { WeaponFIVESEVEN_Draw, WeaponFIVESEVEN_PrimaryFire, Temp_Nothing, WeaponFIVESEVEN_Reload }, - #ifdef SSQC +#ifdef SSQC { WeaponM3_Draw, WeaponM3_PrimaryFire, Temp_Nothing, WeaponM3_Reload }, { WeaponXM1014_Draw, WeaponXM1014_PrimaryFire, Temp_Nothing, WeaponXM1014_Reload }, - #else +#else { WeaponM3_Draw, WeaponM3_PrimaryFire, WeaponM3_Secondary, WeaponM3_Reload }, { WeaponXM1014_Draw, WeaponXM1014_PrimaryFire, WeaponXM1014_Secondary, WeaponXM1014_Reload }, - #endif +#endif { WeaponMP5_Draw, WeaponMP5_PrimaryFire, Temp_Nothing, WeaponMP5_Reload }, { WeaponP90_Draw, WeaponP90_PrimaryFire, Temp_Nothing, WeaponP90_Reload }, { WeaponUMP45_Draw, WeaponUMP45_PrimaryFire, Temp_Nothing, WeaponUMP45_Reload }, @@ -53,61 +83,181 @@ weaponfunc_t wpnFuncTable[ CS_WEAPON_COUNT ] = { { WeaponC4BOMB_Draw, WeaponC4BOMB_PrimaryFire, Temp_Nothing, Temp_Nothing } }; +/* +================= +Weapon_Draw +================= +*/ void Weapon_Draw( float fWeapon ) { if ( !fWeapon ) { return; } - wpnFuncTable[ fWeapon ].vDraw(); - - #ifdef SSQC +#ifdef SSQC // In case reloading logic is still going on self.think = Empty; self.viewzoom = 1.0; - - self.maxspeed = Player_GetMaxSpeed( fWeapon ); + self.weapon = fWeapon; self.fAttackFinished = time + 1.0; - #endif + self.maxspeed = Player_GetMaxSpeed( fWeapon ); +#endif + + wpnFuncTable[ fWeapon ].vDraw(); } +/* +================= +Weapon_PrimaryAttack +================= +*/ void Weapon_PrimaryAttack( float fWeapon ) { - #ifdef SSQC +#ifdef SSQC if ( self.fAttackFinished > time ) { return; } if ( !( self.flags & FL_SEMI_TOGGLED ) ) return; - #endif +#endif wpnFuncTable[ fWeapon ].vPrimary(); } +/* +================= +Weapon_SecondaryAttack +================= +*/ void Weapon_SecondaryAttack( float fWeapon ) { - #ifdef SSQC +#ifdef SSQC if ( self.fAttackFinished > time ) { return; } - #endif +#endif wpnFuncTable[ fWeapon ].vSecondary(); } +/* +================= +Weapon_Reload +================= +*/ void Weapon_Reload( float fWeapon ) { - #ifdef SSQC +#ifdef SSQC if ( self.fAttackFinished > time ) { return; } - #endif +#endif wpnFuncTable[ fWeapon ].vReload(); } #ifdef SSQC +/* +================= +Weapon_Release + +Called when letting go one of the weapon firing buttons +================= +*/ void Weapon_Release( void ) { self.flags = self.flags | FL_SEMI_TOGGLED; } +/* +================= +Weapon_GetSlot + +Returns which slot a weapon belongs to +================= +*/ +int Weapon_GetSlot( float fWeapon ) { + return wptTable[ fWeapon ].iSlot; +} + +/* +================= +Weapon_GetAnimType + +Returns which animationset a weapon will use on a player +================= +*/ +float Weapon_GetAnimType( float fWeapon ) { + return wptTable[ fWeapon ].fAnimType; +} + +/* +================= +Weapon_GetFireRate + +Returns the delay between shots of a given weapon +================= +*/ +float Weapon_GetFireRate( float fWeapon ) { + return wptTable[ fWeapon ].fAttackFinished; +} + +/* +================= +Weapon_GetReloadTime + +Returns the reloading delay before being able to be fired again +================= +*/ +float Weapon_GetReloadTime( float fWeapon ) { + return wptTable[ fWeapon ].fReloadFinished; +} + +/* +================= +Weapon_AlreadyExists + +Returns whether or not we have the given weapon already +================= +*/ +float Weapon_AlreadyExists( float fWeapon ) { + if ( wptTable[ fWeapon ].iSlot == SLOT_PRIMARY ) { + if ( self.fSlotPrimary == fWeapon ) { + return TRUE; + } + } else if ( wptTable[ fWeapon ].iSlot == SLOT_SECONDARY ) { + if ( self.fSlotSecondary == fWeapon ) { + return TRUE; + } + } + + return FALSE; +} + +/* +================= +Weapon_SlotEmpty + +Returns whether or not a slot is empty +================= +*/ +float Weapon_SlotEmpty( int fSlot ) { + if ( fSlot == SLOT_PRIMARY ) { + if ( self.fSlotPrimary == 0 ) { + return TRUE; + } + } else if ( fSlot == SLOT_SECONDARY ) { + if ( self.fSlotSecondary == 0 ) { + return TRUE; + } + } + + return FALSE; +} + +/* +================= +Weapon_Switch + +Switch to the weapon in a given slot +================= +*/ void Weapon_Switch( int iSlot ) { float fWeapon; @@ -125,18 +275,32 @@ void Weapon_Switch( int iSlot ) { return; } - self.weapon = fWeapon; Weapon_Draw( fWeapon ); } +/* +================= +Weapon_UpdateCurrents + +Update the ammo fields for the clientside display +================= +*/ void Weapon_UpdateCurrents( void ) { self.iCurrentMag = self.(wptTable[ self.weapon ].iMagfld); self.iCurrentCaliber = self.(wptTable[ self.weapon ].iCaliberfld); } -// We get a weapon for the first time essentially -// TODO: Drop the current slot weapon upon buying a new one +/* +================= +Weapon_AddItem + +Gives a weapon to the player +================= +*/ void Weapon_AddItem( float fWeapon ) { + if ( Weapon_SlotEmpty ( wptTable[ fWeapon ].iSlot ) == FALSE ) { + Weapon_DropWeapon( wptTable[ fWeapon ].iSlot ); + } // Add the gun to the appropriate slot if( wptTable[ fWeapon ].iSlot == SLOT_MELEE ) { @@ -149,18 +313,29 @@ void Weapon_AddItem( float fWeapon ) { self.fSlotGrenade = fWeapon; } - // Switch to it - self.weapon = fWeapon; - // Make sure we've got at least one full clip - self.(wptTable[ self.weapon ].iMagfld) = wptTable[ fWeapon ].iMagSize; + self.(wptTable[ fWeapon ].iMagfld) = wptTable[ fWeapon ].iMagSize; } +/* +================= +Weapon_GiveAmmo + +Gives a specific amount of ammo to the player +================= +*/ void Weapon_GiveAmmo( float fWeapon, float fAmount ) { - self.(wptTable[ self.weapon ].iCaliberfld ) += fAmount; + self.(wptTable[ fWeapon ].iCaliberfld ) += fAmount; Weapon_UpdateCurrents(); } +/* +================= +Weapon_SwitchBest + +Switches to the currently best suited weapon +================= +*/ void Weapon_SwitchBest( void ) { if ( self.fSlotSecondary ) { Weapon_Switch( SLOT_SECONDARY ); @@ -171,6 +346,83 @@ void Weapon_SwitchBest( void ) { } } +/* +================= +Weapon_DropWeapon + +Drop the weapon in a given slot +================= +*/ +void Weapon_DropWeapon( int iSlot ) { + static void Weapon_DropWeapon_Touch( void ) { + if ( other.classname != "player" ) { + return; + } else if ( other == self.owner ) { + return; + } + + entity eOld = self; + self = other; + + if ( Weapon_SlotEmpty( Weapon_GetSlot( eOld.weapon ) ) ) { + Weapon_AddItem( eOld.weapon ); + Weapon_Draw( eOld.weapon ); + } else { + self = eOld; + return; + } + + self = eOld; + remove( self ); + } + + static void Weapon_DropWeapon_Think( void ) { + self.owner = world; + } + + float fWeapon; + + if ( iSlot == SLOT_PRIMARY ) { + fWeapon = self.fSlotPrimary; + self.fSlotPrimary = 0; + } else if ( iSlot == SLOT_SECONDARY ) { + fWeapon = self.fSlotSecondary; + self.fSlotSecondary = 0; + } else if ( iSlot == SLOT_GRENADE ) { + fWeapon = self.fSlotGrenade; + self.fSlotGrenade = 0; + } else { + return; + } + + self.weapon = 0; + + entity eDrop = spawn(); + setorigin( eDrop, self.origin + self.view_ofs ); + setmodel( eDrop, sWeaponModels[ fWeapon ] ); + eDrop.classname = "remove_me"; + eDrop.owner = self; + eDrop.movetype = MOVETYPE_TOSS; + eDrop.solid = SOLID_TRIGGER; + eDrop.weapon = fWeapon; + eDrop.think = Weapon_DropWeapon_Think; + eDrop.touch = Weapon_DropWeapon_Touch; + eDrop.nextthink = time + 1.0f; + setsize( eDrop, '-16 -16 0', '16 16 16' ); + + makevectors( self.v_angle ); + eDrop.velocity = aim( self, 10000 ) * 256; + + Weapon_SwitchBest(); +} + +/* +================= +CSEv_PlayerBuyWeapon_f + +Client call for buying a weapon through GUI or console command +================= +*/ void CSEv_PlayerBuyWeapon_f( float fWeapon ) { if ( Rules_BuyingPossible() == FALSE ) { return; @@ -196,28 +448,30 @@ void CSEv_PlayerBuyWeapon_f( float fWeapon ) { } else { centerprint( self, "You have insufficient funds!" ); } - - self.fAttackFinished = time + 1.0; } +/* +================= +CSEv_PlayerSwitchWeapon_f + +Client-HUD call that switches to a specific weapon +================= +*/ void CSEv_PlayerSwitchWeapon_f( float fWeapon ) { if ( fWeapon != self.weapon ) { - self.weapon = fWeapon; Weapon_Draw( fWeapon ); } - - self.fAttackFinished = time + 1.0; } -float Weapon_GetAnimType( float fWeapon ) { - return wptTable[ fWeapon ].fAnimType; +/* +================= +CSEv_WeaponDrop + +Client call that tells us to drop the currently equipped weapon +================= +*/ +void CSEv_WeaponDrop( void ) { + Weapon_DropWeapon( wptTable[ self.weapon ].iSlot ); } -float Weapon_GetFireRate( float fWeapon ) { - return wptTable[ fWeapon ].fAttackFinished; -} - -float Weapon_GetReloadTime( float fWeapon ) { - return wptTable[ fWeapon ].fReloadFinished; -} #endif diff --git a/opencs/csprogs.dat b/opencs/csprogs.dat index 2a159126..28f49982 100644 Binary files a/opencs/csprogs.dat and b/opencs/csprogs.dat differ diff --git a/opencs/default.cfg b/opencs/default.cfg index 6949900d..b3016bfb 100644 --- a/opencs/default.cfg +++ b/opencs/default.cfg @@ -1,74 +1,76 @@ -bind w +forward -bind s +back -bind a +moveleft -bind d +moveright -bind "UPARROW" "+forward" -bind "DOWNARROW" "+back" -bind "LEFTARROW" "+left" -bind "RIGHTARROW" "+right" -bind MOUSE1 +attack -bind MOUSE2 +button5 -bind "MWHEELDOWN" "invnext" -bind "MWHEELUP" "invprev" -bind r +button4 -bind e +button6 -bind n nightvision -bind TAB +showscores -bind c radio3 -bind x radio2 -bind z radio1 -bind t messagemode - -bind 1 "impulse 1" -bind 2 "impulse 2" -bind 3 "impulse 3" -bind 4 "impulse 4" - -bind SPACE +jump -bind CTRL +button3 -bind SHIFT +speed - -bind b buy -bind m chooseteam -bind ESC togglemenu -bind v noclip - -// Movement Variables -seta sv_maxspeed 240 -seta cl_forwardspeed 240 -seta cl_sidespeed 240 -seta cl_backspeed 240 -seta cl_movespeedkey 0.2 -seta mp_startmoney "800" -seta mp_buytime 90 -seta mp_freezetime 6 -seta mp_c4timer 45 -seta mp_roundtime 5 -seta mp_fillweapons 0 -seta cl_bobcycle 0.8 -seta cl_bob 0.01 -seta cl_bobup 0.5 -seta r_particledesc default -seta pm_bunnyspeedcap 1 - -seta con_color 255 128 0 -seta vgui_color 255 128 0 -seta cross_color 0 255 0 - -hostname "OpenCS Server" -seta vid_conautoscale "1" -seta snd_device "sdl" - -alias +attack2 +button5 -alias -attack2 -button5 -alias +reload +button4 -alias -reload -button4 -alias +use +button6 -alias -use -button6 - -seta r_polygonoffset_submodel_offset 0 -seta r_polygonoffset_submodel_factor 0 -seta r_fullbrightSkins 0 -seta r_fb_models 0 -seta con_logcenterprint 0 -seta v_contentblend 0 +bind w +forward +bind s +back +bind a +moveleft +bind d +moveright +bind "UPARROW" "+forward" +bind "DOWNARROW" "+back" +bind "LEFTARROW" "+left" +bind "RIGHTARROW" "+right" +bind MOUSE1 +attack +bind MOUSE2 +button5 +bind "MWHEELDOWN" "invnext" +bind "MWHEELUP" "invprev" +bind r +button4 +bind e +button6 +bind n nightvision +bind g drop +bind TAB +showscores +bind c radio3 +bind x radio2 +bind z radio1 +bind t messagemode + +bind 1 "impulse 1" +bind 2 "impulse 2" +bind 3 "impulse 3" +bind 4 "impulse 4" + +bind SPACE +jump +bind CTRL +button3 +bind SHIFT +speed + +bind b buy +bind m chooseteam +bind ESC togglemenu +bind v noclip + +// Movement Variables +seta sv_maxspeed 240 +seta cl_forwardspeed 240 +seta cl_sidespeed 240 +seta cl_backspeed 240 +seta cl_movespeedkey 0.2 +seta mp_startmoney "800" +seta mp_buytime 90 +seta mp_freezetime 6 +seta mp_c4timer 45 +seta mp_roundtime 5 +seta mp_fillweapons 0 +seta cl_bobcycle 0.8 +seta cl_bob 0.01 +seta cl_bobup 0.5 +seta r_particledesc default +seta pm_bunnyspeedcap 1 + +seta con_color 255 128 0 +seta vgui_color 255 128 0 +seta cross_color 0 255 0 + +hostname "OpenCS Server" +seta vid_conautoscale "1" +seta snd_device "sdl" + +alias +attack2 +button5 +alias -attack2 -button5 +alias +reload +button4 +alias -reload -button4 +alias +use +button6 +alias -use -button6 + +seta r_polygonoffset_submodel_offset 0 +seta r_polygonoffset_submodel_factor 0 +seta r_fullbrightSkins 0 +seta r_fb_models 0 +seta con_logcenterprint 0 +seta v_contentblend 0 +seta com_nogamedirnativecode 0 diff --git a/opencs/progs.dat b/opencs/progs.dat index 173314a0..acfd3ba9 100644 Binary files a/opencs/progs.dat and b/opencs/progs.dat differ