示例#1
0
        private void Engine_OnRemoveItem(Item item)
        {
            // Count only Faction Items
            FactionItem factionItem = item as FactionItem;

            if (factionItem == null)
            {
                return;
            }

            // Ignore Items that are not assineable to the FilterType
            if (FilterType != null && !FilterType.IsAssignableFrom(item.GetType()))
            {
                return;
            }

            // Count only own Items
            if (Faction != factionItem.Faction)
            {
                return;
            }

            // Call inherited Method
            OnRemove(factionItem);
        }
示例#2
0
        private void Faction_PopulateInfo(ItemLocation src)
        {
            if ((src is FactionItem) == false)
            {
                return;
            }
            //
            FactionItem topop = src as FactionItem;

            // Name & Area
            TB_Faction_Name.Text           = topop.FactionName;
            CB_Faction_Level.SelectedIndex = (int)topop.Level;
            // Money Cost
            int total = topop.Cost;
            int gold  = total / 10000;

            total -= gold * 10000;
            int silver = total / 100;

            total -= silver * 100;
            TB_Faction_Money_1.Value = gold;
            TB_Faction_Money_2.Value = silver;
            TB_Faction_Money_3.Value = total;
            // Token Map Cost (TODO)
            //
            isChanging = false;
            Faction_InfoChanged();
            isChanging = true;
        }
示例#3
0
 public AnkhofShieldingTB()
 {
     FactionItem.Imbue(this, TrueBritannians.Instance, false, TrueBritannians.Instance.Definition.HuePrimary);
     Hue      = 2214;
     Weight   = 0.1;
     LootType = LootType.Blessed;
 }
示例#4
0
 public AnkhofShieldingCoM()
 {
     FactionItem.Imbue(this, CouncilOfMages.Instance, false, CouncilOfMages.Instance.Definition.HuePrimary);
     Hue      = 1325;
     Weight   = 0.1;
     LootType = LootType.Blessed;
 }
示例#5
0
 public AnkhofShieldingMinax()
 {
     Name = "Ankh of Shielding";
     FactionItem.Imbue(this, Minax.Instance, false, Minax.Instance.Definition.HuePrimary);
     Hue      = 1645;
     Weight   = 0.1;
     LootType = LootType.Blessed;
 }
示例#6
0
 public MinaxArmoredFactionRobe()
     : base(0x2684)
 {
     Name     = "armored shroud";
     Weight   = 3.0;
     LootType = LootType.Blessed;
     FactionItem.Imbue(this, Minax.Instance, false, Minax.Instance.Definition.HuePrimary);
 }
示例#7
0
 public AnkhofShieldingSL()
 {
     Name = "Ankh of Shielding";
     FactionItem.Imbue(this, Shadowlords.Instance, false, Shadowlords.Instance.Definition.HuePrimary);
     Hue      = 1109;
     Weight   = 0.1;
     LootType = LootType.Blessed;
 }
        /// <summary>
        /// Default Constructor for the Type Mapper.
        /// </summary>
        /// <param name="faction">Faction</param>
        /// <param name="item">Item</param>
        /// <param name="interop">UnitInterop</param>
        public RecognitionInterop(Faction faction, FactionItem item, UnitInterop interop)
            : base(faction, item, interop)
        {
            // Get Sniffer Reference
            var sniffer = Item.GetProperty<SnifferProperty>();
            if (sniffer == null)
                throw new ArgumentException("Item does not contain SnifferProperty");

            // Insert sniffed Items into the List.
            sniffer.OnNewSmellableItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (!smellableItems.Contains(info))
                    smellableItems.Add(info);
            };

            // Remove sniffed Items from List.
            sniffer.OnLostSmellableItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (smellableItems.Contains(info))
                    smellableItems.Remove(info);
            };

            // Get Sighting Property
            sighting = Item.GetProperty<SightingProperty>();
            if (sighting == null)
                throw new ArgumentException("Item does not contain SightingProperty");

            // Add visible items to List.
            sighting.OnNewVisibleItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (!visibleItems.Contains(info))
                    visibleItems.Add(info);
            };

            // Remove visible Items from List.
            sighting.OnLostVisibleItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (visibleItems.Contains(info))
                    visibleItems.Remove(info);
            };

            // Set new Environment on Cell Switch
            sighting.OnEnvironmentChanged += (i, value) =>
            {
                if (OnEnvironmentChanged != null)
                    OnEnvironmentChanged(value);
            };
        }
示例#9
0
        /// <summary>
        /// Default Constructor for the Type Mapper.
        /// </summary>
        /// <param name="faction">Faction</param>
        /// <param name="item">Item</param>
        /// <param name="interop">UnitInterop</param>
        public AntMovementInterop(Faction faction, FactionItem item, UnitInterop interop) : base(faction, item, interop)
        {
            // Get Walking Property
            walking = Item.GetProperty <WalkingProperty>();
            if (walking == null)
            {
                throw new NotSupportedException("There is no Walking Property");
            }

            // Get Collision Property
            collidable = Item.GetProperty <CollidableProperty>();
            if (collidable == null)
            {
                throw new NotSupportedException("There is no Collidable Property");
            }

            // Handle Collisions with Walls and Borders.
            walking.OnHitBorder += (i, v) => { if (OnHitWall != null)
                                               {
                                                   OnHitWall(v);
                                               }
            };
            walking.OnHitWall += (i, v) => { if (OnHitWall != null)
                                             {
                                                 OnHitWall(v);
                                             }
            };

            // Kollisionen mit anderen Items füllt die Liste der Kollisionsitems
            // und prüft, ob es sich beim getroffenen Item um das Ziel handelt.
            collidable.OnCollision += (i, v) =>
            {
                // Zur Liste der kollidierten Items hinzufügen.
                collidedItems.Add(v.GetItemInfo(Item));

                // Prüfen, ob es sich um das aktuelle Ziel handelt.
                if (CurrentDestination != null &&
                    Item == Item.GetItemFromInfo(CurrentDestination))
                {
                    // Alles anhalten und Reach melden
                    Stop();
                    if (OnTargetReched != null)
                    {
                        OnTargetReched(i.GetItemInfo(Item));
                    }
                }
            };
        }
