예제 #1
0
        private void HealingSummary_SelectionChanged(object sender, PlayerStatsSelectionChangedEventArgs data)
        {
            var options = new GenerateStatsOptions()
            {
                RequestChartData = true
            };

            HealingStatsManager.Instance.FireChartEvent(options, "SELECT", data.Selected);

            var preview = playerParseTextWindow.Content as ParsePreview;

            // change the update order based on whats displayed
            if (preview.parseList.SelectedItem?.ToString() == Labels.TOPHEALSPARSE)
            {
                preview?.UpdateParse(Labels.HEALPARSE, data.Selected);
                if (data.Selected?.Count == 1 && (data.Selected[0] as PlayerStats).SubStats?.Count > 0)
                {
                    preview?.AddParse(Labels.TOPHEALSPARSE, HealingStatsManager.Instance, data.CurrentStats, data.Selected);
                }
            }
            else
            {
                if (data.Selected?.Count == 1 && (data.Selected[0] as PlayerStats).SubStats?.Count > 0)
                {
                    preview?.AddParse(Labels.TOPHEALSPARSE, HealingStatsManager.Instance, data.CurrentStats, data.Selected);
                }
                preview?.UpdateParse(Labels.HEALPARSE, data.Selected);
            }
        }
예제 #2
0
        private void OpenTankingSummary()
        {
            if (TankingWindow?.IsOpen == true)
            {
                TankingWindow.Close();
            }
            else
            {
#pragma warning disable CA2000 // Dispose objects before losing scope
                var tankingSummary = new TankingSummary();
#pragma warning restore CA2000 // Dispose objects before losing scope

                tankingSummary.EventsSelectionChange += TankingSummary_SelectionChanged;
                TankingWindow = new DocumentWindow(dockSite, "tankingSummary", "Tanking Summary", null, tankingSummary);
                IconToWindow[tankingSummaryIcon.Name] = TankingWindow;

                Helpers.OpenWindow(TankingWindow);
                if (DamageWindow?.IsOpen == true || HealingWindow?.IsOpen == true)
                {
                    TankingWindow.MoveToPreviousContainer();
                }

                RepositionCharts(TankingWindow);

                if (TankingStatsManager.Instance.GetGroupCount() > 0)
                {
                    // keep chart request until resize issue is fixed. resetting the series fixes it at a minimum
                    var tankingOptions = new GenerateStatsOptions()
                    {
                        RequestSummaryData = true
                    };
                    Task.Run(() => TankingStatsManager.Instance.RebuildTotalStats(tankingOptions));
                }
            }
        }
예제 #3
0
    private void ComputeStats()
    {
      var filtered = (npcWindow?.Content as FightTable)?.GetSelectedItems().OrderBy(npc => npc.Id);
      string name = filtered?.FirstOrDefault()?.Name;

      var damageOptions = new GenerateStatsOptions() { Name = name, RequestChartData = DamageChartWindow?.IsOpen == true };
      damageOptions.Npcs.AddRange(filtered);
      if (DamageWindow?.Content is DamageSummary damageSummary && DamageWindow?.IsOpen == true)
      {
        damageOptions.RequestSummaryData = true;
      }

      var healingOptions = new GenerateStatsOptions() { Name = name, RequestChartData = HealingChartWindow?.IsOpen == true };
      healingOptions.Npcs.AddRange(filtered);
      if (HealingWindow?.Content is HealingSummary healingSummary && HealingWindow?.IsOpen == true)
      {
        healingOptions.RequestSummaryData = true;
      }

      var tankingOptions = new GenerateStatsOptions() { Name = name, RequestChartData = TankingChartWindow?.IsOpen == true };
      tankingOptions.Npcs.AddRange(filtered);
      if (TankingWindow?.Content is TankingSummary tankingSummary && TankingWindow?.IsOpen == true)
      {
        tankingOptions.RequestSummaryData = true;
      }

      Task.Run(() => DamageStatsManager.Instance.BuildTotalStats(damageOptions));
      Task.Run(() => HealingStatsManager.Instance.BuildTotalStats(healingOptions));
      Task.Run(() => TankingStatsManager.Instance.BuildTotalStats(tankingOptions));
    }
예제 #4
0
        private void OpenHealingSummary()
        {
            if (HealingWindow?.IsOpen == true)
            {
                HealingWindow.Close();
            }
            else
            {
                var healingSummary = new HealingSummary();
                healingSummary.EventsSelectionChange += HealingSummary_SelectionChanged;
                HealingWindow = new DocumentWindow(dockSite, "healingSummary", "Healing Summary", null, healingSummary);
                IconToWindow[healingSummaryIcon.Name] = HealingWindow;

                Helpers.OpenWindow(HealingWindow);
                if (DamageWindow?.IsOpen == true || TankingWindow?.IsOpen == true)
                {
                    HealingWindow.MoveToPreviousContainer();
                }

                Helpers.RepositionCharts(HealingWindow, DamageChartWindow, TankingChartWindow, HealingChartWindow);

                if (HealingStatsManager.Instance.GetGroupCount() > 0)
                {
                    // keep chart request until resize issue is fixed. resetting the series fixes it at a minimum
                    var healingOptions = new GenerateStatsOptions()
                    {
                        RequestSummaryData = true
                    };
                    Task.Run(() => HealingStatsManager.Instance.RebuildTotalStats(healingOptions));
                }
            }
        }
예제 #5
0
 internal void RebuildTotalStats(GenerateStatsOptions options)
 {
     if (TankingGroups.Count > 0)
     {
         FireNewStatsEvent(options);
         ComputeTankingStats(options);
     }
 }
예제 #6
0
 internal void RebuildTotalStats(GenerateStatsOptions options)
 {
     if (DamageGroups.Count > 0)
     {
         FireNewStatsEvent(options);
         ComputeDamageStats(options);
     }
 }
예제 #7
0
 private void OpenTankingChart()
 {
   if (OpenLineChart(TankingChartWindow, DamageChartWindow, HealingChartWindow, tankingChartIcon, "Tanking Chart", TANKING_CHOICES, false, out TankingChartWindow))
   {
     var summary = TankingWindow?.Content as TankingSummary;
     var options = new GenerateStatsOptions() { RequestChartData = true };
     TankingStatsManager.Instance.FireChartEvent(options, "UPDATE", summary?.GetSelectedStats(), summary?.GetFilter());
   }
 }
