fix: Hair and facial hair "teleporting" when mobile dies several times (#1901)
### Summary * Added World.NewVirtual for creating virtual serial numbers * Reserved range 0x7EEEEEEE to 0x7FFFFFFF for virtual serials * Hair and Facial hair (for mobiles) now use virtual serials instead of FakeSerial() functions * Consolidated virtual hair to a single `VirtualHairInfo` class. Corpse hair and facial hair now persists across save/load and hair and facial hair no longer teleport to newest corpse.
This commit is contained in:
parent
883d873c1c
commit
91e37fb8d4
15 changed files with 548 additions and 357 deletions
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server;
|
||||
|
|
@ -65,83 +66,33 @@ public static class OutgoingVirtualHairPackets
|
|||
}
|
||||
}
|
||||
|
||||
public abstract class BaseHairInfo
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class VirtualHairInfo
|
||||
{
|
||||
protected BaseHairInfo(int itemid, int hue = 0)
|
||||
[SerializableField(0)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private int _itemId;
|
||||
|
||||
[SerializableField(1)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private int _hue;
|
||||
|
||||
public VirtualHairInfo() : this(0)
|
||||
{
|
||||
ItemID = itemid;
|
||||
Hue = hue;
|
||||
}
|
||||
|
||||
protected BaseHairInfo(IGenericReader reader)
|
||||
public VirtualHairInfo(int itemid, int hue = 0)
|
||||
{
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ItemID = reader.ReadInt();
|
||||
Hue = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
_itemId = itemid;
|
||||
_hue = hue;
|
||||
VirtualSerial = World.NewVirtual;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ItemID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Hue { get; set; }
|
||||
|
||||
public virtual void Serialize(IGenericWriter writer)
|
||||
[AfterDeserialization]
|
||||
private void AfterDeserialization()
|
||||
{
|
||||
writer.Write(0); // version
|
||||
writer.Write(ItemID);
|
||||
writer.Write(Hue);
|
||||
VirtualSerial = World.NewVirtual;
|
||||
}
|
||||
}
|
||||
|
||||
public class HairInfo : BaseHairInfo
|
||||
{
|
||||
public HairInfo(int itemid)
|
||||
: base(itemid)
|
||||
{
|
||||
}
|
||||
|
||||
public HairInfo(int itemid, int hue)
|
||||
: base(itemid, hue)
|
||||
{
|
||||
}
|
||||
|
||||
public HairInfo(IGenericReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: Can we make this higher for newer clients?
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint FakeSerial(Serial m) => 0x7FFFFFFF - 0x400 - m.Value * 4;
|
||||
}
|
||||
|
||||
public class FacialHairInfo : BaseHairInfo
|
||||
{
|
||||
public FacialHairInfo(int itemid)
|
||||
: base(itemid)
|
||||
{
|
||||
}
|
||||
|
||||
public FacialHairInfo(int itemid, int hue)
|
||||
: base(itemid, hue)
|
||||
{
|
||||
}
|
||||
|
||||
public FacialHairInfo(IGenericReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: Can we make this higher for newer clients?
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint FakeSerial(Serial m) => 0x7FFFFFFF - 0x400 - 1 - m.Value* 4;
|
||||
|
||||
public Serial VirtualSerial { get; private set; }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue