32 Commits

Author SHA1 Message Date
Jim Shield
ce137d9089 Version Bump
`2.0.08` - `2.0.09`
2025-10-12 00:10:28 +01:00
Jim Shield
d7a8a20491 Make GenerateRandomValues() return 0
Its possible if no health, thirst or stress was set, it may sent back an empty table, which would then break the finish consume function in the server
2025-10-10 01:57:01 +01:00
Jim Shield
38d0b04e71 Fix pack and return items not being given 2025-10-06 12:56:14 +01:00
Jim Shield
762240b500 Version Bump
`2.0.07` - `2.0.08`
2025-10-06 02:29:07 +01:00
Jim Shield
0a0f60468a Rework calculations and fix alcohol/drug effects
This fixes calculation errors and implements support for jim_bridge built in synchronized alcohol/drug effects

Separates "drug control" `canOD` variable too
2025-10-06 02:28:03 +01:00
Jim Shield
9b189d89f5 fix needStats calculcation
My mad on this one, got `needTypes` and `needStats` confused, so made it just one table and included stress in it
2025-10-04 01:12:19 +01:00
Jim Shield
62db9f6900 Version Bump
`2.0.06` - `2.0.07`
2025-10-01 21:44:20 +01:00
Jim Shield
6317dee667 Stop double calculation of hunger and thirst
Missed this, it's doing the player stats + new stats and then in jim_bridge doing this again and doubling it all up
2025-10-01 21:43:14 +01:00
Jim Shield
15bb54c206 Add support for jim_bridge setStress function
Allows multiframework stress events
2025-10-01 01:20:33 +01:00
Jim Shield
94023857ff Release Notifier Push 2025-09-24 18:18:14 +01:00
Jim Shield
daa70a8844 Version Bump
`2.0.05` - `2.0.06`
2025-09-15 16:31:34 +01:00
Jim Shield
25e8d99839 Rework code to server side
In an attempt to tackle exploiters, I reworked a lot of the code to server side

This will be tied to the new `jim_bridge` release but should function as normal now
2025-09-13 02:54:36 +01:00
Jim Shield
2c2a486a41 Update notify-discord.yml 2025-09-04 16:59:41 +01:00
Jim Shield
16e957116e Create release.yml
Automate release zips and make them generate the folder name correctly

This helps users download a correctly named script so they dont end up with a script with a version number in the title
2025-09-01 10:22:10 +01:00
Jim Shield
b4d65ff043 Update notify-discord.yml 2025-07-27 18:48:05 +01:00
Jim Shield
9d866c88ee Update README.md 2025-07-25 00:41:11 +01:00
Jim Shield
018dcca6cc Update README.md 2025-07-24 22:51:21 +01:00
Jim Shield
e27b840a5e Try to fix props now spawning correctly
Not sure what is going on, they are server synced
but Its possible its not loading the correctly because of the spawn location

I've changed it to make the props at the players location in hopes this fixes the issue
2025-07-08 15:02:28 +01:00
Jim Shield
e794d9a446 Version Bump
`2.0.04` - `2.0.05`
2025-06-22 16:37:46 +01:00
Jim Shield
541263b156 Fixes related to progressbars 2025-06-22 16:13:18 +01:00
Jim Shield
60c42b2506 Fix hunger being wrong on esx when consuming 2025-06-20 21:54:14 +01:00
Jim Shield
2a4de6fdc1 Version Bump
`2.0.03` - `2.0.04`
2025-06-16 11:19:07 +01:00
Jim Shield
4b015e5efa Revamp hunger and thirst events
Realised I made a mistake, and the server function wasn't working fully on ESX

moved it to use the jim_bridge `setNeed` trigger and made the function smarter
2025-06-14 22:29:40 +01:00
Jim Shield
518c5204ae Version Bump
`2.0.02` - `2.0.03`
2025-05-22 14:25:48 +01:00
Jim Shield
12642b7e7b Temp fix consumables not being usable randomly
I believe, the imported consumables from other scripts were fighting with each other in the `createUsableItem` event

In theory, when syncing them (at least at the moment) the restaurant would try to make them usable, and also this script would try. Possibly cancelling each other out?

This removes the `createUsableItem` event from the sync add item event
2025-05-22 14:23:12 +01:00
Jim Shield
c2843eaee2 Try to fix hunger/thirst for essx 2025-05-22 14:12:27 +01:00
Jim Shield
b92e26129f Convert to globalstatebag syncing for optimization
When consumables are added from outside the script, it uses global statebags to ensure data is received successfully. This syncs live and for players who have just connected

This removes the callbacks in the script to help optimization
2025-05-22 14:10:30 +01:00
Jim Shield
129b65deda Update version.txt 2025-05-19 17:10:56 +01:00
Jim Shield
d83d0bbfc4 check and store variable
If `jim-consumables:Consume` was triggered by an item with no information it would error and possibly break the script

This a check to instantly `return` when no consumable information is found
2025-05-17 21:03:29 +01:00
Jim Shield
2b6d3f2825 Update README.md 2025-05-14 15:56:13 +01:00
Jim Shield
cab1ddbe52 Update README.md 2025-05-14 15:54:58 +01:00
Jim Shield
868f322c8c Re-add dynamic string changer
Removed this by accident when people were getting notification issues

Restored it to display the correct message when consuming
2025-05-14 15:54:53 +01:00
12 changed files with 522 additions and 279 deletions

12
.gitattributes vendored Normal file
View File

