internal override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList)
        {
            var  attackTargets = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.AttackTarget).ToList();
            long first         = fightData.FightStart;
            long final         = fightData.FightEnd;

            foreach (CombatItem at in attackTargets)
            {
                AgentItem  hand        = agentData.GetAgent(at.DstAgent);
                AgentItem  atAgent     = agentData.GetAgent(at.SrcAgent);
                var        attackables = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.Targetable && x.SrcAgent == atAgent.Agent && x.Time <= atAgent.LastAware && x.Time >= atAgent.FirstAware).ToList();
                var        attackOn    = attackables.Where(x => x.DstAgent == 1 && x.Time >= first + 2000).Select(x => x.Time).ToList();
                var        attackOff   = attackables.Where(x => x.DstAgent == 0 && x.Time >= first + 2000).Select(x => x.Time).ToList();
                var        posFacingHP = combatData.Where(x => x.SrcAgent == hand.Agent && x.Time >= hand.FirstAware && hand.LastAware >= x.Time && (x.IsStateChange == ArcDPSEnums.StateChange.Position || x.IsStateChange == ArcDPSEnums.StateChange.Rotation || x.IsStateChange == ArcDPSEnums.StateChange.MaxHealthUpdate)).ToList();
                CombatItem pos         = posFacingHP.FirstOrDefault(x => x.IsStateChange == ArcDPSEnums.StateChange.Position);
                int        id          = (int)ArcDPSEnums.TrashID.HandOfErosion;
                if (pos != null)
                {
                    (float x, float y, _) = AbstractMovementEvent.UnpackMovementData(pos.DstAgent, 0);
                    if ((Math.Abs(x - 15570.5) < 10 && Math.Abs(y + 693.117) < 10) ||
                        (Math.Abs(x - 14277.2) < 10 && Math.Abs(y + 2202.52) < 10))
                    {
                        id = (int)ArcDPSEnums.TrashID.HandOfEruption;
                    }
                }
                for (int i = 0; i < attackOn.Count; i++)
                {
                    long start = attackOn[i];
                    long end   = final;
                    if (i <= attackOff.Count - 1)
                    {
                        end = attackOff[i];
                    }
                    AgentItem extra = agentData.AddCustomAgent(start, end, AgentItem.AgentType.NPC, hand.Name, hand.Prof, id, hand.Toughness, hand.Healing, hand.Condition, hand.Concentration, hand.HitboxWidth, hand.HitboxHeight);
                    foreach (CombatItem c in combatData)
                    {
                        if (c.Time >= extra.FirstAware && c.Time <= extra.LastAware)
                        {
                            if (c.IsStateChange.SrcIsAgent() && c.SrcAgent == hand.Agent)
                            {
                                c.OverrideSrcAgent(extra.Agent);
                            }
                            if (c.IsStateChange.DstIsAgent() && c.DstAgent == hand.Agent)
                            {
                                c.OverrideDstAgent(extra.Agent);
                            }
                        }
                    }
                    foreach (CombatItem c in posFacingHP)
                    {
                        var cExtra = new CombatItem(c);
                        cExtra.OverrideTime(extra.FirstAware);
                        cExtra.OverrideSrcAgent(extra.Agent);
                        combatData.Add(cExtra);
                    }
                }
            }
            combatData.Sort((x, y) => x.Time.CompareTo(y.Time));
            ComputeFightTargets(agentData, combatData);
        }
        internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions)
        {
            var  attackTargets = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.AttackTarget).ToList();
            long first         = 0;
            long final         = fightData.FightEnd;

            foreach (CombatItem at in attackTargets)
            {
                AgentItem  hand        = agentData.GetAgent(at.DstAgent, at.Time);
                AgentItem  atAgent     = agentData.GetAgent(at.SrcAgent, at.Time);
                var        attackables = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.Targetable && x.SrcMatchesAgent(atAgent)).ToList();
                var        attackOn    = attackables.Where(x => x.DstAgent == 1 && x.Time >= first + 2000).Select(x => x.Time).ToList();
                var        attackOff   = attackables.Where(x => x.DstAgent == 0 && x.Time >= first + 2000).Select(x => x.Time).ToList();
                var        posFacingHP = combatData.Where(x => x.SrcMatchesAgent(hand) && (x.IsStateChange == ArcDPSEnums.StateChange.Position || x.IsStateChange == ArcDPSEnums.StateChange.Rotation || x.IsStateChange == ArcDPSEnums.StateChange.MaxHealthUpdate)).ToList();
                CombatItem pos         = posFacingHP.FirstOrDefault(x => x.IsStateChange == ArcDPSEnums.StateChange.Position);
                int        id          = (int)ArcDPSEnums.TrashID.HandOfErosion;
                if (pos != null)
                {
                    (float x, float y, _) = AbstractMovementEvent.UnpackMovementData(pos.DstAgent, 0);
                    if ((Math.Abs(x - 15570.5) < 10 && Math.Abs(y + 693.117) < 10) ||
                        (Math.Abs(x - 14277.2) < 10 && Math.Abs(y + 2202.52) < 10))
                    {
                        id = (int)ArcDPSEnums.TrashID.HandOfEruption;
                    }
                }
                for (int i = 0; i < attackOn.Count; i++)
                {
                    long start = attackOn[i];
                    long end   = final;
                    if (i <= attackOff.Count - 1)
                    {
                        end = attackOff[i];
                    }
                    AgentItem extra = agentData.AddCustomNPCAgent(start, end, hand.Name, hand.Spec, id, false, hand.Toughness, hand.Healing, hand.Condition, hand.Concentration, hand.HitboxWidth, hand.HitboxHeight);
                    foreach (CombatItem c in combatData)
                    {
                        if (extra.InAwareTimes(c.Time))
                        {
                            if (c.SrcMatchesAgent(hand, extensions))
                            {
                                c.OverrideSrcAgent(extra.Agent);
                            }
                            if (c.DstMatchesAgent(hand, extensions))
                            {
                                c.OverrideDstAgent(extra.Agent);
                            }
                        }
                    }
                    foreach (CombatItem c in posFacingHP)
                    {
                        var cExtra = new CombatItem(c);
                        cExtra.OverrideTime(extra.FirstAware);
                        cExtra.OverrideSrcAgent(extra.Agent);
                        combatData.Add(cExtra);
                    }
                }
            }
            ComputeFightTargets(agentData, combatData, extensions);
        }
