protected override void InitAdditionalCombatReplayData(ParsedEvtcLog log) { log.FightData.Logic.ComputeNPCCombatReplayActors(this, log, CombatReplay); if (CombatReplay.Rotations.Any() && (log.FightData.Logic.TargetAgents.Contains(AgentItem) || log.FriendlyAgents.Contains(AgentItem))) { CombatReplay.Decorations.Add(new FacingDecoration(((int)CombatReplay.TimeOffsets.start, (int)CombatReplay.TimeOffsets.end), new AgentConnector(this), CombatReplay.PolledRotations)); } // Don't put minions of NPC into the minion display system AgentItem master = AgentItem.GetFinalMaster(); if (master != AgentItem && master.IsPlayer) { AbstractSingleActor masterActor = log.FindActor(master); // Basic linkage CombatReplay.Decorations.Add(new LineDecoration(0, ((int)CombatReplay.TimeOffsets.start, (int)CombatReplay.TimeOffsets.end), "rgba(0, 255, 0, 0.5)", new AgentConnector(this), new AgentConnector(masterActor))); // Prof specific treatment ProfHelper.ComputeMinionCombatReplayActors(this, masterActor, log, CombatReplay); } }
internal override void CheckMechanic(ParsedEvtcLog log, Dictionary <Mechanic, List <MechanicEvent> > mechanicLogs, Dictionary <int, AbstractSingleActor> regroupedMobs) { foreach (AgentItem a in log.AgentData.GetNPCsByID((int)SkillId)) { if (!regroupedMobs.TryGetValue(a.ID, out AbstractSingleActor amp)) { amp = log.FindActor(a, false); if (amp == null) { continue; } regroupedMobs.Add(amp.ID, amp); } foreach (DeadEvent devt in log.CombatData.GetDeadEvents(a)) { mechanicLogs[this].Add(new MechanicEvent(devt.Time, this, amp)); } } }
internal override void CheckMechanic(ParsedEvtcLog log, Dictionary <Mechanic, List <MechanicEvent> > mechanicLogs, Dictionary <int, AbstractSingleActor> regroupedMobs) { foreach (AbstractDamageEvent c in log.CombatData.GetDamageData(SkillId)) { AbstractSingleActor amp = null; if (Keep(c, log)) { if (!regroupedMobs.TryGetValue(c.From.ID, out amp)) { amp = log.FindActor(c.From, false); if (amp == null) { continue; } regroupedMobs.Add(amp.ID, amp); } } if (amp != null) { mechanicLogs[this].Add(new MechanicEvent(c.Time, this, amp)); } } }
internal override void CheckMechanic(ParsedEvtcLog log, Dictionary <Mechanic, List <MechanicEvent> > mechanicLogs, Dictionary <int, AbstractSingleActor> regroupedMobs) { foreach (AbstractBuffEvent c in log.CombatData.GetBuffData(SkillId)) { AbstractSingleActor amp = null; if (c is BuffRemoveAllEvent rea && Keep(rea, log)) { if (!regroupedMobs.TryGetValue(rea.To.ID, out amp)) { amp = log.FindActor(rea.To, true); if (amp == null) { continue; } regroupedMobs.Add(amp.ID, amp); } } if (amp != null) { mechanicLogs[this].Add(new MechanicEvent(c.Time, this, amp)); } } }
internal static void ComputeProfessionCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay) { return; IReadOnlyList <EffectEvent> tst = log.CombatData.GetEffectEvents(); IReadOnlyList <EffectEvent> tst1 = log.CombatData.GetEffectEventsByDst(p.AgentItem); var effectGUIDs1 = tst1.Select(x => log.CombatData.GetEffectGUIDEvent(x.EffectID).ContentGUID).ToList(); IReadOnlyList <EffectEvent> tst2 = log.CombatData.GetEffectEvents(p.AgentItem); var effectGUIDs2 = tst2.Select(x => log.CombatData.GetEffectGUIDEvent(x.EffectID).ContentGUID).ToList(); foreach (EffectEvent effectEvt in tst) { if (effectEvt.IsAroundDst) { replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new AgentConnector(log.FindActor(effectEvt.Dst)))); } else { replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new PositionConnector(effectEvt.Position))); } } }
public static JsonLog BuildJsonLog(ParsedEvtcLog log, RawFormatSettings settings, Version parserVersion, string[] uploadLinks) { var jsonLog = new JsonLog(); // log.UpdateProgressWithCancellationCheck("Raw Format: Building Meta Data"); jsonLog.TriggerID = log.FightData.TriggerID; jsonLog.FightName = log.FightData.FightName; jsonLog.FightIcon = log.FightData.Logic.Icon; jsonLog.EliteInsightsVersion = parserVersion.ToString(); jsonLog.ArcVersion = log.LogData.ArcVersion; jsonLog.RecordedBy = log.LogData.PoVName; jsonLog.TimeStart = log.LogData.LogStart; jsonLog.TimeEnd = log.LogData.LogEnd; jsonLog.TimeStartStd = log.LogData.LogStartStd; jsonLog.TimeEndStd = log.LogData.LogEndStd; jsonLog.Duration = log.FightData.DurationString; jsonLog.Success = log.FightData.Success; jsonLog.GW2Build = log.LogData.GW2Build; jsonLog.UploadLinks = uploadLinks; jsonLog.Language = log.LogData.Language; jsonLog.LanguageID = (byte)log.LogData.LanguageID; jsonLog.IsCM = log.FightData.IsCM; var personalBuffs = new Dictionary <string, HashSet <long> >(); var skillMap = new Dictionary <string, SkillDesc>(); var buffMap = new Dictionary <string, BuffDesc>(); var damageModMap = new Dictionary <string, DamageModDesc>(); if (log.StatisticsHelper.PresentFractalInstabilities.Any()) { var presentFractalInstabilities = new List <long>(); foreach (Buff fractalInstab in log.StatisticsHelper.PresentFractalInstabilities) { presentFractalInstabilities.Add(fractalInstab.ID); if (!buffMap.ContainsKey("b" + fractalInstab.ID)) { buffMap["b" + fractalInstab.ID] = BuildBuffDesc(fractalInstab, log); } } jsonLog.PresentFractalInstabilities = presentFractalInstabilities; } // log.UpdateProgressWithCancellationCheck("Raw Format: Building Mechanics"); MechanicData mechanicData = log.MechanicData; var mechanicLogs = new List <MechanicEvent>(); foreach (List <MechanicEvent> mLog in mechanicData.GetAllMechanics(log)) { mechanicLogs.AddRange(mLog); } if (mechanicLogs.Any()) { jsonLog.Mechanics = JsonMechanicsBuilder.GetJsonMechanicsList(mechanicLogs); } // log.UpdateProgressWithCancellationCheck("Raw Format: Building Phases"); jsonLog.Phases = log.FightData.GetNonDummyPhases(log).Select(x => JsonPhaseBuilder.BuildJsonPhase(x, log)).ToList(); // log.UpdateProgressWithCancellationCheck("Raw Format: Building Targets"); jsonLog.Targets = log.FightData.Logic.Targets.Select(x => JsonNPCBuilder.BuildJsonNPC(x, log, settings, skillMap, buffMap)).ToList(); // log.UpdateProgressWithCancellationCheck("Raw Format: Building Players"); jsonLog.Players = log.Friendlies.Select(x => JsonPlayerBuilder.BuildJsonPlayer(x, log, settings, skillMap, buffMap, damageModMap, personalBuffs)).ToList(); // if (log.LogData.LogErrors.Any()) { jsonLog.LogErrors = new List <string>(log.LogData.LogErrors); } if (log.LogData.UsedExtensions.Any()) { var usedExtensions = new List <ExtensionDesc>(); foreach (AbstractExtensionHandler extension in log.LogData.UsedExtensions) { var set = new HashSet <string>(); if (log.LogData.PoV != null) { set.Add(log.FindActor(log.LogData.PoV).Character); foreach (AgentItem agent in extension.RunningExtension) { set.Add(log.FindActor(agent).Character); } } usedExtensions.Add(new ExtensionDesc() { Name = extension.Name, Version = extension.Version, Signature = extension.Signature, Revision = extension.Revision, RunningExtension = set.ToList() }); } jsonLog.UsedExtensions = usedExtensions; } // jsonLog.PersonalBuffs = personalBuffs.ToDictionary(x => x.Key, x => (IReadOnlyCollection <long>)x.Value); jsonLog.SkillMap = skillMap; jsonLog.BuffMap = buffMap; jsonLog.DamageModMap = damageModMap; // if (log.CanCombatReplay) { jsonLog.CombatReplayMetaData = JsonCombatReplayMetaDataBuilder.BuildJsonCombatReplayMetaData(log, settings); } return(jsonLog); }
public IReadOnlyDictionary <string, DamageModifierStat> GetDamageModifierStats(AbstractSingleActor target, ParsedEvtcLog log, long start, long end) { if (!log.ParserSettings.ComputeDamageModifiers || Actor.IsFakeActor) { return(new Dictionary <string, DamageModifierStat>()); } if (_damageModifiersPerTargets == null) { _damageModifiersPerTargets = new CachingCollectionWithTarget <Dictionary <string, DamageModifierStat> >(log); _damageModifierEventsPerTargets = new CachingCollectionWithTarget <Dictionary <string, List <DamageModifierEvent> > >(log); } if (_damageModifiersPerTargets.TryGetValue(start, end, target, out Dictionary <string, DamageModifierStat> res)) { return(res); } res = ComputeDamageModifierStats(target, log, start, end); if (res != null) { return(res); } // var damageMods = new List <DamageModifier>(); if (log.DamageModifiers.DamageModifiersPerSource.TryGetValue(Source.Item, out IReadOnlyList <DamageModifier> list)) { damageMods.AddRange(list); } if (log.DamageModifiers.DamageModifiersPerSource.TryGetValue(Source.Gear, out list)) { damageMods.AddRange(list); } if (log.DamageModifiers.DamageModifiersPerSource.TryGetValue(Source.Common, out list)) { damageMods.AddRange(list); } if (log.DamageModifiers.DamageModifiersPerSource.TryGetValue(Source.FightSpecific, out list)) { damageMods.AddRange(list); } damageMods.AddRange(log.DamageModifiers.GetModifiersPerSpec(Actor.Spec)); // var damageModifierEvents = new List <DamageModifierEvent>(); foreach (DamageModifier damageMod in damageMods) { damageModifierEvents.AddRange(damageMod.ComputeDamageModifier(Actor, log)); } damageModifierEvents.Sort((x, y) => x.Time.CompareTo(y.Time)); var damageModifiersEvents = damageModifierEvents.GroupBy(y => y.DamageModifier.Name).ToDictionary(y => y.Key, y => y.ToList()); _damageModifierEventsPerTargets.Set(0, log.FightData.FightEnd, null, damageModifiersEvents); var damageModifiersEventsByTarget = damageModifierEvents.GroupBy(x => x.Dst).ToDictionary(x => x.Key, x => x.GroupBy(y => y.DamageModifier.Name).ToDictionary(y => y.Key, y => y.ToList())); foreach (AgentItem actor in damageModifiersEventsByTarget.Keys) { _damageModifierEventsPerTargets.Set(0, log.FightData.FightEnd, log.FindActor(actor), damageModifiersEventsByTarget[actor]); } // res = ComputeDamageModifierStats(target, log, start, end); return(res); }
internal DeathRecap(ParsedEvtcLog log, IReadOnlyList <AbstractHealthDamageEvent> damageLogs, DeadEvent dead, IReadOnlyList <DownEvent> downs, IReadOnlyList <AliveEvent> ups, long lastDeathTime) { DeathTime = dead.Time; DownEvent downed; AliveEvent upped = ups.LastOrDefault(x => x.Time <= dead.Time && x.Time >= lastDeathTime); if (upped != null) { downed = downs.LastOrDefault(x => x.Time <= dead.Time && x.Time >= upped.Time); } else { downed = downs.LastOrDefault(x => x.Time <= dead.Time && x.Time >= lastDeathTime); } if (downed != null) { var damageToDown = damageLogs.Where(x => x.Time > lastDeathTime && x.Time <= downed.Time && (x.HasHit || x.HasDowned)).ToList(); ToDown = damageToDown.Count > 0 ? new List <DeathRecapDamageItem>() : null; int damage = 0; for (int i = damageToDown.Count - 1; i >= 0; i--) { AbstractHealthDamageEvent dl = damageToDown[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectHealthDamageEvent, ID = dl.SkillId, Damage = dl.HealthDamage, Src = log.FindActor(ag)?.Character }; damage += dl.HealthDamage; ToDown.Add(item); if (damage > 20000) { break; } } var damageToKill = damageLogs.Where(x => x.Time > downed.Time && x.Time <= dead.Time && (x.HasHit || x.HasKilled)).ToList(); ToKill = damageToKill.Count > 0 ? new List <DeathRecapDamageItem>() : null; for (int i = damageToKill.Count - 1; i >= 0; i--) { AbstractHealthDamageEvent dl = damageToKill[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectHealthDamageEvent, ID = dl.SkillId, Damage = dl.HealthDamage, Src = log.FindActor(ag)?.Character }; ToKill.Add(item); } } else { ToDown = null; var damageToKill = damageLogs.Where(x => x.Time > lastDeathTime && x.Time <= dead.Time && (x.HasHit || x.HasKilled)).ToList(); ToKill = damageToKill.Count > 0 ? new List <DeathRecapDamageItem>() : null; int damage = 0; for (int i = damageToKill.Count - 1; i >= 0; i--) { AbstractHealthDamageEvent dl = damageToKill[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectHealthDamageEvent, ID = dl.SkillId, Damage = dl.HealthDamage, Src = log.FindActor(ag)?.Character }; damage += dl.HealthDamage; ToKill.Add(item); if (damage > 20000) { break; } } } }