Esempio n. 1
0
        private static WorldObject CreateSummoningEssence(int tier, bool mutate = true)
        {
            // Adding a spread of Pet Device levels for each tier - Level 200 pets should only be dropping in T8 Loot - HQ 2/29/2020
            // The spread is from Optim's Data
            // T5-T8 20/35/30/15% split
            // T8- 200,180,150,125
            // T7- 180,150,125,100
            // T6- 150,125,100,80
            // T5- 125,100,80,50
            // T4- 100,80,50
            // T3- 80,50
            // T2- 50
            // T1- 50

            // Tables are already 1-7, so removing them being Tier dependent

            int petLevel = 0;
            int chance   = ThreadSafeRandom.Next(1, 100);

            if (chance > 80)
            {
                petLevel = tier - 1;
            }
            else if (chance > 45)
            {
                petLevel = tier - 2;
            }
            else if (chance > 15)
            {
                petLevel = tier - 3;
            }
            else
            {
                petLevel = tier - 4;
            }
            if (petLevel < 2)
            {
                petLevel = 1;
            }

            int summoningEssenceIndex = ThreadSafeRandom.Next(0, LootTables.SummoningEssencesMatrix.Length - 1);

            var id = (uint)LootTables.SummoningEssencesMatrix[summoningEssenceIndex][petLevel - 1];

            var petDevice = WorldObjectFactory.CreateNewWorldObject(id) as PetDevice;

            if (petDevice != null && mutate)
            {
                MutatePetDevice(petDevice, tier);
            }

            return(petDevice);
        }
        public static void CreateRandomTestWorldObjects(Player player, uint typeId, uint numItems)
        {
            var weenieList           = DatabaseManager.World.GetRandomWeeniesOfType(typeId, numItems);
            List <WorldObject> items = new List <WorldObject>();

            for (int i = 0; i < numItems; i++)
            {
                WorldObject wo = WorldObjectFactory.CreateNewWorldObject(weenieList[i].WeenieClassId);
                items.Add(wo);
            }
            player.HandleAddNewWorldObjectsToInventory(items);
        }
        /// <summary>
        /// Creates a Melee weapon object.
        /// </summary>
        /// <param name="profile"></param><param name="isMagical"></param>
        /// <returns>Returns Melee Weapon WO</returns>
        public static WorldObject CreateMeleeWeapon(TreasureDeath profile, bool isMagical, int weaponType = -1, bool mutate = true)
        {
            int weaponWeenie = 0;
            int subtype      = 0;

            int eleType = ThreadSafeRandom.Next(0, 4);

            if (weaponType == -1)
            {
                weaponType = ThreadSafeRandom.Next(0, 3);
            }

            // Weapon Types
            // 0 = Heavy
            // 1 = Light
            // 2 = Finesse
            // default = Two Handed
            switch (weaponType)
            {
            case 0:
                // Heavy Weapons
                subtype      = ThreadSafeRandom.Next(0, 22);
                weaponWeenie = LootTables.HeavyWeaponsMatrix[subtype][eleType];
                break;

            case 1:
                // Light Weapons
                subtype      = ThreadSafeRandom.Next(0, 19);
                weaponWeenie = LootTables.LightWeaponsMatrix[subtype][eleType];
                break;

            case 2:
                // Finesse Weapons;
                subtype      = ThreadSafeRandom.Next(0, 22);
                weaponWeenie = LootTables.FinesseWeaponsMatrix[subtype][eleType];
                break;

            default:
                // Two handed
                subtype      = ThreadSafeRandom.Next(0, 11);
                weaponWeenie = LootTables.TwoHandedWeaponsMatrix[subtype][eleType];
                break;
            }

            var wo = WorldObjectFactory.CreateNewWorldObject((uint)weaponWeenie);

            if (wo != null && mutate)
            {
                MutateMeleeWeapon(wo, profile, isMagical, weaponType, subtype);
            }

            return(wo);
        }
Esempio n. 4
0
        private static WorldObject CreateRandomScroll(int tier)
        {
            WorldObject wo;

            if (tier > 7)
            {
                int id = CreateLevel8SpellComp();
                wo = WorldObjectFactory.CreateNewWorldObject((uint)id);
                return(wo);
            }

            if (tier == 7)
            {
                // According to wiki, Tier 7 has a chance for level 8 spell components or level 7 spell scrolls
                // No indication of weighting in either direction, so assuming a 50/50 split
                int chance = ThreadSafeRandom.Next(1, 100);
                if (chance > 50)
                {
                    int id = CreateLevel8SpellComp();
                    wo = WorldObjectFactory.CreateNewWorldObject((uint)id);
                    return(wo);
                }
            }

            if (tier < 1)
            {
                tier = 1;
            }

            int scrollLootMatrixIndex = tier - 1;
            int minSpellLevel         = LootTables.ScrollLootMatrix[scrollLootMatrixIndex][0];
            int maxSpellLevel         = LootTables.ScrollLootMatrix[scrollLootMatrixIndex][1];

            int  scrollLootIndex = ThreadSafeRandom.Next(minSpellLevel, maxSpellLevel);
            uint spellID         = 0;

            while (spellID == 0)
            {
                spellID = (uint)LootTables.ScrollSpells[ThreadSafeRandom.Next(0, LootTables.ScrollSpells.Length - 1)][scrollLootIndex];
            }

            var weenie = DatabaseManager.World.GetScrollWeenie(spellID);

            if (weenie == null)
            {
                log.DebugFormat("CreateRandomScroll for tier {0} and spellID of {1} returned null from the database.", tier, spellID);
                return(null);
            }

            wo = WorldObjectFactory.CreateNewWorldObject(weenie.ClassId);
            return(wo);
        }
        private static WorldObject CreateAetheria_New(TreasureDeath profile, bool mutate = true)
        {
            var wcid = AetheriaWcids.Roll(profile.Tier);

            var wo = WorldObjectFactory.CreateNewWorldObject((uint)wcid);

            if (mutate)
            {
                MutateAetheria_New(wo, profile);
            }

            return(wo);
        }
        /// <summary>
        /// Creates and optionally mutates a new MeleeWeapon
        /// </summary>
        public static WorldObject CreateMeleeWeapon(TreasureDeath profile, bool isMagical, MeleeWeaponSkill weaponSkill = MeleeWeaponSkill.Undef, bool mutate = true)
        {
            var wcid       = 0;
            var weaponType = 0;

            var eleType = ThreadSafeRandom.Next(0, 4);

            if (weaponSkill == MeleeWeaponSkill.Undef)
            {
                weaponSkill = (MeleeWeaponSkill)ThreadSafeRandom.Next(1, 4);
            }

            switch (weaponSkill)
            {
            case MeleeWeaponSkill.HeavyWeapons:

                weaponType = ThreadSafeRandom.Next(0, LootTables.HeavyWeaponsMatrix.Length - 1);
                wcid       = LootTables.HeavyWeaponsMatrix[weaponType][eleType];
                break;

            case MeleeWeaponSkill.LightWeapons:

                weaponType = ThreadSafeRandom.Next(0, LootTables.LightWeaponsMatrix.Length - 1);
                wcid       = LootTables.LightWeaponsMatrix[weaponType][eleType];
                break;

            case MeleeWeaponSkill.FinesseWeapons:

                weaponType = ThreadSafeRandom.Next(0, LootTables.FinesseWeaponsMatrix.Length - 1);
                wcid       = LootTables.FinesseWeaponsMatrix[weaponType][eleType];
                break;

            case MeleeWeaponSkill.TwoHandedCombat:

                weaponType = ThreadSafeRandom.Next(0, LootTables.TwoHandedWeaponsMatrix.Length - 1);
                wcid       = LootTables.TwoHandedWeaponsMatrix[weaponType][eleType];
                break;
            }

            var wo = WorldObjectFactory.CreateNewWorldObject((uint)wcid);

            if (wo != null && mutate)
            {
                if (!MutateMeleeWeapon(wo, profile, isMagical))
                {
                    log.Warn($"[LOOT] {wo.WeenieClassId} - {wo.Name} is not a MeleeWeapon");
                    return(null);
                }
            }
            return(wo);
        }
