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:
mdodkins 2024-08-08 04:10:23 +01:00 • committed by GitHub
parent 883d873c1c
commit 91e37fb8d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 548 additions and 357 deletions

View file

@ -504,13 +504,16 @@ namespace Server.Tests.Network
var eq = beheld.Items;
var count = eq.Count;
var hair = beheld.Hair;
var facialHair = beheld.FacialHair;
if (beheld.HairItemID > 0)
if (hair != null)
{
count++;
}
if (beheld.FacialHairItemID > 0)
if (facialHair != null)
{
count++;
}
@ -570,19 +573,19 @@ namespace Server.Tests.Network
}
}
if (beheld.HairItemID > 0)
if (hair?.ItemId > 0)
{
if (m_DupedLayers![(int)Layer.Hair] != m_Version)
{
m_DupedLayers[(int)Layer.Hair] = m_Version;
hue = beheld.HairHue;
hue = hair.Hue;
if (beheld.SolidHueOverride >= 0)
{
hue = beheld.SolidHueOverride;
}
var itemID = beheld.HairItemID & itemIdMask;
var itemID = hair.ItemId & itemIdMask;
var writeHue = newPacket || hue != 0;
if (!newPacket && writeHue)
@ -590,7 +593,7 @@ namespace Server.Tests.Network
itemID |= 0x8000;
}
Stream.Write(HairInfo.FakeSerial(beheld.Serial));
Stream.Write(hair.VirtualSerial);
Stream.Write((ushort)itemID);
Stream.Write((byte)Layer.Hair);
@ -601,19 +604,19 @@ namespace Server.Tests.Network
}
}
if (beheld.FacialHairItemID > 0)
if (facialHair?.ItemId > 0)
{
if (m_DupedLayers![(int)Layer.FacialHair] != m_Version)
{
m_DupedLayers[(int)Layer.FacialHair] = m_Version;
hue = beheld.FacialHairHue;
hue = facialHair.Hue;
if (beheld.SolidHueOverride >= 0)
{
hue = beheld.SolidHueOverride;
}
var itemID = beheld.FacialHairItemID & itemIdMask;
var itemID = facialHair.ItemId & itemIdMask;
var writeHue = newPacket || hue != 0;
if (!newPacket && writeHue)
@ -621,7 +624,7 @@ namespace Server.Tests.Network
itemID |= 0x8000;
}
Stream.Write(FacialHairInfo.FakeSerial(beheld.Serial));
Stream.Write(facialHair.VirtualSerial);
Stream.Write((ushort)itemID);
Stream.Write((byte)Layer.FacialHair);