internal override void ComputeDamageModifier(Dictionary <string, List <DamageModifierStat> > data, Dictionary <NPC, Dictionary <string, List <DamageModifierStat> > > dataTarget, Player p, ParsedEvtcLog log) { List <PhaseData> phases = log.FightData.GetPhases(log); double gain = GainComputer.ComputeGain(GainPerStack, 1); if (!p.GetHitDamageLogs(null, log, phases[0]).Exists(x => DLChecker(x))) { return; } foreach (NPC target in log.FightData.Logic.Targets) { if (!dataTarget.TryGetValue(target, out Dictionary <string, List <DamageModifierStat> > extra)) { dataTarget[target] = new Dictionary <string, List <DamageModifierStat> >(); } Dictionary <string, List <DamageModifierStat> > dict = dataTarget[target]; if (!dict.TryGetValue(Name, out List <DamageModifierStat> list)) { var extraDataList = new List <DamageModifierStat>(); for (int i = 0; i < phases.Count; i++) { int totalDamage = GetTotalDamage(p, log, target, i); List <AbstractDamageEvent> typeHits = GetHitDamageLogs(p, log, target, phases[i]); var effect = typeHits.Where(x => DLChecker(x)).ToList(); extraDataList.Add(new DamageModifierStat(effect.Count, typeHits.Count, gain * effect.Sum(x => x.Damage), totalDamage)); } dict[Name] = extraDataList; } } data[Name] = new List <DamageModifierStat>(); for (int i = 0; i < phases.Count; i++) { int totalDamage = GetTotalDamage(p, log, null, i); List <AbstractDamageEvent> typeHits = GetHitDamageLogs(p, log, null, phases[i]); var effect = typeHits.Where(x => DLChecker(x)).ToList(); data[Name].Add(new DamageModifierStat(effect.Count, typeHits.Count, gain * effect.Sum(x => x.Damage), totalDamage)); } }
internal override void ComputePlayerCombatReplayActors(Player p, ParsedEvtcLog log, CombatReplay replay) { // big bomb var bigbomb = log.CombatData.GetBuffData(37966).Where(x => (x.To == p.AgentItem && x is BuffApplyEvent)).ToList(); foreach (AbstractBuffEvent c in bigbomb) { int bigStart = (int)c.Time; int bigEnd = bigStart + 6000; replay.Decorations.Add(new CircleDecoration(true, 0, 300, (bigStart, bigEnd), "rgba(150, 80, 0, 0.2)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, bigEnd, 300, (bigStart, bigEnd), "rgba(150, 80, 0, 0.2)", new AgentConnector(p))); } // small bomb var smallbomb = log.CombatData.GetBuffData(38247).Where(x => (x.To == p.AgentItem && x is BuffApplyEvent)).ToList(); foreach (AbstractBuffEvent c in smallbomb) { int smallStart = (int)c.Time; int smallEnd = smallStart + 6000; replay.Decorations.Add(new CircleDecoration(true, 0, 80, (smallStart, smallEnd), "rgba(80, 150, 0, 0.3)", new AgentConnector(p))); } // fixated List <AbstractBuffEvent> fixatedSam = GetFilteredList(log.CombatData, 37868, p, true); int fixatedSamStart = 0; foreach (AbstractBuffEvent c in fixatedSam) { if (c is BuffApplyEvent) { fixatedSamStart = Math.Max((int)c.Time, 0); } else { int fixatedSamEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 80, (fixatedSamStart, fixatedSamEnd), "rgba(255, 80, 255, 0.3)", new AgentConnector(p))); } } //fixated Ghuldem List <AbstractBuffEvent> fixatedGuldhem = GetFilteredList(log.CombatData, 38223, p, true); int fixationGuldhemStart = 0; NPC guldhem = null; foreach (AbstractBuffEvent c in fixatedGuldhem) { if (c is BuffApplyEvent) { fixationGuldhemStart = (int)c.Time; long logTime = c.Time; guldhem = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TrashID.Guldhem && logTime >= x.FirstAware && logTime <= x.LastAware); } else { int fixationGuldhemEnd = (int)c.Time; if (guldhem != null) { replay.Decorations.Add(new LineDecoration(0, (fixationGuldhemStart, fixationGuldhemEnd), "rgba(255, 100, 0, 0.3)", new AgentConnector(p), new AgentConnector(guldhem))); } } } //fixated Rigom List <AbstractBuffEvent> fixatedRigom = GetFilteredList(log.CombatData, 37693, p, true); int fixationRigomStart = 0; NPC rigom = null; foreach (AbstractBuffEvent c in fixatedRigom) { if (c is BuffApplyEvent) { fixationRigomStart = (int)c.Time; long logTime = c.Time; rigom = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TrashID.Rigom && logTime >= x.FirstAware && logTime <= x.LastAware); } else { int fixationRigomEnd = (int)c.Time; if (rigom != null) { replay.Decorations.Add(new LineDecoration(0, (fixationRigomStart, fixationRigomEnd), "rgba(255, 0, 0, 0.3)", new AgentConnector(p), new AgentConnector(rigom))); } } } }
/*protected override CombatReplayMap GetCombatMapInternal() * { * return new CombatReplayMap("https://i.imgur.com/RZbs21b.png", * (1099, 1114), * (-5467, 8069, -2282, 11297), * (-12288, -27648, 12288, 27648), * (1920, 12160, 2944, 14464)); * }*/ internal override string GetLogicName(ParsedEvtcLog log) { return("Escort"); }
private static EXTHealingStatsPlayerDetailsDto BuildFriendlyMinionsHealingData(ParsedEvtcLog log, AbstractSingleActor actor, Minions minion, Dictionary<long, SkillItem> usedSkills, Dictionary<long, Buff> usedBuffs) { var dto = new EXTHealingStatsPlayerDetailsDto { HealingDistributions = new List<EXTHealingStatsHealingDistributionDto>(), HealingDistributionsTargets = new List<List<EXTHealingStatsHealingDistributionDto>>() }; foreach (PhaseData phase in log.FightData.GetPhases(log)) { var dmgTargetsDto = new List<EXTHealingStatsHealingDistributionDto>(); foreach (AbstractSingleActor target in log.Friendlies) { dmgTargetsDto.Add(EXTHealingStatsHealingDistributionDto.BuildFriendlyMinionHealingDistData(log, actor, minion, target, phase, usedSkills, usedBuffs)); } dto.HealingDistributionsTargets.Add(dmgTargetsDto); dto.HealingDistributions.Add(EXTHealingStatsHealingDistributionDto.BuildFriendlyMinionHealingDistData(log, actor, minion, null, phase, usedSkills, usedBuffs)); } return dto; }
public PhaseDto(PhaseData phaseData, IReadOnlyList <PhaseData> phases, ParsedEvtcLog log) { Name = phaseData.Name; Duration = phaseData.DurationInMS; Start = phaseData.Start / 1000.0; End = phaseData.End / 1000.0; BreakbarPhase = phaseData.BreakbarPhase; Dummy = phaseData.Dummy; foreach (NPC target in phaseData.Targets) { Targets.Add(log.FightData.Logic.Targets.IndexOf(target)); } PlayerActiveTimes = new List <long>(); foreach (Player p in log.PlayerList) { PlayerActiveTimes.Add(p.GetActiveDuration(log, phaseData.Start, phaseData.End)); } // add phase markup MarkupLines = new List <double>(); MarkupAreas = new List <AreaLabelDto>(); if (!BreakbarPhase) { for (int j = 1; j < phases.Count; j++) { PhaseData curPhase = phases[j]; if (curPhase.Start < phaseData.Start || curPhase.End > phaseData.End || (curPhase.Start == phaseData.Start && curPhase.End == phaseData.End) || !curPhase.CanBeSubPhase) { continue; } if (SubPhases == null) { SubPhases = new List <int>(); } SubPhases.Add(j); long start = curPhase.Start - phaseData.Start; long end = curPhase.End - phaseData.Start; if (curPhase.DrawStart) { MarkupLines.Add(start / 1000.0); } if (curPhase.DrawEnd) { MarkupLines.Add(end / 1000.0); } var phaseArea = new AreaLabelDto { Start = start / 1000.0, End = end / 1000.0, Label = curPhase.DrawLabel ? curPhase.Name : null, Highlight = curPhase.DrawArea }; MarkupAreas.Add(phaseArea); } } if (MarkupAreas.Count == 0) { MarkupAreas = null; } if (MarkupLines.Count == 0) { MarkupLines = null; } }
public override void SetBuffDistributionItem(BuffDistribution distribs, long start, long end, long boonid, ParsedEvtcLog log) { Dictionary <AgentItem, BuffDistributionItem> distrib = GetDistrib(distribs, boonid); AgentItem agent = Src; var value = GetValue(start, end); if (value == 0) { return; } if (distrib.TryGetValue(agent, out BuffDistributionItem toModify)) { toModify.Overstack += value; distrib[agent] = toModify; } else { distrib.Add(agent, new BuffDistributionItem( 0, value, 0, 0, 0, 0)); } }
public static BuffData BuildTargetBoonData(ParsedEvtcLog log, PhaseData phase, NPC target) { IReadOnlyDictionary <long, FinalBuffs> buffs = target.GetBuffs(log, phase.Start, phase.End); return(new BuffData(buffs, log.StatisticsHelper.PresentBoons, target.GetGameplayStats(log, phase.Start, phase.End).AvgBoons)); }
internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases) { List <PhaseData> phases = GetInitialPhase(log); NPC ca = Targets.Find(x => x.ID == (int)ArcDPSEnums.TargetID.ConjuredAmalgamate); if (ca == null) { throw new InvalidOperationException("Conjured Amalgamate not found"); } phases[0].Targets.Add(ca); if (!requirePhases) { return(phases); } phases.AddRange(GetPhasesByInvul(log, 52255, ca, true, false)); for (int i = 1; i < phases.Count; i++) { string name; PhaseData phase = phases[i]; if (i % 2 == 1) { name = "Arm Phase"; } else { name = "Burn Phase"; phase.Targets.Add(ca); } phase.Name = name; } NPC leftArm = Targets.Find(x => x.ID == (int)ArcDPSEnums.TargetID.CALeftArm); if (leftArm != null) { List <long> targetables = GetTargetableTimes(log, leftArm); for (int i = 1; i < phases.Count; i += 2) { PhaseData phase = phases[i]; if (targetables.Exists(x => phase.InInterval(x))) { phase.Name = "Left " + phase.Name; phase.Targets.Add(leftArm); } } } NPC rightArm = Targets.Find(x => x.ID == (int)ArcDPSEnums.TargetID.CARightArm); if (rightArm != null) { List <long> targetables = GetTargetableTimes(log, rightArm); for (int i = 1; i < phases.Count; i += 2) { PhaseData phase = phases[i]; if (targetables.Exists(x => phase.InInterval(x))) { if (phase.Name.Contains("Left")) { phase.Name = "Both Arms Phase"; } else { phase.Name = "Right " + phase.Name; } phase.Targets.Add(rightArm); } } } return(phases); }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); switch (target.ID) { case (int)ArcDPSEnums.TargetID.Gorseval: var blooms = cls.Where(x => x.SkillId == 31616).ToList(); foreach (AbstractCastEvent c in blooms) { int start = (int)c.Time; int end = (int)c.EndTime; replay.Decorations.Add(new CircleDecoration(true, c.ExpectedDuration + start, 600, (start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(false, 0, 600, (start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target))); } IReadOnlyList <PhaseData> phases = log.FightData.GetPhases(log); if (phases.Count > 1) { var rampage = cls.Where(x => x.SkillId == 31834).ToList(); const byte first = 1 << 0; const byte second = 1 << 1; const byte third = 1 << 2; const byte fourth = 1 << 3; const byte fifth = 1 << 4; const byte full = 1 << 5; Point3D pos = replay.PolledPositions.First(); foreach (AbstractCastEvent c in rampage) { int start = (int)c.Time; int end = (int)c.EndTime; replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(0, 125, 255, 0.3)", new AgentConnector(target))); // or spawn -> 3 secs -> explosion -> 0.5 secs -> fade -> 0.5 secs-> next int ticks = (int)Math.Min(Math.Ceiling(c.ActualDuration / 4000.0), 6); int phaseIndex; // get only phases where Gorseval is target (aka main phases) var gorsevalPhases = phases.Where(x => x.Targets.Contains(target)).ToList(); for (phaseIndex = 1; phaseIndex < gorsevalPhases.Count; phaseIndex++) { if (gorsevalPhases[phaseIndex].InInterval(start)) { break; } } if (pos == null) { break; } List <byte> patterns; switch (phaseIndex) { case 1: patterns = new List <byte> { second | third | fifth, second | third | fourth, first | fourth | fifth, first | second | fifth, first | third | fifth, full }; break; case 2: patterns = new List <byte> { second | third | fourth, first | fourth | fifth, first | third | fourth, first | second | fifth, first | second | third, full }; break; case 3: patterns = new List <byte> { first | fourth | fifth, first | second | fifth, second | third | fifth, third | fourth | fifth, third | fourth | fifth, full }; break; default: // no reason to stop parsing because of CR, worst case, no rampage patterns = new List <byte>(); ticks = 0; break; //throw new EIException("Gorseval cast rampage during a split phase"); } start += 2200; for (int i = 0; i < ticks; i++) { int tickStart = start + 4000 * i; int explosion = tickStart + 3000; int tickEnd = tickStart + 3500; byte pattern = patterns[i]; if ((pattern & first) > 0) { replay.Decorations.Add(new CircleDecoration(true, explosion, 360, (tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos))); replay.Decorations.Add(new CircleDecoration(true, 0, 360, (tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos))); } if ((pattern & second) > 0) { replay.Decorations.Add(new DoughnutDecoration(true, explosion, 360, 720, (tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos))); replay.Decorations.Add(new DoughnutDecoration(true, 0, 360, 720, (tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos))); } if ((pattern & third) > 0) { replay.Decorations.Add(new DoughnutDecoration(true, explosion, 720, 1080, (tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos))); replay.Decorations.Add(new DoughnutDecoration(true, 0, 720, 1080, (tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos))); } if ((pattern & fourth) > 0) { replay.Decorations.Add(new DoughnutDecoration(true, explosion, 1080, 1440, (tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos))); replay.Decorations.Add(new DoughnutDecoration(true, 0, 1080, 1440, (tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos))); } if ((pattern & fifth) > 0) { replay.Decorations.Add(new DoughnutDecoration(true, explosion, 1440, 1800, (tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos))); replay.Decorations.Add(new DoughnutDecoration(true, 0, 1440, 1800, (tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos))); } if ((pattern & full) > 0) { tickStart -= 1000; explosion -= 1000; tickEnd -= 1000; replay.Decorations.Add(new CircleDecoration(true, explosion, 1800, (tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos))); replay.Decorations.Add(new CircleDecoration(true, 0, 1800, (tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos))); } } } } var slam = cls.Where(x => x.SkillId == 31875).ToList(); foreach (AbstractCastEvent c in slam) { int start = (int)c.Time; int impactPoint = 1185; int impactTime = start + impactPoint; int end = Math.Min((int)c.EndTime, impactTime); int radius = 320; replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, end), "rgba(255, 0, 0, 0.2)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (impactTime, impactTime + 100), "rgba(255, 0, 0, 0.4)", new AgentConnector(target))); } List <AbstractBuffEvent> protection = GetFilteredList(log.CombatData, 31877, target, true, true); int protectionStart = 0; foreach (AbstractBuffEvent c in protection) { if (c is BuffApplyEvent) { protectionStart = (int)c.Time; } else { int protectionEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 300, (protectionStart, protectionEnd), "rgba(0, 180, 255, 0.5)", new AgentConnector(target))); } } break; case (int)ArcDPSEnums.TrashID.ChargedSoul: var lifespan = ((int)replay.TimeOffsets.start, (int)replay.TimeOffsets.end); replay.Decorations.Add(new CircleDecoration(false, 0, 220, lifespan, "rgba(255, 150, 0, 0.5)", new AgentConnector(target))); break; default: break; } }
public IReadOnlyDictionary <long, FinalPlayerBuffs> GetActiveBuffs(BuffEnum type, ParsedEvtcLog log, long start, long end) { if (_buffStats == null) { _buffStats = new CachingCollectionCustom <BuffEnum, Dictionary <long, FinalPlayerBuffs>[]>(log, BuffEnum.Self); } if (!_buffStats.TryGetValue(start, end, type, out Dictionary <long, FinalPlayerBuffs>[] value)) { value = SetBuffs(log, start, end, type); _buffStats.Set(start, end, type, value); } return(value[1]); }
public override object GetConnectedTo(CombatReplayMap map, ParsedEvtcLog log) { return(_agent.UniqueID); }
// public override AbstractSingleActorSerializable GetCombatReplayJSON(CombatReplayMap map, ParsedEvtcLog log) { if (CombatReplay == null) { InitCombatReplay(log); } return(new PlayerSerializable(this, log, map, CombatReplay)); }
public Dictionary <string, List <DamageModifierStat> > GetDamageModifierStats(ParsedEvtcLog log, NPC target) { if (_damageModifiers == null) { SetDamageModifiersData(log); } if (target != null) { if (_damageModifiersTargets.TryGetValue(target, out Dictionary <string, List <DamageModifierStat> > res)) { return(res); } else { return(new Dictionary <string, List <DamageModifierStat> >()); } } return(_damageModifiers); }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { int crStart = (int)replay.TimeOffsets.start; int crEnd = (int)replay.TimeOffsets.end; IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); switch (target.ID) { case (int)ArcDPSEnums.TargetID.Sabir: List <AbstractBuffEvent> repulsionFields = GetFilteredList(log.CombatData, RepulsionField, target, true, true); int repulsionFieldStart = 0; foreach (AbstractBuffEvent c in repulsionFields) { if (c is BuffApplyEvent) { repulsionFieldStart = (int)c.Time; } else { int repulsionFieldEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 120, (repulsionFieldStart, repulsionFieldEnd), "rgba(80, 0, 255, 0.3)", new AgentConnector(target))); } } List <AbstractBuffEvent> ionShields = GetFilteredList(log.CombatData, IonShield, target, true, true); int ionShieldStart = 0; foreach (AbstractBuffEvent c in ionShields) { if (c is BuffApplyEvent) { ionShieldStart = (int)c.Time; } else { int ionShieldEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 120, (ionShieldStart, ionShieldEnd), "rgba(0, 80, 255, 0.3)", new AgentConnector(target))); } } // var furyOfTheStorm = cls.Where(x => x.SkillId == 56372).ToList(); foreach (AbstractCastEvent c in furyOfTheStorm) { replay.Decorations.Add(new CircleDecoration(true, (int)c.EndTime, 1200, ((int)c.Time, (int)c.EndTime), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } // var unbridledTempest = cls.Where(x => x.SkillId == 56643).ToList(); foreach (AbstractCastEvent c in unbridledTempest) { int start = (int)c.Time; int delay = 3000; // casttime 0 from skill def int duration = 5000; int radius = 1200; Point3D targetPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= start + 1000); if (targetPosition != null) { replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, start + delay), "rgba(255, 100, 0, 0.2)", new PositionConnector(targetPosition))); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start + delay - 10, start + delay + 100), "rgba(255, 100, 0, 0.5)", new PositionConnector(targetPosition))); replay.Decorations.Add(new CircleDecoration(false, start + duration, radius, (start + delay, start + duration), "rgba(255, 150, 0, 0.7)", new PositionConnector(targetPosition))); } } break; case (int)ArcDPSEnums.TrashID.BigKillerTornado: replay.Decorations.Add(new CircleDecoration(true, 0, 480, (crStart, crEnd), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.SmallKillerTornado: replay.Decorations.Add(new CircleDecoration(true, 0, 120, (crStart, crEnd), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.SmallJumpyTornado: case (int)ArcDPSEnums.TrashID.ParalyzingWisp: case (int)ArcDPSEnums.TrashID.VoltaicWisp: break; default: break; } }
public IReadOnlyList <AbstractHealthDamageEvent> GetHitDamageEvents(AbstractSingleActor actor, ParsedEvtcLog log, AbstractSingleActor t, long start, long end) { return(_dmgSrc == DamageSource.All ? actor.GetHitDamageEvents(t, log, start, end, _srcType) : actor.GetJustActorHitDamageEvents(t, log, start, end, _srcType)); }
public override void SetBuffDistributionItem(BuffDistribution distribs, long start, long end, long boonid, ParsedEvtcLog log) { long cDur = GetClampedDuration(start, end); if (cDur == 0) { return; } foreach (BuffSimulationItemDuration item in _stacks) { item.SetBuffDistributionItem(distribs, start, end, boonid, log); } }
internal abstract List <DamageModifierEvent> ComputeDamageModifier(AbstractSingleActor actor, ParsedEvtcLog log);
public ActorChartDataDto(ParsedEvtcLog log, PhaseData phase, AbstractSingleActor actor, bool nullableHPStates) { HealthStates = ChartDataDto.BuildHealthStates(log, actor, phase, nullableHPStates); BarrierStates = ChartDataDto.BuildBarrierStates(log, actor, phase); }
// Constructor public BuffSimulatorIDIntensity(ParsedEvtcLog log, Buff buff, int capacity) : base(log, buff) { _capacity = capacity; }
// Prefer using Add, to insert to the list in a sorted manner protected override void Sort(ParsedEvtcLog log, List <BuffStackItem> stacks) { throw new InvalidOperationException("Do not use Sort for OverrideLogic"); }
internal override void TryFindSrc(ParsedEvtcLog log) { }
/*public List<DamageLog> getHealingLogs(ParsedEvtcLog log, long start, long end) * { * List<DamageLog> res = new List<DamageLog>(); * foreach (Minion minion in this) * { * res.AddRange(minion.getHealingLogs(log, start, end)); * } * return res; * }*/ public override List <AbstractDamageEvent> GetDamageTakenLogs(AbstractActor target, ParsedEvtcLog log, long start, long end) { if (DamageTakenlogs == null) { DamageTakenlogs = new List <AbstractDamageEvent>(); foreach (NPC minion in MinionList) { DamageTakenlogs.AddRange(minion.GetDamageTakenLogs(null, log, 0, log.FightData.FightEnd)); } DamageTakenLogsBySrc = DamageTakenlogs.GroupBy(x => x.From).ToDictionary(x => x.Key, x => x.ToList()); } if (target != null && DamageTakenLogsBySrc.TryGetValue(target.AgentItem, out List <AbstractDamageEvent> list)) { return(list.Where(x => x.Time >= start && x.Time <= end).ToList()); } return(DamageTakenlogs.Where(x => x.Time >= start && x.Time <= end).ToList()); }
internal JsonLog(ParsedEvtcLog log, RawFormatSettings settings, Version parserVersion, string[] uploadLinks) { // log.UpdateProgressWithCancellationCheck("Raw Format: Building Meta Data"); TriggerID = log.FightData.TriggerID; FightName = log.FightData.GetFightName(log); FightIcon = log.FightData.Logic.Icon; EliteInsightsVersion = parserVersion.ToString(); ArcVersion = log.LogData.ArcVersion; RecordedBy = log.LogData.PoVName; TimeStart = log.LogData.LogStart; TimeEnd = log.LogData.LogEnd; TimeStartStd = log.LogData.LogStartStd; TimeEndStd = log.LogData.LogEndStd; Duration = log.FightData.DurationString; Success = log.FightData.Success; GW2Build = log.LogData.GW2Build; UploadLinks = uploadLinks; Language = log.LogData.Language; LanguageID = (byte)log.LogData.LanguageID; 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] = new BuffDesc(fractalInstab, log); } } 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()) { Mechanics = GetJsonMechanicsList(mechanicLogs); } // log.UpdateProgressWithCancellationCheck("Raw Format: Building Phases"); Phases = log.FightData.GetPhases(log).Select(x => new JsonPhase(x, log)).ToList(); // log.UpdateProgressWithCancellationCheck("Raw Format: Building Targets"); Targets = log.FightData.Logic.Targets.Select(x => new JsonNPC(x, log, settings, skillMap, buffMap)).ToList(); // log.UpdateProgressWithCancellationCheck("Raw Format: Building Players"); Players = log.PlayerList.Select(x => new JsonPlayer(x, log, settings, skillMap, buffMap, damageModMap, personalBuffs)).ToList(); // if (log.LogData.LogErrors.Count > 0) { LogErrors = new List <string>(log.LogData.LogErrors); } // PersonalBuffs = personalBuffs.ToDictionary(x => x.Key, x => (IReadOnlyCollection <long>)x.Value); SkillMap = skillMap; BuffMap = buffMap; DamageModMap = damageModMap; }
internal override void ComputePlayerCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay) { // Corruption List <AbstractBuffEvent> corruptedMatthias = GetFilteredList(log.CombatData, 34416, p, true, true); corruptedMatthias.AddRange(GetFilteredList(log.CombatData, 34473, p, true, true)); int corruptedMatthiasStart = 0; foreach (AbstractBuffEvent c in corruptedMatthias) { if (c is BuffApplyEvent) { corruptedMatthiasStart = (int)c.Time; } else { int corruptedMatthiasEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 180, (corruptedMatthiasStart, corruptedMatthiasEnd), "rgba(255, 150, 0, 0.5)", new AgentConnector(p))); Point3D wellNextPosition = replay.PolledPositions.FirstOrDefault(x => x.Time >= corruptedMatthiasEnd); Point3D wellPrevPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= corruptedMatthiasEnd); if (wellNextPosition != null || wellPrevPosition != null) { replay.Decorations.Add(new CircleDecoration(true, 0, 180, (corruptedMatthiasEnd, corruptedMatthiasEnd + 100000), "rgba(0, 0, 0, 0.3)", new InterpolatedPositionConnector(wellPrevPosition, wellNextPosition, corruptedMatthiasEnd))); replay.Decorations.Add(new CircleDecoration(true, corruptedMatthiasEnd + 100000, 180, (corruptedMatthiasEnd, corruptedMatthiasEnd + 100000), "rgba(0, 0, 0, 0.3)", new InterpolatedPositionConnector(wellPrevPosition, wellNextPosition, corruptedMatthiasEnd))); } } } // Well of profane List <AbstractBuffEvent> wellMatthias = GetFilteredList(log.CombatData, 34450, p, true, true); int wellMatthiasStart = 0; foreach (AbstractBuffEvent c in wellMatthias) { if (c is BuffApplyEvent) { wellMatthiasStart = (int)c.Time; } else { int wellMatthiasEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(false, 0, 120, (wellMatthiasStart, wellMatthiasEnd), "rgba(150, 255, 80, 0.5)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, wellMatthiasStart + 9000, 120, (wellMatthiasStart, wellMatthiasEnd), "rgba(150, 255, 80, 0.5)", new AgentConnector(p))); Point3D wellNextPosition = replay.PolledPositions.FirstOrDefault(x => x.Time >= wellMatthiasEnd); Point3D wellPrevPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= wellMatthiasEnd); if (wellNextPosition != null || wellPrevPosition != null) { replay.Decorations.Add(new CircleDecoration(true, 0, 300, (wellMatthiasEnd, wellMatthiasEnd + 90000), "rgba(255, 0, 50, 0.5)", new InterpolatedPositionConnector(wellPrevPosition, wellNextPosition, wellMatthiasEnd))); } } } // Sacrifice List <AbstractBuffEvent> sacrificeMatthias = GetFilteredList(log.CombatData, 34442, p, true, true); int sacrificeMatthiasStart = 0; foreach (AbstractBuffEvent c in sacrificeMatthias) { if (c is BuffApplyEvent) { sacrificeMatthiasStart = (int)c.Time; } else { int sacrificeMatthiasEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 120, (sacrificeMatthiasStart, sacrificeMatthiasEnd), "rgba(0, 150, 250, 0.2)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, sacrificeMatthiasStart + 10000, 120, (sacrificeMatthiasStart, sacrificeMatthiasEnd), "rgba(0, 150, 250, 0.35)", new AgentConnector(p))); } } // Bombs var zealousBenediction = log.CombatData.GetBuffData(34511).Where(x => x.To == p.AgentItem && x is BuffApplyEvent).ToList(); foreach (AbstractBuffEvent c in zealousBenediction) { int zealousStart = (int)c.Time; int zealousEnd = zealousStart + 5000; replay.Decorations.Add(new CircleDecoration(true, 0, 180, (zealousStart, zealousEnd), "rgba(200, 150, 0, 0.2)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, zealousEnd, 180, (zealousStart, zealousEnd), "rgba(200, 150, 0, 0.4)", new AgentConnector(p))); } }
internal GenericAttachedDecorationSerializable(ParsedEvtcLog log, GenericAttachedDecoration decoration, CombatReplayMap map) : base(decoration) { ConnectedTo = decoration.ConnectedTo.GetConnectedTo(map, log); }
public EXTHealingType GetHealingType(ParsedEvtcLog log) { return(log.CombatData.EXTHealingCombatData.GetHealingType(Skill, log)); }
private static List <List <object> > GetMechanicChartPoints(IReadOnlyList <MechanicEvent> mechanicLogs, PhaseData phase, ParsedEvtcLog log, bool enemyMechanic) { var res = new List <List <object> >(); if (!enemyMechanic) { var playerIndex = new Dictionary <AbstractActor, int>(); for (int p = 0; p < log.PlayerList.Count; p++) { playerIndex.Add(log.PlayerList[p], p); res.Add(new List <object>()); } foreach (MechanicEvent ml in mechanicLogs.Where(x => phase.InInterval(x.Time))) { double time = (ml.Time - phase.Start) / 1000.0; if (playerIndex.TryGetValue(ml.Actor, out int p)) { res[p].Add(time); } } } else { var targetIndex = new Dictionary <AbstractActor, int>(); for (int p = 0; p < phase.Targets.Count; p++) { targetIndex.Add(phase.Targets[p], p); res.Add(new List <object>()); } res.Add(new List <object>()); foreach (MechanicEvent ml in mechanicLogs.Where(x => phase.InInterval(x.Time))) { double time = (ml.Time - phase.Start) / 1000.0; if (targetIndex.TryGetValue(ml.Actor, out int p)) { res[p].Add(time); } else { res[res.Count - 1].Add(new object[] { time, ml.Actor.Character }); } } } return(res); }
public override bool ConditionDamageBased(ParsedEvtcLog log) { return(false); }
internal override string GetLogicName(ParsedEvtcLog log) { return("Statue of Ice"); }
private static void GenerateFiles(ParsedEvtcLog log, OperationController operation, string[] uploadresult, FileInfo fInfo) { operation.UpdateProgressWithCancellationCheck("Creating File(s)"); DirectoryInfo saveDirectory = GetSaveDirectory(fInfo); string result = log.FightData.Success ? "kill" : "fail"; string encounterLengthTerm = Properties.Settings.Default.AddDuration ? "_" + (log.FightData.FightEnd / 1000).ToString() + "s" : ""; string PoVClassTerm = Properties.Settings.Default.AddPoVProf ? "_" + log.LogData.PoV.Prof.ToLower() : ""; string fName = fInfo.Name.Split('.')[0]; fName = $"{fName}{PoVClassTerm}_{log.FightData.Logic.Extension}{encounterLengthTerm}_{result}"; // parallel stuff if (Properties.Settings.Default.MultiThreaded && HasFormat()) { IReadOnlyList <PhaseData> phases = log.FightData.GetPhases(log); operation.UpdateProgressWithCancellationCheck("Multi threading"); var playersAndTargets = new List <AbstractSingleActor>(log.PlayerList); playersAndTargets.AddRange(log.FightData.Logic.Targets); foreach (AbstractSingleActor actor in playersAndTargets) { // that part can't be // actor.GetTrackedBuffs(log); } Parallel.ForEach(playersAndTargets, actor => actor.GetStatus(log)); if (log.CanCombatReplay) { var playersAndTargetsAndMobs = new List <AbstractSingleActor>(log.FightData.Logic.TrashMobs); playersAndTargetsAndMobs.AddRange(playersAndTargets); // init all positions Parallel.ForEach(playersAndTargetsAndMobs, actor => actor.GetCombatReplayPolledPositions(log)); } else if (log.CombatData.HasMovementData) { Parallel.ForEach(log.PlayerList, player => player.GetCombatReplayPolledPositions(log)); } Parallel.ForEach(playersAndTargets, actor => actor.GetBuffGraphs(log)); Parallel.ForEach(playersAndTargets, actor => { foreach (PhaseData phase in phases) { actor.GetBuffDistribution(log, phase.Start, phase.End); } }); Parallel.ForEach(playersAndTargets, actor => { foreach (PhaseData phase in phases) { actor.GetBuffPresence(log, phase.Start, phase.End); } }); // Parallel.ForEach(log.PlayerList, player => player.GetDamageModifierStats(log, null)); Parallel.ForEach(log.PlayerList, actor => { foreach (PhaseData phase in phases) { actor.GetBuffs(BuffEnum.Self, log, phase.Start, phase.End); } }); Parallel.ForEach(log.PlayerList, actor => { foreach (PhaseData phase in phases) { actor.GetBuffs(BuffEnum.Group, log, phase.Start, phase.End); } }); Parallel.ForEach(log.PlayerList, actor => { foreach (PhaseData phase in phases) { actor.GetBuffs(BuffEnum.OffGroup, log, phase.Start, phase.End); } }); Parallel.ForEach(log.PlayerList, actor => { foreach (PhaseData phase in phases) { actor.GetBuffs(BuffEnum.Squad, log, phase.Start, phase.End); } }); Parallel.ForEach(log.FightData.Logic.Targets, actor => { foreach (PhaseData phase in phases) { actor.GetBuffs(log, phase.Start, phase.End); } }); } if (Properties.Settings.Default.SaveOutHTML) { operation.UpdateProgressWithCancellationCheck("Creating HTML"); string outputFile = Path.Combine( saveDirectory.FullName, $"{fName}.html" ); operation.GeneratedFiles.Add(outputFile); operation.OpenableFiles.Add(outputFile); operation.OutLocation = saveDirectory.FullName; using (var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) using (var sw = new StreamWriter(fs)) { var builder = new HTMLBuilder(log, new HTMLSettings(Properties.Settings.Default.LightTheme, Properties.Settings.Default.HtmlExternalScripts), htmlAssets, ParserVersion, uploadresult); builder.CreateHTML(sw, saveDirectory.FullName); } operation.UpdateProgressWithCancellationCheck("HTML created"); } if (Properties.Settings.Default.SaveOutCSV) { operation.UpdateProgressWithCancellationCheck("Creating CSV"); string outputFile = Path.Combine( saveDirectory.FullName, $"{fName}.csv" ); operation.GeneratedFiles.Add(outputFile); operation.OpenableFiles.Add(outputFile); operation.OutLocation = saveDirectory.FullName; using (var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) using (var sw = new StreamWriter(fs, Encoding.GetEncoding(1252))) { var builder = new CSVBuilder(log, new CSVSettings(","), ParserVersion, uploadresult); builder.CreateCSV(sw); } operation.UpdateProgressWithCancellationCheck("CSV created"); } if (Properties.Settings.Default.SaveOutJSON || Properties.Settings.Default.SaveOutXML) { var builder = new RawFormatBuilder(log, new RawFormatSettings(Properties.Settings.Default.RawTimelineArrays), ParserVersion, uploadresult); if (Properties.Settings.Default.SaveOutJSON) { operation.UpdateProgressWithCancellationCheck("Creating JSON"); string outputFile = Path.Combine( saveDirectory.FullName, $"{fName}.json" ); operation.OutLocation = saveDirectory.FullName; Stream str; if (Properties.Settings.Default.CompressRaw) { str = new MemoryStream(); } else { str = new FileStream(outputFile, FileMode.Create, FileAccess.Write); } using (var sw = new StreamWriter(str, NoBOMEncodingUTF8)) { builder.CreateJSON(sw, Properties.Settings.Default.IndentJSON); } if (str is MemoryStream msr) { CompressFile(outputFile, msr, operation); operation.UpdateProgressWithCancellationCheck("JSON compressed"); } else { operation.GeneratedFiles.Add(outputFile); } operation.UpdateProgressWithCancellationCheck("JSON created"); } if (Properties.Settings.Default.SaveOutXML) { operation.UpdateProgressWithCancellationCheck("Creating XML"); string outputFile = Path.Combine( saveDirectory.FullName, $"{fName}.xml" ); operation.OutLocation = saveDirectory.FullName; Stream str; if (Properties.Settings.Default.CompressRaw) { str = new MemoryStream(); } else { str = new FileStream(outputFile, FileMode.Create, FileAccess.Write); } using (var sw = new StreamWriter(str, NoBOMEncodingUTF8)) { builder.CreateXML(sw, Properties.Settings.Default.IndentXML); } if (str is MemoryStream msr) { CompressFile(outputFile, msr, operation); operation.UpdateProgressWithCancellationCheck("XML compressed"); } else { operation.GeneratedFiles.Add(outputFile); } operation.UpdateProgressWithCancellationCheck("XML created"); } } operation.UpdateProgress($"Completed parsing for {result}ed {log.FightData.Logic.Extension}"); }