Exemple #1
0
        private void AddRow(SpellDamageStats stats, string type)
        {
            var row = new ExpandoObject() as IDictionary <string, object>;

            row["Caster"] = stats.Caster;
            row["Spell"]  = stats.Spell;
            row["Max"]    = stats.Max;
            row["Hits"]   = stats.Count;
            row["Avg"]    = stats.Total / stats.Count;
            row["Total"]  = stats.Total;
            row["Type"]   = type;

            lock (LockObject)
            {
                Records.Add(row);
            }
        }
Exemple #2
0
        private void Load()
        {
            string selectedSpell  = spellList.SelectedItem as string;
            string selectedPlayer = playerList.SelectedItem as string;
            bool   isPlayerOnly   = showPlayers.IsChecked.Value;

            Records.Clear();
            Spells.Clear();
            Spells.Add("All Spells");
            Players.Clear();
            Players.Add("All Casters");

            var playerDDTotals  = new Dictionary <string, SpellDamageStats>();
            var playerDoTTotals = new Dictionary <string, SpellDamageStats>();
            var uniqueSpells    = new Dictionary <string, byte>();
            var uniquePlayers   = new Dictionary <string, byte>();

            var fights = fightOption.SelectedIndex == 0 ? (Application.Current.MainWindow as MainWindow).GetFightTable()?.GetFights() :
                         (Application.Current.MainWindow as MainWindow).GetFightTable()?.GetSelectedFights();

            foreach (var fight in fights)
            {
                foreach (var kv in fight.DDDamage)
                {
                    if (!isPlayerOnly || PlayerManager.Instance.IsVerifiedPlayer(kv.Value.Caster))
                    {
                        if (!playerDDTotals.TryGetValue(kv.Key, out SpellDamageStats ddStats))
                        {
                            ddStats = new SpellDamageStats {
                                Caster = kv.Value.Caster, Spell = kv.Value.Spell
                            };
                            playerDDTotals[kv.Key]         = ddStats;
                            uniqueSpells[kv.Value.Spell]   = 1;
                            uniquePlayers[kv.Value.Caster] = 1;
                        }

                        ddStats.Max    = Math.Max(ddStats.Max, kv.Value.Max);
                        ddStats.Total += kv.Value.Total;
                        ddStats.Count += kv.Value.Count;
                    }
                }

                foreach (var kv in fight.DoTDamage)
                {
                    if (!isPlayerOnly || PlayerManager.Instance.IsVerifiedPlayer(kv.Value.Caster))
                    {
                        if (!playerDoTTotals.TryGetValue(kv.Key, out SpellDamageStats dotStats))
                        {
                            dotStats = new SpellDamageStats {
                                Caster = kv.Value.Caster, Spell = kv.Value.Spell
                            };
                            playerDoTTotals[kv.Key]        = dotStats;
                            uniqueSpells[kv.Value.Spell]   = 1;
                            uniquePlayers[kv.Value.Caster] = 1;
                        }

                        dotStats.Max    = Math.Max(dotStats.Max, kv.Value.Max);
                        dotStats.Total += kv.Value.Total;
                        dotStats.Count += kv.Value.Count;
                    }
                }
            }

            foreach (var stats in playerDoTTotals.Values)
            {
                AddRow(stats, Labels.DOT);
            }

            foreach (var stats in playerDDTotals.Values)
            {
                AddRow(stats, Labels.DD);
            }

            foreach (var key in uniqueSpells.Keys.OrderBy(k => k, StringComparer.Create(new CultureInfo("en-US"), true)))
            {
                Spells.Add(key);
            }

            foreach (var key in uniquePlayers.Keys.OrderBy(k => k, StringComparer.Create(new CultureInfo("en-US"), true)))
            {
                Players.Add(key);
            }

            spellList.SelectedIndex  = (Spells.IndexOf(selectedSpell) is int s && s > -1) ? s : 0;
            playerList.SelectedIndex = (Players.IndexOf(selectedPlayer) is int p && p > -1) ? p : 0;

            if (dataGrid.ItemsSource is ListCollectionView view)
            {
                view.SortDescriptions.Clear();
                view.SortDescriptions.Add(new SortDescription("Avg", ListSortDirection.Descending));
            }

            titleLabel.Content = Records.Count == 0 ? NODATA : "Spell Damage Stats for " + uniqueSpells.Count + " Unique Spells";
        }