예제 #8
0
 private void OpenDamageChart()
 {
   if (OpenLineChart(DamageChartWindow, HealingChartWindow, TankingChartWindow, damageChartIcon, "Damage Chart", DAMAGE_CHOICES, true, out DamageChartWindow))
   {
     var summary = DamageWindow?.Content as DamageSummary;
     var options = new GenerateStatsOptions() { RequestChartData = true };
     DamageStatsManager.Instance.FireChartEvent(options, "UPDATE", summary?.GetSelectedStats(), summary?.GetFilter());
   }
 }
예제 #9
0
    private void ToggleBaneDamageClick(object sender, RoutedEventArgs e)
    {
      IsBaneDamageEnabled = !IsBaneDamageEnabled;
      ConfigUtil.SetSetting("IncludeBaneDamage", IsBaneDamageEnabled.ToString(CultureInfo.CurrentCulture));
      enableBaneDamageIcon.Visibility = IsBaneDamageEnabled ? Visibility.Visible : Visibility.Hidden;

      var options = new GenerateStatsOptions() { RequestChartData = true, RequestSummaryData = true };
      Task.Run(() => DamageStatsManager.Instance.RebuildTotalStats(options));
    }
예제 #10
0
        private void DamageSummary_SelectionChanged(object sender, PlayerStatsSelectionChangedEventArgs data)
        {
            var options = new GenerateStatsOptions()
            {
                RequestChartData = true
            };

            DamageStatsManager.Instance.FireChartEvent(options, "SELECT", data.Selected);
            (playerParseTextWindow.Content as ParsePreview)?.UpdateParse(Labels.DAMAGEPARSE, data.Selected);
        }
예제 #11
0
 private void FireNewStatsEvent(GenerateStatsOptions options)
 {
     if (options.RequestSummaryData)
     {
         // generating new stats
         EventsGenerationStatus?.Invoke(this, new StatsGenerationEvent()
         {
             Type = Labels.TANKPARSE, State = "STARTED"
         });
     }
 }
예제 #12
0
        private void FireNoDataEvent(GenerateStatsOptions options, string state)
        {
            if (options.RequestSummaryData)
            {
                // nothing to do
                EventsGenerationStatus?.Invoke(this, new StatsGenerationEvent()
                {
                    Type = Labels.TANKPARSE, State = state
                });
            }

            FireChartEvent(options, "CLEAR");
        }
예제 #13
0
        private void FireCompletedEvent(GenerateStatsOptions options, CombinedStats combined, List <List <ActionBlock> > groups)
        {
            if (options.RequestSummaryData)
            {
                // generating new stats
                var genEvent = new StatsGenerationEvent()
                {
                    Type          = Labels.HEALPARSE,
                    State         = "COMPLETED",
                    CombinedStats = combined
                };

                genEvent.Groups.AddRange(groups);
                EventsGenerationStatus?.Invoke(this, genEvent);
            }
        }
예제 #14
0
        public DamageSummary()
        {
            InitializeComponent();
            InitSummaryTable(title, dataGrid, selectedColumns);

            PropertyDescriptor widthPd = DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));
            PropertyDescriptor orderPd = DependencyPropertyDescriptor.FromProperty(DataGridColumn.DisplayIndexProperty, typeof(DataGridColumn));

            foreach (var column in dataGrid.Columns)
            {
                widthPd.AddValueChanged(column, new EventHandler(ColumnWidthPropertyChanged));
                orderPd.AddValueChanged(column, new EventHandler(ColumnDisplayIndexPropertyChanged));
            }

            var list = PlayerManager.Instance.GetClassList();

            list.Insert(0, Properties.Resources.ANY_CLASS);
            classesList.ItemsSource   = list;
            classesList.SelectedIndex = 0;

            petOrPlayerList.ItemsSource = new List <string> {
                Labels.PETPLAYEROPTION, Labels.PLAYEROPTION, Labels.PETOPTION, Labels.EVERYTHINGOPTION
            };
            petOrPlayerList.SelectedIndex = 0;

            CreateClassMenuItems(menuItemShowSpellCounts, DataGridShowSpellCountsClick, DataGridSpellCountsByClassClick);
            CreateClassMenuItems(menuItemShowSpellCasts, DataGridShowSpellCastsClick, DataGridSpellCastsByClassClick);
            CreateClassMenuItems(menuItemShowBreakdown, DataGridShowBreakdownClick, DataGridShowBreakdownByClassClick);

            DamageStatsManager.Instance.EventsGenerationStatus += Instance_EventsGenerationStatus;
            DataManager.Instance.EventsClearedActiveData       += Instance_EventsClearedActiveData;

            SelectionTimer = new DispatcherTimer {
                Interval = new TimeSpan(0, 0, 0, 0, 1200)
            };
            SelectionTimer.Tick += (sender, e) =>
            {
                var damageOptions = new GenerateStatsOptions()
                {
                    RequestSummaryData = true, MaxSeconds = timeChooser.Value
                };
                Task.Run(() => DamageStatsManager.Instance.RebuildTotalStats(damageOptions));
                SelectionTimer.Stop();
            };
        }
예제 #15
0
 internal void RebuildTotalStats(GenerateStatsOptions options, bool updatedAoEOption = false)
 {
     if (HealingGroups.Count > 0)
     {
         if (updatedAoEOption)
         {
             var newOptions = new GenerateStatsOptions()
             {
                 Name = Title, RequestChartData = options.RequestChartData, RequestSummaryData = options.RequestSummaryData
             };
             newOptions.Npcs.AddRange(Selected);
             BuildTotalStats(newOptions);
         }
         else
         {
             FireNewStatsEvent(options);
             ComputeHealingStats(options);
         }
     }
 }
예제 #16
0
        internal void FireChartEvent(GenerateStatsOptions options, string action, List <PlayerStats> selected = null, Predicate <object> filter = null)
        {
            lock (TankingGroupIds)
            {
                if (options.RequestChartData)
                {
                    // send update
                    DataPointEvent de = new DataPointEvent()
                    {
                        Action = action, Iterator = new TankGroupCollection(TankingGroups, options.DamageType), Filter = filter
                    };

                    if (selected != null)
                    {
                        de.Selected.AddRange(selected);
                    }

                    EventsUpdateDataPoint?.Invoke(TankingGroups, de);
                }
            }
        }
예제 #17
0
 internal void FireSelectionEvent(GenerateStatsOptions options, List <PlayerStats> selected)
 {
     FireChartEvent(options, "SELECT", selected);
 }
