Ejemplo n.º 1
0
        private static WorldObject CreateRandomScroll(int tier, LootBias lootBias = LootBias.UnBiased)
        {
            WorldObject wo;

            if (tier > 7 || lootBias != LootBias.UnBiased)
            {
                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);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        private static WorldObject CreateArmor(TreasureDeath profile, bool isMagical, bool isArmor, LootBias lootBias = LootBias.UnBiased)
        {
            var minType = LootTables.ArmorType.Helms;
            var maxType = new LootTables.ArmorType();

            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 == true)
            {
                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)
            {
                return(null);
            }

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

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

            int materialType = GetMaterialType(wo, profile.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(profile.Tier);

            wo.SetProperty(PropertyInt.ItemWorkmanship, workmanship);

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

            wo.Value = value;

            int wield;

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

                wield = profile.Tier switch
                {
                    7 => 150, // In this instance, used for indicating player level, rather than skill level
                    _ => 180, // In this instance, used for indicating player level, rather than skill level
                };

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

            if (armorType == LootTables.ArmorType.CovenantArmor)
            {
                int chance     = ThreadSafeRandom.Next(1, 3);
                var wieldSkill = chance switch
                {
                    // Magic Def
                    1 => Skill.MagicDefense,
                    // Missile Def
                    2 => Skill.MissileDefense,
                    // Melee Def
                    _ => Skill.MeleeDefense,
                };
                wield = GetCovenantWieldReq(profile.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);

            wo = AssignArmorLevel(wo, profile.Tier, armorType);

            wo = AssignEquipmentSetId(wo, profile);

            if (isMagical)
            {
                bool covenantArmor = false || (armorType == LootTables.ArmorType.CovenantArmor || armorType == LootTables.ArmorType.OlthoiArmor);
                wo = AssignMagic(wo, profile, covenantArmor);
            }
            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);
        }
Ejemplo n.º 5
0
        public static List <WorldObject> CreateRandomLootObjects(TreasureDeath profile)
        {
            if (!PropertyManager.GetBool("legacy_loot_system").Item)
            {
                return(CreateRandomLootObjects_New(profile));
            }

            stopwatch.Value.Restart();

            try
            {
                int         numItems;
                WorldObject lootWorldObject;

                LootBias lootBias = LootBias.UnBiased;
                var      loot     = new List <WorldObject>();

                switch (profile.TreasureType)
                {
                case 1001:     // Mana Forge Chest, Advanced Equipment Chest, and Mixed Equipment Chest
                case 2001:
                    lootBias = LootBias.MixedEquipment;
                    break;

                case 1002:     // Armor Chest
                case 2002:
                    lootBias = LootBias.Armor;
                    break;

                case 1003:     // Magic Chest
                case 2003:
                    lootBias = LootBias.MagicEquipment;
                    break;

                case 1004:     // Weapon Chest
                case 2004:
                    lootBias = LootBias.Weapons;
                    break;

                default:     // Default to unbiased loot profile
                    break;
                }

                // For Society Armor - Only generates 2 pieces of Society Armor.
                // breaking it out here to Generate Armor
                if (profile.TreasureType >= 2971 && profile.TreasureType <= 2999)
                {
                    numItems = ThreadSafeRandom.Next(profile.MagicItemMinAmount, profile.MagicItemMaxAmount);

                    for (var i = 0; i < numItems; i++)
                    {
                        lootWorldObject = CreateSocietyArmor(profile);
                        if (lootWorldObject != null)
                        {
                            loot.Add(lootWorldObject);
                        }
                    }

                    return(loot);
                }

                var itemChance = ThreadSafeRandom.Next(1, 100);
                if (itemChance <= profile.ItemChance)
                {
                    numItems = ThreadSafeRandom.Next(profile.ItemMinAmount, profile.ItemMaxAmount);

                    for (var i = 0; i < numItems; i++)
                    {
                        // verify this works as intended. this will also be true for MixedEquipment...
                        if (lootBias == LootBias.MagicEquipment)
                        {
                            lootWorldObject = CreateRandomLootObjects(profile, false, LootBias.Weapons);
                        }
                        else
                        {
                            lootWorldObject = CreateRandomLootObjects(profile, false, lootBias);
                        }

                        if (lootWorldObject != null)
                        {
                            loot.Add(lootWorldObject);
                        }
                    }
                }

                itemChance = ThreadSafeRandom.Next(1, 100);
                if (itemChance <= profile.MagicItemChance)
                {
                    numItems = ThreadSafeRandom.Next(profile.MagicItemMinAmount, profile.MagicItemMaxAmount);

                    for (var i = 0; i < numItems; i++)
                    {
                        lootWorldObject = CreateRandomLootObjects(profile, true, lootBias);
                        if (lootWorldObject != null)
                        {
                            loot.Add(lootWorldObject);
                        }
                    }
                }

                itemChance = ThreadSafeRandom.Next(1, 100);
                if (itemChance <= profile.MundaneItemChance)
                {
                    double dropRate    = PropertyManager.GetDouble("aetheria_drop_rate").Item;
                    double dropRateMod = 1.0 / dropRate;

                    // Coalesced Aetheria doesn't drop in loot tiers less than 5
                    // According to wiki, Weapon Mana Forge chests don't drop Aetheria
                    // An Aetheria drop was in addition to the normal drops of the mundane profile
                    // https://asheron.fandom.com/wiki/Announcements_-_2010/04_-_Shedding_Skin :: May 5th, 2010 entry
                    if (profile.Tier > 4 && lootBias != LootBias.Weapons && dropRate > 0)
                    {
                        if (ThreadSafeRandom.Next(1, (int)(100 * dropRateMod)) <= 2)  // base 1% to drop aetheria?
                        {
                            lootWorldObject = CreateAetheria(profile.Tier);
                            if (lootWorldObject != null)
                            {
                                loot.Add(lootWorldObject);
                            }
                        }
                    }

                    numItems = ThreadSafeRandom.Next(profile.MundaneItemMinAmount, profile.MundaneItemMaxAmount);

                    for (var i = 0; i < numItems; i++)
                    {
                        if (lootBias != LootBias.UnBiased)
                        {
                            lootWorldObject = CreateRandomScroll(profile);
                        }
                        else
                        {
                            lootWorldObject = CreateGenericObjects(profile);
                        }

                        if (lootWorldObject != null)
                        {
                            loot.Add(lootWorldObject);
                        }
                    }
                }

                return(loot);
            }
            finally
            {
                ServerPerformanceMonitor.AddToCumulativeEvent(ServerPerformanceMonitor.CumulativeEventHistoryType.LootGenerationFactory_CreateRandomLootObjects, stopwatch.Value.Elapsed.TotalSeconds);
            }
        }
Ejemplo n.º 6
0
        public static WorldObject CreateRandomLootObjects(TreasureDeath profile, bool isMagical, LootBias lootBias = LootBias.UnBiased)
        {
            WorldObject wo = null;

            var treasureItemTypeChances = isMagical ? TreasureItemTypeChances.DefaultMagical : TreasureItemTypeChances.DefaultNonMagical;

            switch (lootBias)
            {
            case LootBias.Armor:
                treasureItemTypeChances = TreasureItemTypeChances.Armor;
                break;

            case LootBias.Weapons:
                treasureItemTypeChances = TreasureItemTypeChances.Weapons;
                break;

            case LootBias.Jewelry:
                treasureItemTypeChances = TreasureItemTypeChances.Jewelry;
                break;

            case LootBias.MagicEquipment:
            case LootBias.MixedEquipment:
                treasureItemTypeChances = TreasureItemTypeChances.MixedMagicEquipment;
                break;
            }

            var treasureItemType = treasureItemTypeChances.Roll();

            switch (treasureItemType)
            {
            case TreasureItemType.Gem:
                wo = CreateGem(profile, isMagical);
                break;

            case TreasureItemType.Armor:
                wo = CreateArmor(profile, isMagical, true, lootBias);
                break;

            case TreasureItemType.Clothing:
                wo = CreateArmor(profile, isMagical, false, lootBias);
                break;

            case TreasureItemType.Cloak:
                wo = CreateCloak(profile);
                break;

            case TreasureItemType.Weapon:
                wo = CreateWeapon(profile, isMagical);
                break;

            case TreasureItemType.Jewelry:
                wo = CreateJewelry(profile, isMagical);
                break;

            case TreasureItemType.Dinnerware:
                // Added Dinnerware at tail end of distribution, as
                // they are mutable loot drops that don't belong with the non-mutable drops
                // TODO: Will likely need some adjustment/fine tuning
                wo = CreateDinnerware(profile, isMagical);
                break;
            }
            return(wo);
        }
        private static WorldObject CreateArmor(int tier, bool isMagical, LootBias lootBias = LootBias.UnBiased)
        {
            int equipSetId = 0;

            int materialType = 0;

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

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

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

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

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

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

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

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

            default:
                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 = AssignMagic(wo, tier);
            }
            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);
        }
Ejemplo n.º 8
0
        private static WorldObject CreateArmor(int tier, bool isMagical, LootBias lootBias = LootBias.UnBiased)
        {
            var minType = LootTables.ArmorType.MiscClothing;
            var maxType = new LootTables.ArmorType();

            switch (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;

                // armor Mana Forge Chests don't include clothing type items
                if (lootBias == LootBias.Armor)
                {
                    minType = LootTables.ArmorType.Helms;
                }
                break;
            }

            var armorType = (LootTables.ArmorType)ThreadSafeRandom.Next((int)minType, (int)maxType);

            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)
            {
                return(null);
            }

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

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

            int 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 != 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 == 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);

            wo = AssignArmorLevel(wo, tier, armorType);

            wo = AssignEquipmentSetId(wo, tier);

            if (isMagical)
            {
                wo = AssignMagic(wo, tier);
            }
            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 CreateArmor(int tier, bool isMagical, bool isArmor, LootBias lootBias = LootBias.UnBiased)
        {
            var minType = LootTables.ArmorType.Helms;
            var maxType = new LootTables.ArmorType();

            switch (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 == true)
            {
                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)
            {
                return(null);
            }

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

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

            int 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);