diff --git a/resources/[housing]/renzu_motels-main.zip b/resources/[housing]/renzu_motels-main.zip deleted file mode 100644 index fc395dea1..000000000 Binary files a/resources/[housing]/renzu_motels-main.zip and /dev/null differ diff --git a/resources/[inventory]/muhaddil-machines/.gitattributes b/resources/[inventory]/muhaddil-machines/.gitattributes deleted file mode 100644 index dfe077042..000000000 --- a/resources/[inventory]/muhaddil-machines/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto diff --git a/resources/[inventory]/muhaddil-machines/LICENSE b/resources/[inventory]/muhaddil-machines/LICENSE deleted file mode 100644 index 7d57900f2..000000000 --- a/resources/[inventory]/muhaddil-machines/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Muhaddil - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/resources/[inventory]/muhaddil-machines/NUI/NUI.html b/resources/[inventory]/muhaddil-machines/NUI/NUI.html deleted file mode 100644 index be4c2f2c7..000000000 --- a/resources/[inventory]/muhaddil-machines/NUI/NUI.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Vending Machine - - -
-

Elige un producto

-
- -
- - - - diff --git a/resources/[inventory]/muhaddil-machines/README.md b/resources/[inventory]/muhaddil-machines/README.md deleted file mode 100644 index 1b8abbff6..000000000 --- a/resources/[inventory]/muhaddil-machines/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# muhaddil_machines (FiveM) - -A FiveM script that adds several machines to improve user experience. - -## Features - -- Vending machines for drinks and snacks -- Water coolers with a timeout feature -- Food stands with various items -- News sellers with newspapers -- Custom animations for interactions -- Configurable framework support (ESX and QBCore) -- Debug mode for development -- Auto version checker - -## Installation - -1. Clone or download the repository. -2. Add the resource to your `resources` folder. -3. Add `start muhaddil_machines` to your `server.cfg`. - -## Configuration - -You can configure the script by editing the [config.lua](config.lua) file. Here are some of the options available: - -- `DebugMode`: Enable or disable debug mode. -- `Framework`: Choose between 'esx' or 'qb'. -- `UseOXNotifications`: Use OX notifications or frameworks. -- `ThirstRemoval`: Amount of thirst removed by water coolers. -- `WaterCoolerTimeout`: Timeout duration for water coolers. -- `VisibleProp`: Show or hide props during animations. -- `ShowWaitNotification`: Show notification when water cooler is on timeout. -- `MaxDrinksBeforeKill`: Maximum drinks before player death. -- `CountDrinksPlace`: Count drinks before or after drinking. - -## Usage - -### Vending Machines - -Interact with vending machines to buy drinks and snacks. The available items and their prices are configured in the [config.lua](config.lua) file. - -### Water Coolers - -Interact with water coolers to drink water. The script includes a timeout feature to prevent excessive use. - -### Food Stands - -Interact with food stands to buy various food items. The available items and their prices are configured in the [config.lua](config.lua) file. - -### News Sellers - -Interact with news sellers to buy newspapers. The available items and their prices are configured in the [config.lua](config.lua) file. - -## License - -This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. - -

- - -

