fix(core): Converts virtual hair packets (#388)
- [X] Converts virtual hair packets
This commit is contained in:
parent
30ef0761cb
commit
0912876f7c
11 changed files with 214 additions and 86 deletions
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Server.Gumps;
|
using Server.Gumps;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -590,7 +590,7 @@ namespace Server.Tests.Network
|
||||||
itemID |= 0x8000;
|
itemID |= 0x8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.Write(HairInfo.FakeSerial(beheld));
|
Stream.Write(HairInfo.FakeSerial(beheld.Serial));
|
||||||
Stream.Write((ushort)itemID);
|
Stream.Write((ushort)itemID);
|
||||||
Stream.Write((byte)Layer.Hair);
|
Stream.Write((byte)Layer.Hair);
|
||||||
|
|
||||||
|
|
@ -621,7 +621,7 @@ namespace Server.Tests.Network
|
||||||
itemID |= 0x8000;
|
itemID |= 0x8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.Write(FacialHairInfo.FakeSerial(beheld));
|
Stream.Write(FacialHairInfo.FakeSerial(beheld.Serial));
|
||||||
Stream.Write((ushort)itemID);
|
Stream.Write((ushort)itemID);
|
||||||
Stream.Write((byte)Layer.FacialHair);
|
Stream.Write((byte)Layer.FacialHair);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using Server.HuePickers;
|
using Server.HuePickers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using Server.Network;
|
||||||
|
using Server.Tests.Network;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Server.Tests
|
||||||
|
{
|
||||||
|
public class VirtualHairPacketTests: IClassFixture<ServerFixture>
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void TestSendVirtualHairUpdate()
|
||||||
|
{
|
||||||
|
var m = new Mobile(0x1024u);
|
||||||
|
m.DefaultMobileInit();
|
||||||
|
|
||||||
|
var expected = new HairEquipUpdate(m).Compile();
|
||||||
|
|
||||||
|
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||||
|
ns.SendHairEquipUpdatePacket(m, HairInfo.FakeSerial(m.Serial), Layer.Hair);
|
||||||
|
|
||||||
|
var result = ns.SendPipe.Reader.TryRead();
|
||||||
|
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestSendRemoveVirtualHair()
|
||||||
|
{
|
||||||
|
var m = new Mobile(0x1024u);
|
||||||
|
m.DefaultMobileInit();
|
||||||
|
|
||||||
|
var expected = new RemoveHair(m).Compile();
|
||||||
|
|
||||||
|
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||||
|
ns.SendRemoveHairPacket(HairInfo.FakeSerial(m.Serial));
|
||||||
|
|
||||||
|
var result = ns.SendPipe.Reader.TryRead();
|
||||||
|
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
namespace Server.Network
|
||||||
|
{
|
||||||
|
public sealed class HairEquipUpdate : Packet
|
||||||
|
{
|
||||||
|
public HairEquipUpdate(Mobile parent)
|
||||||
|
: base(0x2E, 15)
|
||||||
|
{
|
||||||
|
var hue = parent.SolidHueOverride >= 0 ? parent.SolidHueOverride : parent.HairHue;
|
||||||
|
|
||||||
|
Stream.Write(HairInfo.FakeSerial(parent.Serial));
|
||||||
|
Stream.Write((short)parent.HairItemID);
|
||||||
|
Stream.Write((byte)0);
|
||||||
|
Stream.Write((byte)Layer.Hair);
|
||||||
|
Stream.Write(parent.Serial);
|
||||||
|
Stream.Write((short)hue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class FacialHairEquipUpdate : Packet
|
||||||
|
{
|
||||||
|
public FacialHairEquipUpdate(Mobile parent)
|
||||||
|
: base(0x2E, 15)
|
||||||
|
{
|
||||||
|
var hue = parent.SolidHueOverride >= 0 ? parent.SolidHueOverride : parent.FacialHairHue;
|
||||||
|
|
||||||
|
Stream.Write(FacialHairInfo.FakeSerial(parent.Serial));
|
||||||
|
Stream.Write((short)parent.FacialHairItemID);
|
||||||
|
Stream.Write((byte)0);
|
||||||
|
Stream.Write((byte)Layer.FacialHair);
|
||||||
|
Stream.Write(parent.Serial);
|
||||||
|
Stream.Write((short)hue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RemoveHair : Packet
|
||||||
|
{
|
||||||
|
public RemoveHair(Mobile parent)
|
||||||
|
: base(0x1D, 5)
|
||||||
|
{
|
||||||
|
Stream.Write(HairInfo.FakeSerial(parent.Serial));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RemoveFacialHair : Packet
|
||||||
|
{
|
||||||
|
public RemoveFacialHair(Mobile parent)
|
||||||
|
: base(0x1D, 5)
|
||||||
|
{
|
||||||
|
Stream.Write(FacialHairInfo.FakeSerial(parent.Serial));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,62 @@
|
||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
||||||
namespace Server
|
namespace Server
|
||||||
{
|
{
|
||||||
|
public static class OutgoingVirtualHairPackets
|
||||||
|
{
|
||||||
|
public const int EquipUpdatePacketLength = 15;
|
||||||
|
public const int RemovePacketLength = 5;
|
||||||
|
|
||||||
|
public static void SendHairEquipUpdatePacket(this NetState ns, Mobile m, Serial hairSerial, Layer layer)
|
||||||
|
{
|
||||||
|
if (ns == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[EquipUpdatePacketLength];
|
||||||
|
CreateHairEquipUpdatePacket(buffer, m, hairSerial, layer);
|
||||||
|
ns.Send(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateHairEquipUpdatePacket(Span<byte> buffer, Mobile m, Serial hairSerial, Layer layer)
|
||||||
|
{
|
||||||
|
var hue = m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.HairHue;
|
||||||
|
|
||||||
|
var writer = new SpanWriter(buffer);
|
||||||
|
writer.Write((byte)0x2E); // Packet ID
|
||||||
|
|
||||||
|
writer.Write(hairSerial);
|
||||||
|
writer.Write((short)m.HairItemID);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write((byte)layer);
|
||||||
|
writer.Write(m.Serial);
|
||||||
|
writer.Write((short)hue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendRemoveHairPacket(this NetState ns, Serial hairSerial)
|
||||||
|
{
|
||||||
|
if (ns == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[RemovePacketLength];
|
||||||
|
CreateRemoveHairPacket(buffer, hairSerial);
|
||||||
|
ns.Send(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateRemoveHairPacket(Span<byte> buffer, Serial hairSerial)
|
||||||
|
{
|
||||||
|
var writer = new SpanWriter(buffer);
|
||||||
|
writer.Write((byte)0x1D); // Packet ID
|
||||||
|
writer.Write(hairSerial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class BaseHairInfo
|
public abstract class BaseHairInfo
|
||||||
{
|
{
|
||||||
protected BaseHairInfo(int itemid, int hue = 0)
|
protected BaseHairInfo(int itemid, int hue = 0)
|
||||||
|
|
@ -57,7 +112,8 @@ namespace Server
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Can we make this higher for newer clients?
|
// TODO: Can we make this higher for newer clients?
|
||||||
public static uint FakeSerial(Mobile parent) => 0x7FFFFFFF - 0x400 - parent.Serial * 4;
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint FakeSerial(Serial m) => 0x7FFFFFFF - 0x400 - m * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FacialHairInfo : BaseHairInfo
|
public class FacialHairInfo : BaseHairInfo
|
||||||
|
|
@ -77,57 +133,8 @@ namespace Server
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// TOOD: Can we make this higher for newer clients?
|
// TODO: Can we make this higher for newer clients?
|
||||||
public static uint FakeSerial(Mobile parent) => 0x7FFFFFFF - 0x400 - 1 - parent.Serial * 4;
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
}
|
public static uint FakeSerial(Serial m) => 0x7FFFFFFF - 0x400 - 1 - m * 4;
|
||||||
|
|
||||||
public sealed class HairEquipUpdate : Packet
|
|
||||||
{
|
|
||||||
public HairEquipUpdate(Mobile parent)
|
|
||||||
: base(0x2E, 15)
|
|
||||||
{
|
|
||||||
var hue = parent.SolidHueOverride >= 0 ? parent.SolidHueOverride : parent.HairHue;
|
|
||||||
|
|
||||||
Stream.Write(HairInfo.FakeSerial(parent));
|
|
||||||
Stream.Write((short)parent.HairItemID);
|
|
||||||
Stream.Write((byte)0);
|
|
||||||
Stream.Write((byte)Layer.Hair);
|
|
||||||
Stream.Write(parent.Serial);
|
|
||||||
Stream.Write((short)hue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class FacialHairEquipUpdate : Packet
|
|
||||||
{
|
|
||||||
public FacialHairEquipUpdate(Mobile parent)
|
|
||||||
: base(0x2E, 15)
|
|
||||||
{
|
|
||||||
var hue = parent.SolidHueOverride >= 0 ? parent.SolidHueOverride : parent.FacialHairHue;
|
|
||||||
|
|
||||||
Stream.Write(FacialHairInfo.FakeSerial(parent));
|
|
||||||
Stream.Write((short)parent.FacialHairItemID);
|
|
||||||
Stream.Write((byte)0);
|
|
||||||
Stream.Write((byte)Layer.FacialHair);
|
|
||||||
Stream.Write(parent.Serial);
|
|
||||||
Stream.Write((short)hue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class RemoveHair : Packet
|
|
||||||
{
|
|
||||||
public RemoveHair(Mobile parent)
|
|
||||||
: base(0x1D, 5)
|
|
||||||
{
|
|
||||||
Stream.Write(HairInfo.FakeSerial(parent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class RemoveFacialHair : Packet
|
|
||||||
{
|
|
||||||
public RemoveFacialHair(Mobile parent)
|
|
||||||
: base(0x1D, 5)
|
|
||||||
{
|
|
||||||
Stream.Write(FacialHairInfo.FakeSerial(parent));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3101,11 +3101,11 @@ namespace Server
|
||||||
{
|
{
|
||||||
if (removeHair)
|
if (removeHair)
|
||||||
{
|
{
|
||||||
ourState.Send(new RemoveHair(this));
|
ourState.SendRemoveHairPacket(HairInfo.FakeSerial(Serial));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ourState.Send(new HairEquipUpdate(this));
|
ourState.SendHairEquipUpdatePacket(this, HairInfo.FakeSerial(Serial), Layer.Hair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3113,11 +3113,11 @@ namespace Server
|
||||||
{
|
{
|
||||||
if (removeFacialHair)
|
if (removeFacialHair)
|
||||||
{
|
{
|
||||||
ourState.Send(new RemoveFacialHair(this));
|
ourState.SendRemoveHairPacket(FacialHairInfo.FakeSerial(Serial));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ourState.Send(new FacialHairEquipUpdate(this));
|
ourState.SendHairEquipUpdatePacket(this, FacialHairInfo.FakeSerial(Serial), Layer.FacialHair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3144,9 +3144,6 @@ namespace Server
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet hairPacket = null;
|
|
||||||
Packet facialhairPacket = null;
|
|
||||||
|
|
||||||
var eable = Map.GetClientsInRange(m_Location);
|
var eable = Map.GetClientsInRange(m_Location);
|
||||||
|
|
||||||
Span<byte> statBufferTrue = stackalloc byte[OutgoingMobilePackets.MobileStatusCompactLength];
|
Span<byte> statBufferTrue = stackalloc byte[OutgoingMobilePackets.MobileStatusCompactLength];
|
||||||
|
|
@ -3170,6 +3167,20 @@ namespace Server
|
||||||
Span<byte> hitsPacket = stackalloc byte[OutgoingMobilePackets.MobileAttributePacketLength];
|
Span<byte> hitsPacket = stackalloc byte[OutgoingMobilePackets.MobileAttributePacketLength];
|
||||||
hitsPacket.InitializePacket();
|
hitsPacket.InitializePacket();
|
||||||
|
|
||||||
|
var hairLength = removeHair
|
||||||
|
? OutgoingVirtualHairPackets.RemovePacketLength
|
||||||
|
: OutgoingVirtualHairPackets.EquipUpdatePacketLength;
|
||||||
|
|
||||||
|
Span<byte> hairPacket = stackalloc byte[hairLength];
|
||||||
|
hairPacket.InitializePacket();
|
||||||
|
|
||||||
|
var facialHairLength = removeFacialHair
|
||||||
|
? OutgoingVirtualHairPackets.RemovePacketLength
|
||||||
|
: OutgoingVirtualHairPackets.EquipUpdatePacketLength;
|
||||||
|
|
||||||
|
Span<byte> facialhairPacket = stackalloc byte[facialHairLength];
|
||||||
|
facialhairPacket.InitializePacket();
|
||||||
|
|
||||||
foreach (var state in eable)
|
foreach (var state in eable)
|
||||||
{
|
{
|
||||||
var beholder = state.Mobile;
|
var beholder = state.Mobile;
|
||||||
|
|
@ -3265,18 +3276,46 @@ namespace Server
|
||||||
|
|
||||||
if (sendHair)
|
if (sendHair)
|
||||||
{
|
{
|
||||||
hairPacket ??= removeHair
|
if (hairPacket[0] == 0)
|
||||||
? Packet.Acquire(new RemoveHair(this))
|
{
|
||||||
: Packet.Acquire(new HairEquipUpdate(this));
|
var hairSerial = HairInfo.FakeSerial(Serial);
|
||||||
|
if (removeHair)
|
||||||
|
{
|
||||||
|
OutgoingVirtualHairPackets.CreateRemoveHairPacket(hairPacket, hairSerial);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutgoingVirtualHairPackets.CreateHairEquipUpdatePacket(
|
||||||
|
hairPacket,
|
||||||
|
this,
|
||||||
|
hairSerial,
|
||||||
|
Layer.Hair
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.Send(hairPacket);
|
state.Send(hairPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendFacialHair)
|
if (sendFacialHair)
|
||||||
{
|
{
|
||||||
facialhairPacket ??= removeFacialHair
|
if (facialhairPacket[0] == 0)
|
||||||
? Packet.Acquire(new RemoveFacialHair(this))
|
{
|
||||||
: Packet.Acquire(new FacialHairEquipUpdate(this));
|
var hairSerial = HairInfo.FakeSerial(Serial);
|
||||||
|
if (removeFacialHair)
|
||||||
|
{
|
||||||
|
OutgoingVirtualHairPackets.CreateRemoveHairPacket(facialhairPacket, hairSerial);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutgoingVirtualHairPackets.CreateHairEquipUpdatePacket(
|
||||||
|
facialhairPacket,
|
||||||
|
this,
|
||||||
|
hairSerial,
|
||||||
|
Layer.FacialHair
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.Send(facialhairPacket);
|
state.Send(facialhairPacket);
|
||||||
}
|
}
|
||||||
|
|
@ -3284,9 +3323,6 @@ namespace Server
|
||||||
SendOPLPacketTo(state);
|
SendOPLPacketTo(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet.Release(hairPacket);
|
|
||||||
Packet.Release(facialhairPacket);
|
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -614,7 +614,7 @@ namespace Server.Network
|
||||||
itemID |= 0x8000;
|
itemID |= 0x8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(HairInfo.FakeSerial(beheld));
|
writer.Write(HairInfo.FakeSerial(beheld.Serial));
|
||||||
writer.Write((ushort)itemID);
|
writer.Write((ushort)itemID);
|
||||||
writer.Write((byte)Layer.Hair);
|
writer.Write((byte)Layer.Hair);
|
||||||
|
|
||||||
|
|
@ -637,7 +637,7 @@ namespace Server.Network
|
||||||
itemID |= 0x8000;
|
itemID |= 0x8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(FacialHairInfo.FakeSerial(beheld));
|
writer.Write(FacialHairInfo.FakeSerial(beheld.Serial));
|
||||||
writer.Write((ushort)itemID);
|
writer.Write((ushort)itemID);
|
||||||
writer.Write((byte)Layer.FacialHair);
|
writer.Write((byte)Layer.FacialHair);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,13 @@ namespace Server.Network
|
||||||
if (beheld.Hair?.ItemID > 0)
|
if (beheld.Hair?.ItemID > 0)
|
||||||
{
|
{
|
||||||
Stream.Write((byte)(Layer.Hair + 1));
|
Stream.Write((byte)(Layer.Hair + 1));
|
||||||
Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2);
|
Stream.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beheld.FacialHair?.ItemID > 0)
|
if (beheld.FacialHair?.ItemID > 0)
|
||||||
{
|
{
|
||||||
Stream.Write((byte)(Layer.FacialHair + 1));
|
Stream.Write((byte)(Layer.FacialHair + 1));
|
||||||
Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2);
|
Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.Write((byte)Layer.Invalid);
|
Stream.Write((byte)Layer.Invalid);
|
||||||
|
|
@ -98,7 +98,7 @@ namespace Server.Network
|
||||||
|
|
||||||
if (beheld.Hair?.ItemID > 0)
|
if (beheld.Hair?.ItemID > 0)
|
||||||
{
|
{
|
||||||
Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2);
|
Stream.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2);
|
||||||
Stream.Write((ushort)beheld.Hair.ItemID);
|
Stream.Write((ushort)beheld.Hair.ItemID);
|
||||||
Stream.Write((byte)0); // signed, itemID offset
|
Stream.Write((byte)0); // signed, itemID offset
|
||||||
Stream.Write((ushort)1);
|
Stream.Write((ushort)1);
|
||||||
|
|
@ -112,7 +112,7 @@ namespace Server.Network
|
||||||
|
|
||||||
if (beheld.FacialHair?.ItemID > 0)
|
if (beheld.FacialHair?.ItemID > 0)
|
||||||
{
|
{
|
||||||
Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2);
|
Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2);
|
||||||
Stream.Write((ushort)beheld.FacialHair.ItemID);
|
Stream.Write((ushort)beheld.FacialHair.ItemID);
|
||||||
Stream.Write((byte)0); // signed, itemID offset
|
Stream.Write((byte)0); // signed, itemID offset
|
||||||
Stream.Write((ushort)1);
|
Stream.Write((ushort)1);
|
||||||
|
|
@ -177,7 +177,7 @@ namespace Server.Network
|
||||||
|
|
||||||
if (beheld.Hair?.ItemID > 0)
|
if (beheld.Hair?.ItemID > 0)
|
||||||
{
|
{
|
||||||
Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2);
|
Stream.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2);
|
||||||
Stream.Write((ushort)beheld.Hair.ItemID);
|
Stream.Write((ushort)beheld.Hair.ItemID);
|
||||||
Stream.Write((byte)0); // signed, itemID offset
|
Stream.Write((byte)0); // signed, itemID offset
|
||||||
Stream.Write((ushort)1);
|
Stream.Write((ushort)1);
|
||||||
|
|
@ -192,7 +192,7 @@ namespace Server.Network
|
||||||
|
|
||||||
if (beheld.FacialHair?.ItemID > 0)
|
if (beheld.FacialHair?.ItemID > 0)
|
||||||
{
|
{
|
||||||
Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2);
|
Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2);
|
||||||
Stream.Write((ushort)beheld.FacialHair.ItemID);
|
Stream.Write((ushort)beheld.FacialHair.ItemID);
|
||||||
Stream.Write((byte)0); // signed, itemID offset
|
Stream.Write((byte)0); // signed, itemID offset
|
||||||
Stream.Write((ushort)1);
|
Stream.Write((ushort)1);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue