protected void SetSuccessByDeath(CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents, bool all, List <int> idsToUse) { int success = 0; long maxTime = long.MinValue; foreach (int id in idsToUse) { NPC target = Targets.Find(x => x.ID == id); if (target == null) { return; } DeadEvent killed = combatData.GetDeadEvents(target.AgentItem).LastOrDefault(); if (killed != null) { long time = killed.Time; success++; AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(target.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTaken != null) { time = Math.Min(lastDamageTaken.Time, time); } maxTime = Math.Max(time, maxTime); } } if ((all && success == idsToUse.Count) || (!all && success > 0)) { fightData.SetSuccess(true, maxTime); } }
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)); } } } }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success && _specialSplitLogTime > 0) { Target target = Targets.Find(x => x.ID == TriggerID); if (target == null) { throw new InvalidOperationException("Target for success by combat exit not found"); } List <AttackTargetEvent> attackTargets = combatData.GetAttackTargetEvents(target.AgentItem); if (attackTargets.Count == 0) { return; } long specialSplitTime = fightData.ToFightSpace(_specialSplitLogTime); AgentItem attackTarget = attackTargets.Last().AttackTarget; List <ExitCombatEvent> playerExits = new List <ExitCombatEvent>(); foreach (AgentItem a in playerAgents) { playerExits.AddRange(combatData.GetExitCombatEvents(a)); } ExitCombatEvent lastPlayerExit = playerExits.Count > 0 ? playerExits.MaxBy(x => x.Time) : null; TargetableEvent notAttackableEvent = combatData.GetTargetableEvents(attackTarget).LastOrDefault(x => !x.Targetable && x.Time > specialSplitTime); AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(target.AgentItem).LastOrDefault(x => (x.Damage > 0) && (playerAgents.Contains(x.From) || playerAgents.Contains(x.MasterFrom))); if (notAttackableEvent != null && lastDamageTaken != null && lastPlayerExit != null) { fightData.SetSuccess(lastPlayerExit.Time > notAttackableEvent.Time + 1000, fightData.ToLogSpace(lastDamageTaken.Time)); } } }
public override List <PhaseData> GetPhases(ParsedLog log, bool requirePhases) { long fightDuration = log.FightData.FightDuration; List <PhaseData> phases = GetInitialPhase(log); Target mainTarget = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Matthias); if (mainTarget == null) { throw new InvalidOperationException("Main target of the fight not found"); } phases[0].Targets.Add(mainTarget); if (!requirePhases) { return(phases); } // Special buff cast check AbstractBuffEvent heatWave = log.CombatData.GetBoonData(34526).FirstOrDefault(); if (heatWave != null) { phases.Add(new PhaseData(0, heatWave.Time - 1)); AbstractDamageEvent downPour = log.CombatData.GetDamageData(mainTarget.AgentItem).Find(x => x.SkillId == 34554); if (downPour != null) { phases.Add(new PhaseData(heatWave.Time, downPour.Time - 1)); List <AbstractCastEvent> castLogs = mainTarget.GetCastLogs(log, 0, log.FightData.FightDuration); AbstractCastEvent abo = castLogs.Find(x => x.SkillId == 34427); if (abo != null) { phases.Add(new PhaseData(downPour.Time, abo.Time - 1)); AbstractBuffEvent invulRemove = log.CombatData.GetBoonDataByDst(mainTarget.AgentItem).FirstOrDefault(x => x.Time >= abo.Time && x.Time <= abo.Time + 10000 && x.BuffID == 757 && !(x is BuffApplyEvent)); if (invulRemove != null) { phases.Add(new PhaseData(invulRemove.Time, fightDuration)); } } else { phases.Add(new PhaseData(downPour.Time, fightDuration)); } } else { phases.Add(new PhaseData(heatWave.Time, fightDuration)); } } else { phases.Add(new PhaseData(0, fightDuration)); } string[] namesMat = new [] { "Ice Phase", "Fire Phase", "Storm Phase", "Abomination Phase" }; for (int i = 1; i < phases.Count; i++) { phases[i].Name = namesMat[i - 1]; phases[i].DrawStart = i > 1; phases[i].Targets.Add(mainTarget); } return(phases); }
protected virtual bool Keep(AbstractDamageEvent c, ParsedLog log) { if (_triggerCondition != null) { return(_triggerCondition(c, log)); } return(true); }
protected override bool Keep(AbstractDamageEvent c, ParsedLog log) { if (!c.HasHit) { return(false); } return(base.Keep(c, log)); }
protected override bool Keep(AbstractDamageEvent c, ParsedLog log) { if (GetFirstHit(c.From, log) != c) { return(false); } return(base.Keep(c, log)); }
private AbstractDamageEvent GetFirstHit(AgentItem src, ParsedLog log) { if (!_firstHits.TryGetValue(src, out AbstractDamageEvent evt)) { AbstractDamageEvent res = log.CombatData.GetDamageData(src).Where(x => x.SkillId == SkillId && x.To.Type == AgentItem.AgentType.Player && base.Keep(x, log)).FirstOrDefault(); _firstHits[src] = res; return(res); } return(evt); }
protected double ComputeGain(int stack, AbstractDamageEvent dl) { if (DLChecker != null && !DLChecker(dl)) { return(-1.0); } double gain = GainComputer.ComputeGain(GainPerStack, stack); return(gain > 0.0 ? gain * dl.Damage : -1.0); }
protected double ComputeGainPlayer(int stack, AbstractDamageEvent dl) { if (DLChecker != null && !DLChecker(dl)) { return(-1.0); } double gain = _gainComputerPlayer.ComputeGain(1.0, stack); return(gain > 0.0 ? 1.0 : -1.0); }
private AbstractDamageEvent GetFirstHit(AgentItem src, ParsedLog log) { if (!_firstHits.TryGetValue(src, out AbstractDamageEvent evt)) { AbstractDamageEvent res = log.CombatData.GetDamageData(src).Where(x => x.SkillId == SkillId).FirstOrDefault(); _firstHits[src] = res; return(res); } return(evt); }
protected static void SetSuccessByCombatExit(List <NPC> targets, CombatData combatData, FightData fightData, HashSet <AgentItem> playerAgents) { if (targets.Count == 0) { return; } var playerExits = new List <ExitCombatEvent>(); var targetExits = new List <ExitCombatEvent>(); var lastTargetDamages = new List <AbstractDamageEvent>(); foreach (AgentItem a in playerAgents) { playerExits.AddRange(combatData.GetExitCombatEvents(a)); } 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)); } AbstractDamageEvent lastDamage = combatData.GetDamageTakenData(t.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamage != null) { lastTargetDamages.Add(lastDamage); } } ExitCombatEvent lastPlayerExit = playerExits.Count > 0 ? playerExits.MaxBy(x => x.Time) : null; ExitCombatEvent lastTargetExit = targetExits.Count > 0 ? targetExits.MaxBy(x => x.Time) : null; AbstractDamageEvent lastDamageTaken = lastTargetDamages.Count > 0 ? lastTargetDamages.MaxBy(x => x.Time) : null; if (lastTargetExit != null && lastDamageTaken != null) { if (lastPlayerExit != null) { fightData.SetSuccess(lastPlayerExit.Time > lastTargetExit.Time + 1000, lastDamageTaken.Time); } else if (fightData.FightEnd > targets.Max(x => x.LastAware) + 2000) { fightData.SetSuccess(true, lastDamageTaken.Time); } } }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success && _specialSplit > 0) { NPC target = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.Deimos); if (target == null) { throw new InvalidOperationException("Deimos not found"); } List <AttackTargetEvent> attackTargets = combatData.GetAttackTargetEvents(target.AgentItem); if (attackTargets.Count == 0) { return; } long specialSplitTime = _specialSplit; AgentItem attackTarget = attackTargets.Last().AttackTarget; // sanity check TargetableEvent attackableEvent = combatData.GetTargetableEvents(attackTarget).LastOrDefault(x => x.Targetable && x.Time > specialSplitTime - GeneralHelper.ServerDelayConstant); if (attackableEvent == null) { return; } TargetableEvent notAttackableEvent = combatData.GetTargetableEvents(attackTarget).LastOrDefault(x => !x.Targetable && x.Time > attackableEvent.Time); if (notAttackableEvent == null) { return; } var playerExits = new List <ExitCombatEvent>(); foreach (AgentItem a in playerAgents) { playerExits.AddRange(combatData.GetExitCombatEvents(a)); } ExitCombatEvent lastPlayerExit = playerExits.Count > 0 ? playerExits.MaxBy(x => x.Time) : null; AbstractDamageEvent lastDamageTaken = combatData.GetDamageTakenData(target.AgentItem).LastOrDefault(x => (x.Damage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (lastDamageTaken != null && lastPlayerExit != null) { fightData.SetSuccess(lastPlayerExit.Time > notAttackableEvent.Time + 1000, lastDamageTaken.Time); } } }
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); } } }
public override void CheckSuccess(CombatData combatData, AgentData agentData, FightData fightData, HashSet <AgentItem> playerAgents) { base.CheckSuccess(combatData, agentData, fightData, playerAgents); if (!fightData.Success) { Target target = Targets.Find(x => x.ID == TriggerID); if (target == null) { throw new InvalidOperationException("Target for success by combat exit not found"); } AgentItem zommoros = agentData.GetAgentsByID(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) || playerAgents.Contains(x.MasterFrom))); if (npcSpawn != null && lastDamageTaken != null) { fightData.SetSuccess(true, fightData.ToLogSpace(lastDamageTaken.Time)); } } }
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); }
public DeathRecap(List <AbstractDamageEvent> damageLogs, DeadEvent dead, List <DownEvent> downs, List <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.HasDowned) && x.Damage > 0).ToList(); ToDown = damageToDown.Count > 0 ? new List <DeathRecapDamageItem>() : null; int damage = 0; for (int i = damageToDown.Count - 1; i >= 0; i--) { AbstractDamageEvent dl = damageToDown[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectDamageEvent, ID = dl.SkillId, Damage = dl.Damage, Src = ag != null?ag.Name.Replace("\u0000", "").Split(':')[0] : "" }; damage += dl.Damage; ToDown.Add(item); if (damage > 20000) { break; } } var damageToKill = damageLogs.Where(x => x.Time > downed.Time && x.Time <= dead.Time && (x.HasHit || x.HasDowned) && x.Damage > 0).ToList(); ToKill = damageToKill.Count > 0 ? new List <DeathRecapDamageItem>() : null; for (int i = damageToKill.Count - 1; i >= 0; i--) { AbstractDamageEvent dl = damageToKill[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectDamageEvent, ID = dl.SkillId, Damage = dl.Damage, 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.HasDowned) && x.Damage > 0).ToList(); ToKill = damageToKill.Count > 0 ? new List <DeathRecapDamageItem>() : null; int damage = 0; for (int i = damageToKill.Count - 1; i >= 0; i--) { AbstractDamageEvent dl = damageToKill[i]; AgentItem ag = dl.From; var item = new DeathRecapDamageItem() { Time = (int)dl.Time, IndirectDamage = dl is NonDirectDamageEvent, ID = dl.SkillId, Damage = dl.Damage, Src = ag != null?ag.Name.Replace("\u0000", "").Split(':')[0] : "" }; damage += dl.Damage; ToKill.Add(item); if (damage > 20000) { break; } } } }
private static void FallBackPhases(NPC target, List <PhaseData> phases, ParsedEvtcLog log, bool firstPhaseAt0) { HashSet <AgentItem> pAgents = log.PlayerAgents; // clean Nikare related bugs switch (phases.Count) { case 2: { PhaseData p1 = phases[0]; PhaseData p2 = phases[1]; // P1 and P2 merged if (p1.Start == p2.Start) { AbstractDamageEvent hit = log.CombatData.GetDamageTakenData(target.AgentItem).FirstOrDefault(x => x.Time >= p1.End + 5000 && pAgents.Contains(x.From.GetFinalMaster()) && x.Damage > 0 && x is DirectDamageEvent); if (hit != null) { p2.OverrideStart(hit.Time); } else { p2.OverrideStart(p1.End); } } } break; case 3: { PhaseData p1 = phases[0]; PhaseData p2 = phases[1]; PhaseData p3 = phases[2]; // P1 and P2 merged if (p1.Start == p2.Start) { AbstractDamageEvent hit = log.CombatData.GetDamageTakenData(target.AgentItem).FirstOrDefault(x => x.Time >= p1.End + 5000 && pAgents.Contains(x.From.GetFinalMaster()) && x.Damage > 0 && x is DirectDamageEvent); if (hit != null) { p2.OverrideStart(hit.Time); } else { p2.OverrideStart(p1.End); } } // P1/P2 and P3 are merged if (p1.Start == p3.Start || p2.Start == p3.Start) { AbstractDamageEvent hit = log.CombatData.GetDamageTakenData(target.AgentItem).FirstOrDefault(x => x.Time >= p2.End + 5000 && pAgents.Contains(x.From.GetFinalMaster()) && x.Damage > 0 && x is DirectDamageEvent); if (hit != null) { p3.OverrideStart(hit.Time); } else { p3.OverrideStart(p2.End); } } } break; default: break; } if (!firstPhaseAt0 && phases.Count > 0 && phases.First().Start == 0) { PhaseData p1 = phases[0]; AbstractDamageEvent hit = log.CombatData.GetDamageTakenData(target.AgentItem).FirstOrDefault(x => x.Time >= 0 && pAgents.Contains(x.From.GetFinalMaster()) && x.Damage > 0 && x is DirectDamageEvent); if (hit != null) { p1.OverrideStart(hit.Time); } } }