From fd2f90cba9deed9f007215ea0b6d8450e8e609c1 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sun, 1 Feb 2026 21:28:26 -0800
Subject: [PATCH] feat: Adds SerializableFieldChanged option (#2324)
---
.config/dotnet-tools.json | 2 +-
Projects/Server/Mobiles/Mods/ResistanceMod.cs | 49 +++------
Projects/Server/Mobiles/Mods/SkillMod.cs | 99 ++++++-------------
Projects/Server/Server.csproj | 4 +-
Projects/UOContent/Items/Clothing/Shoes.cs | 26 +++--
Projects/UOContent/UOContent.csproj | 4 +-
6 files changed, 62 insertions(+), 122 deletions(-)
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index cfd9dda1f..cf214cd69 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"modernuoschemagenerator": {
- "version": "2.14.1",
+ "version": "2.14.2",
"commands": [
"ModernUOSchemaGenerator"
]
diff --git a/Projects/Server/Mobiles/Mods/ResistanceMod.cs b/Projects/Server/Mobiles/Mods/ResistanceMod.cs
index c3ade7ed7..bd569f20e 100644
--- a/Projects/Server/Mobiles/Mods/ResistanceMod.cs
+++ b/Projects/Server/Mobiles/Mods/ResistanceMod.cs
@@ -1,6 +1,6 @@
/*************************************************************************
* ModernUO *
- * Copyright 2019-2023 - ModernUO Development Team *
+ * Copyright 2019-2026 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ResistanceMod.cs *
* *
@@ -13,6 +13,7 @@
* along with this program. If not, see . *
*************************************************************************/
+using System.Runtime.CompilerServices;
using ModernUO.Serialization;
namespace Server;
@@ -20,6 +21,20 @@ namespace Server;
[SerializationGenerator(0)]
public partial class ResistanceMod : MobileMod
{
+ [SerializableField(0)]
+ private ResistanceType _type;
+
+ [SerializableFieldChanged(0)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void OnTypeChanged(ResistanceType oldValue, ResistanceType newValue) => Owner?.UpdateResistances();
+
+ [SerializableField(1)]
+ private int _offset;
+
+ [SerializableFieldChanged(1)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void OnOffsetChanged(int oldValue, int newValue) => Owner?.UpdateResistances();
+
public ResistanceMod(Mobile owner) : base(owner)
{
}
@@ -29,36 +44,4 @@ public partial class ResistanceMod : MobileMod
_type = type;
_offset = offset;
}
-
- [SerializableProperty(0)]
- public ResistanceType Type
- {
- get => _type;
- set
- {
- if (_type != value)
- {
- _type = value;
-
- Owner?.UpdateResistances();
- MarkDirty();
- }
- }
- }
-
- [SerializableProperty(1)]
- public int Offset
- {
- get => _offset;
- set
- {
- if (_offset != value)
- {
- _offset = value;
-
- Owner?.UpdateResistances();
- MarkDirty();
- }
- }
- }
}
diff --git a/Projects/Server/Mobiles/Mods/SkillMod.cs b/Projects/Server/Mobiles/Mods/SkillMod.cs
index 4324bdeb8..a78ec5ce6 100644
--- a/Projects/Server/Mobiles/Mods/SkillMod.cs
+++ b/Projects/Server/Mobiles/Mods/SkillMod.cs
@@ -1,6 +1,6 @@
/*************************************************************************
* ModernUO *
- * Copyright 2019-2023 - ModernUO Development Team *
+ * Copyright 2019-2026 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: SkillMod.cs *
* *
@@ -21,6 +21,35 @@ namespace Server;
[SerializationGenerator(0)]
public abstract partial class SkillMod : MobileMod
{
+ [SerializableField(0)]
+ private bool _obeyCap;
+
+ [SerializableFieldChanged(0)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void OnObeCapChanged(bool oldValue, bool newValue) => Owner?.Skills[_skill]?.Update();
+
+ [SerializableField(1)]
+ private SkillName _skill;
+
+ [SerializableFieldChanged(1)]
+ private void OnSkillChanged(SkillName oldValue, SkillName newValue)
+ {
+ Owner?.Skills[newValue]?.Update();
+ Owner?.Skills[oldValue]?.Update();
+ }
+
+ [SerializableField(2)]
+ private bool _relative;
+
+ [SerializableFieldChanged(2)]
+ private void OnRelativeChanged(bool oldValue, bool newValue) => Owner?.Skills[_skill]?.Update();
+
+ [SerializableField(3)]
+ private double _value;
+
+ [SerializableFieldChanged(3)]
+ private void OnValueChanged(double oldValue, double newValue) => Owner?.Skills[_skill]?.Update();
+
public SkillMod(Mobile owner) : base(owner)
{
}
@@ -32,80 +61,12 @@ public abstract partial class SkillMod : MobileMod
_value = value;
}
- [SerializableProperty(0)]
- public bool ObeyCap
- {
- get => _obeyCap;
- set
- {
- _obeyCap = value;
-
- var sk = Owner?.Skills[_skill];
- sk?.Update();
- MarkDirty();
- }
- }
-
- [SerializableProperty(1)]
- public SkillName Skill
- {
- get => _skill;
- set
- {
- if (_skill != value)
- {
- var oldUpdate = Owner?.Skills[_skill];
-
- _skill = value;
-
- var sk = Owner?.Skills[_skill];
- sk?.Update();
- oldUpdate?.Update();
- MarkDirty();
- }
- }
- }
-
- [SerializableProperty(2)]
- public bool Relative
- {
- get => _relative;
- set
- {
- if (_relative != value)
- {
- _relative = value;
-
- var sk = Owner?.Skills[_skill];
- sk?.Update();
- MarkDirty();
- }
- }
- }
-
public bool Absolute
{
get => !Relative;
set => Relative = !value;
}
- [SerializableProperty(3)]
- public double Value
- {
- get => _value;
- set
- {
- if (_value != value)
- {
- _value = value;
-
- var sk = Owner?.Skills[_skill];
- sk?.Update();
- MarkDirty();
- }
- }
- }
-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Remove() => Owner?.RemoveSkillMod(this);
diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj
index d80b415c2..02e830648 100644
--- a/Projects/Server/Server.csproj
+++ b/Projects/Server/Server.csproj
@@ -39,8 +39,8 @@
-
-
+
+
diff --git a/Projects/UOContent/Items/Clothing/Shoes.cs b/Projects/UOContent/Items/Clothing/Shoes.cs
index bae7ec9fa..4d80b4699 100644
--- a/Projects/UOContent/Items/Clothing/Shoes.cs
+++ b/Projects/UOContent/Items/Clothing/Shoes.cs
@@ -1,3 +1,4 @@
+using System.Runtime.CompilerServices;
using ModernUO.Serialization;
namespace Server.Items
@@ -51,6 +52,16 @@ namespace Server.Items
[SerializationGenerator(2, false)]
public partial class ThighBoots : BaseShoes, IArcaneEquip
{
+ [EncodedInt]
+ [InvalidateProperties]
+ [SerializableField(0)]
+ [SerializedCommandProperty(AccessLevel.GameMaster)]
+ private int _curArcaneCharges;
+
+ [SerializableFieldChanged(0)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void OnCurArcaneChargesChanged(int oldValue, int newValue) => Update();
+
[Constructible]
public ThighBoots(int hue = 0) : base(0x1711, hue)
{
@@ -60,21 +71,6 @@ namespace Server.Items
public override CraftResource DefaultResource => CraftResource.RegularLeather;
- [EncodedInt]
- [SerializableProperty(0)]
- [CommandProperty(AccessLevel.GameMaster)]
- public int CurArcaneCharges
- {
- get => _curArcaneCharges;
- set
- {
- _curArcaneCharges = value;
- InvalidateProperties();
- Update();
- this.MarkDirty();
- }
- }
-
[EncodedInt]
[SerializableProperty(1)]
[CommandProperty(AccessLevel.GameMaster)]
diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj
index f38e06a94..482d3a9e1 100644
--- a/Projects/UOContent/UOContent.csproj
+++ b/Projects/UOContent/UOContent.csproj
@@ -47,8 +47,8 @@
-
-
+
+