private static void ComputeFightPhases(List <PhaseData> phases, IReadOnlyList <AbstractCastEvent> castLogs, long fightDuration, long start)
        {
            AbstractCastEvent shield = castLogs.FirstOrDefault(x => x.SkillId == 47396);

            // Dhuum brought down to 10%
            if (shield != null)
            {
                long end = shield.Time;
                phases.Add(new PhaseData(start, end, "Dhuum Fight"));
                AbstractCastEvent firstDamageable = castLogs.FirstOrDefault(x => x.SkillId == 47304 && x.Time >= end);
                // ritual started
                if (firstDamageable != null)
                {
                    phases.Add(new PhaseData(end, firstDamageable.Time, "Shielded Dhuum")
                    {
                        CanBeSubPhase = false
                    });
                    phases.Add(new PhaseData(firstDamageable.Time, fightDuration, "Ritual"));
                }
                else
                {
                    phases.Add(new PhaseData(end, fightDuration, "Shielded Dhuum")
                    {
                        CanBeSubPhase = false
                    });
                }
            }
        }
        // Main method
        public AgentItem TryFindSrc(AgentItem dst, long time, long extension, ParsedEvtcLog log, long buffID)
        {
            if (!_boonIds.Contains(buffID))
            {
                return(dst);
            }
            List <AgentItem> imperialImpactCheck = CouldBeImperialImpact(extension, time, log);

            if (imperialImpactCheck.Count > 1)
            {
                return(ParserHelper._unknownAgent);
            }
            int essenceOfSpeedCheck = CouldBeEssenceOfSpeed(dst, extension, buffID, log);

            // can only be the soulbeast
            if (essenceOfSpeedCheck == 1)
            {
                return(dst);
            }
            HashSet <long> idsToCheck = GetIDs(log, buffID, extension);

            if (idsToCheck.Any())
            {
                List <AbstractCastEvent> cls = GetExtensionSkills(log, time, idsToCheck);
                // If only one cast item
                if (cls.Count == 1)
                {
                    AbstractCastEvent item = cls.First();
                    // If uncertainty due to essence of speed, imbued melodies or imperial impact, return unknown
                    if (essenceOfSpeedCheck == 0 || CouldBeImbuedMelodies(item.Caster, time, extension, log) || imperialImpactCheck.Any())
                    {
                        return(ParserHelper._unknownAgent);
                    }
                    // otherwise the src is the caster
                    return(item.Caster);
                }
                // If no cast item and
                else if (!cls.Any())
                {
                    // If uncertainty due to imbued melodies, return unknown
                    if (CouldBeImbuedMelodies(dst, time, extension, log))
                    {
                        return(ParserHelper._unknownAgent);
                    }
                    // uncertainty due to essence of speed but not due to imperial impact
                    if (essenceOfSpeedCheck == 0 && !imperialImpactCheck.Any())
                    {
                        // the soulbeast
                        return(dst);
                    }
                    // uncertainty due to imperial impact but not due to essence of speed
                    if (essenceOfSpeedCheck == -1 && imperialImpactCheck.Count == 1)
                    {
                        // the vindicator
                        return(imperialImpactCheck.First());
                    }
                }
            }
            return(ParserHelper._unknownAgent);
        }
Ejemplo n.º 3
0
 internal JsonSkill(AbstractCastEvent cl)
 {
     CastTime   = (int)cl.Time;
     Duration   = cl.ActualDuration;
     TimeGained = cl.SavedDuration;
     Quickness  = cl.Acceleration;
 }
Ejemplo n.º 4
0
        private List <PhaseData> GetInBetweenSoulSplits(ParsedLog log, NPC dhuum, long mainStart, long mainEnd, bool hasRitual)
        {
            List <AbstractCastEvent> cls = dhuum.GetCastLogs(log, 0, log.FightData.FightEnd);
            var cataCycle  = cls.Where(x => x.SkillId == 48398).ToList();
            var gDeathmark = cls.Where(x => x.SkillId == 48210).ToList();

            if (gDeathmark.Count < cataCycle.Count)
            {
                return(new List <PhaseData>());
            }
            var  phases = new List <PhaseData>();
            long start  = mainStart;
            long end    = 0;
            int  i      = 0;

            foreach (AbstractCastEvent cl in cataCycle)
            {
                AbstractCastEvent clDeathmark = gDeathmark[i];
                end = Math.Min(clDeathmark.Time, mainEnd);
                phases.Add(new PhaseData(start, end, "Pre-Soulsplit " + ++i));
                start = cl.Time + cl.ActualDuration;
            }
            phases.Add(new PhaseData(start, mainEnd, hasRitual ? "Pre-Ritual" : "Pre-Wipe"));
            return(phases);
        }
