//
        protected static List <CombatItem> GetFilteredList(ParsedLog log, long skillID, AbstractMasterPlayer target)
        {
            bool needStart             = true;
            List <CombatItem> main     = log.GetBoonData(skillID).Where(x => ((x.DstInstid == target.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None) || (x.SrcInstid == target.InstID && x.IsBuffRemove != ParseEnum.BuffRemove.None)) && x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList();
            List <CombatItem> filtered = new List <CombatItem>();

            for (int i = 0; i < main.Count; i++)
            {
                CombatItem c = main[i];
                if (needStart && c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    needStart = false;
                    filtered.Add(c);
                }
                else if (!needStart && c.IsBuffRemove != ParseEnum.BuffRemove.None)
                {
                    // consider only last remove event before another application
                    if ((i == main.Count - 1) || (i < main.Count - 1 && main[i + 1].IsBuffRemove == ParseEnum.BuffRemove.None))
                    {
                        needStart = true;
                        filtered.Add(c);
                    }
                }
            }
            return(filtered);
        }
Exemple #2
0
        public override void ComputeAdditionalTargetData(Target target, ParsedLog log)
        {
            // TODO: facing information (shock wave)
            CombatReplay   replay = target.CombatReplay;
            List <CastLog> cls    = target.GetCastLogs(log, 0, log.FightData.FightDuration);

            switch (target.ID)
            {
            case (ushort)ParseEnum.TargetIDS.Samarog:
                List <CombatItem> brutalize = log.GetBoonData(38226).Where(x => x.IsBuffRemove != ParseEnum.BuffRemove.Manual).ToList();
                int brutStart = 0;
                foreach (CombatItem c in brutalize)
                {
                    if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                    {
                        brutStart = (int)(log.FightData.ToFightSpace(c.Time));
                    }
                    else
                    {
                        int brutEnd = (int)(log.FightData.ToFightSpace(c.Time));
                        replay.Actors.Add(new CircleActor(true, 0, 120, (brutStart, brutEnd), "rgba(0, 180, 255, 0.3)", new AgentConnector(target)));
                    }
                }
                break;

            case (ushort)Rigom:
            case (ushort)Guldhem:
                break;

            default:
                throw new InvalidOperationException("Unknown ID in ComputeAdditionalData");
            }
        }
        private void SetConsumablesList(ParsedLog log)
        {
            List <Boon> consumableList = Boon.GetConsumableList();
            long        timeStart      = log.FightData.FightStart;
            long        fightDuration  = log.FightData.FightEnd - timeStart;

            foreach (Boon consumable in consumableList)
            {
                foreach (CombatItem c in log.GetBoonData(consumable.ID))
                {
                    if (c.IsBuffRemove != ParseEnum.BuffRemove.None || (c.IsBuff != 18 && c.IsBuff != 1) || AgentItem.InstID != c.DstInstid)
                    {
                        continue;
                    }
                    long time = 0;
                    if (c.IsBuff != 18)
                    {
                        time = c.Time - timeStart;
                    }
                    if (time <= fightDuration)
                    {
                        _consumeList.Add(new Tuple <Boon, long, int>(consumable, time, c.Value));
                    }
                }
            }
            _consumeList.Sort((x, y) => x.Item2.CompareTo(y.Item2));
        }
Exemple #4
0
        public override void ComputeAdditionalPlayerData(Player p, ParsedLog log)
        {
            // timed bombs
            CombatReplay      replay     = p.CombatReplay;
            List <CombatItem> timedBombs = log.GetBoonData(31485).Where(x => x.DstInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None).ToList();

            foreach (CombatItem c in timedBombs)
            {
                int start = (int)(c.Time - log.FightData.FightStart);
                int end   = start + 3000;
                replay.Actors.Add(new CircleActor(false, 0, 280, new Tuple <int, int>(start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(p)));
                replay.Actors.Add(new CircleActor(true, end, 280, new Tuple <int, int>(start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(p)));
            }
            // Sapper bombs
            List <CombatItem> sapperBombs = GetFilteredList(log, 31473, p);
            int sapperStart = 0;

            foreach (CombatItem c in sapperBombs)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    sapperStart = (int)(c.Time - log.FightData.FightStart);
                }
                else
                {
                    int sapperEnd = (int)(c.Time - log.FightData.FightStart); replay.Actors.Add(new CircleActor(false, 0, 180, new Tuple <int, int>(sapperStart, sapperEnd), "rgba(200, 255, 100, 0.5)", new AgentConnector(p)));
                    replay.Actors.Add(new CircleActor(true, sapperStart + 5000, 180, new Tuple <int, int>(sapperStart, sapperEnd), "rgba(200, 255, 100, 0.5)", new AgentConnector(p)));
                }
            }
        }
        private void SetConsumablesList(ParsedLog log)
        {
            List <Boon> consumableList = Boon.GetConsumableList();
            long        fightDuration  = log.FightData.FightDuration;

            foreach (Boon consumable in consumableList)
            {
                foreach (CombatItem c in log.GetBoonData(consumable.ID))
                {
                    if (c.IsBuffRemove != ParseEnum.BuffRemove.None || (c.IsBuff != 18 && c.IsBuff != 1) || AgentItem.InstID != c.DstInstid)
                    {
                        continue;
                    }
                    long time = 0;
                    if (c.IsBuff != 18)
                    {
                        time = log.FightData.ToFightSpace(c.Time);
                    }
                    if (time <= fightDuration)
                    {
                        Consumable existing = _consumeList.Find(x => x.Time == time && x.Item.ID == consumable.ID);
                        if (existing != null)
                        {
                            existing.Stack++;
                        }
                        else
                        {
                            _consumeList.Add(new Consumable(consumable, time, c.Value));
                        }
                    }
                }
            }
            _consumeList.Sort((x, y) => x.Time.CompareTo(y.Time));
        }
        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
            CombatItem heatWave = log.GetBoonData(34526).FirstOrDefault();

            if (heatWave != null)
            {
                phases.Add(new PhaseData(0, log.FightData.ToFightSpace(heatWave.Time) - 1));
                CombatItem downPour = log.GetDamageData(mainTarget.InstID, mainTarget.FirstAware, mainTarget.LastAware).Find(x => x.SkillID == 34554);
                if (downPour != null)
                {
                    phases.Add(new PhaseData(log.FightData.ToFightSpace(heatWave.Time), log.FightData.ToFightSpace(downPour.Time) - 1));
                    List <CastLog> castLogs = mainTarget.GetCastLogs(log, 0, log.FightData.FightEnd);
                    CastLog        abo      = castLogs.Find(x => x.SkillId == 34427);
                    if (abo != null)
                    {
                        phases.Add(new PhaseData(log.FightData.ToFightSpace(downPour.Time), abo.Time - 1));
                        CombatItem invulRemove = log.GetBoonDataByDst(mainTarget.InstID, log.FightData.ToLogSpace(abo.Time), log.FightData.ToLogSpace(abo.Time) + 10000).FirstOrDefault(x => x.SkillID == 757 && x.IsBuffRemove != ParseEnum.BuffRemove.None);
                        if (invulRemove != null)
                        {
                            phases.Add(new PhaseData(log.FightData.ToFightSpace(invulRemove.Time), fightDuration));
                        }
                    }
                    else
                    {
                        phases.Add(new PhaseData(log.FightData.ToFightSpace(downPour.Time), fightDuration));
                    }
                }
                else
                {
                    phases.Add(new PhaseData(log.FightData.ToFightSpace(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);
        }
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Target           mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Dhuum);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // Sometimes the preevent is not in the evtc
            List <CastLog> castLogs  = mainTarget.GetCastLogs(log, 0, log.FightData.FightEnd);
            List <CastLog> dhuumCast = mainTarget.GetCastLogs(log, 0, 20000);

            string[] namesDh;
            if (dhuumCast.Count > 0)
            {
                namesDh = new[] { "Main Fight", "Ritual" };
                ComputeFightPhases(mainTarget, phases, log, castLogs, fightDuration, 0);
            }
            else
            {
                CombatItem invulDhuum = log.GetBoonData(762).FirstOrDefault(x => x.IsBuffRemove != ParseEnum.BuffRemove.None && x.SrcInstid == mainTarget.InstID && x.Time > 115000 + log.FightData.FightStart);
                if (invulDhuum != null)
                {
                    long end = log.FightData.ToFightSpace(invulDhuum.Time);
                    phases.Add(new PhaseData(0, end));
                    ComputeFightPhases(mainTarget, phases, log, castLogs, fightDuration, end + 1);
                }
                else
                {
                    phases.Add(new PhaseData(0, fightDuration));
                }
                namesDh = new[] { "Roleplay", "Main Fight", "Ritual" };
            }
            for (int i = 1; i < phases.Count; i++)
            {
                phases[i].Name = namesDh[i - 1];
                phases[i].Targets.Add(mainTarget);
            }
            if (dhuumCast.Count > 0 && phases.Count > 1)
            {
                phases.AddRange(GetInBetweenSoulSplits(log, mainTarget, phases[1].Start, phases[1].End));
                phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            }
            else if (phases.Count > 2)
            {
                phases.AddRange(GetInBetweenSoulSplits(log, mainTarget, phases[2].Start, phases[2].End));
                phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            }
            return(phases);
        }
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             end           = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Boss             mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.BossIDS.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
            CombatItem  heatWave    = log.GetBoonData(34526).FirstOrDefault();
            List <long> phaseStarts = new List <long>();

            if (heatWave != null)
            {
                phaseStarts.Add(heatWave.Time - log.FightData.FightStart);
                CombatItem downPour = log.GetDamageData(mainTarget.InstID).Find(x => x.SkillID == 34554);
                if (downPour != null)
                {
                    phaseStarts.Add(downPour.Time - log.FightData.FightStart);
                    List <CastLog> castLogs = mainTarget.GetCastLogs(log, 0, log.FightData.FightEnd);
                    CastLog        abo      = castLogs.Find(x => x.SkillId == 34427);
                    if (abo != null)
                    {
                        phaseStarts.Add(abo.Time);
                    }
                }
            }
            foreach (long t in phaseStarts)
            {
                end = t;
                phases.Add(new PhaseData(start, end));
                // make sure stuff from the precedent phase mix witch each other
                start = t + 1;
            }
            if (fightDuration - start > 5000 && start >= phases.Last().End)
            {
                phases.Add(new PhaseData(start, 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);
        }
Exemple #9
0
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Boss             mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.BossIDS.Xera);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // split happened
            if (log.FightData.PhaseData.Count == 1)
            {
                CombatItem invulXera = log.GetBoonData(762).Find(x => x.DstInstid == mainTarget.InstID);
                if (invulXera == null)
                {
                    invulXera = log.GetBoonData(34113).Find(x => x.DstInstid == mainTarget.InstID);
                }
                long end = invulXera.Time - log.FightData.FightStart;
                phases.Add(new PhaseData(start, end));
                start = log.FightData.PhaseData[0] - log.FightData.FightStart;
                mainTarget.AddCustomCastLog(new CastLog(end, -5, (int)(start - end), ParseEnum.Activation.None, (int)(start - end), ParseEnum.Activation.None), log);
            }
            if (fightDuration - start > 5000 && start >= phases.Last().End)
            {
                phases.Add(new PhaseData(start, fightDuration));
            }
            for (int i = 1; i < phases.Count; i++)
            {
                phases[i].Name      = "Phase " + i;
                phases[i].DrawArea  = true;
                phases[i].DrawStart = i > 1;
                phases[i].DrawEnd   = i < phases.Count - 1;
                phases[i].Targets.Add(mainTarget);
            }
            return(phases);
        }
        public override void ComputeAdditionalPlayerData(Player p, ParsedLog log)
        {
            // shared agony
            List <CombatItem> agony  = log.GetBoonData(38049).Where(x => (x.DstInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None)).ToList();
            CombatReplay      replay = p.CombatReplay;

            foreach (CombatItem c in agony)
            {
                int agonyStart = (int)log.FightData.ToFightSpace(c.Time);
                int agonyEnd   = agonyStart + 62000;
                replay.Actors.Add(new CircleActor(false, 0, 220, (agonyStart, agonyEnd), "rgba(255, 0, 0, 0.5)", new AgentConnector(p)));
            }
        }
        private ushort TryFindSrc(List <CastLog> castsToCheck, long time, long extension, ParsedLog log)
        {
            HashSet <long> idsToCheck = new HashSet <long>();

            switch (extension)
            {
            // SoI
            case 5000:
                idsToCheck.Add(10236);
                break;

            // Treated True Nature
            case 3000:
                idsToCheck.Add(51696);
                break;

            // Sand Squall, True Nature, Soulbeast trait
            case 2000:
                if (Prof == "Soulbeast")
                {
                    if (log.PlayerListBySpec.ContainsKey("Herald") || log.PlayerListBySpec.ContainsKey("Tempest"))
                    {
                        return(0);
                    }
                    // if not herald or tempest in squad then can only be the trait
                    return(InstID);
                }
                idsToCheck.Add(51696);
                idsToCheck.Add(29453);
                break;
            }
            List <CastLog> cls = castsToCheck.Where(x => idsToCheck.Contains(x.SkillId) && x.Time <= time && time <= x.Time + x.ActualDuration + 10 && x.EndActivation.NoInterruptEndCasting()).ToList();

            if (cls.Count == 1)
            {
                CastLog item = cls.First();
                if (extension == 2000 && log.PlayerListBySpec.TryGetValue("Tempest", out List <Player> tempests))
                {
                    List <CombatItem> magAuraApplications = log.GetBoonData(5684).Where(x => x.IsBuffRemove == ParseEnum.BuffRemove.None && x.IsOffcycle == 0).ToList();
                    foreach (Player tempest in tempests)
                    {
                        if (magAuraApplications.FirstOrDefault(x => x.SrcInstid == tempest.InstID && Math.Abs(x.Time - time) < 50) != null)
                        {
                            return(0);
                        }
                    }
                }
                return(item.SrcInstId);
            }
            return(0);
        }
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Target           mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Xera);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            long       end       = 0;
            CombatItem invulXera = log.GetBoonData(762).Find(x => x.DstInstid == mainTarget.InstID) ?? log.GetBoonData(34113).Find(x => x.DstInstid == mainTarget.InstID);

            if (invulXera != null)
            {
                end = log.FightData.ToFightSpace(invulXera.Time);
                phases.Add(new PhaseData(start, end));
                // split happened
                if (_specialSplit > 0)
                {
                    start = log.FightData.ToFightSpace(_specialSplit);
                    //mainTarget.AddCustomCastLog(end, -5, (int)(start - end), ParseEnum.Activation.None, (int)(start - end), ParseEnum.Activation.None, log);
                    phases.Add(new PhaseData(start, fightDuration));
                }
            }
            for (int i = 1; i < phases.Count; i++)
            {
                phases[i].Name = "Phase " + i;
                phases[i].Targets.Add(mainTarget);
            }
            return(phases);
        }
