using Barotrauma.Networking; using System; namespace Barotrauma.Items.Components { partial class Projectile : ItemComponent { private readonly struct EventData : IEventData { public readonly bool Launch; public readonly byte SpreadCounter; public EventData(bool launch, byte spreadCounter = 0) { Launch = launch; SpreadCounter = spreadCounter; } } private float launchRot; public override bool ValidateEventData(NetEntityEvent.IData data) => TryExtractEventData(data, out _); public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null) { var eventData = ExtractEventData(extraData); bool launch = eventData.Launch; msg.WriteBoolean(launch); if (launch) { msg.WriteUInt16(User?.ID ?? Entity.NullEntityID); msg.WriteSingle(launchPos.X); msg.WriteSingle(launchPos.Y); msg.WriteSingle(launchRot); msg.WriteByte(eventData.SpreadCounter); msg.WriteUInt16(LaunchSub?.ID ?? Entity.NullEntityID); } bool stuck = StickTarget != null && !item.Removed && !StickTargetRemoved(); msg.WriteBoolean(stuck); if (stuck) { msg.WriteUInt16(item.Submarine?.ID ?? Entity.NullEntityID); msg.WriteUInt16(item.CurrentHull?.ID ?? Entity.NullEntityID); msg.WriteSingle(item.SimPosition.X); msg.WriteSingle(item.SimPosition.Y); msg.WriteSingle(jointAxis.X); msg.WriteSingle(jointAxis.Y); if (StickTarget.UserData is Structure structure) { msg.WriteByte((byte)StickTargetType.Structure); msg.WriteUInt16(structure.ID); int bodyIndex = structure.Bodies.IndexOf(StickTarget); msg.WriteByte((byte)(bodyIndex == -1 ? 0 : bodyIndex)); } else if (StickTarget.UserData is Item item) { msg.WriteByte((byte)StickTargetType.Item); msg.WriteUInt16(item.ID); } else if (StickTarget.UserData is Submarine sub) { msg.WriteByte((byte)StickTargetType.Submarine); msg.WriteUInt16(sub.ID); } else if (StickTarget.UserData is Limb limb) { msg.WriteByte((byte)StickTargetType.Limb); msg.WriteUInt16(limb.character.ID); msg.WriteByte((byte)Array.IndexOf(limb.character.AnimController.Limbs, limb)); } else if (StickTarget.UserData is Voronoi2.VoronoiCell cell) { msg.WriteByte((byte)StickTargetType.LevelWall); msg.WriteInt32(Level.Loaded.GetAllCells().IndexOf(cell)); } else { msg.WriteByte((byte)StickTargetType.Unknown); throw new NotImplementedException(StickTarget.UserData?.ToString() ?? "null" + " is not a valid projectile stick target."); } } } } }