aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2017-11-12 02:42:06 +0100
committerShauren <shauren.trinity@gmail.com>2017-11-12 02:42:06 +0100
commit331c70e695c6eef085be03a4f149158b68470035 (patch)
tree57c9ef3800b6fe544198d0070c55aeb615656b64 /src
parentbf0ae32d189d4579920e027f9d2dbfacc5552df3 (diff)
Core/Players: Fixed DK runes and runic power
Closes #19595
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Object/Object.cpp51
-rw-r--r--src/server/game/Entities/Player/Player.cpp111
-rw-r--r--src/server/game/Entities/Player/Player.h10
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp10
-rw-r--r--src/server/game/Spells/Spell.cpp25
-rw-r--r--src/server/game/Spells/SpellInfo.cpp2
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp7
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp7
9 files changed, 89 insertions, 140 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 7c8e163d170..9079a426f4f 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -350,11 +350,11 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint32 flags) const
bool AnimKitCreate = (flags & UPDATEFLAG_ANIMKITS) != 0;
bool Rotation = (flags & UPDATEFLAG_ROTATION) != 0;
bool HasAreaTrigger = (flags & UPDATEFLAG_AREATRIGGER) != 0;
- bool HasGameObject = (flags & UPDATEFLAG_GAMEOBJECT) != 0;;
+ bool HasGameObject = (flags & UPDATEFLAG_GAMEOBJECT) != 0;
bool ThisIsYou = (flags & UPDATEFLAG_SELF) != 0;
bool SmoothPhasing = false;
bool SceneObjCreate = false;
- bool PlayerCreateData = false;
+ bool PlayerCreateData = GetTypeId() == TYPEID_PLAYER && ToUnit()->GetPowerIndex(POWER_RUNES) != MAX_POWERS;
std::vector<uint32> const* PauseTimes = nullptr;
uint32 PauseTimesCount = 0;
if (GameObject const* go = ToGameObject())
@@ -801,26 +801,33 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint32 flags) const
// }
//}
- //if (PlayerCreateData)
- //{
- // data->WriteBit(HasSceneInstanceIDs);
- // data->WriteBit(HasRuneState);
- // data->FlushBits();
- // if (HasSceneInstanceIDs)
- // {
- // *data << uint32(SceneInstanceIDs.size());
- // for (std::size_t i = 0; i < SceneInstanceIDs.size(); ++i)
- // *data << uint32(SceneInstanceIDs[i]);
- // }
- // if (HasRuneState)
- // {
- // *data << uint8(RechargingRuneMask);
- // *data << uint8(UsableRuneMask);
- // *data << uint32(ToUnit()->GetMaxPower(POWER_RUNES));
- // for (uint32 i = 0; i < ToUnit()->GetMaxPower(POWER_RUNES); ++i)
- // *data << uint8(255 - (ToUnit()->ToPlayer()->GetRuneCooldown(i) * 51));
- // }
- //}
+ if (PlayerCreateData)
+ {
+ bool HasSceneInstanceIDs = false;
+ bool HasRuneState = ToUnit()->GetPowerIndex(POWER_RUNES) != MAX_POWERS;
+
+ data->WriteBit(HasSceneInstanceIDs);
+ data->WriteBit(HasRuneState);
+ data->FlushBits();
+ //if (HasSceneInstanceIDs)
+ //{
+ // *data << uint32(SceneInstanceIDs.size());
+ // for (std::size_t i = 0; i < SceneInstanceIDs.size(); ++i)
+ // *data << uint32(SceneInstanceIDs[i]);
+ //}
+ if (HasRuneState)
+ {
+ Player const* player = ToPlayer();
+ float baseCd = float(player->GetRuneBaseCooldown());
+ uint32 maxRunes = uint32(player->GetMaxPower(POWER_RUNES));
+
+ *data << uint8((1 << maxRunes) - 1);
+ *data << uint8(player->GetRunesState());
+ *data << uint32(maxRunes);
+ for (uint32 i = 0; i < maxRunes; ++i)
+ *data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255);
+ }
+ }
}
void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 98be38706f0..5da9a2c1eac 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -203,13 +203,6 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this)
m_DailyQuestChanged = false;
m_lastDailyQuestTime = 0;
- // Init rune flags
- for (uint8 i = 0; i < MAX_RUNES; ++i)
- {
- SetRuneTimer(i, 0xFFFFFFFF);
- SetLastRuneGraceTimer(i, 0);
- }
-
for (uint8 i=0; i < MAX_TIMERS; i++)
m_MirrorTimer[i] = DISABLED_MIRROR_TIMER;
@@ -1347,26 +1340,6 @@ void Player::Update(uint32 p_time)
}
}
- if (getClass() == CLASS_DEATH_KNIGHT)
- {
- // Update rune timers
- for (uint8 i = 0; i < MAX_RUNES; ++i)
- {
- uint32 timer = GetRuneTimer(i);
-
- // Don't update timer if rune is disabled
- if (GetRuneCooldown(i))
- continue;
-
- // Timer has began
- if (timer < 0xFFFFFFFF)
- {
- timer += p_time;
- SetRuneTimer(i, std::min(uint32(2500), timer));
- }
- }
- }
-
// group update
SendUpdateToOutOfRangeGroupMembers();
@@ -1840,9 +1813,9 @@ void Player::RegenerateAll()
{
uint32 regeneratedRunes = 0;
uint32 regenIndex = 0;
- while (regeneratedRunes < MAX_RECHARGING_RUNES && !m_runes->CooldownOrder.empty())
+ while (regeneratedRunes < MAX_RECHARGING_RUNES && m_runes->CooldownOrder.size() > regenIndex)
{
- uint8 runeToRegen = m_runes->CooldownOrder[regenIndex++];
+ uint8 runeToRegen = m_runes->CooldownOrder[regenIndex];
uint32 runeCooldown = GetRuneCooldown(runeToRegen);
if (runeCooldown > m_regenTimer)
{
@@ -1850,7 +1823,7 @@ void Player::RegenerateAll()
++regenIndex;
}
else
- SetRuneCooldown(runeCooldown, 0);
+ SetRuneCooldown(runeToRegen, 0);
++regeneratedRunes;
}
@@ -18037,6 +18010,18 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
SetUInt32Value(UNIT_FIELD_POWER + loadedPowers, 0);
SetPower(POWER_LUNAR_POWER, 0);
+ // Init rune recharge
+ if (GetPowerIndex(POWER_RUNES) != MAX_POWERS)
+ {
+ int32 runes = GetPower(POWER_RUNES);
+ int32 maxRunes = GetMaxPower(POWER_RUNES);
+ uint32 runeCooldown = GetRuneBaseCooldown();
+ while (runes < maxRunes)
+ {
+ SetRuneCooldown(runes, runeCooldown, false);
+ ++runes;
+ }
+ }
TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: The value of player '%s' after load item and aura is: ", m_name.c_str());
outDebugValues();
@@ -25457,6 +25442,11 @@ bool Player::isTotalImmunity() const
return false;
}
+uint8 Player::GetRunesState() const
+{
+ return uint8(m_runes->RuneState & ((1 << GetMaxPower(POWER_RUNES)) - 1));
+}
+
uint32 Player::GetRuneBaseCooldown() const
{
float cooldown = RUNE_BASE_COOLDOWN;
@@ -25481,22 +25471,11 @@ uint32 Player::GetRuneBaseCooldown() const
void Player::SetRuneCooldown(uint8 index, uint32 cooldown, bool casted /*= false*/)
{
- uint32 gracePeriod = GetRuneTimer(index);
-
- if (casted && IsInCombat())
- {
- if (gracePeriod < 0xFFFFFFFF && cooldown > 0)
- {
- uint32 lessCd = std::min(uint32(2500), gracePeriod);
- cooldown = (cooldown > lessCd) ? (cooldown - lessCd) : 0;
- SetLastRuneGraceTimer(index, lessCd);
- }
-
- SetRuneTimer(index, 0);
- }
-
m_runes->Cooldown[index] = cooldown;
m_runes->SetRuneState(index, (cooldown == 0) ? true : false);
+ int32 activeRunes = std::count(std::begin(m_runes->Cooldown), &m_runes->Cooldown[std::min(GetMaxPower(POWER_RUNES), MAX_RUNES)], 0);
+ if (activeRunes != GetPower(POWER_RUNES))
+ SetPower(POWER_RUNES, activeRunes);
}
void Runes::SetRuneState(uint8 index, bool set /*= true*/)
@@ -25505,41 +25484,28 @@ void Runes::SetRuneState(uint8 index, bool set /*= true*/)
if (set)
{
RuneState |= (1 << index); // usable
- if (itr == CooldownOrder.end())
- CooldownOrder.push_back(index);
+ if (itr != CooldownOrder.end())
+ CooldownOrder.erase(itr);
}
else
{
RuneState &= ~(1 << index); // on cooldown
- if (itr != CooldownOrder.end())
- CooldownOrder.erase(itr);
+ if (itr == CooldownOrder.end())
+ CooldownOrder.push_back(index);
}
}
void Player::ResyncRunes() const
{
- WorldPackets::Spells::ResyncRunes data(MAX_RUNES);
- data.Runes.Start = 0;
- data.Runes.Count = GetRunesState();
+ uint32 maxRunes = uint32(GetMaxPower(POWER_RUNES));
- for (uint32 i = 0; i < MAX_RUNES; ++i)
- data.Runes.Cooldowns.push_back(uint8(255 - (GetRuneCooldown(i) * 51)));
-
- // calculate mask of recharging runes
- uint32 regeneratedRunes = 0;
- uint32 regenIndex = 0;
- while (regeneratedRunes < MAX_RECHARGING_RUNES && !m_runes->CooldownOrder.empty())
- {
- uint8 runeToRegen = m_runes->CooldownOrder[regenIndex++];
- uint32 runeCooldown = GetRuneCooldown(runeToRegen);
- if (runeCooldown > m_regenTimer)
- {
- data.Runes.Start |= 1 << runeToRegen;
- ++regenIndex;
- }
+ WorldPackets::Spells::ResyncRunes data(maxRunes);
+ data.Runes.Start = uint8((1 << maxRunes) - 1);
+ data.Runes.Count = GetRunesState();
- ++regeneratedRunes;
- }
+ float baseCd = float(GetRuneBaseCooldown());
+ for (uint32 i = 0; i < maxRunes; ++i)
+ data.Runes.Cooldowns.push_back(uint8((baseCd - float(GetRuneCooldown(i))) / baseCd * 255));
GetSession()->SendPacket(data.Write());
}
@@ -25564,15 +25530,10 @@ void Player::InitRunes()
m_runes->RuneState = 0;
for (uint8 i = 0; i < MAX_RUNES; ++i)
- {
SetRuneCooldown(i, 0); // reset cooldowns
- SetRuneTimer(i, 0xFFFFFFFF); // Reset rune flags
- SetLastRuneGraceTimer(i, 0);
- }
- // set a base regen timer equal to 10 sec
- SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + runeIndex, 0.1f);
- SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + runeIndex, 0.1f);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + runeIndex, 0.0f);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + runeIndex, 0.0f);
}
void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 50381ae0146..f9d0710277d 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1809,10 +1809,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void ApplyManaRegenBonus(int32 amount, bool apply);
void ApplyHealthRegenBonus(int32 amount, bool apply);
void UpdateManaRegen();
- uint32 GetRuneTimer(uint8 index) const { return m_runeGraceCooldown[index]; }
- void SetRuneTimer(uint8 index, uint32 timer) { m_runeGraceCooldown[index] = timer; }
- uint32 GetLastRuneGraceTimer(uint8 index) const { return m_lastRuneGraceTimers[index]; }
- void SetLastRuneGraceTimer(uint8 index, uint32 timer) { m_lastRuneGraceTimers[index] = timer; }
void UpdateAllRunesRegen();
ObjectGuid const& GetLootGUID() const { return GetGuidValue(PLAYER_LOOT_TARGET_GUID); }
@@ -2270,7 +2266,7 @@ 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; }
+ uint8 GetRunesState() const;
uint32 GetRuneCooldown(uint8 index) const { return m_runes->Cooldown[index]; }
uint32 GetRuneBaseCooldown() const;
void SetRuneCooldown(uint8 index, uint32 cooldown, bool casted = false);
@@ -2645,10 +2641,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint8 m_MirrorTimerFlagsLast;
bool m_isInWater;
- // Rune type / Rune timer
- uint32 m_runeGraceCooldown[MAX_RUNES];
- uint32 m_lastRuneGraceTimers[MAX_RUNES];
-
// Current teleport data
WorldLocation m_teleport_dest;
uint32 m_teleport_options;
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 88160cf4f62..8ade3052092 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -767,9 +767,11 @@ void Player::UpdateAllRunesRegen()
if (runeIndex == MAX_POWERS)
return;
+ PowerTypeEntry const* runeEntry = sDB2Manager.GetPowerTypeEntry(POWER_RUNES);
+
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));
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + runeIndex, float(1 * IN_MILLISECONDS) / float(cooldown) - runeEntry->RegenerationPeace);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + runeIndex, float(1 * IN_MILLISECONDS) / float(cooldown) - runeEntry->RegenerationCombat);
}
void Player::_ApplyAllStatBonuses()
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 547e0f6d77a..472f2e3818d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -7842,16 +7842,6 @@ void Unit::ClearInCombat()
m_CombatTimer = 0;
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
- // Reset rune flags after combat
- if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_DEATH_KNIGHT)
- {
- for (uint8 i = 0; i < MAX_RUNES; ++i)
- {
- ToPlayer()->SetRuneTimer(i, 0xFFFFFFFF);
- ToPlayer()->SetLastRuneGraceTimer(i, 0);
- }
- }
-
// Player's state will be cleared in Player::UpdateContestedPvP
if (Creature* creature = ToCreature())
{
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 4e04d91c300..e5c74c91f55 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -54,6 +54,7 @@
#include "Vehicle.h"
#include "World.h"
#include "WorldSession.h"
+#include <numeric>
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
@@ -4022,7 +4023,7 @@ void Spell::SendSpellStart()
{
castData.RemainingRunes->Start = m_runesState; // runes state before
castData.RemainingRunes->Count = player->GetRunesState(); // runes state after
- for (uint8 i = 0; i < MAX_RUNES; ++i)
+ for (uint8 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i)
{
// float casts ensure the division is performed on floats as we need float result
float baseCd = float(player->GetRuneBaseCooldown());
@@ -4033,7 +4034,7 @@ void Spell::SendSpellStart()
{
castData.RemainingRunes->Start = 0;
castData.RemainingRunes->Count = 0;
- for (uint8 i = 0; i < MAX_RUNES; ++i)
+ for (uint8 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i)
castData.RemainingRunes->Cooldowns.push_back(0);
}
}
@@ -4140,7 +4141,7 @@ void Spell::SendSpellGo()
{
castData.RemainingRunes->Start = m_runesState; // runes state before
castData.RemainingRunes->Count = player->GetRunesState(); // runes state after
- for (uint8 i = 0; i < MAX_RUNES; ++i)
+ for (uint8 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i)
{
// float casts ensure the division is performed on floats as we need float result
float baseCd = float(player->GetRuneBaseCooldown());
@@ -4151,7 +4152,7 @@ void Spell::SendSpellGo()
{
castData.RemainingRunes->Start = 0;
castData.RemainingRunes->Count = 0;
- for (uint8 i = 0; i < MAX_RUNES; ++i)
+ for (uint8 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i)
castData.RemainingRunes->Cooldowns.push_back(0);
}
}
@@ -4612,8 +4613,12 @@ void Spell::TakePower()
SpellCastResult Spell::CheckRuneCost()
{
- auto runeCost = std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellPowerCost const& cost) { return cost.Power == POWER_RUNES; });
- if (runeCost == m_powerCost.end())
+ int32 runeCost = std::accumulate(m_powerCost.begin(), m_powerCost.end(), 0, [](int32 totalCost, SpellPowerCost const& cost)
+ {
+ return totalCost + (cost.Power == POWER_RUNES ? cost.Amount : 0);
+ });
+
+ if (!runeCost)
return SPELL_CAST_OK;
Player* player = m_caster->ToPlayer();
@@ -4628,7 +4633,7 @@ SpellCastResult Spell::CheckRuneCost()
if (player->GetRuneCooldown(i) == 0)
++readyRunes;
- if (readyRunes < runeCost->Amount)
+ if (readyRunes < runeCost)
return SPELL_FAILED_NO_POWER; // not sure if result code is correct
return SPELL_CAST_OK;
@@ -4642,10 +4647,10 @@ void Spell::TakeRunePower(bool didHit)
Player* player = m_caster->ToPlayer();
m_runesState = player->GetRunesState(); // store previous state
- int32 runeCost = std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellPowerCost const& cost)
+ int32 runeCost = std::accumulate(m_powerCost.begin(), m_powerCost.end(), 0, [](int32 totalCost, SpellPowerCost const& cost)
{
- return cost.Power == POWER_RUNES;
- })->Amount;
+ return totalCost + (cost.Power == POWER_RUNES ? cost.Amount : 0);
+ });
for (int32 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i)
{
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 9d9dc34d087..84a4fe34330 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -3241,8 +3241,6 @@ std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(Unit const* caster, SpellSc
else
collector(sDB2Manager.GetSpellPowers(Id, caster->GetMap()->GetDifficultyID()));
- // POWER_RUNES is handled by SpellRuneCost.db2, and cost.Amount is always 0 (see Spell::TakeRunePower)
- costs.erase(std::remove_if(costs.begin(), costs.end(), [](SpellPowerCost const& cost) { return cost.Power != POWER_RUNES && cost.Amount <= 0; }), costs.end());
return costs;
}
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index be836943087..fd5170a01a5 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -1006,13 +1006,6 @@ public:
return false;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
- {
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
return false;
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 0edaa189e8e..a12305168c2 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -91,11 +91,12 @@ public:
{
if (Unit* caster = eventInfo.GetActor())
{
- if (caster->GetTypeId() != TYPEID_PLAYER || caster->getClass() != CLASS_DEATH_KNIGHT)
+ Player* player = caster->ToPlayer();
+ if (!player || caster->getClass() != CLASS_DEATH_KNIGHT)
return false;
- for (uint8 i = 0; i < MAX_RUNES; ++i)
- if (caster->ToPlayer()->GetRuneCooldown(i) == 0)
+ for (uint8 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i)
+ if (player->GetRuneCooldown(i) == 0)
return false;
return true;