diff --git a/resources/[inventory]/muhaddil-machines/client.lua b/resources/[inventory]/muhaddil-machines/client.lua deleted file mode 100644 index 727c06d2e..000000000 --- a/resources/[inventory]/muhaddil-machines/client.lua +++ /dev/null @@ -1,487 +0,0 @@ -local buying = false -- Variable to prevent multiple purchases -local LastWaterCoolerUse = 0 -- Variable to prevent multiple uses of the water cooler -local TimeoutDuration = Config.WaterCoolerTimeout * 1000 -- Timeout duration for water coolers in milliseconds -local DrinkCount = 0 -- Variable to count the number of drinks - -if Config.Framework == "esx" then - ESX = exports['es_extended']:getSharedObject() -elseif Config.Framework == "qb" then - QBCore = exports['qb-core']:GetCoreObject() -elseif Config.Framework == "ox" then - Ox = require '@ox_core.lib.init' -else - ESX = exports['es_extended']:getSharedObject() -end - -function DebugPrint(...) -- Debug print function - if Config.DebugMode then - print(...) - end -end - -function Notify(msgtitle, msg, time, type2) -- Notification function - if Config.UseOXNotifications then - lib.notify({ - title = msgtitle, - description = msg, - showDuration = true, - type = type2, - style = { - backgroundColor = 'rgba(0, 0, 0, 0.75)', - color = 'rgba(255, 255, 255, 1)', - ['.description'] = { - color = '#909296', - backgroundColor = 'transparent' - } - } - }) - else - if Config.Framework == 'qb' then - QBCore.Functions.Notify(msg, type2, time) - elseif Config.Framework == 'esx' then - TriggerEvent('esx:showNotification', msg, type2, time) - elseif Config.Framework == 'ox' then - lib.notify({ - title = msgtitle, - description = msg, - showDuration = true, - type = type2, - style = { - backgroundColor = 'rgba(0, 0, 0, 0.75)', - color = 'rgba(255, 255, 255, 1)', - ['.description'] = { - color = '#909296', - backgroundColor = 'transparent' - } - } - }) - end - end -end - -RegisterNetEvent("muhaddil-machines:Notify") -AddEventHandler("muhaddil-machines:Notify", function(msgtitle, msg, time, type) - Notify(msgtitle, msg, time, type) -end) - -local function loadAnimDict(animDict) - RequestAnimDict(animDict) - while not HasAnimDictLoaded(animDict) do - Citizen.Wait(0) - end -end - -local function playAnimation(ped, animDict, animName) - loadAnimDict(animDict) - TaskPlayAnim(ped, animDict, animName, 8.0, 5.0, -1, 1, 1, false, false, false) - Citizen.Wait(4500) - ClearPedTasks(ped) - RemoveAnimDict(animDict) -end - -local function vendingAnimation(entity) - local ped = PlayerPedId() - local position = GetOffsetFromEntityInWorldCoords(entity, 0.0, -0.97, 0.05) - local heading = GetEntityHeading(entity) - local prop_name = 'ng_proc_sodacan_01a' - buying = true - - TaskTurnPedToFaceEntity(ped, entity, -1) - if not IsEntityAtCoord(ped, position.x, position.y, position.z, 0.1, 0.0, 0.1, false, true, 0) then - TaskGoStraightToCoord(ped, position.x, position.y, position.z, 1.0, 20000, heading, 0.1) - Citizen.Wait(1000) - end - TaskTurnPedToFaceEntity(ped, entity, -1) - Citizen.Wait(1000) - - Citizen.CreateThread(function() - local playerPed = PlayerPedId() - local x, y, z = table.unpack(GetEntityCoords(playerPed)) - - if Config.VisibleProp then - local prop = CreateObject(GetHashKey(prop_name), x, y, z + 0.2, true, true, true) - local boneIndex = GetPedBoneIndex(playerPed, 18905) - end - - RequestAmbientAudioBank("VENDING_MACHINE", false) - HintAmbientAudioBank("VENDING_MACHINE", 0) - if Config.VisibleProp then - AttachEntityToEntity(prop, playerPed, boneIndex, 0.12, 0.008, 0.03, 240.0, -60.0, 0.0, true, true, false, - true, 1, true) - end - playAnimation(playerPed, Config.Animations.sodamachines[1], Config.Animations.sodamachines[2]) - Citizen.Wait(1000) - - ClearPedSecondaryTask(playerPed) - if DoesEntityExist(prop) then - DeleteObject(prop) - end - ReleaseAmbientAudioBank() - - buying = false - end) -end - - -local function showQuantityDialog(item, vendingMachineName, entity) - local input = lib.inputDialog("Selecciona la cantidad", { - { type = 'number', label = 'Cantidad', min = 1, max = Config.InputMaxValue, default = 1 } - }) - - if not input then return end - local cantidad = input[1] - - if cantidad and cantidad > 0 then - local ped = PlayerPedId() - if buying then return end - buying = true - - vendingAnimation(entity) - - Citizen.Wait(4500) - - TriggerServerEvent('muhaddil-machines:buy', 'machine', vendingMachineName, item.name, cantidad) - else - Notify('Error', 'Cantidad no válida', 5000, "error") - end - - buying = false -end - -local function replacePrice(inputString, price) - return inputString:gsub("%%price%%", tostring(price)) -end - -local function showVendingMenu(vendingMachineName, entity, items) - local options = {} - - for _, item in pairs(items) do - table.insert(options, { - title = replacePrice(item.label, item.price), - icon = item.icon or 'fa-solid fa-bottle-water', - onSelect = function() - if buying then return end - showQuantityDialog(item, vendingMachineName, entity) - end - }) - end - - lib.registerContext({ - id = 'vending_menu_' .. vendingMachineName, - title = 'Máquina expendedora', - canClose = true, - options = options - }) - - lib.showContext('vending_menu_' .. vendingMachineName) -end - -local function interactWithWaterCooler(entity) - local currentTime = GetGameTimer() - - if Config.ShowWaitNotification then - if currentTime - LastWaterCoolerUse < TimeoutDuration then - DebugPrint("Debes esperar antes de usar nuevamente la fuente de agua.") - Notify('¡Echa el freno madaleno!', 'Relaja, espera un poco antes de volver a usar la máquina', 5000, "error") - return - end - end - - if IsAnimated then return end - IsAnimated = true - LastWaterCoolerUse = currentTime - - local prop_name = 'prop_cs_paper_cup' - local ped = PlayerPedId() - local position = GetOffsetFromEntityInWorldCoords(entity, 0.0, -0.97, 0.05) - local heading = GetEntityHeading(entity) - - if not IsEntityAtCoord(ped, position.x, position.y, position.z, 0.1, 0.1, 0.1, false, true, 0) then - TaskGoStraightToCoord(ped, position.x, position.y, position.z, 1.0, 20000, heading, 0.1) - Wait(1000) - end - TaskTurnPedToFaceEntity(ped, entity, -1) - - lib.progressBar({ - duration = 2000, - label = 'Llenado Vaso', - }) - - Citizen.CreateThread(function() - local playerPed = PlayerPedId() - local x, y, z = table.unpack(GetEntityCoords(playerPed)) - local prop = CreateObject(GetHashKey(prop_name), x, y, z + 0.2, true, true, true) - local boneIndex = GetPedBoneIndex(playerPed, 18905) - AttachEntityToEntity(prop, playerPed, boneIndex, 0.12, 0.008, 0.03, 240.0, -60.0, 0.0, true, true, false, true, 1, - true) - - local animDict = 'mp_player_intdrink' - local animName = 'loop_bottle' - - playAnimation(playerPed, animDict, animName) - - if Config.CountDrinksPlace == 'before' then - DrinkCount = DrinkCount + 1 - end - - if Config.KillPlayerOnExcess then - local warningThreshold = math.ceil(Config.MaxDrinksBeforeKill / 2) - print(warningThreshold) - - if DrinkCount >= Config.MaxDrinksBeforeKill then - SetEntityHealth(playerPed, 0) - Notify('Demasiada agua', 'Has bebido demasiada agua y has muerto.', 5000, "error") - DrinkCount = 0 - elseif DrinkCount >= warningThreshold then - Notify('Agua fresca', 'Sigues bebiendo... ten cuidado.', 3000, "info") - else - Notify('Agua fresca', 'Has tomado un vaso de agua.', 3000, "info") - end - else - Notify('Agua fresca', 'Has tomado un vaso de agua.', 3000, "info") - end - - IsAnimated = false - ClearPedSecondaryTask(playerPed) - DeleteObject(prop) - RemoveAnimDict(animDict) - - TriggerServerEvent('muhaddil-machines:RemoveThirst') - - if Config.CountDrinksPlace == 'after' then - DrinkCount = DrinkCount + 1 - end - end) -end - -local function WaterCoolerTarget() - for waterCoolerName, data in pairs(Config.WaterCoolers) do - local options = { - { - label = "Beber Agua", - icon = 'fa-solid fa-glass-water', - onSelect = function(d) - local entity = d.entity - interactWithWaterCooler(entity) - end - } - } - - exports.ox_target:addModel(joaat(data.model), options) - end -end - -local function standAnimation(entity) - local ped = PlayerPedId() - local position = GetOffsetFromEntityInWorldCoords(entity, 0.0, -0.97, 0.05) - local heading = GetEntityHeading(entity) - buying = true - - TaskTurnPedToFaceEntity(ped, entity, -1) - if not IsEntityAtCoord(ped, position.x, position.y, position.z, 0.1, 0.0, 0.1, false, true, 0) then - TaskGoStraightToCoord(ped, position.x, position.y, position.z, 1.0, 20000, heading, 0.1) - Citizen.Wait(1000) - end - TaskTurnPedToFaceEntity(ped, entity, -1) - Citizen.Wait(1000) - - playAnimation(ped, Config.Animations.stand[1], Config.Animations.stand[2]) - Citizen.Wait(1000) - - ClearPedSecondaryTask(ped) - - buying = false -end - -local function showQuantityDialogStands(item, standName, entity) - local input = lib.inputDialog("Selecciona la cantidad", { - { type = 'number', label = 'Cantidad', min = 1, max = Config.InputMaxValue, default = 1 } - }) - - if not input then return end - local cantidad = input[1] - - if cantidad and cantidad > 0 then - local ped = PlayerPedId() - if buying then return end - buying = true - - standAnimation(entity) - - TriggerServerEvent('muhaddil-machines:buy', 'stand', standName, item.name, cantidad) - else - Notify('Error', 'Cantidad no válida', 5000, "error") - end - - buying = false -end - -local function standMenu(standName, entity, items) - local options = {} - - for _, item in pairs(items) do - table.insert(options, { - title = replacePrice(item.label, item.price), - icon = item.icon or 'fa-solid fa-bottle-water', - onSelect = function() - if buying then return end - showQuantityDialogStands(item, standName, entity) - end - }) - end - - lib.registerContext({ - id = 'stand_menu_' .. standName, - title = 'Puesto de Comida', - canClose = true, - options = options - }) - - lib.showContext('stand_menu_' .. standName) -end - -local function newsAnimation(entity) - local ped = PlayerPedId() - local position = GetOffsetFromEntityInWorldCoords(entity, 0.0, -0.97, 0.05) - local heading = GetEntityHeading(entity) - buying = true - - TaskTurnPedToFaceEntity(ped, entity, -1) - if not IsEntityAtCoord(ped, position.x, position.y, position.z, 0.0, 0.0, 0.0, false, true, 0) then - TaskGoStraightToCoord(ped, position.x, position.y, position.z, 1.0, 20000, heading, 0.1) - Citizen.Wait(1000) - end - TaskTurnPedToFaceEntity(ped, entity, -1) - Citizen.Wait(1000) - - loadAnimDict(Config.Animations.newsSellers[1]) - TaskPlayAnim(ped, Config.Animations.newsSellers[1], Config.Animations.newsSellers[2], 8.0, 5.0, -1, 1, 1, false, - false, false) - Citizen.Wait(2500) - ClearPedTasks(ped) - RemoveAnimDict(Config.Animations.newsSellers[1]) - - ClearPedSecondaryTask(ped) - - buying = false -end - - -local function showQuantityDialogNews(item, newsName, entity) - local input = lib.inputDialog("Selecciona la cantidad", { - { type = 'number', label = 'Cantidad', min = 1, max = Config.InputMaxValue, default = 1 } - }) - - if not input then return end - local cantidad = input[1] - - if cantidad and cantidad > 0 then - local ped = PlayerPedId() - if buying then return end - buying = true - - newsAnimation(entity) - - TriggerServerEvent('muhaddil-machines:buy', 'news', newsName, item.name, cantidad) - else - Notify('Error', 'Cantidad no válida', 5000, "error") - end - - buying = false -end - -local function newsMenu(newsName, entity, items) - local options = {} - - for _, item in pairs(items) do - table.insert(options, { - title = replacePrice(item.label, item.price), - icon = item.icon or 'fa-solid fa-bottle-water', - onSelect = function() - if buying then return end - showQuantityDialogNews(item, newsName, entity) - end - }) - end - - lib.registerContext({ - id = 'news_menu_' .. newsName, - title = 'Venta de Noticias', - canClose = true, - options = options - }) - - lib.showContext('news_menu_' .. newsName) -end - -local function setupTargeting() - for vendingMachineName, data in pairs(Config.machines) do - exports['qb-target']:AddTargetModel(data.model, { - options = { - { - type = "client", - icon = "fas fa-basket-shopping", - label = "Abrir Máquina Expendedora", - action = function(entity) - if buying then return end - showVendingMenu(vendingMachineName, entity, data.items) - end - } - }, - distance = 2.0 - }) - end - - for standName, data in pairs(Config.Stands) do - exports['qb-target']:AddTargetModel(data.model, { - options = { - { - type = "client", - icon = "fas fa-utensils", - label = "Abrir Puesto de Comida", - action = function(entity) - if buying then return end - standMenu(standName, entity, data.items) - end - } - }, - distance = 2.0 - }) - end - - for newsName, data in pairs(Config.NewsSellers) do - exports['qb-target']:AddTargetModel(data.model, { - options = { - { - type = "client", - icon = "fas fa-newspaper", - label = "Abrir Venta de Noticias", - action = function(entity) - if buying then return end - newsMenu(newsName, entity, data.items) - end - } - }, - distance = 2.0 - }) - end -end - -local function WaterCoolerTarget() - for waterCoolerName, data in pairs(Config.WaterCoolers) do - exports['qb-target']:AddTargetModel(data.model, { - options = { - { - type = "client", - icon = "fas fa-glass-water", - label = "Beber Agua", - action = function(entity) - interactWithWaterCooler(entity) - end - } - }, - distance = 2.0 - }) - end -end - diff --git a/resources/[inventory]/muhaddil-machines/config.lua b/resources/[inventory]/muhaddil-machines/config.lua deleted file mode 100644 index d6a79b815..000000000 --- a/resources/[inventory]/muhaddil-machines/config.lua +++ /dev/null @@ -1,266 +0,0 @@ -Config = Config or {} - -Config.DebugMode = true -- Enable debug mode -Config.Framework = 'qb' -- 'esx', 'qb' or 'ox' -Config.UseOXNotifications = true -- Use OX Notifications or framework notifications -Config.Inventory = ''-- 'qs', 'ox' or leave blank -Config.NewQBInventory = false -- If you're using the new QB Inventory - -Config.ThirstRemoval = 150000 -- Amount of thirst removed by water coolers -Config.WaterCoolerTimeout = 30 -- Timeout duration for water coolers in seconds -Config.VisibleProp = false -- Show the prop when buying a drink -Config.InputMaxValue = 10 -- Maximum value for the input -Config.KillPlayerOnExcess = true -- Enable one of the two (WaterCooler) -Config.ShowWaitNotification = false -- Enable one of the two (WaterCooler) -Config.MaxDrinksBeforeKill = 3 -- (WaterCooler) -Config.CountDrinksPlace = 'before' -- 'before' or 'after', it varies in the result of the Config.MaxDrinksBeforeKill (WaterCooler) - -Config.Animations = { -- Animations for the vending machines - stand = { -- Stand animations - "special_ped@baygor@monologue_2@monologue_2h", - "you_can_ignore_me_7" - }, - sodamachines = { -- Soda machine animations - "mini@sprunk@first_person", - "plyr_buy_drink_pt1" - }, - newsSellers = { -- News seller animations - "anim@amb@nightclub@mini@drinking@drinking_shots@ped_c@normal", - "pickup" - }, -} - -Config.machines = { -- Vending machines - { - model = 'prop_vend_soda_02', - items = { - { - name = "ecola_dose", - label = 'E-Cola Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "sprunk_dose", - label = 'Sprunk Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "orange_o_tang_dose", - label = 'Orange O Tang Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "ecola_zero_dose", - label = 'E-Cola Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "orange_o_tang_zero_dose", - label = 'Orange O Tang Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "sprunk_zero_dose", - label = 'Sprunk Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - }, - }, - { - model = 'prop_vend_soda_01', - items = { - { - name = "ecola_dose", - label = 'E-Cola Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "sprunk_dose", - label = 'Sprunk Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "orange_o_tang_dose", - label = 'Orange O Tang Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "ecola_zero_dose", - label = 'E-Cola Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "orange_o_tang_zero_dose", - label = 'Orange O Tang Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "sprunk_zero_dose", - label = 'Sprunk Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - }, - }, - { - model = 'ch_chint10_vending_smallroom_01', - items = { - { - name = "ecola_dose", - label = 'E-Cola Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "sprunk_dose", - label = 'Sprunk Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "orange_o_tang_dose", - label = 'Orange O Tang Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "ecola_zero_dose", - label = 'E-Cola Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "orange_o_tang_zero_dose", - label = 'Orange O Tang Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - { - name = "sprunk_zero_dose", - label = 'Sprunk Zero Dose ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - }, - }, - { - model = 'm23_2_prop_m32_vend_drink_01a', - items = { - { - name = "junk_energy", - label = 'Junk Energy ($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - }, - }, - { - model = 'sf_prop_sf_vend_drink_01a', - items = { - { - name = "junk_energy", - label = 'Junk Energy($%price%)', - icon = 'fa-solid fa-can-food', - price = 4 - }, - }, - }, - { - model = 'prop_vend_water_01', - items = { - { - name = "water", - label = 'Flasche Wasser ($%price%)', - price = 2 - }, - }, - }, - { - model = 'prop_vend_snak_01', - items = { - { - name = "mimis_instant_nudeln", - label = 'Mimis Instant Nudeln ($%price%)', - icon = 'fa-solid fa-pot-food', - price = 6 - }, - { - name = "twerks_candy", - label = 'Ego Chaser Schockriegel ($%price%)', - icon = 'fa-solid fa-candy-bar', - price = 2 - }, - { - name = "snikkel_candy", - label = 'EarthQuakes ($%price%)', - icon = 'fa-solid fa-candy-bar', - price = 2 - }, - }, - }, - { - model = 'prop_vend_snak_01_tu', - items = { - { - name = "mimis_instant_nudeln", - label = 'Mimis Instant Nudeln ($%price%)', - icon = 'fa-solid fa-pot-food', - price = 6 - }, - { - name = "twerks_candy", - label = 'Ego Chaser Schockriegel ($%price%)', - icon = 'fa-solid fa-candy-bar', - price = 2 - }, - { - name = "snikkel_candy", - label = 'EarthQuakes ($%price%)', - icon = 'fa-solid fa-candy-bar', - price = 2 - }, - }, - }, - - { - model = 'prop_vend_coffe_01', - items = { - { - name = "coffe", - label = 'Kaffee Togo ($%price%)', - icon = 'fa fa-mug-hot', - price = 4 - }, - { - name = "kakao", - label = 'Kakao Togo ($%price%)', - icon = 'fa fa-mug-hot', - price = 4 - }, - }, - }, - { - model = 'prop_vend_fags_01', - items = { - { - name = "redwoodpack", - label = 'Packung Redwood Zigaretten ($%price%)', - icon = 'fa-solid fa-smoking', - price = 10 - }, - }, - }, - -} - diff --git a/resources/[inventory]/muhaddil-machines/fxmanifest.lua b/resources/[inventory]/muhaddil-machines/fxmanifest.lua deleted file mode 100644 index c88c2bc08..000000000 --- a/resources/[inventory]/muhaddil-machines/fxmanifest.lua +++ /dev/null @@ -1,16 +0,0 @@ -fx_version 'cerulean' -game 'gta5' -lua54 'yes' - -author 'Muhaddil' -description 'FiveM script that adds vending machines' -version 'v1.0.1' - -shared_scripts { - 'config.lua', - '@ox_lib/init.lua', -} - -client_script 'client.lua' - -server_script 'server/*' \ No newline at end of file diff --git a/resources/[inventory]/muhaddil-machines/server/autoChecker.lua b/resources/[inventory]/muhaddil-machines/server/autoChecker.lua deleted file mode 100644 index 386da32f0..000000000 --- a/resources/[inventory]/muhaddil-machines/server/autoChecker.lua +++ /dev/null @@ -1,120 +0,0 @@ -local currentVersion = GetResourceMetadata(GetCurrentResourceName(), 'version') -local resourceName = 'Muhaddil/muhaddil-machines' -local githubApiUrl = 'https://api.github.com/repos/' .. resourceName .. '/releases/latest' - --- Función para calcular la diferencia en días -local function daysAgo(dateStr) - local year, month, day = dateStr:match("(%d+)-(%d+)-(%d+)") - local releaseTime = os.time({ year = year, month = month, day = day }) - local currentTime = os.time() - local difference = os.difftime(currentTime, releaseTime) / (60 * 60 * 24) -- Diferencia en días - return math.floor(difference) -end - --- Función para convertir la fecha a "hace X días" -local function formatDate(releaseDate) - local days = daysAgo(releaseDate) - if days < 1 then - return "Today" - elseif days == 1 then - return "Yesterday" - else - return days .. " days ago" - end -end - --- Función para acortar la URL -local function shortenTexts(text) - local maxLength = 35 - if #text > maxLength then - local shortened = text:sub(1, maxLength - 3) .. '...' - return shortened - else - return text - end -end - -local function printWithColor(message, colorCode) - if type(message) ~= "string" then - message = tostring(message) - end - print('\27[' .. colorCode .. 'm' .. message .. '\27[0m') -end - -local function printCentered(text, length, colorCode) - local padding = math.max(length - #text - 2, 0) - local leftPadding = math.floor(padding / 2) - local rightPadding = padding - leftPadding - printWithColor('│' .. string.rep(' ', leftPadding) .. text .. string.rep(' ', rightPadding) .. '│', colorCode) -end - -local function printWrapped(text, length, colorCode) - if type(text) ~= "string" then - text = tostring(text) - end - - local maxLength = length - 2 - local pos = 1 - - while pos <= #text do - local endPos = pos + maxLength - 1 - if endPos > #text then - endPos = #text - else - local spaceIndex = text:sub(pos, endPos):match('.*%s') or maxLength - endPos = pos + spaceIndex - 1 - end - - local line = text:sub(pos, endPos) - if endPos < #text then - line = line .. '...' - end - - printWithColor('│' .. line .. string.rep(' ', length - #line) .. '│', colorCode) - - pos = endPos + 1 - end -end - -if Config.AutoVersionChecker then - PerformHttpRequest(githubApiUrl, function(statusCode, response, headers) - if statusCode == 200 then - local data = json.decode(response) - - if data and data.tag_name then - local latestVersion = data.tag_name - local releaseDate = data.published_at or "Unknown" - local formattedDate = formatDate(releaseDate) - local notes = data.body or "No notes available" - local downloadUrl = data.html_url or "No download link available" - local shortenedUrl = shortenTexts(downloadUrl) - local shortenedNotes = shortenTexts(notes) - - - local boxWidth = 52 - - if latestVersion ~= currentVersion then - print('╭────────────────────────────────────────────────────╮') - printWrapped('[muhaddil-machines] - New Version Available', boxWidth, '34') -- Blue - printWrapped('Current version: ' .. currentVersion, boxWidth, '32') -- Green - printWrapped('Latest version: ' .. latestVersion, boxWidth, '33') -- Yellow - printWrapped('Released: ' .. formattedDate, boxWidth, '33') -- Yellow - printWrapped('Notes: ' .. shortenedNotes, boxWidth, '33') -- Yellow - printWrapped('Download: ' .. shortenedUrl, boxWidth, '32') -- Green - print('╰────────────────────────────────────────────────────╯') - else - print('╭────────────────────────────────────────────────────╮') - printWrapped('[muhaddil-machines] - Up-to-date', boxWidth, '32') -- Green - printWrapped('Current version: ' .. currentVersion, boxWidth, '32') -- Green - print('╰────────────────────────────────────────────────────╯') - end - else - printWithColor('[muhaddil-machines] - Error: The JSON structure is not as expected.', '31') -- Red - printWithColor('GitHub API Response: ' .. response, '31') -- Red - end - else - printWithColor( - '[muhaddil-machines] - Failed to check for latest version. Status code: ' .. statusCode, '31') -- Red - end - end, 'GET') -end diff --git a/resources/[inventory]/muhaddil-machines/server/server.lua b/resources/[inventory]/muhaddil-machines/server/server.lua deleted file mode 100644 index d10af7b62..000000000 --- a/resources/[inventory]/muhaddil-machines/server/server.lua +++ /dev/null @@ -1,164 +0,0 @@ -if Config.Framework == "esx" then - ESX = exports['es_extended']:getSharedObject() -elseif Config.Framework == "qb" then - QBCore = exports['qb-core']:GetCoreObject() -elseif Config.Framework == "ox" then - Ox = require '@ox_core.lib.init' -else - ESX = exports['es_extended']:getSharedObject() -end - -local function getPlayerObject(src) -- Get the player object - if Config.Framework == 'qb' then - return QBCore.Functions.GetPlayer(src) - elseif Config.Framework == 'esx' then - return ESX.GetPlayerFromId(src) - elseif Config.Framework == 'ox' then - return Ox.GetPlayer(src) - end -end - -function DebugPrint(...) - if Config.DebugMode then - print(...) - end -end - -local function TakeMoney(playerObject, method, amount) -- Take money from the player - amount = tonumber(amount) - - if Config.Framework == 'qb' then - return playerObject.Functions.RemoveMoney(method, amount) - elseif Config.Framework == 'esx' then - if method == 'cash' then - if playerObject.getMoney() >= amount then - playerObject.removeMoney(amount) - return true - end - elseif method == 'bank' then - if playerObject.getAccount('bank').money >= amount then - playerObject.removeAccountMoney('bank', amount) - return true - end - end - elseif Config.Framework == 'ox' then - if exports.ox_inventory:GetItemCount(source, 'money') >= amount then - exports.ox_inventory:RemoveItem(source, 'money', amount) - return true - end - end - - return false -end - -local function giveItem(src, playerObject, item, amount) -- Give the item to the player - if Config.Framework == 'qb' then - if Config.Inventory == 'qs' then - exports['qs-inventory']:AddItem(src, item.name, amount) - elseif Config.Inventory == 'ox' then - exports.ox_inventory:AddItem(src, item.name, amount) - else - if Config.NewQBInventory then - exports['qb-inventory']:AddItem(source, item.name, amount, false, false, 'Machines') - else - playerObject.Functions.AddItem(item.name, amount) - end - end - elseif Config.Framework == 'esx' then - if Config.Inventory == 'qs' then - exports['qs-inventory']:AddItem(src, item.name, amount) - elseif Config.Inventory == 'ox' then - exports.ox_inventory:AddItem(src, item.name, amount) - else - playerObject.addInventoryItem(item.name, amount) - end - elseif Config.Framework == 'ox' then - exports.ox_inventory:AddItem(source, item.name, amount) - end -end - -local function handlePurchase(src, player, item, machineName, totalPrice, cantidad) -- Handle the purchase - local success = false - - if TakeMoney(player, 'cash', totalPrice) then - success = true - elseif TakeMoney(player, 'bank', totalPrice) then - success = true - end - - if success then - giveItem(src, player, item, cantidad) - else - TriggerClientEvent('muhaddil-machines:Notify', src, '', 'No tienes suficiente dinero.', 'error') - end -end - -local function findItemInSource(sourceData, itemName) -- Find the item in the source data - for _, item in ipairs(sourceData.items) do - if item.name == itemName then - return item - end - end - return nil -end - -RegisterNetEvent('muhaddil-machines:buy', - function(sourceType, sourceName, itemName, cantidad) -- Event for buying the item - local src = source - local player = getPlayerObject(src) - - local sourceData - if sourceType == 'machine' then - sourceData = Config.machines[sourceName] - elseif sourceType == 'stand' then - sourceData = Config.Stands[sourceName] - elseif sourceType == 'news' then - sourceData = Config.NewsSellers[sourceName] - else - TriggerClientEvent('muhaddil-machines:Notify', src, '', 'El tipo de origen no es válido.', 'error') - return - end - - local item = findItemInSource(sourceData, itemName) - if item then - local totalPrice = item.price * cantidad - handlePurchase(src, player, item, sourceName, totalPrice, cantidad) - else - TriggerClientEvent('muhaddil-machines:Notify', src, '', 'El artículo no está disponible', 'error') - end - end) - -RegisterServerEvent('muhaddil-machines:RemoveThirst') -- Event for the watercoolers to remove thirst -AddEventHandler('muhaddil-machines:RemoveThirst', function() - local src = source - - if Config.Framework == 'qb' then - local player = QBCore.Functions.GetPlayer(src) - if player then - local currentThirst = player.PlayerData.metadata['thirst'] or 0 - if currentThirst < 100 then - local newThirst = math.min(currentThirst + Config.ThirstRemoval, 100) - player.Functions.SetMetaData('thirst', newThirst) - - TriggerClientEvent('hud:client:UpdateNeeds', src, player.PlayerData.metadata.hunger or 50, newThirst) - else - print("[Info] El jugador " .. src .. " ya tiene la sed máxima (100).") - end - else - print("[Error] No se pudo obtener el jugador para src: " .. tostring(src)) - end - elseif Config.Framework == 'esx' then - TriggerClientEvent('esx_status:add', src, 'thirst', Config.ThirstRemoval) - elseif Config.Framework == 'ox' then - local player = Ox.GetPlayer(src) - local beforeStatus = player.getStatus('thirst') - player.removeStatus('thirst', Config.ThirstRemoval) - local afterStatus = player.getStatus('thirst') - DebugPrint("[Info] El jugador " .. - src .. " tenía " .. beforeStatus .. " de sed y ahora tiene " .. afterStatus .. ".") - local statuses = player.getStatuses() - DebugPrint("[Info] Los estados del jugador " .. src .. " son: " .. json.encode(statuses)) - else - print("[Error] Configuración de framework no válida.") - end -end) diff --git a/resources/[inventory]/tgiann-inventory/configs/configVendingMachine.lua b/resources/[inventory]/tgiann-inventory/configs/configVendingMachine.lua index 0f5a66667..da0187e28 100644 --- a/resources/[inventory]/tgiann-inventory/configs/configVendingMachine.lua +++ b/resources/[inventory]/tgiann-inventory/configs/configVendingMachine.lua @@ -1,25 +1,72 @@ config.vendingMachine = { - active = false, + active = true, machines = { { objects = { 'prop_vend_soda_01', 'prop_vend_soda_02', + 'ch_chint10_vending_smallroom_01', }, items = { - { name = 'kurkakola', price = 4, amount = 50 }, - { name = 'water_bottle', price = 4, amount = 50 }, + { name = 'ecola_dose', price = 4, amount = 50 }, + { name = 'sprunk_dose', price = 4, amount = 50 }, + { name = 'orange_o_tang_dose', price = 4, amount = 50 }, + { name = 'ecola_zero_dose', price = 4, amount = 50 }, + { name = 'sprunk_zero_dose', price = 4, amount = 50 }, + { name = 'orange_o_tang_zero_dose', price = 4, amount = 50 }, + + + } + }, + { + objects = { + 'sf_prop_sf_vend_drink_01a', + 'm23_2_prop_m32_vend_drink_01a', + }, + items = { + { name = 'junk_energy', price = 4, amount = 50 }, + + } + }, + { + objects = { + 'prop_vend_snak_01_tu', + 'prop_vend_snak_01', + }, + items = { + { name = 'mimis_instant_nudeln', price = 4, amount = 50 }, + { name = 'twerks_candy', price = 4, amount = 50 }, + { name = 'snikkel_candy', price = 4, amount = 50 }, + + + } + }, + { + objects = { + 'prop_vend_coffe_01', + }, + items = { + { name = 'coffe', price = 4, amount = 50 }, + { name = 'kakao', price = 4, amount = 50 }, } }, { objects = { 'prop_vend_water_01', - 'prop_vend_coffe_01', }, items = { - { name = 'kurkakola', price = 7, amount = 50 }, - { name = 'water_bottle', price = 2, amount = 50 }, + { name = 'water', price = 4, amount = 50 }, } }, + { + objects = { + 'prop_vend_fags_01', + }, + items = { + { name = 'redwoodpack', price = 10, amount = 50 }, + } + }, + + } }