diff --git a/TTT.sln b/TTT.sln index 8d65e6e..742c447 100644 --- a/TTT.sln +++ b/TTT.sln @@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TTT.Player", "mod\TTT.Playe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TTT.Manager", "mod\TTT.Manager\TTT.Manager.csproj", "{C3C26EF9-0E5E-4AAF-AE00-EFF4BB129FDB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TTT.Debug", "mod\TTT.Debug\TTT.Debug.csproj", "{5617C94C-B2F9-429C-B4C1-DDD03380A108}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -84,6 +86,10 @@ Global {C3C26EF9-0E5E-4AAF-AE00-EFF4BB129FDB}.Debug|Any CPU.Build.0 = Debug|Any CPU {C3C26EF9-0E5E-4AAF-AE00-EFF4BB129FDB}.Release|Any CPU.ActiveCfg = Release|Any CPU {C3C26EF9-0E5E-4AAF-AE00-EFF4BB129FDB}.Release|Any CPU.Build.0 = Release|Any CPU + {5617C94C-B2F9-429C-B4C1-DDD03380A108}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5617C94C-B2F9-429C-B4C1-DDD03380A108}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5617C94C-B2F9-429C-B4C1-DDD03380A108}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5617C94C-B2F9-429C-B4C1-DDD03380A108}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {A917B0F5-762F-4C4A-9F50-02BA4A0C6B63} = {C7CCF187-9F99-4091-B092-6397C35BE9F1} @@ -97,5 +103,6 @@ Global {E76CD078-0F1B-4EE8-9A19-EE93BAE3FA6B} = {14FF3D75-F9CF-4A32-9F59-83765EA68874} {D9327D60-67EE-4AF3-BD99-8A95634600B5} = {14FF3D75-F9CF-4A32-9F59-83765EA68874} {C3C26EF9-0E5E-4AAF-AE00-EFF4BB129FDB} = {14FF3D75-F9CF-4A32-9F59-83765EA68874} + {5617C94C-B2F9-429C-B4C1-DDD03380A108} = {14FF3D75-F9CF-4A32-9F59-83765EA68874} EndGlobalSection EndGlobal diff --git a/mod/TTT.Debug/Commands/GetRagdoll.cs b/mod/TTT.Debug/Commands/GetRagdoll.cs new file mode 100644 index 0000000..dd75b0e --- /dev/null +++ b/mod/TTT.Debug/Commands/GetRagdoll.cs @@ -0,0 +1,30 @@ +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; +using CounterStrikeSharp.API.Modules.Commands; +using TTT.Public.Behaviors; +using TTT.Public.Extensions; + +namespace TTT.Debug.Commands; + +public class GetRagdoll : IPluginBehavior { + [ConsoleCommand("css_getragdoll")] + [CommandHelper(0, "", CommandUsage.CLIENT_ONLY)] + public void Command_GetRagdoll(CCSPlayerController? executor, + CommandInfo command) { + if (executor == null) return; + + var body = executor.GetClientRagdollAimTarget(); + if (body == null) { + command.ReplyToCommand("No body found"); + return; + } + + if (!body.IsValid) { + command.ReplyToCommand("Found body, but is invalid"); + return; + } + + command.ReplyToCommand("Found " + body.DesignerName + " of " + + body.PlayerName); + } +} \ No newline at end of file diff --git a/mod/TTT.Debug/DebugServiceExtension.cs b/mod/TTT.Debug/DebugServiceExtension.cs new file mode 100644 index 0000000..070c27f --- /dev/null +++ b/mod/TTT.Debug/DebugServiceExtension.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.DependencyInjection; +using TTT.Debug.Commands; +using TTT.Public.Extensions; + +namespace TTT.Debug; + +public static class DebugServiceExtension { + public static void AddDebugBehavior(this IServiceCollection collection) { + collection.AddPluginBehavior(); + } +} \ No newline at end of file diff --git a/mod/TTT.Debug/TTT.Debug.csproj b/mod/TTT.Debug/TTT.Debug.csproj new file mode 100644 index 0000000..f6aaca5 --- /dev/null +++ b/mod/TTT.Debug/TTT.Debug.csproj @@ -0,0 +1,17 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + diff --git a/mod/TTT.Detective/DetectiveManager.cs b/mod/TTT.Detective/DetectiveManager.cs index ed2662f..78d2bb0 100644 --- a/mod/TTT.Detective/DetectiveManager.cs +++ b/mod/TTT.Detective/DetectiveManager.cs @@ -18,7 +18,6 @@ public class DetectiveManager(IPlayerService roleService) public void Start(BasePlugin parent) { parent.RegisterListener(() => { foreach (var player in Utilities.GetPlayers() - .Where(player => player.IsValid && player.IsReal()) .Where(player => (player.Buttons & PlayerButtons.Use) != 0)) OnPlayerUse(player); }); @@ -63,15 +62,11 @@ public HookResult OnZeus(DynamicHook hook) { private void OnPlayerUse(CCSPlayerController player) { IdentifyBody(player); } private void IdentifyBody(CCSPlayerController caller) { - //add states - - if (roleService.GetPlayer(caller).PlayerRole() != Role.Detective) return; + // if (roleService.GetPlayer(caller).PlayerRole() != Role.Detective) return; var entity = caller.GetClientRagdollAimTarget(); - if (entity == null) return; - - if (entity.PawnIsAlive) return; + if (entity == null || !entity.PawnIsAlive) return; var player = roleService.GetPlayer(entity); @@ -95,7 +90,6 @@ private void IdentifyBody(CCSPlayerController caller) { .PlayerRole() .FormatStringFullAfter(killerEntity.PlayerName)); - player.SetFound(true); Server.NextFrame(() => { Server.PrintToChatAll(message); }); @@ -117,9 +111,7 @@ private void IdentifyBody(CCSPlayerController caller) { if (player_pawn == null || !player_pawn.IsValid) return null; // controller valid - if (player_pawn.OriginalController == null - || !player_pawn.OriginalController.IsValid) - return null; + if (player_pawn.OriginalController is not { IsValid: true }) return null; // any further validity is up to the caller return player_pawn.OriginalController.Value; diff --git a/mod/TTT.Roles/RoleBehavior.cs b/mod/TTT.Roles/RoleBehavior.cs index 0f5ae4b..b21b5eb 100644 --- a/mod/TTT.Roles/RoleBehavior.cs +++ b/mod/TTT.Roles/RoleBehavior.cs @@ -18,41 +18,32 @@ public class RoleBehavior : IRoleService, IPluginBehavior { private const int MaxDetectives = 3; private readonly IPlayerService service; - private int _innocentsLeft; - private readonly IRoundService _roundService; - private int _traitorsLeft; + private int innocentsLeft; + private readonly IRoundService roundService; + private int traitorsLeft; public RoleBehavior(IPlayerService playerService) { - _roundService = new RoundBehavior(this); - service = playerService; + roundService = new RoundBehavior(this); + service = playerService; } public void Start(BasePlugin parent) { ModelHandler.RegisterListener(parent); - _roundService.Start(parent); - /* - parent.RegisterEventHandler(OnPlayerConnect); - parent.RegisterEventHandler(OnRoundStart); - parent.RegisterEventHandler(OnRoundEnd); - parent.RegisterEventHandler(OnPlayerDisconnect); - parent.RegisterEventHandler(OnPlayerDeath, HookMode.Pre); - parent.RegisterEventHandler(OnMapStart); - */ + roundService.Start(parent); } - public IRoundService GetRoundService() { return _roundService; } + public IRoundService GetRoundService() { return roundService; } public void AddRoles() { var eligible = Utilities.GetPlayers() - .Where(player => player.IsReal()) .Where(player => player.Team is not (CsTeam.Spectator or CsTeam.None)) .ToList(); var traitorCount = (int)Math.Floor(Convert.ToDouble(eligible.Count / 3)); var detectiveCount = (int)Math.Floor(Convert.ToDouble(eligible.Count / 8)); - _traitorsLeft = traitorCount; - _innocentsLeft = eligible.Count - traitorCount; + traitorsLeft = traitorCount; + innocentsLeft = eligible.Count - traitorCount; if (detectiveCount > MaxDetectives) detectiveCount = MaxDetectives; @@ -68,62 +59,62 @@ public void AddRoles() { AddDetective(chosen); } - AddInnocents(eligible); + AddInnocents(eligible.ToArray()); } public ISet GetTraitors() { - return service.Players() - .Where(player => player.PlayerRole() == Role.Traitor) - .Select(player => player.Player()) - .ToHashSet(); + return GetByRole(Role.Traitor); } public ISet GetDetectives() { - return service.Players() - .Where(player => player.PlayerRole() == Role.Detective) - .Select(player => player.Player()) - .ToHashSet(); + return GetByRole(Role.Detective); } public ISet GetInnocents() { + return GetByRole(Role.Innocent); + } + + public ISet GetByRole(Role role) { return service.Players() - .Where(player => player.PlayerRole() == Role.Innocent) + .Where(player => player.PlayerRole() == role) .Select(player => player.Player()) - .ToHashSet(); + .Where(p => p != null) + .ToHashSet()!; } - public Role GetRole(CCSPlayerController player) { return service.GetPlayer(player).PlayerRole(); } - public void AddTraitor(CCSPlayerController player) { - service.GetPlayer(player).SetPlayerRole(Role.Traitor); - player.SwitchTeam(CsTeam.Terrorist); - player.PrintToCenter( - Role.Traitor.FormatStringFullBefore("You are now a(n)")); - player.PrintToChat(Role.Traitor.FormatStringFullBefore("You are now a(n)")); - ModelHandler.SetModelNextServerFrame(player, - ModelHandler.ModelPathTmPhoenix); + public void AddTraitor(params CCSPlayerController[] players) { + foreach (var player in players) { + service.GetPlayer(player).SetPlayerRole(Role.Traitor); + player.SwitchTeam(CsTeam.Spectator); + player.PrintToCenter( + Role.Traitor.FormatStringFullBefore("You are now a")); + player.PrintToChat(Role.Traitor.FormatStringFullBefore("You are now a")); + ModelHandler.SetModel(player, ModelHandler.ModelPathTmPhoenix); + } } - public void AddDetective(CCSPlayerController player) { - service.GetPlayer(player).SetPlayerRole(Role.Detective); - player.SwitchTeam(CsTeam.CounterTerrorist); - player.PrintToCenter( - Role.Detective.FormatStringFullBefore("You are now a(n)")); - player.GiveNamedItem(CsItem.Taser); - ModelHandler.SetModelNextServerFrame(player, ModelHandler.ModelPathCtmSas); + public void AddDetective(params CCSPlayerController[] players) { + foreach (var player in players) { + service.GetPlayer(player).SetPlayerRole(Role.Detective); + player.SwitchTeam(CsTeam.CounterTerrorist); + player.PrintToCenter( + Role.Detective.FormatStringFullBefore("You are now a")); + player.GiveNamedItem(CsItem.Taser); + ModelHandler.SetModel(player, ModelHandler.ModelPathCtmSas); + } } - public void AddInnocents(IEnumerable players) { + public void AddInnocents(params CCSPlayerController[] players) { foreach (var player in players) { service.GetPlayer(player).SetPlayerRole(Role.Innocent); player.PrintToCenter( Role.Innocent.FormatStringFullBefore("You are now an")); - player.SwitchTeam(CsTeam.Terrorist); - ModelHandler.SetModelNextServerFrame(player, - ModelHandler.ModelPathTmPhoenix); + player.SwitchTeam(CsTeam.Spectator); + ModelHandler.SetModel(player, ModelHandler.ModelPathTmPhoenix); } } @@ -140,24 +131,19 @@ public void Clear() { foreach (var key in service.Players()) { key.SetPlayerRole(Role.Unassigned); if (key.Player() == null) continue; - RemoveColor(key.Player()); + RemoveColor(key.Player()!); } } [GameEventHandler] public HookResult OnRoundStart(EventRoundFreezeEnd @event, GameEventInfo info) { - _roundService.SetRoundStatus(RoundStatus.Waiting); + roundService.SetRoundStatus(RoundStatus.Waiting); foreach (var player in Utilities.GetPlayers() .Where(player => player.IsReal() && player.Team != CsTeam.None || player.Team != CsTeam.Spectator)) { player.RemoveWeapons(); - if (!string.IsNullOrEmpty("weapon_glock")) - player.GiveNamedItem("weapon_glock"); - - if (!string.IsNullOrEmpty(string.Empty)) - player.GiveNamedItem(string.Empty); - + player.GiveNamedItem("weapon_glock"); player.GiveNamedItem("weapon_knife"); service.GetPlayer(player).ModifyKarma(); } @@ -168,10 +154,8 @@ public HookResult [GameEventHandler] public HookResult OnPlayerConnect(EventPlayerConnectFull @event, GameEventInfo info) { - if (Utilities.GetPlayers() - .Count(player => player.IsReal() && player.Team != CsTeam.None - || player.Team == CsTeam.Spectator) < 3) - _roundService.ForceEnd(); + if (Utilities.GetPlayers().Count(player => player.PawnIsAlive) < 3) + roundService.ForceEnd(); return HookResult.Continue; } @@ -183,36 +167,32 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) { var playerWhoWasDamaged = @event.Userid; var attacker = @event.Attacker; - if (playerWhoWasDamaged == null) return HookResult.Continue; SetColor(playerWhoWasDamaged); - playerWhoWasDamaged.ModifyScoreBoard(); service.GetPlayer(playerWhoWasDamaged).SetKiller(attacker); - if (IsTraitor(playerWhoWasDamaged)) _traitorsLeft--; - + if (IsTraitor(playerWhoWasDamaged)) traitorsLeft--; if (IsDetective(playerWhoWasDamaged) || IsInnocent(playerWhoWasDamaged)) - _innocentsLeft--; + innocentsLeft--; - if (_traitorsLeft == 0 || _innocentsLeft == 0) - Server.NextFrame(() => _roundService.ForceEnd()); + if (traitorsLeft == 0 || innocentsLeft == 0) + Server.NextFrame(() => roundService.ForceEnd()); - Server.NextFrame(() => { - Server.PrintToChatAll(StringUtils.FormatTTT( - $"{GetRole(playerWhoWasDamaged).FormatStringFullAfter(" has been found.")}")); + // Server.PrintToChatAll(StringUtils.FormatTTT( + // $"{GetRole(playerWhoWasDamaged).FormatStringFullAfter(" has been found.")}")); - if (attacker == playerWhoWasDamaged || attacker == null) return; + if (attacker == playerWhoWasDamaged || attacker == null) + return HookResult.Continue; - attacker.ModifyScoreBoard(); + attacker.ModifyScoreBoard(); - playerWhoWasDamaged.PrintToChat(StringUtils.FormatTTT( - $"You were killed by {GetRole(attacker).FormatStringFullAfter(" " + attacker.PlayerName)}.")); - attacker.PrintToChat(StringUtils.FormatTTT( - $"You killed {GetRole(playerWhoWasDamaged).FormatStringFullAfter(" " + playerWhoWasDamaged.PlayerName)}.")); - }); + playerWhoWasDamaged.PrintToChat(StringUtils.FormatTTT( + $"You were killed by {GetRole(attacker).FormatStringFullAfter(" " + attacker.PlayerName)}.")); + attacker.PrintToChat(StringUtils.FormatTTT( + $"You killed {GetRole(playerWhoWasDamaged).FormatStringFullAfter(" " + playerWhoWasDamaged.PlayerName)}.")); return HookResult.Continue; } @@ -221,14 +201,12 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) { public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { var players = Utilities.GetPlayers() .Where(player => player.IsValid) - .Where(player => player.IsReal()) .ToList(); foreach (var player in players) player.PrintToCenter(GetWinner().FormatStringFullAfter("s has won!")); - Server.NextFrame(Clear); - + Clear(); return HookResult.Continue; } @@ -236,11 +214,10 @@ public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info) { var player = @event.Userid; - Server.NextFrame(() => { - service.RemovePlayer(player); - if (service.Players().Count == 0) - _roundService.SetRoundStatus(RoundStatus.Paused); - }); + if (player == null) return HookResult.Continue; + service.RemovePlayer(player); + if (service.Players().Count == 0) + roundService.SetRoundStatus(RoundStatus.Paused); return HookResult.Continue; } @@ -250,7 +227,7 @@ public bool IsInnocent(CCSPlayerController player) { } private Role GetWinner() { - return _traitorsLeft == 0 ? Role.Traitor : Role.Innocent; + return traitorsLeft == 0 ? Role.Traitor : Role.Innocent; } public void SetColor(CCSPlayerController player) { diff --git a/mod/TTT.Round/Round.cs b/mod/TTT.Round/Round.cs index d577c37..f72e622 100644 --- a/mod/TTT.Round/Round.cs +++ b/mod/TTT.Round/Round.cs @@ -42,7 +42,6 @@ public void Tick() { public void Start() { foreach (var player in Utilities.GetPlayers() - .Where(player => player.IsReal()) .Where(player => !player.PawnIsAlive) .Where(player => player.Team is CsTeam.Terrorist or CsTeam.CounterTerrorist)) diff --git a/public/TTT.Formatting/Extensions/ViewExtensions.cs b/public/TTT.Formatting/Extensions/ViewExtensions.cs index 8d17538..5b75929 100644 --- a/public/TTT.Formatting/Extensions/ViewExtensions.cs +++ b/public/TTT.Formatting/Extensions/ViewExtensions.cs @@ -56,7 +56,7 @@ public static IView ToPlayerConsole(this IView view, public static IView ToPlayerChat(this IView view, CCSPlayerController player) { - if (!player.IsReal() || player.IsBot) return view; + if (player.IsBot) return view; var writer = view.ToWriter(); diff --git a/src/TTT/TTT.csproj b/src/TTT/TTT.csproj index a561d3a..a05e9e5 100644 --- a/src/TTT/TTT.csproj +++ b/src/TTT/TTT.csproj @@ -6,6 +6,7 @@ + diff --git a/src/TTT/TTTServiceCollection.cs b/src/TTT/TTTServiceCollection.cs index 7b5db9f..2a04d54 100644 --- a/src/TTT/TTTServiceCollection.cs +++ b/src/TTT/TTTServiceCollection.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API.Core; using Microsoft.Extensions.DependencyInjection; +using TTT.Debug; using TTT.Detective; using TTT.Logs; using TTT.Manager; @@ -15,5 +16,6 @@ public void ConfigureServices(IServiceCollection serviceCollection) { serviceCollection.AddDetectiveBehavior(); serviceCollection.AddLogsService(); serviceCollection.AddManagerService(); + serviceCollection.AddDebugBehavior(); } } \ No newline at end of file