public void OnRoundEnded(RoundEndedEventArgs ev) { // I may just consider using reflection and just loop over all members and clear them if I can. TrackingAndMethods.KillAllCoroutines(); TrackingAndMethods.Coroutines.Clear(); TrackingAndMethods.PlayersWithSubclasses.Clear(); TrackingAndMethods.Cooldowns.Clear(); TrackingAndMethods.FriendlyFired.Clear(); TrackingAndMethods.PlayersThatBypassedTeslaGates.Clear(); TrackingAndMethods.PreviousRoles.Clear(); TrackingAndMethods.PlayersWithZombies.Clear(); TrackingAndMethods.PlayersThatHadZombies.Clear(); TrackingAndMethods.QueuedCassieMessages.Clear(); TrackingAndMethods.NextSpawnWave.Clear(); TrackingAndMethods.NextSpawnWaveGetsRole.Clear(); TrackingAndMethods.PlayersThatJustGotAClass.Clear(); TrackingAndMethods.SubClassesSpawned.Clear(); TrackingAndMethods.PreviousSubclasses.Clear(); TrackingAndMethods.PreviousBadges.Clear(); TrackingAndMethods.RagdollRoles.Clear(); TrackingAndMethods.AbilityUses.Clear(); TrackingAndMethods.PlayersInvisibleByCommand.Clear(); TrackingAndMethods.PlayersVenting.Clear(); TrackingAndMethods.NumSpawnWaves.Clear(); TrackingAndMethods.SpawnWaveSpawns.Clear(); TrackingAndMethods.ClassesGiven.Clear(); TrackingAndMethods.DontGiveClasses.Clear(); TrackingAndMethods.PlayersBloodLusting.Clear(); TrackingAndMethods.Zombie106Kills.Clear(); API.EnableAllClasses(); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { response = ""; Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Punch) || player.IsCuffed) { Log.Debug($"Player {player.Nickname} could not use the punch command", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (!subClass.Abilities.Contains(AbilityType.InfiniteSprint)) { if ((player.Stamina.RemainingStamina * 100) - (subClass.FloatOptions.ContainsKey("PunchStaminaUse") ? subClass.FloatOptions["PunchStaminaUse"] : 10) <= 0) { Log.Debug($"Player {player.Nickname} failed to use the punch command", Subclass.Instance.Config.Debug); player.Broadcast(5, Subclass.Instance.Config.OutOfStaminaMessage); return(true); } player.Stamina.RemainingStamina = Mathf.Clamp( player.Stamina.RemainingStamina - (subClass.FloatOptions.ContainsKey("PunchStaminaUse") ? subClass.FloatOptions["PunchStaminaUse"] / 100 : .1f), 0, 1); player.Stamina._regenerationTimer = 0; } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Punch, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Punch, subClass, "punch"); response = ""; return(true); } if (TrackingAndMethods.OnCooldown(player, AbilityType.Punch, subClass)) { Log.Debug($"Player {player.Nickname} failed to use punch", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Punch, subClass, "punch", Time.time); response = ""; return(true); } if (Physics.Raycast(player.CameraTransform.position, player.CameraTransform.forward, out RaycastHit hit, (subClass.FloatOptions.ContainsKey("PunchRange") ? subClass.FloatOptions["PunchRange"] : 1.3f))) { Player target = Player.Get(hit.collider.gameObject) ?? Player.Get(hit.collider.GetComponentInParent <ReferenceHub>()); if (target == null || target.Id == player.Id) { return(true); } TrackingAndMethods.AddCooldown(player, AbilityType.Punch); TrackingAndMethods.UseAbility(player, AbilityType.Punch, subClass); target.Hurt(subClass.FloatOptions["PunchDamage"], null, player.Nickname, player.Id); } return(true); }
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.FlashOnCommand)) { SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (!TrackingAndMethods.CanUseAbility(player, AbilityType.FlashOnCommand, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.FlashOnCommand, subClass, "flash on command"); response = ""; return(true); } if (TrackingAndMethods.OnCooldown(player, AbilityType.FlashOnCommand, subClass)) { Log.Debug($"Player {player.Nickname} failed to flash on command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.FlashOnCommand, subClass, "flash", Time.time); response = ""; return(true); } Utils.SpawnGrenade(ItemType.GrenadeFlash, player, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.FlashOnCommand); TrackingAndMethods.UseAbility(player, AbilityType.FlashOnCommand, subClass); Log.Debug($"Player {player.Nickname} successfully used flash on commad", Subclass.Instance.Config.Debug); } else { Log.Debug($"Player {player.Nickname} could not flash on command", Subclass.Instance.Config.Debug); } response = ""; return(true); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { response = ""; Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Fake)) { Log.Debug($"Player {player.Nickname} could not use the fake command", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.Fake, subClass)) { Log.Debug($"Player {player.Nickname} failed to use the fake command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Fake, subClass, "fake", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Fake, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Fake, subClass, "fake"); response = ""; return(true); } Role role = player.ReferenceHub.characterClassManager.Classes.SafeGet((int)player.Role); if (role.model_ragdoll == null) { return(false); } player.EnableEffect <Ensnared>(subClass.FloatOptions.ContainsKey("FakeDuration") ? subClass.FloatOptions["FakeDuration"] : 3); player.EnableEffect <Scp268>(subClass.FloatOptions.ContainsKey("FakeDuration") ? subClass.FloatOptions["FakeDuration"] : 3); GameObject gameObject = UnityEngine.Object.Instantiate <GameObject>(role.model_ragdoll, player.Position + role.ragdoll_offset.position, Quaternion.Euler(player.GameObject.transform.rotation.eulerAngles + role.ragdoll_offset.rotation)); NetworkServer.Spawn(gameObject); Ragdoll component = gameObject.GetComponent <Ragdoll>(); component.Networkowner = new Ragdoll.Info(player.UserId, player.Nickname, new PlayerStats.HitInfo(0, player.Nickname, DamageTypes.Falldown, player.Id), role, player.Id); component.NetworkallowRecall = false; component.NetworkPlayerVelo = (player.ReferenceHub.playerMovementSync == null) ? Vector3.zero : player.ReferenceHub.playerMovementSync.PlayerVelocity; TrackingAndMethods.UseAbility(player, AbilityType.Fake, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.Fake); Timing.CallDelayed(subClass.FloatOptions.ContainsKey("FakeDuration") ? subClass.FloatOptions["FakeDuration"] : 3, () => { UnityEngine.Object.DestroyImmediate(gameObject); }); return(true); }
public static float TimeLeftOnCooldown(Player p, AbilityType ability) { if (!PlayerHasSubclass(p)) { return(0); } return(TrackingAndMethods.TimeLeftOnCooldown(p, ability, TrackingAndMethods.PlayersWithSubclasses[p], Time.time)); }
public static bool AbilityOnCooldown(Player p, AbilityType ability) { if (!PlayerHasSubclass(p)) { return(false); } return(TrackingAndMethods.OnCooldown(p, ability, TrackingAndMethods.PlayersWithSubclasses[p])); }
public void OnExplodingGrenade(ExplodingGrenadeEventArgs ev) { if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(ev.Thrower) || (!TrackingAndMethods.PlayersWithSubclasses[ev.Thrower].Abilities.Contains(AbilityType.HealGrenadeFlash) && !TrackingAndMethods.PlayersWithSubclasses[ev.Thrower].Abilities.Contains(AbilityType.HealGrenadeFrag))) { Log.Debug($"Player with name {ev.Thrower.Nickname} has no subclass", Subclass.Instance.Config.Debug); return; } if (TrackingAndMethods.PlayersWithSubclasses[ev.Thrower].Abilities.Contains(AbilityType.HealGrenadeFlash) && !ev.IsFrag) { if (!TrackingAndMethods.CanUseAbility(ev.Thrower, AbilityType.HealGrenadeFlash, TrackingAndMethods.PlayersWithSubclasses[ev.Thrower])) { TrackingAndMethods.DisplayCantUseAbility(ev.Thrower, AbilityType.HealGrenadeFlash, TrackingAndMethods.PlayersWithSubclasses[ev.Thrower], "heal flash"); return; } TrackingAndMethods.UseAbility(ev.Thrower, AbilityType.HealGrenadeFlash, TrackingAndMethods.PlayersWithSubclasses[ev.Thrower]); ev.IsAllowed = false; UpdateHealths(ev, "HealGrenadeFlashHealAmount"); } else if (TrackingAndMethods.PlayersWithSubclasses[ev.Thrower].Abilities.Contains(AbilityType.HealGrenadeFrag) && ev.IsFrag) { if (!TrackingAndMethods.CanUseAbility(ev.Thrower, AbilityType.HealGrenadeFrag, TrackingAndMethods.PlayersWithSubclasses[ev.Thrower])) { TrackingAndMethods.DisplayCantUseAbility(ev.Thrower, AbilityType.HealGrenadeFrag, TrackingAndMethods.PlayersWithSubclasses[ev.Thrower], "heal frag"); return; } TrackingAndMethods.UseAbility(ev.Thrower, AbilityType.HealGrenadeFrag, TrackingAndMethods.PlayersWithSubclasses[ev.Thrower]); ev.IsAllowed = false; UpdateHealths(ev, "HealGrenadeFragHealAmount"); } //if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Thrower)) //{ // foreach (EPlayer target in ev.Targets) // { // if (target.Team != ev.Thrower.Team) continue; // if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Thrower) && Tracking.PlayersWithSubclasses.ContainsKey(target) && // Tracking.PlayersWithSubclasses[ev.Thrower].AdvancedFFRules.Contains(Tracking.PlayersWithSubclasses[target].Name)) // { // target.Hurt(ev.TargetToDamages[target], DamageTypes.Grenade); // continue; // } // if (Tracking.FriendlyFired.Contains(target) || (Tracking.PlayersWithSubclasses.ContainsKey(ev.Thrower) && // !Tracking.PlayersWithSubclasses[ev.Thrower].BoolOptions["DisregardHasFF"] && // Tracking.PlayersWithSubclasses[ev.Thrower].BoolOptions["HasFriendlyFire"]) || // (Tracking.PlayersWithSubclasses.ContainsKey(target) && !Tracking.PlayersWithSubclasses[target].BoolOptions["DisregardTakesFF"] && // Tracking.PlayersWithSubclasses[target].BoolOptions["TakesFriendlyFire"])) // { // if (!Tracking.FriendlyFired.Contains(target) && !Tracking.PlayersWithSubclasses[target].BoolOptions["TakesFriendlyFire"]) // Tracking.AddToFF(ev.Thrower); // target.Hurt(ev.TargetToDamages[target], DamageTypes.Grenade); // //ev.IsAllowed = true; // } // } //} }
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.Summon)) { Log.Debug($"Player {player.Nickname} could not use summon", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.Summon, subClass)) { Log.Debug($"Player {player.Nickname} failed to summon", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Summon, subClass, "summon", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Summon, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Summon, subClass, "summon"); response = ""; return(true); } int min = subClass.IntOptions.ContainsKey("SummonMinSpawn") ? subClass.IntOptions["SummonMinSpawn"] : 1; int max = subClass.IntOptions.ContainsKey("SummonMaxSpawn") ? subClass.IntOptions["SummonMaxSpawn"] : 5; List <Player> spectators = Player.List.Where(p => p.Role == RoleType.Spectator).ToList(); if (spectators.Count == 0) { player.Broadcast(2, Subclass.Instance.Config.NoAvailableSpectators); response = ""; return(true); } TrackingAndMethods.UseAbility(player, AbilityType.Summon, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.Summon); int spawns = Mathf.Clamp((int)(rnd.NextDouble() * ((max - min) + 1)) + min, 0, spectators.Count); for (int i = 0; i < spawns; i++) { int index = rnd.Next(spectators.Count); Player p = spectators[index]; spectators.RemoveAt(index); p.Role = RoleType.Scp0492; p.IsFriendlyFireEnabled = true; p.Position = player.Position + new Vector3(rnd.Next(-2, 2), 1, rnd.Next(-2, 2)); TrackingAndMethods.AddZombie(player, p); } response = ""; return(true); }
public static bool RemoveClass(Player p) { if (!PlayerHasSubclass(p)) { return(false); } TrackingAndMethods.RemoveAndAddRoles(p, true); return(true); }
public override void OnDisabled() { base.OnDisabled(); Log.Info("Subclass disabled."); UnregisterEvents(); HarmonyInstance.UnpatchAll(); foreach (Exiled.API.Features.Player player in Exiled.API.Features.Player.List) { TrackingAndMethods.RemoveAndAddRoles(player, true); } Instance = null; }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { response = ""; Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Bloodlust)) { Log.Debug($"Player {player.Nickname} could not use the bloodlust command", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.Bloodlust, subClass)) { Log.Debug($"Player {player.Nickname} failed to use the bloodlust command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Bloodlust, subClass, "bloodlust", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Bloodlust, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Bloodlust, subClass, "bloodlust"); response = ""; return(true); } Scp207 scp207 = player.ReferenceHub.playerEffectsController.GetEffect <Scp207>(); byte prevIntensity = scp207.Intensity; scp207.ServerChangeIntensity((byte)subClass.IntOptions["BloodlustIntensity"]); scp207.ServerChangeDuration(subClass.FloatOptions["BloodlustDuration"], false); TrackingAndMethods.PlayersBloodLusting.Add(player); TrackingAndMethods.UseAbility(player, AbilityType.Bloodlust, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.Bloodlust); Timing.CallDelayed(subClass.FloatOptions["BloodlustDuration"], () => { if (TrackingAndMethods.PlayersBloodLusting.Contains(player)) { TrackingAndMethods.PlayersBloodLusting.Remove(player); } scp207.ServerChangeIntensity(prevIntensity); scp207.ServerChangeDuration(float.MaxValue, false); }); return(true); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { response = ""; Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Corrupt)) { Log.Debug($"Player {player.Nickname} could not use the corrupt command", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.Corrupt, subClass)) { Log.Debug($"Player {player.Nickname} failed to use the corrupt command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Corrupt, subClass, "corrupt", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Corrupt, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Corrupt, subClass, "corrupt"); response = ""; return(true); } Collider[] colliders = Physics.OverlapSphere(player.Position, (subClass.FloatOptions.ContainsKey("CorruptRange") ? subClass.FloatOptions["CorruptRange"] : 10f)); IEnumerable <Player> players = colliders.Select(c => Player.Get(c.gameObject)).Distinct(); if (players.Count() > 0) { TrackingAndMethods.UseAbility(player, AbilityType.Corrupt, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.Corrupt); foreach (Player target in players) { if (target == null || target.Id == player.Id || player.Side == target.Side || (player.Team == Team.SCP && target.Team == Team.TUT)) { continue; } target.EnableEffect <SinkHole>((subClass.FloatOptions.ContainsKey("CorruptDuration") ? subClass.FloatOptions["CorruptDuration"] : 3)); } } return(true); }
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 bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { response = ""; Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Stun) || player.IsCuffed) { Log.Debug($"Player {player.Nickname} could not use the punch command", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.Stun, subClass)) { Log.Debug($"Player {player.Nickname} failed to use the stun command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Stun, subClass, "stun", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Stun, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Stun, subClass, "stun"); response = ""; return(true); } if (Physics.Raycast(player.CameraTransform.position, player.CameraTransform.forward, out RaycastHit hit, (subClass.FloatOptions.ContainsKey("StunRange") ? subClass.FloatOptions["StunRange"] : 1.3f))) { Player target = Player.Get(hit.collider.gameObject) ?? Player.Get(hit.collider.GetComponentInParent <ReferenceHub>()); if (target == null || target.Id == player.Id || player.Side == target.Side || (player.Team == Team.SCP && target.Team == Team.TUT)) { return(true); } TrackingAndMethods.UseAbility(player, AbilityType.Stun, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.Stun); target.Hurt(subClass.FloatOptions["StunDamage"], null, player.Nickname, player.Id); target.EnableEffect <Ensnared>(subClass.FloatOptions.ContainsKey("StunDuration") ? subClass.FloatOptions["StunDuration"] : 3); target.EnableEffect <Blinded>(subClass.FloatOptions.ContainsKey("StunDuration") ? subClass.FloatOptions["StunDuration"] : 3); } return(true); }
public void OnRoundStarted() { TrackingAndMethods.RoundStartedAt = Time.time; Timing.CallDelayed(Subclass.Instance.CommonUtilsEnabled ? 2f : 0.1f, () => { Log.Debug("Round started!", Subclass.Instance.Config.Debug); foreach (EPlayer player in EPlayer.List) { TrackingAndMethods.MaybeAddRoles(player); } foreach (string message in TrackingAndMethods.QueuedCassieMessages) { Cassie.Message(message, true, false); Log.Debug($"Sending message via cassie: {message}", Subclass.Instance.Config.Debug); } TrackingAndMethods.QueuedCassieMessages.Clear(); }); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (player.Role != RoleType.Scp93953 && player.Role != RoleType.Scp93989 && (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Scp939Vision))) { Log.Debug($"Player {player.Nickname} failed to echolocate", Subclass.Instance.Config.Debug); response = ""; return(true); } if (TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) && TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Echolocate)) { SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Echolocate, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Echolocate, subClass, "echolocate"); response = ""; return(true); } if (TrackingAndMethods.OnCooldown(player, AbilityType.Echolocate, subClass)) { Log.Debug($"Player {player.Nickname} failed to echolocate", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Echolocate, subClass, "echolocation", Time.time); response = ""; return(true); } Collider[] lcolliders = Physics.OverlapSphere(player.Position, subClass.FloatOptions.ContainsKey("EcholocateRadius") ? subClass.FloatOptions["EcholocateRadius"] : 10f); foreach (Collider PlayerCollider in lcolliders.Where(c => Player.Get(c.gameObject) != null)) { Player.Get(PlayerCollider.gameObject).ReferenceHub.footstepSync?.CmdScp939Noise(100f); } TrackingAndMethods.AddCooldown(player, AbilityType.Echolocate); TrackingAndMethods.UseAbility(player, AbilityType.Echolocate, subClass); Log.Debug($"Player {player.Nickname} successfully used echolocate", Subclass.Instance.Config.Debug); } response = ""; return(true); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { Player player = Player.Get(((PlayerCommandSender)sender).SenderId); Log.Debug($"Player {player.Nickname} is attempting to noclip", Subclass.Instance.Config.Debug); if (TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) && TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.NoClip)) { SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (!TrackingAndMethods.CanUseAbility(player, AbilityType.NoClip, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.NoClip, subClass, "noclip"); response = ""; return(true); } if (TrackingAndMethods.OnCooldown(player, AbilityType.NoClip, subClass)) { Log.Debug($"Player {player.Nickname} failed to noclip - cooldown", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.NoClip, subClass, "noclip", Time.time); response = ""; return(true); } bool previous = player.NoClipEnabled; player.NoClipEnabled = !player.NoClipEnabled; TrackingAndMethods.AddCooldown(player, AbilityType.NoClip); TrackingAndMethods.UseAbility(player, AbilityType.NoClip, subClass); if (subClass.FloatOptions.ContainsKey("NoClipTime")) { Timing.CallDelayed(subClass.FloatOptions["NoClipTime"], () => { if (player.NoClipEnabled != previous) { player.NoClipEnabled = previous; } }); } Log.Debug($"Player {player.Nickname} successfully noclipped", Subclass.Instance.Config.Debug); } else { Log.Debug($"Player {player.Nickname} could not noclip", Subclass.Instance.Config.Debug); } response = ""; 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) { Player player = Player.Get(((PlayerCommandSender)sender).SenderId); Log.Debug($"Player {player.Nickname} is attempting to revive", Subclass.Instance.Config.Debug); if (TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) && TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Revive)) { SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Revive, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Revive, subClass, "revive"); response = ""; return(false); } Utils.AttemptRevive(player, subClass, false); } response = ""; return(true); }
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.PowerSurge)) { Log.Debug($"Player {player.Nickname} could not use power surge", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.PowerSurge, subClass)) { Log.Debug($"Player {player.Nickname} failed to power surge", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.PowerSurge, subClass, "power surge", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.PowerSurge, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.PowerSurge, subClass, "power surge"); response = ""; return(true); } float radius = subClass.FloatOptions.ContainsKey("PowerSurgeRadius") ? subClass.FloatOptions["PowerSurgeRadius"] : 30f; foreach (Room room in Exiled.API.Features.Map.Rooms) { if (Vector3.Distance(room.Position, player.Position) <= radius) { room.TurnOffLights(subClass.FloatOptions.ContainsKey("PowerSurgeDuration") ? subClass.FloatOptions["PowerSurgeDuration"] : 15f); } } TrackingAndMethods.AddCooldown(player, AbilityType.PowerSurge); TrackingAndMethods.UseAbility(player, AbilityType.PowerSurge, subClass); response = ""; return(true); }
public void OnChangingRole(ChangingRoleEventArgs ev) { Timing.CallDelayed(Subclass.Instance.CommonUtilsEnabled ? 2f : 0.1f, () => { if (!ev.IsEscaped) { TrackingAndMethods.RemoveAndAddRoles(ev.Player); } }); object afkComp = ev.Player.GameObject.GetComponent("AFKComponent"); if (afkComp != null) { if (afkComp.GetType().GetMember("PlayerToReplace").Length > 0) { EPlayer p = (EPlayer)((FieldInfo)afkComp.GetType().GetMember("PlayerToReplace")[0]).GetValue(afkComp); if (p != null) { if (API.PlayerHasSubclass(ev.Player)) { SubClass subClass = API.GetPlayersSubclass(ev.Player); if (!TrackingAndMethods.PlayersThatJustGotAClass.ContainsKey(p)) { TrackingAndMethods.PlayersThatJustGotAClass.Add(p, Time.time + 5f); } else { TrackingAndMethods.PlayersThatJustGotAClass[p] = Time.time + 5f; } Timing.CallDelayed(1f, () => { API.GiveClass(p, subClass, true); }); } } } } }
public void OnInteractingDoor(InteractingDoorEventArgs ev) { if (TrackingAndMethods.PlayersVenting.Contains(ev.Player)) { ev.IsAllowed = false; Vector3 newPos = ev.Player.Position + (ev.Player.GameObject.transform.forward * 3.5f); newPos.y = ev.Player.Position.y; ev.Player.Position = newPos; return; } if (ev.Door is PryableDoor pryableDoor && (ev.Door.RequiredPermissions.RequiredPermissions != KeycardPermissions.None || ev.Door.ActiveLocks != 0) && !ev.Door.IsConsideredOpen() && ev.Player.CurrentItemIndex == -1) { if (TrackingAndMethods.PlayersWithSubclasses.ContainsKey(ev.Player)) { SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[ev.Player]; if (subClass.Abilities.Contains(AbilityType.PryGates)) { if (!TrackingAndMethods.CanUseAbility(ev.Player, AbilityType.PryGates, subClass)) { TrackingAndMethods.DisplayCantUseAbility(ev.Player, AbilityType.PryGates, subClass, "pry gates"); return; } if (TrackingAndMethods.OnCooldown(ev.Player, AbilityType.PryGates, subClass)) { TrackingAndMethods.DisplayCooldown(ev.Player, AbilityType.PryGates, subClass, "pry gates", Time.time); } else { TrackingAndMethods.AddCooldown(ev.Player, AbilityType.PryGates); TrackingAndMethods.UseAbility(ev.Player, AbilityType.PryGates, subClass); pryableDoor.TryPryGate(); } } } }
public void OnRespawningTeam(RespawningTeamEventArgs ev) { if (ev.Players.Count == 0 || !ev.IsAllowed) { return; } Team spawnedTeam = ev.NextKnownTeam == SpawnableTeamType.NineTailedFox ? Team.MTF : Team.CHI; if (!TrackingAndMethods.NumSpawnWaves.ContainsKey(spawnedTeam)) { TrackingAndMethods.NumSpawnWaves.Add(spawnedTeam, 0); } TrackingAndMethods.NumSpawnWaves[spawnedTeam]++; Timing.CallDelayed(5f, () => // Clear them after the wave spawns instead. { TrackingAndMethods.NextSpawnWave.Clear(); TrackingAndMethods.NextSpawnWaveGetsRole.Clear(); TrackingAndMethods.SpawnWaveSpawns.Clear(); }); bool ntfSpawning = ev.NextKnownTeam == Respawning.SpawnableTeamType.NineTailedFox; if (!Subclass.Instance.Config.AdditiveChance) { List <RoleType> hasRole = new List <RoleType>(); foreach (SubClass subClass in Subclass.Instance.Classes.Values.Where(e => e.BoolOptions["Enabled"] && (!e.IntOptions.ContainsKey("MaxSpawnPerRound") || TrackingAndMethods.ClassesSpawned(e) < e.IntOptions["MaxSpawnPerRound"]) && (ntfSpawning ? (e.AffectsRoles.Contains(RoleType.NtfCadet) || e.AffectsRoles.Contains(RoleType.NtfCommander) || e.AffectsRoles.Contains(RoleType.NtfLieutenant)) : e.AffectsRoles.Contains(RoleType.ChaosInsurgency)) && ((e.BoolOptions.ContainsKey("OnlyAffectsSpawnWave") && e.BoolOptions["OnlyAffectsSpawnWave"]) || (e.BoolOptions.ContainsKey("AffectsSpawnWave") && e.BoolOptions["AffectsSpawnWave"])) && (!e.BoolOptions.ContainsKey("WaitForSpawnWaves") || (e.BoolOptions["WaitForSpawnWaves"] && TrackingAndMethods.GetNumWavesSpawned(e.StringOptions.ContainsKey("WaitSpawnWaveTeam") ? (Team)Enum.Parse(typeof(Team), e.StringOptions["WaitSpawnWaveTeam"]) : Team.RIP) < e.IntOptions["NumSpawnWavesToWait"])) && TrackingAndMethods.EvaluateSpawnParameters(e))) { if ((ntfSpawning ? (subClass.AffectsRoles.Contains(RoleType.NtfCadet) || subClass.AffectsRoles.Contains(RoleType.NtfCommander) || subClass.AffectsRoles.Contains(RoleType.NtfLieutenant)) : subClass.AffectsRoles.Contains(RoleType.ChaosInsurgency)) && (rnd.NextDouble() * 100) < subClass.FloatOptions["ChanceToGet"]) { if (ntfSpawning) { if (!hasRole.Contains(RoleType.NtfCadet) && subClass.AffectsRoles.Contains(RoleType.NtfCadet)) { TrackingAndMethods.NextSpawnWaveGetsRole.Add(RoleType.NtfCadet, subClass); hasRole.Add(RoleType.NtfCadet); } if (!hasRole.Contains(RoleType.NtfLieutenant) && subClass.AffectsRoles.Contains(RoleType.NtfLieutenant)) { TrackingAndMethods.NextSpawnWaveGetsRole.Add(RoleType.NtfLieutenant, subClass); hasRole.Add(RoleType.NtfLieutenant); } if (!hasRole.Contains(RoleType.NtfCommander) && subClass.AffectsRoles.Contains(RoleType.NtfCommander)) { TrackingAndMethods.NextSpawnWaveGetsRole.Add(RoleType.NtfCommander, subClass); hasRole.Add(RoleType.NtfCommander); } if (hasRole.Count == 3) { break; } } else { if (subClass.AffectsRoles.Contains(RoleType.ChaosInsurgency)) { TrackingAndMethods.NextSpawnWaveGetsRole.Add(RoleType.ChaosInsurgency, subClass); break; } } } } } else { double num = (rnd.NextDouble() * 100); if (!ntfSpawning && !Subclass.Instance.ClassesAdditive.ContainsKey(RoleType.ChaosInsurgency)) { return; } else if (ntfSpawning && !Subclass.Instance.ClassesAdditive.ContainsKey(RoleType.NtfCadet) && !Subclass.Instance.ClassesAdditive.ContainsKey(RoleType.NtfCommander) && !Subclass.Instance.ClassesAdditive.ContainsKey(RoleType.NtfLieutenant)) { return; } if (!ntfSpawning) { foreach (var possibity in Subclass.Instance.ClassesAdditive[RoleType.ChaosInsurgency].Where(e => e.Key.BoolOptions["Enabled"] && (!e.Key.IntOptions.ContainsKey("MaxSpawnPerRound") || TrackingAndMethods.ClassesSpawned(e.Key) < e.Key.IntOptions["MaxSpawnPerRound"]) && ((e.Key.BoolOptions.ContainsKey("OnlyAffectsSpawnWave") && e.Key.BoolOptions["OnlyAffectsSpawnWave"]) || (e.Key.BoolOptions.ContainsKey("AffectsSpawnWave") && e.Key.BoolOptions["AffectsSpawnWave"])) && (!e.Key.BoolOptions.ContainsKey("WaitForSpawnWaves") || (e.Key.BoolOptions["WaitForSpawnWaves"] && TrackingAndMethods.GetNumWavesSpawned(e.Key.StringOptions.ContainsKey("WaitSpawnWaveTeam") ? (Team)Enum.Parse(typeof(Team), e.Key.StringOptions["WaitSpawnWaveTeam"]) : Team.RIP) < e.Key.IntOptions["NumSpawnWavesToWait"])) && TrackingAndMethods.EvaluateSpawnParameters(e.Key))) { Log.Debug($"Evaluating possible subclass {possibity.Key.Name} for next spawn wave", Subclass.Instance.Config.Debug); if (num < possibity.Value) { TrackingAndMethods.NextSpawnWaveGetsRole.Add(RoleType.ChaosInsurgency, possibity.Key); break; } else { Log.Debug($"Next spawn wave did not get subclass {possibity.Key.Name}", Subclass.Instance.Config.Debug); } } } else { RoleType[] roles = { RoleType.NtfCommander, RoleType.NtfLieutenant, RoleType.NtfCadet }; foreach (RoleType role in roles) { foreach (var possibity in Subclass.Instance.ClassesAdditive[role].Where(e => e.Key.BoolOptions["Enabled"] && (!e.Key.IntOptions.ContainsKey("MaxSpawnPerRound") || TrackingAndMethods.ClassesSpawned(e.Key) < e.Key.IntOptions["MaxSpawnPerRound"]) && ((e.Key.BoolOptions.ContainsKey("OnlyAffectsSpawnWave") && e.Key.BoolOptions["OnlyAffectsSpawnWave"]) || (e.Key.BoolOptions.ContainsKey("AffectsSpawnWave") && e.Key.BoolOptions["AffectsSpawnWave"])) && (!e.Key.BoolOptions.ContainsKey("WaitForSpawnWaves") || (e.Key.BoolOptions["WaitForSpawnWaves"] && TrackingAndMethods.GetNumWavesSpawned(e.Key.StringOptions.ContainsKey("WaitSpawnWaveTeam") ? (Team)Enum.Parse(typeof(Team), e.Key.StringOptions["WaitSpawnWaveTeam"]) : Team.RIP) < e.Key.IntOptions["NumSpawnWavesToWait"])) && TrackingAndMethods.EvaluateSpawnParameters(e.Key))) { Log.Debug($"Evaluating possible subclass {possibity.Key.Name} for next spawn wave", Subclass.Instance.Config.Debug); if (num < possibity.Value) { TrackingAndMethods.NextSpawnWaveGetsRole.Add(role, possibity.Key); break; } else { Log.Debug($"Next spawn wave did not get subclass {possibity.Key.Name}", Subclass.Instance.Config.Debug); } } } } } TrackingAndMethods.NextSpawnWave = ev.Players; }
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); } }
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.InvisibleOnCommand)) { Log.Debug($"Player {player.Nickname} could not go invisible on command", Subclass.Instance.Config.Debug); response = ""; return(true); } Scp268 scp268 = player.ReferenceHub.playerEffectsController.GetEffect <Scp268>(); if (scp268 != null) { SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (!TrackingAndMethods.CanUseAbility(player, AbilityType.InvisibleOnCommand, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.InvisibleOnCommand, subClass, "invisible on command"); response = ""; return(true); } if (scp268.Enabled) { Log.Debug($"Player {player.Nickname} failed to go invisible on command", Subclass.Instance.Config.Debug); player.Broadcast(3, Subclass.Instance.Config.AlreadyInvisibleMessage); response = ""; return(true); } if (TrackingAndMethods.OnCooldown(player, AbilityType.InvisibleOnCommand, subClass)) { Log.Debug($"Player {player.Nickname} failed to go invisible on command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.InvisibleOnCommand, subClass, "invisible", Time.time); response = ""; return(true); } //scp268.Duration = subClass.FloatOptions.ContainsKey("InvisibleOnCommandDuration") ? // subClass.FloatOptions["InvisibleOnCommandDuration"]*2f : 30f*2f; //player.ReferenceHub.playerEffectsController.EnableEffect(scp268); player.ReferenceHub.playerEffectsController.EnableEffect <Scp268>(); TrackingAndMethods.PlayersInvisibleByCommand.Add(player); Timing.CallDelayed(subClass.FloatOptions.ContainsKey("InvisibleOnCommandDuration") ? subClass.FloatOptions["InvisibleOnCommandDuration"] : 30f, () => { if (TrackingAndMethods.PlayersInvisibleByCommand.Contains(player)) { TrackingAndMethods.PlayersInvisibleByCommand.Remove(player); } if (scp268.Enabled) { player.ReferenceHub.playerEffectsController.DisableEffect <Scp268>(); } }); TrackingAndMethods.AddCooldown(player, AbilityType.InvisibleOnCommand); TrackingAndMethods.UseAbility(player, AbilityType.InvisibleOnCommand, subClass); } response = ""; return(true); }
public bool Execute(ArraySegment <string> arguments, ICommandSender sender, out string response) { Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if ((player.Team != Team.MTF && player.Team != Team.CHI) || !TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.BackupCommand)) { Log.Debug($"Player {player.Nickname} could not use the backup command", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.BackupCommand, subClass)) { Log.Debug($"Player {player.Nickname} failed to use the backup command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.BackupCommand, subClass, "backup", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.BackupCommand, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.BackupCommand, subClass, "backup"); response = ""; return(true); } int min = subClass.IntOptions.ContainsKey("BackupMinSpawn") ? subClass.IntOptions["BackupMinSpawn"] : 3; int max = subClass.IntOptions.ContainsKey("BackupMaxSpawn") ? subClass.IntOptions["BackupMaxSpawn"] : 7; List <Player> spectators = Player.List.Where(p => p.Role == RoleType.Spectator).ToList(); if (spectators.Count == 0) { player.Broadcast(2, Subclass.Instance.Config.NoAvailableSpectators); response = ""; return(true); } TrackingAndMethods.UseAbility(player, AbilityType.BackupCommand, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.BackupCommand); int spawns = Mathf.Clamp((int)(rnd.NextDouble() * ((max - min) + 1)) + min, 0, spectators.Count); bool isMTF = player.Team == Team.MTF; int commanders = 1; int lieutenants = 0; int cadets = 0; if (isMTF) { lieutenants = Mathf.Clamp(spawns - commanders, 0, 3); cadets = spawns - lieutenants - commanders; } for (int i = 0; i < spawns; i++) { int index = rnd.Next(spectators.Count); Player p = spectators[index]; spectators.RemoveAt(index); if (!isMTF) { p.SetRole(RoleType.ChaosInsurgency); } else { if (commanders > 0) { p.SetRole(RoleType.NtfCommander); commanders--; } else if (lieutenants > 0) { p.SetRole(RoleType.NtfLieutenant); lieutenants--; } else { p.SetRole(RoleType.NtfCadet); } } } response = ""; return(true); }
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) { response = ""; Player player = Player.Get(((PlayerCommandSender)sender).SenderId); if (!TrackingAndMethods.PlayersWithSubclasses.ContainsKey(player) || !TrackingAndMethods.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Disarm) || player.IsCuffed) { Log.Debug($"Player {player.Nickname} could not use the disarm command", Subclass.Instance.Config.Debug); response = ""; return(true); } SubClass subClass = TrackingAndMethods.PlayersWithSubclasses[player]; if (TrackingAndMethods.OnCooldown(player, AbilityType.Disarm, subClass)) { Log.Debug($"Player {player.Nickname} failed to use the disarm command", Subclass.Instance.Config.Debug); TrackingAndMethods.DisplayCooldown(player, AbilityType.Disarm, subClass, "disarm", Time.time); response = ""; return(true); } if (!TrackingAndMethods.CanUseAbility(player, AbilityType.Disarm, subClass)) { TrackingAndMethods.DisplayCantUseAbility(player, AbilityType.Disarm, subClass, "disarm"); response = ""; return(true); } if (!subClass.BoolOptions.ContainsKey("DisarmSphere") || !subClass.BoolOptions["DisarmSphere"]) { if (Physics.Raycast(player.CameraTransform.position, player.CameraTransform.forward, out RaycastHit hit, (subClass.FloatOptions.ContainsKey("DisarmRange") ? subClass.FloatOptions["DisarmRange"] : 1.3f))) { Player target = Player.Get(hit.collider.gameObject) ?? Player.Get(hit.collider.GetComponentInParent <ReferenceHub>()); if (target == null || target.Id == player.Id || player.Side == target.Side || (player.Team == Team.SCP && target.Team == Team.TUT)) { return(true); } TrackingAndMethods.UseAbility(player, AbilityType.Disarm, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.Disarm); if (target.CurrentItemIndex != -1) { target.DropItem(target.CurrentItem); } } } else { Collider[] colliders = Physics.OverlapSphere(player.Position, (subClass.FloatOptions.ContainsKey("DisarmRange") ? subClass.FloatOptions["DisarmRange"] : 3f)); IEnumerable <Player> players = colliders.Select(c => Player.Get(c.gameObject)).Distinct(); if (players.Count() > 0) { TrackingAndMethods.UseAbility(player, AbilityType.Disarm, subClass); TrackingAndMethods.AddCooldown(player, AbilityType.Disarm); foreach (Player target in players) { if (target == null || target.Id == player.Id || player.Side == target.Side || (player.Team == Team.SCP && target.Team == Team.TUT)) { continue; } if (target.CurrentItemIndex != -1) { target.DropItem(target.CurrentItem); } } } } return(true); }