internal TankingBreakdown(CombinedStats currentStats)
 {
     InitializeComponent();
     InitBreakdownTable(dataGrid, selectedColumns);
     titleLabel.Content = currentStats?.ShortTitle;
     RaidStats          = currentStats?.RaidStats;
 }
Ejemplo n.º 2
0
 internal HealBreakdown(CombinedStats currentStats)
 {
     InitializeComponent();
     titleLabel.Content        = currentStats?.ShortTitle;
     choicesList.ItemsSource   = ChoicesList;
     choicesList.SelectedIndex = 0;
 }
Ejemplo n.º 3
0
        public StatsSummary BuildSummary(string type, CombinedStats currentStats, List <PlayerStats> selected, bool showTotals, bool rankPlayers, bool _)
        {
            List <string> list = new List <string>();

            string title   = "";
            string details = "";

            if (currentStats != null && type == Labels.HEALPARSE)
            {
                if (selected?.Count > 0)
                {
                    foreach (PlayerStats stats in selected.OrderByDescending(item => item.Total))
                    {
                        string playerFormat = rankPlayers ? string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_RANK_FORMAT, stats.Rank, stats.Name) : string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_FORMAT, stats.Name);
                        string damageFormat = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_ONLY_FORMAT, StatsUtil.FormatTotals(stats.Total));
                        list.Add(playerFormat + damageFormat + " ");
                    }
                }

                details = list.Count > 0 ? ", " + string.Join(" | ", list) : "";
                title   = StatsUtil.FormatTitle(currentStats.TargetTitle, currentStats.TimeTitle, showTotals ? currentStats.TotalTitle : "");
            }

            return(new StatsSummary()
            {
                Title = title, RankedPlayers = details,
            });
        }
Ejemplo n.º 4
0
 public DamageBreakdown(CombinedStats currentStats)
 {
     InitializeComponent();
     titleLabel.Content = currentStats?.ShortTitle;
     RaidStats          = currentStats.RaidStats;
     ChildStats         = currentStats.Children;
 }
Ejemplo n.º 5
0
 internal ReceivedHealingBreakdown(CombinedStats currentStats)
 {
     InitializeComponent();
     InitBreakdownTable(dataGrid, selectedColumns);
     titleLabel.Content        = currentStats?.ShortTitle;
     choicesList.ItemsSource   = ChoicesList;
     choicesList.SelectedIndex = 0;
 }
Ejemplo n.º 6
0
        internal void PopulateHealing(CombinedStats combined)
        {
            lock (HealingGroups)
            {
                List <PlayerStats> playerStats = combined.StatsList;
                Dictionary <string, PlayerStats> individualStats = new Dictionary <string, PlayerStats>();
                Dictionary <string, long>        totals          = new Dictionary <string, long>();

                HealingGroups.ForEach(group =>
                {
                    group.ForEach(block =>
                    {
                        block.Actions.ForEach(action =>
                        {
                            if (action is HealRecord record)
                            {
                                PlayerStats stats = StatsUtil.CreatePlayerStats(individualStats, record.Healed);
                                StatsUtil.UpdateStats(stats, record);

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

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

                                long value = 0;
                                if (totals.ContainsKey(record.Healed))
                                {
                                    value = totals[record.Healed];
                                }

                                totals[record.Healed] = record.Total + value;
                            }
                        });
                    });
                });

                Parallel.ForEach(playerStats, stat =>
                {
                    if (individualStats.ContainsKey(stat.Name))
                    {
                        if (totals.ContainsKey(stat.Name))
                        {
                            stat.Extra = totals[stat.Name];
                        }

                        var indStats = individualStats[stat.Name];
                        stat.SubStats2["receivedHealing"] = indStats;
                        UpdateStats(indStats, HealedBySpellTimeRanges, HealedByHealerTimeRanges);

                        indStats.SubStats.Values.ToList().ForEach(subStat => StatsUtil.UpdateCalculations(subStat, indStats));
                        indStats.SubStats2.Values.ToList().ForEach(subStat => StatsUtil.UpdateCalculations(subStat, indStats));
                    }
                });
            }
        }
