Skip to content

Commit

Permalink
rename DoT -> DamageOverTimeEffect
Browse files Browse the repository at this point in the history
  • Loading branch information
lodicolo committed Feb 27, 2025
1 parent b33e7fb commit 1891091
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,35 +1,79 @@
using System.Diagnostics.CodeAnalysis;
using Intersect.Core;
using Intersect.Enums;
using Intersect.Framework.Core;
using Intersect.GameObjects;
using Intersect.Utilities;
using Microsoft.Extensions.Logging;

namespace Intersect.Server.Entities.Combat;


public partial class DoT
public partial class DamageOverTimeEffect
{
public Guid Id = Guid.NewGuid();
public Guid Id { get; set; } = Guid.NewGuid();

public Entity Attacker;
public Entity Attacker { get; set; }

public int Count;
public int Count { get; set; }

private long mInterval;

public SpellDescriptor SpellDescriptor;
public SpellDescriptor SpellDescriptor { get; }

public DoT(Entity attacker, Guid spellId, Entity target)
public static bool TryCreate(
Entity attacker,
Guid spellDescriptorId,
Entity target,
[NotNullWhen(true)] out DamageOverTimeEffect? damageOverTimeEffect
)
{
SpellDescriptor = SpellDescriptor.Get(spellId);
if (SpellDescriptor.TryGet(spellDescriptorId, out var spellDescriptor))
{
return TryCreate(attacker, spellDescriptor, target, out damageOverTimeEffect);
}

Attacker = attacker;
Target = target;
ApplicationContext.CurrentContext.Logger.LogWarning(
"Skipping creation of DamageOverTimeEffect because SpellDescriptor is missing {SpellDescriptorId}",
spellDescriptor.Id
);
damageOverTimeEffect = null;
return false;
}

if (SpellDescriptor == null || SpellDescriptor.Combat.HotDotInterval < 1)
public static bool TryCreate(
Entity attacker,
SpellDescriptor spellDescriptor,
Entity target,
[NotNullWhen(true)] out DamageOverTimeEffect? damageOverTimeEffect
)
{
if (spellDescriptor.Combat.HotDotInterval < 1)
{
return;
ApplicationContext.CurrentContext.Logger.LogWarning(
"Skipping creation of DamageOverTimeEffect because the Heal/Damage-over-time interval is less than 1 for {SpellDescriptorId} ({SpellName})",
spellDescriptor.Id,
spellDescriptor.Name
);
damageOverTimeEffect = null;
return false;
}

damageOverTimeEffect = new DamageOverTimeEffect(attacker, spellDescriptor, target);
return damageOverTimeEffect != null;
}

private DamageOverTimeEffect(Entity attacker, SpellDescriptor spellDescriptor, Entity target)
{
ArgumentNullException.ThrowIfNull(attacker, nameof(attacker));
ArgumentNullException.ThrowIfNull(spellDescriptor, nameof(spellDescriptor));
ArgumentNullException.ThrowIfNull(target, nameof(target));

SpellDescriptor = spellDescriptor;

Attacker = attacker;
Target = target;

// Does target have a cleanse buff? If so, do not allow this DoT when spell is unfriendly.
if (!SpellDescriptor.Combat.Friendly)
{
Expand All @@ -44,11 +88,8 @@ public DoT(Entity attacker, Guid spellId, Entity target)


mInterval = Timing.Global.Milliseconds + SpellDescriptor.Combat.HotDotInterval;
// Subtract 1 since the first tick always occurs when the spell is cast.
Count = (SpellDescriptor.Combat.Duration + SpellDescriptor.Combat.HotDotInterval - 1) / SpellDescriptor.Combat.HotDotInterval;
target.DoT.TryAdd(Id, this);
target.CachedDots = target.DoT.Values.ToArray();

//Subtract 1 since the first tick always occurs when the spell is cast.
}

public Entity Target { get; }
Expand All @@ -57,14 +98,14 @@ public void Expire()
{
if (Target != null)
{
Target.DoT?.TryRemove(Id, out DoT val);
Target.CachedDots = Target.DoT?.Values.ToArray() ?? new DoT[0];
Target.DamageOverTimeEffects?.TryRemove(Id, out DamageOverTimeEffect val);
Target.CachedDamageOverTimeEffects = Target.DamageOverTimeEffects?.Values.ToArray() ?? new DamageOverTimeEffect[0];
}
}

public bool CheckExpired()
{
if (Target != null && !Target.DoT.ContainsKey(Id))
if (Target != null && !Target.DamageOverTimeEffects.ContainsKey(Id))
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion Intersect.Server.Core/Entities/Combat/Status.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public Status(Entity en, Entity attacker, SpellDescriptor spell, SpellEffect typ
}
}

foreach (var dot in en.CachedDots)
foreach (var dot in en.CachedDamageOverTimeEffects)
{
if (spell.Combat.Friendly != dot.SpellDescriptor.Combat.Friendly)
{
Expand Down
24 changes: 14 additions & 10 deletions Intersect.Server.Core/Entities/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@ public string FooterLabelJson
public List<Guid> Animations { get; set; } = [];

//DoT/HoT Spells
[NotMapped, JsonIgnore] public ConcurrentDictionary<Guid, DoT> DoT { get; } = [];
// TODO: Are DoTs from the same source entity not stackable? This should be configurable
[NotMapped, JsonIgnore] public ConcurrentDictionary<Guid, DamageOverTimeEffect> DamageOverTimeEffects { get; } = [];

[NotMapped, JsonIgnore]
public DoT[] CachedDots { get; set; } = new DoT[0];
[NotMapped, JsonIgnore] public DamageOverTimeEffect[] CachedDamageOverTimeEffects { get; set; } = [];

[NotMapped, JsonIgnore]
public EventMoveRoute MoveRoute { get; set; } = null;
Expand Down Expand Up @@ -350,7 +350,7 @@ public virtual void Update(long timeMs)
}

//DoT/HoT timers
foreach (var dot in CachedDots)
foreach (var dot in CachedDamageOverTimeEffects)
{
dot.Tick();
}
Expand Down Expand Up @@ -1946,15 +1946,19 @@ public virtual void TryAttack(
//Handle DoT/HoT spells]
if (spellDescriptor.Combat.HoTDoT)
{
foreach (var dot in target.CachedDots)
foreach (var dot in target.CachedDamageOverTimeEffects)
{
if (dot.SpellDescriptor.Id == spellDescriptor.Id && dot.Attacker == this)
{
dot.Expire();
}
}

new DoT(this, spellDescriptor.Id, target);
if (DamageOverTimeEffect.TryCreate(this, spellDescriptor, target, out var damageOverTimeEffect))
{
target.DamageOverTimeEffects.TryAdd(Id, damageOverTimeEffect);
target.CachedDamageOverTimeEffects = target.DamageOverTimeEffects.Values.ToArray();
}
}
}

Expand Down Expand Up @@ -3102,8 +3106,8 @@ public virtual void Die(bool dropItems = true, Entity killer = null)
instance.ClearEntityTargetsOf(this);
}

DoT?.Clear();
CachedDots = new DoT[0];
DamageOverTimeEffects?.Clear();
CachedDamageOverTimeEffects = new DamageOverTimeEffect[0];
Statuses?.Clear();
CachedStatuses = new Status[0];
Stat?.ToList().ForEach(stat => stat?.Reset());
Expand Down Expand Up @@ -3182,8 +3186,8 @@ public virtual void Reset()
}

// Remove any damage over time effects
DoT.Clear();
CachedDots = [];
DamageOverTimeEffects.Clear();
CachedDamageOverTimeEffects = [];
Statuses.Clear();
CachedStatuses = [];

Expand Down
4 changes: 2 additions & 2 deletions Intersect.Server.Core/Entities/Npc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,8 +1299,8 @@ private void Reset(bool resetVitals, bool clearLocation = false)
{
Statuses.Clear();
CachedStatuses = Statuses.Values.ToArray();
DoT.Clear();
CachedDots = DoT.Values.ToArray();
DamageOverTimeEffects.Clear();
CachedDamageOverTimeEffects = DamageOverTimeEffects.Values.ToArray();
for (var v = 0; v < Enum.GetValues<Vital>().Length; v++)
{
RestoreVital((Vital)v);
Expand Down

0 comments on commit 1891091

Please sign in to comment.