Exemple #13
0
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start  = 0;
            long             end    = 0;
            List <PhaseData> phases = GetInitialPhase(log);
            Target           ca     = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.ConjuredAmalgamate);

            if (ca == null)
            {
                throw new InvalidOperationException("Conjurate Amalgamate not found");
            }
            phases[0].Targets.Add(ca);
            if (!requirePhases)
            {
                return(phases);
            }
            List <CombatItem> CAInvul = GetFilteredList(log, 52255, ca, false);

            for (int i = 0; i < CAInvul.Count; i++)
            {
                CombatItem invul = CAInvul[i];
                if (invul.IsBuffRemove != ParseEnum.BuffRemove.None)
                {
                    end = Math.Min(log.FightData.ToFightSpace(invul.Time), log.FightData.FightDuration);
                    phases.Add(new PhaseData(start, end));
                    if (i == CAInvul.Count - 1)
                    {
                        phases.Add(new PhaseData(end, log.FightData.FightDuration));
                    }
                }
                else
                {
                    start = Math.Min(log.FightData.ToFightSpace(invul.Time), log.FightData.FightDuration);
                    phases.Add(new PhaseData(end, start));
                    if (i == CAInvul.Count - 1)
                    {
                        phases.Add(new PhaseData(start, log.FightData.FightDuration));
                    }
                }
            }
            phases.RemoveAll(x => x.GetDuration() < 1000);
            for (int i = 1; i < phases.Count; i++)
            {
                string    name;
                PhaseData phase = phases[i];
                if (i % 2 == 1)
                {
                    name = "Arm Phase";
                }
                else
                {
                    name = "Burn Phase";
                    phase.Targets.Add(ca);
                }
                phase.Name = name;
            }
            Target leftArm = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.CALeftArm);

            if (leftArm != null)
            {
                List <long> leftArmDown = log.GetBoonData(52430).Where(x => x.IsBuffRemove == ParseEnum.BuffRemove.All && x.SrcInstid == leftArm.InstID).Select(x => log.FightData.ToFightSpace(x.Time)).ToList();
                for (int i = 1; i < phases.Count; i += 2)
                {
                    PhaseData phase = phases[i];
                    if (leftArmDown.Exists(x => phase.InInterval(x)))
                    {
                        phase.Name = "Left " + phase.Name;
                        phase.Targets.Add(leftArm);
                    }
                }
            }
            Target rightArm = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.CARightArm);

            if (rightArm != null)
            {
                List <long> rightArmDown = log.GetBoonData(52430).Where(x => x.IsBuffRemove == ParseEnum.BuffRemove.All && x.SrcInstid == rightArm.InstID).Select(x => log.FightData.ToFightSpace(x.Time)).ToList();
                for (int i = 1; i < phases.Count; i += 2)
                {
                    PhaseData phase = phases[i];
                    if (rightArmDown.Exists(x => phase.InInterval(x)))
                    {
                        if (phase.Name.Contains("Left"))
                        {
                            phase.Name = "Both Arms Phase";
                        }
                        else
                        {
                            phase.Name = "Right " + phase.Name;
                        }
                        phase.Targets.Add(rightArm);
                    }
                }
            }
            return(phases);
        }