Ejemplo n.º 5
0
        // Main method
        public AgentItem TryFindSrc(AgentItem dst, long time, long extension, ParsedLog log, long buffID)
        {
            if (!_boonIds.Contains(buffID))
            {
                return(dst);
            }
            int essenceOfSpeedCheck = CouldBeEssenceOfSpeed(dst, extension, log);

            if (essenceOfSpeedCheck != -1)
            {
                // unknown or self
                return(essenceOfSpeedCheck == 0 ? GeneralHelper.UnknownAgent : dst);
            }
            HashSet <long> idsToCheck = new HashSet <long>();

            if (DurationToIDs.TryGetValue(extension, out idsToCheck))
            {
                List <AbstractCastEvent> cls = GetExtensionSkills(log, time, idsToCheck);
                if (cls.Count == 1)
                {
                    AbstractCastEvent item = cls.First();
                    // Imbued Melodies check
                    if (CouldBeImbuedMelodies(item, time, extension, log))
                    {
                        return(GeneralHelper.UnknownAgent);
                    }
                    return(item.Caster);
                }
            }
            return(GeneralHelper.UnknownAgent);
        }
        private static List <PhaseData> GetInBetweenSoulSplits(ParsedEvtcLog log, NPC dhuum, long mainStart, long mainEnd, bool hasRitual)
        {
            IReadOnlyList <AbstractCastEvent> cls = dhuum.GetCastEvents(log, 0, log.FightData.FightEnd);
            var cataCycles  = cls.Where(x => x.SkillId == 48398).ToList();
            var gDeathmarks = cls.Where(x => x.SkillId == 48210).ToList();

            if (gDeathmarks.Count < cataCycles.Count)
            {
                // anomaly, don't do sub phases
                return(new List <PhaseData>());
            }
            var  phases = new List <PhaseData>();
            long start  = mainStart;
            long end    = 0;
            int  i      = 0;

            foreach (AbstractCastEvent cataCycle in cataCycles)
            {
                AbstractCastEvent gDeathmark = gDeathmarks[i];
                end = Math.Min(gDeathmark.Time, mainEnd);
                long soulsplitEnd = Math.Min(cataCycle.EndTime, mainEnd);
                ++i;
                phases.Add(new PhaseData(start, end, "Pre-Soulsplit " + i));
                phases.Add(new PhaseData(end, soulsplitEnd, "Soulsplit " + i)
                {
                    CanBeSubPhase = false
                });;
                start = cataCycle.EndTime;
            }
            phases.Add(new PhaseData(start, mainEnd, hasRitual ? "Pre-Ritual" : "Pre-Wipe"));
            return(phases);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 9
0
 protected bool Keep(AbstractCastEvent c, ParsedEvtcLog log)
 {
     if (_triggerCondition != null)
     {
         return(_triggerCondition(c, log));
     }
     return(true);
 }
        private static JsonSkill BuildJsonSkill(AbstractCastEvent cl)
        {
            var jsonSkill = new JsonSkill();

            jsonSkill.CastTime   = (int)cl.Time;
            jsonSkill.Duration   = cl.ActualDuration;
            jsonSkill.TimeGained = cl.SavedDuration;
            jsonSkill.Quickness  = cl.Acceleration;
            return(jsonSkill);
        }
Ejemplo n.º 11
0
        // helpers

        public static object[] GetSkillData(AbstractCastEvent cl, long phaseStart)
        {
            object[] rotEntry = new object[5];
            double   start    = (cl.Time - phaseStart) / 1000.0;

            rotEntry[0] = start;
            rotEntry[1] = cl.SkillId;
            rotEntry[2] = cl.ActualDuration;
            rotEntry[3] = EncodeEndActivation(cl);
            rotEntry[4] = cl.UnderQuickness ? 1 : 0;
            return(rotEntry);
        }
        private static object[] GetSkillData(AbstractCastEvent cl, long phaseStart)
        {
            object[] rotEntry = new object[5];
            double   start    = (cl.Time - phaseStart) / 1000.0;

            rotEntry[0] = start;
            rotEntry[1] = cl.SkillId;
            rotEntry[2] = cl.ActualDuration;
            rotEntry[3] = (int)cl.Status;
            rotEntry[4] = cl.Acceleration;
            return(rotEntry);
        }
Ejemplo n.º 13
0
 private bool CouldBeImbuedMelodies(AbstractCastEvent item, long time, long extension, ParsedLog log)
 {
     if (extension == ImbuedMelodies && log.PlayerListBySpec.TryGetValue("Tempest", out List <Player> tempests))
     {
         HashSet <AgentItem> magAuraApplications = new HashSet <AgentItem>(log.CombatData.GetBoonData(5684).Where(x => x is BuffApplyEvent && x.Time - time < 50 && x.By != item.Caster).Select(x => x.By));
         foreach (Player tempest in tempests)
         {
             if (magAuraApplications.Contains(tempest.AgentItem))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Ejemplo n.º 14
0
 private static int EncodeEndActivation(AbstractCastEvent cl)
 {
     if (cl.ReducedAnimation)
     {
         return(1);
     }
     if (cl.Interrupted)
     {
         return(2);
     }
     if (cl.FullAnimation)
     {
         return(3);
     }
     return(0);
 }
Ejemplo n.º 15
0
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            List <PhaseData> phases     = GetInitialPhase(log);
            Target           mainTarget = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Sabir);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            List <AbstractCastEvent> cls = mainTarget.GetCastLogs(log, 0, log.FightData.FightDuration);
            List <AbstractCastEvent> wallopingWinds = cls.Where(x => x.SkillId == 56094).ToList();
            long start = 0, end = 0;

            for (int i = 0; i < wallopingWinds.Count; i++)
            {
                AbstractCastEvent wW = wallopingWinds[i];
                end = wW.Time;
                PhaseData phase = new PhaseData(start, end)
                {
                    Name = "Phase " + (i + 1)
                };
                phase.Targets.Add(mainTarget);
                phases.Add(phase);
                AbstractCastEvent nextAttack = cls.FirstOrDefault(x => x.Time >= end + wW.ActualDuration && (x.SkillId == 56620 || x.SkillId == 56629 || x.SkillId == 56307));
                if (nextAttack == null)
                {
                    break;
                }
                start = nextAttack.Time;
                if (i == wallopingWinds.Count - 1)
                {
                    phase = new PhaseData(start, log.FightData.FightDuration)
                    {
                        Name = "Phase " + (i + 2)
                    };
                    phase.Targets.Add(mainTarget);
                    phases.Add(phase);
                }
            }

            return(phases);
        }
Ejemplo n.º 16
0
        private void ComputeFightPhases(List <PhaseData> phases, List <AbstractCastEvent> castLogs, long fightDuration, long start)
        {
            AbstractCastEvent shield = castLogs.Find(x => x.SkillId == 47396);

            // Dhuum brought down to 10%
            if (shield != null)
            {
                long end = shield.Time;
                phases.Add(new PhaseData(start, end, "Dhuum Fight"));
                AbstractCastEvent firstDamage = castLogs.FirstOrDefault(x => x.SkillId == 47304 && x.Time >= end);
                // ritual started
                if (firstDamage != null)
                {
                    phases.Add(new PhaseData(firstDamage.Time, fightDuration, "Ritual"));
                }
            }
        }
Ejemplo n.º 17
0
            public JsonSkill(AbstractCastEvent cl)
            {
                int timeGained = 0;

                if (cl.ReducedAnimation && cl.ActualDuration < cl.ExpectedDuration)
                {
                    timeGained = cl.ExpectedDuration - cl.ActualDuration;
                }
                else if (cl.Interrupted)
                {
                    timeGained = -cl.ActualDuration;
                }
                CastTime   = (int)cl.Time;
                Duration   = cl.ActualDuration;
                TimeGained = timeGained;
                Quickness  = cl.UnderQuickness;
            }
Ejemplo n.º 18
0
        private void ComputeFightPhases(Target mainTarget, List <PhaseData> phases, ParsedLog log, List <AbstractCastEvent> castLogs, long fightDuration, long start)
        {
            AbstractCastEvent shield = castLogs.Find(x => x.SkillId == 47396);

            if (shield != null)
            {
                long end = shield.Time;
                phases.Add(new PhaseData(start, end));
                AbstractCastEvent firstDamage = castLogs.FirstOrDefault(x => x.SkillId == 47304 && x.Time >= end);
                if (firstDamage != null)
                {
                    phases.Add(new PhaseData(firstDamage.Time, fightDuration));
                }
            }
            else
            {
                phases.Add(new PhaseData(start, fightDuration));
            }
        }
Ejemplo n.º 19
0
        // Main method
        public AgentItem TryFindSrc(AgentItem dst, long time, long extension, ParsedEvtcLog log, long buffID)
        {
            if (!_boonIds.Contains(buffID))
            {
                return(dst);
            }
            int essenceOfSpeedCheck = CouldBeEssenceOfSpeed(dst, extension, log);

            // can only be the soulbeast
            if (essenceOfSpeedCheck == 1)
            {
                return(dst);
            }
            if (DurationToIDs.TryGetValue(extension, out HashSet <long> idsToCheck))
            {
                List <AbstractCastEvent> cls = GetExtensionSkills(log, time, idsToCheck);
                // If only one cast item
                if (cls.Count == 1)
                {
                    AbstractCastEvent item = cls.First();
                    // If uncertainty due to essence of speed or imbued melodies, return unknown
                    if (essenceOfSpeedCheck == 0 || CouldBeImbuedMelodies(item.Caster, time, extension, log))
                    {
                        return(ParserHelper._unknownAgent);
                    }
                    // otherwise the src is the caster
                    return(item.Caster);
                }
                // If no cast item and uncertainty due to essence of speed
                else if (!cls.Any() && essenceOfSpeedCheck == 0)
                {
                    // If uncertainty due to imbued melodies, return unknown
                    if (CouldBeImbuedMelodies(dst, time, extension, log))
                    {
                        return(ParserHelper._unknownAgent);
                    }
                    // otherwise return the soulbeast
                    return(dst);
                }
            }
            return(ParserHelper._unknownAgent);
        }
Ejemplo n.º 20
0
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            List <PhaseData> phases = GetInitialPhase(log);
            NPC mainTarget          = Targets.Find(x => x.ID == (int)ParseEnum.TargetID.Sabir);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Sabir not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            List <AbstractCastEvent> cls = mainTarget.GetCastLogs(log, 0, log.FightData.FightEnd);
            var  wallopingWinds = cls.Where(x => x.SkillId == 56094).ToList();
            long start = 0, end = 0;

            for (int i = 0; i < wallopingWinds.Count; i++)
            {
                AbstractCastEvent wallopinbWind = wallopingWinds[i];
                end = wallopinbWind.Time;
                var phase = new PhaseData(start, end, "Phase " + (i + 1));
                phase.Targets.Add(mainTarget);
                phases.Add(phase);
                AbstractCastEvent nextAttack = cls.FirstOrDefault(x => x.Time >= wallopinbWind.EndTime && (x.SkillId == 56620 || x.SkillId == 56629 || x.SkillId == 56307));
                if (nextAttack == null)
                {
                    break;
                }
                start = nextAttack.Time;
                if (i == wallopingWinds.Count - 1)
                {
                    phase = new PhaseData(start, log.FightData.FightEnd, "Phase " + (i + 2));
                    phase.Targets.Add(mainTarget);
                    phases.Add(phase);
                }
            }

            return(phases);
        }
Ejemplo n.º 21
0
        private List <PhaseData> GetInBetweenSoulSplits(ParsedLog log, Target dhuum, long mainStart, long mainEnd, bool hasRitual)
        {
            List <AbstractCastEvent> cls        = dhuum.GetCastLogs(log, 0, log.FightData.FightDuration);
            List <AbstractCastEvent> cataCycle  = cls.Where(x => x.SkillId == 48398).ToList();
            List <AbstractCastEvent> gDeathmark = cls.Where(x => x.SkillId == 48210).ToList();

            if (gDeathmark.Count < cataCycle.Count)
            {
                return(new List <PhaseData>());
            }
            List <PhaseData> phases = new List <PhaseData>();
            long             start  = mainStart;
            long             end    = 0;
            int i = 1;

            foreach (AbstractCastEvent cl in cataCycle)
            {
                AbstractCastEvent clDeathmark = gDeathmark[i - 1];
                end = Math.Min(clDeathmark.Time, mainEnd);
                phases.Add(new PhaseData(start, end)
                {
                    Name = "Pre-Soulsplit " + i++
                });
                start = cl.Time + cl.ActualDuration;
            }
            phases.Add(new PhaseData(start, mainEnd)
            {
                Name = hasRitual ? "Pre-Ritual" : "Pre-Wipe"
            });
            foreach (PhaseData phase in phases)
            {
                phase.Targets.Add(dhuum);
            }
            phases.RemoveAll(x => x.DurationInMS <= 2200);
            return(phases);
        }
Ejemplo n.º 22
0
        internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases)
        {
            List <PhaseData> phases = GetInitialPhase(log);
            NPC mainTarget          = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.Adina);

            if (mainTarget == null)
            {
                throw new MissingKeyActorsException("Adina not found");
            }
            phases[0].AddTarget(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            List <AbstractBuffEvent> invuls = GetFilteredList(log.CombatData, 762, mainTarget, true);
            long start = 0, end = 0;

            for (int i = 0; i < invuls.Count; i++)
            {
                AbstractBuffEvent be = invuls[i];
                if (be is BuffApplyEvent)
                {
                    start = be.Time;
                    if (i == invuls.Count - 1)
                    {
                        phases.Add(new PhaseData(start, log.FightData.FightEnd, "Split " + (i / 2 + 1)));
                    }
                }
                else
                {
                    end = be.Time;
                    phases.Add(new PhaseData(start, end, "Split " + (i / 2 + 1)));
                }
            }
            var mainPhases    = new List <PhaseData>();
            var quantumQuakes = mainTarget.GetCastEvents(log, 0, log.FightData.FightEnd).Where(x => x.SkillId == 56035 || x.SkillId == 56381).ToList();
            AbstractCastEvent boulderBarrage = mainTarget.GetCastEvents(log, 0, log.FightData.FightEnd).FirstOrDefault(x => x.SkillId == 56648 && x.Time < 6000);

            start = boulderBarrage == null ? 0 : boulderBarrage.EndTime;
            end   = 0;
            if (phases.Count > 1)
            {
                for (int i = 1; i < phases.Count; i++)
                {
                    AbstractCastEvent qQ = quantumQuakes[i - 1];
                    end = qQ.Time;
                    mainPhases.Add(new PhaseData(start, end, "Phase " + i));
                    PhaseData split = phases[i];
                    AddTargetsToPhaseAndFit(split, new List <int> {
                        (int)ArcDPSEnums.TrashID.HandOfErosion, (int)ArcDPSEnums.TrashID.HandOfEruption
                    }, log);
                    start = split.End;
                    if (i == phases.Count - 1 && start != log.FightData.FightEnd)
                    {
                        mainPhases.Add(new PhaseData(start, log.FightData.FightEnd, "Phase " + (i + 1)));
                    }
                }
            }
            else if (start > 0)
            {
                // no split
                mainPhases.Add(new PhaseData(start, log.FightData.FightEnd, "Phase 1"));
            }

            foreach (PhaseData phase in mainPhases)
            {
                phase.AddTarget(mainTarget);
            }
            phases.AddRange(mainPhases);
            phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            GetCombatMap(log).MatchMapsToPhases(new List <string> {
                "https://i.imgur.com/IQn2RJV.png",
                "https://i.imgur.com/gJ55jKy.png",
                "https://i.imgur.com/3pO7eCB.png",
                "https://i.imgur.com/c2Oz5bj.png",
                "https://i.imgur.com/ZFw590w.png",
                "https://i.imgur.com/P4SGbrc.png",
                "https://i.imgur.com/2P7UE8q.png"
            }, phases, log.FightData.FightEnd);
            return(phases);
        }
        internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay)
        {
            // TODO: correct position
            IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd);
            int start = (int)replay.TimeOffsets.start;
            int end   = (int)replay.TimeOffsets.end;

            switch (target.ID)
            {
            case (int)ArcDPSEnums.TargetID.Dhuum:
                var deathmark = cls.Where(x => x.SkillId == 48176).ToList();
                AbstractCastEvent majorSplit = cls.FirstOrDefault(x => x.SkillId == 47396);
                foreach (AbstractCastEvent c in deathmark)
                {
                    start = (int)c.Time;
                    int zoneActive = start + 1550;
                    int zoneDeadly = zoneActive + 6000;     //point where the zone becomes impossible to walk through unscathed
                    int zoneEnd    = zoneActive + 120000;
                    int radius     = 450;
                    if (majorSplit != null)
                    {
                        zoneEnd    = Math.Min(zoneEnd, (int)majorSplit.Time);
                        zoneDeadly = Math.Min(zoneDeadly, (int)majorSplit.Time);
                    }
                    int     spellCenterDistance = 200; //hitbox radius
                    Point3D facing         = replay.Rotations.LastOrDefault(x => x.Time <= start + 3000);
                    Point3D targetPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= start + 3000);
                    if (facing != null && targetPosition != null)
                    {
                        var position = new Point3D(targetPosition.X + (facing.X * spellCenterDistance), targetPosition.Y + (facing.Y * spellCenterDistance), targetPosition.Z, targetPosition.Time);
                        replay.Decorations.Add(new CircleDecoration(true, zoneActive, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position)));
                        replay.Decorations.Add(new CircleDecoration(false, 0, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneActive, zoneDeadly), "rgba(200, 255, 100, 0.5)", new PositionConnector(position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneDeadly, zoneEnd), "rgba(255, 100, 0, 0.5)", new PositionConnector(position)));
                    }
                }
                var cataCycle = cls.Where(x => x.SkillId == 48398).ToList();
                foreach (AbstractCastEvent c in cataCycle)
                {
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    replay.Decorations.Add(new CircleDecoration(true, end, 300, (start, end), "rgba(255, 150, 0, 0.7)", new AgentConnector(target)));
                    replay.Decorations.Add(new CircleDecoration(true, 0, 300, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target)));
                }
                var slash = cls.Where(x => x.SkillId == 47561).ToList();
                foreach (AbstractCastEvent c in slash)
                {
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start);
                    if (facing == null)
                    {
                        continue;
                    }
                    replay.Decorations.Add(new PieDecoration(false, 0, 850, facing, 60, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target)));
                }

                if (majorSplit != null)
                {
                    start = (int)majorSplit.Time;
                    end   = (int)log.FightData.FightEnd;
                    replay.Decorations.Add(new CircleDecoration(true, 0, 320, (start, end), "rgba(0, 180, 255, 0.2)", new AgentConnector(target)));
                }
                break;

            case (int)ArcDPSEnums.TrashID.DhuumDesmina:
                break;

            case (int)ArcDPSEnums.TrashID.Echo:
                replay.Decorations.Add(new CircleDecoration(true, 0, 120, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target)));
                break;

            case (int)ArcDPSEnums.TrashID.Enforcer:
                break;

            case (int)ArcDPSEnums.TrashID.Messenger:
                replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target)));
                break;

            case (int)ArcDPSEnums.TrashID.Deathling:
                break;

            case (int)ArcDPSEnums.TrashID.UnderworldReaper:
                // if not bugged and we assumed we are still on the reapers at the door, check if start is above 2 seconds (first reaper spawns around 10+ seconds). If yes, put _reapersSeen at 0 to start greens.
                if (!_isBugged && _reapersSeen < 0 && start > 2000)
                {
                    //Reminder that agents appear in chronological order, after this one, reaper has spawned afer the first one
                    _reapersSeen = 0;
                }
                if (!_isBugged && _reapersSeen >= 0)
                {
                    if (_greenStart == 0)
                    {
                        AbstractBuffEvent greenTaken = log.CombatData.GetBuffData(46950).Where(x => x is BuffApplyEvent).FirstOrDefault();
                        if (greenTaken != null)
                        {
                            _greenStart = (int)greenTaken.Time - 5000;
                        }
                        else
                        {
                            _greenStart = 30600;
                        }
                    }
                    int multiplier = 210000;
                    int gStart     = _greenStart + _reapersSeen * 30000;
                    var greens     = new List <int>()
                    {
                        gStart,
                        gStart + multiplier,
                        gStart + 2 * multiplier
                    };
                    foreach (int gstart in greens)
                    {
                        int gend = gstart + 5000;
                        replay.Decorations.Add(new CircleDecoration(true, 0, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target)));
                        replay.Decorations.Add(new CircleDecoration(true, gend, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target)));
                    }
                }
                List <AbstractBuffEvent> stealths = GetFilteredList(log.CombatData, 13017, target, true);
                int stealthStart = 0;
                int stealthEnd   = 0;
                foreach (AbstractBuffEvent c in stealths)
                {
                    if (c is BuffApplyEvent)
                    {
                        stealthStart = (int)c.Time;
                    }
                    else
                    {
                        stealthEnd = (int)c.Time;
                        replay.Decorations.Add(new CircleDecoration(true, 0, 180, (stealthStart, stealthEnd), "rgba(80, 80, 80, 0.3)", new AgentConnector(target)));
                    }
                }
                _reapersSeen++;
                break;

            default:
                break;
            }
        }
