Vorspire
Knight
I took the liberty of constructing the lesser known packets that differ between classic and enhanced clients, some of them might not be known in general, but here they are;
Various documentation for these packets on the internet is wrong, the order of some bytes are wrong, due to poorly copy/pasted web page templates that didn't really get filled in correctly.
These packets are accurate and the corrections against the documentation mistakes have been made.
KR support is standard on shards that I work with now, still trying to figure out how to fix gumps though - the EC doesn't preserve the layers order in which the gumps are coded - it seems to give priority to specific entries, like buttons always appear at the front, even if you code them behind a background element.
C#:
#region Support KR
public sealed class KRHealthbarPoison : Packet
{
public KRHealthbarPoison(Mobile m)
: base(0x16)
{
EnsureCapacity(12);
m_Stream.Write(m.Serial);
m_Stream.Write((short)0x01);
m_Stream.Write((short)0x01);
Poison p = m.Poison;
if (p != null)
{
m_Stream.Write((byte)(p.RealLevel + 1));
}
else
{
m_Stream.Write((byte)0x00);
}
}
}
public sealed class KRHealthbarYellow : Packet
{
public KRHealthbarYellow(Mobile m)
: base(0x16)
{
EnsureCapacity(12);
m_Stream.Write(m.Serial);
m_Stream.Write((short)0x01);
m_Stream.Write((short)0x02);
if (m.Blessed || m.YellowHealthbar)
{
m_Stream.Write((byte)0x01);
}
else
{
m_Stream.Write((byte)0x00);
}
}
}
public sealed class KRVerification : Packet
{
public static readonly Packet Instance = SetStatic(new KRVerification());
public KRVerification()
: base(0xE3, 77)
{
// First 2 - Size
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x4D);
// Next ones... I have no idea from now on
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x03);
m_Stream.Write((byte)0x02);
m_Stream.Write((byte)0x01);
m_Stream.Write((byte)0x03);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x13);
m_Stream.Write((byte)0x02);
m_Stream.Write((byte)0x11);
// Next 16
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0xFC);
m_Stream.Write((byte)0x2F);
m_Stream.Write((byte)0xE3);
m_Stream.Write((byte)0x81);
m_Stream.Write((byte)0x93);
m_Stream.Write((byte)0xCB);
m_Stream.Write((byte)0xAF);
m_Stream.Write((byte)0x98);
m_Stream.Write((byte)0xDD);
m_Stream.Write((byte)0x83);
m_Stream.Write((byte)0x13);
m_Stream.Write((byte)0xD2);
m_Stream.Write((byte)0x9E);
m_Stream.Write((byte)0xEA);
m_Stream.Write((byte)0xE4);
// Next 16
m_Stream.Write((byte)0x13);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x10);
m_Stream.Write((byte)0x78);
m_Stream.Write((byte)0x13);
m_Stream.Write((byte)0xB7);
m_Stream.Write((byte)0x7B);
m_Stream.Write((byte)0xCE);
m_Stream.Write((byte)0xA8);
m_Stream.Write((byte)0xD7);
m_Stream.Write((byte)0xBC);
m_Stream.Write((byte)0x52);
m_Stream.Write((byte)0xDE);
m_Stream.Write((byte)0x38);
// Next 16
m_Stream.Write((byte)0x30);
m_Stream.Write((byte)0xEA);
m_Stream.Write((byte)0xE9);
m_Stream.Write((byte)0x1E);
m_Stream.Write((byte)0xA3);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x20);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x00);
m_Stream.Write((byte)0x10);
m_Stream.Write((byte)0x5A);
m_Stream.Write((byte)0xCE);
m_Stream.Write((byte)0x3E);
// Next 13
m_Stream.Write((byte)0xE3);
m_Stream.Write((byte)0x97);
m_Stream.Write((byte)0x92);
m_Stream.Write((byte)0xE4);
m_Stream.Write((byte)0x8A);
m_Stream.Write((byte)0xF1);
m_Stream.Write((byte)0x9A);
m_Stream.Write((byte)0xD3);
m_Stream.Write((byte)0x04);
m_Stream.Write((byte)0x41);
m_Stream.Write((byte)0x03);
m_Stream.Write((byte)0xCB);
m_Stream.Write((byte)0x53);
}
}
public sealed class KRDropConfirm : Packet
{
public static readonly Packet Instance = SetStatic(new KRDropConfirm());
public KRDropConfirm()
: base(0x29, 1)
{ }
}
public sealed class KRPetWindow : Packet
{
public KRPetWindow(Mobile owner, params Mobile[] pets)
: base(0x31)
{
EnsureCapacity(8 + (pets.Length * 5));
m_Stream.Write(owner.Serial);
m_Stream.Write((byte)pets.Length);
foreach (Mobile pet in pets)
{
m_Stream.Write(pet.Serial);
m_Stream.Write((byte)0x01);
}
}
}
public enum KRWaypointType
{
None = 0x0,
Corpse = 0x01,
Party = 0x02,
Unknown = 0x03,
Quest = 0x04,
QuestDestination = 0x05,
Resurrection = 0x06
}
public sealed class KRDisplayWaypoint : Packet
{
public KRDisplayWaypoint(Serial serial, Point3D loc, Map map, KRWaypointType type, string label)
: base(0xE5)
{
bool ignore = false;
int cliloc = 1062613;
switch (type)
{
case KRWaypointType.Corpse:
cliloc = 1046414;
break;
case KRWaypointType.Resurrection:
case KRWaypointType.QuestDestination:
case KRWaypointType.Quest:
case KRWaypointType.Party:
case KRWaypointType.None:
ignore = true;
break;
}
EnsureCapacity(25);
m_Stream.Write(serial);
m_Stream.Write((short)loc.X);
m_Stream.Write((short)loc.Y);
m_Stream.Write((sbyte)loc.Z);
m_Stream.Write((byte)map.MapID);
m_Stream.Write((short)type);
m_Stream.Write(ignore);
m_Stream.Write(cliloc);
m_Stream.WriteLittleUniNull(label);
m_Stream.Write((short)0); // terminate
}
}
public sealed class KRHideWaypoint : Packet
{
public KRHideWaypoint(Serial serial)
: base(0xE6, 5)
{
m_Stream.Write(serial);
}
}
public sealed class KRUIHighlight : Packet
{
public KRUIHighlight(Mobile user, short element, Serial dest)
: base(0xE7, 12)
{
m_Stream.Write(user.Serial);
m_Stream.Write(element);
m_Stream.Write(dest);
m_Stream.Write((byte)0x01);
}
}
public sealed class KRUIToggleHighlight : Packet
{
public static KRUIToggleHighlight Inventory(Mobile user, short element, int dest)
{
return new KRUIToggleHighlight(user, element, "ToggleInventory", dest);
}
public static KRUIToggleHighlight Paperdoll(Mobile user, short element, int dest)
{
return new KRUIToggleHighlight(user, element, "TogglePaperdoll", dest);
}
public static KRUIToggleHighlight Map(Mobile user, short element, int dest)
{
return new KRUIToggleHighlight(user, element, "ToggleMap", dest);
}
public KRUIToggleHighlight(Mobile user, short element, string desc, int dest)
: base(0xE9, 75)
{
m_Stream.Write(element);
m_Stream.Write(user.Serial);
m_Stream.WriteAsciiFixed(desc, 64);
m_Stream.Write(dest);
}
}
public sealed class KRHotbar : Packet
{
public static readonly Packet Enable = SetStatic(new KRHotbar(true));
public static readonly Packet Disable = SetStatic(new KRHotbar(false));
public KRHotbar(bool enable)
: base(0xEA, 3)
{
m_Stream.Write((short)(enable ? 0x01 : 0x00));
}
}
public sealed class KRSlotCooldown : Packet
{
public KRSlotCooldown(Item item, int duration)
: this(item.ItemID, duration)
{ }
public KRSlotCooldown(int id, int duration)
: base(0xBF)
{
m_Stream.Write((short)0x31);
m_Stream.Write((short)0x01);
m_Stream.Write(id);
m_Stream.Write(duration);
}
}
public sealed class KRStatLockInfo : Packet
{
public KRStatLockInfo(Mobile m)
: base(0xBF)
{
EnsureCapacity(17);
m_Stream.Write((short)0x19);
m_Stream.Write((byte)0x05);
m_Stream.Write(m.Serial);
m_Stream.Write((byte)0);
int lockBits = 0;
lockBits |= (int)m.StrLock << 4;
lockBits |= (int)m.DexLock << 2;
lockBits |= (int)m.IntLock;
m_Stream.Write((byte)lockBits);
if (lockBits == 0xFF)
{
m_Stream.Write((byte)m.GetPacketFlags());
m_Stream.Write((short)m.GetIdleAnimation()); //Animation
m_Stream.Write((short)5); //Frame Count
}
else
{
m_Stream.Fill(5);
}
}
}
#endregion
Various documentation for these packets on the internet is wrong, the order of some bytes are wrong, due to poorly copy/pasted web page templates that didn't really get filled in correctly.
These packets are accurate and the corrections against the documentation mistakes have been made.
KR support is standard on shards that I work with now, still trying to figure out how to fix gumps though - the EC doesn't preserve the layers order in which the gumps are coded - it seems to give priority to specific entries, like buttons always appear at the front, even if you code them behind a background element.