Exemple #14
0
        public override void ComputeAdditionalPlayerData(Player p, ParsedLog log)
        {
            // spirit transform
            CombatReplay      replay          = p.CombatReplay;
            List <CombatItem> spiritTransform = log.GetBoonData(46950).Where(x => x.DstInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None).ToList();
            Target            mainTarget      = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Dhuum);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            foreach (CombatItem c in spiritTransform)
            {
                int duration = 15000;
                int start    = (int)(log.FightData.ToFightSpace(c.Time));
                if (mainTarget.HealthOverTime.FirstOrDefault(x => x.X > start).Y < 1050)
                {
                    duration = 30000;
                }
                CombatItem removedBuff = log.GetBoonData(48281).FirstOrDefault(x => x.SrcInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.All && x.Time > c.Time && x.Time < c.Time + duration);
                int        end         = start + duration;
                if (removedBuff != null)
                {
                    end = (int)(log.FightData.ToFightSpace(removedBuff.Time));
                }
                replay.Actors.Add(new CircleActor(true, 0, 100, new Tuple <int, int>(start, end), "rgba(0, 50, 200, 0.3)", new AgentConnector(p)));
                replay.Actors.Add(new CircleActor(true, start + duration, 100, new Tuple <int, int>(start, end), "rgba(0, 50, 200, 0.5)", new AgentConnector(p)));
            }
            // bomb
            List <CombatItem> bombDhuum = GetFilteredList(log, 47646, p);
            int bombDhuumStart          = 0;

            foreach (CombatItem c in bombDhuum)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    bombDhuumStart = (int)(log.FightData.ToFightSpace(c.Time));
                }
                else
                {
                    int bombDhuumEnd = (int)(log.FightData.ToFightSpace(c.Time));
                    replay.Actors.Add(new CircleActor(true, 0, 100, new Tuple <int, int>(bombDhuumStart, bombDhuumEnd), "rgba(80, 180, 0, 0.3)", new AgentConnector(p)));
                    replay.Actors.Add(new CircleActor(true, bombDhuumStart + 13000, 100, new Tuple <int, int>(bombDhuumStart, bombDhuumEnd), "rgba(80, 180, 0, 0.5)", new AgentConnector(p)));
                }
            }
            // shackles connection
            List <CombatItem> shackles = GetFilteredList(log, 47335, p).Concat(GetFilteredList(log, 48591, p)).ToList();
            int    shacklesStart       = 0;
            Player shacklesTarget      = null;

            foreach (CombatItem c in shackles)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    shacklesStart  = (int)(log.FightData.ToFightSpace(c.Time));
                    shacklesTarget = log.PlayerList.FirstOrDefault(x => x.Agent == c.SrcAgent);
                }
                else
                {
                    int shacklesEnd           = (int)(log.FightData.ToFightSpace(c.Time));
                    Tuple <int, int> duration = new Tuple <int, int>(shacklesStart, shacklesEnd);
                    if (shacklesTarget != null)
                    {
                        replay.Actors.Add(new LineActor(0, 10, duration, "rgba(0, 255, 255, 0.5)", new AgentConnector(p), new AgentConnector(shacklesTarget)));
                    }
                }
            }
            // shackles damage (identical to the connection for now, not yet properly distinguishable from the pure connection, further investigation needed due to inconsistent behavior (triggering too early, not triggering the damaging skill though)
            // shackles start with buff 47335 applied from one player to the other, this is switched over to buff 48591 after mostly 2 seconds, sometimes later. This is switched to 48042 usually 4 seconds after initial application and the damaging skill 47164 starts to deal damage from that point on.
            // Before that point, 47164 is only logged when evaded/blocked, but doesn't deal damage. Further investigation needed.
            List <CombatItem> shacklesDmg = GetFilteredList(log, 48042, p);
            int    shacklesDmgStart       = 0;
            Player shacklesDmgTarget      = null;

            foreach (CombatItem c in shacklesDmg)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    shacklesDmgStart  = (int)(log.FightData.ToFightSpace(c.Time));
                    shacklesDmgTarget = log.PlayerList.FirstOrDefault(x => x.Agent == c.SrcAgent);
                }
                else
                {
                    int shacklesDmgEnd        = (int)(log.FightData.ToFightSpace(c.Time));
                    Tuple <int, int> duration = new Tuple <int, int>(shacklesDmgStart, shacklesDmgEnd);
                    if (shacklesDmgTarget != null)
                    {
                        replay.Actors.Add(new LineActor(0, 10, duration, "rgba(0, 255, 255, 0.5)", new AgentConnector(p), new AgentConnector(shacklesDmgTarget)));
                    }
                }
            }
        }
Exemple #15
0
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             end           = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Boss             mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.BossIDS.Deimos);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // Determined + additional data on inst change
            CombatItem invulDei = log.GetBoonData(762).Find(x => x.IsBuffRemove == ParseEnum.BuffRemove.None && x.DstInstid == mainTarget.InstID);

            if (invulDei != null)
            {
                end = invulDei.Time - log.FightData.FightStart;
                phases.Add(new PhaseData(start, end));
                start = (log.FightData.PhaseData.Count == 1 ? log.FightData.PhaseData[0] - log.FightData.FightStart : fightDuration);
                mainTarget.AddCustomCastLog(new CastLog(end, -6, (int)(start - end), ParseEnum.Activation.None, (int)(start - end), ParseEnum.Activation.None), log);
            }
            if (fightDuration - start > 5000 && start >= phases.Last().End)
            {
                phases.Add(new PhaseData(start, fightDuration));
            }
            for (int i = 1; i < phases.Count; i++)
            {
                phases[i].Name = "Phase " + i;
                phases[i].Targets.Add(mainTarget);
                if (i == 2)
                {
                    phases[i].DrawArea = true;
                }
            }
            int        offsetDei = phases.Count;
            CombatItem teleport  = log.GetBoonData(38169).FirstOrDefault(x => x.Time > log.FightData.FightStart);
            int        splits    = 0;

            while (teleport != null && splits < 3)
            {
                start = teleport.Time - log.FightData.FightStart;
                CombatItem teleportBack = log.GetBoonData(38169).FirstOrDefault(x => x.Time - log.FightData.FightStart > start + 10000);
                if (teleportBack != null)
                {
                    end = Math.Min(teleportBack.Time - log.FightData.FightStart, fightDuration);
                }
                else
                {
                    end = fightDuration;
                }
                phases.Add(new PhaseData(start, end));
                splits++;
                teleport = log.GetBoonData(38169).FirstOrDefault(x => x.Time - log.FightData.FightStart > end + 10000);
            }

            string[] namesDeiSplit = new [] { "Thief", "Gambler", "Drunkard" };
            for (int i = offsetDei; i < phases.Count; i++)
            {
                PhaseData phase = phases[i];
                phase.Name     = namesDeiSplit[i - offsetDei];
                phase.DrawArea = true;
                List <ushort> ids = new List <ushort>
                {
                    (ushort)Thief,
                    (ushort)Drunkard,
                    (ushort)Gambler,
                };
                AddTargetsToPhase(phase, ids, log);
            }
            phases.Sort((x, y) => (x.Start < y.Start) ? -1 : 1);
            foreach (PhaseData phase in phases)
            {
                phase.DrawStart = true;
                phase.DrawEnd   = true;
            }
            phases.RemoveAll(x => x.Targets.Count == 0);
            return(phases);
        }
