[Spells] Support for SPA 194 SE_FadingMemories to use max level checks on aggroed mobs (#1979)

* escape fix for different target types

* implemented max level for fade

* test

* update

* update

* support modern limits

* Update ruletypes.h

* update

* [Spells] Support for SPA 194 SE_FadingMemories to use max level checks on aggroed mobs

not sure why this code got removed, maybe merge error.
This commit is contained in:
KayenEQ
2022-02-09 15:12:39 -05:00
committed by GitHub
parent 1f560529da
commit f0bf285836
7 changed files with 67 additions and 6 deletions
+1 -1
View File
@@ -980,7 +980,7 @@ public:
//bool DecreaseByType(uint32 type, uint8 amt);
bool DecreaseByID(uint32 type, int16 quantity);
uint8 SlotConvert2(uint8 slot); //Maybe not needed.
void Escape(); //AA Escape
void Escape(); //keep or quest function
void DisenchantSummonedBags(bool client_update = true);
void RemoveNoRent(bool client_update = true);
void RemoveDuplicateLore(bool client_update = true);
+2 -1
View File
@@ -209,7 +209,8 @@ enum {
IMMUNE_AGGRO_CLIENT = 49,
IMMUNE_AGGRO_NPC = 50,
MODIFY_AVOID_DAMAGE = 51, //Modify by percent the NPCs chance to riposte, block, parry or dodge individually, or for all skills
MAX_SPECIAL_ATTACK = 52
IMMUNE_FADING_MEMORIES = 52,
MAX_SPECIAL_ATTACK = 53
};
typedef enum { //fear states
+27 -1
View File
@@ -1514,7 +1514,7 @@ void EntityList::RemoveFromTargets(Mob *mob, bool RemoveFromXTargets)
if (!m)
continue;
if (RemoveFromXTargets) {
if (RemoveFromXTargets && mob) {
if (m->IsClient() && (mob->CheckAggro(m) || mob->IsOnFeignMemory(m)))
m->CastToClient()->RemoveXTarget(mob, false);
// FadingMemories calls this function passing the client.
@@ -1526,6 +1526,32 @@ void EntityList::RemoveFromTargets(Mob *mob, bool RemoveFromXTargets)
}
}
void EntityList::RemoveFromTargetsFadingMemories(Mob *spell_target, bool RemoveFromXTargets, uint32 max_level)
{
for (auto &e : mob_list) {
auto &mob = e.second;
if (!mob) {
continue;
}
if (max_level && mob->GetLevel() > max_level)
continue;
if (mob->GetSpecialAbility(IMMUNE_FADING_MEMORIES))
continue;
if (RemoveFromXTargets && spell_target) {
if (mob->IsClient() && (spell_target->CheckAggro(mob) || spell_target->IsOnFeignMemory(mob)))
mob->CastToClient()->RemoveXTarget(spell_target, false);
else if (spell_target->IsClient() && (mob->CheckAggro(spell_target) || mob->IsOnFeignMemory(spell_target)))
spell_target->CastToClient()->RemoveXTarget(mob, false);
}
mob->RemoveFromHateList(spell_target);
}
}
void EntityList::RemoveFromXTargets(Mob *mob)
{
auto it = client_list.begin();
+1
View File
@@ -389,6 +389,7 @@ public:
void ExpeditionWarning(uint32 minutes_left);
void RemoveFromTargets(Mob* mob, bool RemoveFromXTargets = false);
void RemoveFromTargetsFadingMemories(Mob* spell_target, bool RemoveFromXTargets = false, uint32 max_level = 0);
void RemoveFromXTargets(Mob* mob);
void RemoveFromAutoXTargets(Mob* mob);
void ReplaceWithTarget(Mob* pOldMob, Mob*pNewTarget);
+33 -1
View File
@@ -2208,9 +2208,41 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Fading Memories");
#endif
int max_level = 0;
if (RuleB(Spells, UseFadingMemoriesMaxLevel)) {
//handle ROF2 era where limit value determines max level
if (spells[spell_id].limit_value[i]) {
max_level = spells[spell_id].limit_value[i];
}
//handle modern client era where max value determines max level or range above client.
else if (spells[spell_id].max_value[i]) {
if (spells[spell_id].max_value[i] >= 1000) {
max_level = 1000 - spells[spell_id].max_value[i];
}
else {
max_level = GetLevel() + spells[spell_id].max_value[i];
}
}
}
if(zone->random.Roll(spells[spell_id].base_value[i])) {
if (IsClient()) {
CastToClient()->Escape();
int pre_aggro_count = CastToClient()->GetAggroCount();
entity_list.RemoveFromTargetsFadingMemories(this, true, max_level);
SetInvisible(Invisibility::Invisible);
int post_aggro_count = CastToClient()->GetAggroCount();
if (RuleB(Spells, UseFadingMemoriesMaxLevel)) {
if (pre_aggro_count == post_aggro_count) {
Message(Chat::SpellFailure, "You failed to escape from all your opponents.");
break;
}
else if (post_aggro_count) {
Message(Chat::SpellFailure, "You failed to escape from combat but you evade some of your opponents.");
break;
}
}
MessageString(Chat::Skills, ESCAPE);
}
else{
entity_list.RemoveFromTargets(caster);