예제 #1
0
 /// <summary>
 /// Override times in a manner that the phase englobes the targets present in the phase (if possible)
 /// </summary>
 /// <param name="log"></param>
 internal void OverrideTimes(ParsedEvtcLog log)
 {
     if (Targets.Count > 0)
     {
         long end   = long.MinValue;
         long start = long.MaxValue;
         foreach (AbstractSingleActor target in Targets)
         {
             long       startTime = target.FirstAware;
             SpawnEvent spawned   = log.CombatData.GetSpawnEvents(target.AgentItem).FirstOrDefault();
             if (spawned != null)
             {
                 startTime = spawned.Time;
             }
             EnterCombatEvent enterCombat = log.CombatData.GetEnterCombatEvents(target.AgentItem).FirstOrDefault();
             if (enterCombat != null)
             {
                 startTime = enterCombat.Time;
             }
             long      deadTime = target.LastAware;
             DeadEvent died     = log.CombatData.GetDeadEvents(target.AgentItem).FirstOrDefault();
             if (died != null)
             {
                 deadTime = died.Time;
             }
             start = Math.Min(start, startTime);
             end   = Math.Max(end, deadTime);
         }
         Start = Math.Max(Math.Max(Start, start), 0);
         End   = Math.Min(Math.Min(End, end), log.FightData.FightEnd);
     }
     DurationInM  = (End - Start) / 60000;
     DurationInMS = (End - Start);
     DurationInS  = (End - Start) / 1000;
 }
예제 #2
0
        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);
        }
        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);
        }
        protected static void SetSuccessByCombatExit(List <NPC> targets, CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents)
        {
            if (targets.Count == 0)
            {
                return;
            }
            var playerExits       = new List <ExitCombatEvent>();
            var targetExits       = new List <ExitCombatEvent>();
            var lastTargetDamages = new List <AbstractDamageEvent>();

            foreach (AgentItem a in playerAgents)
            {
                playerExits.AddRange(combatData.GetExitCombatEvents(a));
            }
            foreach (NPC t in targets)
            {
                EnterCombatEvent enterCombat = combatData.GetEnterCombatEvents(t.AgentItem).LastOrDefault();
                if (enterCombat != null)
                {
                    targetExits.AddRange(combatData.GetExitCombatEvents(t.AgentItem).Where(x => x.Time > enterCombat.Time));
                }
                else
                {
                    targetExits.AddRange(combatData.GetExitCombatEvents(t.AgentItem));
                }
                AbstractDamageEvent lastDamage = combatData.GetDamageTakenData(t.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster()));
                if (lastDamage != null)
                {
                    lastTargetDamages.Add(lastDamage);
                }
            }
            ExitCombatEvent     lastPlayerExit  = playerExits.Count > 0 ? playerExits.MaxBy(x => x.Time) : null;
            ExitCombatEvent     lastTargetExit  = targetExits.Count > 0 ? targetExits.MaxBy(x => x.Time) : null;
            AbstractDamageEvent lastDamageTaken = lastTargetDamages.Count > 0 ? lastTargetDamages.MaxBy(x => x.Time) : null;

            if (lastTargetExit != null && lastDamageTaken != null)
            {
                if (lastPlayerExit != null)
                {
                    fightData.SetSuccess(lastPlayerExit.Time > lastTargetExit.Time + 1000, lastDamageTaken.Time);
                }
                else if (fightData.FightEnd > targets.Max(x => x.LastAware) + 2000)
                {
                    fightData.SetSuccess(true, lastDamageTaken.Time);
                }
            }
        }
