mirror of
https://github.com/EQEmu/Server.git
synced 2026-02-27 07:12:24 +00:00
[Spells] Fix for AA and Discipline recast timers being set on spell casting failure. (#1971)
* recast timer updates * reworked * removed unneeded param * fix expendible AA * fixed * Update spells.cpp * [Spells] Fix for AA and Discipline recast timers being set on spell casting failure. don't check recasts from triggered spells.
This commit is contained in:
parent
a208801d1f
commit
8a48473dbc
78
zone/aa.cpp
78
zone/aa.cpp
@ -1227,65 +1227,65 @@ void Client::IncrementAlternateAdvancementRank(int rank_id) {
|
|||||||
void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
||||||
AA::Rank *rank = zone->GetAlternateAdvancementRank(rank_id);
|
AA::Rank *rank = zone->GetAlternateAdvancementRank(rank_id);
|
||||||
|
|
||||||
if(!rank) {
|
if (!rank) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AA::Ability *ability = rank->base_ability;
|
AA::Ability *ability = rank->base_ability;
|
||||||
if(!ability) {
|
if (!ability) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!IsValidSpell(rank->spell)) {
|
if (!IsValidSpell(rank->spell)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//do not allow AA to cast if your actively casting another AA.
|
||||||
|
if (rank->spell == casting_spell_id && rank->id == casting_spell_aa_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
if (!CanUseAlternateAdvancementRank(rank)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool use_toggle_passive_hotkey = UseTogglePassiveHotkey(*rank);
|
bool use_toggle_passive_hotkey = UseTogglePassiveHotkey(*rank);
|
||||||
|
|
||||||
//make sure it is not a passive
|
//make sure it is not a passive
|
||||||
if(!rank->effects.empty() && !use_toggle_passive_hotkey) {
|
if (!rank->effects.empty() && !use_toggle_passive_hotkey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 charges = 0;
|
uint32 charges = 0;
|
||||||
// We don't have the AA
|
// We don't have the AA
|
||||||
if (!GetAA(rank_id, &charges))
|
if (!GetAA(rank_id, &charges)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
//if expendable make sure we have charges
|
//if expendable make sure we have charges
|
||||||
if(ability->charges > 0 && charges < 1)
|
if (ability->charges > 0 && charges < 1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//check cooldown
|
//check cooldown
|
||||||
if(!p_timers.Expired(&database, rank->spell_type + pTimerAAStart, false)) {
|
if (!p_timers.Expired(&database, rank->spell_type + pTimerAAStart, false)) {
|
||||||
uint32 aaremain = p_timers.GetRemainingTime(rank->spell_type + pTimerAAStart);
|
uint32 aaremain = p_timers.GetRemainingTime(rank->spell_type + pTimerAAStart);
|
||||||
uint32 aaremain_hr = aaremain / (60 * 60);
|
uint32 aaremain_hr = aaremain / (60 * 60);
|
||||||
uint32 aaremain_min = (aaremain / 60) % 60;
|
uint32 aaremain_min = (aaremain / 60) % 60;
|
||||||
uint32 aaremain_sec = aaremain % 60;
|
uint32 aaremain_sec = aaremain % 60;
|
||||||
|
|
||||||
if(aaremain_hr >= 1) {
|
if (aaremain_hr >= 1) {
|
||||||
Message(Chat::Red, "You can use this ability again in %u hour(s) %u minute(s) %u seconds",
|
Message(Chat::Red, "You can use this ability again in %u hour(s) %u minute(s) %u seconds",
|
||||||
aaremain_hr, aaremain_min, aaremain_sec);
|
aaremain_hr, aaremain_min, aaremain_sec);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Message(Chat::Red, "You can use this ability again in %u minute(s) %u seconds",
|
Message(Chat::Red, "You can use this ability again in %u minute(s) %u seconds",
|
||||||
aaremain_min, aaremain_sec);
|
aaremain_min, aaremain_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//calculate cooldown
|
if (!IsCastWhileInvis(rank->spell)) {
|
||||||
int cooldown = rank->recast_time - GetAlternateAdvancementCooldownReduction(rank);
|
|
||||||
if(cooldown < 0) {
|
|
||||||
cooldown = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsCastWhileInvis(rank->spell))
|
|
||||||
CommonBreakInvisible();
|
CommonBreakInvisible();
|
||||||
|
}
|
||||||
|
|
||||||
if (spells[rank->spell].sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) {
|
if (spells[rank->spell].sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) {
|
||||||
MessageString(Chat::SpellFailure, SNEAK_RESTRICT);
|
MessageString(Chat::SpellFailure, SNEAK_RESTRICT);
|
||||||
@ -1293,13 +1293,15 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Modern clients don't require pet targeted for AA casts that are ST_Pet
|
// Modern clients don't require pet targeted for AA casts that are ST_Pet
|
||||||
if (spells[rank->spell].target_type == ST_Pet || spells[rank->spell].target_type == ST_SummonedPet)
|
if (spells[rank->spell].target_type == ST_Pet || spells[rank->spell].target_type == ST_SummonedPet) {
|
||||||
target_id = GetPetID();
|
target_id = GetPetID();
|
||||||
|
}
|
||||||
|
|
||||||
// extra handling for cast_not_standing spells
|
// extra handling for cast_not_standing spells
|
||||||
if (!IgnoreCastingRestriction(rank->spell)) {
|
if (!IgnoreCastingRestriction(rank->spell)) {
|
||||||
if (GetAppearance() == eaSitting) // we need to stand!
|
if (GetAppearance() == eaSitting) { // we need to stand!
|
||||||
SetAppearance(eaStanding, false);
|
SetAppearance(eaStanding, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (GetAppearance() != eaStanding) {
|
if (GetAppearance() != eaStanding) {
|
||||||
MessageString(Chat::SpellFailure, STAND_TO_CAST);
|
MessageString(Chat::SpellFailure, STAND_TO_CAST);
|
||||||
@ -1312,24 +1314,35 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Bards can cast instant cast AAs while they are casting or channeling item cast.
|
// Bards can cast instant cast AAs while they are casting or channeling item cast.
|
||||||
if (GetClass() == BARD && IsCasting() && spells[rank->spell].cast_time == 0) {
|
if (GetClass() == BARD && IsCasting() && spells[rank->spell].cast_time == 0) {
|
||||||
if (!DoCastingChecksOnCaster(rank->spell)) {
|
if (!DoCastingChecksOnCaster(rank->spell)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQ::spells::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].resist_difficulty, false)) {
|
SpellFinished(rank->spell, entity_list.GetMob(target_id), EQ::spells::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].resist_difficulty, false, -1, false, rank->id);
|
||||||
return;
|
|
||||||
}
|
|
||||||
ExpendAlternateAdvancementCharge(ability->id);
|
|
||||||
}
|
}
|
||||||
|
//Known issue: If you attempt to give a Bard an AA with a cast time, the cast timer will not display on the client (no live bard AA have cast time).
|
||||||
else {
|
else {
|
||||||
if (!CastSpell(rank->spell, target_id, EQ::spells::CastingSlot::AltAbility, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, nullptr, rank->id)) {
|
CastSpell(rank->spell, target_id, EQ::spells::CastingSlot::AltAbility, -1, -1, 0, -1, 0xFFFFFFFF, 0, nullptr, rank->id);
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CastToClient()->GetPTimers().Start(rank->spell_type + pTimerAAStart, cooldown);
|
void Client::SetAARecastTimer(AA::Rank *rank_in, int32 spell_id) {
|
||||||
SendAlternateAdvancementTimer(rank->spell_type, 0, 0);
|
|
||||||
|
if (!rank_in) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate AA cooldown
|
||||||
|
int timer_duration = rank_in->recast_time - GetAlternateAdvancementCooldownReduction(rank_in);
|
||||||
|
|
||||||
|
if (timer_duration <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CastToClient()->GetPTimers().Start(rank_in->spell_type + pTimerAAStart, timer_duration);
|
||||||
|
CastToClient()->SendAlternateAdvancementTimer(rank_in->spell_type, 0, 0);
|
||||||
|
LogSpells("Spell [{}]: Setting AA reuse timer [{}] to [{}]", spell_id, rank_in->spell_type + pTimerAAStart, timer_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) {
|
int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) {
|
||||||
@ -1363,6 +1376,7 @@ int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
||||||
|
|
||||||
for (auto &iter : aa_ranks) {
|
for (auto &iter : aa_ranks) {
|
||||||
AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first);
|
AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first);
|
||||||
if (ability && aa_id == ability->id) {
|
if (ability && aa_id == ability->id) {
|
||||||
|
|||||||
@ -1495,6 +1495,8 @@ public:
|
|||||||
void SendItemRecastTimer(int32 recast_type, uint32 recast_delay = 0);
|
void SendItemRecastTimer(int32 recast_type, uint32 recast_delay = 0);
|
||||||
void SetItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
void SetItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
||||||
bool HasItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
bool HasItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
||||||
|
void SetDisciplineRecastTimer(int32 spell_id);
|
||||||
|
void SetAARecastTimer(AA::Rank *rank_in, int32 spell_id);
|
||||||
|
|
||||||
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQ::versions::maskRoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
|
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQ::versions::maskRoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
|
||||||
inline void SetAggroMeterLock(int in) { m_aggrometer.set_lock_id(in); }
|
inline void SetAggroMeterLock(int in) { m_aggrometer.set_lock_id(in); }
|
||||||
|
|||||||
@ -800,51 +800,15 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool instant_recast = true;
|
if (GetClass() == BARD && IsCasting() && spells[spell_id].cast_time == 0) {
|
||||||
|
if (DoCastingChecksOnCaster(spell_id)) {
|
||||||
if(spell.recast_time > 0) {
|
SpellFinished(spell_id, entity_list.GetMob(target), EQ::spells::CastingSlot::Discipline);
|
||||||
uint32 reduced_recast = spell.recast_time / 1000;
|
|
||||||
auto focus = GetFocusEffect(focusReduceRecastTime, spell_id);
|
|
||||||
// do stupid stuff because custom servers.
|
|
||||||
// we really should be able to just do the -= focus but since custom servers could have shorter reuse timers
|
|
||||||
// we have to make sure we don't underflow the uint32 ...
|
|
||||||
// and yes, the focus effect can be used to increase the durations (spell 38944)
|
|
||||||
if (focus > reduced_recast) {
|
|
||||||
reduced_recast = 0;
|
|
||||||
if (GetPTimers().Enabled((uint32)DiscTimer))
|
|
||||||
GetPTimers().Clear(&database, (uint32)DiscTimer);
|
|
||||||
} else {
|
|
||||||
reduced_recast -= focus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reduced_recast > 0){
|
|
||||||
instant_recast = false;
|
|
||||||
|
|
||||||
if (GetClass() == BARD && IsCasting() && spells[spell_id].cast_time == 0) {
|
|
||||||
if (DoCastingChecksOnCaster(spell_id)) {
|
|
||||||
if (SpellFinished(spell_id, entity_list.GetMob(target), EQ::spells::CastingSlot::Discipline, 0, -1, spells[spell_id].resist_difficulty, false, -1, (uint32)DiscTimer, reduced_recast, false)) {
|
|
||||||
SendDisciplineTimer(spells[spell_id].timer_id, reduced_recast);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (CastSpell(spell_id, target, EQ::spells::CastingSlot::Discipline, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast)) {
|
|
||||||
SendDisciplineTimer(spells[spell_id].timer_id, reduced_recast);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (instant_recast) {
|
CastSpell(spell_id, target, EQ::spells::CastingSlot::Discipline);
|
||||||
if (GetClass() == BARD && IsCasting() && spells[spell_id].cast_time == 0) {
|
|
||||||
if (DoCastingChecksOnCaster(spell_id)) {
|
|
||||||
SpellFinished(spell_id, entity_list.GetMob(target), EQ::spells::CastingSlot::Discipline, 0, -1, spells[spell_id].resist_difficulty, false, -1, 0xFFFFFFFF, 0, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CastSpell(spell_id, target, EQ::spells::CastingSlot::Discipline);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -326,7 +326,7 @@ public:
|
|||||||
void CastedSpellFinished(uint16 spell_id, uint32 target_id, EQ::spells::CastingSlot slot, uint16 mana_used,
|
void CastedSpellFinished(uint16 spell_id, uint32 target_id, EQ::spells::CastingSlot slot, uint16 mana_used,
|
||||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
||||||
bool SpellFinished(uint16 spell_id, Mob *target, EQ::spells::CastingSlot slot = EQ::spells::CastingSlot::Item, uint16 mana_used = 0,
|
bool SpellFinished(uint16 spell_id, Mob *target, EQ::spells::CastingSlot slot = EQ::spells::CastingSlot::Item, uint16 mana_used = 0,
|
||||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, bool from_casted_spell = false);
|
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, bool from_casted_spell = false, uint32 aa_id = 0);
|
||||||
void SendBeginCast(uint16 spell_id, uint32 casttime);
|
void SendBeginCast(uint16 spell_id, uint32 casttime);
|
||||||
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, int reflect_effectiveness = 0,
|
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, int reflect_effectiveness = 0,
|
||||||
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, int32 duration_override = 0);
|
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, int32 duration_override = 0);
|
||||||
|
|||||||
@ -1681,7 +1681,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we're done casting, now try to apply the spell
|
// we're done casting, now try to apply the spell
|
||||||
if(!SpellFinished(spell_id, spell_target, slot, mana_used, inventory_slot, resist_adjust, false,-1, 0xFFFFFFFF, 0, true))
|
if(!SpellFinished(spell_id, spell_target, slot, mana_used, inventory_slot, resist_adjust, false,-1, true))
|
||||||
{
|
{
|
||||||
LogSpells("Casting of [{}] canceled: SpellFinished returned false", spell_id);
|
LogSpells("Casting of [{}] canceled: SpellFinished returned false", spell_id);
|
||||||
// most of the cases we return false have a message already or are logic errors that shouldn't happen
|
// most of the cases we return false have a message already or are logic errors that shouldn't happen
|
||||||
@ -2300,7 +2300,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
|
|||||||
// if you need to abort the casting, return false
|
// if you need to abort the casting, return false
|
||||||
bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, uint16 mana_used,
|
bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, uint16 mana_used,
|
||||||
uint32 inventory_slot, int16 resist_adjust, bool isproc, int level_override,
|
uint32 inventory_slot, int16 resist_adjust, bool isproc, int level_override,
|
||||||
uint32 timer, uint32 timer_duration, bool from_casted_spell)
|
bool from_casted_spell, uint32 aa_id)
|
||||||
{
|
{
|
||||||
Mob *ae_center = nullptr;
|
Mob *ae_center = nullptr;
|
||||||
|
|
||||||
@ -2674,32 +2674,54 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
|
|||||||
if (mgb) {
|
if (mgb) {
|
||||||
SetMGB(false);
|
SetMGB(false);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
Set Recast Timer on spells.
|
//all spell triggers use Item slot, but don't have an item associated. We don't need to check recast timers on these.
|
||||||
*/
|
bool is_triggered_spell = false;
|
||||||
if(IsClient() && !isproc)
|
if (slot == CastingSlot::Item && inventory_slot == 0xFFFFFFFF) {
|
||||||
|
is_triggered_spell = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsClient() && !isproc && !is_triggered_spell)
|
||||||
{
|
{
|
||||||
//Support for bards to get disc recast timers while singing
|
//Set Item or Augment Click Recast Timer
|
||||||
if (GetClass() == BARD && spell_id != casting_spell_id && timer != 0xFFFFFFFF) {
|
if (slot == CastingSlot::Item || slot == CastingSlot::PotionBelt) {
|
||||||
CastToClient()->GetPTimers().Start(timer, timer_duration);
|
CastToClient()->SetItemRecastTimer(spell_id, inventory_slot);
|
||||||
LogSpells("Spell [{}]: Setting bard disciple reuse timer from spell finished [{}] to [{}]", spell_id, timer, timer_duration);
|
|
||||||
}
|
}
|
||||||
|
//Set Discipline Recast Timer
|
||||||
|
else if (slot == CastingSlot::Discipline) {
|
||||||
|
if (spell_id == casting_spell_id || (GetClass() == BARD && spells[spell_id].cast_time == 0 && spell_id != casting_spell_id)) {
|
||||||
|
CastToClient()->SetDisciplineRecastTimer(spell_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Set AA Recast Timer.
|
||||||
|
else if (slot == CastingSlot::AltAbility){
|
||||||
|
uint32 active_aa_id = 0;
|
||||||
|
//aa_id is only passed directly into spellfinished when a bard is using AA while casting, this supports casting an AA while clicking an instant AA.
|
||||||
|
if (GetClass() == BARD && spells[spell_id].cast_time == 0 && aa_id) {
|
||||||
|
active_aa_id = aa_id;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
active_aa_id = casting_spell_aa_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
AA::Rank *rank = zone->GetAlternateAdvancementRank(active_aa_id);
|
||||||
|
|
||||||
if(casting_spell_aa_id) {
|
CastToClient()->SetAARecastTimer(rank, spell_id);
|
||||||
AA::Rank *rank = zone->GetAlternateAdvancementRank(casting_spell_aa_id);
|
|
||||||
|
|
||||||
if(rank && rank->base_ability) {
|
if (rank && rank->base_ability) {
|
||||||
ExpendAlternateAdvancementCharge(rank->base_ability->id);
|
ExpendAlternateAdvancementCharge(rank->base_ability->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(spell_id == casting_spell_id && casting_spell_timer != 0xFFFFFFFF)
|
//Set Custom Recast Timer
|
||||||
|
else if (spell_id == casting_spell_id && casting_spell_timer != 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
//aa new todo: aa expendable charges here
|
//aa new todo: aa expendable charges here
|
||||||
CastToClient()->GetPTimers().Start(casting_spell_timer, casting_spell_timer_duration);
|
CastToClient()->GetPTimers().Start(casting_spell_timer, casting_spell_timer_duration);
|
||||||
LogSpells("Spell [{}]: Setting custom reuse timer [{}] to [{}]", spell_id, casting_spell_timer, casting_spell_timer_duration);
|
LogSpells("Spell [{}]: Setting custom reuse timer [{}] to [{}]", spell_id, casting_spell_timer, casting_spell_timer_duration);
|
||||||
}
|
}
|
||||||
else if(spells[spell_id].recast_time > 1000 && !spells[spell_id].is_discipline) {
|
//Set Spell Recast Timer
|
||||||
int recast = spells[spell_id].recast_time/1000;
|
else if (spells[spell_id].recast_time > 1000 && !spells[spell_id].is_discipline) {
|
||||||
|
int recast = spells[spell_id].recast_time / 1000;
|
||||||
if (spell_id == SPELL_LAY_ON_HANDS) //lay on hands
|
if (spell_id == SPELL_LAY_ON_HANDS) //lay on hands
|
||||||
{
|
{
|
||||||
recast -= GetAA(aaFervrentBlessing) * 420;
|
recast -= GetAA(aaFervrentBlessing) * 420;
|
||||||
@ -2719,20 +2741,14 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
|
|||||||
}
|
}
|
||||||
recast = std::max(recast, 0);
|
recast = std::max(recast, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSpells("Spell [{}]: Setting long reuse timer to [{}] s (orig [{}])", spell_id, recast, spells[spell_id].recast_time);
|
LogSpells("Spell [{}]: Setting long reuse timer to [{}] s (orig [{}])", spell_id, recast, spells[spell_id].recast_time);
|
||||||
|
|
||||||
if (recast > 0) {
|
if (recast > 0) {
|
||||||
CastToClient()->GetPTimers().Start(pTimerSpellStart + spell_id, recast);
|
CastToClient()->GetPTimers().Start(pTimerSpellStart + spell_id, recast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
Set Recast Timer on item clicks, including augmenets.
|
|
||||||
*/
|
|
||||||
if(IsClient() && (slot == CastingSlot::Item || slot == CastingSlot::PotionBelt)){
|
|
||||||
CastToClient()->SetItemRecastTimer(spell_id, inventory_slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsNPC()) {
|
if (IsNPC()) {
|
||||||
CastToNPC()->AI_Event_SpellCastFinished(true, static_cast<uint16>(slot));
|
CastToNPC()->AI_Event_SpellCastFinished(true, static_cast<uint16>(slot));
|
||||||
@ -2793,6 +2809,8 @@ bool Mob::ApplyBardPulse(int32 spell_id, Mob *spell_target, CastingSlot slot) {
|
|||||||
if (!SpellFinished(spell_id, spell_target, slot, spells[spell_id].mana, 0xFFFFFFFF, spells[spell_id].resist_difficulty)) {
|
if (!SpellFinished(spell_id, spell_target, slot, spells[spell_id].mana, 0xFFFFFFFF, spells[spell_id].resist_difficulty)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -6283,6 +6301,39 @@ bool Client::HasItemRecastTimer(int32 spell_id, uint32 inventory_slot)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::SetDisciplineRecastTimer(int32 spell_id) {
|
||||||
|
|
||||||
|
if (!IsValidSpell(spell_id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spells[spell_id].recast_time == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTimerType DiscTimer = pTimerDisciplineReuseStart + spells[spell_id].timer_id;
|
||||||
|
uint32 timer_duration = spells[spell_id].recast_time / 1000;
|
||||||
|
auto focus = GetFocusEffect(focusReduceRecastTime, spell_id);
|
||||||
|
|
||||||
|
if (focus > timer_duration) {
|
||||||
|
timer_duration = 0;
|
||||||
|
if (GetPTimers().Enabled((uint32)DiscTimer)) {
|
||||||
|
GetPTimers().Clear(&database, (uint32)DiscTimer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
timer_duration -= focus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer_duration <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CastToClient()->GetPTimers().Start((uint32)DiscTimer, timer_duration);
|
||||||
|
CastToClient()->SendDisciplineTimer(spells[spell_id].timer_id, timer_duration);
|
||||||
|
LogSpells("Spell [{}]: Setting disciple reuse timer [{}] to [{}]", spell_id, spells[spell_id].timer_id, timer_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mob::CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ)
|
void Mob::CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user