Exemple #16
0
        public override void ComputeAdditionalTargetData(Target target, ParsedLog log)
        {
            CombatReplay   replay = target.CombatReplay;
            List <CastLog> cls    = target.GetCastLogs(log, 0, log.FightData.FightDuration);

            switch (target.ID)
            {
            case (ushort)ParseEnum.TargetIDS.Gorseval:
                List <CastLog> blooms = cls.Where(x => x.SkillId == 31616).ToList();
                foreach (CastLog c in blooms)
                {
                    int start = (int)c.Time;
                    int end   = start + c.ActualDuration;
                    replay.Actors.Add(new CircleActor(true, c.ExpectedDuration + (int)c.Time, 600, new Tuple <int, int>(start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target)));
                    replay.Actors.Add(new CircleActor(false, 0, 600, new Tuple <int, int>(start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target)));
                }
                List <PhaseData> phases = log.FightData.GetPhases(log);
                if (phases.Count > 1)
                {
                    List <CastLog> rampage = cls.Where(x => x.SkillId == 31834).ToList();
                    Point3D        pos     = target.CombatReplay.Positions.First();
                    foreach (CastLog c in rampage)
                    {
                        int start = (int)c.Time;
                        int end   = start + c.ActualDuration;
                        replay.Actors.Add(new CircleActor(true, 0, 180, new Tuple <int, int>(start, end), "rgba(0, 125, 255, 0.3)", new AgentConnector(target)));
                        // or spawn -> 3 secs -> explosion -> 0.5 secs -> fade -> 0.5  secs-> next
                        int ticks = (int)Math.Min(Math.Ceiling(c.ActualDuration / 4000.0), 6);
                        int phaseIndex;
                        for (phaseIndex = 1; phaseIndex < phases.Count; phaseIndex++)
                        {
                            if (phases[phaseIndex].InInterval(start))
                            {
                                break;
                            }
                        }
                        if (pos == null)
                        {
                            break;
                        }
                        List <string> patterns;
                        switch (phaseIndex)
                        {
                        case 1:
                            patterns = new List <string>
                            {
                                "2+3+5",
                                "2+3+4",
                                "1+4+5",
                                "1+2+5",
                                "1+3+5",
                                "Full"
                            };
                            break;

                        case 3:
                            patterns = new List <string>
                            {
                                "2+3+4",
                                "1+4+5",
                                "1+3+4",
                                "1+2+5",
                                "1+2+3",
                                "Full"
                            };
                            break;

                        case 5:
                            patterns = new List <string>
                            {
                                "1+4+5",
                                "1+2+5",
                                "2+3+5",
                                "3+4+5",
                                "3+4+5",
                                "Full"
                            };
                            break;

                        default:
                            throw new Exception("how the f**k");
                        }
                        start += 2200;
                        for (int i = 0; i < ticks; i++)
                        {
                            int    tickStart = start + 4000 * i;
                            int    explosion = tickStart + 3000;
                            int    tickEnd   = tickStart + 3500;
                            string pattern   = patterns[i];
                            if (pattern.Contains("1"))
                            {
                                replay.Actors.Add(new CircleActor(true, explosion, 360, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos)));
                                replay.Actors.Add(new CircleActor(true, 0, 360, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos)));
                            }
                            if (pattern.Contains("2"))
                            {
                                replay.Actors.Add(new DoughnutActor(true, explosion, 360, 720, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos)));
                                replay.Actors.Add(new DoughnutActor(true, 0, 360, 720, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos)));
                            }
                            if (pattern.Contains("3"))
                            {
                                replay.Actors.Add(new DoughnutActor(true, explosion, 720, 1080, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos)));
                                replay.Actors.Add(new DoughnutActor(true, 0, 720, 1080, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos)));
                            }
                            if (pattern.Contains("4"))
                            {
                                replay.Actors.Add(new DoughnutActor(true, explosion, 1080, 1440, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos)));
                                replay.Actors.Add(new DoughnutActor(true, 0, 1080, 1440, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos)));
                            }
                            if (pattern.Contains("5"))
                            {
                                replay.Actors.Add(new DoughnutActor(true, explosion, 1440, 1800, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos)));
                                replay.Actors.Add(new DoughnutActor(true, 0, 1440, 1800, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos)));
                            }
                            if (pattern.Contains("Full"))
                            {
                                tickStart -= 1000;
                                explosion -= 1000;
                                tickEnd   -= 1000;
                                replay.Actors.Add(new CircleActor(true, explosion, 1800, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.2)", new PositionConnector(pos)));
                                replay.Actors.Add(new CircleActor(true, 0, 1800, new Tuple <int, int>(tickStart, tickEnd), "rgba(25,25,112, 0.4)", new PositionConnector(pos)));
                            }
                        }
                    }
                }
                List <CastLog> slam = cls.Where(x => x.SkillId == 31875).ToList();
                foreach (CastLog c in slam)
                {
                    int start       = (int)c.Time;
                    int impactPoint = 1185;
                    int impactTime  = start + impactPoint;
                    int end         = (int)Math.Min(start + c.ActualDuration, impactTime);
                    int radius      = 320;
                    replay.Actors.Add(new CircleActor(true, 0, radius, new Tuple <int, int>(start, end), "rgba(255, 0, 0, 0.2)", new AgentConnector(target)));
                    replay.Actors.Add(new CircleActor(true, 0, radius, new Tuple <int, int>(impactTime - 10, impactTime + 100), "rgba(255, 0, 0, 0.4)", new AgentConnector(target)));
                }
                List <CombatItem> protection = log.GetBoonData(31877).Where(x => x.IsBuffRemove != ParseEnum.BuffRemove.Manual).ToList();
                int protectionStart          = 0;
                foreach (CombatItem c in protection)
                {
                    if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                    {
                        protectionStart = (int)(log.FightData.ToFightSpace(c.Time));
                    }
                    else
                    {
                        int protectionEnd = (int)(log.FightData.ToFightSpace(c.Time));
                        replay.Actors.Add(new CircleActor(true, 0, 300, new Tuple <int, int>(protectionStart, protectionEnd), "rgba(0, 180, 255, 0.5)", new AgentConnector(target)));
                    }
                }
                break;

            case (ushort)ChargedSoul:
                Tuple <int, int> lifespan = new Tuple <int, int>((int)replay.TimeOffsets.Item1, (int)replay.TimeOffsets.Item2);
                replay.Actors.Add(new CircleActor(false, 0, 220, lifespan, "rgba(255, 150, 0, 0.5)", new AgentConnector(target)));
                break;

            default:
                throw new InvalidOperationException("Unknown ID in ComputeAdditionalData");
            }
        }
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             end           = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Boss             mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.BossIDS.KeepConstruct);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // Main phases
            List <CastLog> castLogs = mainTarget.GetCastLogs(log, 0, log.FightData.FightEnd);
            List <CastLog> clsKC    = castLogs.Where(x => x.SkillId == 35048).ToList();

            foreach (CastLog cl in clsKC)
            {
                end = cl.Time;
                phases.Add(new PhaseData(start, end));
                start = end + cl.ActualDuration;
            }
            if (fightDuration - start > 5000 && start >= phases.Last().End)
            {
                phases.Add(new PhaseData(start, fightDuration));
                start = fightDuration;
            }
            for (int i = 1; i < phases.Count; i++)
            {
                phases[i].Name = "Phase " + i;
                phases[i].Targets.Add(mainTarget);
            }
            // add burn phases
            int offset = phases.Count;
            List <CombatItem> orbItems = log.GetBoonData(35096).Where(x => x.DstInstid == mainTarget.InstID).ToList();

            // Get number of orbs and filter the list
            start = 0;
            int orbCount = 0;
            List <BoonsGraphModel.Segment> segments = new List <BoonsGraphModel.Segment>();

            foreach (CombatItem c in orbItems)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    if (start == 0)
                    {
                        start = c.Time - log.FightData.FightStart;
                    }
                    orbCount++;
                }
                else if (start != 0)
                {
                    segments.Add(new BoonsGraphModel.Segment(start, Math.Min(c.Time - log.FightData.FightStart, fightDuration), orbCount));
                    orbCount = 0;
                    start    = 0;
                }
            }
            int burnCount = 1;

            foreach (var seg in segments)
            {
                var phase = new PhaseData(seg.Start, seg.End)
                {
                    Name      = "Burn " + burnCount++ + " (" + seg.Value + " orbs)",
                    DrawArea  = true,
                    DrawStart = true,
                    DrawEnd   = true
                };
                phase.Targets.Add(mainTarget);
                phases.Add(phase);
            }
            phases.Sort((x, y) => (x.Start < y.Start) ? -1 : 1);
            phases.Last().DrawEnd = false;
            return(phases);
        }
        public void ComputeMechanics(ParsedLog log)
        {
            MechanicData mechData   = log.MechanicData;
            FightData    fightData  = log.FightData;
            CombatData   combatData = log.CombatData;
            long         start      = fightData.FightStart;
            long         end        = fightData.FightEnd;

            Mechanic.CheckSpecialCondition condition;
            HashSet <ushort> playersIds = new HashSet <ushort>(log.PlayerList.Select(x => x.InstID));
            Dictionary <ushort, AbstractMasterPlayer> regroupedMobs = new Dictionary <ushort, AbstractMasterPlayer>();

            foreach (Mechanic mech in MechanicList)
            {
                switch (mech.MechanicType)
                {
                case Mechanic.MechType.PlayerStatus:
                    foreach (Player p in log.PlayerList)
                    {
                        List <CombatItem> cList = new List <CombatItem>();
                        switch (mech.SkillId)
                        {
                        case SkillItem.DeathId:
                            cList = combatData.GetStates(p.InstID, ParseEnum.StateChange.ChangeDead, start, end);
                            break;

                        case SkillItem.DownId:
                            cList = combatData.GetStates(p.InstID, ParseEnum.StateChange.ChangeDown, start, end);
                            break;

                        case SkillItem.ResurrectId:
                            cList = log.GetCastData(p.InstID).Where(x => x.SkillID == SkillItem.ResurrectId && x.IsActivation.IsCasting()).ToList();
                            break;
                        }
                        foreach (CombatItem mechItem in cList)
                        {
                            mechData[mech].Add(new MechanicLog(mechItem.Time - start, mech, p));
                        }
                    }
                    break;

                case Mechanic.MechType.SkillOnPlayer:
                    foreach (Player p in log.PlayerList)
                    {
                        List <DamageLog> dls = p.GetDamageTakenLogs(log, 0, fightData.FightDuration);
                        condition = mech.SpecialCondition;
                        foreach (DamageLog dLog in dls)
                        {
                            if (condition != null && !condition(new SpecialConditionItem(dLog)))
                            {
                                continue;
                            }
                            if (dLog.SkillId == mech.SkillId && dLog.Result.IsHit())
                            {
                                mechData[mech].Add(new MechanicLog(dLog.Time, mech, p));
                            }
                        }
                    }
                    break;

                case Mechanic.MechType.PlayerBoon:
                case Mechanic.MechType.PlayerOnPlayer:
                case Mechanic.MechType.PlayerBoonRemove:
                    foreach (Player p in log.PlayerList)
                    {
                        condition = mech.SpecialCondition;
                        foreach (CombatItem c in log.GetBoonData(mech.SkillId))
                        {
                            if (condition != null && !condition(new SpecialConditionItem(c)))
                            {
                                continue;
                            }
                            if (mech.MechanicType == Mechanic.MechType.PlayerBoonRemove)
                            {
                                if (c.IsBuffRemove == ParseEnum.BuffRemove.Manual && p.InstID == c.SrcInstid)
                                {
                                    mechData[mech].Add(new MechanicLog(c.Time - start, mech, p));
                                }
                            }
                            else
                            {
                                if (c.IsBuffRemove == ParseEnum.BuffRemove.None && p.InstID == c.DstInstid)
                                {
                                    mechData[mech].Add(new MechanicLog(c.Time - start, mech, p));
                                    if (mech.MechanicType == Mechanic.MechType.PlayerOnPlayer)
                                    {
                                        mechData[mech].Add(new MechanicLog(c.Time - start, mech, log.PlayerList.FirstOrDefault(x => x.InstID == c.SrcInstid)));
                                    }
                                }
                            }
                        }
                    }
                    break;

                case Mechanic.MechType.HitOnEnemy:
                    foreach (Player p in log.PlayerList)
                    {
                        condition = mech.SpecialCondition;
                        IEnumerable <AgentItem> agents = log.AgentData.GetAgentsByID((ushort)mech.SkillId);
                        foreach (AgentItem a in agents)
                        {
                            foreach (DamageLog dl in p.GetDamageLogs(null, log, 0, log.FightData.FightDuration))
                            {
                                if (dl.DstInstId != a.InstID || dl.IsCondi > 0 || dl.Time < a.FirstAware - start || dl.Time > a.LastAware - start || (condition != null && !condition(new SpecialConditionItem(dl))))
                                {
                                    continue;
                                }
                                mechData[mech].Add(new MechanicLog(dl.Time, mech, p));
                            }
                        }
                    }
                    break;

                case Mechanic.MechType.PlayerSkill:
                    foreach (Player p in log.PlayerList)
                    {
                        condition = mech.SpecialCondition;
                        foreach (CombatItem c in log.GetCastDataById(mech.SkillId))
                        {
                            if (condition != null && !condition(new SpecialConditionItem(c)))
                            {
                                continue;
                            }
                            if (c.IsActivation.IsCasting() && c.SrcInstid == p.InstID)
                            {
                                mechData[mech].Add(new MechanicLog(c.Time - fightData.FightStart, mech, p));
                            }
                        }
                    }
                    break;

                case Mechanic.MechType.EnemyBoon:
                case Mechanic.MechType.EnemyBoonStrip:
                    condition = mech.SpecialCondition;
                    foreach (CombatItem c in log.GetBoonData(mech.SkillId))
                    {
                        if (condition != null && !condition(new SpecialConditionItem(c)))
                        {
                            continue;
                        }
                        AbstractMasterPlayer amp = null;
                        if (mech.MechanicType == Mechanic.MechType.EnemyBoon && c.IsBuffRemove == ParseEnum.BuffRemove.None)
                        {
                            Boss target = Targets.Find(x => x.InstID == c.DstInstid && x.FirstAware <= c.Time && x.LastAware >= c.Time);
                            if (target != null)
                            {
                                amp = target;
                            }
                            else
                            {
                                AgentItem a = log.AgentData.GetAgent(c.DstAgent);
                                if (playersIds.Contains(a.InstID))
                                {
                                    continue;
                                }
                                else if (a.MasterAgent != 0)
                                {
                                    AgentItem m = log.AgentData.GetAgent(a.MasterAgent);
                                    if (playersIds.Contains(m.InstID))
                                    {
                                        continue;
                                    }
                                }
                                if (!regroupedMobs.TryGetValue(a.ID, out amp))
                                {
                                    amp = new DummyPlayer(a);
                                    regroupedMobs.Add(a.ID, amp);
                                }
                            }
                        }
                        else if (mech.MechanicType == Mechanic.MechType.EnemyBoonStrip && c.IsBuffRemove == ParseEnum.BuffRemove.Manual)
                        {
                            Boss target = Targets.Find(x => x.InstID == c.SrcInstid && x.FirstAware <= c.Time && x.LastAware >= c.Time);
                            if (target != null)
                            {
                                amp = target;
                            }
                            else
                            {
                                AgentItem a = log.AgentData.GetAgent(c.SrcAgent);
                                if (playersIds.Contains(a.InstID))
                                {
                                    continue;
                                }
                                else if (a.MasterAgent != 0)
                                {
                                    AgentItem m = log.AgentData.GetAgent(a.MasterAgent);
                                    if (playersIds.Contains(m.InstID))
                                    {
                                        continue;
                                    }
                                }
                                if (!regroupedMobs.TryGetValue(a.ID, out amp))
                                {
                                    amp = new DummyPlayer(a);
                                    regroupedMobs.Add(a.ID, amp);
                                }
                            }
                        }
                        if (amp != null)
                        {
                            mechData[mech].Add(new MechanicLog(c.Time - fightData.FightStart, mech, amp));
                        }
                    }
                    break;

                case Mechanic.MechType.EnemyCastEnd:
                case Mechanic.MechType.EnemyCastStart:
                    condition = mech.SpecialCondition;
                    foreach (CombatItem c in log.GetCastDataById(mech.SkillId))
                    {
                        if (condition != null && !condition(new SpecialConditionItem(c)))
                        {
                            continue;
                        }
                        AbstractMasterPlayer amp = null;
                        if ((mech.MechanicType == Mechanic.MechType.EnemyCastStart && c.IsActivation.IsCasting()) || (mech.MechanicType == Mechanic.MechType.EnemyCastEnd && !c.IsActivation.IsCasting()))
                        {
                            Boss target = Targets.Find(x => x.InstID == c.SrcInstid && x.FirstAware <= c.Time && x.LastAware >= c.Time);
                            if (target != null)
                            {
                                amp = target;
                            }
                            else
                            {
                                AgentItem a = log.AgentData.GetAgent(c.SrcAgent);
                                if (playersIds.Contains(a.InstID))
                                {
                                    continue;
                                }
                                else if (a.MasterAgent != 0)
                                {
                                    AgentItem m = log.AgentData.GetAgent(a.MasterAgent);
                                    if (playersIds.Contains(m.InstID))
                                    {
                                        continue;
                                    }
                                }
                                if (!regroupedMobs.TryGetValue(a.ID, out amp))
                                {
                                    amp = new DummyPlayer(a);
                                    regroupedMobs.Add(a.ID, amp);
                                }
                            }
                        }
                        if (amp != null)
                        {
                            mechData[mech].Add(new MechanicLog(c.Time - fightData.FightStart, mech, amp));
                        }
                    }
                    break;

                case Mechanic.MechType.Spawn:
                    foreach (AgentItem a in log.AgentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => x.ID == mech.SkillId))
                    {
                        if (!regroupedMobs.TryGetValue(a.ID, out AbstractMasterPlayer amp))
                        {
                            amp = new DummyPlayer(a);
                            regroupedMobs.Add(a.ID, amp);
                        }
                        mechData[mech].Add(new MechanicLog(a.FirstAware - fightData.FightStart, mech, amp));
                    }
                    break;
                }
            }
            mechData.ComputePresentMechanics(log);
        }
 public override List<PhaseData> GetPhases(ParsedLog log, bool requirePhases)
 {
     long start = 0;
     long end = 0;
     long fightDuration = log.FightData.FightDuration;
     List<PhaseData> phases = GetInitialPhase(log);
     Boss mainTarget = Targets.Find(x => x.ID == (ushort)ParseEnum.BossIDS.Gorseval);
     if (mainTarget == null)
     {
         throw new InvalidOperationException("Main target of the fight not found");
     }
     phases[0].Targets.Add(mainTarget);
     if (!requirePhases)
     {
         return phases;
     }
     // Ghostly protection check
     List<CombatItem> invulsGorse = log.GetBoonData(31790).Where(x => x.IsBuffRemove != ParseEnum.BuffRemove.Manual).ToList();
     for (int i = 0; i < invulsGorse.Count; i++)
     {
         CombatItem c = invulsGorse[i];
         if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
         {
             end = c.Time - log.FightData.FightStart;
             phases.Add(new PhaseData(start, end));
             if (i == invulsGorse.Count - 1)
             {
                 mainTarget.AddCustomCastLog(new CastLog(end, -5, (int)(fightDuration - end), ParseEnum.Activation.None, (int)(fightDuration - end), ParseEnum.Activation.None), log);
             }
         }
         else
         {
             start = c.Time - log.FightData.FightStart;
             phases.Add(new PhaseData(end, start));
             mainTarget.AddCustomCastLog(new CastLog(end, -5, (int)(start - end), ParseEnum.Activation.None, (int)(start - end), ParseEnum.Activation.None), log);
         }
     }
     if (fightDuration - start > 5000 && start >= phases.Last().End)
     {
         phases.Add(new PhaseData(start, fightDuration));
     }
     string[] namesGorse = new [] { "Phase 1", "Split 1", "Phase 2", "Split 2", "Phase 3" };
     for (int i = 1; i < phases.Count; i++)
     {
         PhaseData phase = phases[i];
         phase.Name = namesGorse[i - 1];
         phase.DrawArea = i == 1 || i == 3 || i == 5;
         phase.DrawStart = i == 3 || i == 5;
         phase.DrawEnd = i == 1 || i == 3;
         if (i == 1 || i == 3 || i == 5)
         {
             phase.Targets.Add(mainTarget);
         } else
         {
             List<ushort> ids = new List<ushort>
             {
                (ushort) ChargedSoul
             };
             AddTargetsToPhase(phase, ids, log);
         }
     }
     return phases;
 }
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             end           = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Boss             mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.BossIDS.Dhuum);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // Sometimes the preevent is not in the evtc
            List <CastLog> castLogs  = mainTarget.GetCastLogs(log, 0, log.FightData.FightEnd);
            List <CastLog> dhuumCast = mainTarget.GetCastLogs(log, 0, 20000);

            if (dhuumCast.Count > 0)
            {
                CastLog shield = castLogs.Find(x => x.SkillId == 47396);
                if (shield != null)
                {
                    end = shield.Time;
                    phases.Add(new PhaseData(start, end));
                    start = shield.Time + shield.ActualDuration;
                    if (start < fightDuration - 5000)
                    {
                        phases.Add(new PhaseData(start, fightDuration));
                    }
                }
                if (fightDuration - start > 5000 && start >= phases.Last().End)
                {
                    phases.Add(new PhaseData(start, fightDuration));
                }
                string[] namesDh = new [] { "Main Fight", "Ritual" };
                for (int i = 1; i < phases.Count; i++)
                {
                    phases[i].Name      = namesDh[i - 1];
                    phases[i].DrawArea  = true;
                    phases[i].DrawStart = i > 1;
                    phases[i].DrawEnd   = i < phases.Count - 1;
                    phases[i].Targets.Add(mainTarget);
                }
            }
            else
            {
                CombatItem invulDhuum = log.GetBoonData(762).FirstOrDefault(x => x.IsBuffRemove != ParseEnum.BuffRemove.None && x.SrcInstid == mainTarget.InstID && x.Time > 115000 + log.FightData.FightStart);
                if (invulDhuum != null)
                {
                    end = invulDhuum.Time - log.FightData.FightStart;
                    phases.Add(new PhaseData(start, end));
                    start = end + 1;
                    CastLog shield = castLogs.Find(x => x.SkillId == 47396);
                    if (shield != null)
                    {
                        end = shield.Time;
                        phases.Add(new PhaseData(start, end));
                        start = shield.Time + shield.ActualDuration;
                        if (start < fightDuration - 5000)
                        {
                            phases.Add(new PhaseData(start, fightDuration));
                        }
                    }
                }
                if (fightDuration - start > 5000 && start >= phases.Last().End)
                {
                    phases.Add(new PhaseData(start, fightDuration));
                }
                string[] namesDh = new [] { "Roleplay", "Main Fight", "Ritual" };
                for (int i = 1; i < phases.Count; i++)
                {
                    phases[i].Name      = namesDh[i - 1];
                    phases[i].DrawArea  = i > 1;
                    phases[i].DrawStart = i > 1;
                    phases[i].DrawEnd   = i == 2;
                    phases[i].Targets.Add(mainTarget);
                }
            }
            return(phases);
        }
