diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d95827e --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Build results +[Bb]in/ +[Oo]bj/ + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +*.sln + +# OS-specific files +*.DS_Store +*.Thumbs.db + +# Package files +*.nupkg +*.snupkg diff --git a/source/Deathmatch/API.cs b/source/Deathmatch/API.cs index 7f9237e..6722ca7 100644 --- a/source/Deathmatch/API.cs +++ b/source/Deathmatch/API.cs @@ -1,3 +1,4 @@ +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Modules.Utils; using DeathmatchAPI; using DeathmatchAPI.Events; @@ -26,7 +27,7 @@ public void StartCustomMode(int modeId) SetupCustomMode(modeId.ToString()); } - public void ChangeNextMode(int modeId) + public void SetNextMode(int modeId) { if (!Config.CustomModes.ContainsKey(modeId.ToString())) throw new Exception($"A Custom mode with ID '{modeId}' cannot be set as next mode, because this mode does not exist!"); @@ -42,36 +43,12 @@ public void AddCustomMode(int modeId, ModeData mode) Config.CustomModes.Add(modeId.ToString(), mode); } - public void ChangeCheckDistance(int distance) + public void SetCheckEnemiesSpawnDistance(int distance) { CheckedEnemiesDistance = distance; } - public void SetupCustomSpawns(string team, Dictionary spawns) - { - if (team.Equals("ct")) - { - spawnPositionsCT.Clear(); - foreach (var spawn in spawns) - { - spawnPositionsCT.Add(spawn.Key, spawn.Value); - } - } - else if (team.Equals("t")) - { - spawnPositionsT.Clear(); - foreach (var spawn in spawns) - { - spawnPositionsT.Add(spawn.Key, spawn.Value); - } - } - else - { - throw new Exception($"Invalid team name '{team}'! Allowed options: ct , t"); - } - } - - public void SwapHudMessageVisibility(bool visible) + public void SetHudMessageVisibility(bool visible) { VisibleHud = visible; } @@ -90,4 +67,31 @@ public Dictionary GetCustomModes() { return Config.CustomModes; } + + public int GetDefaultCheckDistance() + { + return Config.Gameplay.DistanceRespawn; + } + + public void SetupCustomSpawns(List spawns, bool clearSpawnsDictionary) + { + if (clearSpawnsDictionary) + { + spawnPositionsCT.Clear(); + spawnPositionsT.Clear(); + } + + foreach (var data in spawns) + { + switch (data.Team) + { + case CsTeam.CounterTerrorist: + spawnPositionsCT[data.Position] = data.Angle; + break; + case CsTeam.Terrorist: + spawnPositionsT[data.Position] = data.Angle; + break; + } + } + } } \ No newline at end of file diff --git a/source/Deathmatch/Common/Classes.cs b/source/Deathmatch/Common/Classes.cs index be228ac..31bae73 100644 --- a/source/Deathmatch/Common/Classes.cs +++ b/source/Deathmatch/Common/Classes.cs @@ -5,13 +5,6 @@ namespace Deathmatch { public partial class Deathmatch { - public class SpawnData - { - public required string team { get; set; } - public required string pos { get; set; } - public required string angle { get; set; } - } - public class DeathmatchPlayerData { public Dictionary PrimaryWeapon { get; set; } = new(); diff --git a/source/Deathmatch/Common/Collections.cs b/source/Deathmatch/Common/Collections.cs index aeeec32..08d7c8b 100644 --- a/source/Deathmatch/Common/Collections.cs +++ b/source/Deathmatch/Common/Collections.cs @@ -12,7 +12,7 @@ public partial class Deathmatch public static Dictionary spawnPositionsCT = new(); public static Dictionary spawnPositionsT = new(); public static Dictionary blockedSpawns = new(); - public static PlayerCache playerData = new(); + public static Dictionary playerData = new(); public static List Preferences = new(); public static List savedSpawnsModel = new(); public static List savedSpawnsVectorText = new(); @@ -51,6 +51,17 @@ public partial class Deathmatch "negative", "enemydown", "sorry", "cheer", "compliment", "thanks", "go_a", "go_b", "needrop", "deathcry" }; - }; + readonly string[] PointsMessagesArray = + { + "Player_Point_Award_Killed_Enemy", + "Player_Point_Award_Killed_Enemy_Plural", + "Player_Point_Award_Assist_Enemy", + "Player_Point_Award_Assist_Enemy_Plural", + "Player_Point_Award_Killed_Enemy_Noweapon", + "Player_Point_Award_Killed_Enemy_Noweapon_Plural", + "Player_Point_Award_Picked_Up_Dogtag", + "Player_Point_Award_Picked_Up_Dogtag_Plural" + }; + }; } \ No newline at end of file diff --git a/source/Deathmatch/Configs.cs b/source/Deathmatch/Configs.cs index f785138..df3d243 100644 --- a/source/Deathmatch/Configs.cs +++ b/source/Deathmatch/Configs.cs @@ -161,7 +161,8 @@ public class Gameplay [JsonPropertyName("Allow Buymenu")] public bool AllowBuyMenu { get; set; } = true; [JsonPropertyName("Use Default Spawns")] public bool DefaultSpawns { get; set; } = false; [JsonPropertyName("Respawn Players After New Mode")] public bool RespawnPlayersAtNewMode { get; set; } = false; - [JsonPropertyName("Spawn Protection Color")] public string SpawnProtectionColor { get; set; } = "#FFFFFF"; + [JsonPropertyName("Fast Weapon Equip")] public bool FastWeaponEquip { get; set; } = true; + [JsonPropertyName("Spawn Protection Color")] public string SpawnProtectionColor { get; set; } = ""; } public class General { @@ -172,6 +173,7 @@ public class General [JsonPropertyName("Block Player ChatWheel")] public bool BlockPlayerChatWheel { get; set; } = true; [JsonPropertyName("Remove Breakable Entities")] public bool RemoveBreakableEntities { get; set; } = true; [JsonPropertyName("Remove Decals")] public bool RemoveDecals { get; set; } = true; + [JsonPropertyName("Remove Kill Points Message")] public bool RemovePointsMessage { 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; } diff --git a/source/Deathmatch/Deathmatch.cs b/source/Deathmatch/Deathmatch.cs index 71cae6a..b44868e 100644 --- a/source/Deathmatch/Deathmatch.cs +++ b/source/Deathmatch/Deathmatch.cs @@ -18,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.3"; + public override string ModuleVersion => "1.2.4"; public void OnConfigParsed(DeathmatchConfig config) { @@ -110,7 +110,7 @@ public override void Load(bool hotReload) } SetupCustomMode(NextMode.ToString()); } - if (!string.IsNullOrEmpty(ActiveMode.CenterMessageText) && Config.CustomModes.TryGetValue(NextMode.ToString(),out var modeData)) + 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}"; @@ -137,7 +137,7 @@ public override void Load(bool hotReload) } else { - if (!GetPrefsValue(p.Slot, "HudMessages") || MenuManager.GetActiveMenu(p) != null) + if ((Config.PlayersPreferences.HudMessages.Enabled && !GetPrefsValue(p.Slot, "HudMessages")) || MenuManager.GetActiveMenu(p) != null) continue; if (!string.IsNullOrEmpty(ActiveMode.CenterMessageText)) @@ -179,6 +179,29 @@ public override void Load(bool hotReload) }, HookMode.Pre); } + if (Config.General.RemovePointsMessage) + { + HookUserMessage(124, um => + { + if (IsCasualGamemode) + return HookResult.Continue; + + for (int i = 0; i < um.GetRepeatedFieldCount("param"); i++) + { + var message = um.ReadString("param", i); + foreach (var msg in PointsMessagesArray) + { + if (message.Contains(msg)) + { + return HookResult.Stop; + } + } + + } + return HookResult.Continue; + }, HookMode.Pre); + } + if (hotReload) { Server.ExecuteCommand($"map {Server.MapName}"); @@ -206,7 +229,7 @@ public void SetupCustomMode(string modeId) ActiveCustomMode = modeId; NextMode = GetModeType(); - if (Config.CustomModes.TryGetValue(NextMode.ToString(),out var modeData) && !string.IsNullOrEmpty(ActiveMode.CenterMessageText)) + if (Config.CustomModes.TryGetValue(NextMode.ToString(), out var modeData) && !string.IsNullOrEmpty(ActiveMode.CenterMessageText)) { ModeCenterMessage = ActiveMode.CenterMessageText.Replace("{NEXTMODE}", modeData.Name); ModeCenterMessage = ModeCenterMessage.Replace("{REMAININGTIME}", RemainingTime.ToString()); @@ -215,7 +238,7 @@ public void SetupCustomMode(string modeId) Server.NextFrame(() => { - DeathmatchAPI.Get()?.TriggerEvent(new OnCustomModeStarted(int.Parse(ActiveCustomMode))); + DeathmatchAPI.Get()?.TriggerEvent(new OnCustomModeStarted(int.Parse(ActiveCustomMode), ActiveMode)); }); } diff --git a/source/Deathmatch/Deathmatch.csproj b/source/Deathmatch/Deathmatch.csproj index 61b6023..1f709d0 100644 --- a/source/Deathmatch/Deathmatch.csproj +++ b/source/Deathmatch/Deathmatch.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + true diff --git a/source/Deathmatch/Events.cs b/source/Deathmatch/Events.cs index f7b6f12..3781cfd 100644 --- a/source/Deathmatch/Events.cs +++ b/source/Deathmatch/Events.cs @@ -18,21 +18,22 @@ public partial class Deathmatch public HookResult OnPlayerConnectFull(EventPlayerConnectFull @event, GameEventInfo info) { var player = @event.Userid; - if (player != null && player.IsValid && !player.IsBot && !player.IsHLTV && player.SteamID.ToString().Length == 17 && !playerData.ContainsPlayer(player)) + if (player != null && player.IsValid && !player.IsBot && !player.IsHLTV && player.SteamID.ToString().Length == 17 && !playerData.ContainsKey(player.Slot)) { - var setupPlayerData = new DeathmatchPlayerData + var data = new DeathmatchPlayerData { BlockRandomWeaponsIntegeration = Server.CurrentTime, }; - playerData[player] = setupPlayerData; + playerData[player.Slot] = data; if (Config.SaveWeapons) { _ = UpdateOrLoadPlayerData(player, player.SteamID.ToString(), null, true); } else { - SetupDefaultWeapons(player); - SetupDefaultPreferences(player); + bool IsVIP = AdminManager.PlayerHasPermissions(player, Config.PlayersSettings.VIPFlag); + SetupDefaultWeapons(player, data, IsVIP); + SetupDefaultPreferences(player, data, IsVIP); } } return HookResult.Continue; @@ -55,7 +56,7 @@ public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo }; _ = UpdateOrLoadPlayerData(player, player.SteamID.ToString(), preferences, false); } - playerData.RemovePlayer(player); + playerData.Remove(player.Slot); } blockedSpawns.Remove(player.Slot); } @@ -69,82 +70,13 @@ public HookResult OnPlayerSpawn(EventPlayerSpawn @event, GameEventInfo info) var player = @event.Userid; if (player != null && player.IsValid) { + PerformRespawn(player, player.Team); GivePlayerWeapons(player, false); } return HookResult.Continue; } - [GameEventHandler(HookMode.Pre)] - public HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info) - { - var attacker = @event.Attacker; - var player = @event.Userid; - - if (player == null || !player.IsValid || attacker == player) - return HookResult.Continue; - - if (attacker != null && attacker.IsValid) - { - if (ActiveMode.OnlyHS) - { - 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) - { - if ((!@event.Weapon.Contains("knife") || !@event.Weapon.Contains("bayonet")) && GetPrefsValue(attacker.Slot, "HitSound")) - { - 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 - }; - } - } - } - } - return HookResult.Continue; - } - [GameEventHandler(HookMode.Pre)] public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) { @@ -177,18 +109,13 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) 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); } AddTimer(timer, () => { if (player != null && player.IsValid && !player.PawnIsAlive) - PerformRespawn(player, player.Team); + player.Respawn(); }, TimerFlags.STOP_ON_MAPCHANGE); if (attacker != null && attacker.IsValid && attacker != player && playerData.TryGetValue(attacker.Slot, out var attackerData) && attacker.PlayerPawn.Value != null) @@ -235,6 +162,7 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) weapon.Value.Clip1 = 250; weapon.Value.ReserveAmmo[0] = 250; + //Utilities.SetStateChanged(weapon.Value.As(), "CBasePlayerWeapon", "m_iClip1"); } } } @@ -245,6 +173,7 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) { activeWeapon.Clip1 = 250; activeWeapon.ReserveAmmo[0] = 250; + //Utilities.SetStateChanged(activeWeapon.As(), "CBasePlayerWeapon", "m_iClip1"); } } } @@ -264,26 +193,73 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) return HookResult.Continue; } - [GameEventHandler] - public HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) + [GameEventHandler(HookMode.Pre)] + public HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info) { - if (Config.General.RemoveBreakableEntities) - RemoveBreakableEntities(); - - return HookResult.Continue; - } + var attacker = @event.Attacker; + var player = @event.Userid; - [GameEventHandler] - public HookResult OnNewMatchBegin(EventBeginNewMatch @event, GameEventInfo info) - { - SetupCustomMode(Config.Gameplay.MapStartMode.ToString()); - return HookResult.Continue; - } + if (player == null || !player.IsValid || attacker == player) + return HookResult.Continue; - private HookResult OnPlayerRadioMessage(CCSPlayerController? player, CommandInfo info) - { - if (Config.General.BlockRadioMessage) - return HookResult.Handled; + if (attacker != null && attacker.IsValid && attacker != player) + { + if (ActiveMode.OnlyHS) + { + 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) + { + if ((!@event.Weapon.Contains("knife") || !@event.Weapon.Contains("bayonet")) && GetPrefsValue(attacker.Slot, "HitSound")) + { + 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 + }; + } + } + } + } return HookResult.Continue; } @@ -334,33 +310,22 @@ private HookResult OnPlayerSay(CCSPlayerController? player, CommandInfo info) return HookResult.Continue; } - private HookResult OnPlayerChatwheel(CCSPlayerController? player, CommandInfo info) - { - if (Config.General.BlockPlayerChatWheel) - return HookResult.Handled; - return HookResult.Continue; - } - - private HookResult OnPlayerPing(CCSPlayerController? player, CommandInfo info) + private HookResult OnTakeDamage(DynamicHook hook) { - if (Config.General.BlockPlayerPing) - return HookResult.Handled; - return HookResult.Continue; - } + var entity = hook.GetParam(0); + if (entity == null || !entity.IsValid || !entity.DesignerName.Equals("player")) + return HookResult.Continue; - private HookResult OnRandomWeapons(CCSPlayerController? player, CommandInfo info) - { - return HookResult.Stop; - } + var pawn = entity.As(); + if (pawn == null || !pawn.IsValid) + return HookResult.Continue; - private HookResult OnTakeDamage(DynamicHook hook) - { - var damageInfo = hook.GetParam(1); - var player = hook.GetParam(0).Controller.Value?.As(); + var player = pawn.OriginalController.Get(); if (player == null || !player.IsValid) return HookResult.Continue; - if (playerData.ContainsPlayer(player) && playerData[player].SpawnProtection) + var damageInfo = hook.GetParam(1); + if (playerData.TryGetValue(player.Slot, out var victimData) && victimData.SpawnProtection) { damageInfo.Damage = 0; return HookResult.Continue; @@ -377,8 +342,11 @@ private HookResult OnTakeDamage(DynamicHook hook) return HookResult.Continue; } - if (Config.PlayersPreferences.OnlyHS.Enabled && damageInfo.GetHitGroup() != HitGroup_t.HITGROUP_HEAD && GetPrefsValue(attacker.Slot, "OnlyHS")) + if (damageInfo.GetHitGroup() != HitGroup_t.HITGROUP_HEAD && GetPrefsValue(attacker.Slot, "OnlyHS")) + { damageInfo.Damage = 0; + return HookResult.Continue; + } return HookResult.Continue; } @@ -450,6 +418,7 @@ private HookResult OnWeaponCanAcquire(DynamicHook hook) return HookResult.Stop; } + var pawn = player.PlayerPawn.Value; if (IsPrimary) { if (data.PrimaryWeapon.TryGetValue(ActiveCustomMode, out var primaryWeapon) && vdata.Name == primaryWeapon) @@ -461,7 +430,7 @@ private HookResult OnWeaponCanAcquire(DynamicHook hook) data.PrimaryWeapon[ActiveCustomMode] = vdata.Name; player.PrintToChat($"{Localizer["Chat.Prefix"]} {Localizer["Chat.PrimaryWeaponSet", localizerWeaponName]}"); - var weapon = GetWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_RIFLE); + var weapon = pawn != null ? GetWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_RIFLE) : null; if (!Config.Gameplay.SwitchWeapons && weapon != null) { hook.SetReturn(AcquireResult.AlreadyOwned); @@ -479,7 +448,7 @@ private HookResult OnWeaponCanAcquire(DynamicHook hook) data.SecondaryWeapon[ActiveCustomMode] = vdata.Name; player.PrintToChat($"{Localizer["Chat.Prefix"]} {Localizer["Chat.SecondaryWeaponSet", localizerWeaponName]}"); - var weapon = GetWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_PISTOL); + var weapon = pawn != null ? GetWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_PISTOL) : null; if (!Config.Gameplay.SwitchWeapons && weapon != null) { hook.SetReturn(AcquireResult.AlreadyOwned); @@ -489,5 +458,47 @@ private HookResult OnWeaponCanAcquire(DynamicHook hook) } return HookResult.Continue; } + + [GameEventHandler] + public HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) + { + if (Config.General.RemoveBreakableEntities) + RemoveBreakableEntities(); + + 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) + return HookResult.Handled; + return HookResult.Continue; + } + + private HookResult OnPlayerChatwheel(CCSPlayerController? player, CommandInfo info) + { + if (Config.General.BlockPlayerChatWheel) + return HookResult.Handled; + return HookResult.Continue; + } + + private HookResult OnPlayerPing(CCSPlayerController? player, CommandInfo info) + { + if (Config.General.BlockPlayerPing) + return HookResult.Handled; + return HookResult.Continue; + } + + private HookResult OnRandomWeapons(CCSPlayerController? player, CommandInfo info) + { + return HookResult.Stop; + } } } \ No newline at end of file diff --git a/source/Deathmatch/Functions/Commands.cs b/source/Deathmatch/Functions/Commands.cs index b7d8b81..563ca90 100644 --- a/source/Deathmatch/Functions/Commands.cs +++ b/source/Deathmatch/Functions/Commands.cs @@ -20,7 +20,7 @@ private void AddCustomCommands(string command, string weapon_name, int type, boo case 1: AddCommand(cmdName, $"Weapon Shortcut: {weapon_name}", (player, info) => { - if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) + if (player == null || !player.IsValid) return; if (ActiveMode.RandomWeapons) @@ -34,7 +34,7 @@ private void AddCustomCommands(string command, string weapon_name, int type, boo case 2: AddCommand(cmdName, "Select a weapon by command", (player, info) => { - if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) + if (player == null || !player.IsValid) return; if (ActiveMode.RandomWeapons) @@ -50,7 +50,7 @@ private void AddCustomCommands(string command, string weapon_name, int type, boo case 3: AddCommand(cmdName, "Opens a Deathmatch menu", (player, info) => { - if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) + if (player == null || !player.IsValid || !playerData.ContainsKey(player.Slot)) return; if (!Preferences.Any()) @@ -74,7 +74,7 @@ private void AddCustomCommands(string command, string weapon_name, int type, boo case 4: AddCommand(cmdName, "Switch Player Preferences", (player, info) => { - if (player == null || !player.IsValid || !playerData.ContainsPlayer(player)) + if (player == null || !player.IsValid || !playerData.ContainsKey(player.Slot)) return; if (onlyVIP && !AdminManager.PlayerHasPermissions(player, Config.PlayersSettings.VIPFlag)) diff --git a/source/Deathmatch/Functions/Database.cs b/source/Deathmatch/Functions/Database.cs index 9b143c9..ae517a2 100644 --- a/source/Deathmatch/Functions/Database.cs +++ b/source/Deathmatch/Functions/Database.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Admin; using MySqlConnector; using Newtonsoft.Json; @@ -89,25 +90,26 @@ ON DUPLICATE KEY UPDATE { if (playerData.TryGetValue(player.Slot, out var data)) { + bool IsVIP = AdminManager.PlayerHasPermissions(player, Config.PlayersSettings.VIPFlag); if (primaryWeapons == null || secondaryWeapons == null) { - SetupDefaultWeapons(player); + SetupDefaultWeapons(player, data, IsVIP); } else { data.PrimaryWeapon = primaryWeapons; data.SecondaryWeapon = secondaryWeapons; - SetupDefaultWeapons(player); + SetupDefaultWeapons(player, data, IsVIP); } if (preferences == null) { - SetupDefaultPreferences(player); + SetupDefaultPreferences(player, data, IsVIP); } else { data.Preferences = preferences; - SetupDefaultPreferences(player); + SetupDefaultPreferences(player, data, IsVIP); } } }); diff --git a/source/Deathmatch/Functions/Players.cs b/source/Deathmatch/Functions/Players.cs index 64e42fb..d04ad59 100644 --- a/source/Deathmatch/Functions/Players.cs +++ b/source/Deathmatch/Functions/Players.cs @@ -90,12 +90,15 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co return; } + if (!playerData.TryGetValue(player.Slot, out var data)) + return; bool IsVIP = AdminManager.PlayerHasPermissions(player, Config.PlayersSettings.VIPFlag); + var pawn = player.PlayerPawn.Value; if (ActiveMode.PrimaryWeapons.Contains(weaponName)) { string localizerWeaponName = Localizer[weaponName]; - if (playerData[player].PrimaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && weaponName == weapon) + if (data.PrimaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && weaponName == weapon) { if (!string.IsNullOrEmpty(Config.SoundSettings.CantEquipSound)) player.ExecuteClientCommand("play " + Config.SoundSettings.CantEquipSound); @@ -112,10 +115,10 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co return; } - playerData[player].PrimaryWeapon[ActiveCustomMode] = weaponName; + data.PrimaryWeapon[ActiveCustomMode] = weaponName; info.ReplyToCommand($"{Localizer["Chat.Prefix"]} {Localizer["Chat.PrimaryWeaponSet", localizerWeaponName]}"); - var primaryWeapon = GetWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_RIFLE); + var primaryWeapon = pawn != null ? GetWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_RIFLE) : null; if (player.PawnIsAlive) { if (primaryWeapon == null) @@ -124,7 +127,7 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co } else if (Config.Gameplay.SwitchWeapons) { - var secondaryWeapon = GetWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_PISTOL); + var secondaryWeapon = pawn != null ? GetWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_PISTOL) : null; player.RemoveWeapons(); player.GiveNamedItem("weapon_knife"); player.GiveNamedItem(weaponName); @@ -143,7 +146,7 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co else if (ActiveMode.SecondaryWeapons.Contains(weaponName)) { string localizerWeaponName = Localizer[weaponName]; - if (playerData[player].SecondaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && weaponName == weapon) + if (data.SecondaryWeapon.TryGetValue(ActiveCustomMode, out var weapon) && weaponName == weapon) { if (!string.IsNullOrEmpty(Config.SoundSettings.CantEquipSound)) player.ExecuteClientCommand("play " + Config.SoundSettings.CantEquipSound); @@ -160,10 +163,10 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co return; } - playerData[player].SecondaryWeapon[ActiveCustomMode] = weaponName; + data.SecondaryWeapon[ActiveCustomMode] = weaponName; info.ReplyToCommand($"{Localizer["Chat.Prefix"]} {Localizer["Chat.SecondaryWeaponSet", localizerWeaponName]}"); - var secondaryWeapon = GetWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_PISTOL); + var secondaryWeapon = pawn != null ? GetWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_PISTOL) : null; if (player.PawnIsAlive) { if (secondaryWeapon == null) @@ -172,7 +175,7 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co } else if (Config.Gameplay.SwitchWeapons) { - var primaryWeapon = GetWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_RIFLE); + var primaryWeapon = pawn != null ? GetWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_RIFLE) : null; player.RemoveWeapons(); player.GiveNamedItem("weapon_knife"); player.GiveNamedItem(weaponName); @@ -200,7 +203,8 @@ public void SetupPlayerWeapons(CCSPlayerController player, string weaponName, Co public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool giveUtilities = true, bool giveKnife = false) { - if (playerData.TryGetValue(player.Slot, out var data) && player.PlayerPawn.Value != null) + var pawn = player.PlayerPawn.Value; + if (playerData.TryGetValue(player.Slot, out var data) && pawn != null) { if (player.InGameMoneyServices != null && giveUtilities) player.InGameMoneyServices.Account = Config.Gameplay.AllowBuyMenu ? 16000 : 0; @@ -211,11 +215,11 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi var timer = IsVIP ? Config.PlayersSettings.VIP.ProtectionTime : Config.PlayersSettings.NonVIP.ProtectionTime; if (timer > 0.1) { - if (string.IsNullOrEmpty(Config.Gameplay.SpawnProtectionColor)) + if (!string.IsNullOrEmpty(Config.Gameplay.SpawnProtectionColor)) { Color transparentColor = ColorTranslator.FromHtml(Config.Gameplay.SpawnProtectionColor); - player.PlayerPawn.Value.Render = transparentColor; - Utilities.SetStateChanged(player.PlayerPawn.Value, "CBaseModelEntity", "m_clrRender"); + pawn.Render = transparentColor; + Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender"); } data.SpawnProtection = true; AddTimer(timer, () => @@ -223,10 +227,10 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi if (player != null && player.IsValid && playerData.TryGetValue(player.Slot, out data)) { data.SpawnProtection = false; - if (string.IsNullOrEmpty(Config.Gameplay.SpawnProtectionColor)) + if (!string.IsNullOrEmpty(Config.Gameplay.SpawnProtectionColor)) { - player.PlayerPawn.Value.Render = Color.White; - Utilities.SetStateChanged(player.PlayerPawn.Value, "CBaseModelEntity", "m_clrRender"); + pawn.Render = Color.White; + Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender"); } } }); @@ -278,75 +282,88 @@ public void GivePlayerWeapons(CCSPlayerController player, bool bNewMode, bool gi player.GiveNamedItem("weapon_knife"); } + if (Config.Gameplay.FastWeaponEquip) + { + Server.NextFrame(() => + { + var activeWeapon = GetActiveWeapon(pawn); + if (activeWeapon != null && activeWeapon.IsValid) + { + activeWeapon.NextPrimaryAttackTick = Server.TickCount + 1; + Utilities.SetStateChanged(player, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick"); + } + }); + } return; } if (player.InGameMoneyServices != null) player.InGameMoneyServices.Account = 0; - if (ActiveMode.PrimaryWeapons.Any()) + if (pawn != null) { - if (!IsHaveWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_RIFLE)) + if (ActiveMode.PrimaryWeapons.Any()) { - var PrimaryWeapon = ActiveMode.PrimaryWeapons.Count switch + if (!IsHaveWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_RIFLE)) { - 1 => ActiveMode.PrimaryWeapons[0], - _ => Config.Gameplay.DefaultModeWeapons switch + var PrimaryWeapon = ActiveMode.PrimaryWeapons.Count switch { - 2 or 3 => GetRandomWeaponFromList(ActiveMode.PrimaryWeapons, ActiveMode, false, player.Team, true), - _ or 1 => ActiveMode.PrimaryWeapons[0] - } - }; - if (!string.IsNullOrEmpty(PrimaryWeapon)) - player.GiveNamedItem(PrimaryWeapon); + 1 => ActiveMode.PrimaryWeapons[0], + _ => Config.Gameplay.DefaultModeWeapons switch + { + 2 or 3 => GetRandomWeaponFromList(ActiveMode.PrimaryWeapons, ActiveMode, false, player.Team, true), + _ or 1 => ActiveMode.PrimaryWeapons[0] + } + }; + if (!string.IsNullOrEmpty(PrimaryWeapon)) + player.GiveNamedItem(PrimaryWeapon); + } } - } - if (ActiveMode.SecondaryWeapons.Any()) - { - if (!IsHaveWeaponFromSlot(player, gear_slot_t.GEAR_SLOT_PISTOL)) + if (ActiveMode.SecondaryWeapons.Any()) { - var SecondaryWeapon = ActiveMode.SecondaryWeapons.Count switch + if (!IsHaveWeaponFromSlot(pawn, gear_slot_t.GEAR_SLOT_PISTOL)) { - 1 => ActiveMode.SecondaryWeapons[0], - _ => Config.Gameplay.DefaultModeWeapons switch + var SecondaryWeapon = ActiveMode.SecondaryWeapons.Count switch { - 2 or 3 => GetRandomWeaponFromList(ActiveMode.SecondaryWeapons, ActiveMode, false, player.Team, false), - _ or 1 => ActiveMode.SecondaryWeapons[0] - } - }; + 1 => ActiveMode.SecondaryWeapons[0], + _ => Config.Gameplay.DefaultModeWeapons switch + { + 2 or 3 => GetRandomWeaponFromList(ActiveMode.SecondaryWeapons, ActiveMode, false, player.Team, false), + _ or 1 => ActiveMode.SecondaryWeapons[0] + } + }; - if (!string.IsNullOrEmpty(SecondaryWeapon)) - player.GiveNamedItem(SecondaryWeapon); + if (!string.IsNullOrEmpty(SecondaryWeapon)) + player.GiveNamedItem(SecondaryWeapon); + } } } } - public void SetupDefaultPreferences(CCSPlayerController player) + public void SetupDefaultPreferences(CCSPlayerController player, DeathmatchPlayerData data, bool IsVIP) { - bool IsVIP = AdminManager.PlayerHasPermissions(player, Config.PlayersSettings.VIPFlag); - foreach (var data in Preferences) + foreach (var pref in Preferences) { - if (playerData[player].Preferences.ContainsKey(data.Name)) + if (data.Preferences.ContainsKey(pref.Name)) continue; - if (data.vipOnly) + if (pref.vipOnly) { if (IsVIP) - playerData[player].Preferences[data.Name] = data.defaultValue; + data.Preferences[pref.Name] = pref.defaultValue; else - playerData[player].Preferences[data.Name] = false; + data.Preferences[pref.Name] = false; } else - playerData[player].Preferences[data.Name] = data.defaultValue; + data.Preferences[pref.Name] = pref.defaultValue; } } - public void SetupDefaultWeapons(CCSPlayerController player) + public void SetupDefaultWeapons(CCSPlayerController player, DeathmatchPlayerData data, bool IsVIP) { - bool IsVIP = AdminManager.PlayerHasPermissions(player, Config.PlayersSettings.VIPFlag); foreach (var mode in Config.CustomModes) { - if (playerData[player].PrimaryWeapon.ContainsKey(mode.Key)) + if (data.PrimaryWeapon.ContainsKey(mode.Key)) continue; switch (Config.Gameplay.DefaultModeWeapons) @@ -355,49 +372,49 @@ public void SetupDefaultWeapons(CCSPlayerController player) 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; + data.PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; } else - playerData[player].PrimaryWeapon[mode.Key] = ""; + data.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; + data.SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; } else - playerData[player].SecondaryWeapon[mode.Key] = ""; + data.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; + data.PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; } else - playerData[player].PrimaryWeapon[mode.Key] = ""; + data.PrimaryWeapon[mode.Key] = ""; if (mode.Value.SecondaryWeapons.Any()) { var secondary = GetRandomWeaponFromList(mode.Value.SecondaryWeapons, mode.Value, IsVIP, player.Team, false); - playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; + data.SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; } else - playerData[player].SecondaryWeapon[mode.Key] = ""; + data.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; + data.PrimaryWeapon[mode.Key] = string.IsNullOrEmpty(primary) ? "" : primary; } else - playerData[player].PrimaryWeapon[mode.Key] = ""; + data.PrimaryWeapon[mode.Key] = ""; if (mode.Value.SecondaryWeapons.Any()) { var secondary = mode.Value.SecondaryWeapons.FirstOrDefault(); - playerData[player].SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; + data.SecondaryWeapon[mode.Key] = string.IsNullOrEmpty(secondary) ? "" : secondary; } else - playerData[player].SecondaryWeapon[mode.Key] = ""; + data.SecondaryWeapon[mode.Key] = ""; break; } } @@ -413,80 +430,15 @@ public static bool GetPrefsValue(int slot, string preference) private void SwitchPrefsValue(CCSPlayerController player, string preference) { - playerData[player].Preferences[preference] = !playerData[player].Preferences[preference]; - var changedValue = playerData[player].Preferences[preference] ? Localizer["Menu.Enabled"] : Localizer["Menu.Disabled"]; + if (!playerData.TryGetValue(player.Slot, out var data)) + return; + + data.Preferences[preference] = !data.Preferences[preference]; + var changedValue = data.Preferences[preference] ? Localizer["Menu.Enabled"] : Localizer["Menu.Disabled"]; var Preference = Localizer[$"Prefs.{preference}"]; player.PrintToChat($"{Localizer["Chat.Prefix"]} {Localizer["Prefs.ValueChanged", Preference, changedValue]}"); } - //https://github.com/K4ryuu/K4-System/blob/dev/src/Plugin/PluginCache.cs - public class PlayerCache : Dictionary - { - public T this[CCSPlayerController? controller] - { - get - { - if (controller is null || !controller.IsValid || controller.SteamID.ToString().Length != 17) - { - throw new ArgumentException("Invalid player controller"); - } - - if (controller.IsBot || controller.IsHLTV) - { - throw new ArgumentException("Player controller is BOT or HLTV"); - } - - if (!ContainsKey(controller.Slot)) - { - throw new KeyNotFoundException($"Player with ID {controller.Slot} not found in cache"); - } - - if (TryGetValue(controller.Slot, out T? value)) - { - return value; - } - - return default(T)!; - } - set - { - if (controller is null || !controller.IsValid || !controller.PlayerPawn.IsValid || controller.SteamID.ToString().Length != 17) - { - throw new ArgumentException("Invalid player controller"); - } - - if (controller.IsBot || controller.IsHLTV) - { - throw new ArgumentException("Player controller is BOT or HLTV"); - } - - this[controller.Slot] = value; - } - } - - public bool ContainsPlayer(CCSPlayerController player) - { - if (player.SteamID.ToString().Length != 17) - return false; - - if (player.IsBot || player.IsHLTV) - return false; - - return ContainsKey(player.Slot); - } - - public bool RemovePlayer(CCSPlayerController? player) - { - if (player == null || !player.IsValid || !player.PlayerPawn.IsValid || player.SteamID.ToString().Length != 17) - return false; - - if (player.IsBot || player.IsHLTV) - return false; - - return Remove(player.Slot); - } - } - public bool IsHaveBlockedRandomWeaponsIntegration(CCSPlayerController player) { if (playerData.TryGetValue(player.Slot, out var data)) diff --git a/source/Deathmatch/Functions/Spawns.cs b/source/Deathmatch/Functions/Spawns.cs index c75fd91..635b8e6 100644 --- a/source/Deathmatch/Functions/Spawns.cs +++ b/source/Deathmatch/Functions/Spawns.cs @@ -6,6 +6,8 @@ using Newtonsoft.Json.Linq; using CounterStrikeSharp.API.Modules.Utils; using System.Globalization; +using static DeathmatchAPI.Events.IDeathmatchEventsAPI; +using DeathmatchAPI.Helpers; namespace Deathmatch { @@ -22,7 +24,7 @@ public void PerformRespawn(CCSPlayerController player, CsTeam team) if (!spawnsDictionary.Any()) { - player.Respawn(); + //player.Respawn(); SendConsoleMessage("[Deathmatch] Spawns list is empty, you got something wrong!", ConsoleColor.Red); return; } @@ -39,7 +41,7 @@ public void PerformRespawn(CCSPlayerController player, CsTeam team) } blockedSpawns[player.Slot] = selectedSpawn.position; - player.Respawn(); + //player.Respawn(); player.Pawn.Value?.Teleport(selectedSpawn.position, selectedSpawn.angle, new Vector()); } @@ -397,6 +399,30 @@ public void LoadMapSpawns(string filePath, bool mapstart) RemoveMapDefaulSpawns(); } } + + Server.NextFrame(() => + { + var spawns = new List(); + foreach (var spawn in spawnPositionsCT) + { + spawns.Add(new() + { + Team = CsTeam.CounterTerrorist, + Position = spawn.Key, + Angle = spawn.Value + }); + } + foreach (var spawn in spawnPositionsT) + { + spawns.Add(new() + { + Team = CsTeam.Terrorist, + Position = spawn.Key, + Angle = spawn.Value + }); + } + DeathmatchAPI.Get()?.TriggerEvent(new OnSpawnPointsLoaded(spawns)); + }); } private static Vector ParseVector(string pos) { diff --git a/source/Deathmatch/Functions/Weapons.cs b/source/Deathmatch/Functions/Weapons.cs index 3a0cdcd..ea0321e 100644 --- a/source/Deathmatch/Functions/Weapons.cs +++ b/source/Deathmatch/Functions/Weapons.cs @@ -10,7 +10,7 @@ public partial class Deathmatch { public bool CheckIsWeaponRestricted(string weaponName, bool isVIP, CsTeam team, bool bPrimary) { - var players = Utilities.GetPlayers().Where(p => playerData.ContainsPlayer(p)).ToList(); + var players = Utilities.GetPlayers().Where(p => playerData.ContainsKey(p.Slot)).ToList(); if (players == null || players.Count < 2) return false; @@ -30,16 +30,15 @@ public bool CheckIsWeaponRestricted(string weaponName, bool isVIP, CsTeam team, 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); + ? playerData[p.Slot].PrimaryWeapon.TryGetValue(ActiveCustomMode, out var primary) && primary == weaponName + : playerData[p.Slot].SecondaryWeapon.TryGetValue(ActiveCustomMode, out var secondary) && secondary == weaponName); return matchingCount >= restrictValue; } - public CBasePlayerWeapon? GetWeaponFromSlot(CCSPlayerController player, gear_slot_t slot) + public CBasePlayerWeapon? GetWeaponFromSlot(CCSPlayerPawn pawn, gear_slot_t slot) { - var pawn = player.PlayerPawn.Value; - if (pawn == null || pawn.WeaponServices == null) + if (pawn.WeaponServices == null) return null; return pawn.WeaponServices.MyWeapons @@ -47,10 +46,9 @@ public bool CheckIsWeaponRestricted(string weaponName, bool isVIP, CsTeam team, .FirstOrDefault(weaponBase => weaponBase != null && weaponBase.VData != null && weaponBase.VData.GearSlot == slot); } - public bool IsHaveWeaponFromSlot(CCSPlayerController player, gear_slot_t slot) + public bool IsHaveWeaponFromSlot(CCSPlayerPawn pawn, gear_slot_t slot) { - var pawn = player.PlayerPawn.Value; - if (pawn == null || pawn.WeaponServices == null || !player.PawnIsAlive) + if (pawn.WeaponServices == null) return false; return pawn.WeaponServices.MyWeapons @@ -95,6 +93,11 @@ public int GetWeaponRestrict(string weaponName, bool isVIP, CsTeam team) : (restrictDataNonVIP.T, restrictDataVIP.T); } + public CBasePlayerWeapon? GetActiveWeapon(CCSPlayerPawn pawn) + { + return pawn.WeaponServices?.ActiveWeapon.Value; + } + public string GetWeaponRestrictLozalizer(int bullets) { switch (bullets) diff --git a/source/DeathmatchAPI/DeathmatchAPI.cs b/source/DeathmatchAPI/DeathmatchAPI.cs index 9ec7ef2..81479ab 100644 --- a/source/DeathmatchAPI/DeathmatchAPI.cs +++ b/source/DeathmatchAPI/DeathmatchAPI.cs @@ -7,18 +7,14 @@ namespace DeathmatchAPI; public interface IDeathmatchAPI { public void StartCustomMode(int modeId); - public void ChangeNextMode(int modeId); + public void SetNextMode(int modeId); public void AddCustomMode(int modeId, ModeData mode); - public void ChangeCheckDistance(int distance); - - /* - Team String - Available values: ct | t - Spawns Dictionary - Vector & QAngle - */ - public void SetupCustomSpawns(string team, Dictionary spawns); - public void SwapHudMessageVisibility(bool visible); + public void SetCheckEnemiesSpawnDistance(int distance); + public void SetupCustomSpawns(List spawns, bool clearSpawnsDictionary); + public void SetHudMessageVisibility(bool visible); public int GetActiveModeId(); public int GetActiveModeRemainingTime(); + public int GetDefaultCheckDistance(); public Dictionary GetCustomModes(); public event EventHandler DeathmatchEventHandlers; public void TriggerEvent(IDeathmatchEventsAPI @event); diff --git a/source/DeathmatchAPI/Events.cs b/source/DeathmatchAPI/Events.cs index ebc74c2..69f73d8 100644 --- a/source/DeathmatchAPI/Events.cs +++ b/source/DeathmatchAPI/Events.cs @@ -1,5 +1,9 @@ + +using DeathmatchAPI.Helpers; + namespace DeathmatchAPI.Events; public interface IDeathmatchEventsAPI { - public record OnCustomModeStarted(int modeId) : IDeathmatchEventsAPI; + public record OnCustomModeStarted(int modeId, ModeData data) : IDeathmatchEventsAPI; + public record OnSpawnPointsLoaded(List spawns) : IDeathmatchEventsAPI; } \ No newline at end of file diff --git a/source/DeathmatchAPI/Helpers.cs b/source/DeathmatchAPI/Helpers.cs index 7cb553a..4e56173 100644 --- a/source/DeathmatchAPI/Helpers.cs +++ b/source/DeathmatchAPI/Helpers.cs @@ -1,3 +1,5 @@ +using CounterStrikeSharp.API.Modules.Utils; + namespace DeathmatchAPI.Helpers; public enum CategoryType @@ -8,9 +10,9 @@ public enum CategoryType public class ModeData { - public string Name { get; set; } = "Defaut Mode"; + public string Name { get; set; } = "Default Mode"; public int Interval { get; set; } = 300; - public int Armor { get; set; } = 100; + public int Armor { get; set; } = 1; public bool OnlyHS { get; set; } = false; public bool KnifeDamage { get; set; } = true; public bool RandomWeapons { get; set; } = false; @@ -28,4 +30,11 @@ public class PreferencesData public required bool defaultValue { get; set; } public required bool vipOnly { get; set; } public List CommandShortcuts { get; set; } = new(); +} + +public class SpawnData +{ + public required CsTeam Team { get; set; } + public required Vector Position { get; set; } + public required QAngle Angle { get; set; } } \ No newline at end of file