From 6628418eef5571fd28e0092d9856fad941f825c8 Mon Sep 17 00:00:00 2001 From: NockyCZ <63038995+NockyCZ@users.noreply.github.com> Date: Sat, 28 Dec 2024 05:24:42 +0100 Subject: [PATCH] Update v1.2.3 --- source/Deathmatch/Common/Classes.cs | 7 ++ source/Deathmatch/Configs.cs | 19 ++- source/Deathmatch/Deathmatch.cs | 74 ++++++----- source/Deathmatch/Deathmatch.csproj | 2 +- source/Deathmatch/Events.cs | 158 +++++++++++++++++------- source/Deathmatch/Functions/Commands.cs | 28 +++-- source/Deathmatch/Functions/Database.cs | 8 +- source/Deathmatch/Functions/Menus.cs | 33 +++-- source/Deathmatch/Functions/Players.cs | 145 +++++++++++----------- source/Deathmatch/Functions/Spawns.cs | 86 ++++++------- source/Deathmatch/Functions/Weapons.cs | 76 +++++------- source/DeathmatchAPI/Helpers.cs | 1 + 12 files changed, 374 insertions(+), 263 deletions(-) diff --git a/source/Deathmatch/Common/Classes.cs b/source/Deathmatch/Common/Classes.cs index 9e086d3..be228ac 100644 --- a/source/Deathmatch/Common/Classes.cs +++ b/source/Deathmatch/Common/Classes.cs @@ -17,11 +17,18 @@ public class DeathmatchPlayerData public Dictionary PrimaryWeapon { get; set; } = new(); public Dictionary SecondaryWeapon { get; set; } = new(); public Dictionary Preferences { get; set; } = new(); + public Dictionary DamageInfo { get; set; } = new(); public bool SpawnProtection { get; set; } = false; public int KillStreak { get; set; } = 0; public float BlockRandomWeaponsIntegeration { get; set; } = 0; } + public class DamageData + { + public int Damage { get; set; } = 0; + public int Hits { get; set; } = 0; + } + public class RestrictData { public int CT { get; set; } diff --git a/source/Deathmatch/Configs.cs b/source/Deathmatch/Configs.cs index f464775..f785138 100644 --- a/source/Deathmatch/Configs.cs +++ b/source/Deathmatch/Configs.cs @@ -157,7 +157,6 @@ public class Gameplay [JsonPropertyName("Check Enemies Distance")] public bool CheckDistance { get; set; } = true; [JsonPropertyName("Distance From Enemies for Respawn")] public int DistanceRespawn { get; set; } = 500; [JsonPropertyName("Default Weapons")] public int DefaultModeWeapons { get; set; } = 2; - [JsonPropertyName("Include Restricted Weapons As Defaults")] public bool RemoveRestrictedWeapons { get; set; } = true; [JsonPropertyName("Switch Weapons")] public bool SwitchWeapons { get; set; } = true; [JsonPropertyName("Allow Buymenu")] public bool AllowBuyMenu { get; set; } = true; [JsonPropertyName("Use Default Spawns")] public bool DefaultSpawns { get; set; } = false; @@ -172,8 +171,9 @@ public class General [JsonPropertyName("Block Player Ping")] public bool BlockPlayerPing { get; set; } = true; [JsonPropertyName("Block Player ChatWheel")] public bool BlockPlayerChatWheel { get; set; } = true; [JsonPropertyName("Remove Breakable Entities")] public bool RemoveBreakableEntities { get; set; } = true; - [JsonPropertyName("Remove Decals After Death")] public bool RemoveDecals { get; set; } = true; + [JsonPropertyName("Remove Decals")] public bool RemoveDecals { get; set; } = true; [JsonPropertyName("Force Map End")] public bool ForceMapEnd { get; set; } = false; + [JsonPropertyName("Restart Map On Plugin Load")] public bool RestartMapOnPluginLoad { get; set; } = false; } public class CustomCommands { @@ -189,6 +189,7 @@ public class PlayersPreferences [JsonPropertyName("Hit Sound")] public HitSound HitSound { get; set; } = new HitSound(); [JsonPropertyName("Only Headshot")] public OnlyHS OnlyHS { get; set; } = new OnlyHS(); [JsonPropertyName("Hud Messages")] public HudMessages HudMessages { get; set; } = new HudMessages(); + [JsonPropertyName("Damage Info")] public DamageInfo DamageInfo { get; set; } = new DamageInfo(); } // sounds/ui/beepclear.vsnd_c @@ -197,6 +198,7 @@ public class OnlyHS [JsonPropertyName("Enabled")] public bool Enabled { get; set; } = true; [JsonPropertyName("Default value")] public bool DefaultValue { get; set; } = false; [JsonPropertyName("Only for VIP")] public bool OnlyVIP { get; set; } = false; + [JsonPropertyName("Command Shortcuts")] public List Shotcuts { get; set; } = new() { "hs", "onlyhs" }; } public class HudMessages @@ -204,6 +206,7 @@ public class HudMessages [JsonPropertyName("Enabled")] public bool Enabled { get; set; } = true; [JsonPropertyName("Default value")] public bool DefaultValue { get; set; } = true; [JsonPropertyName("Only for VIP")] public bool OnlyVIP { get; set; } = false; + [JsonPropertyName("Command Shortcuts")] public List Shotcuts { get; set; } = new() { "hud" }; } public class HitSound { @@ -218,6 +221,7 @@ public class HitSound [JsonPropertyName("Sound path")] public string Path { get; set; } = "sounds/ui/csgo_ui_contract_type2.vsnd_c"; [JsonPropertyName("Default value")] public bool DefaultValue { get; set; } = false; [JsonPropertyName("Only for VIP")] public bool OnlyVIP { get; set; } = false; + [JsonPropertyName("Command Shortcuts")] public List Shotcuts { get; set; } = new(); } public class KnifeKillSound { @@ -225,6 +229,7 @@ public class KnifeKillSound [JsonPropertyName("Sound path")] public string Path { get; set; } = "sounds/ui/armsrace_final_kill_knife.vsnd_c"; [JsonPropertyName("Default value")] public bool DefaultValue { get; set; } = false; [JsonPropertyName("Only for VIP")] public bool OnlyVIP { get; set; } = false; + [JsonPropertyName("Command Shortcuts")] public List Shotcuts { get; set; } = new(); } public class KillSound { @@ -240,6 +245,7 @@ public class KillSound [JsonPropertyName("Sound path")] public string Path { get; set; } = "sounds/ui/armsrace_kill_01.vsnd_c"; [JsonPropertyName("Default value")] public bool DefaultValue { get; set; } = false; [JsonPropertyName("Only for VIP")] public bool OnlyVIP { get; set; } = false; + [JsonPropertyName("Command Shortcuts")] public List Shotcuts { get; set; } = new(); } public class HSKillSound { @@ -247,6 +253,15 @@ public class HSKillSound [JsonPropertyName("Sound path")] public string Path { get; set; } = "sounds/buttons/bell1.vsnd_c"; [JsonPropertyName("Default value")] public bool DefaultValue { get; set; } = false; [JsonPropertyName("Only for VIP")] public bool OnlyVIP { get; set; } = false; + [JsonPropertyName("Command Shortcuts")] public List Shotcuts { get; set; } = new(); +} + +public class DamageInfo +{ + [JsonPropertyName("Enabled")] public bool Enabled { get; set; } = true; + [JsonPropertyName("Default value")] public bool DefaultValue { get; set; } = false; + [JsonPropertyName("Only for VIP")] public bool OnlyVIP { get; set; } = false; + [JsonPropertyName("Command Shortcuts")] public List Shotcuts { get; set; } = new() { "damage", "dmg" }; } public class PlayersSettings diff --git a/source/Deathmatch/Deathmatch.cs b/source/Deathmatch/Deathmatch.cs index 6e45638..71cae6a 100644 --- a/source/Deathmatch/Deathmatch.cs +++ b/source/Deathmatch/Deathmatch.cs @@ -10,7 +10,6 @@ using CounterStrikeSharp.API.Core.Capabilities; using DeathmatchAPI.Helpers; using static DeathmatchAPI.Events.IDeathmatchEventsAPI; -using System.Runtime.InteropServices; using static CounterStrikeSharp.API.Core.Listeners; namespace Deathmatch; @@ -19,7 +18,7 @@ public partial class Deathmatch : BasePlugin, IPluginConfig { public override string ModuleName => "Deathmatch Core"; public override string ModuleAuthor => "Nocky"; - public override string ModuleVersion => "1.2.2"; + public override string ModuleVersion => "1.2.3"; public void OnConfigParsed(DeathmatchConfig config) { @@ -36,6 +35,7 @@ public override void Load(bool hotReload) if (Config.SaveWeapons) _ = CreateDatabaseConnection(); + SetupDeathmatchMenus(); string[] Shortcuts = Config.CustomCommands.CustomShortcuts.Split(','); string[] WSelect = Config.CustomCommands.WeaponSelectCmds.Split(','); string[] DeathmatchMenus = Config.CustomCommands.DeatmatchMenuCmds.Split(','); @@ -51,6 +51,11 @@ public override void Load(bool hotReload) AddCustomCommands(cmd, "", 2); foreach (var cmd in DeathmatchMenus) AddCustomCommands(cmd, "", 3); + foreach (var preference in Preferences.Where(x => x.CommandShortcuts.Any())) + { + foreach (var cmd in preference.CommandShortcuts) + AddCustomCommands(cmd, preference.Name, 4, preference.vipOnly); + } foreach (string radioName in RadioMessagesList) AddCommandListener(radioName, OnPlayerRadioMessage); @@ -69,12 +74,12 @@ public override void Load(bool hotReload) if (!mapLoaded) { mapLoaded = true; + bool RoundTerminated = false; DefaultMapSpawnDisabled = false; playerData.Clear(); AddTimer(3.0f, () => { LoadCustomConfigFile(); - SetupDeathmatchMenus(); SetupCustomMode(Config.Gameplay.MapStartMode.ToString()); SetupDeathMatchConfigValues(); RemoveEntities(); @@ -92,44 +97,37 @@ public override void Load(bool hotReload) if (RemainingTime == 0) { + if (Config.General.ForceMapEnd) + { + var timelimit = Config.Gameplay.GameLength * 60; + var gameStart = GameRules().GameStartTime; + var currentTime = Server.CurrentTime; + var timeleft = timelimit - (currentTime - gameStart); + if (timeleft <= 0 && !RoundTerminated) + { + GameRules().TerminateRound(0.1f, RoundEndReason.RoundDraw); + } + } SetupCustomMode(NextMode.ToString()); } - if (!string.IsNullOrEmpty(ActiveMode.CenterMessageText) && Config.CustomModes.ContainsKey(NextMode.ToString())) + if (!string.IsNullOrEmpty(ActiveMode.CenterMessageText) && Config.CustomModes.TryGetValue(NextMode.ToString(),out var modeData)) { var time = TimeSpan.FromSeconds(RemainingTime); var formattedTime = $"{time.Minutes}:{time.Seconds:D2}";//RemainingTime > 60 ? $"{time.Minutes}:{time.Seconds:D2}" : $"{time.Seconds}"; - var NextModeData = Config.CustomModes[NextMode.ToString()]; ModeCenterMessage = ActiveMode.CenterMessageText.Replace("{REMAININGTIME}", formattedTime); - ModeCenterMessage = ModeCenterMessage.Replace("{NEXTMODE}", NextModeData.Name); + ModeCenterMessage = ModeCenterMessage.Replace("{NEXTMODE}", modeData.Name); } } }, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE); } - if (Config.General.ForceMapEnd) - { - bool RoundTerminated = false; - var timelimit = Config.Gameplay.GameLength * 60; - AddTimer(10.0f, () => - { - var gameStart = GameRules().GameStartTime; - var currentTime = Server.CurrentTime; - var timeleft = timelimit - (currentTime - gameStart); - if (timeleft <= 0 && !RoundTerminated) - { - RoundTerminated = true; - GameRules().TerminateRound(0.1f, RoundEndReason.RoundDraw); - } - - }, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE); - } } }); RegisterListener(() => { if (VisibleHud) { - foreach (var p in Utilities.GetPlayers().Where(p => playerData.ContainsPlayer(p))) + foreach (var p in Utilities.GetPlayers()) { if (ActiveEditor == p) { @@ -139,7 +137,7 @@ public override void Load(bool hotReload) } else { - if (!playerData[p].Preferences.TryGetValue("HudMessages", out var hudMessage) || !hudMessage || MenuManager.GetActiveMenu(p) != null) + if (!GetPrefsValue(p.Slot, "HudMessages") || MenuManager.GetActiveMenu(p) != null) continue; if (!string.IsNullOrEmpty(ActiveMode.CenterMessageText)) @@ -171,6 +169,25 @@ public override void Load(bool hotReload) } } }); + + if (Config.General.RemoveDecals) + { + HookUserMessage(411, um => + { + um.Recipients.Clear(); + return HookResult.Continue; + }, HookMode.Pre); + } + + if (hotReload) + { + Server.ExecuteCommand($"map {Server.MapName}"); + } + else + { + if (Config.General.RestartMapOnPluginLoad) + Server.ExecuteCommand($"map {Server.MapName}"); + } } public override void Unload(bool hotReload) @@ -189,10 +206,9 @@ public void SetupCustomMode(string modeId) ActiveCustomMode = modeId; NextMode = GetModeType(); - if (Config.CustomModes.ContainsKey(NextMode.ToString()) && !string.IsNullOrEmpty(ActiveMode.CenterMessageText)) + if (Config.CustomModes.TryGetValue(NextMode.ToString(),out var modeData) && !string.IsNullOrEmpty(ActiveMode.CenterMessageText)) { - var NextModeData = Config.CustomModes[NextMode.ToString()]; - ModeCenterMessage = ActiveMode.CenterMessageText.Replace("{NEXTMODE}", NextModeData.Name); + ModeCenterMessage = ActiveMode.CenterMessageText.Replace("{NEXTMODE}", modeData.Name); ModeCenterMessage = ModeCenterMessage.Replace("{REMAININGTIME}", RemainingTime.ToString()); } SetupDeathmatchConfiguration(ActiveMode, bNewmode); @@ -212,7 +228,7 @@ public void SetupDeathmatchConfiguration(ModeData mode, bool isNewMode) Server.ExecuteCommand($"mp_free_armor {mode.Armor};mp_damage_headshot_only {mode.OnlyHS};mp_ct_default_primary \"\";mp_t_default_primary \"\";mp_ct_default_secondary \"\";mp_t_default_secondary \"\""); - if (mode.ExecuteCommands.Count > 0) + if (mode.ExecuteCommands.Any()) { foreach (var cmd in mode.ExecuteCommands) Server.ExecuteCommand(cmd); diff --git a/source/Deathmatch/Deathmatch.csproj b/source/Deathmatch/Deathmatch.csproj index 5a5b57d..61b6023 100644 --- a/source/Deathmatch/Deathmatch.csproj +++ b/source/Deathmatch/Deathmatch.csproj @@ -7,7 +7,7 @@ - + diff --git a/source/Deathmatch/Events.cs b/source/Deathmatch/Events.cs index dd7dd67..e29064a 100644 --- a/source/Deathmatch/Events.cs +++ b/source/Deathmatch/Events.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json; using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Memory; +using CounterStrikeSharp.API.Modules.UserMessages; namespace Deathmatch { @@ -38,24 +39,25 @@ public HookResult OnPlayerConnectFull(EventPlayerConnectFull @event, GameEventIn } [GameEventHandler(HookMode.Pre)] - public HookResult OnPlayerConnectDisconnect(EventPlayerDisconnect @event, GameEventInfo info) + public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info) { var player = @event.Userid; if (player != null && player.IsValid) { - if (playerData.ContainsPlayer(player)) + if (playerData.TryGetValue(player.Slot, out var data)) { - string[] data = { - JsonConvert.SerializeObject(playerData[player].PrimaryWeapon), - JsonConvert.SerializeObject(playerData[player].SecondaryWeapon), - JsonConvert.SerializeObject(playerData[player].Preferences), - }; - - _ = UpdateOrLoadPlayerData(player, player.SteamID.ToString(), data, false); + if (Config.SaveWeapons) + { + string[] preferences = { + JsonConvert.SerializeObject(data.PrimaryWeapon), + JsonConvert.SerializeObject(data.SecondaryWeapon), + JsonConvert.SerializeObject(data.Preferences), + }; + _ = UpdateOrLoadPlayerData(player, player.SteamID.ToString(), preferences, false); + } playerData.RemovePlayer(player); } - if (blockedSpawns.ContainsKey(player.Slot)) - blockedSpawns.Remove(player.Slot); + blockedSpawns.Remove(player.Slot); } return HookResult.Continue; @@ -82,24 +84,61 @@ public HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info) if (player == null || !player.IsValid || attacker == player) return HookResult.Continue; - if (attacker != null && attacker.IsValid && playerData.ContainsPlayer(attacker)) + if (attacker != null && attacker.IsValid) { if (ActiveMode.OnlyHS) { - if (@event.Hitgroup == 1 && playerData[attacker].Preferences.TryGetValue("HitSound", out var value) & value && (!@event.Weapon.Contains("knife") || !@event.Weapon.Contains("bayonet"))) - attacker!.ExecuteClientCommand("play " + Config.PlayersPreferences.HitSound.Path); + if (@event.Hitgroup == 1 && playerData.TryGetValue(attacker.Slot, out var data)) + { + if (Config.PlayersPreferences.DamageInfo.Enabled && GetPrefsValue(attacker.Slot, "DamageInfo")) + { + if (data.DamageInfo.TryGetValue(player.Slot, out var damageInfo)) + { + damageInfo.Damage += @event.DmgHealth; + damageInfo.Hits++; + } + else + { + data.DamageInfo[player.Slot] = new DamageData + { + Damage = @event.DmgHealth, + Hits = 1 + }; + } + } + if (GetPrefsValue(attacker.Slot, "HitSound") && (!@event.Weapon.Contains("knife") || !@event.Weapon.Contains("bayonet"))) + attacker!.ExecuteClientCommand("play " + Config.PlayersPreferences.HitSound.Path); + } } else { - if (@event.Hitgroup != 1 && player.PlayerPawn.IsValid) + if (@event.Hitgroup != 1) { - if (playerData[attacker].Preferences.TryGetValue("OnlyHS", out var hsValue) & hsValue) + if ((!@event.Weapon.Contains("knife") || !@event.Weapon.Contains("bayonet")) && GetPrefsValue(attacker.Slot, "HitSound")) { - player.PlayerPawn.Value!.Health = player.PlayerPawn.Value.Health >= 100 ? 100 : player.PlayerPawn.Value.Health + @event.DmgHealth; - player.PlayerPawn.Value.ArmorValue = player.PlayerPawn.Value.ArmorValue >= 100 ? 100 : player.PlayerPawn.Value.ArmorValue + @event.DmgArmor; + if (!GetPrefsValue(attacker.Slot, "OnlyHS")) + attacker.ExecuteClientCommand("play " + Config.PlayersPreferences.HitSound.Path); + } + } + else if (GetPrefsValue(attacker.Slot, "HitSound")) + { + attacker.ExecuteClientCommand("play " + Config.PlayersPreferences.HitSound.Path); + } + if (Config.PlayersPreferences.DamageInfo.Enabled && GetPrefsValue(attacker.Slot, "DamageInfo") && playerData.TryGetValue(attacker.Slot, out var data)) + { + if (data.DamageInfo.TryGetValue(player.Slot, out var damageInfo)) + { + damageInfo.Damage += @event.DmgHealth; + damageInfo.Hits++; + } + else + { + data.DamageInfo[player.Slot] = new DamageData + { + Damage = @event.DmgHealth, + Hits = 1 + }; } - else if (playerData[attacker].Preferences.TryGetValue("HitSound", out var hitValue) & hitValue && (!@event.Weapon.Contains("knife") || !@event.Weapon.Contains("bayonet"))) - attacker!.ExecuteClientCommand("play " + Config.PlayersPreferences.HitSound.Path); } } } @@ -118,14 +157,31 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) var timer = 1.0f; bool IsVIP = AdminManager.PlayerHasPermissions(attacker, Config.PlayersSettings.VIPFlag); - if (playerData.ContainsPlayer(player)) + if (playerData.TryGetValue(player.Slot, out var data)) { - playerData[player].KillStreak = 0; - if (Config.General.RemoveDecals) + data.KillStreak = 0; + if (Config.PlayersPreferences.DamageInfo.Enabled) + { + playerData.Keys.ToList().ForEach(p => + { + playerData[p].DamageInfo.Remove(player.Slot); + }); + + if (GetPrefsValue(player.Slot, "DamageInfo") && attacker != null && attacker.IsValid) + { + if (data.DamageInfo.TryGetValue(attacker.Slot, out var damageInfo)) + player.PrintToChat(Localizer["Chat.Prefix"] + " " + Localizer["Chat.GivenDamageVictim", attacker.PlayerName, damageInfo.Damage, damageInfo.Hits]); + else + player.PrintToChat(Localizer["Chat.Prefix"] + " " + Localizer["Chat.NoDamageGiven", attacker.PlayerName]); + + data.DamageInfo.Clear(); + } + } + /*if (Config.General.RemoveDecals) { var RemoveDecals = NativeAPI.CreateEvent("round_start", false); NativeAPI.FireEventToClient(RemoveDecals, (int)player.Index); - } + }*/ timer = IsVIP ? Config.PlayersSettings.VIP.RespawnTime : Config.PlayersSettings.NonVIP.RespawnTime; @event.FireEventToClient(player); } @@ -135,25 +191,28 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) PerformRespawn(player, player.Team); }, TimerFlags.STOP_ON_MAPCHANGE); - if (attacker != null && attacker.IsValid && attacker != player && playerData.ContainsPlayer(attacker) && attacker!.PlayerPawn.Value != null) + if (attacker != null && attacker.IsValid && attacker != player && playerData.TryGetValue(attacker.Slot, out var attackerData) && attacker.PlayerPawn.Value != null) { - playerData[attacker].KillStreak++; - bool IsHeadshot = @event.Headshot; - bool IsKnifeKill = @event.Weapon.Contains("knife"); + attackerData.KillStreak++; + if (GetPrefsValue(attacker.Slot, "DamageInfo") && attackerData.DamageInfo.TryGetValue(player.Slot, out var damageInfo)) + { + attacker.PrintToChat(Localizer["Chat.Prefix"] + " " + Localizer["Chat.GivenDamageAttacker", player.PlayerName, damageInfo.Damage, damageInfo.Hits]); + attackerData.DamageInfo.Remove(player.Slot); + } - bool TryGetPreference(string key, out bool value) => - playerData[attacker].Preferences.TryGetValue(key, out value) && value; + bool IsHeadshot = @event.Headshot; + bool IsKnifeKill = @event.Weapon.Contains("knife") || @event.Weapon.Contains("bayonet"); - if (IsHeadshot && TryGetPreference("HeadshotKillSound", out var headshotValue)) + if (IsHeadshot && GetPrefsValue(attacker.Slot, "HeadshotKillSound")) attacker.ExecuteClientCommand("play " + Config.PlayersPreferences.HSKillSound.Path); - else if (IsKnifeKill && TryGetPreference("KnifeKillSound", out var knifeValue)) + else if (IsKnifeKill && GetPrefsValue(attacker.Slot, "KnifeKillSound")) attacker.ExecuteClientCommand("play " + Config.PlayersPreferences.KnifeKillSound.Path); - else if (Config.PlayersPreferences.KillSound.Enabled && TryGetPreference("KillSound", out var killValue)) + else if (GetPrefsValue(attacker.Slot, "KillSound")) attacker.ExecuteClientCommand("play " + Config.PlayersPreferences.KillSound.Path); var Health = IsHeadshot ? (IsVIP ? Config.PlayersSettings.VIP.HeadshotHealth : Config.PlayersSettings.NonVIP.HeadshotHealth) - : (IsVIP ? Config.PlayersSettings.VIP.KillHealth : Config.PlayersSettings.VIP.KillHealth); + : (IsVIP ? Config.PlayersSettings.VIP.KillHealth : Config.PlayersSettings.NonVIP.KillHealth); var refillAmmo = IsHeadshot ? (IsVIP ? Config.PlayersSettings.VIP.RefillAmmoHS : Config.PlayersSettings.NonVIP.RefillAmmoHS) @@ -214,6 +273,13 @@ public HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) return HookResult.Continue; } + [GameEventHandler] + public HookResult OnNewMatchBegin(EventBeginNewMatch @event, GameEventInfo info) + { + SetupCustomMode(Config.Gameplay.MapStartMode.ToString()); + return HookResult.Continue; + } + private HookResult OnPlayerRadioMessage(CCSPlayerController? player, CommandInfo info) { if (Config.General.BlockRadioMessage) @@ -290,26 +356,30 @@ private HookResult OnRandomWeapons(CCSPlayerController? player, CommandInfo info private HookResult OnTakeDamage(DynamicHook hook) { var damageInfo = hook.GetParam(1); - var playerPawn = hook.GetParam(0); - if (playerPawn.Controller.Value == null) + var player = hook.GetParam(0).Controller.Value?.As(); + if (player == null || !player.IsValid) return HookResult.Continue; - var player = playerPawn.Controller.Value.As(); + if (playerData.ContainsPlayer(player) && playerData[player].SpawnProtection) { damageInfo.Damage = 0; return HookResult.Continue; } + var attacker = damageInfo.Attacker.Value?.As().Controller.Value?.As(); + if (attacker == null || !attacker.IsValid) + return HookResult.Continue; + if (!ActiveMode.KnifeDamage && damageInfo.Ability.Value != null && (damageInfo.Ability.Value.DesignerName.Contains("knife") || damageInfo.Ability.Value.DesignerName.Contains("bayonet"))) { - var attackerHandle = damageInfo.Attacker; - if (attackerHandle.Value == null) - return HookResult.Continue; - - var attacker = attackerHandle.Value.As(); attacker.PrintToCenter(Localizer["Hud.KnifeDamageIsDisabled"]); damageInfo.Damage = 0; + return HookResult.Continue; } + + if (Config.PlayersPreferences.OnlyHS.Enabled && damageInfo.GetHitGroup() != HitGroup_t.HITGROUP_HEAD && GetPrefsValue(attacker.Slot, "OnlyHS")) + damageInfo.Damage = 0; + return HookResult.Continue; } @@ -374,8 +444,8 @@ private HookResult OnWeaponCanAcquire(DynamicHook hook) if (!string.IsNullOrEmpty(Config.SoundSettings.CantEquipSound)) player.ExecuteClientCommand("play " + Config.SoundSettings.CantEquipSound); - var restrictInfo = GetRestrictData(vdata.Name, player.Team); - player.PrintToChat($"{Localizer["Chat.Prefix"]} {Localizer["Chat.WeaponIsRestricted", localizerWeaponName, restrictInfo.Item1, restrictInfo.Item2]}"); + (int NonVIP, int VIP) restrictInfo = GetRestrictData(vdata.Name, player.Team); + player.PrintToChat($"{Localizer["Chat.Prefix"]} {Localizer["Chat.WeaponIsRestricted", localizerWeaponName, GetWeaponRestrictLozalizer(restrictInfo.NonVIP), GetWeaponRestrictLozalizer(restrictInfo.VIP)]}"); hook.SetReturn(AcquireResult.NotAllowedByMode); return HookResult.Stop; } diff --git a/source/Deathmatch/Functions/Commands.cs b/source/Deathmatch/Functions/Commands.cs index 21ec6d6..db53925 100644 --- a/source/Deathmatch/Functions/Commands.cs +++ b/source/Deathmatch/Functions/Commands.cs @@ -12,7 +12,7 @@ namespace Deathmatch { public partial class Deathmatch { - private void AddCustomCommands(string command, string weapon_name, int type) + private void AddCustomCommands(string command, string weapon_name, int type, bool onlyVIP = false) { string cmdName = $"css_{command}"; switch (type) @@ -20,7 +20,7 @@ private void AddCustomCommands(string command, string weapon_name, int type) case 1: AddCommand(cmdName, $"Weapon Shortcut: {weapon_name}", (player, info) => { - if (player != null && player.IsValid && !playerData.ContainsPlayer(player)) + if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) return; if (ActiveMode.RandomWeapons) @@ -34,8 +34,9 @@ private void AddCustomCommands(string command, string weapon_name, int type) case 2: AddCommand(cmdName, "Select a weapon by command", (player, info) => { - if (player != null && player.IsValid && !playerData.ContainsPlayer(player)) + if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) return; + if (ActiveMode.RandomWeapons) { info.ReplyToCommand($"{Localizer["Chat.Prefix"]} {Localizer["Chat.WeaponsSelectIsDisabled"]}"); @@ -49,18 +50,18 @@ private void AddCustomCommands(string command, string weapon_name, int type) case 3: AddCommand(cmdName, "Opens a Deathmatch menu", (player, info) => { - if (player != null && player.IsValid && !playerData.ContainsPlayer(player)) + if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) return; - if (Preferences.Count == 0) + if (!Preferences.Any()) return; - if (Preferences.Where(x => x.Category == CategoryType.SOUNDS).Count() > 0 && Preferences.Where(x => x.Category == CategoryType.FUNCTIONS).Count() == 0) + if (Preferences.Where(x => x.Category == CategoryType.SOUNDS).Any() && Preferences.Where(x => x.Category == CategoryType.FUNCTIONS).Count() == 0) { OpenSubMenu(player!, CategoryType.SOUNDS, true); return; } - if (Preferences.Where(x => x.Category == CategoryType.FUNCTIONS).Count() > 0 && Preferences.Where(x => x.Category == CategoryType.SOUNDS).Count() == 0) + if (Preferences.Where(x => x.Category == CategoryType.FUNCTIONS).Any() && Preferences.Where(x => x.Category == CategoryType.SOUNDS).Count() == 0) { OpenSubMenu(player!, CategoryType.FUNCTIONS, true); return; @@ -69,6 +70,19 @@ private void AddCustomCommands(string command, string weapon_name, int type) }); break; + + case 4: + AddCommand(cmdName, "Switch Player Preferences", (player, info) => + { + if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) + return; + + if (onlyVIP && !AdminManager.PlayerHasPermissions(player, Config.PlayersSettings.VIPFlag)) + return; + + SwitchPrefsValue(player, weapon_name); + }); + break; } } diff --git a/source/Deathmatch/Functions/Database.cs b/source/Deathmatch/Functions/Database.cs index 7db886f..9b143c9 100644 --- a/source/Deathmatch/Functions/Database.cs +++ b/source/Deathmatch/Functions/Database.cs @@ -87,7 +87,7 @@ ON DUPLICATE KEY UPDATE Server.NextFrame(() => { - if (playerData.ContainsPlayer(player)) + if (playerData.TryGetValue(player.Slot, out var data)) { if (primaryWeapons == null || secondaryWeapons == null) { @@ -95,8 +95,8 @@ ON DUPLICATE KEY UPDATE } else { - playerData[player].PrimaryWeapon = primaryWeapons; - playerData[player].SecondaryWeapon = secondaryWeapons; + data.PrimaryWeapon = primaryWeapons; + data.SecondaryWeapon = secondaryWeapons; SetupDefaultWeapons(player); } @@ -106,7 +106,7 @@ ON DUPLICATE KEY UPDATE } else { - playerData[player].Preferences = preferences; + data.Preferences = preferences; SetupDefaultPreferences(player); } } diff --git a/source/Deathmatch/Functions/Menus.cs b/source/Deathmatch/Functions/Menus.cs index fe2b8c7..cdfb11e 100644 --- a/source/Deathmatch/Functions/Menus.cs +++ b/source/Deathmatch/Functions/Menus.cs @@ -31,7 +31,7 @@ public void OpenSubMenu(CCSPlayerController player, CategoryType menuType, bool foreach (var option in Preferences.Where(x => x.Category == menuType)) { - Value = GetPrefsValue(player, option.Name) ? "ON" : "OFF"; + Value = GetPrefsValue(player.Slot, option.Name) ? "ON" : "OFF"; if (option.vipOnly) { if (IsVIP) @@ -66,7 +66,6 @@ public void OnSelectBack(CCSPlayerController player, ChatMenuOption option) private void SetupDeathmatchMenus() { Preferences.Clear(); - if (Config.PlayersPreferences.KillSound.Enabled) { var data = new PreferencesData() @@ -74,7 +73,8 @@ private void SetupDeathmatchMenus() Name = "KillSound", Category = CategoryType.SOUNDS, defaultValue = Config.PlayersPreferences.KillSound.DefaultValue, - vipOnly = Config.PlayersPreferences.KillSound.OnlyVIP + vipOnly = Config.PlayersPreferences.KillSound.OnlyVIP, + CommandShortcuts = Config.PlayersPreferences.KillSound.Shotcuts }; Preferences.Add(data); } @@ -86,7 +86,8 @@ private void SetupDeathmatchMenus() Name = "HeadshotKillSound", Category = CategoryType.SOUNDS, defaultValue = Config.PlayersPreferences.HSKillSound.DefaultValue, - vipOnly = Config.PlayersPreferences.HSKillSound.OnlyVIP + vipOnly = Config.PlayersPreferences.HSKillSound.OnlyVIP, + CommandShortcuts = Config.PlayersPreferences.HSKillSound.Shotcuts }; Preferences.Add(data); } @@ -98,7 +99,8 @@ private void SetupDeathmatchMenus() Name = "KnifeKillSound", Category = CategoryType.SOUNDS, defaultValue = Config.PlayersPreferences.KnifeKillSound.DefaultValue, - vipOnly = Config.PlayersPreferences.KnifeKillSound.OnlyVIP + vipOnly = Config.PlayersPreferences.KnifeKillSound.OnlyVIP, + CommandShortcuts = Config.PlayersPreferences.KnifeKillSound.Shotcuts }; Preferences.Add(data); } @@ -109,7 +111,8 @@ private void SetupDeathmatchMenus() Name = "HitSound", Category = CategoryType.SOUNDS, defaultValue = Config.PlayersPreferences.HitSound.DefaultValue, - vipOnly = Config.PlayersPreferences.HitSound.OnlyVIP + vipOnly = Config.PlayersPreferences.HitSound.OnlyVIP, + CommandShortcuts = Config.PlayersPreferences.HitSound.Shotcuts }; Preferences.Add(data); } @@ -121,7 +124,8 @@ private void SetupDeathmatchMenus() Name = "OnlyHS", Category = CategoryType.FUNCTIONS, defaultValue = Config.PlayersPreferences.OnlyHS.DefaultValue, - vipOnly = Config.PlayersPreferences.OnlyHS.OnlyVIP + vipOnly = Config.PlayersPreferences.OnlyHS.OnlyVIP, + CommandShortcuts = Config.PlayersPreferences.OnlyHS.Shotcuts }; Preferences.Add(data); } @@ -132,7 +136,20 @@ private void SetupDeathmatchMenus() Name = "HudMessages", Category = CategoryType.FUNCTIONS, defaultValue = Config.PlayersPreferences.HudMessages.DefaultValue, - vipOnly = Config.PlayersPreferences.HudMessages.OnlyVIP + vipOnly = Config.PlayersPreferences.HudMessages.OnlyVIP, + CommandShortcuts = Config.PlayersPreferences.HudMessages.Shotcuts + }; + Preferences.Add(data); + } + if (Config.PlayersPreferences.DamageInfo.Enabled) + { + var data = new PreferencesData() + { + Name = "DamageInfo", + Category = CategoryType.FUNCTIONS, + defaultValue = Config.PlayersPreferences.DamageInfo.DefaultValue, + vipOnly = Config.PlayersPreferences.DamageInfo.OnlyVIP, + CommandShortcuts = Config.PlayersPreferences.DamageInfo.Shotcuts }; Preferences.Add(data); } diff --git a/source/Deathmatch/Functions/Players.cs b/source/Deathmatch/Functions/Players.cs index a96a04d..07df269 100644 --- a/source/Deathmatch/Functions/Players.cs +++ b/source/Deathmatch/Functions/Players.cs @@ -15,7 +15,7 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co { string primaryWeapons = ""; string secondaryWeapons = ""; - if (ActiveMode.PrimaryWeapons.Count != 0) + if (ActiveMode.PrimaryWeapons.Any()) { foreach (string weapon in ActiveMode.PrimaryWeapons) { @@ -27,7 +27,7 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co info.ReplyToCommand($"{Localizer["Chat.ListOfAllowedWeapons"]}"); info.ReplyToCommand($"{ChatColors.DarkRed}• {primaryWeapons.ToUpper()}"); } - if (ActiveMode.SecondaryWeapons.Count != 0) + if (ActiveMode.SecondaryWeapons.Any()) { foreach (string weapon in ActiveMode.SecondaryWeapons) { @@ -46,9 +46,9 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co string replacedweaponName = ""; string matchingValues = ""; int matchingCount = 0; - if (weaponSelectMapping.ContainsKey(weaponName)) + if (weaponSelectMapping.TryGetValue(weaponName, out var name)) { - weaponName = weaponSelectMapping[weaponName]; + weaponName = name; matchingCount = 1; } else @@ -107,8 +107,8 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co if (!string.IsNullOrEmpty(Config.SoundSettings.CantEquipSound)) player.ExecuteClientCommand("play " + Config.SoundSettings.CantEquipSound); - var restrictInfo = GetRestrictData(weaponName, player.Team); - info.ReplyToCommand($"{Localizer["Chat.Prefix"]} {Localizer["Chat.WeaponIsRestricted", localizerWeaponName, restrictInfo.Item1, restrictInfo.Item2]}"); + (int NonVIP, int VIP) restrictInfo = GetRestrictData(weaponName, player.Team); + info.ReplyToCommand($"{Localizer["Chat.Prefix"]} {Localizer["Chat.WeaponIsRestricted", localizerWeaponName, GetWeaponRestrictLozalizer(restrictInfo.NonVIP), GetWeaponRestrictLozalizer(restrictInfo.VIP)]}"); return; } @@ -155,8 +155,8 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co if (!string.IsNullOrEmpty(Config.SoundSettings.CantEquipSound)) player.ExecuteClientCommand("play " + Config.SoundSettings.CantEquipSound); - var restrictInfo = GetRestrictData(weaponName, player.Team); - info.ReplyToCommand($"{Localizer["Chat.Prefix"]} {Localizer["Chat.WeaponIsRestricted", localizerWeaponName, restrictInfo.Item1, restrictInfo.Item2]}"); + (int NonVIP, int VIP) restrictInfo = GetRestrictData(weaponName, player.Team); + info.ReplyToCommand($"{Localizer["Chat.Prefix"]} {Localizer["Chat.WeaponIsRestricted", localizerWeaponName, GetWeaponRestrictLozalizer(restrictInfo.NonVIP), GetWeaponRestrictLozalizer(restrictInfo.VIP)]}"); return; } @@ -200,7 +200,7 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool giveUtilities = true, bool giveKnife = false) { - if (playerData.ContainsPlayer(player) && player.PlayerPawn.Value != null) + if (playerData.TryGetValue(player.Slot, out var data) && player.PlayerPawn.Value != null) { if (player.InGameMoneyServices != null && giveUtilities) player.InGameMoneyServices.Account = Config.Gameplay.AllowBuyMenu ? 16000 : 0; @@ -217,12 +217,12 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi player.PlayerPawn.Value.Render = transparentColor; Utilities.SetStateChanged(player.PlayerPawn.Value, "CBaseModelEntity", "m_clrRender"); } - playerData[player].SpawnProtection = true; + data.SpawnProtection = true; AddTimer(timer, () => { - if (player != null && player.IsValid && playerData.ContainsPlayer(player)) + if (player != null && player.IsValid && playerData.TryGetValue(player.Slot, out data)) { - playerData[player].SpawnProtection = false; + data.SpawnProtection = false; if (string.IsNullOrEmpty(Config.Gameplay.SpawnProtectionColor)) { player.PlayerPawn.Value.Render = Color.White; @@ -234,11 +234,11 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi if (!IsCasualGamemode) { - playerData[player].BlockRandomWeaponsIntegeration = Server.CurrentTime; + data.BlockRandomWeaponsIntegeration = Server.CurrentTime; } } - if (ActiveMode.PrimaryWeapons.Count != 0) + if (ActiveMode.PrimaryWeapons.Any()) { if (ActiveMode.RandomWeapons) { @@ -246,13 +246,13 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi if (!string.IsNullOrEmpty(weapon)) player.GiveNamedItem(weapon); } - else if (playerData[player].PrimaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && !string.IsNullOrEmpty(weapon)) + else if (data.PrimaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && !string.IsNullOrEmpty(weapon)) { player.GiveNamedItem(weapon); } } - if (ActiveMode.SecondaryWeapons.Count != 0) + if (ActiveMode.SecondaryWeapons.Any()) { if (ActiveMode.RandomWeapons) { @@ -260,7 +260,7 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi if (!string.IsNullOrEmpty(weapon)) player.GiveNamedItem(weapon); } - else if (playerData[player].SecondaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && !string.IsNullOrEmpty(weapon)) + else if (data.SecondaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && !string.IsNullOrEmpty(weapon)) { player.GiveNamedItem(weapon); } @@ -269,7 +269,7 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi if (giveKnife) player.GiveNamedItem("weapon_knife"); - if (giveUtilities && ActiveMode.Utilities.Count > 0) + if (giveUtilities && ActiveMode.Utilities.Any()) { foreach (var item in ActiveMode.Utilities) player.GiveNamedItem(item); @@ -284,7 +284,7 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi if (player.InGameMoneyServices != null) player.InGameMoneyServices.Account = 0; - if (ActiveMode.PrimaryWeapons.Count != 0) + if (ActiveMode.PrimaryWeapons.Any()) { if (!IsHaveWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_RIFLE)) { @@ -302,7 +302,7 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi player.GiveNamedItem(PrimaryWeapon); } } - if (ActiveMode.SecondaryWeapons.Count != 0) + if (ActiveMode.SecondaryWeapons.Any()) { if (!IsHaveWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_PISTOL)) { @@ -351,63 +351,66 @@ public void SetupDefaultWeapons(CCSPlayerController player) if (playerData[player].PrimaryWeapon.ContainsKey(mode.Key)) continue; - if (Config.Gameplay.DefaultModeWeapons == 1) + switch (Config.Gameplay.DefaultModeWeapons) { - if (mode.Value.PrimaryWeapons.Count > 0) - { - var primary = mode.Value.PrimaryWeapons.Where(w => !Config.RestrictedWeapons.Restrictions.ContainsKey(w)).FirstOrDefault(); - playerData[player].PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; - } - else - playerData[player].PrimaryWeapon[mode.Key] = ""; - if (mode.Value.SecondaryWeapons.Count > 0) - { - var secondary = mode.Value.SecondaryWeapons.Where(w => !Config.RestrictedWeapons.Restrictions.ContainsKey(w)).FirstOrDefault(); - playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; - } - else - playerData[player].SecondaryWeapon[mode.Key] = ""; - } - else if (Config.Gameplay.DefaultModeWeapons == 2) - { - if (mode.Value.PrimaryWeapons.Count > 0) - { - var primary = GetRandomWeaponFromList(mode.Value.PrimaryWeapons, mode.Value, IsVIP, player.Team, true); - playerData[player].PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; - } - else - playerData[player].PrimaryWeapon[mode.Key] = ""; - if (mode.Value.SecondaryWeapons.Count > 0) - { - var secondary = GetRandomWeaponFromList(mode.Value.SecondaryWeapons, mode.Value, IsVIP, player.Team, true); - playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; - } - else - playerData[player].SecondaryWeapon[mode.Key] = ""; - } - else - { - if (mode.Value.PrimaryWeapons.Count > 0) - { - var primary = mode.Value.PrimaryWeapons.FirstOrDefault(); - playerData[player].PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; - } - else - playerData[player].PrimaryWeapon[mode.Key] = ""; - if (mode.Value.SecondaryWeapons.Count > 0) - { - var secondary = mode.Value.SecondaryWeapons.FirstOrDefault(); - playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; - } - else - playerData[player].SecondaryWeapon[mode.Key] = ""; + case 1: + if (mode.Value.PrimaryWeapons.Any()) + { + var primary = mode.Value.PrimaryWeapons.Where(w => !Config.RestrictedWeapons.Restrictions.ContainsKey(w)).FirstOrDefault(); + playerData[player].PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; + } + else + playerData[player].PrimaryWeapon[mode.Key] = ""; + if (mode.Value.SecondaryWeapons.Any()) + { + var secondary = mode.Value.SecondaryWeapons.Where(w => !Config.RestrictedWeapons.Restrictions.ContainsKey(w)).FirstOrDefault(); + playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; + } + else + playerData[player].SecondaryWeapon[mode.Key] = ""; + break; + case 2 or 3: + if (mode.Value.PrimaryWeapons.Any()) + { + var primary = GetRandomWeaponFromList(mode.Value.PrimaryWeapons, mode.Value, IsVIP, player.Team, true); + playerData[player].PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; + } + else + playerData[player].PrimaryWeapon[mode.Key] = ""; + if (mode.Value.SecondaryWeapons.Any()) + { + var secondary = GetRandomWeaponFromList(mode.Value.SecondaryWeapons, mode.Value, IsVIP, player.Team, true); + playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; + } + else + playerData[player].SecondaryWeapon[mode.Key] = ""; + break; + default: + if (mode.Value.PrimaryWeapons.Any()) + { + var primary = mode.Value.PrimaryWeapons.FirstOrDefault(); + playerData[player].PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; + } + else + playerData[player].PrimaryWeapon[mode.Key] = ""; + if (mode.Value.SecondaryWeapons.Any()) + { + var secondary = mode.Value.SecondaryWeapons.FirstOrDefault(); + playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; + } + else + playerData[player].SecondaryWeapon[mode.Key] = ""; + break; } } } - private static bool GetPrefsValue(CCSPlayerController player, string preference) + public static bool GetPrefsValue(int slot, string preference) { - return playerData[player].Preferences[preference]; + if (playerData.TryGetValue(slot, out var data) && data.Preferences.TryGetValue(preference, out var value)) + return value; + + return false; } private void SwitchPrefsValue(CCSPlayerController player, string preference) diff --git a/source/Deathmatch/Functions/Spawns.cs b/source/Deathmatch/Functions/Spawns.cs index 401e2cd..e9d3a11 100644 --- a/source/Deathmatch/Functions/Spawns.cs +++ b/source/Deathmatch/Functions/Spawns.cs @@ -6,7 +6,6 @@ using Newtonsoft.Json.Linq; using CounterStrikeSharp.API.Modules.Utils; using System.Globalization; -using System.Security.Cryptography.X509Certificates; namespace Deathmatch { @@ -14,47 +13,37 @@ public partial class Deathmatch { public void PerformRespawn(CCSPlayerController player, CsTeam team) { - if (player.PlayerPawn.Value == null || team == CsTeam.None || team == CsTeam.Spectator) + if (team == CsTeam.None || team == CsTeam.Spectator) return; - var spawnsDictionary = team == CsTeam.Terrorist ? spawnPositionsT : spawnPositionsCT; - var availableSpawns = new List>(); + var spawnsDictionary = team == CsTeam.Terrorist ? new Dictionary(spawnPositionsT) : new Dictionary(spawnPositionsCT); + if (blockedSpawns.TryGetValue(player.Slot, out var lastSpawn)) + spawnsDictionary.Remove(lastSpawn); - if (blockedSpawns.ContainsKey(player.Slot)) - { - var lastSpawn = blockedSpawns[player.Slot]; - availableSpawns = spawnsDictionary - .Where(spawn => spawn.Key != lastSpawn) - .ToList(); - } - else - { - availableSpawns = new List>(spawnsDictionary); - } - - if (availableSpawns.Count == 0) + if (!spawnsDictionary.Any()) { player.Respawn(); SendConsoleMessage("[Deathmatch] Spawns list is empty, you got something wrong!", ConsoleColor.Red); return; } - var selectedSpawn = new KeyValuePair(); + (Vector position, QAngle angle) selectedSpawn; if (GameRules().WarmupPeriod || !Config.Gameplay.CheckDistance) { - selectedSpawn = availableSpawns[Random.Next(availableSpawns.Count)]; + var randomSpawn = spawnsDictionary.ElementAt(Random.Next(spawnsDictionary.Count)); + selectedSpawn = (randomSpawn.Key, randomSpawn.Value); } else { - selectedSpawn = GetAvailableSpawn(player, availableSpawns); + selectedSpawn = GetAvailableSpawn(player, new List>(spawnsDictionary)); } - blockedSpawns[player.Slot] = selectedSpawn.Key; + blockedSpawns[player.Slot] = selectedSpawn.position; player.Respawn(); - player.PlayerPawn.Value.Teleport(selectedSpawn.Key, selectedSpawn.Value, new Vector()); + player.Pawn.Value?.Teleport(selectedSpawn.position, selectedSpawn.angle, new Vector()); } - public KeyValuePair GetAvailableSpawn(CCSPlayerController player, List> spawnsList) + public (Vector, QAngle) GetAvailableSpawn(CCSPlayerController player, List> spawnsList) { var allPlayers = Utilities.GetPlayers(); var playerPositions = allPlayers @@ -62,36 +51,36 @@ public KeyValuePair GetAvailableSpawn(CCSPlayerController player .Select(p => p.PlayerPawn.Value!.AbsOrigin) .ToList(); - var spawnDistances = new Dictionary(); + var availableSpawns = new Dictionary(); foreach (var spawn in spawnsList) { - double minDistance = double.MaxValue; + double minDistance = 10000; foreach (var playerPos in playerPositions) { - if (playerPos != null) + if (playerPos == null) + continue; + + double distance = GetDistance(playerPos, spawn.Key); + if (distance < minDistance) { - double distance = GetDistance(playerPos, spawn.Key); - if (distance < minDistance) - { - minDistance = distance; - } + minDistance = distance; } } - spawnDistances[spawn.Key] = minDistance; + if (minDistance > CheckedEnemiesDistance) + availableSpawns[spawn.Key] = spawn.Value; } - var availableSpawns = spawnDistances - .Where(spawn => spawn.Value > CheckedEnemiesDistance) - .Select(spawn => spawnsList.First(x => x.Key == spawn.Key)) - .ToList(); - - if (availableSpawns.Count > 0) + if (availableSpawns.Any()) { - return availableSpawns[Random.Next(availableSpawns.Count)]; + var spawn = availableSpawns.ElementAt(Random.Next(availableSpawns.Count)); + return (spawn.Key, spawn.Value); + } + else + { + SendConsoleMessage($"[Deathmatch] Player {player.PlayerName} was respawned, but no available spawn point was found!", ConsoleColor.DarkYellow); + var spawn = spawnsList.ElementAt(Random.Next(spawnsList.Count)); + return (spawn.Key, spawn.Value); } - - SendConsoleMessage($"[Deathmatch] Player {player.PlayerName} was respawned, but no available spawn point was found!", ConsoleColor.DarkYellow); - return spawnsList.ElementAt(Random.Next(spawnsList.Count)); } public void SaveSpawnsFile() @@ -149,12 +138,10 @@ public void AddNewSpawnPoint(Vector posValue, QAngle angleValue, CsTeam team) switch (team) { case CsTeam.Terrorist: - if (!spawnPositionsT.ContainsKey(newPosition)) - spawnPositionsT.Add(newPosition, newAngle); + spawnPositionsT[newPosition] = newAngle; break; case CsTeam.CounterTerrorist: - if (!spawnPositionsCT.ContainsKey(newPosition)) - spawnPositionsCT.Add(newPosition, newAngle); + spawnPositionsCT[newPosition] = newAngle; break; } @@ -191,11 +178,8 @@ public void RemoveNearestSpawnPoint(Vector? playerPos) if (nearestSpawn == null) return; - if (spawnPositionsCT.ContainsKey(nearestSpawn)) - spawnPositionsCT.Remove(nearestSpawn); - - if (spawnPositionsT.ContainsKey(nearestSpawn)) - spawnPositionsT.Remove(nearestSpawn); + spawnPositionsCT.Remove(nearestSpawn); + spawnPositionsT.Remove(nearestSpawn); RemoveSpawnModels(); ShowAllSpawnPoints(); diff --git a/source/Deathmatch/Functions/Weapons.cs b/source/Deathmatch/Functions/Weapons.cs index 17dbb1a..3a0cdcd 100644 --- a/source/Deathmatch/Functions/Weapons.cs +++ b/source/Deathmatch/Functions/Weapons.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.Eventing.Reader; using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; @@ -27,8 +28,10 @@ public bool CheckIsWeaponRestricted(string weaponName, bool isVIP, CsTeam team, if (restrictValue < 0) return true; - var playersList = Config.RestrictedWeapons.Global ? players : players.Where(p => p.Team == team).ToList(); - int matchingCount = playersList.Count(p => (bPrimary && playerData[p].PrimaryWeapon.TryGetValue(ActiveCustomMode, out var primary) && primary == weaponName) || (!bPrimary && playerData[p].SecondaryWeapon.TryGetValue(ActiveCustomMode, out var secondary) && secondary == weaponName)); + var playersList = Config.RestrictedWeapons.Global ? players : players.Where(p => p.Team == team); + int matchingCount = playersList.Count(p => bPrimary + ? playerData[p].PrimaryWeapon.TryGetValue(ActiveCustomMode, out var primary) && primary == weaponName + : playerData[p].SecondaryWeapon.TryGetValue(ActiveCustomMode, out var secondary) && secondary == weaponName); return matchingCount >= restrictValue; } @@ -55,42 +58,13 @@ public bool IsHaveWeaponFromSlot(CCSPlayerController player, gear_slot_t slot) .Any(weaponBase => weaponBase != null && weaponBase.VData != null && weaponBase.VData.GearSlot == slot); } - public void RemovePlayerWeapon(CCSPlayerController player, string weaponName) - { - var pawn = player.PlayerPawn?.Value; - if (pawn == null || pawn.WeaponServices == null || !player.PawnIsAlive) - return; - - var replacements = new Dictionary - { - { "weapon_m4a1_silencer", "weapon_m4a1" }, - { "weapon_usp_silencer", "weapon_hkp2000" }, - { "weapon_mp5sd", "weapon_mp7" } - }; - - if (replacements.TryGetValue(weaponName, out var replacement)) - { - weaponName = replacement; - } - - var weapon = pawn.WeaponServices.MyWeapons - .Select(weapon => weapon.Value?.As()) - .FirstOrDefault(weaponBase => weaponBase != null && weaponBase.DesignerName.Contains(weaponName)); - - if (weapon != null) - weapon.Remove(); - } - private string GetRandomWeaponFromList(List weaponsList, ModeData modeData, bool isVIP, CsTeam team, bool bPrimary) { - if (weaponsList.Count > 0) + if (weaponsList.Any()) { - if (!modeData.RandomWeapons && Config.Gameplay.RemoveRestrictedWeapons) + if (!modeData.RandomWeapons && (Config.Gameplay.DefaultModeWeapons != 1 || Config.Gameplay.DefaultModeWeapons != 2)) weaponsList.RemoveAll(weapon => CheckIsWeaponRestricted(weapon, isVIP, team, bPrimary)); - //if (weaponsList.Count == 1) - // return weaponsList[0]; - int index = Random.Next(weaponsList.Count); return weaponsList[index]; } @@ -99,29 +73,39 @@ private string GetRandomWeaponFromList(List weaponsList, ModeData modeDa public int GetWeaponRestrict(string weaponName, bool isVIP, CsTeam team) { - if (!Config.RestrictedWeapons.Restrictions.ContainsKey(weaponName) || !Config.RestrictedWeapons.Restrictions[weaponName].ContainsKey(ActiveCustomMode)) + if (!Config.RestrictedWeapons.Restrictions.TryGetValue(weaponName, out var weaponRestrictions) || !weaponRestrictions.TryGetValue(ActiveCustomMode, out var restrictTypes)) return 0; - var restrictInfo = Config.RestrictedWeapons.Restrictions[weaponName][ActiveCustomMode][isVIP ? RestrictType.VIP : RestrictType.NonVIP]; + var restrictInfo = restrictTypes[isVIP ? RestrictType.VIP : RestrictType.NonVIP]; return Config.RestrictedWeapons.Global ? restrictInfo.Global : (team == CsTeam.CounterTerrorist ? restrictInfo.CT : restrictInfo.T); } - public (int, int) GetRestrictData(string weaponName, CsTeam team) + public (int NonVIP, int VIP) GetRestrictData(string weaponName, CsTeam team) { - if (!Config.RestrictedWeapons.Restrictions.ContainsKey(weaponName)) - return (0, 0); - if (!Config.RestrictedWeapons.Restrictions[weaponName].ContainsKey(ActiveCustomMode)) + if (!Config.RestrictedWeapons.Restrictions.TryGetValue(weaponName, out var weaponRestrictions) || !weaponRestrictions.TryGetValue(ActiveCustomMode, out var restrictTypes)) return (0, 0); - var restrictDataVIP = Config.RestrictedWeapons.Restrictions[weaponName][ActiveCustomMode][RestrictType.VIP]; - var restrictDataNonVIP = Config.RestrictedWeapons.Restrictions[weaponName][ActiveCustomMode][RestrictType.NonVIP]; + var restrictDataNonVIP = restrictTypes[RestrictType.NonVIP]; + var restrictDataVIP = restrictTypes[RestrictType.VIP]; - if (Config.RestrictedWeapons.Global) - return (restrictDataNonVIP.Global, restrictDataVIP.Global); + return Config.RestrictedWeapons.Global + ? (restrictDataNonVIP.Global, restrictDataVIP.Global) + : team == CsTeam.CounterTerrorist + ? (restrictDataNonVIP.CT, restrictDataVIP.CT) + : (restrictDataNonVIP.T, restrictDataVIP.T); + } - return team == CsTeam.CounterTerrorist - ? (restrictDataNonVIP.CT, restrictDataVIP.CT) - : (restrictDataNonVIP.T, restrictDataVIP.T); + public string GetWeaponRestrictLozalizer(int bullets) + { + switch (bullets) + { + case -1: + return Localizer["Chat.Disabled"]; + case 0: + return Localizer["Chat.Unlimited"]; + default: + return bullets.ToString(); + } } } } \ No newline at end of file diff --git a/source/DeathmatchAPI/Helpers.cs b/source/DeathmatchAPI/Helpers.cs index 82fb0ad..7cb553a 100644 --- a/source/DeathmatchAPI/Helpers.cs +++ b/source/DeathmatchAPI/Helpers.cs @@ -27,4 +27,5 @@ public class PreferencesData public required CategoryType Category { get; set; } public required bool defaultValue { get; set; } public required bool vipOnly { get; set; } + public List CommandShortcuts { get; set; } = new(); } \ No newline at end of file