Esempio n. 1
0
        List <GarrAbilityRecord> GetClassSpecAbilities(GarrFollowerRecord follower, uint faction)
        {
            List <GarrAbilityRecord> abilities = new List <GarrAbilityRecord>();
            uint classSpecId;

            switch (faction)
            {
            case GarrisonFactionIndex.Horde:
                classSpecId = follower.HordeGarrClassSpecID;
                break;

            case GarrisonFactionIndex.Alliance:
                classSpecId = follower.AllianceGarrClassSpecID;
                break;

            default:
                return(abilities);
            }

            if (!CliDB.GarrClassSpecStorage.ContainsKey(classSpecId))
            {
                return(abilities);
            }

            var garrAbility = _garrisonFollowerClassSpecAbilities.LookupByKey(classSpecId);

            if (!garrAbility.Empty())
            {
                abilities = garrAbility;
            }

            return(abilities);
        }
Esempio n. 2
0
        public void AddFollower(uint garrFollowerId)
        {
            GarrisonAddFollowerResult addFollowerResult = new();

            addFollowerResult.GarrTypeID = GetGarrisonType();
            GarrFollowerRecord followerEntry = CliDB.GarrFollowerStorage.LookupByKey(garrFollowerId);

            if (_followerIds.Contains(garrFollowerId) || followerEntry == null)
            {
                addFollowerResult.Result = GarrisonError.FollowerExists;
                _owner.SendPacket(addFollowerResult);
                return;
            }

            _followerIds.Add(garrFollowerId);
            ulong dbId = Global.GarrisonMgr.GenerateFollowerDbId();

            Follower follower = new();

            follower.PacketInfo.DbID            = dbId;
            follower.PacketInfo.GarrFollowerID  = garrFollowerId;
            follower.PacketInfo.Quality         = (uint)followerEntry.Quality; // TODO: handle magic upgrades
            follower.PacketInfo.FollowerLevel   = followerEntry.FollowerLevel;
            follower.PacketInfo.ItemLevelWeapon = followerEntry.ItemLevelWeapon;
            follower.PacketInfo.ItemLevelArmor  = followerEntry.ItemLevelArmor;
            follower.PacketInfo.Xp = 0;
            follower.PacketInfo.CurrentBuildingID = 0;
            follower.PacketInfo.CurrentMissionID  = 0;
            follower.PacketInfo.AbilityID         = Global.GarrisonMgr.RollFollowerAbilities(garrFollowerId, followerEntry, follower.PacketInfo.Quality, GetFaction(), true);
            follower.PacketInfo.FollowerStatus    = 0;

            _followers[dbId]           = follower;
            addFollowerResult.Follower = follower.PacketInfo;
            _owner.SendPacket(addFollowerResult);

            _owner.UpdateCriteria(CriteriaType.RecruitGarrisonFollower, follower.PacketInfo.DbID);
        }