예제 #5
0
        protected static void SetSuccessByCombatExit(List <AbstractSingleActor> targets, CombatData combatData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents)
        {
            if (targets.Count == 0)
            {
                return;
            }
            var targetExits       = new List <ExitCombatEvent>();
            var lastTargetDamages = new List <AbstractHealthDamageEvent>();

            foreach (AbstractSingleActor t in targets)
            {
                EnterCombatEvent enterCombat = combatData.GetEnterCombatEvents(t.AgentItem).LastOrDefault();
                ExitCombatEvent  exitCombat;
                if (enterCombat != null)
                {
                    exitCombat = combatData.GetExitCombatEvents(t.AgentItem).Where(x => x.Time > enterCombat.Time).LastOrDefault();
                }
                else
                {
                    exitCombat = combatData.GetExitCombatEvents(t.AgentItem).LastOrDefault();
                }
                AbstractHealthDamageEvent lastDamage = combatData.GetDamageTakenData(t.AgentItem).LastOrDefault(x => (x.HealthDamage > 0) && playerAgents.Contains(x.From.GetFinalMaster()));
                if (exitCombat == null || lastDamage == null ||
                    combatData.GetAnimatedCastData(t.AgentItem).Any(x => x.Time > exitCombat.Time + ParserHelper.ServerDelayConstant) ||
                    combatData.GetDamageData(t.AgentItem).Any(x => x.Time > exitCombat.Time + ParserHelper.ServerDelayConstant && playerAgents.Contains(x.To)))
                {
                    return;
                }
                targetExits.Add(exitCombat);
                lastTargetDamages.Add(lastDamage);
            }
            ExitCombatEvent           lastTargetExit  = targetExits.Count > 0 ? targetExits.MaxBy(x => x.Time) : null;
            AbstractHealthDamageEvent lastDamageTaken = lastTargetDamages.Count > 0 ? lastTargetDamages.MaxBy(x => x.Time) : null;

            // Make sure the last damage has been done before last combat exit
            if (lastTargetExit != null && lastDamageTaken != null && lastTargetExit.Time + 150 >= lastDamageTaken.Time)
            {
                if (!AtLeastOnePlayerAlive(combatData, fightData, lastTargetExit.Time, playerAgents))
                {
                    return;
                }
                fightData.SetSuccess(true, lastDamageTaken.Time);
            }
        }
        public static void SetPhasePerTarget(NPC target, List <PhaseData> phases, ParsedLog log)
        {
            long             fightDuration = log.FightData.FightEnd;
            EnterCombatEvent phaseStart    = log.CombatData.GetEnterCombatEvents(target.AgentItem).LastOrDefault();

            if (phaseStart != null)
            {
                long      start    = phaseStart.Time;
                DeadEvent phaseEnd = log.CombatData.GetDeadEvents(target.AgentItem).LastOrDefault();
                long      end      = fightDuration;
                if (phaseEnd != null)
                {
                    end = phaseEnd.Time;
                }
                var phase = new PhaseData(start, Math.Min(end, log.FightData.FightEnd));
                phase.Targets.Add(target);
                phases.Add(phase);
            }
        }
        protected static void SetSuccessByCombatExit(List <NPC> targets, CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents)
        {
            if (targets.Count == 0)
            {
                return;
            }
            var targetExits       = new List <ExitCombatEvent>();
            var lastTargetDamages = new List <AbstractHealthDamageEvent>();

            foreach (NPC t in targets)
            {
                EnterCombatEvent enterCombat = combatData.GetEnterCombatEvents(t.AgentItem).LastOrDefault();
                if (enterCombat != null)
                {
                    targetExits.AddRange(combatData.GetExitCombatEvents(t.AgentItem).Where(x => x.Time > enterCombat.Time));
                }
                else
                {
                    targetExits.AddRange(combatData.GetExitCombatEvents(t.AgentItem));
                }
                AbstractHealthDamageEvent lastDamage = combatData.GetDamageTakenData(t.AgentItem).LastOrDefault(x => (x.HealthDamage > 0) && playerAgents.Contains(x.From.GetFinalMaster()));
                if (lastDamage != null)
                {
                    lastTargetDamages.Add(lastDamage);
                }
            }
            ExitCombatEvent           lastTargetExit  = targetExits.Count > 0 ? targetExits.MaxBy(x => x.Time) : null;
            AbstractHealthDamageEvent lastDamageTaken = lastTargetDamages.Count > 0 ? lastTargetDamages.MaxBy(x => x.Time) : null;

            // Make sure the last damage has been done before last combat exit
            if (lastTargetExit != null && lastDamageTaken != null && lastTargetExit.Time + 100 >= lastDamageTaken.Time)
            {
                if (!AtLeastOnePlayerAlive(combatData, fightData, lastTargetExit.Time, playerAgents))
                {
                    return;
                }
                fightData.SetSuccess(true, lastDamageTaken.Time);
            }
        }
예제 #8
0
 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);
         }
     }
 }