@@ -0,0 +1,12 @@
# VCS / CI noise
.gitattributes export-ignore
.gitignore export-ignore
.github/** export-ignore
.gitmodules export-ignore
# Dev tooling/config
.vscode/** export-ignore
*.code-workspace export-ignore
.editorconfig export-ignore
.eslintrc* export-ignore
.prettier* export-ignore

View File

@@ -3,15 +3,16 @@ name: Discord Commit Notifier
on: on:
push: push:
branches: branches:
- '*' # triggers on all branches - '*'
jobs: jobs:
notify: notify:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Discord Commits - name: Send commit payload to Discord Bot
uses: Sniddl/discord-commits@v1.6 env:
with: URL: http://${{ secrets.DISCORDBOT }}:3000/github-commits
webhook: ${{ secrets.DISCORD_WEBHOOK }} run: |
template: "avatar-with-link" curl -sS -X POST "$URL" \
include-extras: true -H 'Content-Type: application/json' \
--data-binary "@$GITHUB_EVENT_PATH"

71
.github/workflows/notify-release.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: Discord Release Notifier
on:
# Manual or UI-published releases
release:
types: [published]
# Releases created by your tag-driven workflow
workflow_run:
workflows: ["Package & Release"] # must match the 'name:' in release.yml
types: [completed]
permissions:
contents: read
jobs:
# 1) Handle manual / UI / non-workflow-created releases
notify-from-release:
if: github.event_name == 'release' && github.event.action == 'published'
runs-on: ubuntu-latest
steps:
- name: Send release payload to Discord Bot
env:
URL: http://${{ secrets.DISCORDBOT }}:3000/github-releases
run: |
curl -sS -X POST "$URL" \
-H 'Content-Type: application/json' \
--data-binary "@$GITHUB_EVENT_PATH"
# 2) Handle releases created by your 'Package & Release' workflow
# (which wont trigger `on: release` when using GITHUB_TOKEN)
notify-from-workflow-run:
if: >
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq
- name: Fetch release JSON by tag
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
OWNER="${GITHUB_REPOSITORY%/*}"
REPO="${GITHUB_REPOSITORY#*/}"
TAG="${{ github.event.workflow_run.head_branch }}"
# head_branch is the tag name for a tag push workflow_run
curl -fsSL -H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$OWNER/$REPO/releases/tags/$TAG" \
> release.json
- name: Wrap as 'release' event payload & notify bot
env:
URL: http://${{ secrets.DISCORDBOT }}:3000/github-releases
run: |
set -euo pipefail
jq -n --slurpfile rel release.json \
--arg repo "$GITHUB_REPOSITORY" \
--arg repo_url "https://github.com/$GITHUB_REPOSITORY" \
--arg action "published" '
{ action: $action,
repository: { full_name: $repo, html_url: $repo_url },
release: $rel[0],
sender: { login: "github-actions[bot]" } }' > payload.json
curl -sS -X POST "$URL" \
-H 'Content-Type: application/json' \
--data-binary "@payload.json"

88
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,88 @@
name: Package & Release
on:
push:
tags:
- "v*"
- "*.*.*"
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout (full history)
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Derive vars
id: vars
shell: bash
run: |
echo "name=${GITHUB_REPOSITORY##*/}" >> $GITHUB_OUTPUT # e.g. jim_bridge
echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT # strip leading v
- name: Build zip with folder prefix
shell: bash
run: |
NAME='${{ steps.vars.outputs.name }}'
VER='${{ steps.vars.outputs.version }}'
git archive --format=zip --prefix="${NAME}/" -o "${NAME}-${VER}.zip" "$GITHUB_REF_NAME"
ls -lh "${NAME}-${VER}.zip"
# --- Patch notes generation (commit titles + links) -------------------
- name: Find previous tag (SemVer aware)
id: prev
shell: bash
run: |
CUR="${GITHUB_REF_NAME}"
# Sort tags by version desc, drop the current, take the next newest
PREV=$(git tag --sort=-v:refname | grep -v -x "$CUR" | head -n 1 || true)
echo "prev=$PREV" >> $GITHUB_OUTPUT
echo "Previous tag: ${PREV:-<none>}"
- name: Generate RELEASE_NOTES.md from commits
shell: bash
run: |
REPO="${{ github.repository }}"
CUR="${GITHUB_REF_NAME}"
PREV='${{ steps.prev.outputs.prev }}'
if [ -n "$PREV" ]; then
RANGE="$PREV..$CUR"
HEADER="## Changes in $CUR"
else
# First release: include all commits
ROOT=$(git rev-list --max-parents=0 HEAD | tail -n 1)
RANGE="$ROOT..$CUR"
HEADER="## Changes"
fi
{
echo "$HEADER"
echo
# Oldest → newest, subject only, skip merge commits
# Escape '[' and ']' so markdown doesn't break on rare titles
git log --reverse --no-merges --pretty=format:'- ['%h'] - %s' "$RANGE" \
| perl -pe 's/([\[\]])/\\$1/g'
} > RELEASE_NOTES.md
echo "--- RELEASE_NOTES.md ---"
cat RELEASE_NOTES.md
echo "------------------------"
- name: Create / Update GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: ${{ github.ref_name }}
files: |
*.zip
body_path: RELEASE_NOTES.md # attach our generated notes
# If you wanted GitHub's auto notes instead, set:
# generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

129
README.md
View File

