public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success && _specialSplitLogTime > 0) { Target target = Targets.Find(x => x.ID == TriggerID); if (target == null) { throw new InvalidOperationException("Target for success by combat exit not found"); } List <AttackTargetEvent> attackTargets = combatData.GetAttackTargetEvents(target.AgentItem); if (attackTargets.Count == 0) { return; } long specialSplitTime = fightData.ToFightSpace(_specialSplitLogTime); AgentItem attackTarget = attackTargets.Last().AttackTarget; List <ExitCombatEvent> playerExits = new List <ExitCombatEvent>(); foreach (AgentItem a in playerAgents) { playerExits.AddRange(combatData.GetExitCombatEvents(a)); } ExitCombatEvent lastPlayerExit = playerExits.Count > 0 ? playerExits.MaxBy(x => x.Time) : null; TargetableEvent notAttackableEvent = combatData.GetTargetableEvents(attackTarget).LastOrDefault(x => !x.Targetable && x.Time > specialSplitTime); AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(target.AgentItem).LastOrDefault(x => (x.Damage > 0) && (playerAgents.Contains(x.From) || playerAgents.Contains(x.MasterFrom))); if (notAttackableEvent != null && lastDamageTaken != null && lastPlayerExit != null) { fightData.SetSuccess(lastPlayerExit.Time > notAttackableEvent.Time + 1000, fightData.ToLogSpace(lastDamageTaken.Time)); } } }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success && _specialSplit > 0) { NPC target = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.Deimos); if (target == null) { throw new InvalidOperationException("Deimos not found"); } List <AttackTargetEvent> attackTargets = combatData.GetAttackTargetEvents(target.AgentItem); if (attackTargets.Count == 0) { return; } long specialSplitTime = _specialSplit; AgentItem attackTarget = attackTargets.Last().AttackTarget; // sanity check TargetableEvent attackableEvent = combatData.GetTargetableEvents(attackTarget).LastOrDefault(x => x.Targetable && x.Time > specialSplitTime - GeneralHelper.ServerDelayConstant); if (attackableEvent == null) { return; } TargetableEvent notAttackableEvent = combatData.GetTargetableEvents(attackTarget).LastOrDefault(x => !x.Targetable && x.Time > attackableEvent.Time); if (notAttackableEvent == null) { return; } var playerExits = new List <ExitCombatEvent>(); foreach (AgentItem a in playerAgents) { playerExits.AddRange(combatData.GetExitCombatEvents(a)); } ExitCombatEvent lastPlayerExit = playerExits.Count > 0 ? playerExits.MaxBy(x => x.Time) : null; AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(target.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTaken != null && lastPlayerExit != null) { fightData.SetSuccess(lastPlayerExit.Time > notAttackableEvent.Time + 1000, lastDamageTaken.Time); } } }
internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases) { List <PhaseData> phases = GetInitialPhase(log); var subPhasesData = new List <(long start, long end, string name, NPC target)>(); foreach (NPC target in Targets) { long mainPhaseEnd = Math.Min(target.LastAware, log.FightData.FightEnd); switch (target.ID) { case (int)ArcDPSEnums.TrashID.VoidSaltsprayDragon: case (int)ArcDPSEnums.TrashID.VoidTimeCaster: case (int)ArcDPSEnums.TrashID.VoidObliterator: subPhasesData.Add((target.FirstAware, mainPhaseEnd, target.Character, target)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidJormag: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Jormag", target)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidKralkatorrik: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Kralkatorrik", target)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidMordremoth: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Mordremoth", target)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidPrimordious: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Primordious", target)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidSooWon: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Soo-Won", target)); AttackTargetEvent attackTargetEvent = log.CombatData.GetAttackTargetEvents(target.AgentItem).FirstOrDefault(); if (attackTargetEvent != null) { var targetables = log.CombatData.GetTargetableEvents(attackTargetEvent.AttackTarget).Where(x => x.Time >= target.FirstAware).ToList(); var targetOns = targetables.Where(x => x.Targetable).ToList(); var targetOffs = targetables.Where(x => !x.Targetable).ToList(); int id = 0; foreach (TargetableEvent targetOn in targetOns) { long start = targetOn.Time; long end = log.FightData.FightEnd; TargetableEvent targetOff = targetOffs.FirstOrDefault(x => x.Time > start); if (targetOff != null) { end = targetOff.Time; } subPhasesData.Add((start, end, "Soo-Won " + (++id), target)); } } break; case (int)ArcDPSEnums.TargetID.TheDragonVoidZhaitan: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Zhaitan", target)); break; case (int)ArcDPSEnums.TargetID.DummyTarget: phases[0].AddTarget(target); break; } } if (!requirePhases) { return(phases); } foreach ((long start, long end, string name, NPC target)subPhaseData in subPhasesData) { var subPhase = new PhaseData(subPhaseData.start, subPhaseData.end, subPhaseData.name); subPhase.AddTarget(subPhaseData.target); phases.Add(subPhase); } return(phases); }
internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases) { List <PhaseData> phases = GetInitialPhase(log); var subPhasesData = new List <(long start, long end, string name, NPC target, bool canBeSubPhase)>(); foreach (NPC target in Targets) { long mainPhaseEnd = Math.Min(target.LastAware, log.FightData.FightEnd); switch (target.ID) { case (int)ArcDPSEnums.TrashID.VoidSaltsprayDragon: case (int)ArcDPSEnums.TrashID.VoidTimeCaster: case (int)ArcDPSEnums.TrashID.VoidObliterator: case (int)ArcDPSEnums.TrashID.VoidGoliath: subPhasesData.Add((target.FirstAware, mainPhaseEnd, target.Character, target, false)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidJormag: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Jormag", target, true)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidKralkatorrik: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Kralkatorrik", target, true)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidMordremoth: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Mordremoth", target, true)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidPrimordus: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Primordus", target, true)); break; case (int)ArcDPSEnums.TargetID.TheDragonVoidSooWon: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Soo-Won", target, true)); AttackTargetEvent attackTargetEvent = log.CombatData.GetAttackTargetEvents(target.AgentItem).FirstOrDefault(); if (attackTargetEvent != null) { var targetables = log.CombatData.GetTargetableEvents(attackTargetEvent.AttackTarget).Where(x => x.Time >= target.FirstAware).ToList(); var targetOns = targetables.Where(x => x.Targetable).ToList(); var targetOffs = targetables.Where(x => !x.Targetable).ToList(); int id = 0; foreach (TargetableEvent targetOn in targetOns) { long start = targetOn.Time; long end = log.FightData.FightEnd; TargetableEvent targetOff = targetOffs.FirstOrDefault(x => x.Time > start); if (targetOff != null) { end = targetOff.Time; } subPhasesData.Add((start, end, "Soo-Won " + (++id), target, true)); } } break; case (int)ArcDPSEnums.TargetID.TheDragonVoidZhaitan: phases[0].AddTarget(target); subPhasesData.Add((target.FirstAware, mainPhaseEnd, "Zhaitan", target, true)); break; case (int)ArcDPSEnums.TargetID.DummyTarget: phases[0].AddTarget(target); break; } } if (!requirePhases) { return(phases); } foreach ((long start, long end, string name, NPC target, bool canBeSubPhase) in subPhasesData) { var subPhase = new PhaseData(start, end, name); subPhase.CanBeSubPhase = canBeSubPhase; subPhase.AddTarget(target); phases.Add(subPhase); } int purificationID = 0; foreach (NPC voidAmal in Targets.Where(x => x.ID == (int)ArcDPSEnums.TrashID.PushableVoidAmalgamate || x.ID == (int)ArcDPSEnums.TrashID.KillableVoidAmalgamate)) { long end; DeadEvent deadEvent = log.CombatData.GetDeadEvents(voidAmal.AgentItem).LastOrDefault(); if (deadEvent == null) { DespawnEvent despawnEvent = log.CombatData.GetDespawnEvents(voidAmal.AgentItem).LastOrDefault(); if (despawnEvent == null) { end = voidAmal.LastAware; } else { end = despawnEvent.Time; } } else { end = deadEvent.Time; } var purificationPhase = new PhaseData(Math.Max(voidAmal.FirstAware, 0), Math.Min(end, log.FightData.FightEnd), "Purification " + (++purificationID)); purificationPhase.AddTarget(voidAmal); phases.Add(purificationPhase); } return(phases); }