internal List <PhaseData> GetBreakbarPhases(ParsedEvtcLog log, bool requirePhases)
        {
            if (!requirePhases)
            {
                return(new List <PhaseData>());
            }
            var breakbarPhases = new List <PhaseData>();

            foreach (NPC target in Targets)
            {
                int i = 0;
                IReadOnlyList <BreakbarStateEvent>   breakbarStateEvents   = log.CombatData.GetBreakbarStateEvents(target.AgentItem);
                IReadOnlyList <BreakbarPercentEvent> breakbarPercentEvents = log.CombatData.GetBreakbarPercentEvents(target.AgentItem);
                var breakbarActiveEvents    = breakbarStateEvents.Where(x => x.State == ArcDPSEnums.BreakbarState.Active).ToList();
                var breakbarNotActiveEvents = breakbarStateEvents.Where(x => x.State != ArcDPSEnums.BreakbarState.Active).ToList();
                foreach (BreakbarStateEvent active in breakbarActiveEvents)
                {
                    long start = Math.Max(active.Time - 2000, 0);
                    BreakbarStateEvent notActive = breakbarNotActiveEvents.FirstOrDefault(x => x.Time >= active.Time);
                    long end;
                    if (notActive == null)
                    {
                        DeadEvent deadEvent = log.CombatData.GetDeadEvents(target.AgentItem).LastOrDefault();
                        if (deadEvent == null)
                        {
                            end = Math.Min(target.LastAware, log.FightData.FightEnd);
                        }
                        else
                        {
                            end = Math.Min(deadEvent.Time, log.FightData.FightEnd);
                        }
                    }
                    else
                    {
                        end = Math.Min(notActive.Time, log.FightData.FightEnd);
                    }
                    var phase = new PhaseData(start, end, target.Character + " Breakbar " + ++i)
                    {
                        BreakbarPhase = true,
                        CanBeSubPhase = false
                    };
                    phase.AddTarget(target);
                    breakbarPhases.Add(phase);
                }
            }
            return(breakbarPhases);
        }
        internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay)
        {
            var knownEffectsIDs = new HashSet <long>();

            switch (target.ID)
            {
            case (int)ArcDPSEnums.TrashID.PushableVoidAmalgamate:
                //
                EffectGUIDEvent purificationZone = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTemplePurificationZones);
                if (purificationZone != null)
                {
                    var  voidShells              = log.CombatData.GetBuffData(VoidShell).Where(x => x.To == target.AgentItem).ToList();
                    var  voidShellRemovals       = voidShells.Where(x => x is BuffRemoveSingleEvent || x is BuffRemoveAllEvent).ToList();
                    int  voidShellAppliesCount   = voidShells.Where(x => x is BuffApplyEvent).Count();
                    int  voidShellRemovalOffset  = 0;
                    int  purificationAdd         = 0;
                    bool breakPurification       = false;
                    var  purificationZoneEffects = log.CombatData.GetEffectEvents(purificationZone.ContentID).Where(x => x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList();
                    knownEffectsIDs.Add(purificationZone.ContentID);
                    foreach (EffectEvent purificationZoneEffect in purificationZoneEffects)
                    {
                        int start  = (int)purificationZoneEffect.Time;
                        int end    = start + purificationZoneEffect.Duration;
                        int radius = 280;
                        if (voidShellRemovalOffset < voidShellRemovals.Count)
                        {
                            end = (int)voidShellRemovals[voidShellRemovalOffset++].Time;
                        }
                        replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, end), "rgba(0, 180, 255, 0.3)", new PositionConnector(purificationZoneEffect.Position)));
                        purificationAdd++;
                        if (purificationAdd >= voidShellAppliesCount)
                        {
                            breakPurification = true;
                        }
                        if (breakPurification)
                        {
                            break;
                        }
                    }
                }
                //
                EffectGUIDEvent lightning = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTemplePurificationLightnings);
                if (lightning != null)
                {
                    var lightningEffects = log.CombatData.GetEffectEvents(lightning.ContentID).Where(x => x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList();
                    knownEffectsIDs.Add(lightning.ContentID);
                    foreach (EffectEvent lightningEffect in lightningEffects)
                    {
                        int duration = 3000;
                        int start    = (int)lightningEffect.Time - duration;
                        int end      = (int)lightningEffect.Time;
                        replay.Decorations.Add(new CircleDecoration(true, end, 180, (start, end), "rgba(255, 180, 0, 0.2)", new PositionConnector(lightningEffect.Position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(255, 180, 0, 0.2)", new PositionConnector(lightningEffect.Position)));
                    }
                }
                //
                EffectGUIDEvent fireBall = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTemplePurificationFireBalls);
                if (fireBall != null)
                {
                    var fireBallEffects = log.CombatData.GetEffectEvents(fireBall.ContentID).Where(x => x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList();
                    knownEffectsIDs.Add(fireBall.ContentID);
                    foreach (EffectEvent fireBallEffect in fireBallEffects)
                    {
                        int startLoad = (int)fireBallEffect.Time - 2000;
                        int endLoad   = (int)fireBallEffect.Time;
                        replay.Decorations.Add(new CircleDecoration(true, endLoad, 180, (startLoad, endLoad), "rgba(250, 0, 0, 0.2)", new PositionConnector(fireBallEffect.Position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, 180, (startLoad, endLoad), "rgba(250, 0, 0, 0.2)", new PositionConnector(fireBallEffect.Position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, 180, (endLoad, endLoad + 2000), "rgba(250, 0, 0, 0.4)", new PositionConnector(fireBallEffect.Position)));
                    }
                }
                //
                EffectGUIDEvent voidZone = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTemplePurificationVoidZones);
                if (voidZone != null)
                {
                    var voidZoneEffects = log.CombatData.GetEffectEvents(voidZone.ContentID).Where(x => x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList();
                    knownEffectsIDs.Add(voidZone.ContentID);
                    foreach (EffectEvent voidZoneEffect in voidZoneEffects)
                    {
                        int start = (int)voidZoneEffect.Time;
                        int end   = start + 5000;
                        replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, 90, 230, RadianToDegreeF(voidZoneEffect.Orientation.Z), (start, end), "rgba(150, 0, 150, 0.2)", new PositionConnector(voidZoneEffect.Position)));
                        replay.Decorations.Add(new RotatedRectangleDecoration(true, end, 90, 230, RadianToDegreeF(voidZoneEffect.Orientation.Z), (start, end), "rgba(250, 0, 250, 0.3)", new PositionConnector(voidZoneEffect.Position)));
                    }
                }
                //
                EffectGUIDEvent beeLaunch = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTemplePurificationBeeLaunch);
                if (beeLaunch != null)
                {
                    var beeLaunchEffects = log.CombatData.GetEffectEvents(beeLaunch.ContentID).Where(x => x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList();
                    knownEffectsIDs.Add(beeLaunch.ContentID);
                    foreach (EffectEvent beeLaunchEffect in beeLaunchEffects)
                    {
                        int start = (int)beeLaunchEffect.Time;
                        int end   = start + 3000;
                        replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, 380, 30, RadianToDegreeF(beeLaunchEffect.Orientation.Z), 190, (start, end), "rgba(250, 50, 0, 0.4)", new PositionConnector(beeLaunchEffect.Position)));
                        replay.Decorations.Add(new CircleDecoration(true, end, 280, (start, end), "rgba(250, 150, 0, 0.2)", new PositionConnector(beeLaunchEffect.Position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, 280, (start, end), "rgba(250, 150, 0, 0.2)", new PositionConnector(beeLaunchEffect.Position)));
                    }
                }
                //
                EffectGUIDEvent poisonTrail = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTemplePurificationPoisonTrail);
                if (poisonTrail != null)
                {
                    var poisonTrailEffects = log.CombatData.GetEffectEvents(poisonTrail.ContentID).Where(x => x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList();
                    knownEffectsIDs.Add(poisonTrail.ContentID);
                    foreach (EffectEvent poisonTrailEffect in poisonTrailEffects)
                    {
                        int startLoad = (int)poisonTrailEffect.Time - 1000;
                        int start     = (int)poisonTrailEffect.Time;
                        int end       = start + 15000;
                        replay.Decorations.Add(new CircleDecoration(true, start, 220, (startLoad, start), "rgba(0, 150, 0, 0.2)", new PositionConnector(poisonTrailEffect.Position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, 220, (start, end), "rgba(0, 150, 0, 0.4)", new PositionConnector(poisonTrailEffect.Position)));
                    }
                }
                //
                BreakbarStateEvent breakbar = log.CombatData.GetBreakbarStateEvents(target.AgentItem).FirstOrDefault(x => x.State == ArcDPSEnums.BreakbarState.Active);
                if (breakbar != null)
                {
                    int start = (int)breakbar.Time;
                    int end   = (int)target.LastAware;
                    replay.Decorations.Add(new CircleDecoration(true, 0, 120, (start, end), "rgba(0, 180, 255, 0.3)", new AgentConnector(target)));
                }
                //

                /*var effects = log.CombatData.GetEffectEvents(target.AgentItem).Where(x => x.EffectID != 0 && x.EffectID != 29656 && !knownEffectsIDs.Contains(x.EffectID)).ToList();
                 * var effects2 = log.CombatData.GetEffectEvents(ParserHelper._unknownAgent).Where(x => x.EffectID != 0 && !knownEffectsIDs.Contains(x.EffectID) && x.Time >= target.FirstAware && x.Time <= target.LastAware && !x.IsAroundDst).ToList();
                 * foreach (EffectEvent effectEvt in effects)
                 * {
                 *  if (effectEvt.IsAroundDst)
                 *  {
                 *      continue;
                 *  }
                 *  replay.Decorations.Insert(0,new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 2000), "rgba(0, 180, 255, 1.0)", new PositionConnector(effectEvt.Position)));
                 * }
                 * var test = log.CombatData.GetEffectIDToGUIDEvents(18235);*/
                break;

            case (int)ArcDPSEnums.TargetID.TheDragonVoidJormag:
                EffectGUIDEvent iceShard = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTempleJormagIceShards);
                if (iceShard != null)
                {
                    IReadOnlyList <EffectEvent> iceShardEffects = log.CombatData.GetEffectEvents(iceShard.ContentID);
                    knownEffectsIDs.Add(iceShard.ContentID);
                    foreach (EffectEvent iceShardEffect in iceShardEffects)
                    {
                        int duration = 2500;
                        int start    = (int)iceShardEffect.Time;
                        int end      = start + duration;
                        replay.Decorations.Add(new CircleDecoration(true, end, 160, (start, end), "rgba(0, 50, 180, 0.2)", new PositionConnector(iceShardEffect.Position)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, 160, (start, end), "rgba(0, 50, 180, 0.2)", new PositionConnector(iceShardEffect.Position)));
                    }
                }

                /*var effects = log.CombatData.GetEffectEvents(target.AgentItem).Where(x => x.EffectID != 0 && x.EffectID != 29656 && !knownEffectsIDs.Contains(x.EffectID)).ToList();
                 * var effects2 = log.CombatData.GetEffectEvents(ParserHelper._unknownAgent).Where(x => x.EffectID != 0 && !knownEffectsIDs.Contains(x.EffectID) && x.Time >= target.FirstAware && x.Time <= target.LastAware && (!x.IsAroundDst ||(x.IsAroundDst && x.Dst.IsPlayer)) && x.Time > 48500 && x.Time < 48600).ToList();
                 * foreach (EffectEvent effectEvt in effects2)
                 * {
                 *  if (effectEvt.IsAroundDst)
                 *  {
                 *      replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new AgentConnector(log.FindActor(effectEvt.Dst))));
                 *  }
                 *  else
                 *  {
                 *
                 *      replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new PositionConnector(effectEvt.Position)));
                 *  }
                 * }*/
                break;

            case (int)ArcDPSEnums.TargetID.TheDragonVoidPrimordus:
                EffectGUIDEvent smallJaw = log.CombatData.GetEffectGUIDEvent(EffectGUIDs.HarvestTemplePrimordusSmallJaw);
                if (smallJaw != null)
                {
                    IReadOnlyList <EffectEvent> smallJawEffects = log.CombatData.GetEffectEvents(smallJaw.ContentID);
                    knownEffectsIDs.Add(smallJaw.ContentID);
                    // The effect is slightly shifted on X
                    var jawPosition = new Point3D(610, -21400.3f, -15417.3f);
                    foreach (EffectEvent smallJawEffect in smallJawEffects)
                    {
                        int duration = 4500;
                        int start    = (int)smallJawEffect.Time - duration;
                        int end      = (int)smallJawEffect.Time;
                        replay.Decorations.Add(new CircleDecoration(true, end, 580, (start, end), "rgba(200, 100, 0, 0.2)", new PositionConnector(jawPosition)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, 580, (start, end), "rgba(200, 100, 0, 0.2)", new PositionConnector(jawPosition)));
                    }
                }

                /*var effects = log.CombatData.GetEffectEvents(target.AgentItem).Where(x => x.EffectID != 0 && x.EffectID != 3819 && !knownEffectsIDs.Contains(x.EffectID)).ToList();
                 * var effects2 = log.CombatData.GetEffectEvents(ParserHelper._unknownAgent).Where(x => x.EffectID != 0 && x.EffectID != 3819 && !knownEffectsIDs.Contains(x.EffectID) && x.EffectID != EffectGUIDs.HarvestTempleJormagIceShards && x.Time >= target.FirstAware && x.Time <= target.LastAware && (!x.IsAroundDst) && x.Time > 170000 && x.Time < 175000).ToList();
                 * foreach (EffectEvent effectEvt in effects2)
                 * {
                 *  if (effectEvt.IsAroundDst)
                 *  {
                 *      replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new AgentConnector(log.FindActor(effectEvt.Dst))));
                 *  }
                 *  else
                 *  {
                 *
                 *      replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new PositionConnector(effectEvt.Position)));
                 *  }
                 * }*/
                break;

            case (int)ArcDPSEnums.TrashID.DragonBodyVoidAmalgamate:
                /*var effects = log.CombatData.GetEffectEvents(target.AgentItem).Where(x => x.EffectID != 0 && !knownEffectsIDs.Contains(x.EffectID)).ToList();
                 * var effects2 = log.CombatData.GetEffectEvents().Where(x => x.EffectID != 0 && !knownEffectsIDs.Contains(x.EffectID) && x.Time >= target.FirstAware && x.Time <= target.LastAware && (!x.IsAroundDst || (x.IsAroundDst && x.Dst.IsPlayer)) && x.Time > 133000 && x.Time < 142000 && x.Src != ParserHelper._unknownAgent && !x.Src.GetFinalMaster().IsPlayer).ToList();
                 * foreach (EffectEvent effectEvt in effects2)
                 * {
                 *  if (effectEvt.IsAroundDst)
                 *  {
                 *      replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new AgentConnector(log.FindActor(effectEvt.Dst))));
                 *  }
                 *  else
                 *  {
                 *
                 *      replay.Decorations.Insert(0, new CircleDecoration(true, 0, 180, ((int)effectEvt.Time, (int)effectEvt.Time + 100), "rgba(0, 180, 255, 1.0)", new PositionConnector(effectEvt.Position)));
                 *  }
                 * }*/
                break;

            default:
                break;
            }
        }