예제 #18
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (DamageGroupIds)
            {
                try
                {
                    FireNewStatsEvent(options);
                    Reset();

                    Selected = options.Npcs;
                    Title    = options.Name;
                    var damageBlocks = new List <ActionBlock>();

                    Selected.ForEach(fight =>
                    {
                        damageBlocks.AddRange(fight.DamageBlocks);

                        if (fight.GroupId > -1)
                        {
                            DamageGroupIds[fight.GroupId] = 1;
                        }

                        RaidTotals.Ranges.Add(new TimeSegment(fight.BeginDamageTime, fight.LastDamageTime));
                        StatsUtil.UpdateRaidTimeRanges(fight, PlayerTimeRanges, PlayerSubTimeRanges);
                    });

                    damageBlocks.Sort((a, b) => a.BeginTime.CompareTo(b.BeginTime));

                    if (damageBlocks.Count > 0)
                    {
                        RaidTotals.TotalSeconds = RaidTotals.Ranges.GetTotal();
                        RaidTotals.MaxTime      = RaidTotals.TotalSeconds;

                        int rangeIndex = 0;
                        var newBlock   = new List <ActionBlock>();
                        damageBlocks.ForEach(block =>
                        {
                            if (RaidTotals.Ranges.TimeSegments.Count > rangeIndex && block.BeginTime > RaidTotals.Ranges.TimeSegments[rangeIndex].EndTime)
                            {
                                rangeIndex++;

                                if (newBlock.Count > 0)
                                {
                                    DamageGroups.Add(newBlock);
                                }

                                newBlock = new List <ActionBlock>();
                            }

                            newBlock.Add(block);

                            // update pet mapping
                            block.Actions.ForEach(action => UpdatePetMapping(action as DamageRecord));
                        });

                        DamageGroups.Add(newBlock);
                        RaidTotals.Ranges.TimeSegments.ForEach(segment => DataManager.Instance.GetResistsDuring(segment.BeginTime, segment.EndTime).ForEach(block => Resists.AddRange(block.Actions)));
                        ComputeDamageStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    if (ex is ArgumentNullException || ex is NullReferenceException || ex is ArgumentOutOfRangeException || ex is ArgumentException || ex is OutOfMemoryException)
                    {
                        LOG.Error(ex);
                    }
                }
            }
        }
