import { IGame, IEntity } from "../game"; export default function attachmentManager(game: IGame) { mp.events.add("SERVER:LoadAttachments", () => { attachmentMngr.register("char_creator_1", "prop_beggers_sign_04", 28422, new mp.Vector3(0, 0, 0), new mp.Vector3(0, 0, 0)); attachmentMngr.register("ammobox", "gr_prop_gr_crate_mag_01a", 28422, new mp.Vector3(0, 0.25, -0.18), new mp.Vector3(0, 0, 90)); attachmentMngr.register("binbag", "prop_cs_rub_binbag_01", 28422, new mp.Vector3(0.08, 0.0, -0.03), new mp.Vector3(270.0, 0.0, 25.0)); attachmentMngr.register("weapondeal", "ex_prop_crate_ammo_bc", "chassis_dummy", new mp.Vector3(0.08, -0.9, -0.2), new mp.Vector3(0, 0, 0)); attachmentMngr.register("weapondeal1", "ex_office_swag_guns02", "chassis_dummy", new mp.Vector3(0, 0.8, 0), new mp.Vector3(0, 0, 0)); attachmentMngr.register("weapondeal2", "w_sg_pumpshotgun", "chassis_dummy", new mp.Vector3(0.4, 1.6, 0.62), new mp.Vector3(90, 0, 180)); }); const attachmentMngr = { attachments: {}, addFor: async function (entity, id) { if (this.attachments.hasOwnProperty(id)) { if (!entity.__attachmentObjects) { entity.__attachmentObjects = {}; } if (!entity.__attachmentObjects.hasOwnProperty(id)) { let attInfo = this.attachments[id]; let object = mp.objects.new(attInfo.model, entity.position); object.__attMgrData = { targetEntity: entity.handle, bone: (typeof (attInfo.boneName) === 'string') ? entity.getBoneIndexByName(attInfo.boneName) : entity.getBoneIndex(attInfo.boneName), offset: attInfo.offset, rotation: attInfo.rotation }; object.notifyStreaming = true; entity.__attachmentObjects[id] = object; } } else { mp.game.graphics.notify(`Static Attachments Error: ~r~Unknown Attachment Used: ~w~0x${id.toString(16)}`); } }, removeFor: function (entity, id) { if (entity.__attachmentObjects.hasOwnProperty(id)) { let obj = entity.__attachmentObjects[id]; delete entity.__attachmentObjects[id]; if (mp.objects.exists(obj)) { obj.destroy(); } } }, initFor: function (entity) { for (let attachment of entity.__attachments) { attachmentMngr.addFor(entity, attachment); } }, shutdownFor: function (entity) { for (let attachment in entity.__attachmentObjects) { attachmentMngr.removeFor(entity, attachment); } }, register: function (id, model, boneName, offset, rotation) { if (typeof (id) === 'string') { id = mp.game.joaat(id); } if (typeof (model) === 'string') { model = mp.game.joaat(model); } if (!this.attachments.hasOwnProperty(id)) { if (mp.game.streaming.isModelInCdimage(model)) { this.attachments[id] = { id: id, model: model, offset: offset, rotation: rotation, boneName: boneName }; } else { mp.game.graphics.notify(`Static Attachments Error: ~r~Invalid Model (0x${model.toString(16)})`); } } else { mp.game.graphics.notify("Static Attachments Error: ~r~Duplicate Entry"); } }, unregister: function (id) { if (typeof (id) === 'string') { id = mp.game.joaat(id); } if (this.attachments.hasOwnProperty(id)) { this.attachments[id] = undefined; } }, addLocal: function (attachmentName) { if (typeof (attachmentName) === 'string') { attachmentName = mp.game.joaat(attachmentName); } let entity = mp.players.local; if (!entity.__attachments || entity.__attachments.indexOf(attachmentName) === -1) { mp.events.callRemote("staticAttachments.Add", attachmentName.toString(36)); } }, removeLocal: function (attachmentName) { if (typeof (attachmentName) === 'string') { attachmentName = mp.game.joaat(attachmentName); } let entity = mp.players.local; if (entity.__attachments && entity.__attachments.indexOf(attachmentName) !== -1) { mp.events.callRemote("staticAttachments.Remove", attachmentName.toString(36)); } }, getAttachments: function () { return Object.assign({}, this.attachments); } }; mp.events.add("entityStreamIn", (entity) => { if (entity.__attMgrData) { const { targetEntity, bone, offset, rotation } = entity.__attMgrData; entity.attachTo( targetEntity, bone, offset.x, offset.y, offset.z, rotation.x, rotation.y, rotation.z, false, false, false, false, 2, true ); } if (entity.__attachments) { attachmentMngr.initFor(entity); } }); mp.events.add("entityStreamOut", (entity) => { if (entity.__attachmentObjects) { attachmentMngr.shutdownFor(entity); } }); mp.events.addDataHandler("attachmentsData", (entity, data) => { let newAttachments = (data.length > 0) ? data.split('|').map(att => parseInt(att, 36)) : []; if (entity.handle !== 0) { let oldAttachments = entity.__attachments; if (!oldAttachments) { oldAttachments = []; entity.__attachmentObjects = {}; } // process outdated first for (let attachment of oldAttachments) { if (newAttachments.indexOf(attachment) === -1) { attachmentMngr.removeFor(entity, attachment); } } // then new attachments for (let attachment of newAttachments) { if (oldAttachments.indexOf(attachment) === -1) { attachmentMngr.addFor(entity, attachment); } } } entity.__attachments = newAttachments; }); function InitAttachmentsOnJoin() { mp.players.forEach(_player => { let data = _player.getVariable("attachmentsData"); if (data && data.length > 0) { let atts = data.split('|').map(att => parseInt(att, 36)); _player.__attachments = atts; _player.__attachmentObjects = {}; } }); } mp.events.add("playerReady", () => { InitAttachmentsOnJoin(); }); }