Ejemplo n.º 7
0
        public StatsSummary BuildSummary(string type, CombinedStats currentStats, List <PlayerStats> selected, bool showTotals, bool rankPlayers, bool _, bool showTime)
        {
            List <string> list = new List <string>();

            string title   = "";
            string details = "";

            if (currentStats != null)
            {
                if (type == Labels.TANKPARSE)
                {
                    if (selected?.Count > 0)
                    {
                        foreach (PlayerStats stats in selected.OrderByDescending(item => item.Total))
                        {
                            string playerFormat = rankPlayers ? string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_RANK_FORMAT, stats.Rank, stats.Name) : string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_FORMAT, stats.Name);
                            string damageFormat = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_ONLY_FORMAT, StatsUtil.FormatTotals(stats.Total));
                            list.Add(playerFormat + damageFormat + " ");
                        }
                    }

                    details = list.Count > 0 ? ", " + string.Join(" | ", list) : "";
                    var timeTitle = showTime ? (" " + currentStats.TimeTitle) : "";
                    title = StatsUtil.FormatTitle(currentStats.TargetTitle, timeTitle, showTotals ? currentStats.TotalTitle : "");
                }
                else if (type == Labels.RECEIVEDHEALPARSE)
                {
                    if (selected?.Count == 1 && (selected[0] as PlayerStats).SubStats2.TryGetValue("receivedHealing", out PlayerSubStats subStats) && subStats is PlayerStats receivedHealing)
                    {
                        int  rank   = 1;
                        long totals = 0;
                        foreach (var stats in receivedHealing.SubStats.Values.OrderByDescending(stats => stats.Total).Take(10))
                        {
                            string playerFormat = rankPlayers ? string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_RANK_FORMAT, rank++, stats.Name) : string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_FORMAT, stats.Name);
                            string damageFormat = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_ONLY_FORMAT, StatsUtil.FormatTotals(stats.Total));
                            list.Add(playerFormat + damageFormat + " ");
                            totals += stats.Total;
                        }

                        var    hps        = (long)Math.Round(totals / currentStats.RaidStats.TotalSeconds, 2);
                        string totalTitle = showTotals ? (selected[0].Name + " Received " + StatsUtil.FormatTotals(totals) + " Healing") : (selected[0].Name + " Received Healing");
                        details = list.Count > 0 ? ", " + string.Join(" | ", list) : "";
                        var timeTitle = showTime ? (" " + currentStats.TimeTitle) : "";
                        title = StatsUtil.FormatTitle(currentStats.TargetTitle, timeTitle, totalTitle);
                    }
                }
            }

            return(new StatsSummary()
            {
                Title = title, RankedPlayers = details,
            });
        }
Ejemplo n.º 8
0
        public StatsSummary BuildSummary(string type, CombinedStats currentStats, List <PlayerStats> selected, bool showTotals, bool rankPlayers, bool _, bool showTime)
        {
            List <string> list = new List <string>();

            string title   = "";
            string details = "";

            if (currentStats != null)
            {
                if (type == Labels.HEALPARSE)
                {
                    if (selected?.Count > 0)
                    {
                        foreach (PlayerStats stats in selected.OrderByDescending(item => item.Total))
                        {
                            string playerFormat = rankPlayers ? string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_RANK_FORMAT, stats.Rank, stats.Name) : string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_FORMAT, stats.Name);
                            string healsFormat  = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_ONLY_FORMAT, StatsUtil.FormatTotals(stats.Total));
                            list.Add(playerFormat + healsFormat + " ");
                        }
                    }

                    details = list.Count > 0 ? ", " + string.Join(" | ", list) : "";
                    var timeTitle = showTime ? (" " + currentStats.TimeTitle) : "";
                    title = StatsUtil.FormatTitle(currentStats.TargetTitle, timeTitle, showTotals ? currentStats.TotalTitle : "");
                }
                else if (type == Labels.TOPHEALSPARSE)
                {
                    if (selected?.Count == 1 && selected[0].SubStats.Count > 0)
                    {
                        int rank = 1;
                        foreach (var stats in selected[0].SubStats.Values.OrderByDescending(stats => stats.Total).Take(10))
                        {
                            string abbrv        = DataManager.Instance.AbbreviateSpellName(stats.Name);
                            string playerFormat = rankPlayers ? string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_RANK_FORMAT, rank++, abbrv) : string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_FORMAT, abbrv);
                            string healsFormat  = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_ONLY_FORMAT, StatsUtil.FormatTotals(stats.Total));
                            list.Add(playerFormat + healsFormat + " ");
                        }

                        string totalTitle = selected[0].Name + "'s Top Heals";
                        details = list.Count > 0 ? ", " + string.Join(" | ", list) : "";
                        var timeTitle = showTime ? (" " + currentStats.TimeTitle) : "";
                        title = StatsUtil.FormatTitle(currentStats.TargetTitle, timeTitle, totalTitle);
                    }
                }
            }

            return(new StatsSummary()
            {
                Title = title, RankedPlayers = details,
            });
        }
Ejemplo n.º 9
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);
            }
        }
Ejemplo n.º 10
0
        internal SpellCastTable(string title, List <PlayerStats> selectedStats, CombinedStats currentStats)
        {
            InitializeComponent();
            titleLabel.Content = title;
            selectedStats?.ForEach(stats => UniqueNames[stats.OrigName] = 1);
            RaidStats = currentStats?.RaidStats;

            dataGrid.ItemsSource = CollectionViewSource.GetDefaultView(Records);
            BindingOperations.EnableCollectionSynchronization(Records, LockObject);

            castTypes.ItemsSource    = CastTypes;
            castTypes.SelectedIndex  = 0;
            spellTypes.ItemsSource   = SpellTypes;
            spellTypes.SelectedIndex = 0;
            Display();
        }
