diff --git a/resources/[Developer]/[Nordi]/nordi_vending/client/main.lua b/resources/[Developer]/[Nordi]/nordi_vending/client/main.lua new file mode 100644 index 000000000..87578cb55 --- /dev/null +++ b/resources/[Developer]/[Nordi]/nordi_vending/client/main.lua @@ -0,0 +1,239 @@ +local QBCore = exports['qb-core']:GetCoreObject() +local Config = require 'config' +local inZone = false +local currentMachine = nil +local PlayerData = {} + +local function SetupTarget() + if not Config.UseQBTarget then return end + + -- Default 24/7 machines + for modelHash, machineData in pairs(Config.DefaultMachines.Models) do + exports['qb-target']:AddTargetModel(modelHash, { + options = { + { + type = 'client', + event = 'vendingmachines:client:openMenu', + icon = 'fas fa-cash-register', + label = 'Use Vending Machine', + machineModel = modelHash, + isPlayerOwned = false + }, + Config.EnableRobbery and { + type = 'client', + event = 'vendingmachines:client:startRobbery', + icon = 'fas fa-lock', + label = 'Rob Machine', + item = Config.RobberyItem, + machineModel = modelHash, + isPlayerOwned = false + } or nil + }, + distance = Config.TargetOptions.distance + }) + end + + -- Player owned machines will be added dynamically as they're loaded +end + +local function RefreshPlayerMachines() + local playerMachines = QBCore.Functions.TriggerRpc('vendingmachines:server:getPlayerMachines', PlayerData.citizenid) + + for _, machine in pairs(playerMachines) do + exports['qb-target']:AddBoxZone('vending_' .. machine.id, json.decode(machine.location), 0.5, 0.5, { + name = 'vending_' .. machine.id, + heading = 0, + debugPoly = false, + minZ = json.decode(machine.location).z - 0.5, + maxZ = json.decode(machine.location).z + 0.5 + }, { + options = { + { + type = 'client', + event = 'vendingmachines:client:openMenu', + icon = 'fas fa-cash-register', + label = 'Use Vending Machine', + machineId = machine.id, + isPlayerOwned = true, + machineModel = machine.model_hash + }, + Config.EnableRobbery and { + type = 'client', + event = 'vendingmachines:client:startRobbery', + icon = 'fas fa-lock', + label = 'Rob Machine', + item = Config.RobberyItem, + machineId = machine.id, + isPlayerOwned = true + } or nil, + table.contains(Config.PlayerOwnedMachines.AllowedJobs, PlayerData.job.name) and { + type = 'client', + event = 'vendingmachines:client:restockMenu', + icon = 'fas fa-boxes', + label = 'Restock Machine', + machineId = machine.id + } or nil, + table.contains(Config.PlayerOwnedMachines.AllowedJobs, PlayerData.job.name) and { + type = 'client', + event = 'vendingmachines:client:collectEarnings', + icon = 'fas fa-money-bill-wave', + label = 'Collect Earnings', + machineId = machine.id + } or nil + }, + distance = Config.TargetOptions.distance + }) + end +end + +local function OpenVendingMenu(machineInfo) + local menu = { + header = 'Vending Machine', + items = {} + } + + if machineInfo.isPlayerOwned then + menu.header = 'Player Vending Machine' + menu.items[#menu.items + 1] = { + title = 'Stock: ' .. (currentMachine and currentMachine.stock or '?'), + description = 'Available items for purchase', + disabled = true + } + else + menu.header = '24/7 Vending Machine' + end + + local items = Config.DefaultMachines.Models[machineInfo.machineModel].items + for _, item in pairs(items) do + menu.items[#menu.items + 1] = { + title = item.label, + description = 'Price: $' .. item.price, + onSelect = function() + local input = lib.inputDialog('Purchase Amount', { + { type = 'number', label = 'Amount', min = 1, max = 10, default = 1 } + }) + + if input and input[1] then + TriggerServerEvent('vendingmachines:server:processPurchase', + machineInfo.isPlayerOwned, + machineInfo.isPlayerOwned and machineInfo.machineId or machineInfo.machineModel, + item.name, + input[1]) + end + end + } + end + + lib.registerContext(menu) + lib.showContext('vending_menu') +end + +local function StartRobbery(machineInfo) + QBCore.Functions.TriggerCallback('vendingmachines:server:hasItem', function(hasItem) + if hasItem then + local success = lib.skillCheck({ 'easy', 'easy', { areaSize = 60, speedMultiplier = 1 } }, { 'w', 'a', 's', 'd' }) + + if success then + QBCore.Functions.Progressbar('robbing_machine', 'Robbing vending machine...', + Config.RobberyTime * 1000, false, true, { + disableMovement = true, + disableCarMovement = true, + disableMouse = false, + disableCombat = true, + }, { + animDict = 'mini@safe_cracking', + anim = 'idle_base', + flags = 16, + }, {}, {}, function() + TriggerServerEvent('vendingmachines:server:completeRobbery', + machineInfo.isPlayerOwned, + machineInfo.isPlayerOwned and machineInfo.machineId or nil) + end, function() + TriggerServerEvent('vendingmachines:server:robberyFailed', + machineInfo.isPlayerOwned, + machineInfo.isPlayerOwned and machineInfo.machineId or nil) + end) + else + QBCore.Functions.Notify('Robbery failed', 'error') + end + else + QBCore.Functions.Notify('You don\'t have the required item', 'error') + end + end, Config.RobberyItem) +end + +-- Events +RegisterNetEvent('vendingmachines:client:openMenu', function(data) + OpenVendingMenu(data) +end) + +RegisterNetEvent('vendingmachines:client:registerMachine', function() + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local obj = GetClosestObjectOfType(coords, 3.0, GetHashKey('prop_vend_soda_01'), false, false, false) + + if DoesEntityExist(obj) then + local modelHash = GetEntityModel(obj) + local validModel = false + + for _, model in pairs(Config.PlayerOwnedMachines.Models) do + if model == modelHash then + validModel = true + break + end + end + + if not validModel then + QBCore.Functions.Notify('This vending machine cannot be owned', 'error') + return + end + + local objCoords = GetEntityCoords(obj) + TriggerServerEvent('vendingmachines:server:registerMachine', modelHash, objCoords) + else + QBCore.Functions.Notify('No vending machine nearby', 'error') + end +end) + +RegisterNetEvent('vendingmachines:client:startRobbery', function(data) + StartRobbery(data) +end) + +RegisterNetEvent('vendingmachines:client:refreshPlayerMachines', function() + RefreshPlayerMachines() +end) + +RegisterNetEvent('vendingmachines:client:restockMenu', function(data) + local input = lib.inputDialog('Restock Amount', { + { type = 'number', label = 'Amount', min = 1, default = 1 } + }) + + if input and input[1] then + TriggerServerEvent('vendingmachines:server:restockMachine', data.machineId) + end +end) + +RegisterNetEvent('vendingmachines:client:collectEarnings', function(data) + TriggerServerEvent('vendingmachines:server:collectEarnings', data.machineId) +end) + +-- Initialization +AddEventHandler('QBCore:Client:OnPlayerLoaded', function() + PlayerData = QBCore.Functions.GetPlayerData() + SetupTarget() + RefreshPlayerMachines() +end) + +AddEventHandler('QBCore:Client:OnJobUpdate', function(job) + PlayerData.job = job +end) + +AddEventHandler('onResourceStart', function(resource) + if GetCurrentResourceName() == resource then + PlayerData = QBCore.Functions.GetPlayerData() + SetupTarget() + Citizen.SetTimeout(5000, function() + RefreshPlayerMachines() + end) + end +end) diff --git a/resources/[Developer]/[Nordi]/nordi_vending/config.lua b/resources/[Developer]/[Nordi]/nordi_vending/config.lua new file mode 100644 index 000000000..cc0f34130 --- /dev/null +++ b/resources/[Developer]/[Nordi]/nordi_vending/config.lua @@ -0,0 +1,70 @@ +local Config = {} + +-- General Settings +Config.UseQBTarget = true +Config.UseOxLib = true +Config.Inventory = 'qs-inventory' -- or 'qb-inventory' + +-- Robbery Settings +Config.EnableRobbery = true +Config.RobberyItem = 'lockpick' -- item needed to rob +Config.MinRobberyCash = 50 +Config.MaxRobberyCash = 250 +Config.RobberyTime = 15 -- seconds +Config.PoliceJob = 'police' +Config.Dispatch = 'ps-dispatch' -- or 'qb-dispatch' +Config.RobberyAlertChance = 70 -- percentage chance police get alerted + +-- Player-owned Vending Machines +Config.PlayerOwnedMachines = { + AllowedJobs = { -- jobs that can restock/collect money + 'vending', + 'delivery' + }, + Models = { + `prop_vend_soda_01`, + `prop_vend_soda_02`, + `prop_vend_water_01` + }, + RestockItem = 'sodasyrup', -- item needed to restock + StockAmount = 10, -- how much stock restock item provides + PricePerItem = 10, -- how much player earns per sale + MaxStock = 50, + OwnerCut = 0.7 -- percentage owner gets (30% goes to business) +} + +-- 24/7 Vending Machines +Config.DefaultMachines = { + Models = { + [`prop_vend_soda_01`] = { + items = { + { name = 'water_bottle', price = 5, label = 'Water' }, + { name = 'kurkakola', price = 7, label = 'Cola' }, + { name = 'sprunk', price = 7, label = 'Sprunk' } + } + }, + [`prop_vend_soda_02`] = { + items = { + { name = 'water_bottle', price = 5, label = 'Water' }, + { name = 'ecola', price = 8, label = 'eCola' } + } + }, + [`prop_vend_coffe_01`] = { + items = { + { name = 'coffee', price = 10, label = 'Coffee' } + } + } + } +} + +-- Target Options +Config.TargetOptions = { + useZones = true, -- create target zones for machines + distance = 2.0 +} + +-- Notification Settings +Config.Notify = 'qb' -- or 'ox', 'okok', 'esx' +Config.Locale = 'en' -- if using locale files + +return Config diff --git a/resources/[Developer]/[Nordi]/nordi_vending/fxmanifest.lua b/resources/[Developer]/[Nordi]/nordi_vending/fxmanifest.lua new file mode 100644 index 000000000..b169d11be --- /dev/null +++ b/resources/[Developer]/[Nordi]/nordi_vending/fxmanifest.lua @@ -0,0 +1,30 @@ +fx_version 'cerulean' +game 'gta5' + +name 'QB-VendingMachines' +author 'Nordi' +description 'Advanced Vending Machine System for QB-Core' +version '1.0.0' + +shared_scripts { + 'config.lua', + '@qb-core/shared/locale.lua', + 'locales/en.lua' -- add other locales as needed +} + +client_scripts { + '@qb-target/client.lua', + 'client/main.lua' +} + +server_scripts { + '@oxmysql/lib/MySQL.lua', + 'server/main.lua' +} + +dependencies { + 'qb-core', + 'qb-target', + 'qs-inventory', + 'ox_lib' -- or 'ox_lib' if using newer version +} diff --git a/resources/[Developer]/[Nordi]/nordi_vending/server/main.lua b/resources/[Developer]/[Nordi]/nordi_vending/server/main.lua new file mode 100644 index 000000000..c130ad9e9 --- /dev/null +++ b/resources/[Developer]/[Nordi]/nordi_vending/server/main.lua @@ -0,0 +1,316 @@ +local QBCore = exports['qb-core']:GetCoreObject() +local Config = require 'config' + +-- SQL Setup +local function SetupDatabase() + local query = [[ + CREATE TABLE IF NOT EXISTS player_vending_machines ( + id INT AUTO_INCREMENT PRIMARY KEY, + owner VARCHAR(50) NOT NULL, + model_hash BIGINT NOT NULL, + location LONGTEXT NOT NULL, + stock INT DEFAULT 0, + earnings DECIMAL(10,2) DEFAULT 0, + last_collected BIGINT DEFAULT 0, + UNIQUE KEY unique_machine (owner, model_hash, location(255)) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + ]] + MySQL.ready(function() + MySQL.query(query, {}, function(result) + print('^2[Vending Machines]^7 Database table initialized') + end) + end) +end + +-- Global state for 24/7 machine robberies +local robberyCooldown = {} + +-- Register usable items +QBCore.Functions.CreateUseableItem(Config.RobberyItem, function(source) + TriggerClientEvent('vendingmachines:client:startRobbery', source) +end) + +if Config.PlayerOwnedMachines.RestockItem then + QBCore.Functions.CreateUseableItem(Config.PlayerOwnedMachines.RestockItem, function(source) + TriggerClientEvent('vendingmachines:client:startRestock', source) + end) +end + +-- Player-owned machine management +local function GetPlayerMachines(citizenid) + local result = MySQL.query.await('SELECT * FROM player_vending_machines WHERE owner = ?', { citizenid }) + return result +end + +local function GetMachineById(id) + local result = MySQL.query.await('SELECT * FROM player_vending_machines WHERE id = ?', { id }) + return result[1] +end + +local function RegisterPlayerMachine(source, modelHash, coords) + local Player = QBCore.Functions.GetPlayer(source) + if not Player then return false end + + local location = json.encode({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + local result = MySQL.insert.await([[ + INSERT INTO player_vending_machines (owner, model_hash, location) + VALUES (?, ?, ?) + ]], { Player.PlayerData.citizenid, modelHash, location }) + + if result then + TriggerClientEvent('vendingmachines:client:refreshPlayerMachines', -1) + return true + end + return false +end + +local function RestockMachine(machineId, amount) + local machine = GetMachineById(machineId) + if not machine then return false end + + local newStock = math.min(machine.stock + amount, Config.PlayerOwnedMachines.MaxStock) + MySQL.update.await('UPDATE player_vending_machines SET stock = ? WHERE id = ?', { newStock, machineId }) + return true +end + +local function CollectEarnings(machineId) + local machine = GetMachineById(machineId) + if not machine or machine.earnings <= 0 then return 0 end + + local amount = machine.earnings + MySQL.update.await('UPDATE player_vending_machines SET earnings = 0, last_collected = ? WHERE id = ?', + { os.time(), machineId }) + return amount +end + +-- Handle vending machine purchases +local function ProcessPurchase(source, isPlayerOwned, machineId, itemName, amount) + local Player = QBCore.Functions.GetPlayer(source) + if not Player then return false end + + if isPlayerOwned then + -- Player-owned machine purchase + local machine = GetMachineById(machineId) + if not machine or machine.stock < amount then return false end + + local itemData = nil + for _, item in pairs(Config.DefaultMachines.Models[machine.model_hash].items) do + if item.name == itemName then + itemData = item + break + end + end + + if not itemData then return false end + + local totalPrice = itemData.price * amount + if Player.Functions.RemoveMoney('cash', totalPrice) then + local earnings = totalPrice + local ownerCut = math.floor(earnings * Config.PlayerOwnedMachines.OwnerCut) + local businessCut = earnings - ownerCut + + MySQL.update.await('UPDATE player_vending_machines SET stock = stock - ?, earnings = earnings + ? WHERE id = ?', + { amount, businessCut, machineId }) + + -- Give item to player + Player.Functions.AddItem(itemName, amount) + return true + end + else + -- 24/7 machine purchase + local modelHash = tonumber(machineId) + local machineItems = Config.DefaultMachines.Models[modelHash] + if not machineItems then return false end + + local itemData = nil + for _, item in pairs(machineItems.items) do + if item.name == itemName then + itemData = item + break + end + end + + if not itemData then return false end + + local totalPrice = itemData.price * amount + if Player.Functions.RemoveMoney('cash', totalPrice) then + Player.Functions.AddItem(itemName, amount) + return true + end + end +end + +-- Robbery functions +local function AlertPolice(machineCoords) + if Config.Dispatch == 'ps-dispatch' then + exports['ps-dispatch']:VendingMachineRobbery(machineCoords) + elseif Config.Dispatch == 'qb-dispatch' then + TriggerEvent('qb-dispatch:officerDistress', { + dispatchCode = '10-31', + firstStreet = GetStreetAndZone(machineCoords), + priority = 2, + origin = { + x = machineCoords.x, + y = machineCoords.y, + z = machineCoords.z + }, + blip = { + sprite = 52, + scale = 1.5, + color = 1, + flashes = true, + text = 'Vending Machine Robbery', + time = 5 + } + }) + end +end + +local function CompleteRobbery(source, isPlayerOwned, machineId) + local Player = QBCore.Functions.GetPlayer(source) + if not Player then return false end + + if robberyCooldown[source] and os.time() - robberyCooldown[source] < 300 then + TriggerClientEvent('QBCore:Notify', source, 'You need to wait before robbing again', 'error') + return false + end + + if Player.Functions.RemoveItem(Config.RobberyItem, 1) then + local reward = math.random(Config.MinRobberyCash, Config.MaxRobberyCash) + Player.Functions.AddMoney('cash', reward) + + if math.random(1, 100) <= Config.RobberyAlertChance then + local coords = GetEntityCoords(GetPlayerPed(source)) + AlertPolice(coords) + end + + robberyCooldown[source] = os.time() + + if isPlayerOwned then + local machine = GetMachineById(machineId) + if machine then + MySQL.update.await('UPDATE player_vending_machines SET stock = GREATEST(0, stock - ?) WHERE id = ?', + { math.random(5, 15), machineId }) + end + end + + return true + end + return false +end + +-- Server Events +RegisterNetEvent('vendingmachines:server:registerMachine', function(modelHash, coords) + local src = source + if RegisterPlayerMachine(src, modelHash, coords) then + TriggerClientEvent('QBCore:Notify', src, 'Vending machine registered successfully', 'success') + else + TriggerClientEvent('QBCore:Notify', src, 'Failed to register vending machine', 'error') + end +end) + +RegisterNetEvent('vendingmachines:server:processPurchase', function(isPlayerOwned, machineId, itemName, amount) + local src = source + if ProcessPurchase(src, isPlayerOwned, machineId, itemName, amount) then + TriggerClientEvent('QBCore:Notify', src, 'Purchase successful', 'success') + else + TriggerClientEvent('QBCore:Notify', src, 'Purchase failed', 'error') + end +end) + +RegisterNetEvent('vendingmachines:server:restockMachine', function(machineId) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if not Player then return end + + local jobName = Player.PlayerData.job.name + local allowed = false + for _, job in pairs(Config.PlayerOwnedMachines.AllowedJobs) do + if job == jobName then + allowed = true + break + end + end + + if not allowed then + TriggerClientEvent('QBCore:Notify', src, 'You are not authorized to restock machines', 'error') + return + end + + if Player.Functions.RemoveItem(Config.PlayerOwnedMachines.RestockItem, 1) then + if RestockMachine(machineId, Config.PlayerOwnedMachines.StockAmount) then + TriggerClientEvent('QBCore:Notify', src, 'Machine restocked successfully', 'success') + else + Player.Functions.AddItem(Config.PlayerOwnedMachines.RestockItem, 1) + TriggerClientEvent('QBCore:Notify', src, 'Failed to restock machine', 'error') + end + else + TriggerClientEvent('QBCore:Notify', src, 'You don\'t have the restock item', 'error') + end +end) + +RegisterNetEvent('vendingmachines:server:collectEarnings', function(machineId) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if not Player then return end + + local jobName = Player.PlayerData.job.name + local allowed = false + for _, job in pairs(Config.PlayerOwnedMachines.AllowedJobs) do + if job == jobName then + allowed = true + break + end + end + + if not allowed then + TriggerClientEvent('QBCore:Notify', src, 'You are not authorized to collect earnings', 'error') + return + end + + local amount = CollectEarnings(machineId) + if amount > 0 then + Player.Functions.AddMoney('cash', amount) + TriggerClientEvent('QBCore:Notify', src, string.format('Collected $%d from the machine', amount), 'success') + else + TriggerClientEvent('QBCore:Notify', src, 'No earnings to collect', 'error') + end +end) + +RegisterNetEvent('vendingmachines:server:completeRobbery', function(isPlayerOwned, machineId) + local src = source + if CompleteRobbery(src, isPlayerOwned, machineId) then + TriggerClientEvent('QBCore:Notify', src, 'Robbery successful', 'success') + else + TriggerClientEvent('QBCore:Notify', src, 'Robbery failed', 'error') + end +end) + +-- Commands +QBCore.Commands.Add('registermachine', 'Register a player-owned vending machine', {}, false, function(source) + TriggerClientEvent('vendingmachines:client:registerMachine', source) +end, 'admin') + +QBCore.Commands.Add('mymachines', 'View your owned vending machines', {}, false, function(source) + local Player = QBCore.Functions.GetPlayer(source) + if not Player then return end + + local machines = GetPlayerMachines(Player.PlayerData.citizenid) + if #machines > 0 then + local msg = "Your machines:\n" + for _, machine in pairs(machines) do + msg = msg .. string.format("ID: %d | Stock: %d | Earnings: $%.2f\n", machine.id, machine.stock, machine.earnings) + end + TriggerClientEvent('chat:addMessage', source, { args = { 'SYSTEM', msg } }) + else + TriggerClientEvent('QBCore:Notify', source, 'You don\'t own any machines', 'error') + end +end) + +-- Initialize +SetupDatabase() diff --git a/resources/[Developer]/[Nordi]/qb-vehiclesales-main.zip b/resources/[Developer]/[Nordi]/qb-vehiclesales-main.zip new file mode 100644 index 000000000..7567da044 Binary files /dev/null and b/resources/[Developer]/[Nordi]/qb-vehiclesales-main.zip differ diff --git a/resources/[carscripts]/mt_dealerships/configs/vehicles.lua b/resources/[carscripts]/mt_dealerships/configs/vehicles.lua index b4c29d1fe..f7ea9dd44 100644 --- a/resources/[carscripts]/mt_dealerships/configs/vehicles.lua +++ b/resources/[carscripts]/mt_dealerships/configs/vehicles.lua @@ -671,23 +671,27 @@ local vehicles = { -- Vehicle list, credits to qb-core! -- Import Trucks - { model = 'brickadeb', name = 'Brickader Boxtruck', brand = 'MTL', price = 80000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'brickadef', name = 'Brickader Flatbed', brand = 'MTL', price = 80000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'nmule', name = 'Mule 4x4', brand = 'Maibatsu', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'gbvoyagerb2', name = 'Voyager Boxtruck', brand = 'MTL', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'mulef', name = 'Mule Flatbed', brand = 'Maibatsu', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'brickaderv', name = 'Brickader Camper', brand = 'MTL', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'sandroamer', name = 'Sandroamer Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'sandkingrv', name = 'Sandking Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'guardianrv', name = 'Guardian Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'cararv', name = 'Caracara Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, - { model = 'galaxyroamer', name = 'Galaxy Roamer', brand = 'Brute', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'brickadeb', name = 'Brickader Boxtruck', brand = 'MTL', price = 80000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'brickadef', name = 'Brickader Flatbed', brand = 'MTL', price = 80000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'nmule', name = 'Mule 4x4', brand = 'Maibatsu', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'gbvoyagerb2', name = 'Voyager Boxtruck', brand = 'MTL', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'mulef', name = 'Mule Flatbed', brand = 'Maibatsu', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'brickaderv', name = 'Brickader Camper', brand = 'MTL', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'sandroamer', name = 'Sandroamer Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'sandkingrv', name = 'Sandking Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'guardianrv', name = 'Guardian Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'cararv', name = 'Caracara Camper', brand = 'Vapid', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + { model = 'galaxyroamer', name = 'Galaxy Roamer', brand = 'Brute', price = 55000, category = 'importtrucks', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, + + + -- Trailer + { model = ' boattrailer', name = 'Bootsanhänger', brand = 'HVY', price = 8000, category = 'trailer', shop = { 'cardealer', 'fmpdm', 'laryscars' } }, -- Import Cars - { model = 'gb811s2', name = '811 S2', brand = 'Pfister', price = 80000, category = 'importcars', shop = { 'fussion' } }, - { model = 'gbadmiral', name = 'Admiral', brand = 'Declasse', price = 80000, category = 'importcars', shop = { 'fussion' } }, - { model = 'gbargento7f', name = 'Argento 7F', brand = 'Obey', price = 80000, category = 'importcars', shop = { 'fussion' } }, - { model = 'gbbanshees', name = 'Banshee ', brand = 'Bravado', price = 80000, category = 'importcars', shop = { 'fussion' } }, + { model = 'gb811s2', name = '811 S2', brand = 'Pfister', price = 80000, category = 'importcars', shop = { 'fussion' } }, + { model = 'gbadmiral', name = 'Admiral', brand = 'Declasse', price = 80000, category = 'importcars', shop = { 'fussion' } }, + { model = 'gbargento7f', name = 'Argento 7F', brand = 'Obey', price = 80000, category = 'importcars', shop = { 'fussion' } }, + { model = 'gbbanshees', name = 'Banshee ', brand = 'Bravado', price = 80000, category = 'importcars', shop = { 'fussion' } }, diff --git a/resources/[carscripts]/mt_dealerships/dealerships/trucks.lua b/resources/[carscripts]/mt_dealerships/dealerships/trucks.lua index c665cc97f..0aca1c2a4 100644 --- a/resources/[carscripts]/mt_dealerships/dealerships/trucks.lua +++ b/resources/[carscripts]/mt_dealerships/dealerships/trucks.lua @@ -33,6 +33,8 @@ Config.dealerships.cardealer = { -- Dealership ID, NEEDS TO BE THE SAME AS THE J { label = 'LKWS', id = 'trucks' }, { label = 'Import LKWS', id = 'importtrucks' }, { label = 'Vans', id = 'vans' }, + { label = 'Anhänger', id = 'trailer' }, + }, pickups = { vec4(1201.35, -3187.03, 5.98, 175.35) diff --git a/resources/[inventory]/cs_shops/config/config.lua b/resources/[inventory]/cs_shops/config/config.lua index 9230691b7..7cab5d45d 100644 --- a/resources/[inventory]/cs_shops/config/config.lua +++ b/resources/[inventory]/cs_shops/config/config.lua @@ -2452,7 +2452,7 @@ CodeStudio.Shops = { [1] = 'medic_items', }, requiredJob = { - ['ambulance'] = {11,10,9} + ['ambulance'] = {11,10,9,8} }, Locations = { vector4(-1830.3236, -389.1446, 49.3909, 3) diff --git a/resources/[inventory]/qs-inventory/html/images/ecola_dose.png b/resources/[inventory]/qs-inventory/html/images/ecola_dose.png index 33ef805d2..93c50d8be 100644 Binary files a/resources/[inventory]/qs-inventory/html/images/ecola_dose.png and b/resources/[inventory]/qs-inventory/html/images/ecola_dose.png differ diff --git a/resources/[inventory]/qs-inventory/html/images/ecolabottle.png b/resources/[inventory]/qs-inventory/html/images/ecola_flasche.png similarity index 100% rename from resources/[inventory]/qs-inventory/html/images/ecolabottle.png rename to resources/[inventory]/qs-inventory/html/images/ecola_flasche.png diff --git a/resources/[inventory]/qs-inventory/html/images/ecolazerobottle.png b/resources/[inventory]/qs-inventory/html/images/ecola_zero_flasche.png similarity index 100% rename from resources/[inventory]/qs-inventory/html/images/ecolazerobottle.png rename to resources/[inventory]/qs-inventory/html/images/ecola_zero_flasche.png diff --git a/resources/[jobs]/[weapons]/cavok_weapon_handling/config.lua b/resources/[jobs]/[weapons]/cavok_weapon_handling/config.lua index c3f64e4a3..6e97d7ce2 100644 --- a/resources/[jobs]/[weapons]/cavok_weapon_handling/config.lua +++ b/resources/[jobs]/[weapons]/cavok_weapon_handling/config.lua @@ -97,7 +97,8 @@ Config.RagdollTime = { Config.rubberBulletWeapons = { [94989220], [-2009644972], - [-86904375] + [-86904375], + [911657153], } @@ -196,7 +197,7 @@ Config.WeaponRecoil = { [-771403250] = 3.0, --WEAPON_HEAVYPISTOL [137902532] = 2.5, --WEAPON_VINTAGEPISTOL [-598887786] = 4.5, --WEAPON_MARKSMANPISTOL - [584646201] = 2.4, --WEAPON_APPISTOL + [584646201] = 1.8, --WEAPON_APPISTOL [911657153] = 0.02, --WEAPON_STUNGUN [1198879012] = 1.3, --WEAPON_FLAREGUN [-1746263880] = 3.5, --WEAPON_DOUBLEACTION @@ -216,13 +217,13 @@ Config.WeaponRecoil = { [-1121678507] = 2.4, --WEAPON_MINISMG --ASSAULT RIFLES - [-1074790547] = 2.5, --WEAPON_ASSAULTRIFLE + [-1074790547] = 2.2, --WEAPON_ASSAULTRIFLE [961495388] = 2.5, --WEAPON_ASSAULTRIFLEMK2 - [-2084633992] = 2.3, --WEAPON_CARBINERIFLE + [-2084633992] = 2.0, --WEAPON_CARBINERIFLE [-86904375] = 2.3, --WEAPON_CARBINERIFLEMK2 [-1357824103] = 2.5, --WEAPON_ADVANCEDRIFLE - [-1063057011] = 2.4, --WEAPON_SPECIALCARBINE - [2132975508] = 2.4, --WEAPON_BULLPUPRIFLE + [-1063057011] = 2.0, --WEAPON_SPECIALCARBINE + [2132975508] = 2.2, --WEAPON_BULLPUPRIFLE [1649403952] = 2.0, --WEAPON_COMPACTRIFLE --SNIPER RIFLES diff --git a/resources/[phone]/roadphone/addons/jobcalls/config.lua b/resources/[phone]/roadphone/addons/jobcalls/config.lua index f83fba430..438600ac0 100644 --- a/resources/[phone]/roadphone/addons/jobcalls/config.lua +++ b/resources/[phone]/roadphone/addons/jobcalls/config.lua @@ -128,7 +128,27 @@ JobCalls.Positions = { display = 4 } }, - + { + name = "Santoro", + coords = vector3(162.3750, 268.6166, 109.9737), + number = 3131, + needjob = "sud", + useMarker = true, + marker = { + drawDistance = 10.0, + type = 25, + size = {x = 1.0, y = 1.0, z = 1.0}, + color = {r = 50, g = 50, b = 204} + }, + blip = { + active = false, + name = "Santoro Control Center", + sprite = 60, + color = 38, + scale = 0.8, + display = 4 + } + }, } \ No newline at end of file diff --git a/resources/[phone]/roadphone/public/img/service/sud.png b/resources/[phone]/roadphone/public/img/service/sud.png new file mode 100644 index 000000000..5aa673ac4 Binary files /dev/null and b/resources/[phone]/roadphone/public/img/service/sud.png differ diff --git a/resources/[phone]/roadphone/public/static/config/config.json b/resources/[phone]/roadphone/public/static/config/config.json index 3187604be..9ab30a243 100644 --- a/resources/[phone]/roadphone/public/static/config/config.json +++ b/resources/[phone]/roadphone/public/static/config/config.json @@ -70,21 +70,26 @@ "name": "Petrol Head Performance", "number": 5556969, "img": "/public/img/service/php.png", - "acceptMessage": false + "acceptMessage": true }, { "name": "Kayas Restaurant", "number": 5553022, "img": "/public/img/service/kayas.png", - "acceptMessage": false + "acceptMessage": true }, { "name": "Weazel News", "number": 404, "img": "/public/img/service/wn.png", - "acceptMessage": false + "acceptMessage": true + }, + { + "name": "Santoro Unlimited", + "number": 3131, + "img": "/public/img/service/sud.png", + "acceptMessage": true } - ], "Ringtones": {