Core/Items: PvP item levels basic implementation

This commit is contained in:
hondacrx
2018-03-06 11:34:28 -05:00
parent a596b3f1ea
commit ba8d4661fd
16 changed files with 97 additions and 26 deletions
@@ -156,7 +156,7 @@ namespace Framework.Constants
HoverHeight = ObjectFields.End + 0x0b3, // Size: 1, Flags: Public
MinItemLevelCutoff = ObjectFields.End + 0x0b4, // Size: 1, Flags: Public
MinItemLevel = ObjectFields.End + 0x0b5, // Size: 1, Flags: Public
Maxitemlevel = ObjectFields.End + 0x0b6, // Size: 1, Flags: Public
MaxItemlevel = ObjectFields.End + 0x0b6, // Size: 1, Flags: Public
WildBattlepetLevel = ObjectFields.End + 0x0b7, // Size: 1, Flags: Public
BattlepetCompanionNameTimestamp = ObjectFields.End + 0x0b8, // Size: 1, Flags: Public
InteractSpellid = ObjectFields.End + 0x0b9, // Size: 1, Flags: Public
@@ -690,6 +690,9 @@ namespace Framework.Database
// PvpDifficulty.db2
PrepareStatement(HotfixStatements.SEL_PVP_DIFFICULTY, "SELECT ID, BracketID, MinLevel, MaxLevel, MapID FROM pvp_difficulty ORDER BY ID DESC");
// PvpItem.db2
PrepareStatement(HotfixStatements.SEL_PVP_ITEM, "SELECT ID, ItemID, ItemLevelBonus FROM pvp_item ORDER BY ID DESC");
// PvpReward.db2
PrepareStatement(HotfixStatements.SEL_PVP_REWARD, "SELECT ID, HonorLevel, Prestige, RewardPackID FROM pvp_reward ORDER BY ID DESC");
@@ -1391,6 +1394,8 @@ namespace Framework.Database
SEL_PVP_DIFFICULTY,
SEL_PVP_ITEM,
SEL_PVP_REWARD,
SEL_PVP_TALENT,
+1 -1
View File
@@ -1756,7 +1756,7 @@ namespace Game.BattleGrounds
}
}
public void SetBracket(PVPDifficultyRecord bracketEntry)
public void SetBracket(PvpDifficultyRecord bracketEntry)
{
m_BracketId = bracketEntry.GetBracketId();
SetLevelRange(bracketEntry.MinLevel, bracketEntry.MaxLevel);
@@ -249,7 +249,7 @@ namespace Game.BattleGrounds
}
// create a new Battleground that will really be used to play
public Battleground CreateNewBattleground(BattlegroundTypeId originalBgTypeId, PVPDifficultyRecord bracketEntry, ArenaTypes arenaType, bool isRated)
public Battleground CreateNewBattleground(BattlegroundTypeId originalBgTypeId, PvpDifficultyRecord bracketEntry, ArenaTypes arenaType, bool isRated)
{
BattlegroundTypeId bgTypeId = GetRandomBG(originalBgTypeId);
@@ -55,7 +55,7 @@ namespace Game.BattleGrounds
}
// add group or player (grp == null) to bg queue with the given leader and bg specifications
public GroupQueueInfo AddGroup(Player leader, Group grp, BattlegroundTypeId BgTypeId, PVPDifficultyRecord bracketEntry, ArenaTypes ArenaType, bool isRated, bool isPremade, uint ArenaRating, uint MatchmakerRating, uint arenateamid = 0)
public GroupQueueInfo AddGroup(Player leader, Group grp, BattlegroundTypeId BgTypeId, PvpDifficultyRecord bracketEntry, ArenaTypes ArenaType, bool isRated, bool isPremade, uint ArenaRating, uint MatchmakerRating, uint arenateamid = 0)
{
BattlegroundBracketId bracketId = bracketEntry.GetBracketId();
@@ -776,7 +776,7 @@ namespace Game.BattleGrounds
return;
}
PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketById(bg_template.GetMapId(), bracket_id);
PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketById(bg_template.GetMapId(), bracket_id);
if (bracketEntry == null)
{
Log.outError(LogFilter.Battleground, "Battleground: Update: bg bracket entry not found for map {0} bracket id {1}", bg_template.GetMapId(), bracket_id);
+4 -2
View File
@@ -181,7 +181,8 @@ namespace Game.DataStorage
PowerDisplayStorage = DBReader.Read<PowerDisplayRecord>("PowerDisplay.db2", HotfixStatements.SEL_POWER_DISPLAY);
PowerTypeStorage = DBReader.Read<PowerTypeRecord>("PowerType.db2", HotfixStatements.SEL_POWER_TYPE);
PrestigeLevelInfoStorage = DBReader.Read<PrestigeLevelInfoRecord>("PrestigeLevelInfo.db2", HotfixStatements.SEL_PRESTIGE_LEVEL_INFO, HotfixStatements.SEL_PRESTIGE_LEVEL_INFO_LOCALE);
PVPDifficultyStorage = DBReader.Read<PVPDifficultyRecord>("PVPDifficulty.db2", HotfixStatements.SEL_PVP_DIFFICULTY);
PvpDifficultyStorage = DBReader.Read<PvpDifficultyRecord>("PVPDifficulty.db2", HotfixStatements.SEL_PVP_DIFFICULTY);
PvpItemStorage = DBReader.Read<PvpItemRecord>("PVPItem.db2", HotfixStatements.SEL_PVP_ITEM);
PvpRewardStorage = DBReader.Read<PvpRewardRecord>("PvpReward.db2", HotfixStatements.SEL_PVP_REWARD);
PvpTalentStorage = DBReader.Read<PvpTalentRecord>("PvpTalent.db2", HotfixStatements.SEL_PVP_TALENT, HotfixStatements.SEL_PVP_TALENT_LOCALE);
PvpTalentUnlockStorage = DBReader.Read<PvpTalentUnlockRecord>("PvpTalentUnlock.db2", HotfixStatements.SEL_PVP_TALENT_UNLOCK);
@@ -512,7 +513,8 @@ namespace Game.DataStorage
public static DB6Storage<PowerDisplayRecord> PowerDisplayStorage;
public static DB6Storage<PowerTypeRecord> PowerTypeStorage;
public static DB6Storage<PrestigeLevelInfoRecord> PrestigeLevelInfoStorage;
public static DB6Storage<PVPDifficultyRecord> PVPDifficultyStorage;
public static DB6Storage<PvpDifficultyRecord> PvpDifficultyStorage;
public static DB6Storage<PvpItemRecord> PvpItemStorage;
public static DB6Storage<PvpRewardRecord> PvpRewardStorage;
public static DB6Storage<PvpTalentRecord> PvpTalentStorage;
public static DB6Storage<PvpTalentUnlockRecord> PvpTalentUnlockStorage;
+14 -5
View File
@@ -345,6 +345,9 @@ namespace Game.DataStorage
_powerTypes[powerType.PowerTypeEnum] = powerType;
}
foreach (PvpItemRecord pvpItem in CliDB.PvpItemStorage.Values)
_pvpItemBonus[pvpItem.ItemID] = pvpItem.ItemLevelBonus;
foreach (PvpRewardRecord pvpReward in CliDB.PvpRewardStorage.Values)
_pvpRewardPack[Tuple.Create((uint)pvpReward.Prestige, (uint)pvpReward.HonorLevel)] = pvpReward.RewardPackID;
@@ -1142,10 +1145,10 @@ namespace Game.DataStorage
return max;
}
public PVPDifficultyRecord GetBattlegroundBracketByLevel(uint mapid, uint level)
public PvpDifficultyRecord GetBattlegroundBracketByLevel(uint mapid, uint level)
{
PVPDifficultyRecord maxEntry = null; // used for level > max listed level case
foreach (var entry in CliDB.PVPDifficultyStorage.Values)
PvpDifficultyRecord maxEntry = null; // used for level > max listed level case
foreach (var entry in CliDB.PvpDifficultyStorage.Values)
{
// skip unrelated and too-high brackets
if (entry.MapID != mapid || entry.MinLevel > level)
@@ -1163,9 +1166,9 @@ namespace Game.DataStorage
return maxEntry;
}
public PVPDifficultyRecord GetBattlegroundBracketById(uint mapid, BattlegroundBracketId id)
public PvpDifficultyRecord GetBattlegroundBracketById(uint mapid, BattlegroundBracketId id)
{
foreach (var entry in CliDB.PVPDifficultyStorage.Values)
foreach (var entry in CliDB.PvpDifficultyStorage.Values)
if (entry.MapID == mapid && entry.GetBracketId() == id)
return entry;
@@ -1243,6 +1246,11 @@ namespace Game.DataStorage
return null;
}
public byte GetPvpItemLevelBonus(uint itemId)
{
return _pvpItemBonus.LookupByKey(itemId);
}
public List<RewardPackXItemRecord> GetRewardPackItemsByRewardID(uint rewardPackID)
{
return _rewardPackItems.LookupByKey(rewardPackID);
@@ -1513,6 +1521,7 @@ namespace Game.DataStorage
List<Regex>[] _nameValidators = new List<Regex>[(int)LocaleConstant.Total + 1];
MultiMap<uint, uint> _phasesByGroup = new MultiMap<uint, uint>();
Dictionary<PowerType, PowerTypeRecord> _powerTypes = new Dictionary<PowerType, PowerTypeRecord>();
Dictionary<uint, byte> _pvpItemBonus = new Dictionary<uint, byte>();
Dictionary<Tuple<uint /*prestige level*/, uint /*honor level*/>, uint> _pvpRewardPack = new Dictionary<Tuple<uint, uint>, uint>();
List<PvpTalentRecord>[][][] _pvpTalentsByPosition = new List<PvpTalentRecord>[(int)Class.Max][][];
uint[][] _pvpTalentUnlock = new uint[PlayerConst.MaxPvpTalentTiers][];
+8 -1
View File
@@ -156,7 +156,7 @@ namespace Game.DataStorage
public bool IsDisabled() { return Flags.HasAnyFlag(PrestigeLevelInfoFlags.Disabled); }
}
public sealed class PVPDifficultyRecord
public sealed class PvpDifficultyRecord
{
public uint Id;
public byte BracketID;
@@ -168,6 +168,13 @@ namespace Game.DataStorage
public BattlegroundBracketId GetBracketId() { return (BattlegroundBracketId)BracketID; }
}
public sealed class PvpItemRecord
{
public uint Id;
public uint ItemID;
public byte ItemLevelBonus;
}
public sealed class PvpRewardRecord
{
public uint Id;
+23 -4
View File
@@ -1975,10 +1975,16 @@ namespace Game.Entities
public uint GetItemLevel(Player owner)
{
return GetItemLevel(GetTemplate(), _bonusData, owner.getLevel(), GetModifier(ItemModifier.ScalingStatDistributionFixedLevel), GetModifier(ItemModifier.UpgradeId));
uint minItemLevel = owner.GetUInt32Value(UnitFields.MinItemLevel);
uint minItemLevelCutoff = owner.GetUInt32Value(UnitFields.MinItemLevelCutoff);
uint maxItemLevel = GetTemplate().GetFlags3().HasAnyFlag(ItemFlags3.IgnoreItemLevelCapInPvp) ? 0 : owner.GetUInt32Value(UnitFields.MaxItemlevel);
bool pvpBonus = owner.IsUsingPvpItemLevels();
return GetItemLevel(GetTemplate(), _bonusData, owner.getLevel(), GetModifier(ItemModifier.ScalingStatDistributionFixedLevel), GetModifier(ItemModifier.UpgradeId),
minItemLevel, minItemLevelCutoff, maxItemLevel, pvpBonus);
}
public static uint GetItemLevel(ItemTemplate itemTemplate, BonusData bonusData, uint level, uint fixedLevel, uint upgradeId)
public static uint GetItemLevel(ItemTemplate itemTemplate, BonusData bonusData, uint level, uint fixedLevel, uint upgradeId,
uint minItemLevel, uint minItemLevelCutoff, uint maxItemLevel, bool pvpBonus)
{
if (itemTemplate == null)
return 1;
@@ -2004,12 +2010,25 @@ namespace Game.Entities
itemLevel += (uint)bonusData.ItemLevelBonus;
for (uint i = 0; i < ItemConst.MaxGemSockets; ++i)
itemLevel += bonusData.GemItemLevelBonus[i];
uint itemLevelBeforeUpgrades = itemLevel;
ItemUpgradeRecord upgrade = CliDB.ItemUpgradeStorage.LookupByKey(upgradeId);
if (upgrade != null)
itemLevel += upgrade.ItemLevelBonus;
for (uint i = 0; i < ItemConst.MaxGemSockets; ++i)
itemLevel += bonusData.GemItemLevelBonus[i];
if (pvpBonus)
itemLevel += Global.DB2Mgr.GetPvpItemLevelBonus(itemTemplate.GetId());
if (itemTemplate.GetInventoryType() != InventoryType.NonEquip)
{
if (minItemLevel != 0 && (minItemLevelCutoff == 0 || itemLevelBeforeUpgrades >= minItemLevelCutoff) && itemLevel < minItemLevel)
itemLevel = minItemLevel;
if (maxItemLevel != 0 && itemLevel > maxItemLevel)
itemLevel = maxItemLevel;
}
return Math.Min(Math.Max(itemLevel, 1), 1300);
}
@@ -65,6 +65,7 @@ namespace Game.Entities
uint m_ArenaTeamIdInvited;
long m_lastHonorUpdateTime;
uint m_contestedPvPTimer;
bool _usePvpItemLevels;
//Groups/Raids
GroupReference m_group = new GroupReference();
@@ -6713,5 +6713,23 @@ namespace Game.Entities
return null;
}
//Misc
void UpdateItemLevelAreaBasedScaling()
{
// @todo Activate pvp item levels during world pvp
Map map = GetMap();
bool pvpActivity = map.IsBattlegroundOrArena() || ((int)map.GetEntry().Flags[1]).HasAnyFlag(0x40) || HasPvpRulesEnabled();
if (_usePvpItemLevels != pvpActivity)
{
float healthPct = GetHealthPct();
_RemoveAllItemMods();
ActivatePvpItemLevels(pvpActivity);
_ApplyAllItemMods();
SetHealth(MathFunctions.CalculatePct(GetMaxHealth(), healthPct));
}
// @todo other types of power scaling such as timewalking
}
}
}
@@ -334,6 +334,9 @@ namespace Game.Entities
public uint GetHonorLevel() { return GetUInt32Value(PlayerFields.HonorLevel); }
public bool IsMaxHonorLevelAndPrestige() { return IsMaxPrestige() && GetHonorLevel() == PlayerConst.MaxHonorLevel; }
public void ActivatePvpItemLevels(bool activate) { _usePvpItemLevels = activate; }
public bool IsUsingPvpItemLevels() { return _usePvpItemLevels; }
void ResetPvpTalents()
{
foreach (var talentInfo in CliDB.PvpTalentStorage.Values)
@@ -489,6 +492,8 @@ namespace Game.Entities
aura.SetDuration(-1);
}
}
UpdateItemLevelAreaBasedScaling();
}
void DisablePvpRules()
@@ -498,7 +503,10 @@ namespace Game.Entities
return;
if (GetCombatTimer() == 0)
{
RemoveAurasDueToSpell(PlayerConst.SpellPvpRulesEnabled);
UpdateItemLevelAreaBasedScaling();
}
else
{
Aura aura = GetAura(PlayerConst.SpellPvpRulesEnabled);
+2 -2
View File
@@ -651,7 +651,7 @@ namespace Game.Entities
if (pEnchant.ScalingClass != 0)
{
int scalingClass = pEnchant.ScalingClass;
if ((GetUInt32Value(UnitFields.MinItemLevel) != 0 || GetUInt32Value(UnitFields.Maxitemlevel) != 0) && pEnchant.ScalingClassRestricted != 0)
if ((GetUInt32Value(UnitFields.MinItemLevel) != 0 || GetUInt32Value(UnitFields.MaxItemlevel) != 0) && pEnchant.ScalingClassRestricted != 0)
scalingClass = pEnchant.ScalingClassRestricted;
uint minLevel = ((uint)(pEnchant.Flags)).HasAnyFlag(0x20u) ? 1 : 60u;
@@ -691,7 +691,7 @@ namespace Game.Entities
if (pEnchant.ScalingClass != 0)
{
int scalingClass = pEnchant.ScalingClass;
if ((GetUInt32Value(UnitFields.MinItemLevel) != 0 || GetUInt32Value(UnitFields.Maxitemlevel) != 0) && pEnchant.ScalingClassRestricted != 0)
if ((GetUInt32Value(UnitFields.MinItemLevel) != 0 || GetUInt32Value(UnitFields.MaxItemlevel) != 0) && pEnchant.ScalingClassRestricted != 0)
scalingClass = pEnchant.ScalingClassRestricted;
uint minLevel = ((uint)(pEnchant.Flags)).HasAnyFlag(0x20u) ? 1 : 60u;
+2
View File
@@ -5702,6 +5702,8 @@ namespace Game.Entities
if (_garrison != null)
_garrison.SendRemoteInfo();
UpdateItemLevelAreaBasedScaling();
}
public bool CanSpeak()
+3 -3
View File
@@ -1705,7 +1705,7 @@ namespace Game.Groups
if (!reference)
return GroupJoinBattlegroundResult.JoinFailed;
PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bgOrTemplate.GetMapId(), reference.getLevel());
PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bgOrTemplate.GetMapId(), reference.getLevel());
if (bracketEntry == null)
return GroupJoinBattlegroundResult.JoinFailed;
@@ -1729,7 +1729,7 @@ namespace Game.Groups
return GroupJoinBattlegroundResult.JoinTimedOut;
}
// not in the same Battleground level braket, don't let join
PVPDifficultyRecord memberBracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bracketEntry.MapID, member.getLevel());
PvpDifficultyRecord memberBracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bracketEntry.MapID, member.getLevel());
if (memberBracketEntry != bracketEntry)
return GroupJoinBattlegroundResult.JoinRangeIndex;
// don't let join rated matches if the arena team id doesn't match
@@ -2633,7 +2633,7 @@ namespace Game.Groups
BonusData bonusData = new BonusData(itemInstance);
ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(itemid);
uint itemLevel = Item.GetItemLevel(itemTemplate, bonusData, player.getLevel(), 0, lootItemInSlot.upgradeId);
uint itemLevel = Item.GetItemLevel(itemTemplate, bonusData, player.getLevel(), 0, lootItemInSlot.upgradeId, 0, 0, 0, false);
return Item.GetDisenchantLoot(itemTemplate, (uint)bonusData.Quality, itemLevel);
}
+4 -4
View File
@@ -89,7 +89,7 @@ namespace Game
return;
// expected bracket entry
PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
if (bracketEntry == null)
return;
@@ -302,7 +302,7 @@ namespace Game
bgTypeId = bg.GetTypeID();
// expected bracket entry
PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
if (bracketEntry == null)
return;
@@ -466,7 +466,7 @@ namespace Game
continue;
// expected bracket entry
PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
if (bracketEntry == null)
continue;
@@ -503,7 +503,7 @@ namespace Game
BattlegroundTypeId bgTypeId = bg.GetTypeID();
BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, arenatype);
PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
if (bracketEntry == null)
return;