From 497170c4533ba9d8017122eec39deab9cb2b81c6 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sun, 25 Jun 2017 16:30:37 -0400 Subject: [PATCH 1/3] Optimize Entity::AESpell Probably could use more work, but quick testing had this method taking the least amount of time in various situations --- zone/effects.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/zone/effects.cpp b/zone/effects.cpp index 8d8265e32..e7933a833 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -703,6 +703,10 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_ float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range; float dist_targ = 0; + const auto &position = spells[spell_id].targettype == ST_Ring ? caster->GetTargetRingLocation() : static_cast(center->GetPosition()); + glm::vec2 min = { position.x - dist, position.y - dist }; + glm::vec2 max = { position.x + dist, position.y + dist }; + bool bad = IsDetrimentalSpell(spell_id); bool isnpc = caster->IsNPC(); int MAX_TARGETS_ALLOWED = 4; @@ -732,13 +736,10 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_ continue; if (spells[spell_id].pcnpc_only_flag == 2 && (curmob->IsClient() || curmob->IsMerc())) continue; + if (!IsWithinAxisAlignedBox(static_cast(curmob->GetPosition()), min, max)) + continue; - if (spells[spell_id].targettype == ST_Ring) { - dist_targ = DistanceSquared(static_cast(curmob->GetPosition()), caster->GetTargetRingLocation()); - } - else if (center) { - dist_targ = DistanceSquared(curmob->GetPosition(), center->GetPosition()); - } + dist_targ = DistanceSquared(curmob->GetPosition(), position); if (dist_targ > dist2) //make sure they are in range continue; @@ -761,9 +762,7 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_ if (bad) { if (!caster->IsAttackAllowed(curmob, true)) continue; - if (center && !spells[spell_id].npc_no_los && !center->CheckLosFN(curmob)) - continue; - if (!center && !spells[spell_id].npc_no_los && !caster->CheckLosFN(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ(), curmob->GetSize())) + if (!spells[spell_id].npc_no_los && !caster->CheckLosFN(position.x, position.y, position.z, curmob->GetSize())) continue; } else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies... // This does not check faction for beneficial AE buffs..only agro and attackable. From 3e1b75b81484ebc3137dc878e32e1cff16382d97 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sun, 25 Jun 2017 18:18:27 -0400 Subject: [PATCH 2/3] Fix Rain target limit (massive nerf) Added rule Spells:OldRainTargets, set to true if you don't want the nerf --- common/ruletypes.h | 1 + zone/beacon.cpp | 7 +++++-- zone/beacon.h | 1 + zone/effects.cpp | 14 ++++++++++---- zone/entity.h | 2 +- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index e9599e09b..11a55c423 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -397,6 +397,7 @@ RULE_BOOL(Spells, FlatItemExtraSpellAmt, false) // allow SpellDmg stat to affect RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false) // ignore the 5 level spread on applying SpellDmg RULE_BOOL(Spells, AllowItemTGB, false) // TGB doesn't work with items on live, custom servers want it though RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the target type to single target. +RULE_BOOL(Spells, OldRainTargets, false) // use old incorrectly implemented max targets for rains RULE_CATEGORY_END() RULE_CATEGORY(Combat) diff --git a/zone/beacon.cpp b/zone/beacon.cpp index 27f86fce7..e5ea9f38f 100644 --- a/zone/beacon.cpp +++ b/zone/beacon.cpp @@ -68,6 +68,7 @@ Beacon::Beacon(Mob *at_mob, int lifetime) resist_adjust = 0; spell_iterations = 0; caster_id = 0; + max_targets = 4; // default if(lifetime) remove_timer.Start(); @@ -93,10 +94,10 @@ bool Beacon::Process() ) { Mob *caster = entity_list.GetMob(caster_id); - if(caster && spell_iterations--) + if(caster && spell_iterations-- && max_targets) { bool affect_caster = (!caster->IsNPC() && !caster->IsAIControlled()); //NPC AE spells do not affect the NPC caster - entity_list.AESpell(caster, this, spell_id, affect_caster, resist_adjust); + entity_list.AESpell(caster, this, spell_id, affect_caster, resist_adjust, &max_targets); } else { @@ -126,6 +127,8 @@ void Beacon::AELocationSpell(Mob *caster, uint16 cast_spell_id, int16 resist_adj this->resist_adjust = resist_adjust; spell_iterations = spells[spell_id].AEDuration / 2500; spell_iterations = spell_iterations < 1 ? 1 : spell_iterations; // at least 1 + if (spells[spell_id].aemaxtargets) + max_targets = spells[spell_id].aemaxtargets; spell_timer.Start(2500); spell_timer.Trigger(); } diff --git a/zone/beacon.h b/zone/beacon.h index b79ed318c..c22189dfd 100644 --- a/zone/beacon.h +++ b/zone/beacon.h @@ -56,6 +56,7 @@ protected: int16 resist_adjust; int spell_iterations; Timer spell_timer; + int max_targets; uint16 caster_id; private: diff --git a/zone/effects.cpp b/zone/effects.cpp index e7933a833..0585f3c50 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -694,7 +694,7 @@ void EntityList::AETaunt(Client* taunter, float range, int32 bonus_hate) // causes caster to hit every mob within dist range of center with // spell_id. // NPC spells will only affect other NPCs with compatible faction -void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust) +void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int *max_targets) { Mob *curmob = nullptr; @@ -709,9 +709,13 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_ bool bad = IsDetrimentalSpell(spell_id); bool isnpc = caster->IsNPC(); - int MAX_TARGETS_ALLOWED = 4; - if (spells[spell_id].aemaxtargets) + if (RuleB(Spells, OldRainTargets)) + max_targets = nullptr; // ignore it! + + int MAX_TARGETS_ALLOWED = max_targets ? *max_targets : 4; + + if (!max_targets && spells[spell_id].aemaxtargets) MAX_TARGETS_ALLOWED = spells[spell_id].aemaxtargets; int iCounter = 0; @@ -789,8 +793,10 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_ } if (!isnpc || spells[spell_id].aemaxtargets) //npcs are not target limited (unless casting a spell with a target limit)... - iCounter++; + iCounter++; // should really pull out the MAX_TARGETS_ALLOWED calc so we can break early ... } + if (max_targets) + *max_targets = *max_targets - std::min(iCounter, *max_targets); // could be higher than the count } void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster) diff --git a/zone/entity.h b/zone/entity.h index 94078691a..e2224d05d 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -357,7 +357,7 @@ public: void AEAttack(Mob *attacker, float dist, int Hand = EQEmu::inventory::slotPrimary, int count = 0, bool IsFromSpell = false); void AETaunt(Client *caster, float range=0, int32 bonus_hate=0); - void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0); + void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0, int *max_targets = nullptr); void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true); void AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true); From c0f53647b8b7c8e354af224edc238eab1f6dd443 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 25 Jun 2017 20:37:37 -0500 Subject: [PATCH 3/3] Revert 5fac13075b7acbd685821c1c12494a1d0df321b9 until we don't creep client resend up to 4 seconds so quickly, this causes issues in higher traffic amounts and takes longer for clients to recover than needed --- common/net/daybreak_connection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index 2ec7f200f..b4faf2438 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -220,7 +220,7 @@ namespace EQ resend_delay_ms = 150; resend_delay_factor = 1.5; resend_delay_min = 150; - resend_delay_max = 4000; + resend_delay_max = 1000; connect_delay_ms = 500; stale_connection_ms = 90000; connect_stale_ms = 5000;