Esempio n. 3
0
        //todo check this method, might be slow.....
        public List <GarrAbilityRecord> RollFollowerAbilities(uint garrFollowerId, GarrFollowerRecord follower, uint quality, uint faction, bool initial)
        {
            Cypher.Assert(faction < 2);

            bool hasForcedExclusiveTrait    = false;
            List <GarrAbilityRecord> result = new List <GarrAbilityRecord>();

            uint[] slots = { AbilitiesForQuality[quality, 0], AbilitiesForQuality[quality, 1] };

            GarrAbilities garrAbilities = null;
            var           abilities     = _garrisonFollowerAbilities[faction].LookupByKey(garrFollowerId);

            if (abilities != null)
            {
                garrAbilities = abilities;
            }

            List <GarrAbilityRecord> abilityList     = new List <GarrAbilityRecord>();
            List <GarrAbilityRecord> forcedAbilities = new List <GarrAbilityRecord>();
            List <GarrAbilityRecord> traitList       = new List <GarrAbilityRecord>();
            List <GarrAbilityRecord> forcedTraits    = new List <GarrAbilityRecord>();

            if (garrAbilities != null)
            {
                foreach (GarrAbilityRecord ability in garrAbilities.Counters)
                {
                    if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.HordeOnly) && faction != GarrisonFactionIndex.Horde)
                    {
                        continue;
                    }
                    else if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.AllianceOnly) && faction != GarrisonFactionIndex.Alliance)
                    {
                        continue;
                    }

                    if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.CannotRemove))
                    {
                        forcedAbilities.Add(ability);
                    }
                    else
                    {
                        abilityList.Add(ability);
                    }
                }

                foreach (GarrAbilityRecord ability in garrAbilities.Traits)
                {
                    if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.HordeOnly) && faction != GarrisonFactionIndex.Horde)
                    {
                        continue;
                    }
                    else if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.AllianceOnly) && faction != GarrisonFactionIndex.Alliance)
                    {
                        continue;
                    }

                    if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.CannotRemove))
                    {
                        forcedTraits.Add(ability);
                    }
                    else
                    {
                        traitList.Add(ability);
                    }
                }
            }

            abilityList.RandomResize((uint)Math.Max(0, slots[0] - forcedAbilities.Count));
            traitList.RandomResize((uint)Math.Max(0, slots[1] - forcedTraits.Count));

            // Add abilities specified in GarrFollowerXAbility.db2 before generic classspec ones on follower creation
            if (initial)
            {
                forcedAbilities.AddRange(abilityList);
                forcedTraits.AddRange(traitList);
            }

            forcedAbilities.Sort();
            abilityList.Sort();
            forcedTraits.Sort();
            traitList.Sort();

            // check if we have a trait from exclusive category
            foreach (GarrAbilityRecord ability in forcedTraits)
            {
                if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.Exclusive))
                {
                    hasForcedExclusiveTrait = true;
                    break;
                }
            }

            if (slots[0] > forcedAbilities.Count + abilityList.Count)
            {
                List <GarrAbilityRecord>        classSpecAbilities     = GetClassSpecAbilities(follower, faction);
                IEnumerable <GarrAbilityRecord> classSpecAbilitiesTemp = classSpecAbilities.Except(forcedAbilities);

                abilityList = classSpecAbilitiesTemp.Union(abilityList).ToList();
                abilityList.RandomResize((uint)Math.Max(0, slots[0] - forcedAbilities.Count));
            }

            if (slots[1] > forcedTraits.Count + traitList.Count)
            {
                List <GarrAbilityRecord> genericTraitsTemp = new List <GarrAbilityRecord>();
                foreach (GarrAbilityRecord ability in _garrisonFollowerRandomTraits)
                {
                    if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.HordeOnly) && faction != GarrisonFactionIndex.Horde)
                    {
                        continue;
                    }
                    else if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.AllianceOnly) && faction != GarrisonFactionIndex.Alliance)
                    {
                        continue;
                    }

                    // forced exclusive trait exists, skip other ones entirely
                    if (hasForcedExclusiveTrait && ability.Flags.HasAnyFlag(GarrisonAbilityFlags.Exclusive))
                    {
                        continue;
                    }

                    genericTraitsTemp.Add(ability);
                }

                List <GarrAbilityRecord> genericTraits = genericTraitsTemp.Except(forcedTraits).ToList();
                genericTraits.AddRange(traitList);
                genericTraits.Sort((GarrAbilityRecord a1, GarrAbilityRecord a2) =>
                {
                    int e1 = (int)(a1.Flags & GarrisonAbilityFlags.Exclusive);
                    int e2 = (int)(a2.Flags & GarrisonAbilityFlags.Exclusive);
                    if (e1 != e2)
                    {
                        return(e1.CompareTo(e2));
                    }

                    return(a1.Id.CompareTo(a2.Id));
                });
                genericTraits = genericTraits.Distinct().ToList();

                int firstExclusive = 0;
                int total          = genericTraits.Count;
                for (var i = 0; i < total; ++i, ++firstExclusive)
                {
                    if (genericTraits[i].Flags.HasAnyFlag(GarrisonAbilityFlags.Exclusive))
                    {
                        break;
                    }
                }

                while (traitList.Count < Math.Max(0, slots[1] - forcedTraits.Count) && total != 0)
                {
                    var garrAbility = genericTraits[RandomHelper.IRand(0, total-- - 1)];
                    if (garrAbility.Flags.HasAnyFlag(GarrisonAbilityFlags.Exclusive))
                    {
                        total = firstExclusive; // selected exclusive trait - no other can be selected now
                    }
                    else
                    {
                        --firstExclusive;
                    }

                    traitList.Add(garrAbility);
                    genericTraits.Remove(garrAbility);
                }
            }

            result.AddRange(forcedAbilities);
            result.AddRange(abilityList);
            result.AddRange(forcedTraits);
            result.AddRange(traitList);

            return(result);
        }