Ejemplo n.º 11
0
        internal void ShowSpells(List <PlayerStats> selectedStats, CombinedStats currentStats)
        {
            var raidStats = currentStats?.RaidStats;

            if (selectedStats != null && raidStats != null)
            {
                PlayerList     = selectedStats.Select(stats => stats.OrigName).ToList();
                TheSpellCounts = SpellCountBuilder.GetSpellCounts(PlayerList, raidStats);

                if (TheSpellCounts.PlayerCastCounts.Count > 0)
                {
                    selectAll.IsEnabled = true;
                }

                Display();
            }
        }
Ejemplo n.º 12
0
        internal void AddParse(string type, ISummaryBuilder builder, CombinedStats combined, List <PlayerStats> selected = null, bool copy = false)
        {
            Parses[type] = new ParseData()
            {
                Builder = builder, CombinedStats = combined
            };

            if (selected != null)
            {
                Parses[type].Selected.AddRange(selected);
            }

            if (!AvailableParses.Contains(type))
            {
                Dispatcher.InvokeAsync(() => AvailableParses.Add(type));
            }

            TriggerParseUpdate(type, copy);
        }
Ejemplo n.º 13
0
        public StatsSummary BuildSummary(string type, CombinedStats currentStats, List <PlayerStats> selected, bool showTotals, bool rankPlayers, bool showSpecial)
        {
            List <string> list = new List <string>();

            string title   = "";
            string details = "";

            if (currentStats != null && type == Labels.DAMAGEPARSE)
            {
                if (selected?.Count > 0)
                {
                    foreach (PlayerStats stats in selected.OrderByDescending(item => item.Total))
                    {
                        string playerFormat = rankPlayers ? string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_RANK_FORMAT, stats.Rank, stats.Name) : string.Format(CultureInfo.CurrentCulture, StatsUtil.PLAYER_FORMAT, stats.Name);
                        string damageFormat = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_FORMAT, StatsUtil.FormatTotals(stats.Total), "", StatsUtil.FormatTotals(stats.DPS));
                        string timeFormat   = string.Format(CultureInfo.CurrentCulture, StatsUtil.TIME_FORMAT, stats.TotalSeconds);

                        var dps = playerFormat + damageFormat + " " + timeFormat;

                        if (showSpecial && !string.IsNullOrEmpty(stats.Special))
                        {
                            dps = string.Format(CultureInfo.CurrentCulture, StatsUtil.SPECIAL_FORMAT, dps, stats.Special);
                        }

                        list.Add(dps);
                    }
                }

                details = list.Count > 0 ? ", " + string.Join(", ", list) : "";
                title   = StatsUtil.FormatTitle(currentStats.TargetTitle, currentStats.TimeTitle, showTotals ? currentStats.TotalTitle : "");
            }

            return(new StatsSummary()
            {
                Title = title, RankedPlayers = details
            });
        }