示例#10
0
        public UnitInterop(Faction faction, FactionItem item)
        {
            if (faction == null)
                throw new ArgumentNullException("faction");

            // Faction soll bereits teil eines Levels sein.
            if (faction.Level == null)
                throw new ArgumentException("Faction is not Part of a Level");

            // AntItem darf nicht null sein.
            if (item == null)
                throw new ArgumentNullException("item");

            Faction = faction;
            Item = item;
        }
示例#11
0
        private static void FactionReset()
        {
            List <Faction> factions = Faction.Factions;

            for (int i = 0; i < factions.Count; ++i)
            {
                Faction f = factions[i];

                List <PlayerState> memberlist = new List <PlayerState>(f.Members);

                for (int j = 0; j < memberlist.Count; ++j)
                {
                    f.RemoveMember(memberlist[j].Mobile);
                }

                List <FactionItem> itemlist = new List <FactionItem>(f.State.FactionItems);

                for (int j = 0; j < itemlist.Count; ++j)
                {
                    FactionItem fi = itemlist[j];

                    if (fi.Expiration == DateTime.MinValue)
                    {
                        fi.Item.Delete();
                    }
                    else
                    {
                        fi.Detach();
                    }
                }

                List <BaseFactionTrap> traplist = new List <BaseFactionTrap>(f.Traps);

                for (int j = 0; j < traplist.Count; ++j)
                {
                    traplist[i].Delete();
                }
            }
        }
示例#12
0
        protected override void OnCreate()
        {
            base.OnCreate();

            //get all factions. if i encountered a new faction, add it
            Map.Instance.GetObjects(Map.Instance.InitialCollisionBounds, MapObjectSceneGraphGroups.UnitGroupMask, delegate(MapObject mapObject)
            {
                Unit u = mapObject as Unit;

                if (u.InitialFaction != null)
                {
                    FactionItem fact = GetFactionItemByType(u.InitialFaction as VBFactionType);

                    if (u != null && u.InitialFaction != null && fact == null)
                    {
                        FactionItem f      = new FactionItem();
                        f.FactionType      = u.InitialFaction as VBFactionType;
                        f.ObjectiveManager = new ObjectiveManager();
                        factions.Add(f);
                    }
                }
            });
        }
示例#13
0
 /// <summary>
 /// Gets a call on new Items (filtered by FilterType, FactionItem and right Faction)
 /// </summary>
 /// <param name="item">New Item</param>
 protected abstract void OnInsert(FactionItem item);
示例#14
0
 public AnthillInfo(FactionItem item, Item observer)
     : base(item, observer)
 {
     anthillItem = item as AnthillItem;
 }
示例#15
0
 /// <summary>
 /// Gets a call on new Items (filtered by FilterType, FactionItem and right Faction)
 /// </summary>
 /// <param name="item">New Item</param>
 protected override void OnInsert(FactionItem item)
 {
     totalItems++;
     currentItems++;
 }
示例#16
0
        /// <summary>
        /// Default Constructor for the Type Mapper.
        /// </summary>
        /// <param name="faction">Faction</param>
        /// <param name="item">Item</param>
        /// <param name="interop">UnitInterop</param>
        public RecognitionInterop(Faction faction, FactionItem item, UnitInterop interop) : base(faction, item, interop)
        {
            // Get Sniffer Reference
            var sniffer = Item.GetProperty <SnifferProperty>();

            if (sniffer == null)
            {
                throw new ArgumentException("Item does not contain SnifferProperty");
            }

            // Insert sniffed Items into the List.
            sniffer.OnNewSmellableItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (!smellableItems.Contains(info))
                {
                    smellableItems.Add(info);
                }
            };

            // Remove sniffed Items from List.
            sniffer.OnLostSmellableItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (smellableItems.Contains(info))
                {
                    smellableItems.Remove(info);
                }
            };

            // Get Sighting Property
            sighting = Item.GetProperty <SightingProperty>();
            if (sighting == null)
            {
                throw new ArgumentException("Item does not contain SightingProperty");
            }

            // Add visible items to List.
            sighting.OnNewVisibleItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (!visibleItems.Contains(info))
                {
                    visibleItems.Add(info);
                }
            };

            // Remove visible Items from List.
            sighting.OnLostVisibleItem += property =>
            {
                var info = property.Item.GetItemInfo(Item);
                if (visibleItems.Contains(info))
                {
                    visibleItems.Remove(info);
                }
            };

            // Set new Environment on Cell Switch
            sighting.OnEnvironmentChanged += (i, value) =>
            {
                if (OnEnvironmentChanged != null)
                {
                    OnEnvironmentChanged(value);
                }
            };
        }
示例#17
0
 /// <summary>
 /// Default Constructor for the Type Mapper.
 /// </summary>
 /// <param name="faction">Faction</param>
 /// <param name="item">Item</param>
 /// <param name="interop">UnitInterop</param>
 public UnitInteropProperty(Faction faction, FactionItem item, UnitInterop interop)
 {
     Faction = faction;
     Item    = item;
     Interop = interop;
 }
示例#18
0
 /// <summary>
 /// Gets a call on removed Items (filtered by FilterType, FactionItem and right Faction)
 /// </summary>
 /// <param name="item">Removed Item</param>
 protected override void OnRemove(FactionItem item)
 {
     currentItems--;
 }
