// protected static List <AbstractBuffEvent> GetFilteredList(CombatData combatData, long buffID, AbstractSingleActor target, bool beginWithStart, bool padEnd) { bool needStart = beginWithStart; var main = combatData.GetBuffData(buffID).Where(x => x.To == target.AgentItem && (x is BuffApplyEvent || x is BuffRemoveAllEvent)).ToList(); var filtered = new List <AbstractBuffEvent>(); for (int i = 0; i < main.Count; i++) { AbstractBuffEvent c = main[i]; if (needStart && c is BuffApplyEvent) { needStart = false; filtered.Add(c); } else if (!needStart && c is BuffRemoveAllEvent) { // consider only last remove event before another application if ((i == main.Count - 1) || (i < main.Count - 1 && main[i + 1] is BuffApplyEvent)) { needStart = true; filtered.Add(c); } } } if (padEnd && filtered.Any() && filtered.Last() is BuffApplyEvent) { AbstractBuffEvent last = filtered.Last(); filtered.Add(new BuffRemoveAllEvent(ParserHelper._unknownAgent, last.To, target.LastAware, int.MaxValue, last.BuffSkill, BuffRemoveAllEvent.FullRemoval, int.MaxValue)); } return(filtered); }
// protected static List <AbstractBuffEvent> GetFilteredList(CombatData combatData, long buffID, AbstractSingleActor target, bool beginWithStart) { bool needStart = beginWithStart; var main = combatData.GetBuffData(buffID).Where(x => x.To == target.AgentItem && (x is BuffApplyEvent || x is BuffRemoveAllEvent)).ToList(); var filtered = new List <AbstractBuffEvent>(); for (int i = 0; i < main.Count; i++) { AbstractBuffEvent c = main[i]; if (needStart && c is BuffApplyEvent) { needStart = false; filtered.Add(c); } else if (!needStart && c is BuffRemoveAllEvent) { // consider only last remove event before another application if ((i == main.Count - 1) || (i < main.Count - 1 && main[i + 1] is BuffApplyEvent)) { needStart = true; filtered.Add(c); } } } return(filtered); }
protected static List <PhaseData> GetPhasesByInvul(ParsedEvtcLog log, long skillID, AbstractSingleActor mainTarget, bool addSkipPhases, bool beginWithStart, long start, long end) { var phases = new List <PhaseData>(); long last = start; List <AbstractBuffEvent> invuls = GetFilteredList(log.CombatData, skillID, mainTarget, beginWithStart, true); invuls.RemoveAll(x => x.Time < 0); for (int i = 0; i < invuls.Count; i++) { AbstractBuffEvent c = invuls[i]; if (c is BuffApplyEvent) { long curEnd = Math.Min(c.Time, end); phases.Add(new PhaseData(last, curEnd)); last = curEnd; } else { long curEnd = Math.Min(c.Time, end); if (addSkipPhases) { phases.Add(new PhaseData(last, curEnd)); } last = curEnd; } } if (end - last > ParserHelper.PhaseTimeLimit) { phases.Add(new PhaseData(last, end)); } return(phases.Where(x => x.DurationInMS > ParserHelper.PhaseTimeLimit).ToList()); }
public override List <AbstractBuffEvent> SpecialBuffEventProcess(Dictionary <AgentItem, List <AbstractBuffEvent> > buffsByDst, Dictionary <long, List <AbstractBuffEvent> > buffsById, SkillData skillData) { NPC target = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.Deimos); if (target == null) { throw new InvalidOperationException("Deimos not found"); } var res = new List <AbstractBuffEvent>(); if (buffsById.TryGetValue(38224, out List <AbstractBuffEvent> list)) { foreach (AbstractBuffEvent bfe in list) { if (bfe is BuffApplyEvent ba) { AbstractBuffEvent removal = list.FirstOrDefault(x => x is BuffRemoveAllEvent && x.Time > bfe.Time && x.Time < bfe.Time + 30000); if (removal == null) { res.Add(new BuffRemoveAllEvent(GeneralHelper.UnknownAgent, target.AgentItem, ba.Time + ba.AppliedDuration, 0, skillData.Get(38224), 1, 0)); res.Add(new BuffRemoveManualEvent(GeneralHelper.UnknownAgent, target.AgentItem, ba.Time + ba.AppliedDuration, 0, skillData.Get(38224))); } } else if (bfe is BuffRemoveAllEvent) { AbstractBuffEvent apply = list.FirstOrDefault(x => x is BuffApplyEvent && x.Time <bfe.Time && x.Time> bfe.Time - 30000); if (apply == null) { res.Add(new BuffApplyEvent(GeneralHelper.UnknownAgent, target.AgentItem, bfe.Time - 10000, 10000, skillData.Get(38224), uint.MaxValue, true)); } } } } return(res); }
internal override FightData.CMStatus IsCM(CombatData combatData, AgentData agentData, FightData fightData) { var necrosis = combatData.GetBuffData(47414).Where(x => x is BuffApplyEvent).ToList(); if (necrosis.Count == 0) { return(0); } // split necrosis var splitNecrosis = new Dictionary <AgentItem, List <AbstractBuffEvent> >(); foreach (AbstractBuffEvent c in necrosis) { AgentItem tank = c.To; if (!splitNecrosis.ContainsKey(tank)) { splitNecrosis.Add(tank, new List <AbstractBuffEvent>()); } splitNecrosis[tank].Add(c); } List <AbstractBuffEvent> longestNecrosis = splitNecrosis.Values.First(l => l.Count == splitNecrosis.Values.Max(x => x.Count)); long minDiff = long.MaxValue; for (int i = 0; i < longestNecrosis.Count - 1; i++) { AbstractBuffEvent cur = longestNecrosis[i]; AbstractBuffEvent next = longestNecrosis[i + 1]; long timeDiff = next.Time - cur.Time; if (timeDiff > 1000 && minDiff > timeDiff) { minDiff = timeDiff; } } return((minDiff < 11000) ? FightData.CMStatus.CM : FightData.CMStatus.NoCM); }
public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases) { long fightDuration = log.FightData.FightDuration; List <PhaseData> phases = GetInitialPhase(log); Target mainTarget = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Dhuum); if (mainTarget == null) { throw new InvalidOperationException("Main target of the fight not found"); } phases[0].Targets.Add(mainTarget); if (!requirePhases) { return(phases); } // Sometimes the preevent is not in the evtc List <AbstractCastEvent> castLogs = mainTarget.GetCastLogs(log, 0, log.FightData.FightDuration); List <AbstractCastEvent> dhuumCast = mainTarget.GetCastLogs(log, 0, 20000); string[] namesDh; if (dhuumCast.Count > 0) { namesDh = new[] { "Main Fight", "Ritual" }; ComputeFightPhases(mainTarget, phases, log, castLogs, fightDuration, 0); _isBugged = true; } else { AbstractBuffEvent invulDhuum = log.CombatData.GetBoonData(762).FirstOrDefault(x => x is BuffRemoveManualEvent && x.To == mainTarget.AgentItem && x.Time > 115000); if (invulDhuum != null) { long end = invulDhuum.Time; phases.Add(new PhaseData(0, end)); ComputeFightPhases(mainTarget, phases, log, castLogs, fightDuration, end + 1); } else { phases.Add(new PhaseData(0, fightDuration)); } namesDh = new[] { "Roleplay", "Main Fight", "Ritual" }; } for (int i = 1; i < phases.Count; i++) { phases[i].Name = namesDh[i - 1]; phases[i].Targets.Add(mainTarget); } bool hasRitual = phases.Last().Name == "Ritual"; if (dhuumCast.Count > 0 && phases.Count > 1) { phases.AddRange(GetInBetweenSoulSplits(log, mainTarget, phases[1].Start, phases[1].End, hasRitual)); phases.Sort((x, y) => x.Start.CompareTo(y.Start)); } else if (phases.Count > 2) { phases.AddRange(GetInBetweenSoulSplits(log, mainTarget, phases[2].Start, phases[2].End, hasRitual)); phases.Sort((x, y) => x.Start.CompareTo(y.Start)); } return(phases); }
public override List <AbstractBuffEvent> SpecialBuffEventProcess(Dictionary <AgentItem, List <AbstractBuffEvent> > buffsByDst, Dictionary <long, List <AbstractBuffEvent> > buffsById, long offset, SkillData skillData) { Target target = Targets.Find(x => x.ID == TriggerID); if (target == null) { throw new InvalidOperationException("Target for success by combat exit not found"); } List <AbstractBuffEvent> res = new List <AbstractBuffEvent>(); if (buffsById.TryGetValue(38224, out var list)) { foreach (AbstractBuffEvent bfe in list) { if (bfe is BuffApplyEvent) { AbstractBuffEvent removal = list.FirstOrDefault(x => x is BuffRemoveAllEvent && x.Time > bfe.Time && x.Time < bfe.Time + 30000); if (removal == null) { res.Add(new BuffRemoveAllEvent(GeneralHelper.UnknownAgent, target.AgentItem, bfe.Time + 10000, 0, skillData.Get(38224), 0, 0)); res.Add(new BuffRemoveManualEvent(GeneralHelper.UnknownAgent, target.AgentItem, bfe.Time + 10000, 0, skillData.Get(38224))); } } else if (bfe is BuffRemoveAllEvent) { AbstractBuffEvent apply = list.FirstOrDefault(x => x is BuffApplyEvent && x.Time <bfe.Time && x.Time> bfe.Time - 30000); if (apply == null) { res.Add(new BuffApplyEvent(GeneralHelper.UnknownAgent, target.AgentItem, bfe.Time - 10000, 10000, skillData.Get(38224))); } } } } return(res); }
public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases) { long fightDuration = log.FightData.FightDuration; List <PhaseData> phases = GetInitialPhase(log); Target mainTarget = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Matthias); if (mainTarget == null) { throw new InvalidOperationException("Main target of the fight not found"); } phases[0].Targets.Add(mainTarget); if (!requirePhases) { return(phases); } // Special buff cast check AbstractBuffEvent heatWave = log.CombatData.GetBoonData(34526).FirstOrDefault(); if (heatWave != null) { phases.Add(new PhaseData(0, heatWave.Time - 1)); AbstractDamageEvent downPour = log.CombatData.GetDamageData(mainTarget.AgentItem).Find(x => x.SkillId == 34554); if (downPour != null) { phases.Add(new PhaseData(heatWave.Time, downPour.Time - 1)); List <AbstractCastEvent> castLogs = mainTarget.GetCastLogs(log, 0, log.FightData.FightDuration); AbstractCastEvent abo = castLogs.Find(x => x.SkillId == 34427); if (abo != null) { phases.Add(new PhaseData(downPour.Time, abo.Time - 1)); AbstractBuffEvent invulRemove = log.CombatData.GetBoonDataByDst(mainTarget.AgentItem).FirstOrDefault(x => x.Time >= abo.Time && x.Time <= abo.Time + 10000 && x.BuffID == 757 && !(x is BuffApplyEvent)); if (invulRemove != null) { phases.Add(new PhaseData(invulRemove.Time, fightDuration)); } } else { phases.Add(new PhaseData(downPour.Time, fightDuration)); } } else { phases.Add(new PhaseData(heatWave.Time, fightDuration)); } } else { phases.Add(new PhaseData(0, fightDuration)); } string[] namesMat = new [] { "Ice Phase", "Fire Phase", "Storm Phase", "Abomination Phase" }; for (int i = 1; i < phases.Count; i++) { phases[i].Name = namesMat[i - 1]; phases[i].DrawStart = i > 1; phases[i].Targets.Add(mainTarget); } return(phases); }
internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases) { long fightDuration = log.FightData.FightEnd; List <PhaseData> phases = GetInitialPhase(log); NPC mainTarget = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.Matthias); if (mainTarget == null) { throw new MissingKeyActorsException("Matthias not found"); } phases[0].AddTarget(mainTarget); if (!requirePhases) { return(phases); } // Special buff cast check AbstractBuffEvent heatWave = log.CombatData.GetBuffData(34526).FirstOrDefault(); if (heatWave != null) { phases.Add(new PhaseData(0, heatWave.Time - 1)); AbstractHealthDamageEvent downPour = log.CombatData.GetDamageData(mainTarget.AgentItem).FirstOrDefault(x => x.SkillId == 34554); if (downPour != null) { phases.Add(new PhaseData(heatWave.Time, downPour.Time - 1)); IReadOnlyList <AbstractCastEvent> castLogs = mainTarget.GetCastEvents(log, 0, log.FightData.FightEnd); AbstractCastEvent abo = castLogs.FirstOrDefault(x => x.SkillId == 34427); if (abo != null) { phases.Add(new PhaseData(downPour.Time, abo.Time - 1)); AbstractBuffEvent invulRemove = log.CombatData.GetBuffData(mainTarget.AgentItem).FirstOrDefault(x => x.Time >= abo.Time && x.Time <= abo.Time + 10000 && x.BuffID == 757 && !(x is BuffApplyEvent)); if (invulRemove != null) { phases.Add(new PhaseData(invulRemove.Time, fightDuration)); } } else { phases.Add(new PhaseData(downPour.Time, fightDuration)); } } else { phases.Add(new PhaseData(heatWave.Time, fightDuration)); } } else { phases.Add(new PhaseData(0, fightDuration)); } string[] namesMat = new[] { "Ice Phase", "Fire Phase", "Storm Phase", "Abomination Phase" }; for (int i = 1; i < phases.Count; i++) { phases[i].Name = namesMat[i - 1]; phases[i].DrawStart = i > 1; phases[i].AddTarget(mainTarget); } return(phases); }
public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases) { List <PhaseData> phases = GetInitialPhase(log); NPC voice = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.ClawOfTheFallen); NPC claw = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.VoiceOfTheFallen); if (voice == null || claw == null) { throw new InvalidOperationException("Error Encountered: Claw or Voice not found"); } phases[0].Targets.Add(voice); phases[0].Targets.Add(claw); var fightEnd = log.FightData.FightEnd; if (!requirePhases) { return(phases); } // List <PhaseData> unmergedPhases = GetPhasesByInvul(log, 762, claw, false, true); for (int i = 0; i < unmergedPhases.Count; i++) { unmergedPhases[i].Name = "Phase " + (i + 1); unmergedPhases[i].Targets.Add(claw); unmergedPhases[i].Targets.Add(voice); } phases.AddRange(unmergedPhases); // int voiceAndClawCount = 0; var offset = 1; foreach (NPC voiceAndClaw in Targets.Where(x => x.ID == (int)ParseEnum.TargetIDS.VoiceAndClaw)) { EnterCombatEvent enterCombat = log.CombatData.GetEnterCombatEvents(voiceAndClaw.AgentItem).FirstOrDefault(); PhaseData nextUnmergedPhase = unmergedPhases.Count > offset + 1 ? unmergedPhases[offset] : null; if (enterCombat != null) { var phase = new PhaseData(enterCombat.Time, nextUnmergedPhase != null ? nextUnmergedPhase.Start : Math.Min(fightEnd, voiceAndClaw.LastAware), "Voice and Claw " + ++voiceAndClawCount); phase.Targets.Add(voiceAndClaw); phases.Add(phase); offset++; } } // AbstractBuffEvent enrage = log.CombatData.GetBuffData(58619).FirstOrDefault(x => x is BuffApplyEvent); if (enrage != null) { var phase = new PhaseData(enrage.Time, log.FightData.FightEnd, "Enrage"); phase.Targets.Add(claw.AgentItem == enrage.To ? claw : voice); phases.Add(phase); } phases.Sort((x, y) => x.Start.CompareTo(y.Start)); return(phases); }
private static AbstractBuffEvent GetInvulXeraEvent(ParsedEvtcLog log, AbstractSingleActor xera) { AbstractBuffEvent determined = log.CombatData.GetBuffData(762).FirstOrDefault(x => x.To == xera.AgentItem && x is BuffApplyEvent); if (determined == null) { determined = log.CombatData.GetBuffData(34113).FirstOrDefault(x => x.To == xera.AgentItem && x is BuffApplyEvent); } return(determined); }
internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases) { List <PhaseData> phases = GetInitialPhase(log); NPC voice = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.ClawOfTheFallen); NPC claw = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.VoiceOfTheFallen); if (voice == null || claw == null) { throw new MissingKeyActorsException("Claw or Voice not found"); } phases[0].AddTarget(voice); phases[0].AddTarget(claw); long fightEnd = log.FightData.FightEnd; if (!requirePhases) { return(phases); } // List <PhaseData> unmergedPhases = GetPhasesByInvul(log, 762, claw, false, true); for (int i = 0; i < unmergedPhases.Count; i++) { unmergedPhases[i].Name = "Phase " + (i + 1); unmergedPhases[i].AddTarget(claw); unmergedPhases[i].AddTarget(voice); } phases.AddRange(unmergedPhases); // int voiceAndClawCount = 0; int offset = 1; foreach (NPC voiceAndClaw in Targets.Where(x => x.ID == (int)ArcDPSEnums.TargetID.VoiceAndClaw)) { EnterCombatEvent enterCombat = log.CombatData.GetEnterCombatEvents(voiceAndClaw.AgentItem).FirstOrDefault(); PhaseData nextUnmergedPhase = unmergedPhases.Count > offset + 1 ? unmergedPhases[offset] : null; if (enterCombat != null) { var phase = new PhaseData(enterCombat.Time, nextUnmergedPhase != null ? nextUnmergedPhase.Start : Math.Min(fightEnd, voiceAndClaw.LastAware), "Voice and Claw " + ++voiceAndClawCount); phase.AddTarget(voiceAndClaw); phases.Add(phase); offset++; } } // AbstractBuffEvent enrage = log.CombatData.GetBuffData(58619).FirstOrDefault(x => x is BuffApplyEvent); if (enrage != null) { var phase = new PhaseData(enrage.Time, log.FightData.FightEnd, "Enrage"); phase.AddTarget(claw.AgentItem == enrage.To ? claw : voice); phases.Add(phase); } return(phases); }
private static int CompareBuffEventType(AbstractBuffEvent x, AbstractBuffEvent y) { if (x.Time < y.Time) { return(-1); } else if (x.Time > y.Time) { return(1); } else { return(x.CompareTo(y)); } }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { NPC mainTarget = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.SoullessHorror); if (mainTarget == null) { throw new InvalidOperationException("Soulless Horror not found"); } AbstractBuffEvent buffOnDeath = combatData.GetBuffData(895).Where(x => x.To == mainTarget.AgentItem && x is BuffApplyEvent).LastOrDefault(); if (buffOnDeath != null) { fightData.SetSuccess(true, buffOnDeath.Time); } } }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { NPC mainTarget = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.SoullessHorror); if (mainTarget == null) { throw new MissingKeyActorsException("Soulless Horror not found"); } AbstractBuffEvent buffOnDeath = combatData.GetBuffData(895).Where(x => x.To == mainTarget.AgentItem && x is BuffApplyEvent).LastOrDefault(); if (buffOnDeath != null) { fightData.SetSuccess(true, buffOnDeath.Time); } } }
internal override void ComputePlayerCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay) { var green = log.CombatData.GetBuffData(47776).Where(x => x.To == p.AgentItem && x is BuffApplyEvent).ToList(); foreach (AbstractBuffEvent c in green) { int duration = 45000; AbstractBuffEvent removedBuff = log.CombatData.GetBuffRemoveAllData(47776).FirstOrDefault(x => x.To == p.AgentItem && x.Time > c.Time && x.Time < c.Time + duration); int start = (int)c.Time; int end = start + duration; if (removedBuff != null) { end = (int)removedBuff.Time; } replay.Decorations.Add(new CircleDecoration(true, 0, 100, (start, end), "rgba(100, 200, 255, 0.25)", new AgentConnector(p))); } }
public void Add(ParsedEvtcLog log, Buff buff, AbstractBuffEvent buffEvent) { if (!buffEvent.IsBuffSimulatorCompliant(log.FightData.FightEnd, log.CombatData.HasStackIDs)) { return; } buffEvent.TryFindSrc(log); if (_dict.TryGetValue(buff.ID, out List <AbstractBuffEvent> list)) { list.Add(buffEvent); return; } _dict[buff.ID] = new List <AbstractBuffEvent>() { buffEvent }; }
internal override void ComputePlayerCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay) { var spiritTransform = log.CombatData.GetBuffData(SkillIDs.FracturedSpirit).Where(x => x.To == p.AgentItem && x is BuffApplyEvent).ToList(); foreach (AbstractBuffEvent c in spiritTransform) { int duration = 30000; AbstractBuffEvent removedBuff = log.CombatData.GetBuffRemoveAllData(SkillIDs.MortalCoilStatueOfDeath).FirstOrDefault(x => x.To == p.AgentItem && x.Time > c.Time && x.Time < c.Time + duration); int start = (int)c.Time; int end = start + duration; if (removedBuff != null) { end = (int)removedBuff.Time; } replay.Decorations.Add(new CircleDecoration(true, 0, 100, (start, end), "rgba(0, 50, 200, 0.3)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, start + duration, 100, (start, end), "rgba(0, 50, 200, 0.5)", new AgentConnector(p))); } }
public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay) { List <AbstractBuffEvent> spiritTransform = log.CombatData.GetBoonData(46950).Where(x => x.To == p.AgentItem && x is BuffApplyEvent).ToList(); foreach (AbstractBuffEvent c in spiritTransform) { int duration = 30000; AbstractBuffEvent removedBuff = log.CombatData.GetBoonData(48583).FirstOrDefault(x => x.To == p.AgentItem && x is BuffRemoveAllEvent && x.Time > c.Time && x.Time < c.Time + duration); int start = (int)c.Time; int end = start + duration; if (removedBuff != null) { end = (int)removedBuff.Time; } replay.Actors.Add(new CircleActor(true, 0, 100, (start, end), "rgba(0, 50, 200, 0.3)", new AgentConnector(p))); replay.Actors.Add(new CircleActor(true, start + duration, 100, (start, end), "rgba(0, 50, 200, 0.5)", new AgentConnector(p))); } }
protected static void SetSuccessByBuffCount(CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents, NPC target, long buffID, int count) { if (target == null) { return; } List <AbstractBuffEvent> invulsTarget = GetFilteredList(combatData, buffID, target, true); if (invulsTarget.Count == count) { AbstractBuffEvent last = invulsTarget.Last(); if (!(last is BuffApplyEvent)) { SetSuccessByCombatExit(new List <NPC> { target }, combatData, fightData, playerAgents); } } }
/// <summary> /// Calculates on which phase the log started by checking Soo-Won's initial health and invulnerability buffs. /// </summary> /// /// <returns>An integer indicating on which phase the log started: /// <code> /// 0: 100% - 80% /// 1: First Greens /// 2: 80% - 60% /// 3: First Spear /// 4: First Champions /// 5: 60% - 40% /// 6: Second Greens /// 7: 40% - 20% /// 8: Second Spear /// 9: Second Champions /// 10: 20% - 0% /// </code> /// </returns> private static int GetPhaseOffset(ParsedEvtcLog log, AbstractSingleActor mainTarget) { double initialHealth = mainTarget.GetCurrentHealthPercent(log, 0); Func <Func <BuffApplyEvent, bool>, BuffApplyEvent> targetBuffs = log.CombatData.GetBuffData(mainTarget.AgentItem).OfType <BuffApplyEvent>().FirstOrDefault; AbstractBuffEvent initialInvuln = targetBuffs(x => x.Initial && x.BuffID == Invulnerability757); AbstractBuffEvent initialDmgImmunity = targetBuffs(x => x.Initial && x.BuffID == SooWonSpearPhaseInvul); // spear phase int offset = 0; if (initialHealth <= 80 && initialHealth > 60) { offset = 2; } else if (initialHealth <= 60 && initialHealth > 40) { offset = 5; } else if (initialHealth <= 40 && initialHealth > 20) { offset = 7; } else if (initialHealth <= 20 && initialHealth > 0) { offset = 10; } if (offset > 0) { if (initialInvuln != null) { offset--; } else if (initialDmgImmunity != null) { offset++; } } return(offset); }
/// <summary> /// Returns true if the buff count was not reached so that another method can be called, if necessary /// </summary> protected static bool SetSuccessByBuffCount(CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents, AbstractSingleActor target, long buffID, int count) { if (target == null) { return(false); } var invulsTarget = GetFilteredList(combatData, buffID, target, true, false).Where(x => x.Time >= 0).ToList(); if (invulsTarget.Count == count) { AbstractBuffEvent last = invulsTarget.Last(); if (!(last is BuffApplyEvent)) { SetSuccessByCombatExit(new List <AbstractSingleActor> { target }, combatData, fightData, playerAgents); return(false); } } return(true); }
internal override List <AbstractBuffEvent> SpecialBuffEventProcess(CombatData combatData, SkillData skillData) { var res = new List <AbstractBuffEvent>(); IReadOnlyList <AbstractBuffEvent> sappingSurges = combatData.GetBuffData(SappingSurge); var sappingSurgeByDst = sappingSurges.GroupBy(x => x.To).ToDictionary(x => x.Key, x => x.ToList()); foreach (KeyValuePair <AgentItem, List <AbstractBuffEvent> > pair in sappingSurgeByDst.Where(x => x.Value.Exists(y => y is BuffRemoveSingleEvent))) { var sglRemovals = pair.Value.Where(x => x is BuffRemoveSingleEvent).ToList(); foreach (AbstractBuffEvent sglRemoval in sglRemovals) { AbstractBuffEvent ba = pair.Value.LastOrDefault(x => x is BuffApplyEvent && Math.Abs(x.Time - sglRemoval.Time) < 5); if (ba != null) { res.Add(new BuffRemoveAllEvent(sglRemoval.CreditedBy, pair.Key, ba.Time - 1, int.MaxValue, ba.BuffSkill, 0, int.MaxValue)); res.Add(new BuffRemoveManualEvent(sglRemoval.CreditedBy, pair.Key, ba.Time - 1, int.MaxValue, ba.BuffSkill)); } } } return(res); }
public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases) { long start = 0; long fightDuration = log.FightData.FightEnd; List <PhaseData> phases = GetInitialPhase(log); NPC mainTarget = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.Xera); if (mainTarget == null) { throw new InvalidOperationException("Error Encountered: Xera not found"); } phases[0].Targets.Add(mainTarget); if (!requirePhases) { return(phases); } long end = 0; AbstractBuffEvent invulXera = log.CombatData.GetBuffData(762).Find(x => x.To == mainTarget.AgentItem && x is BuffApplyEvent) ?? log.CombatData.GetBuffData(34113).Find(x => x.To == mainTarget.AgentItem && x is BuffApplyEvent); if (invulXera != null) { end = invulXera.Time; phases.Add(new PhaseData(start, end)); // split happened if (_specialSplit > 0) { mainTarget.SetManualHealth(24085950); start = _specialSplit; //mainTarget.AddCustomCastLog(end, -5, (int)(start - end), ParseEnum.Activation.None, (int)(start - end), ParseEnum.Activation.None, log); phases.Add(new PhaseData(start, fightDuration)); } } for (int i = 1; i < phases.Count; i++) { phases[i].Name = "Phase " + i; phases[i].Targets.Add(mainTarget); } return(phases); }
internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases) { long fightDuration = log.FightData.FightEnd; List <PhaseData> phases = GetInitialPhase(log); NPC mainTarget = GetMainTarget(); if (mainTarget == null) { throw new MissingKeyActorsException("Xera not found"); } phases[0].AddTarget(mainTarget); if (requirePhases) { AbstractBuffEvent invulXera = GetInvulXeraEvent(log, mainTarget); // split happened if (invulXera != null) { var phase1 = new PhaseData(0, invulXera.Time, "Phase 1"); phase1.AddTarget(mainTarget); phases.Add(phase1); var glidingEndTime = _xeraSecondPhaseStartTime > 0 ? _xeraSecondPhaseStartTime : fightDuration; var glidingPhase = new PhaseData(invulXera.Time, glidingEndTime, "Gliding"); glidingPhase.AddTargets(Targets.Where(t => t.ID == (int)ArcDPSEnums.TrashID.ChargedBloodstone)); phases.Add(glidingPhase); if (_xeraSecondPhaseStartTime > 0) { var phase2 = new PhaseData(_xeraSecondPhaseStartTime, fightDuration, "Phase 2"); mainTarget.SetManualHealth(24085950); phase2.AddTarget(mainTarget); phase2.AddTargets(Targets.Where(t => t.ID == (int)ArcDPSEnums.TrashID.BloodstoneShard)); //mainTarget.AddCustomCastLog(end, -5, (int)(start - end), ParseEnum.Activation.None, (int)(start - end), ParseEnum.Activation.None, log); phases.Add(phase2); } } } return(phases); }
private static void AddMatthiasBubbles(long buffID, NPC target, ParsedEvtcLog log, CombatReplay replay) { List <AbstractBuffEvent> shields = GetFilteredList(log.CombatData, buffID, target, true); int start = 0; for (int i = 0; i < shields.Count; i++) { AbstractBuffEvent buffEvent = shields[i]; if (buffEvent is BuffApplyEvent) { start = (int)buffEvent.Time; if (i == shields.Count - 1) { replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)start, (int)log.FightData.FightEnd), "rgba(255, 0, 255, 0.5)", new AgentConnector(target))); } } else { replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)start, (int)buffEvent.Time), "rgba(255, 0, 255, 0.5)", new AgentConnector(target))); } } }
protected static List <PhaseData> GetPhasesByInvul(ParsedEvtcLog log, long skillID, NPC mainTarget, bool addSkipPhases, bool beginWithStart) { long fightDuration = log.FightData.FightEnd; var phases = new List <PhaseData>(); long last = 0; List <AbstractBuffEvent> invuls = GetFilteredList(log.CombatData, skillID, mainTarget, beginWithStart); invuls.RemoveAll(x => x.Time < 0); for (int i = 0; i < invuls.Count; i++) { AbstractBuffEvent c = invuls[i]; if (c is BuffApplyEvent) { long end = Math.Min(c.Time, fightDuration); phases.Add(new PhaseData(last, end)); /*if (i == invuls.Count - 1) * { * mainTarget.AddCustomCastLog(end, -5, (int)(fightDuration - end), ParseEnum.Activation.None, (int)(fightDuration - end), ParseEnum.Activation.None, log); * }*/ last = end; } else { long end = Math.Min(c.Time, fightDuration); if (addSkipPhases) { phases.Add(new PhaseData(last, end)); } //mainTarget.AddCustomCastLog(last, -5, (int)(end - last), ParseEnum.Activation.None, (int)(end - last), ParseEnum.Activation.None, log); last = end; } } if (fightDuration - last > ParserHelper.PhaseTimeLimit) { phases.Add(new PhaseData(last, fightDuration)); } return(phases); }
protected List <PhaseData> GetPhasesByInvul(ParsedLog log, long skillID, Target mainTarget, bool addSkipPhases, bool beginWithStart) { long fightDuration = log.FightData.FightDuration; List <PhaseData> phases = new List <PhaseData>(); long last = 0; List <AbstractBuffEvent> invuls = GetFilteredList(log.CombatData, skillID, mainTarget, beginWithStart); for (int i = 0; i < invuls.Count; i++) { AbstractBuffEvent c = invuls[i]; if (c is BuffApplyEvent) { long end = c.Time; phases.Add(new PhaseData(last, end)); /*if (i == invuls.Count - 1) * { * mainTarget.AddCustomCastLog(end, -5, (int)(fightDuration - end), ParseEnum.Activation.None, (int)(fightDuration - end), ParseEnum.Activation.None, log); * }*/ last = end; } else { long end = c.Time; if (addSkipPhases) { phases.Add(new PhaseData(last, end)); } //mainTarget.AddCustomCastLog(last, -5, (int)(end - last), ParseEnum.Activation.None, (int)(end - last), ParseEnum.Activation.None, log); last = end; } } if (fightDuration - last > 5000) { phases.Add(new PhaseData(last, fightDuration)); } return(phases); }
private static void AddSplitPhase(List <PhaseData> phases, IReadOnlyList <AbstractSingleActor> targets, AbstractSingleActor ministerLi, ParsedEvtcLog log, int phaseID) { if (targets.All(x => x != null)) { EnterCombatEvent cbtEnter = null; foreach (NPC target in targets) { cbtEnter = log.CombatData.GetEnterCombatEvents(target.AgentItem).LastOrDefault(); if (cbtEnter != null) { break; } } if (cbtEnter != null) { AbstractBuffEvent nextPhaseStartEvt = log.CombatData.GetBuffData(ministerLi.AgentItem).FirstOrDefault(x => x is BuffRemoveAllEvent && x.BuffID == 762 && x.Time > cbtEnter.Time); long phaseEnd = nextPhaseStartEvt != null ? nextPhaseStartEvt.Time : log.FightData.FightEnd; var addPhase = new PhaseData(cbtEnter.Time, phaseEnd, "Split Phase " + phaseID); addPhase.AddTargets(targets); phases.Add(addPhase); } } }
public override List <AbstractBuffEvent> SpecialBuffEventProcess(Dictionary <AgentItem, List <AbstractBuffEvent> > buffsByDst, Dictionary <long, List <AbstractBuffEvent> > buffsById, SkillData skillData) { var res = new List <AbstractBuffEvent>(); if (buffsById.TryGetValue(56118, out List <AbstractBuffEvent> list)) { var sappingSurgeByDst = list.GroupBy(x => x.To).ToDictionary(x => x.Key, x => x.ToList()); foreach (KeyValuePair <AgentItem, List <AbstractBuffEvent> > pair in sappingSurgeByDst.Where(x => x.Value.Exists(y => y is BuffRemoveSingleEvent))) { var sglRemovals = pair.Value.Where(x => x is BuffRemoveSingleEvent).ToList(); foreach (AbstractBuffEvent sglRemoval in sglRemovals) { AbstractBuffEvent ba = pair.Value.LastOrDefault(x => x is BuffApplyEvent && Math.Abs(x.Time - sglRemoval.Time) < 5); if (ba != null) { res.Add(new BuffRemoveAllEvent(sglRemoval.By, pair.Key, ba.Time - 1, int.MaxValue, ba.BuffSkill, 0, int.MaxValue)); res.Add(new BuffRemoveManualEvent(sglRemoval.By, pair.Key, ba.Time - 1, int.MaxValue, ba.BuffSkill)); } } } } return(res); }