Ejemplo n.º 14
0
        internal static CombinedStats ComputeOverlayStats(int mode, int maxRows, string selectedClass)
        {
            CombinedStats combined = null;

            var   allDamage    = 0L;
            var   allTime      = new TimeRange();
            var   playerTotals = new Dictionary <string, OverlayPlayerTotal>();
            var   playerHasPet = new Dictionary <string, bool>();
            var   updateTime   = 0d;
            var   oldestTime   = 0d;
            var   fights       = DataManager.Instance.GetOverlayFights();
            Fight oldestFight  = null;
            bool  baneEnabled  = MainWindow.IsBaneDamageEnabled;

            // clear out anything pending in the queue
            DamageLineParser.CheckSlainQueue(DateUtil.ToDouble(DateTime.Now.AddSeconds(-3)));

            if (fights.Count > 0)
            {
                oldestFight = fights[0];
                foreach (var fight in fights.Where(fight => !fight.Dead || mode > 0))
                {
                    foreach (var keypair in fight.PlayerTotals)
                    {
                        var player = keypair.Key;
                        if (!string.IsNullOrEmpty(keypair.Value.PetOwner))
                        {
                            player = keypair.Value.PetOwner;
                            playerHasPet[player] = true;
                        }
                        else if (PlayerManager.Instance.GetPlayerFromPet(player) is string owner && owner != Labels.UNASSIGNED)
                        {
                            player = owner;
                            playerHasPet[player] = true;
                        }

                        allDamage += baneEnabled ? keypair.Value.DamageWithBane : keypair.Value.Damage;
                        allTime.Add(new TimeSegment(keypair.Value.BeginTime, fight.LastDamageTime));

                        if (updateTime == 0)
                        {
                            updateTime  = keypair.Value.UpdateTime;
                            oldestTime  = keypair.Value.UpdateTime;
                            oldestFight = fight;
                        }
                        else
                        {
                            updateTime = Math.Max(updateTime, keypair.Value.UpdateTime);
                            if (oldestTime > keypair.Value.UpdateTime)
                            {
                                oldestTime  = keypair.Value.UpdateTime;
                                oldestFight = fight;
                            }
                        }

                        if (playerTotals.TryGetValue(player, out OverlayPlayerTotal total))
                        {
                            total.Damage += baneEnabled ? keypair.Value.DamageWithBane : keypair.Value.Damage;
                            total.Range.Add(new TimeSegment(keypair.Value.BeginTime, keypair.Value.UpdateTime));
                            total.UpdateTime = Math.Max(total.UpdateTime, keypair.Value.UpdateTime);
                        }
                        else
                        {
                            playerTotals[player] = new OverlayPlayerTotal
                            {
                                Name       = player,
                                Damage     = baneEnabled ? keypair.Value.DamageWithBane : keypair.Value.Damage,
                                Range      = new TimeRange(new TimeSegment(keypair.Value.BeginTime, keypair.Value.UpdateTime)),
                                UpdateTime = keypair.Value.UpdateTime
                            };
                        }
                    }
                }

                var timeout      = mode == 0 ? DataManager.FIGHTTIMEOUT : mode;
                var totalSeconds = allTime.GetTotal();
                if (oldestFight != null && totalSeconds > 0 && allDamage > 0 && (DateTime.Now - DateTime.MinValue.AddSeconds(updateTime)).TotalSeconds <= timeout)
                {
                    int rank     = 1;
                    var list     = new List <PlayerStats>();
                    var totalDps = (long)Math.Round(allDamage / totalSeconds, 2);
                    int myIndex  = -1;

                    foreach (var total in playerTotals.Values.OrderByDescending(total => total.Damage))
                    {
                        var time = total.Range.GetTotal();
                        if (time > 0 && (DateTime.Now - DateTime.MinValue.AddSeconds(total.UpdateTime)).TotalSeconds <= DataManager.MAXTIMEOUT)
                        {
                            PlayerStats playerStats = new PlayerStats()
                            {
                                Name         = playerHasPet.ContainsKey(total.Name) ? total.Name + " +Pets" : total.Name,
                                Total        = total.Damage,
                                DPS          = (long)Math.Round(total.Damage / time, 2),
                                TotalSeconds = time,
                                Rank         = (ushort)rank++,
                                ClassName    = PlayerManager.Instance.GetPlayerClass(total.Name),
                                OrigName     = total.Name
                            };

                            if (playerStats.Name.StartsWith(ConfigUtil.PlayerName, StringComparison.Ordinal))
                            {
                                myIndex = list.Count;
                            }

                            if (myIndex == list.Count || selectedClass == Properties.Resources.ANY_CLASS || selectedClass == playerStats.ClassName)
                            {
                                list.Add(playerStats);
                            }
                        }
                    }

                    if (myIndex > (maxRows - 1))
                    {
                        var me = list[myIndex];
                        list = list.Take(maxRows - 1).ToList();
                        list.Add(me);
                    }
                    else
                    {
                        list = list.Take(maxRows).ToList();
                    }

                    combined = new CombinedStats();
                    combined.StatsList.AddRange(list);
                    combined.RaidStats = new PlayerStats {
                        Total = allDamage, DPS = totalDps, TotalSeconds = totalSeconds
                    };
                    combined.TargetTitle = (fights.Count > 1 ? "C(" + fights.Count + "): " : "") + oldestFight.Name;

                    // these are here to support copy/paste of the parse
                    combined.TimeTitle  = string.Format(CultureInfo.CurrentCulture, StatsUtil.TIME_FORMAT, combined.RaidStats.TotalSeconds);
                    combined.TotalTitle = string.Format(CultureInfo.CurrentCulture, StatsUtil.TOTAL_FORMAT, StatsUtil.FormatTotals(combined.RaidStats.Total),
                                                        " Damage ", StatsUtil.FormatTotals(combined.RaidStats.DPS));
                }
            }

            return(combined);
        }
Ejemplo n.º 15
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);
                    }
                }
            }
        }
Ejemplo n.º 16
0
        internal HitLogViewer(CombinedStats currentStats, PlayerStats playerStats, List <List <ActionBlock> > groups, bool defending = false)
        {
            InitializeComponent();

            CurrentGroups = groups;
            Defending     = defending;
            PlayerStats   = playerStats;

            titleLabel.Content = currentStats?.ShortTitle;
            var view = CollectionViewSource.GetDefaultView(Records);

            view.Filter = new Predicate <object>(item =>
            {
                var record = (HitLogRow)item;
                return((string.IsNullOrEmpty(CurrentTypeFilter) || CurrentTypeFilter == record.Type) &&
                       (string.IsNullOrEmpty(CurrentActionFilter) || CurrentActionFilter == record.SubType) &&
                       (string.IsNullOrEmpty(CurrentActedFilter) || CurrentActedFilter == record.Acted) &&
                       (CurrentShowPetsFilter || !record.IsPet));
            });

            BindingOperations.EnableCollectionSynchronization(Records, CollectionLock);
            BindingOperations.EnableCollectionSynchronization(Actions, CollectionLock);
            BindingOperations.EnableCollectionSynchronization(Types, CollectionLock);

            var firstAction = groups?.First()?.First()?.Actions?.First();

            if (firstAction is DamageRecord && !defending)
            {
                ActedOption = "All Defenders";
                dataGrid.Columns[4].Header  = "Damage";
                dataGrid.Columns[10].Header = "Attacker";
                dataGrid.Columns[11].Header = "Defender";
                showPets.Visibility         = Visibility.Visible;
            }
            else if (firstAction is DamageRecord && defending)
            {
                ActedOption = "All Attackers";
                dataGrid.Columns[4].Header     = "Damage";
                dataGrid.Columns[7].Visibility = Visibility.Collapsed;
                dataGrid.Columns[8].Visibility = Visibility.Collapsed;
                dataGrid.Columns[9].Visibility = Visibility.Collapsed;
                dataGrid.Columns[10].Header    = "Defender";
                dataGrid.Columns[11].Header    = "Attacker";
                showPets.Visibility            = Visibility.Collapsed;
                petDivider.Visibility          = Visibility.Collapsed;
            }
            else if (firstAction is HealRecord)
            {
                ActedOption = "All Healed Players";
                dataGrid.Columns[4].Header     = "Heal";
                dataGrid.Columns[5].Visibility = Visibility.Visible;
                dataGrid.Columns[10].Header    = "Healer";
                dataGrid.Columns[11].Header    = "Healed";
                showPets.Visibility            = Visibility.Collapsed;
                petDivider.Visibility          = Visibility.Collapsed;
            }

            actionList.ItemsSource = Actions;
            typeList.ItemsSource   = Types;
            dataGrid.ItemsSource   = view;

            Actions.Add("All Actions");
            Types.Add("All Types");
            actionList.SelectedIndex = 0;
            typeList.SelectedIndex   = 0;

            Display(true);
        }
