diff options
author | Shauren <shauren.trinity@gmail.com> | 2017-11-12 02:42:06 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2017-11-12 02:42:06 +0100 |
commit | 331c70e695c6eef085be03a4f149158b68470035 (patch) | |
tree | 57c9ef3800b6fe544198d0070c55aeb615656b64 /src | |
parent | bf0ae32d189d4579920e027f9d2dbfacc5552df3 (diff) |
Core/Players: Fixed DK runes and runic power
Closes #19595
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 51 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 111 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 10 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/StatSystem.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 25 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_modify.cpp | 7 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_dk.cpp | 7 |
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; |