Compare commits

..

131 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
Jim Shield
23c2e1472e Merge pull request #19 from jimathy/1.0.11
1.0.11
2024-01-30 19:21:33 +00:00
Jim Shield
6367c9ed3b remove loadmodel debug timeout print 2024-01-30 18:47:23 +00:00
Jim Shield
2d299a6a4a chargePlayer & fundPlayer server events/fixes 2024-01-30 18:40:26 +00:00
Jim Shield
ced629d4dc dupewarn info addition 2024-01-30 18:39:51 +00:00
Jim Shield
714121d272 crafting menu workarounds for missing info 2024-01-30 18:38:57 +00:00
Jim Shield
14c140cf85 load model and prop fixes 2024-01-29 22:23:23 +00:00
Jim Shield
881aec7c04 remove ox_lib model check as it was erroring out 2024-01-29 13:27:00 +00:00
Jim Shield
85b31e7e1d getRandomReward added for reward item support 2024-01-29 13:23:02 +00:00
Jim Shield
66c9287202 v1.0.11 - Version Bump 2024-01-28 19:24:19 +00:00
Jim Shield
f0f59b8568 remove debug print 2024-01-28 19:19:58 +00:00
Jim Shield
e03efa6687 update stopAnim to choose ped 2024-01-28 19:19:24 +00:00
Jim Shield
5a22651961 fix ConsumeSuccess and other typos 2024-01-28 19:18:55 +00:00
Jim Shield
236689452e custom stash slot sizes at "register" 2024-01-28 19:17:57 +00:00
Jim Shield
b686f267e1 Remove debug print 2024-01-28 01:44:53 +00:00
Jim Shield
096e323409 Merge pull request #18 from jimathy/1.0.10
1.0.10
2024-01-27 14:27:44 +00:00
Jim Shield
b71ec14615 sendPhoneMail - mutli phone support 2024-01-27 12:55:56 +00:00
Jim Shield
5a2304b785 quick linting 2024-01-26 20:31:46 +00:00
Jim Shield
6f413c555d add basic canCarry function 2024-01-26 20:31:10 +00:00
Jim Shield
fbc92aea41 update common functions to be smurter 2024-01-26 19:02:02 +00:00
Jim Shield
7b31343991 Merge pull request #17 from jimathy/1.0.9
1.0.9
2024-01-25 18:42:19 +00:00
Jim Shield
872cb39715 Fix crafting from pockets and add debugs 2024-01-25 18:40:42 +00:00
Jim Shield
dd35674307 i hate github 2024-01-25 18:31:34 +00:00
Jim Shield
1d102e94b4 Fix loading of ESX Core shared info 2024-01-25 18:31:00 +00:00
Jim Shield
c18932443a Testing fixing stashes 2024-01-25 17:32:40 +00:00
Jim Shield
7563b4abdf Merge pull request #16 from SirOMGitsYOU/patch-1
Fix Typo
2024-01-25 10:56:55 +00:00
Peter
20509e5cc2 Fix Typo
Update wrapper.lua - Fixed a typo on line 141 prevents this update from loading.
2024-01-24 23:33:39 +00:00
Jim Shield
43e30e95bc Tidy up and make ESX timeout longer 2024-01-24 17:10:44 +00:00
Jim Shield
9efff1060b Merge pull request #15 from jimathy/1.0.8
1.0.8 - Fixes crafting issues
2024-01-24 01:13:39 +00:00
Jim Shield
3b608e2b4f Update wrapper.lua 2024-01-24 01:13:30 +00:00
Jim Shield
bfed10c019 more fixes and optmization 2024-01-23 22:39:46 +00:00
Jim Shield
4bb29b8f14 cheeky little core_skills addition 2024-01-23 22:05:07 +00:00
Jim Shield
6eca0dd1d1 Cut down code and optimize crafting functions 2024-01-23 22:04:30 +00:00
Jim Shield
cc96bcde34 Fix stashCrafting not finding items 2024-01-23 22:03:27 +00:00
Jim Shield
ab61e40567 Merge pull request #14 from jimathy/1.0.7
1.0.7
2024-01-23 19:02:13 +00:00
Jim Shield
e17e2fb865 bit'o linting 2024-01-23 19:01:03 +00:00
Jim Shield
a6bd82a41c Fixes for ox showMenu support 2024-01-23 19:00:39 +00:00
Jim Shield
fac495c0ef Change how core information is grabbed 2024-01-23 19:00:04 +00:00
Jim Shield
15bea85bfb Version Bump v1.0.7 2024-01-23 18:59:02 +00:00
Jim Shield
f889080bc0 Merge pull request #13 from jimathy/1.0.6
1.0.6
2024-01-23 00:37:55 +00:00
Jim Shield
7d62358558 ox input default "select" 2024-01-23 00:37:18 +00:00
Jim Shield
f7a7e89c56 lib.showMenu support 2024-01-23 00:36:04 +00:00
Jim Shield
5f6720d37b Merge pull request #12 from solareon/patch-1
fix: job crafting restrictions
2024-01-23 00:34:15 +00:00
solareon
e541201a08 fix: skip amount and job tables 2024-01-22 22:39:16 +00:00
Solareon
2bf04f69cf fix: hasjob
Fixes broken crafting because the wrapper function is called hasJob with a capital J while the variable is called hasjob
2024-01-22 12:50:03 -07:00
Jim Shield
8479aea1b0 Origen inv experimental support 2024-01-22 17:14:56 +00:00
Jim Shield
d17a1da5b2 CoreInv Fully Supported 2024-01-22 16:55:58 +00:00
Jim Shield
f1ff06c098 CoreInv hasItem events updated 2024-01-22 15:31:04 +00:00
Jim Shield
df785043e8 CoreInv add/remove Item fixes 2024-01-22 14:51:51 +00:00
Jim Shield
5ae4799a5f add auto check for ps/lj-inv 2024-01-22 14:41:38 +00:00
Jim Shield
8cf4a6bd23 Version Bump - 1.0.6 2024-01-22 14:35:52 +00:00
Jim Shield
3e067c8492 Merge pull request #9 from jimathy/1.0.5
1.0.5
2024-01-21 22:28:03 +00:00
Jim Shield
6847639c65 Fix version checking system being dumb 2024-01-21 17:24:32 +00:00
Jim Shield
0592c3ebc8 Fix stashRemoveItem for QS-Inv 2024-01-21 17:24:10 +00:00
Jim Shield
2ca1cbd110 fxmanifest.lua - Version Bump v1.0.5 2024-01-21 17:20:15 +00:00
Jim Shield
8642733b78 version.txt - Version bump - 1.0.5 2024-01-21 17:17:55 +00:00
Jim Shield
5a4293182c version number plz work 2024-01-21 17:10:32 +00:00
Jim Shield
6075878038 Update version.txt 2024-01-21 00:56:19 +00:00
Jim Shield
7eaeac886f Merge pull request #8 from jimathy/1.0.4
1.0.4
2024-01-21 00:27:08 +00:00
Jim Shield
fe27a1ca1c speed playAnim up + add default input message 2024-01-21 00:25:42 +00:00
Jim Shield
0caea0b473 advanced checking and handling of setVehicle 2024-01-20 14:28:10 +00:00
Jim Shield
370c77433b Version Bump - v1.0.4 2024-01-20 13:01:26 +00:00
Jim Shield
ac85d35097 Merge pull request #7 from jimathy/1.0.3
1.0.3
2024-01-19 23:58:42 +00:00
Jim Shield
85c3e06910 update addItem/removeItem prints 2024-01-19 23:57:22 +00:00
Jim Shield
7d0736bfc2 Change how bridge decides what get/setvehicleproperties to use 2024-01-19 22:33:35 +00:00
Jim Shield
b0b011ac56 update readme -main 2024-01-19 20:25:44 +00:00
Jim Shield
23091c2e73 add spam free ensureNetToVeh() 2024-01-19 20:25:04 +00:00
Jim Shield
ef2ba3ea7a tidy up new prints more 2024-01-19 20:24:25 +00:00
Jim Shield
df60f3b2b1 tidy prints for setVehicleProperties 2024-01-19 18:13:22 +00:00
Jim Shield
4cc001d2f0 fix typo in stashhasitem 2024-01-19 18:10:05 +00:00
Jim Shield
e2bb32d9de Optimize Crafting/Multicraft Menu + better hasItem prints 2024-01-19 14:46:45 +00:00
Jim Shield
725125a274 add debug prints to new ox setVehicleProperties call 2024-01-19 14:46:09 +00:00
Jim Shield
dcf2018ec6 check for destroyProp if received any info 2024-01-19 13:02:09 +00:00
Jim Shield
e5316f45aa Rewrite + Optimize hasItem() & stashhasItem() 2024-01-19 13:00:50 +00:00
Jim Shield
02c202d075 Version Bump - v1.0.3 2024-01-19 12:53:45 +00:00
Jim Shield
9e9fb14f55 Merge pull request #3 from bandgeekndb/stashoptions
Allow for passing through stash options when opening a stash
2024-01-19 12:50:10 +00:00
Jim Shield
61e0d777a8 Attempt to fix ox_lib's setVehicleProperites + 1.0.2 2024-01-18 20:21:22 +00:00
Jim Shield
78c3e33d38 version bump 1.0.1 2024-01-18 17:50:42 +00:00
Jim Shield
3be5b5e1ee Merge pull request #6 from jimathy/1.0.1
1.0.1
2024-01-18 17:49:05 +00:00
Jim Shield
f550479298 Revert "version bump"
This reverts commit d82366b59f.
2024-01-18 17:48:14 +00:00
Jim Shield
5fe0ab8815 Revert "Resolve merge conflict"
This reverts commit 56ccb43c2b.
2024-01-18 17:48:03 +00:00
Jim Shield
56ccb43c2b Resolve merge conflict 2024-01-18 17:44:25 +00:00
Jim Shield
93d0754935 Make qbx use correct export for getCoreObject
This should be fine as qbox takes over the export but just to be sure
2024-01-18 17:41:28 +00:00
Jim Shield
d82366b59f version bump 2024-01-18 15:38:28 +00:00
Jim Shield
35202f7000 add fix for recipes having no final amount added 2024-01-18 15:33:51 +00:00
Jim Shield
bc5aadc394 add export error check to stashRemoveItem 2024-01-18 15:14:38 +00:00
Jim Shield
181c480ba6 return duty check for hasJob 2024-01-18 15:06:20 +00:00
Jim Shield
b973c71638 Update version.txt(?) 2024-01-18 14:45:41 +00:00
Jim Shield
ede0a44251 fix version.txt? 2024-01-18 14:42:23 +00:00
Jim Shield
e4b0f8601a fix bridge version check looking in wrong place 2024-01-18 14:17:01 +00:00
Jim Shield
d12c615f0b Merge pull request #4 from jimathy/duty-fixes
Duty fixes + CheckVersion + better debug
2024-01-18 13:16:45 +00:00
Jim Shield
e58163d631 CheckVersion supports free script checking 2024-01-18 13:08:16 +00:00
Jim Shield
e801910519 add CheckBridgeVersion and version.txt 2024-01-18 13:07:40 +00:00
Jim Shield
dbca627bc3 Fix hasJob + Add more debug messages 2024-01-18 13:05:45 +00:00
Jim Shield
b09534aad5 toggleduty() better checks - dupewarn() more info 2024-01-18 12:40:15 +00:00
Nicholas Blew
63c2d5d83d Allow for passing through stash options when opening a stash 2024-01-18 02:20:20 -05:00
Jim Shield
52dc9ff8ae Merge pull request #2 from jimathy/fixes
Fixes
2024-01-18 00:54:51 +00:00
Jim Shield
10e184afb0 move old/new qbcore info fixes 2024-01-18 00:52:00 +00:00
Jim Shield
4e645001fb Stop invImg giving errors if no image 2024-01-18 00:50:54 +00:00
Jim Shield
e33b68bd55 change qs-inv getinventory to getuserinventory 2024-01-17 23:39:10 +00:00
Jim Shield
7094bda2fb more old qbcore updates 2024-01-17 23:38:28 +00:00
Jim Shield
409c181cb2 add support for older QBCore GetPlayer event 2024-01-17 23:36:45 +00:00
Jim Shield
6c38f90b9a fix grade crafting 2024-01-17 21:05:38 +00:00
Jim Shield
d693a99852 update readme export info 2024-01-17 20:23:54 +00:00
Jim Shield
508c4a734a fix job crafting breaking and needing grades 2024-01-17 20:23:27 +00:00
Jim Shield
cd93ea3a38 fix esx progressbar triggering with ox 2024-01-17 17:49:42 +00:00
7 changed files with 1925 additions and 502 deletions

615
README.md
View File

@@ -21,6 +21,619 @@ But I want this script to grow with help of others who know more about other cor
--- ---
The installation of this script is simple The installation of this script is simple
- REMOVE `-main` from the folder name, like any other github hosted script
- it just needs to start before any script that requires it - it just needs to start before any script that requires it
- it can start before core scripts if you want - it can start before core scripts if you want
- for `qb-core` I personally place this script in `resources > [standalone]` - for `qb-core` I personally place this script in `resources > [standalone]`
---
### Support for different exports and scripts
In exports.lua is the list of script folder names
This is for people who have customised/renamed scripts
eg. for people who use `ps-inventory`, this is mainly based on qb-inventory
so you need to rename
```lua
QBInv = "qb-inventory",
```
to
```lua
QBInv = "ps-inventory",
```
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