Ejemplo n.º 24
0
        internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases)
        {
            List <PhaseData>    phases     = GetInitialPhase(log);
            AbstractSingleActor mainTarget = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.Adina);

            if (mainTarget == null)
            {
                throw new MissingKeyActorsException("Adina not found");
            }
            phases[0].AddTarget(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // Split phases
            List <AbstractBuffEvent> invuls = GetFilteredList(log.CombatData, 762, mainTarget, true, true);
            long start          = 0;
            var  splitPhases    = new List <PhaseData>();
            var  splitPhaseEnds = new List <long>();

            for (int i = 0; i < invuls.Count; i++)
            {
                PhaseData         splitPhase;
                AbstractBuffEvent be = invuls[i];
                if (be is BuffApplyEvent)
                {
                    start = be.Time;
                    if (i == invuls.Count - 1)
                    {
                        splitPhase = new PhaseData(start, log.FightData.FightEnd, "Split " + (i / 2 + 1));
                        splitPhaseEnds.Add(log.FightData.FightEnd);
                        AddTargetsToPhaseAndFit(splitPhase, new List <int> {
                            (int)ArcDPSEnums.TrashID.HandOfErosion, (int)ArcDPSEnums.TrashID.HandOfEruption
                        }, log);
                        splitPhases.Add(splitPhase);
                    }
                }
                else
                {
                    long end = be.Time;
                    splitPhase = new PhaseData(start, end, "Split " + (i / 2 + 1));
                    splitPhaseEnds.Add(end);
                    AddTargetsToPhaseAndFit(splitPhase, new List <int> {
                        (int)ArcDPSEnums.TrashID.HandOfErosion, (int)ArcDPSEnums.TrashID.HandOfEruption
                    }, log);
                    splitPhases.Add(splitPhase);
                }
            }
            // Main phases
            var mainPhases    = new List <PhaseData>();
            var pillarApplies = log.CombatData.GetBuffData(56204).OfType <BuffApplyEvent>().Where(x => x.To == mainTarget.AgentItem).ToList();
            Dictionary <long, List <BuffApplyEvent> > pillarAppliesGroupByTime = ParserHelper.GroupByTime(pillarApplies);
            var mainPhaseEnds = new List <long>();

            foreach (KeyValuePair <long, List <BuffApplyEvent> > pair in pillarAppliesGroupByTime)
            {
                if (pair.Value.Count == 6)
                {
                    mainPhaseEnds.Add(pair.Key);
                }
            }
            AbstractCastEvent boulderBarrage = mainTarget.GetCastEvents(log, 0, log.FightData.FightEnd).FirstOrDefault(x => x.SkillId == 56648 && x.Time < 6000);

            start = boulderBarrage == null ? 0 : boulderBarrage.EndTime;
            if (mainPhaseEnds.Any())
            {
                int phaseIndex = 1;
                foreach (long quantumQake in mainPhaseEnds)
                {
                    var curPhaseStart = splitPhaseEnds.LastOrDefault(x => x < quantumQake);
                    if (curPhaseStart == 0)
                    {
                        curPhaseStart = start;
                    }
                    long nextPhaseStart = splitPhaseEnds.FirstOrDefault(x => x > quantumQake);
                    if (nextPhaseStart != 0)
                    {
                        start      = nextPhaseStart;
                        phaseIndex = splitPhaseEnds.IndexOf(start) + 1;
                    }
                    mainPhases.Add(new PhaseData(curPhaseStart, quantumQake, "Phase " + phaseIndex));
                }
                if (start != mainPhases.Last().Start)
                {
                    mainPhases.Add(new PhaseData(start, log.FightData.FightEnd, "Phase " + (phaseIndex + 1)));
                }
            }
            else if (start > 0 && !invuls.Any())
            {
                // no split
                mainPhases.Add(new PhaseData(start, log.FightData.FightEnd, "Phase 1"));
            }

            foreach (PhaseData phase in mainPhases)
            {
                phase.AddTarget(mainTarget);
            }
            phases.AddRange(mainPhases);
            phases.AddRange(splitPhases);
            phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            //
            try
            {
                var splitPhasesMap = new List <string>()
                {
                    "https://i.imgur.com/gJ55jKy.png",
                    "https://i.imgur.com/c2Oz5bj.png",
                    "https://i.imgur.com/P4SGbrc.png",
                };
                var mainPhasesMap = new List <string>()
                {
                    "https://i.imgur.com/IQn2RJV.png",
                    "https://i.imgur.com/3pO7eCB.png",
                    "https://i.imgur.com/ZFw590w.png",
                    "https://i.imgur.com/2P7UE8q.png"
                };
                var crMaps          = new List <string>();
                int mainPhaseIndex  = 0;
                int splitPhaseIndex = 0;
                for (int i = 1; i < phases.Count; i++)
                {
                    PhaseData phaseData = phases[i];
                    if (mainPhases.Contains(phaseData))
                    {
                        if (mainPhasesMap.Contains(crMaps.LastOrDefault()))
                        {
                            splitPhaseIndex++;
                        }
                        crMaps.Add(mainPhasesMap[mainPhaseIndex++]);
                    }
                    else
                    {
                        if (splitPhasesMap.Contains(crMaps.LastOrDefault()))
                        {
                            mainPhaseIndex++;
                        }
                        crMaps.Add(splitPhasesMap[splitPhaseIndex++]);
                    }
                }
                GetCombatReplayMap(log).MatchMapsToPhases(crMaps, phases, log.FightData.FightEnd);
            }
            catch (Exception)
            {
                log.UpdateProgressWithCancellationCheck("Failed to associate Adina Combat Replay maps");
            }

            //
            return(phases);
        }
        internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay)
        {
            IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd);
            int start = (int)replay.TimeOffsets.start;
            int end   = (int)replay.TimeOffsets.end;

            switch (target.ID)
            {
            case (int)ArcDPSEnums.TargetID.Matthias:
                var humanShield        = cls.Where(x => x.SkillId == 34468).ToList();
                var humanShieldRemoval = log.CombatData.GetBuffRemoveAllData(34518).Select(x => (int)x.Time).Distinct().ToList();
                for (int i = 0; i < humanShield.Count; i++)
                {
                    AbstractCastEvent shield = humanShield[i];
                    if (i < humanShieldRemoval.Count)
                    {
                        int removal = humanShieldRemoval[i];
                        replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)shield.Time, removal), "rgba(255, 0, 255, 0.5)", new AgentConnector(target)));
                    }
                    else
                    {
                        replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)shield.Time, (int)log.FightData.FightEnd), "rgba(255, 0, 255, 0.5)", new AgentConnector(target)));
                    }
                }
                var aboShield        = cls.Where(x => x.SkillId == 34510).ToList();
                var aboShieldRemoval = log.CombatData.GetBuffRemoveAllData(34376).Select(x => (int)x.Time).Distinct().ToList();
                for (int i = 0; i < aboShield.Count; i++)
                {
                    AbstractCastEvent shield = aboShield[i];
                    if (i < aboShieldRemoval.Count)
                    {
                        int removal = aboShieldRemoval[i];
                        replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)shield.Time, removal), "rgba(255, 0, 255, 0.5)", new AgentConnector(target)));
                    }
                    else
                    {
                        replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)shield.Time, (int)log.FightData.FightEnd), "rgba(255, 0, 255, 0.5)", new AgentConnector(target)));
                    }
                }
                var rageShards = cls.Where(x => x.SkillId == 34404 || x.SkillId == 34411).ToList();
                foreach (AbstractCastEvent c in rageShards)
                {
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    replay.Decorations.Add(new CircleDecoration(false, 0, 300, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target)));
                    replay.Decorations.Add(new CircleDecoration(true, end, 300, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target)));
                }
                var hadouken = cls.Where(x => x.SkillId == 34371 || x.SkillId == 34380).ToList();
                foreach (AbstractCastEvent c in hadouken)
                {
                    start = (int)c.Time;
                    int     preCastTime = 1000;
                    int     duration = 750;
                    int     width = 4000; int height = 130;
                    Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 1000);
                    if (facing != null)
                    {
                        int direction = (int)(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI);
                        replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, direction, width / 2, (start, start + preCastTime), "rgba(255, 0, 0, 0.1)", new AgentConnector(target)));
                        replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, direction, width / 2, (start + preCastTime, start + preCastTime + duration), "rgba(255, 0, 0, 0.7)", new AgentConnector(target)));
                    }
                }
                break;

            case (int)ArcDPSEnums.TrashID.Storm:
                replay.Decorations.Add(new CircleDecoration(false, 0, 260, (start, end), "rgba(0, 80, 255, 0.5)", new AgentConnector(target)));
                break;

            case (int)ArcDPSEnums.TrashID.Spirit:
            case (int)ArcDPSEnums.TrashID.Spirit2:
                replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target)));
                break;

            case (int)ArcDPSEnums.TrashID.IcePatch:
                replay.Decorations.Add(new CircleDecoration(true, 0, 200, (start, end), "rgba(0, 0, 255, 0.5)", new AgentConnector(target)));
                break;

            case (int)ArcDPSEnums.TrashID.Tornado:
                replay.Decorations.Add(new CircleDecoration(true, 0, 90, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target)));
                break;

            default:
                break;
            }
        }
