public void OnTriggeringTesla(TriggeringTeslaEventArgs ev) { if (!Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) || !Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.BypassTeslaGates)) { return; } SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (Tracking.PlayerJustBypassedTeslaGate(ev.Player)) // The triggering tesla happens a lot, this allows the bypass to last 3 seconds. { ev.IsTriggerable = false; return; } if (Tracking.OnCooldown(ev.Player, AbilityType.BypassTeslaGates, subClass)) { Tracking.DisplayCooldown(ev.Player, AbilityType.BypassTeslaGates, subClass, "bypass tesla gates", Time.time); } else { Log.Debug($"Player with subclass {Tracking.PlayersWithSubclasses[ev.Player].Name} has been allowed to bypass tesla gate", Subclass.Instance.Config.Debug); Tracking.AddCooldown(ev.Player, AbilityType.BypassTeslaGates); if (!Tracking.PlayersThatBypassedTeslaGates.ContainsKey(ev.Player)) { Tracking.PlayersThatBypassedTeslaGates.Add(ev.Player, 0); } Tracking.PlayersThatBypassedTeslaGates[ev.Player] = Time.time; ev.IsTriggerable = false; //ev.Player.IsUsingStamina = false; } }
public void OnUnlockingGenerator(UnlockingGeneratorEventArgs ev) { if (ev.IsAllowed) { return; } if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) && Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.BypassKeycardReaders)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (Tracking.OnCooldown(ev.Player, AbilityType.BypassKeycardReaders, subClass)) { Tracking.DisplayCooldown(ev.Player, AbilityType.BypassKeycardReaders, subClass, "bypass keycard readers", Time.time); } else { Log.Debug($"Player with subclass {Tracking.PlayersWithSubclasses[ev.Player].Name} has been allowed to access locked locker", Subclass.Instance.Config.Debug); Tracking.AddCooldown(ev.Player, AbilityType.BypassKeycardReaders); ev.IsAllowed = true; } } }
public void OnInteractingDoor(InteractingDoorEventArgs ev) { if (ev.Door.doorType == Door.DoorTypes.HeavyGate) { if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Player)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (subClass.Abilities.Contains(AbilityType.PryGates)) { if (Tracking.OnCooldown(ev.Player, AbilityType.PryGates, subClass)) { Tracking.DisplayCooldown(ev.Player, AbilityType.PryGates, subClass, "pry gates", Time.time); } else { Tracking.AddCooldown(ev.Player, AbilityType.PryGates); ev.Door.PryGate(); } } } } else if (!ev.IsAllowed && !ev.Door.Networkdestroyed && !ev.Door.Networklocked && Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) && Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.BypassKeycardReaders)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (Tracking.OnCooldown(ev.Player, AbilityType.BypassKeycardReaders, subClass)) { Tracking.DisplayCooldown(ev.Player, AbilityType.BypassKeycardReaders, subClass, "bypass keycard readers", Time.time); } else { Log.Debug($"Player with subclass {Tracking.PlayersWithSubclasses[ev.Player].Name} has been allowed to access door with permission level {ev.Door.PermissionLevels}", Subclass.Instance.Config.Debug); Tracking.AddCooldown(ev.Player, AbilityType.BypassKeycardReaders); ev.IsAllowed = true; } } }
public void AttemptRevive(SendingConsoleCommandEventArgs ev, SubClass subClass, bool necro = false) { Log.Debug($"Player {ev.Player.Nickname} {(necro ? "necromancy" : "revive")} attempt", Subclass.Instance.Config.Debug); AbilityType ability = necro ? AbilityType.Necromancy : AbilityType.Revive; if (Tracking.OnCooldown(ev.Player, ability, subClass)) { Log.Debug($"Player {ev.Player.Nickname} {(necro ? "necromancy" : "revive")} on cooldown", Subclass.Instance.Config.Debug); Tracking.DisplayCooldown(ev.Player, necro ? AbilityType.Necromancy : AbilityType.Revive, subClass, necro ? "necromancy" : "revive", Time.time); return; } List <Collider> colliders = Physics.OverlapSphere(ev.Player.Position, 3f).Where(e => e.gameObject.GetComponentInParent <Ragdoll>() != null).ToList(); colliders.Sort((Collider x, Collider y) => { return(Vector3.Distance(x.gameObject.transform.position, ev.Player.Position).CompareTo(Vector3.Distance(y.gameObject.transform.position, ev.Player.Position))); }); if (colliders.Count == 0) { ev.ReturnMessage = "You must be near a dead body to use this command"; ev.Player.Broadcast(2, "You must be near a dead body."); Log.Debug($"Player {ev.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 {ev.Player.Nickname} {(necro ? "necromancy" : "revive")} failed", Subclass.Instance.Config.Debug); ev.ReturnMessage = "This player is not revivable."; ev.Player.Broadcast(2, "This player is not revivable."); return; } EPlayer owner = EPlayer.Get(colliders[0].gameObject.GetComponentInParent <Ragdoll>().owner.PlayerId); if (owner != null && !owner.IsAlive) { if (!necro && Tracking.GetPreviousTeam(owner) != null && Tracking.GetPreviousTeam(owner) == ev.Player.Team) { owner.Role = (RoleType)Tracking.GetPreviousRole(owner); } else if (necro) { owner.Role = RoleType.Scp0492; Tracking.AddZombie(ev.Player, owner); owner.IsFriendlyFireEnabled = true; } if (owner.Role != RoleType.Spectator) { Timing.CallDelayed(0.2f, () => { owner.Position = colliders[0].gameObject.transform.position + new Vector3(0, 1f, 0); }); UnityEngine.Object.DestroyImmediate(doll.gameObject, true); Tracking.AddCooldown(ev.Player, ability); Log.Debug($"Player {ev.Player.Nickname} {(necro ? "necromancy" : "revive")} succeeded", Subclass.Instance.Config.Debug); } else { Log.Debug($"Player {ev.Player.Nickname} {(necro ? "necromancy" : "revive")} failed", Subclass.Instance.Config.Debug); ev.ReturnMessage = "This player is not revivable."; ev.Player.Broadcast(2, "This player is not revivable."); } } else { Log.Debug($"Player {ev.Player.Nickname} {(necro ? "necromancy" : "revive")} failed", Subclass.Instance.Config.Debug); ev.ReturnMessage = "This player is not revivable."; ev.Player.Broadcast(2, "This player is not revivable."); } }
public void OnSendingConsoleCommand(SendingConsoleCommandEventArgs ev) { Log.Debug($"Player {ev.Player.Nickname} sent a console command", Subclass.Instance.Config.Debug); ev.IsAllowed = false; switch (ev.Name) { case "revive": Log.Debug($"Player {ev.Player.Nickname} is attempting to revive", Subclass.Instance.Config.Debug); if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) && Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.Revive)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; AttemptRevive(ev, subClass); } else { ev.ReturnMessage = "You don't have the ability to revive!"; } break; case "necro": Log.Debug($"Player {ev.Player.Nickname} is attempting to necro", Subclass.Instance.Config.Debug); if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) && Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.Necromancy)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; AttemptRevive(ev, subClass, true); } else { ev.ReturnMessage = "You don't have the ability to necro!"; } break; case "locate": if (ev.Player.Role != RoleType.Scp93953 && ev.Player.Role != RoleType.Scp93989 && (!Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) || !Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.Scp939Vision))) { Log.Debug($"Player {ev.Player.Nickname} failed to echolocate", Subclass.Instance.Config.Debug); ev.ReturnMessage = "You must be SCP-939 or have a subclass with its visuals to use this command"; return; } if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) && Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.Echolocate)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (Tracking.OnCooldown(ev.Player, AbilityType.Echolocate, subClass)) { Log.Debug($"Player {ev.Player.Nickname} failed to echolocate", Subclass.Instance.Config.Debug); Tracking.DisplayCooldown(ev.Player, AbilityType.Echolocate, subClass, "echolocation", Time.time); return; } Collider[] colliders = Physics.OverlapSphere(ev.Player.Position, subClass.FloatOptions.ContainsKey("EcholocateRadius") ? subClass.FloatOptions["EcholocateRadius"] : 10f); foreach (Collider PlayerCollider in colliders.Where(c => EPlayer.Get(c.gameObject) != null)) { EPlayer.Get(PlayerCollider.gameObject).ReferenceHub.footstepSync?.CmdScp939Noise(100f); } Tracking.AddCooldown(ev.Player, AbilityType.Echolocate); Log.Debug($"Player {ev.Player.Nickname} successfully used echolocate", Subclass.Instance.Config.Debug); } break; case "noclip": Log.Debug($"Player {ev.Player.Nickname} is attempting to noclip", Subclass.Instance.Config.Debug); if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) && Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.NoClip)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (Tracking.OnCooldown(ev.Player, AbilityType.NoClip, subClass)) { Log.Debug($"Player {ev.Player.Nickname} failed to noclip - cooldown", Subclass.Instance.Config.Debug); Tracking.DisplayCooldown(ev.Player, AbilityType.NoClip, subClass, "noclip", Time.time); return; } bool previous = ev.Player.NoClipEnabled; ev.Player.NoClipEnabled = !ev.Player.NoClipEnabled; Tracking.AddCooldown(ev.Player, AbilityType.NoClip); if (subClass.FloatOptions.ContainsKey("NoClipTime")) { Timing.CallDelayed(subClass.FloatOptions["NoClipTime"], () => { if (ev.Player.NoClipEnabled != previous) { ev.Player.NoClipEnabled = previous; } }); } Log.Debug($"Player {ev.Player.Nickname} successfully noclipped", Subclass.Instance.Config.Debug); } else { ev.ReturnMessage = "You must have the noclip ability to use this command"; Log.Debug($"Player {ev.Player.Nickname} could not noclip", Subclass.Instance.Config.Debug); } break; case "flash": if (Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) && Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.FlashOnCommand)) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (Tracking.OnCooldown(ev.Player, AbilityType.FlashOnCommand, subClass)) { Log.Debug($"Player {ev.Player.Nickname} failed to flash on command", Subclass.Instance.Config.Debug); Tracking.DisplayCooldown(ev.Player, AbilityType.FlashOnCommand, subClass, "flash", Time.time); return; } // Credit to KoukoCocoa's AdminTools for the grenade spawn script below, I was lost. https://github.com/KoukoCocoa/AdminTools/ GrenadeManager grenadeManager = ev.Player.ReferenceHub.gameObject.GetComponent <GrenadeManager>(); GrenadeSettings settings = grenadeManager.availableGrenades.FirstOrDefault(g => g.inventoryID == ItemType.GrenadeFlash); Grenade grenade = UnityEngine.Object.Instantiate(settings.grenadeInstance).GetComponent <Grenade>(); grenade.fuseDuration = subClass.FloatOptions.ContainsKey("FlashOnCommandFuseTimer") ? subClass.FloatOptions["FlashOnCommandFuseTimer"] : 0.3f; grenade.FullInitData(grenadeManager, ev.Player.Position, Quaternion.Euler(grenade.throwStartAngle), grenade.throwLinearVelocityOffset, grenade.throwAngularVelocity); NetworkServer.Spawn(grenade.gameObject); Tracking.AddCooldown(ev.Player, AbilityType.FlashOnCommand); Log.Debug($"Player {ev.Player.Nickname} successfully used flash on commad", Subclass.Instance.Config.Debug); } else { ev.ReturnMessage = "You must have the flash on command ability to use this command"; Log.Debug($"Player {ev.Player.Nickname} could not flash on command", Subclass.Instance.Config.Debug); } break; case "invis": if (!Tracking.PlayersWithSubclasses.ContainsKey(ev.Player) || !Tracking.PlayersWithSubclasses[ev.Player].Abilities.Contains(AbilityType.InvisibleOnCommand)) { ev.ReturnMessage = "You must have the invisible on command ability to use this command"; Log.Debug($"Player {ev.Player.Nickname} could not go invisible on command", Subclass.Instance.Config.Debug); return; } Scp268 scp268 = ev.Player.ReferenceHub.playerEffectsController.GetEffect <Scp268>(); if (scp268 != null) { SubClass subClass = Tracking.PlayersWithSubclasses[ev.Player]; if (scp268.Enabled) { Log.Debug($"Player {ev.Player.Nickname} failed to go invisible on command", Subclass.Instance.Config.Debug); ev.Player.Broadcast(3, "You're already invisible!"); return; } if (Tracking.OnCooldown(ev.Player, AbilityType.InvisibleOnCommand, subClass)) { Log.Debug($"Player {ev.Player.Nickname} failed to go invisible on command", Subclass.Instance.Config.Debug); Tracking.DisplayCooldown(ev.Player, AbilityType.InvisibleOnCommand, subClass, "invisible", Time.time); return; } //scp268.Duration = subClass.FloatOptions.ContainsKey("InvisibleOnCommandDuration") ? // subClass.FloatOptions["InvisibleOnCommandDuration"]*2f : 30f*2f; //ev.Player.ReferenceHub.playerEffectsController.EnableEffect(scp268); ev.Player.ReferenceHub.playerEffectsController.EnableEffect <Scp268>(); Tracking.PlayersInvisibleByCommand.Add(ev.Player); Timing.CallDelayed(subClass.FloatOptions.ContainsKey("InvisibleOnCommandDuration") ? subClass.FloatOptions["InvisibleOnCommandDuration"] : 30f, () => { if (Tracking.PlayersInvisibleByCommand.Contains(ev.Player)) { Tracking.PlayersInvisibleByCommand.Remove(ev.Player); } if (scp268.Enabled) { ev.Player.ReferenceHub.playerEffectsController.DisableEffect <Scp268>(); } }); Tracking.AddCooldown(ev.Player, AbilityType.InvisibleOnCommand); } break; default: ev.IsAllowed = true; break; } }