예제 #19
0
        private void ComputeDamageStats(GenerateStatsOptions options)
        {
            lock (DamageGroupIds)
            {
                if (RaidTotals != null)
                {
                    CombinedStats combined = null;
                    ConcurrentDictionary <string, Dictionary <string, PlayerStats> > childrenStats = new ConcurrentDictionary <string, Dictionary <string, PlayerStats> >();
                    ConcurrentDictionary <string, PlayerStats> topLevelStats   = new ConcurrentDictionary <string, PlayerStats>();
                    ConcurrentDictionary <string, PlayerStats> aggregateStats  = new ConcurrentDictionary <string, PlayerStats>();
                    Dictionary <string, PlayerStats>           individualStats = new Dictionary <string, PlayerStats>();

                    // always start over
                    RaidTotals.Total = 0;
                    double stopTime = -1;

                    try
                    {
                        FireChartEvent(options, "UPDATE");

                        if (options.RequestSummaryData)
                        {
                            if (options.MaxSeconds > -1 && options.MaxSeconds <= RaidTotals.MaxTime && options.MaxSeconds != RaidTotals.TotalSeconds)
                            {
                                var filteredGroups = new List <List <ActionBlock> >();
                                DamageGroups.ForEach(group =>
                                {
                                    var filteredBlocks = new List <ActionBlock>();
                                    filteredGroups.Add(filteredBlocks);
                                    group.ForEach(block =>
                                    {
                                        stopTime = stopTime == -1 ? block.BeginTime + options.MaxSeconds : stopTime;
                                        if (block.BeginTime <= stopTime)
                                        {
                                            filteredBlocks.Add(block);
                                        }
                                    });
                                });

                                DamageGroups            = filteredGroups;
                                RaidTotals.TotalSeconds = options.MaxSeconds;
                            }
                            else
                            {
                                DamageGroups = AllDamageGroups;
                            }

                            DamageGroups.ForEach(group =>
                            {
                                group.ForEach(block =>
                                {
                                    block.Actions.ForEach(action =>
                                    {
                                        if (action is DamageRecord record)
                                        {
                                            PlayerStats stats = StatsUtil.CreatePlayerStats(individualStats, record.Attacker);

                                            if (!MainWindow.IsBaneDamageEnabled && record.Type == Labels.BANE)
                                            {
                                                stats.BaneHits++;

                                                if (individualStats.TryGetValue(stats.OrigName + " +Pets", out PlayerStats temp))
                                                {
                                                    temp.BaneHits++;
                                                }
                                            }
                                            else
                                            {
                                                RaidTotals.Total += record.Total;
                                                StatsUtil.UpdateStats(stats, record);

                                                if ((!PetToPlayer.TryGetValue(record.Attacker, out string player) && !PlayerPets.ContainsKey(record.Attacker)) || player == Labels.UNASSIGNED)
                                                {
                                                    topLevelStats[record.Attacker] = stats;
                                                    stats.IsTopLevel = true;
                                                }
                                                else
                                                {
                                                    string origName      = player ?? record.Attacker;
                                                    string aggregateName = origName + " +Pets";

                                                    PlayerStats aggregatePlayerStats = StatsUtil.CreatePlayerStats(individualStats, aggregateName, origName);
                                                    StatsUtil.UpdateStats(aggregatePlayerStats, record);
                                                    topLevelStats[aggregateName] = aggregatePlayerStats;

                                                    if (!childrenStats.TryGetValue(aggregateName, out Dictionary <string, PlayerStats> children))
                                                    {
                                                        childrenStats[aggregateName] = new Dictionary <string, PlayerStats>();
                                                    }


                                                    childrenStats[aggregateName][stats.Name] = stats;
                                                    stats.IsTopLevel = false;
                                                }

                                                PlayerSubStats subStats = StatsUtil.CreatePlayerSubStats(stats.SubStats, record.SubType, record.Type);

                                                uint critHits = subStats.CritHits;
                                                StatsUtil.UpdateStats(subStats, record);

                                                // dont count misses or where no damage was done
                                                if (record.Total > 0)
                                                {
                                                    Dictionary <long, int> values = subStats.CritHits > critHits ? subStats.CritFreqValues : subStats.NonCritFreqValues;
                                                    Helpers.LongIntAddHelper.Add(values, record.Total, 1);
                                                }
                                            }
                                        }
                                    });
                                });
                            });
예제 #20
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (TankingGroups)
            {
                try
                {
                    FireNewStatsEvent(options);
                    Reset();

                    Selected = options.Npcs;
                    Title    = options.Name;
                    var damageBlocks = new List <ActionBlock>();

                    Selected.ForEach(fight =>
                    {
                        damageBlocks.AddRange(fight.TankingBlocks);
                        RaidTotals.Ranges.Add(new TimeSegment(fight.BeginTankingTime, fight.LastTankingTime));
                        StatsUtil.UpdateRaidTimeRanges(fight, PlayerTimeRanges, PlayerSubTimeRanges, true);
                    });

                    damageBlocks.Sort((a, b) => a.BeginTime.CompareTo(b.BeginTime));

                    if (damageBlocks.Count > 0)
                    {
                        RaidTotals.TotalSeconds = RaidTotals.MaxTime = RaidTotals.Ranges.GetTotal();

                        int    rangeIndex = 0;
                        double lastTime   = 0;
                        var    newBlock   = new List <ActionBlock>();
                        damageBlocks.ForEach(block =>
                        {
                            if (RaidTotals.Ranges.TimeSegments.Count > rangeIndex && block.BeginTime > RaidTotals.Ranges.TimeSegments[rangeIndex].EndTime)
                            {
                                rangeIndex++;

                                if (newBlock.Count > 0)
                                {
                                    TankingGroups.Add(newBlock);
                                }

                                newBlock = new List <ActionBlock>();
                            }

                            if (lastTime != block.BeginTime)
                            {
                                var copy = new ActionBlock();
                                copy.Actions.AddRange(block.Actions);
                                copy.BeginTime = block.BeginTime;
                                newBlock.Add(copy);
                            }
                            else
                            {
                                newBlock.Last().Actions.AddRange(block.Actions);
                            }
                        });

                        TankingGroups.Add(newBlock);
                        ComputeTankingStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    if (ex is ArgumentNullException || ex is NullReferenceException || ex is ArgumentOutOfRangeException || ex is ArgumentException || ex is OutOfMemoryException)
                    {
                        LOG.Error(ex);
                    }
                }
            }
        }
예제 #21
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (HealingGroups)
            {
                try
                {
                    FireNewStatsEvent(options);
                    Reset();

                    Selected = options.Npcs;
                    Title    = options.Name;

                    Selected.ForEach(fight => RaidTotals.Ranges.Add(new TimeSegment(fight.BeginTankingTime, fight.LastTankingTime)));

                    if (RaidTotals.Ranges.TimeSegments.Count > 0)
                    {
                        // calculate totals first since it can modify the ranges
                        RaidTotals.TotalSeconds = RaidTotals.Ranges.GetTotal();

                        RaidTotals.Ranges.TimeSegments.ForEach(segment =>
                        {
                            var updatedHeals = new List <ActionBlock>();
                            var healedByHealerTimeSegments = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healedBySpellTimeSegments  = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healerHealedTimeSegments   = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healerSpellTimeSegments    = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            DataManager.Instance.GetHealsDuring(segment.BeginTime, segment.EndTime).ForEach(heal =>
                            {
                                var updatedHeal = new ActionBlock()
                                {
                                    BeginTime = heal.BeginTime
                                };
                                foreach (var record in heal.Actions.Cast <HealRecord>())
                                {
                                    if (PlayerManager.Instance.IsPossiblePlayerName(record.Healed) || PlayerManager.Instance.IsPetOrPlayer(record.Healed))
                                    {
                                        bool valid = true;
                                        SpellData spellData;
                                        if (record.SubType != null && (spellData = DataManager.Instance.GetSpellByName(record.SubType)) != null)
                                        {
                                            if (spellData.Target == (byte)SpellTarget.TARGETAE || spellData.Target == (byte)SpellTarget.NEARBYPLAYERSAE ||
                                                spellData.Target == (byte)SpellTarget.TARGETRINGAE)
                                            {
                                                valid = MainWindow.IsAoEHealingEnabled;
                                            }
                                        }

                                        if (valid)
                                        {
                                            updatedHeal.Actions.Add(record);
                                            // store substats and substats2 which is based on the player that was healed
                                            var key = Helpers.CreateRecordKey(record.Type, record.SubType);
                                            StatsUtil.UpdateTimeSegments(null, healedByHealerTimeSegments, record.Healer, record.Healed, heal.BeginTime);
                                            StatsUtil.UpdateTimeSegments(null, healedBySpellTimeSegments, key, record.Healed, heal.BeginTime);
                                            StatsUtil.UpdateTimeSegments(null, healerHealedTimeSegments, record.Healed, record.Healer, heal.BeginTime);
                                            StatsUtil.UpdateTimeSegments(null, healerSpellTimeSegments, key, record.Healer, heal.BeginTime);
                                        }
                                    }
                                }

                                if (updatedHeal.Actions.Count > 0)
                                {
                                    updatedHeals.Add(updatedHeal);
                                }
                            });

                            Parallel.ForEach(healedByHealerTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealedByHealerTimeRanges, kv));
                            Parallel.ForEach(healedBySpellTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealedBySpellTimeRanges, kv));
                            Parallel.ForEach(healerHealedTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealerHealedTimeRanges, kv));
                            Parallel.ForEach(healerSpellTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealerSpellTimeRanges, kv));

                            if (updatedHeals.Count > 0)
                            {
                                HealingGroups.Add(updatedHeals);
                            }
                        });

                        ComputeHealingStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    if (ex is ArgumentNullException || ex is NullReferenceException || ex is ArgumentOutOfRangeException || ex is ArgumentException || ex is OutOfMemoryException)
                    {
                        LOG.Error(ex);
                    }
                }
            }
        }
예제 #22
0
        private void ComputeHealingStats(GenerateStatsOptions options)
        {
            lock (HealingGroups)
            {
                if (RaidTotals != null)
                {
                    CombinedStats combined = null;
                    Dictionary <string, PlayerStats> individualStats = new Dictionary <string, PlayerStats>();

                    // always start over
                    RaidTotals.Total = 0;

                    try
                    {
                        FireChartEvent(options, "UPDATE");

                        if (options.RequestSummaryData)
                        {
                            HealingGroups.ForEach(group =>
                            {
                                group.ForEach(block =>
                                {
                                    block.Actions.ForEach(action =>
                                    {
                                        if (action is HealRecord record)
                                        {
                                            RaidTotals.Total += record.Total;
                                            PlayerStats stats = StatsUtil.CreatePlayerStats(individualStats, record.Healer);
                                            StatsUtil.UpdateStats(stats, record);

                                            var spellStatName         = record.SubType ?? Labels.SELFHEAL;
                                            PlayerSubStats spellStats = StatsUtil.CreatePlayerSubStats(stats.SubStats, spellStatName, record.Type);
                                            StatsUtil.UpdateStats(spellStats, record);

                                            var healedStatName         = record.Healed;
                                            PlayerSubStats healedStats = StatsUtil.CreatePlayerSubStats(stats.SubStats2, healedStatName, record.Type);
                                            StatsUtil.UpdateStats(healedStats, record);
                                        }
                                    });
                                });
                            });

                            RaidTotals.DPS = (long)Math.Round(RaidTotals.Total / RaidTotals.TotalSeconds, 2);
                            Parallel.ForEach(individualStats.Values, stats => UpdateStats(stats, HealerSpellTimeRanges, HealerHealedTimeRanges));

                            combined = new CombinedStats
                            {
                                RaidStats   = RaidTotals,
                                TargetTitle = (Selected.Count > 1 ? "Combined (" + Selected.Count + "): " : "") + Title,
                                TimeTitle   = string.Format(CultureInfo.CurrentCulture, StatsUtil.TIME_FORMAT, RaidTotals.TotalSeconds),
                                TotalTitle  = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_FORMAT, StatsUtil.FormatTotals(RaidTotals.Total), " Heals ", StatsUtil.FormatTotals(RaidTotals.DPS))
                            };

                            combined.StatsList.AddRange(individualStats.Values.AsParallel().OrderByDescending(item => item.Total));
                            combined.FullTitle  = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, combined.TotalTitle);
                            combined.ShortTitle = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, "");

                            for (int i = 0; i < combined.StatsList.Count; i++)
                            {
                                combined.StatsList[i].Rank = Convert.ToUInt16(i + 1);
                                combined.UniqueClasses[combined.StatsList[i].ClassName] = 1;
                            }
                        }
                    }
#pragma warning disable CA1031 // Do not catch general exception types
                    catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                    {
                        if (ex is ArgumentNullException || ex is NullReferenceException || ex is ArgumentOutOfRangeException || ex is ArgumentException || ex is OutOfMemoryException)
                        {
                            LOG.Error(ex);
                        }
                    }

                    if (options.RequestSummaryData)
                    {
                        // generating new stats
                        var genEvent = new StatsGenerationEvent()
                        {
                            Type          = Labels.HEALPARSE,
                            State         = "COMPLETED",
                            CombinedStats = combined
                        };

                        genEvent.Groups.AddRange(HealingGroups);
                        EventsGenerationStatus?.Invoke(this, genEvent);
                    }
                }
            }
        }
