private static bool GrantCustomItem(Player player, Subclass subclass, int id, int index) { if (ItemManager.Items.Handlers.ContainsKey(id)) { ItemManager.Items.Handlers[subclass.imInv[index]].Create((player.GetGameObject() as GameObject).GetComponent <Inventory>(), index); return(true); } return(false); }
public static Subclass Get(this List <Subclass> subclasses, string name) { // IEnumerable to not get fucky strings with no relation to our word at all IEnumerable <Subclass> matchingSubclasses = subclasses.Where(x => x.name.StartsWith(name)); Subclass yourSubclass = Subclass.Empty; int shortestDistance = int.MaxValue, currDistance; if (matchingSubclasses.Count() <= 0) { return(Subclass.Empty); } foreach (Subclass sc in matchingSubclasses) { currDistance = StringDistance.LevenshteinDistance(sc.name, name); if (currDistance < shortestDistance) { yourSubclass = sc; } } return(yourSubclass); }
internal void OnRACommand(ref RACommandEvent ev) { // big brain time int i; for (i = 0; i < ev.Command.Length && ev.Command[i] != ' '; i++) { ; } if (!plugin.Configs.aliases.Contains(ev.Command.Substring(0, i).ToUpperInvariant())) { return; } ev.Allow = false; string[] args = ev.Command.Split(' '); if (args.Length < 2) { ev.Sender.RAMessage(GetUsage(), false); return; } else { switch (args[1].ToUpperInvariant()) { case "RELOAD": ev.Sender.RAMessage($"Reloaded {Methods.LoadClasses()} classes.", true); return; case "LIST": if (args.Length == 2) { ev.Sender.RAMessage("List of names:\n" + string.Join(", ", from subclass in MTFplus.disctinctSubclasses select subclass.name)); } else { Timing.RunCoroutine(Methods.FetchList(ev.Sender)); } return; case "DISPLAY": if (args.Length < 3) { ev.Sender.RAMessage("Please, introduce a name as your second argument.", false); return; } Subclass theOneAndOnly = MTFplus.subclasses.Get(args[2]); if (theOneAndOnly.Equals(Subclass.Empty)) { ev.Sender.RAMessage("Subclass not found.", false); return; } ev.Sender.RAMessage(theOneAndOnly.ToString()); return; case "SPAWN": var player = Plugin.GetPlayer(ev.Sender.SenderId); if (plugin.Configs.ranks.Count > 0 && player != null && player.serverRoles.Permissions != ServerStatic.PermissionsHandler.FullPerm && !plugin.Configs.ranks.Contains(player.serverRoles.GlobalBadge)) { ev.Sender.RAMessage($"You aren't allowed to run this command (role {player.serverRoles.GlobalBadge ?? "(null)"} is not allowed to run this command).", false); return; } if (args.Length < 4) { ev.Sender.RAMessage($"Usage: {string.Join("/", args[0])} SPAWN <player name/player id> <class name>", false); return; } ReferenceHub target = Plugin.GetPlayer(args[2]); if (target == null) { ev.Sender.RAMessage("Player not found.", false); return; } Subclass pickedClass = MTFplus.subclasses.Get(args[3]); if (pickedClass.Equals(Subclass.Empty)) { ev.Sender.RAMessage("Subclass not found.", false); return; } target.characterClassManager.SetPlayersClass(pickedClass.role, target.gameObject, false, false); player.SetClass(pickedClass); if (player != null) { Plugin.Info($"Player {target.nicknameSync.MyNick} spawned as subclass {pickedClass.name} by admin {player.nicknameSync.MyNick}" + $" with ID: ({player.characterClassManager.UserId})"); } ev.Sender.RAMessage("Set player " + target.nicknameSync.MyNick + " as " + pickedClass.name); return; } } ev.Sender.RAMessage(GetUsage(), false); }
public static int LoadClasses(MTFplus plugin = null) { bool verbose = plugin != null; int SuccessfulCount = 0; string directory = FileManager.GetAppFolder() + @"MTFplus"; MTFplus.computedSubclasses = string.Empty; MTFplus.subclasses.Clear(); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); File.WriteAllText(directory + @"/medic.txt", "Inventory: KeycardSeniorGuard, GunProject90, Radio, Disarmer, Medkit, Medkit, Medkit, Medkit\n" + "Max: 2\n" + "Role: NtfCadet\n" + "Probability: 80\n" + "Ammo5: 200\n" + "Ammo7: 70\n" + "Ammo9: 50"); if (verbose) { plugin.DebugMessage("Created " + directory + ". Fill it with your own MTF classes!\nAdditionally, a template class (Medic) was created with it"); } } string[] filenames = Directory.GetFiles(directory, "*.txt"); foreach (string filename in filenames) { string name = filename.Remove(0, directory.Length + 1); if (verbose) { plugin.DebugMessage("Fetching " + name + "..."); } string[] lines = FileManager.ReadAllLines(filename).Where(x => !string.IsNullOrWhiteSpace(x)).Where(x => x[0] != '#').ToArray(); // Default values RoleType role = RoleType.NtfCadet; int maxCount = 1; float probability = 100f; List <ItemType> inventory = new List <ItemType>(); int[] IMinventory = new int[16]; for (int i = 0; i < 16; i++) { IMinventory[i] = -1; } int HP = 0; int[] ammo = new int[3] { 0, 0, 0 }; string broadcast = string.Empty; foreach (string data in lines) { if (data.StartsWith("Inventory")) { string[] invData = data.Remove(0, 10).Split(','); for (int i = 0, j = 0; i < invData.Length; i++, j++) { string item = invData[i].Trim(); #if ItemManager if (item.StartsWith("IM:")) { if (int.TryParse(item.Substring(3), out int aux)) { try { if (ItemManagerExists(aux)) { IMinventory[j] = aux; inventory.Add(ItemType.COIN); } else { if (verbose) { plugin.Error("Custom item (ItemManager) with ID: " + aux + " doesn't exist/isn't installed!"); } j--; } } catch (Exception e) { if (verbose) { plugin.Error("ItemManager not found or threw an error!\n" + e); } } } else { if (verbose) { plugin.Error("Invalid CustomItem \"" + item + " (" + item.Substring(3) + ")" + "\" in " + filename + "!"); } } continue; } #endif if (Enum.TryParse(item, out ItemType parsedItem)) { inventory.Add(parsedItem); } else if (Enum.TryParse(item, out SMod2ItemType smod2Item)) { inventory.Add((ItemType)smod2Item); } else { if (verbose) { plugin.DebugMessage("[ERROR] Invalid item \"" + item + "\" in " + filename + '!'); } } } if (inventory.Count == 0 && IMinventory.Length == 0) { if (verbose) { plugin.DebugMessage("[WARNING] \"" + filename + "\" doesn't have any valid items. Are you sure this is intended?"); } } } else if (data.StartsWith("Role")) { string roleData = data.Remove(0, 5).Trim(); if (Enum.TryParse(roleData, out RoleType roleParsed)) { role = roleParsed; } else if (Enum.TryParse(roleData, out SMod2RoleType smod2Role)) { role = (RoleType)smod2Role; } else { if (verbose) { plugin.DebugMessage("[ERROR] Invalid role \"" + roleData + "\" in " + filename + '!'); } } } else if (data.StartsWith("Max")) { string maxData = data.Remove(0, 4).Trim(); if (!int.TryParse(maxData, out int probablyMaxCount)) { if (verbose) { plugin.DebugMessage("[ERROR] Invalid maximum count \"" + maxData + "\" in " + filename + '!'); } } else { maxCount = probablyMaxCount; } } else if (data.StartsWith("Probability")) { string prob = data.Remove(0, 12).Trim(); if (!float.TryParse(prob, out float probabilitey)) { if (verbose) { plugin.DebugMessage("[ERROR] Invalid probability \"" + prob + "\" in " + filename + '!'); } } else { probability = probabilitey; } } else if (data.StartsWith("Ammo")) { if (!int.TryParse(data[4].ToString(), out int ammoTyperino)) { if (verbose) { plugin.DebugMessage("[ERROR] \"Ammo\" \"" + data + "\" unrecognized in " + filename + '!'); } } int ammoType = (ammoTyperino - 5) / 2; if (ammoType < 0 || ammoType > 2) { if (verbose) { plugin.DebugMessage("[ERROR] " + data[4].ToString() + " is not a type of ammo! (in line: " + data + " in " + filename); } } string ammoStr = data.Remove(0, 6).Trim(); if (!int.TryParse(ammoStr, out int parsedAmmo)) { if (verbose) { plugin.DebugMessage("[ERROR] Invalid Ammo \"" + ammoStr + "\" in " + filename + '!'); } } else { ammo[ammoType] = parsedAmmo; } } else if (data.StartsWith("Broadcast")) { broadcast = data.Remove(0, 10).Trim(); } else if (data.StartsWith("HP")) { string HPstr = data.Substring(3).Trim(); if (!int.TryParse(HPstr, out int HPaux)) { if (verbose) { plugin.DebugMessage("[ERROR] Invalid HP \"" + HPstr + "\" in " + filename + '!'); } } else { HP = HPaux; } } else { if (verbose) { plugin.DebugMessage("[ERROR] Unknown line: " + data + " in file " + filename); } } } name = name.Substring(0, name.Length - 4); Subclass subclass = new Subclass(name, role, inventory, IMinventory, probability, ammo, broadcast, HP); for (int i = 0; i < maxCount; i++) { MTFplus.subclasses.Add(subclass); } MTFplus.disctinctSubclasses.Add(subclass); if (verbose) { plugin.DebugMessage("[INFO] Success! Loaded " + name + " as a new class" + (plugin.Configs.debug ? ":\n" + subclass.ToString() : string.Empty)); if (plugin.Configs.debug) { plugin.DebugMessage(subclass.ToString()); } } SuccessfulCount++; } return(SuccessfulCount); }
public static IEnumerator <float> _SetClass(ReferenceHub player, Subclass subclass) { List <int> indexesToRemove = new List <int>(); if (subclass.role != RoleType.NtfCadet) { player.characterClassManager.SetPlayersClass(subclass.role, player.gameObject); } yield return(Timing.WaitForSeconds(MTFplus.Instance.Configs.delay)); if (subclass.inventory.Count > 0) { player.inventory.items.Clear(); foreach (ItemType item in subclass.inventory) { player.inventory.AddNewItem(item); } } #if ItemManager for (int i = 0; i < 16; i++) { if (subclass.imInv[i] < 0) { continue; } if (!GrantCustomItem(player, subclass, subclass.imInv[i], i)) { MTFplus.Instance.Error("Custom item (ItemManager) with ID: " + subclass.imInv[i] + " doesn't exist/isn't installed!"); indexesToRemove.Add(i); // That's the index inside the inventory, and a coin was there as a placeholder } } #endif try { player.ammoBox.Networkamount = string.Concat(new string[] { subclass.ammo[0].ToString(), ":", subclass.ammo[1].ToString(), ":", subclass.ammo[2].ToString() }); } catch (Exception e) { EXILED.Plugin.Error("Bruh momento\n" + e); } #if ItemManager // Not even updated lol List <Smod2.API.Item> inv = player.GetInventory(); foreach (int i in indexesToRemove) { inv[i].Remove(); } #endif try { if (subclass.maxHP > 0) { player.playerStats.maxHP = subclass.maxHP; player.playerStats.SetHPAmount(subclass.maxHP); } if (!string.IsNullOrWhiteSpace(subclass.broadcast)) { player.GetComponent <Broadcast>().TargetAddElement(player.characterClassManager.connectionToClient, subclass.broadcast, 5u, false); } } catch (Exception e) { EXILED.Plugin.Error(e.ToString()); } }
public static void SetClass(this ReferenceHub player, Subclass subclass) { Timing.RunCoroutine(_SetClass(player, subclass), Segment.FixedUpdate); }