feat: convert all delta-time serialization to anchored time
Every actively-written delta-time value now stores an absolute anchored timestamp, shifted by downtime at load: remaining time is preserved across restarts and idle saves become byte-stable. - Item v11: LastMoved (was whole-minute delta, rewritten every save) and DecayResetTime; Mobile v38: the three stat-gain stamps; BaseCreature v21: SummonEnd; plus VendorInventory, StealableArtifacts, and ML quest objective timers in their own version gates. - 17 code-generated classes swap [DeltaDateTime] for [AnchoredDateTime] with a version bump and MigrateFrom each (generated from their current migration schemas, so old saves replay the delta reads). - GenericPersistence payloads carry no anchor of their own, so they inherit the save-wide shift: entity indexes always load first, and every file in a save shares one SaveStartTime - World.LoadTimeShift is stamped from the idx v5 header and applied to generic persistence readers. This is what makes VirtueContext and StealableArtifacts convertible at all. - Legacy read sites (old-version fallbacks and migration replays) keep ReadDeltaTime: they decode old bytes and must never change. Acceptance tests: item serialization is byte-identical across saves hours apart, and LastMoved/DecayResetTime round-trip exactly at sub-minute precision (impossible under the old minutes encoding). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
b992c7b955
commit
8d1283ba27
46 changed files with 1407 additions and 223 deletions
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Server.Tests;
|
||||
|
||||
[Collection("Sequential Server Tests")]
|
||||
public class AnchoredItemSerializationTests
|
||||
{
|
||||
private static byte[] SerializeItem(Item item)
|
||||
{
|
||||
var writer = new BufferWriter(new byte[256], true);
|
||||
item.Serialize(writer);
|
||||
return writer.Buffer[..(int)writer.Position];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Item v11 stores LastMoved and DecayResetTime as anchored time: the serialized bytes
|
||||
/// are a function of item state only, not of when the save runs. Pre-v11 stored
|
||||
/// minutes-since-moved and delta time, which rewrote the bytes on every save.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void ItemBytes_AreStable_AcrossSavesAtDifferentTimes()
|
||||
{
|
||||
var start = Core._now;
|
||||
|
||||
try
|
||||
{
|
||||
var item = new Item(0x1F13);
|
||||
item.MoveToWorld(new Point3D(120, 100, 0), Map.Felucca);
|
||||
item.RestartDecay();
|
||||
|
||||
var first = SerializeItem(item);
|
||||
|
||||
// A save hours later, with no state change, must produce identical bytes.
|
||||
Core._now = start + TimeSpan.FromHours(5);
|
||||
var second = SerializeItem(item);
|
||||
|
||||
Assert.Equal(first, second);
|
||||
|
||||
item.Delete();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Core._now = start;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pre-v11 LastMoved was stored at whole-minute precision relative to the save time and
|
||||
/// could never round-trip exactly. Anchored storage is absolute and exact.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LastMovedAndDecayReset_RoundTripExactly()
|
||||
{
|
||||
var item = new Item(0x1F13);
|
||||
item.MoveToWorld(new Point3D(121, 100, 0), Map.Felucca);
|
||||
|
||||
// Sub-minute precision that the old minutes encoding would have destroyed.
|
||||
var moved = Core.Now - TimeSpan.FromSeconds(90.5) - TimeSpan.FromMilliseconds(123);
|
||||
item.LastMoved = moved;
|
||||
|
||||
item.RestartDecay();
|
||||
var decayReset = item.DecayResetTime;
|
||||
Assert.NotEqual(default(DateTime), decayReset);
|
||||
|
||||
var bytes = SerializeItem(item);
|
||||
|
||||
var restored = new Item((Serial)0x7ffff123u);
|
||||
restored.Deserialize(new BufferReader(bytes));
|
||||
|
||||
Assert.Equal(moved, restored.LastMoved);
|
||||
Assert.Equal(decayReset, restored.DecayResetTime);
|
||||
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
|
|
@ -863,7 +863,7 @@ public partial class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropert
|
|||
|
||||
public virtual void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(10); // version
|
||||
writer.Write(11); // version
|
||||
|
||||
var flags = SaveFlag.None;
|
||||
|
||||
|
|
@ -1015,19 +1015,13 @@ public partial class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropert
|
|||
|
||||
writer.Write((int)flags);
|
||||
|
||||
/* begin last moved time optimization */
|
||||
var ticks = LastMoved.Ticks;
|
||||
var now = Core.Now.Ticks;
|
||||
|
||||
var minutes = new TimeSpan(now - ticks).TotalMinutes;
|
||||
|
||||
writer.WriteEncodedInt((int)Math.Clamp(minutes, int.MinValue, int.MaxValue));
|
||||
/* end */
|
||||
// Anchored: shifted by downtime at load, so time-since-moved is preserved and the
|
||||
// bytes are stable across saves while the item does not move.
|
||||
writer.WriteAnchoredTime(LastMoved);
|
||||
|
||||
if (GetSaveFlag(flags, SaveFlag.DecayReset))
|
||||
{
|
||||
//TODO Use WriteAnchoredTime once the save-time anchor is ported
|
||||
writer.WriteDeltaTime(info.m_DecayReset);
|
||||
writer.WriteAnchoredTime(info.m_DecayReset);
|
||||
}
|
||||
|
||||
if (GetSaveFlag(flags, SaveFlag.Direction))
|
||||
|
|
@ -2772,6 +2766,7 @@ public partial class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropert
|
|||
|
||||
switch (version)
|
||||
{
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8:
|
||||
|
|
@ -2780,7 +2775,11 @@ public partial class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropert
|
|||
{
|
||||
var flags = (SaveFlag)reader.ReadInt();
|
||||
|
||||
if (version < 7)
|
||||
if (version >= 11)
|
||||
{
|
||||
LastMoved = reader.ReadAnchoredTime();
|
||||
}
|
||||
else if (version < 7)
|
||||
{
|
||||
LastMoved = reader.ReadDeltaTime();
|
||||
}
|
||||
|
|
@ -2800,10 +2799,10 @@ public partial class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropert
|
|||
|
||||
if (version >= 10 && GetSaveFlag(flags, SaveFlag.DecayReset))
|
||||
{
|
||||
var reset = reader.ReadDeltaTime();
|
||||
var reset = version >= 11 ? reader.ReadAnchoredTime() : reader.ReadDeltaTime();
|
||||
|
||||
// LastMoved is stored at whole-minute precision; keep the stamp only
|
||||
// while it still extends the deadline.
|
||||
// Pre-v11 LastMoved was stored at whole-minute precision; keep the
|
||||
// stamp only while it still extends the deadline.
|
||||
if (reset > LastMoved)
|
||||
{
|
||||
DecayResetTime = reset;
|
||||
|
|
|
|||
|
|
@ -2324,11 +2324,11 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
public virtual void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(37); // version
|
||||
writer.Write(38); // version
|
||||
|
||||
writer.WriteDeltaTime(LastStrGain);
|
||||
writer.WriteDeltaTime(LastIntGain);
|
||||
writer.WriteDeltaTime(LastDexGain);
|
||||
writer.WriteAnchoredTime(LastStrGain);
|
||||
writer.WriteAnchoredTime(LastIntGain);
|
||||
writer.WriteAnchoredTime(LastDexGain);
|
||||
|
||||
byte hairflag = 0x00;
|
||||
|
||||
|
|
@ -6150,6 +6150,7 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
switch (version)
|
||||
{
|
||||
case 38: // Stat-gain stamps moved from delta time to anchored time
|
||||
case 37: // Decomposed hair into inline item id/hue (dropped the VirtualHairInfo object)
|
||||
case 36: // Moved virtues to VirtueSystem
|
||||
case 35: // Moved short term murders to PlayerMurderSystem
|
||||
|
|
@ -6158,9 +6159,18 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
case 32: // Removed StuckMenu
|
||||
case 31:
|
||||
{
|
||||
LastStrGain = reader.ReadDeltaTime();
|
||||
LastIntGain = reader.ReadDeltaTime();
|
||||
LastDexGain = reader.ReadDeltaTime();
|
||||
if (version >= 38)
|
||||
{
|
||||
LastStrGain = reader.ReadAnchoredTime();
|
||||
LastIntGain = reader.ReadAnchoredTime();
|
||||
LastDexGain = reader.ReadAnchoredTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
LastStrGain = reader.ReadDeltaTime();
|
||||
LastIntGain = reader.ReadDeltaTime();
|
||||
LastDexGain = reader.ReadDeltaTime();
|
||||
}
|
||||
|
||||
goto case 30;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -504,6 +504,10 @@ public class GenericEntityPersistence<T> : GenericPersistence, IGenericEntityPer
|
|||
var anchor = new DateTime(dataReader.ReadLong(), DateTimeKind.Utc);
|
||||
var shift = Core.Now - anchor;
|
||||
_anchoredTimeShift = anchor.Ticks > 0 && shift > TimeSpan.Zero ? shift : TimeSpan.Zero;
|
||||
|
||||
// The whole save shares one anchor. Publish it so payloads without their own
|
||||
// (GenericPersistence bins) can shift too; indexes load before any of them.
|
||||
World.LoadTimeShift = _anchoredTimeShift;
|
||||
}
|
||||
|
||||
if (version >= 4)
|
||||
|
|
|
|||
|
|
@ -98,7 +98,13 @@ public abstract class GenericPersistence : Persistence, IGenericSerializable
|
|||
|
||||
byte* ptr = null;
|
||||
accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
|
||||
var dataReader = new UnmanagedDataReader(ptr, accessor.Length, typesDb);
|
||||
var dataReader = new UnmanagedDataReader(ptr, accessor.Length, typesDb)
|
||||
{
|
||||
// These payloads carry no anchor of their own; they inherit the save-wide
|
||||
// shift stamped while the entity indexes were read (indexes always load
|
||||
// before persistence payloads — see Persistence.Load).
|
||||
AnchoredTimeShift = World.LoadTimeShift
|
||||
};
|
||||
Deserialize(dataReader);
|
||||
|
||||
error = dataReader.Position != fileLength
|
||||
|
|
|
|||
|
|
@ -99,6 +99,15 @@ public static class World
|
|||
/// anchored timestamps can be re-based by the downtime at load.
|
||||
/// </summary>
|
||||
public static DateTime SaveStartTime { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The anchored-time shift for the save currently being loaded: the downtime between the
|
||||
/// save's start and this load. Stamped while entity indexes are read (they all carry the
|
||||
/// same anchor, since the whole save shares one <see cref="SaveStartTime" />) and applied
|
||||
/// to every reader of that save's files — including <see cref="GenericPersistence" />
|
||||
/// payloads, which carry no anchor of their own. Zero for saves that predate the anchor.
|
||||
/// </summary>
|
||||
public static TimeSpan LoadTimeShift { get; internal set; }
|
||||
public static bool Running => WorldState is not WorldState.Loading and not WorldState.Initial;
|
||||
public static bool Loading => WorldState == WorldState.Loading;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,16 +27,44 @@ using Server.Logging;
|
|||
|
||||
namespace Server.Engines.CannedEvil;
|
||||
|
||||
[SerializationGenerator(10, false)]
|
||||
[SerializationGenerator(11, false)]
|
||||
public partial class ChampionSpawn : Item
|
||||
{
|
||||
private void MigrateFrom(V10Content content)
|
||||
{
|
||||
_level = content.Level;
|
||||
_activatedByProximity = content.ActivatedByProximity;
|
||||
_nextProximityTime = content.NextProximityTime;
|
||||
_maxLevel = content.MaxLevel;
|
||||
_activatedByValor = content.ActivatedByValor;
|
||||
_damageEntries = content.DamageEntries;
|
||||
_confinedRoaming = content.ConfinedRoaming;
|
||||
_idol = content.Idol;
|
||||
_hasBeenAdvanced = content.HasBeenAdvanced;
|
||||
_spawnArea = content.SpawnArea;
|
||||
_randomizeType = content.RandomizeType;
|
||||
_kills = content.Kills;
|
||||
_active = content.Active;
|
||||
_type = content.Type;
|
||||
_creatures = content.Creatures;
|
||||
_redSkulls = content.RedSkulls;
|
||||
_whiteSkulls = content.WhiteSkulls;
|
||||
_platform = content.Platform;
|
||||
_altar = content.Altar;
|
||||
_expireDelay = content.ExpireDelay;
|
||||
_expireTime = content.ExpireTime;
|
||||
_champion = content.Champion;
|
||||
_restartDelay = content.RestartDelay;
|
||||
_restartTime = content.RestartTime;
|
||||
}
|
||||
|
||||
private static readonly ILogger logger = LogFactory.GetLogger(typeof(ChampionSpawn));
|
||||
|
||||
[SerializableField(1)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private bool _activatedByProximity;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(2)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _nextProximityTime;
|
||||
|
|
@ -96,7 +124,7 @@ public partial class ChampionSpawn : Item
|
|||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private TimeSpan _expireDelay;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(20)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _expireTime;
|
||||
|
|
@ -109,7 +137,7 @@ public partial class ChampionSpawn : Item
|
|||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private TimeSpan _restartDelay;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(23, setter: "private")]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _restartTime;
|
||||
|
|
|
|||
|
|
@ -3,15 +3,21 @@ using ModernUO.Serialization;
|
|||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(1, false)]
|
||||
[SerializationGenerator(2, false)]
|
||||
public partial class StarRoomGate : Moongate
|
||||
{
|
||||
private void MigrateFrom(V1Content content)
|
||||
{
|
||||
_decays = content.Decays;
|
||||
_decayTime = content.DecayTime;
|
||||
}
|
||||
|
||||
private static TimeSpan GateDuration = TimeSpan.FromMinutes(2.0);
|
||||
|
||||
[SerializableField(0)]
|
||||
private bool _decays;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(1)]
|
||||
private DateTime _decayTime;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,20 @@ using Server.Mobiles;
|
|||
namespace Server.Ethics;
|
||||
|
||||
[PropertyObject]
|
||||
[SerializationGenerator(1)]
|
||||
[SerializationGenerator(2)]
|
||||
public partial class Player : EthicsEntity
|
||||
{
|
||||
private void MigrateFrom(V1Content content)
|
||||
{
|
||||
_mobile = content.Mobile;
|
||||
_power = content.Power;
|
||||
_history = content.History;
|
||||
_steed = content.Steed;
|
||||
_familiar = content.Familiar;
|
||||
_shield = content.Shield;
|
||||
_ethic = content.Ethic;
|
||||
}
|
||||
|
||||
[SerializableField(0, setter: "private")]
|
||||
private Mobile _mobile;
|
||||
|
||||
|
|
@ -27,7 +38,7 @@ public partial class Player : EthicsEntity
|
|||
[SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
private Mobile _familiar;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(5, setter: "private")]
|
||||
private DateTime _shield;
|
||||
|
||||
|
|
|
|||
|
|
@ -162,10 +162,15 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
|
||||
[SerializationGenerator(0)]
|
||||
[SerializationGenerator(1)]
|
||||
public partial class PuzzleChestSolutionAndTime : PuzzleChestSolution
|
||||
{
|
||||
[DeltaDateTime]
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_when = content.When;
|
||||
}
|
||||
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(0)]
|
||||
private DateTime _when;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Server.Engines.MLQuests
|
|||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(2); // version
|
||||
writer.Write(3); // version
|
||||
writer.Write(MLQuestSystem.Contexts.Count);
|
||||
|
||||
foreach (var context in MLQuestSystem.Contexts.Values)
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ namespace Server.Engines.MLQuests.Objectives
|
|||
if (IsTimed)
|
||||
{
|
||||
writer.Write(true);
|
||||
writer.WriteDeltaTime(EndTime);
|
||||
writer.WriteAnchoredTime(EndTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -135,7 +135,7 @@ namespace Server.Engines.MLQuests.Objectives
|
|||
{
|
||||
if (reader.ReadBool())
|
||||
{
|
||||
var endTime = reader.ReadDeltaTime();
|
||||
var endTime = version >= 3 ? reader.ReadAnchoredTime() : reader.ReadDeltaTime();
|
||||
|
||||
if (objInstance != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ public class StealableArtifacts : GenericPersistence
|
|||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(1); // version
|
||||
writer.WriteEncodedInt(2); // version
|
||||
|
||||
writer.Write(_enabled);
|
||||
|
||||
|
|
@ -261,7 +261,7 @@ public class StealableArtifacts : GenericPersistence
|
|||
var si = _artifacts[i];
|
||||
|
||||
writer.Write(si.Item);
|
||||
writer.WriteDeltaTime(si.NextRespawn);
|
||||
writer.WriteAnchoredTime(si.NextRespawn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -282,7 +282,7 @@ public class StealableArtifacts : GenericPersistence
|
|||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var item = reader.ReadEntity<Item>();
|
||||
var nextRespawn = reader.ReadDeltaTime();
|
||||
var nextRespawn = version >= 2 ? reader.ReadAnchoredTime() : reader.ReadDeltaTime();
|
||||
|
||||
if (i < _artifacts.Length)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,10 +5,29 @@ using Server.Mobiles;
|
|||
namespace Server.Engines.Virtues;
|
||||
|
||||
[PropertyObject]
|
||||
[SerializationGenerator(0)]
|
||||
[SerializationGenerator(1)]
|
||||
public partial class VirtueContext
|
||||
{
|
||||
[DeltaDateTime]
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
// Save-flagged values arrive as nullables; unset flags fall back to the same
|
||||
// defaults the old deserialize left in place.
|
||||
_lastSacrificeGain = content.LastSacrificeGain ?? default;
|
||||
_lastSacrificeLoss = content.LastSacrificeLoss ?? default;
|
||||
_availableResurrects = content.AvailableResurrects ?? 0;
|
||||
_lastJusticeLoss = content.LastJusticeLoss ?? default;
|
||||
_lastCompassionLoss = content.LastCompassionLoss ?? default;
|
||||
_nextCompassionDay = content.NextCompassionDay ?? default;
|
||||
_compassionGains = content.CompassionGains ?? 0;
|
||||
_lastValorLoss = content.LastValorLoss ?? default;
|
||||
_lastHonorUse = content.LastHonorUse ?? default;
|
||||
_honorActive = content.HonorActive;
|
||||
_justiceProtection = content.JusticeProtection;
|
||||
_justiceStatus = content.JusticeStatus ?? JusticeProtectorStatus.None;
|
||||
_values = content.Values;
|
||||
}
|
||||
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(0)]
|
||||
[SaveFlag(nameof(ShouldSerializeLastSacrificeGain))]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
|
|
@ -16,7 +35,7 @@ public partial class VirtueContext
|
|||
|
||||
private bool ShouldSerializeLastSacrificeGain() => !SacrificeVirtue.CanGain(this);
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(1)]
|
||||
[SaveFlag(nameof(ShouldSerializeLastSacrificeLoss))]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
|
|
@ -31,7 +50,7 @@ public partial class VirtueContext
|
|||
|
||||
private bool ShouldSerializeAvailableResurrects() => _availableResurrects > 0;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(3)]
|
||||
[SaveFlag(nameof(ShouldSerializeLastJusticeLoss))]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
|
|
@ -39,7 +58,7 @@ public partial class VirtueContext
|
|||
|
||||
private bool ShouldSerializeLastJusticeLoss() => !JusticeVirtue.CanAtrophy(this);
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(4)]
|
||||
[SaveFlag(nameof(ShouldSerializeLastCompassionLoss))]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
|
|
@ -47,7 +66,7 @@ public partial class VirtueContext
|
|||
|
||||
private bool ShouldSerializeLastCompassionLoss() => !CompassionVirtue.CanAtrophy(this);
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(5)]
|
||||
[SaveFlag(nameof(ShouldSerializeNextCompassionDay))]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
|
|
@ -62,7 +81,7 @@ public partial class VirtueContext
|
|||
|
||||
private bool ShouldSerializeCompassionGains() => _compassionGains > 0;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(7)]
|
||||
[SaveFlag(nameof(ShouldSerializeValorLoss))]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
|
|
@ -70,7 +89,7 @@ public partial class VirtueContext
|
|||
|
||||
private bool ShouldSerializeValorLoss() => !ValorVirtue.CanAtrophy(this);
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(8)]
|
||||
[SaveFlag(nameof(ShouldSerializeLastHonorUse))]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
|
|
|
|||
179
Projects/UOContent/Items/Misc/Corpses/Corpse.Migrations.cs
Normal file
179
Projects/UOContent/Items/Misc/Corpses/Corpse.Migrations.cs
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
public partial class Corpse
|
||||
{
|
||||
// Decay timer and TimeOfDeath moved from delta time to anchored time
|
||||
private void MigrateFrom(V18Content 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Decay timer moved from [TimerDrift]/[DeserializeTimerField] to [DeserializeTimer]
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Decomposed VirtualHairInfo into discrete int fields (hair/facial hair item id + hue)
|
||||
private void MigrateFrom(V16Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
if (content.Hair != null)
|
||||
{
|
||||
_hairItemId = content.Hair.ItemId;
|
||||
_hairHue = content.Hair.Hue;
|
||||
}
|
||||
|
||||
if (content.FacialHair != null)
|
||||
{
|
||||
_facialHairItemId = content.FacialHair.ItemId;
|
||||
_facialHairHue = content.FacialHair.Hue;
|
||||
}
|
||||
}
|
||||
|
||||
// Folded Murderer bool field into CorpseFlag.Murderer
|
||||
private void MigrateFrom(V15Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
if (content.Murderer)
|
||||
{
|
||||
_flags |= CorpseFlag.Murderer;
|
||||
}
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
if (content.Hair != null)
|
||||
{
|
||||
_hairItemId = content.Hair.ItemId;
|
||||
_hairHue = content.Hair.Hue;
|
||||
}
|
||||
|
||||
if (content.FacialHair != null)
|
||||
{
|
||||
_facialHairItemId = content.FacialHair.ItemId;
|
||||
_facialHairHue = content.FacialHair.Hue;
|
||||
}
|
||||
}
|
||||
|
||||
// Replaced int Kills snapshot with bool Murderer snapshot
|
||||
private void MigrateFrom(V14Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
if (content.Kills >= 5)
|
||||
{
|
||||
_flags |= CorpseFlag.Murderer;
|
||||
}
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
if (content.Hair != null)
|
||||
{
|
||||
_hairItemId = content.Hair.ItemId;
|
||||
_hairHue = content.Hair.Hue;
|
||||
}
|
||||
|
||||
if (content.FacialHair != null)
|
||||
{
|
||||
_facialHairItemId = content.FacialHair.ItemId;
|
||||
_facialHairHue = content.FacialHair.Hue;
|
||||
}
|
||||
}
|
||||
|
||||
// Added corpse hair and corpse facial hair
|
||||
private void MigrateFrom(V13Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
if (content.Kills >= 5)
|
||||
{
|
||||
_flags |= CorpseFlag.Murderer;
|
||||
}
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ public enum CorpseFlag
|
|||
OwnerWasAnimatedDead = 0x00000800
|
||||
}
|
||||
|
||||
[SerializationGenerator(18, false)]
|
||||
[SerializationGenerator(19, false)]
|
||||
public partial class Corpse : Container, ICarvable
|
||||
{
|
||||
public static readonly TimeSpan MonsterLootRightSacrifice = TimeSpan.FromMinutes(2.0);
|
||||
|
|
@ -106,7 +106,7 @@ public partial class Corpse : Container, ICarvable
|
|||
[SerializableField(1)]
|
||||
private CorpseFlag _flags;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(2)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _timeOfDeath;
|
||||
|
|
@ -120,31 +120,6 @@ public partial class Corpse : Container, ICarvable
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -342,127 +317,6 @@ public partial class Corpse : Container, ICarvable
|
|||
DevourCorpse();
|
||||
}
|
||||
|
||||
// Decomposed VirtualHairInfo into discrete int fields (hair/facial hair item id + hue)
|
||||
private void MigrateFrom(V16Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
if (content.Hair != null)
|
||||
{
|
||||
_hairItemId = content.Hair.ItemId;
|
||||
_hairHue = content.Hair.Hue;
|
||||
}
|
||||
|
||||
if (content.FacialHair != null)
|
||||
{
|
||||
_facialHairItemId = content.FacialHair.ItemId;
|
||||
_facialHairHue = content.FacialHair.Hue;
|
||||
}
|
||||
}
|
||||
|
||||
// Folded Murderer bool field into CorpseFlag.Murderer
|
||||
private void MigrateFrom(V15Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
if (content.Murderer)
|
||||
{
|
||||
_flags |= CorpseFlag.Murderer;
|
||||
}
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
if (content.Hair != null)
|
||||
{
|
||||
_hairItemId = content.Hair.ItemId;
|
||||
_hairHue = content.Hair.Hue;
|
||||
}
|
||||
|
||||
if (content.FacialHair != null)
|
||||
{
|
||||
_facialHairItemId = content.FacialHair.ItemId;
|
||||
_facialHairHue = content.FacialHair.Hue;
|
||||
}
|
||||
}
|
||||
|
||||
// Replaced int Kills snapshot with bool Murderer snapshot
|
||||
private void MigrateFrom(V14Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
if (content.Kills >= 5)
|
||||
{
|
||||
_flags |= CorpseFlag.Murderer;
|
||||
}
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
if (content.Hair != null)
|
||||
{
|
||||
_hairItemId = content.Hair.ItemId;
|
||||
_hairHue = content.Hair.Hue;
|
||||
}
|
||||
|
||||
if (content.FacialHair != null)
|
||||
{
|
||||
_facialHairItemId = content.FacialHair.ItemId;
|
||||
_facialHairHue = content.FacialHair.Hue;
|
||||
}
|
||||
}
|
||||
|
||||
// Added corpse hair and corpse facial hair
|
||||
private void MigrateFrom(V13Content content)
|
||||
{
|
||||
_restoreEquip = content.RestoreEquip;
|
||||
_flags = content.Flags;
|
||||
if (content.Kills >= 5)
|
||||
{
|
||||
_flags |= CorpseFlag.Murderer;
|
||||
}
|
||||
_timeOfDeath = content.TimeOfDeath;
|
||||
_restoreTable = content.RestoreTable;
|
||||
_decayTimer = new InternalTimer(this, content.DecayTimerDelay);
|
||||
_decayTimer.Start();
|
||||
_looters = content.Looters;
|
||||
_killer = content.Killer;
|
||||
_aggressors = content.Aggressors;
|
||||
_owner = content.Owner;
|
||||
_corpseName = content.CorpseName;
|
||||
_accessLevel = content.AccessLevel;
|
||||
_guild = content.Guild;
|
||||
_equipItems = content.EquipItems;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool InstancedCorpse => Core.SE && Core.Now < TimeOfDeath + InstancedCorpseTime;
|
||||
|
||||
|
|
|
|||
189
Projects/UOContent/Migrations/Server.Engines.CannedEvil.ChampionSpawn.v11.json
generated
Normal file
189
Projects/UOContent/Migrations/Server.Engines.CannedEvil.ChampionSpawn.v11.json
generated
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
{
|
||||
"version": 11,
|
||||
"type": "Server.Engines.CannedEvil.ChampionSpawn",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Level",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ActivatedByProximity",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "NextProximityTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MaxLevel",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ActivatedByValor",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DamageEntries",
|
||||
"type": "System.Collections.Generic.Dictionary\u003CServer.Mobile, int\u003E",
|
||||
"rule": "DictionaryMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Server.Mobile",
|
||||
"SerializableInterfaceMigrationRule",
|
||||
"0",
|
||||
"int",
|
||||
"PrimitiveTypeMigrationRule",
|
||||
"1",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ConfinedRoaming",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Idol",
|
||||
"type": "Server.Engines.CannedEvil.IdolOfTheChampion",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "HasBeenAdvanced",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SpawnArea",
|
||||
"type": "Server.Rectangle2D",
|
||||
"rule": "PrimitiveUOTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Rect2D"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RandomizeType",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Kills",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Active",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Type",
|
||||
"type": "Server.Engines.CannedEvil.ChampionSpawnType",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Creatures",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Mobile\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@Tidy",
|
||||
"Server.Mobile",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RedSkulls",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Item\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@Tidy",
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "WhiteSkulls",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Item\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@Tidy",
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Platform",
|
||||
"type": "Server.Engines.CannedEvil.ChampionPlatform",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Altar",
|
||||
"type": "Server.Engines.CannedEvil.ChampionAltar",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "ExpireDelay",
|
||||
"type": "System.TimeSpan",
|
||||
"rule": "PrimitiveTypeMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "ExpireTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Champion",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "RestartDelay",
|
||||
"type": "System.TimeSpan",
|
||||
"rule": "PrimitiveTypeMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "RestartTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
119
Projects/UOContent/Migrations/Server.Engines.Virtues.VirtueContext.v1.json
generated
Normal file
119
Projects/UOContent/Migrations/Server.Engines.Virtues.VirtueContext.v1.json
generated
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Engines.Virtues.VirtueContext",
|
||||
"properties": [
|
||||
{
|
||||
"name": "LastSacrificeGain",
|
||||
"type": "System.DateTime",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LastSacrificeLoss",
|
||||
"type": "System.DateTime",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AvailableResurrects",
|
||||
"type": "int",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LastJusticeLoss",
|
||||
"type": "System.DateTime",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LastCompassionLoss",
|
||||
"type": "System.DateTime",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "NextCompassionDay",
|
||||
"type": "System.DateTime",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CompassionGains",
|
||||
"type": "int",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LastValorLoss",
|
||||
"type": "System.DateTime",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LastHonorUse",
|
||||
"type": "System.DateTime",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "HonorActive",
|
||||
"type": "bool",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "JusticeProtection",
|
||||
"type": "Server.Mobiles.PlayerMobile",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "JusticeStatus",
|
||||
"type": "Server.Engines.Virtues.JusticeProtectorStatus",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Values",
|
||||
"type": "int[]",
|
||||
"usesSaveFlag": true,
|
||||
"rule": "ArrayMigrationRule",
|
||||
"ruleArguments": [
|
||||
"int",
|
||||
"PrimitiveTypeMigrationRule",
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
50
Projects/UOContent/Migrations/Server.Ethics.Player.v2.json
generated
Normal file
50
Projects/UOContent/Migrations/Server.Ethics.Player.v2.json
generated
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"version": 2,
|
||||
"type": "Server.Ethics.Player",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Mobile",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Power",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "History",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Steed",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Familiar",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Shield",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ethic",
|
||||
"type": "Server.Ethics.Ethic",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
}
|
||||
]
|
||||
}
|
||||
137
Projects/UOContent/Migrations/Server.Items.Corpse.v19.json
generated
Normal file
137
Projects/UOContent/Migrations/Server.Items.Corpse.v19.json
generated
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"version": 19,
|
||||
"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": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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.PuzzleChestSolutionAndTime.v1.json
generated
Normal file
14
Projects/UOContent/Migrations/Server.Items.PuzzleChestSolutionAndTime.v1.json
generated
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Items.PuzzleChestSolutionAndTime",
|
||||
"properties": [
|
||||
{
|
||||
"name": "When",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
22
Projects/UOContent/Migrations/Server.Items.StarRoomGate.v2.json
generated
Normal file
22
Projects/UOContent/Migrations/Server.Items.StarRoomGate.v2.json
generated
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"version": 2,
|
||||
"type": "Server.Items.StarRoomGate",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Decays",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DecayTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
Projects/UOContent/Migrations/Server.Items.TransientItem.v2.json
generated
Normal file
14
Projects/UOContent/Migrations/Server.Items.TransientItem.v2.json
generated
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": 2,
|
||||
"type": "Server.Items.TransientItem",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Expiration",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
62
Projects/UOContent/Migrations/Server.Mobiles.PlayerVendor.v4.json
generated
Normal file
62
Projects/UOContent/Migrations/Server.Mobiles.PlayerVendor.v4.json
generated
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"version": 4,
|
||||
"type": "Server.Mobiles.PlayerVendor",
|
||||
"properties": [
|
||||
{
|
||||
"name": "ShopName",
|
||||
"type": "string",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "NextPayTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "House",
|
||||
"type": "Server.Multis.BaseHouse",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Owner",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "BankAccount",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "HoldGold",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SellItems",
|
||||
"type": "System.Collections.Generic.Dictionary\u003CServer.Item, Server.Mobiles.VendorItem\u003E",
|
||||
"rule": "DictionaryMigrationRule",
|
||||
"ruleArguments": [
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule",
|
||||
"0",
|
||||
"Server.Mobiles.VendorItem",
|
||||
"RawSerializableMigrationRule",
|
||||
"1",
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
62
Projects/UOContent/Migrations/Server.Mobiles.RentedVendor.v1.json
generated
Normal file
62
Projects/UOContent/Migrations/Server.Mobiles.RentedVendor.v1.json
generated
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Mobiles.RentedVendor",
|
||||
"properties": [
|
||||
{
|
||||
"name": "RentalDurationId",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RentalPrice",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LandlordRenew",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RenterRenew",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RenewalPrice",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RentalGold",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RentalExpireTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
Projects/UOContent/Migrations/Server.Mobiles.Sheep.v1.json
generated
Normal file
14
Projects/UOContent/Migrations/Server.Mobiles.Sheep.v1.json
generated
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Mobiles.Sheep",
|
||||
"properties": [
|
||||
{
|
||||
"name": "NextWoolTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
73
Projects/UOContent/Migrations/Server.Multis.BaseBoat.v5.json
generated
Normal file
73
Projects/UOContent/Migrations/Server.Multis.BaseBoat.v5.json
generated
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"version": 5,
|
||||
"type": "Server.Multis.BaseBoat",
|
||||
"properties": [
|
||||
{
|
||||
"name": "MapItem",
|
||||
"type": "Server.Items.MapItem",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "NextNavPoint",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Facing",
|
||||
"type": "Server.Direction",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "TimeOfDecay",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Owner",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "PPlank",
|
||||
"type": "Server.Items.Plank",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "SPlank",
|
||||
"type": "Server.Items.Plank",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "TillerMan",
|
||||
"type": "Server.Items.TillerMan",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Hold",
|
||||
"type": "Server.Items.Hold",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Anchored",
|
||||
"type": "bool",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ShipName",
|
||||
"type": "string",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
34
Projects/UOContent/Migrations/Server.Multis.BaseCamp.v2.json
generated
Normal file
34
Projects/UOContent/Migrations/Server.Multis.BaseCamp.v2.json
generated
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"version": 2,
|
||||
"type": "Server.Multis.BaseCamp",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Items",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Item\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@Tidy",
|
||||
"Server.Item",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Mobiles",
|
||||
"type": "System.Collections.Generic.List\u003CServer.Mobile\u003E",
|
||||
"rule": "ListMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@Tidy",
|
||||
"Server.Mobile",
|
||||
"SerializableInterfaceMigrationRule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DecayTime",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
19
Projects/UOContent/Migrations/Server.Spells.Fifth.PoisonField.v1.json
generated
Normal file
19
Projects/UOContent/Migrations/Server.Spells.Fifth.PoisonField.v1.json
generated
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Spells.Fifth.PoisonField",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Caster",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "End",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
27
Projects/UOContent/Migrations/Server.Spells.Fourth.FireFieldItem.v1.json
generated
Normal file
27
Projects/UOContent/Migrations/Server.Spells.Fourth.FireFieldItem.v1.json
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Spells.Fourth.FireFieldItem",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Damage",
|
||||
"type": "int",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Caster",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "End",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
19
Projects/UOContent/Migrations/Server.Spells.Seventh.EnergyField.v2.json
generated
Normal file
19
Projects/UOContent/Migrations/Server.Spells.Seventh.EnergyField.v2.json
generated
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": 2,
|
||||
"type": "Server.Spells.Seventh.EnergyField",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Caster",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "End",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
19
Projects/UOContent/Migrations/Server.Spells.Sixth.ParalyzeField.v1.json
generated
Normal file
19
Projects/UOContent/Migrations/Server.Spells.Sixth.ParalyzeField.v1.json
generated
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Spells.Sixth.ParalyzeField",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Caster",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "End",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
19
Projects/UOContent/Migrations/Server.Spells.Third.WallOfStone.v1.json
generated
Normal file
19
Projects/UOContent/Migrations/Server.Spells.Third.WallOfStone.v1.json
generated
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": 1,
|
||||
"type": "Server.Spells.Third.WallOfStone",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Caster",
|
||||
"type": "Server.Mobile",
|
||||
"rule": "SerializableInterfaceMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "End",
|
||||
"type": "System.DateTime",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
"AnchoredTime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -5,9 +5,14 @@ using System.Runtime.CompilerServices;
|
|||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[SerializationGenerator(0, false)]
|
||||
[SerializationGenerator(1, false)]
|
||||
public partial class Sheep : BaseCreature, ICarvable
|
||||
{
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_nextWoolTime = content.NextWoolTime;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public Sheep() : base(AIType.AI_Animal, FightMode.Aggressor)
|
||||
{
|
||||
|
|
@ -44,7 +49,7 @@ namespace Server.Mobiles
|
|||
public override string CorpseName => "a sheep corpse";
|
||||
|
||||
[SerializableField(0, fieldChanged: nameof(OnNextWoolTimeChanged))]
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _nextWoolTime;
|
||||
|
||||
|
|
|
|||
|
|
@ -1843,7 +1843,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(20); // version
|
||||
writer.Write(21); // version
|
||||
|
||||
writer.Write((int)m_CurrentAI);
|
||||
writer.Write((int)m_DefaultAI);
|
||||
|
|
@ -1880,7 +1880,7 @@ namespace Server.Mobiles
|
|||
|
||||
if (_summoned)
|
||||
{
|
||||
writer.WriteDeltaTime(SummonEnd);
|
||||
writer.WriteAnchoredTime(SummonEnd);
|
||||
}
|
||||
|
||||
writer.Write(ControlSlots);
|
||||
|
|
@ -2035,7 +2035,7 @@ namespace Server.Mobiles
|
|||
|
||||
if (_summoned)
|
||||
{
|
||||
SummonEnd = reader.ReadDeltaTime();
|
||||
SummonEnd = version >= 21 ? reader.ReadAnchoredTime() : reader.ReadDeltaTime();
|
||||
new UnsummonTimer(this, SummonEnd - Core.Now).Start();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,20 @@ public class PlayerVendorTargetAttribute : Attribute;
|
|||
* Next, uncomment the MigrateFrom function and change the `V3Content` type to match the serialization version
|
||||
* before it was bumped. Then run publish.cmd to generate the migration file.
|
||||
*/
|
||||
[SerializationGenerator(3, false)]
|
||||
[SerializationGenerator(4, false)]
|
||||
public partial class PlayerVendor : Mobile
|
||||
{
|
||||
private void MigrateFrom(V3Content content)
|
||||
{
|
||||
_shopName = content.ShopName;
|
||||
_nextPayTime = content.NextPayTime;
|
||||
_house = content.House;
|
||||
_owner = content.Owner;
|
||||
_bankAccount = content.BankAccount;
|
||||
_holdGold = content.HoldGold;
|
||||
_sellItems = content.SellItems;
|
||||
}
|
||||
|
||||
private Timer _payTimer;
|
||||
|
||||
[InvalidateProperties]
|
||||
|
|
@ -32,7 +43,7 @@ public partial class PlayerVendor : Mobile
|
|||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private string _shopName;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(1, setter: "private")]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _nextPayTime;
|
||||
|
|
|
|||
|
|
@ -46,9 +46,20 @@ public class VendorRentalDuration
|
|||
}
|
||||
}
|
||||
|
||||
[SerializationGenerator(0)]
|
||||
[SerializationGenerator(1)]
|
||||
public partial class RentedVendor : PlayerVendor
|
||||
{
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_rentalDurationId = content.RentalDurationId;
|
||||
_rentalPrice = content.RentalPrice;
|
||||
_landlordRenew = content.LandlordRenew;
|
||||
_renterRenew = content.RenterRenew;
|
||||
_renewalPrice = content.RenewalPrice;
|
||||
_rentalGold = content.RentalGold;
|
||||
_rentalExpireTime = content.RentalExpireTime;
|
||||
}
|
||||
|
||||
private Timer _rentalExpireTimer;
|
||||
|
||||
public RentedVendor(
|
||||
|
|
@ -93,7 +104,7 @@ public partial class RentedVendor : PlayerVendor
|
|||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private int _rentalGold;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(6)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _rentalExpireTime;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace Server.Mobiles
|
|||
Items = reader.ReadEntityList<Item>();
|
||||
Gold = reader.ReadInt();
|
||||
|
||||
ExpireTime = reader.ReadDeltaTime();
|
||||
ExpireTime = version >= 1 ? reader.ReadAnchoredTime() : reader.ReadDeltaTime();
|
||||
|
||||
if (Items.Count == 0 && Gold == 0)
|
||||
{
|
||||
|
|
@ -88,7 +88,7 @@ namespace Server.Mobiles
|
|||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
writer.WriteEncodedInt(1); // version
|
||||
|
||||
writer.Write(Owner);
|
||||
writer.Write(VendorName);
|
||||
|
|
@ -98,7 +98,7 @@ namespace Server.Mobiles
|
|||
writer.Write(Items);
|
||||
writer.Write(Gold);
|
||||
|
||||
writer.WriteDeltaTime(ExpireTime);
|
||||
writer.WriteAnchoredTime(ExpireTime);
|
||||
}
|
||||
|
||||
private class ExpireTimer : Timer
|
||||
|
|
|
|||
|
|
@ -19,9 +19,24 @@ namespace Server.Multis
|
|||
Single
|
||||
}
|
||||
|
||||
[SerializationGenerator(4, false)]
|
||||
[SerializationGenerator(5, false)]
|
||||
public abstract partial class BaseBoat : BaseMulti
|
||||
{
|
||||
private void MigrateFrom(V4Content content)
|
||||
{
|
||||
_mapItem = content.MapItem;
|
||||
_nextNavPoint = content.NextNavPoint;
|
||||
_facing = content.Facing;
|
||||
_timeOfDecay = content.TimeOfDecay;
|
||||
_owner = content.Owner;
|
||||
_pPlank = content.PPlank;
|
||||
_sPlank = content.SPlank;
|
||||
_tillerMan = content.TillerMan;
|
||||
_hold = content.Hold;
|
||||
_anchored = content.Anchored;
|
||||
_shipName = content.ShipName;
|
||||
}
|
||||
|
||||
public enum DryDockResult
|
||||
{
|
||||
Valid,
|
||||
|
|
@ -137,7 +152,7 @@ namespace Server.Multis
|
|||
}
|
||||
|
||||
[SerializableField(3, fieldChanged: nameof(OnTimeOfDecayChanged))]
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _timeOfDecay;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,16 @@ using Server.Mobiles;
|
|||
|
||||
namespace Server.Multis;
|
||||
|
||||
[SerializationGenerator(1, false)]
|
||||
[SerializationGenerator(2, false)]
|
||||
public abstract partial class BaseCamp : BaseMulti
|
||||
{
|
||||
private void MigrateFrom(V1Content content)
|
||||
{
|
||||
_items = content.Items;
|
||||
_mobiles = content.Mobiles;
|
||||
_decayTime = content.DecayTime;
|
||||
}
|
||||
|
||||
[Tidy]
|
||||
[SerializableField(0, setter: "private")]
|
||||
private List<Item> _items;
|
||||
|
|
@ -17,7 +24,7 @@ public abstract partial class BaseCamp : BaseMulti
|
|||
[SerializableField(1, setter: "private")]
|
||||
private List<Mobile> _mobiles;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(2, setter: "private")]
|
||||
private DateTime _decayTime;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,13 +64,19 @@ public class PoisonFieldSpell : MagerySpell, ITargetingSpell<IPoint3D>
|
|||
}
|
||||
|
||||
[DispellableField]
|
||||
[SerializationGenerator(0, false)]
|
||||
[SerializationGenerator(1, false)]
|
||||
public partial class PoisonField : Item
|
||||
{
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_caster = content.Caster;
|
||||
_end = content.End;
|
||||
}
|
||||
|
||||
[SerializableField(0)]
|
||||
private Mobile _caster;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(1)]
|
||||
private DateTime _end;
|
||||
|
||||
|
|
|
|||
|
|
@ -67,16 +67,23 @@ public class FireFieldSpell : MagerySpell, ITargetingSpell<IPoint3D>
|
|||
}
|
||||
|
||||
[DispellableField]
|
||||
[SerializationGenerator(0, false)]
|
||||
[SerializationGenerator(1, false)]
|
||||
public partial class FireFieldItem : Item
|
||||
{
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_damage = content.Damage;
|
||||
_caster = content.Caster;
|
||||
_end = content.End;
|
||||
}
|
||||
|
||||
[SerializableField(0)]
|
||||
private int _damage;
|
||||
|
||||
[SerializableField(1)]
|
||||
private Mobile _caster;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(2)]
|
||||
private DateTime _end;
|
||||
private Timer _timer;
|
||||
|
|
|
|||
|
|
@ -77,13 +77,19 @@ public class EnergyFieldSpell : MagerySpell, ITargetingSpell<IPoint3D>
|
|||
}
|
||||
|
||||
[DispellableField]
|
||||
[SerializationGenerator(1, false)]
|
||||
[SerializationGenerator(2, false)]
|
||||
public partial class EnergyField : Item
|
||||
{
|
||||
private void MigrateFrom(V1Content content)
|
||||
{
|
||||
_caster = content.Caster;
|
||||
_end = content.End;
|
||||
}
|
||||
|
||||
[SerializableField(0)]
|
||||
private Mobile _caster;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(1)]
|
||||
private DateTime _end;
|
||||
|
||||
|
|
|
|||
|
|
@ -77,13 +77,19 @@ public class ParalyzeFieldSpell : MagerySpell, ITargetingSpell<IPoint3D>
|
|||
}
|
||||
|
||||
[DispellableField]
|
||||
[SerializationGenerator(0, false)]
|
||||
[SerializationGenerator(1, false)]
|
||||
public partial class ParalyzeField : Item
|
||||
{
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_caster = content.Caster;
|
||||
_end = content.End;
|
||||
}
|
||||
|
||||
[SerializableField(0)]
|
||||
private Mobile _caster;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(1)]
|
||||
private DateTime _end;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,17 @@ using ModernUO.Serialization;
|
|||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(1, false)]
|
||||
[SerializationGenerator(2, false)]
|
||||
public partial class TransientItem : Item
|
||||
{
|
||||
private void MigrateFrom(V1Content content)
|
||||
{
|
||||
_expiration = content.Expiration;
|
||||
}
|
||||
|
||||
private TimerExecutionToken _timerToken;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(0)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private DateTime _expiration;
|
||||
|
|
|
|||
|
|
@ -63,13 +63,19 @@ public class WallOfStoneSpell : MagerySpell, ITargetingSpell<IPoint3D>
|
|||
}
|
||||
|
||||
[DispellableField]
|
||||
[SerializationGenerator(0, false)]
|
||||
[SerializationGenerator(1, false)]
|
||||
public partial class WallOfStone : Item
|
||||
{
|
||||
private void MigrateFrom(V0Content content)
|
||||
{
|
||||
_caster = content.Caster;
|
||||
_end = content.End;
|
||||
}
|
||||
|
||||
[SerializableField(0)]
|
||||
private Mobile _caster;
|
||||
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(1)]
|
||||
private DateTime _end;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue