protected static void SetSuccessByCombatExit(List <AbstractSingleActor> targets, CombatData combatData, FightData fightData, IReadOnlyCollection <AgentItem> playerAgents) { if (targets.Count == 0) { return; } var targetExits = new List <ExitCombatEvent>(); var lastTargetDamages = new List <AbstractHealthDamageEvent>(); foreach (AbstractSingleActor t in targets) { EnterCombatEvent enterCombat = combatData.GetEnterCombatEvents(t.AgentItem).LastOrDefault(); ExitCombatEvent exitCombat; if (enterCombat != null) { exitCombat = combatData.GetExitCombatEvents(t.AgentItem).Where(x => x.Time > enterCombat.Time).LastOrDefault(); } else { exitCombat = combatData.GetExitCombatEvents(t.AgentItem).LastOrDefault(); } AbstractHealthDamageEvent lastDamage = combatData.GetDamageTakenData(t.AgentItem).LastOrDefault(x => (x.HealthDamage > 0) && playerAgents.Contains(x.From.GetFinalMaster())); if (exitCombat == null || lastDamage == null || combatData.GetAnimatedCastData(t.AgentItem).Any(x => x.Time > exitCombat.Time + ParserHelper.ServerDelayConstant) || combatData.GetDamageData(t.AgentItem).Any(x => x.Time > exitCombat.Time + ParserHelper.ServerDelayConstant && playerAgents.Contains(x.To))) { return; } targetExits.Add(exitCombat); 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 + 150 >= lastDamageTaken.Time) { if (!AtLeastOnePlayerAlive(combatData, fightData, lastTargetExit.Time, playerAgents)) { return; } fightData.SetSuccess(true, lastDamageTaken.Time); } }
internal static void AttachMasterToGadgetByCastData(CombatData combatData, IReadOnlyCollection <AgentItem> gadgets, IReadOnlyList <long> castIDS, long castEndThreshold) { var possibleCandidates = new HashSet <AgentItem>(); var gadgetSpawnCastData = new List <AnimatedCastEvent>(); foreach (long id in castIDS) { gadgetSpawnCastData.AddRange(combatData.GetAnimatedCastData(id)); } gadgetSpawnCastData.Sort((x, y) => x.Time.CompareTo(y.Time)); foreach (AbstractCastEvent castEvent in gadgetSpawnCastData) { long start = castEvent.Time; long end = castEvent.EndTime; possibleCandidates.Add(castEvent.Caster); foreach (AgentItem gadget in gadgets) { if (gadget.FirstAware >= start && gadget.FirstAware <= end + castEndThreshold) { // more than one candidate, put to unknown and drop the search if (gadget.Master != null && gadget.GetFinalMaster() != castEvent.Caster.GetFinalMaster()) { gadget.SetMaster(ParserHelper._unknownAgent); break; } gadget.SetMaster(castEvent.Caster.GetFinalMaster()); } } } if (possibleCandidates.Count == 1) { foreach (AgentItem gadget in gadgets) { if (gadget.Master == null) { gadget.SetMaster(possibleCandidates.First().GetFinalMaster()); } } } }