|
1 | 1 | namespace FunMatchPlugin;
|
| 2 | + |
| 3 | +using System.Runtime.InteropServices; |
2 | 4 | using CounterStrikeSharp.API;
|
3 | 5 | using CounterStrikeSharp.API.Core;
|
| 6 | +using CounterStrikeSharp.API.Core.Translations; |
4 | 7 | using CounterStrikeSharp.API.Modules.Cvars;
|
5 | 8 | using CounterStrikeSharp.API.Modules.Entities.Constants;
|
| 9 | +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; |
6 | 10 | using CounterStrikeSharp.API.Modules.Timers;
|
| 11 | +using CounterStrikeSharp.API.Modules.Utils; |
7 | 12 |
|
8 | 13 | // gameRules not working https://github.com/roflmuffin/CounterStrikeSharp/issues/489
|
9 | 14 | public class FunC4EveryWhere : FunBaseClass
|
10 | 15 | {
|
11 |
| - public override string Decription => "C4 EveryWhere C4大战"; |
| 16 | + public override string Decription => "C4 EveryWhere 10s to explode C4大战 10s爆炸"; |
12 | 17 | public FunC4EveryWhere(FunMatchPlugin plugin) : base(plugin){}
|
13 |
| - public CCSGameRules gameRules; |
14 |
| - private Timer roundTimer; |
| 18 | + public CCSGameRules? gameRules = null; |
| 19 | + private Timer? roundTimer = null; |
| 20 | + |
| 21 | + private Timer? roundTimer90 = null; |
| 22 | + private Timer? roundTimer60 = null; |
| 23 | + private Timer? roundTimer110 = null; |
| 24 | + private bool TeamHasWon = false; |
| 25 | + private CTeam? Team_CT; |
| 26 | + private CTeam? Team_T; |
| 27 | + |
| 28 | + private BasePlugin.GameEventHandler<EventBombPlanted>? EventBombPlantedHandler=null; |
| 29 | + private BasePlugin.GameEventHandler<EventPlayerDeath>? EventPlayerDeathHandler=null; |
15 | 30 | public override void Fun(FunMatchPlugin plugin)
|
16 | 31 | {
|
17 | 32 | Enabled = true;
|
18 |
| - //ConVar.Find("mp_weapons_allow_heavyassaultsuit").SetValue(true); |
| 33 | + ConVar.Find("sv_cheats")!.SetValue(true); |
19 | 34 | ConVar.Find("mp_autokick")!.SetValue(false);
|
20 | 35 | ConVar.Find("mp_c4timer")!.SetValue(10);
|
21 | 36 | ConVar.Find("mp_plant_c4_anywhere")!.SetValue(true);
|
22 | 37 | ConVar.Find("mp_c4_cannot_be_defused")!.SetValue(true);
|
23 | 38 | ConVar.Find("mp_anyone_can_pickup_c4")!.SetValue(true);
|
24 |
| - ConVar.Find("mp_ignore_round_win_conditions")!.SetValue(true); |
25 |
| - |
| 39 | + //ConVar.Find("mp_ignore_round_win_conditions")!.SetValue(true); |
| 40 | + ConVar.Find("sv_cheats")!.SetValue(false); |
| 41 | + |
| 42 | + var gameRulesProxie = Utilities.FindAllEntitiesByDesignerName<CCSGameRulesProxy>("cs_gamerules"); |
| 43 | + var CTeamArray = Utilities.FindAllEntitiesByDesignerName<CTeam>("cs_team_manager").ToArray(); |
| 44 | + gameRules = gameRulesProxie.First().GameRules!; |
| 45 | + foreach (var t in CTeamArray) |
| 46 | + { |
| 47 | + if (t.Teamname == "CT") |
| 48 | + Team_CT = t; |
| 49 | + if (t.Teamname == "TERRORIST") |
| 50 | + Team_T = t; |
| 51 | + } |
| 52 | + |
| 53 | + if (gameRules is null || Team_CT is null || Team_T is null) |
| 54 | + { |
| 55 | + Console.WriteLine("[C4 everywhere] Exception No Gamesrules/Team CTorT Found"); |
| 56 | + return; |
| 57 | + } |
| 58 | + |
26 | 59 | var Allplayers = Utilities.GetPlayers();
|
27 | 60 | foreach (var p in Allplayers)
|
28 | 61 | {
|
| 62 | + if (!p.IsValid) continue; |
29 | 63 | p.RemoveWeapons();
|
30 | 64 | p.GiveNamedItem(CsItem.C4);
|
31 | 65 | p.GiveNamedItem(CsItem.Knife);
|
32 |
| - //p.GiveNamedItem(CsItem.Kevlar); |
33 |
| - //p.GiveNamedItem(CsItem.KevlarHelmet); |
34 |
| - //p.GiveNamedItem<CItemHeavyAssaultSuit>("CItemHeavyAssaultSuit"); |
35 |
| - //CCSPlayerController player = Utilities.GetPlayerFromUserid(id); |
36 |
| - // DesignerName == "cs_gamerules" var gameRules = entity.As<CCSGameRules>(); CCSGameRulesProxy |
37 |
| - //var b = p.Buttons; mp_c4timer 20 mp_plant_c4_anywhere true mp_c4_cannot_be_defused true mp_anyone_can_pickup_c4 true |
38 |
| - //b.HasFlag(PlayerButtons.Forward); mp_ignore_round_win_conditions 0 |
| 66 | + p.RemoveAllItemsOnNextRoundReset = true; |
39 | 67 | }
|
| 68 | + plugin.RegisterEventHandler<EventBombPlanted> (EventBombPlantedHandler = (@event,info)=> |
| 69 | + { |
| 70 | + if (Enabled == false) return HookResult.Stop; |
| 71 | + var player = @event.Userid!.OriginalControllerOfCurrentPawn.Get(); |
| 72 | + if (player is null || !player.IsValid) return HookResult.Continue; |
| 73 | + player.GiveNamedItem(CsItem.C4); |
| 74 | + return HookResult.Continue; |
| 75 | + }); |
40 | 76 |
|
41 |
| - roundTimer = plugin.AddTimer(30, ()=>CTWin() , TimerFlags.STOP_ON_MAPCHANGE); |
| 77 | + if(gameRules.WarmupPeriod) return; |
42 | 78 |
|
43 |
| - plugin.RegisterEventHandler<EventPlayerDeath> ((@event,info)=> |
| 79 | + roundTimer = plugin.AddTimer(120, ()=>CTWin() , TimerFlags.STOP_ON_MAPCHANGE); |
| 80 | + roundTimer60 = plugin.AddTimer(60, ()=>Server.PrintToChatAll(StringExtensions.ReplaceColorTags("{RED}") + "[C4 Everywhere] 60s Left 剩余60s") , TimerFlags.STOP_ON_MAPCHANGE); |
| 81 | + roundTimer90 = plugin.AddTimer(90, ()=>Server.PrintToChatAll(StringExtensions.ReplaceColorTags("{RED}") + "[C4 Everywhere] 30s Left 剩余30s") , TimerFlags.STOP_ON_MAPCHANGE); |
| 82 | + roundTimer110 = plugin.AddTimer(110, ()=>Server.PrintToChatAll(StringExtensions.ReplaceColorTags("{RED}") + "[C4 Everywhere] 10s Left 剩余10s") , TimerFlags.STOP_ON_MAPCHANGE); |
| 83 | + |
| 84 | + plugin.RegisterEventHandler<EventPlayerDeath> (EventPlayerDeathHandler = (@event,info)=> |
44 | 85 | {
|
45 |
| - var entities = Utilities.FindAllEntitiesByDesignerName<CBaseEntity>("cs_gamerules").ToArray(); |
46 |
| - foreach (var e in entities.Where(x => x.DesignerName == "cs_gamerules")) |
| 86 | + if (Enabled == false) return HookResult.Stop; |
| 87 | + if (TeamHasWon == true) return HookResult.Stop; |
| 88 | + int ct_num = AlivePlayerNum(CsTeam.CounterTerrorist); |
| 89 | + int t_num = AlivePlayerNum(CsTeam.Terrorist); |
| 90 | + if (@event.Userid is null || !@event.Userid.IsValid) return HookResult.Continue; |
| 91 | + if (@event.Userid.Team == CsTeam.CounterTerrorist) |
| 92 | + ct_num --; |
| 93 | + if (@event.Userid.Team == CsTeam.Terrorist) |
| 94 | + t_num --; |
| 95 | + if (t_num == 0 && ct_num == 0) |
47 | 96 | {
|
48 |
| - gameRules = e.As<CCSGameRules>(); |
49 |
| - Console.WriteLine($"PlayerKilled {gameRules.AccountCT} {gameRules.AccountTerrorist} {gameRules.NumCT} {gameRules.NumTerrorist}"); |
50 |
| - Console.WriteLine($"{gameRules.RoundEndFunFactData1} {gameRules.RoundEndReason} {gameRules.RoundEndWinnerTeam}"); |
51 |
| - //gameRules.TerminateRound(1,RoundEndReason.TerroristsWin); |
52 |
| - break; |
| 97 | + //gameRules.TerminateRound(3.0f,RoundEndReason.RoundDraw); |
| 98 | + TerminateRoundFix(3.0f,RoundEndReason.RoundDraw); |
| 99 | + roundTimer!.Kill(); |
| 100 | + roundTimer60!.Kill(); |
| 101 | + roundTimer90!.Kill(); |
| 102 | + roundTimer110!.Kill(); |
| 103 | + TeamHasWon = true; |
| 104 | + var q = @event.Userid.Team; |
53 | 105 | }
|
54 |
| - |
55 |
| - return HookResult.Continue; |
56 |
| - }); |
57 |
| - /* |
58 |
| - plugin.RegisterEventHandler<EventRoundFreezeEnd> ((@event,info)=> |
59 |
| - { |
60 |
| - var entities = Utilities.FindAllEntitiesByDesignerName<CBaseEntity> ("cs_gamerules"); |
61 |
| - foreach (var e in entities) |
| 106 | + else if (t_num == 0) |
| 107 | + { |
| 108 | + //gameRules.TerminateRound(3.0f,RoundEndReason.CTsWin); |
| 109 | + TerminateRoundFix(3.0f,RoundEndReason.TargetBombed); |
| 110 | + roundTimer!.Kill(); |
| 111 | + roundTimer60!.Kill(); |
| 112 | + roundTimer90!.Kill(); |
| 113 | + roundTimer110!.Kill(); |
| 114 | + TeamHasWon = true; |
| 115 | + Team_CT!.Score++; |
| 116 | + Utilities.SetStateChanged(Team_CT,"CTeam", "m_iScore"); |
| 117 | + } |
| 118 | + else if (ct_num == 0) |
62 | 119 | {
|
63 |
| - gameRules = e.As<CCSGameRules>(); |
64 |
| - break; |
| 120 | + //gameRules.TerminateRound(3.0f,RoundEndReason.TerroristsWin); |
| 121 | + TerminateRoundFix(3.0f,RoundEndReason.BombDefused); |
| 122 | + roundTimer!.Kill(); |
| 123 | + roundTimer60!.Kill(); |
| 124 | + roundTimer90!.Kill(); |
| 125 | + roundTimer110!.Kill(); |
| 126 | + TeamHasWon = true; |
| 127 | + Team_T!.Score++; |
| 128 | + Utilities.SetStateChanged(Team_T,"CTeam", "m_iScore"); |
65 | 129 | }
|
66 |
| - Console.WriteLine($"FreezeEnd {gameRules.AccountCT} {gameRules.AccountTerrorist} {gameRules.NumCT} {gameRules.NumTerrorist}"); |
67 |
| - //roundTimer = plugin.AddTimer(30, ()=>CTWin() , TimerFlags.STOP_ON_MAPCHANGE); |
68 |
| - return HookResult.Stop; |
| 130 | + return HookResult.Continue; |
69 | 131 | });
|
70 |
| - */ |
| 132 | + |
71 | 133 | }
|
72 | 134 | private void CTWin()
|
73 | 135 | {
|
74 |
| - var csEntities = Utilities.FindAllEntitiesByDesignerName<CBaseEntity>("cs_").ToArray(); |
75 |
| - foreach (var entity in csEntities.Where(x => x.DesignerName == "cs_gamerules")) |
| 136 | + //gameRules!.TerminateRound(0.1f,RoundEndReason.CTsWin); |
| 137 | + //gameRules!.RoundWinStatus = 8; |
| 138 | + //gameRules!.TotalRoundsPlayed++; |
| 139 | + //gameRules!.ITotalRoundsPlayed++; |
| 140 | + TerminateRoundFix(3.0f,RoundEndReason.CTsWin); |
| 141 | + roundTimer!.Kill(); |
| 142 | + roundTimer60!.Kill(); |
| 143 | + roundTimer90!.Kill(); |
| 144 | + roundTimer110!.Kill(); |
| 145 | + TeamHasWon = true; |
| 146 | + Team_CT!.Score++; |
| 147 | + Utilities.SetStateChanged(Team_CT,"CTeam", "m_iScore"); |
| 148 | + |
| 149 | + } |
| 150 | + |
| 151 | + private int AlivePlayerNum(CsTeam csTeam) |
| 152 | + { |
| 153 | + int players = 0; |
| 154 | + foreach (var player in Utilities.GetPlayers().Where(player => player.IsValid && player.Connected == PlayerConnectedState.PlayerConnected && player.PawnIsAlive)) |
76 | 155 | {
|
77 |
| - // gameRules not working https://github.com/roflmuffin/CounterStrikeSharp/issues/489 |
78 |
| - var gameRules = entity.As<CCSGameRules>(); |
79 |
| - gameRules.CTTimeOutActive = true; |
80 |
| - gameRules.TerminateRound(0,RoundEndReason.CTsWin); |
| 156 | + if (player.Team == csTeam) |
| 157 | + players++; |
81 | 158 | }
|
82 |
| - ConVar.Find("mp_ignore_round_win_conditions")!.SetValue(false); |
83 |
| - Console.WriteLine("CTWIN"); |
84 |
| - } |
| 159 | + return players; |
| 160 | + } |
| 161 | + |
85 | 162 | public override void EndFun(FunMatchPlugin plugin)
|
86 | 163 | {
|
87 | 164 | Enabled = false;
|
| 165 | + ConVar.Find("sv_cheats")!.SetValue(true); |
88 | 166 | ConVar.Find("mp_autokick")!.SetValue(true);
|
89 | 167 | ConVar.Find("mp_c4timer")!.SetValue(40);
|
90 | 168 | ConVar.Find("mp_plant_c4_anywhere")!.SetValue(false);
|
91 | 169 | ConVar.Find("mp_c4_cannot_be_defused")!.SetValue(false);
|
92 | 170 | ConVar.Find("mp_anyone_can_pickup_c4")!.SetValue(false);
|
93 | 171 | ConVar.Find("mp_ignore_round_win_conditions")!.SetValue(false);
|
94 |
| - //roundTimer.Kill(); |
| 172 | + ConVar.Find("sv_cheats")!.SetValue(false); |
| 173 | + if (roundTimer is not null) |
| 174 | + roundTimer!.Kill(); |
| 175 | + if (roundTimer60 is not null) |
| 176 | + roundTimer60!.Kill(); |
| 177 | + if (roundTimer90 is not null) |
| 178 | + roundTimer90!.Kill(); |
| 179 | + if (roundTimer110 is not null) |
| 180 | + roundTimer110!.Kill(); |
| 181 | + TeamHasWon = false; |
| 182 | + if (EventBombPlantedHandler is not null) |
| 183 | + plugin.DeregisterEventHandler(EventBombPlantedHandler); |
| 184 | + if (EventPlayerDeathHandler is not null) |
| 185 | + plugin.DeregisterEventHandler(EventPlayerDeathHandler); |
| 186 | + |
| 187 | + } |
| 188 | + |
| 189 | + // to be fixed in https://github.com/roflmuffin/CounterStrikeSharp/issues/489 |
| 190 | + public void TerminateRoundFix(float delay, RoundEndReason roundEndReason) |
| 191 | + { |
| 192 | + if (gameRules is null) return; |
| 193 | + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
| 194 | + TerminateRound(gameRules!.Handle,delay, roundEndReason, 0, 0); |
| 195 | + else |
| 196 | + TerminateRoundLinux(gameRules!.Handle, roundEndReason, 0, 0, delay); |
| 197 | + |
95 | 198 | }
|
| 199 | + public static MemoryFunctionVoid<nint, float, RoundEndReason, nint, uint> TerminateRoundFunc = |
| 200 | + new(GameData.GetSignature("CCSGameRules_TerminateRound")); |
| 201 | + public static Action<IntPtr, float, RoundEndReason, nint, uint> TerminateRound = TerminateRoundFunc.Invoke; |
| 202 | + public static MemoryFunctionVoid<nint, RoundEndReason, nint, uint, float> TerminateRoundLinuxFunc = |
| 203 | + new(GameData.GetSignature("CCSGameRules_TerminateRound")); |
| 204 | + public static Action<IntPtr, RoundEndReason, nint, uint, float> TerminateRoundLinux = TerminateRoundLinuxFunc.Invoke; |
| 205 | + |
96 | 206 | }
|
97 | 207 |
|
0 commit comments