예제 #23
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (HealingGroups)
            {
                Selected = options.Npcs;
                Title    = options.Name;

                try
                {
                    FireNewStatsEvent(options);

                    RaidTotals = StatsUtil.CreatePlayerStats(Labels.RAID);
                    HealingGroups.Clear();

                    Selected.ForEach(npc => StatsUtil.UpdateTimeDiffs(RaidTotals, npc, HEAL_OFFSET));
                    RaidTotals.TotalSeconds = RaidTotals.TimeDiffs.Sum();

                    if (RaidTotals.BeginTimes.Count > 0 && RaidTotals.BeginTimes.Count == RaidTotals.LastTimes.Count)
                    {
                        for (int i = 0; i < RaidTotals.BeginTimes.Count; i++)
                        {
                            var updatedHeals = new List <ActionBlock>();
                            var heals        = DataManager.Instance.GetHealsDuring(RaidTotals.BeginTimes[i], RaidTotals.LastTimes[i]);
                            heals.ForEach(heal =>
                            {
                                var updatedHeal = new ActionBlock()
                                {
                                    BeginTime = heal.BeginTime
                                };
                                updatedHeal.Actions.AddRange(heal.Actions.Where(item => item is HealRecord record && IsValidHeal(record)));

                                if (updatedHeal.Actions.Count > 0)
                                {
                                    updatedHeals.Add(updatedHeal);
                                }
                            });

                            if (updatedHeals.Count > 0)
                            {
                                HealingGroups.Add(updatedHeals);
                            }
                        }

                        ComputeHealingStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
                catch (ArgumentNullException ne)
                {
                    LOG.Error(ne);
                }
                catch (NullReferenceException nr)
                {
                    LOG.Error(nr);
                }
                catch (ArgumentOutOfRangeException aor)
                {
                    LOG.Error(aor);
                }
                catch (ArgumentException ae)
                {
                    LOG.Error(ae);
                }
                catch (OutOfMemoryException oem)
                {
                    LOG.Error(oem);
                }
            }
        }
예제 #24
0
        private void ComputeHealingStats(GenerateStatsOptions options)
        {
            lock (HealingGroups)
            {
                if (RaidTotals != null)
                {
                    CombinedStats combined = null;
                    Dictionary <string, PlayerStats> individualStats = new Dictionary <string, PlayerStats>();

                    // always start over
                    RaidTotals.Total = 0;

                    try
                    {
                        FireUpdateEvent(options);

                        if (options.RequestSummaryData)
                        {
                            HealingGroups.ForEach(group =>
                            {
                                // keep track of time range as well as the players that have been updated
                                Dictionary <string, PlayerSubStats> allStats = new Dictionary <string, PlayerSubStats>();

                                group.ForEach(block =>
                                {
                                    block.Actions.ForEach(action =>
                                    {
                                        if (action is HealRecord record)
                                        {
                                            RaidTotals.Total += record.Total;
                                            PlayerStats stats = StatsUtil.CreatePlayerStats(individualStats, record.Healer);

                                            StatsUtil.UpdateStats(stats, record, block.BeginTime);
                                            allStats[record.Healer] = stats;

                                            var spellStatName         = record.SubType ?? Labels.SELFHEAL;
                                            PlayerSubStats spellStats = StatsUtil.CreatePlayerSubStats(stats.SubStats, spellStatName, record.Type);
                                            StatsUtil.UpdateStats(spellStats, record, block.BeginTime);
                                            allStats[stats.Name + "=" + spellStatName] = spellStats;

                                            var healedStatName         = record.Healed;
                                            PlayerSubStats healedStats = StatsUtil.CreatePlayerSubStats(stats.SubStats2, healedStatName, record.Type);
                                            StatsUtil.UpdateStats(healedStats, record, block.BeginTime);
                                            allStats[stats.Name + "=" + healedStatName] = healedStats;
                                        }
                                    });
                                });

                                foreach (var stats in allStats.Values)
                                {
                                    stats.TotalSeconds += stats.LastTime - stats.BeginTime + 1;
                                    stats.BeginTime     = double.NaN;
                                }
                            });

                            RaidTotals.DPS = (long)Math.Round(RaidTotals.Total / RaidTotals.TotalSeconds, 2);
                            Parallel.ForEach(individualStats.Values, stats => StatsUtil.UpdateCalculations(stats, RaidTotals));

                            combined = new CombinedStats
                            {
                                RaidStats   = RaidTotals,
                                TargetTitle = (Selected.Count > 1 ? "Combined (" + Selected.Count + "): " : "") + Title,
                                TimeTitle   = string.Format(CultureInfo.CurrentCulture, StatsUtil.TIME_FORMAT, RaidTotals.TotalSeconds),
                                TotalTitle  = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_FORMAT, StatsUtil.FormatTotals(RaidTotals.Total), " Heals ", StatsUtil.FormatTotals(RaidTotals.DPS))
                            };

                            combined.StatsList.AddRange(individualStats.Values.AsParallel().OrderByDescending(item => item.Total));
                            combined.FullTitle  = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, combined.TotalTitle);
                            combined.ShortTitle = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, "");

                            for (int i = 0; i < combined.StatsList.Count; i++)
                            {
                                combined.StatsList[i].Rank = Convert.ToUInt16(i + 1);
                                combined.UniqueClasses[combined.StatsList[i].ClassName] = 1;
                            }
                        }
                    }
                    catch (ArgumentNullException ane)
                    {
                        LOG.Error(ane);
                    }
                    catch (NullReferenceException nre)
                    {
                        LOG.Error(nre);
                    }
                    catch (ArgumentOutOfRangeException aro)
                    {
                        LOG.Error(aro);
                    }

                    FireCompletedEvent(options, combined, HealingGroups);
                }
            }
        }
