/// <summary> /// Deserializes xml markup from file into an LootTableItemList object /// </summary> /// <param name="fileName">string xml file to load and deserialize</param> /// <param name="obj">Output LootTableItemList object</param> /// <param name="exception">output Exception value if deserialize failed</param> /// <returns>true if this Serializer can deserialize the object; otherwise, false</returns> public static bool LoadFromFile(string fileName, out LootTableItemList obj, out Exception exception) { exception = null; obj = default(LootTableItemList); try { obj = LoadFromFile(fileName); return(true); } catch (Exception ex) { exception = ex; return(false); } }
/// <summary> /// Deserializes workflow markup into an LootTableItemList object /// </summary> /// <param name="input">string workflow markup to deserialize</param> /// <param name="obj">Output LootTableItemList object</param> /// <param name="exception">output Exception value if deserialize failed</param> /// <returns>true if this Serializer can deserialize the object; otherwise, false</returns> public static bool Deserialize(string input, out LootTableItemList obj, out Exception exception) { exception = null; obj = default(LootTableItemList); try { obj = Deserialize(input); return(true); } catch (Exception ex) { exception = ex; return(false); } }
/// <summary> /// Given a list of items in a loot table, return the items awarded. /// </summary> /// <param name="list">LootTableItemList containing items</param> /// <returns>List of items</returns> public static List <string> CalculateItems(Xml.LootTableItemList list) { // Ordinarily, return one item from the list. var rolls = CalculateSuccessfulRolls(list.Rolls, list.Chance); var loot = new List <Xml.LootItem>(); var itemList = new List <ItemObject>(); // First, process any "always" items, which always drop when the container fires foreach (var item in list.Item.Where(i => i.Always)) { GameLog.SpawnInfo("Processing loot: added always item {item}", item.Value); loot.Add(item); } var totalRolls = 0; // Process the rest of the rolls now do { // Get a random item from the list var item = list.Item.Where(i => !i.Always).PickRandom(); // As soon as we get an item from our table, we've "rolled"; we'll add another roll below if needed rolls--; // Check uniqueness. If something has already dropped, don't drop it again, and reroll if (item.Unique && loot.Contains(item)) { rolls++; GameLog.SpawnInfo("Processing loot: added duplicate unique item {item}. Rerolling", item.Value); continue; } // Check max quantity. If it is exceeded, reroll if (item.Max > 0 && loot.Where(i => i.Value == item.Value).Count() >= item.Max) { rolls++; GameLog.SpawnInfo("Processing loot: added over max quantity for {item}. Rerolling", item.Value); continue; } // If quantity and uniqueness are good, add the item loot.Add(item); GameLog.SpawnInfo("Processing loot: added {item}", item.Value); totalRolls++; // As a check against something incredibly stupid in XML, we only allow a maximum of // 100 rolls if (totalRolls > 100) { GameLog.SpawnInfo("Processing loot: maximum number of rolls exceeded..?"); throw new LootRecursionError("Maximum number of rolls (100) exceeded!"); } }while (rolls > 0); // Now we have the canonical droplist, which needs resolving into Items foreach (var lootitem in loot) { // Does the base item exist? var xmlItemList = Game.World.WorldData.FindItem(lootitem.Value); // Don't handle the edge case of multiple genders .... yet if (xmlItemList.Count != 0) { var xmlItem = xmlItemList.First(); // Handle variants. // If multiple variants are specified, we pick one at random if (lootitem.Variants.Count() > 0) { var lootedVariant = lootitem.Variants.PickRandom(); if (xmlItem.Variants.TryGetValue(lootedVariant, out List <Xml.Item> variantItems)) { itemList.Add(Game.World.CreateItem(variantItems.PickRandom().Id)); } else { GameLog.SpawnError("Spawn loot calculation: variant group {name} not found", lootedVariant); } } else { itemList.Add(Game.World.CreateItem(xmlItem.Id)); } } else { GameLog.SpawnError("Spawn loot calculation: item {name} not found!", lootitem.Value); } } // We store loot as strings inside mobs to avoid having tens or hundreds of thousands of ItemObjects or // Items lying around - they're made into real objects at the time of mob death if (itemList.Count > 0) { return(itemList.Where(x => x != null).Select(y => y.Name).ToList()); } return(new List <String>()); }
public static bool LoadFromFile(string fileName, out LootTableItemList obj) { Exception exception = null; return(LoadFromFile(fileName, out obj, out exception)); }
public static bool Deserialize(string input, out LootTableItemList obj) { Exception exception = null; return(Deserialize(input, out obj, out exception)); }