Ejemplo n.º 17
0
        private void UpdateTimerTick(object sender, EventArgs e)
        {
            lock (StatsLock)
            {
                try
                {
                    Topmost = true; // possible workaround

                    // people wanted shorter delays for damage updates but I don't want the indicator to change constantly
                    // so this limits it to 1/2 the current time value
                    ProcessDirection = !ProcessDirection;

                    Stats = DamageStatsManager.ComputeOverlayStats(CurrentDamageSelectionMode, CurrentMaxRows, SelectedClass);

                    if (Stats == null)
                    {
                        windowBrush.Opacity = 0.0;
                        ButtonPopup.IsOpen  = false;
                        SetVisible(false);
                        Height   = 0;
                        PrevList = null;
                        UpdateTimer.Stop();
                        DataManager.Instance.ResetOverlayFights();
                    }
                    else if (Active)
                    {
                        TitleBlock.Text       = Stats.TargetTitle;
                        TitleDamageBlock.Text = string.Format(CultureInfo.CurrentCulture, "{0} [{1}s @{2}]",
                                                              StatsUtil.FormatTotals(Stats.RaidStats.Total), Stats.RaidStats.TotalSeconds, StatsUtil.FormatTotals(Stats.RaidStats.DPS));

                        long total        = 0;
                        int  goodRowCount = 0;
                        long me           = 0;
                        var  topList      = new Dictionary <int, long>();
                        for (int i = 0; i < CurrentMaxRows; i++)
                        {
                            if (Stats.StatsList.Count > i)
                            {
                                if (ProcessDirection)
                                {
                                    DamageRateList[i].Opacity = 0.0;
                                }

                                if (i == 0)
                                {
                                    total = Stats.StatsList[i].Total;
                                    RectangleList[i].Width = Width;
                                }
                                else
                                {
                                    RectangleList[i].Visibility = Visibility.Hidden; // maybe it calculates width better
                                    RectangleList[i].Width      = Convert.ToDouble(Stats.StatsList[i].Total) / total * Width;
                                }

                                string playerName = ConfigUtil.PlayerName;
                                var    isMe       = !string.IsNullOrEmpty(playerName) && Stats.StatsList[i].Name.StartsWith(playerName, StringComparison.OrdinalIgnoreCase) &&
                                                    (playerName.Length >= Stats.StatsList[i].Name.Length || Stats.StatsList[i].Name[playerName.Length] == ' ');

                                string updateText;
                                if (IsHideOverlayOtherPlayersEnabled && !isMe)
                                {
                                    updateText             = string.Format(CultureInfo.CurrentCulture, "{0}. Hidden Player", Stats.StatsList[i].Rank);
                                    NameIconList[i].Source = PlayerManager.UNK_ICON;
                                }
                                else
                                {
                                    updateText             = string.Format(CultureInfo.CurrentCulture, "{0}. {1}", Stats.StatsList[i].Rank, Stats.StatsList[i].Name);
                                    NameIconList[i].Source = PlayerManager.Instance.GetPlayerIcon(Stats.StatsList[i].OrigName);
                                }

                                if (IsShowOverlayCritRateEnabled)
                                {
                                    List <string> critMods = new List <string>();

                                    if (isMe && PlayerManager.Instance.IsDoTClass(Stats.StatsList[i].ClassName) && DataManager.Instance.MyDoTCritRateMod is uint doTCritRate && doTCritRate > 0)
                                    {
                                        critMods.Add(string.Format(CultureInfo.CurrentCulture, "DoT CR +{0}", doTCritRate));
                                    }

                                    if (isMe && DataManager.Instance.MyNukeCritRateMod is uint nukeCritRate && nukeCritRate > 0)
                                    {
                                        critMods.Add(string.Format(CultureInfo.CurrentCulture, "Nuke CR +{0}", nukeCritRate));
                                    }

                                    if (critMods.Count > 0)
                                    {
                                        updateText = string.Format(CultureInfo.CurrentCulture, "{0} [{1}]", updateText, string.Join(", ", critMods));
                                    }
                                }

                                NameBlockList[i].Text = updateText;

                                if (i <= 4 && !isMe && Stats.StatsList[i].Total > 0)
                                {
                                    topList[i] = Stats.StatsList[i].Total;
                                }
                                else if (isMe)
                                {
                                    me = Stats.StatsList[i].Total;
                                }

                                var damage = StatsUtil.FormatTotals(Stats.StatsList[i].Total) + " [" + Stats.StatsList[i].TotalSeconds.ToString(CultureInfo.CurrentCulture)
                                             + "s @" + StatsUtil.FormatTotals(Stats.StatsList[i].DPS) + "]";
                                DamageBlockList[i].Text = damage;
                                goodRowCount++;
                            }
                        }

                        if (ProcessDirection)
                        {
                            if (me > 0 && topList.Count > 0)
                            {
                                var updatedList = new Dictionary <int, double>();
                                foreach (int i in topList.Keys)
                                {
                                    if (i != me)
                                    {
                                        var diff = topList[i] / (double)me;
                                        updatedList[i] = diff;
                                        if (PrevList != null && PrevList.ContainsKey(i))
                                        {
                                            if (PrevList[i] > diff)
                                            {
                                                DamageRateList[i].Icon       = FontAwesomeIcon.LongArrowDown;
                                                DamageRateList[i].Foreground = OverlayUtil.DOWNBRUSH;
                                                DamageRateList[i].Opacity    = OverlayUtil.DATA_OPACITY;
                                            }
                                            else if (PrevList[i] < diff)
                                            {
                                                DamageRateList[i].Icon       = FontAwesomeIcon.LongArrowUp;
                                                DamageRateList[i].Foreground = OverlayUtil.UPBRUSH;
                                                DamageRateList[i].Opacity    = OverlayUtil.DATA_OPACITY;
                                            }
                                        }
                                    }
                                }

                                PrevList = updatedList;
                            }
                            else
                            {
                                PrevList = null;
                            }
                        }

                        var requested = (goodRowCount + 1) * CalculatedRowHeight;
                        if (ActualHeight != requested)
                        {
                            Height = requested;
                        }

                        if (overlayCanvas.Visibility != Visibility.Visible)
                        {
                            overlayCanvas.Visibility    = Visibility.Hidden;
                            TitleRectangle.Visibility   = Visibility.Hidden;
                            TitlePanel.Visibility       = Visibility.Hidden;
                            TitleDamagePanel.Visibility = Visibility.Hidden;
                            TitleRectangle.Height       = CalculatedRowHeight;
                            TitleDamagePanel.Height     = CalculatedRowHeight;
                            TitlePanel.Height           = CalculatedRowHeight;
                            overlayCanvas.Visibility    = Visibility.Visible;
                            TitleRectangle.Visibility   = Visibility.Visible;
                            TitlePanel.Visibility       = Visibility.Visible;
                            TitleDamagePanel.Visibility = Visibility.Visible;
                            windowBrush.Opacity         = OverlayUtil.OPACITY;
                            ButtonPopup.IsOpen          = true;
                        }

                        for (int i = 0; i < CurrentMaxRows; i++)
                        {
                            SetRowVisible(i < goodRowCount, i);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LOG.Error("Overlay Error", ex);
                }
            }
        }
Ejemplo n.º 18
0
 public TankingBreakdown(CombinedStats currentStats)
 {
     InitializeComponent();
     titleLabel.Content = currentStats?.ShortTitle;
     RaidStats          = currentStats?.RaidStats;
 }
Ejemplo n.º 19
0
        internal void PopulateHealing(CombinedStats combined)
        {
            lock (HealingGroups)
            {
                List <PlayerStats> playerStats = combined.StatsList;
                Dictionary <string, PlayerStats> individualStats = new Dictionary <string, PlayerStats>();
                Dictionary <string, long>        totals          = new Dictionary <string, long>();

                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)
                            {
                                PlayerStats stats = StatsUtil.CreatePlayerStats(individualStats, record.Healed);
                                StatsUtil.UpdateStats(stats, record, block.BeginTime);
                                allStats[record.Healed] = stats;

                                PlayerSubStats subStats = StatsUtil.CreatePlayerSubStats(stats.SubStats, record.Healer, record.Type);
                                StatsUtil.UpdateStats(subStats, record, block.BeginTime);
                                allStats[record.Healer + "-" + record.Healed] = subStats;

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

                                long value = 0;
                                if (totals.ContainsKey(record.Healed))
                                {
                                    value = totals[record.Healed];
                                }

                                totals[record.Healed] = record.Total + value;
                            }
                        });
                    });

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


                Parallel.ForEach(playerStats, stat =>
                {
                    if (individualStats.ContainsKey(stat.Name))
                    {
                        if (totals.ContainsKey(stat.Name))
                        {
                            stat.Extra = totals[stat.Name];
                        }

                        var indStat = individualStats[stat.Name];
                        stat.SubStats2["receivedHealing"] = indStat;
                        StatsUtil.UpdateCalculations(indStat, RaidTotals);

                        indStat.SubStats.Values.ToList().ForEach(subStat => StatsUtil.UpdateCalculations(subStat, indStat));
                        indStat.SubStats2.Values.ToList().ForEach(subStat => StatsUtil.UpdateCalculations(subStat, indStat));
                    }
                });
            }
        }
