From 22a361479d8b32a455abeeb1b3b58e396474eab7 Mon Sep 17 00:00:00 2001 From: Apollyon <37031311+JusCampin@users.noreply.github.com> Date: Thu, 29 Aug 2024 10:24:09 -0700 Subject: [PATCH] Fix tamed horse registration cost (#121) * Update version * Update package.json * Update fxmanifest.lua * Update main.lua - Created separate functions for registering tamed horses - Housekeeping * Update main.lua - Integrated KeepTamedHorse function into tamed horse thread - housekeeping * Update main.lua - removed commented code * Update main.lua --- client/main.lua | 88 ++++++++++++++++++++++++++++++++++++------------- fxmanifest.lua | 2 +- server/main.lua | 83 ++++++++++++++++++++++++++++++++++++++++++++++ ui/package.json | 2 +- version | 2 +- 5 files changed, 151 insertions(+), 26 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4fb9772..37486a9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -117,6 +117,7 @@ CreateThread(function() end end) +---@param site string function OpenStable(site) DisplayRadar(false) InMenu = true @@ -135,6 +136,7 @@ function OpenStable(site) TriggerServerEvent('bcc-stables:GetMyHorses') end +---@param dataHorses table RegisterNetEvent('bcc-stables:ReceiveHorsesData', function(dataHorses) SendNUIMessage({ action = 'updateMyHorses', @@ -143,6 +145,7 @@ RegisterNetEvent('bcc-stables:ReceiveHorsesData', function(dataHorses) end) -- View Horses for Purchase +---@param data table RegisterNUICallback('loadHorse', function(data, cb) cb('ok') if MyEntity ~= 0 then @@ -174,9 +177,10 @@ RegisterNUICallback('loadHorse', function(data, cb) Citizen.InvokeNative(0x6585D955A68452A5, ShopEntity) -- ClearPedEnvDirt end) +---@param data table RegisterNUICallback('BuyHorse', function(data, cb) cb('ok') - CheckPlayerJob(true) + CheckPlayerJob(true, nil) if Stables[Site].trainerBuy and not IsTrainer then VORPcore.NotifyRightTip(_U('trainerBuyHorse'), 4000) StableMenu() @@ -196,6 +200,7 @@ RegisterNUICallback('BuyHorse', function(data, cb) end end) +---@param data table function SetHorseName(data) IsNaming = true if data.origin ~= 'tameHorse' then @@ -238,7 +243,7 @@ function SetHorseName(data) while not Citizen.InvokeNative(0x01FEE67DB37F59B2, playerPed) do -- IsPedOnFoot Wait(10) end - local horseSaved = VORPcore.Callback.TriggerAwait('bcc-stables:SaveNewHorse', data) + local horseSaved = VORPcore.Callback.TriggerAwait('bcc-stables:SaveTamedHorse', data) if horseSaved then DeleteEntity(data.mount) HorseBreed = false @@ -265,6 +270,7 @@ function SetHorseName(data) IsNaming = false end +---@param data table RegisterNUICallback('RenameHorse', function(data, cb) cb('ok') data.origin = 'updateHorse' @@ -272,6 +278,7 @@ RegisterNUICallback('RenameHorse', function(data, cb) end) -- View Owned Horse in Stable Menu +---@param data table RegisterNUICallback('loadMyHorse', function(data, cb) cb('ok') MyEntityID = data.HorseId @@ -316,6 +323,7 @@ RegisterNUICallback('loadMyHorse', function(data, cb) end end) +---@param data table RegisterNUICallback('selectHorse', function(data, cb) cb('ok') TriggerServerEvent('bcc-stables:SelectHorse', data) @@ -330,6 +338,7 @@ function GetSelectedHorse() end end +---@param data table RegisterNUICallback('CloseStable', function(data, cb) cb('ok') SendNUIMessage({ @@ -401,6 +410,8 @@ function StableMenu() TriggerServerEvent('bcc-stables:GetMyHorses') end +---@param horseEntity integer +---@param encodedComponents string RegisterNetEvent('bcc-stables:SetComponents', function(horseEntity, encodedComponents) local components = json.decode(encodedComponents) for _, component in pairs(components) do @@ -408,6 +419,7 @@ RegisterNetEvent('bcc-stables:SetComponents', function(horseEntity, encodedCompo end end) +---@param data table function SpawnHorse(data) if Spawning then return @@ -498,7 +510,7 @@ function SpawnHorse(data) MaxBonding = true end if Config.trainerOnly then - CheckPlayerJob(true) + CheckPlayerJob(true, nil) if IsTrainer then TriggerEvent('bcc-stables:HorseBonding') end @@ -980,7 +992,7 @@ CreateThread(function() goto END end if Config.trainerOnly then - CheckPlayerJob(true) + CheckPlayerJob(true, nil) if not IsTrainer then VORPcore.NotifyRightTip(_U('trainerSellHorse'), 4000) HorseBreed = false @@ -1001,7 +1013,7 @@ CreateThread(function() end end if Citizen.InvokeNative(0xE0F65F0640EF0617, KeepTame) then -- PromptHasHoldModeCompleted - CheckPlayerJob(true) + CheckPlayerJob(true, nil) if Config.trainerOnly then if not IsTrainer then VORPcore.NotifyRightTip(_U('trainerRegHorse'), 4000) @@ -1010,6 +1022,11 @@ CreateThread(function() end end local tameData = {} + if IsTrainer then + tameData.isTrainer = true + else + tameData.isTrainer = false + end tameData.ModelH = TamedModel tameData.origin = 'tameHorse' tameData.IsCash = true @@ -1019,7 +1036,12 @@ CreateThread(function() tameData.gender = 'female' end tameData.mount = mount - KeepTamedHorse(tameData) + local canKeep = VORPcore.Callback.TriggerAwait('bcc-stables:RegisterHorse', tameData) + if canKeep then + SetHorseName(tameData) + else + HorseBreed = false + end end end end @@ -1028,23 +1050,6 @@ CreateThread(function() end end) -function KeepTamedHorse(tameData) - if IsTrainer then - tameData.isTrainer = true - else - tameData.isTrainer = false - end - - tameData.Cash = Config.regCost - - local canKeep = VORPcore.Callback.TriggerAwait('bcc-stables:BuyHorse', tameData) - if canKeep then - SetHorseName(tameData) - else - HorseBreed = false - end -end - AddEventHandler('bcc-stables:CheckHorseHealth', function() if Citizen.InvokeNative(0x3317DEDB88C95038, MyHorse, false) then -- IsPedDeadOrDying if not InWrithe then @@ -1100,6 +1105,9 @@ AddEventHandler('bcc-stables:ReviveHorse', function() end end) +---@param horsePedId integer +---@param horseId integer +---@param isLooting boolean function OpenInventory(horsePedId, horseId, isLooting) local hasBags = Citizen.InvokeNative(0xFB4891BD7578CDC1, horsePedId, -2142954459) -- IsMetaPedUsingComponent @@ -1180,6 +1188,7 @@ AddEventHandler('bcc-stables:HorseBonding', function() end end) +---@param xpSource string function SaveXp(xpSource) local horseXp = nil local updateXp = { @@ -1413,6 +1422,7 @@ RegisterNetEvent('bcc-stables:BrushHorse', function() Citizen.InvokeNative(0x67C540AA08E4A6F5, 'Core_Fill_Up', 'Consumption_Sounds', true, 0) -- PlaySoundFrontend end) +---@param item string RegisterNetEvent('bcc-stables:FeedHorse', function(item) if not MyHorse or MyHorse == 0 then return VORPcore.NotifyRightTip(_U('noHorse'), 4000) @@ -1522,6 +1532,7 @@ function GetClosestPlayer() end -- Select Horse Tack from Menu +---@param data table RegisterNUICallback('Saddles', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1534,6 +1545,7 @@ RegisterNUICallback('Saddles', function(data, cb) end end) +---@param data table RegisterNUICallback('Saddlecloths', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1546,6 +1558,7 @@ RegisterNUICallback('Saddlecloths', function(data, cb) end end) +---@param data table RegisterNUICallback('Stirrups', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1558,6 +1571,7 @@ RegisterNUICallback('Stirrups', function(data, cb) end end) +---@param data table RegisterNUICallback('SaddleBags', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1570,6 +1584,7 @@ RegisterNUICallback('SaddleBags', function(data, cb) end end) +---@param data table RegisterNUICallback('Manes', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1582,6 +1597,7 @@ RegisterNUICallback('Manes', function(data, cb) end end) +---@param data table RegisterNUICallback('Tails', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1594,6 +1610,7 @@ RegisterNUICallback('Tails', function(data, cb) end end) +---@param data table RegisterNUICallback('SaddleHorns', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1606,6 +1623,7 @@ RegisterNUICallback('SaddleHorns', function(data, cb) end end) +---@param data table RegisterNUICallback('Bedrolls', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1618,6 +1636,7 @@ RegisterNUICallback('Bedrolls', function(data, cb) end end) +---@param data table RegisterNUICallback('Masks', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1630,6 +1649,7 @@ RegisterNUICallback('Masks', function(data, cb) end end) +---@param data table RegisterNUICallback('Mustaches', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1642,6 +1662,7 @@ RegisterNUICallback('Mustaches', function(data, cb) end end) +---@param data table RegisterNUICallback('Holsters', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1654,6 +1675,7 @@ RegisterNUICallback('Holsters', function(data, cb) end end) +---@param data table RegisterNUICallback('Bridles', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1666,6 +1688,7 @@ RegisterNUICallback('Bridles', function(data, cb) end end) +---@param data table RegisterNUICallback('Horseshoes', function(data, cb) cb('ok') if tonumber(data.id) == -1 then @@ -1678,16 +1701,20 @@ RegisterNUICallback('Horseshoes', function(data, cb) end end) +---@param entity integer +---@param hash number function SetComponent(entity, hash) Citizen.InvokeNative(0xD3A7B003ED343FD9, entity, tonumber(hash), true, true, true) -- ApplyShopItemToPed Citizen.InvokeNative(0xCC8CA3E88256E58F, entity, false, true, true, true, false) -- UpdatePedVariation end +---@param category integer function RemoveComponent(category) Citizen.InvokeNative(0xD710A5007C2AC539, MyEntity, category, 0) -- RemoveTagFromMetaPed Citizen.InvokeNative(0xCC8CA3E88256E58F, MyEntity, false, true, true, true, false) -- UpdatePedVariation end +---@param data table RegisterNUICallback('sellHorse', function(data, cb) cb('ok') DeleteEntity(MyEntity) @@ -1700,6 +1727,7 @@ RegisterNUICallback('sellHorse', function(data, cb) end end) +---@param dead boolean function SaveHorseStats(dead) local data = {} local healthCore, staminaCore @@ -1719,6 +1747,7 @@ function SaveHorseStats(dead) TriggerServerEvent('bcc-stables:SaveHorseStats', data, MyHorseId) end +---@param data table function SetHorseStats(data) Citizen.InvokeNative(0xC6258F41D86676E0, MyHorse, 0, data.health) -- SetAttributeCoreValue Citizen.InvokeNative(0xC6258F41D86676E0, MyHorse, 1, data.stamina) -- SetAttributeCoreValue @@ -1749,6 +1778,7 @@ function CameraLighting() end -- -- Rotate Horses while Viewing +---@param data table RegisterNUICallback('rotate', function(data, cb) cb('ok') local direction = data.RotateHorse @@ -1760,6 +1790,7 @@ RegisterNUICallback('rotate', function(data, cb) end end) +---@param dir integer function Rotation(dir) local entity = 0 @@ -1867,6 +1898,7 @@ function StartPrompts() PromptRegisterEnd(LootHorse) end +---@param menuGroup integer function HorseTargetPrompts(menuGroup) local currentLevel = Citizen.InvokeNative(0x147149F2E909323C, MyHorse, 7, Citizen.ResultAsInteger()) -- GetAttributeBaseRank @@ -1928,6 +1960,8 @@ function HorseTargetPrompts(menuGroup) end end +---@param trainer boolean +---@param site string function CheckPlayerJob(trainer, site) local result = VORPcore.Callback.TriggerAwait('bcc-stables:CheckJob', trainer, site) if trainer and result then @@ -1946,6 +1980,7 @@ function CheckPlayerJob(trainer, site) end end +---@param site string function AddTrainerBlip(site) local siteCfg = Trainers[site] siteCfg.TrainerBlip = Citizen.InvokeNative(0x554d9d53f696d002, 1664425300, siteCfg.npc.coords) -- BlipAddForCoords @@ -1953,6 +1988,8 @@ function AddTrainerBlip(site) Citizen.InvokeNative(0x9CB1A1623062F402, siteCfg.TrainerBlip, siteCfg.blip.name) -- SetBlipName end +---@param site string +---@param closed boolean function ManageStableBlip(site, closed) local siteCfg = Stables[site] @@ -1976,6 +2013,7 @@ function ManageStableBlip(site, closed) Citizen.InvokeNative(0x662D364ABF16DE2F, Stables[site].Blip, joaat(Config.BlipColors[color])) -- BlipAddModifier end +---@param site string function AddTrainerNPC(site) local siteCfg = Trainers[site] local modelName = siteCfg.npc.model @@ -1990,6 +2028,7 @@ function AddTrainerNPC(site) SetBlockingOfNonTemporaryEvents(siteCfg.TrainerNPC, true) end +---@param site string function AddStableNPC(site) local siteCfg = Stables[site] if not siteCfg.NPC then @@ -2007,6 +2046,7 @@ function AddStableNPC(site) end end +---@param site string function RemoveStableNPC(site) local siteCfg = Stables[site] if siteCfg.NPC then @@ -2015,6 +2055,8 @@ function RemoveStableNPC(site) end end +---@param model integer +---@param modelName string function LoadModel(model, modelName) if not IsModelValid(model) then return print('Invalid model:', modelName) diff --git a/fxmanifest.lua b/fxmanifest.lua index 19f7d9c..5341ef1 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -34,5 +34,5 @@ files { "ui/img/*.*" } -version '1.4.16' +version '1.4.17' diff --git a/server/main.lua b/server/main.lua index 187f580..cd30bf3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,16 +2,19 @@ local VORPcore = exports.vorp_core:GetCore() local CooldownData = {} +---@param data table VORPcore.Callback.Register('bcc-stables:BuyHorse', function(source, cb, data) local src = source local user = VORPcore.getUser(src) if not user then return cb(false) end local Character = user.getUsedCharacter local charid = Character.charIdentifier + local maxHorses = tonumber(Config.maxPlayerHorses) if data.isTrainer then maxHorses = tonumber(Config.maxTrainerHorses) end + local horses = MySQL.query.await('SELECT * FROM `player_horses` WHERE `charid` = ? AND `dead` = ?', { charid, 0 }) if #horses >= maxHorses then VORPcore.NotifyRightTip(src, _U('horseLimit') .. maxHorses .. _U('horses'), 4000) @@ -43,6 +46,37 @@ VORPcore.Callback.Register('bcc-stables:BuyHorse', function(source, cb, data) end end) +---@param data table +VORPcore.Callback.Register('bcc-stables:RegisterHorse', function(source, cb, data) + local src = source + local user = VORPcore.getUser(src) + if not user then return cb(false) end + local Character = user.getUsedCharacter + local charid = Character.charIdentifier + + local maxHorses = tonumber(Config.maxPlayerHorses) + if data.isTrainer then + maxHorses = tonumber(Config.maxTrainerHorses) + end + + local horses = MySQL.query.await('SELECT * FROM `player_horses` WHERE `charid` = ? AND `dead` = ?', { charid, 0 }) + if #horses >= maxHorses then + VORPcore.NotifyRightTip(src, _U('horseLimit') .. maxHorses .. _U('horses'), 4000) + cb(false) + return + end + + if data.IsCash and data.origin == 'tameHorse' then + if Character.money >= Config.regCost then + cb(true) + else + VORPcore.NotifyRightTip(src, _U('shortCash'), 4000) + cb(false) + end + end +end) + +---@param data table RegisterNetEvent('bcc-stables:BuyTack', function(data) local src = source local user = VORPcore.getUser(src) @@ -70,6 +104,7 @@ RegisterNetEvent('bcc-stables:BuyTack', function(data) TriggerClientEvent('bcc-stables:SaveComps', src) end) +---@param data table VORPcore.Callback.Register('bcc-stables:SaveNewHorse', function(source, cb, data) local src = source local user = VORPcore.getUser(src) @@ -103,6 +138,29 @@ VORPcore.Callback.Register('bcc-stables:SaveNewHorse', function(source, cb, data cb(true) end) +---@param data table +VORPcore.Callback.Register('bcc-stables:SaveTamedHorse', function(source, cb, data) + local src = source + local user = VORPcore.getUser(src) + if not user then return cb(false) end + local character = user.getUsedCharacter + local identifier = character.identifier + local charid = character.charIdentifier + + if data.IsCash and data.origin == 'tameHorse' then + if character.money >= Config.regCost then + character.removeCurrency(0, Config.regCost) + else + VORPcore.NotifyRightTip(src, _U('shortCash'), 4000) + return cb(false) + end + end + MySQL.query.await('INSERT INTO `player_horses` (identifier, charid, name, model, gender, captured) VALUES (?, ?, ?, ?, ?, ?)', + { identifier, charid, tostring(data.name), data.ModelH, data.gender, data.captured }) + cb(true) +end) + +---@param data table VORPcore.Callback.Register('bcc-stables:UpdateHorseName', function(source, cb, data) local src = source local user = VORPcore.getUser(src) @@ -116,6 +174,8 @@ VORPcore.Callback.Register('bcc-stables:UpdateHorseName', function(source, cb, d cb(true) end) +---@param Xp integer +---@param horseId integer RegisterServerEvent('bcc-stables:UpdateHorseXp', function(Xp, horseId) local src = source local user = VORPcore.getUser(src) @@ -128,6 +188,8 @@ RegisterServerEvent('bcc-stables:UpdateHorseXp', function(Xp, horseId) { Xp, horseId, identifier, charid }) end) +---@param data table +---@param horseId integer RegisterServerEvent('bcc-stables:SaveHorseStats', function(data, horseId) local src = source local user = VORPcore.getUser(src) @@ -140,6 +202,7 @@ RegisterServerEvent('bcc-stables:SaveHorseStats', function(data, horseId) { data.health, data.stamina, horseId, identifier, charid }) end) +---@param data table RegisterServerEvent('bcc-stables:SelectHorse', function(data) local src = source local user = VORPcore.getUser(src) @@ -162,6 +225,7 @@ RegisterServerEvent('bcc-stables:SelectHorse', function(data) end end) +---@param horseId integer VORPcore.Callback.Register('bcc-stables:DeselectHorse', function(source, cb, horseId) local src = source local user = VORPcore.getUser(src) @@ -175,6 +239,7 @@ VORPcore.Callback.Register('bcc-stables:DeselectHorse', function(source, cb, hor cb(true) end) +---@param horseId integer VORPcore.Callback.Register('bcc-stables:SetHorseDead', function(source, cb, horseId) local src = source local user = VORPcore.getUser(src) @@ -239,6 +304,9 @@ RegisterNetEvent('bcc-stables:GetMyHorses', function() TriggerClientEvent('bcc-stables:ReceiveHorsesData', src, horses) end) +---@param encodedComponents string +---@param horseId integer +---@param MyHorse_entity integer RegisterNetEvent('bcc-stables:UpdateComponents', function(encodedComponents, horseId, MyHorse_entity) local src = source local user = VORPcore.getUser(src) @@ -252,6 +320,7 @@ RegisterNetEvent('bcc-stables:UpdateComponents', function(encodedComponents, hor TriggerClientEvent('bcc-stables:SetComponents', src, MyHorse_entity, encodedComponents) end) +---@param data table VORPcore.Callback.Register('bcc-stables:SellMyHorse', function(source, cb, data) local src = source local user = VORPcore.getUser(src) @@ -289,6 +358,8 @@ VORPcore.Callback.Register('bcc-stables:SellMyHorse', function(source, cb, data) end end) +---@param type string +---@param charid integer local function SetPlayerCooldown(type, charid) CooldownData[type .. tostring(charid)] = os.time() end @@ -313,6 +384,7 @@ RegisterServerEvent('bcc-stables:SellTamedHorse', function(hash) end end) +---@param type string VORPcore.Callback.Register('bcc-stables:CheckPlayerCooldown', function(source, cb, type) local src = source local user = VORPcore.getUser(src) @@ -339,6 +411,8 @@ VORPcore.Callback.Register('bcc-stables:CheckPlayerCooldown', function(source, c end end) +---@param serverId integer +---@param horseId integer RegisterServerEvent('bcc-stables:SaveHorseTrade', function(serverId, horseId) -- Current Owner local src = source @@ -369,6 +443,8 @@ RegisterServerEvent('bcc-stables:SaveHorseTrade', function(serverId, horseId) end end) +---@param id integer +---@param model string RegisterServerEvent('bcc-stables:RegisterInventory', function(id, model) local isRegistered = exports.vorp_inventory:isCustomInventoryRegistered('horse_' .. tostring(id)) if isRegistered then return end @@ -395,6 +471,7 @@ RegisterServerEvent('bcc-stables:RegisterInventory', function(id, model) end end) +---@param id integer RegisterServerEvent('bcc-stables:OpenInventory', function(id) local src = source local user = VORPcore.getUser(src) @@ -411,6 +488,7 @@ for _, item in ipairs(Config.horseFood) do end) end +---@param item string RegisterServerEvent('bcc-stables:RemoveItem', function(item) local src = source local user = VORPcore.getUser(src) @@ -497,6 +575,8 @@ VORPcore.Callback.Register('bcc-stables:HorseReviveItem', function(source, cb) cb(true) end) +---@param trainer boolean +---@param site string VORPcore.Callback.Register('bcc-stables:CheckJob', function(source, cb, trainer, site) local src = source local user = VORPcore.getUser(src) @@ -523,6 +603,9 @@ VORPcore.Callback.Register('bcc-stables:CheckJob', function(source, cb, trainer, end end) +---@param charJob string +---@param jobGrade integer +---@param jobConfig table function CheckPlayerJob(charJob, jobGrade, jobConfig) for _, job in pairs(jobConfig) do if (charJob == job.name) and (tonumber(jobGrade) >= tonumber(job.grade)) then diff --git a/ui/package.json b/ui/package.json index da5f16e..38494d0 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,7 +1,7 @@ { "name": "bcc-stables", - "version": "1.4.16", + "version": "1.4.17", "private": true, "scripts": { diff --git a/version b/version index 8a70e13..3830d6a 100644 --- a/version +++ b/version @@ -1,2 +1,2 @@ -<1.4.16> +<1.4.17> See GitHub for details!