示例#3
0
        public override void SpecialParse(FightData fightData, AgentData agentData, List <CombatItem> combatData)
        {
            List <CombatItem> attackTargets = combatData.Where(x => x.IsStateChange == ParseEnum.StateChange.AttackTarget).ToList();
            long first = combatData.Count > 0 ? combatData.First().LogTime : 0;
            long final = combatData.Count > 0 ? combatData.Last().LogTime : 0;

            foreach (CombatItem at in attackTargets)
            {
                AgentItem         hand        = agentData.GetAgent(at.DstAgent, at.LogTime);
                AgentItem         atAgent     = agentData.GetAgent(at.SrcAgent, at.LogTime);
                List <CombatItem> attackables = combatData.Where(x => x.IsStateChange == ParseEnum.StateChange.Targetable && x.SrcAgent == atAgent.Agent && x.LogTime <= atAgent.LastAwareLogTime && x.LogTime >= atAgent.FirstAwareLogTime).ToList();
                List <long>       attackOn    = attackables.Where(x => x.DstAgent == 1 && x.LogTime >= first + 2000).Select(x => x.LogTime).ToList();
                List <long>       attackOff   = attackables.Where(x => x.DstAgent == 0 && x.LogTime >= first + 2000).Select(x => x.LogTime).ToList();
                List <CombatItem> posFacingHP = combatData.Where(x => x.SrcAgent == hand.Agent && x.LogTime >= hand.FirstAwareLogTime && hand.LastAwareLogTime >= x.LogTime && (x.IsStateChange == ParseEnum.StateChange.Position || x.IsStateChange == ParseEnum.StateChange.Rotation || x.IsStateChange == ParseEnum.StateChange.MaxHealthUpdate)).ToList();
                CombatItem        pos         = posFacingHP.FirstOrDefault(x => x.IsStateChange == ParseEnum.StateChange.Position);
                ushort            id          = (ushort)HandOfErosion;
                if (pos != null)
                {
                    byte[] xy = BitConverter.GetBytes(pos.DstAgent);
                    float  x  = BitConverter.ToSingle(xy, 0);
                    float  y  = BitConverter.ToSingle(xy, 4);
                    if ((Math.Abs(x - 15570.5) < 10 && Math.Abs(y + 693.117) < 10) ||
                        (Math.Abs(x - 14277.2) < 10 && Math.Abs(y + 2202.52) < 10))
                    {
                        id = (ushort)HandOfEruption;
                    }
                }
                for (int i = 0; i < attackOn.Count; i++)
                {
                    long start = attackOn[i];
                    long end   = final;
                    if (i <= attackOff.Count - 1)
                    {
                        end = attackOff[i];
                    }
                    AgentItem extra = agentData.AddCustomAgent(start, end, AgentItem.AgentType.Gadget, hand.Name, hand.Prof, id, hand.Toughness, hand.Healing, hand.Condition, hand.Concentration, hand.HitboxWidth, hand.HitboxHeight);
                    foreach (CombatItem c in combatData.Where(x => x.SrcAgent == hand.Agent && x.LogTime >= extra.FirstAwareLogTime && x.LogTime <= extra.LastAwareLogTime))
                    {
                        c.OverrideSrcValues(extra.Agent, extra.InstID);
                    }
                    foreach (CombatItem c in combatData.Where(x => x.DstAgent == hand.Agent && x.LogTime >= extra.FirstAwareLogTime && x.LogTime <= extra.LastAwareLogTime))
                    {
                        c.OverrideDstValues(extra.Agent, extra.InstID);
                    }
                    foreach (CombatItem c in posFacingHP)
                    {
                        CombatItem cExtra = new CombatItem(c);
                        cExtra.OverrideTime(extra.FirstAwareLogTime);
                        cExtra.OverrideSrcValues(extra.Agent, extra.InstID);
                        combatData.Add(cExtra);
                    }
                }
            }
            combatData.Sort((x, y) => x.LogTime.CompareTo(y.LogTime));
            ComputeFightTargets(agentData, combatData);
        }
