Compare commits

..

26 Commits

Author SHA1 Message Date
Jim Shield
a4e9333ab8 1.0.14 2024-02-23 15:47:08 +00:00
Jim Shield
e08b349e31 Version Bump 2024-02-20 12:44:25 +00:00
Jim Shield
2bf7a28508 fix typo 2024-02-20 12:43:51 +00:00
Jim Shield
e6bee2ae2e dui request callback 2024-02-19 17:57:51 +00:00
Jim Shield
fc832d73f9 dui request callback 2024-02-19 17:57:15 +00:00
Jim Shield
e8e9b53f53 port dui texture changes (needs mutliscripting) 2024-02-19 17:53:23 +00:00
Jim Shield
7304376e90 getDurability updates 2024-02-19 17:52:19 +00:00
Jim Shield
7e9914afda grav inv fixes 2024-02-19 17:50:19 +00:00
Jim Shield
89f6f6deb0 add jpr-phonesystem support 2024-02-16 22:45:22 +00:00
Jim Shield
f1ae24d0fe separate create dui event 2024-02-16 22:42:13 +00:00
Jim Shield
4848b51ecc Update README.md 2024-02-14 17:34:04 +00:00
Jim Shield
2aa0cc9d5d Start adding manual durability changes 2024-02-14 00:19:36 +00:00
Jim Shield
5e3ace804d Adjust ox/qb target name creation 2024-02-14 00:11:08 +00:00
Jim Shield
42b109a5f1 readability 2024-02-09 17:02:45 +00:00
Jim Shield
5a8afb516b Update README.md 2024-02-09 16:51:20 +00:00
Jim Shield
ef2771cc83 Update README.md 2024-02-09 16:49:29 +00:00
Jim Shield
942c11af1d Update README.md
Start adding documentation
2024-02-09 00:46:20 +00:00
Jim Shield
b291e3f4b6 Update functions.lua 2024-02-08 21:54:28 +00:00
Jim Shield
46e3f18edc Merge pull request #20 from jimathy/1.0.12
1.0.12
2024-02-08 18:58:37 +00:00
Jim Shield
0886d8a4b6 Version Bump 2024-02-08 18:39:30 +00:00
Jim Shield
6a23e4ac91 Move loadModel time reset 2024-02-08 18:39:02 +00:00
Jim Shield
f7b7718679 remove unused variable 2024-02-08 18:38:22 +00:00
Jim Shield
9ae034da77 remove unused variable 2024-02-08 18:38:11 +00:00
Jim Shield
4d1b2abd3d blip_info support preview imgs 2024-02-08 18:37:14 +00:00
Jim Shield
f8e3f64907 Origen Inv Fixes 2024-02-08 18:35:54 +00:00
Jim Shield
3702835958 Added sellMenu() 2024-02-08 18:34:17 +00:00
6 changed files with 955 additions and 31 deletions

593
README.md
View File

