[Rule] Over Taunt Hate (#3900)

* [Rule] Over taunt hate rule

Rule to add additional hate when taunt succeeds. This can help tune snap aggro on taunt classes. Only works when taunt succeeds and not already top hate.

* Requested Adjustments

* Add default +1 on rule

* Revert back to 0 default on rule with +1 on the standard formula

* formatting fix
This commit is contained in:
Fryguy
2024-01-08 12:11:04 -05:00
committed by GitHub
parent 3e958c575b
commit dfb06db17b
3 changed files with 53 additions and 43 deletions
+51 -42
View File
@@ -2128,19 +2128,15 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
}
}
void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell, int32 bonus_hate)
void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool from_spell, int32 bonus_hate)
{
if (who == nullptr)
if (!who || DivineAura() || (!from_spell && !CombatRange(who))) {
return;
}
if (DivineAura())
return;
if (!FromSpell && !CombatRange(who))
return;
if (!always_succeed && IsClient())
if (!always_succeed && IsClient()) {
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillTaunt, who, 10);
}
Mob *hate_top = who->GetHateMost();
@@ -2148,57 +2144,63 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell,
bool success = false;
// Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level.
if ((RuleB(Combat, TauntOverLevel) == false) && (level_difference < 0) ||
who->GetSpecialAbility(IMMUNE_TAUNT)) {
if (
!RuleB(Combat, TauntOverLevel) &&
level_difference < 0 ||
who->GetSpecialAbility(IMMUNE_TAUNT)
) {
MessageString(Chat::SpellFailure, FAILED_TAUNT);
return;
}
// All values used based on live parses after taunt was updated in 2006.
if ((hate_top && hate_top->GetHPRatio() >= 20) || hate_top == nullptr || chance_bonus) {
if (
(hate_top && hate_top->GetHPRatio() >= 20) ||
!hate_top ||
chance_bonus
) {
// SE_Taunt this is flat chance
if (chance_bonus) {
success = zone->random.Roll(chance_bonus);
} else {
float tauntchance = 50.0f;
if (always_succeed)
tauntchance = 101.0f;
else {
float taunt_chance = 50.0f;
if (always_succeed) {
taunt_chance = 101.0f;
} else {
if (level_difference < 0) {
tauntchance += static_cast<float>(level_difference) * 3.0f;
if (tauntchance < 20)
tauntchance = 20.0f;
}
else {
tauntchance += static_cast<float>(level_difference) * 5.0f;
if (tauntchance > 65)
tauntchance = 65.0f;
taunt_chance += static_cast<float>(level_difference) * 3.0f;
if (taunt_chance < 20) {
taunt_chance = 20.0f;
}
} else {
taunt_chance += static_cast<float>(level_difference) * 5.0f;
if (taunt_chance > 65) {
taunt_chance = 65.0f;
}
}
}
// TauntSkillFalloff rate is not based on any real data. Default of 33% gives a reasonable
// result.
if (IsClient() && !always_succeed)
tauntchance -= (RuleR(Combat, TauntSkillFalloff) *
if (IsClient() && !always_succeed) {
taunt_chance -= (RuleR(Combat, TauntSkillFalloff) *
(CastToClient()->MaxSkill(EQ::skills::SkillTaunt) -
GetSkill(EQ::skills::SkillTaunt)));
}
if (tauntchance < 1)
tauntchance = 1.0f;
if (taunt_chance < 1) {
taunt_chance = 1.0f;
}
tauntchance /= 100.0f;
success = tauntchance > zone->random.Real(0, 1);
taunt_chance /= 100.0f;
success = taunt_chance > zone->random.Real(0, 1);
LogHate(
"Taunter mob {} target npc {} tauntchance [{}] success [{}] hate_top [{}]",
"Taunter mob {} target npc {} taunt_chance [{}] success [{}] hate_top [{}]",
GetMobDescription(),
who->GetMobDescription(),
tauntchance,
taunt_chance,
success ? "true" : "false",
hate_top ? hate_top->GetMobDescription() : "not found"
);
@@ -2206,27 +2208,34 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell,
if (success) {
if (hate_top && hate_top != this) {
int64 newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1 + bonus_hate;
int64 new_hate = (
(who->GetNPCHate(hate_top) - who->GetNPCHate(this)) +
bonus_hate +
RuleI(Combat, TauntOverAggro) +
1
);
LogHate(
"Taunter mob {} target npc {} newhate [{}] hated_top {} hate_of_top [{}] this_hate [{}] bonus_hate [{}]",
"Not Top Hate - Taunter [{}] Target [{}] Hated Top [{}] Hate Top Amt [{}] This Character Amt [{}] Bonus_Hate Amt [{}] TauntOverAggro Amt [{}] - Total [{}]",
GetMobDescription(),
who->GetMobDescription(),
newhate,
hate_top->GetMobDescription(),
who->GetNPCHate(hate_top),
who->GetNPCHate(this),
bonus_hate
bonus_hate,
RuleI(Combat, TauntOverAggro),
new_hate
);
who->CastToNPC()->AddToHateList(this, newhate);
who->CastToNPC()->AddToHateList(this, new_hate);
success = true;
} else {
who->CastToNPC()->AddToHateList(this, 12);
}
if (who->CanTalk())
if (who->CanTalk()) {
who->SayString(SUCCESSFUL_TAUNT, GetCleanName());
}
} else {
MessageString(Chat::SpellFailure, FAILED_TAUNT);
}