示例#4
0
        internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions)
        {
            var attackTargetEvents = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.AttackTarget).ToList();
            var idsToUse           = new List <ArcDPSEnums.TargetID> {
                ArcDPSEnums.TargetID.TheDragonVoidJormag,
                ArcDPSEnums.TargetID.TheDragonVoidPrimordious,
                ArcDPSEnums.TargetID.TheDragonVoidKralkatorrik,
                ArcDPSEnums.TargetID.TheDragonVoidMordremoth,
                ArcDPSEnums.TargetID.TheDragonVoidZhaitan,
                ArcDPSEnums.TargetID.TheDragonVoidSooWon,
            };
            int index = 0;

            foreach (CombatItem at in attackTargetEvents)
            {
                AgentItem dragonVoid = agentData.GetAgent(at.DstAgent, at.Time);
                AgentItem atAgent    = agentData.GetAgent(at.SrcAgent, at.Time);
                // We take attack events, filter out the first one, present at spawn, that is always a non targetable event
                var targetables = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.Targetable && x.SrcMatchesAgent(atAgent) && x.Time > 2000).ToList();
                // There are only two relevant attack targets, one represents the first five and the last one Soo Won
                if (!targetables.Any())
                {
                    continue;
                }
                var targetOns  = targetables.Where(x => x.DstAgent == 1).ToList();
                var targetOffs = targetables.Where(x => x.DstAgent == 0).ToList();
                // Events to be copied
                var posFacingHP = combatData.Where(x => x.SrcMatchesAgent(dragonVoid) && (x.IsStateChange == ArcDPSEnums.StateChange.Position || x.IsStateChange == ArcDPSEnums.StateChange.Rotation || x.IsStateChange == ArcDPSEnums.StateChange.MaxHealthUpdate)).ToList();
                //
                foreach (CombatItem targetOn in targetOns)
                {
                    // If Soo Won has been already created, we break
                    if (index >= idsToUse.Count)
                    {
                        break;
                    }
                    int        id        = (int)idsToUse[index++];
                    long       start     = targetOn.Time;
                    long       end       = fightData.FightEnd;
                    CombatItem targetOff = targetOffs.FirstOrDefault(x => x.Time > start);
                    // Don't split Soo won into two
                    if (targetOff != null && id != (int)ArcDPSEnums.TargetID.TheDragonVoidSooWon)
                    {
                        end = targetOff.Time;
                    }
                    AgentItem extra = agentData.AddCustomNPCAgent(start, end, dragonVoid.Name, dragonVoid.Spec, id, false, dragonVoid.Toughness, dragonVoid.Healing, dragonVoid.Condition, dragonVoid.Concentration, dragonVoid.HitboxWidth, dragonVoid.HitboxHeight);
                    foreach (CombatItem c in combatData)
                    {
                        if (extra.InAwareTimes(c.Time))
                        {
                            if (c.SrcMatchesAgent(dragonVoid, extensions))
                            {
                                // Avoid making the gadget go back to 100% hp on "death"
                                if (c.IsStateChange == ArcDPSEnums.StateChange.HealthUpdate && c.DstAgent == 10000 && c.Time > extra.LastAware - 2000)
                                {
                                    continue;
                                }
                                c.OverrideSrcAgent(extra.Agent);
                            }
                            if (c.DstMatchesAgent(dragonVoid, extensions))
                            {
                                c.OverrideDstAgent(extra.Agent);
                            }
                        }
                    }
                    var attackTargetCopy = new CombatItem(at);
                    attackTargetCopy.OverrideTime(extra.FirstAware);
                    attackTargetCopy.OverrideDstAgent(extra.Agent);
                    combatData.Add(attackTargetCopy);
                    foreach (CombatItem c in posFacingHP)
                    {
                        var cExtra = new CombatItem(c);
                        cExtra.OverrideTime(extra.FirstAware);
                        cExtra.OverrideSrcAgent(extra.Agent);
                        combatData.Add(cExtra);
                    }
                }
            }
            if (index == 0)
            {
                // Add dummy target as there are no dragon voids
                agentData.AddCustomNPCAgent(0, fightData.FightEnd, "Dummy Harvest Temple", Spec.NPC, (int)ArcDPSEnums.TargetID.DummyTarget, true);
                Targetless = true;
            }
            ComputeFightTargets(agentData, combatData, extensions);
            foreach (NPC target in Targets)
            {
                switch (target.ID)
                {
                case (int)ArcDPSEnums.TargetID.TheDragonVoidJormag:
                    target.OverrideName("The JormagVoid");
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidKralkatorrik:
                    target.OverrideName("The KralkatorrikVoid");
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidMordremoth:
                    target.OverrideName("The MordremothVoid");
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidPrimordious:
                    target.OverrideName("The PrimordiusVoid");
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidSooWon:
                    target.OverrideName("The SooWonVoid");
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidZhaitan:
                    target.OverrideName("The ZhaitanVoid");
                    break;
                }
            }
        }
        internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions)
        {
            //
            var attackTargetEvents = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.AttackTarget).ToList();
            var idsToUse           = new List <ArcDPSEnums.TargetID> {
                ArcDPSEnums.TargetID.TheDragonVoidJormag,
                ArcDPSEnums.TargetID.TheDragonVoidPrimordus,
                ArcDPSEnums.TargetID.TheDragonVoidKralkatorrik,
                ArcDPSEnums.TargetID.TheDragonVoidMordremoth,
                ArcDPSEnums.TargetID.TheDragonVoidZhaitan,
                ArcDPSEnums.TargetID.TheDragonVoidSooWon,
            };
            int index = 0;

            foreach (CombatItem at in attackTargetEvents)
            {
                AgentItem dragonVoid = agentData.GetAgent(at.DstAgent, at.Time);
                AgentItem atAgent    = agentData.GetAgent(at.SrcAgent, at.Time);
                // We take attack events, filter out the first one, present at spawn, that is always a non targetable event
                var targetables = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.Targetable && x.SrcMatchesAgent(atAgent) && x.Time > 2000).ToList();
                // There are only two relevant attack targets, one represents the first five and the last one Soo Won
                if (!targetables.Any())
                {
                    continue;
                }
                var targetOns  = targetables.Where(x => x.DstAgent == 1).ToList();
                var targetOffs = targetables.Where(x => x.DstAgent == 0).ToList();
                // Events to be copied
                var posFacingHPEventsToCopy = combatData.Where(x => x.SrcMatchesAgent(dragonVoid) && (x.IsStateChange == ArcDPSEnums.StateChange.MaxHealthUpdate)).ToList();
                posFacingHPEventsToCopy.AddRange(combatData.Where(x => x.SrcMatchesAgent(atAgent) && (x.IsStateChange == ArcDPSEnums.StateChange.Position || x.IsStateChange == ArcDPSEnums.StateChange.Rotation)));
                var attackTargetEventsToCopy = combatData.Where(x => x.SrcMatchesAgent(atAgent) && (x.IsStateChange == ArcDPSEnums.StateChange.AttackTarget)).ToList();
                //
                foreach (CombatItem targetOn in targetOns)
                {
                    // If Soo Won has been already created, we break
                    if (index >= idsToUse.Count)
                    {
                        break;
                    }
                    int        id        = (int)idsToUse[index++];
                    long       start     = targetOn.Time;
                    long       end       = fightData.FightEnd;
                    CombatItem targetOff = targetOffs.FirstOrDefault(x => x.Time > start);
                    // Don't split Soo won into two
                    if (targetOff != null && id != (int)ArcDPSEnums.TargetID.TheDragonVoidSooWon)
                    {
                        end = targetOff.Time;
                    }
                    AgentItem extra        = agentData.AddCustomNPCAgent(start, end, dragonVoid.Name, dragonVoid.Spec, id, false, dragonVoid.Toughness, dragonVoid.Healing, dragonVoid.Condition, dragonVoid.Concentration, atAgent.HitboxWidth, atAgent.HitboxHeight);
                    ulong     lastHPUpdate = ulong.MaxValue;
                    foreach (CombatItem c in combatData)
                    {
                        if (extra.InAwareTimes(c.Time))
                        {
                            if (c.SrcMatchesAgent(dragonVoid, extensions))
                            {
                                // Avoid making the gadget go back to 100% hp on "death"
                                if (c.IsStateChange == ArcDPSEnums.StateChange.HealthUpdate)
                                {
                                    // Discard hp update that goes up close to death time
                                    if (c.DstAgent >= lastHPUpdate && c.Time > extra.LastAware - 2000)
                                    {
                                        continue;
                                    }
                                    // Remember last hp
                                    lastHPUpdate = c.DstAgent;
                                }
                                c.OverrideSrcAgent(extra.Agent);
                            }
                            // Redirect effects from attack target to main body
                            if (c.IsStateChange == ArcDPSEnums.StateChange.Effect && c.SrcMatchesAgent(atAgent, extensions))
                            {
                                c.OverrideSrcAgent(extra.Agent);
                            }
                            if (c.DstMatchesAgent(dragonVoid, extensions))
                            {
                                c.OverrideDstAgent(extra.Agent);
                            }
                        }
                    }
                    var attackTargetCopy = new CombatItem(at);
                    attackTargetCopy.OverrideTime(extra.FirstAware);
                    attackTargetCopy.OverrideDstAgent(extra.Agent);
                    combatData.Add(attackTargetCopy);
                    foreach (CombatItem c in posFacingHPEventsToCopy)
                    {
                        var cExtra = new CombatItem(c);
                        cExtra.OverrideTime(extra.FirstAware);
                        cExtra.OverrideSrcAgent(extra.Agent);
                        combatData.Add(cExtra);
                    }
                    foreach (CombatItem c in attackTargetEventsToCopy)
                    {
                        var cExtra = new CombatItem(c);
                        cExtra.OverrideTime(extra.FirstAware);
                        cExtra.OverrideDstAgent(extra.Agent);
                        //combatData.Add(cExtra);
                    }
                }
            }
            //
            IReadOnlyList <AgentItem> voidAmalgamates = agentData.GetNPCsByID((int)ArcDPSEnums.TrashID.VoidAmalgamate);
            bool needRefresh = false;

            foreach (AgentItem voidAmal in voidAmalgamates)
            {
                if (combatData.Where(x => x.SkillID == VoidShell && x.IsBuffApply() && x.SrcMatchesAgent(voidAmal)).Any())
                {
                    voidAmal.OverrideID(ArcDPSEnums.TrashID.PushableVoidAmalgamate);
                    needRefresh = true;
                }
            }
            AgentItem dragonBodyVoidAmalgamate = voidAmalgamates.MaxBy(x => x.LastAware - x.FirstAware);

            if (dragonBodyVoidAmalgamate != null)
            {
                dragonBodyVoidAmalgamate.OverrideID(ArcDPSEnums.TrashID.DragonBodyVoidAmalgamate);
                needRefresh = true;
            }
            if (needRefresh)
            {
                agentData.Refresh();
            }
            if (index == 0)
            {
                // Add dummy target as there are no dragon voids
                agentData.AddCustomNPCAgent(0, fightData.FightEnd, "Dummy Harvest Temple", Spec.NPC, (int)ArcDPSEnums.TargetID.DummyTarget, true);
                Targetless = true;
            }
            //
            ComputeFightTargets(agentData, combatData, extensions);
            //
            int  purificationID = 0;
            bool needRedirect   = false;

            (HashSet <ulong> jormagDamagingAgents, NPC jormag)       = (new HashSet <ulong>(), null);
            (HashSet <ulong> primordusDamagingAgents, NPC primordus) = (new HashSet <ulong>(), null);
            (HashSet <ulong> kralkDamagingAgents, NPC kralk)         = (new HashSet <ulong>(), null);
            (HashSet <ulong> mordDamagingAgents, NPC mord)           = (new HashSet <ulong>(), null);
            (HashSet <ulong> zhaitanDamagingAgents, NPC zhaitan)     = (new HashSet <ulong>(), null);
            (HashSet <ulong> soowonDamagingAgents, NPC soowon)       = (new HashSet <ulong>(), null);
            foreach (NPC target in Targets)
            {
                switch (target.ID)
                {
                case (int)ArcDPSEnums.TargetID.TheDragonVoidJormag:
                    target.OverrideName("The JormagVoid");
                    jormag       = target;
                    needRedirect = true;
                    var jormagAttacks = new HashSet <long>()
                    {
                        BreathOfJormag1,
                        BreathOfJormag2,
                        BreathOfJormag3,
                    };
                    jormagDamagingAgents = new HashSet <ulong>(combatData.Where(x => x.IsDamage() && jormagAttacks.Contains(x.SkillID)).Select(x => x.SrcAgent));
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidKralkatorrik:
                    target.OverrideName("The KralkatorrikVoid");
                    kralk        = target;
                    needRedirect = true;
                    var kralkAttacks = new HashSet <long>()
                    {
                        BrandingBeam,
                        CrystalBarrage,
                        VoidPoolKralkatorrik
                    };
                    kralkDamagingAgents = new HashSet <ulong>(combatData.Where(x => x.IsDamage() && kralkAttacks.Contains(x.SkillID)).Select(x => x.SrcAgent));
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidMordremoth:
                    target.OverrideName("The MordremothVoid");
                    mord         = target;
                    needRedirect = true;
                    var mordAttacks = new HashSet <long>()
                    {
                        Shockwave,
                        PoisonRoar,
                    };
                    mordDamagingAgents = new HashSet <ulong>(combatData.Where(x => x.IsDamage() && mordAttacks.Contains(x.SkillID)).Select(x => x.SrcAgent));
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidPrimordus:
                    target.OverrideName("The PrimordusVoid");
                    primordus    = target;
                    needRedirect = true;
                    var primordusAttacks = new HashSet <long>()
                    {
                        LavaSlam,
                        JawsOfDestruction,
                    };
                    primordusDamagingAgents = new HashSet <ulong>(combatData.Where(x => x.IsDamage() && primordusAttacks.Contains(x.SkillID)).Select(x => x.SrcAgent));
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidSooWon:
                    target.OverrideName("The SooWonVoid");
                    soowon       = target;
                    needRedirect = true;
                    var soowonAttacks = new HashSet <long>()
                    {
                        TsunamiSlam1,
                        TsunamiSlam2,
                        ClawSlap,
                        MagicHail,
                        VoidPurge,
                        VoidPoolSooWon,
                        TormentOfTheVoid
                    };
                    soowonDamagingAgents = new HashSet <ulong>(combatData.Where(x => x.IsDamage() && soowonAttacks.Contains(x.SkillID)).Select(x => x.SrcAgent));
                    break;

                case (int)ArcDPSEnums.TargetID.TheDragonVoidZhaitan:
                    target.OverrideName("The ZhaitanVoid");
                    zhaitan      = target;
                    needRedirect = true;
                    var zhaiAttacks = new HashSet <long>()
                    {
                        ScreamOfZhaitan,
                        SlamZhaitan,
                        PutridDeluge
                    };
                    zhaitanDamagingAgents = new HashSet <ulong>(combatData.Where(x => x.IsDamage() && zhaiAttacks.Contains(x.SkillID)).Select(x => x.SrcAgent));
                    break;

                case (int)ArcDPSEnums.TrashID.PushableVoidAmalgamate:
                case (int)ArcDPSEnums.TrashID.KillableVoidAmalgamate:
                    target.OverrideName("Heart " + (++purificationID));
                    break;
                }
            }
            if (needRedirect)
            {
                foreach (CombatItem cbt in combatData)
                {
                    if (cbt.IsDamage())
                    {
                        // sanity check
                        if (agentData.GetAgent(cbt.SrcAgent, cbt.Time).GetFinalMaster().IsPlayer)
                        {
                            continue;
                        }
                        if (jormagDamagingAgents.Any(x => cbt.SrcAgent == x && jormag.FirstAware <= cbt.Time && cbt.Time <= jormag.LastAware))
                        {
                            cbt.OverrideSrcAgent(jormag.AgentItem.Agent);
                        }
                        else if (primordusDamagingAgents.Any(x => cbt.SrcAgent == x && primordus.FirstAware <= cbt.Time && cbt.Time <= primordus.LastAware))
                        {
                            cbt.OverrideSrcAgent(primordus.AgentItem.Agent);
                        }
                        else if (kralkDamagingAgents.Any(x => cbt.SrcAgent == x && kralk.FirstAware <= cbt.Time && cbt.Time <= kralk.LastAware))
                        {
                            cbt.OverrideSrcAgent(kralk.AgentItem.Agent);
                        }
                        else if (mordDamagingAgents.Any(x => cbt.SrcAgent == x && mord.FirstAware <= cbt.Time && cbt.Time <= mord.LastAware))
                        {
                            cbt.OverrideSrcAgent(mord.AgentItem.Agent);
                        }
                        else if (zhaitanDamagingAgents.Any(x => cbt.SrcAgent == x && zhaitan.FirstAware <= cbt.Time && cbt.Time <= zhaitan.LastAware))
                        {
                            cbt.OverrideSrcAgent(zhaitan.AgentItem.Agent);
                        }
                        else if (soowonDamagingAgents.Any(x => cbt.SrcAgent == x && soowon.FirstAware <= cbt.Time && cbt.Time <= soowon.LastAware))
                        {
                            cbt.OverrideSrcAgent(soowon.AgentItem.Agent);
                        }
                    }
                }
            }
        }