예제 #25
0
 internal void FireFilterEvent(GenerateStatsOptions options, Predicate <object> filter)
 {
     FireChartEvent(options, "FILTER", null, filter);
 }
예제 #26
0
        private void ComputeDamageStats(GenerateStatsOptions options)
        {
            lock (DamageGroups)
            {
                if (RaidTotals != null)
                {
                    CombinedStats combined = null;
                    ConcurrentDictionary <string, Dictionary <string, PlayerStats> > childrenStats = new ConcurrentDictionary <string, Dictionary <string, PlayerStats> >();
                    ConcurrentDictionary <string, PlayerStats> topLevelStats   = new ConcurrentDictionary <string, PlayerStats>();
                    ConcurrentDictionary <string, PlayerStats> aggregateStats  = new ConcurrentDictionary <string, PlayerStats>();
                    Dictionary <string, PlayerStats>           individualStats = new Dictionary <string, PlayerStats>();

                    // always start over
                    RaidTotals.Total = 0;

                    try
                    {
                        FireUpdateEvent(options);

                        if (options.RequestSummaryData)
                        {
                            DamageGroups.ForEach(group =>
                            {
                                // keep track of time range as well as the players that have been updated
                                Dictionary <string, PlayerSubStats> allStats = new Dictionary <string, PlayerSubStats>();

                                int found = -1;
                                if (MainWindow.IsIgnoreIntialPullDamageEnabled)
                                {
                                    // ignore initial low activity time
                                    double previousDps = 0;
                                    long rolling       = 0;
                                    for (int i = 0; group.Count >= 10 && i < 10; i++)
                                    {
                                        if (previousDps == 0)
                                        {
                                            rolling     = group[i].Actions.Sum(test => (test as DamageRecord).Total);
                                            previousDps = rolling / 1.0;
                                        }
                                        else
                                        {
                                            double theTime = group[i].BeginTime - group[0].BeginTime + 1;
                                            if (theTime > 12.0)
                                            {
                                                break;
                                            }

                                            rolling          += group[i].Actions.Sum(test => (test as DamageRecord).Total);
                                            double currentDps = rolling / (theTime);
                                            if (currentDps / previousDps > 1.75)
                                            {
                                                found = i - 1;
                                                break;
                                            }
                                            else
                                            {
                                                previousDps = currentDps;
                                            }
                                        }
                                    }
                                }

                                var goodGroups = found > -1 ? group.GetRange(found, group.Count - found) : group;

                                goodGroups.ForEach(block =>
                                {
                                    block.Actions.ForEach(action =>
                                    {
                                        if (action is DamageRecord record)
                                        {
                                            PlayerStats stats = StatsUtil.CreatePlayerStats(individualStats, record.Attacker);

                                            if (!MainWindow.IsBaneDamageEnabled && record.Type == Labels.BANE)
                                            {
                                                stats.BaneHits++;

                                                if (individualStats.TryGetValue(stats.OrigName + " +Pets", out PlayerStats temp))
                                                {
                                                    temp.BaneHits++;
                                                }
                                            }
                                            else
                                            {
                                                RaidTotals.Total += record.Total;
                                                StatsUtil.UpdateStats(stats, record, block.BeginTime);
                                                allStats[record.Attacker] = stats;

                                                if (!PetToPlayer.TryGetValue(record.Attacker, out string player) && !PlayerHasPet.ContainsKey(record.Attacker))
                                                {
                                                    // not a pet
                                                    topLevelStats[record.Attacker] = stats;
                                                }
                                                else
                                                {
                                                    string origName      = player ?? record.Attacker;
                                                    string aggregateName = (player == Labels.UNASSIGNED) ? origName : origName + " +Pets";

                                                    PlayerStats aggregatePlayerStats = StatsUtil.CreatePlayerStats(individualStats, aggregateName, origName);
                                                    StatsUtil.UpdateStats(aggregatePlayerStats, record, block.BeginTime);
                                                    allStats[aggregateName]      = aggregatePlayerStats;
                                                    topLevelStats[aggregateName] = aggregatePlayerStats;

                                                    if (!childrenStats.TryGetValue(aggregateName, out Dictionary <string, PlayerStats> children))
                                                    {
                                                        childrenStats[aggregateName] = new Dictionary <string, PlayerStats>();
                                                    }

                                                    childrenStats[aggregateName][stats.Name] = stats;
                                                }

                                                PlayerSubStats subStats = StatsUtil.CreatePlayerSubStats(stats.SubStats, record.SubType, record.Type);
                                                UpdateSubStats(subStats, record, block.BeginTime);
                                                allStats[stats.Name + "=" + Helpers.CreateRecordKey(record.Type, record.SubType)] = subStats;
                                            }
                                        }
                                    });
                                });

                                foreach (var stats in allStats.Values)
                                {
                                    stats.TotalSeconds += stats.LastTime - stats.BeginTime + 1;
                                    stats.BeginTime     = double.NaN;
                                }
                            });

                            RaidTotals.DPS = (long)Math.Round(RaidTotals.Total / RaidTotals.TotalSeconds, 2);

                            // add up resists
                            Dictionary <string, uint> resistCounts = new Dictionary <string, uint>();

                            Resists.ForEach(resist =>
                            {
                                ResistRecord record = resist as ResistRecord;
                                Helpers.StringUIntAddHelper.Add(resistCounts, record.Spell, 1);
                            });

                            // get special field
                            var specials = StatsUtil.GetSpecials(RaidTotals);

                            Parallel.ForEach(individualStats.Values, stats =>
                            {
                                if (topLevelStats.TryGetValue(stats.Name, out PlayerStats topLevel))
                                {
                                    if (childrenStats.TryGetValue(stats.Name, out Dictionary <string, PlayerStats> children))
                                    {
                                        foreach (var child in children.Values)
                                        {
                                            StatsUtil.UpdateCalculations(child, RaidTotals, resistCounts);

                                            if (stats.Total > 0)
                                            {
                                                child.Percent = Math.Round(Convert.ToDouble(child.Total) / stats.Total * 100, 2);
                                            }

                                            if (specials.TryGetValue(child.Name, out string special1))
                                            {
                                                child.Special = special1;
                                            }
                                        }
                                    }

                                    StatsUtil.UpdateCalculations(stats, RaidTotals, resistCounts);

                                    if (specials.TryGetValue(stats.OrigName, out string special2))
                                    {
                                        stats.Special = special2;
                                    }
                                }
                            });

                            combined = new CombinedStats
                            {
                                RaidStats   = RaidTotals,
                                TargetTitle = (Selected.Count > 1 ? "Combined (" + Selected.Count + "): " : "") + Title,
                                TimeTitle   = string.Format(CultureInfo.CurrentCulture, StatsUtil.TIME_FORMAT, RaidTotals.TotalSeconds),
                                TotalTitle  = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_FORMAT, StatsUtil.FormatTotals(RaidTotals.Total), " Damage ", StatsUtil.FormatTotals(RaidTotals.DPS))
                            };

                            combined.StatsList.AddRange(topLevelStats.Values.AsParallel().OrderByDescending(item => item.Total));
                            combined.FullTitle  = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, combined.TotalTitle);
                            combined.ShortTitle = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, "");

                            for (int i = 0; i < combined.StatsList.Count; i++)
                            {
                                combined.StatsList[i].Rank = Convert.ToUInt16(i + 1);
                                combined.UniqueClasses[combined.StatsList[i].ClassName] = 1;

                                if (childrenStats.TryGetValue(combined.StatsList[i].Name, out Dictionary <string, PlayerStats> children))
                                {
                                    combined.Children.Add(combined.StatsList[i].Name, children.Values.OrderByDescending(stats => stats.Total).ToList());
                                }
                            }
                        }
                    }
                    catch (ArgumentNullException anx)
                    {
                        LOG.Error(anx);
                    }
                    catch (AggregateException agx)
                    {
                        LOG.Error(agx);
                    }

                    FireCompletedEvent(options, combined, DamageGroups);
                }
            }
        }
