Inheritance: PropertyObservable
        public SkillBreakdownViewModel(PlayerInfo playerInfo)
        {
            ComboBoxEntities = CollectionHelper.Instance.CreateSyncedCollection(new []
            {
                new ComboBoxEntity(SkillViewType.FlatView, "Flat View"),
                new ComboBoxEntity(SkillViewType.AggregatedSkillIdView, "Aggregate by Id"),
                new ComboBoxEntity(SkillViewType.AggregatedSkillNameView, "Aggregate by Name")
            });

            //NOTE: These are duplicated in the xaml because of a wpf bug
            SortDescriptionMappings = new Dictionary<SkillViewType, IList<SortDescription>>
            {
                {
                    SkillViewType.FlatView,
                    new List<SortDescription>
                    {
                        new SortDescription(nameof(SkillResult.Time), ListSortDirection.Ascending)
                    }

                },
                {
                    SkillViewType.AggregatedSkillIdView,
                    new List<SortDescription>
                    {
                        new SortDescription(nameof(AggregatedSkillResult.Amount), ListSortDirection.Descending)
                    }
                },
                {
                    SkillViewType.AggregatedSkillNameView,
                    new List<SortDescription>
                    {
                        new SortDescription(nameof(AggregatedSkillResult.Amount), ListSortDirection.Descending)
                    }
                }
            };

            //set the intial view
            var initialView = SkillViewType.AggregatedSkillNameView;
            SortDescriptionSource = SortDescriptionMappings[initialView];
            SelectedCollectionView = ComboBoxEntities.First(cbe => cbe.Key == initialView);

            PlayerInfo = playerInfo;
            SkillLog = PlayerInfo.SkillLog;

            //subscribe to future changes and invoke manually
            SkillLog.CollectionChanged += (sender, args) =>
            {
                UpdateAggregatedSkillLogs(args.NewItems.Cast<SkillResult>());
                CasualMessenger.Instance.Messenger.Send(new ScrollPlayerStatsMessage(), this);
            };

            UpdateAggregatedSkillLogs(SkillLog);
        }
        public PlayerStatsFormatter(PlayerInfo playerInfo, TeraData teraData, FormatHelpers formatHelpers)
        {
            var placeHolders = new List<KeyValuePair<string, object>>();
            placeHolders.Add(new KeyValuePair<string, object>("FullName", playerInfo.FullName));
            placeHolders.Add(new KeyValuePair<string, object>("Name", playerInfo.Name));
            placeHolders.Add(new KeyValuePair<string, object>("Class", playerInfo.Class));

            placeHolders.Add(new KeyValuePair<string, object>("Crits", playerInfo.Dealt.Crits));
            placeHolders.Add(new KeyValuePair<string, object>("Hits", playerInfo.Dealt.Hits));

            placeHolders.Add(new KeyValuePair<string, object>("DamagePercent", formatHelpers.FormatPercent(playerInfo.Dealt.DamageFraction) ?? "NaN"));
            placeHolders.Add(new KeyValuePair<string, object>("CritPercent", formatHelpers.FormatPercent((double)playerInfo.Dealt.Crits / playerInfo.Dealt.Hits) ?? "NaN"));

            placeHolders.Add(new KeyValuePair<string, object>("Damage", formatHelpers.FormatValue(playerInfo.Dealt.Damage)));
            placeHolders.Add(new KeyValuePair<string, object>("DamageReceived", formatHelpers.FormatValue(playerInfo.Received.Damage)));
            placeHolders.Add(new KeyValuePair<string, object>("DPS", $"{formatHelpers.FormatValue(SettingsHelper.Instance.Settings.ShowPersonalDps ? playerInfo.Dealt.PersonalDps : playerInfo.Dealt.Dps)}/s"));

            var lastTick = playerInfo.Tracker.LastAttack?.Ticks ?? 0;
            var firstTick = playerInfo.Tracker.FirstAttack?.Ticks ?? 0;
            var slayingstr = "";
            var death = "";
            var deathDur = "";
            if (lastTick > firstTick && firstTick > 0)
            {
                var buffs = playerInfo.Tracker.Abnormals.Get(playerInfo.Player);
                AbnormalityDuration slaying;
                buffs.Times.TryGetValue(teraData.HotDotDatabase.Get(8888889), out slaying);
                double slayingperc = (double) (slaying?.Duration(firstTick, lastTick) ?? 0)/(lastTick - firstTick);
                slayingstr = formatHelpers.FormatPercent(slayingperc);
                death = buffs.Death.Count(firstTick, lastTick).ToString();
                deathDur = formatHelpers.FormatTimeSpan(TimeSpan.FromTicks(buffs.Death.Duration(firstTick, lastTick)));
            }
            placeHolders.Add(new KeyValuePair<string, object>("Death", death));
            placeHolders.Add(new KeyValuePair<string, object>("DeathDuration", deathDur));
            placeHolders.Add(new KeyValuePair<string, object>("Slaying", slayingstr));

            Placeholders = placeHolders.ToDictionary(x => x.Key, y => y.Value);
            FormatProvider = formatHelpers.CultureInfo;
        }
Example #3
0
        private PlayerInfo GetOrCreate(SkillResult skillResult)
        {
            NpcEntity npctarget = skillResult.Target as NpcEntity;

            //ignore pvp if onlybosses is ticked
            if (OnlyBosses && npctarget == null && IsValidAttack(skillResult)) return null;

            if (npctarget != null)
            {
                if (OnlyBosses)//not count bosses
                    if (!npctarget.Info.Boss)
                        return null;
                if (IgnoreOneshots)
                    if ((npctarget.Info.HP>0)
                        //ignore damage that is more than 10x times than mob's hp
                        && (    npctarget.Info.HP <= skillResult.Damage/10
                        //ignore damage over 100m on a boss
                            ||  (npctarget.Info.Boss && skillResult.Damage > 99999999)))
                        return null;
            }
            var player = skillResult.SourcePlayer;
            PlayerInfo playerStats = StatsByUser.FirstOrDefault(pi => pi.Player.Equals(player));
            if (playerStats == null && (IsFromHealer(skillResult) ||//either healer
               (!IsFromHealer(skillResult) && IsValidAttack(skillResult))))//or damage from non-healer
            {
                playerStats = new PlayerInfo(player, this);
                StatsByUser.Add(playerStats);
            }

            //update primary target if it's a mob
            if (npctarget != null)
            {
                if (!_targetHitCount.ContainsKey(npctarget))
                    _targetHitCount.Add(npctarget, 0);
                _targetHitCount[npctarget]++;

                PrimaryTarget = _targetHitCount.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;
            }
            return playerStats;
        }