示例#19
0
 /// <summary>
 /// Gets a call on removed Items (filtered by FilterType, FactionItem and right Faction)
 /// </summary>
 /// <param name="item">Removed Item</param>
 protected abstract void OnRemove(FactionItem item);
示例#20
0
        /// <summary>
        /// Default Constructor for the Type Mapper.
        /// </summary>
        /// <param name="faction">Faction</param>
        /// <param name="item">Item</param>
        /// <param name="interop">UnitInterop</param>
        public InteractionInterop(Faction faction, FactionItem item, UnitInterop interop) : base(faction, item, interop)
        {
            #region Collector

            sugar = item.GetProperty <SugarCollectorProperty>();
            if (sugar == null)
            {
                throw new ArgumentException("Item does not contain SugarCollector");
            }

            apple = item.GetProperty <AppleCollectorProperty>();
            if (apple == null)
            {
                throw new ArgumentException("Item does not contain AppleCollector");
            }

            #endregion

            #region Carrier

            carrier = item.GetProperty <CarrierProperty>();
            if (carrier == null)
            {
                throw new ArgumentException("Item does not contain CarrierProperty");
            }

            #endregion

            #region Attackable

            attackable = item.GetProperty <AttackableProperty>();
            if (attackable == null)
            {
                throw new ArgumentException("Item does not contain AttackableProperty");
            }

            attackable.OnKill += i =>
            {
                if (OnKill != null)
                {
                    OnKill();
                }
            };

            attackable.OnAttackerHit += (i, value) =>
            {
                if (OnHit != null)
                {
                    OnHit(value);
                }
            };

            attackable.OnNewAttackerItem += i =>
            {
                var info = Item.GetItemInfo(i.Item);

                if (!attackerItems.Contains(info))
                {
                    attackerItems.Add(info);
                }
            };

            attackable.OnLostAttackerItem += i =>
            {
                var info = Item.GetItemInfo(i.Item);

                if (attackerItems.Contains(info))
                {
                    attackerItems.Remove(info);
                }
            };

            #endregion

            #region Attacker

            attacker = item.GetProperty <AttackerProperty>();
            if (attacker == null)
            {
                throw new ArgumentException("Item does not contain AttackerProperty");
            }

            #endregion

            // Automatic Resource Transfer on Anthill Collision.
            var collidable = item.GetProperty <CollidableProperty>();
            if (collidable == null)
            {
                throw new ArgumentException("Item does not contain AttackerProperty");
            }

            collidable.OnCollision += (i, value) =>
            {
                // Ignore if it's not a Anthill
                if (!(value is AnthillItem))
                {
                    return;
                }

                var anthill = value as AnthillItem;

                // Ignore if it's not the right faction
                if (anthill.Faction != item.Faction)
                {
                    return;
                }

                // Transfer all collectables
                Give(anthill);
            };
        }
 /// <summary>
 /// Default Constructor for the Type Mapper.
 /// </summary>
 /// <param name="faction">Faction</param>
 /// <param name="item">Item</param>
 /// <param name="interop">UnitInterop</param>
 public UnitInteropProperty(Faction faction, FactionItem item, UnitInterop interop)
 {
     Faction = faction;
     Item = item;
     Interop = interop;
 }