예제 #27
0
        private void ComputeTankingStats(GenerateStatsOptions options)
        {
            lock (TankingGroupIds)
            {
                CombinedStats combined = null;
                Dictionary <string, PlayerStats> individualStats = new Dictionary <string, PlayerStats>();

                if (RaidTotals != null)
                {
                    // always start over
                    RaidTotals.Total = 0;

                    try
                    {
                        FireChartEvent(options, "UPDATE");

                        if (options.RequestSummaryData)
                        {
                            TankingGroups.ForEach(group =>
                            {
                                group.ForEach(block =>
                                {
                                    block.Actions.ForEach(action =>
                                    {
                                        if (action is DamageRecord record)
                                        {
                                            if (options.DamageType == 0 || (options.DamageType == 1 && IsMelee(record)) || (options.DamageType == 2 && !IsMelee(record)))
                                            {
                                                RaidTotals.Total += record.Total;
                                                PlayerStats stats = StatsUtil.CreatePlayerStats(individualStats, record.Defender);
                                                StatsUtil.UpdateStats(stats, record);
                                                PlayerSubStats subStats = StatsUtil.CreatePlayerSubStats(stats.SubStats, record.SubType, record.Type);
                                                StatsUtil.UpdateStats(subStats, record);
                                            }
                                        }
                                    });
                                });
                            });

                            RaidTotals.DPS = (long)Math.Round(RaidTotals.Total / RaidTotals.TotalSeconds, 2);
                            Parallel.ForEach(individualStats.Values, stats =>
                            {
                                StatsUtil.UpdateAllStatsTimeRanges(stats, PlayerTimeRanges, PlayerSubTimeRanges);
                                StatsUtil.UpdateCalculations(stats, RaidTotals);
                            });

                            combined = new CombinedStats
                            {
                                RaidStats   = RaidTotals,
                                TargetTitle = (Selected.Count > 1 ? "Combined (" + Selected.Count + "): " : "") + Title,
                                TimeTitle   = string.Format(CultureInfo.CurrentCulture, StatsUtil.TIME_FORMAT, RaidTotals.TotalSeconds),
                                TotalTitle  = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_FORMAT, StatsUtil.FormatTotals(RaidTotals.Total), " Tanked ", StatsUtil.FormatTotals(RaidTotals.DPS))
                            };

                            combined.StatsList.AddRange(individualStats.Values.AsParallel().OrderByDescending(item => item.Total));
                            combined.FullTitle  = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, combined.TotalTitle);
                            combined.ShortTitle = StatsUtil.FormatTitle(combined.TargetTitle, combined.TimeTitle, "");

                            for (int i = 0; i < combined.StatsList.Count; i++)
                            {
                                combined.StatsList[i].Rank = Convert.ToUInt16(i + 1);
                                combined.UniqueClasses[combined.StatsList[i].ClassName] = 1;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LOG.Error(ex);
                    }

                    if (options.RequestSummaryData)
                    {
                        // generating new stats
                        var genEvent = new StatsGenerationEvent()
                        {
                            Type          = Labels.TANKPARSE,
                            State         = "COMPLETED",
                            CombinedStats = combined
                        };

                        genEvent.Groups.AddRange(TankingGroups);
                        genEvent.UniqueGroupCount = TankingGroupIds.Count;
                        EventsGenerationStatus?.Invoke(this, genEvent);
                    }
                }
            }
        }