Esempio n. 7
0
        private static WorldObject CreateGenericObjects(int tier)
        {
            int         chance;
            WorldObject wo;

            if (tier < 1)
            {
                tier = 1;
            }
            if (tier > 8)
            {
                tier = 8;
            }

            chance = ThreadSafeRandom.Next(1, 100);

            switch (chance)
            {
            case var rate when(rate < 2):
                wo = WorldObjectFactory.CreateNewWorldObject(49485);     // Encapsulated Spirit

                break;

            case var rate when(rate < 10):
                wo = CreateSummoningEssence(tier);

                break;

            case var rate when(rate < 28):
                wo = CreateRandomScroll(tier);

                break;

            case var rate when(rate < 57):
                wo = CreateFood();

                break;

            default:
                int genericLootMatrixIndex = tier - 1;
                int upperLimit             = LootTables.GenericLootMatrix[genericLootMatrixIndex].Length - 1;

                chance = ThreadSafeRandom.Next(0, upperLimit);
                uint id = (uint)LootTables.GenericLootMatrix[genericLootMatrixIndex][chance];

                wo = WorldObjectFactory.CreateNewWorldObject(id);
                break;
            }

            return(wo);
        }
        private static WorldObject CreateDinnerware(int tier)
        {
            uint        id = 0;
            int         chance;
            WorldObject wo;

            if (tier < 1)
            {
                tier = 1;
            }
            if (tier > 8)
            {
                tier = 8;
            }

            int genericLootMatrixIndex = tier - 1;
            int upperLimit             = LootTables.DinnerwareLootMatrix.Length - 1;

            chance = ThreadSafeRandom.Next(0, upperLimit);
            id     = (uint)LootTables.DinnerwareLootMatrix[chance];

            if (id == 0)
            {
                return(null);
            }

            wo = WorldObjectFactory.CreateNewWorldObject(id);

            // Dinnerware has all these options (plates, tankards, etc)
            // This is just a short-term fix until Loot is overhauled
            // TODO - Doesn't handle damage/speed/etc that the mutate engine should for these types of items.
            wo.SetProperty(PropertyInt.GemCount, ThreadSafeRandom.Next(1, 5));
            wo.SetProperty(PropertyInt.GemType, ThreadSafeRandom.Next(10, 50));

            wo.LongDesc = wo.Name;

            int materialType = GetMaterialType(wo, tier);

            wo.MaterialType = (MaterialType)materialType;
            int workmanship = GetWorkmanship(tier);

            wo.ItemWorkmanship = workmanship;

            wo = SetAppraisalLongDescDecoration(wo);

            wo = AssignValue(wo);

            wo = RandomizeColor(wo);

            return(wo);
        }
Esempio n. 9
0
        public static WorldObject CreateIOU(uint missingWeenieId)
        {
            var iou = (Book)WorldObjectFactory.CreateNewWorldObject("parchment");

            iou.SetProperties("IOU", "An IOU for a missing database object.", "Sorry about that chief...", "ACEmulator", "prewritten");
            iou.AddPage(uint.MaxValue, "ACEmulator", "prewritten", false, $"{missingWeenieId}\n\nSorry but the database does not have a weenie for weenieClassId #{missingWeenieId} so in lieu of that here is an IOU for that item.");
            iou.Bonded         = (int)BondedStatus.Bonded;
            iou.Attuned        = (int)AttunedStatus.Attuned;
            iou.IsSellable     = false;
            iou.Value          = 0;
            iou.EncumbranceVal = 0;

            return(iou);
        }
Esempio n. 10
0
        public static List <WorldObject> CreateRandomObjectsOfType(WeenieType type, int count)
        {
            var weenies = DatabaseManager.World.GetRandomWeeniesOfType((int)type, count);

            var worldObjects = new List <WorldObject>();

            foreach (var weenie in weenies)
            {
                var wo = WorldObjectFactory.CreateNewWorldObject(weenie.WeenieClassId);
                worldObjects.Add(wo);
            }

            return(worldObjects);
        }
Esempio n. 11
0
        public static WorldObject CreateRare()
        {
            int tier = 0;

            if (ThreadSafeRandom.Next(1, 2500) == 1)   // 1 in 2,500 chance
            {
                tier = 1;
                if (ThreadSafeRandom.Next(1, 10) == 1)  // 1 in 25,000 chance
                {
                    tier = 2;
                }
                if (ThreadSafeRandom.Next(1, 100) == 1)  // 1 in 250,000 chance
                {
                    tier = 3;
                }
                if (ThreadSafeRandom.Next(1, 1250) == 1)  // 1 in 3,120,000 chance
                {
                    tier = 4;
                }
                if (ThreadSafeRandom.Next(1, 3017) == 1)  // 1 in 7,542,500 (wiki avg. 7,543,103)
                {
                    tier = 5;
                }
                if (ThreadSafeRandom.Next(1, 3500) == 1)  // 1 in 8,750,000 chance
                {
                    tier = 6;
                }
            }

            if (tier == 0)
            {
                return(null);
            }

            var tierRares = RareWCIDs[tier].ToList();

            var rng = ThreadSafeRandom.Next(0, tierRares.Count - 1);

            var rareWCID = tierRares[rng];

            var wo = WorldObjectFactory.CreateNewWorldObject((uint)rareWCID);

            if (wo == null)
            {
                log.Error($"LootGenerationFactory_Rare.CreateRare(): failed to generate rare wcid {rareWCID}");
            }

            return(wo);
        }
Esempio n. 12
0
        private static WorldObject GetClothingObject(uint weenieClassId, uint palette, double shade)
        {
            var weenie = DatabaseManager.World.GetCachedWeenie(weenieClassId);

            if (weenie == null)
            {
                return(null);
            }

            var worldObject = (Clothing)WorldObjectFactory.CreateNewWorldObject(weenie);

            worldObject.SetProperties((int)palette, shade);

            return(worldObject);
        }
        private static WorldObject CreateDinnerware(TreasureDeath profile, bool isMagical, bool mutate = true)
        {
            var rng = ThreadSafeRandom.Next(0, LootTables.DinnerwareLootMatrix.Length - 1);

            var wcid = (uint)LootTables.DinnerwareLootMatrix[rng];

            var wo = WorldObjectFactory.CreateNewWorldObject(wcid);

            if (wo != null && mutate)
            {
                MutateDinnerware(wo, profile, isMagical);
            }

            return(wo);
        }
Esempio n. 14
0
        /// <summary>
        /// creates a portal of the specified weenie at the position provided
        /// </summary>
        public static void SpawnPortal(PortalWcid weenieClassId, Position newPosition, float despawnTime)
        {
            WorldObject portal = WorldObjectFactory.CreateNewWorldObject((uint)weenieClassId);

            portal.Positions.Add(PositionType.Location, newPosition);

            LandblockManager.AddObject(portal);

            // Create portal decay
            ActionChain despawnChain = new ActionChain();

            despawnChain.AddDelaySeconds(despawnTime);
            despawnChain.AddAction(portal, () => portal.CurrentLandblock.RemoveWorldObject(portal.Guid, false));
            despawnChain.EnqueueChain();
        }
