mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 17:51:28 +00:00
[Bug Fix] Depop Charm Pet and Detach Debuffs on Evacuate (#3888)
* [Bug Fix] depop charm pet and detach debuffs on evac. This will depop charm pets and deteach debuffs to prevent some social aggro issues and exploitable conditions with charming and pulling a mob across the zone with no aggro concerns. * Added Rules
This commit is contained in:
parent
066b762e73
commit
6db6d7dca9
@ -474,6 +474,7 @@ RULE_BOOL(Spells, LegacyManaburn, false, "Enable to have the legacy manaburn sys
|
|||||||
RULE_BOOL(Spells, EvacClearAggroInSameZone, false, "Enable to clear aggro on clients when evacing in same zone.")
|
RULE_BOOL(Spells, EvacClearAggroInSameZone, false, "Enable to clear aggro on clients when evacing in same zone.")
|
||||||
RULE_BOOL(Spells, CharmAggroOverLevel, false, "Enabling this rule will cause Charm casts over level to show resisted and cause aggro. Early EQ style.")
|
RULE_BOOL(Spells, CharmAggroOverLevel, false, "Enabling this rule will cause Charm casts over level to show resisted and cause aggro. Early EQ style.")
|
||||||
RULE_BOOL(Spells, RequireMnemonicRetention, true, "Enabling will require spell slots 9-12 to have the appropriate Mnemonic Retention AA learned.")
|
RULE_BOOL(Spells, RequireMnemonicRetention, true, "Enabling will require spell slots 9-12 to have the appropriate Mnemonic Retention AA learned.")
|
||||||
|
RULE_BOOL(Spells, EvacClearCharmPet, false, "Enable to have evac in zone clear charm from charm pets and detach buffs.")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Combat)
|
RULE_CATEGORY(Combat)
|
||||||
|
|||||||
@ -3545,14 +3545,20 @@ void EntityList::HalveAggro(Mob *who)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//removes "targ" from all hate lists, including feigned, in the zone
|
//removes "targ" from all hate lists, including feigned, in the zone
|
||||||
void EntityList::ClearAggro(Mob* targ)
|
void EntityList::ClearAggro(Mob* targ, bool clear_caster_id)
|
||||||
{
|
{
|
||||||
Client *c = nullptr;
|
Client *c = nullptr;
|
||||||
|
|
||||||
if (targ->IsClient()) {
|
if (targ->IsClient()) {
|
||||||
c = targ->CastToClient();
|
c = targ->CastToClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = npc_list.begin();
|
auto it = npc_list.begin();
|
||||||
while (it != npc_list.end()) {
|
while (it != npc_list.end()) {
|
||||||
|
if (clear_caster_id) {
|
||||||
|
it->second->BuffDetachCaster(targ);
|
||||||
|
}
|
||||||
|
|
||||||
if (it->second->CheckAggro(targ)) {
|
if (it->second->CheckAggro(targ)) {
|
||||||
if (c) {
|
if (c) {
|
||||||
c->RemoveXTarget(it->second, false);
|
c->RemoveXTarget(it->second, false);
|
||||||
|
|||||||
@ -463,7 +463,7 @@ public:
|
|||||||
void UpdateHoTT(Mob* target);
|
void UpdateHoTT(Mob* target);
|
||||||
|
|
||||||
void Process();
|
void Process();
|
||||||
void ClearAggro(Mob* targ);
|
void ClearAggro(Mob* targ, bool clear_caster_id = false);
|
||||||
void ClearWaterAggro(Mob* targ);
|
void ClearWaterAggro(Mob* targ);
|
||||||
void ClearFeignAggro(Mob* targ);
|
void ClearFeignAggro(Mob* targ);
|
||||||
void ClearZoneFeignAggro(Mob* targ);
|
void ClearZoneFeignAggro(Mob* targ);
|
||||||
|
|||||||
@ -445,6 +445,7 @@ public:
|
|||||||
void BuffFadeBySlot(int slot, bool iRecalcBonuses = true);
|
void BuffFadeBySlot(int slot, bool iRecalcBonuses = true);
|
||||||
void BuffFadeDetrimentalByCaster(Mob *caster);
|
void BuffFadeDetrimentalByCaster(Mob *caster);
|
||||||
void BuffFadeBySitModifier();
|
void BuffFadeBySitModifier();
|
||||||
|
void BuffDetachCaster(Mob *caster);
|
||||||
bool IsAffectedByBuffByGlobalGroup(GlobalGroup group);
|
bool IsAffectedByBuffByGlobalGroup(GlobalGroup group);
|
||||||
void BuffModifyDurationBySpellID(uint16 spell_id, int32 newDuration);
|
void BuffModifyDurationBySpellID(uint16 spell_id, int32 newDuration);
|
||||||
int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1, bool disable_buff_overwrite = false);
|
int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1, bool disable_buff_overwrite = false);
|
||||||
|
|||||||
@ -568,19 +568,25 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
// Greater Decession = 3244
|
// Greater Decession = 3244
|
||||||
// Egress = 1566
|
// Egress = 1566
|
||||||
|
|
||||||
if(!target_zone) {
|
if (!target_zone) {
|
||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
LogDebug("Succor/Evacuation Spell In Same Zone");
|
LogDebug("Succor/Evacuation Spell In Same Zone");
|
||||||
#endif
|
#endif
|
||||||
if (IsClient()) {
|
if (IsClient()) {
|
||||||
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
|
if (HasPet()) {
|
||||||
} else {
|
if (RuleB(Spells, EvacClearCharmPet) && GetPet()->IsCharmed()) {
|
||||||
GMMove(x, y, z, heading);
|
GetPet()->BuffFadeByEffect(SE_Charm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(Spells, EvacClearAggroInSameZone)) {
|
|
||||||
entity_list.ClearAggro(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
|
||||||
|
} else {
|
||||||
|
GMMove(x, y, z, heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RuleB(Spells, EvacClearAggroInSameZone)) {
|
||||||
|
entity_list.ClearAggro(this);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
LogDebug("Succor/Evacuation Spell To Another Zone");
|
LogDebug("Succor/Evacuation Spell To Another Zone");
|
||||||
@ -2214,7 +2220,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
|
|
||||||
// clear aggro when summoned in zone and further than aggro clear distance rule.
|
// clear aggro when summoned in zone and further than aggro clear distance rule.
|
||||||
if (RuleR(Spells, CallOfTheHeroAggroClearDist) == 0 || caster->CalculateDistance(GetX(), GetY(), GetZ()) >= RuleR(Spells, CallOfTheHeroAggroClearDist)) {
|
if (RuleR(Spells, CallOfTheHeroAggroClearDist) == 0 || caster->CalculateDistance(GetX(), GetY(), GetZ()) >= RuleR(Spells, CallOfTheHeroAggroClearDist)) {
|
||||||
entity_list.ClearAggro(this);
|
if (RuleB(Spells, EvacClearCharmPet)) {
|
||||||
|
entity_list.ClearAggro(this, true);
|
||||||
|
} else {
|
||||||
|
entity_list.ClearAggro(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (!RuleB(Combat, SummonMeleeRange) && caster->GetZoneID() == GetZoneID() && caster->CombatRange(this)) {
|
} else if (!RuleB(Combat, SummonMeleeRange) && caster->GetZoneID() == GetZoneID() && caster->CombatRange(this)) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -4843,6 +4843,26 @@ bool Mob::IsAffectedByBuffByGlobalGroup(GlobalGroup group)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mob::BuffDetachCaster(Mob *caster) {
|
||||||
|
if (!caster) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int buff_count = GetMaxTotalSlots();
|
||||||
|
for (int j = 0; j < buff_count; j++) {
|
||||||
|
if (buffs[j].spellid != SPELL_UNKNOWN) {
|
||||||
|
if (IsDetrimentalSpell(buffs[j].spellid)) {
|
||||||
|
//this is a pretty terrible way to do this but
|
||||||
|
//there really isn't another way till I rewrite the basics
|
||||||
|
Mob* c = entity_list.GetMob(buffs[j].casterid);
|
||||||
|
if (c && c == caster) {
|
||||||
|
buffs[j].casterid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// checks if 'this' can be affected by spell_id from caster
|
// checks if 'this' can be affected by spell_id from caster
|
||||||
// returns true if the spell should fail, false otherwise
|
// returns true if the spell should fail, false otherwise
|
||||||
bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user