Skip to content

Instantly share code, notes, and snippets.

@tywtyw2002
Created May 29, 2025 05:20
Show Gist options
  • Select an option

  • Save tywtyw2002/0076bc38cbf85122c1323e6223b1ef19 to your computer and use it in GitHub Desktop.

Select an option

Save tywtyw2002/0076bc38cbf85122c1323e6223b1ef19 to your computer and use it in GitHub Desktop.
// 84839 - Paladin
// 84840 - Druid
// 93098 - Warrior
// 93099 - DK
// 120267 - Monk
class spell_common_vengeance : public AuraScript
{
PrepareAuraScript(spell_common_vengeance);
enum { SEPLL_VENGEANCE = 132365 };
struct VeneganceAttackerInfo
{
uint32 LastDamage;
TimeValue LastTime;
};
std::map<uint64, VeneganceAttackerInfo> attackers;
void HandleProc(ProcEventInfo& eventInfo)
{
// Nobody know how this shit should work.
// This fucking formula 0.015 * DamageTaken + OldVengeance * OldVengeanceSecondsRemaining / 20 doesn't work because of buff degradation.
// How to calculate equilibrium point also unknown.
// Fuck it.
Unit* owner = GetUnitOwner();
Unit* actor = eventInfo.GetActor();
bool challenge = owner->GetMap()->GetDifficulty() == DUNGEON_DIFFICULTY_CHALLENGE;
if (!actor || actor->GetCharmerOrOwnerPlayerOrPlayerItself())
return;
uint32 damage = eventInfo.GetProcTriggerContext()->UnmitigatedDamage;
if (!damage)
return;
damage *= owner->GetTotalAuraMultiplier(SPELL_AURA_MOD_DAMAGE_TAKEN, [](AuraEffect const* effect)
{
return effect->GetAmount() > 0;
});
float vengPct = challenge ? 0.018f : 0.015f;
// The Nth strongest(based on pre - mitigation average auto attack DPS) mob that has hit you in the last 5 seconds
// grants 1 / Nth of full vengeance with their attacks.N is recalculated on every hit taken.
uint32 place = 1;
auto now = TimeValue::Now();
auto timecap = now - Seconds(5);
auto& attacker = attackers[actor->GetGUID()];
attacker.LastTime = now;
attacker.LastDamage = damage;
for (auto itr = attackers.begin(); itr != attackers.end();)
{
if (itr->second.LastTime < timecap)
{
attackers.erase(itr++);
continue;
}
if (itr->second.LastDamage > damage)
++place;
++itr;
}
if (eventInfo.GetHitMask() & PROC_EX_CRITICAL_HIT)
damage *= 1.5f; // Only 50% from crit
float newAmount = damage * vengPct;
// Add ap from current strike after the balance point calculation, just assumption
// damage * 1 / palce
if (!challenge)
newAmount /= place;
// modify according to damage type; spell damage gives 2.5x as much Vengeance
if (eventInfo.GetSpellInfo())
newAmount *= 2.5;
newAmount *= sWorld->getFloatConfig(CONFIG_VENGEANCE_MULTIPLIER);
if (AuraEffect* venegance = owner->GetAuraEffect(SEPLL_VENGEANCE, EFFECT_0))
newAmount += venegance->GetFloatAmount() * venegance->GetBase()->GetDuration() / venegance->GetBase()->GetMaxDuration();
float attackFrequency = 0.0f;
if (eventInfo.GetSpellInfo())
attackFrequency = 1.0f / 60.0f;
else
attackFrequency = 1.0f / (actor->GetFloatValue(UNIT_FIELD_ATTACK_ROUND_BASE_TIME) / 1000.0f);
float equilibrium = damage * vengPct * attackFrequency * 20.0f;
// simcraft has equilibrium / 2
if (equilibrium * 0.66f > newAmount)
newAmount = equilibrium * 0.66f;
newAmount = std::min(newAmount, float(owner->GetMaxHealth()));
owner->CastSpell(owner, SEPLL_VENGEANCE, true);
if (Aura* venegance = owner->GetAura(SEPLL_VENGEANCE))
{
venegance->GetEffect(EFFECT_0)->ChangeAmount(newAmount);
venegance->GetEffect(EFFECT_1)->ChangeAmount(newAmount);
venegance->RefreshDuration(false);
}
}
void Register() override
{
OnProc += AuraProcFn(spell_common_vengeance::HandleProc);
}
};
// 2983 - Sprint
// 23451 - Speed (BG buff)
// 54861 - Nitro Boosts
// 58875 - Spirit Walk
// 64129 - Body and Soul
// 68992 - Darkflight
// 85499 - Speed of Light
// 108843 - Blazing Speed
// 111400 - Burning Rush
// 116841 - Tiger's Lust
// 137573 - Burst of Speed
class spell_common_run_speed_marker : public AuraScript
{
PrepareAuraScript(spell_common_run_speed_marker);
enum { SPELL_RUN_SPEED_MARKER = 96223 };
void HandleApply(AuraEffect const*, AuraEffectHandleModes)
{
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_RUN_SPEED_MARKER, true);
}
void HandleRemove(AuraEffect const*, AuraEffectHandleModes)
{
static std::set<uint32> const nonStackBuffs
{
2983, // Sprint
23451, // Speed (BG buff)
54861, // Nitro Boosts
58875, // Spirit Walk
64129, // Body and Soul
68992, // Darkflight
85499, // Speed of Light
108843, // Blazing Speed
111400, // Burning Rush
116841, // Tiger's Lust
137573, // Burst of Speed
};
for (auto&& itr : nonStackBuffs)
if (GetUnitOwner()->HasAura(itr))
return;
GetUnitOwner()->RemoveAurasDueToSpell(SPELL_RUN_SPEED_MARKER);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_common_run_speed_marker::HandleApply, EFFECT_0, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_common_run_speed_marker::HandleRemove, EFFECT_0, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL);
}
};
// 139569 - Combo Point Delayed.
// Triggered by Ruthlessness (14161) and Item - Druid T15 Feral 2P Bonus (138352)
class spell_common_combo_point_delayed : public SpellScript
{
PrepareSpellScript(spell_common_combo_point_delayed);
void GainCombopoint()
{
if (Player* caster = GetCaster()->ToPlayer())
{
uint64 targetGuid = caster->GetTarget();
caster->m_Events.Schedule(1, [=]
{
if (Unit* target = ObjectAccessor::GetUnit(*caster, targetGuid))
caster->CastSpell(target, 139546, true);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment