aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-01-24 15:56:10 +0100
committerShauren <shauren.trinity@gmail.com>2016-05-20 23:46:17 +0200
commit5c2c9a684f1458da0cea1f3536622add77ef1324 (patch)
treed3a2a349e8bed9a31cf417ce93830d508ecea46b /src/server/game/Entities
parent65c0a0ee4d5c299f3caab04b6cb3fcd7a4a93e2e (diff)
Core/DataStores: Updated dbc/db2 to 7.0.1.20810
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp12
-rw-r--r--src/server/game/Entities/Item/Item.cpp184
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.cpp2
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.cpp52
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.h37
-rw-r--r--src/server/game/Entities/Object/Object.cpp7
-rw-r--r--src/server/game/Entities/Object/Object.h1
-rw-r--r--src/server/game/Entities/Player/Player.cpp306
-rw-r--r--src/server/game/Entities/Player/Player.h59
-rw-r--r--src/server/game/Entities/Taxi/TaxiPathGraph.cpp4
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp27
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp78
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
13 files changed, 326 insertions, 445 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 42d7ff404db..9c524413aba 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2052,8 +2052,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec))
- if (modelData->StateDamaged.DisplayID)
- modelId = modelData->StateDamaged.DisplayID;
+ if (modelData->StateDamagedDisplayID)
+ modelId = modelData->StateDamagedDisplayID;
SetDisplayId(modelId);
if (setHealth)
@@ -2080,8 +2080,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec))
- if (modelData->StateDestroyed.DisplayID)
- modelId = modelData->StateDestroyed.DisplayID;
+ if (modelData->StateDestroyedDisplayID)
+ modelId = modelData->StateDestroyedDisplayID;
SetDisplayId(modelId);
if (setHealth)
@@ -2099,8 +2099,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec))
- if (modelData->StateRebuilding.DisplayID)
- modelId = modelData->StateRebuilding.DisplayID;
+ if (modelData->StateRebuildingDisplayID)
+ modelId = modelData->StateRebuildingDisplayID;
SetDisplayId(modelId);
// restores to full health
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 20f1772ef00..3eba4d58d80 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -78,28 +78,29 @@ void AddItemsSetItem(Player* player, Item* item)
++eff->EquippedItemCount;
- ItemSetSpells& spells = sItemSetSpellsStore[setid];
-
- for (ItemSetSpellEntry const* itemSetSpell : spells)
+ if (std::vector<ItemSetSpellEntry const*> const* itemSetSpells = sDB2Manager.GetItemSetSpells(setid))
{
- //not enough for spell
- if (itemSetSpell->Threshold > eff->EquippedItemCount)
- continue;
+ for (ItemSetSpellEntry const* itemSetSpell : *itemSetSpells)
+ {
+ //not enough for spell
+ if (itemSetSpell->Threshold > eff->EquippedItemCount)
+ continue;
- if (eff->SetBonuses.count(itemSetSpell))
- continue;
+ if (eff->SetBonuses.count(itemSetSpell))
+ continue;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemSetSpell->SpellID);
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.player.items", "WORLD: unknown spell id %u in items set %u effects", itemSetSpell->SpellID, setid);
- continue;
- }
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemSetSpell->SpellID);
+ if (!spellInfo)
+ {
+ TC_LOG_ERROR("entities.player.items", "WORLD: unknown spell id %u in items set %u effects", itemSetSpell->SpellID, setid);
+ continue;
+ }
- eff->SetBonuses.insert(itemSetSpell);
- // spell cast only if fit form requirement, in other case will cast at form change
- if (!itemSetSpell->ChrSpecID || itemSetSpell->ChrSpecID == player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID))
- player->ApplyEquipSpell(spellInfo, NULL, true);
+ eff->SetBonuses.insert(itemSetSpell);
+ // spell cast only if fit form requirement, in other case will cast at form change
+ if (!itemSetSpell->ChrSpecID || itemSetSpell->ChrSpecID == player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID))
+ player->ApplyEquipSpell(spellInfo, NULL, true);
+ }
}
}
@@ -132,18 +133,20 @@ void RemoveItemsSetItem(Player* player, ItemTemplate const* proto)
--eff->EquippedItemCount;
- ItemSetSpells const& spells = sItemSetSpellsStore[setid];
- for (ItemSetSpellEntry const* itemSetSpell : spells)
+ if (std::vector<ItemSetSpellEntry const*> const* itemSetSpells = sDB2Manager.GetItemSetSpells(setid))
{
- // enough for spell
- if (itemSetSpell->Threshold <= eff->EquippedItemCount)
- continue;
+ for (ItemSetSpellEntry const* itemSetSpell : *itemSetSpells)
+ {
+ // enough for spell
+ if (itemSetSpell->Threshold <= eff->EquippedItemCount)
+ continue;
- if (!eff->SetBonuses.count(itemSetSpell))
- continue;
+ if (!eff->SetBonuses.count(itemSetSpell))
+ continue;
- player->ApplyEquipSpell(sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID), nullptr, false);
- eff->SetBonuses.erase(itemSetSpell);
+ player->ApplyEquipSpell(sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID), nullptr, false);
+ eff->SetBonuses.erase(itemSetSpell);
+ }
}
if (!eff->EquippedItemCount) //all items of a set were removed
@@ -373,6 +376,21 @@ void Item::SaveToDB(SQLTransaction& trans)
stmt->setUInt64(1, GetGUID().GetCounter());
trans->Append(stmt);
}
+ if (!GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).empty())
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_GEMS);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_INSTANCE_GEMS);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ uint32 i = 0;
+ for (; i < MAX_GEM_SOCKETS && i < GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).size(); ++i)
+ stmt->setUInt32(1 + i, GetDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, i));
+ for (; i < MAX_GEM_SOCKETS; ++i)
+ stmt->setUInt32(1 + i, 0);
+ trans->Append(stmt);
+ }
break;
}
case ITEM_REMOVED:
@@ -381,6 +399,10 @@ void Item::SaveToDB(SQLTransaction& trans)
stmt->setUInt64(0, GetGUID().GetCounter());
trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_GEMS);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ trans->Append(stmt);
+
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
@@ -413,7 +435,9 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
// 0 1 2 3 4 5 6 7 8 9 10 11 12
//result = CharacterDatabase.PQuery("SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text,
// 13 14 15 16 17 18 19 20
- // transmogrification, upgradeId, enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, bonusListIDs FROM item_instance WHERE guid = '%u'", guid);
+ // transmogrification, upgradeId, enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, bonusListIDs,
+ // 21 22 23
+ // gemItemId1, gemItemId2, gemItemId3 FROM item_instance WHERE guid = '%u'", guid);
// create item before any checks for store correct guid
// and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB
@@ -493,6 +517,17 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL, fields[18].GetUInt16());
SetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID, fields[19].GetUInt32());
+ uint32 gemItemIds[3] = { fields[21].GetUInt32(), fields[22].GetUInt32(), fields[23].GetUInt32() };
+ if (gemItemIds[0] || gemItemIds[1] || gemItemIds[2])
+ {
+ // gem slots must be preserved, hence funky logic
+ AddDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, gemItemIds[0]);
+ if (gemItemIds[1] || gemItemIds[2])
+ AddDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, gemItemIds[1]);
+ if (gemItemIds[2])
+ AddDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, gemItemIds[2]);
+ }
+
Tokenizer bonusListIDs(fields[20].GetString(), ' ');
for (char const* token : bonusListIDs)
{
@@ -582,27 +617,25 @@ int32 Item::GenerateItemRandomPropertyId(uint32 item_id)
if (itemProto->GetRandomProperty())
{
uint32 randomPropId = GetItemEnchantMod(itemProto->GetRandomProperty());
- ItemRandomPropertiesEntry const* random_id = sItemRandomPropertiesStore.LookupEntry(randomPropId);
- if (!random_id)
+ if (!sItemRandomPropertiesStore.LookupEntry(randomPropId))
{
TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in 'ItemRandomProperties.dbc'", randomPropId);
return 0;
}
- return random_id->ID;
+ return randomPropId;
}
// RandomSuffix case
else
{
uint32 randomPropId = GetItemEnchantMod(itemProto->GetRandomSuffix());
- ItemRandomSuffixEntry const* random_id = sItemRandomSuffixStore.LookupEntry(randomPropId);
- if (!random_id)
+ if (!sItemRandomSuffixStore.LookupEntry(randomPropId))
{
TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in sItemRandomSuffixStore.", randomPropId);
return 0;
}
- return -int32(random_id->ID);
+ return -int32(randomPropId);
}
}
@@ -613,12 +646,12 @@ void Item::SetItemRandomProperties(int32 randomPropId)
if (randomPropId > 0)
{
- ItemRandomPropertiesEntry const* item_rand = sItemRandomPropertiesStore.LookupEntry(randomPropId);
- if (item_rand)
+ ItemRandomPropertiesEntry const* item_rand = sItemRandomPropertiesStore.LookupEntry(-randomPropId);
+ if (sItemRandomPropertiesStore.LookupEntry(randomPropId))
{
- if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != int32(item_rand->ID))
+ if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != randomPropId)
{
- SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, item_rand->ID);
+ SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, randomPropId);
SetState(ITEM_CHANGED, GetOwner());
}
for (uint32 i = PROP_ENCHANTMENT_SLOT_1; i < PROP_ENCHANTMENT_SLOT_1 + 3; ++i)
@@ -630,10 +663,9 @@ void Item::SetItemRandomProperties(int32 randomPropId)
ItemRandomSuffixEntry const* item_rand = sItemRandomSuffixStore.LookupEntry(-randomPropId);
if (item_rand)
{
- if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != -int32(item_rand->ID) ||
- !GetItemSuffixFactor())
+ if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != randomPropId || !GetItemSuffixFactor())
{
- SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, -int32(item_rand->ID));
+ SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, randomPropId);
UpdateItemSuffixFactor();
SetState(ITEM_CHANGED, GetOwner());
}
@@ -924,36 +956,24 @@ void Item::ClearEnchantment(EnchantmentSlot slot)
bool Item::GemsFitSockets() const
{
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
+ uint32 gemSlot = 0;
+ for (uint32 gemItemId : GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS))
{
- uint8 SocketColor = GetTemplate()->GetSocketColor(enchant_slot - SOCK_ENCHANTMENT_SLOT);
-
+ uint8 SocketColor = GetTemplate()->GetSocketColor(gemSlot);
if (!SocketColor) // no socket slot
continue;
- uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if (!enchant_id) // no gems on this socket
- return false;
-
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if (!enchantEntry) // invalid gem id on this socket
- return false;
-
- uint8 GemColor = 0;
+ uint32 GemColor = 0;
- uint32 gemid = enchantEntry->SRCItemID;
- if (gemid)
+ ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemItemId);
+ if (gemProto)
{
- ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemid);
- if (gemProto)
- {
- GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GetGemProperties());
- if (gemProperty)
- GemColor = gemProperty->Type;
- }
+ GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GetGemProperties());
+ if (gemProperty)
+ GemColor = gemProperty->Type;
}
- if (!(GemColor & SocketColor)) // bad gem color on this socket
+ if (!(GemColor & SocketColorToGemTypeMask[SocketColor])) // bad gem color on this socket
return false;
}
return true;
@@ -961,44 +981,22 @@ bool Item::GemsFitSockets() const
uint8 Item::GetGemCountWithID(uint32 GemID) const
{
- uint8 count = 0;
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
+ return std::count_if(GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).begin(), GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).end(), [GemID](uint32 gemItemId)
{
- uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if (!enchant_id)
- continue;
-
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if (!enchantEntry)
- continue;
-
- if (GemID == enchantEntry->SRCItemID)
- ++count;
- }
- return count;
+ return gemItemId == GemID;
+ });
}
uint8 Item::GetGemCountWithLimitCategory(uint32 limitCategory) const
{
- uint8 count = 0;
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
+ return std::count_if(GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).begin(), GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).end(), [limitCategory](uint32 gemItemId)
{
- uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if (!enchant_id)
- continue;
-
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if (!enchantEntry)
- continue;
-
- ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(enchantEntry->SRCItemID);
+ ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemItemId);
if (!gemProto)
- continue;
+ return false;
- if (gemProto->GetItemLimitCategory() == limitCategory)
- ++count;
- }
- return count;
+ return gemProto->GetItemLimitCategory() == limitCategory;
+ });
}
bool Item::IsLimitedToAnotherMapOrZone(uint32 cur_mapId, uint32 cur_zoneId) const
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
index 7b30480df35..2f82071f66f 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
@@ -178,7 +178,7 @@ TC_GAME_API uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uin
return 0;
}
- RandomPropertiesPointsEntry const* randPropPointsEntry = sRandomPropertiesPointsStore.LookupEntry(itemLevel);
+ RandPropPointsEntry const* randPropPointsEntry = sRandPropPointsStore.LookupEntry(itemLevel);
if (!randPropPointsEntry)
return 0;
diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp
index ebed45eaaac..04873bdddcf 100644
--- a/src/server/game/Entities/Item/ItemTemplate.cpp
+++ b/src/server/game/Entities/Item/ItemTemplate.cpp
@@ -22,6 +22,29 @@
#include "ItemTemplate.h"
#include "Player.h"
+uint32 const SocketColorToGemTypeMask[19] =
+{
+ 0,
+ SOCKET_COLOR_META,
+ SOCKET_COLOR_RED,
+ SOCKET_COLOR_YELLOW,
+ SOCKET_COLOR_BLUE,
+ SOCKET_COLOR_HYDRAULIC,
+ SOCKET_COLOR_COGWHEEL,
+ SOCKET_COLOR_PRISMATIC,
+ SOCKET_COLOR_RELIC_IRON,
+ SOCKET_COLOR_RELIC_BLOOD,
+ SOCKET_COLOR_RELIC_SHADOW,
+ SOCKET_COLOR_RELIC_FEL,
+ SOCKET_COLOR_RELIC_ARCANE,
+ SOCKET_COLOR_RELIC_FROST,
+ SOCKET_COLOR_RELIC_FIRE,
+ SOCKET_COLOR_RELIC_WATER,
+ SOCKET_COLOR_RELIC_LIFE,
+ SOCKET_COLOR_RELIC_WIND,
+ SOCKET_COLOR_RELIC_HOLY
+};
+
char const* ItemTemplate::GetName(LocaleConstant locale) const
{
if (!strlen(ExtendedData->Name->Str[locale]))
@@ -137,21 +160,21 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag
if (GetClass() != ITEM_CLASS_WEAPON || quality > ITEM_QUALITY_ARTIFACT)
return;
- DBCStorage<ItemDamageEntry>* store = NULL;
// get the right store here
if (GetInventoryType() > INVTYPE_RANGEDRIGHT)
return;
+ float dps = 0.0f;
switch (GetInventoryType())
{
case INVTYPE_AMMO:
- store = &sItemDamageAmmoStore;
+ dps = sItemDamageAmmoStore.AssertEntry(itemLevel)->DPS[quality];
break;
case INVTYPE_2HWEAPON:
if (GetFlags2() & ITEM_FLAG2_CASTER_WEAPON)
- store = &sItemDamageTwoHandCasterStore;
+ dps = sItemDamageTwoHandCasterStore.AssertEntry(itemLevel)->DPS[quality];
else
- store = &sItemDamageTwoHandStore;
+ dps = sItemDamageTwoHandStore.AssertEntry(itemLevel)->DPS[quality];
break;
case INVTYPE_RANGED:
case INVTYPE_THROWN:
@@ -159,15 +182,15 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag
switch (GetSubClass())
{
case ITEM_SUBCLASS_WEAPON_WAND:
- store = &sItemDamageWandStore;
- break;
- case ITEM_SUBCLASS_WEAPON_THROWN:
- store = &sItemDamageThrownStore;
+ dps = sItemDamageOneHandCasterStore.AssertEntry(itemLevel)->DPS[quality];
break;
case ITEM_SUBCLASS_WEAPON_BOW:
case ITEM_SUBCLASS_WEAPON_GUN:
case ITEM_SUBCLASS_WEAPON_CROSSBOW:
- store = &sItemDamageRangedStore;
+ if (GetFlags2() & ITEM_FLAG2_CASTER_WEAPON)
+ dps = sItemDamageTwoHandCasterStore.AssertEntry(itemLevel)->DPS[quality];
+ else
+ dps = sItemDamageTwoHandStore.AssertEntry(itemLevel)->DPS[quality];
break;
default:
return;
@@ -177,21 +200,14 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag
case INVTYPE_WEAPONMAINHAND:
case INVTYPE_WEAPONOFFHAND:
if (GetFlags2() & ITEM_FLAG2_CASTER_WEAPON)
- store = &sItemDamageOneHandCasterStore;
+ dps = sItemDamageOneHandCasterStore.AssertEntry(itemLevel)->DPS[quality];
else
- store = &sItemDamageOneHandStore;
+ dps = sItemDamageOneHandStore.AssertEntry(itemLevel)->DPS[quality];
break;
default:
return;
}
- ASSERT(store);
-
- ItemDamageEntry const* damageInfo = store->LookupEntry(itemLevel);
- if (!damageInfo)
- return;
-
- float dps = damageInfo->DPS[quality];
float avgDamage = dps * GetDelay() * 0.001f;
minDamage = (GetStatScalingFactor() * -0.5f + 1.0f) * avgDamage;
maxDamage = floor(float(avgDamage * (GetStatScalingFactor() * 0.5f + 1.0f) + 0.5f));
diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h
index d69f1c88845..38265cc9fed 100644
--- a/src/server/game/Entities/Item/ItemTemplate.h
+++ b/src/server/game/Entities/Item/ItemTemplate.h
@@ -317,15 +317,29 @@ enum BAG_FAMILY_MASK
enum SocketColor
{
- SOCKET_COLOR_META = 1,
- SOCKET_COLOR_RED = 2,
- SOCKET_COLOR_YELLOW = 4,
- SOCKET_COLOR_BLUE = 8,
- SOCKET_COLOR_HYDRAULIC = 16, // not used
- SOCKET_COLOR_COGWHEEL = 32,
-};
-
-#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE | SOCKET_COLOR_COGWHEEL)
+ SOCKET_COLOR_META = 0x00001,
+ SOCKET_COLOR_RED = 0x00002,
+ SOCKET_COLOR_YELLOW = 0x00004,
+ SOCKET_COLOR_BLUE = 0x00008,
+ SOCKET_COLOR_HYDRAULIC = 0x00010, // not used
+ SOCKET_COLOR_COGWHEEL = 0x00020,
+ SOCKET_COLOR_PRISMATIC = 0x0000E,
+ SOCKET_COLOR_RELIC_IRON = 0x00040,
+ SOCKET_COLOR_RELIC_BLOOD = 0x00080,
+ SOCKET_COLOR_RELIC_SHADOW = 0x00100,
+ SOCKET_COLOR_RELIC_FEL = 0x00200,
+ SOCKET_COLOR_RELIC_ARCANE = 0x00400,
+ SOCKET_COLOR_RELIC_FROST = 0x00800,
+ SOCKET_COLOR_RELIC_FIRE = 0x01000,
+ SOCKET_COLOR_RELIC_WATER = 0x02000,
+ SOCKET_COLOR_RELIC_LIFE = 0x04000,
+ SOCKET_COLOR_RELIC_WIND = 0x08000,
+ SOCKET_COLOR_RELIC_HOLY = 0x10000
+};
+
+extern uint32 const SocketColorToGemTypeMask[19];
+
+#define SOCKET_COLOR_STANDARD (SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE)
enum InventoryType
{
@@ -646,10 +660,11 @@ class Player;
struct TC_GAME_API ItemTemplate
{
+ uint32 Id;
ItemEntry const* BasicData;
ItemSparseEntry const* ExtendedData;
- uint32 GetId() const { return BasicData->ID; }
+ uint32 GetId() const { return Id; }
uint32 GetClass() const { return BasicData->Class; }
uint32 GetSubClass() const { return BasicData->SubClass; }
uint32 GetQuality() const { return ExtendedData->Quality; }
@@ -658,7 +673,7 @@ struct TC_GAME_API ItemTemplate
uint32 GetFlags3() const { return ExtendedData->Flags[2]; }
float GetUnk1() const { return ExtendedData->Unk1; }
float GetUnk2() const { return ExtendedData->Unk2; }
- uint32 GetBuyCount() const { return std::max(ExtendedData->BuyCount, 1u); }
+ uint32 GetBuyCount() const { return std::max<uint32>(ExtendedData->BuyCount, 1u); }
uint32 GetBuyPrice() const { return ExtendedData->BuyPrice; }
uint32 GetSellPrice() const { return ExtendedData->SellPrice; }
InventoryType GetInventoryType() const { return InventoryType(ExtendedData->InventoryType); }
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index f9fa1b3aeb6..67d8d89cdf6 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1341,6 +1341,13 @@ std::vector<uint32> const& Object::GetDynamicValues(uint16 index) const
return _dynamicValues[index];
}
+uint32 Object::GetDynamicValue(uint16 index, uint8 offset) const
+{
+ ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false));
+ ASSERT(offset < _dynamicValues[index].size());
+ return _dynamicValues[index][offset];
+}
+
void Object::AddDynamicValue(uint16 index, uint32 value)
{
ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false));
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 503555037e1..bd31af9363c 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -168,6 +168,7 @@ class TC_GAME_API Object
void ApplyModFlag64(uint16 index, uint64 flag, bool apply);
std::vector<uint32> const& GetDynamicValues(uint16 index) const;
+ uint32 GetDynamicValue(uint16 index, uint8 offset) const;
void AddDynamicValue(uint16 index, uint32 value);
void RemoveDynamicValue(uint16 index, uint32 value);
void ClearDynamicValue(uint16 index);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 90f1c829bb9..38a47d999a9 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -421,7 +421,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac
return false;
}
- if (!ValidateAppearance(createInfo->Race, createInfo->Class, createInfo->Sex, createInfo->HairStyle, createInfo->HairColor, createInfo->Face, createInfo->FacialHairStyle, createInfo->Skin, true))
+ if (!ValidateAppearance(createInfo->Race, createInfo->Class, createInfo->Sex, createInfo->HairStyle, createInfo->HairColor, createInfo->Face, createInfo->FacialHairStyle, createInfo->Skin, createInfo->CustomDisplay, true))
{
TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with invalid appearance attributes - refusing to do so",
GetSession()->GetAccountId(), m_name.c_str());
@@ -1805,20 +1805,21 @@ void Player::RegenerateAll()
// Runes act as cooldowns, and they don't need to send any data
if (getClass() == CLASS_DEATH_KNIGHT)
{
- for (uint8 i = 0; i < MAX_RUNES; i += 2)
+ uint32 regeneratedRunes = 0;
+ uint32 regenIndex = 0;
+ while (regeneratedRunes < MAX_RECHARGING_RUNES && !m_runes->CooldownOrder.empty())
{
- uint8 runeToRegen = i;
- uint32 cd = GetRuneCooldown(i);
- uint32 secondRuneCd = GetRuneCooldown(i + 1);
- // Regenerate second rune of the same type only after first rune is off the cooldown
- if (secondRuneCd && (cd > secondRuneCd || !cd))
+ uint8 runeToRegen = m_runes->CooldownOrder[regenIndex++];
+ uint32 runeCooldown = GetRuneCooldown(runeToRegen);
+ if (runeCooldown > m_regenTimer)
{
- runeToRegen = i + 1;
- cd = secondRuneCd;
+ SetRuneCooldown(runeToRegen, runeCooldown - m_regenTimer);
+ ++regenIndex;
}
+ else
+ SetRuneCooldown(runeCooldown, 0);
- if (cd)
- SetRuneCooldown(runeToRegen, (cd > m_regenTimer) ? cd - m_regenTimer : 0);
+ ++regeneratedRunes;
}
}
@@ -2055,8 +2056,8 @@ void Player::ResetAllPowers()
case POWER_RUNIC_POWER:
SetPower(POWER_RUNIC_POWER, 0);
break;
- case POWER_ECLIPSE:
- SetPower(POWER_ECLIPSE, 0);
+ case POWER_LUNAR_POWER:
+ SetPower(POWER_LUNAR_POWER, 0);
break;
default:
break;
@@ -3142,12 +3143,12 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
if (!pSkill)
continue;
- if (pSkill->ID == fromSkill)
+ if (_spell_idx->second->SkillLine == fromSkill)
continue;
// Runeforging special case
- if ((_spell_idx->second->AquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(pSkill->ID)) || ((pSkill->ID == SKILL_RUNEFORGING_2) && _spell_idx->second->TrivialSkillLineRankHigh == 0))
- if (SkillRaceClassInfoEntry const* rcInfo = GetSkillRaceClassInfo(pSkill->ID, getRace(), getClass()))
+ if ((_spell_idx->second->AquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(_spell_idx->second->SkillLine)) || ((_spell_idx->second->SkillLine == SKILL_RUNEFORGING_2) && _spell_idx->second->TrivialSkillLineRankHigh == 0))
+ if (SkillRaceClassInfoEntry const* rcInfo = sDB2Manager.GetSkillRaceClassInfo(_spell_idx->second->SkillLine, getRace(), getClass()))
LearnDefaultSkill(rcInfo);
}
}
@@ -3230,7 +3231,7 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const
bool Player::IsCurrentSpecMasterySpell(SpellInfo const* spellInfo) const
{
if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetSpecId(GetActiveTalentGroup())))
- return spellInfo->Id == chrSpec->MasterySpellID[0] || spellInfo->Id == chrSpec->MasterySpellID[1];
+ return spellInfo->Id == chrSpec->MasterySpellID;
return false;
}
@@ -3968,6 +3969,10 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid);
trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_GEMS_BY_OWNER);
+ stmt->setUInt64(0, guid);
+ trans->Append(stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER);
stmt->setUInt64(0, guid);
trans->Append(stmt);
@@ -4217,7 +4222,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
SetPower(POWER_RAGE, 0);
SetPower(POWER_ENERGY, uint32(GetMaxPower(POWER_ENERGY)*restore_percent));
SetPower(POWER_FOCUS, uint32(GetMaxPower(POWER_FOCUS)*restore_percent));
- SetPower(POWER_ECLIPSE, 0);
+ SetPower(POWER_LUNAR_POWER, 0);
}
// trigger update zone for alive state zone updates
@@ -5326,7 +5331,7 @@ void Player::UpdateSkillsForLevel()
continue;
uint32 pskill = itr->first;
- SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(pskill, getRace(), getClass());
+ SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(pskill, getRace(), getClass());
if (!rcEntry)
continue;
@@ -5363,7 +5368,7 @@ void Player::UpdateSkillsToMaxSkillsForLevel()
continue;
uint32 pskill = itr->first;
- SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(pskill, getRace(), getClass());
+ SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(pskill, getRace(), getClass());
if (!rcEntry)
continue;
@@ -6129,7 +6134,7 @@ void Player::RewardReputation(Quest const* quest)
else
{
uint32 row = ((quest->RewardFactionValue[i] < 0) ? 1 : 0) + 1;
- if (QuestFactionRewEntry const* questFactionRewEntry = sQuestFactionRewardStore.LookupEntry(row))
+ if (QuestFactionRewardEntry const* questFactionRewEntry = sQuestFactionRewardStore.LookupEntry(row))
{
uint32 field = abs(quest->RewardFactionValue[i]);
rep = questFactionRewEntry->QuestRewFactionValue[field];
@@ -9764,7 +9769,7 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const
for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
{
item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (item && IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory))
+ if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory))
return true;
}
@@ -9777,7 +9782,7 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const
for (uint32 j = 0; j < bag->GetBagSize(); ++j)
{
item = GetUseableItemByPos(i, j);
- if (item && IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory))
+ if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory))
return true;
}
}
@@ -12763,20 +12768,23 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
if (pEnchant->RequiredSkillID > 0 && pEnchant->RequiredSkillRank > GetSkillValue(pEnchant->RequiredSkillID))
return;
- // Cogwheel gems dont have requirement data set in SpellItemEnchantment.dbc, but they do have it in Item-sparse.db2
- if (ItemTemplate const* gem = sObjectMgr->GetItemTemplate(pEnchant->SRCItemID))
- if (gem->GetRequiredSkill() && GetSkillValue(gem->GetRequiredSkill()) < gem->GetRequiredSkillRank())
- return;
// If we're dealing with a gem inside a prismatic socket we need to check the prismatic socket requirements
// rather than the gem requirements itself. If the socket has no color it is a prismatic socket.
- if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3)
- && !item->GetSocketColor(slot - SOCK_ENCHANTMENT_SLOT))
+ if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3))
{
- // Check if the requirements for the prismatic socket are met before applying the gem stats
- SpellItemEnchantmentEntry const* pPrismaticEnchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT));
- if (!pPrismaticEnchant || (pPrismaticEnchant->RequiredSkillID > 0 && pPrismaticEnchant->RequiredSkillRank > GetSkillValue(pPrismaticEnchant->RequiredSkillID)))
- return;
+ if (!item->GetSocketColor(slot - SOCK_ENCHANTMENT_SLOT))
+ {
+ // Check if the requirements for the prismatic socket are met before applying the gem stats
+ SpellItemEnchantmentEntry const* pPrismaticEnchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT));
+ if (!pPrismaticEnchant || (pPrismaticEnchant->RequiredSkillID > 0 && pPrismaticEnchant->RequiredSkillRank > GetSkillValue(pPrismaticEnchant->RequiredSkillID)))
+ return;
+ }
+
+ // Cogwheel gems dont have requirement data set in SpellItemEnchantment.dbc, but they do have it in Item-sparse.db2
+ if (ItemTemplate const* gem = sObjectMgr->GetItemTemplate(item->GetDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, uint32(slot - SOCK_ENCHANTMENT_SLOT))))
+ if (gem->GetRequiredSkill() && GetSkillValue(gem->GetRequiredSkill()) < gem->GetRequiredSkillRank())
+ return;
}
if (!item->IsBroken())
@@ -16357,7 +16365,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID),
GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID),
GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE),
- GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID)))
+ GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID),
+ std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE>{ fields[14].GetUInt8(), fields[15].GetUInt8(), fields[16].GetUInt8() }))
{
TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong Appearance values (Hair/Skin/Color), can't load.", guid.ToString().c_str());
return false;
@@ -16922,7 +16931,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
for (; loadedPowers < MAX_POWERS_PER_CLASS; ++loadedPowers)
SetUInt32Value(UNIT_FIELD_POWER + loadedPowers, 0);
- SetPower(POWER_ECLIPSE, 0);
+ SetPower(POWER_LUNAR_POWER, 0);
TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: The value of player '%s' after load item and aura is: ", m_name.c_str());
outDebugValues();
@@ -17265,8 +17274,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
// SELECT ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, ii.transmogrification, ii.upgradeId
- // 15 16 17 18 19 20 21 22
- // ii.enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, ii.bonusListIDs, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot
+ // 15 16 17 18 19 20 21 22 23 24 25
+ // ii.enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, ii.bonusListIDs, ig.gemItemId1, ig.gemItemId2, ig.gemItemId3, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot
//NOTE: the "order by `bag`" is important because it makes sure
//the bagMap is filled before items in the bags are loaded
//NOTE2: the "order by `slot`" is needed because mainhand weapons are (wrongly?)
@@ -17288,8 +17297,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
Field* fields = result->Fetch();
if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields))
{
- ObjectGuid bagGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[21].GetUInt64()) : ObjectGuid::Empty;
- uint8 slot = fields[22].GetUInt8();
+ ObjectGuid bagGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[24].GetUInt64()) : ObjectGuid::Empty;
+ uint8 slot = fields[25].GetUInt8();
GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item);
@@ -21560,23 +21569,11 @@ bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
if (i == slot)
continue;
Item* pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (pItem2 && !pItem2->IsBroken() && pItem2->GetTemplate()->GetSocketColor(0))
+ if (pItem2 && !pItem2->IsBroken())
{
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for (uint32 gemItemId : pItem2->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS))
{
- uint32 enchant_id = pItem2->GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if (!enchant_id)
- continue;
-
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if (!enchantEntry)
- continue;
-
- uint32 gemid = enchantEntry->SRCItemID;
- if (!gemid)
- continue;
-
- ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemid);
+ ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemItemId);
if (!gemProto)
continue;
@@ -21584,13 +21581,11 @@ bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
if (!gemProperty)
continue;
- uint8 GemColor = gemProperty->Type;
+ uint32 GemColor = gemProperty->Type;
for (uint8 b = 0, tmpcolormask = 1; b < 4; b++, tmpcolormask <<= 1)
- {
if (tmpcolormask & GemColor)
++curcount[b];
- }
}
}
}
@@ -23498,7 +23493,7 @@ void Player::ResurrectUsingRequestDataImpl()
SetPower(POWER_RAGE, 0);
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY));
SetPower(POWER_FOCUS, GetMaxPower(POWER_FOCUS));
- SetPower(POWER_ECLIPSE, 0);
+ SetPower(POWER_LUNAR_POWER, 0);
if (uint32 aura = _resurrectionData->Aura)
CastSpell(this, aura, true, nullptr, nullptr, _resurrectionData->GUID);
@@ -24005,16 +24000,16 @@ uint32 Player::GetBarberShopCost(BarberShopStyleEntry const* newHairStyle, uint8
void Player::InitGlyphsForLevel()
{
- uint32 slotMask = 0;
- uint8 slot = 0;
- uint8 level = getLevel();
- for (GlyphSlotEntry const* gs : sDB2Manager.GetGlyphSlots())
- {
- if (level >= ((gs->Tooltip + 1) * 25))
- slotMask |= 1 << slot;
+ //uint32 slotMask = 0;
+ //uint8 slot = 0;
+ //uint8 level = getLevel();
+ //for (GlyphSlotEntry const* gs : sDB2Manager.GetGlyphSlots())
+ //{
+ // if (level >= ((gs->Tooltip + 1) * 25))
+ // slotMask |= 1 << slot;
- SetGlyphSlot(slot++, gs->ID);
- }
+ // SetGlyphSlot(slot++, gs->ID);
+ //}
}
void Player::SetGlyph(uint8 slot, uint32 glyph)
@@ -24095,7 +24090,7 @@ bool Player::isTotalImmunity() const
return false;
}
-uint32 Player::GetRuneTypeBaseCooldown() const
+uint32 Player::GetRuneBaseCooldown() const
{
float cooldown = RUNE_BASE_COOLDOWN;
@@ -24133,72 +24128,33 @@ void Player::SetRuneCooldown(uint8 index, uint32 cooldown, bool casted /*= false
SetRuneTimer(index, 0);
}
- m_runes->runes[index].Cooldown = cooldown;
+ m_runes->Cooldown[index] = cooldown;
m_runes->SetRuneState(index, (cooldown == 0) ? true : false);
}
-void Player::SetRuneConvertAura(uint8 index, AuraEffect const* aura)
-{
- m_runes->runes[index].ConvertAura = aura;
-}
-
-void Player::AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const* aura)
+void Runes::SetRuneState(uint8 index, bool set /*= true*/)
{
- SetRuneConvertAura(index, aura); ConvertRune(index, newType);
-}
-
-void Player::RemoveRunesByAuraEffect(AuraEffect const* aura)
-{
- for (uint8 i = 0; i < MAX_RUNES; ++i)
+ auto itr = std::find(CooldownOrder.begin(), CooldownOrder.end(), index);
+ if (set)
{
- if (m_runes->runes[i].ConvertAura == aura)
- {
- ConvertRune(i, GetBaseRune(i));
- SetRuneConvertAura(i, nullptr);
- }
+ RuneState |= (1 << index); // usable
+ if (itr == CooldownOrder.end())
+ CooldownOrder.push_back(index);
}
-}
-
-void Player::RestoreBaseRune(uint8 index)
-{
- AuraEffect const* aura = m_runes->runes[index].ConvertAura;
- // If rune was converted by a non-passive aura that still active we should keep it converted
- if (aura && !(aura->GetSpellInfo()->Attributes & SPELL_ATTR0_PASSIVE))
- return;
- ConvertRune(index, GetBaseRune(index));
- SetRuneConvertAura(index, nullptr);
- // Don't drop passive talents providing rune convertion
- if (!aura || aura->GetAuraType() != SPELL_AURA_CONVERT_RUNE)
- return;
- for (uint8 i = 0; i < MAX_RUNES; ++i)
+ else
{
- if (aura == m_runes->runes[i].ConvertAura)
- return;
+ RuneState &= ~(1 << index); // on cooldown
+ if (itr != CooldownOrder.end())
+ CooldownOrder.erase(itr);
}
- aura->GetBase()->Remove();
-}
-
-void Player::ConvertRune(uint8 index, RuneType newType)
-{
- SetCurrentRune(index, newType);
-
- WorldPackets::Spells::ConvertRune data;
- data.Index = index;
- data.Rune = newType;
- GetSession()->SendPacket(data.Write());
}
-void Player::ResyncRunes(uint8 count) const
+void Player::ResyncRunes() const
{
- WorldPackets::Spells::ResyncRunes data(count);
+ WorldPackets::Spells::ResyncRunes data(MAX_RUNES);
+ for (uint32 i = 0; i < MAX_RUNES; ++i)
+ data.Runes.push_back(uint8(255 - (GetRuneCooldown(i) * 51)));
- for (uint32 i = 0; i < count; ++i)
- {
- WorldPackets::Spells::ResyncRunes::ResyncRune rune;
- rune.RuneType = GetCurrentRune(i); // rune type
- rune.Cooldown = uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255)
- data.Runes.push_back(rune);
- }
GetSession()->SendPacket(data.Write());
}
@@ -24209,16 +24165,6 @@ void Player::AddRunePower(uint8 index) const
GetSession()->SendPacket(&data);
}
-static RuneType runeSlotTypes[MAX_RUNES] =
-{
- /*0*/ RUNE_BLOOD,
- /*1*/ RUNE_BLOOD,
- /*2*/ RUNE_UNHOLY,
- /*3*/ RUNE_UNHOLY,
- /*4*/ RUNE_FROST,
- /*5*/ RUNE_FROST
-};
-
void Player::InitRunes()
{
if (getClass() != CLASS_DEATH_KNIGHT)
@@ -24228,20 +24174,14 @@ void Player::InitRunes()
if (runeIndex == MAX_POWERS)
return;
- m_runes = new Runes;
-
- m_runes->runeState = 0;
- m_runes->lastUsedRune = RUNE_BLOOD;
+ m_runes = new Runes();
+ m_runes->RuneState = 0;
for (uint8 i = 0; i < MAX_RUNES; ++i)
{
- SetBaseRune(i, runeSlotTypes[i]); // init base types
- SetCurrentRune(i, runeSlotTypes[i]); // init current types
SetRuneCooldown(i, 0); // reset cooldowns
SetRuneTimer(i, 0xFFFFFFFF); // Reset rune flags
SetLastRuneGraceTimer(i, 0);
- SetRuneConvertAura(i, nullptr);
- m_runes->SetRuneState(i);
}
// set a base regen timer equal to 10 sec
@@ -24249,15 +24189,6 @@ void Player::InitRunes()
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + runeIndex, 0.1f);
}
-bool Player::IsBaseRuneSlotsOnCooldown(RuneType runeType) const
-{
- for (uint8 i = 0; i < MAX_RUNES; ++i)
- if (GetBaseRune(i) == runeType && GetRuneCooldown(i) == 0)
- return false;
-
- return true;
-}
-
void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast)
{
Loot loot;
@@ -24400,7 +24331,7 @@ void Player::_LoadSkills(PreparedQueryResult result)
uint16 value = fields[1].GetUInt16();
uint16 max = fields[2].GetUInt16();
- SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skill, getRace(), getClass());
+ SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(skill, getRace(), getClass());
if (!rcEntry)
{
TC_LOG_ERROR("entities.player", "Player::_LoadSkills: Player '%s' (%s, Race: %u, Class: %u) has forbidden skill %u for his race/class combination",
@@ -24512,16 +24443,9 @@ InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limi
return res;
// check unique-equipped on gems
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for (uint32 gemItemId : pItem->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS))
{
- uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if (!enchant_id)
- continue;
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if (!enchantEntry)
- continue;
-
- ItemTemplate const* pGem = sObjectMgr->GetItemTemplate(enchantEntry->SRCItemID);
+ ItemTemplate const* pGem = sObjectMgr->GetItemTemplate(gemItemId);
if (!pGem)
continue;
@@ -24679,6 +24603,11 @@ void Player::CompletedAchievement(AchievementEntry const* entry)
m_achievementMgr->CompletedAchievement(entry, this);
}
+bool Player::ModifierTreeSatisfied(uint32 modifierTreeId) const
+{
+ return m_achievementMgr->ModifierTreeSatisfied(modifierTreeId);
+}
+
bool Player::LearnTalent(uint32 talentId)
{
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
@@ -25306,9 +25235,8 @@ void Player::ActivateTalentGroup(uint8 spec)
if (CanUseMastery())
if (ChrSpecializationEntry const* specialization = sChrSpecializationStore.LookupEntry(GetSpecId(GetActiveTalentGroup())))
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (uint32 mastery = specialization->MasterySpellID[i])
- LearnSpell(mastery, false);
+ if (uint32 mastery = specialization->MasterySpellID)
+ LearnSpell(mastery, false);
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
@@ -26088,7 +26016,19 @@ void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const
uint32 Player::CalculateTalentsTiers() const
{
- uint32 const* rowLevels = (getClass() != CLASS_DEATH_KNIGHT) ? DefaultTalentRowLevels : DKTalentRowLevels;
+ uint32 const* rowLevels;
+ switch (getClass())
+ {
+ case CLASS_DEATH_KNIGHT:
+ rowLevels = DKTalentRowLevels;
+ break;
+ case CLASS_DEMON_HUNTER:
+ rowLevels = DHTalentRowLevels;
+ default:
+ rowLevels = DefaultTalentRowLevels;
+ break;
+ }
+
for (uint32 i = MAX_TALENT_TIERS; i; --i)
if (getLevel() >= rowLevels[i - 1])
return i;
@@ -26219,9 +26159,8 @@ void Player::RemoveSpecializationSpells()
}
}
- for (uint32 j = 0; j < MAX_MASTERY_SPELLS; ++j)
- if (uint32 mastery = specialization->MasterySpellID[j])
- RemoveAurasDueToSpell(mastery);
+ if (uint32 mastery = specialization->MasterySpellID)
+ RemoveAurasDueToSpell(mastery);
}
}
}
@@ -26232,8 +26171,21 @@ void Player::RemoveSocial()
m_social = nullptr;
}
-// TODO: check demon hunter custom display sections
-bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, bool create /*=false*/)
+bool IsSectionFlagValid(CharSectionsEntry const* entry, uint8 class_, bool create)
+{
+ if (create && !(entry->Flags & SECTION_FLAG_PLAYER))
+ return false;
+
+ if (class_ != CLASS_DEATH_KNIGHT && (entry->Flags & SECTION_FLAG_DEATH_KNIGHT))
+ return false;
+
+ if (class_ != CLASS_DEMON_HUNTER && (entry->Flags & SECTION_FLAG_DEMON_HUNTER))
+ return false;
+
+ return true;
+}
+
+bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> const& customDisplay, bool create /*= false*/)
{
// Check skin color
// For Skin type is always 0
@@ -26241,10 +26193,9 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha
{ // Skin Color defined as Face color, too, we check skin & face in one pass
if (CharSectionsEntry const* entry2 = GetCharSectionEntry(race, SECTION_TYPE_FACE, gender, faceID, skinColor))
{
- // Check DeathKnight exclusive
- if (((entry->Flags & SECTION_FLAG_DEATH_KNIGHT) || (entry2->Flags & SECTION_FLAG_DEATH_KNIGHT)) && class_ != CLASS_DEATH_KNIGHT)
+ if (!IsSectionFlagValid(entry, class_, create))
return false;
- if (create && !((entry->Flags & SECTION_FLAG_PLAYER) && (entry2->Flags & SECTION_FLAG_PLAYER)))
+ if (!IsSectionFlagValid(entry2, class_, create))
return false;
}
else
@@ -26259,18 +26210,14 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha
// Check Hair
if (CharSectionsEntry const* entry = GetCharSectionEntry(race, SECTION_TYPE_HAIR, gender, hairID, hairColor))
{
- if ((entry->Flags & SECTION_FLAG_DEATH_KNIGHT) && class_ != CLASS_DEATH_KNIGHT)
- return false;
- if (create && !(entry->Flags & SECTION_FLAG_PLAYER))
+ if (!IsSectionFlagValid(entry, class_, create))
return false;
if (!excludeCheck)
{
if (CharSectionsEntry const* entry2 = GetCharSectionEntry(race, SECTION_TYPE_FACIAL_HAIR, gender, facialHair, hairColor))
{
- if ((entry2->Flags & SECTION_FLAG_DEATH_KNIGHT) && class_ != CLASS_DEATH_KNIGHT)
- return false;
- if (create && !(entry2->Flags & SECTION_FLAG_PLAYER))
+ if (!IsSectionFlagValid(entry2, class_, create))
return false;
}
else
@@ -26285,6 +26232,11 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha
else
return false;
+ for (uint32 i = 0; i < PLAYER_CUSTOM_DISPLAY_SIZE; ++i)
+ if (CharSectionsEntry const* entry = GetCharSectionEntry(race, CharSectionType(SECTION_TYPE_CUSTOM_DISPLAY_1 + i * 2), gender, customDisplay[i], 0))
+ if (!IsSectionFlagValid(entry, class_, create))
+ return false;
+
return true;
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index aa1f1d0697e..b538bbbe05c 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -447,7 +447,8 @@ struct Areas
float y2;
};
-#define MAX_RUNES 6
+#define MAX_RUNES 7
+#define MAX_RECHARGING_RUNES 3
enum RuneCooldowns
{
@@ -455,36 +456,13 @@ enum RuneCooldowns
RUNE_MISS_COOLDOWN = 1500 // cooldown applied on runes when the spell misses
};
-enum RuneType : uint8
-{
- RUNE_BLOOD = 0,
- RUNE_UNHOLY = 1,
- RUNE_FROST = 2,
- RUNE_DEATH = 3,
- NUM_RUNE_TYPES = 4
-};
-
-struct RuneInfo
-{
- RuneType BaseRune;
- RuneType CurrentRune;
- uint32 Cooldown;
- AuraEffect const* ConvertAura;
-};
-
struct Runes
{
- RuneInfo runes[MAX_RUNES];
- uint8 runeState; // mask of available runes
- RuneType lastUsedRune;
+ std::deque<uint8> CooldownOrder;
+ uint32 Cooldown[MAX_RUNES];
+ uint8 RuneState; // mask of available runes
- void SetRuneState(uint8 index, bool set = true)
- {
- if (set)
- runeState |= (1 << index); // usable
- else
- runeState &= ~(1 << index); // on cooldown
- }
+ void SetRuneState(uint8 index, bool set = true);
};
struct EnchantDuration
@@ -1162,6 +1140,7 @@ struct ResurrectionData
static uint32 const DefaultTalentRowLevels[MAX_TALENT_TIERS] = { 15, 30, 45, 60, 75, 90, 100 };
static uint32 const DKTalentRowLevels[MAX_TALENT_TIERS] = { 57, 58, 59, 60, 75, 90, 100 };
+static uint32 const DHTalentRowLevels[MAX_TALENT_TIERS] = { 99, 100, 102, 104, 106, 108, 110 };
struct TC_GAME_API PlayerTalentInfo
{
@@ -1652,7 +1631,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE; }
static bool IsValidClass(uint8 Class) { return ((1 << (Class - 1)) & CLASSMASK_ALL_PLAYABLE) != 0; }
static bool IsValidRace(uint8 Race) { return ((1 << (Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0; }
- static bool ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, bool create = false);
+ static bool ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> const& customDisplay, bool create = false);
/*********************************************************/
/*** SAVE SYSTEM ***/
@@ -2424,24 +2403,11 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool isAllowedToLoot(const Creature* creature);
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
- uint8 GetRunesState() const { return m_runes->runeState; }
- RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); }
- RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); }
- uint32 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
- uint32 GetRuneBaseCooldown(uint8 index) const { return GetRuneTypeBaseCooldown(); }
- uint32 GetRuneTypeBaseCooldown() const;
- bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const;
- RuneType GetLastUsedRune() const { return m_runes->lastUsedRune; }
- void SetLastUsedRune(RuneType type) { m_runes->lastUsedRune = type; }
- void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; }
- void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
+ uint8 GetRunesState() const { return m_runes->RuneState; }
+ uint32 GetRuneCooldown(uint8 index) const { return m_runes->Cooldown[index]; }
+ uint32 GetRuneBaseCooldown() const;
void SetRuneCooldown(uint8 index, uint32 cooldown, bool casted = false);
- void SetRuneConvertAura(uint8 index, AuraEffect const* aura);
- void AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const* aura);
- void RemoveRunesByAuraEffect(AuraEffect const* aura);
- void RestoreBaseRune(uint8 index);
- void ConvertRune(uint8 index, RuneType newType);
- void ResyncRunes(uint8 count) const;
+ void ResyncRunes() const;
void AddRunePower(uint8 index) const;
void InitRunes();
@@ -2454,6 +2420,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void StartCriteriaTimer(CriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveCriteriaTimer(CriteriaTimedTypes type, uint32 entry);
void CompletedAchievement(AchievementEntry const* entry);
+ bool ModifierTreeSatisfied(uint32 modifierTreeId) const;
bool HasTitle(uint32 bitIndex) const;
bool HasTitle(CharTitlesEntry const* title) const { return HasTitle(title->MaskID); }
diff --git a/src/server/game/Entities/Taxi/TaxiPathGraph.cpp b/src/server/game/Entities/Taxi/TaxiPathGraph.cpp
index 6617267be6a..22af722d592 100644
--- a/src/server/game/Entities/Taxi/TaxiPathGraph.cpp
+++ b/src/server/game/Entities/Taxi/TaxiPathGraph.cpp
@@ -108,8 +108,8 @@ void TaxiPathGraph::AddVerticeAndEdgeFromNodeInfo(TaxiNodesEntry const* from, Ta
uint32 map1, map2;
DBCPosition2D pos1, pos2;
- DeterminaAlternateMapPosition(nodes[i - 1]->MapID, nodes[i - 1]->Loc.X, nodes[i - 1]->Loc.Y, nodes[i - 1]->Loc.Z, &map1, &pos1);
- DeterminaAlternateMapPosition(nodes[i]->MapID, nodes[i]->Loc.X, nodes[i]->Loc.Y, nodes[i]->Loc.Z, &map2, &pos2);
+ DB2Manager::DeterminaAlternateMapPosition(nodes[i - 1]->MapID, nodes[i - 1]->Loc.X, nodes[i - 1]->Loc.Y, nodes[i - 1]->Loc.Z, &map1, &pos1);
+ DB2Manager::DeterminaAlternateMapPosition(nodes[i]->MapID, nodes[i]->Loc.X, nodes[i]->Loc.Y, nodes[i]->Loc.Z, &map2, &pos2);
if (map1 != map2)
continue;
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index deb163fde7e..f9ba83c19ca 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -539,24 +539,21 @@ void Player::UpdateMastery()
if (!chrSpec)
return;
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- {
- if (!chrSpec->MasterySpellID[i])
- continue;
+ if (!chrSpec->MasterySpellID)
+ return;
- if (Aura* aura = GetAura(chrSpec->MasterySpellID[i]))
+ if (Aura* aura = GetAura(chrSpec->MasterySpellID))
+ {
+ for (SpellEffectInfo const* effect : aura->GetSpellEffectInfos())
{
- for (SpellEffectInfo const* effect : aura->GetSpellEffectInfos())
- {
- if (!effect)
- continue;
+ if (!effect)
+ continue;
- float mult = effect->BonusCoefficient;
- if (G3D::fuzzyEq(mult, 0.0f))
- continue;
+ float mult = effect->BonusCoefficient;
+ if (G3D::fuzzyEq(mult, 0.0f))
+ continue;
- aura->GetEffect(effect->EffectIndex)->ChangeAmount(int32(value * effect->BonusCoefficient));
- }
+ aura->GetEffect(effect->EffectIndex)->ChangeAmount(int32(value * effect->BonusCoefficient));
}
}
}
@@ -780,7 +777,7 @@ void Player::UpdateAllRunesRegen()
if (runeIndex == MAX_POWERS)
return;
- uint32 cooldown = GetRuneTypeBaseCooldown();
+ uint32 cooldown = GetRuneBaseCooldown();
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + runeIndex, float(1 * IN_MILLISECONDS) / float(cooldown));
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + runeIndex, float(1 * IN_MILLISECONDS) / float(cooldown));
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 271b84364de..2bf8d161798 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -6056,78 +6056,6 @@ bool Unit::HandleAuraProc(Unit* /*victim*/, uint32 /*damage*/, Aura* triggeredBy
}
case SPELLFAMILY_DEATHKNIGHT:
{
- // Blood of the North
- // Reaping
- // Death Rune Mastery
- /// @todo move those to spell scripts
- if (dummySpell->SpellIconID == 3041 || (dummySpell->SpellIconID == 22 && dummySpell->Id != 62459) || dummySpell->SpellIconID == 2622)
- {
- *handled = true;
- // Convert recently used Blood Rune to Death Rune
- if (Player* player = ToPlayer())
- {
- if (player->getClass() != CLASS_DEATH_KNIGHT)
- return false;
-
- RuneType rune = ToPlayer()->GetLastUsedRune();
- // can't proc from death rune use
- if (rune == RUNE_DEATH)
- return false;
- AuraEffect* aurEff = triggeredByAura->GetEffect(EFFECT_0);
- if (!aurEff)
- return false;
-
- // Reset amplitude - set death rune remove timer to 30s
- aurEff->ResetPeriodic(true);
- uint32 runesLeft;
-
- if (dummySpell->SpellIconID == 2622)
- runesLeft = 2;
- else
- runesLeft = 1;
-
- for (uint8 i = 0; i < MAX_RUNES && runesLeft; ++i)
- {
- if (dummySpell->SpellIconID == 2622)
- {
- if (player->GetCurrentRune(i) == RUNE_DEATH ||
- player->GetBaseRune(i) == RUNE_BLOOD)
- continue;
- }
- else
- {
- if (player->GetCurrentRune(i) == RUNE_DEATH ||
- player->GetBaseRune(i) != RUNE_BLOOD)
- continue;
- }
- if (player->GetRuneCooldown(i) != (player->GetRuneBaseCooldown(i) - player->GetLastRuneGraceTimer(i)))
- continue;
-
- --runesLeft;
- // Mark aura as used
- player->AddRuneByAuraEffect(i, RUNE_DEATH, aurEff);
- }
- return true;
- }
- return false;
- }
-
- switch (dummySpell->Id)
- {
- // Bone Shield cooldown
- case 49222:
- {
- *handled = true;
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- {
- if (GetSpellHistory()->HasCooldown(100000))
- return false;
-
- GetSpellHistory()->AddCooldown(100000, 0, std::chrono::milliseconds(cooldown));
- }
- return true;
- }
- }
break;
}
case SPELLFAMILY_WARRIOR:
@@ -11153,16 +11081,16 @@ int32 Unit::GetCreatePowers(Powers power) const
case POWER_RUNIC_POWER:
return 1000;
case POWER_RUNES:
- return 0;
+ return 6;
case POWER_SOUL_SHARDS:
return 400;
- case POWER_ECLIPSE:
+ case POWER_LUNAR_POWER:
return 100;
case POWER_HOLY_POWER:
return 3;
case POWER_CHI:
return 4;
- case POWER_SHADOW_ORBS:
+ case POWER_INSANITY:
return 3;
case POWER_BURNING_EMBERS:
return 40;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 415c46afa5d..5ba84c271be 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1446,7 +1446,7 @@ class TC_GAME_API Unit : public WorldObject
Powers getPowerType() const { return Powers(GetUInt32Value(UNIT_FIELD_DISPLAY_POWER)); }
void setPowerType(Powers power);
int32 GetPower(Powers power) const;
- int32 GetMinPower(Powers power) const { return power == POWER_ECLIPSE ? -100 : 0; }
+ int32 GetMinPower(Powers power) const { return power == POWER_LUNAR_POWER ? -100 : 0; }
int32 GetMaxPower(Powers power) const;
float GetPowerPct(Powers power) const { return GetMaxPower(power) ? 100.f * GetPower(power) / GetMaxPower(power) : 0.0f; }
int32 CountPctFromMaxPower(Powers power, int32 pct) const { return CalculatePct(GetMaxPower(power), pct); }