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 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); } }