private void SetUniqueID(Target target, HashSet <ulong> gadgetAgents, AgentData agentData, List <CombatItem> combatData) { // get unique id for the fusion ushort instID = 0; Random rnd = new Random(); while (agentData.InstIDValues.Contains(instID) || instID == 0) { instID = (ushort)rnd.Next(ushort.MaxValue / 2, ushort.MaxValue); } target.AgentItem.InstID = instID; agentData.Refresh(); HashSet <ulong> allAgents = new HashSet <ulong>(gadgetAgents) { target.Agent }; foreach (CombatItem c in combatData) { if (gadgetAgents.Contains(c.SrcAgent) && c.IsStateChange == ParseEnum.StateChange.MaxHealthUpdate) { continue; } if (allAgents.Contains(c.SrcAgent)) { c.OverrideSrcValues(target.Agent, target.InstID); } if (allAgents.Contains(c.DstAgent)) { c.OverrideDstValues(target.Agent, target.InstID); } } }
public override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { // make those into npcs List <AgentItem> cas = agentData.GetGadgetsByID((int)ParseEnum.TargetIDS.ConjuredAmalgamate); List <AgentItem> leftArms = agentData.GetGadgetsByID((int)ParseEnum.TargetIDS.CALeftArm); List <AgentItem> rightArms = agentData.GetGadgetsByID((int)ParseEnum.TargetIDS.CARightArm); foreach (AgentItem ca in cas) { ca.OverrideType(AgentItem.AgentType.NPC); } foreach (AgentItem leftArm in leftArms) { leftArm.OverrideType(AgentItem.AgentType.NPC); } foreach (AgentItem rightArm in rightArms) { rightArm.OverrideType(AgentItem.AgentType.NPC); } agentData.Refresh(); ComputeFightTargets(agentData, combatData); AgentItem sword = agentData.AddCustomAgent(fightData.FightStart, fightData.FightEnd, AgentItem.AgentType.Player, "Conjured Sword\0:Conjured Sword\051", "Sword", 0); playerList.Add(new Player(sword, false, true)); foreach (CombatItem c in combatData) { if (c.SkillID == 52370 && c.IsStateChange == ParseEnum.StateChange.None && c.IsBuffRemove == ParseEnum.BuffRemove.None && ((c.IsBuff == 1 && c.BuffDmg >= 0 && c.Value == 0) || (c.IsBuff == 0 && c.Value >= 0)) && c.DstInstid != 0 && c.IFF == ParseEnum.IFF.Foe) { c.OverrideSrcAgent(sword.Agent); } } }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { IReadOnlyList <AgentItem> sooWons = agentData.GetGadgetsByID((int)ArcDPSEnums.TargetID.SooWonOW); if (!sooWons.Any()) { throw new MissingKeyActorsException("Soo-Won not found"); } foreach (AgentItem sooWon in sooWons) { sooWon.OverrideType(AgentItem.AgentType.NPC); sooWon.OverrideID(ArcDPSEnums.TargetID.SooWonOW); } IReadOnlyList <AgentItem> sooWonTails = agentData.GetGadgetsByID((int)ArcDPSEnums.TrashID.SooWonTail); foreach (AgentItem sooWonTail in sooWonTails) { sooWonTail.OverrideType(AgentItem.AgentType.NPC); sooWonTail.OverrideID(ArcDPSEnums.TrashID.SooWonTail); } agentData.Refresh(); ComputeFightTargets(agentData, combatData, extensions); }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, List <AbstractSingleActor> friendlies, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { // make those into npcs IReadOnlyList <AgentItem> cas = agentData.GetGadgetsByID((int)ArcDPSEnums.TargetID.ConjuredAmalgamate); IReadOnlyList <AgentItem> leftArms = agentData.GetGadgetsByID((int)ArcDPSEnums.TargetID.CALeftArm); IReadOnlyList <AgentItem> rightArms = agentData.GetGadgetsByID((int)ArcDPSEnums.TargetID.CARightArm); foreach (AgentItem ca in cas) { ca.OverrideType(AgentItem.AgentType.NPC); } foreach (AgentItem leftArm in leftArms) { leftArm.OverrideType(AgentItem.AgentType.NPC); } foreach (AgentItem rightArm in rightArms) { rightArm.OverrideType(AgentItem.AgentType.NPC); } agentData.Refresh(); ComputeFightTargets(agentData, combatData, extensions); AgentItem sword = agentData.AddCustomAgent(0, fightData.FightEnd, AgentItem.AgentType.NPC, "Conjured Sword\0:Conjured Sword\051", ParserHelper.Spec.NPC, (int)ArcDPSEnums.TrashID.ConjuredPlayerSword, true); friendlies.Add(new NPC(sword)); foreach (CombatItem c in combatData) { if (c.IsDamage(extensions) && c.SkillID == 52370) { c.OverrideSrcAgent(sword.Agent); } } }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { var artsariivs = new List <AgentItem>(agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Artsariiv)); if (artsariivs.Any()) { artsariivs.Remove(artsariivs.MaxBy(x => x.LastAware - x.FirstAware)); if (artsariivs.Any()) { foreach (AgentItem subartsariiv in artsariivs) { subartsariiv.OverrideID(ArcDPSEnums.TrashID.CloneArtsariiv); } } agentData.Refresh(); } base.EIEvtcParse(gw2Build, fightData, agentData, combatData, extensions); int count = 0; foreach (NPC trashMob in _trashMobs) { if (trashMob.ID == (int)ArcDPSEnums.TrashID.SmallArtsariiv) { trashMob.OverrideName("Small " + trashMob.Character); } if (trashMob.ID == (int)ArcDPSEnums.TrashID.MediumArtsariiv) { trashMob.OverrideName("Medium " + trashMob.Character); } if (trashMob.ID == (int)ArcDPSEnums.TrashID.BigArtsariiv) { trashMob.OverrideName("Big " + trashMob.Character); } } foreach (NPC target in _targets) { if (target.ID == (int)ArcDPSEnums.TrashID.CloneArtsariiv) { target.OverrideName("Clone " + target.Character + " " + (++count)); } } }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { // We remove extra Mai trins if present IReadOnlyList <AgentItem> maiTrins = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.MaiTrinStrike); if (maiTrins.Count > 1) { for (int i = 1; i < maiTrins.Count; i++) { maiTrins[i].OverrideID(ArcDPSEnums.TargetID.DummyMaiTrinStrike); } agentData.Refresh(); } ComputeFightTargets(agentData, combatData, extensions); var echoesOfScarlet = Targets.Where(x => x.ID == (int)ArcDPSEnums.TargetID.EchoOfScarletBriarNM || x.ID == (int)ArcDPSEnums.TargetID.EchoOfScarletBriarCM).ToList(); foreach (AbstractSingleActor echoOfScarlet in echoesOfScarlet) { var hpUpdates = combatData.Where(x => x.SrcMatchesAgent(echoOfScarlet.AgentItem) && x.IsStateChange == ArcDPSEnums.StateChange.HealthUpdate).ToList(); if (hpUpdates.Count > 1 && hpUpdates.LastOrDefault().DstAgent == 10000) { hpUpdates.LastOrDefault().OverrideSrcAgent(ParserHelper._unknownAgent.Agent); } } foreach (NPC target in Targets) { switch (target.ID) { case (int)ArcDPSEnums.TrashID.ScarletPhantomBreakbar: target.OverrideName("Elite " + target.Character + " CC"); break; case (int)ArcDPSEnums.TrashID.ScarletPhantomHP: case (int)ArcDPSEnums.TrashID.ScarletPhantomHP2: target.OverrideName("Elite " + target.Character + " HP"); break; default: break; } } }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { // make those into npcs IReadOnlyList <AgentItem> cas = agentData.GetGadgetsByID(_cn ? (int)ArcDPSEnums.TargetID.ConjuredAmalgamate_CHINA : (int)ArcDPSEnums.TargetID.ConjuredAmalgamate); if (!cas.Any()) { throw new MissingKeyActorsException("Conjured Amalgamate not found"); } IReadOnlyList <AgentItem> leftArms = agentData.GetGadgetsByID(_cn ? (int)ArcDPSEnums.TargetID.CALeftArm_CHINA : (int)ArcDPSEnums.TargetID.CALeftArm); IReadOnlyList <AgentItem> rightArms = agentData.GetGadgetsByID(_cn ? (int)ArcDPSEnums.TargetID.CARightArm_CHINA : (int)ArcDPSEnums.TargetID.CARightArm); foreach (AgentItem ca in cas) { ca.OverrideType(AgentItem.AgentType.NPC); ca.OverrideID(ArcDPSEnums.TargetID.ConjuredAmalgamate); } foreach (AgentItem leftArm in leftArms) { leftArm.OverrideType(AgentItem.AgentType.NPC); leftArm.OverrideID(ArcDPSEnums.TargetID.CALeftArm); } foreach (AgentItem rightArm in rightArms) { rightArm.OverrideType(AgentItem.AgentType.NPC); rightArm.OverrideID(ArcDPSEnums.TargetID.CARightArm); } agentData.Refresh(); AgentItem sword = agentData.AddCustomNPCAgent(0, fightData.FightEnd, "Conjured Sword\0:Conjured Sword\051", ParserHelper.Spec.NPC, (int)ArcDPSEnums.TrashID.ConjuredPlayerSword, true); ComputeFightTargets(agentData, combatData, extensions); foreach (CombatItem c in combatData) { if (c.IsDamage(extensions) && c.SkillID == 52370) { c.OverrideSrcAgent(sword.Agent); } } }
public override void SpecialParse(FightData fightData, AgentData agentData, List <CombatItem> combatData) { // find target Target target = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Xera); if (target == null) { throw new InvalidOperationException("Main target of the fight not found"); } // enter combat CombatItem enterCombat = combatData.Find(x => x.SrcInstid == target.InstID && x.IsStateChange == ParseEnum.StateChange.EnterCombat); if (enterCombat != null) { fightData.FightStart = enterCombat.Time; } // find split foreach (AgentItem NPC in agentData.GetAgentByType(AgentItem.AgentType.NPC)) { if (NPC.ID == 16286) { target.Health = 24085950; CombatItem move = combatData.FirstOrDefault(x => x.IsStateChange == ParseEnum.StateChange.Position && x.SrcInstid == NPC.InstID && x.Time >= NPC.FirstAware + 500 && x.Time <= NPC.LastAware); if (move != null) { _specialSplit = move.Time; } else { _specialSplit = NPC.FirstAware; } target.AgentItem.LastAware = NPC.LastAware; // get unique id for the fusion ushort instID = 0; Random rnd = new Random(); while (agentData.InstIDValues.Contains(instID) || instID == 0) { instID = (ushort)rnd.Next(ushort.MaxValue / 2, ushort.MaxValue); } target.AgentItem.InstID = instID; agentData.Refresh(); HashSet <ulong> agents = new HashSet <ulong>() { NPC.Agent, target.Agent }; // update combat data foreach (CombatItem c in combatData) { if (agents.Contains(c.SrcAgent)) { c.OverrideSrcValues(target.Agent, target.InstID); } if (agents.Contains(c.DstAgent)) { c.OverrideDstValues(target.Agent, target.InstID); } } break; } } }
private void CompletePlayers() { //Fix Disconnected players List <AgentItem> playerAgentList = _agentData.GetAgentByType(AgentItem.AgentType.Player); bool refresh = false; foreach (AgentItem playerAgent in playerAgentList) { if (playerAgent.InstID == 0 || playerAgent.FirstAware == 0 || playerAgent.LastAware == long.MaxValue) { CombatItem tst = _combatItems.Find(x => x.SrcAgent == playerAgent.Agent); if (tst == null) { tst = _combatItems.Find(x => x.DstAgent == playerAgent.Agent); if (tst == null) { continue; } playerAgent.SetInstid(tst.DstInstid); refresh = true; } else { playerAgent.SetInstid(tst.SrcInstid); refresh = true; } playerAgent.OverrideAwareTimes(_logStartTime, _logEndTime); } bool skip = false; var player = new Player(playerAgent, _fightData.Logic.Mode == FightLogic.ParseMode.Fractal, false); foreach (Player p in _playerList) { if (p.Account == player.Account) // same player { if (p.Character == player.Character) // same character, can be fused { skip = true; ulong agent = p.Agent; foreach (CombatItem c in _combatItems) { if (player.Agent == c.DstAgent && c.IsStateChange.DstIsAgent()) { c.OverrideDstAgent(agent); } if (player.Agent == c.SrcAgent && c.IsStateChange.SrcIsAgent()) { c.OverrideSrcAgent(agent); } } _agentData.SwapMasters(player.AgentItem, p.AgentItem); p.AgentItem.OverrideAwareTimes(Math.Min(p.AgentItem.FirstAware, player.AgentItem.FirstAware), Math.Max(p.AgentItem.LastAware, player.AgentItem.LastAware)); break; } // different character in raid mode, discard it as it can't have any influence, otherwise add as a separate entity else if (_fightData.Logic.Mode == FightLogic.ParseMode.Raid) { skip = true; break; } } } if (!skip) { _playerList.Add(player); } } if (_parserSettings.AnonymousPlayer) { for (int i = 0; i < _playerList.Count; i++) { _playerList[i].Anonymize(i + 1); } } _playerList = _playerList.OrderBy(a => a.Group).ToList(); if (refresh) { _agentData.Refresh(); } }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, List <AbstractSingleActor> friendlies, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { // find target AgentItem firstXera = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Xera).FirstOrDefault(); if (firstXera == null) { throw new MissingKeyActorsException("Xera not found"); } _xeraFirstPhaseEndTime = firstXera.LastAware; // var maxHPUpdates = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.MaxHealthUpdate && x.DstAgent > 0).ToList(); // var bloodstoneFragments = maxHPUpdates.Where(x => x.DstAgent == 104580).Select(x => agentData.GetAgent(x.SrcAgent, x.Time)).Where(x => x.Type == AgentItem.AgentType.Gadget).ToList(); foreach (AgentItem gadget in bloodstoneFragments) { gadget.OverrideType(AgentItem.AgentType.NPC); gadget.OverrideID(ArcDPSEnums.TrashID.BloodstoneFragment); } // var bloodstoneShards = maxHPUpdates.Where(x => x.DstAgent == 343620).Select(x => agentData.GetAgent(x.SrcAgent, x.Time)).Where(x => x.Type == AgentItem.AgentType.Gadget).ToList(); foreach (AgentItem gadget in bloodstoneShards) { gadget.OverrideType(AgentItem.AgentType.NPC); gadget.OverrideID(ArcDPSEnums.TrashID.BloodstoneShard); } // var chargedBloodStones = maxHPUpdates.Where(x => x.DstAgent == 74700).Select(x => agentData.GetAgent(x.SrcAgent, x.Time)).Where(x => x.Type == AgentItem.AgentType.Gadget && x.LastAware > firstXera.LastAware).ToList(); foreach (AgentItem gadget in chargedBloodStones) { gadget.OverrideType(AgentItem.AgentType.NPC); gadget.OverrideID(ArcDPSEnums.TrashID.ChargedBloodstone); } if (bloodstoneFragments.Any() || bloodstoneShards.Any() || chargedBloodStones.Any()) { agentData.Refresh(); } // find split AgentItem secondXera = agentData.GetNPCsByID(16286).FirstOrDefault(); if (secondXera != null) { CombatItem move = combatData.FirstOrDefault(x => x.IsStateChange == ArcDPSEnums.StateChange.Position && x.SrcMatchesAgent(secondXera) && x.Time >= secondXera.FirstAware + 500); if (move != null) { _xeraSecondPhaseStartTime = move.Time; } else { _xeraSecondPhaseStartTime = secondXera.FirstAware; } firstXera.OverrideAwareTimes(firstXera.FirstAware, secondXera.LastAware); agentData.SwapMasters(secondXera, firstXera); // update combat data foreach (CombatItem c in combatData) { if (c.SrcMatchesAgent(secondXera, extensions)) { c.OverrideSrcAgent(firstXera.Agent); } if (c.DstMatchesAgent(secondXera, extensions)) { c.OverrideDstAgent(firstXera.Agent); } } } ComputeFightTargets(agentData, combatData, extensions); if (_xeraSecondPhaseStartTime > 0) { AbstractSingleActor mainTarget = GetMainTarget(); if (mainTarget == null) { throw new MissingKeyActorsException("Xera not found"); } mainTarget.SetManualHealth(24085950); } }
private void CompletePlayers() { //Fix Disconnected players var playerAgentList = _agentData.GetAgentByType(AgentItem.AgentType.Player); foreach (AgentItem playerAgent in playerAgentList) { if (playerAgent.InstID == 0 || playerAgent.FirstAware == 0 || playerAgent.LastAware == long.MaxValue) { CombatItem tst = _combatItems.Find(x => x.SrcAgent == playerAgent.Agent); if (tst == null) { tst = _combatItems.Find(x => x.DstAgent == playerAgent.Agent); if (tst == null) { continue; } playerAgent.InstID = tst.DstInstid; } else { playerAgent.InstID = tst.SrcInstid; } playerAgent.FirstAware = _fightData.FightStart; playerAgent.LastAware = _fightData.FightEnd; } try { bool skip = false; Player player = new Player(playerAgent, _fightData.Logic.Mode == FightLogic.ParseMode.Fractal); foreach (Player p in _playerList) { if (p.Account == player.Account) // same player { if (p.Character == player.Character) // same character, can be fused { skip = true; Random rnd = new Random(); ulong agent = 0; while (_agentData.AgentValues.Contains(agent) || agent == 0) { agent = (ulong)rnd.Next(Int32.MaxValue / 2, Int32.MaxValue); } ushort instid = 0; while (_agentData.InstIDValues.Contains(instid) || instid == 0) { instid = (ushort)rnd.Next(ushort.MaxValue / 2, ushort.MaxValue); } foreach (CombatItem c in _combatItems) { if (c.DstAgent == p.Agent || player.Agent == c.DstAgent) { c.OverrideDstValues(agent, instid); } if (c.SrcAgent == p.Agent || player.Agent == c.SrcAgent) { c.OverrideSrcValues(agent, instid); } } p.AgentItem.InstID = instid; p.AgentItem.Agent = agent; p.AgentItem.FirstAware = Math.Min(p.AgentItem.FirstAware, player.AgentItem.FirstAware); p.AgentItem.LastAware = Math.Max(p.AgentItem.LastAware, player.AgentItem.LastAware); _agentData.Refresh(); break; } // different character in raid mode, discard it as it can't have any influence, otherwise add as a separate entity else if (_fightData.Logic.Mode == FightLogic.ParseMode.Raid) { skip = true; break; } } } if (!skip) { _playerList.Add(player); } } catch (InvalidPlayerException ex) { if (_fightData.Logic.Mode != FightLogic.ParseMode.WvW) { throw ex; } // the players are enemy /*if (!ex.Squadless) * { * _fightData.Logic.Targets.Add(new Target(playerAgent)); * }*/ } } }
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); } } } } }
internal override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { // find target AgentItem firstXera = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Xera).FirstOrDefault(); if (firstXera == null) { throw new MissingKeyActorsException("Xera not found"); } var maxHPUpdates = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.MaxHealthUpdate && x.DstAgent > 0).ToList(); var bloodstoneFragments = maxHPUpdates.Where(x => x.DstAgent == 104580).Select(x => agentData.GetAgent(x.SrcAgent)).Where(x => x.Type == AgentItem.AgentType.Gadget).ToList(); foreach (AgentItem gadget in bloodstoneFragments) { gadget.OverrideType(AgentItem.AgentType.NPC); gadget.OverrideID(ArcDPSEnums.TrashID.BloodstoneFragment); } var bloodstoneShards = maxHPUpdates.Where(x => x.DstAgent == 343620).Select(x => agentData.GetAgent(x.SrcAgent)).Where(x => x.Type == AgentItem.AgentType.Gadget).ToList(); foreach (AgentItem gadget in bloodstoneShards) { gadget.OverrideType(AgentItem.AgentType.NPC); gadget.OverrideID(ArcDPSEnums.TrashID.BloodstoneShard); } var chargedBloodStones = maxHPUpdates.Where(x => x.DstAgent == 74700).Select(x => agentData.GetAgent(x.SrcAgent)).Where(x => x.Type == AgentItem.AgentType.Gadget && x.LastAware > firstXera.LastAware).ToList(); foreach (AgentItem gadget in chargedBloodStones) { gadget.OverrideType(AgentItem.AgentType.NPC); gadget.OverrideID(ArcDPSEnums.TrashID.ChargedBloodstone); // they are actually present from start to finish gadget.OverrideAwareTimes(firstXera.LastAware + 15000, gadget.LastAware); } if (bloodstoneFragments.Any() || bloodstoneShards.Any() || chargedBloodStones.Any()) { agentData.Refresh(); } // find split AgentItem secondXera = agentData.GetNPCsByID(16286).FirstOrDefault(); if (secondXera != null) { CombatItem move = combatData.FirstOrDefault(x => x.IsStateChange == ArcDPSEnums.StateChange.Position && x.SrcAgent == secondXera.Agent && x.Time >= secondXera.FirstAware + 500); if (move != null) { _xeraSecondPhaseStartTime = move.Time; } else { _xeraSecondPhaseStartTime = secondXera.FirstAware; } firstXera.OverrideAwareTimes(firstXera.FirstAware, secondXera.LastAware); agentData.SwapMasters(secondXera, firstXera); // update combat data foreach (CombatItem c in combatData) { if (c.SrcAgent == secondXera.Agent && c.IsStateChange.SrcIsAgent()) { c.OverrideSrcAgent(firstXera.Agent); } if (c.DstAgent == secondXera.Agent && c.IsStateChange.DstIsAgent()) { c.OverrideDstAgent(firstXera.Agent); } } } ComputeFightTargets(agentData, combatData); }
public override void SpecialParse(FightData fightData, AgentData agentData, List <CombatItem> combatData) { // Find target Target target = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Deimos); if (target == null) { throw new InvalidOperationException("Main target of the fight not found"); } // enter combat CombatItem enterCombat = combatData.FirstOrDefault(x => x.SrcInstid == target.InstID && x.IsStateChange == ParseEnum.StateChange.EnterCombat); if (enterCombat != null) { fightData.FightStart = enterCombat.Time; } // Deimos gadgets List <AgentItem> deimosGadgets = agentData.GetAgentByType(AgentItem.AgentType.Gadget).Where(x => x.Name.Contains("Deimos") && x.LastAware > target.LastAware).ToList(); if (deimosGadgets.Count > 0) { CombatItem targetable = combatData.LastOrDefault(x => x.IsStateChange == ParseEnum.StateChange.Targetable && x.Time > combatData.First().Time&& x.DstAgent > 0); long firstAware = deimosGadgets.Max(x => x.FirstAware); if (targetable != null) { firstAware = targetable.Time; } long oldAware = target.LastAware; fightData.PhaseData.Add(firstAware >= oldAware ? firstAware : oldAware); target.AgentItem.LastAware = deimosGadgets.Max(x => x.LastAware); // get unique id for the fusion ushort instID = 1; Random rnd = new Random(); while (agentData.InstIDValues.Contains(instID)) { instID = (ushort)rnd.Next(1, ushort.MaxValue); } target.AgentItem.InstID = instID; agentData.Refresh(); // update combat data HashSet <ulong> gadgetAgents = new HashSet <ulong>(deimosGadgets.Select(x => x.Agent)); HashSet <ulong> allAgents = new HashSet <ulong>(gadgetAgents); allAgents.Add(target.Agent); foreach (CombatItem c in combatData) { if (gadgetAgents.Contains(c.SrcAgent) && c.IsStateChange == ParseEnum.StateChange.MaxHealthUpdate) { continue; } if (allAgents.Contains(c.SrcAgent)) { c.SrcInstid = target.InstID; c.SrcAgent = target.Agent; } if (allAgents.Contains(c.DstAgent)) { c.DstInstid = target.InstID; c.DstAgent = target.Agent; } } } }