@@ -6,25 +6,22 @@ if IsDuplicityVersion() then
end end
end end
local timeout = 0 local timeout, timing, stashItems = 0, false, {}
local timing = false
local stashItems = {}
function GetStashTimeout(stashName, stop) function GetStashTimeout(stashName, stop)
if stop then stashItems = {} timing = false timeout = 0 return end if stop then stashItems, timing, timeout = {}, false, 0 return end
if stashItems[1] then return true else if #stashItems > 0 then return true end
if timeout <= 0 then if timeout <= 0 then
stashItems = triggerCallback(GetCurrentResourceName()..':server:GetStashItems', stashName) stashItems = triggerCallback(GetCurrentResourceName()..':server:GetStashItems', stashName)
timeout = 15000 timeout = 10000
if not timing then if not timing then
CreateThread(function() CreateThread(function()
timing = true timing = true
while timeout > 0 do timeout -= 1000 Wait(1000) end while timeout > 0 do timeout -= 1000 Wait(1000) end
timing = false stashItems = {} timeout = 0 timing, stashItems, timeout = false, {}, 0
end) end)
end end
end end
return false return false
end
end end
local CraftLock = false local CraftLock = false
@@ -33,51 +30,58 @@ function craftingMenu(data)
if data.stashName and not GetStashTimeout(data.stashName) then if data.stashName and not GetStashTimeout(data.stashName) then
--triggerNotify(nil, "Chacking", "success") --triggerNotify(nil, "Chacking", "success")
end end
if (data.job or data.gang) and not jobCheck(data.job or data.gang) then return end if (data.job or data.gang) and not jobCheck(data.job or data.gang) then return end
local Menu = {} local Menu, hasjob = {}, false
local Recipes = data.craftable.Recipes local Recipes = data.craftable.Recipes
local tempCarryTable = {}
for i = 1, #Recipes do for i = 1, #Recipes do
for k, v in pairs(Recipes[i]) do for k in pairs(Recipes[i]) do
if k ~= "amount" and k ~= "job" and k ~= "gang" then
tempCarryTable[k] = Recipes[i].amount or 1
end
end
end
local canCarryTable = triggerCallback(GetCurrentResourceName()..':server:canCarry', tempCarryTable)
for i = 1, #Recipes do
if not Recipes[i]["amount"] then Recipes[i]["amount"] = 1 end
for k, v in pairs(Recipes[i]) do
if k ~= "amount" and k ~= "job" and k ~= "gang" then if k ~= "amount" and k ~= "job" and k ~= "gang" then
if Recipes[i].job then hasjob = false if Recipes[i].job then
for l, b in pairs(data.craftable[i]["job"]) do for l, b in pairs(Recipes[i].job) do
hasjob = hasJob(l) hasjob = hasJob(l, nil, b)
if hasjob == true then break end
end end
end else hasjob = true end
local setheader, settext = "", "" local setheader, settext, disable = "", "", false
local text = "" if hasjob then
local disable = false local itemTable = {}
local checktable = {}
if Recipes[i].job and hasjob == false then else
for l, b in pairs(Recipes[i][tostring(k)]) do for l, b in pairs(Recipes[i][tostring(k)]) do
if not Items[l] then print("^3Error^7: ^2Script can't find ingredient item in Shared Items - ^1"..l.."^7") return end settext = settext..(settext ~= "" and br or "")..(Items[l] and Items[l].label or "error - "..l)..(b > 1 and " x"..b or "")
settext = settext..(settext ~= "" and br or "")..Items[l].label..(b > 1 and " x"..b or "") itemTable[l] = b
if data.stashName then checktable[l] = stashhasItem(stashItems, l, b)
else checktable[l] = hasItem(l, b) end
Wait(0) Wait(0)
end end
for _, v in pairs(checktable) do while not canCarryTable do Wait(0) end
if not v then if Config.System.Debug then print("^6Bridge^7: ^2Checking"..(data.stashName and " ^7'^6"..data.stashName.."^7'" or "").." ^2ingredients^7 - ^6"..k.."^7") end
disable = true if data.stashName then disable = not stashhasItem(stashItems, itemTable)
break else disable = not hasItem(itemTable) end
end setheader = (Items[tostring(k)] and Items[tostring(k)].label or "error - " .. tostring(k)) .. (Recipes[i]["amount"] > 1 and " x" .. Recipes[i]["amount"] or "")
end if not disable then
setheader = Items[tostring(k)].label..(Recipes[i]["amount"] > 1 and " x"..Recipes[i]["amount"] or "")..(not disable and " ✔️" or "") if not canCarryTable[k] then setheader = setheader .. " 📦"
else setheader = setheader .. " ✔️" end
elseif not canCarryTable[k] then setheader = setheader .. " 📦" end
Menu[#Menu + 1] = { Menu[#Menu + 1] = {
isMenuHeader = disable, isMenuHeader = disable or not canCarryTable[k],
icon = invImg(tostring(k)), icon = invImg(tostring(k)),
header = setheader, txt = settext, header = setheader,
txt = settext,
onSelect = function() 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 if Config.Crafting.MultiCraft then multiCraft(transdata) else makeItem(transdata) end
multiCraft(transdata)
else
makeItem(transdata)
end
end, end,
} }
end end
end end
Wait(0)
end end
end end
openMenu(Menu, { header = data.craftable.Header, onBack = data.onBack or nil, canClose = true, onExit = function() end, }) openMenu(Menu, { header = data.craftable.Header, onBack = data.onBack or nil, canClose = true, onExit = function() end, })
@@ -96,17 +100,20 @@ function multiCraft(data) local Menu = {}
} }
for k in pairsByKeys(success) do for k in pairsByKeys(success) do
local settext = "" local settext = ""
local itemTable = {}
for l, b in pairs(data.craft[data.item]) do for l, b in pairs(data.craft[data.item]) do
if data.stashName then itemTable[l] = (b * k)
success[k] = stashhasItem(stashItems, l, (b * k))
else
success[k] = hasItem(l, (b * k))
end
settext = settext..(settext ~= "" and br or "")..Items[l].label..(b*k > 1 and "- x"..b*k or "") settext = settext..(settext ~= "" and br or "")..Items[l].label..(b*k > 1 and "- x"..b*k or "")
Wait(0) Wait(0)
end end
local disable = false
if Config.System.Debug then print("^6Bridge^7: ^2Checking "..(data.stashName and "^7'^6"..data.stashName.."^7'" or "inventory").."^7x^5"..k.." ^2ingredients^7 - ^6"..data.item.."^7") end
if data.stashName then disable = not stashhasItem(stashItems, itemTable)
else disable = not hasItem(itemTable) end
Menu[#Menu + 1] = { Menu[#Menu + 1] = {
isMenuHeader = not success[k], isMenuHeader = disable,
arrow = not disable,
header = "Craft - x"..k * data.craft.amount, header = "Craft - x"..k * data.craft.amount,
txt = settext, txt = settext,
onSelect = function () onSelect = function ()
@@ -118,61 +125,54 @@ function multiCraft(data) local Menu = {}
end end
function makeItem(data) function makeItem(data)
if not CraftLock then CraftLock = true else return end if CraftLock then return end
local bartime, bartext, animDict, anim = nil, nil, nil, nil CraftLock = true
if data.craftable.progressBar then
bartime = data.craftable.progressBar.time
bartext = data.craftable.progressBar.label
else
bartime = 5000
bartext = Loc[Config.Lan].progressbar["progress_make"]
end
animDict = data.craftable.Anims.animDict or "amb@prop_human_parking_meter@male@idle_a"
anim = data.craftable.Anims.anim or "idle_a"
local amount = (data.amount and data.amount ~= 1) and data.amount or 1 local bartime = data.craftable.progressBar and data.craftable.progressBar.time or 5000
local bartext = (data.craftable.progressBar and data.craftable.progressBar.label) or (Loc[Config.Lan].progressbar and Loc[Config.Lan].progressbar["progress_make"]) or "Making a"
local crafted = true local animDict = data.craftable.Anims and data.craftable.Anims.animDict or "amb@prop_human_parking_meter@male@idle_a"
local crafting = true local anim = data.craftable.Anims and data.craftable.Anims.anim or "idle_a"
local amount = data.amount and (data.amount ~= 1) and data.amount or 1
local cam = createTempCam(PlayerPedId(), data.coords)
startTempCam(cam)
local crafted, crafting = true, true
local cam = createTempCam(PlayerPedId(), data.coords)
startTempCam(cam)
for i = 1, amount do for i = 1, amount do
for _, v in pairs(data.craft) do for k, v in pairs(data.craft) do
if type(v) == "table" then if k ~= "amount" and k ~= "job" then
for l, b in pairs(v) do if type(v) == "table" then
if crafting and progressBar({ for l, b in pairs(v) do
label = "Using "..b.." "..Items[l].label, if crafting and progressBar({
time = 1000, label = "Using "..b.." "..Items[l].label,
cancel = true, time = 1000,
dict = 'pickup_object', cancel = true,
anim = "putdown_low", dict = 'pickup_object',
flag = 48, anim = "putdown_low",
icon = l, flag = 48,
}) then icon = l,
--TriggerEvent('inventory:client:ItemBox', Items[l], "use", b) -- Show item box for each item }) then
else --TriggerEvent('inventory:client:ItemBox', Items[l], "use", b) -- Show item box for each item
crafted = false else
crafting = false crafted, crafting = false, false
break break
end
Wait(200)
end end
Wait(200) if crafted then
end if crafting and progressBar({
if crafted then label = bartext..Items[data.item].label,
if crafting and progressBar({ time = bartime,
label = bartext..Items[data.item].label, cancel = true,
time = bartime, dict = animDict,
cancel = true, anim = anim,
dict = animDict, flag = 8,
anim = anim, icon = data.item,
flag = 8, }) then
icon = data.item, TriggerServerEvent(GetCurrentResourceName()..":Crafting:GetItem", data.item, data.craft, data.stashName)
}) then else
TriggerServerEvent(GetCurrentResourceName()..":Crafting:GetItem", data.item, data.craft, data.stashName) crafting = false
else break
crafting = false end
break
end end
end end
end end
@@ -187,32 +187,101 @@ function makeItem(data)
end end
RegisterNetEvent(GetCurrentResourceName()..":Crafting:GetItem", function(ItemMake, craftable, stashName) RegisterNetEvent(GetCurrentResourceName()..":Crafting:GetItem", function(ItemMake, craftable, stashName)
local src = source local src, amount, stashItems = source, craftable and craftable.amount or 1, stashName and getStash(stashName)
local amount = 1
if stashName then if stashName then
local stashItems = getStash(stashName)
if craftable["amount"] then amount = craftable["amount"] end
local itemRemove = {} local itemRemove = {}
for k, v in pairs(craftable[ItemMake]) do for k, v in pairs(craftable[ItemMake] or {}) do
for l, b in pairs(stashItems) do for _, b in pairs(stashItems or {}) do
if k == b.name then if k == b.name then itemRemove[k] = v end
itemRemove[k] = v
end
end end
end end
stashRemoveItem(stashItems, stashName, itemRemove) stashRemoveItem(stashItems, stashName, itemRemove)
else else
if craftable then if craftable then
if craftable["amount"] then amount = craftable["amount"] end for k, v in pairs(craftable[ItemMake] or {}) do
for k, v in pairs(craftable[ItemMake]) do
TriggerEvent(GetCurrentResourceName()..":server:toggleItem", false, tostring(k), v, src) TriggerEvent(GetCurrentResourceName()..":server:toggleItem", false, tostring(k), v, src)
end end
end end
end end
TriggerEvent(GetCurrentResourceName()..":server:toggleItem", true, ItemMake, amount, src) TriggerEvent(GetCurrentResourceName()..":server:toggleItem", true, ItemMake, amount, src)
if GetResourceState("core_skills"):find("start") then exports["core_skills"]:AddExperience(src, 2) end
end) end)
--[[SHOPS]]-- --[[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) function openShop(data)
if (data.job or data.gang) and not jobCheck(data.job or data.gang) then return end if (data.job or data.gang) and not jobCheck(data.job or data.gang) then return end
if GetResourceState(OXInv):find("start") then if GetResourceState(OXInv):find("start") then
@@ -224,149 +293,72 @@ function openShop(data)
end end
-- Client & Server side -- Client & Server side
function hasItem(items, amount, src) local amount, count = amount and amount or 1, 0 function hasItem(items, amount, src) local amount = amount and amount or 1
if src then local grabInv = nil
if GetResourceState(OXInv):find("start") then local foundInv = ""
local item = exports[OXInv]:GetItem(src, items) if type(items) ~= "table" then items = { [items] = amount and amount or 1, } end
local amount = (amount or 1) if GetResourceState(OXInv):find("start") then
if item.count >= amount then foundInv = OXInv
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..item.count.."^7/^3"..amount.." "..tostring(items)) end if src then grabInv = exports[OXInv]:GetInventoryItems(src)
return true else grabInv = exports[OXInv]:GetPlayerItems() end
else if Config.System.Debug then
print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end
return false
end
elseif GetResourceState(QSInv):find("start") then elseif GetResourceState(QSInv):find("start") then
for _, itemData in pairs(exports[QSInv]:GetInventory(src)) do foundInv = QSInv
if itemData and (itemData.name == items) then if src then grabInv = exports[QSInv]:GetInventory(src)
--if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end else grabInv = exports[QSInv]:getUserInventory() end
count += (itemData.amount or 1)
end
end
if count >= amount then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..count.."^7/^3"..amount.." "..tostring(items)) end
return true
else
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end
return false
end
elseif GetResourceState(CoreInv):find("start") then elseif GetResourceState(OrigenInv):find("start") then
local item = exports[CoreInv]:getItems('primary-'..src, items) foundInv = OrigenInv
if src then grabInv = exports[OrigenInv]:GetInventory(src)
else grabInv = exports[OrigenInv]:getPlayerInventory() end
if item.amount >= amount then elseif GetResourceState(CoreInv):find("start") then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..item.amount.."^7/^3"..amount.." "..tostring(items)) end foundInv = CoreInv
return true if src then
else if Config.System.Debug then if GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then
print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end grabInv = Core.Functions.GetPlayer(src).PlayerData.items
return false elseif GetResourceState(ESXExport):find("start") then
local Player = ESX.GetPlayerFromId(src)
grabInv = Player.getInventory(false)
end end
elseif GetResourceState(CodeMInv):find("start") then
local success = exports["codem-inventory"]:CheckItemValid(src, items, amount)
if success then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..amount.." "..tostring(items)) end
return true
end
elseif GetResourceState(CodeMInv):find("start") then
for _, itemData in pairs(exports[CodeMInv]:GetUserInventory(src)) do
if itemData and (itemData.name == items) then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end
count += (itemData.amount or 1)
end
end
if count >= amount then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..count.."^7/^3"..amount.." "..tostring(items)) end
return true
else
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end
return false
end
else else
for _, itemData in pairs(Core.Functions.GetPlayer(src).PlayerData.items) do local p = promise.new()
if itemData and (itemData.name == items) then Core.Functions.TriggerCallback('core_inventory:server:getInventory', function(cb) p:resolve(cb) end)
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end local result = Citizen.Await(p)
count += (itemData.amount or 1) if type(result) == "string" then result = json.decode(result) end
end grabInv = result
end
if count >= amount then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..count.."^7/^3"..amount.." "..tostring(items)) end
return true
else
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end
return false
end
end end
elseif GetResourceState(CodeMInv):find("start") then
foundInv = CodeMInv
if src then grabInv = exports[CodeMInv]:GetUserInventory(src)
else grabInv = exports[CodeMInv]:GetClientPlayerInventory() end
elseif GetResourceState(QBInv):find("start") then
foundInv = QBInv
if src then grabInv = Core.Functions.GetPlayer(src).PlayerData.items
else grabInv = Core.Functions.GetPlayerData().items end
else else
if GetResourceState(OXInv):find("start") then print("^4ERROR^7: ^2No Inventory detected ^7- ^2Check ^3exports^1.^2lua^7")
local count = tonumber(exports[OXInv]:Search('count', items)) end
local amount = (amount or 1)
if count >= amount then if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..count.."^7/^3"..amount.." "..tostring(items)) end return true
else if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end return false end
elseif GetResourceState(QSInv):find("start") then if grabInv then
for _, itemData in pairs(exports[QSInv]:GetInventory()) do local hasTable = {}
if itemData and (itemData.name == items) then for item, amount in pairs(items) do
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end if not Items[item] then print("^4ERROR^7: ^2Script can't find ingredient item in Shared Items - ^1"..item.."^7") end
count += (itemData.amount or 1) local count = 0
end for _, itemData in pairs(grabInv) do
if itemData and (itemData.name == item) then count += (itemData.count or itemData.amount or 1) end
end end
if count >= amount then foundInv = foundInv:gsub("%-", "^7-^6"):gsub("%_", "^7_^6")
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..count.."^7/^3"..amount.." "..tostring(items)) end local foundMessage = "^6Bridge^7: ^3hasItem^7[^6"..foundInv.."^7]: "..tostring(item).." ^3"..count.."^7/^3"..amount
return true if count >= amount then foundMessage = foundMessage.." ^5FOUND^7" else foundMessage = foundMessage .." ^1NOT FOUND^7" end
else if Config.System.Debug then print(foundMessage) end
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end hasTable[item] = { hasItem = count >= amount, count = count }
return false
end
elseif GetResourceState(CoreInv):find("start") then
for _, itemData in pairs(exports[CoreInv]:getInventory('primary-'..GetPlayerServerId(PlayerPedId()))) do
if itemData and (itemData.name == items) then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end
count += (itemData.amount or 1)
end
end
if count >= amount then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..count.."^7/^3"..amount.." "..tostring(items)) end
return true
else
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7") end
return false
end
elseif GetResourceState(CodeMInv):find("start") then
local success = exports[CodeMInv]:CheckItemValid(items, amount)
if success then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..amount.." "..tostring(items)) end
return true
end
elseif GetResourceState(QBInv):find("start") then
--if tonumber(GetResourceMetadata(QBInv, 'version')) <= 1.2 then
-- return exports[QBInv]:HasItem(items, amount)
--else
for _, itemData in pairs(Core.Functions.GetPlayerData().items) do
if itemData and (itemData.name == items) then
if Config.System.Debug then print("^6Bridge^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end
count += (itemData.amount or 1)
end
end
if count >= amount then
if Config.System.Debug then
print("^6Bridge^7: ^3HasItem^7: ^5FOUND^7 ^3"..count.."^7/^3"..amount.." "..tostring(items))
end
return true
else
if Config.System.Debug then
print("^6Bridge^7: ^3HasItem^7: ^2"..tostring(items).." ^1NOT FOUND^7")
end
return false
end
-- end
end end
for k, v in pairs(hasTable) do if not v.hasItem then return false, hasTable end end
return true, hasTable
end end
end end
@@ -379,43 +371,51 @@ function openStash(data)
exports[CodeMInv]:OpenStash(data.stash, 400000, 100) exports[CodeMInv]:OpenStash(data.stash, 400000, 100)
else else
TriggerEvent("inventory:client:SetCurrentStash", data.stash) TriggerEvent("inventory:client:SetCurrentStash", data.stash)
TriggerServerEvent("inventory:server:OpenInventory", "stash", data.stash) TriggerServerEvent("inventory:server:OpenInventory", "stash", data.stash, data.stashOptions)
end end
lookEnt(data.coords) lookEnt(data.coords)
end end
function getStash(stashName) function getStash(stashName) local stashResource = ""
local stashItems, items = {}, {} local stashItems, items = {}, {}
if GetResourceState(OXInv):find("start") then if GetResourceState(OXInv):find("start") then stashResource = OXInv
if Config.System.Debug then print("^6Bridge^7: ^2Retrieving ^3Stash^2 with ^7ox_inventory") end
stashItems = exports[OXInv]:Inventory(stashName).items stashItems = exports[OXInv]:Inventory(stashName).items
elseif GetResourceState(QSInv):find("start") then
if Config.System.Debug then print("^6Bridge^7: ^2Retrieving ^3Stash^2 with ^7qs-inventory") end elseif GetResourceState(QSInv):find("start") then stashResource = QSInv
stashItems = exports[QSInv]:GetStashItems(stashName) stashItems = exports[QSInv]:GetStashItems(stashName)
elseif GetResourceState(CodeMInv):find("start") then
if Config.System.Debug then print("^6Bridge^7: ^2Retrieving ^3Stash^2 with ^7qs-inventory") end elseif GetResourceState(CoreInv):find("start") then stashResource = CoreInv
stashItems = exports[CoreInv]:getInventory(stashName)
elseif GetResourceState(CodeMInv):find("start") then stashResource = CodeMInv
stashItems = exports[CodeMInv]:GetInventoryItems('Stash', stashName) stashItems = exports[CodeMInv]:GetInventoryItems('Stash', stashName)
elseif GetResourceState(QBInv):find("start") then
if Config.System.Debug then print("^6Bridge^7: ^2Retrieving ^3Stash^2 with ^7qb-inventory") end elseif GetResourceState(OrigenInv):find("start") then stashResource = OrigenInv
stashItems = exports[OrigenInv]:GetStashItems(stashName)
elseif GetResourceState(QBInv):find("start") then stashResource = QBInv
local result = MySQL.scalar.await('SELECT items FROM stashitems WHERE stash = ?', { stashName }) local result = MySQL.scalar.await('SELECT items FROM stashitems WHERE stash = ?', { stashName })
if result then stashItems = json.decode(result) end if result then stashItems = json.decode(result) end
end end
if Config.System.Debug then print("^6Bridge^7: ^2Retrieving ^3Stash^2 with ^7"..stashResource) end
if stashItems then if stashItems then
for _, item in pairs(stashItems) do for _, item in pairs(stashItems) do
local itemInfo = Items[item.name:lower()] local itemInfo = Items[item.name:lower()]
if itemInfo then if itemInfo then
items[item.slot] = { local indexNum = #items+1 -- Added to help recreate missing slot numbers
name = itemInfo["name"], items[(item.slot and item.slot) or indexNum] = {
name = itemInfo.name or nil,
amount = tonumber(item.amount) or tonumber(item.count), amount = tonumber(item.amount) or tonumber(item.count),
info = item.info ~= nil and item.info or "", info = item.info or "",
label = itemInfo["label"], label = itemInfo.label or nil,
description = itemInfo["description"] ~= nil and itemInfo["description"] or "", description = itemInfo.description or "",
weight = itemInfo["weight"], weight = itemInfo.weight or nil,
type = itemInfo["type"], type = itemInfo.type or nil,
unique = itemInfo["unique"], unique = itemInfo.unique or nil,
useable = itemInfo["useable"], useable = itemInfo.useable or nil,
image = itemInfo["image"], image = itemInfo.image or nil,
slot = item.slot, slot = (item.slot and item.slot) or indexNum,
} }
end end
end end
@@ -430,11 +430,32 @@ function stashRemoveItem(stashItems, stashName, items) local amount = amount and
exports[OXInv]:RemoveItem(stashName, k, v) exports[OXInv]:RemoveItem(stashName, k, v)
if Config.System.Debug then print("^6Bridge^7: ^2Removing item from ^3Stash^2 with ^7"..OXInv, k, v) end if Config.System.Debug then print("^6Bridge^7: ^2Removing item from ^3Stash^2 with ^7"..OXInv, k, v) end
end end
elseif GetResourceState(QSInv):find("start") then elseif GetResourceState(QSInv):find("start") then
for k, v in pairs(items) do
for l in pairs(stashItems) do
if stashItems[l].name == k then
if (stashItems[l].amount - v) <= 0 then
if Config.System.Debug then
print("^6Bridge^7: ^2None of this item left in stash ^3Stash^7", k, v)
end
stashItems[l] = nil
else
if Config.System.Debug then
print("^6Bridge^7: ^2Removing item from ^3Stash^2 with ^7"..QBInv, k, v)
end
exports[QSInv]:RemoveItemIntoStash(stashName, k, v, l)
end
end
end
end
elseif GetResourceState(CoreInv):find("start") then
for k, v in pairs(items) do for k, v in pairs(items) do
exports[QSInv]:RemoveItemIntoStash(stashName, k, v) exports[CoreInv]:removeItemExact(stashName, k, v)
if Config.System.Debug then print("^6Bridge^7: ^2Removing item from ^3Stash^2 with ^7"..QSInv, k, v) end if Config.System.Debug then print("^6Bridge^7: ^2Removing item from ^3Stash^2 with ^7"..CoreInv, k, v) end
end end
elseif GetResourceState(CodeMInv):find("start") then elseif GetResourceState(CodeMInv):find("start") then
for k, v in pairs(items) do for k, v in pairs(items) do
for l in pairs(stashItems) do for l in pairs(stashItems) do
@@ -456,7 +477,14 @@ function stashRemoveItem(stashItems, stashName, items) local amount = amount and
if Config.System.Debug then if Config.System.Debug then
print("^6Bridge^7: ^3saveStash^7: ^2Saving ^3QB^2 stash ^7'^6"..stashName.."^7'") print("^6Bridge^7: ^3saveStash^7: ^2Saving ^3QB^2 stash ^7'^6"..stashName.."^7'")
end end
else
elseif GetResourceState(OrigenInv):find("start") then
for k, v in pairs(items) do
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
elseif GetResourceState(QBInv):find("start") then
for k, v in pairs(items) do for k, v in pairs(items) do
for l in pairs(stashItems) do for l in pairs(stashItems) do
if stashItems[l].name == k then if stashItems[l].name == k then
@@ -478,26 +506,130 @@ function stashRemoveItem(stashItems, stashName, items) local amount = amount and
print("^6Bridge^7: ^3saveStash^7: ^2Saving ^3QB^2 stash ^7'^6"..stashName.."^7'") print("^6Bridge^7: ^3saveStash^7: ^2Saving ^3QB^2 stash ^7'^6"..stashName.."^7'")
end end
MySQL.Async.insert('INSERT INTO stashitems (stash, items) VALUES (:stash, :items) ON DUPLICATE KEY UPDATE items = :items', { ['stash'] = stashName, ['items'] = json.encode(stashItems) }) MySQL.Async.insert('INSERT INTO stashitems (stash, items) VALUES (:stash, :items) ON DUPLICATE KEY UPDATE items = :items', { ['stash'] = stashName, ['items'] = json.encode(stashItems) })
else
print("^4ERROR^7: ^2No Inventory detected ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
RegisterNetEvent(GetCurrentResourceName()..":server:stashRemoveItem", stashRemoveItem) RegisterNetEvent(GetCurrentResourceName()..":server:stashRemoveItem", stashRemoveItem)
function stashhasItem(stashItems, item, amount) local amount, count = amount and amount or 1, 0 function stashhasItem(stashItems, items, amount)
for k, itemData in pairs(stashItems) do local invs = {OXInv, QSInv, CoreInv, CodeMInv, OrigenInv, QBInv}
if itemData and (itemData.name == item) then local foundInv = ""
--if Config.System.Debug then for _, inv in ipairs(invs) do
-- print("^6Bridge^7: ^3stashHasItem^7: ^2Item^7: '^3"..tostring(item).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") if GetResourceState(inv):find("start") then
--end foundInv = inv:gsub("%-", "^7-^6"):gsub("%_", "^7_^6")
count += (itemData.amount or 1) break
end end
end end
if count >= amount then
if Config.System.Debug then if type(items) ~= "table" then items = { [items] = amount and amount or 1, } end
print("^6Bridge^7: ^3stashHasItem^7: ^2Items ^3"..item.." ^5FOUND^7 x^3"..count.."^7/^3"..amount.."^7") end local hasTable = {}
return for item, amount in pairs(items) do
true local count = 0
else for _, itemData in pairs(stashItems) do
if Config.System.Debug then print("^6Bridge^7: ^3stashHasItem^7: ^2Items ^1NOT FOUND^7 "..json.encode(item)) end if itemData and (itemData.name == item) then
return false count += (itemData.amount or 1)
end
end
local debugMsg = string.format("^6Bridge^7: ^3stashHasItem^7[^6%s^7]: %s '%s' ^3%d^7/^3%d^7", foundInv, (count >= amount and "^5FOUND^7" or "^1NOT FOUND^7"), item, count, amount)
if Config.System.Debug then print(debugMsg) end
hasTable[item] = { hasItem = (count >= amount), count = count }
end
for k, v in pairs(hasTable) do if v.hasItem == false then return false, hasTable end end
return true, hasTable
end
if IsDuplicityVersion() then
if GetResourceState(OXLibExport):find("start") then
createCallback(GetCurrentResourceName()..':server:canCarry', function(source, itemTable) local result = canCarry(itemTable, source) return result end)
else
createCallback(GetCurrentResourceName()..':server:canCarry', function(source, cb, itemTable) local result = canCarry(itemTable, source) cb(result) end)
end
end
function canCarry(itemTable, src)
local resultTable = {}
if src then
if GetResourceState(OXInv):find("start") then
for k, v in pairs(itemTable) do
resultTable[k] = exports[OXInv]:CanCarryItem(src, k, v)
end
elseif GetResourceState(QSInv):find("start") then
for k, v in pairs(itemTable) do
resultTable[k] = exports[OXInv]:CanCarryItem(src, k, v)
end
elseif GetResourceState(CoreInv):find("start") then
--??
elseif GetResourceState(CodeMInv):find("start") then
for k, v in pairs(itemTable) do
local weight = Items[k].weight
resultTable[k] = exports[CodeMInv]:CanCarryItem(src, weight, v)
end
elseif GetResourceState(OrigenInv):find("start") then
for k, v in pairs(itemTable) do
resultTable[k] = exports[OrigenInv]:canCarryItem(src, k, v)
end
elseif GetResourceState(QBInv):find("start") then
local Player = Core.Functions.GetPlayer(src)
local items = Player.PlayerData.items
local weight, totalWeight = 0, 0
if not items then return false end
for _, item in pairs(items) do weight += item.weight * item.amount end
totalWeight = tonumber(weight)
for k, v in pairs(itemTable) do
local itemInfo = Items[k]
if not itemInfo and not Player.Offline then
triggerNotify(nil, 'Item does not exist', 'error', src)
resultTable[k] = true
else
resultTable[k] = (totalWeight + (Items[k]['weight'] * v)) <= 120000
end
end
end
end
return resultTable
end
function getRandomReward(itemName) -- intended for job scripts
if Config.Rewards.RewardPool then
local reward = false
if type(Config.Rewards.RewardItem) == "string" then Config.Rewards.RewardItem = { Config.Rewards.RewardItem } end
for k, v in pairs(Config.Rewards.RewardItem) do
if v == itemName then reward = true break end
end
if reward then
removeItem(itemName, 1)
local totalRarity = 0
for i=1, #Config.Rewards.RewardPool do
totalRarity += Config.Rewards.RewardPool[i].rarity
end
if Config.System.Debug then
print("^6Bridge^7: ^3getRandomReward^7: ^2Total Rarity ^7'^6"..totalRarity.."^7'")
end
local randomNum = math.random(1, totalRarity)
if Config.System.Debug then
print("^6Bridge^7: ^3getRandomReward^7: ^2Random Number ^7'^6"..randomNum.."^7'")
end
local currentRarity = 0
for i=1, #Config.Rewards.RewardPool do
currentRarity += Config.Rewards.RewardPool[i].rarity
if randomNum <= currentRarity then
if Config.System.Debug then
print("^6Bridge^7: ^3getRandomReward^7: ^2Selected toy ^7'^6"..Config.Rewards.RewardPool[i].item.."^7'")
end
addItem(Config.Rewards.RewardPool[i].item, 1)
return
end
end
end
end end
end end

View File

@@ -7,8 +7,9 @@ Exports = {
OXInv = "ox_inventory", OXInv = "ox_inventory",
QBInv = "qb-inventory", QBInv = "qb-inventory",
QSInv = "qs-inventory", QSInv = "qs-inventory",
CoreInv = "core-inventory", CoreInv = "core_inventory",
CodeMInv = "codem-inventory", CodeMInv = "codem-inventory",
OrigenInv = "origen_inventory",
OXLibExport = "ox_lib", OXLibExport = "ox_lib",

View File

@@ -8,20 +8,47 @@ function jobCheck(job)
return canDo return canDo
end end
local time = 100 local time = 500
function loadModel(model) function loadModel(model)
if not HasModelLoaded(model) then if Config.System.Debug then print("^6Bridge^7: ^2Loading Model^7: '^6"..model.."^7'") end if not IsModelValid(model) then print("^6Bridge^7: ^1ERROR^7: ^2Model^7 - '^6"..model.."^7' ^2does not exist in server") return
while not HasModelLoaded(model) do if time > 0 then time = time - 1 RequestModel(model) else
else time = 1000 print("^6Bridge^7: ^3LoadModel^7: ^2Timed out loading model ^7'^6"..model.."^7'") break end if not HasModelLoaded(model) then
Wait(10) end 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 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
function loadAnimDict(animDict)
if not DoesAnimDictExist(animDict) then print("^6Bridge^7: ^1ERROR^7: ^2Anim Dictionary^7 - '^6"..animDict.."^7' ^2does not exist in server") return
else
if Config.System.Debug then print("^6Bridge^7: ^2Loading Anim Dictionary^7: '^6"..animDict.."^7'") end
while not HasAnimDictLoaded(animDict) do RequestAnimDict(animDict) Wait(5) end
end
end
function unloadAnimDict(animDict) if Config.System.Debug then print("^6Bridge^7: ^2Removing Anim Dictionary from memory cache^7: '^6"..animDict.."^7'") end RemoveAnimDict(animDict) end
function loadPtfxDict(ptFxName)
if not HasNamedPtfxAssetLoaded(ptFxName) then
if Config.System.Debug then
print("^6Bridge^7: ^2Loading Ptfx Dictionary^7: '^6"..ptFxName.."^7'")
end
while not HasNamedPtfxAssetLoaded(ptFxName) do RequestNamedPtfxAsset(ptFxName) Wait(5) end
end end
end end
function unloadModel(model) if Config.System.Debug then print("^6Bridge^7: ^2Removing Model^7: '^6"..model.."^7'") end SetModelAsNoLongerNeeded(model) end
function loadAnimDict(dict) if Config.System.Debug then print("^6Bridge^7: ^2Loading Anim Dictionary^7: '^6"..dict.."^7'") end while not HasAnimDictLoaded(dict) do RequestAnimDict(dict) Wait(5) end end
function unloadAnimDict(dict) if Config.System.Debug then print("^6Bridge^7: ^2Removing Anim Dictionary^7: '^6"..dict.."^7'") end RemoveAnimDict(dict) end
function loadPtfxDict(dict) if Config.System.Debug then if not HasNamedPtfxAssetLoaded(dict) then print("^6Bridge^7: ^2Loading Ptfx Dictionary^7: '^6"..dict.."^7'") end end while not HasNamedPtfxAssetLoaded(dict) do RequestNamedPtfxAsset(dict) Wait(5) 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 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 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 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 RequestStreamedTextureDict(dict) Wait(5) end
end
end
function countTable(table) local i = 0 for keys in pairs(table) do i += 1 end return i end function countTable(table) local i = 0 for keys in pairs(table) do i += 1 end return i end
@@ -29,11 +56,12 @@ function pairsByKeys(t) local a = {} for n in pairs(t) do a[#a+1] = n end table.
function playAnim(animDict, animName, duration, flag, ped) function playAnim(animDict, animName, duration, flag, ped)
loadAnimDict(animDict) loadAnimDict(animDict)
TaskPlayAnim(ped and ped or PlayerPedId(), animDict, animName, 1.0, -1.0, duration or 30000, flag or 50, 1, false, false, false) TaskPlayAnim(ped and ped or PlayerPedId(), animDict, animName, 8.0, -8.0, duration or 30000, flag or 50, 1, false, false, false)
end end
function stopAnim(animDict, animName) function stopAnim(animDict, animName, ped)
StopAnimTask(PlayerPedId(), animName, animDict) StopAnimTask(ped or PlayerPedId(), animDict, animName, 0.5)
StopAnimTask(ped or PlayerPedId(), animName, animDict, 0.5)
unloadAnimDict(animDict) unloadAnimDict(animDict)
end end
@@ -60,7 +88,7 @@ local Peds = {}
local Props = {} local Props = {}
function makePed(model, coords, freeze, collision, scenario, anim, synced) function makePed(model, coords, freeze, collision, scenario, anim, synced)
loadModel(model) loadModel(model)
local ped = CreatePed(0, model, coords.x, coords.y, coords.z-1.03, coords.w, synced and 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) SetEntityInvincible(ped, true)
SetBlockingOfNonTemporaryEvents(ped, true) SetBlockingOfNonTemporaryEvents(ped, true)
FreezeEntityPosition(ped, freeze and freeze or true) FreezeEntityPosition(ped, freeze and freeze or true)
@@ -82,7 +110,7 @@ end
function makeProp(data, freeze, synced) function makeProp(data, freeze, synced)
loadModel(data.prop) loadModel(data.prop)
local prop = CreateObject(data.prop, data.coords.x, data.coords.y, data.coords.z-1.03, synced 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) SetEntityHeading(prop, data.coords.w + 180.0)
FreezeEntityPosition(prop, freeze and freeze or 0) FreezeEntityPosition(prop, freeze and freeze or 0)
if Config.System.Debug then if Config.System.Debug then
@@ -95,17 +123,25 @@ function makeProp(data, freeze, synced)
end end
function cv(amount) function cv(amount)
local formatted = amount local formatted = amount or "0"
while true do formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') if (k==0) then break end Wait(0) end while true do formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') if (k==0) then break end Wait(0) end
return formatted return formatted
end end
AddEventHandler('onResourceStop', function(r) function DrawText3D(x, y, z, text)
if r ~= GetCurrentResourceName() then return end SetTextScale(0.35, 0.35)
stopSpinner() SetTextFont(4)
for i = 1, #Peds do DeletePed(Peds[i]) end SetTextProportional(true)
for i = 1, #Props do destroyProp(Props[i]) end SetTextColour(255, 255, 255, 215)
end) BeginTextCommandDisplayText("STRING")
SetTextCentre(true)
AddTextComponentSubstringPlayerName(text)
SetDrawOrigin(x,y,z, 0)
EndTextCommandDisplayText(0.0, 0.0)
local factor = string.len(text) / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
function instantLookEnt(ent, ent2) function instantLookEnt(ent, ent2)
local p1 = GetEntityCoords(ent, true) local p1 = GetEntityCoords(ent, true)
@@ -139,12 +175,14 @@ function lookEnt(entity) local ped = PlayerPedId()
end end
function destroyProp(entity) function destroyProp(entity)
if Config.System.Debug then print("^6Bridge^7: ^2Destroying Prop^7: '^6"..entity.."^7'") end if entity then
if IsEntityAttachedToEntity(entity, PlayerPedId()) then if Config.System.Debug then print("^6Bridge^7: ^2Destroying Prop^7: '^6"..entity.."^7'") end
SetEntityAsMissionEntity(entity) if IsEntityAttachedToEntity(entity, PlayerPedId()) then
DetachEntity(entity, true, true) SetEntityAsMissionEntity(entity)
DetachEntity(entity, true, true)
end
DeleteObject(entity)
end end
DeleteObject(entity)
end end
function pushVehicle(entity) function pushVehicle(entity)
@@ -173,8 +211,23 @@ function pushVehicle(entity)
end end
end end
function ensureNetToVeh(vehNetID)
if Config.System.Debug then print("^6Bridge^7: ^3ensureNetToVeh^7: ^2Requesting NetworkDoesNetworkIdExist^7(^6"..vehNetID.."^7)") end
local timeout = 100
while not NetworkDoesNetworkIdExist(vehNetID) and timeout > 0 do timeout -= 1 Wait(10) end
if not NetworkDoesNetworkIdExist(vehNetID) then return 0 end
timeout = 100
local vehicle = NetToVeh(vehNetID)
while not DoesEntityExist(vehicle) and vehicle ~= 0 and timeout > 0 do timeout -= 1 Wait(10) end
if not DoesEntityExist(vehicle) then return 0 end
return vehicle
end
local scriptTxd = not IsDuplicityVersion() and CreateRuntimeTxd(GetCurrentResourceName()..'scriptTxd') or nil
local customDUIList = {}
function makeBlip(data) function makeBlip(data)
local blip = AddBlipForCoord(data.coords) local blip = AddBlipForCoord(vec3(data.coords.x, data.coords.y, data.coords.z))
SetBlipAsShortRange(blip, true) SetBlipAsShortRange(blip, true)
SetBlipSprite(blip, data.sprite or 106) SetBlipSprite(blip, data.sprite or 106)
SetBlipColour(blip, data.col or 5) SetBlipColour(blip, data.col or 5)
@@ -184,8 +237,20 @@ function makeBlip(data)
BeginTextCommandSetBlipName('STRING') BeginTextCommandSetBlipName('STRING')
AddTextComponentString(tostring(data.name)) AddTextComponentString(tostring(data.name))
EndTextCommandSetBlipName(blip) 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 if Config.System.Debug then print("^6Bridge^7: ^6Blip ^2created for location^7: '^6"..data.name.."^7'") end
return blip return blip
end end
function makeEntityBlip(data) function makeEntityBlip(data)
@@ -200,10 +265,135 @@ function makeEntityBlip(data)
BeginTextCommandSetBlipName('STRING') BeginTextCommandSetBlipName('STRING')
AddTextComponentString(tostring(data.name)) AddTextComponentString(tostring(data.name))
EndTextCommandSetBlipName(blip) 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 if Config.System.Debug then print("^6Bridge^7: ^6Blip ^2created for Entity^7: '^6"..data.name.."^7'") end
return blip return blip
end 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) function lockInv(toggle)
FreezeEntityPosition(PlayerPedId(), toggle) FreezeEntityPosition(PlayerPedId(), toggle)
LocalPlayer.state:set("inv_busy", toggle, true) LocalPlayer.state:set("inv_busy", toggle, true)
@@ -288,8 +478,6 @@ function progressBar(data)
if data.cam then stopTempCam(data.cam) end if data.cam then stopTempCam(data.cam) end
end end
exports["esx_progressbar"]:Progressbar(message, length, Options)
elseif Config.System.ProgressBar == "qb" then elseif Config.System.ProgressBar == "qb" then
Core.Functions.Progressbar("mechbar", Core.Functions.Progressbar("mechbar",
data.label, data.label,
@@ -467,7 +655,7 @@ end)
RegisterNetEvent(GetCurrentResourceName()..":server:setNeed", function(type, amount) local src = source RegisterNetEvent(GetCurrentResourceName()..":server:setNeed", function(type, amount) local src = source
if type == "thirst" then if type == "thirst" then
setThirst(src, amount) setThirst(src, amount)
elseif type == "thirst" then elseif type == "hunger" then
setHunger(src, amount) setHunger(src, amount)
end end
end) end)
@@ -476,7 +664,7 @@ function setThirst(src, thirst)
if GetResourceState(ESXExport):find("start") then if GetResourceState(ESXExport):find("start") then
TriggerClientEvent('esx_status:add', src, 'thirst', thirst) TriggerClientEvent('esx_status:add', src, 'thirst', thirst)
elseif GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then elseif GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then
local Player = QBCore.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('thirst', thirst) Player.Functions.SetMetaData('thirst', thirst)
TriggerClientEvent("hud:client:UpdateNeeds", src, thirst, Player.PlayerData.metadata.thirst) TriggerClientEvent("hud:client:UpdateNeeds", src, thirst, Player.PlayerData.metadata.thirst)
end end
@@ -486,7 +674,7 @@ function setHunger(src, hunger)
if GetResourceState(ESXExport):find("start") then if GetResourceState(ESXExport):find("start") then
TriggerClientEvent('esx_status:add', src, 'hunger', hunger) TriggerClientEvent('esx_status:add', src, 'hunger', hunger)
elseif GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then elseif GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then
local Player = QBCore.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('hunger', hunger) Player.Functions.SetMetaData('hunger', hunger)
TriggerClientEvent("hud:client:UpdateNeeds", src, hunger, Player.PlayerData.metadata.hunger) TriggerClientEvent("hud:client:UpdateNeeds", src, hunger, Player.PlayerData.metadata.hunger)
end end
@@ -504,8 +692,8 @@ end
-- [[CONSUME]] -- -- [[CONSUME]] --
function ConsumeSuccess(itemName, type) function ConsumeSuccess(itemName, type)
ExecuteCommand("e c") ExecuteCommand("e c")
toggleItem(false, itemName, 1) removeItem(itemName, 1)
if GetResourceState(ESXEport):find("start") then if GetResourceState(ESXExport):find("start") then
if Items[itemName].hunger then if Items[itemName].hunger then
TriggerServerEvent(GetCurrentResourceName()..":server:setNeed", "hunger", Items[itemName].hunger * 10000) TriggerServerEvent(GetCurrentResourceName()..":server:setNeed", "hunger", Items[itemName].hunger * 10000)
end end
@@ -521,23 +709,29 @@ function ConsumeSuccess(itemName, type)
end end
end end
if type == "alcohol" then alcoholCount += 1 if type == "alcohol" then alcoholCount += 1
if alcoholCount > 1 and alcoholCount < 4 then TriggerEvent("evidence:client:SetStatus", "alcohol", 200) elseif alcoholCount >= 4 then TriggerEvent("evidence:client:SetStatus", "heavyalcohol", 200) AlienEffect() end if alcoholCount > 1 and alcoholCount < 4 then
TriggerEvent("evidence:client:SetStatus", "alcohol", 200)
elseif alcoholCount >= 4 then
TriggerEvent("evidence:client:SetStatus", "heavyalcohol", 200)
AlienEffect()
end
end end
if Config.RewardItem == itemName then toggleItem(true, Config.RewardPool[math.random(1, #Config.RewardPool)], 1) end getRandomReward(itemName) -- check if a reward item should be given
end end
function addItem(item, amount, info) function addItem(item, amount, info)
TriggerServerEvent(GetCurrentResourceName()..":server:toggleItem", true, item, amount) TriggerServerEvent(GetCurrentResourceName()..":server:toggleItem", true, item, amount, nil, info)
end end
function removeItem(item, amount) function removeItem(item, amount)
TriggerServerEvent(GetCurrentResourceName()..":server:toggleItem", false, item, amount) TriggerServerEvent(GetCurrentResourceName()..":server:toggleItem", false, item, amount, nil, info)
end end
RegisterNetEvent(GetCurrentResourceName()..":server:toggleItem", function(give, item, amount, newsrc) RegisterNetEvent(GetCurrentResourceName()..":server:toggleItem", function(give, item, amount, newsrc)
local src = newsrc or source local src = newsrc or source
local addremove = (tostring(give) == "true" and "addItem" or "removeItem")
if Config.System.Debug then if Config.System.Debug then
print("^6Bridge^7: ^3toggleItem ^2triggered^7: ^6"..(tostring(give) == "true" and "addItem" or "removeItem").."^7 - ['^8"..tostring(item).."^7'] x"..(tostring(amount) or "1")) print("^6Bridge^7: ^3toggleItem ^2triggered^7: ^6"..addremove.."^7 - '"..tostring(item).."' x"..(tostring(amount) or "1"))
end end
local remamount = (amount and amount or 1) local remamount = (amount and amount or 1)
if item == nil then return end if item == nil then return end
@@ -545,12 +739,38 @@ RegisterNetEvent(GetCurrentResourceName()..":server:toggleItem", function(give,
if hasItem(item, amount and amount or 1, src) then -- check if you still have the item if hasItem(item, amount and amount or 1, src) then -- check if you still have the item
if GetResourceState(OXInv):find("start") then if GetResourceState(OXInv):find("start") then
local success = exports[OXInv]:RemoveItem(src, item, (amount and amount or 1), nil) local success = exports[OXInv]:RemoveItem(src, item, (amount and amount or 1), nil)
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..OXInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
elseif GetResourceState(QSInv):find("start") then elseif GetResourceState(QSInv):find("start") then
local success = exports[QSInv]:RemoveItem(src, item, amount) local success = exports[QSInv]:RemoveItem(src, item, amount)
elseif GetResourceState(CoreInv):find("start") then if Config.System.Debug then
local success = exports[CoreInv]:removeItemExact('primary-'..src, item, amount) print("^6Bridge^7: ^3"..addremove.."^7[^6"..QSInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
elseif GetResourceState(CodeMInv):find("start") then end
elseif GetResourceState(CoreInv):find("start") then
if GetResourceState(QBExport):find("start") then
Core.Functions.GetPlayer(src).Functions.RemoveItem(item, amount, nil)
elseif GetResourceState(ESXExport):find("start") then
ESX.GetPlayerFromId(src).removeInventoryItem(item, count)
end
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..CoreInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
elseif GetResourceState(OrigenInv):find("start") then
local success = exports[OrigenInv]:RemoveItem(src, item, amount)
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..OrigenInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
elseif GetResourceState(CodeMInv):find("start") then
local success = exports[CodeMInv]:RemoveItem(src, item, amount) local success = exports[CodeMInv]:RemoveItem(src, item, amount)
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..CodeMInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
elseif GetResourceState(QBInv):find("start") then elseif GetResourceState(QBInv):find("start") then
while remamount > 0 do while remamount > 0 do
if Core.Functions.GetPlayer(src).Functions.RemoveItem(item, 1) then end if Core.Functions.GetPlayer(src).Functions.RemoveItem(item, 1) then end
@@ -559,54 +779,163 @@ RegisterNetEvent(GetCurrentResourceName()..":server:toggleItem", function(give,
if Config.Crafting.showItemBox then if Config.Crafting.showItemBox then
TriggerClientEvent('inventory:client:ItemBox', src, Items[item], "remove", (amount and amount or 1)) TriggerClientEvent('inventory:client:ItemBox', src, Items[item], "remove", (amount and amount or 1))
end end
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..QBInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
else
print("^4ERROR^7: ^2No Inventory detected ^7- ^2Check ^3exports^1.^2lua^7")
end end
if Config.System.Debug then
print("^6Bridge^7: ^1Removing ^2from Player^7(^2"..src.."^7) '^6"..Items[item].label.."^7(^2x^6"..((amount and amount or "1")).."^7)'")
end
else else
dupeWarn(src, item) -- if not boot the player dupeWarn(src, item, amount) -- if not boot the player
end end
else else
local amount = amount and amount or 1 local amount = amount and amount or 1
if GetResourceState(OXInv):find("start") then if GetResourceState(OXInv):find("start") then
local success = exports[OXInv]:AddItem(src, item, amount or 1, nil) local success = exports[OXInv]:AddItem(src, item, amount or 1, nil)
if Config.System.Debug then if Config.System.Debug then
print("^6Bridge^7: ^4Giving ^2Player^7(^2"..src.."^7) '^6"..Items[item].label.."^7(^2x^6"..((amount and amount or "1")).."^7) ^1OX^7'") print("^6Bridge^7: ^3"..addremove.."^7[^6"..OXInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end end
elseif GetResourceState(QSInv):find("start") then elseif GetResourceState(QSInv):find("start") then
local success = exports[QSInv]:AddItem(src, item, amount) local success = exports[QSInv]:AddItem(src, item, amount)
if Config.System.Debug then if Config.System.Debug then
print("^6Bridge^7: ^4Giving ^2Player^7(^2"..src.."^7) '^6"..Items[item].label.."^7(^2x^6"..((amount and amount or "1")).."^7) ^1QS^7'") print("^6Bridge^7: ^3"..addremove.."^7[^6"..QSInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end end
elseif GetResourceState(CoreInv):find("start") then elseif GetResourceState(CoreInv):find("start") then
local success = exports[CoreInv]:addItem('primary-'..src, item, amount) if GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then
if Config.System.Debug then Core.Functions.GetPlayer(src).Functions.AddItem(item, amount, nil, nil)
print("^6Bridge^7: ^4Giving ^2Player^7(^2"..src.."^7) '^6"..Items[item].label.."^7(^2x^6"..((amount and amount or "1")).."^7) ^1Core^7'") elseif GetResourceState(ESXExport):find("start") then
ESX.GetPlayerFromId(src).addInventoryItem(item, amount)
end
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..CoreInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end end
elseif GetResourceState(CodeMInv):find("start") then elseif GetResourceState(CodeMInv):find("start") then
local success = exports[CodeMInv]:AddItem(src, item, amount) local success = exports[CodeMInv]:AddItem(src, item, amount)
elseif GetResourceState(QBInv):find("start") then if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..CodeMInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
elseif GetResourceState(OrigenInv):find("start") then
local success = exports[OrigenInv]:AddItem(src, item, amount)
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..OrigenInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
elseif GetResourceState(QBInv):find("start") then
if Core.Functions.GetPlayer(src).Functions.AddItem(item, amount or 1) then if Core.Functions.GetPlayer(src).Functions.AddItem(item, amount or 1) then
--if Config.Crafting.showItemBox then --if Config.Crafting.showItemBox then
TriggerClientEvent("inventory:client:ItemBox", src, Items[item], "add", amount and amount or 1) TriggerClientEvent("inventory:client:ItemBox", src, Items[item], "add", amount and amount or 1)
--end --end
end end
if Config.System.Debug then
print("^6Bridge^7: ^3"..addremove.."^7[^6"..QBInv.."^7] ^2Player^7("..src..") ^6"..Items[item].label.."^7("..item..") x^5"..(amount and amount or "1").."^7")
end
else
print("^4ERROR^7: ^2No Inventory detected ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
end) end)
--Item Exploit protection --Item Exploit protection
function dupeWarn(src, item) function dupeWarn(src, item, amount)
print("^5DupeWarn^7: (^1"..tostring(src).."^7) ^2Tried to remove item ^7('^3"..item.."^7')^2 but it wasn't there^7") print("^5DupeWarn^7: (^1"..tostring(src).."^7) ^2Tried to remove item ^7('^3"..item.."^7')^2 but it wasn't there^7")
if Config.System.Debug == false then if Config.System.Debug == false then
DropPlayer(src, src.." ^1Kicked for attempting to duplicate items") DropPlayer(src, src.." ^1Kicked for suspected duplicating items:"..item)
end end
print("^5DupeWarn:^7: (^1"..tostring(src).."^7) ^2Dropped from server for item duplicating^7") print("^5DupeWarn:^7: (^1"..tostring(src).."^7) ^2Dropped from server - exploit protection detected an item not being found in players inventory^7")
end 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() function toggleDuty()
if GetResourceState(QBExport):find("start") then if GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then
TriggerServerEvent("QBCore:ToggleDuty") TriggerServerEvent("QBCore:ToggleDuty")
else else
onDuty = not onDuty onDuty = not onDuty
@@ -620,12 +949,21 @@ end
local function CheckVersion() local function CheckVersion()
if IsDuplicityVersion() then if IsDuplicityVersion() then
local currentVersion = "^3"..GetResourceMetadata(GetCurrentResourceName(), 'version'):gsub("%.", "^7.^3").."^7"
PerformHttpRequest('https://raw.githubusercontent.com/jimathy/UpdateVersions/master/'..GetCurrentResourceName()..'.txt', function(err, newestVersion, headers) PerformHttpRequest('https://raw.githubusercontent.com/jimathy/UpdateVersions/master/'..GetCurrentResourceName()..'.txt', function(err, newestVersion, headers)
if not newestVersion then print("Currently unable to run a version check.") return end if not newestVersion then
local currentVersion = "^3"..GetResourceMetadata(GetCurrentResourceName(), 'version'):gsub("%.", "^7.^3").."^7" PerformHttpRequest('https://raw.githubusercontent.com/jimathy/'..GetCurrentResourceName()..'/master/version.txt', function(err, freeVersion, headers)
newestVersion = "^3"..newestVersion:sub(1, -2):gsub("%.", "^7.^3").."^7" if not freeVersion then print("^1Currently unable to run a version check for ^7'^3"..GetCurrentResourceName().."^7' ("..currentVersion.."^7)") return end
print("^6Version Check^7: ^2Running^7: "..currentVersion.." ^2Latest^7: "..newestVersion) local currentVersion = "^3"..GetResourceMetadata(GetCurrentResourceName(), 'version'):gsub("%.", "^7.^3").."^7"
print(newestVersion == currentVersion and '^6You are running the latest version.^7 ('..currentVersion..')' or "^1You are currently running an outdated version^7, ^1please update^7!") freeVersion = "^3"..freeVersion:sub(1, -2):gsub("%.", "^7.^3"):gsub("%\r", "").."^7"
print("^6Version Check^7: ^2Running^7: "..currentVersion.." ^2Latest^7: "..freeVersion)
print(freeVersion == currentVersion and "^7'^3"..GetCurrentResourceName().."^7' - ^6You are running the latest version.^7 ("..currentVersion..")" or "^7'^3"..GetCurrentResourceName().."^7' - ^1You are currently running an outdated version^7, ^1please update^7!")
end)
else
newestVersion = "^3"..newestVersion:sub(1, -2):gsub("%.", "^7.^3"):gsub("%\r", "").."^7"
print("^6Version Check^7: ^2Running^7: "..currentVersion.." ^2Latest^7: "..newestVersion)
print(newestVersion == currentVersion and '^6You are running the latest version.^7 ('..currentVersion..')' or "^1You are currently running an outdated version^7, ^1please update^7!")
end
end) end)
end end
end end
@@ -741,15 +1079,15 @@ function FocusEffect()
focusEffect = false focusEffect = false
if Config.System.Debug then print("^5Debug^7: ^3FocusEffect^7() ^2stopped") end if Config.System.Debug then print("^5Debug^7: ^3FocusEffect^7() ^2stopped") end
end end
local NightVisionEffect = false local nightVisionEffect = false
function NightVisionEffect() 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 if Config.System.Debug then print("^5Debug^7: ^3NightVisionEffect^7() ^2activated") end
SetNightvision(true) SetNightvision(true)
Wait(math.random(3000, 4000)) -- FEEL FREE TO CHANGE THIS Wait(math.random(3000, 4000)) -- FEEL FREE TO CHANGE THIS
SetNightvision(false) SetNightvision(false)
SetSeethrough(false) SetSeethrough(false)
NightVisionEffect = false nightVisionEffect = false
if Config.System.Debug then print("^5Debug^7: ^3NightVisionEffect^7() ^2stopped") end if Config.System.Debug then print("^5Debug^7: ^3NightVisionEffect^7() ^2stopped") end
end end
local thermalEffect = false local thermalEffect = false
@@ -820,4 +1158,11 @@ function StopEffects() -- Used to clear up any effects stuck on screen
AnimpostfxStop('RaceTurbo') AnimpostfxStop('RaceTurbo')
AnimpostfxStop('FocusIn') AnimpostfxStop('FocusIn')
AnimpostfxStop('Rampage') 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" name "Jim_Bridge"
author "Jimathy" author "Jimathy"
version "alpha" version "1.0.14"
description "Framework Bridge By Jimathy" description "Framework Bridge By Jimathy"
fx_version "cerulean" fx_version "cerulean"
game "gta5" game "gta5"
@@ -11,4 +11,4 @@ files {
'functions.lua', 'functions.lua',
'wrapper.lua', 'wrapper.lua',
'crafting.lua', 'crafting.lua',
} }

1
version.txt Normal file
View File

@@ -0,0 +1 @@
1.0.13

View File

@@ -1,73 +1,84 @@
Items, Vehicles, Jobs, Gangs, Core, ESX = {}, nil, nil, nil, nil, nil Items, Vehicles, Jobs, Gangs, Core, ESX = {}, nil, nil, nil, nil, nil
OXLibExport = Exports and Exports.OXLibExport or "" Exports.QBInv = GetResourceState("ps-inventory"):find("start") and "ps-inventory" or GetResourceState("lj-inventory"):find("start") and "lj-inventory" or Exports.QBInv
QBXExport = Exports and Exports.QBXExport or "" OXLibExport, QBXExport, QBExport, ESXExport, OXCoreExport = Exports.OXLibExport or "", Exports.QBXExport or "", Exports.QBExport or "", Exports.ESXExport or "", Exports.OXCoreExport or ""
QBExport = Exports and Exports.QBExport or ""
ESXExport = Exports and Exports.ESXExport or ""
OXCoreExport = Exports and Exports.OXCoreExport or ""
OXInv = Exports and Exports.OXInv or "" OXInv, QBInv, QSInv, CoreInv, CodeMInv, OrigenInv = Exports.OXInv or "", Exports.QBInv or "", Exports.QSInv or "", Exports.CoreInv or "", Exports.CodeMInv or "", Exports.OrigenInv or ""
QBInv = Exports and Exports.QBInv or ""
QSInv = Exports and Exports.QSInv or ""
CoreInv = Exports and Exports.CoreInv or ""
CodeMInv = Exports and Exports.CodeMInv or ""
QBMenuExport = Exports and Exports.QBMenuExport or "" QBMenuExport = Exports.QBMenuExport or ""
QBTargetExport = Exports and Exports.QBTargetExport or "" QBTargetExport, OXTargetExport = Exports.QBTargetExport or "", Exports.OXTargetExport or ""
OXTargetExport = Exports and Exports.OXTargetExport or ""
function CheckBridgeVersion()
if IsDuplicityVersion() then
local currentVersion = "^3"..GetResourceMetadata("jim_bridge", 'version'):gsub("%.", "^7.^3").."^7"
PerformHttpRequest('https://raw.githubusercontent.com/jimathy/jim_bridge/master/version.txt', function(err, newestVersion, headers)
if not newestVersion then print("^1Currently unable to run a version check for ^7'^3jim_bridge^7' ("..currentVersion.."^7)") return end
newestVersion = "^3"..newestVersion:sub(1, -2):gsub("%.", "^7.^3"):gsub("%\r", "").."^7"
print(newestVersion == currentVersion and "^7'^3jim_bridge^7' - ^6You are running the latest version.^7 ("..currentVersion..")" or "^7'^3jim_bridge^7' - ^1You are currently running an outdated version^7, ^1please update^7!")
end)
end
end
CheckBridgeVersion()
for k, v in pairs(Exports) do for k, v in pairs(Exports) do
if GetResourceState(v):find("start") then print("^6Bridge^7: '^3"..v.."^7' ^2export found ^7") end if GetResourceState(v):find("start") then print("^6Bridge^7: '^3"..v.."^7' ^2export found ^7") end
end end
-- Load item lists from qb-core or ox_lib local itemResource, jobResource = "", ""
if GetResourceState(OXInv):find("start") then
print("^6Bridge^7: ^2Loading ^3Items^2 from ^7"..OXInv) -- Load item lists
if GetResourceState(OXInv):find("start") then itemResource = OXInv
Items = exports[OXInv]:Items() Items = exports[OXInv]:Items()
for k, v in pairs(Items) do for k, v in pairs(Items) do
if v.client then if v.client and v.client.image then
if v.client.image then Items[k].image = (Items[k].client.image):gsub("nui://"..OXInv.."/web/images/","") Items[k].image = (v.client.image):gsub("nui://"..OXInv.."/web/images/", "")
else Items[k].image = k..".png" end else
if v.client.hunger then Items[k].hunger = v.client.hunger end Items[k].image = k..".png"
if v.client.thirst then Items[k].thirst = v.client.thirst end
end end
Items[k].hunger = v.client and v.client.hunger or nil
Items[k].thirst = v.client and v.client.thirst or nil
end end
elseif GetResourceState(QBExport):find("start") then
print("^6Bridge^7: ^2Loading ^3Items^2 from ^7"..QBExport) elseif GetResourceState(QBExport):find("start") then itemResource = QBExport
Core = Core or exports[QBExport]:GetCoreObject() Core = Core or exports[QBExport]:GetCoreObject()
Items = Core.Shared.Items Items = Core and Core.Shared.Items or nil
elseif GetResourceState(ESXExport):find("start") then
print("^6Bridge^7: ^2Loading ^3Items^2 from ^7"..ESXExport) elseif GetResourceState(ESXExport):find("start") then itemResource = ESXExport
ESX = exports[ESXExport]:getSharedObject() ESX = exports[ESXExport]:getSharedObject()
Items = ESX.Items Items = ESX and ESX.Items or nil
end
if not Items then
print("^4ERROR^7: ^2No Core Items detected ^7- ^2Check ^3exports^1.^2lua^7")
else
print("^6Bridge^7: ^2Loading ^6"..countTable(Items).." ^3Items^2 from ^7" .. itemResource)
end end
-- Load Vehicles -- Load Vehicles
if GetResourceState(QBXExport):find("start") then if GetResourceState(QBXExport):find("start") or GetResourceState(QBExport):find("start") then
Core = Core or exports[QBExport]:GetCoreObject() Core = Core or exports[QBExport]:GetCoreObject()
print("^6Bridge^7: ^2Loading ^3Vehicles^2 from ^7"..QBXExport) if GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
Vehicles = exports[QBXExport]:GetVehiclesByHash() RegisterNetEvent('QBCore:Client:UpdateObject', function()
elseif GetResourceState(QBExport):find("start") then Core = Core or exports[QBExport]:GetCoreObject()
print("^6Bridge^7: ^2Loading ^3Vehicles^2 from ^7"..QBExport) end)
Core = Core or exports[QBExport]:GetCoreObject() end
RegisterNetEvent('QBCore:Client:UpdateObject', function() Vehicles = Core and Core.Shared.Vehicles
Core = Core or exports[QBExport]:GetCoreObject() print("^6Bridge^7: ^2Loading ^6"..countTable(Vehicles).." ^3Vehicles^2 from ^7"..QBExport)
end)
Vehicles = Core.Shared.Vehicles
elseif GetResourceState(OXCoreExport):find("start") then elseif GetResourceState(OXCoreExport):find("start") then
print("^6Bridge^7: ^2Loading ^3Vehicles^2 from ^7"..OXCoreExport) Vehicles = {}
for k, v in pairs(Ox.GetVehicleData()) do for k, v in pairs(Ox.GetVehicleData()) do
Vehicles = Vehicles or {}
Vehicles[k] = { model = k, price = v.price, name = v.name, brand = v.make } Vehicles[k] = { model = k, price = v.price, name = v.name, brand = v.make }
end end
print("^6Bridge^7: ^2Loading ^6"..countTable(Vehicles).." ^3Vehicles^2 from ^7"..OXCoreExport)
elseif GetResourceState(ESXExport):find("start") then elseif GetResourceState(ESXExport):find("start") then
print("^6Bridge^7: ^2Loading ^3Vehicles^2 from ^7"..ESXExport) print("^6Bridge^7: ^2Loading ^3Vehicles^2 from ^7"..ESXExport)
--print("^6Bridge^7: ^2Loading ^6"..countTable(Vehicles).." ^3Vehicles^2 from ^7"..ESXExport)
CreateThread(function() CreateThread(function()
if IsDuplicityVersion() then if IsDuplicityVersion() then
createCallback(GetCurrentResourceName()..":getVehiclesPrices", function(source) createCallback(GetCurrentResourceName()..":getVehiclesPrices", function(source)
Vehicles = MySQL.query.await('SELECT model, price, name FROM vehicles') Vehicles = MySQL.query.await('SELECT model, price, name FROM vehicles')
print("^6Bridge^7: ^3Found ^6"..countTable(Vehicles).." ^3Vehicles^2 from ^7"..ESXExport)
return Vehicles return Vehicles
end) end)
end end
@@ -79,40 +90,38 @@ elseif GetResourceState(ESXExport):find("start") then
end end
end end
end) end)
else
print("^4ERROR^7: ^2No Vehicle info detected ^7- ^2Check ^3exports^1.^2lua^7")
end end
-- Load Jobs -- Load Jobs
if GetResourceState(QBXExport):find("start") then local jobResource = ""
if GetResourceState(QBXExport):find("start") then jobResource = QBXExport
Core = Core or exports[QBExport]:GetCoreObject() Core = Core or exports[QBExport]:GetCoreObject()
print("^6Bridge^7: ^2Loading ^3Jobs^7/^3Gangs^2 from ^7"..QBXExport) Jobs, Gangs = exports[QBXExport]:GetJobs(), exports[QBXExport]:GetGangs()
Jobs = exports[QBXExport]:GetJobs()
Gangs = exports[QBXExport]:GetGangs()
elseif GetResourceState(OXCoreExport):find("start") then elseif GetResourceState(OXCoreExport):find("start") then jobResource = OXExport
print("^6Bridge^7: ^2Loading ^3Jobs^7/^3Gangs^2 from ^7"..OXCoreExport)
CreateThread(function() CreateThread(function()
if IsDuplicityVersion() then if IsDuplicityVersion() then
createCallback(GetCurrentResourceName()..":getOxGroups", function(source) createCallback(GetCurrentResourceName()..":getOxGroups", function(source)
Jobs = MySQL.query.await('SELECT * FROM `ox_groups`') Jobs = MySQL.query.await('SELECT * FROM `ox_groups`') return Jobs
return Jobs
end) end)
else else
local TempJobs = triggerCallback(GetCurrentResourceName()..":getOxGroups") local TempJobs = triggerCallback(GetCurrentResourceName()..":getOxGroups")
Jobs = TempJobs and {}
for k, v in pairs(TempJobs) do for k, v in pairs(TempJobs) do
local grades = {} local grades = {}
for i = 1, #v.grades do grades[i] = { name = grades[i], isboss = (i == #v.grades)} end for i = 1, #v.grades do grades[i] = { name = v.grades[i], isboss = (i == #v.grades)} end
Jobs = Jobs or {} Jobs[v.name] = { label = v.label, grades = grades }
Jobs[v.name] = { label = v.label, grades = grades, }
end end
Gangs = Jobs
end end
end) end)
elseif GetResourceState(QBExport):find("start") then elseif GetResourceState(QBExport):find("start") then jobResource = QBExport
print("^6Bridge^7: ^2Loading ^3Jobs^7/^3Gangs^2 from ^7"..QBExport)
Core = Core or Core or exports[QBExport]:GetCoreObject() Core = Core or Core or exports[QBExport]:GetCoreObject()
RegisterNetEvent('QBCore:Client:UpdateObject', function() Core = Core or exports[QBExport]:GetCoreObject() end) RegisterNetEvent('QBCore:Client:UpdateObject', function() Core = Core or exports[QBExport]:GetCoreObject() end)
Jobs = Core.Shared.Jobs Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
Gangs = Core.Shared.Gangs
elseif GetResourceState(ESXExport):find("start") then elseif GetResourceState(ESXExport):find("start") then
print("^6Bridge^7: ^2Loading ^3Jobs^7/^3Gangs^2 from ^7"..ESXExport) print("^6Bridge^7: ^2Loading ^3Jobs^7/^3Gangs^2 from ^7"..ESXExport)
@@ -138,26 +147,20 @@ elseif GetResourceState(ESXExport):find("start") then
end end
end) end)
end end
if not GetResourceState(ESXExport):find("start") and Jobs then
print("^6Bridge^7: ^2Loading ^6"..countTable(Jobs).." ^3Jobs^2 from ^7"..jobResource, "^6Bridge^7: ^2Loading ^6"..countTable(Gangs).." ^3Gangs^2 from ^7"..jobResource)
end
function makeBossRoles(role) function makeBossRoles(role)
local boss = {} local boss = {}
if Jobs and Jobs[role] then local data = Jobs and Jobs[role] or Gangs and Gangs[role]
for grade in pairs(Jobs[role].grades) do if data then
if Jobs[role].grades[grade].isboss then for grade, info in pairs(data.grades) do
if boss[role] then if info.isboss then
if boss[role] > tonumber(grade) then boss[role] = tonumber(grade) end boss[role] = boss[role] and math.min(boss[role], tonumber(grade)) or tonumber(grade)
else boss[role] = tonumber(grade) end end
end end
end end
elseif Gangs and Gangs[role] then
for grade in pairs(Gangs[role].grades) do
if Gangs[role].grades[grade].isboss then
if boss[role] then
if boss[role] > tonumber(grade) then boss[role] = tonumber(grade) end
else boss[role] = tonumber(grade) end
end
end
end
return boss return boss
end end
@@ -173,12 +176,10 @@ function createPoly(data) local Location = nil
if Config.System.Debug then print("^6Bridge^7: ^2Creating new poly with ^7PolyZone "..data.name) end if Config.System.Debug then print("^6Bridge^7: ^2Creating new poly with ^7PolyZone "..data.name) end
Location = PolyZone:Create(data.points, { name = data.name, debugPoly = data.debug }) Location = PolyZone:Create(data.points, { name = data.name, debugPoly = data.debug })
Location:onPlayerInOut(function(isPointInside) Location:onPlayerInOut(function(isPointInside)
if isPointInside then if isPointInside then data.onEnter() else data.onExit() end
data.onEnter()
else
data.onExit()
end
end) end)
else
print("^4ERROR^7: ^2No PolyZone creation script detected ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
@@ -196,24 +197,33 @@ function createCirclePoly(data) local Location = nil
data.onExit() data.onExit()
end end
end) end)
else
print("^4ERROR^7: ^2No PolyZone creation script detected ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
function openMenu(Menu, data) function openMenu(Menu, data)
if Config.System.Menu == "ox" then if Config.System.Menu == "ox" then
if data.onBack then local index = nil
if data.onBack and not data.onSelected then
table.insert(Menu, 1, { icon = "fas fa-circle-arrow-left", table.insert(Menu, 1, { icon = "fas fa-circle-arrow-left",
title = "Return", title = "Return",
onSelect = data.onBack, onSelect = data.onBack,
label = "Return"
}) })
end end
for k in pairs(Menu) do for k in pairs(Menu) do
if data.onSelected and Menu[k].arrow then
Menu[k].icon = "fas fa-angle-right"
end
if not Menu[k].title then if not Menu[k].title then
if Menu[k].header ~= nil and Menu[k].header ~= "" then if Menu[k].header ~= nil and Menu[k].header ~= "" then
Menu[k].title = Menu[k].header Menu[k].title = Menu[k].header
Menu[k].label = Menu[k].header
if Menu[k].txt then Menu[k].description = Menu[k].txt else Menu[k].description = "" end if Menu[k].txt then Menu[k].description = Menu[k].txt else Menu[k].description = "" end
else else
Menu[k].title = Menu[k].txt Menu[k].title = Menu[k].txt
Menu[k].label = Menu[k].txt
end end
end end
if Menu[k].params then if Menu[k].params then
@@ -224,8 +234,35 @@ function openMenu(Menu, data)
Menu[k].disabled = true Menu[k].disabled = true
end end
end end
lib.registerContext({id = 'Menu', title = data.header..br..br..(data.headertxt and data.headertxt or ""), position = 'top-right', options = Menu, canClose = data.canClose and data.canClose or nil, onExit = data.onExit and data.onExit or nil, }) local menuID = 'Menu'
lib.showContext("Menu") (data.onSelected and lib.registerMenu or lib.registerContext)({
id = menuID,
title = data.header..br..br..(data.headertxt and data.headertxt or ""),
position = 'top-right',
options = Menu,
canClose = data.canClose and data.canClose or nil,
onClose = (data.onBack and data.onBack) or (data.onExit and data.onExit) or nil,
onExit = data.onExit and data.onExit or nil,
onSelected = data.onSelected and (function(selected) index = selected end) or nil,
}, (data.onSelected and (function(x, y, args)
if Menu[x].refresh then
if Menu[x].onSelect then
Menu[x].onSelect()
end
lib.showMenu(menuID, index)
else
if Menu[x].onSelect then
Menu[x].onSelect()
else
lib.showMenu(menuID, index)
end
end
end) or nil))
if data.onSelected then
lib.showMenu(menuID, 1)
else
lib.showContext(menuID)
end
elseif Config.System.Menu == "qb" then elseif Config.System.Menu == "qb" then
if data.onBack then if data.onBack then
table.insert(Menu, 1, { icon = "fas fa-circle-arrow-left", table.insert(Menu, 1, { icon = "fas fa-circle-arrow-left",
@@ -364,6 +401,18 @@ function isOx() return (Config.System.Menu == "ox" or Config.System.Menu == "gta
function isWarMenuOpen() if Config.System.Menu == "gta" then return WarMenu.IsAnyMenuOpened() else return false end end function isWarMenuOpen() if Config.System.Menu == "gta" then return WarMenu.IsAnyMenuOpened() else return false end end
local TextTargets = {}
local Keys = {
[322] = "ESC", [288] = "F1", [289] = "F2", [170] = "F3", [166] = "F5",
[167] = "F6", [168] = "F7", [169] = "F8", [56] = "F9", [57] = "F10",
[243] = "~", [157] = "1", [158] = "2", [160] = "3", [164] = "4", [165] = "5", [159] = "6", [161] = "7", [162] = "8", [163] = "9", [84] = "-", [83] = "=", [177] = "BACKSPACE", [37] = "TAB",
[44] = "Q", [32] = "W", [38] = "E", [45] = "R", [245] = "T", [246] = "Y", [303] = "U", [199] = "P",
[39] = "[", [40] = "]", [18] = "ENTER", [137] = "CAPS",
[34] = "A", [8] = "S", [9] = "D", [23] = "F", [47] = "G",
[74] = "H", [311] = "K", [182] = "L", [21] = "LEFTSHIFT",
[20] = "Z", [73] = "X", [26] = "C", [0] = "V", [29] = "B", [249] = "N",
[244] = "M", [82] = ",", [81] = "."
}
-- Targets -- -- Targets --
local targetEntities = {} local targetEntities = {}
function createEntityTarget(entity, opts, dist) function createEntityTarget(entity, opts, dist)
@@ -392,6 +441,14 @@ function createEntityTarget(entity, opts, dist)
end end
local options = { options = opts, distance = dist } local options = { options = opts, distance = dist }
exports[QBTargetExport]:AddTargetEntity(entity, options) exports[QBTargetExport]:AddTargetEntity(entity, options)
else
local tempText = ""
local keyTable = { 38, 29, 303, }
for i = 1, #opts do
opts[i].key = keyTable[i]
tempText = tempText.."~b~["..Keys[opts[i].key].."] ~w~"..opts[i].label.." "
end
TextTargets[entity] = { coords = GetEntityCoords(entity), buttontext = tempText, options = opts, dist = dist }
end end
end end
@@ -434,7 +491,16 @@ function createBoxTarget(data, opts, dist)
local options = { options = opts, distance = dist } local options = { options = opts, distance = dist }
local target = exports[QBTargetExport]:AddBoxZone(data[1], data[2], data[3], data[4], data[5], options) local target = exports[QBTargetExport]:AddBoxZone(data[1], data[2], data[3], data[4], data[5], options)
boxTargets[#boxTargets+1] = target boxTargets[#boxTargets+1] = target
return target return data[1]
else
local tempText = ""
local keyTable = { 38, 29, 303, }
for i = 1, #opts do
opts[i].key = keyTable[i]
tempText = tempText.."~b~["..Keys[opts[i].key].."] ~w~"..opts[i].label.." "
end
TextTargets[data[1]] = { coords = data[2], buttontext = tempText, options = opts, dist = dist }
return data[1]
end end
end end
@@ -474,18 +540,53 @@ function createCircleTarget(data, opts, dist)
local target = exports[QBTargetExport]:AddCircleZone(data[1], data[2], data[3], data[4], options) local target = exports[QBTargetExport]:AddCircleZone(data[1], data[2], data[3], data[4], options)
circleTargets[#circleTargets+1] = target circleTargets[#circleTargets+1] = target
return target return data[1]
else
local tempText = ""
local keyTable = { 38, 29, 303, }
for i = 1, #opts do
opts[i].key = keyTable[i]
tempText = tempText.."~b~["..Keys[opts[i].key].."] ~w~"..opts[i].label.." "
end
TextTargets[data[1]] = { coords = data[2], buttontext = tempText, options = opts, dist = dist }
return data[1]
end end
end end
function removeEntityTarget(entity) function removeEntityTarget(entity)
if GetResourceState(QBTargetExport):find("start") then exports[QBTargetExport]:RemoveTargetEntity(entity) end if GetResourceState(QBTargetExport):find("start") then exports[QBTargetExport]:RemoveTargetEntity(entity) end
if GetResourceState(OXTargetExport):find("start") then exports[OXTargetExport]:removeLocalEntity(entity, nil) end if GetResourceState(OXTargetExport):find("start") then exports[OXTargetExport]:removeLocalEntity(entity, nil) end
if not GetResourceState(OXTargetExport):find("start") and not GetResourceState(QBTargetExport):find("start") then
TextTargets[entity] = nil
end
end end
function removeZoneTarget(target) function removeZoneTarget(target)
if GetResourceState(QBTargetExport):find("start") then exports[QBTargetExport]:RemoveZone(target) end if GetResourceState(QBTargetExport):find("start") then exports[QBTargetExport]:RemoveZone(target) end
if GetResourceState(OXTargetExport):find("start") then exports[OXTargetExport]:removeZone(target, true) end if GetResourceState(OXTargetExport):find("start") then exports[OXTargetExport]:removeZone(target, true) end
if not GetResourceState(OXTargetExport):find("start") and not GetResourceState(QBTargetExport):find("start") then
TextTargets[target] = nil
end
end
if not GetResourceState(OXTargetExport):find("start") and not GetResourceState(QBTargetExport):find("start") and not IsDuplicityVersion() then
CreateThread(function()
while true do
local pedCoords = GetEntityCoords(PlayerPedId())
for k, v in pairs (TextTargets) do
if #(pedCoords - v.coords) <= v.dist then
DrawText3D(v.coords.x, v.coords.y, v.coords.z + 1.0, v.buttontext)
for i = 1, #v.options do
if IsControlJustPressed(0, v.options[i].key) then
if v.options[i].onSelect then v.options[i].onSelect() end
if v.options[i].action then v.options[i].action() end
end
end
end
end
Wait(0)
end
end)
end end
AddEventHandler('onResourceStop', function(r) AddEventHandler('onResourceStop', function(r)
@@ -644,6 +745,8 @@ function onPlayerLoaded(func)
elseif GetResourceState(OXCoreExport):find("start") then elseif GetResourceState(OXCoreExport):find("start") then
if Config.System.Debug then print("^6Bridge^7: ^2Registering ^3onPlayerLoaded^2 with ^7"..OXLibExport) end if Config.System.Debug then print("^6Bridge^7: ^2Registering ^3onPlayerLoaded^2 with ^7"..OXLibExport) end
AddEventHandler('ox:playerLoaded', func) AddEventHandler('ox:playerLoaded', func)
else
print("^4ERROR^7: ^2No Core detected for onPlayerLoaded ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
@@ -656,14 +759,13 @@ function createInput(title, opts)
if opts[i].type == "radio" then if opts[i].type == "radio" then
for k in pairs(opts[i].options) do for k in pairs(opts[i].options) do
opts[i].options[k].label = opts[i].options[k].text opts[i].options[k].label = opts[i].options[k].text
print(opts[i].options[k].text)
end end
options[i] = { options[i] = {
type = "select", type = "select",
isRequired = opts[i].isRequired, isRequired = opts[i].isRequired,
label = opts[i].label or opts[i].text, label = opts[i].label or opts[i].text,
name = opts[i].name, name = opts[i].name,
default = opts[i].options[1].value, default = opts[i].default or opts[i].options[1].value,
options = opts[i].options, options = opts[i].options,
} }
end end
@@ -676,6 +778,14 @@ function createInput(title, opts)
options = opts[i].options, options = opts[i].options,
} }
end end
if opts[i].type == "text" then
options[i] = {
type = "input",
label = opts[i].text ..(opts[i].txt and " - "..opts[i].txt or ""),
default = opts[i].default,
isRequired = opts[i].isRequired,
}
end
if opts[i].type == "select" then if opts[i].type == "select" then
options[i] = { options[i] = {
type = "select", type = "select",
@@ -829,46 +939,122 @@ end
function getVehicleProperties(vehicle) function getVehicleProperties(vehicle)
local properties = {} local properties = {}
if vehicle == nil then return nil end if vehicle == nil then return nil end
if GetResourceState(OXLibExport):find("start") then if GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
properties = lib.getVehicleProperties(vehicle)
elseif GetResourceState(QBExport):find("start") then
properties = Core.Functions.GetVehicleProperties(vehicle) properties = Core.Functions.GetVehicleProperties(vehicle)
if Config.System.Debug then print("^6Bridge^7: ^2Getting Vehicle Properties ^7[^6"..QBExport.."^7] - [^3"..vehicle.."^7] - [^3"..GetEntityModel(vehicle).."^7/^3"..properties.model.."^7] - [^3"..properties.plate.."^7]") end
elseif GetResourceState(OXLibExport):find("start") then
properties = lib.getVehicleProperties(vehicle)
if Config.System.Debug then print("^6Bridge^7: ^2Getting Vehicle Properties ^7[^6"..OXLibExport.."^7] - [^3"..vehicle.."^7] - [^3"..GetEntityModel(vehicle).."^7/^3"..properties.model.."^7] - [^3"..properties.plate.."^7]") end
end end
return properties return properties
end end
function setVehicleProperties(vehicle, props) function setVehicleProperties(vehicle, props)
if not DoesEntityExist(vehicle) then local oldProps = getVehicleProperties(vehicle)
print(("Unable to set vehicle properties for '%s' (entity does not exist)"): if checkDifferences(vehicle, props) then
format(vehicle)) --if Config.System.Debug then debugDifferences(vehicle, props) end
end if not DoesEntityExist(vehicle) then
if GetResourceState(OXLibExport):find("start") then print(("Unable to set vehicle properties for '%s' (entity does not exist)"):
lib.setVehicleProperties(vehicle, props) format(vehicle))
elseif GetResourceState(QBExport):find("start") then end
Core.Functions.SetVehicleProperties(vehicle, props) if GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
Core.Functions.SetVehicleProperties(vehicle, props)
if Config.System.Debug then print("^6Bridge^7: ^2Setting Vehicle Properties ^7[^6"..QBExport.."^7] - [^3"..vehicle.."^7] - [^3"..GetEntityModel(vehicle).."^7/^3"..props.model.."^7] - [^3"..props.plate.."^7]") end
else
TriggerServerEvent(GetCurrentResourceName()..":ox:setVehicleProperties", VehToNet(vehicle), props)
end
else
if Config.System.Debug then print("^6Bridge^7: ^2No Changes Found ^7 [^3"..vehicle.."^7] - [^3"..GetEntityModel(vehicle).."^7/^3"..props.model.."^7] - [^3"..props.plate.."^7]") end
end end
end end
RegisterNetEvent(GetCurrentResourceName()..":server:ChargePlayer", function(cost, type) local src = source function checkDifferences(vehicle, newProps)
if Config.System.Debug then print("^6Bridge^7: ^2Charging ^2Player: '^6"..cost.."^7'", type) end local oldProps = getVehicleProperties(vehicle)
if Config.System.Debug then print("^6Bridge^7: ^2Finding differences in ^3Vehicle Properties^7") end
local allow = false
for k in pairs(oldProps) do
if json.encode(oldProps[k]) ~= json.encode(newProps[k]) then
allow = true
if Config.System.Debug then
print("^6Bridge^7: ^5Old ^7[^3"..k.."^7] - "..json.encode(oldProps[k], { indent = true }))
print("^6Bridge^7: ^5New ^7[^3"..k.."^7] - "..json.encode(newProps[k], { indent = true }))
end
end
end
return allow
end
RegisterNetEvent(GetCurrentResourceName()..":ox:setVehicleProperties", function(netId, props)
local vehicle = NetworkGetEntityFromNetworkId(netId)
local value = props
Entity(vehicle).state[GetCurrentResourceName()..':setVehicleProperties'] = value
end)
AddStateBagChangeHandler(GetCurrentResourceName()..':setVehicleProperties', '', function(bagName, _, value)
if not value or not GetEntityFromStateBagName then return end
local entity = GetEntityFromStateBagName(bagName)
local networked = not bagName:find('localEntity')
if Config.System.Debug then print("^6Bridge^7: ^2Setting Vehicle Properties ^7[^6"..OXLibExport.."^7] - [^3"..entity.."^7] - [^3"..GetEntityModel(entity).."^7] - [^3"..value.plate.."^7]") end
if networked and NetworkGetEntityOwner(entity) ~= cache.playerId then return end
if lib.setVehicleProperties(entity, value) then
Entity(entity).state:set('setVehicleProperties', nil, true)
end
end)
RegisterNetEvent(GetCurrentResourceName()..":server:ChargePlayer", function(cost, type, newsrc)
local src = newsrc or source
local fundResource = ""
if type == "cash" then if type == "cash" then
if GetResourceState(OXInv):find("start") then if GetResourceState(OXInv):find("start") then fundResource = OXInv
exports[OXInv]:RemoveItem(src, "money", cost) exports[OXInv]:RemoveItem(src, "money", cost)
elseif GetResourceState(QBExport):find("start") then elseif GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then fundResource = QBExport
Core.Functions.GetPlayer(src).Functions.RemoveMoney("cash", cost) Core.Functions.GetPlayer(src).Functions.RemoveMoney("cash", cost)
elseif GetResourceState(ESXExport):find("start") then elseif GetResourceState(ESXExport):find("start") then fundResource = ESXExport
local Player = ESX.GetPlayerFromId(src) local Player = ESX.GetPlayerFromId(src)
Player.removeMoney(cost, "") Player.removeMoney(cost, "")
end end
end end
if type == "bank" then if type == "bank" then
if GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then if GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then fundResource = QBExport
Core.Functions.GetPlayer(src).Functions.RemoveMoney("bank", cost) Core.Functions.GetPlayer(src).Functions.RemoveMoney("bank", cost)
elseif GetResourceState(ESXExport):find("start") then elseif GetResourceState(ESXExport):find("start") then fundResource = ESXExport
local Player = ESX.GetPlayerFromId(src) local Player = ESX.GetPlayerFromId(src)
Player.removeMoney(cost, "") Player.removeMoney(cost, "")
end end
end end
if fundResource == "" then print("error - check exports.lua")
else
if Config.System.Debug then print("^6Bridge^7: ^2Charging ^2Player^7: '^6"..cost.."^7'", type, fundResource) end
end
end)
RegisterNetEvent(GetCurrentResourceName()..":server:FundPlayer", function(fund, type, newsrc)
local src = newsrc or source
local fundResource = ""
if type == "cash" then
if GetResourceState(OXInv):find("start") then fundResource = OXInv
exports[OXInv]:AddItem(src, "money", fund)
elseif GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then fundResource = QBExport
Core.Functions.GetPlayer(src).Functions.AddMoney("cash", fund)
elseif GetResourceState(ESXExport):find("start") then fundResource = ESXExport
local Player = ESX.GetPlayerFromId(src)
Player.addMoney(fund, "")
end
end
if type == "bank" then
if GetResourceState(QBExport):find("start") or GetResourceState(QBXExport):find("start") then fundResource = QBExport
Core.Functions.GetPlayer(src).Functions.AddMoney("bank", fund)
elseif GetResourceState(ESXExport):find("start") then fundResource = ESXExport
local Player = ESX.GetPlayerFromId(src)
Player.addMoney(fund, "")
end
end
if fundResource == "" then print("error - check exports.lua")
else
if Config.System.Debug then print("^6Bridge^7: ^2Funding ^2Player^7: '^2"..fund.."^7'", type, fundResource) end
end
end) end)
function createUseableItem(item, funct) function createUseableItem(item, funct)
@@ -885,8 +1071,9 @@ function createUseableItem(item, funct)
end end
end end
function hasJob(job, src) local hasJob = false function hasJob(job, source, grade) local hasJob, duty = false, true
if src then if source then
local src = tonumber(source)
if GetResourceState(ESXExport):find("start") then if GetResourceState(ESXExport):find("start") then
local info = ESX.GetPlayerFromId(src).job local info = ESX.GetPlayerFromId(src).job
while not info do while not info do
@@ -905,14 +1092,39 @@ function hasJob(job, src) local hasJob = false
elseif GetResourceState(QBXExport):find("start") then elseif GetResourceState(QBXExport):find("start") then
local jobinfo = exports[QBXExport]:GetPlayer(src).PlayerData.job local jobinfo = exports[QBXExport]:GetPlayer(src).PlayerData.job
if jobinfo.name == job then hasJob = true end if jobinfo.name == job then hasJob = true
duty = exports[QBXExport]:GetPlayer(src).PlayerData.job.onduty
if grade and not (grade <= jobinfo.grade.level) then hasJob = false end
end
local ganginfo = exports[QBXExport]:GetPlayer(src).PlayerData.gang local ganginfo = exports[QBXExport]:GetPlayer(src).PlayerData.gang
if ganginfo.name == job then hasJob = true end if ganginfo.name == job then hasJob = true
if grade and not (grade <= ganginfo.grade.level) then hasJob = false end
end
elseif GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
if Core.Functions.GetPlayer then -- support older qb-core functions
local jobinfo = Core.Functions.GetPlayer(src).PlayerData.job
if jobinfo.name == job then hasJob = true
duty = Core.Functions.GetPlayer(src).PlayerData.job.onduty
if grade and not (grade <= jobinfo.grade.level) then hasJob = false end
end
local ganginfo = Core.Functions.GetPlayer(src).PlayerData.gang
if ganginfo.name == job then hasJob = true
if grade and not (grade <= ganginfo.grade.level) then hasJob = false end
end
else -- support newer qb-core exports
local jobinfo = exports[QBExport]:GetPlayer(src).PlayerData.job
if jobinfo.name == job then hasJob = true
duty = exports[QBExport]:GetPlayer(src).PlayerData.job.onduty
if grade and not (grade <= jobinfo.grade.level) then hasJob = false end
end
local ganginfo = exports[QBExport]:GetPlayer(src).PlayerData.gang
if ganginfo.name == job then hasJob = true
if grade and not (grade <= ganginfo.grade.level) then hasJob = false end
end
end
else else
local jobinfo = exports[QBExport]:GetPlayer(src).PlayerData.job print("^4ERROR^7: ^2No Core detected for hasJob ^7- ^2Check ^3exports^1.^2lua^7")
if jobinfo.name == job then hasJob = true end
local ganginfo = exports[QBExport]:GetPlayer(src).PlayerData.gang
if ganginfo.name == job then hasJob = true end
end end
else else
if GetResourceState(ESXExport):find("start") then if GetResourceState(ESXExport):find("start") then
@@ -931,26 +1143,42 @@ function hasJob(job, src) local hasJob = false
elseif GetResourceState(QBXExport):find("start") then elseif GetResourceState(QBXExport):find("start") then
local jobinfo = QBX.PlayerData.job local jobinfo = QBX.PlayerData.job
if jobinfo.name == job then hasJob = true end if jobinfo.name == job then hasJob = true
duty = QBX.PlayerData.job.onduty
if grade and not (grade <= jobinfo.grade.level) then hasJob = false end
end
local ganginfo = QBX.PlayerData.gang local ganginfo = QBX.PlayerData.gang
if ganginfo.name == job then hasJob = true end if ganginfo.name == job then hasJob = true
else if grade and not (grade <= ganginfo.grade.level) then hasJob = false end
end
elseif GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
local info = nil local info = nil
Core.Functions.GetPlayerData(function(PlayerData) Core.Functions.GetPlayerData(function(PlayerData)
info = PlayerData info = PlayerData
end) end)
local jobinfo = info.job local jobinfo = info.job
if jobinfo.name == job then hasJob = true end if jobinfo.name == job then hasJob = true
duty = jobinfo.onduty
if grade and not (grade <= jobinfo.grade.level) then hasJob = false end
end
local ganginfo = info.gang local ganginfo = info.gang
if ganginfo.name == job then hasJob = true end if ganginfo.name == job then
hasJob = true
if grade and not (grade <= ganginfo.grade.level) then hasJob = false end
end
else
print("^4ERROR^7: ^2No Core detected for hasJob() ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
return hasJob return hasJob, duty
end end
function getPlayer(src) local Player = {} function getPlayer(source) local Player = {}
if Config.System.Debug then print("^6Bridge^7: ^2Getting ^3Player^2 info^7") end if Config.System.Debug then print("^6Bridge^7: ^2Getting ^3Player^2 info^7") end
if src then -- If called from server if source then -- If called from server
local src = tonumber(source)
if GetResourceState(ESXExport):find("start") then if GetResourceState(ESXExport):find("start") then
local info = ESX.GetPlayerFromId(src) local info = ESX.GetPlayerFromId(src)
Player = { Player = {
@@ -958,6 +1186,7 @@ function getPlayer(src) local Player = {}
cash = info.getMoney(), cash = info.getMoney(),
bank = info.getAccount("bank").money, bank = info.getAccount("bank").money,
} }
elseif GetResourceState(OXCoreExport):find("start") then elseif GetResourceState(OXCoreExport):find("start") then
local file = ('imports/%s.lua'):format('server') local file = ('imports/%s.lua'):format('server')
local import = LoadResourceFile('ox_core', file) local import = LoadResourceFile('ox_core', file)
@@ -969,6 +1198,7 @@ function getPlayer(src) local Player = {}
cash = exports[OXInv]:Search(src, 'count', "money"), cash = exports[OXInv]:Search(src, 'count', "money"),
bank = 0, bank = 0,
} }
elseif GetResourceState(QBXExport):find("start") then elseif GetResourceState(QBXExport):find("start") then
local info = exports[QBXExport]:GetPlayer(src) local info = exports[QBXExport]:GetPlayer(src)
Player = { Player = {
@@ -976,16 +1206,29 @@ function getPlayer(src) local Player = {}
cash = exports[OXInv]:Search(src, 'count', "money"), cash = exports[OXInv]:Search(src, 'count', "money"),
bank = info.Functions.GetMoney("bank"), bank = info.Functions.GetMoney("bank"),
} }
elseif GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then elseif GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
local info = Core.Functions.GetPlayer(tonumber(src)) if Core.Functions.GetPlayer ~= nil then -- support older qb-core functions
Player = { local info = Core.Functions.GetPlayer(src).PlayerData
name = info.PlayerData.charinfo.firstname.." "..info.PlayerData.charinfo.lastname, Player = {
cash = info.PlayerData.money["cash"], name = info.charinfo.firstname.." "..info.charinfo.lastname,
bank = info.PlayerData.money["bank"], cash = info.money["cash"],
} bank = info.money["bank"],
}
else
local info = exports[QBExport]:GetPlayer(src).PlayerData
Player = {
name = info.charinfo.firstname.." "..info.charinfo.lastname,
cash = info.money["cash"],
bank = info.money["bank"],
}
end
else
print("^4ERROR^7: ^2No Core detected for getPlayer() ^7- ^2Check ^3exports^1.^2lua^7")
end end
else else
if ESX ~= nil then if GetResourceState(ESXExport):find("start") and ESX ~= nil then
local info = ESX.GetPlayerData() local info = ESX.GetPlayerData()
local cash, bank = 0, 0 local cash, bank = 0, 0
for k, v in pairs(ESX.GetPlayerData().accounts) do for k, v in pairs(ESX.GetPlayerData().accounts) do
@@ -1011,21 +1254,91 @@ function getPlayer(src) local Player = {}
cash = info.money["cash"], cash = info.money["cash"],
bank = info.money["bank"], bank = info.money["bank"],
} }
else elseif GetResourceState(QBExport):find("start") and not GetResourceState(QBXExport):find("start") then
local info = nil local info = nil
Core.Functions.GetPlayerData(function(PlayerData) Core.Functions.GetPlayerData(function(PlayerData) info = PlayerData end)
info = PlayerData
end)
Player = { Player = {
name = info.charinfo.firstname.." "..info.charinfo.lastname, name = info.charinfo.firstname.." "..info.charinfo.lastname,
cash = info.money["cash"], cash = info.money["cash"],
bank = info.money["bank"], bank = info.money["bank"],
} }
else
print("^4ERROR^7: ^2No Core detected for hasJob ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
return Player return Player
end end
function sendPhoneMail(data) local phoneResource = ""
if GetResourceState("gksphone"):find("start") then phoneResource = "gksphone"
exports["gksphone"]:SendNewMail(data)
elseif GetResourceState("yflip-phone"):find("start") then phoneResource = "yflip-phone"
TriggerServerEvent(GetCurrentResourceName()..":yflip:SendMail", data)
elseif GetResourceState("qs-smartphone"):find("start") then phoneResource = "qs-smartphone"
TriggerServerEvent('qs-smartphone:server:sendNewMail', data)
elseif GetResourceState("qs-smartphone-pro"):find("start") then phoneResource = "qs-smartphone-pro"
TriggerServerEvent('phone:sendNewMail', data)
elseif GetResourceState("roadphone"):find("start") then phoneResource = "roadphone"
data.message = data.message:gsub("%<br>", "\n")
exports['roadphone']:sendMail(data)
elseif GetResourceState("lb-phone"):find("start") then phoneResource = "lb-phone"
TriggerServerEvent(GetCurrentResourceName()..":lbphone:SendMail", data)
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
else print("^6Bridge^7: ^1ERROR ^2Sending mail to player ^7 - ^2No supported phone found") end
end
RegisterNetEvent(GetCurrentResourceName()..":lbphone:SendMail", function(data)
local src = source
local phoneNumber = exports["lb-phone"]:GetEquippedPhoneNumber(src)
local emailAddress = exports["lb-phone"]:GetEmailAddress(phoneNumber)
exports["lb-phone"]:SendMail({
to = emailAddress,
subject = data.subject,
message = data.message,
--[[attachments = {
"https://cdn.discordapp.com/attachments/1035667053115363349/1042500877426110474/upload.png",
},]]
actions = data.buttons,
})
end)
RegisterNetEvent(GetCurrentResourceName()..":yflip:SendMail", function(data)
local src = source
exports["yflip-phone"]:SendMail({
title = data.subject,
sender = data.sender,
senderDisplayName = data.sender,
content = data.message,
actions = data.buttons,
}, '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) function registerCommand(command, options)
if GetResourceState(OXLibExport):find("start") then if GetResourceState(OXLibExport):find("start") then
if Config.System.Debug then print("^6Bridge^7: ^2Registering ^3Command^2 with ^7"..OXLibExport, command) end if Config.System.Debug then print("^6Bridge^7: ^2Registering ^3Command^2 with ^7"..OXLibExport, command) end
@@ -1040,25 +1353,43 @@ function invImg(item)
local imgLink = "" local imgLink = ""
if item ~= "" and Items[item] then if item ~= "" and Items[item] then
if GetResourceState(OXInv):find("start") then if GetResourceState(OXInv):find("start") then
imgLink = "nui://"..OXInv.."/web/images/"..Items[item].image imgLink = "nui://"..OXInv.."/web/images/"..(Items[item].image or "")
elseif GetResourceState(QSInv and QSInv or ""):find("start") then elseif GetResourceState(QSInv):find("start") then
imgLink = "nui://"..QSInv.."/html/images/"..Items[item].image imgLink = "nui://"..QSInv.."/html/images/"..(Items[item].image or "")
elseif GetResourceState(CoreInv and CoreInv or ""):find("start") then elseif GetResourceState(CoreInv):find("start") then
imgLink = "nui://"..CoreInv.."/html/img/"..Items[item].image imgLink = "nui://"..CoreInv.."/html/img/"..(Items[item].image or "")
elseif GetResourceState(QBInv and QBInv or ""):find("start") then elseif GetResourceState(OrigenInv):find("start") then
imgLink = "nui://"..QBInv.."/html/images/"..Items[item].image imgLink = "nui://"..OrigenInv.."/html/img/"..(Items[item].image or "")
elseif GetResourceState(QBInv):find("start") then
imgLink = "nui://"..QBInv.."/html/images/"..(Items[item].image or "")
else
print("^4ERROR^7: ^2No Inventory detected for invImg ^7- ^2Check ^3exports^1.^2lua^7")
end end
end end
return imgLink return imgLink
end end
function registerStash(name, label) function registerStash(name, label, slots, weight)
if GetResourceState(OXInv):find("start") then if GetResourceState(OXInv):find("start") then
--print("Registering OX Stash:", name, label) --print("Registering OX Stash:", name, label)
exports[OXInv]:RegisterStash(name, label, 50, 4000000) exports[OXInv]:RegisterStash(name, label, slots or 50, weight or 4000000)
elseif GetResourceState(QSInv):find("start") then elseif GetResourceState(QSInv):find("start") then
--print("Registering QS Stash:", name, label) --print("Registering QS Stash:", name, label)
exports[QSInv]:RegisterStash(name, 50, 4000000) exports[QSInv]:RegisterStash(name, slots or 50, weight or 4000000)
end end
end end
-- IN NO WAY PERFECT --
-- 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 --