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); }
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; }
public AnkhofShieldingTB() { FactionItem.Imbue(this, TrueBritannians.Instance, false, TrueBritannians.Instance.Definition.HuePrimary); Hue = 2214; Weight = 0.1; LootType = LootType.Blessed; }
public AnkhofShieldingCoM() { FactionItem.Imbue(this, CouncilOfMages.Instance, false, CouncilOfMages.Instance.Definition.HuePrimary); Hue = 1325; Weight = 0.1; LootType = LootType.Blessed; }
public AnkhofShieldingMinax() { Name = "Ankh of Shielding"; FactionItem.Imbue(this, Minax.Instance, false, Minax.Instance.Definition.HuePrimary); Hue = 1645; Weight = 0.1; LootType = LootType.Blessed; }
public MinaxArmoredFactionRobe() : base(0x2684) { Name = "armored shroud"; Weight = 3.0; LootType = LootType.Blessed; FactionItem.Imbue(this, Minax.Instance, false, Minax.Instance.Definition.HuePrimary); }
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); }; }
/// <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)); } } }; }
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; }
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(); } } }
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); } } }); }
/// <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);
public AnthillInfo(FactionItem item, Item observer) : base(item, observer) { anthillItem = item as AnthillItem; }
/// <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++; }
/// <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); } }; }
/// <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; }
/// <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--; }
/// <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);
/// <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); }; }
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); } }