Ejemplo n.º 26
0
        internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay)
        {
            // TODO: correct position
            IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd);
            int start = (int)replay.TimeOffsets.start;
            int end   = (int)replay.TimeOffsets.end;

            switch (target.ID)
            {
            case (int)ArcDPSEnums.TargetID.Dhuum:
                var deathmark = cls.Where(x => x.SkillId == 48176).ToList();
                AbstractCastEvent majorSplit = cls.FirstOrDefault(x => x.SkillId == 47396);
                foreach (AbstractCastEvent c in deathmark)
                {
                    start = (int)c.Time;
                    int zoneActive = start + 1550;
                    int zoneDeadly = zoneActive + 6000;     //point where the zone becomes impossible to walk through unscathed
                    int zoneEnd    = zoneActive + 120000;
                    int radius     = 450;
                    if (majorSplit != null)
                    {
                        zoneEnd    = Math.Min(zoneEnd, (int)majorSplit.Time);
                        zoneDeadly = Math.Min(zoneDeadly, (int)majorSplit.Time);
                    }
                    int     spellCenterDistance = 200; //hitbox radius
                    Point3D facing         = replay.Rotations.LastOrDefault(x => x.Time <= start + 3000);
                    Point3D targetPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= start + 3000);
                    if (facing != null && targetPosition != null)
                    {
                        var position = new Point3D(targetPosition.X + (facing.X * spellCenterDistance), targetPosition.Y + (facing.Y * spellCenterDistance), targetPosition.Z);
                        replay.Decorations.Add(new CircleDecoration(true, zoneActive, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position)));
                        replay.Decorations.Add(new CircleDecoration(false, 0, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneActive, zoneDeadly), "rgba(200, 255, 100, 0.5)", new PositionConnector(position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneDeadly, zoneEnd), "rgba(255, 100, 0, 0.5)", new PositionConnector(position)));
                    }
                }
                var cataCycle = cls.Where(x => x.SkillId == 48398).ToList();
                foreach (AbstractCastEvent c in cataCycle)
                {
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    replay.Decorations.Add(new CircleDecoration(true, end, 300, (start, end), "rgba(255, 150, 0, 0.7)", new AgentConnector(target)));
                    replay.Decorations.Add(new CircleDecoration(true, 0, 300, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target)));
                }
                var slash = cls.Where(x => x.SkillId == 47561).ToList();
                foreach (AbstractCastEvent c in slash)
                {
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start);
                    if (facing == null)
                    {
                        continue;
                    }
                    replay.Decorations.Add(new PieDecoration(false, 0, 850, facing, 60, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target)));
                }

                if (majorSplit != null)
                {
                    start = (int)majorSplit.Time;
                    end   = (int)log.FightData.FightEnd;
                    replay.Decorations.Add(new CircleDecoration(true, 0, 320, (start, end), "rgba(0, 180, 255, 0.2)", new AgentConnector(target)));
                }
                break;

            case (int)ArcDPSEnums.TrashID.DhuumDesmina:
                break;

            case (int)ArcDPSEnums.TrashID.Echo:
                replay.Decorations.Add(new CircleDecoration(true, 0, 120, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target)));
                break;

            case (int)ArcDPSEnums.TrashID.Enforcer:
                break;

            case (int)ArcDPSEnums.TrashID.Messenger:
                replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target)));
                break;

            case (int)ArcDPSEnums.TrashID.Deathling:
                break;

            case (int)ArcDPSEnums.TrashID.UnderworldReaper:
                List <AbstractBuffEvent> stealths = GetFilteredList(log.CombatData, 13017, target, true, true);
                int stealthStart = 0;
                int stealthEnd   = 0;
                foreach (AbstractBuffEvent c in stealths)
                {
                    if (c is BuffApplyEvent)
                    {
                        stealthStart = (int)c.Time;
                    }
                    else
                    {
                        stealthEnd = (int)c.Time;
                        replay.Decorations.Add(new CircleDecoration(true, 0, 180, (stealthStart, stealthEnd), "rgba(80, 80, 80, 0.3)", new AgentConnector(target)));
                    }
                }
                if (!_isBugged)
                {
                    if (_greenStart == 0)
                    {
                        AbstractBuffEvent greenTaken = log.CombatData.GetBuffData(46950).Where(x => x is BuffApplyEvent).FirstOrDefault();
                        if (greenTaken != null)
                        {
                            _greenStart = (int)greenTaken.Time - 5000;
                        }
                        else
                        {
                            _greenStart = 30600;
                        }
                    }
                    Point3D pos = replay.Positions.FirstOrDefault();
                    if (replay.Positions.Count > 1)
                    {
                        replay.Trim(replay.Positions.LastOrDefault().Time, replay.TimeOffsets.end);
                    }
                    if (pos == null)
                    {
                        break;
                    }
                    int reaper = -1;
                    foreach (KeyValuePair <Point3D, int> pair in ReapersToGreen)
                    {
                        if (pair.Key.DistanceToPoint(pos) < 10)
                        {
                            reaper = pair.Value;
                            break;
                        }
                    }
                    if (reaper == -1)
                    {
                        break;
                    }
                    int multiplier = 210000;
                    int gStart     = _greenStart + reaper * 30000;
                    var greens     = new List <int>()
                    {
                        gStart,
                        gStart + multiplier,
                        gStart + 2 * multiplier
                    };
                    foreach (int gstart in greens)
                    {
                        int gend = gstart + 5000;
                        replay.Decorations.Add(new CircleDecoration(true, 0, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target)));
                        replay.Decorations.Add(new CircleDecoration(true, gend, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target)));
                    }
                }
                break;

            default:
                break;
            }
        }
