feat: convert timers to [DeserializeTimer]; drifting timers become anchored
The 8 drifting timers ([TimerDrift]) change wire format from delta to anchored time, so each class bumps its serialization version with a MigrateFrom that replays the old delta read through the migration schema. The 2 wall-clock timers (Aquarium, FountainOfLife) keep their format via wallClock: true with no bump. Restart methods drop their TimeSpan.MinValue sentinel checks - v4 invokes them only when a timer was actually running at save. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
46bd0ca3c0
commit
6cae6db360
18 changed files with 486 additions and 35 deletions
|
|
@ -31,9 +31,9 @@ namespace Server.Items
|
|||
private bool m_EvaluateDay;
|
||||
|
||||
[SerializableField(0, setter: "private")]
|
||||
[DeserializeTimer(nameof(DeserializeEvaluateTimer), wallClock: true)]
|
||||
private Timer _evaluateTimer;
|
||||
|
||||
[DeserializeTimerField(0)]
|
||||
private void DeserializeEvaluateTimer(TimeSpan delay)
|
||||
{
|
||||
_evaluateTimer = Timer.DelayCall(delay, EvaluationInterval, Evaluate);
|
||||
|
|
|
|||
|
|
@ -37,21 +37,22 @@ namespace Server.Items
|
|||
public override double DefaultWeight => 3.0;
|
||||
}
|
||||
|
||||
[SerializationGenerator(3, false)]
|
||||
[SerializationGenerator(4, false)]
|
||||
public partial class DeathRobe : Robe
|
||||
{
|
||||
private static readonly TimeSpan m_DefaultDecayTime = TimeSpan.FromMinutes(1.0);
|
||||
|
||||
[TimerDrift]
|
||||
[SerializableField(0)]
|
||||
[DeserializeTimer(nameof(DeserializeDecayTimer))]
|
||||
private Timer _decayTimer;
|
||||
|
||||
[DeserializeTimerField(0)]
|
||||
private void DeserializeDecayTimer(TimeSpan delay)
|
||||
private void DeserializeDecayTimer(TimeSpan delay) => BeginDecay(delay);
|
||||
|
||||
private void MigrateFrom(V3Content content)
|
||||
{
|
||||
if (delay != TimeSpan.MinValue)
|
||||
if (content.DecayTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
BeginDecay(delay);
|
||||
DeserializeDecayTimer(content.DecayTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,19 +3,22 @@ using ModernUO.Serialization;
|
|||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(2, false)]
|
||||
[SerializationGenerator(3, false)]
|
||||
public abstract partial class FillableContainer : LockableContainer
|
||||
{
|
||||
[TimerDrift]
|
||||
[SerializableField(1)]
|
||||
[DeserializeTimer(nameof(DeserializeRespawnTimer))]
|
||||
private Timer _respawnTimer;
|
||||
|
||||
[DeserializeTimerField(1)]
|
||||
private void DeserializeRespawnTimer(TimeSpan delay)
|
||||
private void DeserializeRespawnTimer(TimeSpan delay) => _respawnTimer = Timer.DelayCall(delay, Respawn);
|
||||
|
||||
private void MigrateFrom(V2Content content)
|
||||
{
|
||||
if (delay > TimeSpan.MinValue)
|
||||
_contentType = content.ContentType;
|
||||
|
||||
if (content.RespawnTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
_respawnTimer = Timer.DelayCall(delay, Respawn);
|
||||
DeserializeRespawnTimer(content.RespawnTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@ using ModernUO.Serialization;
|
|||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
[SerializationGenerator(1, false)]
|
||||
public partial class MarkContainer : LockableContainer
|
||||
{
|
||||
[TimerDrift]
|
||||
[SerializableField(1, getter: "private", setter: "private")]
|
||||
[DeserializeTimer(nameof(DeserializeRelockTimer))]
|
||||
private InternalTimer _relockTimer;
|
||||
|
||||
[DeserializeTimerField(1)]
|
||||
private void DeserializeRelockTimer(TimeSpan delay)
|
||||
{
|
||||
if (!Locked && _autoLock)
|
||||
|
|
@ -19,6 +18,19 @@ public partial class MarkContainer : LockableContainer
|
|||
}
|
||||
}
|
||||
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_autoLock = content.AutoLock;
|
||||
_targetMap = content.TargetMap;
|
||||
_target = content.Target;
|
||||
_description = content.Description;
|
||||
|
||||
if (content.RelockTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
DeserializeRelockTimer(content.RelockTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializableField(2)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private Map _targetMap;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using Server.Network;
|
|||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(3, false)]
|
||||
[SerializationGenerator(4, false)]
|
||||
public partial class TreasureMapChest : LockableContainer
|
||||
{
|
||||
[Tidy]
|
||||
|
|
@ -29,12 +29,11 @@ public partial class TreasureMapChest : LockableContainer
|
|||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private int _level;
|
||||
|
||||
[TimerDrift]
|
||||
[SerializableField(4)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
[DeserializeTimer(nameof(DeserializeExpireTimer))]
|
||||
private Timer _expireTimer;
|
||||
|
||||
[DeserializeTimerField(4)]
|
||||
private void DeserializeExpireTimer(TimeSpan delay)
|
||||
{
|
||||
if (!_temporary)
|
||||
|
|
@ -43,6 +42,20 @@ public partial class TreasureMapChest : LockableContainer
|
|||
}
|
||||
}
|
||||
|
||||
private void MigrateFrom(V3Content content)
|
||||
{
|
||||
_guardians = content.Guardians;
|
||||
_temporary = content.Temporary;
|
||||
_owner = content.Owner;
|
||||
_level = content.Level;
|
||||
_lifted = content.Lifted;
|
||||
|
||||
if (content.ExpireTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
DeserializeExpireTimer(content.ExpireTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
[Tidy]
|
||||
[CanBeNull]
|
||||
[SerializableField(5, setter: "private")]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using ModernUO.Serialization;
|
|||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(1, false)]
|
||||
[SerializationGenerator(2, false)]
|
||||
public abstract partial class BaseLight : Item
|
||||
{
|
||||
public static readonly bool Burnout = false;
|
||||
|
|
@ -16,11 +16,10 @@ public abstract partial class BaseLight : Item
|
|||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private bool _protected;
|
||||
|
||||
[TimerDrift]
|
||||
[SerializableField(4, getter: "private", setter: "private")]
|
||||
[DeserializeTimer(nameof(DeserializeTimer))]
|
||||
private Timer _burnTimer;
|
||||
|
||||
[DeserializeTimerField(4)]
|
||||
private void DeserializeTimer(TimeSpan delay)
|
||||
{
|
||||
if (_burning && _duration != TimeSpan.Zero)
|
||||
|
|
@ -29,6 +28,19 @@ public abstract partial class BaseLight : Item
|
|||
}
|
||||
}
|
||||
|
||||
private void MigrateFrom(V1Content content)
|
||||
{
|
||||
_burntOut = content.BurntOut;
|
||||
_burning = content.Burning;
|
||||
_duration = content.Duration;
|
||||
_protected = content.Protected;
|
||||
|
||||
if (content.BurnTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
DeserializeTimer(content.BurnTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public BaseLight(int itemID) : base(itemID)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public enum CorpseFlag
|
|||
OwnerWasAnimatedDead = 0x00000800
|
||||
}
|
||||
|
||||
[SerializationGenerator(17, false)]
|
||||
[SerializationGenerator(18, false)]
|
||||
public partial class Corpse : Container, ICarvable
|
||||
{
|
||||
public static readonly TimeSpan MonsterLootRightSacrifice = TimeSpan.FromMinutes(2.0);
|
||||
|
|
@ -114,13 +114,37 @@ public partial class Corpse : Container, ICarvable
|
|||
[SerializableField(3, getter: "private", setter: "private")]
|
||||
private Dictionary<Item, Point3D> _restoreTable;
|
||||
|
||||
[TimerDrift]
|
||||
[SerializableField(4, getter: "private", setter: "private")]
|
||||
[DeserializeTimer(nameof(DeserializeDecayTimer))]
|
||||
private Timer _decayTimer;
|
||||
|
||||
[DeserializeTimerField(4)]
|
||||
private void DeserializeDecayTimer(TimeSpan delay) => BeginDecay(delay);
|
||||
|
||||
private void MigrateFrom(V17Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
_hairItemId = content.HairItemId;
|
||||
_hairHue = content.HairHue;
|
||||
_facialHairItemId = content.FacialHairItemId;
|
||||
_facialHairHue = content.FacialHairHue;
|
||||
|
||||
if (content.DecayTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
DeserializeDecayTimer(content.DecayTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializableField(5, setter: "private")]
|
||||
private HashSet<Mobile> _looters;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,18 +3,25 @@ using ModernUO.Serialization;
|
|||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(2, false)]
|
||||
[SerializationGenerator(3, false)]
|
||||
public partial class DecayedCorpse : Container
|
||||
{
|
||||
private static TimeSpan _defaultDecayTime = TimeSpan.FromMinutes(7.0);
|
||||
|
||||
[TimerDrift]
|
||||
[SerializableField(0, getter: "private", setter: "private")]
|
||||
[DeserializeTimer(nameof(DeserializeDecayTimer))]
|
||||
private Timer _decayTimer;
|
||||
|
||||
[DeserializeTimerField(0)]
|
||||
private void DeserializeDecayTimer(TimeSpan delay) => BeginDecay(delay);
|
||||
|
||||
private void MigrateFrom(V2Content content)
|
||||
{
|
||||
if (content.DecayTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
DeserializeDecayTimer(content.DecayTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
public DecayedCorpse(string name) : base(Utility.Random(0xECA, 9))
|
||||
{
|
||||
Movable = false;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public partial class FountainOfLife : BaseAddonContainer
|
|||
public const int MaxCharges = 10;
|
||||
|
||||
[SerializableField(1)]
|
||||
[DeserializeTimer(nameof(DeserializeTimer), wallClock: true)]
|
||||
private Timer _timer;
|
||||
|
||||
[Constructible]
|
||||
|
|
@ -39,7 +40,6 @@ public partial class FountainOfLife : BaseAddonContainer
|
|||
_charges = charges;
|
||||
}
|
||||
|
||||
[DeserializeTimerField(1)]
|
||||
private void DeserializeTimer(TimeSpan delay)
|
||||
{
|
||||
_timer = Timer.DelayCall(Utility.Max(delay, TimeSpan.Zero), RechargeTime, Recharge);
|
||||
|
|
|
|||
43
Projects/UOContent/Migrations/Server.Items.BaseLight.v2.json
generated
Normal file
43
Projects/UOContent/Migrations/Server.Items.BaseLight.v2.json
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"version": 2,
|
||||
"type": "Server.Items.BaseLight",
|
||||
"properties": [
|
||||
{
|
||||
"name": "BurntOut",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Burning",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Duration",
|
||||
"type": "System.TimeSpan",
|
||||
"rule": "PrimitiveTypeMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Protected",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BurnTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
137
Projects/UOContent/Migrations/Server.Items.Corpse.v18.json
generated
Normal file
137
Projects/UOContent/Migrations/Server.Items.Corpse.v18.json
generated
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"version": 18,
|
||||
"type": "Server.Items.Corpse",
|
||||
"properties": [
|
||||
{
|
||||
"name": "RestoreEquip",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Item\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Flags",
|
||||
"type": "Server.Items.CorpseFlag",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "TimeOfDeath",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"DeltaTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RestoreTable",
|
||||
"type": "System.Collections.Generic.Dictionary\u003CServer.Item, Server.Point3D\u003E",
|
||||
"rule": "DictionaryMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule",
|
||||
"0",
|
||||
"Server.Point3D",
|
||||
"PrimitiveUOTypeMigrationRule",
|
||||
"1",
|
||||
"Point3D"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DecayTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Looters",
|
||||
"type": "System.Collections.Generic.HashSet\u003CServer.Mobile\u003E",
|
||||
"rule": "HashSetMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Server.Mobile",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Killer",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Aggressors",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Mobile\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Server.Mobile",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Owner",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "CorpseName",
|
||||
"type": "string",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AccessLevel",
|
||||
"type": "Server.AccessLevel",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Guild",
|
||||
"type": "Server.Guilds.Guild",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "EquipItems",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Item\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "HairItemId",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "HairHue",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FacialHairItemId",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FacialHairHue",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
Projects/UOContent/Migrations/Server.Items.DeathRobe.v4.json
generated
Normal file
14
Projects/UOContent/Migrations/Server.Items.DeathRobe.v4.json
generated
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": 4,
|
||||
"type": "Server.Items.DeathRobe",
|
||||
"properties": [
|
||||
{
|
||||
"name": "DecayTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
Projects/UOContent/Migrations/Server.Items.DecayedCorpse.v3.json
generated
Normal file
14
Projects/UOContent/Migrations/Server.Items.DecayedCorpse.v3.json
generated
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": 3,
|
||||
"type": "Server.Items.DecayedCorpse",
|
||||
"properties": [
|
||||
{
|
||||
"name": "DecayTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
19
Projects/UOContent/Migrations/Server.Items.FillableContainer.v3.json
generated
Normal file
19
Projects/UOContent/Migrations/Server.Items.FillableContainer.v3.json
generated
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": 3,
|
||||
"type": "Server.Items.FillableContainer",
|
||||
"properties": [
|
||||
{
|
||||
"name": "ContentType",
|
||||
"type": "Server.Items.FillableContentType",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "RespawnTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
46
Projects/UOContent/Migrations/Server.Items.MarkContainer.v1.json
generated
Normal file
46
Projects/UOContent/Migrations/Server.Items.MarkContainer.v1.json
generated
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Items.MarkContainer",
|
||||
"properties": [
|
||||
{
|
||||
"name": "AutoLock",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RelockTimer",
|
||||
"type": "Server.Items.MarkContainer.InternalTimer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "TargetMap",
|
||||
"type": "Server.Map",
|
||||
"rule": "PrimitiveUOTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Map"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Target",
|
||||
"type": "Server.Point3D",
|
||||
"rule": "PrimitiveUOTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Point3D"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Description",
|
||||
"type": "string",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
57
Projects/UOContent/Migrations/Server.Items.TreasureMapChest.v4.json
generated
Normal file
57
Projects/UOContent/Migrations/Server.Items.TreasureMapChest.v4.json
generated
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"version": 4,
|
||||
"type": "Server.Items.TreasureMapChest",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Guardians",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Mobile\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@Tidy",
|
||||
"@CanBeNull",
|
||||
"Server.Mobile",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Temporary",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Owner",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Level",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ExpireTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Lifted",
|
||||
"type": "System.Collections.Generic.HashSet\u003CServer.Item\u003E",
|
||||
"rule": "HashSetMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@Tidy",
|
||||
"@CanBeNull",
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
43
Projects/UOContent/Migrations/Server.Mobiles.BaseEscortable.v3.json
generated
Normal file
43
Projects/UOContent/Migrations/Server.Mobiles.BaseEscortable.v3.json
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"version": 3,
|
||||
"type": "Server.Mobiles.BaseEscortable",
|
||||
"properties": [
|
||||
{
|
||||
"name": "DestinationString",
|
||||
"type": "string",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DeleteTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@AnchoredTimer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MlQuestType",
|
||||
"type": "System.Type",
|
||||
"rule": "PrimitiveTypeMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "MlQuestDestinationMessage",
|
||||
"type": "Server.TextDefinition",
|
||||
"rule": "PrimitiveUOTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"TextDefinition"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MlQuestPaymentMessage",
|
||||
"type": "Server.TextDefinition",
|
||||
"rule": "PrimitiveUOTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"TextDefinition"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ using EDI = Server.Mobiles.EscortDestinationInfo;
|
|||
|
||||
namespace Server.Mobiles;
|
||||
|
||||
[SerializationGenerator(2, false)]
|
||||
[SerializationGenerator(3, false)]
|
||||
public partial class BaseEscortable : BaseCreature
|
||||
{
|
||||
private static readonly ILogger logger = LogFactory.GetLogger(typeof(BaseEscortable));
|
||||
|
|
@ -158,16 +158,22 @@ public partial class BaseEscortable : BaseCreature
|
|||
[SerializableField(0, setter: "private")]
|
||||
private string _destinationString;
|
||||
|
||||
[TimerDrift]
|
||||
[SerializableField(1)]
|
||||
[DeserializeTimer(nameof(DeserializeDeleteTimer))]
|
||||
private Timer _deleteTimer;
|
||||
|
||||
[DeserializeTimerField(1)]
|
||||
private void DeserializeDeleteTimer(TimeSpan delay)
|
||||
private void DeserializeDeleteTimer(TimeSpan delay) => Timer.DelayCall(delay, Delete);
|
||||
|
||||
private void MigrateFrom(V2Content content)
|
||||
{
|
||||
if (delay >= TimeSpan.Zero)
|
||||
_destinationString = content.DestinationString;
|
||||
_mlQuestType = content.MlQuestType;
|
||||
_mlQuestDestinationMessage = content.MlQuestDestinationMessage;
|
||||
_mlQuestPaymentMessage = content.MlQuestPaymentMessage;
|
||||
|
||||
if (content.DeleteTimerDelay != TimeSpan.MinValue)
|
||||
{
|
||||
Timer.DelayCall(delay, Delete);
|
||||
DeserializeDeleteTimer(content.DeleteTimerDelay);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue