[Spells] Support for bards using Disciplines while casting or /melody. (#1936)

* test

* complete

* Update effects.cpp

* Update spells.cpp

* Update effects.cpp

* [Spells] Support for bards using Disciplines while casting or /melody.

Support for spell field 'cast not standing' not allow casting from divine aura

* [Spells] Support for bards using Disciplines while casting or /melody.

DA bypass logic for spells with field 'cast_not_standing'
This commit is contained in:
KayenEQ
2022-01-19 22:44:17 -05:00
committed by GitHub
parent 804f0681a9
commit e09a8f8f8f
3 changed files with 72 additions and 26 deletions
+37 -12
View File
@@ -159,9 +159,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
LogSpells("CastSpell called for spell [{}] ([{}]) on entity [{}], slot [{}], time [{}], mana [{}], from item slot [{}]",
(IsValidSpell(spell_id))?spells[spell_id].name:"UNKNOWN SPELL", spell_id, target_id, static_cast<int>(slot), cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
if(casting_spell_id == spell_id)
if (casting_spell_id == spell_id) {
ZeroCastingVars();
}
if
(
!IsValidSpell(spell_id) ||
@@ -216,8 +216,8 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
return(false);
}
//cannot cast under divine aura
if(DivineAura()) {
//cannot cast under divine aura, unless spell has 'cast_not_standing' flag.
if(DivineAura() && !spells[spell_id].cast_not_standing) {
LogSpells("Spell casting canceled: cannot cast while Divine Aura is in effect");
InterruptSpell(173, 0x121, false);
if(IsClient()) {
@@ -240,7 +240,6 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
if ((item_slot != -1 && cast_time == 0) || aa_id) {
can_send_spellbar_enable = false;
}
if (can_send_spellbar_enable) {
SendSpellBarEnable(spell_id);
}
@@ -620,15 +619,30 @@ void Mob::SendBeginCast(uint16 spell_id, uint32 casttime)
* it's probably doing something wrong.
*/
bool Mob::DoCastingChecks()
bool Mob::DoCastingChecks(int32 spell_id, uint16 target_id)
{
if (!IsClient() || (IsClient() && CastToClient()->GetGM())) {
casting_spell_checks = true;
return true;
}
uint16 spell_id = casting_spell_id;
Mob *spell_target = entity_list.GetMob(casting_spell_targetid);
bool ignore_casting_spell_checks = false;
/*
If variables are passed into this function it is NOT being called from main spell process
thefore we do not want to set the 'casting_spell_checks' state keeping variable.
*/
if (spell_id != SPELL_UNKNOWN || target_id) {
ignore_casting_spell_checks = true;
}
if (spell_id == SPELL_UNKNOWN) {
spell_id = casting_spell_id;
}
if (!target_id) {
target_id = casting_spell_targetid;
}
Mob *spell_target = entity_list.GetMob(target_id);
if (RuleB(Spells, BuffLevelRestrictions)) {
// casting_spell_targetid is guaranteed to be what we went, check for ST_Self for now should work though
@@ -665,7 +679,9 @@ bool Mob::DoCastingChecks()
if (!CastToClient()->IsLinkedSpellReuseTimerReady(spells[spell_id].timer_id))
return false;
casting_spell_checks = true;
if (!ignore_casting_spell_checks){
casting_spell_checks = true;
}
return true;
}
@@ -2143,7 +2159,8 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
// we can't interrupt in this, or anything called from this!
// if you need to abort the casting, return false
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)
{
//EQApplicationPacket *outapp = nullptr;
Mob *ae_center = nullptr;
@@ -2567,6 +2584,12 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
//set our reuse timer on long ass reuse_time spells...
if(IsClient() && !isproc)
{
//Support for bards to get disc recast timers while singing.
if (GetClass() == BARD && spell_id != casting_spell_id && timer != 0xFFFFFFFF) {
CastToClient()->GetPTimers().Start(timer, timer_duration);
LogSpells("Spell [{}]: Setting bard custom disciple reuse timer [{}] to [{}]", spell_id, timer, timer_duration);
}
if(casting_spell_aa_id) {
AA::Rank *rank = zone->GetAlternateAdvancementRank(casting_spell_aa_id);
@@ -3765,8 +3788,10 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
}
}
// invuln mobs can't be affected by any spells, good or bad
if(spelltar->GetInvul() || spelltar->DivineAura()) {
// invuln mobs can't be affected by any spells, good or bad, except if caster is casting a spell with 'cast_not_standing' on self.
if ((spelltar->GetInvul() && !spelltar->DivineAura()) ||
(spelltar != this && spelltar->DivineAura()) ||
(spelltar == this && spelltar->DivineAura() && !spells[spell_id].cast_not_standing)) {
LogSpells("Casting spell [{}] on [{}] aborted: they are invulnerable", spell_id, spelltar->GetName());
safe_delete(action_packet);
return false;