Example #1
0
        private void AssignAgentMasters(ParsedLog log, LogProcessorState state)
        {
            // Requires aware times to be set first
            Debug.Assert(state.AwareTimesSet);
            Debug.Assert(!state.MastersAssigned);
            Debug.Assert(state.AgentsByAddress != null);
            Debug.Assert(state.AgentsById != null);

            foreach (var combatItem in log.ParsedCombatItems)
            {
                if (combatItem.IsStateChange == StateChange.Normal)
                {
                    if (combatItem.SrcMasterId != 0)
                    {
                        Agent minion = null;

                        if (state.AgentsById.TryGetValue(combatItem.SrcAgentId, out var agentsWithId))
                        {
                            foreach (var agent in agentsWithId)
                            {
                                if (agent.IsWithinAwareTime(combatItem.Time))
                                {
                                    minion = agent;
                                    break;
                                }
                            }
                        }

                        if (minion != null && minion.Master == null)
                        {
                            Agent master = null;
                            if (state.AgentsById.TryGetValue(combatItem.SrcMasterId, out var potentialMasters))
                            {
                                foreach (var agent in potentialMasters)
                                {
                                    if (!(agent is Gadget) && agent.IsWithinAwareTime(combatItem.Time))
                                    {
                                        master = agent;
                                        break;
                                    }
                                }
                            }

                            if (master != null)
                            {
                                bool inCycle      = false;
                                var  masterParent = master;
                                while (masterParent != null)
                                {
                                    if (masterParent == minion)
                                    {
                                        // A cycle is present in the minion hierarchy, this minion would end up as
                                        // a transitive minion of itself, which could cause infinite looping.
                                        // This is common in very old logs where minion data is somewhat weird.
                                        inCycle = true;
                                        break;
                                    }

                                    masterParent = masterParent.Master;
                                }

                                if (!inCycle)
                                {
                                    minion.Master = master;
                                    master.MinionList.Add(minion);
                                }
                            }
                        }
                    }
                }

                if (combatItem.IsStateChange == StateChange.AttackTarget)
                {
                    ulong attackTargetAddress = combatItem.SrcAgent;
                    ulong masterGadgetAddress = combatItem.DstAgent;

                    AttackTarget target = null;
                    Gadget       master = null;
                    foreach (var agent in state.Agents)
                    {
                        switch (agent)
                        {
                        case Gadget gadget when gadget.AgentOrigin.OriginalAgentData.Any(x => x.Address == masterGadgetAddress):
                            master = gadget;

                            break;

                        case AttackTarget attackTarget when attackTarget.AgentOrigin.OriginalAgentData.Any(x => x.Address == attackTargetAddress):
                            target = attackTarget;

                            break;
                        }
                    }

                    if (master != null && target != null)
                    {
                        master.AddAttackTarget(target);
                        target.Gadget = master;
                    }
                }
            }

            state.MastersAssigned = true;
        }
Example #2
0
        // Requires aware times to be set first
        private void AssignAgentMasters(ParsedLog log, IReadOnlyCollection <Agent> agents)
        {
            foreach (var combatItem in log.ParsedCombatItems)
            {
                if (combatItem.IsStateChange == StateChange.Normal)
                {
                    if (combatItem.SrcMasterId != 0)
                    {
                        Agent minion = null;

                        // TODO: Look up by id with a dictionary first
                        foreach (var agent in agents)
                        {
                            if (agent.Id == combatItem.SrcAgentId && agent.IsWithinAwareTime(combatItem.Time))
                            {
                                minion = agent;
                                break;
                            }
                        }

                        if (minion != null && minion.Master == null)
                        {
                            Agent master = null;
                            foreach (var agent in agents)
                            {
                                if (!(agent is Gadget) && agent.Id == combatItem.SrcMasterId &&
                                    agent.IsWithinAwareTime(combatItem.Time))
                                {
                                    master = agent;
                                    break;
                                }
                            }

                            if (master != null)
                            {
                                bool inCycle      = false;
                                var  masterParent = master;
                                while (masterParent != null)
                                {
                                    if (masterParent == minion)
                                    {
                                        // A cycle is present in the minion hierarchy, this minion would end up as
                                        // a transitive minion of itself, which could cause infinite looping.
                                        // This is common in very old logs where minion data is somewhat weird.
                                        inCycle = true;
                                        break;
                                    }
                                    masterParent = masterParent.Master;
                                }

                                if (!inCycle)
                                {
                                    minion.Master = master;
                                    master.MinionList.Add(minion);
                                }
                            }
                        }
                    }
                }

                if (combatItem.IsStateChange == StateChange.AttackTarget)
                {
                    ulong attackTargetAddress = combatItem.SrcAgent;
                    ulong masterGadgetAddress = combatItem.DstAgent;

                    AttackTarget target = null;
                    Gadget       master = null;
                    foreach (var agent in agents)
                    {
                        switch (agent)
                        {
                        case Gadget gadget when gadget.Address == masterGadgetAddress:
                            master = gadget;
                            break;

                        case AttackTarget attackTarget when attackTarget.Address == attackTargetAddress:
                            target = attackTarget;
                            break;
                        }
                    }

                    if (master != null && target != null)
                    {
                        master.AddAttackTarget(target);
                        target.Gadget = master;
                    }
                }
            }
        }