[Bug Fix] Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs (#1986)

* Update spells.cpp

* Update spells.cpp

* [Bug Fix] Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs

disc failure log

* [Bug Fix] Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs

improved HasItemRecastTimer check
This commit is contained in:
KayenEQ 2022-02-10 14:58:28 -05:00 committed by GitHub
parent fbbbd3b09d
commit d656be6be4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 25 deletions

View File

@ -807,6 +807,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
} }
else { else {
if (!CastSpell(spell_id, target, EQ::spells::CastingSlot::Discipline)) { if (!CastSpell(spell_id, target, EQ::spells::CastingSlot::Discipline)) {
LogSpells("Discipline [{}] failed at cast spell.", spell_id);
return false; return false;
} }
} }

View File

@ -697,25 +697,32 @@ bool Mob::DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob *sp
Always check again on SpellOnTarget to account for AE checks. Always check again on SpellOnTarget to account for AE checks.
*/ */
bool ignore_on_casting = false;
bool ignore_if_npc_or_gm = false; bool ignore_if_npc_or_gm = false;
if (!IsClient() || (IsClient() && CastToClient()->GetGM())) { if (!IsClient() || (IsClient() && CastToClient()->GetGM())) {
ignore_if_npc_or_gm = true; ignore_if_npc_or_gm = true;
} }
if (check_on_casting && !spell_target){ if (check_on_casting){
if (!spell_target) {
if (IsGroupSpell(spell_id) || if (IsGroupSpell(spell_id) ||
spells[spell_id].target_type == ST_AEClientV1 || spells[spell_id].target_type == ST_AEClientV1 ||
spells[spell_id].target_type == ST_AECaster || spells[spell_id].target_type == ST_AECaster ||
spells[spell_id].target_type == ST_Ring || spells[spell_id].target_type == ST_Ring ||
spells[spell_id].target_type == ST_Beam){ spells[spell_id].target_type == ST_Beam) {
return true; return true;
} }
else if (spells[spell_id].target_type == ST_Self) { else if (spells[spell_id].target_type == ST_Self) {
spell_target = this; spell_target = this;
} }
} }
else {
if (IsGroupSpell(spell_id) && spell_target != this) {
ignore_on_casting = true;
}
}
}
//If we still do not have a target end. //If we still do not have a target end.
if (!spell_target){ if (!spell_target){
@ -773,15 +780,22 @@ bool Mob::DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob *sp
Prevents buff from being cast based on tareget ing PC OR NPC (1 = PCs, 2 = NPCs) Prevents buff from being cast based on tareget ing PC OR NPC (1 = PCs, 2 = NPCs)
These target types skip pcnpc only check (according to dev quotes) These target types skip pcnpc only check (according to dev quotes)
*/ */
if (spells[spell_id].pcnpc_only_flag && spells[spell_id].target_type != ST_AETargetHateList && if (!ignore_on_casting) {
spells[spell_id].target_type != ST_HateList) { if (spells[spell_id].pcnpc_only_flag && spells[spell_id].target_type != ST_AETargetHateList && spells[spell_id].target_type != ST_HateList) {
if (spells[spell_id].pcnpc_only_flag == 1 && !spell_target->IsClient() && !spell_target->IsMerc() && !spell_target->IsBot()) { if (spells[spell_id].pcnpc_only_flag == 1 && !spell_target->IsClient() && !spell_target->IsMerc() && !spell_target->IsBot()) {
if (check_on_casting) {
Message(Chat::SpellFailure, "This spell only works on other PCs");
}
return false; return false;
} }
else if (spells[spell_id].pcnpc_only_flag == 2 && (spell_target->IsClient() || spell_target->IsMerc() || spell_target->IsBot())) { else if (spells[spell_id].pcnpc_only_flag == 2 && (spell_target->IsClient() || spell_target->IsMerc() || spell_target->IsBot())) {
if (check_on_casting) {
Message(Chat::SpellFailure, "This spell only works on NPCs.");
}
return false; return false;
} }
} }
}
/* /*
Cannot cast life tap on self Cannot cast life tap on self
*/ */
@ -1272,7 +1286,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
item = CastToClient()->GetInv().GetItem(inventory_slot); //checked for in reagents and charges. item = CastToClient()->GetInv().GetItem(inventory_slot); //checked for in reagents and charges.
if (CastToClient()->HasItemRecastTimer(spell_id, inventory_slot)) { if (CastToClient()->HasItemRecastTimer(spell_id, inventory_slot)) {
MessageString(Chat::Red, SPELL_RECAST); MessageString(Chat::Red, SPELL_RECAST);
LogSpells("Casting of [{}] canceled: item spell reuse timer not expired", spell_id); LogSpells("Casting of [{}] canceled: item or augment spell reuse timer not expired", spell_id);
StopCasting(); StopCasting();
return; return;
} }
@ -3480,10 +3494,6 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
} }
} }
if (!DoCastingChecksOnTarget(false, spell_id, spelltar)) {
return false;
}
EQApplicationPacket *action_packet = nullptr, *message_packet = nullptr; EQApplicationPacket *action_packet = nullptr, *message_packet = nullptr;
float spell_effectiveness; float spell_effectiveness;
@ -3577,6 +3587,11 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
mod_spell_cast(spell_id, spelltar, reflect_effectiveness, use_resist_adjust, resist_adjust, isproc); mod_spell_cast(spell_id, spelltar, reflect_effectiveness, use_resist_adjust, resist_adjust, isproc);
if (!DoCastingChecksOnTarget(false, spell_id, spelltar)) {
safe_delete(action_packet);
return false;
}
// now check if the spell is allowed to land // now check if the spell is allowed to land
if (RuleB(Spells, EnableBlockedBuffs)) { if (RuleB(Spells, EnableBlockedBuffs)) {
// We return true here since the caster's client should act like normal // We return true here since the caster's client should act like normal
@ -6194,13 +6209,19 @@ bool Client::HasItemRecastTimer(int32 spell_id, uint32 inventory_slot)
} }
if (aug->Click.Effect == spell_id) { if (aug->Click.Effect == spell_id) {
if (aug_i->GetItem() && aug_i->GetItem()->RecastDelay > 0) {
recast_delay = aug_i->GetItem()->RecastDelay; recast_delay = aug_i->GetItem()->RecastDelay;
recast_type = aug_i->GetItem()->RecastType; recast_type = aug_i->GetItem()->RecastType;
}
break; break;
} }
} }
} }
//do not check if item has no recast delay.
if (!recast_delay) {
return false;
}
//if time is not expired, then it exists and therefore we have a recast on this item.
if (!CastToClient()->GetPTimers().Expired(&database, (pTimerItemStart + recast_type), false)) { if (!CastToClient()->GetPTimers().Expired(&database, (pTimerItemStart + recast_type), false)) {
return true; return true;
} }