Ejemplo n.º 27
0
        // privates

        protected static bool KeepIntersectingCastLog(AbstractCastEvent evt, long start, long end)
        {
            return((evt.Time >= start && evt.Time <= end) ||       // start inside
                   (evt.EndTime >= start && evt.EndTime <= end) || // end inside
                   (evt.Time <= start && evt.EndTime >= end));     // start before, end after
        }
        internal override List <PhaseData> GetPhases(ParsedEvtcLog log, bool requirePhases)
        {
            List <PhaseData>    phases     = GetInitialPhase(log);
            AbstractSingleActor mainTarget = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.PeerlessQadim);

            if (mainTarget == null)
            {
                throw new MissingKeyActorsException("Peerless Qadim not found");
            }
            phases[0].AddTarget(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            var phaseStarts = new List <long>();
            var phaseEnds   = new List <long>();
            //
            var magmaDrops = log.CombatData.GetBuffData(MagmaDrop).Where(x => x is BuffApplyEvent).ToList();

            foreach (AbstractBuffEvent magmaDrop in magmaDrops)
            {
                if (phaseEnds.Count > 0)
                {
                    if (Math.Abs(phaseEnds.Last() - magmaDrop.Time) > 1000)
                    {
                        phaseEnds.Add(magmaDrop.Time);
                    }
                }
                else
                {
                    phaseEnds.Add(magmaDrop.Time);
                }
            }
            IReadOnlyList <AnimatedCastEvent> pushes = log.CombatData.GetAnimatedCastData(ForceOfRetaliationCast);

            if (pushes.Count > 0)
            {
                AbstractCastEvent push = pushes[0];
                phaseStarts.Add(push.Time);
                foreach (long magmaDrop in phaseEnds)
                {
                    push = pushes.FirstOrDefault(x => x.Time >= magmaDrop);
                    if (push == null)
                    {
                        break;
                    }
                    phaseStarts.Add(push.Time);
                }
            }
            // rush to pylon
            phaseEnds.AddRange(log.CombatData.GetAnimatedCastData(BatteringBlitz).Select(x => x.Time).ToList());
            phaseEnds.Add(log.FightData.FightEnd);
            // tp to middle after pylon destruction
            phaseStarts.AddRange(log.CombatData.GetAnimatedCastData(PeerlessQadimTPCenter).Select(x => x.EndTime));
            // There should be at least as many starts as ends, otherwise skip phases
            if (phaseEnds.Count < phaseStarts.Count)
            {
                return(phases);
            }
            for (int i = 0; i < phaseStarts.Count; i++)
            {
                var phase = new PhaseData(phaseStarts[i], phaseEnds[i], "Phase " + (i + 1));
                phase.AddTarget(mainTarget);
                phases.Add(phase);
            }
            // intermission phase never finished, add a "dummy" log end
            if (phaseEnds.Count - 1 == phaseStarts.Count)
            {
                phaseStarts.Add(log.FightData.FightEnd);
            }
            // There should be as many ends as starts, otherwise anomaly, skip intermission phases
            if (phaseEnds.Count != phaseStarts.Count)
            {
                return(phases);
            }
            string[] intermissionNames = { "Magma Drop 1", "Magma Drop 2", "North Pylon", "SouthWest Pylon", "SouthEast Pylon" };
            bool     skipNames         = intermissionNames.Length < phaseEnds.Count - 1;

            for (int i = 0; i < phaseEnds.Count - 1; i++)
            {
                var phase = new PhaseData(phaseEnds[i], Math.Min(phaseStarts[i + 1], log.FightData.FightEnd), skipNames ? "Intermission " + (i + 1) : intermissionNames[i]);
                phase.AddTarget(mainTarget);
                phases.Add(phase);
            }
            return(phases);
        }
