internal override FightData.EncounterMode GetEncounterMode(CombatData combatData, AgentData agentData, FightData fightData) { AbstractSingleActor target = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.Adina); if (target == null) { throw new MissingKeyActorsException("Adina not found"); } return((target.GetHealth(combatData) > 23e6) ? FightData.EncounterMode.CM : FightData.EncounterMode.Normal); }
protected override void SetSuccessByDeath(CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents, bool all) { SetSuccessByDeath(combatData, fightData, playerAgents, all, (int)ParseEnum.TargetID.ClawOfTheFallen, (int)ParseEnum.TargetID.VoiceOfTheFallen); }
internal override FightData.CMStatus IsCM(CombatData combatData, AgentData agentData, FightData fightData) { var necrosis = combatData.GetBuffData(47414).Where(x => x is BuffApplyEvent).ToList(); if (necrosis.Count == 0) { return(0); } // split necrosis var splitNecrosis = new Dictionary <AgentItem, List <AbstractBuffEvent> >(); foreach (AbstractBuffEvent c in necrosis) { AgentItem tank = c.To; if (!splitNecrosis.ContainsKey(tank)) { splitNecrosis.Add(tank, new List <AbstractBuffEvent>()); } splitNecrosis[tank].Add(c); } List <AbstractBuffEvent> longestNecrosis = splitNecrosis.Values.First(l => l.Count == splitNecrosis.Values.Max(x => x.Count)); long minDiff = long.MaxValue; for (int i = 0; i < longestNecrosis.Count - 1; i++) { AbstractBuffEvent cur = longestNecrosis[i]; AbstractBuffEvent next = longestNecrosis[i + 1]; long timeDiff = next.Time - cur.Time; if (timeDiff > 1000 && minDiff > timeDiff) { minDiff = timeDiff; } } return((minDiff < 11000) ? FightData.CMStatus.CM : FightData.CMStatus.NoCM); }
internal override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { return(GetFightOffsetByFirstInvulFilter(fightData, agentData, combatData, (int)ArcDPSEnums.TargetID.Ensolyss, 762, 1500)); }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { HashSet <int> raidRewardsTypes = new HashSet <int> { 55821, 60685, 914, 22797 }; List <RewardEvent> rewards = combatData.GetRewardEvents(); RewardEvent reward = rewards.FirstOrDefault(x => raidRewardsTypes.Contains(x.RewardType)); if (reward != null) { fightData.SetSuccess(true, fightData.ToLogSpace(reward.Time)); } else { switch (GenericFallBackMethod) { case FallBackMethod.Death: SetSuccessByDeath(combatData, fightData, playerAgents, true, GetSuccessCheckIds()); break; case FallBackMethod.CombatExit: SetSuccessByCombatExit(new HashSet <ushort>(GetSuccessCheckIds()), combatData, fightData, playerAgents); break; default: break; } } }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { Target mainTarget = Targets.Find(x => x.ID == TriggerID); if (mainTarget == null) { throw new InvalidOperationException("Main target of the fight not found"); } AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(mainTarget.AgentItem).LastOrDefault(x => x.Damage > 0); long fightEndLogTime = fightData.FightEndLogTime; bool success = false; if (lastDamageTaken != null) { fightEndLogTime = fightData.ToLogSpace(lastDamageTaken.Time); } List <HealthUpdateEvent> hpUpdates = combatData.GetHealthUpdateEvents(mainTarget.AgentItem); if (hpUpdates.Count > 0) { success = hpUpdates.Last().HPPercent < 2.00; } fightData.SetSuccess(success, fightEndLogTime); }
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 virtual FightData.CMStatus IsCM(CombatData combatData, AgentData agentData, FightData fightData) { return(FightData.CMStatus.NoCM); }
protected static void SetSuccessByCombatExit(List <NPC> targets, CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents) { if (targets.Count == 0) { return; } var targetExits = new List <ExitCombatEvent>(); var lastTargetDamages = new List <AbstractHealthDamageEvent>(); foreach (NPC t in targets) { EnterCombatEvent enterCombat = combatData.GetEnterCombatEvents(t.AgentItem).LastOrDefault(); if (enterCombat != null) { targetExits.AddRange(combatData.GetExitCombatEvents(t.AgentItem).Where(x => x.Time > enterCombat.Time)); } else { targetExits.AddRange(combatData.GetExitCombatEvents(t.AgentItem)); } AbstractHealthDamageEvent lastDamage = combatData.GetDamageTakenData(t.AgentItem).LastOrDefault(x => (x.HealthDamage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamage != null) { lastTargetDamages.Add(lastDamage); } } ExitCombatEvent lastTargetExit = targetExits.Count > 0 ? targetExits.MaxBy(x => x.Time) : null; AbstractHealthDamageEvent lastDamageTaken = lastTargetDamages.Count > 0 ? lastTargetDamages.MaxBy(x => x.Time) : null; // Make sure the last damage has been done before last combat exit if (lastTargetExit != null && lastDamageTaken != null && lastTargetExit.Time + 100 >= lastDamageTaken.Time) { if (!AtLeastOnePlayerAlive(combatData, fightData, lastTargetExit.Time, playerAgents)) { return; } fightData.SetSuccess(true, lastDamageTaken.Time); } }
protected void SetSuccessByCombatExit(HashSet <int> targetIds, CombatData combatData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { var targets = Targets.Where(x => targetIds.Contains(x.ID)).ToList(); SetSuccessByCombatExit(targets, combatData, fightData, playerAgents); }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { var raidRewardsTypes = new HashSet <int>(); ulong build = combatData.GetBuildEvent().Build; if (build < 97235) { raidRewardsTypes = new HashSet <int> { // Old types, on each kill 55821, 60685 }; } else { raidRewardsTypes = new HashSet <int> { // New types, once per week 22797 }; } IReadOnlyList <RewardEvent> rewards = combatData.GetRewardEvents(); RewardEvent reward = rewards.FirstOrDefault(x => raidRewardsTypes.Contains(x.RewardType)); if (reward != null) { fightData.SetSuccess(true, reward.Time); } else { switch (GenericFallBackMethod) { case FallBackMethod.Death: SetSuccessByDeath(combatData, fightData, playerAgents, true, GetSuccessCheckIds()); break; case FallBackMethod.CombatExit: SetSuccessByDeath(combatData, fightData, playerAgents, true, GetSuccessCheckIds()); if (!fightData.Success) { SetSuccessByCombatExit(new HashSet <int>(GetSuccessCheckIds()), combatData, fightData, playerAgents); } break; default: break; } } }
public override int IsCM(CombatData combatData, AgentData agentData, FightData fightData) { return(2); }
public override long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { return(GetFightOffsetByFirstInvulFilter(fightData, agentData, combatData, (int)ParseEnum.TargetIDS.MAMA, 762, 1500)); }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { SetSuccessByBuffCount(combatData, fightData, playerAgents, Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.Artsariiv), 762, 4); }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { // check reward NPC mainTarget = Targets.Find(x => x.ID == GenericTriggerID); if (mainTarget == null) { throw new InvalidOperationException("Error Encountered: Main target of the fight not found"); } RewardEvent reward = combatData.GetRewardEvents().LastOrDefault(); AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(mainTarget.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTaken != null) { if (reward != null && lastDamageTaken.Time - reward.Time < 100) { fightData.SetSuccess(true, Math.Min(lastDamageTaken.Time, reward.Time)); } else { SetSuccessByDeath(combatData, fightData, playerAgents, true, GenericTriggerID); if (fightData.Success) { fightData.SetSuccess(true, Math.Min(fightData.FightEnd, lastDamageTaken.Time)); } } } }
internal virtual void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { SetSuccessByDeath(combatData, fightData, playerAgents, true, GenericTriggerID); }
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.SrcInstid = target.InstID; c.SrcAgent = target.Agent; } if (agents.Contains(c.DstAgent)) { c.DstInstid = target.InstID; c.DstAgent = target.Agent; } } break; } } }
internal virtual long GetFightOffset(FightData fightData, AgentData agentData, List <CombatItem> combatData) { return(fightData.LogStart); }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, List <AbstractSingleActor> friendlies, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { // has breakbar state into if (combatData.Any(x => x.IsStateChange == ArcDPSEnums.StateChange.BreakbarState)) { long sacrificeID = 34442; var sacrificeList = combatData.Where(x => x.SkillID == sacrificeID && !x.IsExtension && (x.IsBuffRemove == ArcDPSEnums.BuffRemove.All || x.IsBuffApply())).ToList(); var sacrificeStartList = sacrificeList.Where(x => x.IsBuffRemove == ArcDPSEnums.BuffRemove.None).ToList(); var sacrificeEndList = sacrificeList.Where(x => x.IsBuffRemove == ArcDPSEnums.BuffRemove.All).ToList(); var copies = new List <CombatItem>(); for (int i = 0; i < sacrificeStartList.Count; i++) { // long sacrificeStartTime = sacrificeStartList[i].Time; long sacrificeEndTime = i < sacrificeEndList.Count ? sacrificeEndList[i].Time : fightData.FightEnd; // Player sacrifice = friendlies.OfType <Player>().FirstOrDefault(x => x.AgentItem == agentData.GetAgent(sacrificeStartList[i].DstAgent, sacrificeStartList[i].Time)); if (sacrifice == null) { continue; } AgentItem sacrificeCrystal = agentData.AddCustomAgent(sacrificeStartTime, sacrificeEndTime + 100, AgentItem.AgentType.NPC, "Sacrificed " + (i + 1) + " " + sacrifice.Character, sacrifice.Spec, (int)ArcDPSEnums.TrashID.MatthiasSacrificeCrystal, false); foreach (CombatItem cbt in combatData) { if (!sacrificeCrystal.InAwareTimes(cbt.Time)) { continue; } bool skip = !(cbt.DstMatchesAgent(sacrifice.AgentItem, extensions) || cbt.SrcMatchesAgent(sacrifice.AgentItem, extensions)); if (skip) { continue; } // redirect damage events if (cbt.IsDamage(extensions)) { // only redirect incoming damage if (cbt.DstMatchesAgent(sacrifice.AgentItem, extensions)) { cbt.OverrideDstAgent(sacrificeCrystal.Agent); } } // copy the rest else { var copy = new CombatItem(cbt); if (copy.DstMatchesAgent(sacrifice.AgentItem, extensions)) { copy.OverrideDstAgent(sacrificeCrystal.Agent); } if (copy.SrcMatchesAgent(sacrifice.AgentItem, extensions)) { copy.OverrideSrcAgent(sacrificeCrystal.Agent); } copies.Add(copy); } } } if (copies.Any()) { combatData.AddRange(copies); } } ComputeFightTargets(agentData, combatData, extensions); foreach (AbstractSingleActor target in Targets) { if (target.ID == (int)ArcDPSEnums.TrashID.MatthiasSacrificeCrystal) { target.SetManualHealth(100000); } } }
internal virtual void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { ComputeFightTargets(agentData, combatData); }
public virtual void SpecialParse(FightData fightData, AgentData agentData, List <CombatItem> combatData) { }
protected virtual void SetSuccessByDeath(CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents, bool all) { SetSuccessByDeath(combatData, fightData, playerAgents, all, GenericTriggerID); }
internal override FightData.CMStatus IsCM(CombatData combatData, AgentData agentData, FightData fightData) { return(FightData.CMStatus.CMnoName); }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { var strikeRewardIDs = new HashSet <ulong> { 993 }; IReadOnlyList <RewardEvent> rewards = combatData.GetRewardEvents(); RewardEvent reward = rewards.FirstOrDefault(x => strikeRewardIDs.Contains(x.RewardID)); if (reward != null) { fightData.SetSuccess(true, reward.Time); } else { SetSuccessByDeath(combatData, fightData, playerAgents, true); } }
internal override FightData.CMStatus IsCM(CombatData combatData, AgentData agentData, FightData fightData) { NPC target = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.Dhuum); if (target == null) { throw new MissingKeyActorsException("Dhuum not found"); } return((target.GetHealth(combatData) > 35e6) ? FightData.CMStatus.CM : FightData.CMStatus.NoCM); }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { SetSuccessByDeath(combatData, fightData, playerAgents, true, TriggerID); }
public override FightData.CMStatus IsCM(CombatData combatData, AgentData agentData, FightData fightData) { NPC target = Targets.Find(x => x.ID == (int)ParseEnum.TargetID.Nikare); if (target == null) { throw new InvalidOperationException("Nikare not found"); } return((target.GetHealth(combatData) > 18e6) ? FightData.CMStatus.CM : FightData.CMStatus.NoCM); //Health of Nikare }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { SetSuccessByDeath(combatData, fightData, playerAgents, true, (int)ArcDPSEnums.TargetID.SoulEater); }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { NPC mainTarget = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.SoullessHorror); if (mainTarget == null) { throw new MissingKeyActorsException("Soulless Horror not found"); } AbstractBuffEvent buffOnDeath = combatData.GetBuffData(895).Where(x => x.To == mainTarget.AgentItem && x is BuffApplyEvent).LastOrDefault(); if (buffOnDeath != null) { fightData.SetSuccess(true, buffOnDeath.Time); } } }
internal override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { // First check using hp, best HPCheck(combatData, fightData); // hp could be unreliable or missing, fall back (around 200 ms more) if (!fightData.Success) { SetSuccessByDeath(combatData, fightData, playerAgents, false, (int)ArcDPSEnums.TargetID.EyeOfFate, (int)ArcDPSEnums.TargetID.EyeOfJudgement); } }