mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
[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:
+51
-42
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user