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