# Smoking System

{% embed url="<https://www.youtube.com/watch?v=jQ9WdbfH-lk>" %}

## Purchase

[Purchase this resource](https://rtx.tebex.io/package/7419073)

## Installation

{% hint style="info" %}
**Framework compatibility**

This resource is **standalone** and works on any FiveM server.

Compatible with **ESX**, **QBCore**, **QBox**, **vRP**, and other frameworks.

If you are using a framework other than ESX, QBCore, or QBox, follow the **Standalone** installation instructions.
{% endhint %}

### Standalone

{% stepper %}
{% step %}

### Standalone installation

* Put the `rtx_smoking` folder into your `resources`.
* Open `config.lua`.
* Configure your `config.lua` to your preferences.
* Add `rtx_smoking` to your `server.cfg`.
* Put the `rtx_smoking_objects` folder into your `resources`.
* Add `rtx_smoking_objects` to your `server.cfg`.
  {% endstep %}
  {% endstepper %}

### QBCore

{% stepper %}
{% step %}

### QBCore installation

* Put the `rtx_smoking` folder into your `resources`.
* Open `config.lua`.
* Replace `Config.Framework = "standalone"` with `Config.Framework = "qbcore"`.
* Configure your `config.lua` to your preferences.
* Add `rtx_smoking` to your `server.cfg`.
* Put the `rtx_smoking_objects` folder into your `resources`.
* Add `rtx_smoking_objects` to your `server.cfg`.
  {% endstep %}
  {% endstepper %}

### ESX

{% stepper %}
{% step %}

### ESX installation

* Put the `rtx_smoking` folder into your `resources`.
* Open `config.lua`.
* Replace `Config.Framework = "standalone"` with `Config.Framework = "esx"`.
* Configure your `config.lua` to your preferences.
* Add `rtx_smoking` to your `server.cfg`.
* Put the `rtx_smoking_objects` folder into your `resources`.
* Add `rtx_smoking_objects` to your `server.cfg.`
  {% endstep %}
  {% endstepper %}

## Config Preview

<details>

<summary>Show Config</summary>

```lua
Config = {}

Config.Framework = "standalone"  -- Supported frameworks: standalone, qbcore, esx

Config.InterfaceColor = "#ff66ff" -- UI theme color in HEX format (e.g. #ff66ff)

Config.Language = "English" -- UI language used by the script (English)

Config.OxInventory = true -- Enable this if you are using ox_inventory instead of default inventory system

Config.QBCoreNewInventoryVersion = true -- Enable this if you are using the newer QBCore inventory system (fixes item-related errors)

Config.InventorySystem = "oxinventory" -- types (oxinventory, qbcoreinventory, codeminventory, coreinventory, psinventory, chezza, jaksam_inventory, tgiann-inventory) (you can add your own inventory system in server/other.lua)

Config.SmokingInteractionSystem = 1 -- Interaction style: 1 = Custom interaction, 2 = 3D Text, 3 = GTA Online style, 4 = Floating Text Box Style

Config.Target = false -- Enable target-based interaction (true/false)

Config.Targettype = "oxtarget" -- Target system type: qtarget, qbtarget, oxtarget

Config.TargetSystemsNames = {qtarget = "qtarget", qbtarget = "qb-target", oxtarget = "ox_target"} -- target resource names

Config.TargetIcons = {hookahmanage = "fa-solid fa-list", hookahgrab = "fa-solid fa-smoking"} -- FontAwesome icons used by target interactions

Config.HookahUseKey = "e" -- Key used to interact with the hookah

Config.HookahHoseKey = "g" -- Key used to take or return a hookah hose

Config.HookahRenderDistance = 100.0 -- Maximum distance where hookah objects are rendered

Config.HookahInteractDistance = 2.5 -- Distance required to interact with an hookah

Config.MaxHoses = 2 -- Maximum number of hoses available per hookah

Config.DebugMode = false -- Enables debug prints for hookah system

Config.CoalItem = "shisha_charcoal_box" -- Inventory item used as hookah charcoal

Config.CoalHeatDuration = 15000 -- Time required to heat hookah coal in milliseconds
Config.CoalHeatUpdateInterval = 500 -- Coal heating progress update interval in milliseconds

Config.CoalBurnDuration = 1200000 -- Total coal burn duration in milliseconds
Config.CoalBurnUpdateInterval = 1000 -- Coal burn status update interval in milliseconds

Config.HookahConsumeInterval = 15000 -- Interval for hookah resource consumption in milliseconds
Config.HookahWaterConsume = 3 -- Water amount consumed each hookah tick
Config.HookahTobaccoConsume = 4 -- Tobacco amount consumed each hookah tick
Config.HookahLowWaterLevel = 25 -- Water percentage considered low for hookah use

Config.HookahMaxHoseDistance = 3.0 -- Maximum distance allowed between player and hookah hose

Config.StaticHookahs = {
    [1] = {
        label = "Hookah Bar", -- Display name of the static hookah
        enabled = true, -- Enable or disable this static hookah
        hookahType = 1, -- Hookah type from Config.HookahTypes
        coords = vector3(-557.26, 291.45, 81.17), -- Hookah position
        rotation = vector3(0.0, 0.0, 90.0), -- Hookah rotation

        defaultState = {
            water = { state = "good", level = 100 }, -- Default water state
            tobacco = { state = "prepared", amount = 100, flavor = "Apple" }, -- Default tobacco state
            coal = { state = "placed", progress = 100, durability = 100 }, -- Default coal state
            hoses = { connected = 0, max = 4, players = {} }, -- Hose settings
        },

        managePermissions = {
            everyone = false, -- Allow everyone to manage the hookah
            permissions = {
                { permissiontype = "ace", permission = "hookah.manage" }, -- ACE permission
                { permissiontype = "job", permission = "bahama" }, -- Job permission
                { permissiontype = "identifier", permission = "license:59cda6cea2cba2d00a2866476b76a12cf58be27a" }, -- Identifier permission
            },
        },
    },

    [2] = {
        label = "Empty Hookah", -- Display name of the static hookah
        enabled = true, -- Enable or disable this static hookah
        hookahType = 2, -- Hookah type from Config.HookahTypes
        coords = vector3(2.78, 527.38, 174.18), -- Hookah position
        rotation = vector3(0.0, 0.0, 180.0), -- Hookah rotation

        defaultState = {
            water = { state = "empty", level = 0 }, -- Empty water state
            tobacco = { state = "empty", amount = 0, flavor = nil }, -- Empty tobacco state
            coal = { state = "missing", progress = 0, durability = 0 }, -- No coal placed
            hoses = { connected = 0, max = 4, players = {} }, -- Hose settings
        },

        managePermissions = {
            everyone = true, -- Allow everyone to manage the hookah
            permissions = {
                { permissiontype = "ace", permission = "hookah.manage" }, -- ACE permission
                { permissiontype = "job", permission = "bahama" }, -- Job permission
                { permissiontype = "identifier", permission = "license:59cda6cea2cba2d00a2866476b76a12cf58be27a" }, -- Identifier permission
            },
        },
    },
}

Config.HookahSmokeEffect = { -- Hookah exhale smoke particle settings
    dict = "core", -- Animation or particle dictionary name
    name = "exp_grd_bzgas_smoke", -- Particle effect name

    minHoldMs = 300, -- Minimum hold duration in milliseconds
    maxHoldMs = 5000, -- Maximum hold duration in milliseconds

    minSmokeTimeMs = 800, -- Minimum hookah smoke duration in milliseconds
    maxSmokeTimeMs = 5000, -- Maximum hookah smoke duration in milliseconds

    scale = 0.3, -- Particle or effect scale

    bone = 47495, -- Ped bone index used for prop attachment
    offset = vec3(0.15, 0.0, 0.0), -- Position offset relative to the bone or prop
    rotation = vec3(0.0, 0.0, 0.0) -- Rotation offset relative to the bone or prop
}

Config.SoundEffects = true -- Enable synced sound effects
Config.SoundEffectsVolume = 0.45 -- Default sound volume
Config.SoundEffectsDistance = 5.0 -- Max distance where players can hear sounds

Config.Sounds = {
    inhalenormal = "sounds/inhalenormal.mp3", -- Default inhale sound for cigarettes, cigars, joints
    bongLoop = "sounds/bong.mp3", -- Loop sound while inhaling from bong (water bubbling)
    
    cough_male = "sounds/coughmale.mp3", -- Male cough sound (used on strong hits or forced release)
    cough_female = "sounds/coughfemale.mp3", -- Female cough sound (used on strong hits or forced release)
    
    exhalemale = "sounds/exhalemale.mp3", -- Male exhale sound (optional, if using gender-based exhale)
    exhalefemale = "sounds/exhalefemale.mp3", -- Female exhale sound (optional, if using gender-based exhale)
    
    lighter = "sounds/lighter.mp3", -- Lighter ignition sound (used when lighting cigarettes/joints)
    
    hookahInhale = "sounds/hookah.mp3", -- Loop sound while inhaling from hookah (soft bubbling/airflow)
    
    vape = "sounds/vape.mp3", -- Vape inhale
}

Config.ItemNames = { -- if you want to change the item names you can do it here
	["rolling_paper"] = "rolling_paper",  -- item give name
	["water"] = "water", -- item give name
	["vape_battery"] = "vape_battery", -- item give name
	["lighter"] = "lighter", -- item give name
}

Config.HookahTypes = { -- Available hookah models and colors
    [1] = {
        label = "Shisha (Blue)", -- Display name shown in UI
        item = "shisha_0", -- Inventory item name
		color = 0, -- Hookah color variation index
    },

    [2] = {
        label = "Shisha (Red)", -- Display name shown in UI
        item = "shisha_1", -- Inventory item name
		color = 1, -- Hookah color variation index
    },

    [3] = {
        label = "Shisha (Pink)", -- Display name shown in UI
        item = "shisha_2", -- Inventory item name
		color = 2, -- Hookah color variation index
    },

    [4] = {
        label = "Shisha (Green)", -- Display name shown in UI
        item = "shisha_3", -- Inventory item name
		color = 3, -- Hookah color variation index
    },

    [5] = {
        label = "Shisha (Yellow)", -- Display name shown in UI
        item = "shisha_4", -- Inventory item name
		color = 4, -- Hookah color variation index
    },

    [6] = {
        label = "Shisha (Gray)", -- Display name shown in UI
        item = "shisha_5", -- Inventory item name
		color = 5, -- Hookah color variation index
    },
}

Config.HookahFlavors = { -- Available hookah tobacco flavors
    ["apple"] = {
        label = "Apple", -- Display name shown in UI
        itemname = "shisha_tobacco_apple", -- Inventory item required for this option
        type = "classic" -- Internal item type identifier
    },

    ["blueberry"] = {
        label = "Blueberry", -- Display name shown in UI
        itemname = "shisha_tobacco_blueberry", -- Inventory item required for this option
        type = "sweet" -- Internal item type identifier
    },

    ["lemon"] = {
        label = "Lemon", -- Display name shown in UI
        itemname = "shisha_tobacco_lemon", -- Inventory item required for this option
        type = "citrus" -- Internal item type identifier
    },

    ["mint"] = {
        label = "Mint", -- Display name shown in UI
        itemname = "shisha_tobacco_mint", -- Inventory item required for this option
        type = "fresh" -- Internal item type identifier
    },

    ["orange"] = {
        label = "Orange", -- Display name shown in UI
        itemname = "shisha_tobacco_orange", -- Inventory item required for this option
        type = "citrus" -- Internal item type identifier
    },

    ["strawberry"] = {
        label = "Strawberry", -- Display name shown in UI
        itemname = "shisha_tobacco_strawberry", -- Inventory item required for this option
        type = "sweet" -- Internal item type identifier
    },

    ["vanilla"] = {
        label = "Vanilla", -- Display name shown in UI
        itemname = "shisha_tobacco_vanilla", -- Inventory item required for this option
        type = "dessert" -- Internal item type identifier
    },

    ["watermelon"] = {
        label = "Watermelon", -- Display name shown in UI
        itemname = "shisha_tobacco_watermelon", -- Inventory item required for this option
        type = "refreshing" -- Internal item type identifier
    },
}

Config.HoldKey = 38 -- Key used to hold/use the smoking item (E)

Config.Debug = false -- Enables general debug mode

Config.CycleIdleKey = 104 -- Key to cycle cigarette position while idle (cigarette position change) (H)

Config.SecretSwitchPuffKey = 137 -- Key to switch puff style secretly (Caps Lock)

Config.CancelKey = 177 -- Key to cancel smoking action (stop smoking) (Backspace)

Config.SettingsKey = 23 -- Key to open settings for the current smoking type (F)

Config.GiveKey = 47 -- Key to give a smoking item to another player (G)

Config.GiveDistance = 3.0 -- Maximum distance for giving a smoking item to another player

Config.SelectionSets = { -- Selectable refill or strain options for supported item types
	["vape"] = {
		["apple"] = {
			label = "Apple", -- Display name shown in UI
			itemname = "eliquid_box_apple", -- Inventory item required for this option
			image = "eliquid_box_apple.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_apple", -- Object model used for this option
			category = "Crisp and refreshing apple taste" -- Category or description shown in the selection UI
		},

		["blueberry"] = {
			label = "Blueberry", -- Display name shown in UI
			itemname = "eliquid_box_blueberry", -- Inventory item required for this option
			image = "eliquid_box_blueberry.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_blueberry", -- Object model used for this option
			category = "Sweet and juicy blueberry flavour" -- Category or description shown in the selection UI
		},

		["cherry"] = {
			label = "Cherry", -- Display name shown in UI
			itemname = "eliquid_box_cherry", -- Inventory item required for this option
			image = "eliquid_box_cherry.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_cherry", -- Object model used for this option
			category = "Rich and slightly tart cherry taste" -- Category or description shown in the selection UI
		},

		["ecola"] = {
			label = "eCola", -- Display name shown in UI
			itemname = "eliquid_box_ecola", -- Inventory item required for this option
			image = "eliquid_box_ecola.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_ecola", -- Object model used for this option
			category = "Classic fizzy cola sensation" -- Category or description shown in the selection UI
		},

		["grape"] = {
			label = "Grape", -- Display name shown in UI
			itemname = "eliquid_box_grape", -- Inventory item required for this option
			image = "eliquid_box_grape.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_grape", -- Object model used for this option
			category = "Bold and sweet grape aroma" -- Category or description shown in the selection UI
		},

		["lemon"] = {
			label = "Lemon", -- Display name shown in UI
			itemname = "eliquid_box_lemon", -- Inventory item required for this option
			image = "eliquid_box_lemon.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_lemon", -- Object model used for this option
			category = "Sharp and zesty citrus kick" -- Category or description shown in the selection UI
		},

		["mint"] = {
			label = "Mint", -- Display name shown in UI
			itemname = "eliquid_box_mint", -- Inventory item required for this option
			image = "eliquid_box_mint.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_mint", -- Object model used for this option
			category = "Cool and refreshing mint breeze" -- Category or description shown in the selection UI
		},

		["orange"] = {
			label = "Orange", -- Display name shown in UI
			itemname = "eliquid_box_orange", -- Inventory item required for this option
			image = "eliquid_box_orange.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_orange", -- Object model used for this option
			category = "Fresh and juicy orange burst" -- Category or description shown in the selection UI
		},

		["peach"] = {
			label = "Peach", -- Display name shown in UI
			itemname = "eliquid_box_peach", -- Inventory item required for this option
			image = "eliquid_box_peach.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_peach", -- Object model used for this option
			category = "Smooth and sweet peach flavour" -- Category or description shown in the selection UI
		},

		["strawberry"] = {
			label = "Strawberry", -- Display name shown in UI
			itemname = "eliquid_box_strawberry", -- Inventory item required for this option
			image = "eliquid_box_strawberry.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_strawberry", -- Object model used for this option
			category = "Sweet and fruity strawberry delight" -- Category or description shown in the selection UI
		},

		["vanilla"] = {
			label = "Vanilla", -- Display name shown in UI
			itemname = "eliquid_box_vanilla", -- Inventory item required for this option
			image = "eliquid_box_vanilla.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_vanilla", -- Object model used for this option
			category = "Soft and creamy vanilla aroma" -- Category or description shown in the selection UI
		},

		["watermelon"] = {
			label = "Watermelon", -- Display name shown in UI
			itemname = "eliquid_box_watermelon", -- Inventory item required for this option
			image = "eliquid_box_watermelon.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_eliquid_flask_watermelon", -- Object model used for this option
			category = "Light and juicy summer watermelon" -- Category or description shown in the selection UI
		}
	},

    ["bong"] = {
		["og_kush"] = {
			label = "OG Kush", -- Display name shown in UI
			itemname = "weed_og_kush", -- Inventory item required for this option
			image = "weed_og_kush.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_og", -- Object model used for this option
			category = "Strong classic strain with earthy aroma" -- Category or description shown in the selection UI
		},

		["purple_haze"] = {
			label = "Purple Haze", -- Display name shown in UI
			itemname = "weed_purple_haze", -- Inventory item required for this option
			image = "weed_purple_haze.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_purple", -- Object model used for this option
			category = "Sweet aromatic strain with smooth smoke" -- Category or description shown in the selection UI
		},

		["amnesia_haze"] = {
			label = "Amnesia Haze", -- Display name shown in UI
			itemname = "weed_amnesia_haze", -- Inventory item required for this option
			image = "weed_amnesia_haze.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_haze", -- Object model used for this option
			category = "Citrus-heavy strain with strong kick" -- Category or description shown in the selection UI
		},

		["white_widow"] = {
			label = "White Widow", -- Display name shown in UI
			itemname = "weed_white_widow", -- Inventory item required for this option
			image = "weed_white_widow.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_white", -- Object model used for this option
			category = "Balanced hybrid with dense smoke" -- Category or description shown in the selection UI
		}
    },

    ["joint"] = {
		["og_kush"] = {
			label = "OG Kush", -- Display name shown in UI
			itemname = "weed_og_kush", -- Inventory item required for this option
			itemnamecrafted = "joint_og_kush", -- Crafted inventory item output
			image = "weed_og_kush.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_og", -- Object model used for this option
			category = "Strong classic strain with earthy aroma" -- Category or description shown in the selection UI
		},

		["purple_haze"] = {
			label = "Purple Haze", -- Display name shown in UI
			itemname = "weed_purple_haze", -- Inventory item required for this option
			itemnamecrafted = "joint_purple_haze", -- Crafted inventory item output
			image = "weed_purple_haze.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_purple", -- Object model used for this option
			category = "Sweet aromatic strain with smooth smoke" -- Category or description shown in the selection UI
		},

		["amnesia_haze"] = {
			label = "Amnesia Haze", -- Display name shown in UI
			itemname = "weed_amnesia_haze", -- Inventory item required for this option
			itemnamecrafted = "joint_amnesia_haze", -- Crafted inventory item output
			image = "weed_amnesia_haze.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_haze", -- Object model used for this option
			category = "Citrus-heavy strain with strong kick" -- Category or description shown in the selection UI
		},

		["white_widow"] = {
			label = "White Widow", -- Display name shown in UI
			itemname = "weed_white_widow", -- Inventory item required for this option
			itemnamecrafted = "joint_white_widow", -- Crafted inventory item output
			image = "weed_white_widow.png", -- Image file used in the UI
			object = "rtx_sempre_smoking_weed_white", -- Object model used for this option
			category = "Balanced hybrid with dense smoke" -- Category or description shown in the selection UI
		}
    },

    ["shisha"] = {
        ["apple"] = {
            label = "Apple", -- Display name shown in UI
            itemname = "shisha_tobacco_apple", -- Inventory item required for this option
            category = "classic" -- Category or description shown in the selection UI
        },

        ["blueberry"] = {
            label = "Blueberry", -- Display name shown in UI
            itemname = "shisha_tobacco_blueberry", -- Inventory item required for this option
            category = "sweet" -- Category or description shown in the selection UI
        },

        ["lemon"] = {
            label = "Lemon", -- Display name shown in UI
            itemname = "shisha_tobacco_lemon", -- Inventory item required for this option
            category = "citrus" -- Category or description shown in the selection UI
        },

        ["mint"] = {
            label = "Mint", -- Display name shown in UI
            itemname = "shisha_tobacco_mint", -- Inventory item required for this option
            category = "fresh" -- Category or description shown in the selection UI
        },

        ["orange"] = {
            label = "Orange", -- Display name shown in UI
            itemname = "shisha_tobacco_orange", -- Inventory item required for this option
            category = "citrus" -- Category or description shown in the selection UI
        },

        ["strawberry"] = {
            label = "Strawberry", -- Display name shown in UI
            itemname = "shisha_tobacco_strawberry", -- Inventory item required for this option
            category = "sweet" -- Category or description shown in the selection UI
        },

        ["vanilla"] = {
            label = "Vanilla", -- Display name shown in UI
            itemname = "shisha_tobacco_vanilla", -- Inventory item required for this option
            category = "dessert" -- Category or description shown in the selection UI
        },

        ["watermelon"] = {
            label = "Watermelon", -- Display name shown in UI
            itemname = "shisha_tobacco_watermelon", -- Inventory item required for this option
            category = "refreshing" -- Category or description shown in the selection UI
        }
    }
}

Config.PackOpenRewards = {
    ["cigarette_redwood_pack"] = { -- Redwood cigarette pack reward
        item = 'cigarette_redwood', -- Item given when opened
        count = 20 -- Amount of items received
    },

    ["cigarette_debonair_pack"] = { -- Debonaire cigarette pack reward
        item = 'cigarette_debonair', -- Item given when opened
        count = 20 -- Amount of items received
    },

    ["cigar_estancia_pack"] = { -- Estancia cigar pack reward
        item = 'cigar_estancia', -- Item given when opened
        count = 5 -- Amount of items received
    },

    ["rolling_papers_pack"] = { -- Rolling papers pack reward
        item = 'rolling_paper', -- Item given when opened
        count = 20 -- Amount of items received
    }
}

Config.ProgressActions = { -- Progress bar actions and animations
    ["change_battery"] = {
        title = "Vape", -- Progress bar title
        label = "Changing battery...", -- Display name shown in UI
        icon = "fa-solid fa-battery-half", -- FontAwesome icon shown in UI
        time = 4000, -- Progress action duration in milliseconds
        canCancel = true, -- Allows the player to cancel this action
        animation = { -- Progress action animation settings
            enabled = true, -- Enables or disables this feature
            dict = "mp_arresting", -- Animation or particle dictionary name
            anim = "a_uncuff", -- Animation clip name
            flag = 49 -- Animation flag controlling playback behavior
        }
    },

    ["fill_water"] = {
        title = "Bong", -- Progress bar title
        label = "Changing water...", -- Display name shown in UI
        icon = "fa-solid fa-droplet", -- FontAwesome icon shown in UI
        time = 3500, -- Progress action duration in milliseconds
        canCancel = true, -- Allows the player to cancel this action
        animation = { -- Progress action animation settings
            enabled = true, -- Enables or disables this feature
            dict = "vapeliquid@rtx", -- Animation or particle dictionary name
            anim = "vapeliquid", -- Animation clip name
            flag = 49 -- Animation flag controlling playback behavior
        }
    },

    ["fill_bong"] = {
        title = "Bong", -- Progress bar title
        label = "Packing bong...", -- Display name shown in UI
        icon = "fa-solid fa-cannabis", -- FontAwesome icon shown in UI
        time = 3500, -- Progress action duration in milliseconds
        canCancel = true, -- Allows the player to cancel this action
        animation = { -- Progress action animation settings
            enabled = true, -- Enables or disables this feature
            dict = "mp_arresting", -- Animation or particle dictionary name
            anim = "a_uncuff", -- Animation clip name
            flag = 49 -- Animation flag controlling playback behavior
        }
    },

    ["fill_flavour"] = {
        title = "Vape", -- Progress bar title
        label = "Filling flavour...", -- Display name shown in UI
        icon = "fa-solid fa-bottle-droplet", -- FontAwesome icon shown in UI
        time = 4500, -- Progress action duration in milliseconds
        canCancel = true, -- Allows the player to cancel this action
        animation = { -- Progress action animation settings
            enabled = true, -- Enables or disables this feature
            dict = "vapeliquid@rtx", -- Animation or particle dictionary name
            anim = "vapeliquid", -- Animation clip name
            flag = 49 -- Animation flag controlling playback behavior
        }
    },

    ["craft_joint"] = {
        title = "Joint", -- Progress bar title
        label = "Rolling joint...", -- Display name shown in UI
        icon = "fa-solid fa-cannabis", -- FontAwesome icon shown in UI
        time = 5000, -- Progress action duration in milliseconds
        canCancel = true, -- Allows the player to cancel this action
        animation = { -- Progress action animation settings
            enabled = true, -- Enables or disables this feature
            dict = "mp_arresting", -- Animation or particle dictionary name
            anim = "a_uncuff", -- Animation clip name
            flag = 49 -- Animation flag controlling playback behavior
        }
    }
}

Config.AttachPresets = { -- Attachment presets for props, bones, offsets, and rotations
    ["cigarette_classic"] = {
        mainItem = { -- Main smoking prop attachment settings
            idleVariants = { -- Idle prop placement variants
                hand = { -- Hand attachment placement
                    bone = 57005, -- Ped bone index used for prop attachment
                    offset = vec3(0.118000, 0.046000, -0.001000), -- Position offset relative to the bone or prop
                    rotation = vec3(-70.849998, -75.650002, 5.800000) -- Rotation offset relative to the bone or prop
                },

                ear = { -- Ear attachment placement
                    bone = 31086, -- Ped bone index used for prop attachment
                    offset = vec3(0.056000, -0.038000, -0.073000), -- Position offset relative to the bone or prop
                    rotation = vec3(52.000000, -15.150000, -92.199997) -- Rotation offset relative to the bone or prop
                }
            },

            light = { -- Lighting animation or attachment settings
                bone = 31086, -- Ped bone index used for prop attachment
                offset = vec3(-0.015000, 0.119000, -0.002000), -- Position offset relative to the bone or prop
                rotation = vec3(0.000000, 0.000000, -53.950001) -- Rotation offset relative to the bone or prop
            },
			puffStyles = { -- Available puff animation styles
				[1] = {
					bone = 57005, -- Ped bone index used for prop attachment
					offset = vec3(0.171000, 0.017000, -0.009000), -- Position offset relative to the bone or prop
					rotation = vec3(9.300000, 95.150002, -3.650000) -- Rotation offset relative to the bone or prop
				},

				[2] = {
					bone = 6286, -- Ped bone index used for prop attachment
					offset = vec3(0.0929, 0.0662, -0.0382), -- Position offset relative to the bone or prop
					rotation = vec3(0.0, 0.0, 90.0) -- Rotation offset relative to the bone or prop
				}
			},
        }, 
        secondaryItem = { -- Secondary prop attachment settings
            enabled = true, -- Enables or disables this feature
            model = "p_cs_lighter_01", -- Secondary prop model name
            phase = "light", -- Action phase where this secondary item is shown

            light = { -- Lighting animation or attachment settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.123000, 0.018000, -0.019000), -- Position offset relative to the bone or prop
                rotation = vec3(-63.650002, 16.400000, -26.250000) -- Rotation offset relative to the bone or prop
            }
        }
    },
    ["cigar"] = {
        mainItem = { -- Main smoking prop attachment settings
            idleVariants = { -- Idle prop placement variants
                hand = { -- Hand attachment placement
                    bone = 57005, -- Ped bone index used for prop attachment
                    offset = vec3(0.157000, 0.048000, 0.001000), -- Position offset relative to the bone or prop
                    rotation = vec3(45.799999, 156.000000, 70.650002) -- Rotation offset relative to the bone or prop
                },

                ear = { -- Ear attachment placement
                    bone = 31086, -- Ped bone index used for prop attachment
                    offset = vec3(0.072000, 0.038000, -0.085000), -- Position offset relative to the bone or prop
                    rotation = vec3(52.000000, -15.150000, -92.199997) -- Rotation offset relative to the bone or prop
                }
            },

            light = { -- Lighting animation or attachment settings
                bone = 31086, -- Ped bone index used for prop attachment
                offset = vec3(-0.000000, 0.091000, -0.003000), -- Position offset relative to the bone or prop
                rotation = vec3(16.049999, 0.000000, 117.900002) -- Rotation offset relative to the bone or prop
            },
			puffStyles = { -- Available puff animation styles
				[1] = {
					bone = 57005, -- Ped bone index used for prop attachment
					offset = vec3(0.161000, 0.026000, -0.019000), -- Position offset relative to the bone or prop
					rotation = vec3(9.200000, 261.500000, 51.150002), -- Rotation offset relative to the bone or prop
				},
				[2] = {
					bone = 31086, -- Ped bone index used for prop attachment
					offset = vec3(0.002000, 0.086000, 0.000000), -- Position offset relative to the bone or prop
					rotation = vec3(0.000000, 0.000000, 112.050003), -- Rotation offset relative to the bone or prop
				},
			},			
        },
        secondaryItem = { -- Secondary prop attachment settings
            enabled = true, -- Enables or disables this feature
            model = "p_cs_lighter_01", -- Secondary prop model name
            phase = "light", -- Action phase where this secondary item is shown

            light = { -- Lighting animation or attachment settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.123000, 0.018000, -0.019000), -- Position offset relative to the bone or prop
                rotation = vec3(-63.650002, 16.400000, -26.250000) -- Rotation offset relative to the bone or prop
            }
        }
    },	
    ["joint"] = {
        mainItem = { -- Main smoking prop attachment settings
            idleVariants = { -- Idle prop placement variants
                hand = { -- Hand attachment placement
                    bone = 57005, -- Ped bone index used for prop attachment
                    offset = vec3(0.118000, 0.046000, -0.001000), -- Position offset relative to the bone or prop
                    rotation = vec3(-70.849998, -75.650002, 5.800000) -- Rotation offset relative to the bone or prop
                },

                ear = { -- Ear attachment placement
                    bone = 31086, -- Ped bone index used for prop attachment
                    offset = vec3(0.056000, -0.038000, -0.073000), -- Position offset relative to the bone or prop
                    rotation = vec3(52.000000, -15.150000, -92.199997) -- Rotation offset relative to the bone or prop
                }
            },

            light = { -- Lighting animation or attachment settings
                bone = 31086, -- Ped bone index used for prop attachment
                offset = vec3(-0.017000, 0.126000, -0.002000), -- Position offset relative to the bone or prop
                rotation = vec3(1.500000, 0.000000, -67.800003) -- Rotation offset relative to the bone or prop
            },

			puffStyles = { -- Available puff animation styles
				[1] = {
					bone = 57005, -- Ped bone index used for prop attachment
					offset = vec3(0.171000, 0.017000, -0.009000), -- Position offset relative to the bone or prop
					rotation = vec3(9.300000, 95.150002, -3.650000), -- Rotation offset relative to the bone or prop
				},
				[2] = {
					bone = 31086, -- Ped bone index used for prop attachment
					offset = vec3(-0.019000, 0.130000, -0.004000), -- Position offset relative to the bone or prop
					rotation = vec3(22.400000, 0.000000, -56.000000), -- Rotation offset relative to the bone or prop
				},
			},				
        },
        secondaryItem = { -- Secondary prop attachment settings
            enabled = true, -- Enables or disables this feature
            model = "p_cs_lighter_01", -- Secondary prop model name
            phase = "light", -- Action phase where this secondary item is shown

            light = { -- Lighting animation or attachment settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.123000, 0.018000, -0.019000), -- Position offset relative to the bone or prop
                rotation = vec3(-63.650002, 16.400000, -26.250000) -- Rotation offset relative to the bone or prop
            }
        }
    },	
    ["vape_pen_a"] = {
        mainItem = { -- Main smoking prop attachment settings
            idle = { -- Idle animation or attachment settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.139000, 0.038000, -0.021000), -- Position offset relative to the bone or prop
                rotation = vec3(-80.449997, 0.000000, -3.700001) -- Rotation offset relative to the bone or prop
            },
            progress = { -- Progress action attachment settings
                fillFlavour = { -- Attachment used while filling vape flavour
                    bone = 57005, -- Ped bone index used for prop attachment
                    offset = vec3(0.116000, 0.059000, -0.049000), -- Position offset relative to the bone or prop
                    rotation = vec3(310.250000, 50.700001, 64.949997), -- Rotation offset relative to the bone or prop
                },
            },
            puff = { -- Puff action settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.110000, 0.024000, -0.022000), -- Position offset relative to the bone or prop
                rotation = vec3(-70.900002, 6.400000, -24.799990) -- Rotation offset relative to the bone or prop
            }
        },
        secondaryItem = { -- Secondary prop attachment settings
            enabled = false, -- Enables or disables this feature
            progress = { -- Progress action attachment settings
                fillFlavour = { -- Attachment used while filling vape flavour
                    bone = 18905, -- Ped bone index used for prop attachment
                    offset = vec3(0.151000, 0.010000, 0.053000), -- Position offset relative to the bone or prop
                    rotation = vec3(-1.600000, -4.699998, -4.850000), -- Rotation offset relative to the bone or prop
                },
            },	
        }
    },

    ["vape_pen_b"] = {
        mainItem = { -- Main smoking prop attachment settings
            idle = { -- Idle animation or attachment settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.093000, -0.031000, -0.038000), -- Position offset relative to the bone or prop
                rotation = vec3(-59.150002, 23.400000, -0.950000) -- Rotation offset relative to the bone or prop
            },
            progress = { -- Progress action attachment settings
                fillFlavour = { -- Attachment used while filling vape flavour
                    bone = 57005, -- Ped bone index used for prop attachment
                    offset = vec3(0.114000, -0.010000, -0.071000), -- Position offset relative to the bone or prop
                    rotation = vec3(-55.349998, 52.150002, 66.849998), -- Rotation offset relative to the bone or prop
                },
            },
            puff = { -- Puff action settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.068000, -0.029000, -0.027000), -- Position offset relative to the bone or prop
                rotation = vec3(-20.450001, 76.900002, 53.250000) -- Rotation offset relative to the bone or prop
            }
        },

        secondaryItem = { -- Secondary prop attachment settings
            enabled = false, -- Enables or disables this feature
            progress = { -- Progress action attachment settings
                fillFlavour = { -- Attachment used while filling vape flavour
                    bone = 18905, -- Ped bone index used for prop attachment
                    offset = vec3(0.151000, 0.010000, 0.053000), -- Position offset relative to the bone or prop
                    rotation = vec3(-12.600000, -4.699998, -4.850000), -- Rotation offset relative to the bone or prop
                },
            },				
        }
    },
    ["bong_classic"] = {
        mainItem = { -- Main smoking prop attachment settings
            idle = { -- Idle animation or attachment settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.120000, -0.205000, -0.116000), -- Position offset relative to the bone or prop
                rotation = vec3(-29.449997, 64.199997, 71.69999) -- Rotation offset relative to the bone or prop
            },
            progress = { -- Progress action attachment settings
                fillWater = { -- Attachment used while filling water
                    bone = 57005, -- Ped bone index used for prop attachment
                    offset = vec3(0.167000, -0.302000, -0.158000), -- Position offset relative to the bone or prop
                    rotation = vec3(21.549999, 69.650002, 107.250000), -- Rotation offset relative to the bone or prop
                },
            },
            puff = { -- Puff action settings
                bone = 57005, -- Ped bone index used for prop attachment
                offset = vec3(0.060000, -0.205000, -0.116000), -- Position offset relative to the bone or prop
                rotation = vec3(-29.449997, 64.199997, 71.69999) -- Rotation offset relative to the bone or prop
            }
        },

        secondaryItem = { -- Secondary prop attachment settings
            enabled = true, -- Enables or disables this feature
            model = "p_cs_lighter_01", -- Secondary prop model name
            phase = "puff", -- Action phase where this secondary item is shown

            idle = { -- Idle animation or attachment settings
                bone = 18905, -- Ped bone index used for prop attachment
                offset = vec3(0.139000, 0.007000, 0.027000), -- Position offset relative to the bone or prop
                rotation = vec3(13.950000, 90.400002, 56.299995) -- Rotation offset relative to the bone or prop
            },
            progress = { -- Progress action attachment settings
                fillWater = { -- Attachment used while filling water
                    bone = 18905, -- Ped bone index used for prop attachment
                    offset = vec3(0.141000, 0.014000, -0.006000), -- Position offset relative to the bone or prop
                    rotation = vec3(-1.850000, -9.850000, 10.400000), -- Rotation offset relative to the bone or prop
                },
            },	
            puff = { -- Puff action settings
                bone = 18905, -- Ped bone index used for prop attachment
                offset = vec3(0.139000, 0.007000, 0.027000), -- Position offset relative to the bone or prop
                rotation = vec3(13.950000, 90.400002, 56.299995) -- Rotation offset relative to the bone or prop
            }
        }
    }
}

 Config.SmokingVariants = { -- Configured usable smoking item variants
    ["cigarette_redwood"] = {
        item = "cigarette_redwood", -- Inventory item name
        type = "cigarette", -- Internal item type identifier
        label = "Cigarette", -- Display name shown in UI
        brand = "Redwood", -- Brand name shown for this variant
        image = "cigarette.png", -- Image file used in the UI
        prop = "prop_cs_ciggy_01b", -- Prop model spawned for this variant
        attachPreset = "cigarette_classic" -- Attachment preset used for this prop
    },

    ["cigarette_debonair"] = {
        item = "cigarette_debonair", -- Inventory item name
        type = "cigarette", -- Internal item type identifier
        label = "Cigarette", -- Display name shown in UI
        brand = "Debonaire", -- Brand name shown for this variant
        image = "cigarette.png", -- Image file used in the UI
        prop = "prop_cs_ciggy_01b", -- Prop model spawned for this variant
        attachPreset = "cigarette_classic" -- Attachment preset used for this prop
    },

    ["cigar_estancia"] = {
        item = "cigar_estancia", -- Inventory item name
        type = "cigar", -- Internal item type identifier
        label = "Cigar", -- Display name shown in UI
        brand = "Estancia", -- Brand name shown for this variant
        image = "cigar.png", -- Image file used in the UI
        prop = "prop_cigar_03", -- Prop model spawned for this variant
        attachPreset = "cigar" -- Attachment preset used for this prop
    },

    ["joint_og_kush"] = {
        item = "joint_og_kush", -- Inventory item name
        type = "joint", -- Internal item type identifier
        label = "Joint", -- Display name shown in UI
        image = "joint.png", -- Image file used in the UI
        prop = "p_cs_joint_01", -- Prop model spawned for this variant
        attachPreset = "joint" -- Attachment preset used for this prop
    },

    ["joint_purple_haze"] = {
        item = "joint_purple_haze", -- Inventory item name
        type = "joint", -- Internal item type identifier
        label = "Joint", -- Display name shown in UI
        image = "joint.png", -- Image file used in the UI
        prop = "p_cs_joint_01", -- Prop model spawned for this variant
        attachPreset = "joint" -- Attachment preset used for this prop
    },

    ["joint_amnesia_haze"] = {
        item = "joint_amnesia_haze", -- Inventory item name
        type = "joint", -- Internal item type identifier
        label = "Joint", -- Display name shown in UI
        image = "joint.png", -- Image file used in the UI
        prop = "p_cs_joint_01", -- Prop model spawned for this variant
        attachPreset = "joint" -- Attachment preset used for this prop
    },

    ["joint_white_widow"] = {
        item = "joint_white_widow", -- Inventory item name
        type = "joint", -- Internal item type identifier
        label = "Jointt", -- Display name shown in UI
        image = "joint.png", -- Image file used in the UI
        prop = "p_cs_joint_01", -- Prop model spawned for this variant
        attachPreset = "joint" -- Attachment preset used for this prop
    },

	["vape_1_red"] = {
		item = "vape_1_red", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_1_red.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig", -- Prop model spawned for this variant
		attachPreset = "vape_pen_b", -- Attachment preset used for this prop
		tintValue = 1 -- Object tint or color variation value
	},

	["vape_1_blue"] = {
		item = "vape_1_blue", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_1_blue.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig", -- Prop model spawned for this variant
		attachPreset = "vape_pen_b", -- Attachment preset used for this prop
		tintValue = 0 -- Object tint or color variation value
	},

	["vape_1_pink"] = {
		item = "vape_1_pink", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_1_pink.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig", -- Prop model spawned for this variant
		attachPreset = "vape_pen_b", -- Attachment preset used for this prop
		tintValue = 2 -- Object tint or color variation value
	},

	["vape_1_turquoise"] = {
		item = "vape_1_turquoise", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_1_turquoise.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig", -- Prop model spawned for this variant
		attachPreset = "vape_pen_b", -- Attachment preset used for this prop
		tintValue = 3 -- Object tint or color variation value
	},

	["vape_1_yellow"] = {
		item = "vape_1_yellow", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_1_yellow.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig", -- Prop model spawned for this variant
		attachPreset = "vape_pen_b", -- Attachment preset used for this prop
		tintValue = 4 -- Object tint or color variation value
	},

	["vape_1_white"] = {
		item = "vape_1_white", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_1_white.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig", -- Prop model spawned for this variant
		attachPreset = "vape_pen_b", -- Attachment preset used for this prop
		tintValue = 5 -- Object tint or color variation value
	},

	["vape_2_red"] = {
		item = "vape_2_red", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_2_red.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig_2", -- Prop model spawned for this variant
		attachPreset = "vape_pen_a", -- Attachment preset used for this prop
		tintValue = 1 -- Object tint or color variation value
	},

	["vape_2_blue"] = {
		item = "vape_2_blue", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_2_blue.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig_2", -- Prop model spawned for this variant
		attachPreset = "vape_pen_a", -- Attachment preset used for this prop
		tintValue = 0 -- Object tint or color variation value
	},

	["vape_2_pink"] = {
		item = "vape_2_pink", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_2_pink.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig_2", -- Prop model spawned for this variant
		attachPreset = "vape_pen_a", -- Attachment preset used for this prop
		tintValue = 2 -- Object tint or color variation value
	},

	["vape_2_turquoise"] = {
		item = "vape_2_turquoise", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_2_turquoise.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig_2", -- Prop model spawned for this variant
		attachPreset = "vape_pen_a", -- Attachment preset used for this prop
		tintValue = 3 -- Object tint or color variation value
	},

	["vape_2_yellow"] = {
		item = "vape_2_yellow", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_2_yellow.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig_2", -- Prop model spawned for this variant
		attachPreset = "vape_pen_a", -- Attachment preset used for this prop
		tintValue = 4 -- Object tint or color variation value
	},

	["vape_2_white"] = {
		item = "vape_2_white", -- Inventory item name
		type = "vape", -- Internal item type identifier
		label = "Vape", -- Display name shown in UI
		image = "vape_2_white.png", -- Image file used in the UI
		prop = "rtx_sempre_smoking_e_cig_2", -- Prop model spawned for this variant
		attachPreset = "vape_pen_a", -- Attachment preset used for this prop
		tintValue = 5 -- Object tint or color variation value
	},
    ["bong"] = {
        item = "bong", -- Inventory item name
        type = "bong", -- Internal item type identifier
        label = "Bong", -- Display name shown in UI
        image = "bong.png", -- Image file used in the UI
        prop = "prop_sh_bong_01", -- Prop model spawned for this variant
        attachPreset = "bong_classic" -- Attachment preset used for this prop
    },
}

Config.Items = { -- Main smoking item behavior configuration
    ["cigarette"] = {
        label = "Cigarette", -- Display name shown in UI
        supportsLighting = true, -- Defines whether this item must be lit before use

        nui = { -- NUI display settings
            type = "cigarette", -- Internal item type identifier
            emptyText = "Not selected" -- Text shown when no selection is selected
        },

        requirements = { -- Usage requirement settings
            requireSelection = false -- Requires player to select a refill, flavor, or strain
        },

        stats = { -- Item stat definitions
            durability = { -- Durability stat configuration
                label = "Durability", -- Display name shown in UI
                minRequiredToUse = 1.0 -- Minimum stat value required to use the item
            }
        },

        consumption = { -- Consumption settings while using the item
            puff = { -- Puff action settings
                duration = {
                    minHoldMs = 150, -- Minimum hold duration in milliseconds
                    maxHoldMs = 3500 -- Maximum hold duration in milliseconds
                },

                stats = { -- Item stat definitions
                    durability = { -- Durability stat configuration
                        perSecond = 7.0, -- Amount consumed per second while using the item
                        min = 0.5, -- Minimum amount consumed per use
                        max = 8.0 -- Maximum amount consumed per use
                    }
                }
            }
        },

        animations = { -- Animation settings for this item
            idle = { -- Idle animation or attachment settings
                enabled = false, -- Enables or disables this feature
                dict = "amb@world_human_smoking_fat@male@male_b@idle_a", -- Animation or particle dictionary name
                anim = "idle_a", -- Animation clip name
                flag = 49 -- Animation flag controlling playback behavior
            },

            light = { -- Lighting animation or attachment settings
                enabled = true, -- Enables or disables this feature
                dict = "ciglightning@rtx", -- Animation or particle dictionary name
                anim = "ciglightning_clip", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 2500 -- Animation or effect duration in milliseconds
            },

            puffStyles = { -- Available puff animation styles
				[1] = {
					enabled = true, -- Enables or disables this feature
					dict = "cigsmoke_2@rtx", -- Animation or particle dictionary name
					anim = "cigsmoke_2_clip", -- Animation clip name
					flag = 49, -- Animation flag controlling playback behavior
				},

				[2] = {
					enabled = true, -- Enables or disables this feature
					dict = "cigsmoke@rtx", -- Animation or particle dictionary name
					anim = "cigsmoke_clip", -- Animation clip name
					flag = 49, -- Animation flag controlling playback behavior
				},
			},
            forceRelease = { -- Forced release or cough animation settings
                enabled = true, -- Enables or disables this feature
                dict = "timetable@gardener@smoking_joint", -- Animation or particle dictionary name
                anim = "idle_cough", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 1500 -- Animation or effect duration in milliseconds
            },
        },

        particles = { -- Particle effect settings
			
			idleMain = { -- Idle smoke particle settings
				enabled = true, -- Enables or disables this feature
				attachTo = "mainItem", -- Attachment target used for particle effects
				ptfxDict = "core", -- Particle effect dictionary name
				ptfxName = "ent_anim_cig_smoke", -- Particle effect name
				scale = 0.8, -- Particle or effect scale
				offset = vec3(-0.070, 0.0, 0.00), -- Position offset relative to the bone or prop
				rotation = vec3(0.0, 0.0, 90.0), -- Rotation offset relative to the bone or prop
			},
            lightSecondary = { -- Lighter flame particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "secondaryItem", -- Attachment target used for particle effects
                ptfxDict = "cut_family1", -- Particle effect dictionary name
                ptfxName = "cs_mich1_lighter_flame", -- Particle effect name
                scale = 0.8, -- Particle or effect scale
                offset = vec3(-0.005, 0.0, 0.054), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 80.0) -- Rotation offset relative to the bone or prop
            },

            exhale = { -- Exhale smoke particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "mouth", -- Attachment target used for particle effects
                ptfxDict = "core", -- Particle effect dictionary name
                ptfxName = "exp_grd_bzgas_smoke", -- Particle effect name
                scale = 0.22, -- Particle or effect scale
                mouthBone = 47495, -- Mouth bone index used for exhale particles
                offset = vec3(0.12, 0.0, 0.0), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 0.0), -- Rotation offset relative to the bone or prop
                minHoldMs = 200, -- Minimum hold duration in milliseconds
                maxHoldMs = 3000, -- Maximum hold duration in milliseconds
                minDurationMs = 250, -- Minimum particle duration in milliseconds
                maxDurationMs = 1000 -- Maximum particle duration in milliseconds
            }
        }
    },
    ["joint"] = {
        label = "Joint", -- Display name shown in UI
        supportsLighting = true, -- Defines whether this item must be lit before use

        nui = { -- NUI display settings
            type = "joint", -- Internal item type identifier
            emptyText = "Not selected" -- Text shown when no selection is selected
        },

        requirements = { -- Usage requirement settings
            requireSelection = false -- Requires player to select a refill, flavor, or strain
        },

        stats = { -- Item stat definitions
            durability = { -- Durability stat configuration
                label = "Durability", -- Display name shown in UI
                minRequiredToUse = 1.0 -- Minimum stat value required to use the item
            }
        },

        consumption = { -- Consumption settings while using the item
            puff = { -- Puff action settings
                duration = {
                    minHoldMs = 150, -- Minimum hold duration in milliseconds
                    maxHoldMs = 3500 -- Maximum hold duration in milliseconds
                },

                stats = { -- Item stat definitions
                    durability = { -- Durability stat configuration
                        perSecond = 7.0, -- Amount consumed per second while using the item
                        min = 0.5, -- Minimum amount consumed per use
                        max = 8.0 -- Maximum amount consumed per use
                    }
                }
            }
        },

        animations = { -- Animation settings for this item
            idle = { -- Idle animation or attachment settings
                enabled = false, -- Enables or disables this feature
                dict = "amb@world_human_smoking_fat@male@male_b@idle_a", -- Animation or particle dictionary name
                anim = "idle_a", -- Animation clip name
                flag = 49 -- Animation flag controlling playback behavior
            },

            light = { -- Lighting animation or attachment settings
                enabled = true, -- Enables or disables this feature
                dict = "ciglightning@rtx", -- Animation or particle dictionary name
                anim = "ciglightning_clip", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 2500 -- Animation or effect duration in milliseconds
            },

            puffStyles = { -- Available puff animation styles
				[1] = {
					enabled = true, -- Enables or disables this feature
					dict = "cigsmoke_2@rtx", -- Animation or particle dictionary name
					anim = "cigsmoke_2_clip", -- Animation clip name
					flag = 49, -- Animation flag controlling playback behavior
				},

				[2] = {
					enabled = true, -- Enables or disables this feature
					dict = "cigsmoke@rtx", -- Animation or particle dictionary name
					anim = "cigsmoke_clip", -- Animation clip name
					flag = 49, -- Animation flag controlling playback behavior
				},
			},

            forceRelease = { -- Forced release or cough animation settings
                enabled = true, -- Enables or disables this feature
                dict = "timetable@gardener@smoking_joint", -- Animation or particle dictionary name
                anim = "idle_cough", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 1500 -- Animation or effect duration in milliseconds
            }
        },

        particles = { -- Particle effect settings
            idleMain = { -- Idle smoke particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "mainItem", -- Attachment target used for particle effects
                ptfxDict = "core", -- Particle effect dictionary name
                ptfxName = "ent_anim_cig_smoke", -- Particle effect name
                scale = 0.15, -- Particle or effect scale
                offset = vec3(-0.09, 0.0, 0.00), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 90.0) -- Rotation offset relative to the bone or prop
            },

            lightSecondary = { -- Lighter flame particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "secondaryItem", -- Attachment target used for particle effects
                ptfxDict = "cut_family1", -- Particle effect dictionary name
                ptfxName = "cs_mich1_lighter_flame", -- Particle effect name
                scale = 0.8, -- Particle or effect scale
                offset = vec3(-0.005, 0.0, 0.054), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 80.0) -- Rotation offset relative to the bone or prop
            },

            exhale = { -- Exhale smoke particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "mouth", -- Attachment target used for particle effects
                ptfxDict = "core", -- Particle effect dictionary name
                ptfxName = "exp_grd_bzgas_smoke", -- Particle effect name
                scale = 0.22, -- Particle or effect scale
                mouthBone = 47495, -- Mouth bone index used for exhale particles
                offset = vec3(0.12, 0.0, 0.0), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 0.0), -- Rotation offset relative to the bone or prop
                minHoldMs = 200, -- Minimum hold duration in milliseconds
                maxHoldMs = 3000, -- Maximum hold duration in milliseconds
                minDurationMs = 250, -- Minimum particle duration in milliseconds
                maxDurationMs = 1000 -- Maximum particle duration in milliseconds
            }
        }
    },
    ["cigar"] = {
        label = "Cigar", -- Display name shown in UI
        supportsLighting = true, -- Defines whether this item must be lit before use

        nui = { -- NUI display settings
            type = "cigar", -- Internal item type identifier
            emptyText = "Not selected" -- Text shown when no selection is selected
        },

        requirements = { -- Usage requirement settings
            requireSelection = false -- Requires player to select a refill, flavor, or strain
        },

        stats = { -- Item stat definitions
            durability = { -- Durability stat configuration
                label = "Durability", -- Display name shown in UI
                minRequiredToUse = 1.0 -- Minimum stat value required to use the item
            }
        },

        consumption = { -- Consumption settings while using the item
            puff = { -- Puff action settings
                duration = {
                    minHoldMs = 150, -- Minimum hold duration in milliseconds
                    maxHoldMs = 3500 -- Maximum hold duration in milliseconds
                },

                stats = { -- Item stat definitions
                    durability = { -- Durability stat configuration
                        perSecond = 7.0, -- Amount consumed per second while using the item
                        min = 0.5, -- Minimum amount consumed per use
                        max = 8.0 -- Maximum amount consumed per use
                    }
                }
            }
        },

        animations = { -- Animation settings for this item
            idle = { -- Idle animation or attachment settings
                enabled = false, -- Enables or disables this feature
                dict = "amb@world_human_smoking_fat@male@male_b@idle_a", -- Animation or particle dictionary name
                anim = "idle_a", -- Animation clip name
                flag = 49 -- Animation flag controlling playback behavior
            },

            light = { -- Lighting animation or attachment settings
                enabled = true, -- Enables or disables this feature
                dict = "ciglightning@rtx", -- Animation or particle dictionary name
                anim = "ciglightning_clip", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 2500 -- Animation or effect duration in milliseconds
            },

            puffStyles = { -- Available puff animation styles
				[1] = {
					enabled = true, -- Enables or disables this feature
					dict = "cigsmoke_2@rtx", -- Animation or particle dictionary name
					anim = "cigsmoke_2_clip", -- Animation clip name
					flag = 49, -- Animation flag controlling playback behavior
				},

				[2] = {
					enabled = true, -- Enables or disables this feature
					dict = "cigsmoke@rtx", -- Animation or particle dictionary name
					anim = "cigsmoke_clip", -- Animation clip name
					flag = 49, -- Animation flag controlling playback behavior
				},
			},

            forceRelease = { -- Forced release or cough animation settings
                enabled = true, -- Enables or disables this feature
                dict = "timetable@gardener@smoking_joint", -- Animation or particle dictionary name
                anim = "idle_cough", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 1500 -- Animation or effect duration in milliseconds
            }
        },
        particles = { -- Particle effect settings
            idleMain = { -- Idle smoke particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "mainItem", -- Attachment target used for particle effects
                ptfxDict = "core", -- Particle effect dictionary name
                ptfxName = "ent_anim_cig_smoke", -- Particle effect name
                scale = 0.8, -- Particle or effect scale
                offset = vec3(0.115, 0.0, 0.00), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 90.0), -- Rotation offset relative to the bone or prop
            },

            lightSecondary = { -- Lighter flame particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "secondaryItem", -- Attachment target used for particle effects
                ptfxDict = "cut_family1", -- Particle effect dictionary name
                ptfxName = "cs_mich1_lighter_flame", -- Particle effect name
                scale = 0.8, -- Particle or effect scale
                offset = vec3(-0.005, 0.0, 0.054), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 80.0) -- Rotation offset relative to the bone or prop
            },

            exhale = { -- Exhale smoke particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "mouth", -- Attachment target used for particle effects
                ptfxDict = "core", -- Particle effect dictionary name
                ptfxName = "exp_grd_bzgas_smoke", -- Particle effect name
                scale = 0.22, -- Particle or effect scale
                mouthBone = 47495, -- Mouth bone index used for exhale particles
                offset = vec3(0.12, 0.0, 0.0), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 0.0), -- Rotation offset relative to the bone or prop
                minHoldMs = 200, -- Minimum hold duration in milliseconds
                maxHoldMs = 3000, -- Maximum hold duration in milliseconds
                minDurationMs = 250, -- Minimum particle duration in milliseconds
                maxDurationMs = 1000 -- Maximum particle duration in milliseconds
            }
        }
    },	
    ["vape"] = {
        label = "Vape", -- Display name shown in UI
        supportsLighting = false, -- Defines whether this item must be lit before use

        nui = { -- NUI display settings
            type = "vape", -- Internal item type identifier
            emptyText = "Not selected" -- Text shown when no selection is selected
        },

        requirements = { -- Usage requirement settings
            requireSelection = true -- Requires player to select a refill, flavor, or strain
        },

        stats = { -- Item stat definitions
            fill = { -- Fill status configuration
                label = "Flavour Status", -- Display name shown in UI
                minRequiredToUse = 1.0 -- Minimum stat value required to use the item
            },

            battery = { -- Battery status configuration
                label = "Battery", -- Display name shown in UI
                minRequiredToUse = 1.0 -- Minimum stat value required to use the item
            }
        },

        consumption = { -- Consumption settings while using the item
            puff = { -- Puff action settings
                duration = {
                    minHoldMs = 150, -- Minimum hold duration in milliseconds
                    maxHoldMs = 5000 -- Maximum hold duration in milliseconds
                },

                stats = { -- Item stat definitions
                    fill = { -- Fill status configuration
                        perSecond = 5.0, -- Amount consumed per second while using the item
                        min = 0.25, -- Minimum amount consumed per use
                        max = 4.0 -- Maximum amount consumed per use
                    },

                    battery = { -- Battery status configuration
                        perSecond = 1.5, -- Amount consumed per second while using the item
                        min = 0.1, -- Minimum amount consumed per use
                        max = 1.5 -- Maximum amount consumed per use
                    }
                }
            }
        },

        animations = { -- Animation settings for this item
            idle = { -- Idle animation or attachment settings
                enabled = false, -- Enables or disables this feature
                dict = "", -- Animation or particle dictionary name
                anim = "", -- Animation clip name
                flag = 49 -- Animation flag controlling playback behavior
            },

            light = { -- Lighting animation or attachment settings
                enabled = false, -- Enables or disables this feature
                dict = "", -- Animation or particle dictionary name
                anim = "", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 0 -- Animation or effect duration in milliseconds
            },

            puff = { -- Puff action settings
                enabled = true, -- Enables or disables this feature
                dict = "shishaanimsmoke@rtx", -- Animation or particle dictionary name
                anim = "shishaanimsmoke", -- Animation clip name
                flag = 49 -- Animation flag controlling playback behavior
            },

            forceRelease = { -- Forced release or cough animation settings
                enabled = true, -- Enables or disables this feature
                dict = "timetable@gardener@smoking_joint", -- Animation or particle dictionary name
                anim = "idle_cough", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 1500 -- Animation or effect duration in milliseconds
            }
        },

        particles = { -- Particle effect settings
            exhale = { -- Exhale smoke particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "mouth", -- Attachment target used for particle effects
                ptfxDict = "core", -- Particle effect dictionary name
                ptfxName = "exp_grd_bzgas_smoke", -- Particle effect name
                scale = 0.55, -- Particle or effect scale
                mouthBone = 47495, -- Mouth bone index used for exhale particles
                offset = vec3(0.15, 0.0, 0.0), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 0.0), -- Rotation offset relative to the bone or prop
                minHoldMs = 300, -- Minimum hold duration in milliseconds
                maxHoldMs = 5000, -- Maximum hold duration in milliseconds
                minDurationMs = 500, -- Minimum particle duration in milliseconds
                maxDurationMs = 3000 -- Maximum particle duration in milliseconds
            }
        }
    },

    ["bong"] = {
        label = "Bong", -- Display name shown in UI
        supportsLighting = false, -- Defines whether this item must be lit before use

        nui = { -- NUI display settings
            type = "bong", -- Internal item type identifier
            emptyText = "Not selected" -- Text shown when no selection is selected
        },

        requirements = { -- Usage requirement settings
            requireSelection = true -- Requires player to select a refill, flavor, or strain
        },

        stats = { -- Item stat definitions
            fill = { -- Fill status configuration
                label = "Fill Status", -- Display name shown in UI
                minRequiredToUse = 1.0 -- Minimum stat value required to use the item
            },

            water = { -- Water status configuration
                label = "Water", -- Display name shown in UI
                minRequiredToUse = 1.0 -- Minimum stat value required to use the item
            }
        },

        consumption = { -- Consumption settings while using the item
            puff = { -- Puff action settings
                duration = {
                    minHoldMs = 200, -- Minimum hold duration in milliseconds
                    maxHoldMs = 5000 -- Maximum hold duration in milliseconds
                },

                stats = { -- Item stat definitions
                    fill = { -- Fill status configuration
                        perSecond = 4.0, -- Amount consumed per second while using the item
                        min = 0.25, -- Minimum amount consumed per use
                        max = 3.0 -- Maximum amount consumed per use
                    },

                    water = { -- Water status configuration
                        perSecond = 0.8, -- Amount consumed per second while using the item
                        min = 0.05, -- Minimum amount consumed per use
                        max = 0.8 -- Maximum amount consumed per use
                    }
                }
            }
        },

        animations = { -- Animation settings for this item
            idle = { -- Idle animation or attachment settings
                enabled = false, -- Enables or disables this feature
                dict = "", -- Animation or particle dictionary name
                anim = "", -- Animation clip name
                flag = 49 -- Animation flag controlling playback behavior
            },

            light = { -- Lighting animation or attachment settings
                enabled = false, -- Enables or disables this feature
                dict = "", -- Animation or particle dictionary name
                anim = "", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 0 -- Animation or effect duration in milliseconds
            },

            puff = { -- Puff action settings
                enabled = true, -- Enables or disables this feature
                dict = "bongosmoke@rtx", -- Animation or particle dictionary name
                anim = "bongosmoke", -- Animation clip name
                flag = 49 -- Animation flag controlling playback behavior
            },

            forceRelease = { -- Forced release or cough animation settings
                enabled = true, -- Enables or disables this feature
                dict = "timetable@gardener@smoking_joint", -- Animation or particle dictionary name
                anim = "idle_cough", -- Animation clip name
                flag = 49, -- Animation flag controlling playback behavior
                durationMs = 1500 -- Animation or effect duration in milliseconds
            }
        },

        particles = { -- Particle effect settings
            puffSecondary = { -- Puff flame particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "secondaryItem", -- Attachment target used for particle effects
                ptfxDict = "cut_family1", -- Particle effect dictionary name
                ptfxName = "cs_mich1_lighter_flame", -- Particle effect name
                scale = 0.8, -- Particle or effect scale
                offset = vec3(-0.005, 0.0, 0.054), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 80.0) -- Rotation offset relative to the bone or prop
            },

            exhale = { -- Exhale smoke particle settings
                enabled = true, -- Enables or disables this feature
                attachTo = "mouth", -- Attachment target used for particle effects
                ptfxDict = "core", -- Particle effect dictionary name
                ptfxName = "exp_grd_bzgas_smoke", -- Particle effect name
                scale = 0.45, -- Particle or effect scale
                mouthBone = 47495, -- Mouth bone index used for exhale particles
                offset = vec3(0.15, 0.0, 0.0), -- Position offset relative to the bone or prop
                rotation = vec3(0.0, 0.0, 0.0), -- Rotation offset relative to the bone or prop
                minHoldMs = 300, -- Minimum hold duration in milliseconds
                maxHoldMs = 5000, -- Maximum hold duration in milliseconds
                minDurationMs = 500, -- Minimum particle duration in milliseconds
                maxDurationMs = 3000 -- Maximum particle duration in milliseconds
            }
        }
    }
}

Config.HookahForceRelease = {
    enabled = true, -- Enable forced release / cough for hookah
    maxHoldMs = 3500, -- Maximum inhale hold time before cough starts
    dict = "timetable@gardener@smoking_joint", -- Cough animation dictionary
    anim = "idle_cough", -- Cough animation name
    flag = 49, -- Animation flag
    durationMs = 1500, -- Cough animation duration
    coughSound = true -- Play cough sound when forced release happens
}

Config.SmokeEffects = { -- Optional screen and movement effects triggered by smoking
    enabled = false, -- Enables or disables this feature

    triggerStage = "puff_end", -- puff_end / puff_start

    categories = { -- Effect trigger settings by item category
        ["joint"] = {
            enabled = true, -- Enables or disables this feature
            chance = 8, -- %
            effects = { "weed_relaxed", "weed_heavy" } -- Effects that can be randomly applied
        },

        ["bong"] = {
            enabled = true, -- Enables or disables this feature
            chance = 80, -- Percentage chance to trigger this effect
            effects = { "weed_relaxed", "weed_heavy", "weed_wobbly" } -- Effects that can be randomly applied
        },

        ["cigarette"] = {
            enabled = false, -- Enables or disables this feature
            chance = 0, -- Percentage chance to trigger this effect
            effects = {} -- No special effects are configured for this category
        },

        ["cigar"] = {
            enabled = false, -- Enables or disables this feature
            chance = 0, -- Percentage chance to trigger this effect
            effects = {} -- No special effects are configured for this category
        },

        ["vape"] = {
            enabled = false, -- Enables or disables this feature
            chance = 0, -- Percentage chance to trigger this effect
            effects = {} -- No special effects are configured for this category
        },
    },

    effects = { -- Effect definitions
        ["weed_relaxed"] = {
            label = "Relaxed High", -- Display name shown in UI
            durationMs = 30000, -- Animation or effect duration in milliseconds
            screenEffect = "ChopVision", -- GTA screen effect name
            timecycle = "spectator5", -- GTA timecycle modifier name
            movementClipset = "MOVE_M@DRUNK@VERYDRUNK", -- Movement clipset applied during the effect
            shake = 1.5, -- Camera shake intensity
            isDrunk = true, -- Applies drunk movement behavior when enabled
            motionBlur = false -- Enables motion blur during the effect
        },

        ["weed_heavy"] = {
            label = "Heavy High", -- Display name shown in UI
            durationMs = 30000, -- Animation or effect duration in milliseconds
            screenEffect = "DrugsMichaelAliensFight", -- GTA screen effect name
            timecycle = "spectator5", -- GTA timecycle modifier name
            movementClipset = "MOVE_M@DRUNK@VERYDRUNK", -- Movement clipset applied during the effect
            shake = 3.0, -- Camera shake intensity
            isDrunk = true, -- Applies drunk movement behavior when enabled
            motionBlur = false -- Enables motion blur during the effect
        },

        ["weed_wobbly"] = {
            label = "Wobbly High", -- Display name shown in UI
            durationMs = 30000, -- Animation or effect duration in milliseconds
            screenEffect = "HeistCelebPass", -- GTA screen effect name
            timecycle = "drug_wobbly", -- GTA timecycle modifier name
            movementClipset = "move_m@hobo@a", -- Movement clipset applied during the effect
            shake = 3.0, -- Camera shake intensity
            isDrunk = true, -- Applies drunk movement behavior when enabled
            motionBlur = false -- Enables motion blur during the effect
        }
    }
}

Config.ESXFramework = { -- ESX framework compatibility settings
	newversion = true, -- Set to true if you're using the newer ESX versions (prevents old SharedObject errors)
	getsharedobject = "esx:getSharedObject", -- Event name used to fetch ESX shared object (old ESX compatibility)
	resourcename = "es_extended" -- Name of your ESX resource folder
}

Config.QBCoreFrameworkResourceName = "qb-core" -- QBCore resource name (change if your core resource has a different folder name)

function Notify(notifytype, title, text) -- Sends a notification to the player
	exports["rtx_smoking"]:ShowNotify({
		title   = title, -- Notification title
		text    = text, -- Notification message text
		type    = notifytype, -- Notify type
		timeout = 5000 -- Notification display time in milliseconds
	})	
	--exports["rtx_notify"]:Notify("Smoking", text, 5000, notifytype) -- if you get error in this line its because you dont use our notify system buy it here https://rtx.tebex.io/package/5402098 or you can use some other notify system just replace this notify line with your notify system
end

```

</details>

***

## ITEMS SETUP

Go to the Items folder and install items based on your framework:

* QBCore / OX Inventory: Copy items into your items definition file
* ESX: Add the items into your item system based on your server setup

Below is a full list of all item names used by RTX Smoking.

<details>

<summary>All RTX Smoking item names</summary>

```lua
-- Hookahs
shisha_0
shisha_1
shisha_2
shisha_3
shisha_4
shisha_5

-- Hookah utilities
shisha_charcoal_box

-- Hookah tobacco
shisha_tobacco_apple
shisha_tobacco_blueberry
shisha_tobacco_lemon
shisha_tobacco_mint
shisha_tobacco_orange
shisha_tobacco_strawberry
shisha_tobacco_vanilla
shisha_tobacco_watermelon

-- E-liquids
eliquid_box_apple
eliquid_box_blueberry
eliquid_box_cherry
eliquid_box_ecola
eliquid_box_grape
eliquid_box_lemon
eliquid_box_mint
eliquid_box_orange
eliquid_box_peach
eliquid_box_strawberry
eliquid_box_vanilla
eliquid_box_watermelon

-- Vape devices
vape_1_red
vape_1_blue
vape_1_pink
vape_1_turquoise
vape_1_yellow
vape_1_white

vape_2_red
vape_2_blue
vape_2_pink
vape_2_turquoise
vape_2_yellow
vape_2_white

-- Vape utility
vape_battery

-- Weed
weed_og_kush
weed_purple_haze
weed_amnesia_haze
weed_white_widow

-- Joints
joint_og_kush
joint_purple_haze
joint_amnesia_haze
joint_white_widow

-- Rolling papers
rolling_papers_pack
rolling_paper

-- Cigarettes / cigars
cigarette_redwood_pack
cigarette_debonair_pack
cigar_estancia_pack

cigarette_redwood
cigarette_debonair
cigar_estancia

-- Smoking utilities
lighter
water
bong
```

</details>

***

## OPTIONAL – REMOVE MLO

If you do not want to use the included Smoke Shop MLO on your server, you can simply remove it from the resource.

Path: rtx\_smoking\_objects/stream/stream/MLO

Delete or remove the MLO folder from this path.

The smoking system will continue to work normally without the MLO.

**Coords**:

-663.6406 -887.6094 23.90407

***

## SMOKE SHOP MLO

The custom smoke shop MLO is included with the resource.

You can enable or disable the shop in the configuration.

If you do not want to use the included shop, you can add smoking items to any other shop system on your server.

***

## Shop Locations Setup

RTX Smoking includes ready-to-use shop examples for multiple frameworks and inventory systems, but you can also use any other shop system as long as the required items are properly added into the shop.

Supported systems:

```txt
OX-INVENTORY-SHOP
ESX-SHOPS
QB-SHOPS
```

***

### Shop Files Location

```txt
Smoking System/[Shop]
```

***

### Basic Setup

```txt
1. Go to:
   Smoking System/[Shop]

2. Choose the file matching your framework/shop system

3. Copy the example into your shop config/script

4. Restart your server
```

***

### Default Smoke Shop Location

<details>

<summary>Default smoke shop coordinates</summary>

```lua
vector3(-657.76, -885.73, 23.61)
```

</details>

***

### Recommended Smoke Shop Items

<details>

<summary>Recommended smoke shop item names</summary>

```lua
-- Utility
lighter
vape_battery

-- Rolling
rolling_papers_pack
rolling_paper

-- Cigarettes / cigars packs
cigarette_redwood_pack
cigarette_debonair_pack
cigar_estancia_pack

-- Bong
bong

-- E-Liquids
eliquid_box_apple
eliquid_box_blueberry
eliquid_box_cherry
eliquid_box_ecola
eliquid_box_grape
eliquid_box_lemon
eliquid_box_mint
eliquid_box_orange
eliquid_box_peach
eliquid_box_strawberry
eliquid_box_vanilla
eliquid_box_watermelon

-- Vapes 1
vape_1_red
vape_1_blue
vape_1_pink
vape_1_turquoise
vape_1_yellow
vape_1_white

-- Vapes 2
vape_2_red
vape_2_blue
vape_2_pink
vape_2_turquoise
vape_2_yellow
vape_2_white
```

</details>

***

### OX Inventory Example

<details>

<summary>OX Inventory shop setup</summary>

```txt
Use:
Smoking System/[Shop]/OX-INVENTORY-SHOP.lua
```

This file already includes:

```txt
- Ready-to-use items
- Correct item names
- Compatible shop structure
- Example prices
- Example locations
```

</details>

***

### Custom Shop Systems

RTX Smoking works with any custom shop system.

Required:

<details>

<summary>Custom shop requirements</summary>

```txt
- Correct item names
- Registered inventory items
- Shop coordinates
- Your own pricing/shop logic
```

</details>

***

## Puff Events

RTX Smoking provides puff events for both client-side and server-side integrations.

***

### Client-Side Puff Event

This event is triggered on the client every time the local player makes a puff.

Use it for visual effects, camera effects, sounds, UI updates, custom animations, or screen effects.

```lua
AddEventHandler("rtx_smoking:client:OnPuff", function(data)
    -- Your custom client-side code here
end)
```

<details>

<summary>Client-side example</summary>

```lua
AddEventHandler("rtx_smoking:client:OnPuff", function(data)
    if data.type == "vape" then
        -- Vape visual effect
    elseif data.type == "bong" then
        -- Bong visual effect
    elseif data.type == "joint" then
        -- Weed/high visual effect
    elseif data.type == "cigarette" then
        -- Light nicotine effect
    elseif data.type == "cigar" then
        -- Stronger nicotine effect
    elseif data.type == "hookah" then
        -- Hookah/shisha effect
    end
end)
```

</details>

***

### Server-Side Puff Event

This event is triggered on the server every time a player makes a puff.

Use it for stress systems, needs, addiction, rewards, logging, status effects, or server-side integrations.

```lua
AddEventHandler("rtx_smoking:server:OnPlayerPuff", function(src, data)
    -- Your custom server-side code here
end)
```

<details>

<summary>Server-side example</summary>

```lua
AddEventHandler("rtx_smoking:server:OnPlayerPuff", function(src, data)
    local playerId = src
    local itemType = data.type
    local itemName = data.item
    local puffStrength = data.amount
    local holdTime = data.holdDuration
    local hookahId = data.hookahId
    local stats = data.stats

    local stressReduce = math.floor(puffStrength)

    if itemType == "joint" or itemType == "bong" or itemType == "hookah" then
        stressReduce = math.floor(puffStrength * 2.0)
    elseif itemType == "vape" then
        stressReduce = math.floor(puffStrength * 1.5)
    elseif itemType == "cigar" then
        stressReduce = math.floor(puffStrength * 1.2)
    end

    -- Example for qb-hud / common stress systems:
    -- TriggerClientEvent("hud:client:RelieveStress", playerId, stressReduce)

    -- Example logging:
    -- print(("[RTX Smoking] Player %s puffed %s (%s), strength: %.2f, hold: %sms"):format(
    --     playerId,
    --     tostring(itemName),
    --     tostring(itemType),
    --     puffStrength,
    --     holdTime
    -- ))
end)
```

</details>

***

### Puff Data

Both client and server puff events return the same `data` table.

<details>

<summary>Available data</summary>

#### `data.type`

The smoking item type.

```lua
"cigarette" -- Classic cigarette
"cigar"     -- Cigar
"joint"     -- Weed joint
"bong"      -- Bong
"vape"      -- Electronic vape
"hookah"    -- Hookah / shisha
```

#### `data.item`

Exact item name.

```lua
"vape_1_red"
"bong"
"joint_og_kush"
"cigarette_redwood"
"hookah"
```

#### `data.amount`

Puff strength based on hold duration.

```lua
0.1  -- Very small puff
10.0 -- Very strong puff
```

#### `data.holdDuration`

How long the puff key was held, in milliseconds.

```lua
500  -- Short puff
2000 -- Long puff
```

#### `data.autoReleased`

Whether the puff ended automatically.

```lua
true  -- Forced release
false -- Manual release
```

#### `data.hookahId`

Unique hookah ID.

Only available when:

```lua
data.type == "hookah"
```

</details>

***

### Stats Data

`data.stats` depends on the smoking item type.

<details>

<summary>Stats by item type</summary>

#### Vape

```lua
data.stats.battery
data.stats.fill
data.stats.heat
data.stats.durability
```

#### Bong

```lua
data.stats.water
data.stats.fill
data.stats.smokeLevel
data.stats.durability
```

#### Cigarette / Cigar / Joint

```lua
data.stats.durability
data.stats.burnLevel
data.stats.smokeLevel
data.stats.fill
```

#### Hookah

```lua
data.stats.water
data.stats.tobacco
data.stats.coal
data.stats.hoses
```

</details>

***

## Smoking Exports

RTX Smoking provides exports for checking whether a player is currently smoking.

***

### Client-Side Export

Returns whether the local player is currently smoking.

```lua
exports["rtx_smoking"]:IsPlayerSmoking()
```

Returns:

```lua
true / false
```

<details>

<summary>Client-side example</summary>

```lua
CreateThread(function()
    while true do
        Wait(1000)

        local isSmoking = exports["rtx_smoking"]:IsPlayerSmoking()

        if isSmoking then
            print("Local player is smoking")
        end
    end
end)
```

</details>

***

### Server-Side Export

Returns whether the specified player is currently smoking.

```lua
exports["rtx_smoking"]:IsPlayerSmoking(source)
```

Returns:

```lua
true / false
```

<details>

<summary>Server-side example</summary>

```lua
RegisterCommand("checksmoking", function(source)
    local isSmoking = exports["rtx_smoking"]:IsPlayerSmoking(source)

    if isSmoking then
        print(("Player %s is smoking"):format(source))
    else
        print(("Player %s is not smoking"):format(source))
    end
end)
```

</details>

***

## Static Hookah Locations

Static hookahs are hookahs that are automatically spawned from the config when the resource starts.

They are useful for:

```lua
-- Hookah bars
-- Clubs
-- Lounges
-- VIP rooms
-- Public shisha areas
```

Static hookahs cannot be removed by players.

***

### Config Location

Add your static hookahs inside:

<details>

<summary>Config location example</summary>

```lua
Config.StaticHookahs = {
    -- Your hookah locations here
}
```

</details>

***

### Creating a New Static Hookah

To create a new hookah location:

```lua
-- Copy an existing entry
-- Change the index number
-- Change coords/rotation/type
```

Example:

<details>

<summary>New static hookah example</summary>

```lua
[3] = {
    label = "VIP Lounge Hookah", -- Display name of the static hookah
    enabled = true, -- Enable or disable this static hookah
    hookahType = 3, -- Hookah type from Config.HookahTypes
    coords = vector3(0.0, 0.0, 0.0), -- Hookah position
    rotation = vector3(0.0, 0.0, 0.0), -- Hookah rotation

    defaultState = {
        water = { state = "empty", level = 0 }, -- Empty water state
        tobacco = { state = "empty", amount = 0, flavor = nil }, -- Empty tobacco state
        coal = { state = "missing", progress = 0, durability = 0 }, -- No coal placed
        hoses = { connected = 0, max = 4, players = {} }, -- Hose settings
    },

    managePermissions = {
        everyone = true, -- Allow everyone to manage the hookah
        permissions = {},
    },
},
```

</details>

***

### Location Settings

<details>

<summary>Location settings explanation</summary>

#### `label`

Display name of the hookah location.

```lua
label = "Hookah Bar"
```

***

#### `enabled`

Enable or disable this static hookah.

```lua
enabled = true
```

***

#### `hookahType`

Hookah type from:

```lua
Config.HookahTypes
```

Example:

```lua
hookahType = 1
```

***

#### `coords`

Position where the hookah will spawn.

```lua
coords = vector3(-557.26, 291.45, 81.17)
```

***

#### `rotation`

Rotation of the hookah object.

```lua
rotation = vector3(0.0, 0.0, 90.0)
```

</details>

***

### Default Hookah State

The default state controls whether the hookah starts empty or fully prepared.

***

<details>

<summary>Prepared hookah example</summary>

```lua
defaultState = {
    water = { state = "good", level = 100 },
    tobacco = { state = "prepared", amount = 100, flavor = "Apple" },
    coal = { state = "placed", progress = 100, durability = 100 },
    hoses = { connected = 0, max = 4, players = {} },
}
```

</details>

***

<details>

<summary>Empty hookah example</summary>

```lua
defaultState = {
    water = { state = "empty", level = 0 },
    tobacco = { state = "empty", amount = 0, flavor = nil },
    coal = { state = "missing", progress = 0, durability = 0 },
    hoses = { connected = 0, max = 4, players = {} },
}
```

</details>

***

### Hose Settings

<details>

<summary>Hose settings example</summary>

```lua
hoses = {
    connected = 0,
    max = 4,
    players = {}
}
```

</details>

#### Explanation

```lua
connected -- Current connected hose count
max       -- Maximum hose connections
players   -- Internal player tracking table
```

***

### Manage Permissions

Permissions only affect who can open/manage the hookah menu.

All players can still use the hose.

***

<details>

<summary>Everyone can manage example</summary>

```lua
managePermissions = {
    everyone = true,
    permissions = {},
}
```

</details>

***

<details>

<summary>Restricted management example</summary>

```lua
managePermissions = {
    everyone = false,
    permissions = {
        { permissiontype = "ace", permission = "hookah.manage" },
        { permissiontype = "job", permission = "bahama" },
        { permissiontype = "identifier", permission = "license:xxxxxxxxxxxxxxxx" },
    },
}
```

</details>

***

### Permission Types

<details>

<summary>Permission type explanation</summary>

```lua
"ace"        -- Uses FiveM ACE permissions
"job"        -- Uses ESX/QBCore job name
"identifier" -- Uses player identifier/license
```

</details>

***

### Full Example

<details>

<summary>Full static hookah config example</summary>

```lua
Config.StaticHookahs = {
    [1] = {
        label = "Hookah Bar",
        enabled = true,
        hookahType = 1,
        coords = vector3(-557.26, 291.45, 81.17),
        rotation = vector3(0.0, 0.0, 90.0),

        defaultState = {
            water = { state = "good", level = 100 },
            tobacco = { state = "prepared", amount = 100, flavor = "Apple" },
            coal = { state = "placed", progress = 100, durability = 100 },
            hoses = { connected = 0, max = 4, players = {} },
        },

        managePermissions = {
            everyone = false,
            permissions = {
                { permissiontype = "ace", permission = "hookah.manage" },
                { permissiontype = "job", permission = "bahama" },
                { permissiontype = "identifier", permission = "license:xxxxxxxxxxxxxxxx" },
            },
        },
    },

    [2] = {
        label = "Empty Hookah",
        enabled = true,
        hookahType = 2,
        coords = vector3(2.78, 527.38, 174.18),
        rotation = vector3(0.0, 0.0, 180.0),

        defaultState = {
            water = { state = "empty", level = 0 },
            tobacco = { state = "empty", amount = 0, flavor = nil },
            coal = { state = "missing", progress = 0, durability = 0 },
            hoses = { connected = 0, max = 4, players = {} },
        },

        managePermissions = {
            everyone = true,
            permissions = {},
        },
    },
}
```

</details>

***

## Notes

The script is designed to be highly flexible and fully customizable. All framework-related functions are editable, allowing you to easily adapt the script to your own server logic.

Most core systems can be modified, and you are free to implement your own logic, interaction system, target system, or any other custom features based on your needs.

The script also includes a language file, making it easy to translate and customize all texts.

## Support

If you need help with installation, configuration or have any questions regarding this resource, feel free to contact us on our Discord server:

[Join our Discord](https://discord.gg/rtxdev)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rtx-dev.gitbook.io/rtxdev/smoking-system.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
