public IEnumerable <Rotation> GetRotations()
        {
            var log     = GetLog();
            var players = log.Agents.OfType <Player>();

            if (characterNames != null)
            {
                players = players.Where(x => characterNames.Contains(x.Name));
            }

            var rotationCalculator = new RotationCalculator();

            foreach (var player in players)
            {
                var playerRotation = rotationCalculator.GetRotation(log, player);
                var items          = new List <RotationItem>();
                foreach (var item in playerRotation.Items)
                {
                    if (item is SkillCastItem skillCast)
                    {
                        items.Add(GetSkillCast(skillCast));
                    }
                    else if (item is WeaponSwapItem weaponSwap)
                    {
                        items.Add(GetWeaponSwap(weaponSwap));
                    }
                }
                yield return(new Rotation(player.Name, player.Profession, player.EliteSpecialization, items));
            }
        }
Exemple #2
0
        private void CalculatePlayerData()
        {
            var players = GetPlayers();

            var deathCounts = players.ToDictionary(x => x, x => 0);
            var downCounts  = players.ToDictionary(x => x, x => 0);
            var usedSkills  = players.ToDictionary(x => x, x => new HashSet <Skill>());

            foreach (var deadEvent in log.Events.OfType <AgentDeadEvent>().Where(x => x.Agent is Player))
            {
                var player = (Player)deadEvent.Agent;
                deathCounts[player]++;
            }

            foreach (var downEvent in log.Events.OfType <AgentDownedEvent>().Where(x => x.Agent is Player))
            {
                var player = (Player)downEvent.Agent;
                downCounts[player]++;
            }

            // Buff damage events only tell us which conditions/buffs, not what skill actually applied them
            foreach (var damageEvent in log.Events.OfType <PhysicalDamageEvent>().Where(x => x.Attacker is Player))
            {
                var player = (Player)damageEvent.Attacker;
                usedSkills[player].Add(damageEvent.Skill);
            }

            foreach (var activationEvent in log.Events.OfType <SkillCastEvent>().Where(x => x.Agent is Player))
            {
                var player = (Player)activationEvent.Agent;
                usedSkills[player].Add(activationEvent.Skill);
            }

            var playerData = new List <PlayerData>();

            foreach (var player in players)
            {
                HashSet <SkillData> utilitySkills = null;
                HashSet <SkillData> healingSkills = null;
                HashSet <SkillData> eliteSkills   = null;
                if (ApiData != null)
                {
                    utilitySkills = new HashSet <SkillData>();
                    healingSkills = new HashSet <SkillData>();
                    eliteSkills   = new HashSet <SkillData>();
                    foreach (var usedSkill in usedSkills[player])
                    {
                        var skillData = ApiData.GetSkillData(usedSkill);

                        // Skills may be also registered as used if they affect other players and do damage through them
                        if (skillData != null && skillData.Professions.Contains(player.Profession))
                        {
                            if (skillData.Slot == SkillSlot.Elite)
                            {
                                eliteSkills.Add(skillData);
                            }
                            else if (skillData.Slot == SkillSlot.Utility)
                            {
                                utilitySkills.Add(skillData);
                            }
                            else if (skillData.Slot == SkillSlot.Heal)
                            {
                                healingSkills.Add(skillData);
                            }
                        }
                    }
                }

                WeaponType land1Weapon1 = WeaponType.Other;
                WeaponType land1Weapon2 = WeaponType.Other;
                WeaponType land2Weapon1 = WeaponType.Other;
                WeaponType land2Weapon2 = WeaponType.Other;
                IEnumerable <SkillData> land1WeaponSkills = null;
                IEnumerable <SkillData> land2WeaponSkills = null;

                // TODO: Dual wield skill handling for Thieves
                if (ApiData != null)
                {
                    WeaponSet currentWeaponSet = WeaponSet.Unknown;
                    // We are only interested in land weapons. This may be imperfect if started on an underwater set.
                    var firstWeaponSwap = log.Events.OfType <AgentWeaponSwapEvent>().FirstOrDefault(x =>
                                                                                                    x.NewWeaponSet == WeaponSet.Land1 || x.NewWeaponSet == WeaponSet.Land2);

                    if (firstWeaponSwap == null)
                    {
                        currentWeaponSet = WeaponSet.Land1;
                    }
                    else
                    {
                        // First weapon set is the other one than the first swap swaps to (unless it was an underwater one)
                        currentWeaponSet = firstWeaponSwap.NewWeaponSet == WeaponSet.Land1
                                                        ? WeaponSet.Land2
                                                        : WeaponSet.Land1;
                    }

                    foreach (var logEvent in log.Events)
                    {
                        if (logEvent is AgentWeaponSwapEvent weaponSwapEvent && weaponSwapEvent.Agent == player)
                        {
                            currentWeaponSet = weaponSwapEvent.NewWeaponSet;
                            continue;
                        }

                        SkillData skillData = null;
                        if (logEvent is StartSkillCastEvent castEvent && castEvent.Agent == player)
                        {
                            skillData = ApiData.GetSkillData(castEvent.Skill);
                        }

                        if (skillData != null)
                        {
                            if (skillData.Professions.Contains(player.Profession) && skillData.Type == SkillType.Weapon)
                            {
                                if (skillData.WeaponType.IsTwoHanded() || skillData.Slot == SkillSlot.Weapon1 ||
                                    skillData.Slot == SkillSlot.Weapon2 || skillData.Slot == SkillSlot.Weapon3)
                                {
                                    if (currentWeaponSet == WeaponSet.Land1)
                                    {
                                        land1Weapon1 = skillData.WeaponType;
                                    }
                                    else if (currentWeaponSet == WeaponSet.Land2)
                                    {
                                        land2Weapon1 = skillData.WeaponType;
                                    }
                                }

                                if (skillData.WeaponType.IsTwoHanded() || skillData.Slot == SkillSlot.Weapon4 ||
                                    skillData.Slot == SkillSlot.Weapon5)
                                {
                                    if (currentWeaponSet == WeaponSet.Land1)
                                    {
                                        land1Weapon2 = skillData.WeaponType;
                                    }
                                    else if (currentWeaponSet == WeaponSet.Land2)
                                    {
                                        land2Weapon2 = skillData.WeaponType;
                                    }
                                }
                            }
                        }
                    }

                    land1WeaponSkills = WeaponSkillData
                                        .GetWeaponSkillIds(player.Profession, land1Weapon1, land1Weapon2)
                                        .Select(x => x == -1 ? null : ApiData.GetSkillData(x));
                    land2WeaponSkills = WeaponSkillData
                                        .GetWeaponSkillIds(player.Profession, land2Weapon1, land2Weapon2)
                                        .Select(x => x == -1 ? null : ApiData.GetSkillData(x));
                }

                if (ApiData != null)
                {
                    var skillDetections = SkillDetections.GetSkillDetections(player.Profession).ToArray();
                    foreach (var e in log.Events)
                    {
                        foreach (var detection in skillDetections)
                        {
                            if (detection.Detection.IsDetected(player, e))
                            {
                                var skill = ApiData.GetSkillData(detection.SkillId);
                                if (detection.Slot == SkillSlot.Utility)
                                {
                                    utilitySkills.Add(skill);
                                }
                                else if (detection.Slot == SkillSlot.Heal)
                                {
                                    healingSkills.Add(skill);
                                }
                                else if (detection.Slot == SkillSlot.Elite)
                                {
                                    eliteSkills.Add(skill);
                                }
                            }
                        }
                    }
                }

                var ignoredSkills = SkillDetections.GetIgnoredSkillIds(player.Profession);
                healingSkills?.RemoveWhere(x => ignoredSkills.Contains(x.Id));
                utilitySkills?.RemoveWhere(x => ignoredSkills.Contains(x.Id));
                eliteSkills?.RemoveWhere(x => ignoredSkills.Contains(x.Id));

                var specializationDetections =
                    SpecializationDetections.GetSpecializationDetections(player.Profession).ToArray();
                var badges = new List <PlayerBadge>();

                var specializations = new HashSet <CoreSpecialization>();
                foreach (var e in log.Events)
                {
                    foreach (var detection in specializationDetections)
                    {
                        if (detection.Detection.IsDetected(player, e))
                        {
                            specializations.Add(detection.Specialization);
                        }
                    }
                }

                foreach (var spec in specializations.OrderBy(x => x.ToString()))
                {
                    badges.Add(new PlayerBadge(spec.ToString(), BadgeType.Specialization));
                }

                var rotation = RotationCalculator.GetRotation(log, player);

                var data = new PlayerData(player, downCounts[player], deathCounts[player], rotation, usedSkills[player],
                                          healingSkills, utilitySkills, eliteSkills, land1Weapon1, land1Weapon2, land2Weapon1, land2Weapon2,
                                          land1WeaponSkills, land2WeaponSkills, badges);

                playerData.Add(data);
            }

            logPlayerData = playerData;
        }