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