Updated DB2 structs

This commit is contained in:
hondacrx
2018-02-26 13:13:54 -05:00
parent 0a3dfaba37
commit 82dca6de94
61 changed files with 2639 additions and 2517 deletions
+214 -154
View File
@@ -1580,158 +1580,166 @@ namespace Game.Entities
return true;
}
// used by mail items, transmog cost, stationeryinfo and others
static uint GetSellPrice(ItemTemplate proto, out bool normalSellPrice)
uint GetBuyPrice(Player owner, out bool standardPrice)
{
normalSellPrice = true;
if (proto.GetFlags2().HasAnyFlag(ItemFlags2.OverrideGoldCost))
{
return proto.GetBuyPrice();
}
else
{
var qualityPrice = CliDB.ImportPriceQualityStorage.LookupByKey(proto.GetQuality() + 1);
var basePrice = CliDB.ItemPriceBaseStorage.LookupByKey(proto.GetBaseItemLevel());
if (qualityPrice == null || basePrice == null)
return 0;
float qualityFactor = qualityPrice.Factor;
float baseFactor = 0.0f;
var inventoryType = proto.GetInventoryType();
if (inventoryType == InventoryType.Weapon ||
inventoryType == InventoryType.Weapon2Hand ||
inventoryType == InventoryType.WeaponMainhand ||
inventoryType == InventoryType.WeaponOffhand ||
inventoryType == InventoryType.Ranged ||
inventoryType == InventoryType.Thrown ||
inventoryType == InventoryType.RangedRight)
baseFactor = basePrice.WeaponFactor;
else
baseFactor = basePrice.ArmorFactor;
if (inventoryType == InventoryType.Robe)
inventoryType = InventoryType.Chest;
float typeFactor = 0.0f;
sbyte weapType = -1;
switch (inventoryType)
{
case InventoryType.Head:
case InventoryType.Shoulders:
case InventoryType.Chest:
case InventoryType.Waist:
case InventoryType.Legs:
case InventoryType.Feet:
case InventoryType.Wrists:
case InventoryType.Hands:
case InventoryType.Cloak:
{
var armorPrice = CliDB.ImportPriceArmorStorage.LookupByKey(inventoryType);
if (armorPrice == null)
return 0;
switch ((ItemSubClassArmor)proto.GetSubClass())
{
case ItemSubClassArmor.Miscellaneous:
case ItemSubClassArmor.Cloth:
typeFactor = armorPrice.ClothFactor;
break;
case ItemSubClassArmor.Leather:
typeFactor = armorPrice.LeatherFactor;
break;
case ItemSubClassArmor.Mail:
typeFactor = armorPrice.MailFactor;
break;
case ItemSubClassArmor.Plate:
typeFactor = armorPrice.PlateFactor;
break;
default:
return 0;
}
break;
}
case InventoryType.Shield:
{
var shieldPrice = CliDB.ImportPriceShieldStorage.LookupByKey(1); // it only has two rows, it's unclear which is the one used
if (shieldPrice == null)
return 0;
typeFactor = shieldPrice.Factor;
break;
}
case InventoryType.WeaponMainhand:
weapType = 0;
break;
case InventoryType.WeaponOffhand:
weapType = 1;
break;
case InventoryType.Weapon:
weapType = 2;
break;
case InventoryType.Weapon2Hand:
weapType = 3;
break;
case InventoryType.Ranged:
case InventoryType.RangedRight:
case InventoryType.Relic:
weapType = 4;
break;
default:
return proto.GetBuyPrice();
}
if (weapType != -1)
{
var weaponPrice = CliDB.ImportPriceWeaponStorage.LookupByKey(weapType + 1);
if (weaponPrice == null)
return 0;
typeFactor = weaponPrice.Factor;
}
normalSellPrice = false;
return (uint)(qualityFactor * proto.GetUnk2() * proto.GetUnk1() * typeFactor * baseFactor);
}
return GetBuyPrice(GetTemplate(), (uint)GetQuality(), GetItemLevel(owner), out standardPrice);
}
public static uint GetSpecialPrice(ItemTemplate proto, uint minimumPrice = 10000)
static uint GetBuyPrice(ItemTemplate proto, uint quality, uint itemLevel, out bool standardPrice)
{
uint cost = 0;
standardPrice = true;
if (proto.GetFlags2().HasAnyFlag(ItemFlags2.OverrideGoldCost))
cost = proto.GetSellPrice();
else
{
bool normalPrice;
cost = GetSellPrice(proto, out normalPrice);
return proto.GetBuyPrice();
if (!normalPrice)
{
if (proto.GetBuyCount() <= 1)
{
var classEntry = Global.DB2Mgr.GetItemClassByOldEnum(proto.GetClass());
if (classEntry != null)
cost *= (uint)classEntry.PriceMod;
else
cost = 0;
}
else
cost /= 4 * proto.GetBuyCount();
}
else
cost = proto.GetSellPrice();
var qualityPrice = CliDB.ImportPriceQualityStorage.LookupByKey(quality + 1);
if (qualityPrice == null)
return 0;
var basePrice = CliDB.ItemPriceBaseStorage.LookupByKey(proto.GetBaseItemLevel());
if (basePrice == null)
return 0;
float qualityFactor = qualityPrice.Factor;
float baseFactor = 0.0f;
var inventoryType = proto.GetInventoryType();
if (inventoryType == InventoryType.Weapon ||
inventoryType == InventoryType.Weapon2Hand ||
inventoryType == InventoryType.WeaponMainhand ||
inventoryType == InventoryType.WeaponOffhand ||
inventoryType == InventoryType.Ranged ||
inventoryType == InventoryType.Thrown ||
inventoryType == InventoryType.RangedRight)
baseFactor = basePrice.WeaponFactor;
else
baseFactor = basePrice.ArmorFactor;
if (inventoryType == InventoryType.Robe)
inventoryType = InventoryType.Chest;
if (proto.GetClass() == ItemClass.Gem && (ItemSubClassGem)proto.GetSubClass() == ItemSubClassGem.ArtifactRelic)
{
inventoryType = InventoryType.Weapon;
baseFactor = basePrice.WeaponFactor / 3.0f;
}
if (cost < minimumPrice)
cost = minimumPrice;
return cost;
float typeFactor = 0.0f;
sbyte weapType = -1;
switch (inventoryType)
{
case InventoryType.Head:
case InventoryType.Neck:
case InventoryType.Shoulders:
case InventoryType.Chest:
case InventoryType.Waist:
case InventoryType.Legs:
case InventoryType.Feet:
case InventoryType.Wrists:
case InventoryType.Hands:
case InventoryType.Finger:
case InventoryType.Trinket:
case InventoryType.Cloak:
case InventoryType.Holdable:
{
var armorPrice = CliDB.ImportPriceArmorStorage.LookupByKey(inventoryType);
if (armorPrice == null)
return 0;
switch ((ItemSubClassArmor)proto.GetSubClass())
{
case ItemSubClassArmor.Miscellaneous:
case ItemSubClassArmor.Cloth:
typeFactor = armorPrice.ClothFactor;
break;
case ItemSubClassArmor.Leather:
typeFactor = armorPrice.LeatherFactor;
break;
case ItemSubClassArmor.Mail:
typeFactor = armorPrice.MailFactor;
break;
case ItemSubClassArmor.Plate:
typeFactor = armorPrice.PlateFactor;
break;
default:
typeFactor = 1.0f;
break;
}
break;
}
case InventoryType.Shield:
{
var shieldPrice = CliDB.ImportPriceShieldStorage.LookupByKey(2); // it only has two rows, it's unclear which is the one used
if (shieldPrice == null)
return 0;
typeFactor = shieldPrice.Factor;
break;
}
case InventoryType.WeaponMainhand:
weapType = 0;
break;
case InventoryType.WeaponOffhand:
weapType = 1;
break;
case InventoryType.Weapon:
weapType = 2;
break;
case InventoryType.Weapon2Hand:
weapType = 3;
break;
case InventoryType.Ranged:
case InventoryType.RangedRight:
case InventoryType.Relic:
weapType = 4;
break;
default:
return proto.GetBuyPrice();
}
if (weapType != -1)
{
var weaponPrice = CliDB.ImportPriceWeaponStorage.LookupByKey(weapType + 1);
if (weaponPrice == null)
return 0;
typeFactor = weaponPrice.Factor;
}
standardPrice = false;
return (uint)(proto.GetUnk2() * typeFactor * baseFactor * qualityFactor * proto.GetUnk1());
}
public uint GetSellPrice(Player owner)
{
return GetSellPrice(GetTemplate(), (uint)GetQuality(), GetItemLevel(owner));
}
public static uint GetSellPrice(ItemTemplate proto, uint quality, uint itemLevel)
{
if (proto.GetFlags2().HasAnyFlag(ItemFlags2.OverrideGoldCost))
return proto.GetSellPrice();
bool standardPrice;
uint cost = GetBuyPrice(proto, quality, itemLevel, out standardPrice);
if (standardPrice)
{
ItemClassRecord classEntry = Global.DB2Mgr.GetItemClassByOldEnum(proto.GetClass());
if (classEntry != null)
{
uint buyCount = Math.Max(proto.GetBuyCount(), 1u);
return (uint)(cost * classEntry.PriceMod / buyCount);
}
return 0;
}
else
return proto.GetSellPrice();
}
public int GetReforgableStat(ItemModType statType)
@@ -1967,35 +1975,41 @@ namespace Game.Entities
public uint GetItemLevel(Player owner)
{
ItemTemplate stats = GetTemplate();
if (stats == null)
return GetItemLevel(GetTemplate(), _bonusData, owner.getLevel(), GetModifier(ItemModifier.ScalingStatDistributionFixedLevel), GetModifier(ItemModifier.UpgradeId));
}
public static uint GetItemLevel(ItemTemplate itemTemplate, BonusData bonusData, uint level, uint fixedLevel, uint upgradeId)
{
if (itemTemplate == null)
return 1;
uint itemLevel = stats.GetBaseItemLevel();
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(GetScalingStatDistribution());
uint itemLevel = itemTemplate.GetBaseItemLevel();
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(bonusData.ScalingStatDistribution);
if (ssd != null)
{
uint level = owner.getLevel();
uint fixedLevel = GetModifier(ItemModifier.ScalingStatDistributionFixedLevel);
if (fixedLevel != 0)
level = fixedLevel;
else
level = Math.Min(Math.Max(level, ssd.MinLevel), ssd.MaxLevel);
SandboxScalingRecord sandbox = CliDB.SandboxScalingStorage.LookupByKey(bonusData.SandboxScalingId);
if (sandbox != null)
if ((Convert.ToBoolean(sandbox.Flags & 2) || sandbox.MinLevel != 0 || sandbox.MaxLevel != 0) && !Convert.ToBoolean(sandbox.Flags & 4))
level = Math.Min(Math.Max(level, sandbox.MinLevel), sandbox.MaxLevel);
uint heirloomIlvl = (uint)Global.DB2Mgr.GetCurveValueAt(ssd.ItemLevelCurveID, level);
if (heirloomIlvl != 0)
itemLevel = heirloomIlvl;
}
itemLevel += (uint)_bonusData.ItemLevelBonus;
itemLevel += (uint)bonusData.ItemLevelBonus;
ItemUpgradeRecord upgrade = CliDB.ItemUpgradeStorage.LookupByKey(GetModifier(ItemModifier.UpgradeId));
ItemUpgradeRecord upgrade = CliDB.ItemUpgradeStorage.LookupByKey(upgradeId);
if (upgrade != null)
itemLevel += upgrade.ItemLevelBonus;
for (uint i = 0; i < ItemConst.MaxGemSockets; ++i)
itemLevel += _bonusData.GemItemLevelBonus[i];
itemLevel += bonusData.GemItemLevelBonus[i];
return Math.Min(Math.Max(itemLevel, 1), 1300);
}
@@ -2018,6 +2032,48 @@ namespace Game.Entities
return _bonusData.ItemStatValue[index];
}
public ItemDisenchantLootRecord GetDisenchantLoot(Player owner)
{
return GetDisenchantLoot(GetTemplate(), (uint)GetQuality(), GetItemLevel(owner));
}
public static ItemDisenchantLootRecord GetDisenchantLoot(ItemTemplate itemTemplate, uint quality, uint itemLevel)
{
if (itemTemplate.GetFlags().HasAnyFlag(ItemFlags.Conjured | ItemFlags.NoDisenchant) || itemTemplate.GetBonding() == ItemBondingType.Quest)
return null;
if (itemTemplate.GetArea() != 0 || itemTemplate.GetMap() != 0 || itemTemplate.GetMaxStackSize() > 1)
return null;
if (GetSellPrice(itemTemplate, quality, itemLevel) == 0 && !Global.DB2Mgr.HasItemCurrencyCost(itemTemplate.GetId()))
return null;
byte itemClass = (byte)itemTemplate.GetClass();
uint itemSubClass = itemTemplate.GetSubClass();
byte expansion = itemTemplate.GetRequiredExpansion();
foreach (ItemDisenchantLootRecord disenchant in CliDB.ItemDisenchantLootStorage.Values)
{
if (disenchant.ItemClass != itemClass)
continue;
if (disenchant.ItemSubClass >= 0 && itemSubClass != 0)
continue;
if (disenchant.ItemQuality != quality)
continue;
if (disenchant.MinItemLevel > itemLevel || disenchant.MaxItemLevel < itemLevel)
continue;
if (disenchant.Expansion != -2 && disenchant.Expansion != expansion)
continue;
return disenchant;
}
return null;
}
public uint GetDisplayId(Player owner)
{
ItemModifier transmogModifier = ItemModifier.TransmogAppearanceAllSpecs;
@@ -2535,8 +2591,6 @@ namespace Game.Entities
public uint GetScriptId() { return GetTemplate().ScriptId; }
public uint GetSpecialPrice(uint minimumPrice = 10000) { return GetSpecialPrice(GetTemplate(), minimumPrice); }
public ObjectGuid GetChildItem() { return m_childItem; }
public void SetChildItem(ObjectGuid childItem) { m_childItem = childItem; }
@@ -2804,6 +2858,7 @@ namespace Game.Entities
if (values[1] < _state.ScalingStatDistributionPriority)
{
ScalingStatDistribution = (uint)values[0];
SandboxScalingId = (uint)values[2];
_state.ScalingStatDistributionPriority = values[1];
}
break;
@@ -2813,6 +2868,9 @@ namespace Game.Entities
case ItemBonusType.RelicType:
RelicType = values[0];
break;
case ItemBonusType.OverrideRequiredLevel:
RequiredLevel = values[0];
break;
}
}
@@ -2828,6 +2886,8 @@ namespace Game.Entities
public uint AppearanceModID;
public float RepairCostMultiplier;
public uint ScalingStatDistribution;
public uint SandboxScalingId;
public uint DisenchantLootId;
public uint[] GemItemLevelBonus = new uint[ItemConst.MaxGemSockets];
public int[] GemRelicType = new int[ItemConst.MaxGemSockets];
public ushort[] GemRelicRankBonus = new ushort[ItemConst.MaxGemSockets];
+3 -4
View File
@@ -237,9 +237,9 @@ namespace Game.Entities
public uint GetBuyCount() { return Math.Max(ExtendedData.BuyCount, 1u); }
public uint GetBuyPrice() { return ExtendedData.BuyPrice; }
public uint GetSellPrice() { return ExtendedData.SellPrice; }
public InventoryType GetInventoryType() { return (InventoryType)ExtendedData.inventoryType; }
public InventoryType GetInventoryType() { return ExtendedData.inventoryType; }
public int GetAllowableClass() { return ExtendedData.AllowableClass; }
public int GetAllowableRace() { return ExtendedData.AllowableRace; }
public long GetAllowableRace() { return ExtendedData.AllowableRace; }
public uint GetBaseItemLevel() { return ExtendedData.ItemLevel; }
public int GetBaseRequiredLevel() { return ExtendedData.RequiredLevel; }
public uint GetRequiredSkill() { return ExtendedData.RequiredSkill; }
@@ -297,6 +297,7 @@ namespace Game.Entities
public HolidayIds GetHolidayID() { return (HolidayIds)ExtendedData.HolidayID; }
public float GetStatScalingFactor() { return ExtendedData.StatScalingFactor; }
public byte GetArtifactID() { return ExtendedData.ArtifactID; }
public byte GetRequiredExpansion() { return ExtendedData.RequiredExpansion; }
public bool IsCurrencyToken() { return (GetBagFamily() & BagFamilyMask.CurrencyTokens) != 0; }
@@ -321,8 +322,6 @@ namespace Game.Entities
// extra fields, not part of db2 files
public uint ScriptId;
public uint DisenchantID;
public uint RequiredDisenchantSkill;
public uint FoodType;
public uint MinMoneyLoot;
public uint MaxMoneyLoot;
+3 -3
View File
@@ -3046,7 +3046,7 @@ namespace Game.Entities
float bubble0 = 0.031f;
//speed collect rest bonus in offline, in logout, in tavern, city (section/in hour)
float bubble1 = 0.125f;
float bubble = result.Read<byte>(32) > 0
float bubble = result.Read<byte>(33) > 0
? bubble1 * WorldConfig.GetFloatValue(WorldCfg.RateRestOfflineInTavernOrCity)
: bubble0 * WorldConfig.GetFloatValue(WorldCfg.RateRestOfflineInWilderness);
@@ -3125,7 +3125,7 @@ namespace Game.Entities
stmt.AddValue(index++, transLowGUID);
StringBuilder ss = new StringBuilder();
for (byte i = 0; i < PlayerConst.TaxiMaskSize; ++i)
for (int i = 0; i < PlayerConst.TaxiMaskSize; ++i)
ss.Append(m_taxi.m_taximask[i] + " ");
stmt.AddValue(index++, ss.ToString());
@@ -3274,7 +3274,7 @@ namespace Game.Entities
stmt.AddValue(index++, transLowGUID);
StringBuilder ss = new StringBuilder();
for (byte i = 0; i < PlayerConst.TaxiMaskSize; ++i)
for (int i = 0; i < PlayerConst.TaxiMaskSize; ++i)
ss.Append(m_taxi.m_taximask[i] + " ");
stmt.AddValue(index++, ss.ToString());
+3 -3
View File
@@ -1476,7 +1476,7 @@ namespace Game.Entities
if (Convert.ToBoolean(proto.GetFlags2() & ItemFlags2.FactionAlliance) && GetTeam() != Team.Alliance)
return InventoryResult.CantEquipEver;
if ((proto.GetAllowableClass() & getClassMask()) == 0 || (proto.GetAllowableRace() & getRaceMask()) == 0)
if ((proto.GetAllowableClass() & getClassMask()) == 0 || (proto.GetAllowableRace() & (long)getRaceMask()) == 0)
return InventoryResult.CantEquipEver;
if (proto.GetRequiredSkill() != 0)
@@ -3323,7 +3323,7 @@ namespace Game.Entities
return InventoryResult.ItemNotFound;
// Used by group, function GroupLoot, to know if a prototype can be used by a player
if ((proto.GetAllowableClass() & getClassMask()) == 0 || (proto.GetAllowableRace() & getRaceMask()) == 0)
if ((proto.GetAllowableClass() & getClassMask()) == 0 || (proto.GetAllowableRace() & (long)getRaceMask()) == 0)
return InventoryResult.CantEquipEver;
if (proto.GetRequiredSpell() != 0 && !HasSpell(proto.GetRequiredSpell()))
@@ -6320,7 +6320,7 @@ namespace Game.Entities
switch (loot_type)
{
case LootType.Disenchanting:
loot.FillLoot(item.GetTemplate().DisenchantID, LootStorage.Disenchant, this, true);
loot.FillLoot(item.GetDisenchantLoot(this).Id, LootStorage.Disenchant, this, true);
break;
case LootType.Prospecting:
loot.FillLoot(item.GetEntry(), LootStorage.Prospecting, this, true);
+1 -1
View File
@@ -1382,7 +1382,7 @@ namespace Game.Entities
if (reqraces == -1)
return true;
if ((reqraces & getRaceMask()) == 0)
if ((reqraces & (long)getRaceMask()) == 0)
{
if (msg)
{
+1 -1
View File
@@ -1573,7 +1573,7 @@ namespace Game.Entities
void LearnSkillRewardedSpells(uint skillId, uint skillValue)
{
uint raceMask = getRaceMask();
ulong raceMask = getRaceMask();
uint classMask = getClassMask();
foreach (var ability in CliDB.SkillLineAbilityStorage.Values)
{
+2 -2
View File
@@ -5330,7 +5330,7 @@ namespace Game.Entities
if (pet)
pet.SynchronizeLevelWithOwner();
MailLevelReward mailReward = Global.ObjectMgr.GetMailLevelReward(level, getRaceMask());
MailLevelReward mailReward = Global.ObjectMgr.GetMailLevelReward(level, (uint)getRaceMask());
if (mailReward != null)
{
//- TODO: Poor design of mail system
@@ -7057,7 +7057,7 @@ namespace Game.Entities
}
public bool IsSpellFitByClassAndRace(uint spell_id)
{
uint racemask = getRaceMask();
ulong racemask = getRaceMask();
uint classmask = getClassMask();
var bounds = Global.SpellMgr.GetSkillLineAbilityMapBounds(spell_id);
+5 -1
View File
@@ -4185,7 +4185,11 @@ namespace Game.Entities
if (castItem != null)
{
castItemGuid = castItem.GetGUID();
castItemLevel = (int)castItem.GetItemLevel(castItem.GetOwner());
Player owner = castItem.GetOwner();
if (owner)
castItemLevel = (int)castItem.GetItemLevel(owner);
else if (castItem.GetOwnerGUID() == caster.GetGUID())
castItemLevel = (int)castItem.GetItemLevel(caster.ToPlayer());
}
// find current aura from spell and change it's stackamount, or refresh it's duration
+2 -2
View File
@@ -2126,9 +2126,9 @@ namespace Game.Entities
{
return (Race)GetByteValue(UnitFields.Bytes0, 0);
}
public uint getRaceMask()
public ulong getRaceMask()
{
return (uint)(1 << ((int)GetRace() - 1));
return (1ul << ((int)GetRace() - 1));
}
public Class GetClass()
{