diff --git a/common/ruletypes.h b/common/ruletypes.h index e1475fa79..c3a8fd5dc 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -66,6 +66,7 @@ RULE_INT(Character, AutosaveIntervalS, 300) //0=disabled RULE_INT(Character, HPRegenMultiplier, 100) RULE_INT(Character, ManaRegenMultiplier, 100) RULE_INT(Character, EnduranceRegenMultiplier, 100) +RULE_BOOL(Character, OldMinMana, false) // this is used for servers that want to follow older skill cap formulas so they can still have some regen w/o mediate RULE_INT(Character, ConsumptionMultiplier, 100) //item's hunger restored = this value * item's food level, 100 = normal, 50 = people eat 2x as fast, 200 = people eat 2x as slow RULE_BOOL(Character, HealOnLevel, false) RULE_BOOL(Character, FeignKillsPet, false) diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 06c78c999..340493578 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -1274,6 +1274,11 @@ void Mob::ClearFeignMemory() { AI_feign_remember_timer->Disable(); } +bool Mob::IsOnFeignMemory(Client *attacker) const +{ + return feign_memory_list.find(attacker->CharacterID()) != feign_memory_list.end(); +} + bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) { /* diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 541454a58..696214113 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -1240,6 +1240,10 @@ int32 Client::CalcManaRegen(bool bCombat) { int regen = 0; auto level = GetLevel(); + // so the new formulas break down with older skill caps where you don't have the skill until 4 or 8 + // so for servers that want to use the old skill progression they can set this rule so they + // will get at least 1 for standing and 2 for sitting. + bool old = RuleB(Character, OldMinMana); if (!IsStarved()) { // client does some base regen for shrouds here if (IsSitting() || CanMedOnHorse()) { @@ -1255,6 +1259,10 @@ int32 Client::CalcManaRegen(bool bCombat) regen += skill / 15; } } + if (old) + regen = std::max(regen, 2); + } else if (old) { + regen = std::max(regen, 1); } } diff --git a/zone/entity.cpp b/zone/entity.cpp index a06a67092..0ab10982a 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1419,10 +1419,10 @@ void EntityList::RemoveFromTargets(Mob *mob, bool RemoveFromXTargets) continue; if (RemoveFromXTargets) { - if (m->IsClient() && mob->CheckAggro(m)) + if (m->IsClient() && (mob->CheckAggro(m) || mob->IsOnFeignMemory(m->CastToClient()))) m->CastToClient()->RemoveXTarget(mob, false); // FadingMemories calls this function passing the client. - else if (mob->IsClient() && m->CheckAggro(mob)) + else if (mob->IsClient() && (m->CheckAggro(mob) || m->IsOnFeignMemory(mob->CastToClient()))) mob->CastToClient()->RemoveXTarget(m, false); } @@ -1461,7 +1461,7 @@ void EntityList::RefreshAutoXTargets(Client *c) if (!m || m->GetHP() <= 0) continue; - if (m->CheckAggro(c) && !c->IsXTarget(m)) { + if ((m->CheckAggro(c) || m->IsOnFeignMemory(c)) && !c->IsXTarget(m)) { c->AddAutoXTarget(m, false); // we only call this before a bulk, so lets not send right away break; } @@ -2617,12 +2617,13 @@ void EntityList::RemoveFromHateLists(Mob *mob, bool settoone) auto it = npc_list.begin(); while (it != npc_list.end()) { if (it->second->CheckAggro(mob)) { - if (!settoone) + if (!settoone) { it->second->RemoveFromHateList(mob); - else + if (mob->IsClient()) + mob->CastToClient()->RemoveXTarget(it->second, false); // gotta do book keeping + } else { it->second->SetHateAmountOnEnt(mob, 1); - if (mob->IsClient()) - mob->CastToClient()->RemoveXTarget(it->second, false); // gotta do book keeping + } } ++it; } @@ -3079,7 +3080,10 @@ void EntityList::ClearAggro(Mob* targ) c->RemoveXTarget(it->second, false); it->second->RemoveFromHateList(targ); } - it->second->RemoveFromFeignMemory(targ->CastToClient()); //just in case we feigned + if (c && it->second->IsOnFeignMemory(c)) { + it->second->RemoveFromFeignMemory(c); //just in case we feigned + c->RemoveXTarget(it->second, false); + } ++it; } } @@ -3088,7 +3092,8 @@ void EntityList::ClearFeignAggro(Mob *targ) { auto it = npc_list.begin(); while (it != npc_list.end()) { - if (it->second->CheckAggro(targ)) { + // add Feign Memory check because sometimes weird stuff happens + if (it->second->CheckAggro(targ) || (targ->IsClient() && it->second->IsOnFeignMemory(targ->CastToClient()))) { if (it->second->GetSpecialAbility(IMMUNE_FEIGN_DEATH)) { ++it; continue; diff --git a/zone/mob.h b/zone/mob.h index 2642a96fb..058774c54 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -588,6 +588,7 @@ public: void AddFeignMemory(Client* attacker); void RemoveFromFeignMemory(Client* attacker); void ClearFeignMemory(); + bool IsOnFeignMemory(Client *attacker) const; void PrintHateListToClient(Client *who) { hate_list.PrintHateListToClient(who); } std::list& GetHateList() { return hate_list.GetHateList(); } bool CheckLosFN(Mob* other);