public BoonSimulationItemWasted(AgentItem src, long waste, long time) : base(src, waste, time) { }
internal AgentItem TryFindSrc(AgentItem dst, long time, long extension, ParsedEvtcLog log, long buffID) { return(_buffSourceFinder.TryFindSrc(dst, time, extension, log, buffID)); }
internal DeathRecap(IReadOnlyList <AbstractHealthDamageEvent> damageLogs, DeadEvent dead, IReadOnlyList <DownEvent> downs, IReadOnlyList <AliveEvent> ups, long lastDeathTime) { DeathTime = dead.Time; DownEvent downed; AliveEvent upped = ups.LastOrDefault(x => x.Time <= dead.Time && x.Time >= lastDeathTime); if (upped != null) { downed = downs.LastOrDefault(x => x.Time <= dead.Time && x.Time >= upped.Time); } else { downed = downs.LastOrDefault(x => x.Time <= dead.Time && x.Time >= lastDeathTime); } if (downed != null) { var damageToDown = damageLogs.Where(x => x.Time > lastDeathTime && x.Time <= downed.Time && x.HasHit && x.HealthDamage > 0).ToList(); ToDown = damageToDown.Count > 0 ? new List <DeathRecapDamageItem>() : null; int damage = 0; for (int i = damageToDown.Count - 1; i >= 0; i--) { AbstractHealthDamageEvent dl = damageToDown[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectHealthDamageEvent, ID = dl.SkillId, Damage = dl.HealthDamage, Src = ag != null?ag.Name.Replace("\u0000", "").Split(':')[0] : "" }; damage += dl.HealthDamage; ToDown.Add(item); if (damage > 20000) { break; } } var damageToKill = damageLogs.Where(x => x.Time > downed.Time && x.Time <= dead.Time && x.HasHit && x.HealthDamage > 0).ToList(); ToKill = damageToKill.Count > 0 ? new List <DeathRecapDamageItem>() : null; for (int i = damageToKill.Count - 1; i >= 0; i--) { AbstractHealthDamageEvent dl = damageToKill[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectHealthDamageEvent, ID = dl.SkillId, Damage = dl.HealthDamage, Src = ag != null?ag.Name.Replace("\u0000", "").Split(':')[0] : "" }; ToKill.Add(item); } } else { ToDown = null; var damageToKill = damageLogs.Where(x => x.Time > lastDeathTime && x.Time <= dead.Time && x.HasHit && x.HealthDamage > 0).ToList(); ToKill = damageToKill.Count > 0 ? new List <DeathRecapDamageItem>() : null; int damage = 0; for (int i = damageToKill.Count - 1; i >= 0; i--) { AbstractHealthDamageEvent dl = damageToKill[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectHealthDamageEvent, ID = dl.SkillId, Damage = dl.HealthDamage, Src = ag != null?ag.Name.Replace("\u0000", "").Split(':')[0] : "" }; damage += dl.HealthDamage; ToKill.Add(item); if (damage > 20000) { break; } } } }
public override void Remove(AgentItem by, long removedDuration, int removedStacks, long time, ArcDPSEnums.BuffRemove removeType, uint stackID) { BuffStackItemID toRemove; switch (removeType) { case ArcDPSEnums.BuffRemove.All: // remove all due to despawn event if (removedStacks == BuffRemoveAllEvent.FullRemoval) { BuffStack.Clear(); return; } if (BuffStack.Count != 1) { if (BuffStack.Count < removedStacks) { throw new EIBuffSimulatorIDException("Remove all failed"); } // buff cleanse all for (int i = 0; i < BuffStack.Count; i++) { BuffStackItem stackItem = BuffStack[i]; WasteSimulationResult.Add(new BuffSimulationItemWasted(stackItem.Src, stackItem.Duration, time)); if (stackItem.Extensions.Any()) { foreach ((AgentItem src, long value) in stackItem.Extensions) { WasteSimulationResult.Add(new BuffSimulationItemWasted(src, value, time)); } } } BuffStack.Clear(); return; } toRemove = BuffStack[0]; break; case ArcDPSEnums.BuffRemove.Single: toRemove = BuffStack.FirstOrDefault(x => x.StackID == stackID); break; default: throw new InvalidDataException("Unknown remove type"); } if (toRemove == null) { throw new EIBuffSimulatorIDException("Remove has failed"); } BuffStack.Remove(toRemove); if (removedDuration > ParserHelper.BuffSimulatorDelayConstant) { // safe checking, this can happen when an inactive stack is being removed but it was actually active if (Math.Abs(removedDuration - toRemove.TotalDuration) > ParserHelper.BuffSimulatorDelayConstant && !toRemove.Active) { toRemove.Activate(); toRemove.Shift(0, Math.Abs(removedDuration - toRemove.TotalDuration)); } // Removed due to override if (by == ParserHelper._unknownAgent) { WasteSimulationResult.Add(new BuffSimulationItemWasted(toRemove.Src, toRemove.Duration, time)); if (toRemove.Extensions.Any()) { foreach ((AgentItem src, long value) in toRemove.Extensions) { WasteSimulationResult.Add(new BuffSimulationItemWasted(src, value, time)); } } } // Removed due to a cleanse else { WasteSimulationResult.Add(new BuffSimulationItemWasted(toRemove.Src, toRemove.Duration, time)); if (toRemove.Extensions.Any()) { foreach ((AgentItem src, long value) in toRemove.Extensions) { WasteSimulationResult.Add(new BuffSimulationItemWasted(src, value, time)); } } } } }
internal override void EIEvtcParse(FightData fightData, AgentData agentData, List <CombatItem> combatData, List <Player> playerList) { // 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.IsBuffRemove == ArcDPSEnums.BuffRemove.All && x.IsBuff != 0) || (x.IsBuff != 0 && x.BuffDmg == 0 && x.Value > 0 && x.IsStateChange == ArcDPSEnums.StateChange.None && x.IsActivation == ArcDPSEnums.Activation.None && x.IsBuffRemove == ArcDPSEnums.BuffRemove.None))).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 = playerList.FirstOrDefault(x => x.AgentItem == agentData.GetAgent(sacrificeStartList[i].DstAgent)); if (sacrifice == null) { continue; } AgentItem sacrificeCrystal = agentData.AddCustomAgent(sacrificeStartTime, sacrificeEndTime + 100, AgentItem.AgentType.NPC, "Sacrificed " + (i + 1) + " " + sacrifice.Character, sacrifice.Prof, (int)ArcDPSEnums.TrashID.MatthiasSacrificeCrystal); foreach (CombatItem cbt in combatData) { if (!sacrificeCrystal.InAwareTimes(cbt.Time)) { continue; } bool skip = !((cbt.IsStateChange.DstIsAgent() && cbt.DstAgent == sacrifice.Agent) || (cbt.IsStateChange.SrcIsAgent() && cbt.SrcAgent == sacrifice.Agent)); if (skip) { continue; } bool isDamageEvent = cbt.IsStateChange == ArcDPSEnums.StateChange.None && cbt.IsActivation == ArcDPSEnums.Activation.None && cbt.IsBuffRemove == ArcDPSEnums.BuffRemove.None && ((cbt.IsBuff != 0 && cbt.Value == 0) || (cbt.IsBuff == 0)); // redirect damage events if (isDamageEvent) { // only redirect incoming damage if (cbt.DstAgent == sacrifice.Agent) { cbt.OverrideDstAgent(sacrificeCrystal.Agent); } } // copy the rest else { var copy = new CombatItem(cbt); if (cbt.IsStateChange.DstIsAgent() && cbt.DstAgent == sacrifice.Agent) { cbt.OverrideDstAgent(sacrificeCrystal.Agent); } if (cbt.IsStateChange.SrcIsAgent() && cbt.SrcAgent == sacrifice.Agent) { cbt.OverrideSrcAgent(sacrificeCrystal.Agent); } copies.Add(copy); } } } if (copies.Any()) { combatData.AddRange(copies); combatData.Sort((x, y) => x.Time.CompareTo(y.Time)); } } ComputeFightTargets(agentData, combatData); foreach (NPC target in Targets) { if (target.ID == (int)ArcDPSEnums.TrashID.MatthiasSacrificeCrystal) { target.SetManualHealth(100000); } } }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { // has breakbar state into if (combatData.Any(x => x.IsStateChange == ArcDPSEnums.StateChange.BreakbarState)) { var sacrificeList = combatData.Where(x => x.SkillID == MatthiasSacrifice && !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; // AgentItem sacrifice = agentData.GetAgentByType(AgentItem.AgentType.Player).FirstOrDefault(x => x == agentData.GetAgent(sacrificeStartList[i].DstAgent, sacrificeStartList[i].Time)); if (sacrifice == null) { continue; } AgentItem sacrificeCrystal = agentData.AddCustomNPCAgent(sacrificeStartTime, sacrificeEndTime + 100, "Sacrificed " + (i + 1) + " " + sacrifice.Name.Split('\0')[0], sacrifice.Spec, (int)ArcDPSEnums.TrashID.MatthiasSacrificeCrystal, false); foreach (CombatItem cbt in combatData) { if (!sacrificeCrystal.InAwareTimes(cbt.Time)) { continue; } bool skip = !(cbt.DstMatchesAgent(sacrifice, extensions) || cbt.SrcMatchesAgent(sacrifice, extensions)); if (skip) { continue; } // redirect damage events if (cbt.IsDamage(extensions)) { // only redirect incoming damage if (cbt.DstMatchesAgent(sacrifice, extensions)) { cbt.OverrideDstAgent(sacrificeCrystal.Agent); } } // copy the rest else { var copy = new CombatItem(cbt); if (copy.DstMatchesAgent(sacrifice, extensions)) { copy.OverrideDstAgent(sacrificeCrystal.Agent); } if (copy.SrcMatchesAgent(sacrifice, 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); } } }
public BuffRemoveManualEvent(AgentItem by, AgentItem to, long time, int removedDuration, SkillItem buffSkill) : base(by, to, time, removedDuration, buffSkill) { }
public BuffSimulationItemDuration(BuffStackItem other) : base(other.Start, other.Duration) { _src = other.Src; _seedSrc = other.SeedSrc; _isExtension = other.IsExtension; }
public override void SetBuffDistributionItem(BuffDistribution distribs, long start, long end, long boonid, ParsedLog log) { Dictionary <AgentItem, BuffDistributionItem> distrib = GetDistrib(distribs, boonid); long cDur = GetClampedDuration(start, end); AgentItem agent = _src; AgentItem seedAgent = _seedSrc; if (distrib.TryGetValue(agent, out BuffDistributionItem toModify)) { toModify.Value += cDur; distrib[agent] = toModify; } else { distrib.Add(agent, new BuffDistributionItem( cDur, 0, 0, 0, 0, 0)); } if (_isExtension) { if (distrib.TryGetValue(agent, out toModify)) { toModify.Extension += cDur; distrib[agent] = toModify; } else { distrib.Add(agent, new BuffDistributionItem( 0, 0, 0, 0, cDur, 0)); } } if (agent != seedAgent) { if (distrib.TryGetValue(seedAgent, out toModify)) { toModify.Extended += cDur; distrib[seedAgent] = toModify; } else { distrib.Add(seedAgent, new BuffDistributionItem( 0, 0, 0, 0, 0, cDur)); } } if (agent == GeneralHelper.UnknownAgent) { if (distrib.TryGetValue(seedAgent, out toModify)) { toModify.UnknownExtension += cDur; distrib[seedAgent] = toModify; } else { distrib.Add(seedAgent, new BuffDistributionItem( 0, 0, 0, cDur, 0, 0)); } } }
public BoonSimulationItemOverstack(AgentItem src, long overstack, long time) : base(src, overstack, time) { }
internal AttackTargetEvent(CombatItem evtcItem, AgentData agentData) : base(evtcItem, agentData) { AttackTarget = Src; Src = agentData.GetAgent(evtcItem.DstAgent); }
public static List <AbstractBuffEvent> TransformWeaverAttunements(IReadOnlyList <AbstractBuffEvent> buffs, Dictionary <long, List <AbstractBuffEvent> > buffsByID, AgentItem a, SkillData skillData) { var res = new List <AbstractBuffEvent>(); var attunements = new HashSet <long> { 5585, 5586, 5575, 5580 }; // not useful for us /*const long fireAir = 45162; * const long fireEarth = 42756; * const long fireWater = 45502; * const long waterAir = 46418; * const long waterEarth = 42792; * const long airEarth = 45683;*/ var weaverAttunements = new HashSet <long> { FireMajor, FireMinor, WaterMajor, WaterMinor, AirMajor, AirMinor, EarthMajor, EarthMinor, FireDual, WaterDual, AirDual, EarthDual, /*fireAir, * fireEarth, * fireWater, * waterAir, * waterEarth, * airEarth,*/ }; // first we get rid of standard attunements var toClean = new HashSet <long>(); var attuns = buffs.Where(x => attunements.Contains(x.BuffID)).ToList(); foreach (AbstractBuffEvent c in attuns) { toClean.Add(c.BuffID); c.Invalidate(skillData); } // get all weaver attunements ids and group them by time var weaverAttuns = buffs.Where(x => weaverAttunements.Contains(x.BuffID)).ToList(); if (weaverAttuns.Count == 0) { return(res); } var groupByTime = new Dictionary <long, List <AbstractBuffEvent> >(); foreach (AbstractBuffEvent c in weaverAttuns) { long key = groupByTime.Keys.FirstOrDefault(x => Math.Abs(x - c.Time) < ParserHelper.ServerDelayConstant); if (key != 0) { groupByTime[key].Add(c); } else { groupByTime[c.Time] = new List <AbstractBuffEvent> { c }; } } long prevID = 0; foreach (KeyValuePair <long, List <AbstractBuffEvent> > pair in groupByTime) { var applies = pair.Value.OfType <BuffApplyEvent>().ToList(); long curID = TranslateWeaverAttunement(applies); foreach (AbstractBuffEvent c in pair.Value) { toClean.Add(c.BuffID); c.Invalidate(skillData); } if (curID == 0) { continue; } uint curInstanceID = applies.First().BuffInstance; res.Add(new BuffApplyEvent(a, a, pair.Key, int.MaxValue, skillData.Get(curID), curInstanceID, true)); if (prevID != 0) { res.Add(new BuffRemoveManualEvent(a, a, pair.Key, int.MaxValue, skillData.Get(prevID))); res.Add(new BuffRemoveAllEvent(a, a, pair.Key, int.MaxValue, skillData.Get(prevID), 1, int.MaxValue)); } prevID = curID; } foreach (long buffID in toClean) { buffsByID[buffID].RemoveAll(x => x.BuffID == NoBuff); } return(res); }
public AttackTargetEvent(CombatItem evtcItem, AgentData agentData, long offset) : base(evtcItem, agentData, offset) { AttackTarget = agentData.GetAgent(evtcItem.SrcAgent, evtcItem.LogTime); Src = agentData.GetAgent(evtcItem.DstAgent, evtcItem.LogTime); }
internal static bool IsClone(AgentItem agentItem) { return(_cloneIDs.Contains(agentItem.ID)); }
public AbstractStatusEvent(AgentItem src, long time) : base(time) { Src = src; }
internal override void EIEvtcParse(ulong gw2Build, FightData fightData, AgentData agentData, List <CombatItem> combatData, 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); } }
public AbstractStatusEvent(CombatItem evtcItem, AgentData agentData) : base(evtcItem.Time) { Src = agentData.GetAgent(evtcItem.SrcAgent); }
protected AbstractActor(AgentItem agent) { string[] name = agent.Name.Split('\0'); Character = name[0]; AgentItem = agent; }
public DeadEvent(AgentItem src, long time) : base(src, time) { }
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"); } if (!target.Character.Contains("Deimos")) { target.OverrideName("Deimos"); } // enter combat CombatItem enterCombat = combatData.FirstOrDefault(x => x.SrcInstid == target.InstID && x.IsStateChange == ParseEnum.StateChange.EnterCombat); if (enterCombat != null) { fightData.FightStart = enterCombat.Time; } // Remove deimos despawn events as they are useless and mess with combat replay combatData.RemoveAll(x => x.IsStateChange == ParseEnum.StateChange.Despawn && x.SrcInstid == target.InstID && x.Time <= target.LastAware && x.Time >= target.FirstAware); // Deimos gadgets List <AgentItem> deimosGadgets = agentData.GetAgentByType(AgentItem.AgentType.Gadget).Where(x => x.Name.Contains("Deimos") && x.LastAware > target.LastAware).ToList(); CombatItem invulApp = combatData.FirstOrDefault(x => x.DstInstid == target.InstID && x.IsBuff != 0 && x.BuffDmg == 0 && x.Value > 0 && x.SkillID == 762); CombatItem targetable = combatData.LastOrDefault(x => x.IsStateChange == ParseEnum.StateChange.Targetable && x.Time > combatData.First().Time&& x.DstAgent > 0); if (invulApp != null && targetable != null) { HashSet <ulong> gadgetAgents = new HashSet <ulong>(); long firstAware = targetable.Time; AgentItem targetAgent = agentData.GetAgentByInstID(targetable.SrcInstid, targetable.Time); if (targetAgent != GeneralHelper.UnknownAgent) { try { string[] names = targetAgent.Name.Split('-'); if (ushort.TryParse(names[2], out ushort masterInstid)) { CombatItem structDeimosDamageEvent = combatData.FirstOrDefault(x => x.Time >= firstAware && x.IFF == ParseEnum.IFF.Foe && x.DstInstid == masterInstid && x.IsStateChange == ParseEnum.StateChange.Normal && x.IsBuffRemove == ParseEnum.BuffRemove.None && ((x.IsBuff == 1 && x.BuffDmg >= 0 && x.Value == 0) || (x.IsBuff == 0 && x.Value >= 0))); if (structDeimosDamageEvent != null) { gadgetAgents.Add(structDeimosDamageEvent.DstAgent); } CombatItem armDeimosDamageEvent = combatData.FirstOrDefault(x => x.Time >= firstAware && (x.SkillID == 37980 || x.SkillID == 37982 || x.SkillID == 38046) && x.SrcAgent != 0 && x.SrcInstid != 0); if (armDeimosDamageEvent != null) { gadgetAgents.Add(armDeimosDamageEvent.SrcAgent); } } ; } catch { // nothing to do } } invulApp.OverrideValue((int)(firstAware - invulApp.Time)); _specialSplit = (firstAware >= target.LastAware ? firstAware : target.LastAware); target.AgentItem.LastAware = combatData.Last().Time; SetUniqueID(target, gadgetAgents, agentData, combatData); } // legacy method else if (deimosGadgets.Count > 0) { long firstAware = deimosGadgets.Max(x => x.FirstAware); _specialSplit = (firstAware >= target.LastAware ? firstAware : target.LastAware); target.AgentItem.LastAware = deimosGadgets.Max(x => x.LastAware); HashSet <ulong> gadgetAgents = new HashSet <ulong>(deimosGadgets.Select(x => x.Agent)); SetUniqueID(target, gadgetAgents, agentData, combatData); } }
public BuffStackItemID(long start, long boonDuration, AgentItem src, bool active, long stackID) : base(start, boonDuration, src) { Active = active; StackID = stackID; }
internal static bool IsKnownMinionID(AgentItem minion, Spec spec) { if (minion.Type == AgentItem.AgentType.Gadget) { return(false); } long id = minion.ID; bool res = CommonMinions.Contains(id); switch (spec) { // case Spec.Elementalist: case Spec.Tempest: case Spec.Weaver: case Spec.Catalyst: res |= ElementalistHelper.IsKnownMinionID(id); break; // case Spec.Necromancer: case Spec.Scourge: case Spec.Harbinger: res |= NecromancerHelper.IsKnownMinionID(id); break; case Spec.Reaper: res |= NecromancerHelper.IsKnownMinionID(id); res |= ReaperHelper.IsKnownMinionID(id); break; // case Spec.Mesmer: res |= MesmerHelper.IsKnownMinionID(id); break; case Spec.Chronomancer: res |= MesmerHelper.IsKnownMinionID(id); res |= ChronomancerHelper.IsKnownMinionID(id); break; case Spec.Mirage: res |= MesmerHelper.IsKnownMinionID(id); res |= MirageHelper.IsKnownMinionID(id); break; case Spec.Virtuoso: res |= MesmerHelper.IsKnownMinionID(id); res |= VirtuosoHelper.IsKnownMinionID(id); break; // case Spec.Thief: res |= ThiefHelper.IsKnownMinionID(id); break; case Spec.Daredevil: res |= ThiefHelper.IsKnownMinionID(id); res |= DaredevilHelper.IsKnownMinionID(id); break; case Spec.Deadeye: res |= ThiefHelper.IsKnownMinionID(id); res |= DeadeyeHelper.IsKnownMinionID(id); break; case Spec.Specter: res |= ThiefHelper.IsKnownMinionID(id); res |= SpecterHelper.IsKnownMinionID(id); break; // case Spec.Engineer: case Spec.Scrapper: case Spec.Holosmith: res |= EngineerHelper.IsKnownMinionID(id); break; case Spec.Mechanist: res |= EngineerHelper.IsKnownMinionID(id); res |= MechanistHelper.IsKnownMinionID(id); break; // case Spec.Ranger: case Spec.Druid: case Spec.Soulbeast: case Spec.Untamed: res |= RangerHelper.IsKnownMinionID(id); break; // case Spec.Revenant: case Spec.Herald: case Spec.Vindicator: res |= RevenantHelper.IsKnownMinionID(id); break; case Spec.Renegade: res |= RevenantHelper.IsKnownMinionID(id); res |= RenegadeHelper.IsKnownMinionID(id); break; // case Spec.Guardian: case Spec.Dragonhunter: case Spec.Firebrand: case Spec.Willbender: res |= GuardianHelper.IsKnownMinionID(id); break; } return(res); }
internal static Dictionary <long, FinalActorBuffs>[] GetBuffsForPlayers(List <Player> playerList, ParsedEvtcLog log, AgentItem agentItem, long start, long end) { long phaseDuration = end - start; var buffDistribution = new Dictionary <Player, BuffDistribution>(); foreach (Player p in playerList) { buffDistribution[p] = p.GetBuffDistribution(log, start, end); } var buffsToTrack = new HashSet <Buff>(buffDistribution.SelectMany(x => x.Value.BuffIDs).Select(x => log.Buffs.BuffsByIds[x])); var buffs = new Dictionary <long, FinalActorBuffs>(); var activeBuffs = new Dictionary <long, FinalActorBuffs>(); foreach (Buff boon in buffsToTrack) { double totalGeneration = 0; double totalOverstack = 0; double totalWasted = 0; double totalUnknownExtension = 0; double totalExtension = 0; double totalExtended = 0; // double totalActiveGeneration = 0; double totalActiveOverstack = 0; double totalActiveWasted = 0; double totalActiveUnknownExtension = 0; double totalActiveExtension = 0; double totalActiveExtended = 0; bool hasGeneration = false; int activePlayerCount = 0; foreach (KeyValuePair <Player, BuffDistribution> pair in buffDistribution) { BuffDistribution boons = pair.Value; long playerActiveDuration = pair.Key.GetActiveDuration(log, start, end); if (boons.HasBuffID(boon.ID)) { hasGeneration = hasGeneration || boons.HasSrc(boon.ID, agentItem); double generation = boons.GetGeneration(boon.ID, agentItem); double overstack = boons.GetOverstack(boon.ID, agentItem); double wasted = boons.GetWaste(boon.ID, agentItem); double unknownExtension = boons.GetUnknownExtension(boon.ID, agentItem); double extension = boons.GetExtension(boon.ID, agentItem); double extended = boons.GetExtended(boon.ID, agentItem); totalGeneration += generation; totalOverstack += overstack; totalWasted += wasted; totalUnknownExtension += unknownExtension; totalExtension += extension; totalExtended += extended; if (playerActiveDuration > 0) { activePlayerCount++; totalActiveGeneration += generation / playerActiveDuration; totalActiveOverstack += overstack / playerActiveDuration; totalActiveWasted += wasted / playerActiveDuration; totalActiveUnknownExtension += unknownExtension / playerActiveDuration; totalActiveExtension += extension / playerActiveDuration; totalActiveExtended += extended / playerActiveDuration; } } } totalGeneration /= phaseDuration; totalOverstack /= phaseDuration; totalWasted /= phaseDuration; totalUnknownExtension /= phaseDuration; totalExtension /= phaseDuration; totalExtended /= phaseDuration; if (hasGeneration) { var uptime = new FinalActorBuffs(); var uptimeActive = new FinalActorBuffs(); buffs[boon.ID] = uptime; activeBuffs[boon.ID] = uptimeActive; if (boon.Type == BuffType.Duration) { uptime.Generation = Math.Round(100.0 * totalGeneration / playerList.Count, ParserHelper.BuffDigit); uptime.Overstack = Math.Round(100.0 * (totalOverstack + totalGeneration) / playerList.Count, ParserHelper.BuffDigit); uptime.Wasted = Math.Round(100.0 * (totalWasted) / playerList.Count, ParserHelper.BuffDigit); uptime.UnknownExtended = Math.Round(100.0 * (totalUnknownExtension) / playerList.Count, ParserHelper.BuffDigit); uptime.ByExtension = Math.Round(100.0 * (totalExtension) / playerList.Count, ParserHelper.BuffDigit); uptime.Extended = Math.Round(100.0 * (totalExtended) / playerList.Count, ParserHelper.BuffDigit); // if (activePlayerCount > 0) { uptimeActive.Generation = Math.Round(100.0 * totalActiveGeneration / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.Overstack = Math.Round(100.0 * (totalActiveOverstack + totalActiveGeneration) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.Wasted = Math.Round(100.0 * (totalActiveWasted) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.UnknownExtended = Math.Round(100.0 * (totalActiveUnknownExtension) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.ByExtension = Math.Round(100.0 * (totalActiveExtension) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.Extended = Math.Round(100.0 * (totalActiveExtended) / activePlayerCount, ParserHelper.BuffDigit); } } else if (boon.Type == BuffType.Intensity) { uptime.Generation = Math.Round(totalGeneration / playerList.Count, ParserHelper.BuffDigit); uptime.Overstack = Math.Round((totalOverstack + totalGeneration) / playerList.Count, ParserHelper.BuffDigit); uptime.Wasted = Math.Round((totalWasted) / playerList.Count, ParserHelper.BuffDigit); uptime.UnknownExtended = Math.Round((totalUnknownExtension) / playerList.Count, ParserHelper.BuffDigit); uptime.ByExtension = Math.Round((totalExtension) / playerList.Count, ParserHelper.BuffDigit); uptime.Extended = Math.Round((totalExtended) / playerList.Count, ParserHelper.BuffDigit); // if (activePlayerCount > 0) { uptimeActive.Generation = Math.Round(totalActiveGeneration / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.Overstack = Math.Round((totalActiveOverstack + totalActiveGeneration) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.Wasted = Math.Round((totalActiveWasted) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.UnknownExtended = Math.Round((totalActiveUnknownExtension) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.ByExtension = Math.Round((totalActiveExtension) / activePlayerCount, ParserHelper.BuffDigit); uptimeActive.Extended = Math.Round((totalActiveExtended) / activePlayerCount, ParserHelper.BuffDigit); } } } } return(new Dictionary <long, FinalActorBuffs>[] { buffs, activeBuffs }); }
internal static void SetGadgetMaster(IReadOnlyCollection <AgentItem> gadgets, AgentItem master) { foreach (AgentItem gadget in gadgets) { gadget.SetMaster(master); } }
public bool HasSrc(long buffID, AgentItem src) { return(_distribution.ContainsKey(buffID) && _distribution[buffID].ContainsKey(src)); }
public TagEvent(CombatItem evtcItem, AgentData agentData) : base(evtcItem) { TagID = evtcItem.Value; Src = agentData.GetAgent(evtcItem.SrcAgent); Src.SetCommanderTag(this); }
protected static void TrimCombatReplay(ParsedEvtcLog log, CombatReplay replay, AgentItem agentItem) { // Trim DespawnEvent despawnCheck = log.CombatData.GetDespawnEvents(agentItem).LastOrDefault(); SpawnEvent spawnCheck = log.CombatData.GetSpawnEvents(agentItem).LastOrDefault(); DeadEvent deathCheck = log.CombatData.GetDeadEvents(agentItem).LastOrDefault(); AliveEvent aliveCheck = log.CombatData.GetAliveEvents(agentItem).LastOrDefault(); if (deathCheck != null && (aliveCheck == null || aliveCheck.Time < deathCheck.Time)) { replay.Trim(agentItem.FirstAware, deathCheck.Time); } else if (despawnCheck != null && (spawnCheck == null || spawnCheck.Time < despawnCheck.Time)) { replay.Trim(agentItem.FirstAware, despawnCheck.Time); } else { replay.Trim(agentItem.FirstAware, agentItem.LastAware); } }
public AbstractCastEvent(long time, SkillItem skill, AgentItem caster) : base(time, 0) { Skill = skill; Caster = caster; MasterCaster = null; }
internal AbstractCastEvent(long time, SkillItem skill, AgentItem caster) : base(time) { Skill = skill; Caster = caster; }
public static List <AbstractBuffEvent> TransformWeaverAttunements(List <AbstractBuffEvent> buffs, AgentItem a, SkillData skillData) { List <AbstractBuffEvent> res = new List <AbstractBuffEvent>(); HashSet <long> attunements = new HashSet <long> { 5585, 5586, 5575, 5580 }; // not useful for us /*const long fireAir = 45162; * const long fireEarth = 42756; * const long fireWater = 45502; * const long waterAir = 46418; * const long waterEarth = 42792; * const long airEarth = 45683;*/ HashSet <long> weaverAttunements = new HashSet <long> { _fireMajor, _fireMinor, _waterMajor, _waterMinor, _airMajor, _airMinor, _earthMajor, _earthMinor, FireDual, WaterDual, AirDual, EarthDual, /*fireAir, * fireEarth, * fireWater, * waterAir, * waterEarth, * airEarth,*/ }; // first we get rid of standard attunements List <AbstractBuffEvent> attuns = buffs.Where(x => attunements.Contains(x.BuffID)).ToList(); foreach (AbstractBuffEvent c in attuns) { c.Invalidate(skillData); } // get all weaver attunements ids and group them by time List <AbstractBuffEvent> weaverAttuns = buffs.Where(x => weaverAttunements.Contains(x.BuffID)).ToList(); if (weaverAttuns.Count == 0) { return(res); } Dictionary <long, List <AbstractBuffEvent> > groupByTime = new Dictionary <long, List <AbstractBuffEvent> >(); foreach (AbstractBuffEvent c in weaverAttuns) { long key = groupByTime.Keys.FirstOrDefault(x => Math.Abs(x - c.Time) < 10); if (key != 0) { groupByTime[key].Add(c); } else { groupByTime[c.Time] = new List <AbstractBuffEvent> { c }; } } long prevID = 0; foreach (var pair in groupByTime) { List <AbstractBuffEvent> applies = pair.Value.Where(x => x is BuffApplyEvent).ToList(); long curID = TranslateWeaverAttunement(applies); foreach (AbstractBuffEvent c in pair.Value) { c.Invalidate(skillData); } if (curID == 0) { continue; } res.Add(new BuffApplyEvent(a, a, pair.Key, int.MaxValue, skillData.Get(curID))); if (prevID != 0) { res.Add(new BuffRemoveManualEvent(a, a, pair.Key, int.MaxValue, skillData.Get(prevID))); res.Add(new BuffRemoveAllEvent(a, a, pair.Key, int.MaxValue, skillData.Get(prevID), int.MaxValue, 1)); } prevID = curID; } return(res); }