Ejemplo n.º 20
0
        public GanttChart(CombinedStats currentStats, List <PlayerStats> selected, List <List <ActionBlock> > groups)
        {
            InitializeComponent();

            Selected  = selected;
            StartTime = groups.Min(group => group.First().BeginTime) - BUFFS_OFFSET;
            EndTime   = groups.Max(group => group.Last().BeginTime) + 1;
            Length    = EndTime - StartTime;

            switch (Selected.Count)
            {
            case 1:
                titleLabel1.Content = Selected[0].OrigName + "'s ADPS | " + currentStats?.ShortTitle;
                break;

            case 2:
                titleLabel1.Content = Selected[0].OrigName + " vs ";
                titleLabel2.Content = Selected[1].OrigName + "'s ";
                titleLabel3.Content = "ADPS | " + currentStats?.ShortTitle;
                break;
            }

            for (int i = 0; i < Selected.Count; i++)
            {
                var player     = Selected[i].OrigName;
                var spellClass = PlayerManager.Instance.GetPlayerClassEnum(player);

                DataManager.Instance.GetReceivedSpellsDuring(StartTime, EndTime).ForEach(group =>
                {
                    foreach (var action in group.Actions.Where(action => action is ReceivedSpell spell && spell.Receiver == player &&
                                                               spell.SpellData.Adps > 0 && (spell.SpellData.MaxHits > 0 || spell.SpellData.Duration <= 1800)))
                    {
                        var received  = action as ReceivedSpell;
                        var spellData = received.SpellData;

                        if (DataManager.Instance.CheckForSpellAmbiguity(spellData, spellClass, out SpellData replaced))
                        {
                            spellData = replaced;
                        }

                        var spellName = spellData.NameAbbrv;

                        if (string.IsNullOrEmpty(spellData.LandsOnOther))
                        {
                            SelfOnly[spellName] = 1;
                        }

                        if (!SpellRanges.TryGetValue(spellName, out SpellRange spellRange))
                        {
                            spellRange = new SpellRange()
                            {
                                Adps = spellData.Adps
                            };
                            var duration = GetDuration(spellData, EndTime, group.BeginTime);
                            spellRange.Ranges.Add(new TimeRange()
                            {
                                BlockBrush = BlockBrushes[i], BeginSeconds = (int)(group.BeginTime - StartTime), Duration = duration
                            });
                            SpellRanges[spellName] = spellRange;
                        }
                        else
                        {
                            var last          = spellRange.Ranges.LastOrDefault(range => range.BlockBrush == BlockBrushes[i]);
                            var offsetSeconds = (int)(group.BeginTime - StartTime);
                            if (last != null && offsetSeconds >= last.BeginSeconds && offsetSeconds <= (last.BeginSeconds + last.Duration))
                            {
                                last.Duration = GetDuration(spellData, EndTime, group.BeginTime) + (offsetSeconds - last.BeginSeconds);
                            }
                            else
                            {
                                var duration = GetDuration(spellData, EndTime, group.BeginTime);
                                spellRange.Ranges.Add(new TimeRange()
                                {
                                    BlockBrush = BlockBrushes[i], BeginSeconds = (int)(group.BeginTime - StartTime), Duration = duration
                                });
                            }
                        }
                    }
                });
            }

            showSelfOnly.IsEnabled = showCasterAdps.IsEnabled = showMeleeAdps.IsEnabled = SpellRanges.Count > 0;

            addHeaderLabel(0, "Buffs (T-90)", 20);
            addHeaderLabel(BUFFS_OFFSET, DateUtil.FormatSimpleTime(StartTime), 10);

            int minutes = 1;

            for (int more = (int)(BUFFS_OFFSET + 60); more < Length; more += 60)
            {
                addHeaderLabel(more, minutes + "m", 0);
                minutes++;
            }

            Display();
        }