@@ -1,126 +1,25 @@
# Jim-Consumables # Jim-Consumables
Consumables script for QBCore
## FiveM MultiFrameork Consumables script
# What is this? # What is this?
This script is designed as a replacement/override for food and drink consumables in `qb-smallresources` This script WAS designed as a replacement/override for food and drink consumables in `qb-smallresources`
It's main purpose was to make it so players did not stand up while sitting with my scripts due to lazy events such as ClearPedTasks in progressbar and dpemotes, this one is designed to cancel the animation you have chosen, not all animations. It's main purpose was to make it so players did not stand up while sitting with my scripts due to lazy events such as ClearPedTasks in progressbar and dpemotes, this one is designed to cancel the animation you have chosen, not ALL animations.
It's recommended to set `Config.UseProgBar` to `false` to get this effect. Users requested I readd the progressbar but it ended up being a config option to enable it
# THIS DOESN'T USE DPEMOTES OR RPEMOTES Though if your players are cancelling all animations when consuming, it's recommended to set `Config.UseProgBar` to `false` to get this effect.
# YOU **NEED** TO PUT THE EMOTES IN THE BOTTOM OF THE CONFIG.LUA
## v1.5 Update Information # THIS DOESN'T USE DPEMOTES OR RPEMOTES OR SCULLYS EMOTEMENU
I've added a export system that allows scripts to easily add new foods and drinks to be usable and then sync them between players
This should work but may have issues.
But because of the export system being used, Jim-Consumables **NEEDS** to start before any scripts that use it. ---
This will be built into my scripts that use consumables to make it more plug and play # Installation and Previews:
## [JixelPatterns GitBook Documentation](https://jixelpatterns.gitbook.io/docs)
# Installation ### If you need support I have a discord server available, it helps me keep track of issues and give better support.
## [JixelPatterns Discord](https://discord.gg/9pCDHmjYwd)
- I always recommend starting my scripts **AFTER** `[qb]` not inside it as it can mess with any dependancies on server load ### If you think I did a good job here, consider donating as it keeps by lights on and my cat round:
- I have a separate folder called `[jimextras]` (that is also in the resources folder) that starts before any scripts would use it. ## [JixelPatterns Kofi](https://ko-fi.com/jixelpatterns)
- This ensure's it has everything it requires before trying to load
- Example of my load order:
```CSS
# QBCore & Extra stuff
ensure qb-core
ensure [qb]
ensure [standalone]
ensure [voice]
ensure [defaultmaps]
ensure [vehicles]
# Extra Jim Stuff
ensure [jimextras]
ensure [jim]
```
## QB-SmallResources
- It should already take control of default qbcore food, drink and drugs.
- If it fails to do this and attempts to use qb-smallresources still you will need to:
- `[qb]` > `qb-smallresources` > `server` > `consumables.lua`
- Remove or comment out the `CreateUseableItem` events for *alcohol*, *eat*, *drink* and *drug* in this file
- Not all of them! (such as armour related items)
- This ***should*** stop `qb-smallresources` taking control and confusing `jim-consumables`
## New Items
To add an item, you only need to add a new item table in the Config.Consumables like this:
```lua
["heartstopper"] = {
emote = "burger", -- Select an emote from below, it has to be in here
time = math.random(5000, 6000), -- Amount of time it takes to consume the item
stress = math.random(1, 2), -- Amount of stress relief, can be 0
heal = 0, -- Set amount to heal by after consuming
armor = 5, -- Amount of armor to add
type = "food", -- Type: "alcohol" / "drink" / "food"
returnItem = { -- Item that will be given when the item is used
item = "plastic", -- eg. Plastic bottles can give "plastic"
amount = 1,
},
stats = {
screen = "rampage", -- The screen effect to be played when after consuming the item
effect = "heal", -- The status effect given by the item, "heal" / "stamina"
time = 10000, -- How long the effect should last (if not added it will default to 10000)
amount = 2, -- How much the value is changed by per second
hunger = math.random(10,20), -- The hunger/thirst stats of the item, if not found in the items.lua
thirst = math.random(10,20), -- The hunger/thirst stats of the item, if not found in the items.lua
},
},
```
Consuming an item can also manually activate screen effects
The example above uses `rampage` as this is what the effect is named after, you can use it for any item you think best
```lua
--The current list of screen effects are:
"turbo"
"focus"
"rampage"
"weed"
"trevor"
"nightvision"
"thermal"
```
## PS-Buffs Support
This scripts can be expanded with ps-buffs (https://github.com/Project-Sloth/ps-buffs)
If this script is enabled it will automatically try to use their system to apply buffs:
```lua
--The extra buffs that can be set include:
"heal" -- Health recovery buff
"stamina" -- Stamina recovery buff
"swimming" -- Swimming speed buff
"stress" -- Stress recovery buff
"armor" -- Armour recovery buff
"hacking" -- Hacking effect
"intelligence" -- Intelligence effect
"luck" -- Luck effect
"strength" -- Strength effect
```
This script supports dpemotes style emotes, so if you have some that you want to be triggered when eating or drinking drop it in the Config.Emotes section.
## Add consumables from external scripts
A small example of a server-sided snippet for this imports the item and the emote, then syncs it to players before and after they connect.
```lua
local foodTable = {
["shotfries"] = { emote = "bsfries", canRun = false, time = math.random(5000, 6000), stress = math.random(2, 4), heal = 0, armor = 0, type = "food", stats = { hunger = math.random(55,65), }},
}
local emoteTable = {
["bsfries"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger_fp", "Fries", AnimationOptions = { Prop = "prop_food_bs_chips", PropBone = 18905, PropPlacement = {0.09, -0.06, 0.05, 300.0, 150.0}, EmoteMoving = true, EmoteLoop = true, }},
}
for k, v in pairs(foodTable) do TriggerEvent("jim-consumables:server:syncAddItem", k, v) end
for k, v in pairs(emoteTable) do TriggerEvent("jim-consumables:server:syncAddEmote", k, v) end
```
This will grab the `shotfries` item info and add it to the `Config.Consumables` while the servers running and the same with the built-in emote system

View File

@@ -1,46 +1,69 @@
local alcoholCount, drugCount, consuming, cancelled = 0, 0, false, false local alcoholCount, drugCount, consuming, cancelled = 0, 0, false, false
Consumables, Emotes = {}, {} Consumables, Emotes = {}, {}
local function syncConsumables()
Consumables = triggerCallback(getScript()..":server:syncConsumables")
Emotes = triggerCallback(getScript()..":server:syncEmotes")
debugPrint("^5Debug^7: ^2Retrieved ^6"..countTable(Consumables).." ^2Items and ^6"..countTable(Emotes).." ^2Emotes^7")
end
RegisterNetEvent(getScript()..":client:syncConsumables", function(NewConsumables)
if debugMode then
for k, v in pairs(NewConsumables) do
if not Consumables[k] then
print("^5Debug^7: ^2New Item Info added^7: ^6"..k.."^7")
end
end
end
Consumables = NewConsumables
end)
RegisterNetEvent(getScript()..":client:syncEmotes", function(NewEmotes)
if debugMode then
for k, v in pairs(NewEmotes) do
if not Emotes[k] then
print("^5Debug^7: ^2New Emote Info added^7: ^6"..k.."^7")
end
end
end
Emotes = NewEmotes
end)
onPlayerLoaded(function() onPlayerLoaded(function()
syncConsumables() -- Wait until statebag exists, then trigger local handler
CreateThread(function()
while not GlobalState.jimConsumableItems do Wait(100) end
local newConsumables = GlobalState.jimConsumableItems
for k in pairsByKeys(newConsumables) do
if not Consumables[k] then
debugPrint("^5Statebag^7: ^2New ^3Consumable ^2Info synced^7: ^6"..k.."^7")
end
end
while not GlobalState.jimConsumableEmotes do Wait(100) end
local newEmotes = GlobalState.jimConsumableEmotes
for k in pairsByKeys(newEmotes) do
if not Emotes[k] then
debugPrint("^5Statebag^7: ^2New ^3Emote ^2Info synced^7: ^6"..k.."^7")
end
end
Consumables = newConsumables
Emotes = newEmotes
debugPrint("^5Statebag^7: ^2Synced ^6"..countTable(Consumables).." ^2Items and ^6"..countTable(Emotes).." ^2Emotes^7")
end)
end, true) end, true)
-- Handlers to recieve global statebag data from the server
AddStateBagChangeHandler("jimConsumableItems", nil, function(bagName, key, value, _unused)
if type(value) == "table" then
local newItemCount = 0
for k in pairsByKeys(value) do
if not Consumables[k] then
newItemCount += 1
debugPrint("^5Statebag^7: ^2New ^3Consumable ^2Info synced^7: ^6"..k.."^7")
end
end
Consumables = value
debugPrint("^5Statebag^7: ^2Synced ^6"..newItemCount.." ^2new Consumables^7")
end
end)
AddStateBagChangeHandler("jimConsumableEmotes", nil, function(bagName, key, value, _unused)
if type(value) == "table" then
local newEmoteCount = 0
for k in pairsByKeys(value) do
if not Emotes[k] then
newEmoteCount += 1
debugPrint("^5Statebag^7: ^2New ^3Emote ^2Info synced^7: ^6"..k.."^7")
end
end
Emotes = value
debugPrint("^5Statebag^7: ^2Synced ^6"..newEmoteCount.." ^2new Emotes^7")
end
end)
RegisterNetEvent(getScript()..':Consume', function(itemName) RegisterNetEvent(getScript()..':Consume', function(itemName)
if not Consumables[itemName] then return end
local consumable = Consumables[itemName]
if not hasItem(itemName, 1) then if not hasItem(itemName, 1) then
print("^5Debug^7: ^1Error^7: ^2Item not found in inventory^7, ^2stopping^7..") print("^5Debug^7: ^1Error^7: ^2Item not found in inventory^7, ^2stopping^7..")
end end
local requiredItem = Consumables[itemName].requiredItem or nil local requiredItem = consumable and consumable.requiredItem or nil
if requiredItem then if requiredItem then
if not hasItem(requiredItem, 1) then if not hasItem(requiredItem, 1) then
triggerNotify(nil, "You need a "..Items[requiredItem].label, "error") triggerNotify(nil, "You need a "..getItemLabel(requiredItem), "error")
return return
else else
-- if requiredItem == "lighter" then breakTool({ item = "lighter", damage = math.random(0, 1) }) end -- if requiredItem == "lighter" then breakTool({ item = "lighter", damage = math.random(0, 1) }) end
@@ -50,7 +73,8 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
debugPrint("^5Debug^7: ^3Consume^7: ^2Starting event, locking inventory and grabbing data^7..") debugPrint("^5Debug^7: ^3Consume^7: ^2Starting event, locking inventory and grabbing data^7..")
tempLockInv(true) tempLockInv(true)
local Player = PlayerPedId() local Player = PlayerPedId()
local emote = Emotes[Consumables[itemName].emote] or Emotes["crisps"] local pedCoords = GetEntityCoords(Player)
local emote = Emotes[consumable.emote] or Emotes["crisps"]
if isAnimal then --- Animal ped adjustments if isAnimal then --- Animal ped adjustments
local presets = { local presets = {
["default"] = { ["default"] = {
@@ -98,32 +122,30 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
Prop = "v_res_tt_bowl", Prop = "v_res_tt_bowl",
PropBone = 64081, PropBone = 64081,
PropPlacement = propPlacement, PropPlacement = propPlacement,
SecondProp = Emotes[Consumables[itemName].emote].AnimationOptions.Prop or nil, SecondProp = Emotes[consumable.emote].AnimationOptions.Prop or nil,
SecondPropBone = Emotes[Consumables[itemName].emote].AnimationOptions.Prop and 64081 or nil, SecondPropBone = Emotes[consumable.emote].AnimationOptions.Prop and 64081 or nil,
SecondPropPlacement = Emotes[Consumables[itemName].emote].AnimationOptions.Prop and propPlacement2 or nil, SecondPropPlacement = Emotes[consumable.emote].AnimationOptions.Prop and propPlacement2 or nil,
}, },
} }
end end
local returnItem = Consumables[itemName].returnItem or nil
local animDict, anim = tostring(emote[1]), tostring(emote[2]) local animDict, anim = tostring(emote[1]), tostring(emote[2])
local model, model2, bone, bone2, drugeffect, stress local model, model2, bone, bone2, drugeffect, stress
local P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 = table.unpack({0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}) -- Default placement coord cariable local P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 = table.unpack({0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}) -- Default placement coord cariable
local RewardItem = Consumables[itemName].rewards or nil local type = consumable.type or ""
local type = Consumables[itemName].type or ""
local pack = Consumables[itemName].pack or nil
local string = "Using " local string = "Using "
local canRun = Consumables[itemName].canRun local canRun = consumable.canRun
local stats = Consumables[itemName].stats local stats = consumable.stats
local time, stress, heal, armor, needStats = GenerateRandomValues({ local time, heal, armor, needStats = GenerateRandomValues({
time = Consumables[itemName].time or { 5000, 6000 }, time = consumable.time or { 5000, 6000 },
stress = Consumables[itemName].stress or 0, heal = consumable.heal or 0,
heal = Consumables[itemName].heal or 0, armor = consumable.armor or 0,
armor = Consumables[itemName].armor or 0, hunger = consumable.stats and consumable.stats.hunger or 0,
hunger = Consumables[itemName].stats and Consumables[itemName].stats.hunger or 0, thirst = consumable.stats and consumable.stats.thirst or 0,
thirst = Consumables[itemName].stats and Consumables[itemName].stats.thirst or 0, stress = consumable.stress or 0,
}) })
if emote.AnimationOptions.Prop then if emote.AnimationOptions.Prop then
model = emote.AnimationOptions.Prop model = emote.AnimationOptions.Prop
bone = GetPedBoneIndex(Player, emote.AnimationOptions.PropBone) bone = GetPedBoneIndex(Player, emote.AnimationOptions.PropBone)
@@ -133,14 +155,24 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
bone2 = GetPedBoneIndex(Player, emote.AnimationOptions.SecondPropBone) bone2 = GetPedBoneIndex(Player, emote.AnimationOptions.SecondPropBone)
P7, P8, P9, P10, P11, P12 = table.unpack(emote.AnimationOptions.SecondPropPlacement) P7, P8, P9, P10, P11, P12 = table.unpack(emote.AnimationOptions.SecondPropPlacement)
end end
end end
if consuming then if type == "drink" or type == "alcohol" then
cancelled = true string = "Drinking "
elseif type == "food" then
string = "Eating "
elseif type == "smoke" then
string = "Smoking "
elseif type == "pack" then
string = "Opening "
end
if consuming then
cancelled = true
debugPrint("^5Debug^7: ^3Consume^7: ^2Event already started^7, ^1Cancelling^7.") debugPrint("^5Debug^7: ^3Consume^7: ^2Event already started^7, ^1Cancelling^7.")
tempLockInv(false) tempLockInv(false)
if Config.UseProgbar then if Config.UseProgbar then
stopPropgressBar() stopProgressBar()
else else
triggerNotify(nil, "Stopped "..string, "error") triggerNotify(nil, "Stopped "..string, "error")
end end
@@ -176,13 +208,21 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
debugPrint("^5Debug^7: ^3Consume^7: ^2Player Movement Flag^7 - ^6"..json.encode(MovementType).." ^7") debugPrint("^5Debug^7: ^3Consume^7: ^2Player Movement Flag^7 - ^6"..json.encode(MovementType).." ^7")
if Config.Main.UseProgbar then if Config.Main.UseProgbar then
CreateThread(function() CreateThread(function()
if progressBar({ time = time, label = string..Items[itemName].label.."..", dead = false, cancel = false}) then if progressBar({
time = time,
label = string..getItemLabel(itemName).."..",
dead = false,
disableMovement = false,
disableCombat = true,
cancel = false
}) then
consuming = false consuming = false
else else
consuming = false
end end
end) end)
else else
triggerNotify(nil, string..Items[itemName].label.."..", "success") triggerNotify(nil, string..getItemLabel(itemName).."..", "success")
end end
consuming = true consuming = true
@@ -192,11 +232,11 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
if model then if model then
if IsModelValid(model) == 1 then if IsModelValid(model) == 1 then
debugPrint("^5Debug^7: ^3PropSpawn^7: ^2Spawning consumable prop^7...") debugPrint("^5Debug^7: ^3PropSpawn^7: ^2Spawning consumable prop^7...")
attachProp = makeProp({ prop = model, coords = vector4(0.0,0.0,0.0,0.0)}, 1, 1) attachProp = makeProp({ prop = model, coords = vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0)}, 1, 1, true)
AttachEntityToEntity(attachProp, Player, bone, P1, P2, P3, P4, P5, P6, true, true, false, true, 1, true) AttachEntityToEntity(attachProp, Player, bone, P1, P2, P3, P4, P5, P6, true, true, false, true, 1, true)
if model2 then if model2 then
if IsModelValid(model2) == 1 then if IsModelValid(model2) == 1 then
attachProp2 = makeProp({ prop = model2, coords = vector4(0.0,0.0,0.0,0.0)}, 1, 1) attachProp2 = makeProp({ prop = model2, coords = vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0)}, 1, 1)
AttachEntityToEntity(attachProp2, Player, bone2, P7, P8, P9, P10, P11, P12, true, true, false, true, 1, true) AttachEntityToEntity(attachProp2, Player, bone2, P7, P8, P9, P10, P11, P12, true, true, false, true, 1, true)
else else
print("^5Debug^7: ^3PropSpawn^7: ^2Second prop model isn't valid/found^7.") print("^5Debug^7: ^3PropSpawn^7: ^2Second prop model isn't valid/found^7.")
@@ -210,7 +250,7 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
if DoesEntityExist(attachProp2) then if DoesEntityExist(attachProp2) then
destroyProp(attachProp2) destroyProp(attachProp2)
attachProp2 = nil attachProp2 = nil
end end
else else
print("^5Debug^7: ^3PropSpawn^7: ^2Prop model isn't valid/found^7.") print("^5Debug^7: ^3PropSpawn^7: ^2Prop model isn't valid/found^7.")
end end
@@ -224,14 +264,14 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
"Type: "..(type or ""), "Type: "..(type or ""),
"Hunger: "..(needStats.hunger or 0).."%", "Hunger: "..(needStats.hunger or 0).."%",
"Thirst: "..(needStats.thirst or 0).."%", "Thirst: "..(needStats.thirst or 0).."%",
"Stress: "..(stress or 0).."%", "Stress: "..(needStats.stress or 0).."%",
"Heal: "..(heal or 0).."%", "Heal: "..(heal or 0).."%",
"Armour: "..(armor or 0).."%", "Armour: "..(armor or 0).."%",
}, nil, nil) }, nil, nil)
end end
makeInstructionalButtons({ makeInstructionalButtons({
{ keys = { 194 }, text = "Stop Consuming" }, { keys = { 194 }, text = "Stop Consuming" },
}) })
if time <= 0 then if time <= 0 then
consuming = false consuming = false
end end
@@ -241,58 +281,23 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
tempLockInv(false) tempLockInv(false)
hideText() hideText()
if Config.Main.UseProgbar then if Config.Main.UseProgbar then
stopPropgressBar() stopProgressBar()
else else
triggerNotify(nil, "Cancelled "..string, "error") triggerNotify(nil, "Cancelled "..string, "error")
end end
TriggerServerEvent(getScript()..":server:stopConsume")
end end
Wait(0) Wait(0)
time -= 12 time -= 12
end end
StopEntityAnim(Player, anim, animDict, 1.0) StopEntityAnim(Player, anim, animDict, 1.0)
unloadAnimDict(animDict) unloadAnimDict(animDict)
if not cancelled then if not cancelled then
hideText() hideText()
removeItem(itemName, 1)
if returnItem ~= nil then
debugPrint("returnItem detected")
currentToken = triggerCallback(AuthEvent)
addItem(returnItem.item, returnItem.amount)
end
-- Reward Item calculations TriggerServerEvent(getScript()..":server:finishConsume", needStats)
CreateThread(function()
if RewardItem then
debugPrint("Reward Item detected")
for i = 1, Consumables[itemName].amounttogive do
local rarity = math.random(1, 4) -- rarity calculation
while true do
local item = math.random(1, countTable(RewardItem)) -- random item in the list to pick
if RewardItem[item].rarity >= rarity then
currentToken = triggerCallback(AuthEvent)
addItem(RewardItem[item].item, math.random(1, RewardItem[item].max or 1))
debugPrint("^5Debug^7: ^2Given reward prize^7: '^6"..RewardItem[item].item.."^7'")
break
end
Wait(100)
end
Wait(1500)
end
end
end)
if needStats then
if needStats.hunger then
TriggerServerEvent(getScript()..":server:addNeed", Core.Functions.GetPlayerData().metadata["hunger"] + needStats.hunger, "hunger")
end
if needStats.thirst then
TriggerServerEvent(getScript()..":server:addNeed", Core.Functions.GetPlayerData().metadata["thirst"] + needStats.thirst, "thirst")
end
end
debugPrint("^5Debug^7: ^2Hunger^7: [^6"..(needStats.hunger or 0).."^7] ^2Thrist^7: [^6"..(needStats.thirst or 0).."^7]" )
if stress and stress ~= 0 then
debugPrint("^5Debug^7: ^3Consume^7: ^2Relieving ^6"..stress.." ^2stress^7.")
TriggerServerEvent('hud:server:RelieveStress', stress)
end
if heal and heal ~= 0 then if heal and heal ~= 0 then
debugPrint("^5Debug^7: ^3Consume^7: ^2Healing player by^7: ^6"..heal) debugPrint("^5Debug^7: ^3Consume^7: ^2Healing player by^7: ^6"..heal)
SetEntityHealth(Player, GetEntityHealth(Player) + heal) SetEntityHealth(Player, GetEntityHealth(Player) + heal)
@@ -302,20 +307,42 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
TriggerServerEvent('hospital:server:SetArmor', (GetPedArmour(Player) + armor)) SetPedArmour(Player, (GetPedArmour(Player) + armor)) TriggerServerEvent('hospital:server:SetArmor', (GetPedArmour(Player) + armor)) SetPedArmour(Player, (GetPedArmour(Player) + armor))
end end
if type == "alcohol" then if type == "alcohol" then
alcoholCount += 1 if checkExportExists("jim_bridge", "addAlcoholCount") then
debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4alcoholCount^7: ^6"..alcoholCount) exports.jim_bridge:addAlcoholCount(1, stats.canOD)
if alcoholCount > 1 and alcoholCount < 4 then else
TriggerEvent("evidence:client:SetStatus", "alcohol", 200) alcoholCount = alcoholCount + 1
elseif alcoholCount >= 4 then debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4alcoholCount^7: ^6"..alcoholCount)
TriggerEvent("evidence:client:SetStatus", "heavyalcohol", 200) if alcoholCount > 1 and alcoholCount <= 4 then
CreateThread(function() TriggerEvent("evidence:client:SetStatus", "alcohol", 200)
AlienEffect() elseif alcoholCount >= 4 then
end) -- Used as overdosing/too drunk effect TriggerEvent("evidence:client:SetStatus", "heavyalcohol", 200)
CreateThread(function()
AlienEffect()
end)
end
if stats.canOD and alcoholCount >= 5 then
SetEntityHealth(Player, GetEntityHealth(Player) - math.random(5, 10))
end
end end
end end
if pack then if type == "drug" then
currentToken = triggerCallback(AuthEvent) if checkExportExists("jim_bridge", "addDrugCount") then
addItem(pack.item, pack.amount) exports.jim_bridge:addDrugCount(1, stats.canOD or false)
else
drugCount = drugCount + 1
debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4drugCount^7: ^6"..drugCount)
if drugCount > 3 and drugCount < 7 then
elseif drugCount >= 7 then
CreateThread(function()
AlienEffect()
end)
end
if stats.canOD and drugCount >= 4 then
SetEntityHealth(Player, GetEntityHealth(Player) - math.random(5, 10))
end
end
end end
if stats then if stats then
if stats.screen then -- Screen effect activation if stats.screen then -- Screen effect activation
@@ -336,14 +363,8 @@ RegisterNetEvent(getScript()..':Consume', function(itemName)
end end
end end
if stats.canOD then if stats.canOD then
drugCount += 1 if drugCount >= 4 or alcoholCount >= 5 then
debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4drugCount^7: ^6"..drugCount) SetEntityHealth(Player, GetEntityHealth(Player) - math.random(5, 10))
if drugCount >= 4 then
debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4drugCount^7: ^6"..drugCount.."^7 - ^2 removing health")
SetEntityHealth(PlayerPedId(), GetEntityHealth(Player) - math.random(10, 15))
if drugCount >= 7 then
CreateThread(function() AlienEffect() end) -- If too many drugs, if not dead will make you stumble
end
end end
end end
if stats.effect then if stats.effect then

View File

@@ -10,7 +10,7 @@ Config = {
}, },
Main = { Main = {
UseProgbar = false, -- Disabled this, progress bars stop all anims when complete. UseProgbar = false, -- Recommended to disable this, progress bars stop ALL anims when complete.
-- This is intended to create a progressbar to show consuming but it was usually forces animations to end weirdly -- This is intended to create a progressbar to show consuming but it was usually forces animations to end weirdly
}, },
Crafting = { Crafting = {

View File

@@ -1,6 +1,6 @@
name "Jim-Consumables" name "Jim-Consumables"
author "Jimathy" author "Jimathy"
version "2.0.02" version "2.0.09"
description "Consumables Script" description "Consumables Script"
fx_version "cerulean" fx_version "cerulean"
game "gta5" game "gta5"

View File

@@ -1,51 +1,174 @@
local Consumables = Config.Consumables local Consumables = Config.Consumables
local Emotes = Config.Emotes local Emotes = Config.Emotes
local isConsuming = {}
local function massMakeUseable()
for k, v in pairs(Config.Consumables) do
createUseableItem(k, function(source, item)
local src = source
if not isConsuming[src] and hasItem(item.name, 1, src) then
registerConsume(src, item.name)
TriggerClientEvent(getScript()..':Consume', src, item.name)
end
end)
end
end
function registerConsume(src, item)
-- Start building server sided item return table
local consumable = Consumables[item]
isConsuming[src] = {
item = item,
rewardItem = checkReward(consumable) or nil,
returnItem = checkReturnItem(consumable) or nil,
packItem = checkPackItem(consumable) or nil
}
debugPrint("^5Debug^7: ^2Player ^3"..src.." ^2started consuming ^7'^2"..item.."^7'")
end
RegisterNetEvent(getScript()..":RegisterConsuming", function(item)
local src = source
registerConsume(src, item)
end)
onResourceStart(function() onResourceStart(function()
for k, v in pairs(Config.Consumables) do for k, v in pairs(Config.Consumables) do
createUseableItem(k, function(source, item) TriggerClientEvent(getScript()..':Consume', source, item.name) end) if not Items[k] then
if not Items[k] then print("^1Debug^7: ^2Item check ^7- '^1"..k.."^7' ^2not found in the shared lua^7") end print("^1Debug^7: ^2Item check ^7- '^1"..k.."^7' ^2not found in the shared lua^7")
if not Config.Emotes[v.emote] then print("^1Debug^7: ^2Emote check ^7- '^1"..k.."^7' ^2requested emote ^7'^6"..v.emote.."^7' - ^2not found in config^7.^2lua^7") end end
if not Config.Emotes[v.emote] then
print("^1Debug^7: ^2Emote check ^7- '^1"..k.."^7' ^2requested emote ^7'^6"..v.emote.."^7' - ^2not found in config^7.^2lua^7")
end
end end
--Export Import System-- massMakeUseable()
createCallback(getScript()..':server:syncConsumables', function(source) return Consumables end)
createCallback(getScript()..':server:syncEmotes', function(source) return Emotes end)
--Export Import System--
GlobalState.jimConsumableItems = Consumables
GlobalState.jimConsumableEmotes = Emotes
end, true) end, true)
RegisterNetEvent(getScript()..':server:addNeed', function(amount, type) onResourceStop(function()
local Player = Core.Functions.GetPlayer(source) if not Player then return end GlobalState.jimConsumableItems = Consumables
if type == "thirst" then GlobalState.jimConsumableEmotes = Emotes
Player.Functions.SetMetaData('thirst', amount)
TriggerClientEvent('hud:client:UpdateNeeds', source, Player.PlayerData.metadata.hunger, amount)
elseif type == "hunger" then
Player.Functions.SetMetaData('hunger', amount)
TriggerClientEvent('hud:client:UpdateNeeds', source, amount, Player.PlayerData.metadata.thirst)
end
end) end)
local syncScheduled = false local syncScheduled = false
function syncConsumables() function syncConsumables()
debugPrint("^5Debug^7: ^2Sending ^6"..countTable(Consumables).." ^3Consumables ^2to all clients^7") debugPrint("^5Statebag^7: ^2Sending ^6"..countTable(Consumables).." ^3Consumables ^2to all clients^7")
TriggerClientEvent(getScript()..":client:syncConsumables", -1, Consumables) massMakeUseable()
GlobalState.jimConsumableItems = Consumables
syncScheduled = false syncScheduled = false
end end
local emoteSyncScheduled = false local emoteSyncScheduled = false
function syncEmotes() function syncEmotes()
debugPrint("^5Debug^7: ^2Sending ^6"..countTable(Emotes).." ^3Emotes to all clients^7") debugPrint("^5Statebag^7: ^2Sending ^6"..countTable(Emotes).." ^3Emotes to all clients^7")
TriggerClientEvent(getScript()..":client:syncEmotes", -1, Emotes) GlobalState.jimConsumableEmotes = Emotes
emoteSyncScheduled = false emoteSyncScheduled = false
end end
-- Return item
function checkPackItem(consumable)
local result = nil
if consumable.pack then
result = { item = consumable.pack.item, amount = consumable.pack.amount }
end
return result
end
-- Return item
function checkReturnItem(consumable)
local result = nil
if consumable.returnItem then
result = { item = consumable.returnItem.item, amount = consumable.returnItem.amount }
end
return result
end
-- Reward items
function checkReward(consumable)
local result = nil
local rewardItem = consumable.rewards or nil
if rewardItem then
debugPrint("Reward Item detected")
for i = 1, consumable.amounttogive or 1 do
local rarity = math.random(1, 4) -- rarity calculation
while true do
local item = math.random(1, countTable(rewardItem)) -- random item in the list to pick
if rewardItem[item].rarity >= rarity then
result = result or {}
result[#result+1] = { item = rewardItem[item].item, amount = math.random(1, rewardItem[item].max or 1) }
debugPrint("^5Debug^7: ^2Cachced reward prize^7: '^6"..rewardItem[item].item.."^7'")
break
end
Wait(10)
break
end
end
end
return result
end
RegisterNetEvent(getScript()..":server:finishConsume", function(needTypes)
local src = source
if isConsuming[src] ~= nil then
removeItem(isConsuming[src].item, 1, src)
if isConsuming[src].rewardItem then
debugPrint("^5Debug^7: ^2Giving player ^3"..src.." ^2reward items^7")
local item = isConsuming[src].rewardItem
addItem(item.item, item.amount, nil, src)
end
if isConsuming[src].returnItem then
debugPrint("^5Debug^7: ^2Giving player ^3"..src.." ^2return item^7")
for i = 1, #isConsuming[src].returnItem do
local item = isConsuming[src].returnItem[i]
addItem(item.item, item.amount, nil, src)
end
end
if isConsuming[src].packItem then
debugPrint("^5Debug^7: ^2Giving player ^3"..src.." ^2Pack items^7")
local item = isConsuming[src].packItem
addItem(item.item, item.amount, nil, src)
end
-- Needs
if needTypes.thirst then
debugPrint("^5Debug^7: ^2Thrist^7: [^6"..(needTypes.thirst or 0).."^7]")
setThirst(src, needTypes.thirst)
end
if needTypes.hunger then
debugPrint("^5Debug^7: ^2Hunger^7: [^6"..(needTypes.hunger or 0).."^7]")
setHunger(src, needTypes.hunger)
end
if needTypes.stress then
debugPrint("^5Debug^7: ^2Stress^7: [^6"..(needTypes.stress or 0).."^7]")
setStress(src, needTypes.stress)
end
isConsuming[src] = nil
else
return
end
end)
RegisterNetEvent(getScript()..":server:stopConsume", function()
local src = source
debugPrint("^5Player stopped consuming early^7", src)
isConsuming[src] = nil
end)
RegisterNetEvent(getScript()..':server:syncAddItem', function(itemName, data) RegisterNetEvent(getScript()..':server:syncAddItem', function(itemName, data)
if not Consumables[itemName] then if not Consumables[itemName] then
Consumables[itemName] = data Consumables[itemName] = data
createUseableItem(itemName, function(source, item) TriggerClientEvent(getScript()..':Consume', source, itemName) end) --createUseableItem(itemName, function(source, item) TriggerClientEvent(getScript()..':Consume', source, itemName) end)
debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Item^7: '"..itemName.."'") debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Item^7: '"..itemName.."'")
if not syncScheduled then if not syncScheduled then
syncScheduled = true syncScheduled = true
Citizen.SetTimeout(5000, syncConsumables) SetTimeout(5000, syncConsumables)
end end
else else
debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Item^7: '"..itemName.."'") debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Item^7: '"..itemName.."'")
@@ -58,20 +181,13 @@ RegisterNetEvent(getScript()..':server:syncAddEmote', function(emoteName, data)
debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Emote^7: '"..emoteName.."'") debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Emote^7: '"..emoteName.."'")
if not emoteSyncScheduled then if not emoteSyncScheduled then
emoteSyncScheduled = true emoteSyncScheduled = true
Citizen.SetTimeout(5000, syncEmotes) SetTimeout(5000, syncEmotes)
end end
else else
debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Emote^7: '"..emoteName.."'") debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Emote^7: '"..emoteName.."'")
end end
end) end)
RegisterNetEvent(getScript()..":server:syncConsumables", function()
TriggerClientEvent(getScript()..':client:syncConsumables', -1, Consumables)
end)
RegisterNetEvent(getScript()..":server:syncEmotes", function()
TriggerClientEvent(getScript()..':client:syncEmotes', -1, Emotes)
end)
--[[ --[[
Core.Commands.Add('consumableCreator', "Create consumables (admin only)", {}, false, function(source) Core.Commands.Add('consumableCreator', "Create consumables (admin only)", {}, false, function(source)
if source > 0 then return TriggerClientEvent(getScript()..":client:consumableCreator", source) end if source > 0 then return TriggerClientEvent(getScript()..":client:consumableCreator", source) end

View File

@@ -47,7 +47,7 @@ Config.Consumables = {
-- heal = 0, -- Set amount to heal by after consuming -- heal = 0, -- Set amount to heal by after consuming
-- armor = 5, -- Amount of armor to add -- armor = 5, -- Amount of armor to add
-- type = "food", -- Type: "alcohol" / "drink" / "food" -- type = "food", -- Type: "alcohol" / "drink" / "food"
-- canRun = true, -- If true player can run while using the item, not to it will cancel the event -- canRun = true, -- If true player can run while using the item, if not it will cancel the event
-- --
-- stats = { -- stats = {
-- screen = "thermal", -- The screen effect to be played when after consuming the item "rampage" "turbo" "focus" "weed" "trevor" "nightvision" "thermal" -- screen = "thermal", -- The screen effect to be played when after consuming the item "rampage" "turbo" "focus" "weed" "trevor" "nightvision" "thermal"
@@ -74,7 +74,7 @@ Config.Consumables = {
-- Example Box Item -- Example Box Item
-- ["9_box"] = { -- Name of the box item in the shared -- ["9_box"] = { -- Name of the box item in the shared
-- emote = "uncuff", -- The emote than should run when "unboxing" -- emote = "uncuff", -- The emote than should run when "unboxing"
-- canRun = true, -- If true player can run while using the item, not to it will cancel the event -- canRun = true, -- If true player can run while using the item, if not it will cancel the event
-- time = 3500, -- How long it takes to use the item -- time = 3500, -- How long it takes to use the item
-- type = "pack", -- Designate it as a "pack" to the script knows what to do -- type = "pack", -- Designate it as a "pack" to the script knows what to do
-- pack = { -- pack = {
@@ -83,4 +83,18 @@ Config.Consumables = {
-- }, -- },
-- }, -- },
-- Example Cigar Item wiht requirements
-- ["cigar"] = { -- Name of the item in your shared items
-- emote = "smokecigar", -- The emote than should run when "smoking"
-- canRun = true, -- If true player can run while using the item, if not it will cancel the event
-- time = math.random(5000, 6000), -- How long it takes to use the item
-- type = "smoke", -- Designate it as a "smoke" to the script knows what to do
-- requiredItem = "lighter", -- Set a required item making it unsable if they don't have it
-- stats = {
-- effect = "stress",
-- time = 5000,
-- amount = math.random(10, 15),
-- canOD = false
-- }
-- },
} }

View File

@@ -15,9 +15,25 @@ function GenerateRandomValues(data)
transData[k] = v transData[k] = v
end end
end end
return transData["time"],
transData["stress"], if transData.hunger > 0 then
transData["heal"], transData.hunger = transData.hunger > 100 and 100 or transData.hunger
transData["armor"], end
{ hunger = transData["hunger"], thirst = transData["thirst"] }
if transData.thirst > 0 then
transData.thirst = transData.thirst > 100 and 100 or transData.thirst
end
if transData.stress > 0 then
transData.stress = transData.stress > 100 and 100 or transData.stress
end
return transData["time"],
transData["heal"],
transData["armor"],
{
hunger = transData["hunger"] or 0,
thirst = transData["thirst"] or 0,
stress = transData["stress"] or 0
}
end end

View File

@@ -1 +1,6 @@
2.0.02 2.0.09
- Fix possible issue with nil needTypes tables being sent
- Fix packitems and return items not giving any items
https://github.com/jimathy/jim-consumables/releases/latest