/// <summary> /// Increments the count of number of times an item was purchased "number" times in a match, with average purchase time. /// </summary> public void Increment(ItemPurchaseInformation purchase) { PerMatchCounts.AddOrUpdate(purchase.Number, id => new ItemPurchaseTrackerData(ItemId, id, purchase), (id, tracker) => { tracker.Increment(purchase); return(tracker); } ); }
/// <summary> /// Add information about how items built into other items. /// </summary> private void AddBuildsIntoInformation(List <ItemPurchaseInformation> purchases) { ItemPurchaseInformation latestPurchase = null; for (int i = 0; i < purchases.Count; ++i) { ItemPurchaseInformation evt = purchases[i]; switch (evt.EventType) { case EventType.ItemDestroyed: { // Find the item that was destroyed var originalpurchase = purchases.Take(i).LastOrDefault(p => p.ItemId == evt.ItemId && p.IsInInventory); // Check if this item builds into the latest purchase var item = evt.Item; var latestPurchaseItem = (latestPurchase == null) ? null : latestPurchase.Item; if (originalpurchase != null && // some items are granted without a purchase, and can be upgraded (e.g. Viktor's Hex Core) latestPurchase != null && item.BuildsInto(latestPurchaseItem)) { // It does, mark the original purchase as building into the latest purchase originalpurchase.BuildsInto = latestPurchase; latestPurchase.BuiltFrom.Add(originalpurchase); } // Mark the destroy and the purchase it links to if (originalpurchase != null) // some items are granted without a purchase, and can be destroyed (e.g. Kalista's Black Spear) { originalpurchase.DestroyedBy = evt; evt.Destroys = originalpurchase; } } break; case EventType.ItemPurchased: { // Store the new purchase latestPurchase = evt; } break; case EventType.ItemSold: { // Find the purchase to attribute this sale to var salepurchase = purchases.Take(i).LastOrDefault(p => p.ItemId == evt.ItemId && p.IsInInventory); if (salepurchase != null) { salepurchase.SoldBy = evt; evt.Sells = salepurchase; } } break; } } }
public ItemPurchaseTrackerData(int itemId, int number, ItemPurchaseInformation purchase) { ItemId = itemId; Number = number; Count = 1; AveragePurchaseTimeSeconds = purchase.GameState.Timestamp.TotalSeconds; Kills = purchase.GameState.TotalKills; TowerKills = purchase.GameState.TotalTowerKills; InnerTowerKills = purchase.GameState.TotalTowerKillsByType(TowerType.InnerTurret); BaseTowerKills = purchase.GameState.TotalTowerKillsByType(TowerType.BaseTurret); if (purchase.BuildsInto != null) { BuiltInto.Add(new ItemPurchaseKey(purchase.BuildsInto), 1); } var finalItem = purchase.FinalBuildItem; if (finalItem != null) { FinalBuildItem.Add(new ItemPurchaseKey(finalItem), 1); } }
public void Increment(ItemPurchaseInformation purchase) { double lerpValue = (double)Count / (double)(Count + 1); AveragePurchaseTimeSeconds = (AveragePurchaseTimeSeconds * lerpValue) + (purchase.GameState.Timestamp.TotalSeconds * (1.0 - lerpValue)); ++Count; Kills += purchase.GameState.TotalKills; TowerKills += purchase.GameState.TotalTowerKills; InnerTowerKills += purchase.GameState.TotalTowerKillsByType(TowerType.InnerTurret); BaseTowerKills += purchase.GameState.TotalTowerKillsByType(TowerType.BaseTurret); if (purchase.BuildsInto != null) { var buildsIntoKey = new ItemPurchaseKey(purchase.BuildsInto); if (BuiltInto.ContainsKey(buildsIntoKey)) { ++BuiltInto[buildsIntoKey]; } else { BuiltInto[buildsIntoKey] = 1; } } if (purchase.FinalBuildItem != null) { var finalBuildKey = new ItemPurchaseKey(purchase.FinalBuildItem); if (FinalBuildItem.ContainsKey(finalBuildKey)) { ++FinalBuildItem[finalBuildKey]; } else { FinalBuildItem[finalBuildKey] = 1; } } }
public async Task ConsumeMatchDetail(MatchDetail match) { int processedId = Interlocked.Increment(ref ProcessedCount); Console.WriteLine("Processing Match {0}", processedId); Dictionary <int, ChampionMatchItemPurchases> championPurchases = new Dictionary <int, ChampionMatchItemPurchases>(); var smiteSpell = StaticDataStore.SummonerSpells.SummonerSpells["SummonerSmite"]; // Get all champions in this match, and initialize recording structures foreach (Participant participant in match.Participants) { int championId = participant.ChampionId; //// Create a new match listing and add it to listings Lane lane = participant.Timeline.Lane; bool hasSmite = (participant.Spell1Id == smiteSpell.Id || participant.Spell2Id == smiteSpell.Id); bool isWinner = participant.Stats.Winner; ChampionMatchItemPurchases championItemPurchases = new ChampionMatchItemPurchases(championId, match.MatchId, lane, isWinner, hasSmite); // For recording, we'll index by participant id so we don't have to look up champion id every time championPurchases.Add(participant.ParticipantId, championItemPurchases); } // Process item purchases GameState gameState = new GameState(match); // Handle null values if (match.Timeline == null || match.Timeline.Frames == null) { return; } match.Timeline.Frames.ForEach(frame => { if (frame == null || frame.Events == null) { return; } frame.Events.ForEach(e => { if (e == null) { return; } // Skip null events if (e.EventType == null) { return; } // Update any game state that can be gathered from all events gameState.Update(frame, e); // Process item events if (ItemEventTypes.Contains(e.EventType.Value)) { ItemPurchaseInformation itemPurchase = new ItemPurchaseInformation(e, gameState); // Handle a weird error with ItemId 1501, ItemDestroyed, ParticipantId 0 if (!championPurchases.ContainsKey(e.ParticipantId)) { return; } championPurchases[e.ParticipantId].ItemPurchases.Add(itemPurchase); } }); }); // Analyze match championPurchases.Values.AsParallel().WithDegreeOfParallelism(5).ForAll(it => { var tracker = ChampionPurchaseTrackers.GetOrAdd(it.ChampionId, id => new ChampionPurchaseTracker(id)); tracker.Process(it); }); }
public ItemPurchaseKey(ItemPurchaseInformation purchase) { ItemId = purchase.ItemId; Number = purchase.Number; }