--#region Variables local PlayerData = {} local PlayerInfo = {} local inInventory = false local currentWeapon = nil local currentOtherInventory = nil local Drops = {} local CurrentDrop = nil local DropsNear = {} local CurrentVehicle = nil local CurrentGlovebox = nil local CurrentStash = nil local isCrafting = false local isHotbar = false local dropType = nil local testPed = nil local controlller = false local ItemsList = {} local inv = {} giveId = 0 varUniqId = nil varDropId = nil varDropItem = nil xValue = 0.0 lastDropItem = nil counter = 0 nearbyPlayers = {} playerDamage = {} dropItem = nil --#endregion Variables --#region Functions ---Checks if you have an item or not ---@param items string | string[] | table The items to check, either a string, array of strings or a key-value table of a string and number with the string representing the name of the item and the number representing the amount ---@param amount? number The amount of the item to check for, this will only have effect when items is a string or an array of strings ---@return boolean success Returns true if the player has the item local function HasItem(items, amount) local isTable = type(items) == 'table' local isArray = isTable and table.type(items) == 'array' or false local totalItems = #items local count = 0 local kvIndex = 2 if isTable and not isArray then totalItems = 0 for _ in pairs(items) do totalItems += 1 end kvIndex = 1 end for _, itemData in pairs(inv) do if isTable then for k, v in pairs(items) do local itemKV = { k, v } if itemData and itemData.name == itemKV[kvIndex] and ((amount and itemData.amount >= amount) or (not isArray and itemData.amount >= v) or (not amount and isArray)) then count += 1 end end if count == totalItems then return true end else -- Single item as string if itemData and itemData.name == items and (not amount or (itemData and amount and itemData.amount >= amount)) then return true end end end return false end exports('HasItem', HasItem) ---Gets the closest vending machine object to the client ---@return integer closestVendingMachine local function GetClosestVending() local ped = PlayerPedId() local pos = GetEntityCoords(ped) local object = nil for _, machine in pairs(Config.VendingObjects) do local ClosestObject = GetClosestObjectOfType(pos.x, pos.y, pos.z, 0.75, joaat(machine), false, false, false) if ClosestObject ~= 0 then if object == nil then object = ClosestObject end end end return object end ---Opens the vending machine shop local function OpenVending() local ShopItems = {} ShopItems.label = 'Vending Machine' ShopItems.items = Config.VendingItem ShopItems.slots = #Config.VendingItem TriggerServerEvent('inventory:server:OpenInventory', 'shop', 'Vendingshop_' .. math.random(1, 99), ShopItems) end ---Draws 3d text in the world on the given position ---@param x number The x coord of the text to draw ---@param y number The y coord of the text to draw ---@param z number The z coord of the text to draw ---@param text string The text to display local function DrawText3Ds(x, y, z, text) SetTextScale(0.35, 0.35) if GetConvar('qb_locale', 'en') == 'en' then SetTextFont(4) else SetTextFont(1) end SetTextProportional(1) SetTextColour(255, 255, 255, 215) SetTextEntry('STRING') SetTextCentre(true) AddTextComponentString(text) SetDrawOrigin(x, y, z, 0) DrawText(0.0, 0.0) local factor = string.len(text) / 370 DrawRect(0.0, 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75) ClearDrawOrigin() end ---Load an animation dictionary before playing an animation from it ---@param dict string Animation dictionary to load local function LoadAnimDict(dict) if HasAnimDictLoaded(dict) then return end RequestAnimDict(dict) while not HasAnimDictLoaded(dict) do Wait(10) end end ---Returns a formatted attachments table from item data ---@param itemdata table Data of an item ---@return table attachments local function FormatWeaponAttachments(itemdata) if not itemdata.info or not itemdata.info.attachments or #itemdata.info.attachments == 0 then return {} end local attachments = {} local weaponName = itemdata.name local WeaponAttachments = exports['qb-weapons']:getConfigWeaponAttachments() if not WeaponAttachments then return {} end for attachmentType, weapons in pairs(WeaponAttachments) do local componentHash = weapons[weaponName] if componentHash then for _, attachmentData in pairs(itemdata.info.attachments) do if attachmentData.component == componentHash then local label = SharedItemsClient(attachmentType) and SharedItemsClient(attachmentType).label or 'Unknown' attachments[#attachments + 1] = { attachment = attachmentType, label = label } end end end end return attachments end ---Checks if the vehicle's engine is at the back or not ---@param vehModel integer The model hash of the vehicle ---@return boolean isBackEngine local function IsBackEngine(vehModel) return BackEngineVehicles[vehModel] end ---Opens the trunk of the closest vehicle local function OpenTrunk() local vehicle = GetClosestVehicle() LoadAnimDict('amb@prop_human_bum_bin@idle_b') TaskPlayAnim(PlayerPedId(), 'amb@prop_human_bum_bin@idle_b', 'idle_d', 4.0, 4.0, -1, 50, 0, false, false, false) if IsBackEngine(GetEntityModel(vehicle)) then SetVehicleDoorOpen(vehicle, 4, false, false) else SetVehicleDoorOpen(vehicle, 5, false, false) end end ---Closes the trunk of the closest vehicle local function CloseTrunk() local vehicle = GetClosestVehicle() LoadAnimDict('amb@prop_human_bum_bin@idle_b') TaskPlayAnim(PlayerPedId(), 'amb@prop_human_bum_bin@idle_b', 'exit', 4.0, 4.0, -1, 50, 0, false, false, false) if IsBackEngine(GetEntityModel(vehicle)) then SetVehicleDoorShut(vehicle, 4, false) else SetVehicleDoorShut(vehicle, 5, false) end end ---Checks weight and size of the vehicle trunk local function GetTrunkSize(vehicleClass) local trunkSize = Config.TrunkSpace[vehicleClass] or Config.TrunkSpace['default'] return trunkSize[vehicleClass].maxweight, trunkSize[vehicleClass].slots end exports('GetTrunkSize', GetTrunkSize) ---Closes the inventory NUI local function closeInventory() SendNUIMessage({ action = 'close', }) end ---Toggles the hotbar of the inventory ---@param toggle boolean If this is true, the hotbar will open local function ToggleHotbar(toggle,inv) local HotbarItems = { [1] = inv[1], [2] = inv[2], [3] = inv[3], [4] = inv[4], [5] = inv[5], -- [41] = inv[41], } SendNUIMessage({ action = 'toggleHotbar', open = toggle, items = HotbarItems }) end ---Plays the opening animation of the inventory local function openAnim() LoadAnimDict('pickup_object') TaskPlayAnim(PlayerPedId(), 'pickup_object', 'putdown_low', 5.0, 1.5, 1.0, 48, 0.0, 0, 0, 0) end local function ItemsToItemInfo() local items = {} for i = 1, #Config.CraftingItems do local craftingItem = Config.CraftingItems[i] local itemInfo = SharedItemsClient(craftingItem.name:lower()) if itemInfo then local itemCost = {} for material, amount in pairs(craftingItem.costs) do local materialInfo = SharedItemsClient(material:lower()) if materialInfo then itemCost[#itemCost + 1] = materialInfo.label .. ': ' .. amount .. 'x' end end local itemCostString = table.concat(itemCost, ', ') items[i] = { name = itemInfo.name, amount = tonumber(craftingItem.amount), info = { costs = itemCostString }, label = itemInfo.label, description = itemInfo.description or '', weight = itemInfo.weight, type = itemInfo.type, unique = itemInfo.unique, useable = itemInfo.useable, image = itemInfo.image, slot = i, costs = craftingItem.costs, threshold = craftingItem.threshold, points = craftingItem.points, } end end Config.CraftingItems = items end local function SetupAttachmentItemsInfo() local items = {} for i = 1, #Config.AttachmentCrafting do local attachmentItem = Config.AttachmentCrafting[i] local itemInfo = SharedItemsClient(attachmentItem.name:lower()) if itemInfo then local itemCost = {} for material, amount in pairs(attachmentItem.costs) do local materialInfo = SharedItemsClient(material:lower()) if materialInfo then itemCost[#itemCost + 1] = materialInfo.label .. ': ' .. amount .. 'x' end end local itemCostString = table.concat(itemCost, ', ') items[i] = { name = itemInfo.name, amount = tonumber(attachmentItem.amount), info = { costs = itemCostString }, label = itemInfo.label, description = itemInfo.description or '', weight = itemInfo.weight, type = itemInfo.type, unique = itemInfo.unique, useable = itemInfo.useable, image = itemInfo.image, slot = i, costs = attachmentItem.costs, threshold = attachmentItem.threshold, points = attachmentItem.points, } end end Config.AttachmentCrafting = items end ---Runs ItemsToItemInfo() and checks if the client has enough reputation to support the threshold, otherwise the items is not available to craft for the client ---@return table items local function GetThresholdItems() ItemsToItemInfo() local items = {} for i = 1, #Config.CraftingItems do if PlayerData.metadata['craftingrep'] >= Config.CraftingItems[i].threshold then items[i] = Config.CraftingItems[i] end end return items end ---Runs SetupAttachmentItemsInfo() and checks if the client has enough reputation to support the threshold, otherwise the items is not available to craft for the client ---@return table items local function GetAttachmentThresholdItems() SetupAttachmentItemsInfo() local items = {} for i = 1, #Config.AttachmentCrafting do -- if PlayerData.metadata['attachmentcraftingrep'] >= Config.AttachmentCrafting[i].threshold then items[i] = Config.AttachmentCrafting[i] -- end end return items end ---Removes drops in the area of the client ---@param index integer The drop id to remove local function RemoveNearbyDrop(index) if not DropsNear[index] then return end local dropItem = DropsNear[index].object if DoesEntityExist(dropItem) then TriggerServerEvent('realboss:removeSyncDrop', index ) -- closeInventory() DeleteEntity(dropItem) end DropsNear[index] = nil if not Drops[index] then return end Drops[index].object = nil Drops[index].isDropShowing = nil end ---Removes all drops in the area of the client local function RemoveAllNearbyDrops() for k in pairs(DropsNear) do RemoveNearbyDrop(k) end end ---@return integer local function CreateDropId() if Drops then local id = math.random(10000, 99999) local dropid = id while Drops[dropid] do id = math.random(10000, 99999) dropid = id end return dropid else local id = math.random(10000, 99999) local dropid = id return dropid end end createObjectName = nil createItemName = nil local object currentIndex = 0 createItem = false throw = false newCoords = nil ---@param index integer The drop id to save the object in local function CreateItemDrop(index,v,xValue) currentIndex = index closeInventory() if dropType == "down" then local ped = PlayerPedId() myCoords = GetEntityCoords(ped) dropItem = CreateObject(Config.ItemDropObject, myCoords.x-0.5, myCoords.y+xValue, myCoords.z, true, false, false) DropsNear[currentIndex].object = dropItem DropsNear[currentIndex].isDropShowing = true PlaceObjectOnGroundProperly(dropItem) FreezeEntityPosition(dropItem, true) TriggerServerEvent('realboss:syncDropItem', currentIndex,dropItem ) TriggerServerEvent('realboss:syncDrop', currentIndex , "Pickup", vector3(myCoords.x-0.5, myCoords.y+xValue, myCoords.z)) end end RegisterNetEvent('realboss:addDropItem') AddEventHandler('realboss:addDropItem', function(currentIndex,dropItem,adcoords) Drops[currentIndex] = { id = currentIndex, coords = { x = adcoords.x, y = adcoords.y, z = adcoords.z, } } -- dropItem end) local function RotationToDirection( rotation ) local adjustedRotation = { x = (math.pi / 180) * rotation.x, y = (math.pi / 180) * rotation.y, z = (math.pi / 180) * rotation.z } local direction = { x = -math.sin(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), y = math.cos(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), z = math.sin(adjustedRotation.x) } return direction end local function RayCastGamePlayCamera( distance ) local cameraRotation = GetGameplayCamRot() local cameraCoord = GetGameplayCamCoord() local direction = RotationToDirection(cameraRotation) local destination = { x = cameraCoord.x + direction.x * distance, y = cameraCoord.y + direction.y * distance, z = cameraCoord.z + direction.z * distance } local a, b, c, d, e = GetShapeTestResult(StartShapeTestRay(cameraCoord.x, cameraCoord.y, cameraCoord.z, destination.x, destination.y, destination.z, -1, PlayerPedId(), 0)) return c, e end local function up( object, offset ) DisableControlAction(0, 27, true) if IsDisabledControlPressed(0, 27) then -- arrow up local delta = 0.05 DisableControlAction(0, 36, true) if IsDisabledControlPressed(0, 36) then -- ctrl held down delta = 0.10 end local object_coords = GetEntityCoords(object) if objectDistance then SetEntityCoords(object, object_coords.x + offset.x, object_coords.y + offset.y, object_coords.z + offset.z + delta) end end end local function down( object, offset ) DisableControlAction(0, 173, true) if IsDisabledControlPressed(0, 173) then -- arrow up local delta = 0.05 DisableControlAction(0, 36, true) if IsDisabledControlPressed(0, 36) then -- ctrl held down delta = 0.10 end local object_coords = GetEntityCoords(object) if objectDistance then SetEntityCoords(object, object_coords.x + offset.x, object_coords.y + offset.y, object_coords.z + offset.z - delta) end end end local function left( object, offset, xy ) DisableControlAction(0, 174, true) if IsDisabledControlPressed(0, 174) then -- arrow up local delta = 0.05 DisableControlAction(0, 36, true) if IsDisabledControlPressed(0, 36) then -- ctrl held down delta = 0.10 end local object_coords = GetEntityCoords(object) if objectDistance then if xy == "x" then SetEntityCoords(object, object_coords.x + offset.x + delta, object_coords.y + offset.y, object_coords.z + offset.z) else SetEntityCoords(object, object_coords.x + offset.x, object_coords.y + offset.y + delta, object_coords.z + offset.z) end end end end local function right( object, offset, xy ) DisableControlAction(0, 175, true) if IsDisabledControlPressed(0, 175) then -- arrow up local delta = 0.05 DisableControlAction(0, 36, true) if IsDisabledControlPressed(0, 36) then -- ctrl held down delta = 0.10 end local object_coords = GetEntityCoords(object) if objectDistance then if xy == "x" then SetEntityCoords(object, object_coords.x + offset.x - delta, object_coords.y + offset.y, object_coords.z + offset.z) else SetEntityCoords(object, object_coords.x + offset.x, object_coords.y + offset.y - delta, object_coords.z + offset.z) end end end end Citizen.CreateThread(function() while true do Citizen.Wait(0) if IsControlPressed(0, Config.HealthOpenKey) then SendNUIMessage({ action = 'health', playerDamage = playerDamage, }) SetNuiFocus(true, true) end end end) bossDropItem = nil textTable = {} RegisterNetEvent('realboss:removetext') AddEventHandler('realboss:removetext', function(id) exports['nc-textui-2']:delete3DTextUI(id) for i = 1, #textTable do if textTable[i].id == id then DeleteEntity(textTable[i].dropItem) table.remove(textTable, i) break end end end) RegisterNetEvent('realboss:addtext') AddEventHandler('realboss:addtext', function(id,syncId , dropItem , text, coords) table.insert(textTable, {id = id, dropItem = dropItem,syncId = syncId}) exports['nc-textui-2']:create3DTextUI(id, { coords = vector3(coords.x, coords.y, coords.z), displayDist = 2.0, interactDist = 1.2, enableKeyClick = true, -- If true when you near it and click key it will trigger the event that you write inside triggerData keyNum = 38, key = "E", text = text, theme = "green", -- or red triggerData = { isServer = true, triggerName = "realboss:addItem", args = {type = 'drop' , index = syncId , textIndex = id} }, }) end) local objectDistance = false function ChooseSpawnLocation(model, offset, index,dropId) local plyped = PlayerPedId() local pedCoord = GetEntityCoords(plyped) local object_placed = false local xy = "x" local maxDistance = Config.MaxDistance -- Karakterden maksimum uzaklık TriggerEvent('qb-inventory:deleteText2',giveId,false) object = CreateProp(GetHashKey(model), pedCoord.x + offset.x, pedCoord.y + offset.y, pedCoord.z + offset.z, 1, 0, 0) SetEntityCollision(object, false, false) while true do BlockWeaponWheelThisFrame() local coords, entity = RayCastGamePlayCamera(50.0) if IsControlJustReleased(0, 38) then object_placed = true end if IsControlJustReleased(0, 191) then local ec = GetEntityCoords(object) local w = GetEntityHeading(object) PlaceObjectOnGroundProperly(object) FreezeEntityPosition(object, true) DeleteEntity(object) newObject = CreateProp(GetHashKey(model), ec.x - offset.x, ec.y - offset.y, ec.z - offset.z + 0.001, 1, 0, 0) FreezeEntityPosition(newObject, true) SetEntityCollision(newObject, true, true) newCoords = vector3(ec.x - offset.x, ec.y - offset.y, ec.z - offset.z + 0.1) local forward = GetEntityForwardVector(GetPlayerPed(GetPlayerFromServerId(player))) local x, y, z = table.unpack(newCoords + forward * 0.5) Drops[lastDropItem] = { id = lastDropItem, coords = { x = x, y = y, z = z - 0.3, }, } TriggerServerEvent('realboss:syncDrop', varUniqId , varDropId , newObject , "Pickup", newCoords) TriggerServerEvent('realboss:removeItem', lastDropItem) TriggerEvent('qb-inventory:deleteText2',giveId,true) return vector4(ec.x - offset.x, ec.y - offset.y, ec.z - offset.z, w) end up(object, offset) down(object, offset) right(object, offset, xy) left(object, offset, xy) DisableControlAction(0, 81, true) if IsDisabledControlJustPressed(0, 81) then local head = GetEntityHeading(object) local delta = 7.5 DisableControlAction(0, 36, true) if IsDisabledControlPressed(0, 36) then -- ctrl held down delta = 1.0 end head = head + delta SetEntityHeading(object, head) end DisableControlAction(0, 99, true) if IsDisabledControlJustPressed(0, 99) then local head = GetEntityHeading(object) local delta = 7.5 DisableControlAction(0, 36, true) if IsDisabledControlPressed(0, 36) then -- ctrl held down delta = 1.0 end head = head - delta SetEntityHeading(object, head) end DisableControlAction(0, 200, true) if IsDisabledControlJustPressed(0, 200) then DeleteEntity(object) return "exit" end if IsControlPressed(0, 10) then xy = "x" end if IsControlPressed(0, 11) then xy = "y" end DisableControlAction(0, 36, true) local objectCoords = GetEntityCoords(object) local distanceToPlayer = #(objectCoords - pedCoord) currentPedCoords = GetEntityCoords(PlayerPedId()) if not object_placed and object ~= 0 then if distanceToPlayer <= maxDistance then SetEntityCoords(object, coords.x + offset.x, coords.y + offset.y, coords.z + offset.z) objectDistance = true else objectDistance = false DeleteEntity(object) return "exit" end end Wait(0) FreezeEntityPosition(object,true) end end --#endregion Functions --#region Events RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() LocalPlayer.state:set('inv_busy', false, true) PlayerData = GetPlayerData() TriggerCallback('inventory:server:GetCurrentDrops', function(theDrops) Drops = theDrops end) TriggerServerEvent('qb-inventory:server:loadPlayerInventory') end) RegisterNetEvent('esx:playerLoaded', function() LocalPlayer.state:set('inv_busy', false, true) PlayerData = GetPlayerData() TriggerCallback('inventory:server:GetCurrentDrops', function(theDrops) Drops = theDrops end) TriggerServerEvent('qb-inventory:server:loadPlayerInventory') end) Citizen.CreateThread(function() while true do Citizen.Wait(2500) if NetworkIsPlayerActive(PlayerId()) then PlayerData = GetPlayerData() TriggerCallback('inventory:server:GetCurrentDrops', function(theDrops) Drops = theDrops end) TriggerCallback('qb-inventory:server:GetItemData',function(data) ItemsList = data end) -- TriggerServerEvent('qb-inventory:server:loadPlayerInventory') break end end end) RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() LocalPlayer.state:set('inv_busy', true, true) PlayerData = {} RemoveAllNearbyDrops() end) -- RegisterNetEvent('esx:onPlayerDeath', function(job) -- LocalPlayer.state:set('inv_busy', true, true) -- PlayerData = {} -- RemoveAllNearbyDrops() -- end) -- RegisterNetEvent('QBCore:Client:UpdateObject', function() -- QBCore = exports['qb-core']:GetCoreObject() -- end) -- RegisterNetEvent('ESX.SetPlayerData', function(val) -- PlayerData = val -- end) -- RegisterNetEvent('QBCore:Player:SetPlayerData', function(val) -- PlayerData = val -- end) -- AddEventHandler('onResourceStop', function(name) -- if name ~= GetCurrentResourceName() then return end -- if Config.UseItemDrop then RemoveAllNearbyDrops() end -- end) RegisterNetEvent('qb-inventory:client:closeinv', function() closeInventory() end) RegisterNetEvent('inventory:client:CheckOpenState', function(type, id, label) local name = SplitStr(label, '-')[2] if type == 'stash' then if name ~= CurrentStash or CurrentStash == nil then TriggerServerEvent('inventory:server:SetIsOpenState', false, type, id) end elseif type == 'trunk' then if name ~= CurrentVehicle or CurrentVehicle == nil then TriggerServerEvent('inventory:server:SetIsOpenState', false, type, id) end elseif type == 'glovebox' then if name ~= CurrentGlovebox or CurrentGlovebox == nil then TriggerServerEvent('inventory:server:SetIsOpenState', false, type, id) end elseif type == 'drop' then if name ~= CurrentDrop or CurrentDrop == nil then TriggerServerEvent('inventory:server:SetIsOpenState', false, type, id) end end end) RegisterNetEvent('inventory:client:ItemBox', function(itemData, type,amount) SendNUIMessage({ action = 'itemBox', item = itemData, type = type, amount = amount }) end) RegisterNetEvent('inventory:client:requiredItems', function(items, bool) local itemTable = {} if bool then for k in pairs(items) do itemTable[#itemTable + 1] = { item = items[k].name, label = SharedItemsClient(items[k].name['label']), image = items[k].image, } end end SendNUIMessage({ action = 'requiredItem', items = itemTable, toggle = bool }) end) RegisterNetEvent('inventory:server:RobPlayer', function(TargetId) if Config.MoneyType == "cash" then SendNUIMessage({ action = 'RobMoney', TargetId = TargetId, }) end end) RegisterNUICallback('getWeapons',function(data,cb) local ped = PlayerPedId() for k, v in pairs(Config.WeaponsExtra) do if v.name == "weapon_unarmed" and GetSelectedPedWeapon(ped) == GetHashKey(v.name) then cb(false) return end if GetSelectedPedWeapon(ped) == GetHashKey(v.name) then cb(true) return end end end) RegisterNUICallback('removeMagazine',function(data,cb) TriggerEvent('weapons:client:RemoveWeaponAmmo',data.fromData.info.ammo,data.fromData) end) RegisterNUICallback('weaponreload',function(data,cb) if data.fromData.info.ammo==nil then return end closeInventory() TriggerEvent('weapons:client:AddAmmo',data.fromData.info.ammo,data.fromData) end) RegisterCommand("die",function() local ped = PlayerPedId() SetEntityHealth(ped, 0.0) end) RegisterNetEvent('inventory:client:OpenInventory', function(PlayerAmmo, inventory, other) if not IsEntityDead(PlayerPedId()) then SetNuiFocus(true, true) if other then currentOtherInventory = other.name end filterWeapon = {} for k, v in pairs(SharedItemsClient()) do if v.type == "weapon" then table.insert(filterWeapon, v.label) end end inv = inventory playerData = GetPlayerData() if CoreName == "qb-core" then PlayerInfo = {firstname = playerData.charinfo.firstname, lastname = playerData.charinfo.lastname, cid = playerData.citizenid, phone = playerData.charinfo.phone , vehicle = 0 , source = playerData.source} else PlayerInfo = {firstname = playerData.firstname, lastname = playerData.lastname, cid = playerData.identifier, phone = playerData.phone_number , vehicle = 0 , source = 0} end SendNUIMessage({ action = 'open', inventory = inventory, slots = Config.MaxInventorySlots, other = other, maxweight = Config.MaxInventoryWeight, Ammo = PlayerAmmo, maxammo = Config.MaximumAmmoValues, realboss = Config.NewInventoryItems, firstData = Config.FirstData, weapons = filterWeapon, filter = Config.Filter, weaponsAmmoList = Config.WeaponsAmmo, weaponsAll = Config.WeaponsExtra, magazineList = Config.MagazineMaxAmmo, PlayerInfo = PlayerInfo, }) inInventory = true end end) RegisterNetEvent('inventory:client:UpdatePlayerInventory', function(isError) SendNUIMessage({ action = 'update', inventory = PlayerData.items, maxweight = Config.MaxInventoryWeight, slots = Config.MaxInventorySlots, error = isError, }) end) RegisterNetEvent('inventory:client:CraftItems', function(itemName, itemCosts, amount, toSlot, points) local ped = PlayerPedId() SendNUIMessage({ action = 'close', }) isCrafting = true Progressbar('repair_vehicle', Lang:t('progress.crafting'), (math.random(2000, 5000) * amount), false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = 'mini@repair', anim = 'fixing_a_player', flags = 16, }, {}, {}, function() -- Done StopAnimTask(ped, 'mini@repair', 'fixing_a_player', 1.0) TriggerServerEvent('inventory:server:CraftItems', itemName, itemCosts, amount, toSlot, points) TriggerEvent('inventory:client:ItemBox', SharedItemsClient(itemName), 'add') isCrafting = false end, function() -- Cancel StopAnimTask(ped, 'mini@repair', 'fixing_a_player', 1.0) Notify(Lang:t('notify.failed'), 'error') isCrafting = false end) end) RegisterNetEvent('inventory:client:CraftAttachment', function(itemName, itemCosts, amount, toSlot, points) local ped = PlayerPedId() SendNUIMessage({ action = 'close', }) isCrafting = true Progressbar('repair_vehicle', Lang:t('progress.crafting'), (math.random(2000, 5000) * amount), false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = 'mini@repair', anim = 'fixing_a_player', flags = 16, }, {}, {}, function() -- Done StopAnimTask(ped, 'mini@repair', 'fixing_a_player', 1.0) TriggerServerEvent('inventory:server:CraftAttachment', itemName, itemCosts, amount, toSlot, points) TriggerEvent('inventory:client:ItemBox', SharedItemsClient(itemName), 'add') isCrafting = false end, function() -- Cancel StopAnimTask(ped, 'mini@repair', 'fixing_a_player', 1.0) Notify(Lang:t('notify.failed'), 'error') isCrafting = false end) end) RegisterNetEvent('inventory:client:PickupSnowballs', function() local ped = PlayerPedId() LoadAnimDict('anim@mp_snowball') TaskPlayAnim(ped, 'anim@mp_snowball', 'pickup_snowball', 3.0, 3.0, -1, 0, 1, 0, 0, 0) Progressbar('pickupsnowball', Lang:t('progress.snowballs'), 1500, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, {}, {}, {}, function() -- Done ClearPedTasks(ped) TriggerServerEvent('inventory:server:snowball', 'add') TriggerEvent('inventory:client:ItemBox', SharedItemsClient('snowball'), 'add') end, function() -- Cancel ClearPedTasks(ped) Notify(Lang:t('notify.canceled'), 'error') end) end) RegisterNetEvent('inventory:client:UseWeapon', function(weaponData, shootbool) local ped = PlayerPedId() local weaponName = tostring(weaponData.name) local weaponHash = joaat(weaponData.name) if currentWeapon == weaponName then TriggerEvent('weapons:client:DrawWeapon', nil) SetCurrentPedWeapon(ped, `WEAPON_UNARMED`, true) RemoveAllPedWeapons(ped, true) TriggerEvent('weapons:client:SetCurrentWeapon', nil, shootbool) currentWeapon = nil elseif weaponName == 'weapon_stickybomb' or weaponName == 'weapon_pipebomb' or weaponName == 'weapon_smokegrenade' or weaponName == 'weapon_flare' or weaponName == 'weapon_proxmine' or weaponName == 'weapon_ball' or weaponName == 'weapon_molotov' or weaponName == 'weapon_grenade' or weaponName == 'weapon_bzgas' then TriggerEvent('weapons:client:DrawWeapon', weaponName) GiveWeaponToPed(ped, weaponHash, 1, false, false) SetPedAmmo(ped, weaponHash, 1) SetCurrentPedWeapon(ped, weaponHash, true) TriggerEvent('weapons:client:SetCurrentWeapon', weaponData, shootbool) currentWeapon = weaponName elseif weaponName == 'weapon_snowball' then TriggerEvent('weapons:client:DrawWeapon', weaponName) GiveWeaponToPed(ped, weaponHash, 10, false, false) SetPedAmmo(ped, weaponHash, 10) SetCurrentPedWeapon(ped, weaponHash, true) TriggerServerEvent('inventory:server:snowball', 'remove') TriggerEvent('weapons:client:SetCurrentWeapon', weaponData, shootbool) currentWeapon = weaponName else TriggerEvent('weapons:client:DrawWeapon', weaponName) TriggerEvent('weapons:client:SetCurrentWeapon', weaponData, shootbool) local ammo = tonumber(weaponData.info.ammo) or 0 if weaponName == 'weapon_petrolcan' or weaponName == 'weapon_fireextinguisher' then ammo = 4000 end GiveWeaponToPed(ped, weaponHash, ammo, false, false) SetPedAmmo(ped, weaponHash, ammo) SetCurrentPedWeapon(ped, weaponHash, true) if weaponData.info.attachments then for _, attachment in pairs(weaponData.info.attachments) do GiveWeaponComponentToPed(ped, weaponHash, joaat(attachment.component)) end end if weaponData.info.tint then SetPedWeaponTintIndex(ped, weaponHash, weaponData.info.tint) end currentWeapon = weaponName end end) RegisterNetEvent('inventory:client:CheckWeapon', function(weaponName) if currentWeapon ~= weaponName:lower() then return end local ped = PlayerPedId() TriggerEvent('weapons:ResetHolster') SetCurrentPedWeapon(ped, `WEAPON_UNARMED`, true) RemoveAllPedWeapons(ped, true) currentWeapon = nil end) function GetAllObjects() local objects = {} for object in EnumerateObjects() do table.insert(objects, object) end return objects end function GetItemProp(item) for k, v in pairs(Config.DropItems) do if k == item then return v end end end -- This needs to be changed to do a raycast so items arent placed in walls RegisterNetEvent('inventory:client:AddDropItem', function(dropId, player, coords, realboss, specialId, itemName, itemAmount) uniqId = specialId lastDropItem = dropId if dropType == "down" then local randomRange = 1.0 local ped = GetPlayerPed(GetPlayerFromServerId(player)) local forward = GetEntityForwardVector(ped) local baseX, baseY, baseZ = table.unpack(coords + forward * 0.5) local randomX = math.random() * randomRange * (math.random() < 0.5 and -1 or 1) local randomY = math.random() * randomRange * (math.random() < 0.5 and -1 or 1) local adjustedCoords = vector3(baseX + randomX, baseY + randomY, baseZ - 0.3) Drops[dropId] = { id = dropId, coords = { x = adjustedCoords.x, y = adjustedCoords.y, z = adjustedCoords.z, } } dropItem = CreateObject(Config.ItemDropObject, adjustedCoords.x, adjustedCoords.y, adjustedCoords.z, true, false, false) PlaceObjectOnGroundProperly(dropItem) FreezeEntityPosition(dropItem, true) myCoords = GetEntityCoords(dropItem) TriggerServerEvent('realboss:syncDropItem', dropId, dropItem,adjustedCoords ) TriggerServerEvent('realboss:syncDrop', uniqId, dropId, dropItem, "Pickup", vector3(myCoords.x, myCoords.y, myCoords.z)) else varDropId = dropId varUniqId = uniqId varDropItem = dropItem end createObjectName = GetItemProp(realboss.name) if createObjectName == nil then createObjectName = Config.ItemDropObject end createItemName = realboss.name local ped = PlayerPedId() if dropType ~= "down" then SendNUIMessage({ action = 'close' }) LoadAnimDict('pickup_object') TaskPlayAnim(ped, 'pickup_object', 'pickup_low', 8.0, -8.0, -1, 1, 0, false, false, false) Wait(2000) ClearPedTasks(ped) if testPed == nil then return end if ped == testPed then if not throw then SendNUIMessage({ action = 'openplace' }) createItem = true dropItem = CreateThrowable(createItemName, true) while createItem do Wait(0) if IsControlJustReleased(0, 306) then throw = true createItem = false DeleteEntity(dropItem) if ChooseSpawnLocation(createObjectName, vector4(0, 0, 0,0),dropId) == "exit" then SendNUIMessage({ action = 'closeplace' }) if dropType ~= "" then TriggerServerEvent('boss:giveitem', itemName, itemAmount) end Notify(Lang:t('notify.distance'), 'error') return else SendNUIMessage({ action = 'closeplace' }) end end if IsControlJustPressed(1, 200) then SendNUIMessage({ action = 'closeplace' }) DeleteEntity(dropItem) TriggerEvent('qb-inventory:deleteText2',giveId,true) if dropType ~= "" then TriggerServerEvent('boss:giveitem', itemName, itemAmount) end createItem = false return end if IsControlJustPressed(1, 51) then TriggerServerEvent('realboss:removeItem', dropId) SendNUIMessage({ action = 'closeplace' }) createItem = false holdingBall = dropItem while holdingBall do throw = true CreateThread(function() PlayAnim(ped, "melee@thrown@streamed_core", "plyr_takedown_front", -8.0, 8.0, -1, 49) Wait(600) ClearPedTasks(ped) end) Wait(550) DetachEntity(dropItem, false, true) SetEntityCollision(dropItem, true, true) SetEntityRecordsCollisions(dropItem, true) TriggerServerEvent("nc-throwables:throwObject", {throwType = createItemName, net_id = ObjToNet(dropItem)}) local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.0, 1.0) SetEntityCoords(dropItem, coords.x, coords.y, coords.z) SetEntityHeading(dropItem, GetEntityHeading(ped) + 90.0) PerformPhysics(createItemName, dropItem) holdingBall = nil TriggerEvent('qb-inventory:deleteText2',giveId,true) Wait(8000) coords = vector3(GetEntityCoords(dropItem)) TriggerServerEvent('realboss:syncDrop', varUniqId, varDropId, dropItem, "Pickup", vector3(coords.x, coords.y, coords.z)) end return end end end end end TriggerServerEvent('realbossCustomDropSystem:server:throw', createItemName) end) RegisterNetEvent('inventory:client:RemoveDropItem', function(dropId) -- Drops[dropId] = nil if Config.UseItemDrop then RemoveNearbyDrop(dropId) else -- DropsNear[dropId] = nil end end) RegisterNetEvent('inventory:client:DropItemAnim', function() local ped = PlayerPedId() SendNUIMessage({ action = 'close', }) LoadAnimDict('pickup_object') TaskPlayAnim(ped, 'pickup_object', 'pickup_low', 8.0, -8.0, -1, 1, 0, false, false, false) Wait(2000) ClearPedTasks(ped) end) RegisterNetEvent('inventory:client:SetCurrentStash', function(stash) CurrentStash = stash end) RegisterNetEvent('qb-inventory:client:giveAnim', function() if IsPedInAnyVehicle(PlayerPedId(), false) then return else LoadAnimDict('mp_common') TaskPlayAnim(PlayerPedId(), 'mp_common', 'givetake1_b', 8.0, 1.0, -1, 16, 0, 0, 0, 0) end end) RegisterNetEvent('inventory:client:craftTarget', function() local crafting = {} crafting.label = Lang:t('label.craft') crafting.items = GetThresholdItems() TriggerServerEvent('inventory:server:OpenInventory', 'crafting', math.random(1, 99), crafting) end) --#endregion Events --#region Commands RegisterCommand('closeinv', function() closeInventory() end, false) RegisterCommand('inventory', function() if IsNuiFocused() then return end if not isCrafting and not inInventory then if not IsPauseMenuActive() then local ped = PlayerPedId() local curVeh = nil local VendingMachine = nil if not Config.UseTarget then VendingMachine = GetClosestVending() end if IsPedInAnyVehicle(ped, false) then -- Is Player In Vehicle local vehicle = GetVehiclePedIsIn(ped, false) CurrentGlovebox = GetPlate(vehicle) curVeh = vehicle CurrentVehicle = nil else local vehicle = GetClosestVehicle() if vehicle ~= 0 and vehicle ~= nil then local pos = GetEntityCoords(ped) local dimensionMin, dimensionMax = GetModelDimensions(GetEntityModel(vehicle)) local trunkpos = GetOffsetFromEntityInWorldCoords(vehicle, 0.0, (dimensionMin.y), 0.0) if (IsBackEngine(GetEntityModel(vehicle))) then trunkpos = GetOffsetFromEntityInWorldCoords(vehicle, 0.0, (dimensionMax.y), 0.0) end if #(pos - trunkpos) < 1.5 and not IsPedInAnyVehicle(ped) then if GetVehicleDoorLockStatus(vehicle) < 2 then CurrentVehicle = GetPlate(vehicle) curVeh = vehicle CurrentGlovebox = nil else Notify(Lang:t('notify.vlocked'), 'error') return end else CurrentVehicle = nil end else CurrentVehicle = nil end end if CurrentVehicle then -- Trunk local vehicleClass = GetVehicleClass(curVeh) local trunkConfig = Config.TrunkSpace[vehicleClass] or Config.TrunkSpace['default'] if not trunkConfig then return end local slots = trunkConfig.slots local maxweight = trunkConfig.maxWeight if not slots or not maxweight then return end local other = { maxweight = maxweight, slots = slots, } TriggerServerEvent('inventory:server:OpenInventory', 'trunk', CurrentVehicle, other) OpenTrunk() elseif CurrentGlovebox then TriggerServerEvent('inventory:server:OpenInventory', 'glovebox', CurrentGlovebox) elseif CurrentDrop ~= 0 then TriggerServerEvent('inventory:server:OpenInventory', 'drop', CurrentDrop) elseif VendingMachine then local ShopItems = {} ShopItems.label = 'Vending Machine' ShopItems.items = Config.VendingItem ShopItems.slots = #Config.VendingItem TriggerServerEvent('inventory:server:OpenInventory', 'shop', 'Vendingshop_' .. math.random(1, 99), ShopItems) else openAnim() TriggerServerEvent('inventory:server:OpenInventory') end end end end, false) RegisterKeyMapping('inventory', Lang:t('inf_mapping.opn_inv'), 'keyboard', Config.KeyBinds.Inventory) RegisterCommand('hotbar', function() isHotbar = not isHotbar if not IsPauseMenuActive() then TriggerCallback('inventory:server:GetCurrentData', function(data) ToggleHotbar(isHotbar,data) end) end end, false) RegisterKeyMapping('hotbar', Lang:t('inf_mapping.tog_slots'), 'keyboard', Config.KeyBinds.HotBar) for i = 1, 6 do RegisterCommand('slot' .. i, function() if not IsPauseMenuActive() then if i == 6 then i = Config.MaxInventorySlots end TriggerServerEvent('inventory:server:UseItemSlot', i) closeInventory() end end, false) RegisterKeyMapping('slot' .. i, Lang:t('inf_mapping.use_item') .. i, 'keyboard', i) end --#endregion Commands --#region NUI RegisterNUICallback('RobMoney', function(data, cb) TriggerServerEvent('police:server:RobPlayer', data.TargetId) cb('ok') end) RegisterNUICallback('Notify', function(data, cb) Notify(data.message, data.type) cb('ok') end) RegisterNUICallback('GetWeaponData', function(cData, cb) local data = { WeaponData = SharedItemsClient(cData.weapon), AttachmentData = FormatWeaponAttachments(cData.ItemData) } cb(data) end) RegisterNUICallback('RemoveAttachment', function(data, cb) local ped = PlayerPedId() local WeaponData = data.WeaponData local allAttachments = exports['qb-weapons']:getConfigWeaponAttachments() local Attachment = allAttachments[data.AttachmentData.attachment][WeaponData.name] TriggerCallback('weapons:server:RemoveAttachment', function(NewAttachments) if NewAttachments ~= false then local Attachies = {} RemoveWeaponComponentFromPed(ped, joaat(WeaponData.name), joaat(Attachment)) for _, v in pairs(NewAttachments) do for attachmentType, weapons in pairs(allAttachments) do local componentHash = weapons[WeaponData.name] if componentHash and v.component == componentHash then local label = SharedItemsClient(attachmentType) and SharedItemsClient(attachmentType).label or 'Unknown' Attachies[#Attachies + 1] = { attachment = attachmentType, label = label, } end end end local DJATA = { Attachments = Attachies, WeaponData = WeaponData, } cb(DJATA) else RemoveWeaponComponentFromPed(ped, joaat(WeaponData.name), joaat(Attachment)) cb({}) end end, data.AttachmentData, WeaponData) end) RegisterNUICallback('getCombineItem', function(data, cb) cb(SharedItemsClient(data.item)) end) RegisterNUICallback('CloseInventory', function(_, cb) if currentOtherInventory == 'none-inv' then CurrentDrop = nil CurrentVehicle = nil CurrentGlovebox = nil CurrentStash = nil SetNuiFocus(false, false) inInventory = false ClearPedTasks(PlayerPedId()) return end if CurrentVehicle ~= nil then CloseTrunk() TriggerServerEvent('inventory:server:SaveInventory', 'trunk', CurrentVehicle) CurrentVehicle = nil elseif CurrentGlovebox ~= nil then TriggerServerEvent('inventory:server:SaveInventory', 'glovebox', CurrentGlovebox) CurrentGlovebox = nil elseif CurrentStash ~= nil then TriggerServerEvent('inventory:server:SaveInventory', 'stash', CurrentStash) CurrentStash = nil else TriggerServerEvent('inventory:server:SaveInventory', 'drop', CurrentDrop) CurrentDrop = nil end SetNuiFocus(false, false) inInventory = false cb('ok') counter = 0 end) RegisterNUICallback('UseItem', function(data, cb) TriggerServerEvent('inventory:server:UseItem', data.inventory, data.item) cb('ok') end) RegisterNUICallback('combineItem', function(data, cb) Wait(150) TriggerServerEvent('inventory:server:combineItem', data.reward, data.fromItem, data.toItem) cb('ok') end) RegisterNUICallback('combineWithAnim', function(data, cb) local ped = PlayerPedId() local combineData = data.combineData local aDict = combineData.anim.dict local aLib = combineData.anim.lib local animText = combineData.anim.text local animTimeout = combineData.anim.timeOut Progressbar('combine_anim', animText, animTimeout, false, true, { disableMovement = false, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = aDict, anim = aLib, flags = 16, }, {}, {}, function() -- Done StopAnimTask(ped, aDict, aLib, 1.0) TriggerServerEvent('inventory:server:combineItem', combineData.reward, data.requiredItem, data.usedItem) end, function() -- Cancel StopAnimTask(ped, aDict, aLib, 1.0) Notify(Lang:t('notify.failed'), 'error') end) cb('ok') end) local isItemDropped = false RegisterNUICallback('SetInventoryData', function(data, cb) dropType = data.dropType throw = false testPed = PlayerPedId() isItemDropped = true TriggerServerEvent('inventory:server:SetInventoryData', data.fromInventory, data.toInventory, data.fromSlot, data.toSlot, data.fromAmount, data.toAmount, data.setType) cb('ok') end) RegisterNUICallback('PlayDropSound', function(_, cb) PlaySound(-1, 'CLICK_BACK', 'WEB_NAVIGATION_SOUNDS_PHONE', 0, 0, 1) cb('ok') end) RegisterNUICallback('PlayDropFail', function(_, cb) PlaySound(-1, 'Place_Prop_Fail', 'DLC_Dmod_Prop_Editor_Sounds', 0, 0, 1) cb('ok') end) function GetPlayersInArea(coords, maxDistance) return EnumerateEntitiesWithinDistance(GetPlayers(true, true), true, coords, maxDistance) end function EnumerateEntitiesWithinDistance(entities, isPlayerEntities, coords, maxDistance) local nearbyEntities = {} if coords then coords = vector3(coords.x, coords.y, coords.z) else local playerPed = PlayerPedId() coords = GetEntityCoords(playerPed) end for k, v in pairs(entities) do local distance = #(coords - GetEntityCoords(v.entity)) if distance <= maxDistance then nearbyEntities[#nearbyEntities + 1] = v.id end end return nearbyEntities end function GetPlayers(onlyOtherPlayers, returnKeyValue, returnPeds) local players, myPlayer = {}, PlayerId() local active = GetActivePlayers() for i = 1, #active do local currentPlayer = active[i] local ped = GetPlayerPed(currentPlayer) if DoesEntityExist(ped) and ((onlyOtherPlayers and currentPlayer ~= myPlayer) or not onlyOtherPlayers) then if returnKeyValue then players[currentPlayer] = {entity = ped, id = GetPlayerServerId(currentPlayer)} else players[#players + 1] = returnPeds and ped or currentPlayer end end end return players end RegisterNetEvent('qb-inventory:deleteText') AddEventHandler('qb-inventory:deleteText',function(id) DeleteEntity(dropItem) DeleteObject(dropItem) DetachEntity(dropItem, false, true) createItem = false Wait(1000) SendNUIMessage({ action = 'closeplace', }) if next(nearbyPlayers) ~= nil and next(nearbyPlayers) then for _, id in pairs(nearbyPlayers) do exports['nc-textui-2']:delete3DTextUIOnPlayers(id) end end end) RegisterNetEvent('qb-inventory:deleteText2') AddEventHandler('qb-inventory:deleteText2',function(id,b) if b then SendNUIMessage({ action = 'closeplace', }) end if next(nearbyPlayers) ~= nil and next(nearbyPlayers) then for _, id in pairs(nearbyPlayers) do exports['nc-textui-2']:delete3DTextUIOnPlayers(id) end end end) RegisterNUICallback('GiveItem', function(data, cb) closeInventory() SetNuiFocus(false, false) dropType = "" createObjectName = GetItemProp(data.item.name) if createObjectName == nil then createObjectName = Config.ItemDropObject end createItemName = data.item.name local player, distance = GetClosestPlayer(GetEntityCoords(PlayerPedId())) -- if player == nil then return end if player ~= nil then if player ~= -1 and distance < 3 then if data.inventory == 'player' then local playerId = GetPlayerServerId(player) nearbyPlayers = GetPlayersInArea(GetEntityCoords(PlayerPedId()), 5.0) Wait(2000) if next(nearbyPlayers) ~= nil and next(nearbyPlayers) then for _, id in pairs(nearbyPlayers) do giveId = id exports['nc-textui-2']:create3DTextUIOnPlayers(id, { displayDist = 5.0, interactDist = 1.3, id = id, enableKeyClick = true, -- If true when you near it and click key it will trigger the event that you write inside triggerData keyNum = 191, key = "Enter", text = "Give Item", theme = "green", -- or red triggerData = { isServer = true, triggerName = "inventory:server:GiveItem", args = {id = id ,playerId = playerId , name = data.item.name, amount = data.amount, slot = data.item.slot} }, }) end end SetCurrentPedWeapon(PlayerPedId(), 'WEAPON_UNARMED', true) -- TriggerServerEvent('inventory:server:GiveItem', playerId, data.item.name, data.amount, data.item.slot) else Notify(Lang:t('notify.notowned'), 'error') end else Notify(Lang:t('notify.nonb'), 'error') end end cb('ok') end) CreateThread(function() while true do local sleep = 100 if DropsNear ~= nil then local ped = PlayerPedId() local closestDrop = nil local closestDistance = nil local xValue = 0 for k, v in pairs(DropsNear) do if DropsNear[k] ~= nil then if Config.UseItemDrop then if not v.isDropShowing then isItemDropped = false end else sleep = 0 end local coords = (v.object ~= nil and GetEntityCoords(v.object)) or vector3(v.coords.x, v.coords.y, v.coords.z) local distance = #(GetEntityCoords(ped) - coords) if distance < 2 and (not closestDistance or distance < closestDistance) then closestDrop = k closestDistance = distance xValue = xValue + 0.5 end end end if not closestDrop then CurrentDrop = 0 else CurrentDrop = closestDrop end end Wait(sleep) end end) CreateThread(function() while true do if Drops ~= nil and next(Drops) ~= nil then local pos = GetEntityCoords(PlayerPedId(), true) for k, v in pairs(Drops) do if Drops[k] ~= nil then local dist = #(pos - vector3(v.coords.x, v.coords.y, v.coords.z)) if dist < Config.MaxDropViewDistance then DropsNear[k] = v else if Config.UseItemDrop and DropsNear[k] then -- RemoveNearbyDrop(k) else DropsNear[k] = nil end end end end else DropsNear = {} end Wait(500) end end) CreateThread(function() if Config.UseTarget then exports[Config.Interaction.Target]:AddTargetModel(Config.VendingObjects, { options = { { icon = 'fa-solid fa-cash-register', label = Lang:t('menu.vending'), action = function() OpenVending() end }, }, distance = 2.5 }) end end) CreateThread(function() if Config.UseTarget then exports[Config.Interaction.Target]:AddTargetModel(Config.CraftingObject, { options = { { event = 'inventory:client:craftTarget', icon = 'fas fa-tools', label = Lang:t('menu.craft'), }, }, distance = 2.5, }) else while true do local sleep = 1000 if LocalPlayer.state['isLoggedIn'] then local pos = GetEntityCoords(PlayerPedId()) local craftObject = GetClosestObjectOfType(pos, 2.0, Config.CraftingObject, false, false, false) if craftObject ~= 0 then local objectPos = GetEntityCoords(craftObject) if #(pos - objectPos) < 1.5 then sleep = 0 DrawText3Ds(objectPos.x, objectPos.y, objectPos.z + 1.0, Lang:t('interaction.craft')) if IsControlJustReleased(0, 38) then local crafting = {} crafting.label = Lang:t('label.craft') crafting.items = GetThresholdItems() TriggerServerEvent('inventory:server:OpenInventory', 'crafting', math.random(1, 99), crafting) sleep = 100 end end end end Wait(sleep) end end end) CreateThread(function() while true do local sleep = 1000 if LocalPlayer.state['isLoggedIn'] then local pos = GetEntityCoords(PlayerPedId()) local distance = #(pos - Config.AttachmentCraftingLocation) if distance < 10 then if distance < 1.5 then sleep = 0 DrawText3Ds(Config.AttachmentCraftingLocation.x, Config.AttachmentCraftingLocation.y, Config.AttachmentCraftingLocation.z, Lang:t('interaction.craft')) if IsControlJustPressed(0, 38) then local crafting = {} crafting.label = Lang:t('label.a_craft') crafting.items = GetAttachmentThresholdItems() TriggerServerEvent('inventory:server:OpenInventory', 'attachment_crafting', math.random(1, 99), crafting) sleep = 100 end end end end Wait(sleep) end end) AddEventHandler('gameEventTriggered', function(event, data) if Config.ExperimentalFeatures == false then return end local count = 0 if event == 'CEventNetworkEntityDamage' then local victim, attacker, victimDied, weapon = data[1], data[2], data[4], data[7] if not IsEntityAPed(victim) then return end if victimDied and NetworkGetPlayerIndexFromPed(victim) == PlayerId() then local damage = { name = "nd", label = "Not detected!" ,count = 0} local playerid = NetworkGetPlayerIndexFromPed(victim) local killerId = NetworkGetPlayerIndexFromPed(attacker) victimid = NetworkGetPlayerIndexFromPed(victim) victimid = GetPlayerServerId(victimid) local weaponLabel = (Config.WeaponsExtra and Config.WeaponsExtra[weapon] and Config.WeaponsExtra[weapon].label) or 'Unknown' local weaponName = (Config.WeaponsExtra and Config.WeaponsExtra[weapon] and Config.WeaponsExtra[weapon].name) or 'Unknown' local weaponType = (Config.WeaponsExtra and Config.WeaponsExtra[weapon] and Config.WeaponsExtra[weapon].weapontype) or 'Unknown' if weaponName == "weapon_run_over_by_car" or weaponName == "weapon_rammed_by_car" then damage = { name = weaponName, label = weaponLabel ,count += 1} end if weaponName == "weapon_fall" then damage = { name = weaponName, label = weaponLabel.." Damage" ,count += 1 } end if weaponType == "Melee" then damage = { name = "knife", label = "Stabbed with knife" ,count += 1} end if weaponType == "Melee" and weaponName == "weapon_unarmed" then damage = { name = "weapon_unarmed", label = "Punch attack" , count += 1} end if damage.name == "nd" then damage = { name = weaponName, label = weaponLabel ,count += 1} end if damage.name == "nd" then return end local FoundLastDamagedBone, LastDamagedBone = GetPedLastDamageBone(victim) TriggerEvent("boss-damage", victimid, damage, victim, LastDamagedBone) end end end) damageCount = 0 RegisterNetEvent("boss-damage") AddEventHandler("boss-damage", function(victim, damage, victim_ped, LastDamagedBone) playerDamage = damage local alt = Config.GetAlternativeBone(LastDamagedBone) if alt ~= false and damage then damage.bone = alt damageCount += 1 damage.count = damageCount for k,v in pairs(Config.PlayerBones) do if v == alt then Config.FirstData[k].health = Config.FirstData[k].health - Config.FirstData[k].damage Config.FirstData[k].severity = Config.FirstData[k].severity + 1 if Config.FirstData[k].health <= 50 then Config.FirstData[k].health = 0 Config.FirstData[k].broken = true Config.FirstData[k].bleeding = true else Config.FirstData[k].broken = false Config.FirstData[k].bleeding = false end if Config.FirstData[k].severity >= 3 then Config.FirstData[k].broken = true Config.FirstData[k].bleeding = true end end end end end) RegisterNetEvent(Config.ReviveEvent) AddEventHandler(Config.ReviveEvent, function() for k,v in pairs(Config.FirstData) do Config.FirstData[k].health = 100 Config.FirstData[k].severity = 0 Config.FirstData[k].broken = false Config.FirstData[k].bleeding = false damageCount = 0 end end) --güzel anim weapons@pistol@pistol_50_str reload_aim local isPlayingAnim = false local anim = true RegisterCommand("animasyon", function() if not isPlayingAnim then isPlayingAnim = true dict = "weapons@pistol@pistol_50_str" RequestAnimDict(dict) while not HasAnimDictLoaded(dict) do Wait(0) end while anim do Wait(400) TaskPlayAnim(PlayerPedId(), dict, "reload_aim", 8.0, 8.0, -1, 50, 0, false, false, true) end Wait(10000) -- 10 saniye bekleyin isPlayingAnim = false end end) RegisterCommand("ccs",function() ClearPedTasks(PlayerPedId()) anim = false end) local ThrowingPower = 1 local Throwables = {} local canInteract = true local attemptingCatch = false local holdingBall = nil function GetClosestPlayer(coords, radius) local closest local coords = coords or GetEntityCoords(PlayerPedId()) local radius = radius or 2.0 for _, player in ipairs(GetActivePlayers()) do local ped = GetPlayerPed(player) if PlayerPedId() ~= ped then local pedCoords = GetEntityCoords(ped) local distance = #(coords - pedCoords) if distance < radius and (not closest or closest.distance > distance) then closest = {player = player, distance = distance} end end end return closest?.player, closest?.distance end function GetDirectionFromRotation(rotation) local dm = (math.pi / 180) return vector3(-math.sin(dm * rotation.z) * math.abs(math.cos(dm * rotation.x)), math.cos(dm * rotation.z) * math.abs(math.cos(dm * rotation.x)), math.sin(dm * rotation.x)) end function PerformPhysics(throwType, entity, action) local power = (ThrowingPower / 10) * 200 FreezeEntityPosition(entity, false) local rot = GetGameplayCamRot(2) local dir = GetDirectionFromRotation(rot) SetEntityHeading(entity, rot.z + 90.0) if not action or action == "throw" then SetEntityVelocity(entity, dir.x * power, dir.y * power, dir.z * power) else SetEntityVelocity(entity, dir.x * power, dir.y * power, (dir.z * 1.75) * power) end end function CreateThrowable(throwType, attach) local model = Config.ItemDropObject if GetItemProp(throwType) then model = GetItemProp(throwType) end local ped = PlayerPedId() local heading = GetEntityHeading(ped) local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 1.0, 0.5) local prop prop = CreateProp(model, coords.x, coords.y, coords.z, true, true, true) if not prop then return end if attach then local off, rot = vector3(0.05, 0.0, -0.085), vector3(90.0, 90.0, 0.0) AttachEntityToEntity(prop, ped, GetPedBoneIndex(ped, 28422), off.x, off.y, off.z, rot.x, rot.y, rot.z, false, false, false, true, 2, true) else local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 1.0, -0.9) SetEntityCoords(prop, coords.x, coords.y, coords.z) end return prop end function HoldThrowable(throwType) local ped = PlayerPedId() if holdingBall then return end local prop = CreateThrowable(throwType, true) holdingBall = prop CreateThread(function() while holdingBall do local player, dist = GetClosestPlayer() if IsControlJustPressed(1, 51) then CreateThread(function() PlayAnim(ped, "melee@thrown@streamed_core", "plyr_takedown_front", -8.0, 8.0, -1, 49) Wait(600) ClearPedTasks(ped) end) Wait(550) DetachEntity(prop, false, true) SetEntityCollision(prop, true, true) SetEntityRecordsCollisions(prop, true) TriggerServerEvent("nc-throwables:throwObject", {throwType = throwType, net_id = ObjToNet(prop)}) local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.0, 1.0) SetEntityCoords(prop, coords.x, coords.y, coords.z) SetEntityHeading(prop, GetEntityHeading(ped) + 90.0) PerformPhysics(throwType, prop) holdingBall = nil elseif IsControlJustPressed(1, 47) then PlayAnim(ped, "pickup_object", "pickup_low", -8.0, 8.0, -1, 49, 1.0) Wait(800) DetachEntity(prop, true, true) SetEntityCollision(prop, true, true) SetEntityRecordsCollisions(prop, true) ActivatePhysics(prop) TriggerServerEvent("nc-throwables:throwObject", {throwType = throwType, net_id = ObjToNet(prop)}) Wait(800) ClearPedTasks(ped) holdingBall = nil elseif IsControlJustPressed(1, 74) then if player then ServerCallback("nc-throwables:giveObject", function(result) if not result then return end DeleteEntity(prop) holdingBall = nil PlayAnim(PlayerPedId(), "mp_common", "givetake1_b", -8.0, 8.0, -1, 49, 1.0) Wait(1600) ClearPedTasks(ped) end, GetPlayerServerId(player)) else ServerCallback("nc-throwables:storeObject", function(result) if not result then return end PlayAnim(PlayerPedId(), "pickup_object", "putdown_low", -8.0, 8.0, -1, 49, 1.0) Wait(1600) ClearPedTasks(ped) DeleteEntity(prop) holdingBall = nil end) end end PowerControls() Wait(0) end end) end function CatchObject(index, cb) if attemptingCatch then return end attemptingCatch = true local data = Throwables[index] local entity = NetToObj(data.net_id) SetEntityCollision(entity, false, false) DeleteEntity(entity) ServerCallback("nc-throwables:catchObject", cb, index) Wait(100) attemptingCatch = false end function PowerControls() if IsControlJustPressed(1, 181) then ThrowingPower = (ThrowingPower + 1 > 10 and 10 or ThrowingPower + 1) elseif IsControlJustPressed(1, 180) then ThrowingPower = (ThrowingPower - 1 < 1 and 1 or ThrowingPower - 1) end end function deepcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in next, orig, nil do copy[deepcopy(orig_key)] = deepcopy(orig_value) end setmetatable(copy, deepcopy(getmetatable(orig))) else -- number, string, boolean, etc copy = orig end return copy end RegisterNetEvent("nc-throwables:giveObject", function(data) HoldThrowable(data.throwType) end) RegisterNetEvent("nc-throwables:setObjectData", function(throwID, data) Throwables[throwID] = data end) -- AddEventHandler("onResourceStop", function(name) -- if (GetCurrentResourceName() ~= name) then return end -- for k,v in pairs(Throwables) do -- DeleteEntity(NetToObj(v.net_id)) -- end -- end) function ModelRequest(modelHash) if not IsModelInCdimage(modelHash) then return end RequestModel(modelHash) local loaded for i=1, 100 do if HasModelLoaded(modelHash) then loaded = true break end Wait(100) end return loaded end function CreateVeh(modelHash, ...) if not ModelRequest(modelHash) then return end local veh = CreateVehicle(modelHash, ...) SetModelAsNoLongerNeeded(modelHash) return veh end function CreateNPC(modelHash, ...) if not ModelRequest(modelHash) then return end local ped = CreatePed(26, modelHash, ...) SetModelAsNoLongerNeeded(modelHash) return ped end function CreateProp(modelHash, ...) if not ModelRequest(modelHash) then local obj = CreateObject(Config.ItemDropObject, ...) SetModelAsNoLongerNeeded(Config.ItemDropObject) return obj end local obj = CreateObject(modelHash, ...) SetModelAsNoLongerNeeded(modelHash) return obj end function PlayAnim(ped, dict, ...) RequestAnimDict(dict) while not HasAnimDictLoaded(dict) do Wait(0) end TaskPlayAnim(ped, dict, ...) end -- ===== Added: unified close for clean toggle via TAB ===== function CloseInventoryProperly() -- Attempt to gracefully close any open inventory and save it if currentOtherInventory == 'none-inv' then CurrentDrop = nil CurrentVehicle = nil CurrentGlovebox = nil CurrentStash = nil SetNuiFocus(false, false) inInventory = false if ClearPedTasks then ClearPedTasks(PlayerPedId()) end counter = 0 return end if CurrentVehicle ~= nil then if CloseTrunk then CloseTrunk() end TriggerServerEvent('inventory:server:SaveInventory', 'trunk', CurrentVehicle) CurrentVehicle = nil elseif CurrentGlovebox ~= nil then TriggerServerEvent('inventory:server:SaveInventory', 'glovebox', CurrentGlovebox) CurrentGlovebox = nil elseif CurrentStash ~= nil then TriggerServerEvent('inventory:server:SaveInventory', 'stash', CurrentStash) CurrentStash = nil else TriggerServerEvent('inventory:server:SaveInventory', 'drop', CurrentDrop) CurrentDrop = nil end SetNuiFocus(false, false) inInventory = false counter = 0 end -- ===== End Added ===== -- ===== Added: TAB toggle command and key mapping ===== RegisterCommand('inventory_toggle', function() if inInventory then if CloseInventoryProperly then CloseInventoryProperly() else -- fallback: basic close if helper missing SetNuiFocus(false, false) inInventory = false end return end -- Open using the existing logic of your /inventory command if not IsPauseMenuActive() and (not isCrafting) then ExecuteCommand('inventory') end end, false) -- Bind TAB to the toggle (safe description if Lang:t is unavailable) local _desc = "Open/Close Inventory" if Lang and Lang.t then local ok, val = pcall(function() return Lang:t('inf_mapping.opn_inv') end) if ok and type(val) == "string" and val ~= "" then _desc = val end end RegisterKeyMapping('inventory_toggle', _desc, 'keyboard', 'TAB') -- ===== End Added ===== -- ===== Added: optional client event to close via helper ===== RegisterNetEvent('inventory:client:CloseInventoryProperly', function() if CloseInventoryProperly then CloseInventoryProperly() end end) -- ===== End Added =====