using System; using System.Collections.Generic; using System.Linq; using GTANetworkAPI; public static class AttachmentSync { /// /// Adds/Removes an attachment for an entity /// /// The entity to attach the object to /// The attachment, should be in string or long type /// Pass true to remove the specified attachment, false otherwise. public static void AddAttachment(this Entity entity, dynamic attachment, bool remove) { if (!entity.HasData("Attachments")) entity.SetData("Attachments", new List()); List currentAttachments = entity.GetData>("Attachments"); uint attachmentHash = 0; if (attachment.GetType() == typeof(string)) attachmentHash = NAPI.Util.GetHashKey(attachment); else attachmentHash = Convert.ToUInt32(attachment); if (attachmentHash == 0) { Console.WriteLine($"Attachment hash couldn't be found for { attachment }"); return; } if (currentAttachments.IndexOf(attachmentHash) == -1) // if current attachment hasn't already been added { if (!remove) // if it needs to be added { currentAttachments.Add(attachmentHash); } } else if (remove) // if it was found and needs to be removed { currentAttachments.Remove(attachmentHash); } // send updated data to playerside entity.SetSharedData("attachmentsData", currentAttachments.Serialize()); } /// /// Returns true if an entity has a certain attachment /// /// The entity to check /// The attachment to look for /// True if attachment was found, false otherwise public static bool HasAttachment(this Entity entity, dynamic attachment) { if (!entity.HasData("Attachments")) return false; List currentAttachments = entity.GetData>("Attachments"); uint attachmentHash = 0; if (attachment.GetType() == typeof(string)) attachmentHash = NAPI.Util.GetHashKey(attachment); else attachmentHash = Convert.ToUInt32(attachment); if (attachmentHash == 0) { Console.WriteLine($"Attachment hash couldn't be found for { attachment }"); return false; } return currentAttachments.IndexOf(attachmentHash) != -1; } /// /// Clears the entity's current attachments /// /// The entity to clear the attachments of public static void ClearAttachments(this Entity entity) { if (!entity.HasData("Attachments")) return; List currentAttachments = entity.GetData>("Attachments"); if (currentAttachments.Count > 0) { for (int i = currentAttachments.Count - 1; i >= 0; i--) { entity.AddAttachment(currentAttachments[i], true); } } entity.SetData("Attachments", new List()); } /// /// Serializes a list of attachments /// /// a list of attachments in uint type /// serialized attachment string public static string Serialize(this List attachments) { return string.Join('|', attachments.Select(a => Base36Extensions.ToBase36(a)).ToArray()); } } public class AttachmentSyncExample : Script { //REQUIRED [ServerEvent(Event.PlayerConnected)] public void OnPlayerConnect(Player player) { // reset data on connect player.ClearAttachments(); player.TriggerEvent("SERVER:LoadAttachments"); } //REQUIRED [RemoteEvent("staticAttachments.Add")] private void OnStaticAttachmentAdd(Player player, string hash) { player.AddAttachment(Base36Extensions.FromBase36(hash), false); } //REQUIRED [RemoteEvent("staticAttachments.Remove")] private void OnStaticAttachmentRemove(Player player, string hash) { player.AddAttachment(Base36Extensions.FromBase36(hash), true); } //[Command("xdd")] public void attachment(Player player) { Vehicle veh = player.Vehicle; if (!player.HasAttachment("ammobox")) { player.AddAttachment("ammobox", false); player.PlayAnimation("anim@heists@box_carry@", "idle", 49); //veh.AddAttachment("weapondeal1", false); //veh.AddAttachment("weapondeal2", false); } else { player.StopAnimation(); player.ClearAttachments(); } } }