Esempio n. 15
0
        private static WorldObject CreateJewelry(int tier, bool isMagical)
        {
            // 35% chance ring, 35% chance bracelet, 30% chance necklace
            int ringPercent     = 35;
            int braceletPercent = 35;
            int necklacePercent = 30;

            int jewelrySlot = ThreadSafeRandom.Next(0, ringPercent + braceletPercent + necklacePercent);
            int jewelType;

            switch (jewelrySlot)
            {
            case int n when(n <= ringPercent):
                jewelType = LootTables.ringItems[ThreadSafeRandom.Next(0, LootTables.ringItems.Length - 1)];

                break;

            case int n when(n <= ringPercent + braceletPercent && n > ringPercent):
                jewelType = LootTables.braceletItems[ThreadSafeRandom.Next(0, LootTables.braceletItems.Length - 1)];

                break;

            case int n when(n <= ringPercent + braceletPercent + necklacePercent && n > ringPercent + braceletPercent):
                jewelType = LootTables.necklaceItems[ThreadSafeRandom.Next(0, LootTables.necklaceItems.Length - 1)];

                break;

            default:
                return(null);
            }

            //int rank = 0;
            //int skill_level_limit = 0;

            WorldObject wo = WorldObjectFactory.CreateNewWorldObject((uint)jewelType);

            if (wo == null)
            {
                return(null);
            }

            wo.SetProperty(PropertyInt.AppraisalLongDescDecoration, 1);
            wo.SetProperty(PropertyString.LongDesc, wo.GetProperty(PropertyString.Name));
Esempio n. 16
0
        public static WorldObject CreateIOU(uint missingWeenieId)
        {
            if (!PropertyManager.GetBool("iou_trades").Item)
            {
                log.Warn($"CreateIOU: Skipping creation of IOU for missing weenie {missingWeenieId} because IOU system is disabled.");

                return(null);
            }

            var iou = (Book)WorldObjectFactory.CreateNewWorldObject("parchment");

            iou.SetProperties("IOU", "An IOU for a missing database object.", "Sorry about that chief...", "ACEmulator", "prewritten");
            iou.AddPage(uint.MaxValue, "ACEmulator", "prewritten", false, $"{missingWeenieId}\n\nSorry but the database does not have a weenie for weenieClassId #{missingWeenieId} so in lieu of that here is an IOU for that item.", out _);
            iou.Bonded         = BondedStatus.Bonded;
            iou.Attuned        = AttunedStatus.Attuned;
            iou.IsSellable     = false;
            iou.Value          = 0;
            iou.EncumbranceVal = 0;

            return(iou);
        }
Esempio n. 17
0
        private static WorldObject CreateGem(int tier, bool isMagical, bool mutate = true)
        {
            int gemLootMatrixIndex = tier - 1;

            if (gemLootMatrixIndex > 4)
            {
                gemLootMatrixIndex = 4;
            }
            int upperLimit = LootTables.GemsMatrix[gemLootMatrixIndex].Length - 1;

            uint gemWCID = (uint)LootTables.GemsWCIDsMatrix[gemLootMatrixIndex][ThreadSafeRandom.Next(0, upperLimit)];

            WorldObject wo = WorldObjectFactory.CreateNewWorldObject(gemWCID) as Gem;

            if (wo != null && mutate)
            {
                MutateGem(wo, tier, isMagical);
            }

            return(wo);
        }
Esempio n. 18
0
        private static WorldObject CreateMundaneObjects(int tier)
        {
            uint        id = 0;
            int         chance;
            WorldObject wo;

            if (tier < 1)
            {
                tier = 1;
            }
            if (tier > 8)
            {
                tier = 8;
            }

            chance = ThreadSafeRandom.Next(0, 1);

            switch (chance)
            {
            case 0:
                id = (uint)CreateFood();
                break;

            default:
                int mundaneLootMatrixIndex = tier - 1;
                int upperLimit             = LootTables.MundaneLootMatrix[mundaneLootMatrixIndex].Length - 1;

                chance = ThreadSafeRandom.Next(0, upperLimit);
                id     = (uint)LootTables.MundaneLootMatrix[mundaneLootMatrixIndex][chance];
                break;
            }

            if (id == 0)
            {
                return(null);
            }

            wo = WorldObjectFactory.CreateNewWorldObject(id);
            return(wo);
        }
Esempio n. 19
0
        private static WorldObject CreateGem(TreasureDeath profile, bool isMagical, bool mutate = true)
        {
            var idx = profile.Tier - 1;

            if (idx > 4)
            {
                idx = 4;
            }

            var rng = ThreadSafeRandom.Next(0, LootTables.GemsMatrix[idx].Length - 1);

            var wcid = (uint)LootTables.GemsMatrix[idx][rng];

            var wo = WorldObjectFactory.CreateNewWorldObject(wcid) as Gem;

            if (wo != null && mutate)
            {
                MutateGem(wo, profile, isMagical);
            }

            return(wo);
        }
Esempio n. 20
0
        private static WorldObject CreateRandomScroll(TreasureDeath profile, TreasureRoll roll = null)
        {
            // level 8 spell components shouldn't be in here,
            // they should be associated with TreasureItemType.SpellComponent (peas)
            if (roll == null && profile.Tier >= 7)
            {
                // According to wiki, Tier 7 has a chance for level 8 spell components or level 7 spell scrolls (as does Tier 8)
                // No indication of weighting in either direction, so assuming a 50/50 split
                var rng = ThreadSafeRandom.Next(0.0f, 1.0f);

                if (rng < 0.5f)
                {
                    var wcid = RollLevel8SpellComp();

                    return(WorldObjectFactory.CreateNewWorldObject((uint)wcid));
                }
            }
            var spellLevel = ScrollLevelChance.Roll(profile);

            // todo: switch to SpellLevelProgression
            var spellId = SpellId.Undef;

            do
            {
                var spellIdx = ThreadSafeRandom.Next(0, ScrollSpells.Table.Length - 1);

                spellId = ScrollSpells.Table[spellIdx][spellLevel - 1];
            }while (spellId == SpellId.Undef);   // simple way of handling spells that start at level 3 (blasts, volleys)

            var weenie = DatabaseManager.World.GetScrollWeenie((uint)spellId);

            if (weenie == null)
            {
                log.DebugFormat("CreateRandomScroll for tier {0} and spellID of {1} returned null from the database.", profile.Tier, spellId);
                return(null);
            }

            return(WorldObjectFactory.CreateNewWorldObject(weenie.WeenieClassId));
        }
Esempio n. 21
0
        /// <summary>
        /// Creates Caster (Wand, Staff, Orb)
        /// </summary>
        public static WorldObject CreateCaster(TreasureDeath profile, bool isMagical, int wield = -1, bool forceWar = false, bool mutate = true)
        {
            // Refactored 11/20/19  - HarliQ
            int casterWeenie = 0;
            int subType      = 0;
            int element      = 0;

            if (wield == -1)
            {
                wield = GetWieldDifficulty(profile.Tier, WieldType.Caster);
            }

            // Getting the caster Weenie needed.
            if (wield == 0)
            {
                // Determine plain caster type: 0 - Orb, 1 - Sceptre, 2 - Staff, 3 - Wand
                subType      = ThreadSafeRandom.Next(0, 3);
                casterWeenie = LootTables.CasterWeaponsMatrix[wield][subType];
            }
            else
            {
                // Determine caster type: 1 - Sceptre, 2 - Baton, 3 - Staff
                int casterType = ThreadSafeRandom.Next(1, 3);

                // Determine element type: 0 - Slashing, 1 - Piercing, 2 - Blunt, 3 - Frost, 4 - Fire, 5 - Acid, 6 - Electric, 7 - Nether
                element      = forceWar ? ThreadSafeRandom.Next(0, 6) : ThreadSafeRandom.Next(0, 7);
                casterWeenie = LootTables.CasterWeaponsMatrix[casterType][element];
            }

            WorldObject wo = WorldObjectFactory.CreateNewWorldObject((uint)casterWeenie);

            // Why is this here?  Should not get a null object
            if (wo != null && mutate)
            {
                MutateCaster(wo, profile, isMagical, wield, element);
            }

            return(wo);
        }
Esempio n. 22
0
        private static WorldObject CreateRandomScroll(int tier)
        {
            WorldObject wo;

            if (tier > 7)
            {
                int id = CreateLevel8SpellComp();
                wo = WorldObjectFactory.CreateNewWorldObject((uint)id);
                return(wo);
            }

            if (tier < 1)
            {
                tier = 1;
            }

            int scrollLootMatrixIndex = tier - 1;
            int minSpellLevel         = LootTables.ScrollLootMatrix[scrollLootMatrixIndex][0];
            int maxSpellLevel         = LootTables.ScrollLootMatrix[scrollLootMatrixIndex][1];

            int  scrollLootIndex = ThreadSafeRandom.Next(minSpellLevel, maxSpellLevel);
            uint spellID         = 0;

            while (spellID == 0)
            {
                spellID = (uint)LootTables.ScrollSpells[ThreadSafeRandom.Next(0, LootTables.ScrollSpells.Length - 1)][scrollLootIndex];
            }

            var weenie = DatabaseManager.World.GetScrollWeenie(spellID);

            if (weenie == null)
            {
                log.WarnFormat("CreateRandomScroll for tier {0} and spellID of {1} returned null from the database.", tier, spellID);
                return(null);
            }

            wo = WorldObjectFactory.CreateNewWorldObject(weenie.ClassId);
            return(wo);
        }
Esempio n. 23
0
        private static void AddWeeniesToInventory(Player player, HashSet <uint> weenieIds, ushort?stackSize = null)
        {
            foreach (uint weenieId in weenieIds)
            {
                var loot = WorldObjectFactory.CreateNewWorldObject(weenieId);

                if (loot == null) // weenie doesn't exist
                {
                    continue;
                }

                if (stackSize == null)
                {
                    stackSize = loot.MaxStackSize;
                }

                if (stackSize > 1)
                {
                    loot.SetStackSize(stackSize);
                }

                player.TryAddToInventory(loot);
            }
        }
Esempio n. 24
0
        private static WorldObject CreateArmor(TreasureDeath profile, bool isMagical, bool isArmor, LootBias lootBias = LootBias.UnBiased, bool mutate = true)
        {
            var minType = LootTables.ArmorType.Helms;

            LootTables.ArmorType maxType;

            switch (profile.Tier)
            {
            case 1:
            default:
                maxType = LootTables.ArmorType.ChainmailArmor;
                break;

            case 2:
                maxType = LootTables.ArmorType.DiforsaArmor;
                break;

            case 3:
            case 4:
                maxType = LootTables.ArmorType.CovenantArmor;
                break;

            case 5:
                maxType = LootTables.ArmorType.AlduressaArmor;
                break;

            case 6:
                maxType = LootTables.ArmorType.HaebreanArmor;
                break;

            case 7:
            case 8:
                maxType = LootTables.ArmorType.OlthoiAlduressaArmor;
                break;
            }

            // Added for making clothing drops their own drop, and not involved in armor roll chance
            LootTables.ArmorType armorType;
            if (isArmor)
            {
                armorType = (LootTables.ArmorType)ThreadSafeRandom.Next((int)minType, (int)maxType);
            }
            else
            {
                armorType = LootTables.ArmorType.MiscClothing;
            }

            int[] table = LootTables.GetLootTable(armorType);

            int rng = ThreadSafeRandom.Next(0, table.Length - 1);

            int armorWeenie = table[rng];

            WorldObject wo = WorldObjectFactory.CreateNewWorldObject((uint)armorWeenie);

            if (wo != null && mutate)
            {
                MutateArmor(wo, profile, isMagical, armorType);
            }

            return(wo);
        }
Esempio n. 25
0
        private static WorldObject CreateSummoningEssence(int tier)
        {
            uint id = 0;

            if (tier < 1)
            {
                tier = 1;
            }
            if (tier > 7)
            {
                tier = 7;
            }

            int summoningEssenceIndex = ThreadSafeRandom.Next(0, LootTables.SummoningEssencesMatrix.Length - 1);

            id = (uint)LootTables.SummoningEssencesMatrix[summoningEssenceIndex][tier - 1];

            if (id == 0)
            {
                return(null);
            }

            if (!(WorldObjectFactory.CreateNewWorldObject(id) is PetDevice petDevice))
            {
                return(null);
            }

            var ratingChance = 0.5f;

            // add rng ratings to pet device
            // linear or biased?
            if (ratingChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                petDevice.GearDamage = GeneratePetDeviceRating(tier);
            }
            if (ratingChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                petDevice.GearDamageResist = GeneratePetDeviceRating(tier);
            }
            if (ratingChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                petDevice.GearCritDamage = GeneratePetDeviceRating(tier);
            }
            if (ratingChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                petDevice.GearCritDamageResist = GeneratePetDeviceRating(tier);
            }
            if (ratingChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                petDevice.GearCrit = GeneratePetDeviceRating(tier);
            }
            if (ratingChance > ThreadSafeRandom.Next(0.0f, 1.0f))
            {
                petDevice.GearCritResist = GeneratePetDeviceRating(tier);
            }

            var workmanship = GetWorkmanship(tier);

            petDevice.SetProperty(PropertyInt.ItemWorkmanship, workmanship);

            return(petDevice);
        }
Esempio n. 26
0
        /// <summary>
        /// Creates Caster (Wand, Staff, Orb)
        /// </summary>
        public static WorldObject CreateCaster(int tier, bool isMagical, int wield = -1, bool forceWar = false)
        {
            // Refactored 11/20/19  - HarliQ

            int              casterWeenie       = 0;
            double           elementalDamageMod = 0;
            Skill            wieldSkillType     = Skill.None;
            WieldRequirement wieldRequirement   = WieldRequirement.RawSkill;
            int              subType            = 0;

            if (wield == -1)
            {
                wield = GetWield(tier, 2);
            }

            // Getting the caster Weenie needed.
            if (wield == 0)
            {
                // Determine plain caster type: 0 - Orb, 1 - Sceptre, 2 - Staff, 3 - Wand
                subType      = ThreadSafeRandom.Next(0, 3);
                casterWeenie = LootTables.CasterWeaponsMatrix[wield][subType];

                if (tier > 6)
                {
                    wieldRequirement = WieldRequirement.Level;
                    wieldSkillType   = Skill.Axe; // Set by examples from PCAP data

                    switch (tier)
                    {
                    case 7:
                        wield = 150;     // In this instance, used for indicating player level, rather than skill level
                        break;

                    default:
                        wield = 180;     // In this instance, used for indicating player level, rather than skill level
                        break;
                    }
                }
            }
            else
            {
                // Determine the Elemental Damage Mod amount
                elementalDamageMod = DetermineElementMod(wield);

                // Determine caster type: 1 - Sceptre, 2 - Baton, 3 - Staff
                int casterType = ThreadSafeRandom.Next(1, 3);

                // Determine element type: 0 - Slashing, 1 - Piercing, 2 - Blunt, 3 - Frost, 4 - Fire, 5 - Acid, 6 - Electric, 7 - Nether
                int element = forceWar ? ThreadSafeRandom.Next(0, 6) : ThreadSafeRandom.Next(0, 7);
                casterWeenie = LootTables.CasterWeaponsMatrix[casterType][element];

                // If element is Nether, Void Magic is required, else War Magic is required for all other elements
                if (element == 7)
                {
                    wieldSkillType = Skill.VoidMagic;
                }
                else
                {
                    wieldSkillType = Skill.WarMagic;
                }
            }

            WorldObject wo = WorldObjectFactory.CreateNewWorldObject((uint)casterWeenie);

            // Why is this here?  Should not get a null object
            if (wo == null)
            {
                return(null);
            }

            // Setting MagicD and MissileD Bonuses to null (some weenies have a value)
            wo.WeaponMagicDefense   = null;
            wo.WeaponMissileDefense = null;
            // Not sure why this is here, guessing some wienies have it by default
            wo.ItemSkillLevelLimit = null;

            // Setting general traits of weapon
            wo.ItemWorkmanship = GetWorkmanship(tier);

            int materialType = GetMaterialType(wo, tier);

            if (materialType > 0)
            {
                wo.MaterialType = (MaterialType)materialType;
            }
            wo.GemCount = ThreadSafeRandom.Next(1, 5);
            wo.GemType  = (MaterialType)ThreadSafeRandom.Next(10, 50);
            wo.Value    = GetValue(tier, wo.ItemWorkmanship.Value, LootTables.getMaterialValueModifier(wo), LootTables.getGemMaterialValueModifier(wo));
            // Is this right??
            wo.LongDesc = wo.Name;

            // Setting Weapon defensive mods
            wo.WeaponDefense        = GetWieldReqMeleeDMod(wield);
            wo.WeaponMagicDefense   = GetMagicMissileDMod(tier);
            wo.WeaponMissileDefense = GetMagicMissileDMod(tier);

            // Setting weapon Offensive Mods
            if (elementalDamageMod > 1.0f)
            {
                wo.ElementalDamageMod = elementalDamageMod;
            }

            // Setting Wield Reqs for weapon
            if (wield > 0 || wieldRequirement == WieldRequirement.Level)
            {
                wo.WieldRequirements = wieldRequirement;
                wo.WieldSkillType    = (int)wieldSkillType;
                wo.WieldDifficulty   = wield;
            }
            else
            {
                wo.WieldRequirements = WieldRequirement.Invalid;
                wo.WieldSkillType    = null;
                wo.WieldDifficulty   = null;
            }

            // Adjusting Properties if weapon has magic (spells)
            double manaConMod = GetManaCMod(tier);

            if (manaConMod > 0.0f)
            {
                wo.ManaConversionMod = manaConMod;
            }

            if (isMagical)
            {
                wo = AssignMagic(wo, tier);
            }
            else
            {
                wo.ItemManaCost   = null;
                wo.ItemMaxMana    = null;
                wo.ItemCurMana    = null;
                wo.ItemSpellcraft = null;
                wo.ItemDifficulty = null;
            }

            wo = RandomizeColor(wo);

            return(wo);
        }
Esempio n. 27
0
        private static WorldObject GetClothingObject(uint weenieClassId, uint palette, double shade)
        {
            var weenie = DatabaseManager.World.GetCachedWeenie(weenieClassId);

            if (weenie == null)
            {
                return(null);
            }

            var worldObject = (Clothing)WorldObjectFactory.CreateNewWorldObject(weenie);

            worldObject.SetProperties((int)palette, shade);

            //if (shirtCT.ClothingBaseEffects.ContainsKey(sex.SetupID))
            //{
            //    ClothingBaseEffect shirtCBE = shirtCT.ClothingBaseEffects[sex.SetupID];
            //    for (int i = 0; i < shirtCBE.CloObjectEffects.Count; i++)
            //    {
            //        byte partNum = (byte)shirtCBE.CloObjectEffects[i].Index;
            //        shirt.AnimationOverrides.Add(new AnimationOverride()
            //        {
            //            AceObjectId = shirt.AceObjectId,
            //            AnimationId = shirtCBE.CloObjectEffects[i].ModelId,
            //            Index = (byte)shirtCBE.CloObjectEffects[i].Index
            //        });

            //        for (int j = 0; j < shirtCBE.CloObjectEffects[i].CloTextureEffects.Count; j++)
            //        {
            //            shirt.TextureOverrides.Add(new TextureMapOverride()
            //            {
            //                AceObjectId = shirt.AceObjectId,
            //                Index = (byte)shirtCBE.CloObjectEffects[i].Index,
            //                OldId = (ushort)shirtCBE.CloObjectEffects[i].CloTextureEffects[j].OldTexture,
            //                NewId = (ushort)shirtCBE.CloObjectEffects[i].CloTextureEffects[j].NewTexture
            //            });
            //        }
            //    }

            //    // Apply the proper palette(s). Unlike character skin/hair, clothes can have several palette ranges!
            //    if (shirtCT.ClothingSubPalEffects.ContainsKey(appearance.ShirtColor))
            //    {
            //        CloSubPalEffect shirtSubPal = shirtCT.ClothingSubPalEffects[appearance.ShirtColor];
            //        for (int i = 0; i < shirtSubPal.CloSubPalettes.Count; i++)
            //        {
            //            PaletteSet shirtPalSet = PaletteSet.ReadFromDat(shirtSubPal.CloSubPalettes[i].PaletteSet);
            //            ushort shirtPal = (ushort)shirtPalSet.GetPaletteID(appearance.ShirtHue);

            //            if (shirtPal > 0) // shirtPal will be 0 if the palette set is empty/not found
            //            {
            //                for (int j = 0; j < shirtSubPal.CloSubPalettes[i].Ranges.Count; j++)
            //                {
            //                    uint palOffset = shirtSubPal.CloSubPalettes[i].Ranges[j].Offset / 8;
            //                    uint numColors = shirtSubPal.CloSubPalettes[i].Ranges[j].NumColors / 8;
            //                    shirt.PaletteOverrides.Add(new PaletteOverride()
            //                    {
            //                        AceObjectId = shirt.AceObjectId,
            //                        SubPaletteId = shirtPal,
            //                        Offset = (ushort)palOffset,
            //                        Length = (ushort)numColors
            //                    });
            //                }
            //            }
            //        }
            //    }
            //}

            return(worldObject);
        }
Esempio n. 28
0
        public static CreateResult Create(CharacterCreateInfo characterCreateInfo, Weenie weenie, ObjectGuid guid, uint accountId, WeenieType weenieType, out Player player)
        {
            var heritageGroup = DatManager.PortalDat.CharGen.HeritageGroups[characterCreateInfo.Heritage];

            if (weenieType == WeenieType.Admin)
            {
                player = new Admin(weenie, guid, accountId);
            }
            else if (weenieType == WeenieType.Sentinel)
            {
                player = new Sentinel(weenie, guid, accountId);
            }
            else
            {
                player = new Player(weenie, guid, accountId);
            }

            player.SetProperty(PropertyInt.HeritageGroup, (int)characterCreateInfo.Heritage);
            player.SetProperty(PropertyString.HeritageGroup, heritageGroup.Name);
            player.SetProperty(PropertyInt.Gender, (int)characterCreateInfo.Gender);
            player.SetProperty(PropertyString.Sex, characterCreateInfo.Gender == 1 ? "Male" : "Female");

            //player.SetProperty(PropertyDataId.Icon, cgh.IconImage); // I don't believe this is used anywhere in the client, but it might be used by a future custom launcher

            // pull character data from the dat file
            var sex = heritageGroup.Genders[(int)characterCreateInfo.Gender];

            player.SetProperty(PropertyDataId.MotionTable, sex.MotionTable);
            player.SetProperty(PropertyDataId.SoundTable, sex.SoundTable);
            player.SetProperty(PropertyDataId.PhysicsEffectTable, sex.PhysicsTable);
            player.SetProperty(PropertyDataId.Setup, sex.SetupID);
            player.SetProperty(PropertyDataId.PaletteBase, sex.BasePalette);
            player.SetProperty(PropertyDataId.CombatTable, sex.CombatTable);

            // Check the character scale
            if (sex.Scale != 100u)
            {
                player.SetProperty(PropertyFloat.DefaultScale, (sex.Scale / 100f)); // Scale is stored as a percentage
            }
            // Get the hair first, because we need to know if you're bald, and that's the name of that tune!
            var hairstyle = sex.HairStyleList[Convert.ToInt32(characterCreateInfo.Apperance.HairStyle)];

            // Olthoi and Gear Knights have a "Body Style" instead of a hair style. These styles have multiple model/texture changes, instead of a single head/hairstyle.
            // Storing this value allows us to send the proper appearance ObjDesc
            if (hairstyle.ObjDesc.AnimPartChanges.Count > 1)
            {
                player.SetProperty(PropertyInt.Hairstyle, (int)characterCreateInfo.Apperance.HairStyle);
            }

            // Certain races (Undead, Tumeroks, Others?) have multiple body styles available. This is controlled via the "hair style".
            if (hairstyle.AlternateSetup > 0)
            {
                player.SetProperty(PropertyDataId.Setup, hairstyle.AlternateSetup);
            }

            player.SetProperty(PropertyDataId.EyesTexture, sex.GetEyeTexture(characterCreateInfo.Apperance.Eyes, hairstyle.Bald));
            player.SetProperty(PropertyDataId.DefaultEyesTexture, sex.GetDefaultEyeTexture(characterCreateInfo.Apperance.Eyes, hairstyle.Bald));
            player.SetProperty(PropertyDataId.NoseTexture, sex.GetNoseTexture(characterCreateInfo.Apperance.Nose));
            player.SetProperty(PropertyDataId.DefaultNoseTexture, sex.GetDefaultNoseTexture(characterCreateInfo.Apperance.Nose));
            player.SetProperty(PropertyDataId.MouthTexture, sex.GetMouthTexture(characterCreateInfo.Apperance.Mouth));
            player.SetProperty(PropertyDataId.DefaultMouthTexture, sex.GetDefaultMouthTexture(characterCreateInfo.Apperance.Mouth));
            player.Character.HairTexture        = sex.GetHairTexture(characterCreateInfo.Apperance.HairStyle);
            player.Character.DefaultHairTexture = sex.GetDefaultHairTexture(characterCreateInfo.Apperance.HairStyle);
            // HeadObject can be null if we're dealing with GearKnight or Olthoi
            var headObject = sex.GetHeadObject(characterCreateInfo.Apperance.HairStyle);

            if (headObject != null)
            {
                player.SetProperty(PropertyDataId.HeadObject, (uint)headObject);
            }

            // Skin is stored as PaletteSet (list of Palettes), so we need to read in the set to get the specific palette
            var skinPalSet = DatManager.PortalDat.ReadFromDat <PaletteSet>(sex.SkinPalSet);

            player.SetProperty(PropertyDataId.SkinPalette, skinPalSet.GetPaletteID(characterCreateInfo.Apperance.SkinHue));
            player.SetProperty(PropertyFloat.Shade, characterCreateInfo.Apperance.SkinHue);

            // Hair is stored as PaletteSet (list of Palettes), so we need to read in the set to get the specific palette
            var hairPalSet = DatManager.PortalDat.ReadFromDat <PaletteSet>(sex.HairColorList[Convert.ToInt32(characterCreateInfo.Apperance.HairColor)]);

            player.SetProperty(PropertyDataId.HairPalette, hairPalSet.GetPaletteID(characterCreateInfo.Apperance.HairHue));

            // Eye Color
            player.SetProperty(PropertyDataId.EyesPalette, sex.EyeColorList[Convert.ToInt32(characterCreateInfo.Apperance.EyeColor)]);

            if (characterCreateInfo.Apperance.HeadgearStyle < 0xFFFFFFFF) // No headgear is max UINT
            {
                var hat = GetClothingObject(sex.GetHeadgearWeenie(characterCreateInfo.Apperance.HeadgearStyle), characterCreateInfo.Apperance.HeadgearColor, characterCreateInfo.Apperance.HeadgearHue);
                if (hat != null)
                {
                    player.TryEquipObject(hat, hat.ValidLocations ?? 0);
                }
                else
                {
                    player.TryAddToInventory(CreateIOU(sex.GetHeadgearWeenie(characterCreateInfo.Apperance.HeadgearStyle)));
                }
            }

            var shirt = GetClothingObject(sex.GetShirtWeenie(characterCreateInfo.Apperance.ShirtStyle), characterCreateInfo.Apperance.ShirtColor, characterCreateInfo.Apperance.ShirtHue);

            if (shirt != null)
            {
                player.TryEquipObject(shirt, shirt.ValidLocations ?? 0);
            }
            else
            {
                player.TryAddToInventory(CreateIOU(sex.GetShirtWeenie(characterCreateInfo.Apperance.ShirtStyle)));
            }

            var pants = GetClothingObject(sex.GetPantsWeenie(characterCreateInfo.Apperance.PantsStyle), characterCreateInfo.Apperance.PantsColor, characterCreateInfo.Apperance.PantsHue);

            if (pants != null)
            {
                player.TryEquipObject(pants, pants.ValidLocations ?? 0);
            }
            else
            {
                player.TryAddToInventory(CreateIOU(sex.GetPantsWeenie(characterCreateInfo.Apperance.PantsStyle)));
            }

            var shoes = GetClothingObject(sex.GetFootwearWeenie(characterCreateInfo.Apperance.FootwearStyle), characterCreateInfo.Apperance.FootwearColor, characterCreateInfo.Apperance.FootwearHue);

            if (shoes != null)
            {
                player.TryEquipObject(shoes, shoes.ValidLocations ?? 0);
            }
            else
            {
                player.TryAddToInventory(CreateIOU(sex.GetFootwearWeenie(characterCreateInfo.Apperance.FootwearStyle)));
            }

            string templateName = heritageGroup.Templates[characterCreateInfo.TemplateOption].Name;

            //player.SetProperty(PropertyString.Title, templateName);
            player.SetProperty(PropertyString.Template, templateName);
            player.AddTitle(heritageGroup.Templates[characterCreateInfo.TemplateOption].Title, true);

            // stats
            uint totalAttributeCredits = heritageGroup.AttributeCredits;
            uint usedAttributeCredits  = 0;

            player.Strength.StartingValue = ValidateAttributeCredits(characterCreateInfo.StrengthAbility, usedAttributeCredits, totalAttributeCredits);
            usedAttributeCredits         += player.Strength.StartingValue;

            player.Endurance.StartingValue = ValidateAttributeCredits(characterCreateInfo.EnduranceAbility, usedAttributeCredits, totalAttributeCredits);
            usedAttributeCredits          += player.Endurance.StartingValue;

            player.Coordination.StartingValue = ValidateAttributeCredits(characterCreateInfo.CoordinationAbility, usedAttributeCredits, totalAttributeCredits);
            usedAttributeCredits += player.Coordination.StartingValue;

            player.Quickness.StartingValue = ValidateAttributeCredits(characterCreateInfo.QuicknessAbility, usedAttributeCredits, totalAttributeCredits);
            usedAttributeCredits          += player.Quickness.StartingValue;

            player.Focus.StartingValue = ValidateAttributeCredits(characterCreateInfo.FocusAbility, usedAttributeCredits, totalAttributeCredits);
            usedAttributeCredits      += player.Focus.StartingValue;

            player.Self.StartingValue = ValidateAttributeCredits(characterCreateInfo.SelfAbility, usedAttributeCredits, totalAttributeCredits);
            usedAttributeCredits     += player.Self.StartingValue;

            if (usedAttributeCredits > heritageGroup.AttributeCredits)
            {
                return(CreateResult.TooManySkillCreditsUsed);
            }

            // data we don't care about
            //characterCreateInfo.CharacterSlot;
            //characterCreateInfo.ClassId;

            // characters start with max vitals
            player.Health.Current  = player.Health.Base;
            player.Stamina.Current = player.Stamina.Base;
            player.Mana.Current    = player.Mana.Base;

            // set initial skill credit amount. 52 for all but "Olthoi", which have 68
            player.SetProperty(PropertyInt.AvailableSkillCredits, (int)heritageGroup.SkillCredits);

            for (int i = 0; i < characterCreateInfo.SkillAdvancementClasses.Count; i++)
            {
                var sac = characterCreateInfo.SkillAdvancementClasses[i];

                if (sac == SkillAdvancementClass.Inactive)
                {
                    continue;
                }

                if (!DatManager.PortalDat.SkillTable.SkillBaseHash.ContainsKey((uint)i))
                {
                    log.ErrorFormat("Character {0} tried to create with skill {1} that was not found in Portal dat.", characterCreateInfo.Name, i);
                    return(CreateResult.InvalidSkillRequested);
                }

                var skill = DatManager.PortalDat.SkillTable.SkillBaseHash[(uint)i];

                var trainedCost     = skill.TrainedCost;
                var specializedCost = skill.UpgradeCostFromTrainedToSpecialized;

                foreach (var skillGroup in heritageGroup.Skills)
                {
                    if (skillGroup.SkillNum == i)
                    {
                        trainedCost     = skillGroup.NormalCost;
                        specializedCost = skillGroup.PrimaryCost;
                        break;
                    }
                }

                if (sac == SkillAdvancementClass.Specialized)
                {
                    if (!player.TrainSkill((Skill)i, trainedCost))
                    {
                        return(CreateResult.FailedToTrainSkill);
                    }
                    if (!player.SpecializeSkill((Skill)i, specializedCost))
                    {
                        return(CreateResult.FailedToSpecializeSkill);
                    }
                }
                else if (sac == SkillAdvancementClass.Trained)
                {
                    if (!player.TrainSkill((Skill)i, trainedCost))
                    {
                        return(CreateResult.FailedToTrainSkill);
                    }
                }
                else if (sac == SkillAdvancementClass.Untrained)
                {
                    player.UntrainSkill((Skill)i, 0);
                }
            }

            var isDualWieldTrainedOrSpecialized = player.Skills[Skill.DualWield].AdvancementClass > SkillAdvancementClass.Untrained;

            // Set Heritage based Melee and Ranged Masteries
            GetMasteries(player.HeritageGroup, out WeaponType meleeMastery, out WeaponType rangedMastery);

            player.SetProperty(PropertyInt.MeleeMastery, (int)meleeMastery);
            player.SetProperty(PropertyInt.RangedMastery, (int)rangedMastery);

            // Set innate augs
            SetInnateAugmentations(player);

            // grant starter items based on skills
            var starterGearConfig = StarterGearFactory.GetStarterGearConfiguration();
            var grantedWeenies    = new List <uint>();

            foreach (var skillGear in starterGearConfig.Skills)
            {
                var charSkill = player.Skills[(Skill)skillGear.SkillId];
                if (charSkill.AdvancementClass == SkillAdvancementClass.Trained || charSkill.AdvancementClass == SkillAdvancementClass.Specialized)
                {
                    foreach (var item in skillGear.Gear)
                    {
                        if (grantedWeenies.Contains(item.WeenieId))
                        {
                            var existingItem = player.Inventory.Values.FirstOrDefault(i => i.WeenieClassId == item.WeenieId);
                            if (existingItem == null || (existingItem.MaxStackSize ?? 1) <= 1)
                            {
                                continue;
                            }

                            existingItem.SetStackSize(existingItem.StackSize + item.StackSize);
                            continue;
                        }

                        var loot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                        if (loot != null)
                        {
                            if (loot.StackSize.HasValue && loot.MaxStackSize.HasValue)
                            {
                                loot.SetStackSize((item.StackSize <= loot.MaxStackSize) ? item.StackSize : loot.MaxStackSize);
                            }
                        }
                        else
                        {
                            player.TryAddToInventory(CreateIOU(item.WeenieId));
                        }

                        if (loot != null && player.TryAddToInventory(loot))
                        {
                            grantedWeenies.Add(item.WeenieId);
                        }

                        if (isDualWieldTrainedOrSpecialized && loot != null)
                        {
                            if (loot.WeenieType == WeenieType.MeleeWeapon)
                            {
                                var dualloot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                                if (dualloot != null)
                                {
                                    player.TryAddToInventory(dualloot);
                                }
                                else
                                {
                                    player.TryAddToInventory(CreateIOU(item.WeenieId));
                                }
                            }
                        }
                    }

                    var heritageLoot = skillGear.Heritage.FirstOrDefault(sh => sh.HeritageId == characterCreateInfo.Heritage);
                    if (heritageLoot != null)
                    {
                        foreach (var item in heritageLoot.Gear)
                        {
                            if (grantedWeenies.Contains(item.WeenieId))
                            {
                                var existingItem = player.Inventory.Values.FirstOrDefault(i => i.WeenieClassId == item.WeenieId);
                                if (existingItem == null || (existingItem.MaxStackSize ?? 1) <= 1)
                                {
                                    continue;
                                }

                                existingItem.SetStackSize(existingItem.StackSize + item.StackSize);
                                continue;
                            }

                            var loot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                            if (loot != null)
                            {
                                if (loot.StackSize.HasValue && loot.MaxStackSize.HasValue)
                                {
                                    loot.SetStackSize((item.StackSize <= loot.MaxStackSize) ? item.StackSize : loot.MaxStackSize);
                                }
                            }
                            else
                            {
                                player.TryAddToInventory(CreateIOU(item.WeenieId));
                            }

                            if (loot != null && player.TryAddToInventory(loot))
                            {
                                grantedWeenies.Add(item.WeenieId);
                            }

                            if (isDualWieldTrainedOrSpecialized && loot != null)
                            {
                                if (loot.WeenieType == WeenieType.MeleeWeapon)
                                {
                                    var dualloot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                                    if (dualloot != null)
                                    {
                                        player.TryAddToInventory(dualloot);
                                    }
                                    else
                                    {
                                        player.TryAddToInventory(CreateIOU(item.WeenieId));
                                    }
                                }
                            }
                        }
                    }

                    foreach (var spell in skillGear.Spells)
                    {
                        // Olthoi Spitter is a special case
                        if (characterCreateInfo.Heritage == (int)HeritageGroup.OlthoiAcid)
                        {
                            player.AddKnownSpell(spell.SpellId);
                            // Continue to next spell as Olthoi spells do not have the SpecializedOnly field
                            continue;
                        }

                        if (charSkill.AdvancementClass == SkillAdvancementClass.Trained && spell.SpecializedOnly == false)
                        {
                            player.AddKnownSpell(spell.SpellId);
                        }
                        else if (charSkill.AdvancementClass == SkillAdvancementClass.Specialized)
                        {
                            player.AddKnownSpell(spell.SpellId);
                        }
                    }
                }
            }

            player.Name           = characterCreateInfo.Name;
            player.Character.Name = characterCreateInfo.Name;


            // Index used to determine the starting location
            var startArea = characterCreateInfo.StartArea;

            var starterArea = DatManager.PortalDat.CharGen.StarterAreas[(int)startArea];

            player.Location = new Position(starterArea.Locations[0].ObjCellID,
                                           starterArea.Locations[0].Frame.Origin.X, starterArea.Locations[0].Frame.Origin.Y, starterArea.Locations[0].Frame.Origin.Z,
                                           starterArea.Locations[0].Frame.Orientation.X, starterArea.Locations[0].Frame.Orientation.Y, starterArea.Locations[0].Frame.Orientation.Z, starterArea.Locations[0].Frame.Orientation.W);

            var instantiation = new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f); // ultimate fallback.
            var spellFreeRide = new Spell();

            switch (starterArea.Name)
            {
            case "OlthoiLair":        //todo: check this when olthoi play is allowed in ace
                spellFreeRide = null; // no training area for olthoi, so they start and fall back to same place.
                instantiation = new Position(player.Location);
                break;

            case "Shoushi":
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3813);     // Free Ride to Shoushi
                break;

            case "Yaraq":
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3814);     // Free Ride to Yaraq
                break;

            case "Sanamar":
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3535);     // Free Ride to Sanamar
                break;

            case "Holtburg":
            default:
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3815);     // Free Ride to Holtburg
                break;
            }
            if (spellFreeRide != null && spellFreeRide.Name != "")
            {
                instantiation = new Position(spellFreeRide.PositionObjCellId.Value, spellFreeRide.PositionOriginX.Value, spellFreeRide.PositionOriginY.Value, spellFreeRide.PositionOriginZ.Value, spellFreeRide.PositionAnglesX.Value, spellFreeRide.PositionAnglesY.Value, spellFreeRide.PositionAnglesZ.Value, spellFreeRide.PositionAnglesW.Value);
            }

            player.Instantiation = new Position(instantiation);

            player.Sanctuary = new Position(player.Location);

            player.SetProperty(PropertyBool.RecallsDisabled, true);

            if (player is Sentinel || player is Admin)
            {
                player.Character.IsPlussed = true;
                player.CloakStatus         = CloakStatus.Off;
                player.ChannelsAllowed     = player.ChannelsActive;
            }

            CharacterCreateSetDefaultCharacterOptions(player);

            return(CreateResult.Success);
        }
        private static WorldObject CreateArmor(int tier, bool isMagical, LootBias lootBias = LootBias.UnBiased)
        {
            int lowSpellTier  = 0;
            int highSpellTier = 0;

            int equipSetId = 0;

            int materialType = 0;

            int armorPiece  = 0;
            int armorType   = 0;
            int armorWeenie = 0;

            switch (tier)
            {
            case 1:
                lowSpellTier  = 1;
                highSpellTier = 3;
                armorType     = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.ChainmailArmor);
                break;

            case 2:
                lowSpellTier  = 3;
                highSpellTier = 5;
                armorType     = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.DiforsaArmor);
                break;

            case 3:
                lowSpellTier  = 4;
                highSpellTier = 6;
                armorType     = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.CovenantArmor);
                break;

            case 4:
                lowSpellTier  = 5;
                highSpellTier = 6;
                armorType     = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.CovenantArmor);
                break;

            case 5:
                lowSpellTier  = 5;
                highSpellTier = 7;
                armorType     = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.AlduressaArmor);
                break;

            case 6:
                lowSpellTier  = 6;
                highSpellTier = 7;
                armorType     = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.HaebreanArmor);
                break;

            case 7:
                lowSpellTier  = 6;
                highSpellTier = 8;
                armorType     = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.OlthoiAlduressaArmor);
                break;

            default:
                lowSpellTier  = 7;
                highSpellTier = 8;
                if (lootBias == LootBias.Armor)     // Armor Mana Forge Chests don't include clothing type items
                {
                    armorType = ThreadSafeRandom.Next((int)LootTables.ArmorType.Helms, (int)LootTables.ArmorType.OlthoiAlduressaArmor);
                }
                else
                {
                    armorType = ThreadSafeRandom.Next((int)LootTables.ArmorType.MiscClothing, (int)LootTables.ArmorType.OlthoiAlduressaArmor);
                }
                break;
            }

            switch (armorType)
            {
            case (int)LootTables.ArmorType.MiscClothing:
                armorPiece  = ThreadSafeRandom.Next(0, 47);
                armorWeenie = LootTables.MiscClothing[armorPiece];
                break;

            case (int)LootTables.ArmorType.Helms:
                armorPiece  = ThreadSafeRandom.Next(0, 8);
                armorWeenie = LootTables.Helms[armorPiece];
                break;

            case (int)LootTables.ArmorType.Shields:
                armorPiece  = ThreadSafeRandom.Next(0, 4);
                armorWeenie = LootTables.Shields[armorPiece];
                break;

            case (int)LootTables.ArmorType.LeatherArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 15);
                armorWeenie = LootTables.LeatherArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.StuddedLeatherArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 14);
                armorWeenie = LootTables.StuddedLeatherArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.ChainmailArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 12);
                armorWeenie = LootTables.ChainmailArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.PlatemailArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 10);
                armorWeenie = LootTables.PlatemailArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.ScalemailArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 13);
                armorWeenie = LootTables.ScalemailArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.YoroiArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 7);
                armorWeenie = LootTables.YoroiArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.DiforsaArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 12);
                armorWeenie = LootTables.DiforsaArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.CeldonArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 3);
                armorWeenie = LootTables.CeldonArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.AmuliArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 1);
                armorWeenie = LootTables.AmuliArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.KoujiaArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 2);
                armorWeenie = LootTables.KoujiaArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.TenassaArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 2);
                armorWeenie = LootTables.TenassaArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.CovenantArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 9);
                armorWeenie = LootTables.CovenantArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.LoricaArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 5);
                armorWeenie = LootTables.LoricaArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.NariyidArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 6);
                armorWeenie = LootTables.NariyidArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.ChiranArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 4);
                armorWeenie = LootTables.ChiranArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.AlduressaArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 4);
                armorWeenie = LootTables.AlduressaArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.KnorrAcademyArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 7);
                armorWeenie = LootTables.KnorrAcademyArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.SedgemailLeatherArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 5);
                armorWeenie = LootTables.SedgemailLeatherArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.HaebreanArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 8);
                armorWeenie = LootTables.HaebreanArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.OlthoiArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 9);
                armorWeenie = LootTables.OlthoiArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.OlthoiAmuliArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 4);
                armorWeenie = LootTables.OlthoiAmuliArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.OlthoiCeldonArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 6);
                armorWeenie = LootTables.OlthoiCeldonArmor[armorPiece];
                break;

            case (int)LootTables.ArmorType.OlthoiKoujiaArmor:
                armorPiece  = ThreadSafeRandom.Next(0, 4);
                armorWeenie = LootTables.OlthoiKoujiaArmor[armorPiece];
                break;

            default:     // Olthoi Alduressa
                armorPiece  = ThreadSafeRandom.Next(0, 4);
                armorWeenie = LootTables.OlthoiAlduressaArmor[armorPiece];
                break;
            }

            WorldObject wo = WorldObjectFactory.CreateNewWorldObject((uint)armorWeenie);

            if (wo == null)
            {
                return(null);
            }

            wo.SetProperty(PropertyString.LongDesc, wo.GetProperty(PropertyString.Name));

            wo.SetProperty(PropertyInt.AppraisalItemSkill, 7);
            wo.SetProperty(PropertyInt.AppraisalLongDescDecoration, 1);

            materialType = GetMaterialType(wo, tier);
            if (materialType > 0)
            {
                wo.MaterialType = (MaterialType)materialType;
            }

            int gemCount = ThreadSafeRandom.Next(1, 6);
            int gemType  = ThreadSafeRandom.Next(10, 50);

            wo.SetProperty(PropertyInt.GemCount, gemCount);
            wo.SetProperty(PropertyInt.GemType, gemType);

            int workmanship = GetWorkmanship(tier);

            wo.SetProperty(PropertyInt.ItemWorkmanship, workmanship);

            double materialMod    = LootTables.getMaterialValueModifier(wo);
            double gemMaterialMod = LootTables.getGemMaterialValueModifier(wo);
            var    value          = GetValue(tier, workmanship, gemMaterialMod, materialMod);

            wo.Value = value;

            int wield;

            if (tier > 6 && armorType != (int)LootTables.ArmorType.CovenantArmor)
            {
                wo.SetProperty(PropertyInt.WieldRequirements, (int)WieldRequirement.Level);
                wo.SetProperty(PropertyInt.WieldSkillType, (int)Skill.Axe);  // Set by examples from PCAP data

                switch (tier)
                {
                case 7:
                    wield = 150;     // In this instance, used for indicating player level, rather than skill level
                    break;

                default:
                    wield = 180;     // In this instance, used for indicating player level, rather than skill level
                    break;
                }

                wo.SetProperty(PropertyInt.WieldDifficulty, wield);
            }

            if (armorType == (int)LootTables.ArmorType.CovenantArmor)
            {
                Skill wieldSkill;

                int chance = ThreadSafeRandom.Next(1, 3);
                switch (chance)
                {
                case 1:     // Magic Def
                    wieldSkill = Skill.MagicDefense;
                    break;

                case 2:     // Missile Def
                    wieldSkill = Skill.MissileDefense;
                    break;

                default:     // Melee Def
                    wieldSkill = Skill.MeleeDefense;
                    break;
                }

                wield = GetCovenantWieldReq(tier, wieldSkill);

                wo.SetProperty(PropertyInt.WieldRequirements, (int)WieldRequirement.RawSkill);
                wo.SetProperty(PropertyInt.WieldSkillType, (int)wieldSkill);
                wo.SetProperty(PropertyInt.WieldDifficulty, wield);
            }

            // Setting random color
            wo.SetProperty(PropertyInt.PaletteTemplate, ThreadSafeRandom.Next(1, 2047));
            double shade = .1 * ThreadSafeRandom.Next(0, 9);

            wo.SetProperty(PropertyFloat.Shade, shade);

            var baseArmorLevel = wo.GetProperty(PropertyInt.ArmorLevel) ?? 0;

            if (baseArmorLevel > 0)
            {
                int adjustedArmorLevel = baseArmorLevel + GetArmorLevelModifier(tier, armorType);
                wo.SetProperty(PropertyInt.ArmorLevel, adjustedArmorLevel);
            }

            wo.SetProperty(PropertyInt.EquipmentSetId, equipSetId);

            if (isMagical)
            {
                wo.SetProperty(PropertyInt.UiEffects, (int)UiEffects.Magical);
                int numSpells = GetNumSpells(tier);

                int spellcraft = GetSpellcraft(numSpells, tier);
                wo.SetProperty(PropertyInt.ItemSpellcraft, spellcraft);
                wo.SetProperty(PropertyInt.ItemDifficulty, GetDifficulty(tier, spellcraft));

                int maxMana = GetMaxMana(numSpells, tier);
                wo.SetProperty(PropertyInt.ItemMaxMana, maxMana);
                wo.SetProperty(PropertyInt.ItemCurMana, maxMana);

                int[][] spells;
                int[][] cantrips;

                spells   = LootTables.ArmorSpells;
                cantrips = LootTables.ArmorCantrips;

                int[] shuffledValues = new int[spells.Length];
                for (int i = 0; i < spells.Length; i++)
                {
                    shuffledValues[i] = i;
                }

                Shuffle(shuffledValues);

                int minorCantrips     = GetNumMinorCantrips(tier);
                int majorCantrips     = GetNumMajorCantrips(tier);
                int epicCantrips      = GetNumEpicCantrips(tier);
                int legendaryCantrips = GetNumLegendaryCantrips(tier);
                int numCantrips       = minorCantrips + majorCantrips + epicCantrips + legendaryCantrips;

                if (numSpells - numCantrips > 0)
                {
                    for (int a = 0; a < numSpells - numCantrips; a++)
                    {
                        int col     = ThreadSafeRandom.Next(lowSpellTier - 1, highSpellTier - 1);
                        int spellID = spells[shuffledValues[a]][col];
                        wo.Biota.GetOrAddKnownSpell(spellID, wo.BiotaDatabaseLock, wo.BiotaPropertySpells, out _);
                    }
                }

                if (numCantrips > 0)
                {
                    shuffledValues = new int[cantrips.Length];
                    for (int i = 0; i < cantrips.Length; i++)
                    {
                        shuffledValues[i] = i;
                    }
                    Shuffle(shuffledValues);
                    int shuffledPlace = 0;
                    //minor cantripps
                    for (int a = 0; a < minorCantrips; a++)
                    {
                        int spellID = cantrips[shuffledValues[shuffledPlace]][0];
                        shuffledPlace++;
                        wo.Biota.GetOrAddKnownSpell(spellID, wo.BiotaDatabaseLock, wo.BiotaPropertySpells, out _);
                    }
                    //major cantrips
                    for (int a = 0; a < majorCantrips; a++)
                    {
                        int spellID = cantrips[shuffledValues[shuffledPlace]][1];
                        shuffledPlace++;
                        wo.Biota.GetOrAddKnownSpell(spellID, wo.BiotaDatabaseLock, wo.BiotaPropertySpells, out _);
                    }
                    // epic cantrips
                    for (int a = 0; a < epicCantrips; a++)
                    {
                        int spellID = cantrips[shuffledValues[shuffledPlace]][2];
                        shuffledPlace++;
                        wo.Biota.GetOrAddKnownSpell(spellID, wo.BiotaDatabaseLock, wo.BiotaPropertySpells, out _);
                    }
                    //legendary cantrips
                    for (int a = 0; a < legendaryCantrips; a++)
                    {
                        int spellID = cantrips[shuffledValues[shuffledPlace]][3];
                        shuffledPlace++;
                        wo.Biota.GetOrAddKnownSpell(spellID, wo.BiotaDatabaseLock, wo.BiotaPropertySpells, out _);
                    }
                }
            }
            else
            {
                wo.RemoveProperty(PropertyInt.ItemManaCost);
                wo.RemoveProperty(PropertyInt.ItemMaxMana);
                wo.RemoveProperty(PropertyInt.ItemCurMana);
                wo.RemoveProperty(PropertyInt.ItemSpellcraft);
                wo.RemoveProperty(PropertyInt.ItemDifficulty);
            }

            wo = RandomizeColor(wo);

            return(wo);
        }
        private static WorldObject CreateSocietyArmor(TreasureDeath profile, bool mutate = true)
        {
            int society   = 0;
            int armortype = 0;

            if (profile.TreasureType >= 2971 && profile.TreasureType <= 2980)
            {
                society = 0; // CH
            }
            else if (profile.TreasureType >= 2981 && profile.TreasureType <= 2990)
            {
                society = 1; // EW
            }
            else if (profile.TreasureType >= 2991 && profile.TreasureType <= 3000)
            {
                society = 2; // RB
            }
            switch (profile.TreasureType)
            {
            case 2971:
            case 2981:
            case 2991:
                armortype = 0;     // BP
                break;

            case 2972:
            case 2982:
            case 2992:
                armortype = 1;     // Gauntlets
                break;

            case 2973:
            case 2983:
            case 2993:
                armortype = 2;     // Girth
                break;

            case 2974:
            case 2984:
            case 2994:
                armortype = 3;     // Greaves
                break;

            case 2975:
            case 2985:
            case 2995:
                armortype = 4;     // Helm
                break;

            case 2976:
            case 2986:
            case 2996:
                armortype = 5;     // Pauldrons
                break;

            case 2977:
            case 2987:
            case 2997:
                armortype = 6;     // Tassets
                break;

            case 2978:
            case 2988:
            case 2998:
                armortype = 7;     // Vambraces
                break;

            case 2979:
            case 2989:
            case 2999:
                armortype = 8;     // Sollerets
                break;

            default:
                break;
            }

            int         societyArmorWeenie = LootTables.SocietyArmorMatrix[armortype][society];
            WorldObject wo = WorldObjectFactory.CreateNewWorldObject((uint)societyArmorWeenie);

            if (wo != null && mutate)
            {
                MutateSocietyArmor(wo, profile, true);
            }

            return(wo);
        }