Пример #1
0
 public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents)
 {
     base.CheckSuccess(combatData, agentData, fightData, playerAgents);
     if (!fightData.Success)
     {
         NPC desmina = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.Desmina);
         if (desmina == null)
         {
             throw new InvalidOperationException("Error Encountered: Desmina not found");
         }
         ExitCombatEvent ooc = combatData.GetExitCombatEvents(desmina.AgentItem).LastOrDefault();
         if (ooc != null)
         {
             long time = 0;
             foreach (NPC mob in TrashMobs.Where(x => x.ID == (int)SpiritHorde3))
             {
                 DespawnEvent dspwnHorde = combatData.GetDespawnEvents(mob.AgentItem).LastOrDefault();
                 if (dspwnHorde != null)
                 {
                     time = Math.Max(dspwnHorde.Time, time);
                 }
             }
             DespawnEvent dspwn = combatData.GetDespawnEvents(desmina.AgentItem).LastOrDefault();
             if (time != 0 && dspwn == null && time <= desmina.LastAware)
             {
                 fightData.SetSuccess(true, time);
             }
         }
     }
 }
        protected virtual void ComputeFightTargets(AgentData agentData, List <CombatItem> combatItems)
        {
            foreach (int id in GetUniqueTargetIDs())
            {
                RegroupTargetsByID(id, agentData, combatItems);
            }
            List <int> ids = GetFightTargetsIDs();

            foreach (int id in ids)
            {
                List <AgentItem> agents = agentData.GetNPCsByID(id);
                foreach (AgentItem agentItem in agents)
                {
                    Targets.Add(new NPC(agentItem));
                }
            }
            List <ParseEnum.TrashIDS> ids2 = GetTrashMobsIDS();
            var aList = agentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => ids2.Contains(ParseEnum.GetTrashIDS(x.ID))).ToList();

            //aList.AddRange(agentData.GetAgentByType(AgentItem.AgentType.Gadget).Where(x => ids2.Contains(ParseEnum.GetTrashIDS(x.ID))));
            foreach (AgentItem a in aList)
            {
                var mob = new NPC(a);
                TrashMobs.Add(mob);
            }
        }
Пример #3
0
        protected void ComputeFightTargets(AgentData agentData, List <CombatItem> combatItems)
        {
            foreach (ushort id in GetUniqueTargetIDs())
            {
                RegroupTargetsByID(id, agentData, combatItems);
            }
            List <ushort> ids = GetFightTargetsIDs();

            foreach (ushort id in ids)
            {
                List <AgentItem> agents = agentData.GetAgentsByID(id);
                foreach (AgentItem agentItem in agents)
                {
                    Targets.Add(new Target(agentItem));
                }
            }
            List <ParseEnum.TrashIDS> ids2  = GetTrashMobsIDS();
            List <AgentItem>          aList = agentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => ids2.Contains(ParseEnum.GetTrashIDS(x.ID))).ToList();

            foreach (AgentItem a in aList)
            {
                Mob mob = new Mob(a);
                TrashMobs.Add(mob);
            }
        }
