Skip to content

Commit

Permalink
Fix various issues with SpellHandler.Effectiveness
Browse files Browse the repository at this point in the history
* Replaced with `CasterEffectiveness`, and is no longer modified by damage, duration, buff / debuff value calculations. This is typically 1.0, unless the caster has resurrection illness.
* Removed effectiveness parameter from `CalculateEffectDuration`. It now uses `CasterEffectiveness` to avoid wrong values being passed down.
* Removed many overrides to `ApplyEffectOnTarget` that were replacing `Effectiveness`. Most of them were copy pasted. Side note: the same could probably be done to `CalculateEffectDuration`.
* Added `CalculateBuffDebuffEffectiveness`. Called by `OnDurationEffectApply`. It handles both buffs and debuffs, the same way `SingleStatBuff.ApplyEffectOnTarget` did (which may or may not be accurate): 0.75~1.25 effectiveness based on spec and spell level, depending if the spell is a buff or a debuff and if the caster is a list caster or not.
* Added `CalculateDamageEffectiveness`. Called by `CalculateDamageToTarget`. Currently only overridden by `StyleBleeding` to ignore spell damage. Side note: bleeds seem to be affected by power relics.
* Updated various MLs and new archery accordingly. Side note: these seem very outdated.
* Removed unused `SpellHandler.m_stage`
* Made `/combatstats on` display buff and debuff effectivenesses if != 1 instead of whether a ToA bonus is present or not.

* Fixes DD+Snare debuff effectiveness affecting damage, resulting in much higher damage than intended.
* Fixes DD+Snare debuff effectiveness being affected by buff bonuses instead of debuff when the caster is a player (list caster).
* Fixes HoTs from NPCs benefiting from a 25% effectiveness bonus.
* Fixes buff and debuff duration being affected by buff and debuff effectiveness. Only values were supposed to be affected, not duration. Resurrection illness still affects duration.
* Fixes resurrection illness not affecting single target combat style effects, single target offensive procs, and savagery.
* Fixes resurrection illness affecting AoE item effects.
* Fixes heal and debuff crits granularity.
* Changes HoTs to be affected by buff effectiveness bonuses. No source for this, but it was one of the very few buffs not being affected by it and it didn’t seem to be on purpose.
* Changes HoTs to follow the same rule as buffs: 1.0 effectiveness for list-casters and NPCs, 0.75~1.25 for non-list casters.
  • Loading branch information
