Greetings everyone from Hane Studios Team!
As the Hane Studios team, we are happy to announce our new sub-studio, Hane Scripts.
Hane Script Release
Welcome to the hane-goldenpubjob, a detailed job script for the FiveM map called Hane Golden Pub. This resource is developed by Hane Scripts and is designed to enhance the gameplay experience of FiveM players who love roleplaying.
Introduction
The hane-goldenpubjob is a job script that allows players to work as bartenders, waiters, and cooks in a virtual pub called Golden Pub. Players can interact with customers, take orders, prepare food and drinks, and earn money for their services. The script is highly customizable and can be configured to suit different server setups.
Golden Pub Cfxre Topic
For Purchase the Golden Pub Job Script Only:
SOON
Features
- Framework related functions isolated so you can edit it the way you want.
- NUI menu that you can use to select your meal
- Dynamic menu system (Menu and prices can be set with ingredients from config file)
- Interactable objects (tables, chairs, cash register, kitchen appliances, etc.)
- Realistic work environment (players can simulate a real-life pub experience)
- Custom pathfinding algorithm for NPC Waiter
Planned Updates
We will implement more features to this resource and enhance the existing ones over the course of a month, as we aim to provide a useful and unique resource to addition to our Golden Pub. Here are some of the planned updates for the near future:
- Multiple job positions (bartender, waiter, cook)
- More enhanced AI system for customers (e.g. realistic behavior, preferences, and reactions)
- NUI POS (Point-of-sale) system for register
- Localization file for you to change the language
- Bug fixes and performance improvements
Dependencies
Server Related
- Onesync Infinity
- Server Artifact >= 5848
- Server Build >= 2699 (The Criminal Enterprises)
Resource Related
This resource uses some libraries such as target, zone, context menu. Currently this resource supports two stack.
QBCoreâs library stack
- PolyZone
- progressbar
- qb-menu
- qb-target
OXâs library stack
- ox_lib
- ox_target
This resource is optimized and tested for these two stack, however you might use ox_lib with qb-target or vice-versa and it shouldnât be a problem as long as you configure it through config.lua
.
If you have any suggestion for us to add support to please donât hesitate writing to us!
For inventory of your choice there are few methods that you should change to be able to use this resource. This resource comes with an ox_inventory configuration for now. We will continue to test and adapt other inventories as we progress with the updates.
Framework
To framework related stuff to work we isolated some functions for you edit so even if your framework has a different kind of implementation on a method you can still work it out. One of many configuration is QBCore with ox_inventory and you can see it below.
client/framework.lua
Framework = {}
local QBCore = exports['qb-core']:GetCoreObject()
RegisterNetEvent('QBCore:Client:UpdateObject')
AddEventHandler('QBCore:Client:UpdateObject', function()
QBCore = exports['qb-core']:GetCoreObject()
end)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
PlayerJob = QBCore.Functions.GetPlayerData().job
if PlayerJob.name == 'goldenpub' then
HasJob = true
else
HasJob = false
end
end)
Framework.IsBoss = function()
return PlayerJob.grade.level == 1
end
Framework.Notification = function(text, type, length)
TriggerEvent("QBCore:Notify", text, type, length)
end
Framework.GetItemLabel = function(itemName)
return QBCore.Shared.Items[itemName].label
end
Framework.GetItemDescription = function(itemName)
return QBCore.Shared.Items[itemName].description
end
Framework.GetPlayerCashMoney = function()
return QBCore.Functions.GetPlayerData().money['cash']
end
Framework.CheckIfAllIngredients = function(ingredients)
local PlayerData = QBCore.Functions.GetPlayerData()
local checkedIngredients = {}
for _, ingredient in pairs(ingredients) do
checkedIngredients[_] = false
end
for _, item in pairs(PlayerData.items) do
if ingredients[item.name] then
if item.count >= ingredients[item.name].amount then
checkedIngredients[item.name] = true
else
checkedIngredients[item.name] = false
end
end
end
for _, has in pairs(checkedIngredients) do
if not has then
return false
end
end
return true
end
Framework.DeleteItemsFromPlayer = function(ingredients)
local PlayerData = QBCore.Functions.GetPlayerData()
for _, item in pairs(PlayerData.items) do
if ingredients[item.name] then
if Config.Framework == "qb-core" then
TriggerServerEvent('QBCore:Server:AddItem', item.name, ingredients[item.name].amount)
elseif Config.Framework == "qbox" then
TriggerServerEvent('hane-goldenpubjob:server:removeItem', item.name, ingredients[item.name].amount)
end
end
end
end
Framework.GiveItemToPlayer = function(itemName, value)
if Config.Framework == "qb-core" then
TriggerServerEvent('QBCore:Server:AddItem', itemName, value)
elseif Config.Framework == "qbox" then
TriggerServerEvent('hane-goldenpubjob:server:giveItem', itemName, value)
end
end
Framework.openTableInventory = function(inventoryName)
if exports.ox_inventory:openInventory('stash', inventoryName) == false then
TriggerServerEvent('hane-goldenpub:server:createStash', inventoryName, 'Table', 20, 20000)
end
end
Framework.openTrayInventory = function()
if exports.ox_inventory:openInventory('stash', 'goldenpub-tray') == false then
TriggerServerEvent('hane-goldenpub:server:createStash', 'goldenpub-tray', 'Tray', 20, 20000)
end
end
Framework.openBarInventory = function()
if exports.ox_inventory:openInventory('stash', 'goldenpub-backbar') == false then
TriggerServerEvent('hane-goldenpub:server:createStash', 'goldenpub-backbar', 'Back Bar', 20, 20000)
end
end
Framework.TriggerCallback = function(callbackName, callback, args)
if Config.Framework == "qb-core" or Config.Framework == "qbox" then
if args then
QBCore.Functions.TriggerCallback(callbackName, callback, table.unpack(args))
else
QBCore.Functions.TriggerCallback(callbackName, callback)
end
elseif Config.Framework == "esx" then
if args then
ESX.TriggerServerCallback(callbackName, callback, table.unpack(args))
else
ESX.TriggerServerCallback(callbackName, callback)
end
end
end
server/framework.lua
Framework = {}
--- Getting Framework object. You can call it what ever you want.
local QBCore = exports['qb-core']:GetCoreObject()
RegisterNetEvent('QBCore:Server:UpdateObject')
AddEventHandler('QBCore:Server:UpdateObject', function()
QBCore = exports['qb-core']:GetCoreObject()
end)
RegisterNetEvent('QBCore:Server:OnJobUpdate', function(source, currJob)
TriggerClientEvent('hane-goldenpubjob:client:updatePlayerJob', source, currJob)
end)
Framework.GetAllPlayersHasJob = function()
local players = Framework.GetPlayers()
local workerTable = {}
local workerCount = 0
for _, src in pairs(players) do
local player = QBCore.Functions.GetPlayer(src)
if player.PlayerData.job.name == 'goldenpub' then
workerCount = workerCount + 1
workerTable[src] = {
firstname = player.PlayerData.charinfo.firstname,
lastname = player.PlayerData.charinfo.lastname,
}
end
end
return workerTable, workerCount
end
Framework.RemoveItem = function(source, itemName, amount)
local Player = QBCore.Functions.GetPlayer(source)
Player.Functions.RemoveItem(itemName, amount)
end
Framework.GiveItem = function(source, itemName, amount)
local Player = QBCore.Functions.GetPlayer(source)
Player.Functions.AddItem(itemName, amount, nil, {})
end
Framework.GetBusinessMoney = function()
return exports['qb-management']:GetAccount('goldenpub')
end
Framework.AddBusinessMoney = function(amount)
exports['qb-management']:AddMoney('goldenpub', amount)
end
Framework.RemoveBusinessMoney = function(amount)
local result = exports['qb-management']:RemoveMoney('goldenpub', amount)
return result
end
Framework.CreateStash = function(stashName, label, slot, weight)
exports.ox_inventory:RegisterStash(stashName, label, slot, weight, false)
end
Framework.RemovePlayerMoney = function(source, amount)
local Player = QBCore.Functions.GetPlayer(source)
local result = Player.Functions.RemoveMoney('cash', amount)
return result
end
Framework.AddPlayerMoney = function(source, amount)
local Player = QBCore.Functions.GetPlayer(source)
Player.Functions.AddMoney('cash', amount)
end
Framework.CreateCallback = function(callbackName, callback)
if Config.Framework == "qb-core" or Config.Framework == "qbox" then
QBCore.Functions.CreateCallback(callbackName, callback)
elseif Config.Framework == "esx" then
ESX.RegisterServerCallback(callbackName, callback)
end
end
Framework.SetTableInventory = function(items, tableNum)
local tableNumber = tostring(tableNum)
local isValid = exports.ox_inventory:GetInventory('hane-goldenpub-table-'..tableNumber, false)
if not isValid then
exports.ox_inventory:RegisterStash('hane-goldenpub-table-'..tableNumber, 'Table', 20, 20000, false)
end
for itemName, amount in pairs(items) do
local success, response = exports.ox_inventory:AddItem('hane-goldenpub-table-'..tableNumber, itemName, amount)
if not success then
return print(response)
end
end
end
Framework.GetPlayerFullName = function(player)
return player.PlayerData.charinfo.firstname .. " " .. player.PlayerData.charinfo.lastname
end
Framework.GetPlayers = function()
return QBCore.Functions.GetPlayers()
end
Framework.GetPlayer = function(source)
return QBCore.Functions.GetPlayer(source)
end
Framework.HireEmployee = function(targetSource)
local Target = QBCore.Functions.GetPlayer(targetSource)
if Target and Target.Functions.SetJob('goldenpub', 0) then
TriggerClientEvent('hane-goldenpubjob:client:notif', targetSource, 'You are hired as!', 'primary', 5000)
end
end
Framework.FireEmployee = function(targetSource)
local Target = QBCore.Functions.GetPlayer(targetSource)
if Target and Target.Functions.SetJob('unemployed', 0) then
TriggerClientEvent('hane-goldenpubjob:client:notif', targetSource, 'You have been fired!', 'secondary', 5000)
end
end
Configuration
The hane-goldenpubjob is highly customizable and can be configured to suit different server setups. Here are some of the configuration options that you can modify:
Menu items and prices (in the config.lua file)
You will be able to customise the menu you want to server in Golden Pub! In config.lua you will see Config.Menu table that you can edit the way you want. Indexes should be your item names and you can set the ingredients. We provided an example menu below.
Config.Menu
Config.Menu = {
[âstartersâ] = {
name = âStartersâ,
items = {
[âloadednachosâ] = {
name = âLoaded Nachosâ,
description = âTortilla chips stacked high with black beans, salsa, pepper-jack cheese, guacamole & sour creamâ,
price = 9.5,
ingredients = {
[âtortillachipâ] = {
amount = 4,
consume = true
},
[âblackbeansâ] = {
amount = 1,
consume = true
},
[âsalsaâ] = {
amount = 1,
consume = true
},
[âpepperjackcheeseâ] = {
amount = 1,
consume = true
},
[âguacamoleâ] = {
amount = 1,
consume = true
},
[âsourcreamâ] = {
amount = 1,
consume = true
}
}
},
}
}
}
When configuring Config.Menu you should also configure Config.MenuIndexes as the way you want them to show up in the menu. This defines the order of the categories.
Config.MenuIndexes
Config.MenuIndexes = {
âstartersâ,
âburgersâ,
âhot_drinksâ,
âdraftsâ,
âimporteddraftsâ
}
Your choice of libraries (in the config.lua file)
Framework related methods (in the client/framework.lua and server/framework.lua file)
Documentation Web Site for All Information
Installation
First of all this resource requires Onesync Infinity enabled because it uses state bags and server-side spawned and networked NPC. We tested in artifact 5848 and game build 2699 therefore we would advice to run this script at least in these versions.
Resource should be started after all dependencies and of course Golden Pub map.
For QBCore, you will need to add your items and goldenpub
job to your qb-core/shared/items.lua and qb-core/shared/jobs.lua
Items
-- Meals
["chipsanddip"] = {["name"] = "tortillachip", ["label"] = "Chips & Dip", ["weight"] = 100, ["type"] = "item", ["image"] = "chipsanddip.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["chickenquesadilla"] = {["name"] = "chickenquesadilla", ["label"] = "Chicken Quesadilla", ["weight"] = 100, ["type"] = "item", ["image"] = "chickenquesadilla.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["loadednachos"] = {["name"] = "loadednachos", ["label"] = "Loaded Nachos", ["weight"] = 100, ["type"] = "item", ["image"] = "loadednachos.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["mushroomswissburger"] = {["name"] = "mushroomswissburger", ["label"] = "Mushroom Swiss Burger", ["weight"] = 100, ["type"] = "item", ["image"] = "burger2.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["chickenclubburger"] = {["name"] = "chickenclubburger", ["label"] = "Chicken Club Burger", ["weight"] = 100, ["type"] = "item", ["image"] = "hamburger.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
-- Ingredients
["tortillachip"] = {["name"] = "tortillachip", ["label"] = "Tortilla Chips", ["weight"] = 100, ["type"] = "item", ["image"] = "tortillachip.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["chickenbreast"] = {["name"] = "chickenbreast", ["label"] = "Chicken Breast", ["weight"] = 100, ["type"] = "item", ["image"] = "chickenbreast.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["sourcream"] = {["name"] = "sourcream", ["label"] = "Sourcream", ["weight"] = 100, ["type"] = "item", ["image"] = "sauce.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["guacamole"] = {["name"] = "guacamole", ["label"] = "Guacamole", ["weight"] = 100, ["type"] = "item", ["image"] = "sauce.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["salsa"] = {["name"] = "salsa", ["label"] = "Salsa", ["weight"] = 100, ["type"] = "item", ["image"] = "sauce.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["blackbeans"] = {["name"] = "blackbeans", ["label"] = "Black Beans", ["weight"] = 100, ["type"] = "item", ["image"] = "blackbeans.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["pepperjackcheese"] = {["name"] = "pepperjackcheese", ["label"] = "Pepperjack Cheese", ["weight"] = 100, ["type"] = "item", ["image"] = "pepperjackcheese.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["lettuce"] = {["name"] = "lettuce", ["label"] = "Lettuce", ["weight"] = 100, ["type"] = "item", ["image"] = "lettuce.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["tomato"] = {["name"] = "tomato", ["label"] = "Tomato", ["weight"] = 100, ["type"] = "item", ["image"] = "tomato.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["sauteedmushroom"] = {["name"] = "sauteedmushroom", ["label"] = "Sauteed Mushroom", ["weight"] = 100, ["type"] = "item", ["image"] = "sauteedmushroom.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["swisscheese"] = {["name"] = "swisscheese", ["label"] = "Swiss Cheese", ["weight"] = 100, ["type"] = "item", ["image"] = "swisscheese.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["bacon"] = {["name"] = "bacon", ["label"] = "Bacon", ["weight"] = 100, ["type"] = "item", ["image"] = "bacon.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["redonion"] = {["name"] = "redonion", ["label"] = "Red Onion", ["weight"] = 100, ["type"] = "item", ["image"] = "onion.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["provolonecheese"] = {["name"] = "provolonecheese", ["label"] = "Provolone Cheese", ["weight"] = 100, ["type"] = "item", ["image"] = "provolonecheese.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["milk"] = {["name"] = "milk", ["label"] = "Milk", ["weight"] = 100, ["type"] = "item", ["image"] = "milk.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["water"] = {["name"] = "water", ["label"] = "Water", ["weight"] = 100, ["type"] = "item", ["image"] = "water.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["groundcoffee"] = {["name"] = "groundcoffee", ["label"] = "Ground Coffee", ["weight"] = 100, ["type"] = "item", ["image"] = "groundcoffee.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
-- Coffee
["filtercoffee"] = {["name"] = "filtercoffee", ["label"] = "Filter Coffee", ["weight"] = 100, ["type"] = "item", ["image"] = "filtercoffee.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["latte"] = {["name"] = "latte", ["label"] = "Latte", ["weight"] = 100, ["type"] = "item", ["image"] = "latte.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["espresso"] = {["name"] = "espresso", ["label"] = "Espresso", ["weight"] = 100, ["type"] = "item", ["image"] = "espresso.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
-- Alcohols
-- Draft Beers
["budweiser"] = {["name"] = "budweiser", ["label"] = "Budweiser", ["weight"] = 100, ["type"] = "item", ["image"] = "draftbeer.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["budlight"] = {["name"] = "budlight", ["label"] = "Bud Light", ["weight"] = 100, ["type"] = "item", ["image"] = "draftbeer.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["yuengling"] = {["name"] = "yuengling", ["label"] = "Yuengling", ["weight"] = 100, ["type"] = "item", ["image"] = "draftbeer.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
-- Imported Draft Beers
["guinnessstout"] = {["name"] = "guinnessstout", ["label"] = "Guinnessstout", ["weight"] = 100, ["type"] = "item", ["image"] = "beer.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["hoegaardenbelgianwhite"] = {["name"] = "hoegaardenbelgianwhite", ["label"] = "Hoegaarden Belgian White", ["weight"] = 100, ["type"] = "item", ["image"] = "beer.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["warsteinerpilsner"] = {["name"] = "warsteinerpilsner", ["label"] = "Warsteiner Pilsner", ["weight"] = 100, ["type"] = "item", ["image"] = "beer.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["lindemansframboise"] = {["name"] = "lindemansframboise", ["label"] = "Lindemans Framboise", ["weight"] = 100, ["type"] = "item", ["image"] = "beer.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
-- Whiskeys
["jameson"] = {["name"] = "jameson", ["label"] = "Jameson", ["weight"] = 100, ["type"] = "item", ["image"] = "whiskey.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
["jackdaniels"] = {["name"] = "jackdaniels", ["label"] = "Jack Danielâs", ["weight"] = 100, ["type"] = "item", ["image"] = "whiskey.png", ["unique"] = false, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = ""},
Jobs
['goldenpub'] = {
label = 'Golden Pub',
defaultDuty = true,
offDutyPay = false,
grades = {
[0] = {
name = 'Sales',
payment = 50
},
[1] = {
name = 'Boss',
payment = 50
}
},
},
For ESX, configurations and needed files will be shared with the next update.
Preview
Showcase
In this showcase both clients are on the same machine, normally resmon values should be around 0.01-0.02 while walking around the tables as the zones are creating and destructing, while targetting it can increase upto 0.04 and while creating and using context menus it can go upto 0.08-0.09 because all context menus are dynamically created. As you can see in the showcase the resmon values are doubled because of running two clients on the same machine.
Method caching done to increase the target and context menu performance. We will be working on these resmon values later on but it shouldnât affect much on the overall performance since they are not used constantly.
Credits
The hane-goldenpubjob is developed by Hane Scripts and is inspired by the FiveM communityâs love for roleplaying.
Hane Studios Resources
Mirror Park 18 Houses- Pack 2 | 18 Vintage house maps
[MLO] Mirror Park 18 House Pack 2 | 25% Christmas Sale
Mirror Park 7 Houses- Pack 1 | 7 Vintage house maps
[MLO] Mirror Park 7 House Pack 1 | 15% November Sale
Mirror Park Expansion | End of Construction
Mirror Park Expansion | End of Construction | 15% Black Friday Sale
Cigar Bar | A vintage Cigar Business
[MLO] Cigar Bar & Store | Pipe Down | 15% Summer Sale | 3 Location
Golden Pub | A Pub with classic gold details
[MLO] Golden Pub & Restaurant
Hogs Pub | A cafe inspired by the Harry Potter Series
[MLO] Hogs Pub & Restaurant | Harry Potter Inspired | 15% Summer Sale
Del Perro 2 Villas Pack | 2 Modern Villas
[MLO] Del Perro 2 Beach Villas Pack
Pond Cafe | A sweet cafe located at the Mirror Park pond
[MLO] Pond Cafe - Mirror Park
Bohem Beach
[YMAP] Bohem Beach
Vespucci 6 Villas 1
[MLO] Vespucci 6 Villas Pack
Vespucci 6 Villas 2
[MLO]Vespucci 6/12 Villas Pack 2
Cafe Cool Beans
[MLO] Cafe Cool Beans
Limeyâs Juice Bar
[MLO][PAID] Limey's Juice Bar
Trey Bakery&Cafe
[MLO][PAID] Trey Bakery&Cafe
For support, please DM to Hane Studiosâ forum Profile.
Code is accessible | Partially |
Subscription-based | No |
Lines (approximately) | Client ~= 1300 - Server ~= 1500 |
Requirements | Refer to Dependencies |
Support | Yes |