@@ -45,4 +45,595 @@ to
QBInv = "ps-inventory",
```
This will now use events from `ps-inventory` and use it through out the scripts.
This will now use events from `ps-inventory` and use it through out the scripts.
# WIP
## Documentation
This script brings alot of features to simplify making scripts with preset functions and automations.
It attempts to make use of configs from the scripts its loaded into. For example:
### `Config`
This needs to be in every script that uses it, a `System` table with Debug, Menu, Notify, drawText, progressBar
This is required to use jim_bridge with your script
```lua
Config = {
System = {
Debug = true, -- This enables Debug mode
-- Revealing debug prints and debug boxes on targets
Menu = "qb", -- This specifies what menu script will be loaded
-- "qb" = `qb-menu` and edited versions of it
-- "ox" = `ox_lib`'s context menu system
-- "gta" = `WarMenu' a free script for a gta style menu
Notify = "gta", -- This allows you to choose the notification system for scripts
-- "qb" = `qb-core`'s built in notifications
-- "ox" = `ox_lib`'s built in notifications
-- "esx" = `esx_notify` esx's default notifications
-- "okok" = `okok-notify` okok's notifications
-- "gta" = Native GTA style popups
drawText = "gta", -- The style of drawText you want to use
-- "qb" = `qb-core`'s drawText system
-- "ox" = `ox_lib`'s drawTextUI system
-- "gta" = Native GTA style popups
progressBar = "gta" -- The style of progressBar you want to use
-- "qb" = `qb-core`'s style progressBar
-- "ox" = `ox_lib`'s default progressBar
-- "gta" = Native GTA style "spinner"
},
}
```
### `openMenu(Menu, data)`
This handles creation of menus using `OX_Lib`, `qb-menu` or `WarMenu`
It uses mixed/new functions to bring more compatability to one another
`Menu` is your button entries and works like qb-menu or ox_lib, for example:
```lua
local Menu = {}
Menu[#Menu + 1] = {
isMenuHeader = true, -- This makes the current button unclickable
icon = invImg("lockpick") -- Supports fontawesome or custom images
-- This example use the custom function `invImg()` to retreive an nui:// link to the given item's image
arrow = true, -- Adds a arrow icon to the button (in qb-menu overrides the icon)
header = "Header Test", -- The header/title for the button
txt = "Text test", -- The txt/description for the button
onSelect = function() -- This brings the onSelect function to qb-menu
TriggerEvent("lolhi", { lol = hi }),
end,
-- Enter what happens when you click the button
}
```
As you can see above, it mixes variables but makes it possible to switch between menus just by changing the config option
After you have created the info above, you need to then trigger opening of this menu with:
```lua
openMenu(Menu, -- Menu here is your table name you created above
{ -- Next entry in openMenu is a table
header = "Menu Header", -- What your menu title will be shown as
headertxt = "Header info", -- Info to be displayed under the title
onExit = function() -- Will create a "Close button"
TriggerEvent("lolhi", { lol = hi }),
end, -- When clicked it will trigger the onExit event
onBack = function() -- Will create a "Back button"
TriggerEvent("lolhi", { lol = hi }),
end, -- When clicked it will trigger the onBack event
})
```
### Support for multiple target events
These automatically detect what target script you are using
They are also automatically removed when the script is stopped (for helping optimization)
### `createEntityTarget(entity, opts, dist)`
Create an entity based target
```lua
createEntityTarget(
entity, -- The entity ID of what you want to target
{
{ -- Your target options here
icon = "icon", -- Your icon, only supports font awesome icons
label = "Test Label", -- The label of your target
item = "lockpick" -- The required it em
job = "mechanic", -- The required job
gang = "lostmc", -- The required gang
action = function() -- What happens when the target is selected
TriggerEvent("lolhi", { lol = hi }),
end,
},
}
, dist) -- How close you ned to be to see the target
```
### `createBoxTarget(data, opts, dist)`
Create an entity based target
```lua
createBoxTarget(
{
"TargetName", -- The name/id of your target here
vec3(0, 0, 0), -- The coordinates of your target
2.0, -- The width of your target box
2.0, -- The depth of your target box
{
name = "TargetName", -- The name/id of your target here
heading = 200.0, -- The direction your target will be placed
debugPoly = true, -- Wether to show debug boxes to help place targets
minZ = 190.0, -- The bottom of your box
maxZ = 210.0, -- The top of your box
},
},
{
{ -- Your target options here
icon = "icon", -- Your icon, only supports font awesome icons
label = "Test Label", -- The label of your target
item = "lockpick" -- The required it em
job = "mechanic", -- The required job
gang = "lostmc", -- The required gang
action = function() -- What happens when the target is selected
TriggerEvent("lolhi", { lol = hi }),
end,
},
},
dist) -- How close you ned to be to see the target
```
### `createCircleTarget(data, opts, dist)`
Create an entity based target
```lua
createCircleTarget(
{
"TargetName", -- The name/id of your target here
vec3(0, 0, 0), -- The coordinates of your target
2.0, -- The radius of your target circle
{
name = "TargetName", -- The name/id of your target here
heading = 200.0, -- The direction your target will be placed
debugPoly = true, -- Wether to show debug boxes to help place targets
minZ = 190.0, -- The bottom of your box
maxZ = 210.0, -- The top of your box
},
},
{
{ -- Your target options here
icon = "icon", -- Your icon, only supports font awesome icons
label = "Test Label", -- The label of your target
item = "lockpick" -- The required it em
job = "mechanic", -- The required job
gang = "lostmc", -- The required gang
action = function() -- What happens when the target is selected
TriggerEvent("lolhi", { lol = hi }),
end,
},
},
dist) -- How close you ned to be to see the target
```
### `removeEntityTarget(entity)`
Triggers removal of the target entity, by checking the entity name
### `removeZoneTarget(target)`
Triggers removal of a zone(Box/Circle) target by calling the target's name/id
### `triggerNotify(title, message, type, src)`
Handles notifications for the script called from either the server or client
Supports:
- `okok`
- `qb`
- `ox`
- `gta`
- `esx`
```lua
triggerNotify(
title = "Notification Title", -- Usually 'nil' in my scripts, supports notifications with titles
message = "Notification Message", -- The notification's message
type = "success" -- The type of notification, depends on the supporting script
src = 1, -- If in the server, this is required to send to player
)
```
### `drawText(image, input, style)`
This handles calling drawText functions
Supports:
- `gta`
- `qb`
- `ox`
- `esx`
```lua
drawText(
187, -- Very specific for adding blip images to drawtexts, usually nil
{
"Line 1", -- Supports multiple lines, helpful for displaying button prompts
"Line 2",
},
"g" -- Sets colour of text after a ":" when using GTA drawtext
)
```
### `hideText()`
Simply used to hide drawText prompts when not needed anymore
### `createCallback(callbackName, funct)`
This is my attempt at making multiframework server callbacks by using their provided events
(Only works server side)
```lua
createCallback(
"jimsCallback", -- Callback event name, needs to be something that isn't already set
function()
end)
end
```
### `triggerCallback(callBackName, value)`
This is an attempt at a mutliframework callback
### `onPlayerLoaded(func)`
This is a multiframework event that is triggered when a player has fully loaded their character in
```lua
onPlayerLoaded(
function()
print("Player Loaded In!")
end
)
```
### `createInput(title, opts)`
### `searchCar(vehicle)`
This function was made for `jim-mechanic` but can be used in other instances
I searches the model name of a currently spawned vehicle and retrieves info about it
It is smart, in terms of, if you use this multiple times it reteives the previously found info instead of searching again
It retrieves data from your vehicles.lua/database:
- `name` for example: "Zentorno Pegassi"
- `price` for example: 100000
- `class` this converts the class number to a String, for example: if the class is 10 it converts this to "Off-road"
### `getVehicleProperties(vehicle)`
Gets the current properties of the vehicle in a table
- if using qb-core it will default to its version
- if not it will attempt to use ox_libs version
### `setVehicleProperties(vehicle, props)`
Set's the vehicles properites using the `props` table provided
- if using qb-core it will default to its version
- if not it will attempt to use ox_libs version
### `checkDifferences(vehicle, newProps)`
This function is used by `setVehicleProperties`
It determine's what differences there are between the current vehicle and the new set of properites
If there are differences, return `true`
### `RegisterNetEvent(GetCurrentResourceName()..":server:ChargePlayer", function(cost, type, newsrc)`
This event is made to REMOVE money from a player
It can be called from client with `TriggerServerEvent`
Also can be called from server with `TriggerEvent` and a source id in `newsrc`
The name of the event uses `GetCurrentResourceName()` so it doesn't double up results with other scripts
```lua
cost = 100 -- The amount of money to be removed
type = "cash" or "card" -- The type of money that should be removed
newsrc = 1 -- The source of the player, must be nil if calling from client
```
Examples of use:
```lua
-- Client
TriggerEvent(GetCurrentResourceName()..":server:ChargePlayer", function(1000, "cash")
-- Server
TriggerServerEvent(GetCurrentResourceName()..":server:ChargePlayer", function(1000, "bank", 1)
```
## `RegisterNetEvent(GetCurrentResourceName()..":server:FundPlayer", function(cost, type, newsrc)`
This event is made to ADD money from a player
It can be called from client with `TriggerServerEvent`
Also can be called from server with `TriggerEvent` and a source id in `newsrc`
The name of the event uses `GetCurrentResourceName()` so it doesn't double up results with other scripts
```lua
fund = 100 -- The amount of money to be added
type = "cash" or "card" -- The type of money that should be added
newsrc = 1 -- The source of the player, must be `nil` if calling from client
```
Examples of use:
```lua
-- Client
TriggerEvent(GetCurrentResourceName()..":server:FundPlayer", function(1000, "cash")
-- Server
TriggerServerEvent(GetCurrentResourceName()..":server:FundPlayer", function(1000, "bank", newsrc)
```
### `createUseableItem(item, funct)`
This is a server side event to make an item usable
Note: If using ox_inv and the items.lua info has event or a `status` section, this will be ignored
```lua
createUseableItem(
"lockpick", -- The item you want to make usable
function(source, item)
TriggerClientEvent("lolhi", source, { lol = item.name }),
end
)
```
### `hasJob(job, source, grade)`
This is an event that makes checking if the player has the requested job simple
It works both client side and server side
returns `true` or `false` and if they are on duty or not
```lua
local hasjob, duty =
hasJob(
"mechanic", -- the job role
1, -- the source id of the player, set to nil if on client
3, -- the required grade of the player, can be nil to check job
)
```
### `getPlayer(source)`
This retrieves basic info of the player
works client side and server side
Retrieves:
- Players Name
- Players Current Cash
- Players Current Bank Balance
```lua
local PlayerInfo =
getPlayer(
1 -- The
)
print(json.encode(PlayerInfo, { indent = true })
```
### `registerCommand(command, options)`
This is a server side event that uses
- `ox_lib`'s - `lib.addCommand`
- `qb-core`'s - `QBCore.Commands.Add`
Example:
```lua
registerCommand(
"hello", -- /hello the command to be used
"Print 'hello world'", -- text to show in chat
{ name = "lol", help = "hi" }, -- Help text for the command
false,
function() -- Function to be ran when the command is triggered
print("Hello World")
end,
"admin", -- the restriction, can be nil
)
```
### `invImg(item)`
This is used mainly for menu's to retrieve the item images
It detects what inventory you are using and automatically generates an `nui://` link
```lua
local imgLink = invImg("lockpick")
print(imgLink)
```
### `registerStash(name, label, slots, weight)`
This is a serverside function used to register a new stash in `ox_inventory` and `qs-inventory`
```lua
registerStash(
"newStash", -- The stash name/ID, this is used to open it later
"New created Stash", -- The name of the stash that shows in inventories
50, -- The amount of slots in the inventory
4000000, -- The max weight in the inventory
)
```
### `loadModel(model)`
This loads the requested model into the memory cache to help spawning of props
- Checks if the model exists in the server
- Attempts to load the model with a timeout, if not loaded, sends warning
### `unloadModel(model)`
This unloads a model to help clear the memory cache and help optimization
- Recommended to run after spawning a prop
### `loadAnimDict(animDict)`
This loads the requested animDict into the memory cache to help loading anims
- Checks if the dict exists in the server
### `unloadAnimDict(animDict)`
This unloads the animDict to help clear the memory cache and help optimization
- Recommended to run after running an animation
### `loadPtfxDict(ptFxName)`
This loads the requested ptFx dict into the memory cache to help loading particle effects
- Skips if the effect is alredy loaded
### `unloadPtfxDict(dict)`
This unloads a particle effect to help clear the memory cache and help optimization
- Recommended to run after running an ptfx
### `loadTextureDict(dict)`
This loads the requested texture dictionary into memory
### `countTable(table)`
This is a simple function to count how many entires are in a table, for if your table keys aren't numbered
Example:
```lua
local table = {
["tableentry"] = true,
["anotherentry"] = true,
}
print("countTable", countTable(table))
```
### `pairsByKeys(t)`
Searches through a table alphabetically instead of randomly
This is an optional function made to replace:
```lua
for k, v in pairs(table) do end
```
with:
```lua
for k, v in pairsByKeys(table) do end
```
### `playAnim(animDict, animName, duration, flag, ped)`
A simplified version of `TaskPlayAnim()`
Has some settings already set and basic ones ready to change
Loads the animDict automatically with `loadAnimDict()`
```lua
playAnim(
animDict, -- The animation dictionary
animName, -- The animation's name
duration, -- How far into the animation it should stop
flag, -- The animation flag
ped, -- Optional, for if you want any one other than the player to do the animation
)
```
### `stopAnim(animDict, animName, ped)`
Similar to `StopAnimTask()`
Made to stop the given animation with being able to choose which ped
```lua
stopAnim(
animDict, -- The animation dictionary
animName, -- The animation's name
ped, -- Optional, for if you want any one other than the player to do the animation
)
```
### `makeVeh(model, coords)`
Spawns a vehicle for the player to use
- Server Synced
- Easy creation
- Returns entity id for further control through the script
- Loads model before spawning
- Unloads model from memory cache after spawn
Example of use:
```lua
local vehicle = makeVeh(
`zentorno`,
vec4(-596.74, 2090.99, 131.41, 16.6)
)
print(vehicle, GetEntityCoords(vehicle))
```
### `makePed(model, coords, freeze, collision, scenario, anim, synced)`
Spawns a controllable ped
- Loads the model before spawning
- Unloads model from memory cache after spawn
- Several options for creation
- Can spawn with scenario name or anims
- Spawns invincible
Example of use:
```lua
local ped = makePed(
`MP_M_Freemode_011,
vec4(-596.74, 2090.99, 131.41, 16.6),
true,
false,
nil,
{ "amb@prop_human_parking_meter@male@idle_a", "idle_a" },
false
)
print(ped, GetEntityCoords(ped))
```
### `makeProp(data, freeze, synced)`
This function is made to easily load a prop in the world
- Has a simplified process
- Lodas model before spawning prop
- Unloads model from memory cache when done
- Returns entity id for control through the script
Example of use:
```lua
local entityid = makeProp(
{
prop = "v_serv_plas_boxgt2", -- Prop model, can be a string or hash key
coords = vec4(-596.74, 2090.99, 131.41, 16.6), -- needs to be vector4 or vec4, 4th variable is heading
},
true, -- Decide if the entiy is frozen in place
false -- Does this prop spawn for everyone or just the client
)
print(entityid, GetEntityCoords(entityid))
```
### `instantLookEnt(ent, ent2)`
This function forcibly changes `ent`'s heading to face `ent2`
Helpful for animations in a specific direction
### `lookEnt(entity)`
This function attempts to slowly turn the player to the given entity/coords
Accepts either a `entity ID` or `vector3`
### `destroyProp(entity)`
Attempts to remove a spawned prop
If its attached to a player it attempts to to detatch it first
### `pushVehicle(entity)`
This attempts to make the current entity(vehicle) network controlled
This helps with syncing it with other players (used in jim-mechanic often)
### `ensureNetToVeh(vehNetId)`
This was created to get around fivem's warnings of failing to get network objects
Although these warnings mean't nothing, it is annoying
This is made to replace the native `NetToVeh()` but checking first if it exists
### `makeBlip(data)`
---

View File

@@ -75,7 +75,7 @@ function craftingMenu(data)
header = setheader,
txt = settext,
onSelect = function()
local transdata = { item = k, craft = data.craftable.Recipes[i], craftable = data.craftable, coords = data.coords, stashName = data.stashName, onBack = data.onBack }
local transdata = { item = k, craft = data.craftable.Recipes[i], craftable = data.craftable, coords = data.coords, stashName = data.stashName, onBack = data.onBack, }
if Config.Crafting.MultiCraft then multiCraft(transdata) else makeItem(transdata) end
end,
}
@@ -137,7 +137,6 @@ function makeItem(data)
local crafted, crafting = true, true
local cam = createTempCam(PlayerPedId(), data.coords)
startTempCam(cam)
for i = 1, amount do
for k, v in pairs(data.craft) do
if k ~= "amount" and k ~= "job" then
@@ -209,6 +208,80 @@ RegisterNetEvent(GetCurrentResourceName()..":Crafting:GetItem", function(ItemMak
end)
--[[SHOPS]]--
function sellMenu(data)
local origData = data
local Menu = {}
if data.sellTable.Items then
local itemList = {}
for k, v in pairs(data.sellTable.Items) do itemList[k] = 1 end
local hasitems, hasTable = hasItem(itemList)
for k, v in pairsByKeys(data.sellTable.Items) do
Menu[#Menu +1] = {
isMenuHeader = not hasTable[k].hasItem,
icon = invImg(k),
header = Items[k].label.. (hasTable[k].hasItem and "💰 (x"..hasTable[k].count..")" or ""),
txt = Loc[Config.Lan].info["sell_all"].." "..v.." "..Loc[Config.Lan].info["sell_each"],
onSelect = function()
sellAnim({ item = k, price = v, ped = data.ped, onBack = function() sellMenu(data) end })
end,
}
end
else
for k, v in pairsByKeys(data.sellTable) do
if type(v) == "table" then
Menu[#Menu +1] = {
arrow = true,
header = k,
txt = "Amount of items: "..countTable(v.Items),
onSelect = function()
v.onBack = function() sellMenu(origData) end
v.sellTable = data.sellTable[k]
sellMenu(v)
end,
}
end
end
end
openMenu(Menu, { header = data.sellTable.Header or "Amount of items: "..countTable(data.sellTable.Items), canClose = true, onBack = data.onBack })
end
function sellAnim(data)
if not hasItem(data.item, 1) then
triggerNotify(nil, Loc[Config.Lan].error["dont_have"].." "..Items[data.item].label, "error")
return
end
for k, v in pairs(GetGamePool('CObject')) do
for _, model in pairs({`p_cs_clipboard`}) do
if GetEntityModel(v) == model then
if IsEntityAttachedToEntity(data.ped, v) then
DeleteObject(v) DetachEntity(v, 0, 0) SetEntityAsMissionEntity(v, true, true)
Wait(100) DeleteEntity(v)
end
end
end
end
TriggerServerEvent(GetCurrentResourceName().."Sellitems", data) -- Had to slip in the sell command during the animation command
lookEnt(data.ped)
local dict = "mp_common"
playAnim(dict, "givetake2_a", 0.3, 2)
playAnim(dict, "givetake2_b", 0.3, 2, data.ped)
Wait(2000)
StopAnimTask(PlayerPedId(), dict, "givetake2_a", 0.5)
StopAnimTask(data.ped, dict, "givetake2_b", 0.5)
if data.onBack then data.onBack() end
end
RegisterNetEvent(GetCurrentResourceName().."Sellitems", function(data)
local src = source
local hasItems, hasTable = hasItem(data.item, 1, src)
if hasItems then
TriggerEvent(GetCurrentResourceName()..":server:toggleItem", false, data.item, hasTable[data.item].count, src)
TriggerEvent(GetCurrentResourceName()..":server:FundPlayer", (hasTable[data.item].count * data.price), "cash", src)
else
triggerNotify(nil,Loc[Config.Lan].error["dont_have"].." "..Items[data.item].label, "error", src)
end
end)
function openShop(data)
if (data.job or data.gang) and not jobCheck(data.job or data.gang) then return end
if GetResourceState(OXInv):find("start") then
@@ -236,7 +309,7 @@ function hasItem(items, amount, src) local amount = amount and amount or 1
elseif GetResourceState(OrigenInv):find("start") then
foundInv = OrigenInv
if src then grabInv = exports[OrigenInv]:getPlayerInventory(src)
if src then grabInv = exports[OrigenInv]:GetInventory(src)
else grabInv = exports[OrigenInv]:getPlayerInventory() end
elseif GetResourceState(CoreInv):find("start") then
@@ -258,11 +331,13 @@ function hasItem(items, amount, src) local amount = amount and amount or 1
elseif GetResourceState(CodeMInv):find("start") then
foundInv = CodeMInv
grabInv = src and exports[CodeMInv]:GetUserInventory(src) or exports[CodeMInv]:GetClientPlayerInventory()
if src then grabInv = exports[CodeMInv]:GetUserInventory(src)
else grabInv = exports[CodeMInv]:GetClientPlayerInventory() end
elseif GetResourceState(QBInv):find("start") then
foundInv = QBInv
grabInv = src and Core.Functions.GetPlayer(src).PlayerData.items or Core.Functions.GetPlayerData().items
if src then grabInv = Core.Functions.GetPlayer(src).PlayerData.items
else grabInv = Core.Functions.GetPlayerData().items end
else
print("^4ERROR^7: ^2No Inventory detected ^7- ^2Check ^3exports^1.^2lua^7")
@@ -405,7 +480,7 @@ function stashRemoveItem(stashItems, stashName, items) local amount = amount and
elseif GetResourceState(OrigenInv):find("start") then
for k, v in pairs(items) do
exports[OrigenInv]:RemoveItem(stashName, k, v)
exports[OrigenInv]:RemoveFromStash(stashName, k, v)
if Config.System.Debug then print("^6Bridge^7: ^2Removing item from ^3Stash^2 with ^7"..OrigenInv, k, v) end
end

View File

@@ -15,8 +15,9 @@ function loadModel(model)
if not HasModelLoaded(model) then
if Config.System.Debug then print("^6Bridge^7: ^2Loading Model^7: '^6"..model.."^7'") end
while not HasModelLoaded(model) and time > 0 do time -= 1 RequestModel(model) Wait(0) end
if not HasModelLoaded(model) then time = 500 print("^6Bridge^7: ^3LoadModel^7: ^2Timed out loading model ^7'^6"..model.."^7'") end
if not HasModelLoaded(model) then print("^6Bridge^7: ^3LoadModel^7: ^2Timed out loading model ^7'^6"..model.."^7'") end
end
time = 500
end
end
function unloadModel(model) if Config.System.Debug then print("^6Bridge^7: ^2Removing Model from memory cache^7: '^6"..model.."^7'") end SetModelAsNoLongerNeeded(model) end
@@ -39,12 +40,13 @@ function loadPtfxDict(ptFxName)
end
end
function unloadPtfxDict(dict) if Config.System.Debug then print("^6Bridge^7: ^2Removing Ptfx Dictionary^7: '^6"..dict.."^7'") end RemoveNamedPtfxAsset(dict) end
function loadTextureDict(dict)
if not HasStreamedTextureDictLoaded(dict) then
if Config.System.Debug then
print("^6Bridge^7: ^2Loading Texture Dictionary^7: '^6"..dict.."^7'")
end
while not HasStreamedTextureDictLoaded(dict) do RequestNamedPtfxAsset(dict) Wait(5) end
while not HasStreamedTextureDictLoaded(dict) do RequestStreamedTextureDict(dict) Wait(5) end
end
end
@@ -58,7 +60,8 @@ function playAnim(animDict, animName, duration, flag, ped)
end
function stopAnim(animDict, animName, ped)
StopAnimTask(ped and ped or PlayerPedId(), animName, animDict)
StopAnimTask(ped or PlayerPedId(), animDict, animName, 0.5)
StopAnimTask(ped or PlayerPedId(), animName, animDict, 0.5)
unloadAnimDict(animDict)
end
@@ -85,7 +88,7 @@ local Peds = {}
local Props = {}
function makePed(model, coords, freeze, collision, scenario, anim, synced)
loadModel(model)
local ped = CreatePed(0, model, coords.x, coords.y, coords.z-1.03, coords.w, synced or true, false)
local ped = CreatePed(0, model, coords.x, coords.y, coords.z-1.03, coords.w, synced and synced or false, false)
SetEntityInvincible(ped, true)
SetBlockingOfNonTemporaryEvents(ped, true)
FreezeEntityPosition(ped, freeze and freeze or true)
@@ -107,7 +110,7 @@ end
function makeProp(data, freeze, synced)
loadModel(data.prop)
local prop = CreateObject(data.prop, data.coords.x, data.coords.y, data.coords.z-1.03, freeze or false, synced or false, false)
local prop = CreateObject(data.prop, data.coords.x, data.coords.y, data.coords.z-1.03, synced and synced or false, synced and synced or false, false)
SetEntityHeading(prop, data.coords.w + 180.0)
FreezeEntityPosition(prop, freeze and freeze or 0)
if Config.System.Debug then
@@ -140,13 +143,6 @@ function DrawText3D(x, y, z, text)
ClearDrawOrigin()
end
AddEventHandler('onResourceStop', function(r)
if r ~= GetCurrentResourceName() then return end
stopSpinner()
for i = 1, #Peds do DeletePed(Peds[i]) end
for i = 1, #Props do destroyProp(Props[i]) end
end)
function instantLookEnt(ent, ent2)
local p1 = GetEntityCoords(ent, true)
local p2 = GetEntityCoords(ent2, true)
@@ -227,8 +223,11 @@ function ensureNetToVeh(vehNetID)
return vehicle
end
local scriptTxd = not IsDuplicityVersion() and CreateRuntimeTxd(GetCurrentResourceName()..'scriptTxd') or nil
local customDUIList = {}
function makeBlip(data)
local blip = AddBlipForCoord(data.coords)
local blip = AddBlipForCoord(vec3(data.coords.x, data.coords.y, data.coords.z))
SetBlipAsShortRange(blip, true)
SetBlipSprite(blip, data.sprite or 106)
SetBlipColour(blip, data.col or 5)
@@ -238,8 +237,20 @@ function makeBlip(data)
BeginTextCommandSetBlipName('STRING')
AddTextComponentString(tostring(data.name))
EndTextCommandSetBlipName(blip)
if GetResourceState("blip_info"):find("start") or GetResourceState("blip-info"):find("start") or GetResourceState("blipinfo"):find("start") then
if data.preview then
local txname = tostring(data.name..'preview'..string.gsub(data.coords.z, "%.", ""))
if data.preview:find("http") then
createDui(txname, data.preview, vec2(512, 256), scriptTxd)
else
CreateRuntimeTextureFromImage(scriptTxd, txname, data.preview)
end
exports["blip_info"]:SetBlipInfoImage(blip, GetCurrentResourceName()..'scriptTxd', txname)
exports["blip_info"]:SetBlipInfoTitle(blip, data.name, false)
end
end
if Config.System.Debug then print("^6Bridge^7: ^6Blip ^2created for location^7: '^6"..data.name.."^7'") end
return blip
return blip
end
function makeEntityBlip(data)
@@ -254,10 +265,135 @@ function makeEntityBlip(data)
BeginTextCommandSetBlipName('STRING')
AddTextComponentString(tostring(data.name))
EndTextCommandSetBlipName(blip)
if GetResourceState("blip_info"):find("start") or GetResourceState("blip-info"):find("start") or GetResourceState("blipinfo"):find("start") then
if data.preview then
local txname = data.name..'preview'
if data.preview:find("http") then
createDui(txname, data.preview, vec2(512, 256), scriptTxd)
else
CreateRuntimeTextureFromImage(scriptTxd, txname, data.preview)
end
exports["blip_info"]:SetBlipInfoImage(blip, GetCurrentResourceName()..'previewTxd', txname)
exports["blip_info"]:SetBlipInfoTitle(blip, data.name, false)
end
end
if Config.System.Debug then print("^6Bridge^7: ^6Blip ^2created for Entity^7: '^6"..data.name.."^7'") end
return blip
end
-- DUI STUFF - WIP --
-- DUI CLIENT
function createDui(name, http, size, txd)
if not customDUIList[name] then
local newTxt = CreateDui(http, math.floor(size.x), math.floor(size.y))
while not GetDuiHandle(newTxt) do Wait(0) end
CreateRuntimeTextureFromDuiHandle(txd, name, GetDuiHandle(newTxt))
customDUIList[name] = newTxt
SetDuiUrl(customDUIList[name], http)
else
SetDuiUrl(customDUIList[name], http)
end
end
function DuiSelect(data)
local image = ""
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
if duiList[data.name][k] then
image = "<center>- Current Image -<br>"..
"<img src="..duiList[data.name][k].url.." width=150px><br>"..
"Size: ["..math.floor(data.size.x)..", "..math.floor(data.size.y).."]<br><br>"
end
end
end
local dialog = exports['qb-input']:ShowInput({
header = image..Loc[Config.Lan].menu["dui_new"],
submitText = Loc[Config.Lan].menu["dui_change"],
inputs = { { type = 'text', isRequired = true, name = 'url', text = Loc[Config.Lan].menu["dui_url"] } } })
if dialog then
if not dialog.url then return end
data.url = dialog.url
--Scan the link to see if it has an image extention otherwise, stop here.
local searchList = { "png", "jpg", "jpeg", "gif", "webp", "bmp" }
--Scan the link for certain terms that will flag it and refuse to show it
local banList = { "porn" } -- I dunno, let me know what links people manage to find
local searchFound = false
for k, v in pairs(searchList) do
if string.find(tostring(data.url), tostring(v))then
searchFound = true
end
end
for k, v in pairs(banList) do
if string.find(tostring(data.url), tostring(v)) then
searchFound = false print("BANNED WORD: "..v)
end
end
if searchFound then
TriggerServerEvent(GetCurrentResourceName()..":Server:ChangeDUI", data)
end
end
end
RegisterNetEvent(GetCurrentResourceName()..":Client:ChangeDUI", function(data)
if Config.System.Debug then print("^6Bridge^7: ^2Recieving new DUI ^7- ^6"..data.url.."^7") end
if tostring(data.url) ~= "-" then
createDui(data.texn, tostring(data.url), data.size, scriptTxd)
AddReplaceTexture(tostring(data.texd), tostring(data.texn), GetCurrentResourceName()..'scriptTxd', tostring(data.texn))
end
end)
RegisterNetEvent(GetCurrentResourceName()..":Client:ClearDUI", function(data)
if customDUIList[tostring(data.texn)] then
RemoveReplaceTexture(tostring(data.texd), tostring(data.texn))
if IsDuiAvailable(customDUIList[tostring(data.texn)]) then
SetDuiUrl(customDUIList[data.name], nil)
end
end
end)
-- DUI SERVER
RegisterNetEvent(GetCurrentResourceName()..":Server:ChangeDUI", function(data)
-- if no url given, "reset" it back to preset
if not data.url then
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
if Config.System.Debug then print("^6Bridge^7: ^2Preset^7: ^6"..tostring(duiList[data.name][k].preset).."^7") end
data.url = duiList[data.name][k].preset
end
end
end
-- if it has a url, update server DUI list and send to players
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
duiList[data.name][k].url = data.url
end
end
if Config.System.Debug then print("^6Bridge^7: ^3DUI^2 Sending new DUI to all players^7 - ^6"..data.url.."^7") end
TriggerClientEvent(GetCurrentResourceName()..":Client:ChangeDUI", -1, data)
end)
RegisterNetEvent(GetCurrentResourceName()..":Server:ClearDUI", function(data)
if data.url == "-" then
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
duiList[data.name][k].url = "-"
end
end
end
-- Clear the DUI from loading
TriggerClientEvent(GetCurrentResourceName()..":Client:ClearDUI", -1, data)
--duiList[tostring(data.tex)].url = ""
end)
AddEventHandler('onResourceStop', function(r) if r ~= GetCurrentResourceName() then return end
for k, v in pairs(duiList or {}) do
for i = 1, #v do
RemoveReplaceTexture(tostring(v[i].tex.texd), tostring(v[i].tex.texn))
end
end
end)
function lockInv(toggle)
FreezeEntityPosition(PlayerPedId(), toggle)
LocalPlayer.state:set("inv_busy", toggle, true)
@@ -713,6 +849,91 @@ function dupeWarn(src, item, amount)
print("^5DupeWarn:^7: (^1"..tostring(src).."^7) ^2Dropped from server - exploit protection detected an item not being found in players inventory^7")
end
function breakTool(data) --wip
local durability, slot = getDurability(item)
durability -= data.damage
if not durability then durability = 100 end
if durability <= 0 then
removeItem(data.item, 1)
local breakId = GetSoundId()
PlaySoundFromEntity(breakId, "Drill_Pin_Break", PlayerPedId(), "DLC_HEIST_FLEECA_SOUNDSET", 1, 0)
else
TriggerServerEvent(GetCurrentResourceName()..":server:setMetaData", { item = data.item, slot = slot, metadata = { durability = durability }})
end
end
function getDurability(item)
local lowestSlot = 100 -- anything above your players max slots
local durability = nil
if GetResourceState(QBInv):find("start") then
local itemcheck = Core.Functions.GetPlayerData().items
for k, v in pairs(itemcheck) do
if v.name == item then
if v.slot <= lowestSlot then
lowestSlot = v.slot
durability = itemcheck[k].info.durability
end
end
end
end
if GetResourceState(OXInv):find("start") then
local itemcheck = exports[OXInv]:Search('slots', item)
for k, v in pairs(itemcheck) do
if v.slot <= lowestSlot then
lowestSlot = v.slot
durability = itemcheck[k].metadata.durability
end
end
end
if GetResourceState(QSInv):find("start") then
local itemcheck = exports[QSInv]:getUserInventory()
for k, v in pairs(itemcheck) do
if v.name == item and v.slot <= lowestSlot then
lowestSlot = v.slot
durability = itemcheck[k].metadata.durability
end
end
end
if GetResourceState(OrigenInv):find("start") then
local itemcheck = exports[OrigenInv]:getPlayerInventory()
for k, v in pairs(itemcheck) do
if v.name == item and v.slot <= lowestSlot then
lowestSlot = v.slot
durability = itemcheck[k].metadata.durability
end
end
end
return durability, lowestSlot
end
RegisterNetEvent(GetCurrentResourceName()..":server:setMetaData", function(data)
local src = source
if GetResourceState(QBInv):find("start") then
local Player = Core.Functions.GetPlayer(src)
Player.PlayerData.items[data.slot].info = data.metadata
Player.PlayerData.items[data.slot].description = "HP : "..data.metadata.durability
Player.Functions.SetInventory(Player.PlayerData.items)
end
if GetResourceState(OXInv):find("start") then
exports[OXInv]:SetMetadata(source, data.slot, data.metadata)
end
if GetResourceState(QSInv):find("start") then
exports[QSInv]:SetItemMetadata(source, data.slot, data.metadata)
end
if GetResourceState(OrigenInv):find("start") then
local item = exports[OrigenInv]:GetItemBySlot(source, data.slot)
if item then
exports[OrigenInv]:SetItemData(source, item.name, "durability", data.metadata.durability)
end
end
end)
function toggleDuty()
if GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then
TriggerServerEvent("QBCore:ToggleDuty")
@@ -858,15 +1079,15 @@ function FocusEffect()
focusEffect = false
if Config.System.Debug then print("^5Debug^7: ^3FocusEffect^7() ^2stopped") end
end
local NightVisionEffect = false
local nightVisionEffect = false
function NightVisionEffect()
if NightVisionEffect then return else NightVisionEffect = true end
if NightVisionEffect then return else nightVisionEffect = true end
if Config.System.Debug then print("^5Debug^7: ^3NightVisionEffect^7() ^2activated") end
SetNightvision(true)
Wait(math.random(3000, 4000)) -- FEEL FREE TO CHANGE THIS
SetNightvision(false)
SetSeethrough(false)
NightVisionEffect = false
nightVisionEffect = false
if Config.System.Debug then print("^5Debug^7: ^3NightVisionEffect^7() ^2stopped") end
end
local thermalEffect = false
@@ -937,4 +1158,11 @@ function StopEffects() -- Used to clear up any effects stuck on screen
AnimpostfxStop('RaceTurbo')
AnimpostfxStop('FocusIn')
AnimpostfxStop('Rampage')
end
end
AddEventHandler('onResourceStop', function(r)
if r ~= GetCurrentResourceName() then return end
stopSpinner()
for i = 1, #Peds do DeletePed(Peds[i]) end
for i = 1, #Props do destroyProp(Props[i]) end
end)

View File

@@ -1,6 +1,6 @@
name "Jim_Bridge"
author "Jimathy"
version "1.0.11"
version "1.0.14"
description "Framework Bridge By Jimathy"
fx_version "cerulean"
game "gta5"

View File

@@ -1 +1 @@
1.0.11
1.0.13

View File

@@ -26,7 +26,7 @@ for k, v in pairs(Exports) do
if GetResourceState(v):find("start") then print("^6Bridge^7: '^3"..v.."^7' ^2export found ^7") end
end
local itemResource, vehResource, jobResource = "", "", ""
local itemResource, jobResource = "", ""
-- Load item lists
if GetResourceState(OXInv):find("start") then itemResource = OXInv
@@ -56,7 +56,7 @@ else
end
-- Load Vehicles
if GetResourceState(QBXExport):find("start") or GetResourceState(QBExport):find("start") then vehResource = QBExport
if GetResourceState(QBXExport):find("start") or GetResourceState(QBExport):find("start") then
Core = Core or exports[QBExport]:GetCoreObject()
if GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
RegisterNetEvent('QBCore:Client:UpdateObject', function()
@@ -491,7 +491,7 @@ function createBoxTarget(data, opts, dist)
local options = { options = opts, distance = dist }
local target = exports[QBTargetExport]:AddBoxZone(data[1], data[2], data[3], data[4], data[5], options)
boxTargets[#boxTargets+1] = target
return target
return data[1]
else
local tempText = ""
local keyTable = { 38, 29, 303, }
@@ -540,7 +540,7 @@ function createCircleTarget(data, opts, dist)
local target = exports[QBTargetExport]:AddCircleZone(data[1], data[2], data[3], data[4], options)
circleTargets[#circleTargets+1] = target
return target
return data[1]
else
local tempText = ""
local keyTable = { 38, 29, 303, }
@@ -1291,6 +1291,9 @@ function sendPhoneMail(data) local phoneResource = ""
elseif GetResourceState("qb-phone"):find("start") then phoneResource = "qb-phone"
TriggerServerEvent('qb-phone:server:sendNewMail', data)
elseif GetResourceState("jpr-phonesystem"):find("start") then phoneResource = "jpr-phonesystem"
TriggerServerEvent(GetCurrentResourceName()..":jpr:SendMail", data)
end
if phoneResource ~= "" then if Config.System.Debug then print("^6Bridge^7[^3"..phoneResource.."^7]: ^2Sending mail to player") end
@@ -1323,6 +1326,19 @@ RegisterNetEvent(GetCurrentResourceName()..":yflip:SendMail", function(data)
}, 'source', src)
end)
RegisterNetEvent(GetCurrentResourceName()..":jpr:SendMail", function(data)
local QBCore = exports['qb-core']:GetCoreObject()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
TriggerEvent('jpr-phonesystem:server:sendEmail', {
Assunto = data.subject, -- Subject
Conteudo = data.message, -- Content
Enviado = data.sender, -- Submitted by
Destinatario = Player.PlayerData.citizenid, -- Target
Event = {}, -- Optional
})
end)
function registerCommand(command, options)
if GetResourceState(OXLibExport):find("start") then
if Config.System.Debug then print("^6Bridge^7: ^2Registering ^3Command^2 with ^7"..OXLibExport, command) end
@@ -1362,4 +1378,18 @@ function registerStash(name, label, slots, weight)
exports[QSInv]:RegisterStash(name, slots or 50, weight or 4000000)
end
end
-- duiList callback here because it wouldnt load in functions.lua
if IsDuplicityVersion() then
createCallback(GetCurrentResourceName()..":Server:duiList", function(source, cb)
if GetResourceState(OXLibExport):find("start") then
return duiList
else
cb(duiList)
end
end)
end
-- IN NO WAY PERFECT --