public static bool GiveClass(Player p, SubClass subClass, bool lite = false) { if (PlayerHasSubclass(p) || !subClass.AffectsRoles.Contains(p.Role)) { return(false); } if (Subclass.Instance.Scp035Enabled) { Player scp035 = (Player)Loader.Plugins.First(pl => pl.Name == "scp035").Assembly.GetType("scp035.API.Scp035Data").GetMethod("GetScp035", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); TrackingAndMethods.AddClass(p, subClass, Subclass.Instance.Scp035Enabled && scp035?.Id == p.Id, lite); return(true); } TrackingAndMethods.AddClass(p, subClass, false, lite); return(true); }
public void OnSpawning(SpawningEventArgs ev) { Timing.CallDelayed(Subclass.Instance.CommonUtilsEnabled ? 2f : 0.1f, () => { if (!Subclass.Instance.RealisticSizesEnabled) { ev.Player.Scale = new Vector3(1, 1, 1); } try { TrackingAndMethods.RemoveZombie(ev.Player); TrackingAndMethods.QueuedCassieMessages.Clear(); if (TrackingAndMethods.NextSpawnWave.Contains(ev.Player) && TrackingAndMethods.NextSpawnWaveGetsRole.ContainsKey(ev.Player.Role)) { TrackingAndMethods.AddClass(ev.Player, TrackingAndMethods.NextSpawnWaveGetsRole[ev.Player.Role]); } else { if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(ev.Player)) { if (Subclass.Instance.Scp035Enabled) { EPlayer scp035 = (EPlayer)Loader.Plugins.First(pl => pl.Name == "scp035").Assembly.GetType("scp035.API.Scp035Data").GetMethod("GetScp035", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); TrackingAndMethods.RemoveAndAddRoles(ev.Player, false, scp035?.Id == ev.Player.Id); } else { TrackingAndMethods.RemoveAndAddRoles(ev.Player, false, false); } } } foreach (string message in TrackingAndMethods.QueuedCassieMessages) { Cassie.Message(message, true, false); Log.Debug($"Sending message via cassie: {message}", Subclass.Instance.Config.Debug); } Timing.RunCoroutine(TrackingAndMethods.CheckRoundEnd()); } catch (Exception e) { Log.Error(e); } }); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { if (sender is PlayerCommandSender player) { Player p = Player.Get(player.SenderId); if (!p.CheckPermission("sc.giveclass")) { response = "You do not have the necessary permissions to run this command. Requires: sc.giveclass"; return(false); } if (arguments.Count == 0) { response = "Command syntax should be subclass (player id/all) [class]."; return(false); } try { if (Player.Get(int.Parse(arguments.Array[arguments.Offset])) != null) { Player player1 = Player.Get(int.Parse(arguments.Array[arguments.Offset])); if (!Subclass.Instance.Classes.ContainsKey(string.Join(" ", arguments.Array.Segment(arguments.Offset + 1)))) { response = "Class not found."; return(false); } else { SubClass sc = Subclass.Instance.Classes[string.Join(" ", arguments.Array.Segment(arguments.Offset + 1))]; if (!sc.AffectsRoles.Contains(player1.Role)) { player1.SetRole(sc.AffectsRoles[rnd.Next(sc.AffectsRoles.Count)], true); } TrackingAndMethods.RemoveAndAddRoles(player1, true); TrackingAndMethods.AddClass(player1, sc); response = "Success."; return(true); } } else { if (Subclass.Instance.Classes.ContainsKey(string.Join(" ", arguments.Array.Segment(arguments.Offset)))) { SubClass sc = Subclass.Instance.Classes[string.Join(" ", arguments.Array.Segment(arguments.Offset))]; if (!sc.AffectsRoles.Contains(p.Role)) { p.SetRole(sc.AffectsRoles[rnd.Next(sc.AffectsRoles.Count)], true); } TrackingAndMethods.RemoveAndAddRoles(p, true); TrackingAndMethods.AddClass(p, sc); response = "Success."; return(true); } response = "Player not found."; return(false); } } catch { if (arguments.Array[arguments.Offset].ToLower() != "all") { if (!Subclass.Instance.Classes.ContainsKey(string.Join(" ", arguments.Array.Segment(arguments.Offset)))) { response = "Class not found."; return(false); } else { SubClass sc = Subclass.Instance.Classes[string.Join(" ", arguments.Array.Segment(arguments.Offset))]; if (!sc.AffectsRoles.Contains(p.Role)) { p.SetRole(sc.AffectsRoles[rnd.Next(sc.AffectsRoles.Count)], true); } TrackingAndMethods.RemoveAndAddRoles(p, true); TrackingAndMethods.AddClass(p, sc); response = "Success."; return(true); } } else { if (!Subclass.Instance.Classes.ContainsKey(string.Join(" ", arguments.Array.Segment(arguments.Offset + 1)))) { response = "Class not found."; return(false); } else { SubClass sc = Subclass.Instance.Classes[string.Join(" ", arguments.Array.Segment(arguments.Offset + 1))]; foreach (Player p1 in Player.List) { if (p1.Role == RoleType.Spectator) { continue; } if (!sc.AffectsRoles.Contains(p1.Role)) { p1.SetRole(sc.AffectsRoles[rnd.Next(sc.AffectsRoles.Count)], true); } TrackingAndMethods.RemoveAndAddRoles(p1, true); TrackingAndMethods.AddClass(p1, sc); } response = "Success."; return(true); } } } } response = ""; return(false); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Disguise)) { Log.Debug($"Player {player.Nickname} could not disguise", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.Disguise, subClass)) { Log.Debug($"Player {player.Nickname} failed to disguise", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Disguise, subClass, "disguise", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Disguise, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Disguise, subClass, "disguise"); response = ""; return(true); } Team mostTeam = Team.RIP; Dictionary <Team, int> occurrences = new Dictionary <Team, int>(); Collider[] dcolliders = Physics.OverlapSphere(player.Position, 50); foreach (Collider c in dcolliders.Where(c => c.enabled && Player.Get(c.gameObject) != null)) { Team t = Player.Get(c.gameObject).Team; if (t == Team.CDP) { t = Team.CHI; } if (t == Team.RSC) { t = Team.MTF; } if (!occurrences.ContainsKey(t)) { occurrences.Add(t, 0); } occurrences[t]++; } var copy = occurrences.ToList(); copy.Sort((x, y) => y.Value.CompareTo(x.Value)); mostTeam = copy[0].Key; if (mostTeam == player.Team || mostTeam == Team.RIP || mostTeam == Team.SCP) { Log.Debug($"Player {player.Nickname} failed to disguise", Subclass.Instance.Config.Debug); player.Broadcast(3, Subclass.Instance.Config.DisguiseFailedMessage); response = ""; return(true); } RoleType role = RoleType.None; switch (mostTeam) { case Team.CDP: role = RoleType.ClassD; break; case Team.CHI: role = RoleType.ChaosInsurgency; break; case Team.MTF: role = RoleType.NtfCadet; break; case Team.RSC: role = RoleType.Scientist; break; case Team.TUT: role = RoleType.Tutorial; break; } bool wasLockedBefore = Round.IsLocked; Round.IsLocked = true; TrackingAndMethods.AddCooldown(player, AbilityType.Disguise); TrackingAndMethods.UseAbility(player, AbilityType.Disguise, subClass); TrackingAndMethods.PlayersThatJustGotAClass[player] = Time.time + 5f; TrackingAndMethods.RemoveAndAddRoles(player, true, false, false, true); float health = player.Health; float armor = player.ArtificialHealth; int maxHealth = player.MaxHealth; int maxArmor = player.MaxArtificialHealth; RoleType trueRole = player.Role; SubClass cloneClass = new SubClass(subClass); cloneClass.BoolOptions["TakesFriendlyFire"] = true; player.SetRole(role, true); Timing.CallDelayed(0.1f, () => { player.Health = health; player.ArtificialHealth = armor; player.IsFriendlyFireEnabled = true; Player scp035 = null; if (Subclass.Instance.Scp035Enabled) { scp035 = (Player)Loader.Plugins.FirstOrDefault(pl => pl.Name == "scp035")?.Assembly?.GetType("scp035.API.Scp035Data") ?.GetMethod("GetScp035", BindingFlags.Public | BindingFlags.Static)?.Invoke(null, null); } TrackingAndMethods.AddClass(player, cloneClass, scp035?.Id == player.Id, true, false, true); }); if (subClass.StringOptions.ContainsKey("Badge") && player.RankName == subClass.StringOptions["Badge"]) { player.RankName = null; } if (subClass.StringOptions.ContainsKey("BadgeColor") && player.RankColor == subClass.StringOptions["BadgeColor"]) { player.RankColor = null; } Timing.CallDelayed(subClass.FloatOptions["DisguiseDuration"], () => { if (!player.IsAlive) { return; } TrackingAndMethods.PlayersThatJustGotAClass[player] = Time.time + 5f; TrackingAndMethods.RemoveAndAddRoles(player, true, false, false, true); float curHealth = player.Health; float curArmor = player.ArtificialHealth; player.SetRole(trueRole, true); Timing.CallDelayed(Subclass.Instance.CommonUtilsEnabled ? 2f : 0.1f, () => { Player scp035 = null; if (Subclass.Instance.Scp035Enabled) { scp035 = (Player)Loader.Plugins.FirstOrDefault(pl => pl.Name == "scp035")?.Assembly?.GetType("scp035.API.Scp035Data") ?.GetMethod("GetScp035", BindingFlags.Public | BindingFlags.Static)?.Invoke(null, null); } TrackingAndMethods.AddClass(player, subClass, scp035?.Id == player.Id, true, false, true); player.MaxHealth = maxHealth; player.MaxArtificialHealth = maxArmor; player.Health = curHealth; player.ArtificialHealth = curArmor; player.IsFriendlyFireEnabled = !subClass.BoolOptions["DisregardHasFF"] && subClass.BoolOptions["HasFriendlyFire"]; }); if (subClass.StringOptions.ContainsKey("Badge") && player.RankName == null) { player.RankName = subClass.StringOptions["Badge"]; } if (subClass.StringOptions.ContainsKey("BadgeColor") && player.RankColor == null) { player.RankColor = subClass.StringOptions["BadgeColor"]; } Round.IsLocked = wasLockedBefore; }); response = ""; return(true); }
public static void AttemptRevive(Player player, SubClass subClass, bool necro = false) { Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} attempt", Subclass.Instance.Config.Debug); AbilityType ability = necro ? AbilityType.Necromancy : AbilityType.Revive; if (TrackingAndMethods.OnCooldown(player, ability, subClass)) { Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} on cooldown", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, necro ? AbilityType.Necromancy : AbilityType.Revive, subClass, necro ? "necromancy" : "revive", Time.time); return; } List <Collider> colliders = Physics.OverlapSphere(player.Position, 3f).Where(e => e.gameObject.GetComponentInParent <Ragdoll>() != null).ToList(); colliders.Sort((Collider x, Collider y) => { return(Vector3.Distance(x.gameObject.transform.position, player.Position).CompareTo(Vector3.Distance(y.gameObject.transform.position, player.Position))); }); if (colliders.Count == 0) { player.Broadcast(2, Subclass.Instance.Config.ReviveFailedNoBodyMessage); Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} overlap did not hit a ragdoll", Subclass.Instance.Config.Debug); return; } Ragdoll doll = colliders[0].gameObject.GetComponentInParent <Ragdoll>(); if (doll.owner == null) { Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} failed", Subclass.Instance.Config.Debug); player.Broadcast(2, Subclass.Instance.Config.CantReviveMessage); return; } if (doll.owner.DeathCause.GetDamageType() == DamageTypes.Lure) { Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} failed", Subclass.Instance.Config.Debug); player.Broadcast(2, Subclass.Instance.Config.CantReviveMessage); return; } Player owner = Player.Get(doll.owner.PlayerId); if (owner != null && !owner.IsAlive) { bool revived = false; if (!necro && TrackingAndMethods.GetPreviousTeam(owner) != null && TrackingAndMethods.GetPreviousTeam(owner) == player.Team && TrackingAndMethods.RagdollRole(doll) != null && TrackingAndMethods.RagdollRole(doll) == TrackingAndMethods.GetPreviousRole(owner)) { if (TrackingAndMethods.PlayersThatJustGotAClass.ContainsKey(owner)) { TrackingAndMethods.PlayersThatJustGotAClass[owner] = Time.time + 3f; } else { TrackingAndMethods.PlayersThatJustGotAClass.Add(owner, Time.time + 3f); } owner.SetRole((RoleType)TrackingAndMethods.GetPreviousRole(owner), true); if (TrackingAndMethods.PreviousSubclasses.ContainsKey(owner) && TrackingAndMethods.PreviousSubclasses[owner].AffectsRoles.Contains((RoleType)TrackingAndMethods.GetPreviousRole(owner))) { TrackingAndMethods.AddClass(owner, TrackingAndMethods.PreviousSubclasses[owner], false, true); } owner.Inventory.Clear(); revived = true; } else if (necro) { owner.Role = RoleType.Scp0492; TrackingAndMethods.AddZombie(player, owner); owner.IsFriendlyFireEnabled = true; revived = true; } if (revived) { Timing.CallDelayed(0.2f, () => { owner.ReferenceHub.playerMovementSync.OverridePosition(player.Position + new Vector3(0.3f, 1f, 0), 0, true); if (subClass.FloatOptions.ContainsKey("PercentHealthOnRevive") && !necro) { owner.Health *= (subClass.FloatOptions["PercentHealthOnRevive"] / 100f); } else if (subClass.FloatOptions.ContainsKey("PercentHealthOnNecro") && necro) { owner.Health *= (subClass.FloatOptions["PercentHealthOnNecro"] / 100f); } }); NetworkServer.Destroy(doll.gameObject); TrackingAndMethods.AddCooldown(player, ability); TrackingAndMethods.UseAbility(player, ability, subClass); Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} succeeded", Subclass.Instance.Config.Debug); } else { Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} failed", Subclass.Instance.Config.Debug); player.Broadcast(2, Subclass.Instance.Config.CantReviveMessage); } } else { Log.Debug($"Player {player.Nickname} {(necro ? "necromancy" : "revive")} failed", Subclass.Instance.Config.Debug); player.Broadcast(2, Subclass.Instance.Config.CantReviveMessage); } }