fix(items): harden Battle Lust cleanup
This commit is contained in:
parent
4d9a7f815f
commit
d1580614e0
4 changed files with 184 additions and 3 deletions
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Text;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -99,6 +100,7 @@ public class BattleLustPropertyTests
|
|||
var wielder = CreateMobile(hitsMax: 5000, hits: 5000);
|
||||
var source = CreateMobile(location: new Point3D(6201, 500, 0));
|
||||
var deletedSource = CreateMobile(location: new Point3D(6202, 500, 0));
|
||||
var deadSource = CreateDeadPlayerMobile(new Point3D(6203, 500, 0));
|
||||
var weapon = EquipBattleLustWeapon(wielder);
|
||||
|
||||
try
|
||||
|
|
@ -122,6 +124,10 @@ public class BattleLustPropertyTests
|
|||
ApplyDamage(wielder, deletedSource, BattleLust.DamageThreshold);
|
||||
Assert.Equal(0, BattleLust.GetPoints(wielder));
|
||||
|
||||
Core._now = Core._now.AddSeconds(2);
|
||||
ApplyDamage(wielder, deadSource, BattleLust.DamageThreshold);
|
||||
Assert.Equal(0, BattleLust.GetPoints(wielder));
|
||||
|
||||
Core._now = Core._now.AddSeconds(2);
|
||||
ApplyDamage(wielder, source, BattleLust.DamageThreshold);
|
||||
Assert.Equal(1, BattleLust.GetPoints(wielder));
|
||||
|
|
@ -135,6 +141,38 @@ public class BattleLustPropertyTests
|
|||
wielder.Delete();
|
||||
source.Delete();
|
||||
deletedSource.Delete();
|
||||
deadSource.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DamageTaken_DoesNotGainWhenMobileDamageAppliesNoHitPointLoss()
|
||||
{
|
||||
var previousExpansion = Core.Expansion;
|
||||
var previousNow = Core._now;
|
||||
var wielder = CreateMobile(hitsMax: 5000, hits: 5000);
|
||||
var source = CreateMobile(location: new Point3D(6201, 500, 0));
|
||||
var weapon = EquipBattleLustWeapon(wielder);
|
||||
|
||||
try
|
||||
{
|
||||
Core.Expansion = Expansion.SA;
|
||||
Core._now = TestNow;
|
||||
wielder.Blessed = true;
|
||||
|
||||
ApplyDamage(wielder, source, BattleLust.DamageThreshold);
|
||||
|
||||
Assert.Equal(5000, wielder.Hits);
|
||||
Assert.Equal(0, BattleLust.GetPoints(wielder));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Core.Expansion = previousExpansion;
|
||||
Core._now = previousNow;
|
||||
BattleLust.Clear(wielder);
|
||||
weapon.Delete();
|
||||
wielder.Delete();
|
||||
source.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,6 +295,105 @@ public class BattleLustPropertyTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuntimeContext_ClearsOnWeaponLossEvenIfReequippedBeforeLazyCleanup()
|
||||
{
|
||||
var previousExpansion = Core.Expansion;
|
||||
var previousNow = Core._now;
|
||||
var wielder = CreateMobile();
|
||||
var source = CreateMobile(location: new Point3D(6201, 500, 0));
|
||||
var weapon = EquipBattleLustWeapon(wielder);
|
||||
|
||||
try
|
||||
{
|
||||
Core.Expansion = Expansion.SA;
|
||||
Core._now = TestNow;
|
||||
|
||||
ApplyDamage(wielder, source, BattleLust.DamageThreshold);
|
||||
Assert.Equal(1, BattleLust.GetPoints(wielder));
|
||||
|
||||
wielder.RemoveItem(weapon);
|
||||
wielder.AddItem(weapon);
|
||||
|
||||
Assert.Equal(0, BattleLust.GetPoints(wielder));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Core.Expansion = previousExpansion;
|
||||
Core._now = previousNow;
|
||||
BattleLust.Clear(wielder);
|
||||
weapon.Delete();
|
||||
wielder.Delete();
|
||||
source.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuntimeContext_ClearsWhenBattleLustPropertyIsRemovedEvenIfRestoredBeforeLazyCleanup()
|
||||
{
|
||||
var previousExpansion = Core.Expansion;
|
||||
var previousNow = Core._now;
|
||||
var wielder = CreateMobile();
|
||||
var source = CreateMobile(location: new Point3D(6201, 500, 0));
|
||||
var weapon = EquipBattleLustWeapon(wielder);
|
||||
|
||||
try
|
||||
{
|
||||
Core.Expansion = Expansion.SA;
|
||||
Core._now = TestNow;
|
||||
|
||||
ApplyDamage(wielder, source, BattleLust.DamageThreshold);
|
||||
Assert.Equal(1, BattleLust.GetPoints(wielder));
|
||||
|
||||
weapon.WeaponAttributes.BattleLust = 0;
|
||||
weapon.WeaponAttributes.BattleLust = 1;
|
||||
|
||||
Assert.Equal(0, BattleLust.GetPoints(wielder));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Core.Expansion = previousExpansion;
|
||||
Core._now = previousNow;
|
||||
BattleLust.Clear(wielder);
|
||||
weapon.Delete();
|
||||
wielder.Delete();
|
||||
source.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuntimeContext_ClearsOnInvalidMapEvenIfOwnerReturnsBeforeDecayTick()
|
||||
{
|
||||
var previousExpansion = Core.Expansion;
|
||||
var previousNow = Core._now;
|
||||
var wielder = CreateMobile();
|
||||
var source = CreateMobile(location: new Point3D(6201, 500, 0));
|
||||
var weapon = EquipBattleLustWeapon(wielder);
|
||||
|
||||
try
|
||||
{
|
||||
Core.Expansion = Expansion.SA;
|
||||
Core._now = TestNow;
|
||||
|
||||
ApplyDamage(wielder, source, BattleLust.DamageThreshold);
|
||||
Assert.Equal(1, BattleLust.GetPoints(wielder));
|
||||
|
||||
wielder.MoveToWorld(Point3D.Zero, Map.Internal);
|
||||
wielder.MoveToWorld(new Point3D(6200, 500, 0), Map.Felucca);
|
||||
|
||||
Assert.Equal(0, BattleLust.GetPoints(wielder));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Core.Expansion = previousExpansion;
|
||||
Core._now = previousNow;
|
||||
BattleLust.Clear(wielder);
|
||||
weapon.Delete();
|
||||
wielder.Delete();
|
||||
source.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDamageBonus_UsesAggressedCountAndPropertySpecificPvpPvmCaps()
|
||||
{
|
||||
|
|
@ -400,6 +537,18 @@ public class BattleLustPropertyTests
|
|||
return mobile;
|
||||
}
|
||||
|
||||
private static PlayerMobile CreateDeadPlayerMobile(Point3D location)
|
||||
{
|
||||
var mobile = new PlayerMobile(World.NewMobile);
|
||||
mobile.DefaultMobileInit();
|
||||
mobile.Player = true;
|
||||
mobile.Hits = mobile.HitsMax;
|
||||
mobile.MoveToWorld(location, Map.Felucca);
|
||||
mobile.Body = mobile.Race.GhostBody(mobile);
|
||||
Assert.False(mobile.Alive);
|
||||
return mobile;
|
||||
}
|
||||
|
||||
private static void InitializeHits(Mobile mobile, int hitsMax, int hits)
|
||||
{
|
||||
mobile.RawStr = Math.Max(1, (hitsMax - 50) * 2);
|
||||
|
|
|
|||
|
|
@ -1140,6 +1140,11 @@ public abstract partial class BaseWeapon
|
|||
return;
|
||||
}
|
||||
|
||||
if (WeaponAttributes.BattleLust != 0)
|
||||
{
|
||||
BattleLust.Clear(m);
|
||||
}
|
||||
|
||||
var serial = Serial;
|
||||
|
||||
m.RemoveStatMod($"{serial}Str");
|
||||
|
|
@ -1176,6 +1181,16 @@ public abstract partial class BaseWeapon
|
|||
m.Delta(MobileDelta.WeaponDamage);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
base.OnMapChange();
|
||||
|
||||
if ((Map == null || Map == Map.Internal) && Parent is Mobile m && WeaponAttributes.BattleLust != 0)
|
||||
{
|
||||
BattleLust.Clear(m);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual SkillName GetUsedSkill(Mobile m, bool checkSkillAttrs)
|
||||
{
|
||||
SkillName sk;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ModernUO.CodeGeneratedEvents;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
|
|
@ -86,7 +88,11 @@ public static class BattleLust
|
|||
return context.Points;
|
||||
}
|
||||
|
||||
internal static void Clear(Mobile mobile)
|
||||
[OnEvent(nameof(PlayerMobile.PlayerDeathEvent))]
|
||||
[OnEvent(nameof(PlayerMobile.PlayerDeletedEvent))]
|
||||
[OnEvent(nameof(BaseCreature.CreatureDeathEvent))]
|
||||
[OnEvent(nameof(BaseCreature.CreatureDeletedEvent))]
|
||||
public static void Clear(Mobile mobile)
|
||||
{
|
||||
if (mobile != null && _contexts.Remove(mobile, out var context))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -236,8 +236,9 @@ namespace Server
|
|||
SpellHelper.DoLeech(totalDamage, from, m);
|
||||
}
|
||||
|
||||
var oldHits = m.Hits;
|
||||
m.Damage(totalDamage, from);
|
||||
BattleLust.OnDamageTaken(m, from, totalDamage);
|
||||
BattleLust.OnDamageTaken(m, from, Math.Max(0, oldHits - m.Hits));
|
||||
return totalDamage;
|
||||
}
|
||||
|
||||
|
|
@ -987,7 +988,17 @@ namespace Server
|
|||
public int BattleLust
|
||||
{
|
||||
get => this[AosWeaponAttribute.BattleLust];
|
||||
set => this[AosWeaponAttribute.BattleLust] = value;
|
||||
set
|
||||
{
|
||||
var hadBattleLust = BattleLust != 0;
|
||||
|
||||
this[AosWeaponAttribute.BattleLust] = value;
|
||||
|
||||
if (hadBattleLust && value == 0 && Owner is BaseWeapon { Parent: Mobile m })
|
||||
{
|
||||
Server.Items.BattleLust.Clear(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetValue(Mobile m, AosWeaponAttribute attribute)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue