[Spells] Updates to spell field 'cast not stands' to ignore casting restrictions (#1938)

* 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'

* updates

* stun and mez bypass

* Update spdat.cpp

* Update spdat.cpp

* Update spells.cpp
This commit is contained in:
KayenEQ 2022-01-28 22:05:45 -05:00 committed by GitHub
parent afdbc0ce80
commit 44b8c9203a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 9 deletions

View File

@ -1671,3 +1671,15 @@ bool CastRestrictedSpell(int spellid)
return false; return false;
} }
} }
bool IgnoreCastingRestriction(int32 spell_id) {
/*
field 'cast_not_standing' allows casting when sitting, stunned, mezed, Divine Aura, through SPA 343 Interrupt casting
Likely also allows for casting while feared, but need to confirm. Possibly also while charmed.
This field also allows for damage to ignore DA immunity.
*/
if (spells[spell_id].cast_not_standing) {
return true;
}
return false;
}

View File

@ -1357,7 +1357,7 @@ struct SPDat_Spell_Struct
/* 181 */ int pvp_duration; // buffdurationformula for PvP -- PVP_DURATION /* 181 */ int pvp_duration; // buffdurationformula for PvP -- PVP_DURATION
/* 182 */ int pvp_duration_cap; // buffduration for PvP -- PVP_DURATION_CAP /* 182 */ int pvp_duration_cap; // buffduration for PvP -- PVP_DURATION_CAP
/* 183 */ int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG /* 183 */ int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG
/* 184 */ bool cast_not_standing; // this is checked in the client's EQ_Spell::IsCastWhileInvisSpell, this also blocks SE_InterruptCasting from affecting this spell -- CAST_NOT_STANDING /* 184 */ bool cast_not_standing; // this is checked in the client's EQ_Spell::IsCastWhileInvisSpell, this also blocks SE_InterruptCasting from affecting this spell -- CAST_NOT_STANDING (Allows casting if DA, stun, mezed, charm? fear?, damage to invul targets)
/* 185 */ bool can_mgb; // 0=no, -1 or 1 = yes -- CAN_MGB /* 185 */ bool can_mgb; // 0=no, -1 or 1 = yes -- CAN_MGB
/* 186 */ int dispel_flag; // -- NO_DISPELL /* 186 */ int dispel_flag; // -- NO_DISPELL
/* 187 */ //int npc_category; // -- NPC_MEM_CATEGORY /* 187 */ //int npc_category; // -- NPC_MEM_CATEGORY
@ -1537,6 +1537,7 @@ int GetViralMaxSpreadTime(int32 spell_id);
int GetViralSpreadRange(int32 spell_id); int GetViralSpreadRange(int32 spell_id);
bool IsInstrumentModAppliedToSpellEffect(int32 spell_id, int effect); bool IsInstrumentModAppliedToSpellEffect(int32 spell_id, int effect);
uint32 GetProcLimitTimer(int32 spell_id, int proc_type); uint32 GetProcLimitTimer(int32 spell_id, int proc_type);
bool IgnoreCastingRestriction(int32 spell_id);
int CalcPetHp(int levelb, int classb, int STA = 75); int CalcPetHp(int levelb, int classb, int STA = 75);
int GetSpellEffectDescNum(uint16 spell_id); int GetSpellEffectDescNum(uint16 spell_id);

View File

@ -1297,7 +1297,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
target_id = GetPetID(); target_id = GetPetID();
// extra handling for cast_not_standing spells // extra handling for cast_not_standing spells
if (!spells[rank->spell].cast_not_standing) { if (!IgnoreCastingRestriction(rank->spell)) {
if (GetAppearance() == eaSitting) // we need to stand! if (GetAppearance() == eaSitting) // we need to stand!
SetAppearance(eaStanding, false); SetAppearance(eaStanding, false);

View File

@ -725,7 +725,11 @@ void Client::SendDisciplineUpdate() {
bool Client::UseDiscipline(uint32 spell_id, uint32 target) { bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
// Dont let client waste a reuse timer if they can't use the disc // Dont let client waste a reuse timer if they can't use the disc
if (IsStunned() || IsFeared() || IsMezzed() || IsAmnesiad() || IsPet()) if ((IsStunned() && !IgnoreCastingRestriction(spell_id))||
IsFeared() ||
(IsMezzed() && !IgnoreCastingRestriction(spell_id)) ||
IsAmnesiad() ||
IsPet())
{ {
if (IsAmnesiad()) { if (IsAmnesiad()) {
MessageString(Chat::Red, MELEE_SILENCE); MessageString(Chat::Red, MELEE_SILENCE);
@ -748,7 +752,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
return(false); return(false);
} }
if (DivineAura() && !spells[spell_id].cast_not_standing) { if (DivineAura() && !IgnoreCastingRestriction(spell_id)) {
return false; return false;
} }

View File

@ -3911,7 +3911,7 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
case SE_InterruptCasting: { case SE_InterruptCasting: {
if (IsCasting()) { if (IsCasting()) {
const auto &spell = spells[casting_spell_id]; const auto &spell = spells[casting_spell_id];
if (!spell.cast_not_standing && zone->random.Roll(spells[buff.spellid].base_value[i])) { if (!IgnoreCastingRestriction(spell.id) && zone->random.Roll(spells[buff.spellid].base_value[i])) {
InterruptSpell(); InterruptSpell();
} }
} }

View File

@ -168,9 +168,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
casting_spell_id || casting_spell_id ||
delaytimer || delaytimer ||
spellend_timer.Enabled() || spellend_timer.Enabled() ||
IsStunned() || (IsStunned() && !IgnoreCastingRestriction(spell_id)) ||
IsFeared() || IsFeared() ||
IsMezzed() || (IsMezzed() && !IgnoreCastingRestriction(spell_id)) ||
(IsSilenced() && !IsDiscipline(spell_id)) || (IsSilenced() && !IsDiscipline(spell_id)) ||
(IsAmnesiad() && IsDiscipline(spell_id)) (IsAmnesiad() && IsDiscipline(spell_id))
) )
@ -217,7 +217,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
} }
//cannot cast under divine aura, unless spell has 'cast_not_standing' flag. //cannot cast under divine aura, unless spell has 'cast_not_standing' flag.
if(DivineAura() && !spells[spell_id].cast_not_standing) { if(DivineAura() && !IgnoreCastingRestriction(spell_id)) {
LogSpells("Spell casting canceled: cannot cast while Divine Aura is in effect"); LogSpells("Spell casting canceled: cannot cast while Divine Aura is in effect");
InterruptSpell(173, 0x121, false); InterruptSpell(173, 0x121, false);
if(IsClient()) { if(IsClient()) {
@ -3792,7 +3792,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
// 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. // 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()) || if ((spelltar->GetInvul() && !spelltar->DivineAura()) ||
(spelltar != this && spelltar->DivineAura()) || (spelltar != this && spelltar->DivineAura()) ||
(spelltar == this && spelltar->DivineAura() && !spells[spell_id].cast_not_standing)) { (spelltar == this && spelltar->DivineAura() && !IgnoreCastingRestriction(spell_id))) {
LogSpells("Casting spell [{}] on [{}] aborted: they are invulnerable", spell_id, spelltar->GetName()); LogSpells("Casting spell [{}] on [{}] aborted: they are invulnerable", spell_id, spelltar->GetName());
safe_delete(action_packet); safe_delete(action_packet);
return false; return false;