Ejemplo n.º 21
0
        internal Dictionary <string, List <HitFreqChartData> > GetHitFreqValues(PlayerStats selected, CombinedStats damageStats)
        {
            Dictionary <string, List <HitFreqChartData> > results = new Dictionary <string, List <HitFreqChartData> >();

            // get chart data for player and pets if available
            if (damageStats?.Children.ContainsKey(selected.Name) == true)
            {
                damageStats?.Children[selected.Name].ForEach(stats => AddStats(stats));
            }
            else
            {
                AddStats(selected);
            }

            return(results);

            void AddStats(PlayerStats stats)
            {
                results[stats.Name] = new List <HitFreqChartData>();
                foreach (string type in stats.SubStats.Keys)
                {
                    HitFreqChartData chartData = new HitFreqChartData()
                    {
                        HitType = stats.SubStats[type].Name
                    };

                    // add crits
                    chartData.CritXValues.AddRange(stats.SubStats[type].CritFreqValues.Keys.OrderBy(key => key));
                    chartData.CritXValues.ForEach(damage => chartData.CritYValues.Add(stats.SubStats[type].CritFreqValues[damage]));

                    // add non crits
                    chartData.NonCritXValues.AddRange(stats.SubStats[type].NonCritFreqValues.Keys.OrderBy(key => key));
                    chartData.NonCritXValues.ForEach(damage => chartData.NonCritYValues.Add(stats.SubStats[type].NonCritFreqValues[damage]));
                    results[stats.Name].Add(chartData);
                }
            }
        }
