[Rules] Add HasteCap and Hastev3Cap rules for NPCs, Bots and Mercs (#4406)

* [Rules] Add HasteCap and Hastev3Cap rules for NPCs, Bots and Mercs

Previously NPCs, bots and mercs all had a flat haste cap of 150 whereas clients were capped at 100.

NPCs, bots and mercs used the character rule for v3 cap, they now each have their own.

Rules for v3 cap are the default of 25 as they were using.
Rules for haste caps are the default of 150 for NPCs they were using but lowered to 100 for bots and mercs, the same as clients.

This also adds haste output to the GM target stat window

* Fix for stat windows to account for client haste
This commit is contained in:
nytmyr
2024-07-22 05:06:49 -05:00
committed by GitHub
parent 3bfdc0cf71
commit c73a1e8bea
3 changed files with 63 additions and 14 deletions
+44 -14
View File
@@ -2415,7 +2415,7 @@ void Mob::SendStatsWindow(Client* c, bool use_window)
DialogueWindow::TableCell(
fmt::format(
"{} ({})",
Strings::Commify(GetHaste()),
IsClient() ? Strings::Commify(CastToClient()->GetHaste()) : Strings::Commify(GetHaste()),
Strings::Commify(RuleI(Character, HasteCap))
)
)
@@ -2682,12 +2682,12 @@ void Mob::SendStatsWindow(Client* c, bool use_window)
).c_str()
);
if (GetHaste()) {
if ((IsClient() && CastToClient()->GetHaste()) || (!IsClient() && GetHaste())) {
c->Message(
Chat::White,
fmt::format(
"Haste: {}/{} (Item: {} + Spell: {} + Over: {})",
Strings::Commify(GetHaste()),
IsClient() ? Strings::Commify(CastToClient()->GetHaste()) : Strings::Commify(GetHaste()),
Strings::Commify(RuleI(Character, HasteCap)),
Strings::Commify(itembonuses.haste),
Strings::Commify(spellbonuses.haste + spellbonuses.hastetype2),
@@ -3217,6 +3217,14 @@ void Mob::ShowStats(Client* c)
).c_str()
);
c->Message(
Chat::White,
fmt::format(
"Combat Stats | Haste: {}",
GetHaste()
).c_str()
);
// Stats
c->Message(
Chat::White,
@@ -5431,10 +5439,19 @@ int Mob::GetHaste()
h += spellbonuses.hastetype2 > 10 ? 10 : spellbonuses.hastetype2;
// 26+ no cap, 1-25 10
if (level > 25 || (IsClient() && RuleB(Character, IgnoreLevelBasedHasteCaps))) // 26+
if (
level > 25 ||
(
(IsNPC() && RuleB(NPC, NPCIgnoreLevelBasedHasteCaps)) ||
(IsBot() && RuleB(Bots, BotsIgnoreLevelBasedHasteCaps)) ||
(IsMerc() && RuleB(Mercs, MercsIgnoreLevelBasedHasteCaps))
)
) {
h += itembonuses.haste;
else // 1-25
}
else { // 1-25
h += itembonuses.haste > 10 ? 10 : itembonuses.haste;
}
// mobs are different!
Mob *owner = nullptr;
@@ -5446,23 +5463,36 @@ int Mob::GetHaste()
cap = 10 + level;
cap += std::max(0, owner->GetLevel() - 39) + std::max(0, owner->GetLevel() - 60);
} else {
cap = 150;
cap = (IsNPC() ? RuleI(NPC, NPCHasteCap) : IsBot() ? RuleI(Bots, BotsHasteCap) : IsMerc() ? RuleI(Mercs, MercsHasteCap) : 150);
}
if(h > cap)
h = cap;
// 51+ 25 (despite there being higher spells...), 1-50 10
if (level > 50 || (IsClient() && RuleB(Character, IgnoreLevelBasedHasteCaps))) { // 51+
cap = RuleI(Character, Hastev3Cap);
if (spellbonuses.hastetype3 > cap) {
h += cap;
} else {
h += spellbonuses.hastetype3;
if (
(IsNPC() && !RuleB(NPC, NPCIgnoreLevelBasedHasteCaps)) ||
(IsBot() && !RuleB(Bots, BotsIgnoreLevelBasedHasteCaps)) ||
(IsMerc() && !RuleB(Mercs, MercsIgnoreLevelBasedHasteCaps))
) {
if (level > 50) { // 51+
cap = (IsNPC() ? RuleI(NPC, NPCHastev3Cap) : IsBot() ? RuleI(Bots, BotsHastev3Cap) : IsMerc() ? RuleI(Mercs, MercsHastev3Cap) : RuleI(Character, Hastev3Cap));
if (spellbonuses.hastetype3 > cap) {
h += cap;
}
else {
h += spellbonuses.hastetype3;
}
}
else { // 1-50
h += spellbonuses.hastetype3 > 10 ? 10 : spellbonuses.hastetype3;
}
} else { // 1-50
h += spellbonuses.hastetype3 > 10 ? 10 : spellbonuses.hastetype3;
}
else {
h += spellbonuses.hastetype3;
}
h += extra_haste; //GM granted haste.
return 100 + h;
+10
View File
@@ -234,6 +234,15 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
return std::to_string(mob->GetMitigationAC());
}
if (attribute == "haste") {
if (mob->IsClient()) {
return Strings::Commify(std::to_string(mob->CastToClient()->GetHaste()));
}
else {
return Strings::Commify(std::to_string(mob->GetHaste()));
}
}
if (mob->IsNPC()) {
NPC *npc = mob->CastToNPC();
@@ -700,6 +709,7 @@ void Mob::DisplayInfo(Mob *mob)
"total_defense",
"offense",
"mitigation_ac",
"haste",
};
window_text += WriteDisplayInfoSection(mob, "Calculations", calculations, 1, true);