Exemple #21
0
        public override void ComputeAdditionalPlayerData(Player p, ParsedLog log)
        {
            // big bomb
            CombatReplay      replay  = p.CombatReplay;
            List <CombatItem> bigbomb = log.GetBoonData(37966).Where(x => (x.DstInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None)).ToList();

            foreach (CombatItem c in bigbomb)
            {
                int bigStart = (int)(log.FightData.ToFightSpace(c.Time));
                int bigEnd   = bigStart + 6000;
                replay.Actors.Add(new CircleActor(true, 0, 300, (bigStart, bigEnd), "rgba(150, 80, 0, 0.2)", new AgentConnector(p)));
                replay.Actors.Add(new CircleActor(true, bigEnd, 300, (bigStart, bigEnd), "rgba(150, 80, 0, 0.2)", new AgentConnector(p)));
            }
            // small bomb
            List <CombatItem> smallbomb = log.GetBoonData(38247).Where(x => (x.DstInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None)).ToList();

            foreach (CombatItem c in smallbomb)
            {
                int smallStart = (int)(log.FightData.ToFightSpace(c.Time));
                int smallEnd   = smallStart + 6000;
                replay.Actors.Add(new CircleActor(true, 0, 80, (smallStart, smallEnd), "rgba(80, 150, 0, 0.3)", new AgentConnector(p)));
            }
            // fixated
            List <CombatItem> fixatedSam = GetFilteredList(log, 37868, p, true);
            int fixatedSamStart          = 0;

            foreach (CombatItem c in fixatedSam)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    fixatedSamStart = Math.Max((int)(log.FightData.ToFightSpace(c.Time)), 0);
                }
                else
                {
                    int fixatedSamEnd = (int)(log.FightData.ToFightSpace(c.Time));
                    replay.Actors.Add(new CircleActor(true, 0, 80, (fixatedSamStart, fixatedSamEnd), "rgba(255, 80, 255, 0.3)", new AgentConnector(p)));
                }
            }
            //fixated Ghuldem
            List <CombatItem> fixatedGuldhem = GetFilteredList(log, 38223, p, true);
            int    fixationGuldhemStart      = 0;
            Target guldhem = null;

            foreach (CombatItem c in fixatedGuldhem)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    fixationGuldhemStart = (int)(log.FightData.ToFightSpace(c.Time));
                    guldhem = Targets.FirstOrDefault(x => x.ID == (ushort)ParseEnum.TrashIDS.Guldhem && c.Time >= x.FirstAware && c.Time <= x.LastAware);
                }
                else
                {
                    int fixationGuldhemEnd = (int)(log.FightData.ToFightSpace(c.Time));
                    if (guldhem != null)
                    {
                        replay.Actors.Add(new LineActor(0, (fixationGuldhemStart, fixationGuldhemEnd), "rgba(255, 100, 0, 0.3)", new AgentConnector(p), new AgentConnector(guldhem)));
                    }
                }
            }
            //fixated Rigom
            List <CombatItem> fixatedRigom = GetFilteredList(log, 37693, p, true);
            int    fixationRigomStart      = 0;
            Target rigom = null;

            foreach (CombatItem c in fixatedRigom)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    fixationRigomStart = (int)(log.FightData.ToFightSpace(c.Time));
                    rigom = Targets.FirstOrDefault(x => x.ID == (ushort)ParseEnum.TrashIDS.Rigom && c.Time >= x.FirstAware && c.Time <= x.LastAware);
                }
                else
                {
                    int fixationRigomEnd = (int)(log.FightData.ToFightSpace(c.Time));
                    if (rigom != null)
                    {
                        replay.Actors.Add(new LineActor(0, (fixationRigomStart, fixationRigomEnd), "rgba(255, 0, 0, 0.3)", new AgentConnector(p), new AgentConnector(rigom)));
                    }
                }
            }
        }
        public override void ComputeAdditionalBossData(Boss boss, ParsedLog log)
        {
            // TODO: needs facing information for hadouken
            CombatReplay   replay = boss.CombatReplay;
            List <CastLog> cls    = boss.GetCastLogs(log, 0, log.FightData.FightDuration);

            switch (boss.ID)
            {
            case (ushort)ParseEnum.BossIDS.Matthias:
                List <CastLog> humanShield        = cls.Where(x => x.SkillId == 34468).ToList();
                List <int>     humanShieldRemoval = log.GetBoonData(34518).Where(x => x.IsBuffRemove == ParseEnum.BuffRemove.All).Select(x => (int)(x.Time - log.FightData.FightStart)).Distinct().ToList();
                for (var i = 0; i < humanShield.Count; i++)
                {
                    var shield = humanShield[i];
                    if (i < humanShieldRemoval.Count)
                    {
                        int removal = humanShieldRemoval[i];
                        replay.Actors.Add(new CircleActor(true, 0, 250, new Tuple <int, int>((int)shield.Time, removal), "rgba(255, 0, 255, 0.5)", new AgentConnector(boss)));
                    }
                    else
                    {
                        replay.Actors.Add(new CircleActor(true, 0, 250, new Tuple <int, int>((int)shield.Time, (int)log.FightData.FightDuration), "rgba(255, 0, 255, 0.5)", new AgentConnector(boss)));
                    }
                }
                List <CastLog> aboShield        = cls.Where(x => x.SkillId == 34510).ToList();
                List <int>     aboShieldRemoval = log.GetBoonData(34376).Where(x => x.IsBuffRemove == ParseEnum.BuffRemove.All).Select(x => (int)(x.Time - log.FightData.FightStart)).Distinct().ToList();
                for (var i = 0; i < aboShield.Count; i++)
                {
                    var shield = aboShield[i];
                    if (i < aboShieldRemoval.Count)
                    {
                        int removal = aboShieldRemoval[i];
                        replay.Actors.Add(new CircleActor(true, 0, 250, new Tuple <int, int>((int)shield.Time, removal), "rgba(255, 0, 255, 0.5)", new AgentConnector(boss)));
                    }
                    else
                    {
                        replay.Actors.Add(new CircleActor(true, 0, 250, new Tuple <int, int>((int)shield.Time, (int)log.FightData.FightDuration), "rgba(255, 0, 255, 0.5)", new AgentConnector(boss)));
                    }
                }
                List <CastLog> rageShards = cls.Where(x => x.SkillId == 34404 || x.SkillId == 34411).ToList();
                foreach (CastLog c in rageShards)
                {
                    int start = (int)c.Time;
                    int end   = start + c.ActualDuration;
                    replay.Actors.Add(new CircleActor(false, 0, 300, new Tuple <int, int>(start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(boss)));
                    replay.Actors.Add(new CircleActor(true, end, 300, new Tuple <int, int>(start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(boss)));
                }
                List <CastLog> hadouken = cls.Where(x => x.SkillId == 34371 || x.SkillId == 34380).ToList();
                foreach (CastLog c in hadouken)
                {
                    int     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.Actors.Add(new RotatedRectangleActor(true, 0, width, height, direction, width / 2, new Tuple <int, int>(start, start + preCastTime), "rgba(255, 0, 0, 0.1)", new AgentConnector(boss)));
                        replay.Actors.Add(new RotatedRectangleActor(true, 0, width, height, direction, width / 2, new Tuple <int, int>(start + preCastTime, start + preCastTime + duration), "rgba(255, 0, 0, 0.7)", new AgentConnector(boss)));
                    }
                }
                break;

            default:
                throw new InvalidOperationException("Unknown ID in ComputeAdditionalData");
            }
        }
        public override void ComputeAdditionalPlayerData(Player p, ParsedLog log)
        {
            // Corruption
            CombatReplay      replay            = p.CombatReplay;
            List <CombatItem> corruptedMatthias = GetFilteredList(log, 34416, p);

            corruptedMatthias.AddRange(GetFilteredList(log, 34473, p));
            int corruptedMatthiasStart = 0;

            foreach (CombatItem c in corruptedMatthias)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    corruptedMatthiasStart = (int)(c.Time - log.FightData.FightStart);
                }
                else
                {
                    int corruptedMatthiasEnd = (int)(c.Time - log.FightData.FightStart);
                    replay.Actors.Add(new CircleActor(true, 0, 180, new Tuple <int, int>(corruptedMatthiasStart, corruptedMatthiasEnd), "rgba(255, 150, 0, 0.5)", new AgentConnector(p)));
                    Point3D wellNextPosition = replay.Positions.FirstOrDefault(x => x.Time >= corruptedMatthiasEnd);
                    Point3D wellPrevPosition = replay.Positions.LastOrDefault(x => x.Time <= corruptedMatthiasEnd);
                    if (wellNextPosition != null || wellPrevPosition != null)
                    {
                        replay.Actors.Add(new CircleActor(true, 0, 180, new Tuple <int, int>(corruptedMatthiasEnd, corruptedMatthiasEnd + 100000), "rgba(0, 0, 0, 0.3)", new InterpolatedPositionConnector(wellPrevPosition, wellNextPosition, corruptedMatthiasEnd)));
                        replay.Actors.Add(new CircleActor(true, corruptedMatthiasEnd + 100000, 180, new Tuple <int, int>(corruptedMatthiasEnd, corruptedMatthiasEnd + 100000), "rgba(0, 0, 0, 0.3)", new InterpolatedPositionConnector(wellPrevPosition, wellNextPosition, corruptedMatthiasEnd)));
                    }
                }
            }
            // Well of profane
            List <CombatItem> wellMatthias = GetFilteredList(log, 34450, p);
            int wellMatthiasStart          = 0;

            foreach (CombatItem c in wellMatthias)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    wellMatthiasStart = (int)(c.Time - log.FightData.FightStart);
                }
                else
                {
                    int wellMatthiasEnd = (int)(c.Time - log.FightData.FightStart);
                    replay.Actors.Add(new CircleActor(false, 0, 120, new Tuple <int, int>(wellMatthiasStart, wellMatthiasEnd), "rgba(150, 255, 80, 0.5)", new AgentConnector(p)));
                    replay.Actors.Add(new CircleActor(true, wellMatthiasStart + 9000, 120, new Tuple <int, int>(wellMatthiasStart, wellMatthiasEnd), "rgba(150, 255, 80, 0.5)", new AgentConnector(p)));
                    Point3D wellNextPosition = replay.Positions.FirstOrDefault(x => x.Time >= wellMatthiasEnd);
                    Point3D wellPrevPosition = replay.Positions.LastOrDefault(x => x.Time <= wellMatthiasEnd);
                    if (wellNextPosition != null || wellPrevPosition != null)
                    {
                        replay.Actors.Add(new CircleActor(true, 0, 300, new Tuple <int, int>(wellMatthiasEnd, wellMatthiasEnd + 90000), "rgba(255, 0, 50, 0.5)", new InterpolatedPositionConnector(wellPrevPosition, wellNextPosition, wellMatthiasEnd)));
                    }
                }
            }
            // Sacrifice
            List <CombatItem> sacrificeMatthias = GetFilteredList(log, 34442, p);
            int sacrificeMatthiasStart          = 0;

            foreach (CombatItem c in sacrificeMatthias)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    sacrificeMatthiasStart = (int)(c.Time - log.FightData.FightStart);
                }
                else
                {
                    int sacrificeMatthiasEnd = (int)(c.Time - log.FightData.FightStart);
                    replay.Actors.Add(new CircleActor(true, 0, 120, new Tuple <int, int>(sacrificeMatthiasStart, sacrificeMatthiasEnd), "rgba(0, 150, 250, 0.2)", new AgentConnector(p)));
                    replay.Actors.Add(new CircleActor(true, sacrificeMatthiasStart + 10000, 120, new Tuple <int, int>(sacrificeMatthiasStart, sacrificeMatthiasEnd), "rgba(0, 150, 250, 0.35)", new AgentConnector(p)));
                }
            }
            // Bombs
            List <CombatItem> zealousBenediction = log.GetBoonData(34511).Where(x => (x.DstInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None)).ToList();

            foreach (CombatItem c in zealousBenediction)
            {
                int zealousStart = (int)(c.Time - log.FightData.FightStart);
                int zealousEnd   = zealousStart + 5000;
                replay.Actors.Add(new CircleActor(true, 0, 180, new Tuple <int, int>(zealousStart, zealousEnd), "rgba(200, 150, 0, 0.2)", new AgentConnector(p)));
                replay.Actors.Add(new CircleActor(true, zealousEnd, 180, new Tuple <int, int>(zealousStart, zealousEnd), "rgba(200, 150, 0, 0.4)", new AgentConnector(p)));
            }
        }
