internal override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { // The walls and bombers spawn at the start of the encounter, we fix it by overriding their first aware to the first velocity change event var agentsToOverrideFirstAware = new List <AgentItem>(agentData.GetNPCsByID((int)ArcDPSEnums.TrashID.RiverOfSouls)); agentsToOverrideFirstAware.AddRange(agentData.GetNPCsByID((int)ArcDPSEnums.TrashID.HollowedBomber)); bool sortCombatList = false; foreach (AgentItem agentToOverrideFirstAware in agentsToOverrideFirstAware) { CombatItem firstMovement = combatData.FirstOrDefault(x => x.IsStateChange == ArcDPSEnums.StateChange.Velocity && x.SrcAgent == agentToOverrideFirstAware.Agent && x.DstAgent != 0); if (firstMovement != null) { // update start agentToOverrideFirstAware.OverrideAwareTimes(firstMovement.Time - ParserHelper.ServerDelayConstant, agentToOverrideFirstAware.LastAware); foreach (CombatItem c in combatData) { if (c.SrcAgent == agentToOverrideFirstAware.Agent && (c.IsStateChange == ArcDPSEnums.StateChange.Position || c.IsStateChange == ArcDPSEnums.StateChange.Rotation) && c.Time <= agentToOverrideFirstAware.FirstAware) { sortCombatList = true; c.OverrideTime(agentToOverrideFirstAware.FirstAware); } } } } // make sure the list is still sorted by time after overrides if (sortCombatList) { combatData.Sort((x, y) => x.Time.CompareTo(y.Time)); } ComputeFightTargets(agentData, combatData); }
protected static long GetFightOffsetByFirstInvulFilter(FightData fightData, AgentData agentData, List <CombatItem> combatData, int targetID, long invulID, long invulGainOffset) { // Find target AgentItem target = agentData.GetNPCsByID(targetID).FirstOrDefault(); if (target == null) { throw new MissingKeyActorsException("Main target of the fight not found"); } // check first invul gain at the start of the fight CombatItem invulGain = combatData.FirstOrDefault(x => x.DstMatchesAgent(target) && x.IsBuffApply() && x.SkillID == invulID); // get invul lost CombatItem invulLost = combatData.FirstOrDefault(x => x.SrcMatchesAgent(target) && x.IsBuffRemove == ArcDPSEnums.BuffRemove.All && x.SkillID == invulID); // invul loss matches the gained invul if (invulGain != null && invulLost != null && invulLost.Time > invulGain.Time) { // check against offset if (invulGain.Time - fightData.LogStart < invulGainOffset) { return(invulLost.Time + 1); } } else if (invulLost != null) { // only invul lost, missing buff apply event CombatItem enterCombat = combatData.FirstOrDefault(x => x.SrcMatchesAgent(target) && x.IsStateChange == ArcDPSEnums.StateChange.EnterCombat); // verify that first enter combat matches the moment invul is lost if (enterCombat != null && Math.Abs(enterCombat.Time - invulLost.Time) < ParserHelper.ServerDelayConstant) { return(invulLost.Time + 1); } } return(fightData.LogStart); }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { IReadOnlyList <AgentItem> prisoners = agentData.GetNPCsByID((int)ArcDPSEnums.TrashID.Prisoner2); var prisonerDeaths = new List <DeadEvent>(); foreach (AgentItem prisoner in prisoners) { prisonerDeaths.AddRange(combatData.GetDeadEvents(prisoner)); } if (prisonerDeaths.Count == 0) { AbstractSingleActor narella = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.Narella); if (narella == null) { throw new MissingKeyActorsException("Narella not found"); } DeadEvent deadEvent = combatData.GetDeadEvents(narella.AgentItem).LastOrDefault(); if (deadEvent != null) { fightData.SetSuccess(true, deadEvent.Time); return; } SetSuccessByCombatExit(new HashSet <int>(GetSuccessCheckIds()), combatData, fightData, playerAgents); } } }
private void FillSubLogics(AgentData agentData) { var allTargetIDs = Enum.GetValues(typeof(ArcDPSEnums.TargetID)).Cast <int>().ToList(); var blackList = new HashSet <int>() { (int)ArcDPSEnums.TargetID.Artsariiv, (int)ArcDPSEnums.TargetID.Deimos, (int)ArcDPSEnums.TargetID.ConjuredAmalgamate, (int)ArcDPSEnums.TargetID.CALeftArm_CHINA, (int)ArcDPSEnums.TargetID.CARightArm_CHINA, (int)ArcDPSEnums.TargetID.ConjuredAmalgamate_CHINA, }; foreach (int targetID in allTargetIDs) { if (agentData.GetNPCsByID(targetID).Any()) { if (blackList.Contains(targetID)) { continue; } _targetIDs.Add(targetID); /*switch (targetID) * { * case (int)ArcDPSEnums.TargetID.AiKeeperOfThePeak: * //_subLogics.Add(new AiKeeperOfThePeak(targetID)); * break; * default: * break; * }*/ } } }
protected static long GetFightOffsetByFirstInvulFilter(FightData fightData, AgentData agentData, List <CombatItem> combatData, int targetID, long invulID, long invulGainOffset) { // Find target AgentItem target = agentData.GetNPCsByID(targetID).FirstOrDefault(); if (target == null) { throw new MissingKeyActorsException("Main target of the fight not found"); } // check invul gain at the start of the fight (initial or with a small threshold) CombatItem invulGain = combatData.FirstOrDefault(x => x.DstAgent == target.Agent && (x.IsStateChange == ArcDPSEnums.StateChange.None || x.IsStateChange == ArcDPSEnums.StateChange.BuffInitial) && x.IsBuffRemove == ArcDPSEnums.BuffRemove.None && x.IsBuff > 0 && x.SkillID == invulID); // get invul lost CombatItem invulLost = combatData.FirstOrDefault(x => x.Time >= fightData.LogStart && x.SrcAgent == target.Agent && x.IsStateChange == ArcDPSEnums.StateChange.None && x.IsBuffRemove == ArcDPSEnums.BuffRemove.All && x.SkillID == invulID); if (invulGain != null && invulGain.Time - fightData.LogStart < invulGainOffset && invulLost != null && invulLost.Time > invulGain.Time) { return(invulLost.Time + 1); } else if (invulLost != null) { CombatItem enterCombat = combatData.FirstOrDefault(x => x.SrcAgent == target.Agent && x.IsStateChange == ArcDPSEnums.StateChange.EnterCombat && Math.Abs(x.Time - invulLost.Time) < ParserHelper.ServerDelayConstant); if (enterCombat != null) { return(enterCombat.Time + 1); } } return(fightData.LogStart); }
private static void RegroupTargetsByID(int id, AgentData agentData, List <CombatItem> combatItems) { IReadOnlyList <AgentItem> agents = agentData.GetNPCsByID(id); if (agents.Count > 1) { AgentItem firstItem = agents.First(); var agentValues = new HashSet <ulong>(agents.Select(x => x.Agent)); var newTargetAgent = new AgentItem(firstItem); newTargetAgent.OverrideAwareTimes(agents.Min(x => x.FirstAware), agents.Max(x => x.LastAware)); agentData.SwapMasters(new HashSet <AgentItem>(agents), firstItem); agentData.OverrideID(id, newTargetAgent); foreach (CombatItem c in combatItems) { if (agentValues.Contains(c.SrcAgent) && c.IsStateChange.SrcIsAgent()) { c.OverrideSrcAgent(newTargetAgent.Agent); } if (agentValues.Contains(c.DstAgent) && c.IsStateChange.DstIsAgent()) { c.OverrideDstAgent(newTargetAgent.Agent); } } } }
internal 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) { IReadOnlyList <AgentItem> agents = agentData.GetNPCsByID(id); foreach (AgentItem agentItem in agents) { _targets.Add(new NPC(agentItem)); } } List <ArcDPSEnums.TrashID> ids2 = GetTrashMobsIDS(); var aList = agentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => ids2.Contains(ArcDPSEnums.GetTrashID(x.ID))).ToList(); //aList.AddRange(agentData.GetAgentByType(AgentItem.AgentType.Gadget).Where(x => ids2.Contains(ParseEnum.GetTrashIDS(x.ID)))); foreach (AgentItem a in aList) { _trashMobs.Add(new NPC(a)); } }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { AgentItem desmina = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Desmina).FirstOrDefault(); if (desmina == null) { throw new MissingKeyActorsException("Desmina not found"); } ExitCombatEvent ooc = combatData.GetExitCombatEvents(desmina).LastOrDefault(); if (ooc != null) { long time = 0; foreach (NPC mob in TrashMobs) { time = Math.Max(mob.LastAware, time); } DespawnEvent dspwn = combatData.GetDespawnEvents(desmina).LastOrDefault(); if (time != 0 && dspwn == null && time + 500 <= desmina.LastAware) { if (!AtLeastOnePlayerAlive(combatData, fightData, time, playerAgents)) { return; } fightData.SetSuccess(true, time); } } } }
internal override FightData.EncounterMode GetEncounterMode(CombatData combatData, AgentData agentData, FightData fightData) { if (!Targetless) { var targetIDs = new HashSet <int>() { (int)ArcDPSEnums.TargetID.TheDragonVoidJormag, (int)ArcDPSEnums.TargetID.TheDragonVoidKralkatorrik, (int)ArcDPSEnums.TargetID.TheDragonVoidMordremoth, (int)ArcDPSEnums.TargetID.TheDragonVoidPrimordus, (int)ArcDPSEnums.TargetID.TheDragonVoidZhaitan, }; if (Targets.Where(x => targetIDs.Contains(x.ID)).Any(x => x.GetHealth(combatData) > 16000000)) { return(FightData.EncounterMode.CM); } } IReadOnlyList <AgentItem> voidMelters = agentData.GetNPCsByID((int)ArcDPSEnums.TrashID.VoidMelter); if (voidMelters.Count > 5) { long firstAware = voidMelters[0].FirstAware; if (voidMelters.Count(x => Math.Abs(x.FirstAware - firstAware) < ParserHelper.ServerDelayConstant) > 5) { return(FightData.EncounterMode.CM); } } return(FightData.EncounterMode.Normal); }
private static void RegroupTargetsByID(int id, AgentData agentData, List <CombatItem> combatItems, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { IReadOnlyList <AgentItem> agents = agentData.GetNPCsByID(id); if (agents.Count > 1) { AgentItem firstItem = agents.First(); var agentValues = new HashSet <ulong>(agents.Select(x => x.Agent)); var newTargetAgent = new AgentItem(firstItem); newTargetAgent.OverrideAwareTimes(agents.Min(x => x.FirstAware), agents.Max(x => x.LastAware)); agentData.SwapMasters(new HashSet <AgentItem>(agents), newTargetAgent); agentData.ReplaceAgentsFromID(newTargetAgent); foreach (CombatItem c in combatItems) { if (agentValues.Contains(c.SrcAgent) && c.SrcIsAgent(extensions)) { c.OverrideSrcAgent(newTargetAgent.Agent); } if (agentValues.Contains(c.DstAgent) && c.DstIsAgent(extensions)) { c.OverrideDstAgent(newTargetAgent.Agent); } } } }
public override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { // The walls spawn at the start of the encounter, we fix it by overriding their first aware to the first velocity change event List <AgentItem> riverOfSouls = agentData.GetNPCsByID((int)RiverOfSouls); bool sortCombatList = false; foreach (AgentItem riverOfSoul in riverOfSouls) { CombatItem firstMovement = combatData.FirstOrDefault(x => x.IsStateChange == ParseEnum.StateChange.Velocity && x.SrcAgent == riverOfSoul.Agent && x.DstAgent != 0); if (firstMovement != null) { // update start riverOfSoul.OverrideAwareTimes(firstMovement.Time - GeneralHelper.ServerDelayConstant, riverOfSoul.LastAware); foreach (CombatItem c in combatData) { if (c.SrcAgent == riverOfSoul.Agent && (c.IsStateChange == ParseEnum.StateChange.Position || c.IsStateChange == ParseEnum.StateChange.Rotation) && c.Time <= riverOfSoul.FirstAware) { sortCombatList = true; c.OverrideTime(riverOfSoul.FirstAware); } } } } // make sure the list is still sorted by time after overrides if (sortCombatList) { combatData.Sort((x, y) => x.Time.CompareTo(y.Time)); } ComputeFightTargets(agentData, combatData); }
internal override FightData.CMStatus IsCM(CombatData combatData, AgentData agentData, FightData fightData) { NPC target = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.Skorvald); if (target == null) { throw new MissingKeyActorsException("Skorvald not found"); } if (combatData.GetBuildEvent().Build >= 106277) { return(agentData.GetNPCsByID(16725).Any() && agentData.GetNPCsByID(11245).Any() ? FightData.CMStatus.CM : FightData.CMStatus.NoCM); } else { return((target.GetHealth(combatData) == 5551340) ? FightData.CMStatus.CM : FightData.CMStatus.NoCM); } }
internal virtual void ComputeFightTargets(AgentData agentData, List <CombatItem> combatItems, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { foreach (int id in GetUniqueNPCIDs()) { RegroupTargetsByID(id, agentData, combatItems, extensions); } // List <int> targetIDs = GetTargetsIDs(); foreach (int id in targetIDs) { IReadOnlyList <AgentItem> agents = agentData.GetNPCsByID(id); foreach (AgentItem agentItem in agents) { _targets.Add(new NPC(agentItem)); } } _targets.Sort((x, y) => x.FirstAware.CompareTo(y.FirstAware)); // List <ArcDPSEnums.TrashID> trashIDs = GetTrashMobsIDs(); var aList = agentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => trashIDs.Contains(ArcDPSEnums.GetTrashID(x.ID))).ToList(); //aList.AddRange(agentData.GetAgentByType(AgentItem.AgentType.Gadget).Where(x => ids2.Contains(ParseEnum.GetTrashIDS(x.ID)))); foreach (AgentItem a in aList) { _trashMobs.Add(new NPC(a)); } _trashMobs.Sort((x, y) => x.FirstAware.CompareTo(y.FirstAware)); // List <int> friendlyNPCIDs = GetFriendlyNPCIDs(); foreach (int id in friendlyNPCIDs) { IReadOnlyList <AgentItem> agents = agentData.GetNPCsByID(id); foreach (AgentItem agentItem in agents) { _nonPlayerFriendlies.Add(new NPC(agentItem)); } } _nonPlayerFriendlies.Sort((x, y) => x.FirstAware.CompareTo(y.FirstAware)); // TargetAgents = new HashSet <AgentItem>(_targets.Select(x => x.AgentItem)); NonPlayerFriendlyAgents = new HashSet <AgentItem>(_nonPlayerFriendlies.Select(x => x.AgentItem)); TrashMobAgents = new HashSet <AgentItem>(_trashMobs.Select(x => x.AgentItem)); }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, List <AbstractSingleActor> friendlies, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { agentData.AddCustomAgent(0, fightData.FightEnd, AgentItem.AgentType.NPC, "River of Souls", Spec.NPC, (int)ArcDPSEnums.TargetID.DummyTarget, true); ComputeFightTargets(agentData, combatData, extensions); AgentItem desmina = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Desmina).FirstOrDefault(); if (desmina != null) { friendlies.Add(new NPC(desmina)); } }
internal override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { // Find target AgentItem target = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Sabir).FirstOrDefault(); if (target == null) { throw new MissingKeyActorsException("Sabir not found"); } CombatItem enterCombat = combatData.FirstOrDefault(x => x.IsStateChange == ArcDPSEnums.StateChange.EnterCombat && x.SrcMatchesAgent(target)); return(enterCombat != null ? enterCombat.Time : fightData.LogStart); }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { AgentItem target = agentData.GetNPCsByID(GenericTriggerID).FirstOrDefault(); foreach (CombatItem c in combatData) { // redirect all attacks to the main golem if (c.DstAgent == 0 && c.DstInstid == 0 && c.IsDamage(extensions)) { c.OverrideDstAgent(target.Agent); } } ComputeFightTargets(agentData, combatData, extensions); }
internal override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { AgentItem target = agentData.GetNPCsByID(GenericTriggerID).FirstOrDefault(); foreach (CombatItem c in combatData) { // redirect all attacks to the main golem if (c.DstAgent == 0 && c.DstInstid == 0 && c.IsStateChange == ArcDPSEnums.StateChange.None && c.IFF == ArcDPSEnums.IFF.Foe && c.IsActivation == ArcDPSEnums.Activation.None && c.IsBuffRemove == ArcDPSEnums.BuffRemove.None) { c.OverrideDstAgent(target.Agent); } } ComputeFightTargets(agentData, combatData); }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { List <AgentItem> prisoners = agentData.GetNPCsByID((int)ArcDPSEnums.TrashID.Prisoner2); var prisonerDeaths = new List <DeadEvent>(); foreach (AgentItem prisoner in prisoners) { prisonerDeaths.AddRange(combatData.GetDeadEvents(prisoner)); } if (prisonerDeaths.Count == 0) { SetSuccessByCombatExit(new HashSet <int>(GetSuccessCheckIds()), combatData, fightData, playerAgents); } } }
internal override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { AgentItem target = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Xera).FirstOrDefault(); if (target == null) { throw new MissingKeyActorsException("Xera not found"); } // enter combat CombatItem enterCombat = combatData.Find(x => x.SrcMatchesAgent(target) && x.IsStateChange == ArcDPSEnums.StateChange.EnterCombat); if (enterCombat != null) { return(enterCombat.Time); } return(fightData.LogStart); }
public override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { AgentItem target = agentData.GetNPCsByID((int)ParseEnum.TargetID.Cairn).FirstOrDefault(); if (target == null) { throw new InvalidOperationException("Cairn not found"); } // spawn protection loss CombatItem spawnProtectionLoss = combatData.Find(x => x.IsBuffRemove == ParseEnum.BuffRemove.All && x.IsBuff != 0 && x.SrcAgent == target.Agent && x.SkillID == 34113); if (spawnProtectionLoss != null) { fightData.OverrideOffset(spawnProtectionLoss.Time); } return(fightData.FightOffset); }
public override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { // find target AgentItem target = agentData.GetNPCsByID((int)ParseEnum.TargetIDS.Xera).FirstOrDefault(); if (target == null) { throw new InvalidOperationException("Error Encountered: Xera not found"); } // find split foreach (AgentItem NPC in agentData.GetAgentByType(AgentItem.AgentType.NPC)) { if (NPC.ID == 16286) { CombatItem move = combatData.FirstOrDefault(x => x.IsStateChange == ParseEnum.StateChange.Position && x.SrcAgent == NPC.Agent && x.Time >= NPC.FirstAware + 500); if (move != null) { _specialSplit = move.Time; } else { _specialSplit = NPC.FirstAware; } target.OverrideAwareTimes(target.FirstAware, NPC.LastAware); agentData.SwapMasters(NPC, target); var agents = new HashSet <ulong>() { NPC.Agent, target.Agent }; // update combat data foreach (CombatItem c in combatData) { if (agents.Contains(c.SrcAgent) && c.IsStateChange.SrcIsAgent()) { c.OverrideSrcAgent(target.Agent); } if (agents.Contains(c.DstAgent) && c.IsStateChange.DstIsAgent()) { c.OverrideDstAgent(target.Agent); } } break; } } ComputeFightTargets(agentData, combatData); }
public override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { AgentItem target = agentData.GetNPCsByID((int)ParseEnum.TargetIDS.Xera).FirstOrDefault(); if (target == null) { throw new InvalidOperationException("Error Encountered: Xera not found"); } // enter combat CombatItem enterCombat = combatData.Find(x => x.SrcAgent == target.Agent && x.IsStateChange == ParseEnum.StateChange.EnterCombat); if (enterCombat != null) { fightData.OverrideOffset(enterCombat.Time); } return(fightData.FightOffset); }
public override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { List <AgentItem> deimosAgents = agentData.GetNPCsByID((int)ParseEnum.TargetIDS.Deimos); long offset = fightData.FightOffset; foreach (AgentItem deimos in deimosAgents) { // enter combat CombatItem enterCombat = combatData.FirstOrDefault(x => x.SrcAgent == deimos.Agent && x.IsStateChange == ParseEnum.StateChange.EnterCombat); if (enterCombat != null) { offset = Math.Max(offset, enterCombat.Time); } } fightData.OverrideOffset(offset); return(fightData.FightOffset); }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { AbstractSingleActor target = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.ConjuredAmalgamate); AbstractSingleActor leftArm = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.CALeftArm); AbstractSingleActor rightArm = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.CARightArm); if (target == null) { throw new MissingKeyActorsException("Conjured Amalgamate not found"); } AgentItem zommoros = agentData.GetNPCsByID(21118).LastOrDefault(); if (zommoros == null) { return; } SpawnEvent npcSpawn = combatData.GetSpawnEvents(zommoros).LastOrDefault(); AbstractHealthDamageEvent lastDamageTaken = combatData.GetDamageTakenData(target.AgentItem).LastOrDefault(x => (x.HealthDamage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTaken == null) { return; } if (rightArm != null) { AbstractHealthDamageEvent lastDamageTakenArm = combatData.GetDamageTakenData(rightArm.AgentItem).LastOrDefault(x => (x.HealthDamage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTakenArm != null) { lastDamageTaken = lastDamageTaken.Time > lastDamageTakenArm.Time ? lastDamageTaken : lastDamageTakenArm; } } if (leftArm != null) { AbstractHealthDamageEvent lastDamageTakenArm = combatData.GetDamageTakenData(leftArm.AgentItem).LastOrDefault(x => (x.HealthDamage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTakenArm != null) { lastDamageTaken = lastDamageTaken.Time > lastDamageTakenArm.Time ? lastDamageTaken : lastDamageTakenArm; } } if (npcSpawn != null) { fightData.SetSuccess(true, lastDamageTaken.Time); } } }
internal override void ComputeFightTargets(AgentData agentData, List <CombatItem> combatItems) { int id = GetFightTargetsIDs().First(); AgentItem agentItem = agentData.GetNPCsByID(id).FirstOrDefault(); // Trigger ID is not NPC if (agentItem == null) { agentItem = agentData.GetGadgetsByID(id).FirstOrDefault(); if (agentItem != null) { _targets.Add(new NPC(agentItem)); } } else { _targets.Add(new NPC(agentItem)); } }
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) { 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)); } } }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { NPC target = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.ConjuredAmalgamate); NPC leftArm = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.CALeftArm); NPC rightArm = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.CARightArm); if (target == null) { throw new InvalidOperationException("Error Encountered: Conjured Amalgamate not found"); } AgentItem zommoros = agentData.GetNPCsByID(21118).LastOrDefault(); if (zommoros == null) { return; } SpawnEvent npcSpawn = combatData.GetSpawnEvents(zommoros).LastOrDefault(); AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(target.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (rightArm != null) { AbstractDamageEvent lastDamageTakenArm = combatData.GetDamageTakenData(rightArm.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTakenArm != null) { lastDamageTaken = lastDamageTaken.Time > lastDamageTakenArm.Time ? lastDamageTaken : lastDamageTakenArm; } } if (leftArm != null) { AbstractDamageEvent lastDamageTakenArm = combatData.GetDamageTakenData(leftArm.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTakenArm != null) { lastDamageTaken = lastDamageTaken.Time > lastDamageTakenArm.Time ? lastDamageTaken : lastDamageTakenArm; } } if (npcSpawn != null && lastDamageTaken != null) { fightData.SetSuccess(true, lastDamageTaken.Time); } } }
internal override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { AgentItem target = agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.Cairn).FirstOrDefault(); if (target == null) { throw new MissingKeyActorsException("Cairn not found"); } // spawn protection loss -- most reliable CombatItem spawnProtectionLoss = combatData.Find(x => x.IsBuffRemove == ArcDPSEnums.BuffRemove.All && x.SrcMatchesAgent(target) && x.SkillID == 34113); if (spawnProtectionLoss != null) { return(spawnProtectionLoss.Time - 1); } else { // get first end casting CombatItem firstCastEnd = combatData.FirstOrDefault(x => x.EndCasting() && (x.Time - fightData.LogStart) < 2000 && x.SrcMatchesAgent(target)); // It has to Impact(38102), otherwise anomaly, player may have joined mid fight, do nothing if (firstCastEnd != null && firstCastEnd.SkillID == 38102) { // Action 4 from skill dump for 38102 long actionHappened = 1025; // Adds around 10 to 15 ms diff compared to buff loss if (firstCastEnd.BuffDmg > 0) { double nonScaledToScaledRatio = (double)firstCastEnd.Value / firstCastEnd.BuffDmg; return(firstCastEnd.Time - firstCastEnd.Value + (long)Math.Round(nonScaledToScaledRatio * actionHappened) - 1); } // Adds around 15 to 20 ms diff compared to buff loss else { return(firstCastEnd.Time - firstCastEnd.Value + actionHappened - 1); } } } return(fightData.LogStart); }
internal override void ComputeFightTargets(AgentData agentData, List <CombatItem> combatItems, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { int id = GetTargetsIDs().First(); AgentItem agentItem = agentData.GetNPCsByID(id).FirstOrDefault(); // Trigger ID is not NPC if (agentItem == null) { agentItem = agentData.GetGadgetsByID(id).FirstOrDefault(); if (agentItem != null) { _targets.Add(new NPC(agentItem)); } } else { _targets.Add(new NPC(agentItem)); } // TargetAgents = new HashSet <AgentItem>(_targets.Select(x => x.AgentItem)); TrashMobAgents = new HashSet <AgentItem>(_trashMobs.Select(x => x.AgentItem)); }