mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Rule] Add rule for NPC Level Based Buff Restrictions. (#2708)
* [Rule] Add rule for NPC Level Based Buff Restrictions. * Erroneous whitespace * Change prefix on log message * Added log message when GM casts
This commit is contained in:
parent
9e3539295b
commit
ca0ae3cb98
@ -426,6 +426,7 @@ RULE_BOOL(Spells, BuffsFadeOnDeath, true, "Disable to keep buffs from fading on
|
||||
RULE_BOOL(Spells, IllusionsAlwaysPersist, false, "Allows Illusions to persist beyond death and zoning always.")
|
||||
RULE_BOOL(Spells, UseItemCastMessage, false, "Enable to use the \"item begins to glow\" messages when casting from an item.")
|
||||
RULE_BOOL(Spells, TargetsTargetRequiresCombatRange, true, "Disable to remove combat range requirement from Target's Target Spell Target Type")
|
||||
RULE_BOOL(Spells, NPCBuffLevelRestrictions, false, "Impose BuffLevelRestrictions on NPCs if true")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
|
||||
@ -560,7 +560,6 @@ public:
|
||||
inline virtual int32 GetDelayDeath() const { return aabonuses.DelayDeath + spellbonuses.DelayDeath + itembonuses.DelayDeath + 11; }
|
||||
|
||||
virtual bool CheckFizzle(uint16 spell_id);
|
||||
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
|
||||
virtual int GetCurrentBuffSlots() const;
|
||||
virtual int GetCurrentSongSlots() const;
|
||||
virtual int GetCurrentDiscSlots() const { return 1; }
|
||||
|
||||
@ -373,7 +373,7 @@ public:
|
||||
bool DoCastingChecksZoneRestrictions(bool check_on_casting, int32 spell_id);
|
||||
bool DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob* spell_target);
|
||||
virtual bool CheckFizzle(uint16 spell_id);
|
||||
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
|
||||
virtual bool CheckSpellLevelRestriction(Mob *caster, uint16 spell_id);
|
||||
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
|
||||
virtual float GetAOERange(uint16 spell_id);
|
||||
void InterruptSpell(uint16 spellid = SPELL_UNKNOWN);
|
||||
|
||||
@ -735,11 +735,11 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pet::CheckSpellLevelRestriction(uint16 spell_id)
|
||||
bool Pet::CheckSpellLevelRestriction(Mob *caster, uint16 spell_id)
|
||||
{
|
||||
auto owner = GetOwner();
|
||||
if (owner)
|
||||
return owner->CheckSpellLevelRestriction(spell_id);
|
||||
return owner->CheckSpellLevelRestriction(caster, spell_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ struct NPCType;
|
||||
class Pet : public NPC {
|
||||
public:
|
||||
Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power);
|
||||
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
|
||||
virtual bool CheckSpellLevelRestriction(Mob *caster, uint16 spell_id);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -734,10 +734,6 @@ bool Mob::DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob *sp
|
||||
*/
|
||||
|
||||
bool ignore_on_casting = false;
|
||||
bool ignore_if_npc_or_gm = false;
|
||||
if (!IsClient() || (IsClient() && CastToClient()->GetGM())) {
|
||||
ignore_if_npc_or_gm = true;
|
||||
}
|
||||
|
||||
if (check_on_casting) {
|
||||
if (spells[spell_id].target_type == ST_AEClientV1 ||
|
||||
@ -803,15 +799,9 @@ bool Mob::DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob *sp
|
||||
/*
|
||||
Prevent buffs from being cast on targets who don't meet level restriction
|
||||
*/
|
||||
if (!ignore_if_npc_or_gm && RuleB(Spells, BuffLevelRestrictions)) {
|
||||
// casting_spell_targetid is guaranteed to be what we went, check for ST_Self for now should work though
|
||||
if (spells[spell_id].target_type != ST_Self && !spell_target->CheckSpellLevelRestriction(spell_id)) {
|
||||
LogSpells("Spell [{}] failed: recipient did not meet the level restrictions", spell_id);
|
||||
if (!IsBardSong(spell_id)) {
|
||||
MessageString(Chat::SpellFailure, SPELL_TOO_POWERFUL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!spell_target->CheckSpellLevelRestriction(this, spell_id)) {
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
Prevents buff from being cast based on tareget ing PC OR NPC (1 = PCs, 2 = NPCs)
|
||||
@ -1161,6 +1151,9 @@ void Mob::InterruptSpell(uint16 message, uint16 color, uint16 spellid)
|
||||
}
|
||||
}
|
||||
|
||||
LogSpells("Interrupt: casting_spell_id [{}] casting_spell_slot [{}]",
|
||||
casting_spell_id, (int) casting_spell_slot);
|
||||
|
||||
if(casting_spell_id && IsNPC()) {
|
||||
CastToNPC()->AI_Event_SpellCastFinished(false, static_cast<uint16>(casting_spell_slot));
|
||||
}
|
||||
@ -1275,8 +1268,9 @@ void Mob::StopCastSpell(int32 spell_id, bool send_spellbar_enable)
|
||||
-AA that fail at CastSpell because they never get timer set.
|
||||
-Instant cast items that fail at CastSpell because they never get timer set.
|
||||
*/
|
||||
if (casting_spell_id && IsNPC()) {
|
||||
CastToNPC()->AI_Event_SpellCastFinished(false, static_cast<uint16>(casting_spell_slot));
|
||||
// Often called before spell_id and slot are set. For NPCs always update AI
|
||||
if (IsNPC()) {
|
||||
CastToNPC()->AI_Event_SpellCastFinished(false, 1);
|
||||
}
|
||||
|
||||
if (send_spellbar_enable) {
|
||||
@ -3210,29 +3204,60 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2,
|
||||
// spells 1-50: no restrictons
|
||||
// 51-65: SpellLevel/2+15
|
||||
// 66+ Group Spells 62, Single Target 61
|
||||
bool Mob::CheckSpellLevelRestriction(uint16 spell_id)
|
||||
bool Mob::CheckSpellLevelRestriction(Mob *caster, uint16 spell_id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool check_for_restrictions = false;
|
||||
bool can_cast = true;
|
||||
|
||||
bool Client::CheckSpellLevelRestriction(uint16 spell_id)
|
||||
{
|
||||
int SpellLevel = GetMinLevel(spell_id);
|
||||
if (!caster) {
|
||||
LogSpells("[CheckSpellLevelRestriction] No caster");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only check for beneficial buffs
|
||||
if (IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) {
|
||||
if (SpellLevel > 65) {
|
||||
if (IsGroupSpell(spell_id) && GetLevel() < 62)
|
||||
return false;
|
||||
else if (GetLevel() < 61)
|
||||
return false;
|
||||
} else if (SpellLevel > 50) { // 51-65
|
||||
if (GetLevel() < (SpellLevel / 2 + 15))
|
||||
return false;
|
||||
if (caster->IsClient() && caster->CastToClient()->GetGM()) {
|
||||
LogSpells("[CheckSpellLevelRestriction] GM casting - No restrictions");
|
||||
return true;
|
||||
}
|
||||
|
||||
// NON GM clients might be restricted by rule setting
|
||||
if (caster->IsClient()) {
|
||||
if (RuleB(Spells, BuffLevelRestrictions)) {
|
||||
check_for_restrictions = true;
|
||||
}
|
||||
}
|
||||
// NPCS might be restricted by rule setting
|
||||
else if (RuleB(Spells, NPCBuffLevelRestrictions)) {
|
||||
check_for_restrictions = true;
|
||||
}
|
||||
|
||||
if (check_for_restrictions) {
|
||||
int spell_level = GetMinLevel(spell_id);
|
||||
|
||||
// Only check for beneficial buffs
|
||||
if (IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) {
|
||||
if (spell_level > 65) {
|
||||
if (IsGroupSpell(spell_id) && GetLevel() < 62) {
|
||||
can_cast = false;
|
||||
}
|
||||
else if (GetLevel() < 61) {
|
||||
can_cast = false;
|
||||
}
|
||||
} else if (spell_level > 50) { // 51-65
|
||||
if (GetLevel() < (spell_level / 2 + 15)) {
|
||||
can_cast = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!can_cast) {
|
||||
LogSpells("Spell [{}] failed: recipient did not meet the level restrictions", spell_id);
|
||||
if (!IsBardSong(spell_id)) {
|
||||
caster->MessageString(Chat::SpellFailure, SPELL_TOO_POWERFUL);
|
||||
}
|
||||
}
|
||||
|
||||
return can_cast;
|
||||
}
|
||||
|
||||
uint32 Mob::GetFirstBuffSlot(bool disc, bool song)
|
||||
@ -4175,12 +4200,7 @@ bool Mob::SpellOnTarget(
|
||||
}
|
||||
|
||||
// make sure spelltar is high enough level for the buff
|
||||
if (RuleB(Spells, BuffLevelRestrictions) && !spelltar->CheckSpellLevelRestriction(spell_id)) {
|
||||
LogSpells("Spell [{}] failed: recipient did not meet the level restrictions", spell_id);
|
||||
if (!IsBardSong(spell_id)) {
|
||||
MessageString(Chat::SpellFailure, SPELL_TOO_POWERFUL);
|
||||
}
|
||||
|
||||
if (!spelltar->CheckSpellLevelRestriction(this, spell_id)) {
|
||||
safe_delete(action_packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user