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; }
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; }