예제 #28
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (DamageGroups)
            {
                Selected = options.Npcs;
                Title    = options.Name;

                try
                {
                    FireNewStatsEvent(options);

                    RaidTotals = StatsUtil.CreatePlayerStats(Labels.RAID);
                    DamageGroups.Clear();
                    DamageGroupIds.Clear();
                    PlayerHasPet.Clear();
                    PetToPlayer.Clear();
                    Resists.Clear();

                    var damageBlocks = new List <ActionBlock>();
                    Selected.ForEach(fight =>
                    {
                        StatsUtil.UpdateTimeDiffs(RaidTotals, fight);
                        damageBlocks.AddRange(fight.DamageBlocks);

                        if (fight.GroupId > -1)
                        {
                            DamageGroupIds[fight.GroupId] = 1;
                        }
                    });

                    damageBlocks.Sort((a, b) => a.BeginTime.CompareTo(b.BeginTime));

                    if (damageBlocks.Count > 0)
                    {
                        RaidTotals.TotalSeconds = RaidTotals.TimeDiffs.Sum();

                        var newBlock  = new List <ActionBlock>();
                        var timeIndex = 0;

                        damageBlocks.ForEach(block =>
                        {
                            if (block.BeginTime > RaidTotals.LastTimes[timeIndex])
                            {
                                timeIndex++;

                                if (newBlock.Count > 0)
                                {
                                    DamageGroups.Add(newBlock);
                                }

                                newBlock = new List <ActionBlock>();
                            }

                            newBlock.Add(block);

                            block.Actions.ForEach(action =>
                            {
                                DamageRecord damage = action as DamageRecord;
                                // see if there's a pet mapping, check this first
                                string pname = PlayerManager.Instance.GetPlayerFromPet(damage.Attacker);
                                if (!string.IsNullOrEmpty(pname) || !string.IsNullOrEmpty(pname = damage.AttackerOwner))
                                {
                                    PlayerHasPet[pname]          = 1;
                                    PetToPlayer[damage.Attacker] = pname;
                                }
                            });
                        });

                        DamageGroups.Add(newBlock);

                        for (int i = 0; i < RaidTotals.BeginTimes.Count && i < RaidTotals.LastTimes.Count; i++)
                        {
                            var group = DataManager.Instance.GetResistsDuring(RaidTotals.BeginTimes[i], RaidTotals.LastTimes[i]);
                            group.ForEach(block => Resists.AddRange(block.Actions));
                        }

                        ComputeDamageStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
                catch (ArgumentNullException ne)
                {
                    LOG.Error(ne);
                }
                catch (NullReferenceException nr)
                {
                    LOG.Error(nr);
                }
                catch (ArgumentOutOfRangeException aor)
                {
                    LOG.Error(aor);
                }
                catch (ArgumentException ae)
                {
                    LOG.Error(ae);
                }
                catch (OutOfMemoryException oem)
                {
                    LOG.Error(oem);
                }
            }
        }
예제 #29
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (TankingGroupIds)
            {
                try
                {
                    FireNewStatsEvent(options);
                    Reset();

                    Selected = options.Npcs.OrderBy(sel => sel.Id).ToList();
                    Title    = options.Name;
                    var damageBlocks = new List <ActionBlock>();

                    Selected.ForEach(fight =>
                    {
                        damageBlocks.AddRange(fight.TankingBlocks);

                        if (fight.GroupId > -1)
                        {
                            TankingGroupIds[fight.GroupId] = 1;
                        }

                        RaidTotals.Ranges.Add(new TimeSegment(fight.BeginTankingTime, fight.LastTankingTime));
                        StatsUtil.UpdateRaidTimeRanges(fight, PlayerTimeRanges, PlayerSubTimeRanges, true);
                    });

                    damageBlocks.Sort((a, b) => a.BeginTime.CompareTo(b.BeginTime));

                    if (damageBlocks.Count > 0)
                    {
                        RaidTotals.TotalSeconds = RaidTotals.MaxTime = RaidTotals.Ranges.GetTotal();

                        int    rangeIndex = 0;
                        double lastTime   = 0;
                        var    newBlock   = new List <ActionBlock>();
                        damageBlocks.ForEach(block =>
                        {
                            if (RaidTotals.Ranges.TimeSegments.Count > rangeIndex && block.BeginTime > RaidTotals.Ranges.TimeSegments[rangeIndex].EndTime)
                            {
                                rangeIndex++;

                                if (newBlock.Count > 0)
                                {
                                    TankingGroups.Add(newBlock);
                                }

                                newBlock = new List <ActionBlock>();
                            }

                            if (lastTime != block.BeginTime)
                            {
                                var copy = new ActionBlock();
                                copy.Actions.AddRange(block.Actions);
                                copy.BeginTime = block.BeginTime;
                                newBlock.Add(copy);
                            }
                            else
                            {
                                newBlock.Last().Actions.AddRange(block.Actions);
                            }
                        });

                        TankingGroups.Add(newBlock);
                        ComputeTankingStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
                catch (Exception ex)
                {
                    LOG.Error(ex);
                }
            }
        }
예제 #30
0
 internal void FireUpdateEvent(GenerateStatsOptions options, List <PlayerStats> selected = null, Predicate <object> filter = null)
 {
     FireChartEvent(options, "UPDATE", selected, filter);
 }