示例#22
0
        private void bwParseItemSource_DoWork(object sender, DoWorkEventArgs e)
        {
            string hdoc = e.Argument as string;
            int id = _lastItemId;
            string itemId = "0";
            try
            {
                // First lets make sure it downloaded properly and pull the Item Id out of it. If not, stop working
                Regex idFinder = new Regex("wowhead.com.item=(\\d+)\"");
                Match match;
                if ((match = idFinder.Match(hdoc)).Success) {
                    id = int.Parse(match.Groups[1].Value);
                } else { return; } // It didn't load right
                Item item = ItemCache.Instance.Items[id];
                itemId = item.Id.ToString();

                //bool LocInfoIsValid = item.LocationInfo != null && item.LocationInfo.Count > 0;

                if (/*LocInfoIsValid &&*/ item.LocationInfo[0] is VendorItem) {
                    List<string> tokenIds = new List<string> { };
                    List<int> tokenCounts = new List<int> { };
                    string tokenName = "Unknown Currency";
                    //TokenDropInfo tokenDropInfo = null;
                    int goldCost = 0;
                    string repSource = "", repLevel = "";

                    #region Try to get the Token Names and individual costs
                    int liststartpos = hdoc.IndexOf("new Listview({template: 'npc', id: 'sold-by'");
                    if (liststartpos > 1) {
                        int listendpos = hdoc.IndexOf(";", liststartpos);
                        string costExcerpt = hdoc.Substring(liststartpos, listendpos - liststartpos);
                        // we are looking for something like cost:[0,0,0,[[40633,1]]]

                        // cost:[gold,[[currencyId1,currencyQu1],[currencyId2,currencyQu2]],[objectId,objectQu]]
                        Regex costRegex = new Regex(@"cost:\[(?<gold>\d+)\[(?:\[(?<currencyId1>\d+),(?<currencyQu1>\d+)\])?,?(?:\[(?<currencyId2>\d+),(?<currencyQu2>\d+)\])?\],\[(?:\[?(?<tokenId1>\d+),(?<tokenQu1>\d+)\]?)?,?(?:\[?(?<tokenId2>\d+),(?<tokenQu2>\d+)\]?)?\]\]");
                        Regex costRegexGoldOnly = new Regex(@"cost:\[(?<gold>\d+)\]");
                        Match costMatch;

                        if ((costMatch = costRegex.Match(costExcerpt)).Success) {
                            // Yay! it worked!
                            // Start with Gold Cost. Items that don't cost Gold will still get a default of 0
                            goldCost = int.Parse(costMatch.Groups["gold"].Value);
                            // Lets try Currency 1, such as Justice Points
                            if (!String.IsNullOrEmpty(costMatch.Groups["currencyId1"].Value)) {
                                tokenIds.Add(costMatch.Groups["currencyId1"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["currencyQu1"].Value));
                            }
                            // Lets try Currency 2, such as Justice Points
                            // Not sure if there would ever actually be a 2nd here, but it was formatted as if it was possible
                            // If nothing else, when currencyId1 fails but 2 is valid we put something in the array
                            if (!String.IsNullOrEmpty(costMatch.Groups["currencyId2"].Value)) {
                                tokenIds.Add(costMatch.Groups["currencyId2"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["currencyQu2"].Value));
                            }
                            // Lets try Token 1 cost, such as Mantle of the Conqueror
                            if (!String.IsNullOrEmpty(costMatch.Groups["tokenId1"].Value)) {
                                tokenIds.Add(costMatch.Groups["tokenId1"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["tokenQu1"].Value));
                            }
                            // Lets try Token 2 cost, such as Mantle of the Conqueror
                            if (!String.IsNullOrEmpty(costMatch.Groups["tokenId2"].Value)) {
                                tokenIds.Add(costMatch.Groups["tokenId2"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["tokenQu2"].Value));
                            }
                        } else if ((costMatch = costRegex.Match(costExcerpt)).Success) {
                            // Yay! it worked!
                            // Just do Gold Cost. Items that don't cost Gold will still get a default of 0
                            goldCost = int.Parse(costMatch.Groups["gold"].Value);
                        }
                    }
                    #endregion
                    #region Check to see if it requires a specific Faction and get its required level
                    liststartpos = hdoc.IndexOf("Requires <a href=\"/faction=");
                    if (liststartpos > 1)
                    {
                        int listendpos = hdoc.IndexOf("</td>", liststartpos);
                        string repExcerpt = hdoc.Substring(liststartpos, listendpos - liststartpos);
                        // we are looking for something like cost:[0,0,0,[[40633,1]]]

                        // cost:[gold,[[currencyId1,currencyQu1],[currencyId2,currencyQu2]],[objectId,objectQu]]
                        Regex repRegex = new Regex(@"Requires .a href=.\/faction=(?<factionId>\d+). class=.q\d.>.+\/a. - (?<level>(?:Friendly|Honored|Revered|Exalted))");
                        Match repMatch;

                        if ((repMatch = repRegex.Match(repExcerpt)).Success)
                        {
                            // Yay! it worked!
                            // Lets get the Faction's name based on the ID
                            repSource = GetItemFactionVendorInfo(repMatch.Groups["factionId"].Value, "0")[0];
                            switch (repMatch.Groups["level"].Value) {
                                case "Friendly":{ repLevel = "4"; break; }
                                case "Honored": { repLevel = "5"; break; }
                                case "Revered": { repLevel = "6"; break; }
                                case "Exalted": { repLevel = "7"; break; }
                                default: { repLevel = "0"; break; }
                            }
                        }
                    }
                    #endregion

                    VendorItem vendorItem = item.LocationInfo[0] as VendorItem;
                    vendorItem.Cost = goldCost;

                    for (int i = 0; i < 3; i++)
                    {
                        if (tokenIds.Count < i + 1) { break; } // stop processing if we don't have any more
                        // Check to see if it's a PvP token/Currency
                        if (!String.IsNullOrEmpty(tokenIds[i]) && _pvpTokenMap.TryGetValue(tokenIds[i], out tokenName)) {
                            if (tokenName == "Honor Points" || tokenIds[i] == "392")
                                item.LocationInfo = new ItemLocationList() { new PvpItem() { Points = tokenCounts[i], PointType = "Honor" } };
                            else if (tokenName == "Conquest Points" || tokenIds[i] == "390")
                                item.LocationInfo = new ItemLocationList() { new PvpItem() { Points = tokenCounts[i], PointType = "Conquest" } };
                            else
                                item.LocationInfo = new ItemLocationList() { new PvpItem() { TokenCount = tokenCounts[i], TokenType = tokenName } };
                            vendorItem = null; // invalidate the vendor item so it doesn't get added in later
                            break;
                        } else if (tokenIds[i] != null && _vendorTokenMap.TryGetValue(tokenIds[i], out tokenName)) {
                            vendorItem.TokenMap[tokenName] = tokenCounts[i];
                        } else if (tokenIds[i] != null) {
                            if ((tokenName == "Justice Points" || tokenIds[i] == "395")
                                || (tokenName == "Valor Points" || tokenIds[i] == "396"))
                            { item.Cost = tokenCounts[i]; } // Sets the cost on the item for the user
                            #region It's a PvE Token
                            // ok now let's see what info we can get about this token
                            string boss = null; string vendor = null;
                            string area = null; string vendorarea = null;
                            bool heroic = false;
                            bool lfr = false;
                            bool container = false;
                            if (!_tokenDropMap.ContainsKey(tokenIds[i])) {
                                // Not doing this =^( hopefully we won't actually need to cuz I mapped all the currencies listed in wowhead
                                #region We *really* haven't seen this before so we need to pull the data
                                /*XDocument docToken = wrw.DownloadItemWowhead(site, tokenIds[i]);
                                if (docToken != null)
                                {
                                    tokenNames[i] = docToken.SelectSingleNode("wowhead/item/name").Value;

                                    // we don't want token => boss propagation anymore, otherwise you get weird stuff like 277 gloves dropping from Toravon
                                    /*string tokenJson = docToken.SelectSingleNode("wowhead/item/json").InnerText;

                                    string tokenSource = string.Empty;
                                    if (tokenJson.Contains("\"source\":["))
                                    {
                                        tokenSource = tokenJson.Substring(tokenJson.IndexOf("\"source\":[") + "\"source\":[".Length);
                                        tokenSource = tokenSource.Substring(0, tokenSource.IndexOf("]"));
                                    }

                                    string tokenSourcemore = string.Empty;
                                    if (tokenJson.Contains("\"sourcemore\":[{"))
                                    {
                                        tokenSourcemore = tokenJson.Substring(tokenJson.IndexOf("\"sourcemore\":[{") + "\"sourcemore\":[{".Length);
                                        tokenSourcemore = tokenSourcemore.Substring(0, tokenSourcemore.IndexOf("}]"));
                                    }

                                    if (!string.IsNullOrEmpty(tokenSource) && !string.IsNullOrEmpty(tokenSourcemore))
                                    {
                                        string[] tokenSourceKeys = tokenSource.Split(',');
                                        string[] tokenSourcemoreKeys = tokenSourcemore.Split(new string[] { "},{" }, StringSplitOptions.RemoveEmptyEntries);

                                        // for tokens we prefer loot info, we don't care if it can be bought with badges
                                        tokenSource = tokenSourceKeys[0];
                                        tokenSourcemore = tokenSourcemoreKeys[0];

                                        int dropIndex = Array.IndexOf(tokenSourceKeys, "2");
                                        if (dropIndex >= 0)
                                        {
                                            tokenSource = tokenSourceKeys[dropIndex];
                                            tokenSourcemore = tokenSourcemoreKeys[dropIndex];
                                        }

                                        if (tokenSource == "2")
                                        {
                                            foreach (string kv in tokenSourcemore.Split(','))
                                            {
                                                if (!string.IsNullOrEmpty(kv))
                                                {
                                                    string[] keyvalsplit = kv.Split(':');
                                                    string key = keyvalsplit[0];
                                                    string val = keyvalsplit[1];
                                                    switch (key.Trim('"'))
                                                    {
                                                        case "t":
                                                            container = val == "2" || val == "3";
                                                            break;
                                                        case "n":       // NPC 'Name'
                                                            boss = val.Replace("\\'", "'").Trim('"');
                                                            break;
                                                        case "z":       // Zone
                                                            area = GetZoneName(val);
                                                            break;
                                                        case "dd":      // Dungeon Difficulty (1 = Normal, 2 = Heroic)
                                                            heroic = val == "2";
                                                            break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    if (boss == null) 
                                    { 
                                        //boss = "Unknown Boss (Wowhead lacks data)";
                                        area = null; // if boss is null prefer treating this as pve token
                                    }*/
                                /*
                                if (tokenNames[i] != null)
                                {
                                    _tokenDropMap[tokenIds[i]] = new TokenDropInfo() { Boss = boss, Area = area, Heroic = heroic, Name = tokenNames[i], Container = container };
                                }
                            }*/
                                #endregion
                            } else {
                                #region We've seen this before so just use that data
                                TokenDropInfo info = _tokenDropMap[tokenIds[i]];
                                boss = info.Boss; vendor = info.Vendor;
                                area = info.Area; vendorarea = info.VendorArea;
                                heroic = info.Heroic;
                                lfr = info.LFR;
                                tokenName = info.Name;
                                container = info.Container;
                                #endregion
                            }
                            if (tokenName != null) {
                                #region This is NOT a Dropped Token, so treat it as a normal vendor item and include token info
                                vendorItem.TokenMap[tokenName] = tokenCounts[i];
                                if (!String.IsNullOrEmpty(area) && !String.IsNullOrEmpty(vendorarea) && area != vendorarea && vendorarea != "Unknown Area") {
                                    // We are lucky enough to have BOTH drop points, so lets set both up
                                    vendorItem.VendorArea = vendorarea;
                                    vendorItem.VendorName = vendor;
                                    vendorItem.TokenMap[tokenName] = tokenCounts[i];
                                    ItemLocation droppoint = new StaticDrop() { Area = area, Boss = boss, Heroic = heroic, LFR = lfr };
                                    item.LocationInfo = new ItemLocationList() { vendorItem, droppoint }; 
                                    vendorItem = null;
                                    break;
                                } else {
                                    vendorItem.VendorArea = area;
                                    vendorItem.VendorName = boss;
                                }
                                #endregion
                            } else if (area != null) {
                                #region This is a Dropped Token or we know what vendor is dropping it, so assign it to where it drops from
                                if (container) {
                                    ItemLocation locInfo = new ContainerItem()
                                    {
                                        Area = area,
                                        Container = boss,
                                        Heroic = heroic,
                                        LFR = lfr,
                                    };
                                    item.LocationInfo = new ItemLocationList() { locInfo };
                                    vendorItem = null;
                                    break;
                                } else {
                                    ItemLocation locInfo = new StaticDrop()
                                    {
                                        Area = area,
                                        Boss = boss,
                                        Heroic = heroic,
                                        LFR = lfr,
                                    };
                                    item.LocationInfo = new ItemLocationList() { locInfo };
                                    vendorItem = null;
                                    break;
                                }
                                #endregion
                            } else /*if (tokenNames[i] == null)*/ {
                                // there was an error pulling token data from web
                                // ignore source information
                                vendorItem = null;
                                break;
                            }
                            #endregion
                        } else {
                            #region There is no token so this is a normal vendor item
                            if (!String.IsNullOrEmpty(repSource) && !String.IsNullOrEmpty(repLevel)) {
                                string[] repInfo = GetItemFactionVendorInfo(repSource, repLevel);
                                FactionItem locInfo = new FactionItem()
                                {
                                    FactionName = repInfo[0],
                                    Level = (ReputationLevel)int.Parse(repLevel), // repInfo[3]
                                    Cost = goldCost,
                                };
                                item.LocationInfo = new ItemLocationList() { locInfo };
                                vendorItem = null;
                                break;
                            }/* else {
                                VendorItem locInfo = new VendorItem()
                                {
                                    Cost = goldCost,
                                };
                                if (!string.IsNullOrEmpty(n)) locInfo.VendorName = n;
                                if (sourcemore != null && sourcemore.TryGetValue("z", out tmp))
                                {
                                    locInfo.VendorArea = GetZoneName(tmp.ToString());
                                }
                                item.LocationInfo = new ItemLocationList() { locInfo };
                                vendorItem = null;
                                break;
                            }*/
                            #endregion
                        }
                    }
                    if (vendorItem != null) {
                        // We already set the Vendor Name and Zone
                        item.LocationInfo = new ItemLocationList() { vendorItem };
                    }
                }else if (/*LocInfoIsValid &&*/ item.LocationInfo[0] is StaticDrop) {
                    int count = 0, outof = 0;

                    #region Try to get the Count and OutOf numbers, which are used to make the Drop Rate Perc
                    int liststartpos = hdoc.IndexOf("new Listview({template: 'npc', id: 'dropped-by'");
                    if (liststartpos > 1) {
                        int listendpos = hdoc.IndexOf(";", liststartpos);
                        string dropExcerpt = hdoc.Substring(liststartpos, listendpos - liststartpos);
                        // we are looking for something like count:2939,outof:13677

                        // (?:count:(?<count>\d+),outof:(?<outof>\d+))
                        Regex dropRegex = new Regex(@"(?:count:(?<count>\d+),outof:(?<outof>\d+))");
                        Match dropMatch;

                        if ((dropMatch = dropRegex.Match(dropExcerpt)).Success) {
                            // Yay! it worked!
                            count = int.Parse(dropMatch.Groups["count"].Value);
                            outof = int.Parse(dropMatch.Groups["outof"].Value);
                        }
                    }
                    #endregion

                    StaticDrop dropItem = item.LocationInfo[0] as StaticDrop;

                    if (dropItem != null) {
                        dropItem.Count = count;
                        dropItem.OutOf = outof;
                        item.LocationInfo = new ItemLocationList() { dropItem };
                    }
                } else if (/*LocInfoIsValid &&*/ item.LocationInfo[0] is PvpItem) {
                    List<string> tokenIds = new List<string> { };
                    List<int> tokenCounts = new List<int> { };
                    string tokenName = "Unknown Currency";
                    //TokenDropInfo tokenDropInfo = null;
                    string repSource = "", repLevel = "";

                    #region Try to get the Token Names and individual costs
                    int liststartpos = hdoc.IndexOf("new Listview({template: 'npc', id: 'sold-by'");
                    if (liststartpos > 1) {
                        int listendpos = hdoc.IndexOf(";", liststartpos);
                        string costExcerpt = hdoc.Substring(liststartpos, listendpos - liststartpos);
                        // we are looking for something like cost:[0,0,0,[[40633,1]]]

                        // cost:[gold,[[currencyId1,currencyQu1],[currencyId2,currencyQu2]],[objectId,objectQu]]
                        Regex costRegex = new Regex(@"cost:\[(?<gold>\d+),\[(?:\[(?<currencyId1>\d+),(?<currencyQu1>\d+)\])?,?(?:\[(?<currencyId2>\d+),(?<currencyQu2>\d+)\])?\],\[(?:\[?(?<tokenId1>\d+),(?<tokenQu1>\d+)\]?)?,?(?:\[?(?<tokenId2>\d+),(?<tokenQu2>\d+)\]?)?\]\]");
                        Regex costRegexGoldOnly = new Regex(@"cost:\[(?<gold>\d+)\]");
                        Match costMatch;

                        if ((costMatch = costRegex.Match(costExcerpt)).Success) {
                            // Yay! it worked!
                            // Lets try Currency 1, such as Justice Points
                            if (!String.IsNullOrEmpty(costMatch.Groups["currencyId1"].Value)) {
                                tokenIds.Add(costMatch.Groups["currencyId1"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["currencyQu1"].Value));
                            }
                            // Lets try Currency 2, such as Justice Points
                            // Not sure if there would ever actually be a 2nd here, but it was formatted as if it was possible
                            // If nothing else, when currencyId1 fails but 2 is valid we put something in the array
                            if (!String.IsNullOrEmpty(costMatch.Groups["currencyId2"].Value)) {
                                tokenIds.Add(costMatch.Groups["currencyId2"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["currencyQu2"].Value));
                            }
                            // Lets try Token 1 cost, such as Mantle of the Conqueror
                            if (!String.IsNullOrEmpty(costMatch.Groups["tokenId1"].Value)) {
                                tokenIds.Add(costMatch.Groups["tokenId1"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["tokenQu1"].Value));
                            }
                            // Lets try Token 2 cost, such as Mantle of the Conqueror
                            if (!String.IsNullOrEmpty(costMatch.Groups["tokenId2"].Value)) {
                                tokenIds.Add(costMatch.Groups["tokenId2"].Value);
                                tokenCounts.Add(int.Parse(costMatch.Groups["tokenQu2"].Value));
                            }
                        } else if ((costMatch = costRegex.Match(costExcerpt)).Success) {
                            // Yay! it worked!
                        }
                    }
                    #endregion
                    #region Check to see if it requires a specific Faction and get its required level
                    liststartpos = hdoc.IndexOf("Requires <a href=\"/faction=");
                    if (liststartpos > 1)
                    {
                        int listendpos = hdoc.IndexOf("</td>", liststartpos);
                        string repExcerpt = hdoc.Substring(liststartpos, listendpos - liststartpos);
                        // we are looking for something like cost:[0,0,0,[[40633,1]]]

                        // cost:[gold,[[currencyId1,currencyQu1],[currencyId2,currencyQu2]],[objectId,objectQu]]
                        Regex repRegex = new Regex(@"Requires .a href=.\/faction=(?<factionId>\d+). class=.q\d.>.+\/a. - (?<level>(?:Friendly|Honored|Revered|Exalted))");
                        Match repMatch;

                        if ((repMatch = repRegex.Match(repExcerpt)).Success)
                        {
                            // Yay! it worked!
                            // Lets get the Faction's name based on the ID
                            repSource = GetItemFactionVendorInfo(repMatch.Groups["factionId"].Value, "0")[0];
                            switch (repMatch.Groups["level"].Value) {
                                case "Friendly":{ repLevel = "4"; break; }
                                case "Honored": { repLevel = "5"; break; }
                                case "Revered": { repLevel = "6"; break; }
                                case "Exalted": { repLevel = "7"; break; }
                                default: { repLevel = "0"; break; }
                            }
                        }
                    }
                    #endregion

                    PvpItem pvpItem = item.LocationInfo[0] as PvpItem;

                    for (int i = 0; i < 3; i++)
                    {
                        if (tokenIds.Count < i + 1) { break; } // stop processing if we don't have any more
                        // Check to see if it's a PvP token/Currency
                        if (!String.IsNullOrEmpty(tokenIds[i]) && _pvpTokenMap.TryGetValue(tokenIds[i], out tokenName)) {
                            if (tokenName == "Honor Points" || tokenIds[i] == "392")
                                item.LocationInfo = new ItemLocationList() { new PvpItem() { Points = tokenCounts[i], PointType = "Honor" } };
                            else if (tokenName == "Conquest Points" || tokenIds[i] == "390")
                                item.LocationInfo = new ItemLocationList() { new PvpItem() { Points = tokenCounts[i], PointType = "Conquest" } };
                            else
                                item.LocationInfo = new ItemLocationList() { new PvpItem() { TokenCount = tokenCounts[i], TokenType = tokenName } };
                            pvpItem = null; // invalidate the vendor item so it doesn't get added in later
                            break;
                        } else if (tokenIds[i] != null && _vendorTokenMap.TryGetValue(tokenIds[i], out tokenName)) {
                            //pvpItem.TokenMap[tokenName] = tokenCounts[i];
                        } else if (tokenIds[i] != null) {
                            if ((tokenName == "Justice Points" || tokenIds[i] == "395")
                                || (tokenName == "Valor Points" || tokenIds[i] == "396"))
                            { item.Cost = tokenCounts[i]; } // Sets the cost on the item for the user
                            #region It's a PvE Token
                            // ok now let's see what info we can get about this token
                            string boss = null; string vendor = null;
                            string area = null; string vendorarea = null;
                            bool heroic = false;
                            bool lfr = false;
                            bool container = false;
                            if (!_tokenDropMap.ContainsKey(tokenIds[i])) {
                                // Not doing this =^( hopefully we won't actually need to cuz I mapped all the currencies listed in wowhead
                                #region We *really* haven't seen this before so we need to pull the data
                                /*XDocument docToken = wrw.DownloadItemWowhead(site, tokenIds[i]);
                                if (docToken != null)
                                {
                                    tokenNames[i] = docToken.SelectSingleNode("wowhead/item/name").Value;

                                    // we don't want token => boss propagation anymore, otherwise you get weird stuff like 277 gloves dropping from Toravon
                                    /*string tokenJson = docToken.SelectSingleNode("wowhead/item/json").InnerText;

                                    string tokenSource = string.Empty;
                                    if (tokenJson.Contains("\"source\":["))
                                    {
                                        tokenSource = tokenJson.Substring(tokenJson.IndexOf("\"source\":[") + "\"source\":[".Length);
                                        tokenSource = tokenSource.Substring(0, tokenSource.IndexOf("]"));
                                    }

                                    string tokenSourcemore = string.Empty;
                                    if (tokenJson.Contains("\"sourcemore\":[{"))
                                    {
                                        tokenSourcemore = tokenJson.Substring(tokenJson.IndexOf("\"sourcemore\":[{") + "\"sourcemore\":[{".Length);
                                        tokenSourcemore = tokenSourcemore.Substring(0, tokenSourcemore.IndexOf("}]"));
                                    }

                                    if (!string.IsNullOrEmpty(tokenSource) && !string.IsNullOrEmpty(tokenSourcemore))
                                    {
                                        string[] tokenSourceKeys = tokenSource.Split(',');
                                        string[] tokenSourcemoreKeys = tokenSourcemore.Split(new string[] { "},{" }, StringSplitOptions.RemoveEmptyEntries);

                                        // for tokens we prefer loot info, we don't care if it can be bought with badges
                                        tokenSource = tokenSourceKeys[0];
                                        tokenSourcemore = tokenSourcemoreKeys[0];

                                        int dropIndex = Array.IndexOf(tokenSourceKeys, "2");
                                        if (dropIndex >= 0)
                                        {
                                            tokenSource = tokenSourceKeys[dropIndex];
                                            tokenSourcemore = tokenSourcemoreKeys[dropIndex];
                                        }

                                        if (tokenSource == "2")
                                        {
                                            foreach (string kv in tokenSourcemore.Split(','))
                                            {
                                                if (!string.IsNullOrEmpty(kv))
                                                {
                                                    string[] keyvalsplit = kv.Split(':');
                                                    string key = keyvalsplit[0];
                                                    string val = keyvalsplit[1];
                                                    switch (key.Trim('"'))
                                                    {
                                                        case "t":
                                                            container = val == "2" || val == "3";
                                                            break;
                                                        case "n":       // NPC 'Name'
                                                            boss = val.Replace("\\'", "'").Trim('"');
                                                            break;
                                                        case "z":       // Zone
                                                            area = GetZoneName(val);
                                                            break;
                                                        case "dd":      // Dungeon Difficulty (1 = Normal, 2 = Heroic)
                                                            heroic = val == "2";
                                                            break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    if (boss == null) 
                                    { 
                                        //boss = "Unknown Boss (Wowhead lacks data)";
                                        area = null; // if boss is null prefer treating this as pve token
                                    }*/
                                /*
                                if (tokenNames[i] != null)
                                {
                                    _tokenDropMap[tokenIds[i]] = new TokenDropInfo() { Boss = boss, Area = area, Heroic = heroic, Name = tokenNames[i], Container = container };
                                }
                            }*/
                                #endregion
                            } else {
                                #region We've seen this before so just use that data
                                TokenDropInfo info = _tokenDropMap[tokenIds[i]];
                                boss = info.Boss; vendor = info.Vendor;
                                area = info.Area; vendorarea = info.VendorArea;
                                heroic = info.Heroic;
                                lfr = info.LFR;
                                tokenName = info.Name;
                                container = info.Container;
                                #endregion
                            }
                            if (tokenName != null) {
                                #region This is NOT a Dropped Token, so treat it as a normal vendor item and include token info
                                //pvpItem.TokenMap[tokenName] = tokenCounts[i];
                                if (!String.IsNullOrEmpty(area) && !String.IsNullOrEmpty(vendorarea) && area != vendorarea && vendorarea != "Unknown Area") {
                                    // We are lucky enough to have BOTH drop points, so lets set both up
                                    //pvpItem.VendorArea = vendorarea;
                                    //pvpItem.VendorName = vendor;
                                    //pvpItem.TokenMap[tokenName] = tokenCounts[i];
                                    ItemLocation droppoint = new StaticDrop() { Area = area, Boss = boss, Heroic = heroic, LFR = lfr, };
                                    item.LocationInfo = new ItemLocationList() { pvpItem, droppoint }; 
                                    pvpItem = null;
                                    break;
                                } else {
                                    //pvpItem.VendorArea = area;
                                    //pvpItem.VendorName = boss;
                                }
                                #endregion
                            } else if (area != null) {
                                #region This is a Dropped Token or we know what vendor is dropping it, so assign it to where it drops from
                                if (container) {
                                    ItemLocation locInfo = new ContainerItem()
                                    {
                                        Area = area,
                                        Container = boss,
                                        Heroic = heroic,
                                        LFR = lfr,
                                    };
                                    item.LocationInfo = new ItemLocationList() { locInfo };
                                    pvpItem = null;
                                    break;
                                } else {
                                    ItemLocation locInfo = new StaticDrop()
                                    {
                                        Area = area,
                                        Boss = boss,
                                        Heroic = heroic,
                                        LFR = lfr,
                                    };
                                    item.LocationInfo = new ItemLocationList() { locInfo };
                                    pvpItem = null;
                                    break;
                                }
                                #endregion
                            } else /*if (tokenNames[i] == null)*/ {
                                // there was an error pulling token data from web
                                // ignore source information
                                pvpItem = null;
                                break;
                            }
                            #endregion
                        } else {
                            #region There is no token so this is a normal vendor item
                            if (!String.IsNullOrEmpty(repSource) && !String.IsNullOrEmpty(repLevel)) {
                                string[] repInfo = GetItemFactionVendorInfo(repSource, repLevel);
                                FactionItem locInfo = new FactionItem()
                                {
                                    FactionName = repInfo[0],
                                    Level = (ReputationLevel)int.Parse(repLevel), // repInfo[3]
                                    //Cost = goldCost,
                                };
                                item.LocationInfo = new ItemLocationList() { locInfo };
                                pvpItem = null;
                                break;
                            }/* else {
                                VendorItem locInfo = new VendorItem()
                                {
                                    Cost = goldCost,
                                };
                                if (!string.IsNullOrEmpty(n)) locInfo.VendorName = n;
                                if (sourcemore != null && sourcemore.TryGetValue("z", out tmp))
                                {
                                    locInfo.VendorArea = GetZoneName(tmp.ToString());
                                }
                                item.LocationInfo = new ItemLocationList() { locInfo };
                                vendorItem = null;
                                break;
                            }*/
                            #endregion
                        }
                    }
                    if (pvpItem != null) {
                        // We already set the Vendor Name and Zone
                        item.LocationInfo = new ItemLocationList() { pvpItem };
                    }
                } /*else if (item.LocationInfo == null) {
                   * // NOTICE: This check isn't possible anymore, but it's generating an Unknown automatically so it's not necessary either
                    // We DON'T have Source Data AND we didn't have one before. So lets set it to Unknown
                    item.LocationInfo = new ItemLocationList() { UnknownItem.Construct() };
                }*/ else {
                    // We DON'T have Source Data
                    // Since we are doing nothing, the ItemSource cache doesn't change
                    // Therefore the original ItemSource persists, if it's there
                }

                // If it's Craftable and Binds on Pickup, mark it as such
                if (item.LocationInfo[0] is CraftedItem && (item.Bind == BindsOn.BoP))
                {
                    (item.LocationInfo[0] as CraftedItem).Bind = BindsOn.BoP;
                }
            } catch (Exception ex) {
                (sender as BackgroundWorker).ReportProgress(0, ex.Message + "|" + ex.StackTrace);
            }
        }