Пример #4
0
        public void InitTrashMobCombatReplay(ParsedLog log, int pollingRate)
        {
            List <ParseEnum.TrashIDS> ids   = GetTrashMobsIDS();
            List <AgentItem>          aList = log.AgentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => ids.Contains(ParseEnum.GetTrashIDS(x.ID))).ToList();

            foreach (AgentItem a in aList)
            {
                Mob mob = new Mob(a);
                mob.InitCombatReplay(log, pollingRate, true, false);
                TrashMobs.Add(mob);
            }
        }
        public override void ComputeAdditionalPlayerData(Player p, ParsedLog log)
        {
            // Bombs
            CombatReplay      replay   = p.CombatReplay;
            List <CombatItem> xeraFury = GetFilteredList(log, 35103, p);
            int xeraFuryStart          = 0;

            foreach (CombatItem c in xeraFury)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    xeraFuryStart = (int)(c.Time - log.FightData.FightStart);
                }
                else
                {
                    int xeraFuryEnd = (int)(c.Time - log.FightData.FightStart);
                    replay.Actors.Add(new CircleActor(true, 0, 550, new Tuple <int, int>(xeraFuryStart, xeraFuryEnd), "rgba(200, 150, 0, 0.2)", new AgentConnector(p)));
                    replay.Actors.Add(new CircleActor(true, xeraFuryEnd, 550, new Tuple <int, int>(xeraFuryStart, xeraFuryEnd), "rgba(200, 150, 0, 0.4)", new AgentConnector(p)));
                }
            }
            //fixated Statue
            List <CombatItem> fixatedStatue = GetFilteredList(log, 34912, p).Concat(GetFilteredList(log, 34925, p)).ToList();
            int fixationStatueStart         = 0;
            Mob statue = null;

            foreach (CombatItem c in fixatedStatue)
            {
                if (c.IsBuffRemove == ParseEnum.BuffRemove.None)
                {
                    fixationStatueStart = (int)(c.Time - log.FightData.FightStart);
                    statue = TrashMobs.FirstOrDefault(x => x.Agent == c.SrcAgent);
                }
                else
                {
                    int fixationStatueEnd     = (int)(c.Time - log.FightData.FightStart);
                    Tuple <int, int> duration = new Tuple <int, int>(fixationStatueStart, fixationStatueEnd);
                    if (statue != null)
                    {
                        replay.Actors.Add(new LineActor(0, 10, duration, "rgba(255, 0, 255, 0.5)", new AgentConnector(p), new AgentConnector(statue)));
                    }
                }
            }
        }
        public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay)
        {
            // Bombs
            List <AbstractBuffEvent> xeraFury = GetFilteredList(log.CombatData, 35103, p, true);
            int xeraFuryStart = 0;

            foreach (AbstractBuffEvent c in xeraFury)
            {
                if (c is BuffApplyEvent)
                {
                    xeraFuryStart = (int)c.Time;
                }
                else
                {
                    int xeraFuryEnd = (int)c.Time;
                    replay.Decorations.Add(new CircleDecoration(true, 0, 550, (xeraFuryStart, xeraFuryEnd), "rgba(200, 150, 0, 0.2)", new AgentConnector(p)));
                    replay.Decorations.Add(new CircleDecoration(true, xeraFuryEnd, 550, (xeraFuryStart, xeraFuryEnd), "rgba(200, 150, 0, 0.4)", new AgentConnector(p)));
                }
            }
            //fixated Statue
            var fixatedStatue       = GetFilteredList(log.CombatData, 34912, p, true).Concat(GetFilteredList(log.CombatData, 34925, p, true)).ToList();
            int fixationStatueStart = 0;
            NPC statue = null;

            foreach (AbstractBuffEvent c in fixatedStatue)
            {
                if (c is BuffApplyEvent)
                {
                    fixationStatueStart = (int)c.Time;
                    statue = TrashMobs.FirstOrDefault(x => x.AgentItem == c.By);
                }
                else
                {
                    int fixationStatueEnd = (int)c.Time;
                    if (statue != null)
                    {
                        replay.Decorations.Add(new LineDecoration(0, (fixationStatueStart, fixationStatueEnd), "rgba(255, 0, 255, 0.5)", new AgentConnector(p), new AgentConnector(statue)));
                    }
                }
            }
        }
        protected FightLogic(ushort triggerID, AgentData agentData)
        {
            TriggerID          = triggerID;
            HasCombatReplayMap = GetCombatMap() != null;
            MechanicList       = new List <Mechanic>()
            {
                new PlayerStatusMechanic(SkillItem.DeathId, "Dead", new MechanicPlotlySetting("x", "rgb(0,0,0)"), "Dead", 0),
                new PlayerStatusMechanic(SkillItem.DownId, "Downed", new MechanicPlotlySetting("cross", "rgb(255,0,0)"), "Downed", 0),
                new PlayerStatusMechanic(SkillItem.ResurrectId, "Resurrect", new MechanicPlotlySetting("cross-open", "rgb(0,255,255)"), "Res", 0),
                new PlayerStatusMechanic(SkillItem.AliveId, "Got up", new MechanicPlotlySetting("cross", "rgb(0,255,0)"), "Got up", 0),
                new PlayerStatusMechanic(SkillItem.DCId, "Disconnected", new MechanicPlotlySetting("x", "rgb(120,120,120)"), "DC", 0),
                new PlayerStatusMechanic(SkillItem.RespawnId, "Respawn", new MechanicPlotlySetting("cross", "rgb(120,120,255)"), "Resp", 0)
            };
            _basicMechanicsCount = MechanicList.Count;
            List <ParseEnum.TrashIDS> ids   = GetTrashMobsIDS();
            List <AgentItem>          aList = agentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => ids.Contains(ParseEnum.GetTrashIDS(x.ID))).ToList();

            foreach (AgentItem a in aList)
            {
                Mob mob = new Mob(a);
                TrashMobs.Add(mob);
            }
        }
        internal override void ComputePlayerCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay)
        {
            // fixated
            List <AbstractBuffEvent> fixated = GetFilteredList(log.CombatData, FixatedQadimThePeerless, p, true, true);
            int fixatedStart = 0;

            foreach (AbstractBuffEvent c in fixated)
            {
                if (c is BuffApplyEvent)
                {
                    fixatedStart = Math.Max((int)c.Time, 0);
                }
                else
                {
                    int fixatedEnd = (int)c.Time;
                    replay.Decorations.Add(new CircleDecoration(true, 0, 120, (fixatedStart, fixatedEnd), "rgba(255, 80, 255, 0.3)", new AgentConnector(p)));
                }
            }
            // Chaos Corrosion
            List <AbstractBuffEvent> chaosCorrosion = GetFilteredList(log.CombatData, ChaosCorrosion, p, true, true);
            int corrosionStart = 0;

            foreach (AbstractBuffEvent c in chaosCorrosion)
            {
                if (c is BuffApplyEvent)
                {
                    corrosionStart = (int)c.Time;
                }
                else
                {
                    int corrosionEnd = (int)c.Time;
                    replay.Decorations.Add(new CircleDecoration(true, 0, 100, (corrosionStart, corrosionEnd), "rgba(80, 80, 80, 0.3)", new AgentConnector(p)));
                }
            }
            // Critical Mass, debuff while carrying an orb
            List <AbstractBuffEvent> criticalMass = GetFilteredList(log.CombatData, CriticalMass, p, true, true);
            int criticalMassStart = 0;

            foreach (AbstractBuffEvent c in criticalMass)
            {
                if (c is BuffApplyEvent)
                {
                    criticalMassStart = (int)c.Time;
                }
                else
                {
                    int criticalMassEnd = (int)c.Time;
                    replay.Decorations.Add(new CircleDecoration(false, 0, 200, (criticalMassStart, criticalMassEnd), "rgba(255, 0, 0, 0.3)", new AgentConnector(p)));
                }
            }
            // Magma drop
            List <AbstractBuffEvent> magmaDrop = GetFilteredList(log.CombatData, MagmaDrop, p, true, true);
            int magmaDropStart = 0;
            int magmaRadius    = 420;
            int magmaOffset    = 4000;

            string[] magmaColors = { "255, 215, 0", "255, 130, 50" };
            int      magmaColor  = 0;

            foreach (AbstractBuffEvent c in magmaDrop)
            {
                if (c is BuffApplyEvent)
                {
                    magmaDropStart = (int)c.Time;
                }
                else
                {
                    int magmaDropEnd = (int)c.Time;
                    replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 50, 0, 0.15)", new AgentConnector(p)));
                    replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 50, 0, 0.25)", new AgentConnector(p)));
                    Point3D magmaNextPos = replay.PolledPositions.FirstOrDefault(x => x.Time >= magmaDropEnd);
                    Point3D magmaPrevPos = replay.PolledPositions.LastOrDefault(x => x.Time <= magmaDropEnd);
                    if (magmaNextPos != null || magmaPrevPos != null)
                    {
                        string colorToUse = magmaColors[magmaColor];
                        magmaColor = (magmaColor + 1) % 2;
                        replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(" + colorToUse + ", 0.15)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd)));
                        replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd + magmaOffset, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(" + colorToUse + ", 0.25)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd + magmaOffset, (int)log.FightData.FightEnd), "rgba(" + colorToUse + ", 0.5)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd)));
                    }
                }
            }
            //sapping surge, bad red tether
            List <AbstractBuffEvent> sappingSurge = GetFilteredList(log.CombatData, SappingSurge, p, true, true);
            int surgeStart             = 0;
            AbstractSingleActor source = null;

            foreach (AbstractBuffEvent c in sappingSurge)
            {
                if (c is BuffApplyEvent)
                {
                    AbstractSingleActor qadim = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.PeerlessQadim);
                    surgeStart = (int)c.Time;
                    source     = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.CreditedBy) ?? qadim;
                }
                else
                {
                    int surgeEnd = (int)c.Time;
                    if (source != null)
                    {
                        replay.Decorations.Add(new LineDecoration(0, (surgeStart, surgeEnd), "rgba(255, 0, 0, 0.4)", new AgentConnector(p), new AgentConnector(source)));
                    }
                }
            }
            // kinetic abundance, good (blue) tether
            List <AbstractBuffEvent> kineticAbundance = GetFilteredList(log.CombatData, KineticAbundance, p, true, true);
            int kinStart = 0;
            AbstractSingleActor kinSource = null;

            foreach (AbstractBuffEvent c in kineticAbundance)
            {
                if (c is BuffApplyEvent)
                {
                    kinStart = (int)c.Time;
                    //kinSource = log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By);
                    kinSource = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.CreditedBy) ?? TrashMobs.FirstOrDefault(x => x.AgentItem == c.CreditedBy);
                }
                else
                {
                    int kinEnd = (int)c.Time;
                    if (kinSource != null)
                    {
                        replay.Decorations.Add(new LineDecoration(0, (kinStart, kinEnd), "rgba(0, 0, 255, 0.4)", new AgentConnector(p), new AgentConnector(kinSource)));
                    }
                }
            }
        }
        internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay)
        {
            IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd);
            int start = (int)replay.TimeOffsets.start;
            int end   = (int)replay.TimeOffsets.end;

            switch (target.ID)
            {
            case (int)ArcDPSEnums.TargetID.PeerlessQadim:
                var cataCycle    = cls.Where(x => x.SkillId == 56329).ToList();
                var forceOfHavoc = cls.Where(x => x.SkillId == 56017).ToList();
                var forceOfRetal = cls.Where(x => x.SkillId == ForceOfRetaliationCast).ToList();
                var etherStrikes = cls.Where(x => x.SkillId == 56012 || x.SkillId == 56653).ToList();
                var causticChaos = cls.Where(x => x.SkillId == 56332).ToList();
                var expoReperc   = cls.Where(x => x.SkillId == 56223).ToList();
                foreach (AbstractCastEvent c in cataCycle)
                {
                    int magmaRadius = 850;
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    Point3D pylonPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= end);
                    replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (start, end), "rgba(255, 50, 50, 0.15)", new PositionConnector(pylonPosition)));
                    replay.Decorations.Add(new CircleDecoration(true, end, magmaRadius, (start, end), "rgba(255, 50, 50, 0.25)", new PositionConnector(pylonPosition)));
                    replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (end, (int)log.FightData.FightEnd), "rgba(255, 50, 0, 0.5)", new PositionConnector(pylonPosition)));
                }
                foreach (AbstractCastEvent c in forceOfHavoc)
                {
                    int roadLength   = 2400;
                    int roadWidth    = 360;
                    int hitboxOffset = 200;
                    int subdivisions = 100;
                    int rollOutTime  = 3250;
                    start = (int)c.Time;
                    int     preCastTime = 1500;
                    int     duration    = 22500;
                    Point3D facing      = replay.Rotations.LastOrDefault(x => x.Time <= start + 1000);
                    Point3D position    = replay.Positions.LastOrDefault(x => x.Time <= start + 1000);
                    if (facing != null && position != null)
                    {
                        float direction = ParserHelper.RadianToDegreeF(Math.Atan2(facing.Y, facing.X));
                        replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, roadLength, roadWidth, direction, roadLength / 2 + 200, (start, start + preCastTime), "rgba(255, 0, 0, 0.1)", new PositionConnector(position)));
                        for (int i = 0; i < subdivisions; i++)
                        {
                            replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, roadLength / subdivisions, roadWidth, direction, (int)((i + 0.5) * roadLength / subdivisions + hitboxOffset), (start + preCastTime + i * (rollOutTime / subdivisions), start + preCastTime + i * (rollOutTime / subdivisions) + duration), "rgba(143, 0, 179, 0.6)", new PositionConnector(position)));
                        }
                    }
                }
                foreach (AbstractCastEvent c in forceOfRetal)
                {
                    int    radius              = 650;
                    double radiusIncrement     = 433.3;
                    int    preCastTime         = 1800;
                    int    timeBetweenCascades = 200;
                    int    cascades            = 5;
                    start = (int)c.Time + 1400;
                    Point3D position = replay.Positions.LastOrDefault(x => x.Time <= start + 1000);
                    replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, start + preCastTime), "rgba(255, 220, 50, 0.15)", new PositionConnector(position)));
                    replay.Decorations.Add(new CircleDecoration(true, start + preCastTime, radius, (start, start + preCastTime), "rgba(255, 220, 50, 0.25)", new PositionConnector(position)));
                    for (int i = 0; i < cascades; i++)
                    {
                        replay.Decorations.Add(new DoughnutDecoration(true, 0, radius + (int)(radiusIncrement * i), radius + (int)(radiusIncrement * (i + 1)), (start + preCastTime + timeBetweenCascades * i, start + preCastTime + timeBetweenCascades * (i + 1)), "rgba(30, 30, 30, 0.5)", new PositionConnector(position)));
                        replay.Decorations.Add(new DoughnutDecoration(true, 0, radius + (int)(radiusIncrement * i), radius + (int)(radiusIncrement * (i + 1)), (start + preCastTime + timeBetweenCascades * (i + 1), start + preCastTime + timeBetweenCascades * (i + 2)), "rgba(50, 20, 50, 0.25)", new PositionConnector(position)));
                    }
                }
                foreach (AbstractCastEvent c in etherStrikes)
                {
                    int coneRadius = 2600;
                    int coneAngle  = 60;
                    start = (int)c.Time;
                    end   = start + 250;
                    Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 300);
                    replay.Decorations.Add(new PieDecoration(false, 0, coneRadius, facing, coneAngle, (start, end), "rgba(255, 100, 0, 0.30)", new AgentConnector(target)));
                    replay.Decorations.Add(new PieDecoration(true, 0, coneRadius, facing, coneAngle, (start, end), "rgba(255, 100, 0, 0.1)", new AgentConnector(target)));
                }
                foreach (AbstractCastEvent c in causticChaos)
                {
                    double acceleration = c.Acceleration;
                    double ratio        = 1.0;
                    if (acceleration > 0)
                    {
                        ratio = acceleration * 0.5 + 1;
                    }
                    else
                    {
                        ratio = acceleration * 0.6 + 1;
                    }
                    int chaosLength = 2600;
                    int chaosWidth  = 100;
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    int aimTime = (int)((double)c.ExpectedDuration * ratio);
                    replay.Decorations.Add(new FacingDecoration((0, end), new AgentConnector(target), replay.PolledRotations));
                    replay.Decorations.Add(new FacingRectangleDecoration((start, end), new AgentConnector(target), replay.PolledRotations, chaosLength, chaosWidth, chaosLength / 2, "rgba(255,100,0,0.3)"));
                    if (end > start + aimTime)
                    {
                        replay.Decorations.Add(new FacingRectangleDecoration((start + aimTime, end), new AgentConnector(target), replay.PolledRotations, chaosLength, chaosWidth, chaosLength / 2, "rgba(100,100,100,0.7)"));
                    }
                }
                foreach (AbstractCastEvent c in expoReperc)
                {
                    int radius = 650;
                    start = (int)c.Time;
                    end   = (int)c.EndTime;
                    Point3D position = replay.Positions.LastOrDefault(x => x.Time <= start + 1000);
                    replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, end), "rgba(255, 220, 0, 0.15)", new PositionConnector(position)));
                    replay.Decorations.Add(new CircleDecoration(true, end, radius, (start, end), "rgba(255, 220, 50, 0.25)", new PositionConnector(position)));

                    foreach (NPC pylon in TrashMobs.Where(x => x.ID == 21962))
                    {
                        replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, end), "rgba(255, 220, 0, 0.15)", new AgentConnector(pylon)));
                        replay.Decorations.Add(new CircleDecoration(true, end, radius, (start, end), "rgba(255, 220, 50, 0.25)", new AgentConnector(pylon)));
                    }
                }
                break;

            case (int)ArcDPSEnums.TrashID.EntropicDistortion:
                //sapping surge, red tether
                List <AbstractBuffEvent> sappingSurge = GetFilteredList(log.CombatData, SappingSurge, target, true, true);
                int surgeStart             = 0;
                AbstractSingleActor source = null;
                foreach (AbstractBuffEvent c in sappingSurge)
                {
                    if (c is BuffApplyEvent)
                    {
                        AbstractSingleActor qadim = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.PeerlessQadim);
                        surgeStart = (int)c.Time;
                        source     = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.CreditedBy) ?? qadim;
                    }
                    else
                    {
                        int surgeEnd = (int)c.Time;
                        if (source != null)
                        {
                            replay.Decorations.Add(new LineDecoration(0, (surgeStart, surgeEnd), "rgba(255, 0, 0, 0.3)", new AgentConnector(target), new AgentConnector(source)));
                        }
                    }
                }
                Point3D firstEntropicPosition = replay.PolledPositions.FirstOrDefault();
                if (firstEntropicPosition != null)
                {
                    replay.Decorations.Add(new CircleDecoration(true, 0, 300, (start - 5000, start), "rgba(255, 0, 0, 0.4)", new PositionConnector(firstEntropicPosition)));
                    replay.Decorations.Add(new CircleDecoration(true, start, 300, (start - 5000, start), "rgba(255, 0, 0, 0.4)", new PositionConnector(firstEntropicPosition)));
                }
                break;

            case (int)ArcDPSEnums.TrashID.BigKillerTornado:
                replay.Decorations.Add(new CircleDecoration(true, 0, 450, (start, end), "rgba(255, 150, 0, 0.4)", new AgentConnector(target)));
                break;

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

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

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

            default:
                break;
            }
        }
        public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay)
        {
            // fixated
            List <AbstractBuffEvent> fixated = GetFilteredList(log.CombatData, 56510, p, true);
            int fixatedStart = 0;

            foreach (AbstractBuffEvent c in fixated)
            {
                if (c is BuffApplyEvent)
                {
                    fixatedStart = Math.Max((int)c.Time, 0);
                }
                else
                {
                    int fixatedEnd = (int)c.Time;
                    replay.Decorations.Add(new CircleDecoration(true, 0, 120, (fixatedStart, fixatedEnd), "rgba(255, 80, 255, 0.3)", new AgentConnector(p)));
                }
            }
            // Magma drop
            List <AbstractBuffEvent> magmaDrop = GetFilteredList(log.CombatData, 56475, p, true);
            int magmaDropStart = 0;
            int magmaRadius    = 420;
            int magmaOffset    = 4000;

            foreach (AbstractBuffEvent c in magmaDrop)
            {
                if (c is BuffApplyEvent)
                {
                    magmaDropStart = (int)c.Time;
                }
                else
                {
                    int magmaDropEnd = (int)c.Time;
                    replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 150, 0, 0.15)", new AgentConnector(p)));
                    replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 150, 0, 0.25)", new AgentConnector(p)));
                    Point3D magmaNextPos = replay.PolledPositions.FirstOrDefault(x => x.Time >= magmaDropEnd);
                    Point3D magmaPrevPos = replay.PolledPositions.LastOrDefault(x => x.Time <= magmaDropEnd);
                    if (magmaNextPos != null || magmaPrevPos != null)
                    {
                        replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(255, 220, 50, 0.15)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd)));
                        replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd + magmaOffset, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(255, 220, 50, 0.25)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd)));
                        replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd + magmaOffset, (int)log.FightData.FightEnd), "rgba(255, 220, 50, 0.5)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd)));
                    }
                }
            }
            //sapping surge, bad red tether
            List <AbstractBuffEvent> sappingSurge = GetFilteredList(log.CombatData, 56118, p, true);
            int surgeStart             = 0;
            AbstractSingleActor source = null;

            foreach (AbstractBuffEvent c in sappingSurge)
            {
                if (c is BuffApplyEvent)
                {
                    NPC qadim = Targets.Find(x => x.ID == (int)ParseEnum.TargetID.PeerlessQadim);
                    surgeStart = (int)c.Time;
                    source     = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By) ?? qadim;
                }
                else
                {
                    int surgeEnd = (int)c.Time;
                    if (source != null)
                    {
                        replay.Decorations.Add(new LineDecoration(0, (surgeStart, surgeEnd), "rgba(255, 0, 0, 0.4)", new AgentConnector(p), new AgentConnector(source)));
                    }
                }
            }
            // kinetic abundance, good (blue) tether
            List <AbstractBuffEvent> kineticAbundance = GetFilteredList(log.CombatData, 56609, p, true);
            int kinStart = 0;
            AbstractSingleActor kinSource = null;

            foreach (AbstractBuffEvent c in kineticAbundance)
            {
                if (c is BuffApplyEvent)
                {
                    kinStart = (int)c.Time;
                    //kinSource = log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By);
                    kinSource = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By) ?? TrashMobs.FirstOrDefault(x => x.AgentItem == c.By);
                }
                else
                {
                    int kinEnd = (int)c.Time;
                    if (kinSource != null)
                    {
                        replay.Decorations.Add(new LineDecoration(0, (kinStart, kinEnd), "rgba(0, 0, 255, 0.4)", new AgentConnector(p), new AgentConnector(kinSource)));
                    }
                }
            }
        }