// protected static List <CombatItem> GetFilteredList(CombatData combatData, long skillID, AbstractMasterActor target, bool beginWithStart) { bool needStart = beginWithStart; List <CombatItem> main = combatData.GetBoonData(skillID).Where(x => ((x.DstInstid == target.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None) || (x.SrcInstid == target.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.Manual)) && x.Time >= target.FirstAware && x.Time <= target.LastAware).ToList(); List <CombatItem> filtered = new List <CombatItem>(); for (int i = 0; i < main.Count; i++) { CombatItem c = main[i]; if (needStart && c.IsBuffRemove == ParseEnum.BuffRemove.None) { needStart = false; filtered.Add(c); } else if (!needStart && c.IsBuffRemove == ParseEnum.BuffRemove.Manual) { // consider only last remove event before another application if ((i == main.Count - 1) || (i < main.Count - 1 && main[i + 1].IsBuffRemove == ParseEnum.BuffRemove.None)) { needStart = true; filtered.Add(c); } } } return(filtered); }
private void CalculateDefenses() { CombatData combatData = _log.CombatData; foreach (Player player in _log.PlayerList) { FinalDefenses[] phaseDefense = new FinalDefenses[_statistics.Phases.Count]; for (int phaseIndex = 0; phaseIndex < _statistics.Phases.Count; phaseIndex++) { FinalDefenses final = new FinalDefenses(); PhaseData phase = _statistics.Phases[phaseIndex]; long start = _log.FightData.ToLogSpace(phase.Start); long end = _log.FightData.ToLogSpace(phase.End); List <DamageLog> damageLogs = player.GetDamageTakenLogs(null, _log, phase.Start, phase.End); //List<DamageLog> healingLogs = player.getHealingReceivedLogs(log, phase.getStart(), phase.getEnd()); final.DamageTaken = damageLogs.Sum(x => (long)x.Damage); //final.allHealReceived = healingLogs.Sum(x => x.getDamage()); final.BlockedCount = damageLogs.Count(x => x.Result == ParseEnum.Result.Block); final.InvulnedCount = 0; final.DamageInvulned = 0; final.EvadedCount = damageLogs.Count(x => x.Result == ParseEnum.Result.Evade); final.DodgeCount = player.GetCastLogs(_log, 0, _log.FightData.FightDuration).Count(x => x.SkillId == SkillItem.DodgeId); final.DamageBarrier = damageLogs.Sum(x => x.ShieldDamage); final.InterruptedCount = damageLogs.Count(x => x.Result == ParseEnum.Result.Interrupt); foreach (DamageLog log in damageLogs.Where(x => x.Result == ParseEnum.Result.Absorb)) { final.InvulnedCount++; final.DamageInvulned += log.Damage; } List <CombatItem> deads = combatData.GetStatesData(player.InstID, ParseEnum.StateChange.ChangeDead, start, end); List <CombatItem> downs = combatData.GetStatesData(player.InstID, ParseEnum.StateChange.ChangeDown, start, end); List <CombatItem> dcs = combatData.GetStatesData(player.InstID, ParseEnum.StateChange.Despawn, start, end); final.DownCount = downs.Count - combatData.GetBoonData(5620).Where(x => x.SrcInstid == player.InstID && x.Time >= start && x.Time <= end && x.IsBuffRemove == ParseEnum.BuffRemove.All).Count(); final.DeadCount = deads.Count; final.DcCount = dcs.Count; phaseDefense[phaseIndex] = final; } List <(long start, long end)> dead = new List <(long start, long end)>(); List <(long start, long end)> down = new List <(long start, long end)>(); List <(long start, long end)> dc = new List <(long start, long end)>(); combatData.GetAgentStatus(player.FirstAware, player.LastAware, player.InstID, dead, down, dc); for (int phaseIndex = 0; phaseIndex < _statistics.Phases.Count; phaseIndex++) { FinalDefenses defenses = phaseDefense[phaseIndex]; PhaseData phase = _statistics.Phases[phaseIndex]; long start = phase.Start; long end = phase.End; defenses.DownDuration = (int)down.Where(x => x.end >= start && x.start <= end).Sum(x => Math.Min(end, x.end) - Math.Max(x.start, start)); defenses.DeadDuration = (int)dead.Where(x => x.end >= start && x.start <= end).Sum(x => Math.Min(end, x.end) - Math.Max(x.start, start)); defenses.DcDuration = (int)dc.Where(x => x.end >= start && x.start <= end).Sum(x => Math.Min(end, x.end) - Math.Max(x.start, start)); } _statistics.Defenses[player] = phaseDefense; } }
// protected static List <AbstractBuffEvent> GetFilteredList(CombatData combatData, long buffID, AbstractMasterActor target, bool beginWithStart) { bool needStart = beginWithStart; List <AbstractBuffEvent> main = combatData.GetBoonData(buffID).Where(x => x.To == target.AgentItem && (x is BuffApplyEvent || x is BuffRemoveAllEvent)).ToList(); List <AbstractBuffEvent> filtered = new List <AbstractBuffEvent>(); for (int i = 0; i < main.Count; i++) { AbstractBuffEvent c = main[i]; if (needStart && c is BuffApplyEvent) { needStart = false; filtered.Add(c); } else if (!needStart && c is BuffRemoveAllEvent) { // consider only last remove event before another application if ((i == main.Count - 1) || (i < main.Count - 1 && main[i + 1] is BuffApplyEvent)) { needStart = true; filtered.Add(c); } } } return(filtered); }
public override int IsCM(CombatData combatData, AgentData agentData, FightData fightData) { List <AbstractBuffEvent> necrosis = combatData.GetBoonData(47414).Where(x => x is BuffApplyEvent).ToList(); if (necrosis.Count == 0) { return(0); } // split necrosis Dictionary <AgentItem, List <AbstractBuffEvent> > 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) ? 1 : 0); }
public override int IsCM(CombatData combatData, AgentData agentData, FightData fightData) { Target target = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.ConjuredAmalgamate); if (target == null) { throw new InvalidOperationException("Target for CM detection not found"); } return(combatData.GetBoonData(53075).Count > 0 ? 1 : 0); }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { Target mainTarget = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.SoullessHorror); if (mainTarget == null) { throw new InvalidOperationException("Main target of the fight not found"); } AbstractBuffEvent buffOnDeath = combatData.GetBoonData(895).Where(x => x.To == mainTarget.AgentItem && x is BuffApplyEvent).LastOrDefault(); if (buffOnDeath != null) { fightData.SetSuccess(true, fightData.ToLogSpace(buffOnDeath.Time)); } } }
public override void CheckMechanic(ParsedLog log, Dictionary <Mechanic, List <MechanicEvent> > mechanicLogs, Dictionary <ushort, DummyActor> regroupedMobs) { CombatData combatData = log.CombatData; foreach (Player p in log.PlayerList) { List <long> cList = new List <long>(); switch (SkillId) { case SkillItem.DeathId: cList = combatData.GetDeadEvents(p.AgentItem).Select(x => x.Time).ToList(); break; case SkillItem.DCId: cList = combatData.GetDespawnEvents(p.AgentItem).Select(x => x.Time).ToList(); break; case SkillItem.RespawnId: cList = combatData.GetSpawnEvents(p.AgentItem).Select(x => x.Time).ToList(); break; case SkillItem.AliveId: cList = combatData.GetAliveEvents(p.AgentItem).Select(x => x.Time).ToList(); break; case SkillItem.DownId: cList = combatData.GetDownEvents(p.AgentItem).Select(x => x.Time).ToList(); List <long> downByVaporForm = combatData.GetBoonData(5620).Where(x => x.To == p.AgentItem && x is BuffRemoveAllEvent).Select(x => x.Time).ToList(); foreach (long time in downByVaporForm) { cList.RemoveAll(x => Math.Abs(x - time) < 20); } break; case SkillItem.ResurrectId: cList = log.CombatData.GetCastData(p.AgentItem).Where(x => x.SkillId == SkillItem.ResurrectId).Select(x => x.Time).ToList(); break; } foreach (long time in cList) { mechanicLogs[this].Add(new MechanicEvent(time, this, p)); } } }
public List <CombatItem> GetBoonData(long key) { return(CombatData.GetBoonData(key)); }
public void ComputeMechanics(ParsedLog log) { MechanicData mechData = log.MechanicData; CombatData combatData = log.CombatData; Mechanic.CheckSpecialCondition condition; HashSet <ushort> playersIds = log.PlayerIDs; Dictionary <ushort, DummyActor> regroupedMobs = new Dictionary <ushort, DummyActor>(); foreach (Mechanic mech in MechanicList) { switch (mech.MechanicType) { case Mechanic.MechType.PlayerStatus: foreach (Player p in log.PlayerList) { List <CombatItem> cList = new List <CombatItem>(); switch (mech.SkillId) { case SkillItem.DeathId: cList = combatData.GetStatesData(p.InstID, ParseEnum.StateChange.ChangeDead, log.FightData.FightStart, log.FightData.FightEnd); break; case SkillItem.DownId: cList = combatData.GetStatesData(p.InstID, ParseEnum.StateChange.ChangeDown, log.FightData.FightStart, log.FightData.FightEnd); List <CombatItem> downByVaporForm = combatData.GetBoonData(5620).Where(x => x.SrcInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.All).ToList(); foreach (CombatItem c in downByVaporForm) { cList.RemoveAll(x => Math.Abs(x.Time - c.Time) < 20); } break; case SkillItem.ResurrectId: cList = log.GetCastData(p.InstID, log.FightData.FightStart, log.FightData.FightEnd).Where(x => x.SkillID == SkillItem.ResurrectId && x.IsActivation.StartCasting()).ToList(); break; } foreach (CombatItem mechItem in cList) { mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(mechItem.Time), mech, p)); } } break; case Mechanic.MechType.SkillOnPlayer: foreach (Player p in log.PlayerList) { List <DamageLog> dls = p.GetDamageTakenLogs(null, log, 0, log.FightData.FightDuration); condition = mech.SpecialCondition; foreach (DamageLog dLog in dls) { if (condition != null && !condition(new SpecialConditionItem(dLog))) { continue; } if (dLog.SkillId == mech.SkillId && dLog.Result.IsHit()) { mechData[mech].Add(new MechanicLog(dLog.Time, mech, p)); } } } break; case Mechanic.MechType.PlayerBoon: case Mechanic.MechType.PlayerOnPlayer: case Mechanic.MechType.PlayerBoonRemove: foreach (Player p in log.PlayerList) { condition = mech.SpecialCondition; foreach (CombatItem c in log.GetBoonData(mech.SkillId)) { if (condition != null && !condition(new SpecialConditionItem(c))) { continue; } if (mech.MechanicType == Mechanic.MechType.PlayerBoonRemove) { if (c.IsBuffRemove == ParseEnum.BuffRemove.Manual && p.InstID == c.SrcInstid) { mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(c.Time), mech, p)); } } else { if (c.IsBuffRemove == ParseEnum.BuffRemove.None && p.InstID == c.DstInstid) { mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(c.Time), mech, p)); if (mech.MechanicType == Mechanic.MechType.PlayerOnPlayer) { mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(c.Time), mech, log.PlayerList.FirstOrDefault(x => x.InstID == c.SrcInstid))); } } } } } break; case Mechanic.MechType.HitOnEnemy: foreach (Player p in log.PlayerList) { condition = mech.SpecialCondition; IEnumerable <AgentItem> agents = log.AgentData.GetAgentsByID((ushort)mech.SkillId); foreach (AgentItem a in agents) { foreach (DamageLog dl in p.GetDamageLogs(null, log, 0, log.FightData.FightDuration)) { if (dl.DstInstId != a.InstID || dl.IsIndirectDamage || dl.Time < log.FightData.ToFightSpace(a.FirstAware) || dl.Time > log.FightData.ToFightSpace(a.LastAware) || (condition != null && !condition(new SpecialConditionItem(dl)))) { continue; } mechData[mech].Add(new MechanicLog(dl.Time, mech, p)); } } } break; case Mechanic.MechType.PlayerSkill: foreach (Player p in log.PlayerList) { condition = mech.SpecialCondition; foreach (CombatItem c in log.GetCastDataById(mech.SkillId)) { if (condition != null && !condition(new SpecialConditionItem(c))) { continue; } if (c.IsActivation.StartCasting() && c.SrcInstid == p.InstID) { mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(c.Time), mech, p)); } } } break; case Mechanic.MechType.EnemyBoon: case Mechanic.MechType.EnemyBoonStrip: condition = mech.SpecialCondition; foreach (CombatItem c in log.GetBoonData(mech.SkillId)) { if (condition != null && !condition(new SpecialConditionItem(c))) { continue; } DummyActor amp = null; if (mech.MechanicType == Mechanic.MechType.EnemyBoon && c.IsBuffRemove == ParseEnum.BuffRemove.None) { Target target = Targets.Find(x => x.InstID == c.DstInstid && x.FirstAware <= c.Time && x.LastAware >= c.Time); if (target != null) { amp = target; } else { AgentItem a = log.AgentData.GetAgent(c.DstAgent, c.Time); if (playersIds.Contains(a.InstID)) { continue; } else if (a.MasterAgent != 0) { AgentItem m = log.AgentData.GetAgent(a.MasterAgent, c.Time); if (playersIds.Contains(m.InstID)) { continue; } } if (!regroupedMobs.TryGetValue(a.ID, out amp)) { amp = new DummyActor(a); regroupedMobs.Add(a.ID, amp); } } } else if (mech.MechanicType == Mechanic.MechType.EnemyBoonStrip && c.IsBuffRemove == ParseEnum.BuffRemove.Manual) { Target target = Targets.Find(x => x.InstID == c.SrcInstid && x.FirstAware <= c.Time && x.LastAware >= c.Time); if (target != null) { amp = target; } else { AgentItem a = log.AgentData.GetAgent(c.SrcAgent, c.Time); if (playersIds.Contains(a.InstID)) { continue; } else if (a.MasterAgent != 0) { AgentItem m = log.AgentData.GetAgent(a.MasterAgent, c.Time); if (playersIds.Contains(m.InstID)) { continue; } } if (!regroupedMobs.TryGetValue(a.ID, out amp)) { amp = new DummyActor(a); regroupedMobs.Add(a.ID, amp); } } } if (amp != null) { mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(c.Time), mech, amp)); } } break; case Mechanic.MechType.EnemyCastEnd: case Mechanic.MechType.EnemyCastStart: condition = mech.SpecialCondition; foreach (CombatItem c in log.GetCastDataById(mech.SkillId)) { if (condition != null && !condition(new SpecialConditionItem(c))) { continue; } DummyActor amp = null; if ((mech.MechanicType == Mechanic.MechType.EnemyCastStart && c.IsActivation.StartCasting()) || (mech.MechanicType == Mechanic.MechType.EnemyCastEnd && !c.IsActivation.StartCasting())) { Target target = Targets.Find(x => x.InstID == c.SrcInstid && x.FirstAware <= c.Time && x.LastAware >= c.Time); if (target != null) { amp = target; } else { AgentItem a = log.AgentData.GetAgent(c.SrcAgent, c.Time); if (playersIds.Contains(a.InstID)) { continue; } else if (a.MasterAgent != 0) { AgentItem m = log.AgentData.GetAgent(a.MasterAgent, c.Time); if (playersIds.Contains(m.InstID)) { continue; } } if (!regroupedMobs.TryGetValue(a.ID, out amp)) { amp = new DummyActor(a); regroupedMobs.Add(a.ID, amp); } } } if (amp != null) { mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(c.Time), mech, amp)); } } break; case Mechanic.MechType.Spawn: foreach (AgentItem a in log.AgentData.GetAgentByType(AgentItem.AgentType.NPC).Where(x => x.ID == mech.SkillId)) { if (!regroupedMobs.TryGetValue(a.ID, out DummyActor amp)) { amp = new DummyActor(a); regroupedMobs.Add(a.ID, amp); } mechData[mech].Add(new MechanicLog(log.FightData.ToFightSpace(a.FirstAware), mech, amp)); } break; } } mechData.ComputePresentMechanics(log); }