Exemple #24
0
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             end           = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Target           mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Deimos);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // Determined + additional data on inst change
            CombatItem invulDei = log.GetBoonData(762).Find(x => x.IsBuffRemove == ParseEnum.BuffRemove.None && x.DstInstid == mainTarget.InstID);

            if (invulDei != null)
            {
                end = log.FightData.ToFightSpace(invulDei.Time);
                phases.Add(new PhaseData(start, end));
                start = (_specialSplit > 0 ? log.FightData.ToFightSpace(_specialSplit) : fightDuration);
                //mainTarget.AddCustomCastLog(end, -6, (int)(start - end), ParseEnum.Activation.None, (int)(start - end), ParseEnum.Activation.None, log);
            }
            if (fightDuration - start > 5000 && start >= phases.Last().End)
            {
                phases.Add(new PhaseData(start, fightDuration));
            }
            string[] names = { "100% - 10%", "10% - 0%" };
            for (int i = 1; i < phases.Count; i++)
            {
                phases[i].Name = names[i - 1];
                phases[i].Targets.Add(mainTarget);
            }
            foreach (Target tar in Targets)
            {
                if (tar.ID == (ushort)Thief || tar.ID == (ushort)Drunkard || tar.ID == (ushort)Gambler)
                {
                    string    name     = (tar.ID == (ushort)Thief ? "Thief" : (tar.ID == (ushort)Drunkard ? "Drunkard" : (tar.ID == (ushort)Gambler ? "Gambler" : "")));
                    PhaseData tarPhase = new PhaseData(log.FightData.ToFightSpace(tar.FirstAware) - 1000, log.FightData.ToFightSpace(tar.LastAware) + 1000);
                    tarPhase.Targets.Add(tar);
                    tarPhase.Targets.Add(mainTarget);
                    tarPhase.OverrideTimes(log);
                    tarPhase.Name = name;
                    phases.Add(tarPhase);
                }
            }

            /*
             * List<CombatItem> signets = GetFilteredList(log, 38224, mainTarget, true);
             * long sigStart = 0;
             * long sigEnd = 0;
             * int burstID = 1;
             * for (int i = 0; i < signets.Count; i++)
             * {
             *  CombatItem signet = signets[i];
             *  if (signet.IsBuffRemove == ParseEnum.BuffRemove.None)
             *  {
             *      sigStart = log.FightData.ToFightSpace(signet.Time);
             *  }
             *  else
             *  {
             *      sigEnd = log.FightData.ToFightSpace(signet.Time);
             *      PhaseData burstPhase = new PhaseData(sigStart, sigEnd)
             *      {
             *          Name = "Burst " + burstID++
             *      };
             *      burstPhase.Targets.Add(mainTarget);
             *      phases.Add(burstPhase);
             *  }
             * }*/
            phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            phases.RemoveAll(x => x.Targets.Count == 0);
            return(phases);
        }