예제 #9
0
        public static void SetPhasePerTarget(NPC target, List <PhaseData> phases, ParsedEvtcLog log)
        {
            long             fightDuration = log.FightData.FightEnd;
            EnterCombatEvent phaseStart    = log.CombatData.GetEnterCombatEvents(target.AgentItem).LastOrDefault();

            if (phaseStart != null)
            {
                long      start    = phaseStart.Time;
                DeadEvent phaseEnd = log.CombatData.GetDeadEvents(target.AgentItem).LastOrDefault();
                long      end      = fightDuration;
                if (phaseEnd != null)
                {
                    end = phaseEnd.Time;
                }
                var phase = new PhaseData(start, Math.Min(end, log.FightData.FightEnd));
                phase.Targets.Add(target);
                switch (target.ID)
                {
                case (int)ArcDPSEnums.TargetID.Narella:
                    phase.Name = "Narella";
                    break;

                case (int)ArcDPSEnums.TargetID.Berg:
                    phase.Name = "Berg";
                    break;

                case (int)ArcDPSEnums.TargetID.Zane:
                    phase.Name = "Zane";
                    break;

                default:
                    throw new InvalidOperationException("Unknown target in Bandit Trio");
                }
                phases.Add(phase);
            }
        }
        internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases)
        {
            List <PhaseData>    phases  = GetInitialPhase(log);
            AbstractSingleActor fraenir = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.FraenirOfJormag);

            if (fraenir == null)
            {
                throw new MissingKeyActorsException("Fraenir of Jormag not found");
            }
            phases[0].AddTarget(fraenir);
            AbstractSingleActor icebrood = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.IcebroodConstructFraenir);

            if (icebrood != null)
            {
                phases[0].AddTarget(icebrood);
            }
            if (!requirePhases)
            {
                return(phases);
            }
            AbstractBuffEvent invulApplyFraenir = log.CombatData.GetBuffData(762).Where(x => x.To == fraenir.AgentItem && x is BuffApplyEvent).FirstOrDefault();

            if (invulApplyFraenir != null)
            {
                // split happened
                phases.Add(new PhaseData(0, invulApplyFraenir.Time, "Fraenir 1"));
                if (icebrood != null)
                {
                    // icebrood enters combat
                    EnterCombatEvent enterCombatIce = log.CombatData.GetEnterCombatEvents(icebrood.AgentItem).LastOrDefault();
                    if (enterCombatIce != null)
                    {
                        // icebrood phasing
                        AbstractBuffEvent invulApplyIce  = log.CombatData.GetBuffData(757).Where(x => x.To == icebrood.AgentItem && x is BuffApplyEvent).FirstOrDefault();
                        AbstractBuffEvent invulRemoveIce = log.CombatData.GetBuffData(757).Where(x => x.To == icebrood.AgentItem && x is BuffRemoveAllEvent).FirstOrDefault();
                        long icebroodStart = enterCombatIce.Time;
                        long icebroodEnd   = log.FightData.FightEnd;
                        if (invulApplyIce != null && invulRemoveIce != null)
                        {
                            long icebrood2Start = invulRemoveIce.Time;
                            phases.Add(new PhaseData(icebroodStart + 1, invulApplyIce.Time, "Icebrood 1"));
                            AbstractBuffEvent invulRemoveFraenir = log.CombatData.GetBuffData(762).Where(x => x.To == fraenir.AgentItem && x is BuffRemoveAllEvent).FirstOrDefault();
                            if (invulRemoveFraenir != null)
                            {
                                // fraenir came back
                                DeadEvent deadIce = log.CombatData.GetDeadEvents(icebrood.AgentItem).LastOrDefault();
                                if (deadIce != null)
                                {
                                    icebroodEnd = deadIce.Time;
                                }
                                else
                                {
                                    icebroodEnd = invulRemoveFraenir.Time - 1;
                                }
                                phases.Add(new PhaseData(invulRemoveFraenir.Time, log.FightData.FightEnd, "Fraenir 2"));
                            }
                            phases.Add(new PhaseData(icebrood2Start, icebroodEnd, "Icebrood 2"));
                        }
                        phases.Add(new PhaseData(icebroodStart, icebroodEnd, "Icebrood"));
                    }
                }
            }
            phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            for (int i = 1; i < phases.Count; i++)
            {
                PhaseData phase = phases[i];
                if (i == 1 || i == 5)
                {
                    phase.AddTarget(fraenir);
                }
                else
                {
                    phase.AddTarget(icebrood);
                }
            }
            return(phases);
        }
        internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases)
        {
            List <PhaseData>    phases = GetInitialPhase(log);
            AbstractSingleActor voice  = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.ClawOfTheFallen);
            AbstractSingleActor 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;

            foreach (AbstractSingleActor voiceAndClaw in Targets.Where(x => x.ID == (int)ArcDPSEnums.TargetID.VoiceAndClaw))
            {
                EnterCombatEvent enterCombat = log.CombatData.GetEnterCombatEvents(voiceAndClaw.AgentItem).FirstOrDefault();
                long             phaseStart  = 0;
                if (enterCombat != null)
                {
                    phaseStart = enterCombat.Time;
                }
                else
                {
                    phaseStart = voiceAndClaw.FirstAware;
                }
                PhaseData nextUnmergedPhase = unmergedPhases.FirstOrDefault(x => x.Start > phaseStart);
                long      phaseEnd          = Math.Min(fightEnd, voiceAndClaw.LastAware);
                if (nextUnmergedPhase != null)
                {
                    phaseEnd = nextUnmergedPhase.Start - 1;
                }
                var phase = new PhaseData(phaseStart, phaseEnd, "Voice and Claw " + ++voiceAndClawCount);
                phase.AddTarget(voiceAndClaw);
                phases.Add(phase);
            }
            //
            var  teleports       = voice.GetCastEvents(log, 0, log.FightData.FightDuration).Where(x => x.SkillId == 58382).ToList();
            long tpCount         = 0;
            long preTPPhaseStart = 0;

            foreach (AbstractCastEvent teleport in teleports)
            {
                long preTPPhaseEnd = Math.Min(teleport.Time, log.FightData.FightDuration);
                AbstractSingleActor voiceAndClaw = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.VoiceAndClaw && x.FirstAware >= preTPPhaseStart);
                if (voiceAndClaw != null)
                {
                    long oldEnd = preTPPhaseEnd;
                    preTPPhaseEnd = Math.Min(preTPPhaseEnd, voiceAndClaw.FirstAware);
                    // To handle position phase after merge phase end
                    if (oldEnd != preTPPhaseEnd)
                    {
                        PhaseData nextUnmergedPhase = unmergedPhases.FirstOrDefault(x => x.Start > voiceAndClaw.LastAware);
                        if (nextUnmergedPhase != null)
                        {
                            long postMergedStart = nextUnmergedPhase.Start + 1;
                            long postMergedEnd   = oldEnd;
                            var  phase           = new PhaseData(postMergedStart, postMergedEnd, "Position " + (++tpCount));
                            phase.AddTarget(claw);
                            phase.AddTarget(voice);
                            phases.Add(phase);
                        }
                    }
                }
                if (preTPPhaseEnd - preTPPhaseStart > 2000)
                {
                    var phase = new PhaseData(preTPPhaseStart, preTPPhaseEnd, "Position " + (++tpCount));
                    phase.AddTarget(claw);
                    phase.AddTarget(voice);
                    phases.Add(phase);
                }
                preTPPhaseStart = teleport.EndTime;
            }

            //
            AbstractBuffEvent enrage = log.CombatData.GetBuffData(SkillIDs.EnragedVC).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);
            }
            // Missing final position event
            {
                PhaseData nextUnmergedPhase = unmergedPhases.FirstOrDefault(x => x.Start > preTPPhaseStart);
                long      finalStart        = preTPPhaseStart;
                long      finalPositionEnd  = log.FightData.FightDuration;
                if (nextUnmergedPhase != null)
                {
                    finalStart = nextUnmergedPhase.Start + 1;
                }
                if (enrage != null)
                {
                    finalPositionEnd = enrage.Time;
                }
                if (finalPositionEnd - finalStart > 2000)
                {
                    var phase = new PhaseData(finalStart, finalPositionEnd, "Position " + (++tpCount));
                    phase.AddTarget(claw);
                    phase.AddTarget(voice);
                    phases.Add(phase);
                }
            }
            return(phases);
        }