Ejemplo n.º 22
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);
                                                }
                                            }
                                        }
                                    });
                                });
                            });
Ejemplo n.º 23
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);
                }
            }
        }
Ejemplo n.º 24
0
 internal void AddAndCopyDamageParse(CombinedStats combined, List <PlayerStats> selected)
 {
     (playerParseTextWindow.Content as ParsePreview)?.AddParse(Labels.DAMAGEPARSE, DamageStatsManager.Instance, combined, selected, true);
 }
Ejemplo n.º 25
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);
                    }
                }
            }
        }
Ejemplo n.º 26
0
        internal GanttChart(CombinedStats currentStats, List <PlayerStats> selected, List <List <ActionBlock> > groups, bool tanking = false)
        {
            InitializeComponent();

            if (selected != null && selected.Count > 0)
            {
                TankingMode = tanking;
                Selected    = selected;
                StartTime   = groups.Min(block => block.First().BeginTime) - DataManager.BUFFS_OFFSET;
                EndTime     = groups.Max(block => block.Last().BeginTime) + 1;
                Length      = EndTime - StartTime;

                string type = TankingMode ? "Defensive Skills" : "ADPS";
                switch (Selected.Count)
                {
                case 1:
                    titleLabel1.Content = Selected[0].OrigName + "'s " + type + " | " + currentStats?.ShortTitle;
                    break;

                case 2:
                    titleLabel1.Content = Selected[0].OrigName + " vs ";
                    titleLabel2.Content = Selected[1].OrigName + "'s ";
                    titleLabel3.Content = type + " | " + currentStats?.ShortTitle;
                    break;
                }

                if (tanking)
                {
                    showSelfOnly.Visibility   = Visibility.Hidden;
                    showMeleeAdps.Visibility  = Visibility.Hidden;
                    showCasterAdps.Visibility = Visibility.Hidden;
                }

                for (int i = 0; i < Selected.Count; i++)
                {
                    var player    = Selected[i].OrigName;
                    var allSpells = new List <ActionBlock>();
                    allSpells.AddRange(DataManager.Instance.GetCastsDuring(StartTime, EndTime));
                    allSpells.AddRange(DataManager.Instance.GetReceivedSpellsDuring(StartTime, EndTime));

                    foreach (var block in allSpells.OrderBy(block => block.BeginTime).ThenBy(block => (block.Actions.Count > 0 && block.Actions[0] is ReceivedSpell) ? 1 : -1))
                    {
                        foreach (var action in block.Actions)
                        {
                            if (action is SpellCast cast && !cast.Interrupted && cast.Caster == player && cast.SpellData != null && cast.SpellData.Target == (int)SpellTarget.SELF &&
                                cast.SpellData.Adps > 0 && (cast.SpellData.MaxHits > 0 || cast.SpellData.Duration <= 1800) && ClassFilter(cast.SpellData))
                            {
                                if (string.IsNullOrEmpty(cast.SpellData.LandsOnOther))
                                {
                                    SelfOnlyOverride[cast.SpellData.NameAbbrv] = 1;

                                    if (SelfOnly.ContainsKey(cast.SpellData.NameAbbrv))
                                    {
                                        SelfOnly.Remove(cast.SpellData.NameAbbrv);
                                    }
                                }

                                UpdateSpellRange(cast.SpellData, block.BeginTime, BlockBrushes[i]);
                            }
                            else if (action is ReceivedSpell received && received.Receiver == player)
                            {
                                var spellData = received.SpellData;

                                if (spellData == null && received.Ambiguity.Count > 0 && DataManager.ResolveSpellAmbiguity(received, out SpellData replaced))
                                {
                                    spellData = replaced;
                                }

                                if (spellData != null && spellData.Adps > 0 && (spellData.MaxHits > 0 || spellData.Duration <= 1800) && ClassFilter(spellData))
                                {
                                    if (string.IsNullOrEmpty(spellData.LandsOnOther) && !SelfOnlyOverride.ContainsKey(spellData.NameAbbrv))
                                    {
                                        SelfOnly[spellData.NameAbbrv] = 1;
                                    }

                                    UpdateSpellRange(spellData, block.BeginTime, BlockBrushes[i]);
                                }
                            }
                        }
Ejemplo n.º 27
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);
                }
            }
        }