Exemple #25
0
        public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases)
        {
            long             start         = 0;
            long             end           = 0;
            long             fightDuration = log.FightData.FightDuration;
            List <PhaseData> phases        = GetInitialPhase(log);
            Target           mainTarget    = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.KeepConstruct);

            if (mainTarget == null)
            {
                throw new InvalidOperationException("Main target of the fight not found");
            }
            phases[0].Targets.Add(mainTarget);
            if (!requirePhases)
            {
                return(phases);
            }
            // Main phases 34894
            List <CastLog> castLogs    = mainTarget.GetCastLogs(log, 0, log.FightData.FightEnd);
            List <CastLog> magicCharge = castLogs.Where(x => x.SkillId == 35048).ToList();
            List <CastLog> magicBlast  = castLogs.Where(x => x.SkillId == 34894).ToList();

            foreach (CastLog cl in magicCharge)
            {
                end = cl.Time;
                phases.Add(new PhaseData(start, end));
                CastLog blast = magicBlast.FirstOrDefault(x => x.Time >= cl.Time);
                if (blast != null)
                {
                    start = blast.Time + blast.ActualDuration;
                }
                else
                {
                    start = end + cl.ActualDuration;
                }
            }
            if (fightDuration - start > 5000 && start >= phases.Last().End)
            {
                phases.Add(new PhaseData(start, fightDuration));
                start = fightDuration;
            }
            string[] mainPhaseNames = { "100% - 66%", "66% - 33%", "33% - 0%" };
            for (int i = 1; i < phases.Count; i++)
            {
                phases[i].Name = mainPhaseNames[i - 1];
                phases[i].Targets.Add(mainTarget);
            }
            // add burn phases
            int offset = phases.Count;
            List <CombatItem> orbItems = log.GetBoonData(35096).Where(x => x.DstInstid == mainTarget.InstID).ToList();

            // Get number of orbs and filter the list
            start = 0;
            int orbCount = 0;
            List <BoonsGraphModel.Segment> segments = new List <BoonsGraphModel.Segment>();

            foreach (CombatItem c in orbItems)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    if (start == 0)
                    {
                        start = log.FightData.ToFightSpace(c.Time);
                    }
                    orbCount++;
                }
                else if (start != 0)
                {
                    segments.Add(new BoonsGraphModel.Segment(start, Math.Min(log.FightData.ToFightSpace(c.Time), fightDuration), orbCount));
                    orbCount = 0;
                    start    = 0;
                }
            }
            int burnCount = 1;

            foreach (var seg in segments)
            {
                var phase = new PhaseData(seg.Start, seg.End)
                {
                    Name = "Burn " + burnCount++ + " (" + seg.Value + " orbs)",
                };
                phase.Targets.Add(mainTarget);
                phases.Add(phase);
            }
            phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            // pre burn phases
            int preBurnCount = 1;
            List <PhaseData>  preBurnPhase = new List <PhaseData>();
            List <CombatItem> kcInvuls     = GetFilteredList(log, 762, mainTarget, true);

            foreach (CombatItem invul in kcInvuls)
            {
                if (invul.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    end = log.FightData.ToFightSpace(invul.Time);
                    PhaseData prevPhase = phases.LastOrDefault(x => x.Start <= end || x.End <= end);
                    if (prevPhase != null)
                    {
                        start = (prevPhase.End >= end ? prevPhase.Start : prevPhase.End) + 1;
                        if (end - start > 5000)
                        {
                            var phase = new PhaseData(start, end)
                            {
                                Name = "Pre-Burn " + preBurnCount++,
                            };
                            phase.Targets.Add(mainTarget);
                            preBurnPhase.Add(phase);
                        }
                    }
                }
            }
            phases.AddRange(preBurnPhase);
            phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            // add leftover phases
            PhaseData        cur            = null;
            int              leftOverCount  = 1;
            List <PhaseData> leftOverPhases = new List <PhaseData>();

            for (int i = 0; i < phases.Count; i++)
            {
                PhaseData phase = phases[i];
                if (phase.Name.Contains("%"))
                {
                    cur = phase;
                }
                else if (phase.Name.Contains("orbs"))
                {
                    if (cur != null)
                    {
                        if (cur.End >= phase.End + 5000 && (i == phases.Count - 1 || phases[i + 1].Name.Contains("Phase")))
                        {
                            PhaseData leftOverPhase = new PhaseData(phase.End + 1, cur.End)
                            {
                                Name = "Leftover " + leftOverCount++,
                            };
                            leftOverPhase.Targets.Add(mainTarget);
                            leftOverPhases.Add(leftOverPhase);
                        }
                    }
                }
            }
            phases.AddRange(leftOverPhases);
            phases.Sort((x, y) => x.Start.CompareTo(y.Start));
            return(phases);
        }