Exemple #3
0
        private void HandleDamageProcessed(object sender, DamageProcessedEvent processed)
        {
            if (LastFightProcessTime != processed.BeginTime)
            {
                DataManager.Instance.CheckExpireFights(processed.BeginTime);
                ValidCombo.Clear();

                if (processed.BeginTime - LastFightProcessTime > RECENTSPELLTIME)
                {
                    RecentSpellCache.Clear();
                }
            }

            // cache recent player spells to help determine who the caster was
            var isAttackerPlayer = PlayerManager.Instance.IsPetOrPlayer(processed.Record.Attacker) || processed.Record.Attacker == Labels.RS;

            if (isAttackerPlayer && (processed.Record.Type == Labels.DD || processed.Record.Type == Labels.DOT || processed.Record.Type == Labels.PROC))
            {
                RecentSpellCache[processed.Record.SubType] = true;
            }

            string comboKey = processed.Record.Attacker + "=" + processed.Record.Defender;

            if (ValidCombo.TryGetValue(comboKey, out bool defender) || IsValidAttack(processed.Record, isAttackerPlayer, out defender))
            {
                ValidCombo[comboKey] = defender;
                bool   isNonTankingFight = false;
                string origTimeString    = processed.OrigTimeString.Substring(4, 15);

                // fix for unknown spells having a good name to work from
                if (processed.Record.AttackerIsSpell && defender)
                {
                    processed.Record.Attacker = Labels.UNK;
                }

                Fight fight = Get(processed.Record, processed.BeginTime, origTimeString, defender);

                if (defender)
                {
                    Helpers.AddAction(fight.DamageBlocks, processed.Record, processed.BeginTime);
                    AddPlayerTime(fight, processed.Record, processed.Record.Attacker, processed.BeginTime);
                    fight.BeginDamageTime = double.IsNaN(fight.BeginDamageTime) ? processed.BeginTime : fight.BeginDamageTime;
                    fight.LastDamageTime  = processed.BeginTime;

                    if (StatsUtil.IsHitType(processed.Record.Type))
                    {
                        fight.DamageHits++;
                        fight.Total      += processed.Record.Total;
                        isNonTankingFight = fight.DamageHits == 1;

                        var attacker = processed.Record.AttackerOwner ?? processed.Record.Attacker;
                        if (fight.PlayerTotals.TryGetValue(attacker, out FightTotalDamage total))
                        {
                            total.Damage         += (processed.Record.Type == Labels.BANE) ? 0 : processed.Record.Total;
                            total.DamageWithBane += processed.Record.Total;
                            total.Name            = processed.Record.Attacker;
                            total.PetOwner        = total.PetOwner ?? processed.Record.AttackerOwner;
                            total.UpdateTime      = processed.BeginTime;
                        }
                        else
                        {
                            fight.PlayerTotals[attacker] = new FightTotalDamage
                            {
                                Damage         = (processed.Record.Type == Labels.BANE) ? 0 : processed.Record.Total,
                                DamageWithBane = processed.Record.Total,
                                Name           = processed.Record.Attacker,
                                PetOwner       = processed.Record.AttackerOwner,
                                UpdateTime     = processed.BeginTime,
                                BeginTime      = processed.BeginTime
                            };
                        }

                        SpellDamageStats stats = null;
                        var spellKey           = processed.Record.Attacker + "++" + processed.Record.SubType;
                        if (processed.Record.Type == Labels.DD)
                        {
                            if (!fight.DDDamage.TryGetValue(spellKey, out stats))
                            {
                                stats = new SpellDamageStats {
                                    Caster = processed.Record.Attacker, Spell = processed.Record.SubType
                                };
                                fight.DDDamage[spellKey] = stats;
                            }
                        }
                        else if (processed.Record.Type == Labels.DOT)
                        {
                            if (!fight.DoTDamage.TryGetValue(spellKey, out stats))
                            {
                                stats = new SpellDamageStats {
                                    Caster = processed.Record.Attacker, Spell = processed.Record.SubType
                                };
                                fight.DoTDamage[spellKey] = stats;
                            }
                        }

                        if (stats != null)
                        {
                            stats.Count += 1;
                            stats.Max    = Math.Max(processed.Record.Total, stats.Max);
                            stats.Total += processed.Record.Total;
                        }

                        // only a pet can 'hit' with a Flurry since players only crush/slash/punch/pierce with main hand weapons
                        if (processed.Record.AttackerOwner == null && processed.Record.Type == Labels.MELEE && processed.Record.SubType == "Hits" &&
                            LineModifiersParser.IsFlurry(processed.Record.ModifiersMask))
                        {
                            PlayerManager.Instance.AddVerifiedPet(processed.Record.Attacker);
                        }
                    }
                }
                else
                {
                    Helpers.AddAction(fight.TankingBlocks, processed.Record, processed.BeginTime);
                    AddPlayerTime(fight, processed.Record, processed.Record.Defender, processed.BeginTime);
                    fight.BeginTankingTime = double.IsNaN(fight.BeginTankingTime) ? processed.BeginTime : fight.BeginTankingTime;
                    fight.LastTankingTime  = processed.BeginTime;

                    if (StatsUtil.IsHitType(processed.Record.Type))
                    {
                        fight.TankHits++;
                    }
                }

                fight.LastTime       = processed.BeginTime;
                LastFightProcessTime = processed.BeginTime;

                var ttl = fight.LastTime - fight.BeginTime + 1;
                fight.TooltipText = string.Format(CultureInfo.CurrentCulture, "#Hits To Players: {0}, #Hits From Players: {1}, Time Alive: {2}s", fight.TankHits, fight.DamageHits, ttl);

                DataManager.Instance.UpdateIfNewFightMap(fight.CorrectMapKey, fight, isNonTankingFight);
            }
        }