From 5631a0711fd51af35692bbbc7741de794fae7b97 Mon Sep 17 00:00:00 2001 From: Fryguy Date: Sun, 20 Aug 2023 00:36:06 -0400 Subject: [PATCH] [Feature] Add adjustability for AERampage Range. (#3548) * [Feature] Add adjustability for AERampage Range. This functionality is needed for fights like Ture to be accurate, where their ramp range was 101% of their melee safe range. Example in lua of utilizing this scripting ``` e.self:SetSpecialAbilityParam(SpecialAbility.area_rampage,8,101; ``` * Updates to address comments --- common/ruletypes.h | 2 +- zone/aggro.cpp | 29 +++++++++++++++++++---------- zone/common.h | 2 +- zone/hate_list.cpp | 6 ++++-- zone/mob.h | 2 +- zone/mob_ai.cpp | 5 +++++ 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index 077d86503..2ac07f0b4 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -455,7 +455,7 @@ RULE_INT(Spells, WizardCritMaximumRandomRatio, 70, "The maximum value for the ra RULE_CATEGORY_END() RULE_CATEGORY(Combat) -RULE_REAL(Combat, AERampageSafeZone, 0.018, "max hit ae ramp reduction range") +RULE_REAL(Combat, AERampageMaxDistance, 70, "Max AERampage range (% of max combat distance)") RULE_INT(Combat, PetBaseCritChance, 0, "Pet base crit chance") RULE_INT(Combat, NPCBashKickLevel, 6, "The level that NPCcan KICK/BASH") RULE_INT(Combat, MeleeCritDifficulty, 8900, "Value against which is rolled to check if a melee crit is triggered. Lower is easier") diff --git a/zone/aggro.cpp b/zone/aggro.cpp index b79a95246..f6b87a261 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -975,8 +975,7 @@ bool Mob::IsBeneficialAllowed(Mob *target) return false; } -bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage) -{ +bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage, ExtraAttackOptions *opts) { if (!other) { return(false); } @@ -1071,18 +1070,28 @@ bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage) SetPseudoRoot(false); } } + if (aeRampage) { - float multiplyer = GetSize() * RuleR(Combat, AERampageSafeZone); - float ramp_range = (size_mod * multiplyer); - if (_DistNoRoot <= ramp_range) { - return true; - } else { - return false; + float aeramp_size = RuleR(Combat, AERampageMaxDistance); + + if (opts) { + if (opts->range_percent > 0) { + aeramp_size = opts->range_percent; + } } + + if (aeramp_size <= 0) { + aeramp_size = 0.90; + } else { + aeramp_size /= 100; + } + + float ramp_range = size_mod * aeramp_size; + + return _DistNoRoot <= ramp_range; } - if (_DistNoRoot <= size_mod) - { + if (_DistNoRoot <= size_mod) { //A hack to kill an exploit till we get something better. if (flymode != GravityBehavior::Flying && _zDist > 500 && !CheckLastLosState()) { return false; diff --git a/zone/common.h b/zone/common.h index c019d408a..420d71c9b 100644 --- a/zone/common.h +++ b/zone/common.h @@ -891,7 +891,7 @@ struct ExtraAttackOptions { int hit_chance; int melee_damage_bonus_flat; int skilldmgtaken_bonus_flat; - + int range_percent; }; struct DamageTable { diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 9ef52765a..2acb30b9b 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -714,8 +714,9 @@ void HateList::PrintHateListToClient(Client *c) int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts) { - if (!target || !caster) + if (!target || !caster) { return 0; + } // tank will be hit ONLY if they are the only target on the hate list // if there is anyone else on the hate list, the tank will not be hit, even if those others aren't hit either @@ -730,9 +731,10 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption std::vector id_list; for (auto &h : list) { if (h->entity_on_hatelist && h->entity_on_hatelist != caster && h->entity_on_hatelist != target && - caster->CombatRange(h->entity_on_hatelist, 1.0, true)) { + caster->CombatRange(h->entity_on_hatelist, 1.0, true, opts)) { id_list.push_back(h->entity_on_hatelist->GetID()); } + if (count != -1 && id_list.size() > count) { break; } diff --git a/zone/mob.h b/zone/mob.h index cf20f85f3..d1673ea8e 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -249,7 +249,7 @@ public: inline int GetMitigationAC() { return mitigation_ac; } void MeleeMitigation(Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr); double RollD20(int offense, int mitigation); // CALL THIS FROM THE DEFENDER - bool CombatRange(Mob* other, float fixed_size_mod = 1.0, bool aeRampage = false); + bool CombatRange(Mob* other, float fixed_size_mod = 1.0, bool aeRampage = false, ExtraAttackOptions *opts = nullptr); virtual inline bool IsBerserk() { return false; } // only clients void RogueEvade(Mob *other); void CommonOutgoingHitSuccess(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index ea1e951eb..bae828059 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1285,6 +1285,11 @@ void Mob::AI_Process() { opts.crit_flat = cur; } + cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 8); + if (cur > 0) { + opts.range_percent = cur; + } + AreaRampage(&opts); specialed = true; }