public static bool GiveClass(Player p, SubClass subClass, bool lite = false) { if (PlayerHasSubClass(p) || !subClass.AffectsRoles.Contains(p.Role)) { return(false); } Tracking.AddClass(p, subClass, Subclass.Instance.Scp035Enabled && scp035.API.Scp035Data.GetScp035().Id == p.Id, lite); return(true); }
public static bool EnableClass(SubClass sc) { try { Subclass.Instance.Classes[sc.Name].BoolOptions["Enabled"] = true; return(true); }catch { return(false); } }
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 SubClass(SubClass subClass) { Name = subClass.Name; AffectsRoles = new List <RoleType>(subClass.AffectsRoles); StringOptions = new Dictionary <string, string>(subClass.StringOptions); BoolOptions = new Dictionary <string, bool>(subClass.BoolOptions); IntOptions = new Dictionary <string, int>(subClass.IntOptions); FloatOptions = new Dictionary <string, float>(subClass.FloatOptions); SpawnLocations = new List <RoomType>(subClass.SpawnLocations); SpawnItems = new Dictionary <int, Dictionary <ItemType, float> >(subClass.SpawnItems); SpawnAmmo = new Dictionary <AmmoType, int>(subClass.SpawnAmmo); Abilities = new List <AbilityType>(subClass.Abilities); AbilityCooldowns = new Dictionary <AbilityType, float>(subClass.AbilityCooldowns); AdvancedFFRules = new List <string>(subClass.AdvancedFFRules); OnHitEffects = new List <string>(subClass.OnHitEffects); OnSpawnEffects = new List <string>(subClass.OnSpawnEffects); RolesThatCantDamage = new List <RoleType>(subClass.RolesThatCantDamage); EndsRoundWith = subClass.EndsRoundWith; SpawnsAs = subClass.SpawnsAs; }
public static void AddClass(Player player, SubClass subClass, bool is035 = false, bool lite = false) { if (is035) { SubClass copy = new SubClass(subClass); if (!copy.Abilities.Contains(AbilityType.Disable096Trigger)) { copy.Abilities.Add(AbilityType.Disable096Trigger); } if (!copy.Abilities.Contains(AbilityType.Disable173Stop)) { copy.Abilities.Add(AbilityType.Disable173Stop); } if (!copy.Abilities.Contains(AbilityType.NoSCPDamage)) { copy.Abilities.Add(AbilityType.NoSCPDamage); } copy.BoolOptions["HasFriendlyFire"] = true; copy.BoolOptions["TakesFriendlyFire"] = true; copy.SpawnsAs = RoleType.None; copy.SpawnLocations.Clear(); copy.SpawnLocations.Add(RoomType.Unknown); copy.IntOptions["MaxHealth"] = -1; copy.IntOptions["HealthOnSpawn"] = -1; copy.IntOptions["MaxArmor"] = -1; copy.IntOptions["ArmorOnSpawn"] = -1; copy.SpawnItems.Clear(); copy.RolesThatCantDamage.Clear(); copy.StringOptions["GotClassMessage"] = subClass.StringOptions["GotClassMessage"] + " You are SCP-035."; subClass = new SubClass(copy.Name + "-SCP-035 (p)", copy.AffectsRoles, copy.StringOptions, copy.BoolOptions, copy.IntOptions, copy.FloatOptions, copy.SpawnLocations, copy.SpawnItems, new Dictionary <AmmoType, int>() { { AmmoType.Nato556, -1 }, { AmmoType.Nato762, -1 }, { AmmoType.Nato9, -1 } }, copy.Abilities, copy.AbilityCooldowns, copy.AdvancedFFRules, copy.OnHitEffects, copy.OnSpawnEffects, copy.RolesThatCantDamage, Team.SCP ); } if (NextSpawnWave.Contains(player) && NextSpawnWaveGetsRole.ContainsKey(player.Role) && !SpawnWaveSpawns.Contains(subClass)) { if (SubClassesSpawned.ContainsKey(subClass)) { SubClassesSpawned[subClass]++; } else { SubClassesSpawned.Add(subClass, 1); } SpawnWaveSpawns.Add(subClass); } else if (!SpawnWaveSpawns.Contains(subClass)) { if (SubClassesSpawned.ContainsKey(subClass)) { SubClassesSpawned[subClass]++; } else { SubClassesSpawned.Add(subClass, 1); } } PlayersWithSubclasses.Add(player, subClass); if (!PlayersThatJustGotAClass.ContainsKey(player)) { PlayersThatJustGotAClass.Add(player, Time.time + 3f); } else { PlayersThatJustGotAClass[player] = Time.time + 3f; } try { player.Broadcast(subClass.FloatOptions.ContainsKey("BroadcastTimer") ? (ushort)subClass.FloatOptions["BroadcastTimer"] : (ushort)Subclass.Instance.Config.GlobalBroadcastTime, subClass.StringOptions["GotClassMessage"]); if (subClass.StringOptions.ContainsKey("CassieAnnouncement") && !QueuedCassieMessages.Contains(subClass.StringOptions["CassieAnnouncement"])) { QueuedCassieMessages.Add(subClass.StringOptions["CassieAnnouncement"]); } if (subClass.SpawnsAs != RoleType.None) { player.Role = subClass.SpawnsAs; } if (subClass.SpawnItems.Count != 0) { player.ClearInventory(); foreach (var item in subClass.SpawnItems) { foreach (var item2 in item.Value) { if ((rnd.NextDouble() * 100) < subClass.SpawnItems[item.Key][item2.Key]) { if (item2.Key == ItemType.None) { break; } player.AddItem(item2.Key); break; } } } } if (subClass.IntOptions["MaxHealth"] != -1) { player.MaxHealth = subClass.IntOptions["MaxHealth"]; } if (subClass.IntOptions["HealthOnSpawn"] != -1) { player.Health = subClass.IntOptions["HealthOnSpawn"]; } if (subClass.IntOptions["MaxArmor"] != -1) { player.MaxAdrenalineHealth = subClass.IntOptions["MaxArmor"]; } if (subClass.IntOptions["ArmorOnSpawn"] != -1) { player.AdrenalineHealth = subClass.IntOptions["ArmorOnSpawn"]; } Vector3 scale = new Vector3(player.Scale.x, player.Scale.y, player.Scale.z); if (subClass.FloatOptions.ContainsKey("ScaleX")) { scale.x = subClass.FloatOptions["ScaleX"]; } if (subClass.FloatOptions.ContainsKey("ScaleY")) { scale.y = subClass.FloatOptions["ScaleY"]; } if (subClass.FloatOptions.ContainsKey("ScaleZ")) { scale.z = subClass.FloatOptions["ScaleZ"]; } player.Scale = scale; if (!subClass.BoolOptions["DisregardHasFF"]) { player.IsFriendlyFireEnabled = subClass.BoolOptions["HasFriendlyFire"]; } int index = rnd.Next(subClass.SpawnLocations.Count); if (!lite && subClass.SpawnLocations[index] != RoomType.Unknown) { List <Room> spawnLocations = Map.Rooms.Where(r => r.Type == subClass.SpawnLocations[index]).ToList(); if (spawnLocations.Count != 0) { Timing.CallDelayed(0.1f, () => { Vector3 offset = new Vector3(0, 2f, 0); if (subClass.FloatOptions.ContainsKey("SpawnOffsetX")) { offset.x = subClass.FloatOptions["SpawnOffsetX"]; } if (subClass.FloatOptions.ContainsKey("SpawnOffsetY")) { offset.y = subClass.FloatOptions["SpawnOffsetY"]; } if (subClass.FloatOptions.ContainsKey("SpawnOffsetZ")) { offset.z = subClass.FloatOptions["SpawnOffsetZ"]; } player.Position = spawnLocations[rnd.Next(spawnLocations.Count)].Position + offset; }); } } } catch (KeyNotFoundException e) { Log.Error($"A required option was not provided. Class: {subClass.Name}"); throw new Exception($"A required option was not provided. Class: {subClass.Name}"); } if (subClass.Abilities.Contains(AbilityType.GodMode)) { player.IsGodModeEnabled = true; } if (subClass.Abilities.Contains(AbilityType.InvisibleUntilInteract)) { player.ReferenceHub.playerEffectsController.EnableEffect <Scp268>(); } if (subClass.Abilities.Contains(AbilityType.InfiniteSprint)) { player.GameObject.AddComponent <MonoBehaviours.InfiniteSprint>(); } if (subClass.Abilities.Contains(AbilityType.Disable173Stop)) { Scp173.TurnedPlayers.Add(player); } if (subClass.Abilities.Contains(AbilityType.Scp939Vision)) { Visuals939 visuals = player.ReferenceHub.playerEffectsController.GetEffect <Visuals939>(); visuals.Intensity = 2; player.ReferenceHub.playerEffectsController.EnableEffect(visuals); } if (subClass.Abilities.Contains(AbilityType.NoArmorDecay)) { player.ReferenceHub.playerStats.artificialHpDecay = 0f; } if (subClass.SpawnAmmo[AmmoType.Nato556] != -1) { player.Ammo[(int)AmmoType.Nato556] = (uint)subClass.SpawnAmmo[AmmoType.Nato556]; } if (subClass.SpawnAmmo[AmmoType.Nato762] != -1) { player.Ammo[(int)AmmoType.Nato762] = (uint)subClass.SpawnAmmo[AmmoType.Nato762]; } if (subClass.SpawnAmmo[AmmoType.Nato9] != -1) { player.Ammo[(int)AmmoType.Nato9] = (uint)subClass.SpawnAmmo[AmmoType.Nato9]; } if (subClass.Abilities.Contains(AbilityType.InfiniteAmmo)) { player.Ammo[0] = uint.MaxValue; player.Ammo[1] = uint.MaxValue; player.Ammo[2] = uint.MaxValue; } if (player.GlobalBadge?.Type == 0) // Comply with verified server rules. { AddPreviousBadge(player, true); if (subClass.StringOptions.ContainsKey("Badge")) { player.ReferenceHub.serverRoles.HiddenBadge = subClass.StringOptions["Badge"]; } } else { AddPreviousBadge(player); if (subClass.StringOptions.ContainsKey("Badge")) { player.RankName = subClass.StringOptions["Badge"]; } if (subClass.StringOptions.ContainsKey("BadgeColor")) { player.RankColor = subClass.StringOptions["BadgeColor"]; } } if (subClass.OnSpawnEffects.Count != 0) { Timing.CallDelayed(0.1f, () => { Log.Debug($"Subclass {subClass.Name} has on spawn effects", Subclass.Instance.Config.Debug); foreach (string effect in subClass.OnSpawnEffects) { Log.Debug($"Evaluating chance for on spawn {effect} for player {player.Nickname}", Subclass.Instance.Config.Debug); if ((rnd.NextDouble() * 100) < subClass.FloatOptions[("OnSpawn" + effect + "Chance")]) { player.ReferenceHub.playerEffectsController.EnableByString(effect, subClass.FloatOptions.ContainsKey(("OnSpawn" + effect + "Duration")) ? subClass.FloatOptions[("OnSpawn" + effect + "Duration")] : -1, true); Log.Debug($"Player {player.Nickname} has been given effect {effect} on spawn", Subclass.Instance.Config.Debug); } else { Log.Debug($"Player {player.Nickname} has been not given effect {effect} on spawn", Subclass.Instance.Config.Debug); } } }); } else { Log.Debug($"Subclass {subClass.Name} has no on spawn effects", Subclass.Instance.Config.Debug); } Log.Debug($"Player with name {player.Nickname} got subclass {subClass.Name}", Subclass.Instance.Config.Debug); }
public static bool OnCooldown(Player p, AbilityType ability, SubClass subClass) { return(Cooldowns.ContainsKey(p) && Cooldowns[p].ContainsKey(ability) && Time.time - Cooldowns[p][ability] < subClass.AbilityCooldowns[ability]); }
public static void RemoveAndAddRoles(Player p, bool dontAddRoles = false, bool is035 = false) { if (PlayersThatJustGotAClass.ContainsKey(p) && PlayersThatJustGotAClass[p] > Time.time) { return; } if (RoundJustStarted()) { return; } if (Cooldowns.ContainsKey(p)) { Cooldowns.Remove(p); } if (FriendlyFired.Contains(p)) { FriendlyFired.RemoveAll(e => e == p); } if (PlayersWithSubclasses.ContainsKey(p) && PlayersWithSubclasses[p].Abilities.Contains(AbilityType.Disable173Stop) && Scp173.TurnedPlayers.Contains(p)) { Scp173.TurnedPlayers.Remove(p); } if (PlayersWithSubclasses.ContainsKey(p) && PlayersWithSubclasses[p].Abilities.Contains(AbilityType.NoArmorDecay)) { p.ReferenceHub.playerStats.artificialHpDecay = 0.75f; } if (PlayersWithZombies.ContainsKey(p)) { PlayersThatHadZombies.Add(p, PlayersWithZombies[p]); foreach (Player z in PlayersThatHadZombies[p]) { z.GameObject.AddComponent <ZombieEscape>(); } PlayersWithZombies.Remove(p); } if (p.ReferenceHub.serverRoles.HiddenBadge != null && p.ReferenceHub.serverRoles.HiddenBadge != "") { p.ReferenceHub.serverRoles.HiddenBadge = null; } SubClass subClass = PlayersWithSubclasses.ContainsKey(p) ? PlayersWithSubclasses[p] : null; if (subClass != null) { if (!PreviousSubclasses.ContainsKey(p)) { PreviousSubclasses.Add(p, subClass); } else { PreviousSubclasses[p] = subClass; } if (subClass.StringOptions.ContainsKey("Badge") && p.RankName == subClass.StringOptions["Badge"]) { p.RankName = PreviousBadges.ContainsKey(p) ? System.Text.RegularExpressions.Regex.Split(PreviousBadges[p], System.Text.RegularExpressions.Regex.Escape(" [-/-] "))[0] : null; p.RankColor = PreviousBadges.ContainsKey(p) ? System.Text.RegularExpressions.Regex.Split(PreviousBadges[p], System.Text.RegularExpressions.Regex.Escape(" [-/-] "))[1] : null; } else if (subClass.StringOptions.ContainsKey("Badge") && p.ReferenceHub.serverRoles.HiddenBadge == subClass.StringOptions["Badge"]) { p.ReferenceHub.serverRoles.HiddenBadge = PreviousBadges.ContainsKey(p) ? System.Text.RegularExpressions.Regex.Split(PreviousBadges[p], System.Text.RegularExpressions.Regex.Escape(" [-/-] "))[0] : null;; } } if (p.GameObject.GetComponent <InfiniteSprint>() != null) { Log.Debug($"Player {p.Nickname} has infinite stamina, destroying", Subclass.Instance.Config.Debug); p.GameObject.GetComponent <InfiniteSprint>().Destroy(); p.IsUsingStamina = true; // Have to set it to true for it to remove fully... for some reason? } if (p.GameObject.GetComponent <ZombieEscape>() != null) { Log.Debug($"Player {p.Nickname} has zombie escape, destroying", Subclass.Instance.Config.Debug); p.GameObject.GetComponent <ZombieEscape>().Destroy(); } if (PlayersWithSubclasses.ContainsKey(p)) { PlayersWithSubclasses.Remove(p); } if (!dontAddRoles) { Subclass.Instance.server.MaybeAddRoles(p, is035); } }