public static void SendDisplayBoatHS(this NetState ns, Mobile beholder, BaseBoat boat) { if (ns?.HighSeas != true) { return; } var minLength = PacketContainerBuilder.MinPacketLength + OutgoingEntityPackets.MaxWorldEntityPacketLength * 5; // Minimum of boat, hold, planks, and the player using var builder = new PacketContainerBuilder(stackalloc byte[minLength]); Span <byte> buffer = builder.GetSpan(OutgoingEntityPackets.MaxWorldEntityPacketLength); foreach (var entity in boat.GetMovingEntities(true)) { if (!beholder.CanSee(entity)) { continue; } buffer.InitializePacket(); var bytesWritten = OutgoingEntityPackets.CreateWorldEntity(buffer, entity, true); builder.Advance(bytesWritten); } ns.Send(builder.Finalize()); }
public void DockBoat(BaseBoat boat, BaseHouse house) { List <ISpawnable> list = boat.GetMovingEntities(); foreach (ISpawnable o in list) { if (!(o is Item) || o == this || boat.IsComponentItem(o) || o is EffectItem || o == boat.TillerMan) { continue; } Item item = o as Item; if (!item.Deleted && boat.Contains(item)) { if (item is AddonComponent || item is BaseAddon) { BaseAddon addon = item is AddonComponent ? ((AddonComponent)item).Addon : (BaseAddon)item; Item deed = addon.Deed; bool retainDeedHue = false; int hue = 0; if (addon != null && addon.RetainDeedHue) { retainDeedHue = true; for (int j = 0; hue == 0 && j < addon.Components.Count; ++j) { AddonComponent c = addon.Components[j]; if (c.Hue != 0) { hue = c.Hue; } } } if (deed != null) { if (retainDeedHue) { deed.Hue = hue; } house.DropToMovingCrate(deed); } } else { item.Delete(); } } Container cont; if (boat is BaseGalleon) { cont = ((BaseGalleon)boat).GalleonHold; } else { cont = boat.Hold; } if (cont != null) { cont.Items.ForEach(i => { if (i is BaseWeapon) { house.DropToMovingCrate(i); } else { i.Delete(); } }); } } BaseDockedBoat model = boat.BoatItem; if (model == null || model.Deleted) { model = boat.DockedBoat; } if (model == null) { return; } model.BoatItem = boat; if (boat.IsClassicBoat && boat.Owner != null) { boat.RemoveKeys(boat.Owner); } house.DropToMovingCrate(model); boat.OnDryDock(); boat.Refresh(); boat.Internalize(); list.Clear(); list.TrimExcess(); }
public DisplayBoatHS(Mobile beholder, BaseBoat boat) : base(0xF7) { var ents = boat.GetMovingEntities(true); EnsureCapacity(3 + 2 + 5 * 26); Stream.Write((short)0); // count placeholder var count = 0; foreach (var ent in ents) { if (!beholder.CanSee(ent)) { continue; } // Embedded WorldItemHS packets Stream.Write((byte)0xF3); Stream.Write((short)0x1); if (ent is BaseMulti bm) { Stream.Write((byte)0x02); Stream.Write(bm.Serial); // TODO: Mask no longer needed, merge with Item case? Stream.Write((ushort)(bm.ItemID & 0x3FFF)); Stream.Write((byte)0); Stream.Write((short)bm.Amount); Stream.Write((short)bm.Amount); Stream.Write((short)(bm.X & 0x7FFF)); Stream.Write((short)(bm.Y & 0x3FFF)); Stream.Write((sbyte)bm.Z); Stream.Write((byte)bm.Light); Stream.Write((short)bm.Hue); Stream.Write((byte)bm.GetPacketFlags()); } else if (ent is Mobile m) { Stream.Write((byte)0x01); Stream.Write(m.Serial); Stream.Write((short)m.Body); Stream.Write((byte)0); Stream.Write((short)1); Stream.Write((short)1); Stream.Write((short)(m.X & 0x7FFF)); Stream.Write((short)(m.Y & 0x3FFF)); Stream.Write((sbyte)m.Z); Stream.Write((byte)m.Direction); Stream.Write((short)m.Hue); Stream.Write((byte)m.GetPacketFlags(true)); } else if (ent is Item item) { Stream.Write((byte)0x00); Stream.Write(item.Serial); Stream.Write((ushort)(item.ItemID & 0xFFFF)); Stream.Write((byte)0); Stream.Write((short)item.Amount); Stream.Write((short)item.Amount); Stream.Write((short)(item.X & 0x7FFF)); Stream.Write((short)(item.Y & 0x3FFF)); Stream.Write((sbyte)item.Z); Stream.Write((byte)item.Light); Stream.Write((short)item.Hue); Stream.Write((byte)item.GetPacketFlags()); } Stream.Write((short)0x00); ++count; } Stream.Seek(3, SeekOrigin.Begin); Stream.Write((short)count); }