private void SolveWvWPlayers(AgentData agentData, List <CombatItem> combatData, List <AbstractSingleActor> friendlies, IReadOnlyDictionary <uint, AbstractExtensionHandler> extensions) { IReadOnlyList <AgentItem> aList = agentData.GetAgentByType(AgentItem.AgentType.NonSquadPlayer); var set = new HashSet <string>(); var toRemove = new HashSet <AgentItem>(); var garbageList = new List <AbstractSingleActor>(); var teamChangeDict = combatData.Where(x => x.IsStateChange == ArcDPSEnums.StateChange.TeamChange).GroupBy(x => x.SrcAgent).ToDictionary(x => x.Key, x => x.ToList()); // IReadOnlyList <AgentItem> squadPlayers = agentData.GetAgentByType(AgentItem.AgentType.Player); ulong greenTeam = ulong.MaxValue; var greenTeams = new List <ulong>(); foreach (AgentItem a in squadPlayers) { if (teamChangeDict.TryGetValue(a.Agent, out List <CombatItem> teamChangeList)) { greenTeams.AddRange(teamChangeList.Where(x => x.SrcMatchesAgent(a)).Select(x => x.DstAgent)); } } if (greenTeams.Any()) { greenTeam = greenTeams.GroupBy(x => x).OrderByDescending(x => x.Count()).Select(x => x.Key).First(); } var playersToMerge = new Dictionary <PlayerNonSquad, AbstractSingleActor>(); var agentsToPlayersToMerge = new Dictionary <ulong, PlayerNonSquad>(); // foreach (AgentItem a in aList) { if (teamChangeDict.TryGetValue(a.Agent, out List <CombatItem> teamChangeList)) { a.OverrideIsNotInSquadFriendlyPlayer(teamChangeList.Where(x => x.SrcMatchesAgent(a)).Select(x => x.DstAgent).Any(x => x == greenTeam)); } List <AbstractSingleActor> actorListToFill = a.IsNotInSquadFriendlyPlayer ? friendlies : _detailed ? _targets : garbageList; var nonSquadPlayer = new PlayerNonSquad(a); if (!set.Contains(nonSquadPlayer.Character)) { actorListToFill.Add(nonSquadPlayer); set.Add(nonSquadPlayer.Character); } else { // we merge AbstractSingleActor mainPlayer = actorListToFill.FirstOrDefault(x => x.Character == nonSquadPlayer.Character); playersToMerge[nonSquadPlayer] = mainPlayer; agentsToPlayersToMerge[nonSquadPlayer.AgentItem.Agent] = nonSquadPlayer; } } if (playersToMerge.Any()) { foreach (CombatItem c in combatData) { if (agentsToPlayersToMerge.TryGetValue(c.SrcAgent, out PlayerNonSquad nonSquadPlayer) && c.SrcMatchesAgent(nonSquadPlayer.AgentItem, extensions)) { AbstractSingleActor mainPlayer = playersToMerge[nonSquadPlayer]; c.OverrideSrcAgent(mainPlayer.AgentItem.Agent); } if (agentsToPlayersToMerge.TryGetValue(c.DstAgent, out nonSquadPlayer) && c.DstMatchesAgent(nonSquadPlayer.AgentItem, extensions)) { AbstractSingleActor mainPlayer = playersToMerge[nonSquadPlayer]; c.OverrideDstAgent(mainPlayer.AgentItem.Agent); } } foreach (KeyValuePair <PlayerNonSquad, AbstractSingleActor> pair in playersToMerge) { PlayerNonSquad nonSquadPlayer = pair.Key; AbstractSingleActor mainPlayer = pair.Value; agentData.SwapMasters(nonSquadPlayer.AgentItem, mainPlayer.AgentItem); mainPlayer.AgentItem.OverrideAwareTimes(Math.Min(nonSquadPlayer.FirstAware, mainPlayer.FirstAware), Math.Max(nonSquadPlayer.LastAware, mainPlayer.LastAware)); toRemove.Add(nonSquadPlayer.AgentItem); } } agentData.RemoveAllFrom(toRemove); }