override internal void Display(List <PlayerStats> _ = null) { if (Running == false && PlayerStats != null) { Running = true; choicesList.IsEnabled = false; Task.Delay(10).ContinueWith(task => { try { Helpers.SetBusy(true); if (PlayerStats != null) { ObservableCollection <PlayerSubStats> list = new ObservableCollection <PlayerSubStats>(); foreach (var playerStat in PlayerStats.AsParallel().OrderByDescending(stats => GetSortValue(stats))) { list.Add(playerStat); if (CurrentShowSpellsChoice) { SortSubStats(playerStat.SubStats.Values.ToList()).ForEach(subStat => list.Add(subStat)); } else { SortSubStats(playerStat.SubStats2.Values.ToList()).ForEach(subStat => list.Add(subStat)); } } Dispatcher.InvokeAsync(() => dataGrid.ItemsSource = list); if (CurrentColumn != null) { Dispatcher.InvokeAsync(() => CurrentColumn.SortDirection = CurrentSortDirection); } } } catch (ArgumentNullException ane) { LOG.Error(ane); } catch (NullReferenceException nre) { LOG.Error(nre); } catch (ArgumentOutOfRangeException aro) { LOG.Error(aro); } finally { Helpers.SetBusy(false); Dispatcher.InvokeAsync(() => choicesList.IsEnabled = true); Running = false; } }, TaskScheduler.Default); } }
private void Display(bool init = false) { if (init || actionList.IsEnabled) { actionList.IsEnabled = typeList.IsEnabled = actedList.IsEnabled = showPets.IsEnabled = groupHits.IsEnabled = false; dataGrid.Columns[6].Visibility = CurrentGroupSpellCastsFilter ? Visibility.Visible : Visibility.Collapsed; Task.Delay(125).ContinueWith(task => { Helpers.SetBusy(true); var rowCache = new Dictionary <string, HitLogRow>(); Dictionary <string, byte> uniqueDefenders = new Dictionary <string, byte>(); Dictionary <string, byte> uniqueActions = new Dictionary <string, byte>(); Dictionary <string, byte> uniqueTypes = new Dictionary <string, byte>(); ObservableCollection <string> acted = new ObservableCollection <string> { ActedOption }; lock (CollectionLock) { Records.Clear(); } LastSeenCache.Clear(); CurrentGroups?.ForEach(group => { group.ForEach(block => { rowCache.Clear(); block.Actions.ForEach(action => { if (CreateRow(rowCache, PlayerStats, action, block.BeginTime, Defending) is HitLogRow row && !CurrentGroupSpellCastsFilter) { AddRow(row, uniqueActions, uniqueDefenders, uniqueTypes, acted); } }); if (CurrentGroupSpellCastsFilter) { foreach (var row in rowCache.Values.OrderByDescending(row => row.Total)) { AddRow(row, uniqueActions, uniqueDefenders, uniqueTypes, acted); } } }); }); Dispatcher.InvokeAsync(() => { actedList.ItemsSource = acted; if (CurrentActedFilter == null) { actedList.SelectedIndex = 0; } else if (acted.IndexOf(CurrentActedFilter) is int actedIndex && actedIndex > -1) { actedList.SelectedIndex = actedIndex; } else { CurrentActedFilter = null; actedList.SelectedIndex = 0; } actionList.IsEnabled = typeList.IsEnabled = actedList.IsEnabled = showPets.IsEnabled = groupHits.IsEnabled = true; });
private void Load() { if (!Running) { Running = true; itemsList.IsEnabled = playersList.IsEnabled = optionsList.IsEnabled = false; Task.Delay(75).ContinueWith(task => { Helpers.SetBusy(true); lock (CollectionLock) { TotalRecords.Clear(); IndividualRecords.Clear(); } List <LootRow> totalRecords = new List <LootRow>(); Dictionary <string, byte> uniquePlayers = new Dictionary <string, byte>(); Dictionary <string, byte> uniqueItems = new Dictionary <string, byte>(); List <string> players = new List <string> { ALLPLAYERS }; List <string> itemNames = new List <string> { ALLITEMS, ONLYCURR, ONLYITEMS }; DataManager.Instance.GetAllLoot().ForEach(blocks => { blocks.Actions.ForEach(record => { if (record is LootRecord looted) { lock (CollectionLock) { IndividualRecords.Add(CreateRow(looted, blocks.BeginTime)); } UpdateTotals(totalRecords, looted); uniquePlayers[looted.Player] = 1; if (!looted.IsCurrency) { uniqueItems[looted.Item] = 1; } } }); }); uniquePlayers.Keys.OrderBy(player => player).ToList().ForEach(newPlayer => players.Add(newPlayer)); uniqueItems.Keys.OrderBy(item => item).ToList().ForEach(newItem => itemNames.Add(newItem)); lock (CollectionLock) { totalRecords.OrderByDescending(row => row.Quantity).ToList().ForEach(s => TotalRecords.Add(s)); } Helpers.SetBusy(false); Dispatcher.InvokeAsync(() => { itemsList.ItemsSource = itemNames; playersList.ItemsSource = players; UpdateUI(); itemsList.SelectedItem = CurrentSelectedItem; playersList.SelectedItem = CurrentSelectedPlayer; Running = false; }); }, TaskScheduler.Default); } }
private void Load() { Helpers.SetBusy(true); var npcStatsRows = new Dictionary <string, NpcStatsRow>(); foreach (var kv in DataManager.Instance.GetNpcResistStats()) { if (!PlayerManager.Instance.IsPetOrPlayer(kv.Key) && !PlayerManager.Instance.IsPetOrPlayer(TextFormatUtils.ToUpper(kv.Key))) { var row = new NpcStatsRow { Name = TextFormatUtils.CapitalizeNpc(kv.Key) }; foreach (var resists in kv.Value) { var rate = GetRate(resists.Value.Landed, resists.Value.Resisted); switch (resists.Key) { case SpellResist.AVERAGE: row.Average = rate.Item1; row.AverageText = rate.Item2; row.AverageTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.COLD: row.Cold = rate.Item1; row.ColdText = rate.Item2; row.ColdTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.CORRUPTION: row.Corruption = rate.Item1; row.CorruptionText = rate.Item2; row.CorruptionTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.DISEASE: row.Disease = rate.Item1; row.DiseaseText = rate.Item2; row.DiseaseTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.FIRE: row.Fire = rate.Item1; row.FireText = rate.Item2; row.FireTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.LOWEST: row.Lowest = rate.Item1; row.LowestText = rate.Item2; row.LowestTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.MAGIC: row.Magic = rate.Item1; row.MagicText = rate.Item2; row.MagicTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.PHYSICAL: row.Physical = rate.Item1; row.PhysicalText = rate.Item2; row.PhysicalTotal = resists.Value.Landed + resists.Value.Resisted; break; case SpellResist.POISON: row.Poison = rate.Item1; row.PoisonText = rate.Item2; row.PoisonTotal = resists.Value.Landed + resists.Value.Resisted; break; } } npcStatsRows[kv.Key] = row; } } foreach (var kv in DataManager.Instance.GetNpcTotalSpellCounts()) { if (!npcStatsRows.TryGetValue(kv.Key, out NpcStatsRow updateRow)) { updateRow = new NpcStatsRow { Name = TextFormatUtils.CapitalizeNpc(kv.Key) }; } var rate = GetRate(kv.Value.Landed, kv.Value.Reflected); updateRow.Reflected = rate.Item1; updateRow.ReflectedText = rate.Item2; updateRow.ReflectedTotal = kv.Value.Landed + kv.Value.Reflected; } dataGrid.ItemsSource = npcStatsRows.Values.OrderBy(row => row.Name).ToList(); titleLabel.Content = npcStatsRows.Values.Count == 0 ? NODATA : "Your Spell Stats for " + npcStatsRows.Count + " Unique NPCs"; Helpers.SetBusy(false); Tuple <double, string> GetRate(uint landed, uint notLanded) { Tuple <double, string> results; double computed = 0.0; uint total = landed + notLanded; if (landed == 0 && total > 0) { computed = 1.0; } else if (total > 0) { computed = notLanded / (double)total; } if (total > 0) { computed = Math.Round(computed * 100, 2); string computedString = string.Format(CultureInfo.CurrentCulture, "{0} ({1}/{2})", computed, notLanded, total); results = new Tuple <double, string>(computed, computedString); } else { results = new Tuple <double, string>(0.0, "-"); } return(results); } }
protected override void Display(List <PlayerStats> selectedStats = null) { if (Running == false && ChildStats != null && RaidStats != null) { Running = true; groupDirectDamage.IsEnabled = groupDoT.IsEnabled = groupProcs.IsEnabled = groupResisted.IsEnabled = showPets.IsEnabled = false; Task.Delay(10).ContinueWith(task => { try { Helpers.SetBusy(true); ObservableCollection <PlayerSubStats> list = new ObservableCollection <PlayerSubStats>(); // initial load if (selectedStats != null) { PlayerStats = new List <PlayerSubStats>(); foreach (var playerStats in selectedStats.AsParallel().OrderByDescending(stats => GetSortValue(stats))) { if (ChildStats.ContainsKey(playerStats.Name)) { foreach (var childStat in ChildStats[playerStats.Name]) { PlayerStats.Add(childStat); BuildGroups(childStat, childStat.SubStats.Values.ToList()); } Dispatcher.InvokeAsync(() => { if (!showPets.IsEnabled) { showPets.IsEnabled = true; } }); } else { PlayerStats.Add(playerStats); BuildGroups(playerStats, playerStats.SubStats.Values.ToList()); } } } if (PlayerStats != null) { var filtered = CurrentShowPets ? PlayerStats : PlayerStats.Where(playerStats => !PlayerManager.Instance.IsVerifiedPet(playerStats.Name)); foreach (var playerStats in SortSubStats(filtered.ToList())) { Dispatcher.InvokeAsync(() => { list.Add(playerStats); var optionalList = GetSubStats(playerStats as PlayerStats); SortSubStats(optionalList).ForEach(subStat => list.Add(subStat)); }); } Dispatcher.InvokeAsync(() => playerDamageDataGrid.ItemsSource = list); if (CurrentColumn != null) { Dispatcher.InvokeAsync(() => CurrentColumn.SortDirection = CurrentSortDirection); } } } catch (ArgumentNullException ane) { LOG.Error(ane); } catch (NullReferenceException nre) { LOG.Error(nre); } catch (ArgumentOutOfRangeException aro) { LOG.Error(aro); } finally { Helpers.SetBusy(false); Dispatcher.InvokeAsync(() => groupDirectDamage.IsEnabled = groupDoT.IsEnabled = groupProcs.IsEnabled = groupResisted.IsEnabled = showPets.IsEnabled = true); Running = false; } }, TaskScheduler.Default); } }
protected override void Display(List <PlayerStats> _ = null) { if (Running == false) { Running = true; choicesList.IsEnabled = false; Task.Delay(10).ContinueWith(task => { try { Helpers.SetBusy(true); if (PlayerStats != null) { ObservableCollection <PlayerSubStats> list = new ObservableCollection <PlayerSubStats>(); List <PlayerStats> receivedHealing = new List <PlayerStats>(); PlayerStats.ForEach(selected => { if (selected.SubStats2.Count > 0) { receivedHealing.AddRange(selected.SubStats2.Values.Cast <PlayerStats>().ToList()); } }); foreach (var playerStat in receivedHealing.AsParallel().OrderByDescending(stats => GetSortValue(stats))) { Dispatcher.InvokeAsync(() => { list.Add(playerStat); // Spells are kept under SubStats2 and Healers under SubStats1. Both are children in the parent's SubStats2 as the 'receivedHealing' attribute if (CurrentShowSpellsChoice) { SortSubStats(playerStat.SubStats2.Values.ToList()).ForEach(subStat => list.Add(subStat)); } else { SortSubStats(playerStat.SubStats.Values.ToList()).ForEach(subStat => list.Add(subStat)); } }); } Dispatcher.InvokeAsync(() => playerDamageDataGrid.ItemsSource = list); if (CurrentColumn != null) { Dispatcher.InvokeAsync(() => CurrentColumn.SortDirection = CurrentSortDirection); } } } catch (ArgumentNullException ane) { LOG.Error(ane); } catch (NullReferenceException nre) { LOG.Error(nre); } catch (ArgumentOutOfRangeException aro) { LOG.Error(aro); } finally { Helpers.SetBusy(false); Dispatcher.InvokeAsync(() => choicesList.IsEnabled = true); Running = false; } }, TaskScheduler.Default); } }
private void Load() { if (!Running) { Running = true; Task.Delay(75).ContinueWith(task => { Helpers.SetBusy(true); lock (CollectionLock) { EventRows.Clear(); } var rows = new List <EventRow>(); DataManager.Instance.GetDeathsDuring(0, double.MaxValue).ForEach(block => { block.Actions.ForEach(action => { if (action is DeathRecord death) { if (!(PlayerManager.Instance.IsVerifiedPet(death.Killed) && !Helpers.IsPossiblePlayerName(death.Killed))) { var isActorNpc = DataManager.Instance.IsLifetimeNpc(death.Killer) || DataManager.Instance.IsKnownNpc(death.Killer); var isTargetNpc = DataManager.Instance.IsLifetimeNpc(death.Killed) || DataManager.Instance.IsKnownNpc(death.Killed); var isActorPlayer = PlayerManager.Instance.IsPetOrPlayerOrSpell(death.Killer); var isTargetPlayer = PlayerManager.Instance.IsPetOrPlayer(death.Killed); string text = KILLSHOT_EVENT; if (isTargetPlayer && isActorPlayer) { text = PLAYERKILL_EVENT; } else if (isTargetPlayer || (isActorNpc && !isTargetNpc && Helpers.IsPossiblePlayerName(death.Killed))) { text = PLAYERSLAIN_EVENT; } rows.Add(new EventRow() { Time = block.BeginTime, Actor = death.Killer, Target = death.Killed, Event = text }); } } }); }); DataManager.Instance.GetMiscDuring(0, double.MaxValue).ForEach(block => { block.Actions.ForEach(action => { if (action is MezBreakRecord mezBreak) { rows.Add(new EventRow() { Time = block.BeginTime, Actor = mezBreak.Breaker, Target = mezBreak.Awakened, Event = MEZBREAK_EVENT }); } else if (action is ZoneRecord zone) { rows.Add(new EventRow() { Time = block.BeginTime, Actor = ConfigUtil.PlayerName, Event = ZONE_EVENT, Target = zone.Zone }); } }); }); rows.Sort((a, b) => a.Time.CompareTo(b.Time)); rows.ForEach(row => EventRows.Add(row)); Helpers.SetBusy(false); Dispatcher.InvokeAsync(() => { UpdateUI(rows.Count > 0); Running = false; }); }, TaskScheduler.Default); } }
private void Display() { lock (LockObject) { if (Running == false) { Running = true; Helpers.SetBusy(true); showSelfOnly.IsEnabled = showProcs.IsEnabled = spellTypes.IsEnabled = castTypes.IsEnabled = countTypes.IsEnabled = minFreqList.IsEnabled = false; Task.Delay(50).ContinueWith(task => { try { Dispatcher.InvokeAsync(() => { var column = new DataGridTextColumn() { Header = "", Binding = new Binding("Spell") }; var columnStyle = new Style(typeof(TextBlock)); columnStyle.Setters.Add(new Setter(TextBlock.ForegroundProperty, new Binding("Spell") { Converter = new ReceivedSpellColorConverter() })); column.ElementStyle = columnStyle; dataGrid.Columns.Add(column); }); Dictionary <string, Dictionary <string, uint> > filteredPlayerMap = new Dictionary <string, Dictionary <string, uint> >(); Dictionary <string, uint> totalCountMap = new Dictionary <string, uint>(); Dictionary <string, uint> uniqueSpellsMap = new Dictionary <string, uint>(); uint totalCasts = 0; PlayerList.ForEach(player => { filteredPlayerMap[player] = new Dictionary <string, uint>(); if ((CurrentCastType == 0 || CurrentCastType == 1) && TheSpellCounts.PlayerCastCounts.ContainsKey(player)) { foreach (string id in TheSpellCounts.PlayerCastCounts[player].Keys) { totalCasts = UpdateMaps(id, player, TheSpellCounts.PlayerCastCounts[player][id], TheSpellCounts.MaxCastCounts, totalCountMap, uniqueSpellsMap, filteredPlayerMap, false, totalCasts); } } if ((CurrentCastType == 0 || CurrentCastType == 2) && TheSpellCounts.PlayerReceivedCounts.ContainsKey(player)) { foreach (string id in TheSpellCounts.PlayerReceivedCounts[player].Keys) { totalCasts = UpdateMaps(id, player, TheSpellCounts.PlayerReceivedCounts[player][id], TheSpellCounts.MaxReceivedCounts, totalCountMap, uniqueSpellsMap, filteredPlayerMap, true, totalCasts); } } }); List <string> sortedPlayers = totalCountMap.Keys.OrderByDescending(key => totalCountMap[key]).ToList(); List <string> sortedSpellList = uniqueSpellsMap.Keys.OrderByDescending(key => uniqueSpellsMap[key]).ToList(); int colCount = 0; foreach (string name in sortedPlayers) { string colBinding = "Values[" + colCount + "]"; // dont use colCount directly since it will change during Dispatch double total = totalCountMap.ContainsKey(name) ? totalCountMap[name] : 0; string header = name + " = " + ((CurrentCountType == 0) ? total.ToString(CultureInfo.CurrentCulture) : Math.Round(total / totalCasts * 100, 2).ToString(CultureInfo.CurrentCulture)); Dispatcher.InvokeAsync(() => { DataGridTextColumn col = new DataGridTextColumn() { Header = header, Binding = new Binding(colBinding) }; col.CellStyle = Application.Current.Resources["SpellGridDataCellStyle"] as Style; col.HeaderStyle = Application.Current.Resources["BrightCenterGridHeaderStyle"] as Style; dataGrid.Columns.Add(col); }); Thread.Sleep(5); colCount++; } string totalHeader = CurrentCountType == 0 ? "Totals = " + totalCasts : "Totals = 100"; Dispatcher.InvokeAsync(() => { DataGridTextColumn col = new DataGridTextColumn() { Header = totalHeader, Binding = new Binding("Values[" + colCount + "]") }; col.CellStyle = Application.Current.Resources["SpellGridDataCellStyle"] as Style; col.HeaderStyle = Application.Current.Resources["BrightCenterGridHeaderStyle"] as Style; dataGrid.Columns.Add(col); }); int existingIndex = 0; foreach (var spell in sortedSpellList) { var row = (SpellRowsView.Count > existingIndex) ? SpellRowsView[existingIndex] : new SpellCountRow(); row.Spell = spell; //row.IsReceived = spell.StartsWith("Received", StringComparison.Ordinal); row.IconColor = ACTIVEICON; int i; double[] values = new double[sortedPlayers.Count + 1]; for (i = 0; i < sortedPlayers.Count; i++) { if (filteredPlayerMap.ContainsKey(sortedPlayers[i])) { if (filteredPlayerMap[sortedPlayers[i]].ContainsKey(spell)) { if (CurrentCountType == 0) { values[i] = filteredPlayerMap[sortedPlayers[i]][spell]; } else { values[i] = Math.Round((double)filteredPlayerMap[sortedPlayers[i]][spell] / totalCountMap[sortedPlayers[i]] * 100, 2); } } else { values[i] = CurrentCountType == 0 ? 0 : 0.0; } } } values[i] = CurrentCountType == 0 ? uniqueSpellsMap[spell] : Math.Round((double)uniqueSpellsMap[spell] / totalCasts * 100, 2); row.Values.Clear(); row.Values.AddRange(values); if ((SpellRowsView.Count <= existingIndex)) { Dispatcher.InvokeAsync(() => SpellRowsView.Add(row)); } existingIndex++; Thread.Sleep(5); } } catch (Exception ex) { LOG.Error(ex); throw; } finally { Helpers.SetBusy(false); Dispatcher.InvokeAsync(() => { showProcs.IsEnabled = spellTypes.IsEnabled = castTypes.IsEnabled = countTypes.IsEnabled = minFreqList.IsEnabled = true; showSelfOnly.IsEnabled = PlayerList.Contains(ConfigUtil.PlayerName); exportClick.IsEnabled = copyOptions.IsEnabled = removeRowClick.IsEnabled = SpellRowsView.Count > 0; lock (LockObject) { Running = false; } }); } }, TaskScheduler.Default); } } }
private void Instance_EventsGenerationStatus(object sender, StatsGenerationEvent e) { Dispatcher.InvokeAsync(() => { if (e.Type == Labels.HEALPARSE && e.State == "COMPLETED") { (Application.Current.MainWindow as MainWindow).Busy(true); if (CurrentStats != null) { HealingStatsManager.Instance.PopulateHealing(CurrentStats); dataGrid.Items?.Refresh(); if (!MainWindow.IsAoEHealingEnabled) { title.Content = CurrentStats.FullTitle + " (Not Including AE Healing)"; } else { title.Content = CurrentStats.FullTitle; } } Helpers.SetBusy(false); } else if (e.Type == Labels.TANKPARSE) { switch (e.State) { case "STARTED": Helpers.SetBusy(true); title.Content = "Calculating Tanking DPS..."; dataGrid.ItemsSource = null; break; case "COMPLETED": CurrentStats = e.CombinedStats as CombinedStats; CurrentGroups = e.Groups; if (CurrentStats == null) { title.Content = NODATA_TABLE_LABEL; } else { title.Content = CurrentStats.FullTitle; HealingStatsManager.Instance.PopulateHealing(CurrentStats); var view = CollectionViewSource.GetDefaultView(CurrentStats.StatsList); dataGrid.ItemsSource = SetFilter(view); } if (!MainWindow.IsAoEHealingEnabled) { title.Content += " (Not Including AE Healing)"; } Helpers.SetBusy(false); UpdateDataGridMenuItems(); break; case "NONPC": case "NODATA": CurrentStats = null; title.Content = e.State == "NONPC" ? DEFAULT_TABLE_LABEL : NODATA_TABLE_LABEL; Helpers.SetBusy(false); UpdateDataGridMenuItems(); break; } } }); }
internal void Display() { lock (LockObject) { if (Running == false) { Running = true; Helpers.SetBusy(true); showSelfOnly.IsEnabled = castTypes.IsEnabled = spellTypes.IsEnabled = false; Task.Delay(50).ContinueWith(task => { Dispatcher.InvokeAsync(() => { foreach (var name in UniqueNames.Keys) { var column = new DataGridTextColumn() { Header = name, Width = DataGridLength.Auto, Binding = new Binding(name) }; var columnStyle = new Style(typeof(TextBlock)); columnStyle.Setters.Add(new Setter(TextBlock.ForegroundProperty, new Binding(name) { Converter = new ReceivedSpellColorConverter() })); column.ElementStyle = columnStyle; dataGrid.Columns.Add(column); } }); var allSpells = new HashSet <ActionBlock>(); double maxTime = -1; RaidStats.Ranges.TimeSegments.ForEach(segment => { maxTime = maxTime == -1 ? segment.BeginTime + RaidStats.TotalSeconds : maxTime; var blocks = DataManager.Instance.GetCastsDuring(segment.BeginTime - SpellCountBuilder.COUNT_OFFSET, segment.EndTime); blocks.ForEach(block => { if (block.BeginTime <= maxTime) { allSpells.Add(block); } }); blocks = DataManager.Instance.GetReceivedSpellsDuring(segment.BeginTime - SpellCountBuilder.COUNT_OFFSET, segment.EndTime); blocks.ForEach(block => { if (block.BeginTime <= maxTime) { allSpells.Add(block); } }); }); var playerSpells = new Dictionary <string, List <string> >(); var helper = new DictionaryListHelper <string, string>(); int max = 0; double lastTime = double.NaN; foreach (var block in allSpells.OrderBy(block => block.BeginTime).ThenBy(block => (block.Actions.Count > 0 && block.Actions[0] is ReceivedSpell) ? 1 : -1)) { if (!double.IsNaN(lastTime) && block.BeginTime != lastTime) { AddRow(playerSpells, max, lastTime); playerSpells.Clear(); max = 0; } if (block.Actions.Count > 0) { int size = 0; if ((CurrentCastType == 0 || CurrentCastType == 1) && block.Actions[0] is SpellCast) { foreach (var cast in block.Actions.Cast <SpellCast>().Where(cast => IsValid(cast, UniqueNames, cast.Caster, out _))) { size = helper.AddToList(playerSpells, cast.Caster, cast.Spell); } } else if ((CurrentCastType == 0 || CurrentCastType == 2) && block.Actions[0] is ReceivedSpell) { SpellData replaced = null; foreach (var received in block.Actions.Cast <ReceivedSpell>().Where(received => IsValid(received, UniqueNames, received.Receiver, out replaced))) { if (replaced != null) { size = helper.AddToList(playerSpells, received.Receiver, "Received " + replaced.NameAbbrv); } } } max = Math.Max(max, size); } lastTime = block.BeginTime; } if (playerSpells.Count > 0 && max > 0) { AddRow(playerSpells, max, lastTime); } Helpers.SetBusy(false); Dispatcher.InvokeAsync(() => { // only enable for current player showSelfOnly.IsEnabled = UniqueNames.ContainsKey(ConfigUtil.PlayerName); castTypes.IsEnabled = spellTypes.IsEnabled = true; lock (LockObject) { Running = false; } }); }, TaskScheduler.Default); } } }