bm01 committed Jul 14, 2024
1 parent 9408758 commit 85a9847
Show file tree
Hide file tree
Showing 52 changed files with 853 additions and 1,965 deletions.
2 changes: 1 addition & 1 deletion GameServer/Enums/eProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ public enum eProperty : byte
BuffEffectiveness = 190,
CastingSpeed = 191,
OffhandDamageAndChance = 192,
DebuffEffectivness = 193,
DebuffEffectiveness = 193,
Fatigue = 194,
HealingEffectiveness = 195,
PowerPool = 196,
Expand Down
2 changes: 1 addition & 1 deletion GameServer/gameutils/GamePlayerUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ private static string ItemBonusDescription(int iBonus, int iBonusType)
//cap at 25 with no chance of going over
//DebuffEffectivness, BuffEffectiveness, HealingEffectiveness
//SpellDuration
if (iBonusType == (int)eProperty.DebuffEffectivness || iBonusType == (int)eProperty.BuffEffectiveness || iBonusType == (int)eProperty.HealingEffectiveness || iBonusType == (int)eProperty.SpellDuration || iBonusType == (int)eProperty.ArcaneSyphon)
if (iBonusType == (int)eProperty.DebuffEffectiveness || iBonusType == (int)eProperty.BuffEffectiveness || iBonusType == (int)eProperty.HealingEffectiveness || iBonusType == (int)eProperty.SpellDuration || iBonusType == (int)eProperty.ArcaneSyphon)
{
if (iBonus > 25)
iBonus = 25;
Expand Down
2 changes: 1 addition & 1 deletion GameServer/gameutils/SkillBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1822,7 +1822,7 @@ private static void RegisterPropertyNames()
"SkillBase.RegisterPropertyNames.CastingSpeed"));
m_propertyNames.Add(eProperty.OffhandDamageAndChance, LanguageMgr.GetTranslation(ServerProperties.Properties.DB_LANGUAGE,
"SkillBase.RegisterPropertyNames.OffhandChanceAndDamage"));
m_propertyNames.Add(eProperty.DebuffEffectivness, LanguageMgr.GetTranslation(ServerProperties.Properties.DB_LANGUAGE,
m_propertyNames.Add(eProperty.DebuffEffectiveness, LanguageMgr.GetTranslation(ServerProperties.Properties.DB_LANGUAGE,
"SkillBase.RegisterPropertyNames.DebuffEffectivness"));
m_propertyNames.Add(eProperty.Fatigue, LanguageMgr.GetTranslation(ServerProperties.Properties.DB_LANGUAGE,
"SkillBase.RegisterPropertyNames.Fatigue"));
Expand Down
2 changes: 1 addition & 1 deletion GameServer/propertycalc/TOABonusCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace DOL.GS.PropertyCalc
/// </summary>

//Debuff Effectivness
[PropertyCalculator(eProperty.DebuffEffectivness)]
[PropertyCalculator(eProperty.DebuffEffectiveness)]
public class DebuffEffectivnessPercentCalculator : PropertyCalculator
{
public override int CalcValue(GameLiving living, eProperty property)
Expand Down
10 changes: 2 additions & 8 deletions GameServer/spells/AblativeArmorSpellHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,8 @@ public override void FinishSpellCast(GameLiving target)
m_caster.Mana -= PowerCost(target);
base.FinishSpellCast(target);
}

/// <summary>
/// Calculates the effect duration in milliseconds
/// </summary>
/// <param name="target">The effect target</param>
/// <param name="effectiveness">The effect effectiveness</param>
/// <returns>The effect duration in milliseconds</returns>
protected override int CalculateEffectDuration(GameLiving target, double effectiveness)

protected override int CalculateEffectDuration(GameLiving target)
{
double duration = Spell.Duration;
duration *= 1.0 + m_caster.GetModified(eProperty.SpellDuration) * 0.01;
Expand Down
2 changes: 1 addition & 1 deletion GameServer/spells/Archery/Archery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ public override bool CasterIsAttacked(GameLiving attacker)
if (Spell.Uninterruptible)
return false;

if (IsInCastingPhase && Stage < 2)
if (IsInCastingPhase)
{
int mod = Caster.GetConLevel(attacker);
double chance = 65;
Expand Down
15 changes: 12 additions & 3 deletions GameServer/spells/Archery/Arrow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ public override bool UnstealthCasterOnStart
get { return false; }
}

protected override double CalculateDamageEffectiveness()
{
// Half of the damage is magical.
// Subtract any spelldamage bonus and re-calculate after half damage is calculated.
if (Caster is GamePlayer playerCaster)
return CasterEffectiveness * (0.5 - playerCaster.GetModified(eProperty.SpellDamage) * 0.01);
else
return CasterEffectiveness * 0.5;
}

/// <summary>
/// Fire arrow
/// </summary>
Expand Down Expand Up @@ -115,6 +125,8 @@ public ArrowOnTargetAction(GameLiving actionSource, GameLiving arrowTarget, Arro

protected override int OnTick(ECSGameTimer timer)
{
// A lot of things here seem to be outdated and need to be cleaned up.

GameLiving target = m_arrowTarget;
GameLiving caster = (GameLiving) timer.Owner;

Expand All @@ -131,9 +143,6 @@ protected override int OnTick(ECSGameTimer timer)
missrate += targetAD.Style.BonusToDefense;
}

// half of the damage is magical
// subtract any spelldamage bonus and re-calculate after half damage is calculated
m_handler.Effectiveness = 0.5 - caster.GetModified(eProperty.SpellDamage) * 0.01;
AttackData ad = m_handler.CalculateDamageToTarget(target);

// check for bladeturn miss
Expand Down
20 changes: 0 additions & 20 deletions GameServer/spells/Artifacts/BandofStars.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
/*
* DAWN OF LIGHT - The first free open source DAoC server emulator
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/

using System;
using DOL.AI.Brain;
using DOL.GS.Effects;
Expand Down Expand Up @@ -87,7 +68,6 @@ protected override int OnTick(ECSGameTimer timer)
if (target == null || !target.IsAlive || target.ObjectState != GameObject.eObjectState.Active || target.CurrentRegionID != caster.CurrentRegionID)
return 0;

m_handler.Effectiveness = 1;
AttackData ad = m_handler.CalculateDamageToTarget(target);
ad.Damage = (int)m_handler.Spell.Damage;
m_handler.SendDamageMessages(ad);
Expand Down
30 changes: 9 additions & 21 deletions GameServer/spells/CCSpellHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public override int OnEffectExpires(GameSpellEffect effect, bool noMessages)
return (effect.Name == "Pet Stun") ? 0 : 60000;
}

protected override int CalculateEffectDuration(GameLiving target, double effectiveness)
protected override int CalculateEffectDuration(GameLiving target)
{
double duration = base.CalculateEffectDuration(target, effectiveness);
double duration = base.CalculateEffectDuration(target);

// [Atlas - Takii] Disabling MOC effectiveness scaling in OF.
// double mocFactor = 1.0;
Expand Down Expand Up @@ -200,15 +200,9 @@ protected override bool CheckSpellResist(GameLiving target)
return base.CheckSpellResist(target);
}

/// <summary>
/// Calculates the effect duration in milliseconds
/// </summary>
/// <param name="target">The effect target</param>
/// <param name="effectiveness">The effect effectiveness</param>
/// <returns>The effect duration in milliseconds</returns>
protected override int CalculateEffectDuration(GameLiving target, double effectiveness)
protected override int CalculateEffectDuration(GameLiving target)
{
double duration = base.CalculateEffectDuration(target, effectiveness);
double duration = base.CalculateEffectDuration(target);
duration *= target.GetModified(eProperty.MesmerizeDurationReduction) * 0.01;
NPCECSMezImmunityEffect npcImmune = (NPCECSMezImmunityEffect)EffectListService.GetEffectOnTarget(target, eEffect.NPCMezImmunity);

Expand Down Expand Up @@ -244,11 +238,11 @@ protected override GameSpellEffect CreateSpellEffect(GameLiving target, double e
if (Spell.ResurrectMana == 1)
{
int freq = Spell != null ? Spell.Frequency : 0;
return new GameSpellEffect(this, CalculateEffectDuration(target, effectiveness), freq, effectiveness);
return new GameSpellEffect(this, CalculateEffectDuration(target), freq, effectiveness);
}

else
return new GameSpellAndImmunityEffect(this, CalculateEffectDuration(target, effectiveness), 0, effectiveness);
return new GameSpellAndImmunityEffect(this, CalculateEffectDuration(target), 0, effectiveness);
}

/// <summary>
Expand Down Expand Up @@ -300,16 +294,10 @@ public override void ApplyEffectOnTarget(GameLiving target)

base.ApplyEffectOnTarget(target);
}

/// <summary>
/// Calculates the effect duration in milliseconds
/// </summary>
/// <param name="target">The effect target</param>
/// <param name="effectiveness">The effect effectiveness</param>
/// <returns>The effect duration in milliseconds</returns>
protected override int CalculateEffectDuration(GameLiving target, double effectiveness)

protected override int CalculateEffectDuration(GameLiving target)
{
double duration = base.CalculateEffectDuration(target, effectiveness);
double duration = base.CalculateEffectDuration(target);
duration *= target.GetModified(eProperty.StunDurationReduction) * 0.01;
NPCECSStunImmunityEffect npcImmune = (NPCECSStunImmunityEffect)EffectListService.GetEffectOnTarget(target, eEffect.NPCStunImmunity);

Expand Down
2 changes: 1 addition & 1 deletion GameServer/spells/CommonAstralSpells.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public override void ApplyEffectOnTarget(GameLiving target)
}

Point2D summonloc;
beffect = CreateSpellEffect(target, Effectiveness);
beffect = CreateSpellEffect(target, CasterEffectiveness);
{
summonloc = target.GetPointFromHeading(target.Heading, 64);

Expand Down
10 changes: 2 additions & 8 deletions GameServer/spells/DamageAddAndShield.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,19 +277,13 @@ public override void FinishSpellCast(GameLiving target)
base.FinishSpellCast(target);
}

/// <summary>
/// Calculates the effect duration in milliseconds
/// </summary>
/// <param name="target">The effect target</param>
/// <param name="effectiveness">The effect effectiveness</param>
/// <returns>The effect duration in milliseconds</returns>
protected override int CalculateEffectDuration(GameLiving target, double effectiveness)
protected override int CalculateEffectDuration(GameLiving target)
{
double duration = Spell.Duration;
duration *= (1.0 + m_caster.GetModified(eProperty.SpellDuration) * 0.01);
return (int)duration;
}

/// <summary>
/// called when spell effect has to be started and applied to targets
/// </summary>
Expand Down
22 changes: 1 addition & 21 deletions GameServer/spells/DamageSpeedDecrease.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
/*
* DAWN OF LIGHT - The first free open source DAoC server emulator
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/

using System.Collections.Generic;
using DOL.GS.Effects;
using DOL.GS.PacketHandler;
Expand Down Expand Up @@ -114,8 +95,7 @@ public override int OnEffectExpires(GameSpellEffect effect, bool noMessages)
/// <returns></returns>
protected override GameSpellEffect CreateSpellEffect(GameLiving target, double effectiveness)
{
int duration = CalculateEffectDuration(target, effectiveness);
return new GameSpellEffect(this, duration, 0, effectiveness);
return new GameSpellEffect(this, CalculateEffectDuration(target), 0, effectiveness);
}

/// <summary>
Expand Down
22 changes: 1 addition & 21 deletions GameServer/spells/DisarmSpellHandler.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
/*
* DAWN OF LIGHT - The first free open source DAoC server emulator
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
using System;
using System.Collections;
using System.Collections.Generic;
using DOL.AI.Brain;
using DOL.GS.Effects;
Expand Down Expand Up @@ -57,7 +37,7 @@ public override void OnEffectStart(GameSpellEffect effect)
effect.Owner.LastAttackedByEnemyTickPvP = effect.Owner.CurrentRegion.Time;
Caster.LastAttackTickPvP = Caster.CurrentRegion.Time;
}
effect.Owner.DisarmedTime = effect.Owner.CurrentRegion.Time + CalculateEffectDuration(effect.Owner, Caster.Effectiveness);
effect.Owner.DisarmedTime = effect.Owner.CurrentRegion.Time + CalculateEffectDuration(effect.Owner);
effect.Owner.attackComponent.StopAttack();
MessageToLiving(effect.Owner, Spell.Message1, eChatType.CT_Spell);
Message.SystemToArea(effect.Owner, Util.MakeSentence(Spell.Message2, effect.Owner.GetName(0, false)), eChatType.CT_Spell, effect.Owner);
Expand Down
10 changes: 2 additions & 8 deletions GameServer/spells/DiseaseSpellHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,9 @@ public override int OnEffectExpires(GameSpellEffect effect, bool noMessages)
return 0;
}

/// <summary>
/// Calculates the effect duration in milliseconds
/// </summary>
/// <param name="target">The effect target</param>
/// <param name="effectiveness">The effect effectiveness</param>
/// <returns>The effect duration in milliseconds</returns>
protected override int CalculateEffectDuration(GameLiving target, double effectiveness)
protected override int CalculateEffectDuration(GameLiving target)
{
double duration = base.CalculateEffectDuration(target, effectiveness);
double duration = base.CalculateEffectDuration(target);
duration -= duration * target.GetResist(Spell.DamageType) * 0.01;

if (duration < 1)
Expand Down
25 changes: 0 additions & 25 deletions GameServer/spells/Fury.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
/*
* DAWN OF LIGHT - The first free open source DAoC server emulator
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/

using DOL.GS.Effects;

namespace DOL.GS.Spells
{
[SpellHandlerAttribute("Fury")]
public class FuryHandler : SpellHandler
{
public override void ApplyEffectOnTarget(GameLiving target)
{
Effectiveness = 1;
base.ApplyEffectOnTarget(target);
}

public override void OnEffectStart(GameSpellEffect effect)
{
int value = (int)m_spell.Value;
Expand Down
Loading

0 comments on commit 85a9847

Please sign in to comment.