Ejemplo n.º 29
0
 protected override long GetTime(AbstractCastEvent evt)
 {
     return(evt.EndTime);
 }
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            List <PhaseData> phases = GetInitialPhase(log);
            NPC mainTarget          = Targets.Find(x => x.ID == (int)ParseEnum.TargetID.PeerlessQadim);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Peerless Qadim not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            var phaseStarts = new List <long>();
            var phaseEnds   = new List <long>();
            //
            var magmaDrops = log.CombatData.GetBuffData(56475).Where(x => x is BuffApplyEvent).ToList();

            foreach (AbstractBuffEvent magmaDrop in magmaDrops)
            {
                if (phaseEnds.Count > 0)
                {
                    if (Math.Abs(phaseEnds.Last() - magmaDrop.Time) > 1000)
                    {
                        phaseEnds.Add(magmaDrop.Time);
                    }
                }
                else
                {
                    phaseEnds.Add(magmaDrop.Time);
                }
            }
            List <AbstractCastEvent> pushes = log.CombatData.GetCastData(56405);

            if (pushes.Count > 0)
            {
                AbstractCastEvent push = pushes[0];
                phaseStarts.Add(push.EndTime);
                foreach (long magmaDrop in phaseEnds)
                {
                    push = pushes.FirstOrDefault(x => x.Time >= magmaDrop);
                    if (push == null)
                    {
                        break;
                    }
                    phaseStarts.Add(push.EndTime);
                }
            }
            // rush to pylon
            phaseEnds.AddRange(log.CombatData.GetCastData(56616).Select(x => x.Time).ToList());
            phaseEnds.Add(log.FightData.FightEnd);
            // tp to middle after pylon destruction
            phaseStarts.AddRange(log.CombatData.GetCastData(56375).Select(x => x.EndTime));
            if (phaseEnds.Count < phaseStarts.Count)
            {
                return(phases);
            }
            for (int i = 0; i < phaseStarts.Count; i++)
            {
                var phase = new PhaseData(phaseStarts[i], phaseEnds[i], "Phase " + (i + 1));
                phase.Targets.Add(mainTarget);
                phases.Add(phase);
            }
            return(phases);
        }