# SIREC STUDIO DOCS

<figure><img src="/files/yH52ShxVYOmXTKJdoAkJ" alt=""><figcaption><p>DOC ! Hey Doc, are the docs here Doc ?</p></figcaption></figure>


# SS-Core

The Heart of Our Scripts

<figure><img src="/files/8lnx3Fw3lEyFk27l7BKm" alt=""><figcaption></figcaption></figure>

Our SS-*CORE* script is the essential foundation that powers and coordinates all other scripts in our RedM suite. Designed as a centralized support system, the *CORE* provides a unified and versatile interface, ensuring each script can operate optimally regardless of the underlying framework (such as RSG, VORP, etc.). Thanks to the SS-*CORE*, users can benefit from a consistent setup and streamlined management of features.

### What Does the SS-CORE Do?

* **Compatibility Bridge**: The *CORE* acts as a bridge that automatically identifies and applies the correct functions and methods for the framework in use. This means that whether the server runs RSG, VORP, or another framework, the SS-*CORE* adapts seamlessly, maintaining full compatibility.
* **Centralized Function Management**: With the SS-*CORE*, there’s no need to configure each script individually for framework alignment. Core functions such as user authentication, inventory management, transactions, and more are centralized within the SS-*CORE*. This way, every script can access the same resources and work in harmony without additional configuration.
* **Efficiency and Optimization**: The SS-*CORE* is designed to reduce overhead and eliminate redundancies. By managing primary calls and ensuring synchronized operations, it improves the server's overall efficiency and optimizes resource usage, ensuring a smoother experience for all users.
* **Configurability and Modularity**: We structured the SS-*CORE* to be highly modular. You can enable or disable specific functions as needed, allowing for customization without compromising the stability of other scripts.

### Why is the CORE Essential?

The *SS-CORE* serves as the backbone for all other scripts. Its presence provides greater flexibility and significantly reduces compatibility issues that can arise when working with different frameworks. Here are the main benefits:

* **Scalability**: With the *SS-CORE* , adding new scripts to an existing configuration is simple, as each one is designed to work natively with it.
* **Simplified Maintenance**: Since core functions are centralized, updating or fixing issues is more efficient. Any improvements to the *SS-CORE* are instantly reflected across all scripts that rely on it.
* **Consistency**: The *SS-CORE* ensures that each script follows the same operational standards and logic, offering a uniform and predictable experience for admins and players alike.


# How to Configure the SS-CORE

Follow these steps to properly configure the *SS-CORE* script on your RedM server:

### Step 1: Set Your Server IP on the Website

1. Go to your account page on our website: <https://www.sirecstudio.com/account/my-account>.
2. Make sure to enter your server’s IP address in the designated field. This is crucial for linking your server with the license. You need enter only the IP without the port.

### Step 2: Configure the License in SS-Core

1. Open the file `SS-Core/license.lua`.
2. In this file, locate the `YourSSLicense` variable.
3. Copy the license key from your account page (where you set the IP) and paste it as the value of `YourSSLicense`.

### Step 3: Set Your Steam Access for CORE Panel Access

1. In `SS-Core`, open the file that controls access permissions (usually found in `config.lua` or similar).
2. Locate the `SteamAccess` variable.
3. Enter your Steam ID here to allow access to the CORE panel, enabling you to see all your scripts.

### Step 4: Enable SS-Core in server.cfg

1. After setting up the previous configurations, add `ensure SS-Core` in your `server.cfg` file. And all the others SS scripts must be below SS-Core.

***

### Important Notes

* In fxmanifest.lua you can choice the framework !

By following these steps, your *SS-CORE* script should be correctly configured and ready to manage all other scripts smoothly on your server.


# SS-Crafting

<figure><img src="/files/JgVebI9SCucSXtcZMIw0" alt=""><figcaption><p>CRAFTING SYSTEM</p></figcaption></figure>

<figure><img src="/files/2Bd6YLjxPBzbX7w6jywT" alt=""><figcaption></figcaption></figure>

* [**How to create a receipe ?**](/readme-1/create-a-receipe)
* [**Permanent Items ?**](/readme-1/permanent-items)
* [**Create a book / workbench ?**](/readme-1/create-a-book-workbench)

***

## Create a receipe.

<details>

<summary>Receipe Example</summary>

```
["horsebrush"] = { -- RECEIPE NAME SHOULD BE SAME AS THE ITEM
	Item = "horsebrush", -- ITEM TO RECEIVE
	Amount = 2, -- AMOUNT TO RECEIVE WHEN CRAFTED
	Desc = "help keep your horse's coat clean by removing dust and dirt particles
	 while also giving them a massage which helps release oils that give their 
	coat a glossy shine.", -- ITEM DESCRIPTION AND INFO
	Category = "medic", -- IN WICH CATEGORY SHOULD ADD THE EXP ?
	Level = 0, -- LVL NEED TO CAN CRAFT THIS ITEM
	Exp = 25, -- HOW MUCH EXPERIENCE TO ADD WHEN CRAFT
	isGun = false, -- IS THIS ITEM A GUN ?
	Jobs = {}, -- WHAT JOBS CAN CRAFT THIS ITEM ? {} WILL ALLOW ANYBODY / {"jobname, "jobname"} WILL BE SHOWED ONLY TO THEM
	JobGrades = {}, -- WHAT JOBS GRADE CAN CRAFT THIS ITEM ? {} WILL ALLOW ANY / {1, 5} WILL BE SHOWED ONLY TO THIS RANK
	SuccessRate = 100, -- % CHANCE TO CRAFT THIS ITEM ?
	Time = 5, -- TIME NEED TO WAIT
        Metadata = {description = "TESTING : ", ["qty"] = 20}, -- ADD METADATA IF YES WICH ? false TURN IT OFF
        Price = 100,
	Ingredients = { -- WHAT INGREDIENTS NEED TO CRAFT THIS RECEIPE
		['bread'] = {amount = 2, returnItem = false, returnAmount = 1},
		['beer'] = {amount = 2, returnItem = false, returnAmount = 1},
	}
},   
```

</details>


# Create a receipe

To create a recipe, you must first have it planned. Add the item you want to be crafted and the items needed to create the recipe in your framework after which you can configure and set the recipe to your liking.

***

Let's assume that we have this recipe to create nails, in which we have ironbar and hammer as materials. The ironban will be consumed and will disappear from the inventory, instead the hammer will remain and only the presence will be necessary!

<pre class="language-lua" data-overflow="wrap"><code class="lang-lua">["<a data-footnote-ref href="#user-content-fn-1">nails</a>"] = { -- RECEIPE NAME SHOULD BE SAME AS THE ITEM
		<a data-footnote-ref href="#user-content-fn-2">Item </a>= "nails", -- ITEM TO RECEIVE
		<a data-footnote-ref href="#user-content-fn-3">Amount </a>= 5, -- AMOUNT TO RECEIVE WHEN CRAFTED
		<a data-footnote-ref href="#user-content-fn-4">Desc </a>= "A simple nail !", -- ITEM DESCRIPTION AND INFO
		<a data-footnote-ref href="#user-content-fn-5">Category </a>= "tools", -- IN WICH CATEGORY SHOULD ADD THE EXP ?
		<a data-footnote-ref href="#user-content-fn-6">Level </a>= 0, -- LVL NEED TO CAN CRAFT THIS ITEM
		<a data-footnote-ref href="#user-content-fn-7">Exp </a>= 25, -- HOW MUCH EXPERIENCE TO ADD WHEN CRAFT
		<a data-footnote-ref href="#user-content-fn-8">isGun </a>= false, -- IS THIS ITEM A GUN ?
		<a data-footnote-ref href="#user-content-fn-9">Jobs </a>= {}, -- WHAT JOBS CAN CRAFT THIS ITEM ? {} WILL ALLOW ANYBODY / {"jobname, "jobname"} WILL BE SHOWED ONLY TO THEM
		<a data-footnote-ref href="#user-content-fn-10">JobGrades </a>= {}, -- WHAT JOBS GRADE CAN CRAFT THIS ITEM ? {} WILL ALLOW ANY / {1, 5} WILL BE SHOWED ONLY TO THIS RANK
		<a data-footnote-ref href="#user-content-fn-11">SuccessRate </a>= 100, -- % CHANCE TO CRAFT THIS ITEM ?
		<a data-footnote-ref href="#user-content-fn-12">Time </a>= 5, -- TIME NEED TO WAIT
        	<a data-footnote-ref href="#user-content-fn-13">Metadata </a>= false, -- ADD METADATA IF YES WICH ? false TURN IT OFF
        	<a data-footnote-ref href="#user-content-fn-14">Price </a>= 100,
Ingredients = { -- WHAT INGREDIENTS NEED TO CRAFT THIS RECEIPE
	['<a data-footnote-ref href="#user-content-fn-15">ironbar</a>'] = {<a data-footnote-ref href="#user-content-fn-16">amount = 2</a>, <a data-footnote-ref href="#user-content-fn-17">returnItem = false</a>, <a data-footnote-ref href="#user-content-fn-18">returnAmount = 1</a>},
	['<a data-footnote-ref href="#user-content-fn-15">hammer</a>'] = {<a data-footnote-ref href="#user-content-fn-16">amount = 2</a>, <a data-footnote-ref href="#user-content-fn-17">returnItem = false</a>, <a data-footnote-ref href="#user-content-fn-18">returnAmount = 1</a>},
	}
},   
</code></pre>

Here you must set the item you want to be crafted, and which you want the player to receive after finishing crafting the recipe!

{% code overflow="wrap" %}

```lua
PermanentItems = {
    ["hammer"] = true,
    ["shovel"] = true,
}, 
```

{% endcode %}

Here you must set the item you want to be crafted, and which you want the player to receive after finishing crafting the recipe!

{% code overflow="wrap" %}

```lua
    ["itemcrafted"] = { -- RECEIPE NAME SHOULD BE SAME AS THE ITEM
        Item = "itemcrafted", -- ITEM TO RECEIVE
```

{% endcode %}

Here you have to set the amount you want the player to receive after finishing crafting the recipe.

{% code overflow="wrap" %}

```lua
        Amount = 2, -- AMOUNT TO RECEIVE WHEN CRAFTED
```

{% endcode %}

Here are the information and description of the recipe such as the description of the item, its category which can be EX: doctor, tools, furniture etc etc, the level required to create this recipe and the experience it gives when finishing the craft..

{% code overflow="wrap" %}

```lua
Desc = "description", -- ITEM DESCRIPTION AND INFO
Category = "medic", -- IN WICH CATEGORY SHOULD ADD THE EXP ?
Level = 0, -- LVL NEED TO CAN CRAFT THIS ITEM
Exp = 25, -- HOW MUCH EXPERIENCE TO ADD WHEN CRAFT
```

{% endcode %}

If the item is a weapon you will have to set true, if it is only an item you will have to set false.

{% code overflow="wrap" %}

```lua
isGun = false, -- IS THIS ITEM A GUN ?
```

{% endcode %}

If this recipe requires a specific job or a specific degree, you will have to set the required job and degree, those who do not have this job or degree will not be able to craft this recipe even if they have the necessary materials and experience.

{% code overflow="wrap" %}

```lua
// FOR NO JOBS & GRADE 
Jobs = {}, -- WHAT JOBS CAN CRAFT THIS ITEM ? {} WILL ALLOW ANYBODY / {"jobname, "jobname"} WILL BE SHOWED ONLY TO THEM
JobGrades = {}, -- WHAT JOBS GRADE CAN CRAFT THIS ITEM ? {} WILL 
// FOR JOB OR GRADE
Jobs = {"police}, -- WHAT JOBS CAN CRAFT THIS ITEM ? {} WILL ALLOW ANYBODY / {"jobname, "jobname"} WILL BE SHOWED ONLY TO THEM
JobGrades = {2, 3, 10}, -- WHAT JOBS GRADE CAN CRAFT THIS ITEM ? {} WILL 
```

{% endcode %}

If you want this recipe to be crafted without problems and you can always set it to 100%, if you want the probability of crafting to be difficult and to fail, set the probability of success.

{% code overflow="wrap" %}

```lua
    SuccessRate = 100, -- % CHANCE TO CRAFT THIS ITEM ?
    Time = 5, -- TIME NEED TO WAIT
```

{% endcode %}

Some frameworks accept metadata for items, which you can set directly here, and upon completion of the craft, that item will already have predefined metadata.

{% code overflow="wrap" %}

```lua
    Metadata = {description = "TESTING : ", ["qty"] = 20},
```

{% endcode %}

Here you will have to set the necessary materials (items) for crafting this recipe, any desired materials can be added. A material can return another material after its use, if yes, set which and how many. A good example is to suppose that you need a bottle of water, you set the water bottle as an item and on return you can set an empty bottle.

{% code overflow="wrap" %}

```lua
    Ingredients = { -- WHAT INGREDIENTS NEED TO CRAFT THIS RECEIPE
        ['bread'] = {amount = 2, returnItem = false, returnAmount = 1},
        ['beer'] = {amount = 2, returnItem = false, returnAmount = 1},
    }
```

{% endcode %}

[^1]: Items to be crafter and receipe name !

[^2]: Item to receive when craft finish !

[^3]: How many to receive

[^4]: Description of the item to show in the book !

[^5]: From wich category is this item ?

[^6]: From wich level can be crafted ?

[^7]: How many EXP to give when craft finish ?

[^8]: Is a gun or item ?

[^9]: Block this receipe for some jobs ?

[^10]: Block this receipe for some grades of jobs ?

[^11]: Success to finish the craft

[^12]: How many seconds to wait ?

[^13]: Choice metadata for this item.

[^14]: Need to pay for this receipe ?

[^15]: Item to take !

[^16]: Amount to take

[^17]: What item should return? item/false

[^18]: Amount the of the returned item !


# Permanent items

Permanent items means they may be needed in a recipe but will not be taken. They only require the presence in the inventory to create the recipe, for example for a recipe in which you want to create some nails, you needed an iron and a hammer. The iron will be consumed for the creation of the nails, the exchange of the hammer only requires its presence in the inventory for the creation of the nails, being a permanent object and not consumable.

***

Let's assume that we have this recipe to create nails, in which we have ironbar and hammer as materials. The ironban will be consumed and will disappear from the inventory, instead the hammer will remain and only the presence will be necessary!

{% code overflow="wrap" %}

```lua
["nails"] = { -- RECEIPE NAME SHOULD BE SAME AS THE ITEM
		Item = "nails", -- ITEM TO RECEIVE
		Amount = 5, -- AMOUNT TO RECEIVE WHEN CRAFTED
		Desc = "A simple nail !", -- ITEM DESCRIPTION AND INFO
		Category = "tools", -- IN WICH CATEGORY SHOULD ADD THE EXP ?
		Level = 0, -- LVL NEED TO CAN CRAFT THIS ITEM
		Exp = 25, -- HOW MUCH EXPERIENCE TO ADD WHEN CRAFT
		isGun = false, -- IS THIS ITEM A GUN ?
		Jobs = {}, -- WHAT JOBS CAN CRAFT THIS ITEM ? {} WILL ALLOW ANYBODY / {"jobname, "jobname"} WILL BE SHOWED ONLY TO THEM
		JobGrades = {}, -- WHAT JOBS GRADE CAN CRAFT THIS ITEM ? {} WILL ALLOW ANY / {1, 5} WILL BE SHOWED ONLY TO THIS RANK
		SuccessRate = 100, -- % CHANCE TO CRAFT THIS ITEM ?
		Time = 5, -- TIME NEED TO WAIT
        	Metadata = false, -- ADD METADATA IF YES WICH ? false TURN IT OFF
        	Price = 100,
Ingredients = { -- WHAT INGREDIENTS NEED TO CRAFT THIS RECEIPE
	['ironbar'] = {amount = 2, returnItem = false, returnAmount = 1},
	['hammer'] = {amount = 2, returnItem = false, returnAmount = 1},
	}
},   
```

{% endcode %}

***

In permanent items we have the hammer, and will not be removed from your inventory, just need to have it on you !

{% code overflow="wrap" %}

```lua
PermanentItems = {
    ["hammer"] = true,
    ["shovel"] = true,
}, 
```

{% endcode %}


# Create a book / workbench

**This is a book and a predefined workbench.**

**Book:**

<pre class="language-lua" data-overflow="wrap"><code class="lang-lua">["medicinebook"] = {
<strong>    Cover = "coverbook",
</strong>    PropSpawn = "p_campfire_coloursmoke01x",
    Animation = {"amb_camp@world_camp_fire_tend_sit@poke_fire@male_a@base", "base"},
    Receipes = {"cigarette"},
},
</code></pre>

Workbench:

<pre class="language-lua" data-overflow="wrap"><code class="lang-lua">[1] = {
    Cover = "coverbook",
    Name = "WorkBench Craft", 
<strong>    Coords = {-2392.17, -2375.76, 60.17, 150.0},
</strong>    Distance = 2.0,
    DrawTxt = "Wood WorkBench",
    SpawnProp = "p_workbench01x", 
    Animation = {"amb_camp@world_camp_fire_tend_sit@poke_fire@male_a@base", "base"}, 
    UseBlip = -758970771, 
    Receipes = {"horsebrush", "boiledegg", "porkcooked", "friedchicken", "scrambledeggsbacon", "fishchips"}, 
    Jobs = {},
    JobsGrades = {},
},      
</code></pre>

***

*Creating a book or workbench is very simple, but we still suggest that they be created after you finish making the recipes. Creating a book is simpler, fewer options.*&#x20;

**Cover:** *You can choose the book cover as you wish, you can choose or create one for each category, or as you like. Or you can leave the default "coverbook" cover!*

{% code overflow="wrap" %}

```lua
Cover = "coverbook",
```

{% endcode %}

***

**PropSpawn:** *is the item that you want to be spawned when you open a book, you can choose a prop for each book to identify and express more correctly the craft category or domain. Default is a campfire with quite visible smoke, otherwise it is clear that someone is working and crafting something at the fire.*

**Animation:** *you can choose any animation you want the character to do when crafting. {"DICT", "ANIM"}*

{% code overflow="wrap" %}

```lua
PropSpawn = "p_campfire_coloursmoke01x",
Animation = {"amb_camp@world_camp_fire_tend_sit@poke_fire@male_a@base", "base"},
```

{% endcode %}

***

```
// Some code
```


# Configuration File

Configuration and Usage Guide for the SS-Crafting Script in RedM

The configuration file defines settings for crafting items in the game, including crafting books, recipes, and other parameters such as language, keys, explosion effects, and permanent items.

{% code overflow="wrap" %}

```lua
-- Author 'SIREC' Discord Username
-- REPORT ANY BUGS ON https://discord.gg/9XNBaQSmMd --

Config = {
    Dev = true,  -- USE ONLY ON TEST SERVER FOR CONFIGURATION & TESTS
    Language = "EN", -- TRANSLATE LANGUAGE ("EN")
    Key = 0xD9D0E1C0, -- KEY TO OPEN MENU/PARK
    
    ExplodeFailCraft = 35, -- EXPLOSION TYPE 35 = POISON, 32 = FIRE EFFECT, 24 = FIRE EXPLOSION, 3 = LOW EXPLOSION / false TO TURN IT OFF
    ExplosionPower = 0.7, -- 0.0 - 1.0 / TEST AND CHOOSE
    
    PermanentItems = { -- ITEMS THAT JUST NEED TO BE IN INVENTORY, WILL NOT BE REMOVED WHEN CRAFTING
        ["hammer"] = true,
        ["shovel"] = true,
    }, 
    
    CraftBooks = {
        ["medicinebook"] = {
            Cover = "coverbook", -- IMAGE NAME (THE IMAGE MUST BE .png IN UI/img/*.png / FOLLOW THE DIMENSIONS OF THE EXAMPLE COVER)
            PropSpawn = "p_campfire_coloursmoke01x", -- SPAWN PROP FOR THIS BOOK ? false TO DISABLE
            Animation = {"amb_camp@world_camp_fire_tend_sit@poke_fire@male_a@base", "base"}, -- USE ANIMATION ? IF YES WHICH ? {dict, anim} false TO DISABLE
            Recipes = {"cigarette"},
        },
        ["jewelrybook"] = {
            Cover = "coverbook", -- IMAGE NAME
            PropSpawn = "p_campfire_coloursmoke01x", -- SPAWN PROP
            Animation = {"amb_camp@world_camp_fire_tend_sit@poke_fire@male_a@base", "base"}, -- USE ANIMATION
            Recipes = {"boiledegg", "porkcooked", "friedchicken", "scrambledeggsbacon", "fishchips", "pocket_watch", "WEAPON_MELEE_LANTERN", "WEAPON_MELEE_DAVY_LANTERN", "barrel"},
        },
        ["book"] = {
            Cover = "coverbook", -- IMAGE NAME
            PropSpawn = "p_campfire_coloursmoke01x", -- SPAWN PROP
            Animation = {"amb_camp@world_camp_fire_tend_sit@poke_fire@male_a@base", "base"}, -- USE ANIMATION
            Recipes = {"horsebrush"},
        },
    },
    
    Crafting = {
        ["cigarette"] = {
            Item = "cigarette", -- ITEM TO RECEIVE
            Amount = 1, -- AMOUNT TO RECEIVE WHEN CRAFTED
            Desc = "A handmade cigarette.", -- ITEM DESCRIPTION
            Category = "medicine", -- CATEGORY FOR EXPERIENCE
            Level = 0, -- LEVEL REQUIRED TO CRAFT
            Exp = 2, -- EXPERIENCE GAINED WHEN CRAFTED
            isGun = false, -- IS THIS ITEM A GUN?
            Jobs = {}, -- ALLOWED JOBS, EMPTY ARRAY FOR ALL JOBS
            JobGrades = {}, -- ALLOWED JOB GRADES
            SuccessRate = 90, -- % CHANCE TO SUCCESSFULLY CRAFT
            Time = 2, -- TIME REQUIRED TO CRAFT
            Metadata = false, -- ADD METADATA IF NEEDED
            Ingredients = { -- REQUIRED INGREDIENTS
                ['rollingpaper'] = {amount = 1, returnItem = false},
                ['tobacco'] = {amount = 2, returnItem = false},
            }
        },
        -- ADD MORE RECIPES HERE
    }
}

function NOTIFY(text) -- SET YOUR NOTIFICATIONS
    TriggerEvent("vorp:TipBottom", text, 5000)      
end

function playAnim(dict, name)
    local playerPed = PlayerPedId()
    RequestAnimDict(dict)
    while not HasAnimDictLoaded(dict) do
        Citizen.Wait(100)
    end
    TaskPlayAnim(playerPed, dict, name, 1.0, 1.0, -1, 1, 0, false, false, false)  
end

```

{% endcode %}

#### Using the Script

1. **Development Mode**: Set `Dev` to `true` for testing and configuration on a test server. Set it to `false` for production.
2. **Language**: Configure the language setting with `Language`.
3. **Key Bindings**: Define the key binding for opening the crafting menu with `Key`.
4. **Explosion Effects**: Configure the explosion effects for failed crafts using `ExplodeFailCraft` and `ExplosionPower`.
5. **Permanent Items**: List items in `PermanentItems` that will not be consumed during crafting.
6. **Crafting Books**: Define crafting books in `CraftBooks` with associated animations, props, and recipes.
7. **Crafting Recipes**: Configure recipes in the `Crafting` section, specifying items required, success rate, experience gained, and other parameters.

#### Final Considerations

This guide covers the basic configuration and use of the SS-Crafting script for RedM. You can further expand the functionality by adding new recipes, crafting books, and customizing the crafting experience based on your needs. If you have any further questions or need assistance, feel free to ask!


# SS-Metabolism

SS-Metabolism documentation

<figure><img src="/files/RdgEIjne0Uuw4TO3bs39" alt=""><figcaption></figcaption></figure>

**Overview**

\
SS-Metabolism is a fully integrated and highly configurable metabolism system for RedM, designed to enhance realism by managing key survival mechanics such as hunger, thirst, stress, dirtiness, reputation, and temperature. This system dynamically adjusts based on player actions, environmental conditions, and reputation levels, providing an immersive experience.

The system also includes **horse metabolism support** when used with SS-Stable, allowing players to monitor their horse's hunger, thirst, stamina, and health in real-time. The **drag-and-save HUD customization** ensures that players can position the interface to their preference, with settings saved automatically for a seamless experience.

Whether you're looking for a fully immersive survival system or a configurable addition to your roleplay server, SS-Metabolism provides the flexibility and depth needed to enhance gameplay.

1. **Comprehensive Metabolism System**
   * Tracks hunger, thirst, stress, dirtiness, reputation, and temperature
   * Supports **horse metabolism management** (requires SS-Stable)
   * Fully adjustable **HUD positioning** with a **drag-and-save** system
   * **Auto-hide functionality** to keep the interface clean and responsive
2. **Realistic Status Effects**
   * Hunger and thirst impact **health, stamina, and overall player condition**
   * Stress influences **stamina regeneration**, increasing exhaustion and ragdoll probability
   * Dirtiness affects **NPC interactions**, leading to negative reactions from townsfolk
   * Reputation dynamically adjusts **NPC behavior**, influencing how they react to the player
   * **Temperature system** modifies metabolism rates based on clothing and weather conditions
3. **Horse Metabolism (With SS-Stable)**
   * Automatically displays **horse hunger, thirst, stamina, and health**
   * Dynamic **needs system** requiring players to manage their horse’s well-being
   * Metabolism adjusts based on **activity levels and environmental factors**
4. **Customizable Gameplay**
   * Fully adjustable **metabolism decay rates**, status thresholds, and effects
   * Configurable **NPC reactions** based on the player’s reputation level
   * **Blacklist specific NPCs** to prevent them from reacting to reputation changes
   * Adjustable **temperature effects**, with specific thresholds for metabolism changes
5. **Dynamic Economy and Item System**
   * Supports **custom food, drinks, medicine, and stimulants**, each with unique metabolism effects
   * Fully integrated with **health and stamina mechanics**, allowing strategic gameplay
   * Configurable **buffs and debuffs** for different consumables, including alcohol, drugs, and medicine
6. **Developer-Friendly Integration**
   * **Export system** with GET, ADD, and REMOVE functions for each status
   * Optimized performance with a **dynamic update system**
   * Adaptable for **future updates and custom server configurations**


# Preview

<div><figure><img src="/files/Us1rUE7mHoEaxrKCYfTC" alt=""><figcaption><p>WITH HORSE METABOLISM</p></figcaption></figure> <figure><img src="/files/OAXFgBeuO3Ji0LfX0XME" alt=""><figcaption><p>WITHOUT HORSE METABOLISM</p></figcaption></figure></div>

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


# Configuration File

## config.lua

{% code overflow="wrap" %}

```lua
-- Author: SIREC
-- Support / bug reports: https://discord.gg/9XNBaQSmMd
--
--[[
===========================================================================
 SS-Metabolism Configuration
===========================================================================
 This file is written to be easy to understand even for people who do not
 work with Lua regularly.

 IMPORTANT RULES:
 1. Change values, not logic.
 2. Use Dev = true only while testing.
 3. If a feature depends on another script, disable it here when you do not
    have that resource on your server.
 4. Read README.md before changing UI, metabolism, horse, housing or item
    settings.
===========================================================================
]]

Config = {

    --=====================================================================
    -- GENERAL SETTINGS
    --=====================================================================

    Dev = true, -- true = dev/test mode | false = recommended for live server
    WaitBeforeLoad = 10, -- seconds to wait after character selected before HUD loads

    CommandSetHud = "sethud", -- opens HUD edit mode: move icons, scale, hide/show, save with ESC
    ToggleHud = "shud", -- show/hide the full HUD

    -- Main metabolism tick.
    -- This updates hungry, thirsty, stress, dirtiness, reputation and horse metabolism.
    -- Health/stamina cores are refreshed separately and faster.
    Refresh = 20, -- seconds | recommended 10-20+

    -- Database save throttle for player metabolism info.
    -- HUD can refresh more often, but DB saves are limited by this value.
    SaveRefresh = 60, -- seconds

    -- Clock style shown in the HUD.
    -- Options: "analog" or "digital"
    ClockMode = "analog",

    --=====================================================================
    -- INITIAL PLAYER VALUES
    -- Used when the character has no saved metabolism data yet.
    -- Values are percentages, except Reputation which is 0-1000 internally.
    --=====================================================================

    Initial = {
        Thirsty = 90,
        Hungry = 75,
        Stress = 10,
        Reputation = 100,
    },

    --=====================================================================
    -- HUD FEATURE SWITCHES
    --=====================================================================

    UseHealthStamina = true, -- true = custom player health/stamina cores
    UseHorseHealthStamina = true, -- true = custom horse health/stamina cores
    HorseStats = true, -- true = horse hungry/thirsty HUD and decrease system
    RepStats = true, -- true = reputation HUD and NPC reaction system

    --=====================================================================
    -- HOUSING HUD INTEGRATION
    -- This script does not own housing logic. External scripts can use:
    -- exports["SS-Metabolism"]:SetHousing(mode, number)
    -- exports["SS-Metabolism"]:HousingIcon(icon)
    --=====================================================================

    SSHousing = true,
    HouseIcons = {
        ["stash"] = "housingkey_bg.png",
        ["outfit"] = "housingkey_bg.png",
        ["crafting"] = "housingkey_bg.png",
        ["phone"] = "housingkey_bg.png",
    },

    --=====================================================================
    -- REPUTATION / NPC REACTION SETTINGS
    -- Reputation is stored internally from 0 to 1000.
    -- GetRep() export returns floor(REP / 100), so 0-10.
    --=====================================================================

    ActiveNpcHate = true, -- true = NPCs can react to very low reputation
    RadiusNpc = 20.0, -- radius used to search nearby NPCs
    PeopleStartWalkingAway = 3, -- NPCs walk away when reputation level is this low
    PeopleStartRunningAway = 2, -- NPCs run away when reputation level is this low
    PeopleStartHateYou = 1, -- NPCs may fight/shoot when reputation level is this low

    -- Models listed here are ignored by the reputation reaction system.
    BlackListModels = {
        "a_m_m_valtownfolk_01",
        "mp_u_m_m_lom_train_prisoners_01",
        "g_m_m_bountyhunters_01",
        "g_m_m_unibanditos_01",
        "re_street_fight_males_01",
        "U_M_M_BHT_ODRISCOLLSLEEPING",
        "re_street_fight_males_01",
        "mp_g_m_m_bountyhunters_01",
        "U_M_M_BHT_ODRISCOLLMAULED",
        "U_M_M_BHT_ODRISCOLLDRUNK",
    },

    --=====================================================================
    -- HORSE METABOLISM SETTINGS
    -- These values are removed every Config.Refresh tick while the player
    -- has a horse loaded and HorseStats is enabled.
    --=====================================================================

    HorseMetabolism = {
        Thirsty = 1,
        Hungry = 1,
    },

    --=====================================================================
    -- TEMPERATURE SETTINGS
    -- Temperature = {min, max}
    -- Clothing entries add warmth to the current external temperature.
    -- MIN/MAX entries define metabolism changes when the final temperature
    -- is outside the safe range.
    --=====================================================================

    Temperature = {3, 35},
    TemperatureSettings = {
        ["HAT"] = 1,
        ["SHIRT"] = 2,
        ["PANTS"] = 3,
        ["BOOTS"] = 2,
        ["COAT"] = 5,
        ["GLOVES"] = 2,
        ["VEST"] = 2,
        ["PONCHO"] = 5,
        ["MIN"] = {Thirsty = 0, Hungry = 0.5, Stress = 0.2},
        ["MAX"] = {Thirsty = 0.5, Hungry = 0, Stress = 0.2},
    },

    --=====================================================================
    -- METABOLISM DECREASE SETTINGS
    -- Hungry/Thirsty values are removed.
    -- Stress values are added. Negative stress means stress goes down.
    --=====================================================================

    Metabolism = {
        ["Idle"] = {Thirsty = 0.4, Hungry = 0.3, Stress = 0},
        ["Walking"] = {Thirsty = 0.7, Hungry = 0.6, Stress = 0},
        ["Running"] = {Thirsty = 1.0, Hungry = 0.8, Stress = 0},
        ["Combat"] = {Thirsty = 1.2, Hungry = 1.2, Stress = 5},
        ["InBoat"] = {Thirsty = 0.5, Hungry = 0.4, Stress = -5},
        ["InWagon"] = {Thirsty = 0.5, Hungry = 0.4, Stress = -3},
        ["OnMount"] = {Thirsty = 0.4, Hungry = 0.4, Stress = -1},
    },

    KillWhenZero = false, -- true = kill/reset player when hungry or thirsty reaches 0
    DecreaseByStress = 0.2, -- extra hungry/thirsty decrease based on stress percent

    -- What happens when hungry/thirsty goes below MetabolismMin.
    MetabolismMin = 20,
    MetabolismStats = {
        ["THIRSTY"] = {Health = 30, Stamina = 10, Stress = 5},
        ["HUNGRY"] = {Health = 25, Stamina = 5, Stress = 5},
    },

    --=====================================================================
    -- STRESS EFFECT SETTINGS
    --=====================================================================

    StressRagdoll = true,
    RagDollObjects = true, -- true = player can ragdoll when sprinting into objects
    RagDollObjectsChance = 85,
    RagDollFalling = false, -- true = high falls can trigger ragdoll task

    -- Stamina drains faster when stress is high.
    DecreaseFasterStamina1 = 1.5, -- used at stress >= 50
    DecreaseFasterStamina2 = 2.0, -- used at stress >= 80
    StressChance1 = 50, -- chance gate for stress >= 50
    StressChance2 = 50, -- chance gate for stress >= 80

    --=====================================================================
    -- USABLE GOODS / ITEMS
    -- Each entry registers one usable item through SS-Core.
    --
    -- Supported Mode values:
    -- EAT / DRINK / SMOKE / SYRINGE / BOWL / BOTTLE / BANDAGE
    --
    -- Metabolism fields:
    -- hunger  = adds hungry value
    -- thirsty = adds thirst value
    -- stress  = adds stress value; negative removes stress
    -- health  = heals player by value, or false
    -- stamina = restores stamina by value, or false
    --
    -- false means disabled for that field.
    --
    -- Example:
    -- ["apple"] = {
    --     Label = "Apple",
    --     Mode = "EAT",
    --     Prop = "p_apple01x",
    --     Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
    --     Times = 1,
    --     Alcohol = false,
    --     Effect = false,
    --     OverPowerStamina = false,
    --     OverPowerHealth = false,
    -- },
    --=====================================================================

    Goods = {
	-- FOOD
	["apple"] = {
		Label = "Mar",
        Mode = "EAT", -- EAT / DRINK / SMOKE / SYRINGE / BOWL / BOTTLE
        Prop = "p_apple01x", -- THE PROP TO USE / false DISABLE
        Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false}, -- CHOICE WHAT DO    
		Times = 1, -- HOW MANY TIME DRINK/EAT TO FINISH !
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false,
        OverPowerHealth = false,    
	},
	["bread"] = {
		Label = "Paine",
        Mode = "EAT",
        Prop = "p_bread_13_ab_s_a",
        Metabolism = {hunger = 30, thirsty = false, stress = -3, health = false, stamina = false},  
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_pear"] = {
		Label = "Para",
        Mode = "EAT",
        Prop = "p_pear_02x",
        Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_peach"] = {
		Label = "Piersica",
        Mode = "EAT",
        Prop = "s_peach01x",
        Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
    ["Red_Raspberry"] = {
		Label = "Zmeura",
        Mode = "EAT",
        Prop = "p_blackberry01x",
        Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
    ["Black_Berry"] = {
		Label = "Mure",
        Mode = "EAT",
        Prop = "p_blackberry01x",
        Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
    ["grapes"] = {
		Label = "Struguri",
        Mode = "EAT",
        Prop = "p_blackberry01x",
        Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
    ["Creekplum"] = {
		Label = "Prune",
        Mode = "EAT",
        Prop = "p_blackberry01x",
        Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
	["boiledegg"] = {
		Label = "Ou Fiert",
        Mode = "EAT",
        Prop = "p_egg01x",
        Metabolism = {hunger = 10, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
	["consumable_salmon"] = {
		Label = "Somon",
        Mode = "EAT",
        Prop = "p_whitefishfilet01xb",
        Metabolism = {hunger = 30, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false, 
	},
	["consumable_trout"] = {
		Label = "Pastrav Prajit",
        Mode = "EAT",
        Prop = "p_whitefishfilet01xb",
        Metabolism = {hunger = 30, thirsty = false, stress = -5, health = false, stamina = false}, 
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
	["consumable_salmon_can"] = {
		Label = "Somon la conserva",
        Mode = "EAT",
        Prop = "s_canBeans01x",
        Metabolism = {hunger = 40, thirsty = 10, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
	["consumable_bluegil"] = {
		Label = "Platica gatita",
        Mode = "EAT",
        Prop = "p_cs_meatstewsmall01x",
        Metabolism = {hunger = 30, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
	["consumable_game"] = {
		Label = "Carne de vanat",
        Mode = "EAT",
        Prop = "p_cs_duckmeat01x",
        Metabolism = {hunger = 50, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
	["beefjerky"] = {
		Label = "Pastrama de vita",
        Mode = "EAT",
        Prop = "p_wrappedmeat01x",
        Metabolism = {hunger = 60, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,
	},
	["consumable_kidneybeans_can"] = {
		Label = "Fasole la conserva",
        Mode = "EAT",
        Prop = "s_canbeansused01x",
        Metabolism = {hunger = 30, thirsty = 30, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_chocolate"] = {
		Label = "Ciocolata",
        Mode = "EAT",
        Prop = "s_chocolatebar02x",
        Metabolism = {hunger = 25, thirsty = false, stress = -5, health = false, stamina = 50},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_caramel"] = {
		Label = "Caramel",
        Mode = "EAT",
        Prop = "s_chocolatebar02x",
        Metabolism = {hunger = 5, thirsty = 1, stress = -5, health = false, stamina = 10},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = 1.0, 
        OverPowerHealth = false,    
	},
	["caviar"] = {
		Label = "Icre Negre",
        Mode = "EAT",
        Prop = "s_canbeansused01x",
        Metabolism = {hunger = 25, thirsty = 25, stress = -5, health = false, stamina = 10},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["roe"] = {
		Label = "Icre la conserva",
        Mode = "EAT",
        Prop = "s_canbeansused01x",
        Metabolism = {hunger = 40, thirsty = 1, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["fishchips"] = {
		Label = "Peste cu cartofi",
        Mode = "EAT",
        Prop = "p_redfishfilet01xa",
        Metabolism = {hunger = 60, thirsty = 1, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["porkbacon"] = {
		Label = "Bacon",
        Mode = "EAT",
        Prop = "p_bacon_cabbage01x",
        Metabolism = {hunger = 30, thirsty = 1, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["fishcookedlmb"] = {
		Label = "Biban Prajit",
        Mode = "EAT",
        Prop = "p_main_friedcatfish02x",
        Metabolism = {hunger = 40, thirsty = 1, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["birdmeatcook"] = {
		Label = "Carne de pasare gatita",
        Mode = "EAT",
        Prop = "p_cs_rabbitmeat02x",
        Metabolism = {hunger = 50, thirsty = 1, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["friedchicken"] = {
		Label = "Pui prajit",
        Mode = "EAT",
        Prop = "p_main_prairiechicken01x",
        Metabolism = {hunger = 50, thirsty = 1, stress = -5, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["steakveg"] = {
		Label = "Friptura cu legume",
        Mode = "BOWL",
        Prop = "p_stewplate01x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_breakfast"] = {
		Label = "Mic Dejun",
        Mode = "BOWL",
        Prop = "p_cs_platestew01x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false, --
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_meat_greavy"] = {
		Label = "Sos cu carne",
        Mode = "BOWL",
        Prop = "p_camp_plate_02x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["spaghetti"] = {
		Label = "Spaghete cu chiftele",
        Mode = "BOWL",
        Prop = "p_camp_plate_01x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["porkcooked"] = {
		Label = "Carne de porc gatita",
        Mode = "BOWL",
        Prop = "p_stewplate01x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["steakpierce"] = {
		Label = "Platou cu friptura",
        Mode = "BOWL",
        Prop = "p_crab_plate_02",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["muttoncooked"] = {
		Label = "Carne de oaie gatita",
        Mode = "BOWL",
        Prop = "p_camp_plate_02x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["deckersroast"] = {
		Label = "Tocanita cu carne",
        Mode = "BOWL",
        Prop = "p_stewplate01x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["primerib"] = {
		Label = "Costita cu legume",
        Mode = "BOWL",
        Prop = "p_cs_platestew01x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["biggamecooked"] = {
		Label = "Cotlete carne vanat",
        Mode = "BOWL",
        Prop = "p_camp_plate_01x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["scrambledeggsbacon"] = {
		Label = "Omleta cu bacon",
        Mode = "BOWL",
        Prop = "p_bowl03x",
        Metabolism = {hunger = 20, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_veggies"] = {
		Label = "Legume comestibile",
        Mode = "BOWL",
        Prop = "mp006_p_bowl_apple01x",
        Metabolism = {hunger = 20, thirsty = 15, stress = -5, health = false, stamina = false},
		Times = 3,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["consumable_fruitsalad"] = {
		Label = "Salata de fructe",
        Mode = "BOWL",
        Prop = "mp006_p_bowl_banana01x",
        Metabolism = {hunger = 15, thirsty = 15, stress = -5, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["vanillacake"] = {
		Label = "Prajitura vanilie",
        Mode = "BOWL",
        Prop = "mp006_p_bowl_banana01x",
        Metabolism = {hunger = 25, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 4,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["chococake"] = {
		Label = "Prajitura ciocolata",
        Mode = "BOWL",
        Prop = "mp006_p_bowl_banana01x",
        Metabolism = {hunger = 25, thirsty = false, stress = -5, health = false, stamina = false},
		Times = 4,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	-- DRINKS !
	["water"] = {
		Label = "Apa",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer01a",
        Metabolism = {hunger = false, thirsty = 30, stress = -2, health = false, stamina = false},
		Times = 2,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false,
        OverPowerHealth = false,
	},
	["consumable_coffee"] = {
		Label = "Cafea",
        Mode = "DRINK",
        Prop = "p_mugcoffee01x",
        Metabolism = {hunger = false, thirsty = 20, stress = -60, health = false, stamina = false},
		Times = 3,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["chocolatemilk"] = {
		Label = "Ciocolata cu lapte",
        Mode = "DRINK",
        Prop = "p_mugcoffee01x",
        Metabolism = {hunger = false, thirsty = 15, stress = -5, health = false, stamina = false},
		Times = 3,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["milk"] = {
		Label = "Lapte",
        Mode = "DRINK",
        Prop = "p_mugcoffee01x",
        Metabolism = {hunger = false, thirsty = 10, stress = -5, health = false, stamina = false},
		Times = 3,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["tea"] = {
		Label = "Ceai",
        Mode = "DRINK",
        Prop = "p_mugcoffee01x",
        Metabolism = {hunger = false, thirsty = 15, stress = -10, health = false, stamina = false},
		Times = 3,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["ginsengtea"] = {
		Label = "Ceai Ginseng",
        Mode = "DRINK",
        Prop = "p_mugcoffee01x",
        Metabolism = {hunger = false, thirsty = 15, stress = -5, health = false, stamina = false},
		Times = 3,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["vodka"] = {
		Label = "Vodka",
        Mode = "BOTTLE",
        Prop = "p_bottleredmist01x",
        Metabolism = {hunger = false, thirsty = 20, stress = -10, health = false, stamina = false},
		Times = 4,
        Alcohol = 0.3,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["beer"] = {
		Label = "Bere",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer01a",
        Metabolism = {hunger = false, thirsty = 25, stress = -20, health = false, stamina = false},
		Times = 3,
        Alcohol = 0.2,
        Effect = false,
        OverPowerStamina = 5000, 
        OverPowerHealth = false,    
	},
	["wine"] = {
		Label = "Vin",
        Mode = "BOTTLE",
        Prop = "p_bottleconklin01x",
        Metabolism = {hunger = false, thirsty = 25, stress = -20, health = false, stamina = false},
		Times = 3,
        Alcohol = 0.2,
        Effect = false,
        OverPowerStamina = 5000, 
        OverPowerHealth = false,    
	},
	["whisky"] = {
		Label = "Whisky",
        Mode = "BOTTLE",
        Prop = "p_bottleredmist01x",
        Metabolism = {hunger = false, thirsty = 15, stress = -20, health = false, stamina = false},
		Times = 3,
        Alcohol = 0.4,
        Effect = false,
        OverPowerStamina = 5000, 
        OverPowerHealth = false,    
	},
	["tequila"] = {
		Label = "Tequila",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 15, stress = -20, health = false, stamina = false},
		Times = 3,
        Alcohol = 0.4,
        Effect = false,
        OverPowerStamina = 5000, 
        OverPowerHealth = false,    
	},
	["rum"] = {
		Label = "Rom",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer01x",
        Metabolism = {hunger = false, thirsty = 20, stress = -20, health = false, stamina = false},
		Times = 5,
        Alcohol = 0.2,
        Effect = false,
        OverPowerStamina = 5000, 
        OverPowerHealth = false,    
	},
	["tuica"] = {
		Label = "Tuica",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 20, stress = -20, health = false, stamina = false},
		Times = 3,
        Alcohol = 0.35,
        Effect = false,
        OverPowerStamina = 5000, 
        OverPowerHealth = false,    
	},
    ["Consumable_moonshine_apple"] = {
		Label = "Suc de mere",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 100, stress = -10, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 200, 
        OverPowerHealth = 100,    
	},
    ["consumable_moonshine_plum"] = {
		Label = "Suc de prune",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 100, stress = -10, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 200, 
        OverPowerHealth = 100,    
	},
    ["consumable_moonshine_blackberry"] = {
		Label = "Suc de mure",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 100, stress = -10, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 200, 
        OverPowerHealth = 100,    
	},
    ["consumable_moonshine_wild_cider"] = {
		Label = "Suc de menta",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 100, stress = -10, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 200, 
        OverPowerHealth = 100,    
	},
    ["consumable_moonshine_raspberry"] = {
		Label = "Suc de zmeura",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 100, stress = -10, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 200, 
        OverPowerHealth = 100,    
	},
    ["consumable_moonshine_peach"] = {
		Label = "Suc de piersici",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 100, stress = -10, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 200, 
        OverPowerHealth = 100,    
	},
    ["consumable_moonshine"] = {
		Label = "Suc natural",
        Mode = "BOTTLE",
        Prop = "p_bottlebeer02x",
        Metabolism = {hunger = false, thirsty = 100, stress = -10, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 200, 
        OverPowerHealth = 100,    
	},
	-- DRUGS
	["cigarette"] = {
		Label = "Tigara",
        Mode = "SMOKE",
        Prop = "P_CIGARETTE01X",
        Metabolism = {hunger = false, thirsty = false, stress = -10, health = false, stamina = false},
		Times = 10,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 1.0, 
        OverPowerHealth = 1.0,    
	},
	--[[["cigar"] = {
		Label = "Trabuc",
        Mode = "SMOKE",
        Prop = "p_cigar01x",
        Metabolism = {hunger = false, thirsty = false, stress = -10, health = false, stamina = false},
		Times = 10,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = 1.0, 
        OverPowerHealth = 1.0,    
	},]]
	["joint"] = {
		Label = "Joint",
        Mode = "SMOKE",
        Prop = "P_CIGARETTE01X",
        Metabolism = {hunger = false, thirsty = false, stress = -20, health = false, stamina = false},
		Times = 5,
        Alcohol = false,
        Effect = {"PlayerDrugsHalluc01", 30000},
        OverPowerStamina = 1.0, 
        OverPowerHealth = 1.0,    
	},
	["opium"] = {
		Label = "Opiu",
        Mode = "EAT",
        Prop = "p_package09",
        Metabolism = {hunger = false, thirsty = false, stress = -50, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = {"PlayerSickDoctorsOpinionOutBad", 20000},
        OverPowerStamina = 1000.0, 
        OverPowerHealth = false,    
	},
	["hashish"] = {
		Label = "Hasis",
        Mode = "EAT",
        Prop = "p_package09",
        Metabolism = {hunger = false, thirsty = false, stress = -25, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = {"PlayerDrugsPoisonWell", 15000},
        OverPowerStamina = 100.0, 
        OverPowerHealth = 100.0,    
	},
	["morphine"] = {
		Label = "Morfina",
        Mode = "SYRINGE",
        Prop = "mp007_p_mp_syringe01x_1",
        Metabolism = {hunger = false, thirsty = false, stress = 25, health = 25, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = {"PlayerSickDoctorsOpinion", 30000},
        OverPowerStamina = 2000.0, 
        OverPowerHealth = false,    
	},
	["heroin"] = {
		Label = "Heroina",
        Mode = "EAT",
        Prop = "p_package09",
        Metabolism = {hunger = false, thirsty = false, stress = 50, health = false, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = {"PlayerKnockout_WeirdoPat", 40000},
        OverPowerStamina = 5000.0, 
        OverPowerHealth = 100.0,    
	},
	-- MEDICINE
	["bandage"] = {
		Label = "Bandaje",
        Mode = "BANDAGE",
        Prop = "p_cs_bandage01x",
        Metabolism = {hunger = false, thirsty = false, stress = -10, health = 50, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["herbmed"] = {
		Label = "Bautura medicinala",
        Mode = "BOTTLE",
        Prop = "p_bottlemedicine09x",
        Metabolism = {hunger = 15, thirsty = 15, stress = -15, health = 15, stamina = 15},
		Times = 2,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
    ["herbal_tonic"] = {
		Label = "Amestec Plante",
        Mode = "BOTTLE",
        Prop = "p_bottlemedicine09x",
        Metabolism = {hunger = 15, thirsty = 15, stress = -15, health = 15, stamina = 15},
		Times = 2,
        Alcohol = false,
        Effect = false,
        OverPowerStamina = false, 
        OverPowerHealth = false,    
	},
	["blutonic"] = {
		Label = "Blu Tonic",
        Mode = "BOTTLE",
        Prop = "p_bottlemedicine01x",
        Metabolism = {hunger = false, thirsty = 15, stress = -25, health = 25, stamina = 25},
		Times = 2,
        Alcohol = false,
        Effect = {"MP_ArrowDisorient", 15000},
        OverPowerStamina = 5000.0, 
        OverPowerHealth = false,    
	},
	["mircacleelyxir"] = {
		Label = "Elixir Miraculos",
        Mode = "BOTTLE",
        Prop = "p_bottlemedicine25x",
        Metabolism = {hunger = false, thirsty = 15, stress = 1, health = 100, stamina = false},
		Times = 1,
        Alcohol = false,
        Effect = {"PlayerSickDoctorsOpinionOutGood", 20000},
        OverPowerStamina = 5000.0, 
        OverPowerHealth = 100.0,    
	},
}
    

}

--=========================================================================
-- TRANSLATIONS
-- These messages are used when players consume/drop items.
--=========================================================================

TR = {
    ["drop"] = "Arunca",
    ["smoke"] = "Fumeaza",  
    ["youdrink"] = "You threw it almost full the ",
    ["youdrinkfull"] = "You drank the whole bottle of ",
	["youeat"] = "You just eated a ",
	["youbowlfull"] = "You eat the entire bowl of ",
	["youbowl"] = "You get a taset from the bowl, and drop almost full the ",
	["youbandage"] = "You healed a little with ",
	["yousyringe"] = "You injected yourself with ",
    ["you_drunk"] = "You got DRUNK !",
    ["you_not_drunk"] = "You are not anymore DRUNK ! YUHU...",
    ["youdrop"] = "You droped the ",
}

function NOTIFY(text)
    TriggerEvent("vorp:TipBottom", text, 5000)
end

--[[
===========================================================================
EXPORTS / EVENT USAGE
===========================================================================

PLAYER METABOLISM
1) exports["SS-Metabolism"]:GetStress()
   Returns current stress value from 0 to 100.

2) exports["SS-Metabolism"]:AddStress(amount)
   Adds stress. Example: exports["SS-Metabolism"]:AddStress(10)

3) exports["SS-Metabolism"]:RemoveStress(amount)
   Removes stress. Example: exports["SS-Metabolism"]:RemoveStress(10)

4) exports["SS-Metabolism"]:GetThirsty()
   Returns current thirsty value from 0 to 100.

5) exports["SS-Metabolism"]:AddThirsty(amount)
   Adds thirst. Example: exports["SS-Metabolism"]:AddThirsty(20)

6) exports["SS-Metabolism"]:RemoveThirsty(amount)
   Removes thirst. Example: exports["SS-Metabolism"]:RemoveThirsty(20)

7) exports["SS-Metabolism"]:GetHungry()
   Returns current hungry value from 0 to 100.

8) exports["SS-Metabolism"]:AddHungry(amount)
   Adds food. Example: exports["SS-Metabolism"]:AddHungry(20)

9) exports["SS-Metabolism"]:RemoveHungry(amount)
   Removes food. Example: exports["SS-Metabolism"]:RemoveHungry(20)

REPUTATION
10) exports["SS-Metabolism"]:GetRep()
    Returns reputation level from 0 to 10.

11) exports["SS-Metabolism"]:AddRep(amount)
    Adds internal reputation points. Internal max is 1000.

12) exports["SS-Metabolism"]:RemoveRep(amount)
    Removes internal reputation points.

HORSE METABOLISM
13) exports["SS-Metabolism"]:GetHorseHungry()
14) exports["SS-Metabolism"]:AddHorseHungry(amount)
15) exports["SS-Metabolism"]:RemoveHorseHungry(amount)

16) exports["SS-Metabolism"]:GetHorseThirsty()
17) exports["SS-Metabolism"]:AddHorseThirsty(amount)
18) exports["SS-Metabolism"]:RemoveHorseThirsty(amount)

HOUSING HUD
19) exports["SS-Metabolism"]:SetHousing(mode, number)
    mode 0 = white/default, mode 1 = green, mode 2 = red.
    number is shown in the small badge.

20) exports["SS-Metabolism"]:HousingIcon(icon)
    Uses Config.HouseIcons[icon]. Example: "stash", "outfit", "crafting".

NUI FOCUS HELPERS
TriggerEvent("SS-Metabolism:setNuiFocus", true)
TriggerEvent("SS-Metabolism:setNuiFocus", false)

DISEASE / CUSTOM HEALTH ICON
TriggerEvent("SS-METABOLISM:CLIENT:DISEASE", icon)
Example: TriggerEvent("SS-METABOLISM:CLIENT:DISEASE", "snakepoison")
The image must exist in UI/img/health as icon.png, or use "default".
===========================================================================
]]
```

{% endcode %}


# Configuration Helps

## SS-Metabolism Setup & Configuration Guide

SS-Metabolism is a RedM metabolism HUD script with a custom NUI interface. It manages hunger, thirst, stress, dirtiness, reputation, health and stamina cores, horse stats, temperature, housing indicators, voice status, clock display, HUD editing, and usable item effects.

This guide is written for server owners who want to install, configure, and test the script safely, even without deep Lua knowledge.

***

## Features Overview

SS-Metabolism includes:

* Custom Red Dead Redemption style HUD.
* Hunger, thirst, stress, dirtiness, and reputation tracking.
* Player health and stamina inner/outer cores.
* Horse health, stamina, hunger, and thirst HUD support.
* Temperature and outside degrees display.
* Housing icon support through exports.
* Voice/microphone status and pma-voice range display.
* Analog or digital in-game clock.
* HUD editor through `/sethud`.
* HUD toggle through `/shud`.
* Saved HUD positions, scale, and hidden icons.
* Usable food, drink, alcohol, drug, and medicine item support through `SS-Core`.

***

## Dependencies

### Required

* `SS-Core`
* `oxmysql`

### Used By Default

* RedM NUI
* `vorp:TipBottom`, used for notifications.

### Optional / External Behavior

* `pma-voice` for microphone talking status and voice range.
* Housing scripts can call the housing exports.
* Stable or horse scripts can send horse metabolism data.
* Medic scripts can pause metabolism while the player is hospitalized.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-Metabolism
```

Keep the resource folder name exactly:

```
SS-Metabolism
```

### 2. Import SQL

Import:

```
EXTRA/ss_metabolism.sql
```

The table is:

```
ss_metabolism
```

It stores character ID, saved metabolism values, HUD positions, HUD scale, and hidden HUD icons.

If you already had the table before this HUD editor version, run this once:

```sql
ALTER TABLE `ss_metabolism` MODIFY `opt` TEXT DEFAULT NULL;
```

This gives enough space for positions, scale, and hidden icon settings.

### 3. Start Order

Recommended start order:

```cfg
ensure oxmysql
ensure SS-Core
ensure SS-Metabolism
```

If you use `pma-voice`, make sure it is also started on your server.

### 4. Restart The Server

After importing SQL and checking start order, restart the server and test the HUD in-game.

***

## Main Files

* `fxmanifest.lua`: Resource manifest.
* `config.lua`: Main server/client configuration.
* `config.js`: UI thresholds and core max values.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.
* `UI/UI.html`: NUI page.
* `UI/css/css.css`: NUI styling.
* `UI/js/js.js`: NUI logic.
* `EXTRA/ss_metabolism.sql`: Database table.

***

## First Configuration

Open:

```
config.lua
```

The file is grouped into clear sections. Change values, not logic.

### General Settings

```lua
Dev = true
WaitBeforeLoad = 10
CommandSetHud = "sethud"
ToggleHud = "shud"
Refresh = 20
SaveRefresh = 60
ClockMode = "analog"
```

* `Dev`: Use `true` while testing. Use `false` on live servers.
* `WaitBeforeLoad`: Seconds before HUD loads after character selection.
* `CommandSetHud`: Command used to edit the HUD.
* `ToggleHud`: Command used to show/hide the HUD.
* `Refresh`: Main metabolism tick in seconds.
* `SaveRefresh`: Minimum seconds between database saves.
* `ClockMode`: `"analog"` or `"digital"`.

***

## UI Thresholds

Open:

```
config.js
```

Example:

```js
CONFIG = {
    MaxHealth: 60,
    MaxStamina: 60,
    Hungry: 20,
    Thirsty: 20,
    Stress: 80,
    Dirtiness: 80,
};
```

* `MaxHealth` and `MaxStamina`: Max outer core shown by the UI.
* `Hungry`, `Thirsty`, `Health`, and `Stamina`: Blink when below the configured value.
* `Stress` and `Dirtiness`: Blink when above the configured value.
* Horse values follow the same rule for horse HUD icons.

***

## HUD Editor

Players can use:

```
/sethud
```

This opens HUD edit mode.

In edit mode players can:

* Drag HUD icons.
* Change HUD scale with `+` and `-`.
* Hide/show every HUD icon with switches.
* Press `ESC` to save and close.

Saved settings are stored in the `opt` column in `ss_metabolism`.

If no saved position exists, the HUD uses the default bottom-centered layout.

### HUD Toggle

Players can use:

```
/shud
```

This hides or shows the full HUD.

***

## Initial Player Values

```lua
Initial = {
    Thirsty = 90,
    Hungry = 75,
    Stress = 10,
    Reputation = 100,
}
```

These values are used when a character has no saved metabolism data yet.

***

## Player Health & Stamina Cores

```lua
UseHealthStamina = true
```

If enabled, the script shows custom player health and stamina cores.

The UI uses:

* `UI/img/health`
* `UI/img/stamina`
* `UI/img/meter`

The outer core respects `MaxHealth` and `MaxStamina` from `config.js`.

***

## Horse HUD

```lua
UseHorseHealthStamina = true
HorseStats = true
HorseMetabolism = {
    Thirsty = 1,
    Hungry = 1,
}
```

* `UseHorseHealthStamina`: Shows horse health/stamina cores.
* `HorseStats`: Shows horse hunger/thirst.
* `HorseMetabolism`: Values removed every `Refresh` tick.

Horse stats appear when the player is mounted or when external horse data is sent to the script.

***

## Temperature

```lua
Temperature = {3, 35}
```

* First number: Minimum safe temperature.
* Second number: Maximum safe temperature.

Clothing can add warmth:

```lua
TemperatureSettings = {
    ["HAT"] = 1,
    ["SHIRT"] = 2,
    ["COAT"] = 5,
}
```

If the final player temperature is too low or too high, the script can affect hunger, thirst, and stress.

***

## Metabolism Decrease

```lua
Metabolism = {
    ["Idle"] = {Thirsty = 0.4, Hungry = 0.3, Stress = 0},
    ["Running"] = {Thirsty = 1.0, Hungry = 0.8, Stress = 0},
    ["Combat"] = {Thirsty = 1.2, Hungry = 1.2, Stress = 5},
}
```

* `Thirsty`: Removed from thirst.
* `Hungry`: Removed from hunger.
* `Stress`: Added to stress. Negative values remove stress.

These values apply every `Config.Refresh` tick.

***

## Low Hunger / Low Thirst Effects

```lua
MetabolismMin = 20
MetabolismStats = {
    ["THIRSTY"] = {Health = 30, Stamina = 10, Stress = 5},
    ["HUNGRY"] = {Health = 25, Stamina = 5, Stress = 5},
}
```

If hunger or thirst goes below `MetabolismMin`, the script can damage health, reduce stamina, and increase stress.

If the player is hospitalized through the medic state, metabolism decrease is paused.

***

## Stress Effects

```lua
StressRagdoll = true
RagDollObjects = true
RagDollObjectsChance = 85
DecreaseFasterStamina1 = 1.5
DecreaseFasterStamina2 = 2.0
```

High stress can make stamina drain faster and can trigger ragdoll behavior if enabled.

***

## Reputation

```lua
RepStats = true
ActiveNpcHate = true
RadiusNpc = 20.0
```

Reputation is stored internally from `0` to `1000`.

The export:

```lua
exports["SS-Metabolism"]:GetRep()
```

returns a reputation level from `0` to `10`.

Very low reputation can make NPCs walk away, run away, or become aggressive depending on config.

***

## Housing HUD

The script can show a housing icon and a small number badge.

External scripts can call:

```lua
exports["SS-Metabolism"]:SetHousing(mode, number)
```

Modes:

* `0`: White/default.
* `1`: Green.
* `2`: Red.

Example:

```lua
exports["SS-Metabolism"]:SetHousing(1, 25)
```

To change the icon:

```lua
exports["SS-Metabolism"]:HousingIcon("stash")
```

***

## Voice / Microphone HUD

The microphone HUD uses RedM mumble talking status:

```lua
MumbleIsPlayerTalking(PlayerId())
```

Voice range is read from:

```lua
LocalPlayer.state.proximity
```

This works with pma-voice style proximity state.

***

## Clock HUD

The HUD supports:

```lua
ClockMode = "analog"
```

or:

```lua
ClockMode = "digital"
```

The clock updates only when Lua sends a sync to NUI. It does not run its own JavaScript time loop.

***

## Usable Goods / Items

Items are configured in:

```lua
Config.Goods
```

Example:

```lua
["apple"] = {
    Label = "Mar",
    Mode = "EAT",
    Prop = "p_apple01x",
    Metabolism = {hunger = 20, thirsty = 10, stress = -2, health = false, stamina = false},
    Times = 1,
    Alcohol = false,
    Effect = false,
    OverPowerStamina = false,
    OverPowerHealth = false,
}
```

Important fields:

* `Label`: Item label used in messages.
* `Mode`: Animation/action type.
* `Prop`: Prop model attached during use. Use `false` to disable.
* `Metabolism.hunger`: Adds hunger.
* `Metabolism.thirsty`: Adds thirst.
* `Metabolism.stress`: Adds stress. Use a negative value to remove stress.
* `Metabolism.health`: Heals player or `false`.
* `Metabolism.stamina`: Restores stamina or `false`.
* `Times`: How many uses/sips/bites before finished.
* `Alcohol`: Drunkness amount or `false`.
* `Effect`: PostFX effect table or `false`.
* `OverPowerStamina`: Stamina core overpower duration/value or `false`.
* `OverPowerHealth`: Health core overpower duration/value or `false`.

Supported modes:

* `EAT`
* `DRINK`
* `SMOKE`
* `SYRINGE`
* `BOWL`
* `BOTTLE`
* `BANDAGE`

***

## Add A New Item

Copy an existing item and change only the values:

```lua
["my_food"] = {
    Label = "My Food",
    Mode = "EAT",
    Prop = "p_bread_13_ab_s_a",
    Metabolism = {hunger = 25, thirsty = false, stress = -2, health = false, stamina = false},
    Times = 1,
    Alcohol = false,
    Effect = false,
    OverPowerStamina = false,
    OverPowerHealth = false,
}
```

The item name must also exist in your inventory/items system.

***

## Exports

### Stress

```lua
exports["SS-Metabolism"]:GetStress()
exports["SS-Metabolism"]:AddStress(10)
exports["SS-Metabolism"]:RemoveStress(10)
```

### Thirst

```lua
exports["SS-Metabolism"]:GetThirsty()
exports["SS-Metabolism"]:AddThirsty(20)
exports["SS-Metabolism"]:RemoveThirsty(20)
```

### Hunger

```lua
exports["SS-Metabolism"]:GetHungry()
exports["SS-Metabolism"]:AddHungry(20)
exports["SS-Metabolism"]:RemoveHungry(20)
```

### Reputation

```lua
exports["SS-Metabolism"]:GetRep()
exports["SS-Metabolism"]:AddRep(100)
exports["SS-Metabolism"]:RemoveRep(100)
```

### Horse Hunger

```lua
exports["SS-Metabolism"]:GetHorseHungry()
exports["SS-Metabolism"]:AddHorseHungry(20)
exports["SS-Metabolism"]:RemoveHorseHungry(20)
```

### Horse Thirst

```lua
exports["SS-Metabolism"]:GetHorseThirsty()
exports["SS-Metabolism"]:AddHorseThirsty(20)
exports["SS-Metabolism"]:RemoveHorseThirsty(20)
```

### Housing

```lua
exports["SS-Metabolism"]:SetHousing(1, 25)
exports["SS-Metabolism"]:HousingIcon("stash")
```

***

## Events

### NUI Focus

```lua
TriggerEvent("SS-Metabolism:setNuiFocus", true)
TriggerEvent("SS-Metabolism:setNuiFocus", false)
```

### Disease / Custom Health Icon

```lua
TriggerEvent("SS-METABOLISM:CLIENT:DISEASE", "snakepoison")
```

The image must exist in:

```
UI/img/health
```

Use this to restore the default health icon:

```lua
TriggerEvent("SS-METABOLISM:CLIENT:DISEASE", "default")
```

### Horse Data

External horse scripts can send:

```lua
TriggerEvent("S!r@#Blu$$-SS-METABOLISM:CLIENT:SENDHORSE", horse, stats)
```

Where `stats` can include:

```lua
{
    thirsty = 100,
    hungry = 100
}
```

### Medical Cabinet / Hospital State

The script listens for:

```lua
TriggerEvent("SS-MedicJob:Client:MedicalCabinet", true)
TriggerEvent("SS-MedicJob:Client:MedicalCabinet", false)
```

When enabled, metabolism decrease/damage is paused.

***

## Database

Table:

```
ss_metabolism
```

Columns:

* `charid`: Character ID.
* `info`: Saved metabolism data.
* `opt`: Saved HUD settings. Use `TEXT`, because positions, scale, and hidden icons can be longer than 500 characters.

HUD settings can contain:

```json
{
  "scale": 1,
  "hidden": {
    "mic": true
  },
  "ry": {
    "left": 250,
    "top": 900
  }
}
```

***

## Troubleshooting

### HUD Does Not Show

Check:

* Resource name is `SS-Metabolism`.
* `SS-Core` starts before this resource.
* SQL table exists.
* Character selected event is being triggered.
* `Dev = true` if testing without normal character selection.

### HUD Icons Are Top-left

This should no longer happen. If a player has old or broken saved settings, open:

```
/sethud
```

Move or save again with `ESC`.

### Item Does Not Work

Check:

* Item exists in your inventory/core.
* Item name matches `Config.Goods`.
* `SS-Core` usable registration is working.
* Resource started after `SS-Core`.

### Microphone Icon Does Not Turn Green

Check:

* pma-voice/mumble is running.
* `MumbleIsPlayerTalking` exists in your RedM build.
* `LocalPlayer.state.proximity` exists for voice range.

### Clock Is Not Moving Every Second

This is intentional. The clock updates only on sync from Lua for better fidelity with server time.

### Stress Or Dirtiness Looks Full

This is intended when the value is high:

* Higher value = fuller meter.
* Lower value = emptier meter.

### Database Is Not Saving

Check:

* `oxmysql` is started.
* `ss_metabolism` table exists.
* `charid` is valid.
* `SaveRefresh` is not too high for your test.

***

## Recommended Live Checklist

Before going live, confirm:

* SQL has been imported.
* `oxmysql` starts first.
* `SS-Core` starts before this script.
* Resource folder name is `SS-Metabolism`.
* `Dev = false`.
* `Refresh` is set to a sane value, recommended `10-20+`.
* `SaveRefresh` is set to a sane value, recommended `60+`.
* Item names are checked in `Config.Goods`.
* `/sethud` works.
* `/shud` works.
* Hunger/thirst decrease works.
* Stress effects work.
* Horse HUD works if enabled.
* pma-voice microphone works if used.


# Change logs

All SS-Metabolism updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-Metabolism V1.4](/ss-metabolism/change-logs/ss-metabolism-v1.4)
* [SS-Metabolism V1.3](/ss-metabolism/change-logs/ss-metabolism-v1.3)


# SS-Metabolism V1.4

## Update Summary

SS-Metabolism keeps growing. Version 1.4 introduces a new HUD panel, icon scaling, icon visibility controls, new HUD icons, temperature display improvements, and several UI/code optimizations.

***

## Added

* Added a new HUD panel for icon management.
* Added support for up to 15 HUD icons.
* Added icon scaling, allowing players to make HUD icons bigger or smaller.
* Added hide/show controls for every HUD icon.
* Added clock display selection, allowing players to choose between digital and analog clock styles.
* Added direct HUD display for microphone and voice range.
* Added outside temperature display on the body hot/cold icon.

***

## Fixes & Improvements

* Fixed the screen moving up and down while repositioning HUD icons.
* Optimized HUD code.
* Applied UI fixes and cleanup for this release.

***

## UI & HUD

* Players can now personalize the HUD more deeply through the new panel.
* Icons can be scaled, hidden, shown, and arranged more cleanly.
* Voice, clock, and temperature information are now easier to read directly from the HUD.

***

## Preview

<figure><img src="/files/HwfOBNddMjj7TmgaIM03" alt=""><figcaption></figcaption></figure>

![](/files/bofJLquzdpbS1QmFSYTA) ![](/files/F7sK4ePIpMx8ziCIUnng) ![](/files/98dZ41alxt7pbK7wxJKx) ![](/files/HhdugdS8hfN0KNfK3uG6)


# SS-Metabolism V1.3

## Update Summary

Version 1.3 added compatibility with SS-Housing, allowing housing information to be displayed directly inside the metabolism HUD.

***

## Added

* Added compatibility with `SS-Housing`.
* Housing information can now be included in the HUD.

***

## Preview

<figure><img src="/files/dOaDINgNU8LqpMRBDoMR" alt=""><figcaption></figcaption></figure>


# SS-Telegram

SS-Telegram documentation

<figure><img src="/files/b2heSZSKr9bnBXCOahdx" alt=""><figcaption></figcaption></figure>

## Overview

**SS-Telegram** is a RedM telegram system built around immersive bird delivery, NUI telegram writing, saved telegram items, anonymous messages, money transfers, location sharing, and optional `SS-IdentityCard` integration.

The script lets players send roleplay telegrams by name, receive unread telegrams through a delivery bird flow, keep old telegrams as inventory items, and use real, fake, or official institution identities when the identity card integration is enabled.

## Main Features

* **Telegram Sending**
  * Players can send telegrams to other players by first and last name.
  * Supports normal telegrams and anonymous telegrams.
  * Supports optional money transfer inside a telegram.
  * Supports optional sender coordinates with a temporary map blip and GPS route.
* **Telegram Receiving**
  * The script checks for unread telegrams on a configurable interval.
  * New telegrams are delivered through a bird flow.
  * Players can call the bird down when they are ready to read the telegram.
  * The telegram is marked as read after it is collected.
* **Saved Telegram Items**
  * Received telegrams are saved back into the player inventory as item metadata.
  * Old telegram items can be read again later.
  * Saved telegrams can be used as roleplay evidence or shared with other players.
* **Anonymous Telegrams**
  * Anonymous telegrams use a separate item.
  * Sender identity is hidden from the receiver.
  * Anonymous telegrams use a separate bird model.
* **SS-IdentityCard Integration**
  * Uses real identity names, fake identity names, and official job/institution names.
  * Recipient search can use identity card data when enabled.
  * Official jobs can send telegrams as the job/institution name.
* **Multi-Language Support**
  * Includes language support for `EN`, `IT`, `ES`, `FR`, `DE`, `PT`, `RU`, and `RO`.
  * Supports both Lua notification text and UI text.


# Preview

Photos & Video Preview

<figure><img src="/files/b2heSZSKr9bnBXCOahdx" alt=""><figcaption><p>Normal telegram paper interface.</p></figcaption></figure>

{% embed url="<https://www.tiktok.com/@sirecstudio/video/7642393393011657986>" %}


# Configuration File

Default SS-Telegram config file.

```
-- Author: SIREC
-- Support / bug reports: https://discord.gg/9XNBaQSmMd
--
--[[
===========================================================================
 SS-Telegram Configuration
===========================================================================
 This file is written to be easy to understand even for people who do not
 work with Lua regularly.

 IMPORTANT RULES:
 1. Change values, not logic.
 2. Use Dev = true only while testing.
 3. If a feature depends on another script, disable it here when you do not
    have that resource on your server.
 4. Read README.md before changing any integrations.
===========================================================================
]]

Config = {

    --=====================================================================
    -- GENERAL SETTINGS
    --=====================================================================

    Dev = true, -- true = extra logs/dev commands | false = recommended for live server

    -- Available languages already included in l/l.lua:
    -- EN / IT / ES / FR / DE / PT / RU / RO
    Language = "EN",

    Key = 0xD9D0E1C0, -- prompt key used to call/open/read/write telegrams

    AutoSetupDatabase = true, -- true = create required tables/columns automatically on resource start

    --=====================================================================
    -- OPTIONAL / ADDON INTEGRATIONS
    -- Enable only if those resources exist on your server
    --=====================================================================

    SSIdentityCard = true, -- true = use SS-IdentityCard names/data for recipients and sender identities

    -- Jobs listed here can send telegrams using the institution/job name.
    OfficialJobs = {"police", "SheriffValentine"},

    --=====================================================================
    -- DISCORD WEBHOOK SETTINGS
    --=====================================================================

    Webhook = "", -- webhook URL | leave empty to disable logs
    WebhookTittle = "NEW TELEGRAM HAS BEEN SENT", -- webhook title

    --=====================================================================
    -- TELEGRAM DATE / UI SETTINGS
    --=====================================================================

    CustomDate = "08/1875", -- custom month/year printed in sent telegram text | false = use game date

    --=====================================================================
    -- BIRD / CAMERA SETTINGS
    --=====================================================================

    Use3DCam = false, -- true = enables optional 3D camera prompt while calling the bird
    CameraKey = 0x4BC9DABB, -- key used to switch optional 3D camera

    Model = "A_C_Eagle_01", -- normal telegram bird model
    ModelAnonymouse = "a_c_crow_01", -- anonymous telegram bird model

    --=====================================================================
    -- MONEY / ITEM SETTINGS
    --=====================================================================

    EnableSendMoney = true, -- true = players can attach money to telegrams | false = disable money option completely
    EnableShareLocation = true, -- true = players can attach location/blip/GPS | false = disable location option completely

    MaxMoneyAmount = 500, -- maximum money amount that can be sent by telegram

    Telegram = "telegram", -- usable item used to send normal telegrams
    AnonymousTelegram = "blacktelegram", -- usable item used to send anonymous telegrams

    -- true = players can send unlimited telegrams while having the item
    -- false = one item is removed for each telegram sent
    UnlimitedTelegram = false,

    --=====================================================================
    -- TIMERS / FAILSAFE SETTINGS
    --=====================================================================

    TimeCheck = 60, -- seconds between checks for new telegrams
    ResetTelegram = 600, -- seconds before stuck/dead bird reset | false = disable reset
}

function NOTIFY(text)
    -- Default VORP notification. Replace this event if your server uses another notify system.
    TriggerEvent("vorp:TipBottom", text, 5000)
end

```


# Configuration Helps

## SS-Telegram Setup & Configuration Guide

SS-Telegram is an immersive RedM telegram system with bird delivery, normal and anonymous telegrams, saved telegram items, money transfer, coordinate sharing, address book support, Discord webhook logs, and optional `SS-IdentityCard` integration.

This guide is written for server owners who want to install, configure, and test the script safely.

***

## Features Overview

SS-Telegram includes:

* Normal telegram item flow.
* Anonymous telegram item flow.
* Bird delivery for new telegrams.
* Saved telegram items with metadata.
* Money transfer through telegrams.
* Coordinate sharing with temporary map blip and GPS route.
* Address book / saved receiver list.
* Optional `SS-IdentityCard` integration.
* Official job/institution sender names.
* Discord webhook logging.
* Multi-language support.

***

## Dependencies

### Required

* `SS-Core`
* `ghmattimysql`

### Optional Integrations

* `SS-IdentityCard`

If `SSIdentityCard = true`, start `SS-IdentityCard` before `SS-Telegram`.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-Telegram
```

Keep the resource folder name exactly:

```
SS-Telegram
```

### 2. Import SQL

For VORP style character IDs, import:

```
EXTRA/ss_telegram.sql
```

For RSG style character IDs, import:

```
EXTRA/ss_telegram_rsg.sql
```

The main tables are:

```
ss_telegram
ss_telegramlist
```

### 3. Check Coordinates Column

The current script supports coordinate sharing and writes a `coords` field to `ss_telegram`.

If your SQL table does not include `coords`, run:

```sql
ALTER TABLE `ss_telegram`
ADD COLUMN `coords` varchar(500) DEFAULT NULL;
```

### 4. Start Order

Recommended start order:

```cfg
ensure ghmattimysql
ensure SS-Core
ensure SS-IdentityCard
ensure SS-Telegram
```

If `SSIdentityCard = false`, `SS-IdentityCard` is not required.

### 5. Restart The Server

After importing SQL and checking the start order, restart the server and test normal telegrams, anonymous telegrams, money transfer, and coordinate sharing.

***

## Main Files

* `fxmanifest.lua`: Resource manifest.
* `config.lua`: Main configuration.
* `l/l.lua`: Lua translations.
* `config.js`: UI translations.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.
* `UI/UI.html`: Telegram UI.
* `EXTRA/ss_telegram.sql`: VORP SQL.
* `EXTRA/ss_telegram_rsg.sql`: RSG SQL.

***

## Languages

Languages are configured in:

```
config.lua
```

Example:

```lua
Language = "RO"
```

Included languages:

* `EN`
* `IT`
* `ES`
* `FR`
* `DE`
* `PT`
* `RU`
* `RO`

Lua translations are stored in:

```
l/l.lua
```

NUI translations are stored in:

```
config.js
```

***

## First Configuration

Open:

```
config.lua
```

Start with:

```lua
Dev = true
Language = "EN"
Key = 0xD9D0E1C0
```

* `Dev`: Use `true` while testing, then set it to `false` on live servers.
* `Language`: Main script language.
* `Key`: Prompt key used for telegram interactions.

***

## SS-IdentityCard Integration

```lua
SSIdentityCard = true
OfficialJobs = {"police", "PolitiaFederala"}
```

When enabled, SS-Telegram can use:

* Real identity card names.
* Fake identity card names.
* Official job/institution sender names.
* Recipient search through identity card data.

If your server does not use SS-IdentityCard, disable it:

```lua
SSIdentityCard = false
```

***

## Telegram Items

```lua
Telegram = "telegram"
AnonymousTelegram = "blacktelegram"
UnlimitedTelegram = false
```

* `Telegram`: Item used to send normal telegrams.
* `AnonymousTelegram`: Item used to send anonymous telegrams.
* `UnlimitedTelegram`: Controls whether the item is consumed after sending.

If `UnlimitedTelegram = false`, one item is removed after a telegram is sent.

***

## Money Transfer

```lua
MaxMoneyAmount = 500
```

Players can send money through normal telegrams up to the configured maximum amount.

Recommended:

* Keep the max amount reasonable.
* Test with one player sending and another receiving.
* Confirm the money is removed from the sender and given to the receiver only once.

***

## Coordinate Sharing

The telegram UI can send the player's current coordinates.

When coordinates are included:

* The server stores them in the `coords` column.
* The receiver sees a location reference.
* A temporary map blip is created.
* A GPS route points to the shared location.
* Reading the saved telegram item later can show the location again.

Make sure the database includes:

```sql
ALTER TABLE `ss_telegram`
ADD COLUMN `coords` varchar(500) DEFAULT NULL;
```

***

## Bird Delivery

Bird settings:

```lua
Model = "A_C_Eagle_01"
ModelAnonymouse = "a_c_crow_01"
Use3DCam = false
CameraKey = 0x4BC9DABB
```

* `Model`: Bird used for normal telegrams.
* `ModelAnonymouse`: Bird used for anonymous telegrams.
* `Use3DCam`: Enables optional camera mode.
* `CameraKey`: Key for the optional camera mode.

Players must be in a valid outdoor situation before calling the telegram bird down.

***

## Timers

```lua
TimeCheck = 60
ResetTelegram = 600
```

* `TimeCheck`: How often the script checks for unread telegrams.
* `ResetTelegram`: Failsafe timer for stuck/dead bird delivery.

Use `false` to disable the reset:

```lua
ResetTelegram = false
```

***

## Webhook Logs

```lua
Webhook = ""
WebhookTittle = "NEW TELEGRAM HAS BEEN SENT"
```

Leave `Webhook` empty to disable Discord logs.

If enabled, use a private staff log channel because telegram logs may contain roleplay information.

***

## Normal Telegram Flow

1. Player uses the normal telegram item.
2. Bird spawns and flies to the player.
3. Player opens the telegram UI.
4. Player selects sender identity, receiver name, message, optional money, and optional coordinates.
5. Server finds the receiver.
6. Server inserts the telegram in `ss_telegram`.
7. Item and money are removed according to config.

***

## Anonymous Telegram Flow

1. Player uses the anonymous telegram item.
2. Bird spawns and flies to the player.
3. Player writes the telegram.
4. Sender name is saved as anonymous.
5. Receiver can read the telegram without seeing the sender's identity.

***

## Receiving Telegrams

1. Client checks for unread telegrams every `TimeCheck` seconds.
2. Player receives a notification when a telegram exists.
3. Bird delivery starts.
4. Player calls the bird down.
5. Player reads the telegram.
6. Telegram is saved as an inventory item with metadata.
7. Database row is marked as read.

***

## Saved Telegrams

After reading a new telegram, the player receives a saved telegram item.

Saved telegrams can be:

* Read again later.
* Dropped.
* Given to another player.
* Used as roleplay evidence.

***

## Troubleshooting

### The Bird Does Not Come

Check:

* Item names in `config.lua`.
* `SS-Core` usable item registration.
* Player is outside.
* Player is not mounted, tied, dead, or inside a vehicle.
* `ResetTelegram` is not blocking a stuck delivery for too long.

### Recipient Is Not Found

Check:

* First name and last name spelling.
* `SSIdentityCard` setting.
* `SS-IdentityCard` data if integration is enabled.
* Framework character table data if integration is disabled.

### Money Cannot Be Sent

Check:

* `MaxMoneyAmount`.
* Player has enough money.
* Money value is a valid whole number.
* `SS-Core` money functions work on your server.

### Coordinates Do Not Save

Check:

* `coords` column exists in `ss_telegram`.
* Server console for SQL insert errors.
* The player selected the coordinate option in the telegram UI.

### Old Telegram Item Does Not Open

Check:

* Item metadata contains `id`.
* `SS-Core` registered usable items.
* The database row still exists.

### UI Opens In The Wrong Language

Check:

* `Language` in `config.lua`.
* Language key exists in `l/l.lua`.
* UI text exists in `config.js`.
* Resource was restarted after config changes.

***

## Recommended Live Checklist

Before going live, confirm:

* SQL has been imported.
* `coords` column exists if coordinate sharing is used.
* `ghmattimysql` starts before `SS-Telegram`.
* `SS-Core` starts before `SS-Telegram`.
* `SS-IdentityCard` starts before `SS-Telegram` if enabled.
* `Dev = false`.
* Language is selected.
* Normal telegram item works.
* Anonymous telegram item works.
* New telegram delivery works.
* Saved telegram item opens.
* Money transfer works.
* Coordinate sharing works.
* Webhook is tested or left empty.


# Send a telegram

REDM SCRIPTS | SIREC STUDIO

Players send telegrams by using the configured telegram item:

```lua
Telegram = "telegram"
```

When the item is used, the telegram bird is called and the write interface opens when the player can interact with it.

***

## Normal Telegrams

Normal telegrams can include:

* Receiver first and last name.
* Sender identity.
* Telegram message.
* Optional money transfer.
* Optional current coordinates.

If `SSIdentityCard = true`, the sender can use identity card data and the receiver can be found through `SS-IdentityCard`.

***

## Anonymous Telegrams

Anonymous telegrams use:

```lua
AnonymousTelegram = "blacktelegram"
```

Anonymous telegrams hide the sender identity from the receiver.

***

## Item Consumption

```lua
UnlimitedTelegram = false
```

If `UnlimitedTelegram = false`, one telegram item is consumed after sending.

If `UnlimitedTelegram = true`, the player can keep using the item without consuming it.

***

## Official Sender Names

Official jobs can send telegrams using the institution/job name:

```lua
OfficialJobs = {"police", "PolitiaFederala"}
```

Use this for sheriff offices, police departments, federal offices, or other roleplay institutions.


# Receive a telegram

REDM SCRIPTS | SIREC STUDIO

SS-Telegram checks for unread telegrams on a configured interval:

```lua
TimeCheck = 60
ResetTelegram = 600
```

When a new telegram exists, the player receives a notification and the bird delivery flow starts.

***

## Delivery Flow

1. The script detects an unread telegram.
2. The player is notified.
3. A bird flies above the player.
4. The player calls the bird down when ready.
5. The telegram opens in the read interface.
6. The telegram is saved as an inventory item.
7. The database row is marked as read.

This avoids forcing the telegram open during combat, roleplay scenes, interiors, or other bad timing.

***

## Coordinate Telegrams

If the telegram includes coordinates, the receiver can see a location reference and temporary map route.

The database must include:

```sql
ALTER TABLE `ss_telegram`
ADD COLUMN `coords` varchar(500) DEFAULT NULL;
```

***

## Money Telegrams

If the telegram includes money, the receiver gets the money when reading the new telegram.

Old saved telegram items should not pay the money again after the first read.


# Saved telegram

REDM SCRIPTS | SIREC STUDIO

After a new telegram is read, SS-Telegram gives the player a saved telegram item with metadata.

Saved telegrams can be used for roleplay records, evidence, personal letters, contracts, threats, ransom notes, or any other story item your server allows.

***

## How Saved Telegrams Work

1. Player receives and reads a new telegram.
2. The script marks it as read in the database.
3. The script gives the player a telegram item.
4. The item metadata stores the telegram ID.
5. When the item is used later, the script loads the telegram by ID.

***

## Normal & Anonymous Saved Items

Normal telegrams use:

```lua
Telegram = "telegram"
```

Anonymous telegrams use:

```lua
AnonymousTelegram = "blacktelegram"
```

***

## Troubleshooting

If a saved telegram item does not open:

* Check that the item metadata contains `id`.
* Check that the telegram row still exists in `ss_telegram`.
* Check that `SS-Core` registered the usable item.
* Check server console for SQL errors.


# Change logs

All SS-Telegram updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-Telegram V4.5](/ss-telegram/change-logs/ss-telegram-v4.5)
* [SS-Telegram V4.4](/ss-telegram/change-logs/ss-telegram-v4.4)


# SS-Telegram V4.5

## Update Summary

SS-Telegram V4.5 is a major feature and stability update focused on the telegram sending experience, location sharing, configurable money/location options, automatic database setup, and better UI behavior.

This update also improves the bird delivery flow and adds stronger server-side validation so disabled features cannot be forced through NUI or client-side data.

***

## Added

* Added location sharing for normal telegrams.
* Added temporary map blip and GPS route support when a telegram contains shared coordinates.
* Added saved coordinate support for old telegram items, allowing location telegrams to be viewed again later.
* Added `EnableSendMoney` config option to fully enable or disable money attachments.
* Added `EnableShareLocation` config option to fully enable or disable location sharing.
* Added `AutoSetupDatabase` config option for automatic table and column setup.
* Added receiver name autocomplete/ghost preview inside the telegram UI.
* Added database repair checks for missing required columns.

***

## Location Sharing

Players can now attach their current location to a normal telegram.

When location sharing is enabled:

* the sender can select the location option from the telegram UI
* the script stores the sender coordinates in the `coords` database column
* the receiver sees the sent location zone on the telegram
* a temporary map blip is created for the shared position
* a GPS route points the receiver to the shared location
* old saved telegram items can show the shared location again when read later

When `EnableShareLocation = false`:

* the location option is hidden from the UI
* the client `getcoords` callback returns `false`
* new telegrams do not save coordinates
* old saved coordinates are ignored
* no blip or GPS route is created when receiving or reading telegrams

***

## Config & Database

Added new configuration controls in `config.lua`:

```lua
AutoSetupDatabase = true
EnableSendMoney = true
EnableShareLocation = true
```

`AutoSetupDatabase` prepares the required SQL structure on resource start.

The setup process now supports:

* `CREATE TABLE IF NOT EXISTS` for `ss_telegram`
* `CREATE TABLE IF NOT EXISTS` for `ss_telegramlist`
* `SHOW COLUMNS` checks for required fields
* `ALTER TABLE ADD COLUMN` only when a column is missing
* automatic checks for fields such as `money`, `coords`, `isread`, `destid`, sender data, and recipient data

The MySQL database/schema itself must still exist in the `oxmysql` or `ghmattimysql` connection string before the resource starts.

***

## UI Improvements

* Improved the send telegram UI flow.
* Added receiver autocomplete with a ghost text preview for faster name entry.
* Updated the UI to hide money and location options when the related config option is disabled.
* Updated location selection so the selected zone name is displayed after coordinates are captured.
* Improved read telegram metadata so shared locations can show a clear `Sent from` label.
* Preserved anonymous telegram behavior by keeping money and location options hidden for anonymous sends.

***

## Animations & Interaction

* Added improved telegram inspection animations for live telegram writing and reading.
* Added separate old telegram item interaction flow when reading saved telegrams from inventory.
* Improved enter/exit animation handling when opening or closing the telegram UI.
* Improved the player interaction flow around calling, writing, reading, and closing telegrams.

***

## Money & Security

Money sending can now be disabled completely with:

```lua
EnableSendMoney = false
```

When disabled:

* the money option is hidden from the UI
* client/NUI money values are forced to `0`
* the server ignores manually sent money values
* receivers do not receive money from disabled money telegrams

The server also keeps validation for maximum money amount, whole number checks, and sender balance checks.

***

## Bird Delivery Flow

* Improved the bird delivery logic around the player.
* Improved bird landing and hover behavior during read/send flows.
* Improved failsafe handling for stuck or invalid bird states.
* Reduced cases where birds could get stuck around buildings or bad landing positions.

***

## Stability & Performance

* Added stronger config-based validation on both client and server.
* Improved old telegram reading so disabled location sharing does not create legacy blips.
* Improved compatibility for older telegrams that stored coordinates before the dedicated `coords` column.
* Improved database compatibility with both `oxmysql` and `ghmattimysql`.
* Updated README documentation for the new configuration options, location sharing flow, automatic database setup, and troubleshooting notes.


# SS-Telegram V4.4

## Update Summary

SS-Telegram V4.4 expands the telegram system with improved documentation, identity integration notes, anonymous telegram support, money transfer guidance, coordinate sharing, saved telegram items, and clearer setup instructions for server owners.

***

## Added

* Added full GitBook documentation for installation, configuration, usage, SQL, and troubleshooting.
* Added documentation for normal and anonymous telegram items.
* Added documentation for money transfer through telegrams.
* Added documentation for coordinate sharing and the required `coords` database column.
* Added documentation for saved telegram items and metadata usage.
* Added documentation for `SS-IdentityCard` integration.
* Added documentation for official job/institution sender names.

***

## Telegram System

* Documented the bird delivery flow for new telegrams.
* Documented unread telegram checks through `TimeCheck`.
* Documented stuck/dead bird reset through `ResetTelegram`.
* Documented normal bird and anonymous bird model configuration.

***

## Config & Translations

* Documented `config.lua`, `l/l.lua`, and `config.js`.
* Added setup notes for `EN`, `IT`, `ES`, `FR`, `DE`, `PT`, `RU`, and `RO`.
* Added safe configuration examples for items, webhooks, date, camera, money, and timers.

***

## SQL & Compatibility

* Documented VORP and RSG SQL files.
* Added upgrade note for the `coords` column required by coordinate sharing.

***

## Preview

* Added GitBook preview images for normal telegram, anonymous telegram, and telegram item visuals.


# SS-Weapons

SS-Weapons documentation

<figure><img src="/files/p4fveM6jADYJkAPMK3JD" alt=""><figcaption></figcaption></figure>

**Overview**

**SS-Weapons** is a complete RedM weapon store, ammo, gunsmith, weapon customization, weapon condition, repair, cleaning, HUD, and preview system.

The script lets server owners configure weapon stores, gunsmith benches, weapon and ammo catalogs, custom weapon serials and labels, component editing, saved gunsmith templates, weapon dirt/soot/damage/permanent wear, cleaning through the native inspection flow, repair kits, ammo box usage, and optional poison/tranquilizer effects.

* **Weapon & Ammo Store System**
  * Players can buy weapons and ammo from configured stores.
  * Stores can sell all configured items or only selected weapons/ammo.
  * Custom serials and custom labels can be enabled per store.
* **Gunsmith System**
  * Configured gunsmith benches allow supported weapons to be edited.
  * Supports component, material, engraving, engraving material, tint, scope, grip, wrap, body, barrel, sight, trigger, hammer, cylinder, clip, and skin pricing.
  * Gunsmith access can be limited by job.
* **Weapon Templates**
  * Players can save a gunsmith setup as a template.
  * Templates can be applied again later or deleted.
  * Templates are saved per owner, character, weapon, and template name.
* **Weapon Wear, Cleaning & Repair**
  * Saves dirt, soot, condition, damage, and permanent rust/wear.
  * Cleaning uses the native weapon inspection flow.
  * Repair kits can reduce permanent rust/damage.
  * Weapons can be blocked from use when permanent degradation reaches the configured limit.
* **Weapon HUD & Preview**
  * Optional weapon HUD with weapon image and ammo display.
  * Gunsmith preview weapons can be synchronized to nearby players.
  * Weapon and ammo images are loaded from the NUI assets.
* **Catalog Data**
  * Includes 57 weapon entries in `cfg/weapons.lua`.
  * Includes 44 ammo entries in `cfg/ammo.lua`.
  * Supports category-based UI browsing.
* **Multi-Language Support**
  * Includes language support for `EN`, `IT`, `ES`, `FR`, `DE`, `PT`, `RU`, and `RO`.


# Preview

Photos & Video Preview

<figure><img src="/files/p4fveM6jADYJkAPMK3JD" alt=""><figcaption><p>SS-Weapons Gunsmith Bench</p></figcaption></figure>

<figure><img src="/files/1AZ8sH3XMNIznZzy7C5i" alt=""><figcaption><p>SS-Weapons Store Book</p></figcaption></figure>

<figure><img src="/files/XJVuYZSmUHgSR8Thvmjm" alt=""><figcaption><p>Inspect Weapon</p></figcaption></figure>


# Configuration File

## Main Files

SS-Weapons is configured from:

* `config.lua`: Main settings, stores, gunsmith benches, cleaning, repair, wear, HUD, preview sync, poison/tranquilizer, and prices.
* `cfg/weapons.lua`: Weapon catalog.
* `cfg/ammo.lua`: Ammo catalog.
* `l/l.lua`: Lua translations.
* `config.js`: NUI / interface translations and book UI settings.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.
* `UI/UI.html`: Weapon store and gunsmith UI.

***

## config.lua

{% code overflow="wrap" %}

```lua
Config = {
    Dev = false,
    Language = "EN",
    PressKey = 0xD9D0E1C0,
    WaitingAnime = true,

    MinLabel = 2,
    MaxLabel = 10,
    PriceForCustomSerial = 1000,
    PriceForCustomLabel = 25,

    CleanWeaponItem = "leather",
    RemoveAfterClean = true,
    CleanWeaponTime = 10000,
    MinCleanWeaponTime = 2500,
    InspectWeaponCommand = "w_inspect",
    DirtyWeaponCommand = "dirtyweapon",

    WeaponHud = {
        Enabled = false,
        Position = "top-right",
        UpdateInterval = 150,
        HideWhenUiOpen = true,
        ImagePath = "img/weapons/%s.png",
        AmmoIconPath = "img/ammo_types/%s.png",
    },

    PreviewSync = {
        Enabled = true,
        Radius = 8.0,
        MaxSpectators = 6,
        CheckInterval = 2000,
    },

    WeaponRepair = {
        Enabled = true,
        Item = "weapon_repair_kit",
        RemoveItem = true,
        RepairAmount = 0.10,
        MinRustRequired = 0.01,
    },

    UseDegradation = true,
}
```

{% endcode %}

***

## General Settings

```lua
Dev = false
Language = "EN"
PressKey = 0xD9D0E1C0
WaitingAnime = true
```

* `Dev`: Enables test/debug commands when `true`. Use `false` on live servers.
* `Language`: Translation table used by the script.
* `PressKey`: Key used to open store and gunsmith prompts.
* `WaitingAnime`: Plays idle animation while the UI is open.

***

## Custom Weapon Label & Serial

```lua
MinLabel = 2
MaxLabel = 10
PriceForCustomSerial = 1000
PriceForCustomLabel = 25
```

* `MinLabel`: Minimum custom weapon label length.
* `MaxLabel`: Maximum custom weapon label length.
* `PriceForCustomSerial`: Extra price for custom serial number.
* `PriceForCustomLabel`: Extra price for custom weapon label.

***

## Weapon HUD

```lua
WeaponHud = {
    Enabled = false,
    Position = "top-right",
    UpdateInterval = 150,
    HideWhenUiOpen = true,
}
```

Position options:

* `top-left`
* `top-center`
* `top-right`
* `middle-left`
* `center`
* `middle-right`
* `bottom-left`
* `bottom-center`
* `bottom-right`

***

## Weapon Repair

```lua
WeaponRepair = {
    Enabled = true,
    Item = "weapon_repair_kit",
    RemoveItem = true,
    RepairAmount = 0.10,
    MinRustRequired = 0.01,
}
```

* `Enabled`: Enables weapon repair.
* `Item`: Required repair item.
* `RemoveItem`: Removes one item after successful repair.
* `RepairAmount`: Amount of permanent rust/damage removed.
* `MinRustRequired`: Minimum rust required before repair is allowed.

***

## Weapon Wear

```lua
UseDegradation = true

WeaponWear = {
    SaveDirt = true,
    SaveDirtInterval = 10000,
    NativeStatusCacheInterval = 1000,
    SaveLevelDecimals = 4,
    PermanentDamageOnMaxDamage = 0.10,
    PermanentDamageOnClean = 0.02,
}
```

Weapon condition values are stored from `0.0` to `1.0`.

Example:

```
0.25 = 25%
1.0 = 100%
```

***

## Gunsmith Payment

```lua
WeaponEditPayment = {
    Type = "gold",
}
```

Payment type can be:

* `gold`
* `money`

***

## Stores & Gunsmith Benches

Stores are configured in:

```lua
Config.Stores = {
    [1] = {
        Cover = "coverbook",
        Name = "GunSmith",

        EnableStore = true,
        StoreBlip = 202506373,
        CatalogWeapon = {-281.4826, 780.6805, 119.4771, 187.0176},
        CamStore = {-281.23, 779.84, 120.00, -90.0, -180.0, 0.0, 50.0},
        WichWeapons = false,
        WichAmmo = false,
        Serial = false,
        CustomLabel = false,

        EnableGunsmith = true,
        GunSmithBlip = 1321928545,
        ModifyWeapons = {-277.2002, 778.7532, 119.4539},
        ModifyPos = {-276.20, 778.82, 119.55, 90.0, 180.0, -89.73},
        CamGunSmith = {-276.29, 778.99, 120.00, -90.0, 0.0, -90.0, 80.0},
        Jobs = {"Guvernator", "Manager", "ArmurierVAL", "Armurier"},
    },
}
```

Important fields:

* `EnableStore`: Enables the buy catalog.
* `EnableGunsmith`: Enables the gunsmith bench.
* `WichWeapons`: `false` for all weapons, `{}` for none, or a list of weapon keys.
* `WichAmmo`: `false` for all ammo, `{}` for none, or a list of ammo item keys.
* `Jobs`: Jobs allowed to use the gunsmith bench.

***

## Weapon Catalog

Weapons are configured in:

```
cfg/weapons.lua
```

Example:

```lua
["WEAPON_REVOLVER_CATTLEMAN"] = {
    Weapon = "WEAPON_REVOLVER_CATTLEMAN",
    Label = "Cattleman Revolver",
    Tittle = "Cattleman Revolver",
    Description = "The Cattleman Revolver is a dependable weapon...",
    Category = "Revolver",
    Price = 50,
    Gold = 0,
    BuyJobs = {},
    BuyJobsGrade = {},
    ModifyJobs = {},
    ModifyJobsGrade = {},
    Typ = "WEAPON",
}
```

***

## Ammo Catalog

Ammo is configured in:

```
cfg/ammo.lua
```

Example:

```lua
["ammorevolvernormal"] = {
    Item = "ammorevolvernormal",
    Label = "Revolver Normal Ammo",
    Category = "Ammo",
    Price = 50,
    Gold = 0,
    Type = "AMMO_REVOLVER",
    MaxAmmo = 200,
    Amount = 100,
}
```

* `Type`: Ammo type added to the player belt.
* `MaxAmmo`: Maximum ammo allowed in the belt.
* `Amount`: Bullets added by one ammo box.


# Configuration Helps

## SS-Weapons Setup & Configuration Guide

SS-Weapons is a RedM weapon store, ammo, gunsmith, customization, weapon condition, cleaning, repair, HUD, and preview system.

This guide is written for server owners who want to install, configure, and test the script safely.

***

## Features Overview

SS-Weapons includes:

* Weapon stores with configurable weapon and ammo catalogs.
* Ammo boxes that add bullets to the player's ammo belt.
* Gunsmith benches with job restrictions.
* Weapon component customization.
* Gunsmith templates for saving and reusing component setups.
* Custom weapon serial and custom weapon label support.
* Persistent weapon dirt, soot, condition, damage, and rust/wear.
* Weapon cleaning through the native inspection flow.
* Weapon repair with configurable repair item.
* Optional weapon HUD with weapon image and ammo count.
* Gunsmith preview sync for nearby players.
* Optional poison and tranquilizer effects.
* Multi-language support.

***

## Dependencies

### Required

* `SS-Core`
* `ghmattimysql`
* `vorp_inventory`

### Used By Default

* `@SS-Core/dataview.lua`
* `vorp:NotifyLeft` in the default `NOTIFY` function.
* RedM/RDR3 weapon native functions.

### Optional Integrations

* `SS-Notify`, if you switch the `NOTIFY` function to the included commented example.
* `SS-PlayerShops`, if you use the external player shop open/buy flow already supported by the client.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-Weapons
```

Keep the resource folder name exactly:

```
SS-Weapons
```

The script checks the resource name, and the NUI expects `SS-Weapons`.

### 2. Database

SS-Weapons creates and upgrades its own extra tables automatically:

```
ss_weapons
ss_weaponstemp
```

The script also reads and updates your existing weapon `loadout` table.

Make sure your server already has the standard weapon/loadout setup used by `SS-Core` and your inventory.

### 3. Start Order

Recommended:

```cfg
ensure ghmattimysql
ensure vorp_inventory
ensure SS-Core
ensure SS-Weapons
```

If you use `SS-Notify`, start it before `SS-Weapons`.

### 4. Restart The Server

After checking dependencies, start order, and config, restart the server and test one store, one gunsmith bench, one ammo box, one cleaning item, and one repair item.

***

## Main Files

* `fxmanifest.lua`: Resource manifest.
* `config.lua`: Main configuration.
* `cfg/weapons.lua`: Weapon catalog.
* `cfg/ammo.lua`: Ammo catalog.
* `l/l.lua`: Lua translations.
* `config.js`: UI translations and book UI settings.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.
* `UI/UI.html`: Weapon store and gunsmith UI.

***

## Languages

Languages are configured in:

```
config.lua
```

Example:

```lua
Language = "RO"
```

Included languages:

* `EN`
* `IT`
* `ES`
* `FR`
* `DE`
* `PT`
* `RU`
* `RO`

Lua translations are in:

```
l/l.lua
```

UI translations are in:

```
config.js
```

***

## First Configuration

Open:

```
config.lua
```

Start with:

```lua
Dev = false
Language = "EN"
PressKey = 0xD9D0E1C0
WaitingAnime = true
```

* `Dev`: Keep `false` on live servers.
* `Language`: Main script language.
* `PressKey`: Key used to open store and gunsmith prompts.
* `WaitingAnime`: Keeps the player in an idle animation while UI is open.

***

## Stores

Stores are configured in:

```
config.lua
```

Each store can enable a buy catalog, a gunsmith bench, or both.

```lua
EnableStore = true
EnableGunsmith = true
```

Use these fields to control what each store sells:

```lua
WichWeapons = false
WichAmmo = false
```

Meaning:

* `false`: Sell all configured weapons/ammo.
* `{}`: Sell nothing from that type.
* `{ "WEAPON_REVOLVER_CATTLEMAN" }`: Sell only listed entries.

***

## Add A New Store

Copy an existing store entry and change the name, positions, cameras, blips, and jobs.

```lua
[5] = {
    Cover = "coverbook",
    Name = "Annesburg",

    EnableStore = true,
    StoreBlip = 202506373,
    CatalogWeapon = {2946.54, 1319.93, 44.82, 246.31},
    CamStore = {2947.55, 1319.71, 45.62, -90.0, 110.0, 0.0, 50.0},
    WichWeapons = false,
    WichAmmo = false,

    EnableGunsmith = true,
    GunSmithBlip = 202506373,
    ModifyWeapons = {2949.89, 1314.15, 44.91},
    ModifyPos = {2949.89, 1314.15, 44.91, 90.0, 163.0, 178.0},
    CamGunSmith = {2950.21, 1314.14, 45.41, -90.0, 200.0, 0.0, 80.0},
    Jobs = {"Armurier"},
},
```

After adding a store, restart the resource and test both prompt positions.

***

## Weapon Catalog

Weapons are configured in:

```
cfg/weapons.lua
```

Each weapon can control:

* Weapon hash/name.
* Label and title.
* Description and extra text.
* Category.
* Money price.
* Gold value.
* Buy job restrictions.
* Modify job restrictions.
* Weapon type.

If a weapon should only be sold to specific jobs, fill:

```lua
BuyJobs = {"police"}
BuyJobsGrade = {2}
```

If everyone can buy it, leave:

```lua
BuyJobs = {}
BuyJobsGrade = {}
```

***

## Ammo Catalog

Ammo is configured in:

```
cfg/ammo.lua
```

Important fields:

* `Item`: Inventory item name.
* `Label`: UI label.
* `Category`: UI category.
* `Price`: Price per ammo box.
* `Type`: Ammo type added to the belt.
* `MaxAmmo`: Maximum belt amount.
* `Amount`: Bullets added by one box.

Example:

```lua
["ammorevolvernormal"] = {
    Item = "ammorevolvernormal",
    Label = "Revolver Normal Ammo",
    Price = 50,
    Type = "AMMO_REVOLVER",
    MaxAmmo = 200,
    Amount = 100,
}
```

***

## Buying Flow

Weapon buying works like this:

1. Player opens a configured store.
2. UI displays weapons and ammo by category.
3. Player chooses custom serial or label if the store allows it.
4. Client asks the server if the player has money and carry space.
5. Server gives the weapon or ammo item.
6. Ammo boxes can later be used to add bullets to the ammo belt.

***

## Gunsmith Flow

Gunsmith editing works like this:

1. Player equips a supported weapon.
2. Player goes to a gunsmith bench.
3. Script checks job access.
4. Preview weapon spawns on the bench.
5. UI opens component notes and selections.
6. Player changes components and sees the price update.
7. Server syncs preview changes to nearby spectators if enabled.
8. Player pays and saves components to the weapon loadout.

***

## Gunsmith Prices

Gunsmith prices are configured in:

```lua
GunSmith = {
    ["GRIP"] = {
        ["COMP"] = 45,
        ["MATERIAL"] = 20,
        ["ENGRAVE"] = 20,
        ["ENGRAVEM"] = 20,
        ["TINT"] = 20,
    },
}
```

Payment type:

```lua
WeaponEditPayment = {
    Type = "gold",
}
```

Use `gold` or `money`.

***

## Gunsmith Templates

Templates let players save, apply, and delete weapon component setups.

Stored table:

```
ss_weaponstemp
```

Templates are saved by:

* Identifier.
* Character ID.
* Weapon.
* Template name.

***

## Weapon Cleaning

Cleaning settings:

```lua
CleanWeaponItem = "leather"
RemoveAfterClean = true
CleanWeaponTime = 10000
MinCleanWeaponTime = 2500
InspectWeaponCommand = "w_inspect"
```

Cleaning uses the native weapon inspection flow and can reduce dirt, soot, and runtime degradation.

***

## Weapon Repair

Repair settings:

```lua
WeaponRepair = {
    Enabled = true,
    Item = "weapon_repair_kit",
    RemoveItem = true,
    RepairAmount = 0.10,
    MinRustRequired = 0.01,
}
```

Repair reduces permanent rust/damage stored by the script.

***

## Weapon Wear

Stored table:

```
ss_weapons
```

The script stores:

* Serial number.
* Weapon name.
* Last loadout ID.
* Dirt level.
* Soot level.
* Condition level.
* Damage level.
* Rust/permanent wear level.

When `UseDegradation = true`, permanent wear can eventually make a weapon unusable.

***

## Weapon HUD

Weapon HUD settings:

```lua
WeaponHud = {
    Enabled = false,
    Position = "top-right",
    UpdateInterval = 150,
    HideWhenUiOpen = true,
}
```

Weapon icons are loaded from:

```
UI/img/weapons
```

Ammo icons are loaded from:

```
UI/img/ammo_types
```

***

## Preview Sync

Preview sync settings:

```lua
PreviewSync = {
    Enabled = true,
    Radius = 8.0,
    MaxSpectators = 6,
    CheckInterval = 2000,
}
```

When enabled, nearby players can see the gunsmith preview weapon while someone edits it.

***

## Poison & Tranquilizer

These systems are disabled by default:

```lua
ActivePoison = false
ActiveTranq = false
```

Enable them only if your server intentionally uses poison arrow or tranquilizer gameplay.

***

## Dev Commands

These commands are only for testing and require:

```lua
Dev = true
```

Commands:

* `/dirtyweapon`
* `/wstatus`
* `/wdirt`
* `/wsoot`
* `/wdegradation`
* `/wdamage`
* `/wthreshold`
* `/wwear`
* `/wresetwear`

Normal inspect command:

```
/w_inspect
```

***

## Troubleshooting

### Store Prompt Does Not Appear

Check:

* `EnableStore = true`.
* `CatalogWeapon` coordinates.
* `PressKey`.
* Resource folder name is exactly `SS-Weapons`.

### Gunsmith Prompt Does Not Appear

Check:

* `EnableGunsmith = true`.
* `ModifyWeapons` coordinates.
* Player job is allowed in `Jobs`.

### Player Cannot Edit Weapon

Check:

* Weapon is equipped.
* Weapon is supported by component data.
* Player re-equipped the weapon after receiving it.
* Job restrictions allow the player.

### Player Cannot Buy

Check:

* Player has enough money.
* Carry limits from `SS-Core`.
* Weapon exists in `cfg/weapons.lua`.
* Ammo exists in `cfg/ammo.lua`.

### Ammo Item Does Not Add Bullets

Check:

* Ammo item name matches the inventory item.
* `Type` is correct.
* Belt is not already full.
* `MaxAmmo` and `Amount` are correct.

### Weapon HUD Image Is Missing

Check:

* Weapon image exists in `UI/img/weapons`.
* File name matches the lower-case weapon name.
* Ammo icon exists in `UI/img/ammo_types`.

### Cleaning Does Not Work

Check:

* Player has `CleanWeaponItem`.
* Weapon is equipped.
* Native inspection starts.
* `RemoveAfterClean` is configured correctly.

### Repair Does Not Work

Check:

* `WeaponRepair.Enabled = true`.
* Player has the repair item.
* Weapon has at least `MinRustRequired` permanent damage.

***

## Recommended Live Checklist

Before going live, confirm:

* `ghmattimysql` starts before `SS-Weapons`.
* `vorp_inventory` starts before `SS-Weapons`.
* `SS-Core` starts before `SS-Weapons`.
* Resource folder is named `SS-Weapons`.
* `Dev = false`.
* Stores open correctly.
* Gunsmith benches open correctly.
* Weapon buying works.
* Ammo buying and ammo item usage work.
* Gunsmith edit/save works.
* Template save/apply/delete works.
* Weapon cleaning works.
* Weapon repair works.
* Weapon HUD works if enabled.
* Preview sync works if enabled.

***

## Editing Rules For Beginners

When editing Lua:

* Strings use quotes: `"text"`.
* Table entries usually end with a comma: `,`.
* `true` enables a feature.
* `false` disables a feature or means all/everyone depending on the field.
* Numbers do not use quotes.
* Coordinates use `{x, y, z}` or `{x, y, z, heading}` style.
* Do not rename the resource folder.

Bad:

```lua
Dev = "false"
```

Good:

```lua
Dev = false
```


# Change logs

All SS-Weapons updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-Weapons V1.0](/ss-weapons/change-logs/ss-weapons-v1.0)


# SS-Weapons V1.0

## Update Summary

Initial GitBook documentation release for SS-Weapons, covering weapon stores, ammo boxes, gunsmith customization, weapon templates, cleaning, repair, weapon wear, HUD, preview sync, and configuration setup.

***

## Added

* Added full GitBook documentation for SS-Weapons.
* Added setup and configuration guide for server owners.
* Added weapon store and gunsmith configuration documentation.
* Added weapon catalog and ammo catalog documentation.
* Added weapon cleaning, repair, and wear documentation.
* Added weapon HUD and preview sync documentation.
* Added troubleshooting and live checklist.

***

## Weapon Store System

* Documented configurable stores through `Config.Stores`.
* Documented weapon and ammo filtering through `WichWeapons` and `WichAmmo`.
* Documented custom serial and custom label settings.

***

## Gunsmith System

* Documented gunsmith benches and job restrictions.
* Documented component edit pricing.
* Documented payment type selection between `gold` and `money`.
* Documented template save, apply, and delete workflow.

***

## Weapon Condition System

* Documented persistent condition storage in `ss_weapons`.
* Documented cleaning item flow.
* Documented repair kit flow.
* Documented permanent wear and degradation behavior.

***

## Config & Translations

* Documented `config.lua`, `cfg/weapons.lua`, `cfg/ammo.lua`, `l/l.lua`, and `config.js`.
* Added setup notes for `EN`, `IT`, `ES`, `FR`, `DE`, `PT`, `RU`, and `RO`.

***

## Preview

* Added GitBook preview images for the catalog, gunsmith UI, weapon book UI, weapon icon, and ammo icon.


# SS-Farming


# SS-IdentityCard

SS-IdentityCard documentation

<figure><img src="/files/mYvSMTVaOLLzqj0zS7QY" alt=""><figcaption></figcaption></figure>

**Overview**

**SS-IdentityCard** is a **fully customizable identity system** for FiveM, designed to integrate seamlessly into roleplay servers. This system allows players to **register their real or fake identity**, providing them with an **in-game ID card** that can be used for various roleplay interactions, police verifications, and business transactions.

With **support for fake identities**, immigration stamps, and seamless integration with **other SS scripts**, SS-IdentityCard enhances realism while allowing for unique RP scenarios such as **criminal identity forgery** or **law enforcement identity checks**.

* **Real & Fake Identity System**
  * Players can register a **real identity card** with their personal details.
  * **Fake IDs** are available, allowing players to assume a false identity.
  * Admin-configurable **limitations on fake IDs**, including **deletion restrictions** and costs.
* **Seamless Integration with SS Scripts**
  * Compatible with **SS-Archives** (for storing fines and legal records).
  * Works with **SS-Licenses**, **SS-Housing**, **SS-Boats**, **SS-TrainTransport**, and more.
  * Connects with **SS-MedicArchives**, allowing medical records to be linked to an ID.
* **In-Game Image Uploading**
  * Players can **upload or update** their ID photo directly in-game.
  * Custom server branding with **server name displayed on the ID**.
* **National Registration Offices**
  * **Multiple registration offices** available across major cities, including:
    * **Valentine**
    * **Blackwater**
    * **Rhodes**
    * **Saint Denis**
  * **Illegal ID services** available in certain locations for criminals.
* **Identity Card Management**
  * Players can **pay for a new ID**, request **copies**, or **update their information**.
  * **Admins can configure fees** for registrations, copies, and updates.
  * Police jobs can be configured to **view and verify** identity cards.
* **Fully Configurable and Optimized**
  * **Configurable menu keybind and layout** (`right` or `left` alignment).
  * **Blacklist jobs** (e.g., police, marshal) from appearing on ID cards.
  * **Server-specific birth years** and age limits.
  * **Police access restrictions** to ID verifications.
  * **Synced with in-game economy**, allowing ID payments to be redirected to police funds.


# Preview

Photos & Video Preview

<figure><img src="/files/mYvSMTVaOLLzqj0zS7QY" alt="SS-IdentityCard Redm Script"><figcaption><p>SS-IdentityCard UI</p></figcaption></figure>


# Configuration File

Default Configuration File config.lua

{% code overflow="wrap" %}

```lua
-- Author: SIREC
-- Support / bug reports: https://discord.gg/9XNBaQSmMd
--
--[[
===========================================================================
 SS-IdentityCard Configuration
===========================================================================
 This file is written to be easy to understand even for people who do not
 work with Lua regularly.

 IMPORTANT RULES:
 1. Change values, not logic.
 2. Use Dev = true only while testing.
 3. If a feature depends on another script, disable it here when you do not
    have that resource on your server.
 4. Read README.md before changing any integrations.
===========================================================================
]]

Config = {

    --=====================================================================
    -- GENERAL SETTINGS
    --=====================================================================

    Dev = false, -- true = extra logs/dev info | false = recommended for live server

    -- Available languages already included in l/l.lua:
    -- EN / IT / ES / FR / DE / PT / RU / RO
    Language = "EN",

    Key = 0xD9D0E1C0, -- key used to open the office menu
    Align = "right", -- menu alignment

    NXTInventory = false, -- true only if your server uses NXTInventory integration
    ServerName = "Sirec Studio", -- shown as the authority/sign under the ID photo

    -- Discord webhook settings
    WebHook = "", -- webhook URL | leave empty to disable
    WebHookInfo = "HAS REGISTERED HIS IDENTITY CARD ID WITH NR",
    WebHookUpdate = "HAS UPDATED HIS IDENTITY CARD",

    --=====================================================================
    -- OPTIONAL / ADDON INTEGRATIONS
    -- Enable only if those resources exist on your server
    --=====================================================================

    ImigrationStamp = "stampilabilet", -- usable item used for immigration stamp in/out
    SSMedicArchives = true,
    SSArchives = true, -- enables fines/payment integration
    SSLicenses = true, -- enables licenses menu
    SSHousing = true, -- enables house certificate menu
    SSPlayerShops = true, -- enables shop certificate menu
    SSBoats = true, -- enables boat certificate menu
    SSTrainTransport = true, -- enables train ticket button/event
    SSPrimary = true, -- enables jobs panel button/event
    SSCommunityJobs = true, -- enables community jobs button/event

    --=====================================================================
    -- REAL IDENTITY CARD SETTINGS
    --=====================================================================

    IdentityCardItem = "identitycard", -- usable inventory item for the real ID card
    PayRegistration = 5, -- false = free | number = registration price
    PayCopyRegistration = 1, -- false = free copy | number = copy price
    PayInfoUpdate = 1, -- false = free update | number = update price
    AllowImageInGame = true, -- true = players can add/update image URL from UI

    --=====================================================================
    -- FAKE IDENTITY CARD SETTINGS
    --=====================================================================

    FakeIdentityCardItem = "salt", -- usable inventory item for the fake ID card
    PayFakeId = 250, -- false = disable fake registration price | number = price
    PayFakeCopyId = 150, -- false = free fake copy | number = fake copy price
    Only1FakeId = false, -- true = player can only ever keep one fake ID at a time
    PayDeleteFakeId = 1000, -- false = free delete | number = delete fake ID price

    --=====================================================================
    -- JOB / PRIVACY / MONEY SETTINGS
    --=====================================================================

    SynSociety = "police", -- job account that receives fine money | false = disable
    SSBank = false, -- bank integration placeholder, keep false unless you support it

    -- Jobs listed here will not be shown on the visible ID card.
    BlackListJobs = {"police", "marshal"},
    ReplaceBlackListJobs = "Unemployed", -- replacement text shown instead of blacklisted job
    FakeIdDefaultJob = "Unemployed", -- job text always shown on fake identity cards

    -- Which jobs are allowed to inspect / stamp / work with identity card data.
    -- false = everyone can interact with this part of the script
    PoliceJobs = false, -- example: {"police", "marshall"}

    --=====================================================================
    -- AGE / SERVER LORE SETTINGS
    --=====================================================================

    ServerYear = 1905, -- year printed on registrations and used to validate age
    MaxYears = 80, -- maximum player age allowed on registration
    MinYears = 18, -- minimum player age allowed on registration

    --=====================================================================
    -- VISUAL / ANIMATION SETTINGS
    --=====================================================================

    UseAnimProp = true, -- true = show card prop + animation while presenting the ID

    --=====================================================================
    -- NATIONAL REGISTRATION OFFICES
    -- Each office creates an NPC and optional blip.
    -- FakeServices = true means this office opens the fake ID menu.
    -- Pos format = {x, y, z, heading}
    --=====================================================================

    NationalRegistration = {
        [1] = {
            City = "Valentine", -- city printed on IDs registered here
            FakeServices = false, -- false = real ID office | true = fake ID office
            Name = "Valentine NR Office", -- menu/blip title
            Desc = "NATIONAL OFFICE", -- menu subtitle/description
            NpcModel = "S_M_M_VHTDEALER_01", -- NPC model
            Pos = {-175.2606048584, 631.74407958984, 113.08966064454, 320.85287475586},
            Distance = 3.0, -- interaction distance
            Blip = 587827268, -- blip hash | false = hide blip
        },
        [2] = {
            City = "Blackwater",
            FakeServices = false,
            Name = "BlackWater NR Office",
            Desc = "NATIONAL OFFICE",
            NpcModel = "S_M_M_VHTDEALER_01",
            Pos = {-762.0810546875, -1272.1394042968, 43.050540924072, 86.552299499512},
            Distance = 3.0,
            Blip = 587827268,
        },
        [3] = {
            City = "Rhodes",
            FakeServices = false,
            Name = "Rhodes NR Office",
            Desc = "NATIONAL OFFICE",
            NpcModel = "S_M_M_VHTDEALER_01",
            Pos = {1230.1987304688, -1298.5638427734, 75.904258728028, 232.19049072266},
            Distance = 3.0,
            Blip = 587827268,
        },
        [4] = {
            City = "Saint Denis",
            FakeServices = false,
            Name = "Saint Denis NR Office",
            Desc = "NATIONAL OFFICE",
            NpcModel = "S_M_M_VHTDEALER_01",
            Pos = {2747.9025878906, -1396.4379882812, 46.183067321778, 24.291278839112},
            Distance = 3.0,
            Blip = 587827268,
        },
        [5] = {
            City = "Saint Denis",
            FakeServices = true,
            Name = "Mrs Thomson",
            Desc = "NATIONAL OFFICE",
            NpcModel = "S_M_M_VHTDEALER_01",
            Pos = {2859.19140625, -1202.2645263672, 48.590869903564, 1.381891965866},
            Distance = 3.0,
            Blip = false,
        },
        [6] = {
            City = "Annesburg",
            FakeServices = false,
            Name = "Oficiul Postal Annesburg",
            Desc = "Oficiu Postal",             
            NpcModel = "s_m_m_nbxriverboatguards_01",
            Pos = {2938.853759765625, 1286.9677734375, 43.75288391113281, -22.61572074890136},
            Distance = 3.0,
            Blip = -1656531561,
        },
    },
}

function NOTIFY(text)
    TriggerEvent("vorp:TipBottom", text, 5000)
end

--[[
===========================================================================
EXPORTS / CALLBACK USAGE
===========================================================================

1) exports["SS-IdentityCard"]:GetIdentityCard()
   Returns your loaded real identity card table or false.

2) exports["SS-IdentityCard"]:GetIdentityFakeCard()
   Returns your loaded fake identity card table or false.

3) exports["SS-IdentityCard"]:GetIdCard(recordid)
   Returns a specific identity card from the server by record ID.

4) SSCORE.TriggerServerCallback("SS-IDENTITYCARD:SERVER:GETDATA", function(allIds)
   Returns all identity cards.
end)

5) SSCORE.TriggerServerCallback("S!r@#Blu$$-SS-ARCHIVES:SERVER:GETIDCARD", function(idCard)
   Returns one specific identity card by ID number / record ID.
end, idcard)

REGISTER THROUGH TRIGGER WITH THESE FIELDS:
local info = {
    year = "1855",
    eyes = "blue",
    recordid = "K54V86Y73",
    sex = "M",
    city = "Saint Denis",
    firstname = "Fane",
    lastname = "Baboia",
    kg = "80",
    date = "04-11-1905",
    month = "12",
    dob = "1855-12-11",
    cm = "180",
    hair = "black",
    day = "11"
}
TriggerServerEvent("S!r@#Blu$$-SS-IDENTITYCARD:SERVER:REGISTERID", info)
]]

```

{% endcode %}


# Configuration Helps

## SS-IdentityCard Setup & Configuration Guide

SS-IdentityCard is an identity card system for RedM. It supports real ID cards, fake ID cards, national registration offices, immigration stamps, fines integration, licenses integration, and multiple optional integrations with other Sirec Studio scripts.

This guide is written for server owners who want to install, configure, and test the script safely, even without deep Lua knowledge.

***

## Features Overview

SS-IdentityCard includes:

* Real identity card registration at national registration offices.
* Player information updates after registration.
* Real ID card copies.
* Fake identity card creation, fake copies, and fake ID removal.
* Identity card display for the owner and nearby players.
* Immigration stamp in/out support.
* Fine payment integration.
* Optional integrations with licenses, housing, boats, player shops, train transport, archives, and jobs panel systems.
* Multi-language support.

***

## Dependencies

### Required

* `SS-Core`
* `oxmysql`

### Used By Default

* `menuapi`
* `vorp:TipBottom`, used for notifications.

### Optional Integrations

* `SS-Archives`
* `SS-MedicArchives`
* `SS-Licenses`
* `SS-Housing`
* `SS-PlayerShops`
* `SS-Boats`
* `SS-TrainTransport`
* `SS-Primary`
* `SS-JoinScene`

If you do not use an optional integration, disable it in `config.lua`.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-IdentityCard
```

Keep the resource folder name exactly:

```
SS-IdentityCard
```

### 2. Import SQL

Import the main SQL file:

```
EXTRA/sql.sql
```

If your existing table is old and does not include immigration or fines fields, also check:

```
EXTRA/imigration.sql
```

The main database table is:

```
ss_identitycard
```

It stores identifier data, character ID, record ID, real and fake identity data, image URL, immigration status, and fines total.

### 3. Start Order

Recommended start order:

```cfg
ensure oxmysql
ensure SS-Core
ensure SS-IdentityCard
```

### 4. Restart The Server

After importing SQL and checking the start order, restart the server and test the registration flow in-game.

***

## Main Files

* `fxmanifest.lua`: Resource manifest.
* `config.lua`: Main configuration.
* `l/l.lua`: Translations.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.
* `UI/UI.html`: Identity card UI page.

***

## Languages

Languages are configured in:

```
l/l.lua
```

Included languages:

* `EN`
* `IT`
* `ES`
* `FR`
* `DE`
* `PT`
* `RU`
* `RO`

Example:

```lua
Language = "RO"
```

If an invalid language is set, the script falls back to `EN`.

***

## First Configuration

Open:

```
config.lua
```

The file is grouped into clear sections for general settings, card settings, fake ID settings, integrations, offices, registration behavior, and notifications.

### General Settings

```lua
Dev = true
Language = "EN"
Key = 0xD9D0E1C0
Align = "right"
ServerName = "Sirec Studio"
```

* `Dev`: Use `true` while testing. Use `false` on live servers.
* `Language`: Translation language used by the script.
* `Key`: Key used to open office interactions.
* `Align`: Menu alignment, usually `"left"` or `"right"`.
* `ServerName`: Authority or server name displayed on the ID card.

### Real ID Card Settings

```lua
IdentityCardItem = "identitycard"
PayRegistration = 5
PayCopyRegistration = 1
PayInfoUpdate = 1
AllowImageInGame = true
```

* `IdentityCardItem`: Item used to show a real identity card.
* `PayRegistration`: Registration price. Use `false` to make registration free.
* `PayCopyRegistration`: Copy price. Use `false` to make copies free.
* `PayInfoUpdate`: Information update price. Use `false` to make updates free.
* `AllowImageInGame`: Allows players to upload or update their ID image URL in-game.

### Fake ID Settings

```lua
FakeIdentityCardItem = "salt"
PayFakeId = 250
PayFakeCopyId = 150
Only1FakeId = false
PayDeleteFakeId = 1000
```

* `FakeIdentityCardItem`: Usable item for fake identity cards.
* `PayFakeId`: Price for registering a fake ID.
* `PayFakeCopyId`: Price for a fake ID copy.
* `Only1FakeId`: Controls whether players can have only one fake ID at a time.
* `PayDeleteFakeId`: Cost to remove a fake identity.

### Job Privacy Settings

```lua
BlackListJobs = {"police", "marshal"}
ReplaceBlackListJobs = "Unemployed"
FakeIdDefaultJob = "Unemployed"
PoliceJobs = false
```

* `BlackListJobs`: Jobs hidden from the visible ID card.
* `ReplaceBlackListJobs`: Replacement text shown instead of blacklisted jobs.
* `FakeIdDefaultJob`: Job text always shown on fake IDs.
* `PoliceJobs`: Jobs allowed to access protected identity interactions. Use `false` to allow everyone.

***

## Optional Integrations

Only enable integrations for scripts that are actually installed on your server:

```lua
SSMedicArchives = true
SSArchives = true
SSLicenses = true
SSHousing = true
SSPlayerShops = true
SSBoats = true
SSTrainTransport = true
SSPrimary = true
```

If you do not have one of these scripts, set the related option to `false`.

***

## National Registration Offices

Registration offices are configured in:

```lua
Config.NationalRegistration
```

Example:

```lua
[1] = {
    City = "Valentine",
    FakeServices = false,
    Name = "Valentine NR Office",
    Desc = "NATIONAL OFFICE",
    NpcModel = "S_M_M_VHTDEALER_01",
    Pos = {-175.26, 631.74, 113.08, 320.85},
    Distance = 3.0,
    Blip = 587827268,
},
```

Important fields:

* `City`: City printed on IDs registered at this office.
* `FakeServices`: `true` opens fake ID services instead of real ID services.
* `Name`: Office name in the menu or blip.
* `Desc`: Menu subtitle.
* `NpcModel`: NPC model used at the office.
* `Pos`: Office coordinates in `x, y, z, heading` format.
* `Distance`: Interaction range.
* `Blip`: Blip hash or `false`.

### Add A New Office

Copy an existing office and change only the values:

```lua
[6] = {
    City = "Strawberry",
    FakeServices = false,
    Name = "Strawberry NR Office",
    Desc = "NATIONAL OFFICE",
    NpcModel = "S_M_M_VHTDEALER_01",
    Pos = {-1800.0, -350.0, 160.0, 90.0},
    Distance = 3.0,
    Blip = 587827268,
},
```

After adding a new office, restart the resource/server and test the NPC, blip, menu, and registration flow.

***

## Real ID Flow

Real ID registration works like this:

1. The player goes to a real national registration office.
2. The player opens the menu.
3. The player selects register, update, or copy.
4. The UI opens.
5. The script validates age, hair, eyes, height, weight, and payment.
6. The server inserts or updates data in `ss_identitycard`.
7. The identity card item is given to the player.

### Required Registration Data

The registration UI expects:

* First name
* Last name
* Date of birth
* City
* Eye color
* Hair color
* Weight
* Height
* Sex
* Generated record ID

***

## Fake ID Flow

Fake ID registration works like this:

1. The player goes to an office where `FakeServices = true`.
2. The player registers a fake identity.
3. The script checks duplicate names and payment.
4. The server inserts the fake card with `isfake = 1`.
5. The fake identity card item is given to the player.

Fake IDs always show the configured job text from:

```lua
FakeIdDefaultJob = "Unemployed"
```

***

## Immigration Stamp

The script supports an immigration stamp item:

```lua
ImigrationStamp = "stampilabilet"
```

Behavior:

* When another player is showing an ID in stamp mode, the viewer can stamp it.
* Card status changes between `in` and `out`.
* Immigration status is stored in the database.

***

## Fines

If archive integrations are enabled, SS-IdentityCard can:

* Read fines from archive tables.
* Show fines in the menu.
* Let players pay fines.
* Optionally send the money to a society/bank integration.

Related config:

```lua
SSArchives = true
SSMedicArchives = true
SynSociety = "police"
SSBank = false
```

***

## Exports

### Get Your Real ID

```lua
exports["SS-IdentityCard"]:GetIdentityCard()
```

Returns the loaded real ID table, or `false`.

### Get Your Fake ID

```lua
exports["SS-IdentityCard"]:GetIdentityFakeCard()
```

Returns the loaded fake ID table, or `false`.

### Get One ID By Record ID

```lua
exports["SS-IdentityCard"]:GetIdCard(recordid)
```

Returns one identity card from the server, or `false`.

***

## Server Callback Examples

### Get All IDs

```lua
SSCORE.TriggerServerCallback("SS-IDENTITYCARD:SERVER:GETDATA", function(allIds)
    print(allIds)
end)
```

### Get One Specific ID

```lua
SSCORE.TriggerServerCallback("S!r@#Blu$$-SS-ARCHIVES:SERVER:GETIDCARD", function(idCard)
    print(idCard)
end, "K54V86Y73")
```

***

## Manual Register Example

```lua
local info = {
    year = "1855",
    eyes = "blue",
    recordid = "K54V86Y73",
    sex = "M",
    city = "Saint Denis",
    firstname = "Fane",
    lastname = "Baboia",
    kg = "80",
    date = "04-11-1905",
    month = "12",
    dob = "1855-12-11",
    cm = "180",
    hair = "black",
    day = "11"
}

TriggerServerEvent("S!r@#Blu$$-SS-IDENTITYCARD:SERVER:REGISTERID", info)
```

***

## Admin & JoinScene Integrations

SS-IdentityCard also supports these flows:

* Admins can open the registration UI for a player.
* `SS-JoinScene` can open a forced registration UI flow.

These flows are already handled by the script and should not need changes unless you customize the external resources.

***

## Troubleshooting

### Menu Opens But Nothing Happens

Check:

* `menuapi`.
* `SS-Core`.
* Office distance and coordinates.
* NPC and blip config.

### Player Cannot Register

Check:

* Age range settings such as `MinYears` and `MaxYears`.
* Money settings.
* Item names.
* Database table import.

### Card Item Exists But Does Not Show

Check:

* Usable item name in config.
* Metadata `id`.
* Item registration in your inventory/core.

### Image Is Not Visible

Check:

* `AllowImageInGame`.
* Valid image URL.
* UI resource loading correctly.

### Fake ID Menu Should Not Exist

Check offices where:

```lua
FakeServices = true
```

### Fines Do Not Show

Check:

* `SSArchives`.
* `SSMedicArchives`.
* Related archive tables and resources.

***

## Recommended Live Checklist

Before going live, confirm:

* SQL has been imported.
* `SS-Core` starts before `SS-IdentityCard`.
* `Dev = false`.
* `Language` is selected.
* Optional integrations are disabled if missing.
* Item names are checked.
* Real registration office works.
* Fake registration office works.
* ID show/use flow works.
* Immigration stamping works.
* Fine payment works.

***

## Editing Rules For Beginners

When editing Lua:

* Strings use quotes: `"text"`.
* Table entries usually end with a comma: `,`.
* `true` enables a feature.
* `false` disables a feature.
* Numbers do not use quotes: `100`.
* Item names usually use quotes: `"itemname"`.
* Coordinates usually look like `{x, y, z, heading}`.

Bad:

```lua
PayRegistration = "5"
```

Good:

```lua
PayRegistration = 5
```

Bad, if you do not actually use `SS-Housing`:

```lua
SSHousing = true
```

Good:

```lua
SSHousing = false
```


# Change logs

All SS-IdentityCard updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-IdentityCard V4.5](/ss-identitycard/change-logs/ss-identitycard-v4.5)
* [SS-IdentityCard V4.4](/ss-identitycard/change-logs/ss-identitycard-v4.4)


# SS-IdentityCard V4.5

## Update Summary

This is a major update for SS-IdentityCard. It introduces new integration support, UI optimizations, complete README documentation, and expanded translation coverage.

Please review the changes before updating, especially if your server uses archives, fines, or external job systems.

***

## Added

* Added integration support for `SS-CommunityJobs`.
* Added support for forced labor workflows for players with active dossiers from `SS-Archives`.
* Added fine repayment while working.
* Added complete README documentation with installation, configuration, and usage instructions.
* Added multiple language options: `EN`, `RO`, `IT`, `DE`, `FR`, `ES`, and `PT`.

***

## SS-CommunityJobs Integration

`SS-CommunityJobs` integration has been added in preparation for the upcoming community jobs system.

Players can now perform different jobs, including forced labor for characters who have active dossiers from `SS-Archives`.

When a player is assigned to forced labor:

* The player does not receive normal payment.
* Their fines decrease gradually while working.
* Once all fines are cleared, the player starts receiving normal payment again.

***

## UI Optimizations

* Optimized the UI for better performance.
* Cleaned up the UI code structure.
* Improved maintainability for future updates.

***

## Documentation

* Added a complete README for SS-IdentityCard.
* The README includes detailed instructions for installation, configuration, and full feature usage.

***

## Config & Translations

* Added translation support for multiple languages.
* Included language options: `EN`, `RO`, `IT`, `DE`, `FR`, `ES`, and `PT`.


# SS-IdentityCard V4.4

## Update Summary

This update adds first-join registration compatibility with SS-JoinScene and introduces the immigration stamp system for servers that use Mexico, Guarma, or another territory as a separate state.

***

## Added

* Added compatibility with `SS-JoinScene`, allowing players to create their identity card when joining the server for the first time.
* Added immigration stamp support for servers that use Mexico, Guarma, or another location as a separate state.

***

## Immigration System

* Police can stamp a citizen's identity card with an `IN` or `OUT` status from the main state.
* Showing an identity card now displays the current immigration stamp.
* The stamp helps identify whether a citizen has entered or exited the main state.

***

## Preview

![](/files/l84dfHukpu5xJUuyRHxy)


# SS-Archives

SS-Archives documentation

## Overview

SS-Archives is a police archive system for RedM. It provides a sheriff archive UI where allowed jobs can search citizens, manage dossiers, handle jail/prison workflows, write officer notes, and interact with identity card data.

The script integrates with SS-IdentityCard and can optionally connect to housing, player shops, and bounty hunter systems for property/store seizure and legal roleplay flows.

## Main Features

* Citizen search and identity record access.
* Dossier creation with fine, jail, work, bounty, and penal status.
* Dossier deletion with grade restrictions.
* Archive notes on citizens.
* Officer notes board stored in server memory.
* Identity card creation through SS-IdentityCard.
* Automatic and manual jail flow.
* Prison canteen, prison work, and sentence reduction.
* Property and store seizure support.
* Webhook logs for archive actions.


# Configuration File

## config.lua

{% code overflow="wrap" %}

```lua
-- Author: SIREC
-- Support / bug reports: https://discord.gg/9XNBaQSmMd
--
--[[
===========================================================================
 SS-Archives Configuration
===========================================================================
 This file is written to be easy to understand even for server owners who
 do not work with Lua often.

 IMPORTANT RULES:
 1. Change values, not logic.
 2. Use Dev = true only while testing.
 3. If you do not use an optional integration, disable it here.
 4. Read README.md before changing offices, penitentiary settings, or jobs.
===========================================================================
]]

Config = {

    --=====================================================================
    -- GENERAL SETTINGS
    --=====================================================================

    Dev = true, -- true = extra console logs for testing | false = recommended for live server

    -- Available languages included in l/l.lua:
    -- EN / IT / ES / FR / DE / PT / RU / RO
    Language = "EN",

    SSHousing = true, -- true only if you use SS-Housing integration
    SSPlayerShops = true, -- true only if you use SS-PlayerShops integration
    WebHook = "", -- Discord webhook URL for archive action logs | leave empty to disable

    Align = "right", -- menu alignment used by menuapi
    Button = "PRESS", -- menu prompt button text
    Key = 0xD9D0E1C0, -- key used to open archive prompts
    ServerYear = "1905", -- world/server lore year shown on records

    -- Tax system.
    -- NOTE: TaxDays is currently disabled in runtime because jailtime is now
    -- used as online remaining jail time, not absolute timestamp.
    TaxDays = 10,
    TaxPercentual = 10,

    DrinkItem = "water", -- canteen drink item
    FoodItem = "bread", -- canteen food item

    BountyHunter = true, -- true if you use SS-BountyHunter integration
    PayFromSheriff = true, -- true = bounty money is taken from the sheriff officer

    AllowedJobs = {"Guvernator", "marshal", "sheriff", "police"}, -- jobs allowed to open and use the archive
    OfficerNotesCooldown = 1, -- minutes between officer notes | minimum is 1
    PropertyOnly = {"Primar"}, -- reserved list used by property-related logic
    DeleteNotesGrade = 5, -- minimum grade required to remove notes
    DeleteJobGrade = 9, -- minimum grade required to delete dossiers
    SeizureProperty = 5, -- minimum grade required to seize property/stores
    TransferProperty = 8, -- minimum grade required to transfer property/stores

    AutoEject = true, -- eject civilians who enter prison zone if not allowed
    AutoTeleport = true, -- teleport prisoners back if they escape prison range
    AutoDoors = true, -- old door flow placeholder, keep true only if you still need that legacy behavior

    NoteBook = "archivesbook", -- usable inventory item that opens the archive UI
    DossierItem = "sulf", -- usable item given as a dossier copy

    ShowJailDossier = "showdossier", -- command used to show jail paper while jailed
    HideJailDossier = "hidedossier", -- command used to hide jail paper while jailed
    TimeToCheckJail = 60000, -- milliseconds between jail checks
    AutoJail = true, -- true = officer can choose automatic jail when creating a dossier
    ShowJailInfo = true, -- true = jail paper can be shown while jailed

    --=====================================================================
    -- ARCHIVE OFFICES
    -- Pos format = {x, y, z, heading}
    -- Distance = interaction range
    -- Blip = blip hash | false = hide blip
    --=====================================================================

    Offices = {
        [1] = {
            Name = "Blackwater Archive",
            Pos = {-761.92901611328, -1266.8898925782, 44.050498962402, 170.40016174316},
            Blip = 587827268,
            Distance = 2.0,
        }
    },

    --=====================================================================
    -- PRISON CROP JOB
    -- WorkBonus = how many seconds are removed per completed crop
    -- Money = false disables payment, or set a number to reward prisoners
    --=====================================================================

    CropJob = {
        Name = "Work for the benefit of the Country",
        Angles = {
            vector2(3300.67, -593.41),
            vector2(3278.85, -596.57),
            vector2(3214.08, -554.26),
            vector2(3248.91, -501.93),
            vector2(3328.92, -552.39)
        },
        Zcoords = {35, 54},
        WorkBonus = 20,
        Money = false,
        Debug = false,
        ReWorkDistance = 8.0,
        WaitCrop = 10000,
    },

    -- Reserved for future jobs logic
    Jobs = {},

    --=====================================================================
    -- PENITENTIARY SETTINGS
    -- Cells = possible prison cell spawn points
    -- JailPos = manual jail delivery point
    -- SpawnBoat / BoatModel = manual jail transport sequence
    --=====================================================================

    Penintetiary = {
        Name = "Sisika Penitetiary",
        Angles = {
            vector2(3386.60, -636.57),
            vector2(3410.79, -678.88),
            vector2(3369.20, -727.20),
            vector2(3329.68, -703.74),
            vector2(3315.48, -655.87)
        },
        Zcoords = {42, 54},
        Debug = true,
        Blip = -1489164512,
        Pos = {3363.4689941406, -681.2964477539, 46.466829681396},
        Canteen = {3334.93603515625, -658.6146850585938, 45.97416305541992, 281.05603027344},
        CanteenName = "Sisika Canteen",
        CanteenBlip = -1138864184,
        CanteenDistance = 2.0,
        Cells = {
            [1] = {3328.6863, -668.3199, 48.8897, 27.1767},
            [2] = {3327.9915, -661.4512, 48.8881, 89.6623},
            [3] = {3332.6626, -667.0618, 48.8896, 197.2037},
            [4] = {3333.2444, -659.8171, 48.8896, 26.3801},
            [5] = {3336.9790, -666.5901, 48.8897, 181.3364},
            [6] = {3337.1565, -658.8512, 48.8917, 12.6926},
            [7] = {3341.1169, -665.6801, 48.8897, 278.9239},
            [8] = {3341.5369, -657.7955, 48.8924, 7.8863}
        },
        JobPermit = {3380.7498, -659.0895, 46.9061, 28.9527, 45.64087295532226},
        JobPermitName = "Job Permission",
        JobPermitBlip = 1109348405,
        ReleasePos = {2685.7255859375, -1454.185913086, 46.278060913086, 187.82933044434},
        Range = 100,
        NpcMenuModel = "s_m_m_ambientblwpolice_01",
        NpcMenu = {3353.7534179688, -641.92889404296, 44.29126739502, 13.36182308197},
        JailPos = {2926.742919921875, -1254.27099609375, 42.38059997558594},
        JailDistance = 10.0,
        SpawnBoat = {2949.8779296875, -1246.3270263671875, 40.50966644287109, -82.29},
        BoatModel = "rowboat",
        NpcGuardModel = "s_m_m_skpguard_01",
        NpcGuard = {3347.1630859375, -643.75970458984, 44.291255950928, 23.405473709106},
    },
}

function ARCHIVESNOTIFY(text)
    TriggerEvent("vorp:TipBottom", text, 5000)
end

function ADDFINES(source, charid, amount, tittle, description)
    TriggerEvent("S!r@#Blu$$-SS-ARCHIVES:SERVER:SENDFINE", source, charid, amount)
end
```

{% endcode %}


# Configuration Helps

## SS-Archives Setup & Configuration Guide

SS-Archives is a police archive system for RedM. It supports citizen search, dossier management, jail/prison logic, property and store seizure, officer notes, webhook logs, and integration with SS-IdentityCard.

This guide is written for server owners who want to install, configure, and test the script safely, even without deep Lua knowledge.

***

## Features Overview

SS-Archives includes:

* Sheriff archive UI for allowed police/government jobs.
* Citizen search and identity record access.
* Dossier creation with fine, jail, work, bounty, and penal status.
* Dossier deletion with grade restrictions.
* Archive notes on citizens.
* Identity card creation from the archive through `SS-IdentityCard`.
* Automatic jail and manual jail flows.
* Prison canteen, prison work, and sentence reduction while online.
* Property and store seizure/unseizure support.
* Internal officer notes board stored in server memory.
* Webhook logs for important archive actions.

***

## Dependencies

### Required

* `SS-Core`
* `ghmattimysql`
* `menuapi`
* `PolyZone`
* `SS-IdentityCard`

### Used By Default

* `vorp:TipBottom`, used for notifications.

### Optional Integrations

* `SS-Housing`
* `SS-PlayerShops`
* `SS-BountyHunter`

If you do not use an optional integration, disable it in `config.lua`.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-Archives
```

Keep the resource folder name exactly:

```
SS-Archives
```

### 2. Import SQL

Import the main archive SQL file:

```
EXTRA/sql.sql
```

Optional or update SQL files:

```
EXTRA/sql-notes.sql
EXTRA/sql-work-update.sql
```

Main tables used by this script:

* `ss_archives`
* `ss_archivesnotes`

Also used through integrations:

* `ss_identitycard`
* `ss_housing`
* `ss_playershops`

### 3. Start Order

Recommended start order:

```cfg
ensure ghmattimysql
ensure SS-Core
ensure SS-IdentityCard
ensure SS-Archives
```

If you use property, store, or bounty integrations, make sure those resources also start before or together with `SS-Archives`.

### 4. Restart The Server

After importing SQL and checking the start order, restart the server and test the archive flow in-game.

***

## Main Files

* `fxmanifest.lua`: Resource manifest.
* `config.lua`: Main configuration.
* `l/l.lua`: Server/client translations.
* `config.js`: Archive UI texts.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.
* `UI/UI.html`: Archive UI page.

***

## Languages

Languages are configured in:

```
l/l.lua
```

Included languages:

* `EN`
* `IT`
* `ES`
* `FR`
* `DE`
* `PT`
* `RU`
* `RO`

Example:

```lua
Language = "RO"
```

If an invalid language is set, the script falls back to `EN`.

Important:

* `l/l.lua` controls game-side notifications and messages.
* `config.js` controls UI text shown inside the archive page.

***

## First Configuration

Open:

```
config.lua
```

The file is grouped into clear sections so you can change values without touching logic.

### General Settings

```lua
Dev = true
Language = "EN"
WebHook = ""
Key = 0xD9D0E1C0
Align = "right"
ServerYear = "1905"
```

* `Dev`: Use `true` while testing. Use `false` on live servers.
* `Language`: Translation language used by the script.
* `WebHook`: Discord webhook URL for archive action logs.
* `Key`: Interaction key used by menu prompts.
* `Align`: Menu alignment.
* `ServerYear`: Lore/server year printed on archive records.

### Job & Permission Settings

```lua
AllowedJobs = {"Guvernator", "marshal", "sheriff", "police"}
OfficerNotesCooldown = 1
DeleteNotesGrade = 5
DeleteJobGrade = 9
SeizureProperty = 5
TransferProperty = 8
```

* `AllowedJobs`: Jobs allowed to open and use the archive.
* `OfficerNotesCooldown`: Minutes between each officer note.
* `DeleteNotesGrade`: Minimum grade required to remove archive notes.
* `DeleteJobGrade`: Minimum grade required to delete dossiers.
* `SeizureProperty`: Minimum grade required to seize/unseize properties and stores.
* `TransferProperty`: Minimum grade reserved for transfer-related logic.

### Items & Commands

```lua
NoteBook = "archivesbook"
DossierItem = "sulf"
ShowJailDossier = "showdossier"
HideJailDossier = "hidedossier"
```

* `NoteBook`: Usable inventory item that opens the archive UI.
* `DossierItem`: Item used for dossier copies.
* `ShowJailDossier`: Command used to show jail paper.
* `HideJailDossier`: Command used to hide jail paper.

***

## Archive Offices

Offices are configured in:

```lua
Config.Offices
```

Example:

```lua
[1] = {
    Name = "Blackwater Archive",
    Pos = {-761.92, -1266.88, 44.05, 170.40},
    Blip = 587827268,
    Distance = 2.0,
}
```

Important fields:

* `Name`: Office name used for prompt and blip.
* `Pos`: Coordinates in `x, y, z, heading` format.
* `Blip`: Blip hash or `false`.
* `Distance`: Interaction range.

### Add A New Archive Office

Copy an existing office and change only the values:

```lua
[2] = {
    Name = "Valentine Archive",
    Pos = {-180.00, 625.00, 114.00, 90.00},
    Blip = 587827268,
    Distance = 2.0,
}
```

After adding a new office, restart the resource/server and test the prompt, blip, archive opening, and permissions.

***

## Dossier Flow

Main flow:

1. Officer opens the archive.
2. Officer searches a citizen.
3. Officer opens that citizen file.
4. Officer selects `Add Dossier`.
5. Officer sets charge, jail, work, fine, bounty, description, and flags.
6. Script creates a dossier in `ss_archives`.
7. If auto jail is enabled and the player is online, the player can be jailed immediately.

Important:

* `jail` in the dossier remains the original sentence given by the officer.
* Remaining jail time is tracked separately in `jailtime`.
* Jail time does not continue while the player is offline.

***

## IdentityCard Integration

SS-Archives is connected to `SS-IdentityCard`.

It uses `SS-IdentityCard` to:

* Read citizen identity data.
* Read notes linked to identity.
* Create identity cards from the archive UI.
* Support fake/real identity checks when needed.

From the archive, officers can create an identity card for a player if that player does not already have one.

***

## Prison & Penitentiary Settings

The prison configuration is in:

```lua
Config.Penintetiary
```

This section controls:

* Prison polygon.
* Prison cells.
* Canteen.
* Prison NPCs.
* Job permit area.
* Boat transport for manual jail.
* Release position.

### Prison Work

The crop job configuration is in:

```lua
Config.CropJob
```

Example:

```lua
CropJob = {
    Name = "Work for the benefit of the Country",
    WorkBonus = 20,
    Money = false,
    WaitCrop = 10000,
}
```

* `WorkBonus`: Seconds reduced from sentence per completed crop.
* `Money`: `false` disables payment, or use a number.
* `WaitCrop`: Work duration before reward or reduction is applied.

***

## Property & Store Integrations

If enabled:

```lua
SSHousing = true
SSPlayerShops = true
```

The archive can:

* List houses.
* List stores.
* Seize and unseize them.

This script updates the database and local archive cache. It does not broadcast refreshes to all players.

***

## Officer Notes

The `Officer Notes` page replaces the old global dossier page.

Behavior:

* Available in the archive UI.
* Messages are kept only in server memory.
* Notes reset automatically when the resource/server restarts.
* Notes are synced only to players with jobs listed in `Config.AllowedJobs`.
* Cooldown is controlled by `OfficerNotesCooldown`.

***

## Webhook Logs

Set your Discord webhook here:

```lua
WebHook = "https://discord.com/api/webhooks/..."
```

Leave it empty to disable Discord logs.

The script sends logs for actions such as:

* Create dossier.
* Delete dossier.
* Seize/unseize store.
* Seize/unseize house.

***

## Notification Handler

You can replace the default notify function in `config.lua`:

```lua
function ARCHIVESNOTIFY(text)
    TriggerEvent("vorp:TipBottom", text, 5000)
end
```

If your server uses another notification system, change only this function.

***

## Fine / Billing Handler

You can replace the default fine destination in `config.lua`:

```lua
function ADDFINES(source, charid, amount, tittle, description)
    TriggerEvent("S!r@#Blu$$-SS-ARCHIVES:SERVER:SENDFINE", source, charid, amount)
end
```

If your billing system is different, change only this function.

***

## Example Config Recipes

### Disable Property Integration

```lua
SSHousing = false
SSPlayerShops = false
```

### Allow Only Sheriff And Marshal

```lua
AllowedJobs = {"marshal", "sheriff"}
```

### Make Officer Notes Slower

```lua
OfficerNotesCooldown = 2
```

This means one note every 2 minutes.

### Disable Auto Jail Choice

```lua
AutoJail = false
```

### Make Dossier Deletion Stricter

```lua
DeleteJobGrade = 12
```

***

## Troubleshooting

### Archive Opens But There Is No Citizen Data

Check:

* `SS-IdentityCard`.
* Callback integrations between both resources.
* SQL imported correctly.
* Resource start order.

### Dossier Is Created But Jail Does Not Start

Check:

* `AutoJail`.
* Player online status.
* Character ID integration.
* Prison config.

### Officer Notes Do Not Sync

Check:

* Player job is included in `AllowedJobs`.
* Resource started correctly.
* Client opened the archive after startup.

### Properties / Stores Do Not Show

Check:

* `SSHousing`.
* `SSPlayerShops`.
* Corresponding database tables.

### Notebook Item Does Nothing

Check:

* `NoteBook` item name.
* Usable item registration.
* `SS-Archives` resource started.

***

## Recommended Live Checklist

Before going live, confirm:

* SQL has been imported.
* `SS-Core` starts before `SS-Archives`.
* `SS-IdentityCard` starts before `SS-Archives`.
* `Dev = false`.
* `Language` is selected.
* Optional integrations are disabled if missing.
* Archive office works.
* Notebook item works.
* Citizen search works.
* Dossier create/delete works.
* Jail flow works.
* Officer notes work.
* Property/store actions work.

***

## Editing Rules For Beginners

When editing Lua:

* Strings use quotes: `"text"`.
* Table entries usually end with a comma: `,`.
* `true` enables a feature.
* `false` disables a feature.
* Numbers do not use quotes: `100`.
* Item names usually use quotes: `"itemname"`.
* Coordinates usually look like `{x, y, z, heading}`.

Bad:

```lua
DeleteJobGrade = "9"
```

Good:

```lua
DeleteJobGrade = 9
```


# Change logs

All SS-Archives updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-Archives V3.7](/ss-archives/change-logs/ss-archives-v3.7)


# SS-Archives V3.7

## Update Summary

SS-Archives V3.7 focuses on a cleaner archive workflow, improved dossier handling, prison support, officer notes, and stronger integration with SS-IdentityCard and optional property/store systems.

***

## Added

* Added full GitBook documentation for SS-Archives.
* Added configuration documentation based on the current `config.lua`.
* Added setup and usage guide based on the project README.
* Added changelog structure with versioned underpages.

***

## Main Systems

* Citizen search and archive UI access for allowed jobs.
* Dossier creation with fine, jail, work, bounty, and penal status.
* Jail/prison flow with sentence tracking and prison work reduction.
* Officer notes stored in server memory and synced to allowed jobs.
* Property and store seizure support through optional integrations.
* SS-IdentityCard integration for citizen data and identity card creation.


# SS-CommunityJobs

SS-CommunityJobs documentation

## Overview

SS-CommunityJobs is a community jobs and forced labor system for RedM. It lets players perform configured city jobs, track salary server-side, reduce forced labor tasks, and repay fines through work when integrated with SS-Archives.

The script supports simple one-step jobs, two-step carry jobs, configurable offices, optional SS-Menu or vorp\_menu/menuapi support, and external opening from scripts such as SS-IdentityCard.

## Main Features

* Community jobs menu per configured city.
* Multiple work types per city office.
* One-step jobs such as broom and windows.
* Two-step carry jobs with pickup and delivery flow.
* Server-side salary tracking until withdrawal.
* Forced labor reduction through SS-Archives integration.
* Fine reduction before cash payment when enabled.
* External menu opening from another script.
* Multi-language support.


# Configuration File

## config.lua

{% code overflow="wrap" %}

```lua
-- Author: SIREC
-- Support / bug reports: https://discord.gg/9XNBaQSmMd
--
--[[
===========================================================================
 SS-CommunityJobs Configuration
===========================================================================
 This file is written to be easy to understand even for people who do not
 work with Lua regularly.

 IMPORTANT RULES:
 1. Change values, not logic.
 2. If a feature depends on another script, disable it here when you do not
    have that resource on your server.
 3. Read README.md before changing integrations or adding new offices.
===========================================================================
]]

Config = {

    --=====================================================================
    -- GENERAL SETTINGS
    --=====================================================================

    -- AVAILABLE: EN / RO / IT / DE / FR / ES / PT
    Language = "EN", -- language used for all translated notifications and prompts

    SSMenu = false, -- true = use SS-Menu | false = use vorp_menu / menuapi
    Align = "right", -- menu alignment used by both supported menu systems

    --=====================================================================
    -- KEY SETTINGS
    --=====================================================================

    WorkButton = 0x8AAA0AD4, -- prompt key used to interact with the current work point
    StopButton = 0x760A9C6F, -- prompt key used to stop the active work session

    -- Legacy compatibility variables kept from the original script.
    -- They are not part of the active community jobs flow right now.
    EnterExitPassenger = 0x760A9C6F,
    RentBallon = 0x8AAA0AD4,
    BallonRoutes = 0x760A9C6F,

    --=====================================================================
    -- OPTIONAL / ADDON INTEGRATIONS
    -- Enable only if those resources exist on your server
    --=====================================================================

    SSIdentityCard = true, -- intended integration with SS-IdentityCard office flow
    SSArchives = true, -- enables forced labor and fine reduction integration
    DecreaseFines = true, -- true = withdrawn salary reduces fines first, then pays the remaining cash

    --=====================================================================
    -- BLIP / GPS SETTINGS
    --=====================================================================

    BlipStyle = "BLIP_STYLE_DEBUG_GREEN", -- style applied to generated job blips
    BlipGps = "COLOR_GREEN", -- GPS route color used for job destinations

    --=====================================================================
    -- COMMUNITY JOB OFFICES
    -- City key must match the external city that opens this menu.
    --
    -- OFFICE FIELDS:
    -- Name = office title in menu
    -- Description = office subtitle in menu
    -- Distance = prompt interaction distance
    --
    -- JOB FIELDS:
    -- Blip = blip sprite hash
    -- WorkTime = progress bar time in milliseconds
    -- Pay = random pay range {min, max}
    -- ForcedWork = true = reduces SS-Archives work tasks first
    -- WorkTitle = menu label
    -- WorkDesc = menu description
    -- Locations = work destinations
    -- Start = only used by CARRY as pickup location
    -- Prop = only used by CARRY as carried object model
    --=====================================================================

    Offices = {
        ["Annesburg"] = {
            Name = "Community Jobs",
            Description = "Work & Get Paid",
            Distance = 3.0,

            ["BROOM"] = {
                Blip = -576151168,
                WorkTime = 20000,
                Pay = {0.1, 0.9},
                ForcedWork = true,
                WorkTitle = "Broom The City",
                WorkDesc = "Broom & clean the city.",
                Locations = {
                    {2938.399169921875, 1308.7247314453125, 43.57914352416992},
                    {2957.786865234375, 1301.2540283203125, 43.5886116027832},
                    {2911.4111328125, 1307.12451171875, 43.77418899536133},
                    {2916.231689453125, 1319.9664306640625, 43.61255645751953},
                },
            },

            ["WINDOWS"] = {
                Blip = 1321928545,
                WorkTime = 20000,
                Pay = {0.1, 0.9},
                ForcedWork = true,
                WorkTitle = "Clean City Windows",
                WorkDesc = "Clean the city windows.",
                Locations = {
                    {2931.623291015625, 1291.8941650390625, 44.76031112670898},
                    {2928.22998046875, 1285.9609375, 44.7767219543457},
                    {2927.299072265625, 1283.5289306640625, 44.76520156860351},
                    {2926.19091796875, 1277.10888671875, 44.72944259643555},
                    {2931.369873046875, 1267.0167236328125, 44.75484848022461},
                    {2939.483154296875, 1279.17138671875, 44.73685455322265},
                    {2939.985595703125, 1280.4405517578125, 44.73633575439453},
                    {2940.375732421875, 1281.516357421875, 44.73600769042969},
                    {2941.58447265625, 1288.06640625, 44.73311996459961},
                    {2942.590576171875, 1290.5225830078125, 44.81488418579101},
                    {2935.00439453125, 1294.5941162109375, 44.7454719543457},
                },
            },

            ["CARRY"] = {
                Blip = 1321928545,
                WorkTime = 20000,
                Pay = {0.4, 1.2},
                ForcedWork = true,
                Prop = "p_woodpile06x",
                WorkTitle = "Carry Firewoods",
                WorkDesc = "Carry firewoods to the houses.",
                Start = {2905.87939453125, 1292.447509765625, 44.03779602050781},
                Locations = {
                    {2967.615966796875, 1422.7041015625, 44.64105224609375},
                    {2966.428955078125, 1437.837646484375, 45.17163467407226},
                    {2851.25537109375, 1447.829345703125, 67.52664947509766},
                    {2917.459228515625, 1355.168212890625, 43.5555191040039},
                    {2953.803955078125, 1326.9671630859375, 43.2729377746582},
                },
            },
        },
    },
}

function NOTIFY(text)
    exports["MNotify"]:Notify({
        image = "maiorca.png",
        title = TR["notify_title"],
        text = text,
        duration = 5000,
        position = "center-right"
    })
end
```

{% endcode %}


# Configuration Helps

## SS-CommunityJobs Setup & Configuration Guide

SS-CommunityJobs is a community jobs and forced labor script for RedM. It supports city job offices, one-step work tasks, carry jobs, salary tracking, fine reduction, forced labor integration, and optional menu systems.

This guide is written for server owners who want to install, configure, and test the script safely, even without deep Lua knowledge.

***

## Features Overview

SS-CommunityJobs includes:

* City-based community jobs menu.
* Multiple work types per city office.
* One-step jobs such as broom and windows.
* Two-step carry jobs with pickup and delivery flow.
* Server-side salary tracking until withdrawal.
* Forced labor reduction through `SS-Archives`.
* Fine reduction before cash payment.
* External opening from scripts such as `SS-IdentityCard`.
* Multi-language support.

***

## Dependencies

### Required

* `SS-Core`
* `oxmysql`

### Used By Default

* `MNotify`
* `SS-ProgressBar`

### Menu Support

* `SS-Menu` if `Config.SSMenu = true`.
* `vorp_menu` / `menuapi` if `Config.SSMenu = false`.

### Optional Integrations

* `SS-Archives`
* `SS-IdentityCard`

If you do not use an optional integration, disable it in `config.lua`.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-CommunityJobs
```

Keep the resource folder name exactly:

```
SS-CommunityJobs
```

### 2. Check Start Order

Recommended start order:

```cfg
ensure oxmysql
ensure SS-Core
ensure MNotify
ensure SS-ProgressBar
ensure SS-Menu
ensure SS-CommunityJobs
```

If you use `vorp_menu` instead of `SS-Menu`, make sure `menuapi` is started before this resource and set:

```lua
SSMenu = false
```

### 3. Optional Integrations

If your server uses `SS-Archives` and `SS-IdentityCard`, make sure they are started too:

```cfg
ensure SS-Archives
ensure SS-IdentityCard
```

### 4. Restart The Server

After checking your config and start order, restart the server and test the main job flow in-game.

***

## Main Files

* `fxmanifest.lua`: Resource manifest.
* `config.lua`: Main configuration.
* `l/l.lua`: Translations.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.

***

## Languages

Languages are configured in:

```
l/l.lua
```

Included languages:

* `EN`
* `RO`
* `IT`
* `DE`
* `FR`
* `ES`
* `PT`

Example:

```lua
Language = "RO"
```

If an invalid language is selected, the script automatically falls back to `EN`.

***

## First Configuration

Open:

```
config.lua
```

The file is grouped into clear sections so you can configure it safely without touching code logic.

### General Settings

```lua
Language = "EN"
SSMenu = true
Align = "right"
```

* `Language`: Translation language used by the script.
* `SSMenu`: `true` uses `SS-Menu`; `false` uses `vorp_menu` / `menuapi`.
* `Align`: Menu alignment.

### Keybind Settings

```lua
WorkButton = 0x8AAA0AD4
StopButton = 0x760A9C6F
EnterExitPassenger = 0x760A9C6F
RentBallon = 0x8AAA0AD4
BallonRoutes = 0x760A9C6F
```

* `WorkButton`: Prompt key used to start or confirm work.
* `StopButton`: Prompt key used to stop working.
* `EnterExitPassenger`, `RentBallon`, and `BallonRoutes`: Legacy compatibility variables kept for the current script structure.

### Integration Settings

```lua
SSIdentityCard = true
SSArchives = true
DecreaseFines = true
```

* `SSIdentityCard`: Intended integration with the identity office flow.
* `SSArchives`: Enables forced labor and archives integration.
* `DecreaseFines`: When `true`, withdrawn salary reduces fines first, then pays the remaining cash.

### Blip & GPS Settings

```lua
BlipStyle = "BLIP_STYLE_DEBUG_GREEN"
BlipGps = "COLOR_GREEN"
```

* `BlipStyle`: Style applied to generated job blips.
* `BlipGps`: GPS route color used for job destinations.

***

## Office Configuration

All offices and jobs are configured in:

```lua
Config.Offices
```

Each city office can contain:

* `Name`
* `Description`
* `Distance`
* `BROOM`
* `WINDOWS`
* `CARRY`

Example:

```lua
["Annesburg"] = {
    Name = "Community Jobs",
    Description = "Work & Get Paid",
    Distance = 3.0,
    ["BROOM"] = {
        Blip = -576151168,
        WorkTime = 20000,
        Pay = {0.1, 0.9},
        ForcedWork = true,
        WorkTitle = "Broom The City",
        WorkDesc = "Broom & clean the city.",
        Locations = {
            {2938.39, 1308.72, 43.57},
        },
    },
}
```

Important fields:

* `Name`: Office title shown in the jobs menu.
* `Description`: Office subtitle shown in the jobs menu.
* `Distance`: Prompt interaction range.
* `Blip`: Blip sprite hash for the job.
* `WorkTime`: Progress bar duration in milliseconds.
* `Pay`: Random salary range in `{min, max}` format.
* `ForcedWork`: If `true`, the job reduces `SS-Archives` work tasks first.
* `WorkTitle`: Menu label for the job.
* `WorkDesc`: Menu description for the job.
* `Locations`: Work destinations used by that job.
* `Start`: Used by `CARRY` as the pickup location.
* `Prop`: Used by `CARRY` as the carried object model.

***

## Job Flow

### BROOM / WINDOWS

1. The player opens the menu.
2. The player starts the selected job.
3. The script selects a random work location.
4. The player goes to the work point and presses the work prompt.
5. The progress bar completes.
6. Salary is added, or forced labor is reduced.
7. A new location is selected.

### CARRY

1. The player starts the carry job.
2. The player goes to the pickup point.
3. The player presses the work prompt and picks up the goods.
4. The script selects a random delivery point.
5. The player delivers the goods.
6. Salary is added, or forced labor is reduced.
7. The route returns to the pickup point for the next cycle.

***

## Forced Labor & Fines Logic

If integrations are enabled, the script follows this order:

1. Forced labor
2. Fines
3. Cash

This means:

* If the player still has `work > 0` in `SS-Archives`, finishing jobs reduces work tasks first.
* Once forced labor is finished, salary accumulates normally.
* When the player withdraws salary, unpaid fines are reduced first if `DecreaseFines = true`.
* Only the remaining amount is given as money.

***

## Opening The Menu From Another Script

This script exposes a client event:

```lua
TriggerEvent("SS-COMMUNITYJOBS:CLIENT:OPENJOBS", idnr, "Annesburg")
```

Arguments:

* `idnr`: Player identity number if your external flow needs it.
* City name: Must match one key from `Config.Offices`.

There is also a client export:

```lua
exports["SS-CommunityJobs"]:HasJobsInCity("Annesburg")
```

Returns:

* `true` if that city has at least one configured job.
* `false` otherwise.

***

## Notifications

All notification strings are configured in:

```
l/l.lua
```

If you want to edit wording or add your own language, do it there.

The default notification function uses `MNotify`:

```lua
function NOTIFY(text)
    exports["MNotify"]:Notify({
        image = "maiorca.png",
        title = TR["notify_title"],
        text = text,
        duration = 5000,
        position = "center-right"
    })
end
```

***

## Add A New City

Copy an existing city block inside `Config.Offices` and change only the values:

```lua
["Valentine"] = {
    Name = "Valentine Community Jobs",
    Description = "Work for the city",
    Distance = 3.0,
    ["BROOM"] = {
        Blip = -576151168,
        WorkTime = 20000,
        Pay = {0.2, 1.0},
        ForcedWork = true,
        WorkTitle = "Clean The Streets",
        WorkDesc = "Help keep the city clean.",
        Locations = {
            {-200.0, 650.0, 113.0},
            {-180.0, 640.0, 112.8},
        },
    },
}
```

After adding a city, restart the resource/server and test the menu, prompts, blips, GPS route, payment, forced labor, and fine reduction flow.

***

## Disable A Job Type

Remove that job block from the office or leave it undefined.

Examples:

* No `WINDOWS` entry means no windows job in that city.
* No `CARRY` entry means no carry job in that city.

***

## Troubleshooting

### Menu Does Not Open

Check:

* `SS-Core`.
* Start order.
* City name passed to the open event.
* `SS-Menu` or `menuapi`, depending on your config.

### Player Cannot See Jobs In A City

Check:

* The city exists in `Config.Offices`.
* At least one of `BROOM`, `WINDOWS`, or `CARRY` exists in that office.

### Player Works But Receives No Cash

Check:

* `SSArchives = true`.
* `ForcedWork = true` in the job config.
* Whether the player still has `work` tasks in `ss_archives`.

### Salary Withdraw Gives Less Money Than Expected

Check:

* `DecreaseFines = true`.
* Whether the player still has unpaid fines in `ss_archives`.

### Menu Fails When `SSMenu = false`

Check:

* `vorp_menu`.
* `menuapi`.
* The resource providing `menuapi:getData` is started before this resource.

***

## Recommended Live Checklist

Before going live, confirm:

* Language is selected.
* Menu system is selected correctly.
* Integrations are disabled if missing.
* City names are checked.
* Job coordinates are tested.
* Salary flow works.
* Forced labor reduction works.
* Fine reduction works.

***

## Editing Rules For Beginners

When editing Lua:

* Strings use quotes: `"text"`.
* Table entries usually end with a comma: `,`.
* `true` enables a feature.
* `false` disables a feature.
* Numbers do not use quotes: `100`.
* Coordinates usually look like `{x, y, z}` or `{x, y, z, heading}`.

Bad:

```lua
SSArchives = "true"
```

Good:

```lua
SSArchives = true
```


# Change logs

All SS-CommunityJobs updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-CommunityJobs V1.0](/ss-communityjobs/change-logs/ss-communityjobs-v1.0)


# SS-CommunityJobs V1.0

## Update Summary

Initial release of SS-CommunityJobs, introducing configurable city community jobs, salary tracking, forced labor reduction, fine repayment, and optional integration with SS-Archives and SS-IdentityCard.

***

## Added

* Added community job offices by city.
* Added one-step job types such as broom and windows.
* Added two-step carry jobs with pickup and delivery flow.
* Added server-side salary tracking until withdrawal.
* Added forced labor reduction through `SS-Archives`.
* Added fine reduction before cash payment when `DecreaseFines = true`.
* Added external menu opening support for scripts such as `SS-IdentityCard`.
* Added `SS-Menu` and `vorp_menu` / `menuapi` support.
* Added multi-language support for `EN`, `RO`, `IT`, `DE`, `FR`, `ES`, and `PT`.

***

## Integrations

* `SS-Archives`: Used for forced labor and fines.
* `SS-IdentityCard`: Can open the community jobs menu from an external identity/office flow.

***

## Documentation

* Added full configuration documentation.
* Added setup and usage guide.
* Added troubleshooting and live checklist.


# SS-Admin

SS-Admin documentation

<figure><img src="/files/kBE8TPzMxNNi9mfi21w0" alt=""><figcaption></figcaption></figure>

## Overview

**SS-Admin** is an advanced RedM administration panel for server staff. It provides a full NUI admin interface, player moderation tools, permission-based commands, ticket handling, admin chat, admin jail, ban and warn management, and support for both Discord role permissions and Steam identifier permissions.

The script is designed for live roleplay servers where staff need fast access to player actions, server tools, logs, tickets, and safety controls from one configurable panel.

## Main Features

* **Admin Panel Interface**
  * NUI admin panel with dashboard, player list, tickets, ban list, give item/weapon tools, wagon and horse tools, and admin chat.
  * Configurable button icons and translated UI labels.
  * Optional keybind opening and command-based opening.
* **Player Moderation Tools**
  * Revive, heal, freeze, kill, spectate, kick, warn, ban, unban, bring, goto, notify, cuff, and admin jail actions.
  * Temporary bans, permanent bans, warning limits, and automatic ban after max warnings.
  * Player death check support with detailed translated damage reasons.
* **Server & Utility Tools**
  * Noclip, god mode, waypoint teleport, coordinate teleport, player blips, nearby player visibility, clear zone, wagon repair/delete, horse delete, and admin stash.
  * Give money, gold, items, weapons, horses, and wagons.
  * Set job and open player inventory tools.
* **Ticket & Staff Communication**
  * Player report command with ticket list for staff.
  * Ticket status flow for new, taken, and solved tickets.
  * Admin chat inside the admin panel with configurable history size.
* **Permissions & Whitelist**
  * Discord role-based staff permissions.
  * Steam identifier-based staff permissions.
  * Optional Discord whitelist system.
  * Per-action permission indexes for admin, moderator, and helper categories.
* **Integrations**
  * Required integration with `SS-Core`.
  * Database storage through `oxmysql`.
  * Optional admin voice support through `pma-voice`.
  * Admin actions for `SS-Stable` horse tools and `SS-IdentityCard` identity creation/removal flows.
* **Multi-Language Support**
  * Lua translations and UI translations for multiple languages.
  * Default language support for `EN`, `RO`, `IT`, `DE`, `FR`, `ES`, and `PT`.


# Preview

Photos & Video Preview

<figure><img src="/files/kBE8TPzMxNNi9mfi21w0" alt=""><figcaption><p>SS-Admin Panel</p></figcaption></figure>

<figure><img src="/files/7fp3ldvVzgBJ4eQ0y2Qa" alt=""><figcaption><p>SS-Admin Ticket System</p></figcaption></figure>


# Configuration File

## Main Files

SS-Admin is configured mainly from these files:

* `config.lua`: Main client/server configuration, permissions, commands, ticket settings, admin jail, UI icons, vehicle lists, horse lists, weapon lists, and helper functions.
* `s/config.lua`: Discord bot token and Discord guild ID.
* `l/l.lua`: Lua translations.
* `config.js`: NUI / interface translations.
* `EXTRA/ss_admin.sql`: Database table.

***

## config.lua

{% code overflow="wrap" %}

```lua
Config = {
    Language = "EN",
    AdminVoice = true,
    RoleplayNameList = false,
    OpenMenu = 0x3C3DD371,
    ActiveCommands = true,

    MaxWarns = 3,
    BanWarns = 3,
    MaxWarnsBanReason = "Reached max warns",

    Notify = true,
    PrintUnauthorizedAccess = true,

    NoclipSpeed = 0xB2F377E8,
    NoclipStop = 0x760A9C6F,
    NoclipUp = 0xD9D0E1C0,
    NoclipDown = 0x8FFC75D6,
    NoclipPlayersDistance = 20,

    SpectateStop = 0x760A9C6F,

    ModelTicket = "cs_crackpotrobot",
    TicketSystem = true,
    TpBack = true,
    ReportCommand = "report",
    Webhook = "YOUR_TICKET_WEBHOOK",
    TicketSolved = "TICKET SOLVED",
    TicketTaken = "TICKET TAKEN",
    TicketNew = "NEW TICKET",

    AdminJail = {2369.5132, -1492.2881, 45.9974},
    JailRadius = 13.0,
    ReleaseJail = {2680.5466, -1449.5090, 46.3672},

    BlipsUseSteamName = true,
    BlipsRefresh = 2000,

    AdminChat = true,
    AdminChatHistoryLimit = 60,

    TpEffects = true,
    VolumeEffects = 0.1,
    TimeToCheckBans = 6000 * 60 * 60,
    WebHook = "YOUR_ADMIN_LOGS_WEBHOOK",

    UseSteamPermissions = false,
}
```

{% endcode %}

***

## Discord Bot Config

Open:

```
s/config.lua
```

{% code overflow="wrap" %}

```lua
Discord = {
    Token = "YOUR_BOT_TOKEN",
    GuildId = "YOUR_DISCORD_SERVER_ID",
}
```

{% endcode %}

Keep the Discord bot token private. If the token is leaked, regenerate it in the Discord developer portal before starting the server again.

***

## Permission Mode

SS-Admin supports two permission modes.

### Discord Role Permissions

{% code overflow="wrap" %}

```lua
UseSteamPermissions = false

DiscordPermissions = {
    {name = "ADMIN", roles = {"ROLE_ID_HERE"}},
    {name = "MODERATOR", roles = {"ROLE_ID_HERE"}},
    {name = "HELPER", roles = {"ROLE_ID_HERE"}},
}
```

{% endcode %}

When this mode is used, the Discord bot checks the player's Discord roles inside the configured guild.

### Steam Identifier Permissions

{% code overflow="wrap" %}

```lua
UseSteamPermissions = true

SteamPermissions = {
    {name = "ADMIN", roles = {"steam:xxxxxxxxxxxx"}},
    {name = "MODERATOR", roles = {}},
    {name = "HELPER", roles = {}},
}
```

{% endcode %}

Use this mode if you do not want to depend on Discord roles for staff permissions.

***

## Whitelist

{% code overflow="wrap" %}

```lua
WhiteList = true
WhiteListRoles = {"DISCORD_ROLE_ID"}
```

{% endcode %}

If `WhiteList = true`, players must have one of the configured Discord roles to join the server.

Set it to `false` if you do not want SS-Admin to handle whitelist access.

***

## Admin Permissions

Every action is controlled by a numeric permission index.

{% code overflow="wrap" %}

```lua
Permissions = {
    [1] = { Command = "adminmenu", Roles = {"ADMIN", "MODERATOR", "HELPER"} },
    [4] = { Command = "noclip", Roles = {"ADMIN", "MODERATOR", "HELPER"} },
    [17] = { Command = "revive", Roles = {"ADMIN", "MODERATOR"} },
    [28] = { Command = "ban", Roles = {"ADMIN"} },
}
```

{% endcode %}

Do not change the numeric indexes. Change only `Command` and `Roles`.

Important indexes:

* `[1]`: Open admin panel.
* `[13]`: Unban.
* `[14]`: Spectate.
* `[19]`: Give money.
* `[20]`: Give gold.
* `[21]`: Give item.
* `[22]`: Give weapon.
* `[26]`: Kick.
* `[27]`: Warn.
* `[28]`: Ban.
* `[34]`: Admin jail.
* `[36]`: Admin stash.
* `[37]`: Open player inventory.
* `[50]`: See nearby players.

***

## Ticket System

{% code overflow="wrap" %}

```lua
TicketSystem = true
ReportCommand = "report"
TpBack = true
ModelTicket = "cs_crackpotrobot"
Webhook = "YOUR_TICKET_WEBHOOK"
```

{% endcode %}

* `TicketSystem`: Enables player reports and ticket handling.
* `ReportCommand`: Command used by players to open the report form.
* `TpBack`: Sends staff back after solving a ticket.
* `ModelTicket`: Temporary model used during the ticket flow, or `false`.
* `Webhook`: Discord webhook used for ticket logs.

***

## Admin Chat

{% code overflow="wrap" %}

```lua
AdminChat = true
AdminChatHistoryLimit = 60
```

{% endcode %}

Admin chat is shown inside the admin panel for staff members with permission to open the panel. History is stored in memory while the resource is running.

***

## SQL

Import:

```
EXTRA/ss_admin.sql
```

Main table:

```
ss_admin
```

Stored data includes identifiers, Discord ID, license, warning count, ban state, playtime, last join/leave timestamps, ban details, and admin jail time.


# Configuration Helps

## SS-Admin Setup & Configuration Guide

SS-Admin is an advanced admin panel and staff toolset for RedM. It includes player moderation actions, ticket reports, admin chat, admin jail, Discord or Steam permissions, optional whitelist checks, server utility tools, economy tools, and integrations with other Sirec Studio systems.

This guide is written for server owners who want to install, configure, and test the script safely.

***

## Features Overview

SS-Admin includes:

* NUI admin panel with dashboard, player tools, tickets, ban list, item/weapon tools, horse tools, wagon tools, and admin chat.
* Staff actions such as revive, heal, freeze, kill, spectate, bring, goto, kick, warn, ban, unban, notify, cuff, and admin jail.
* Utility tools such as noclip, god mode, waypoint teleport, coordinate teleport, player blips, nearby player visibility, clear zone, and admin stash.
* Economy tools for giving money, gold, items, and weapons.
* Horse and wagon admin tools.
* Ticket system with player report command.
* Admin chat with configurable in-memory history.
* Discord role permissions or Steam identifier permissions.
* Optional Discord whitelist.
* Multi-language support for Lua and UI text.

***

## Dependencies

### Required

* `SS-Core`
* `oxmysql`

### Optional

* `pma-voice`, only if `AdminVoice = true`.

### Related Integrations

* `SS-Stable`, used by horse and wagon related admin actions.
* `SS-IdentityCard`, used by identity creation and identity removal actions.
* `SS-PoliceJob`, used by cuff metadata events if your server uses that integration.

If you do not use the related scripts, restrict or disable the matching permission buttons.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-Admin
```

Keep the resource folder name exactly:

```
SS-Admin
```

### 2. Import SQL

Import:

```
EXTRA/ss_admin.sql
```

This creates the table:

```
ss_admin
```

The table stores player identifiers, warnings, ban state, ban details, playtime, last join/leave data, and admin jail time.

### 3. Start Order

Recommended start order:

```cfg
ensure oxmysql
ensure SS-Core
ensure SS-Admin
```

If admin voice is enabled:

```cfg
ensure pma-voice
```

### 4. Restart The Server

After importing SQL and configuring permissions, restart the server fully and test with one staff account before opening the server to players.

***

## Main Files

* `fxmanifest.lua`: Resource manifest.
* `config.lua`: Main script configuration.
* `s/config.lua`: Discord bot token and guild ID.
* `l/l.lua`: Lua translations.
* `config.js`: UI translations.
* `c/c.lua`: Client logic.
* `s/s.lua`: Server logic.
* `UI/UI.html`: Admin panel UI.
* `EXTRA/ss_admin.sql`: SQL table.

***

## Languages

The main language is configured in:

```
config.lua
```

Example:

```lua
Language = "EN"
```

Included languages:

* `EN`
* `RO`
* `IT`
* `DE`
* `FR`
* `ES`
* `PT`

Lua translations are in:

```
l/l.lua
```

UI translations are in:

```
config.js
```

***

## First Configuration

Open:

```
config.lua
```

Start with the general settings:

```lua
Language = "EN"
AdminVoice = true
RoleplayNameList = false
OpenMenu = 0x3C3DD371
ActiveCommands = true
MaxWarns = 3
BanWarns = 3
Notify = true
```

* `Language`: Main language used by Lua notifications and supported UI text.
* `AdminVoice`: Sends staff to the admin voice channel when they have admin access.
* `RoleplayNameList`: Uses character names instead of Steam names in player lists and commands.
* `OpenMenu`: Key hash used to open the admin panel, or `false` to disable key opening.
* `ActiveCommands`: Enables admin commands such as `/kick`, `/ban`, `/tp`, `/givemoney`, and `/giveitem`.
* `MaxWarns`: Number of warnings before automatic ban.
* `BanWarns`: Number of days for the automatic ban.
* `Notify`: Sends notifications for admin actions.

***

## Discord Bot Setup

Open:

```
s/config.lua
```

Set:

```lua
Discord = {
    Token = "YOUR_BOT_TOKEN",
    GuildId = "YOUR_DISCORD_SERVER_ID",
}
```

The Discord bot is required when:

* `UseSteamPermissions = false`
* Discord role permissions are used.
* Discord whitelist is enabled.

Keep the token private. Never share it publicly or include it in screenshots.

***

## Permission Mode

### Discord Permissions

Use this mode when staff access should be based on Discord role IDs:

```lua
UseSteamPermissions = false

DiscordPermissions = {
    {name = "ADMIN", roles = {"ROLE_ID_HERE"}},
    {name = "MODERATOR", roles = {"ROLE_ID_HERE"}},
    {name = "HELPER", roles = {"ROLE_ID_HERE"}},
}
```

The role names `ADMIN`, `MODERATOR`, and `HELPER` are then used inside `Permissions`.

### Steam Permissions

Use this mode when staff access should be based on Steam identifiers:

```lua
UseSteamPermissions = true

SteamPermissions = {
    {name = "ADMIN", roles = {"steam:xxxxxxxxxxxx"}},
    {name = "MODERATOR", roles = {}},
    {name = "HELPER", roles = {}},
}
```

***

## Whitelist

Whitelist is controlled by:

```lua
WhiteList = true
WhiteListRoles = {"DISCORD_ROLE_ID"}
```

If `WhiteList = true`, players must have one of the configured Discord roles to join.

If your server does not use SS-Admin for whitelist access, set:

```lua
WhiteList = false
```

***

## Admin Permissions

Admin permissions are configured in:

```lua
Permissions = {
    [1] = { Command = "adminmenu", Roles = {"ADMIN", "MODERATOR", "HELPER"} },
}
```

Each entry has:

* `Command`: Chat command used for that action, or `false` if it should only be used from the panel.
* `Roles`: Staff categories allowed to use the action.

Do not change the numeric indexes. The script logic depends on those numbers.

### Common Permission Examples

Only admins can ban:

```lua
[28] = { Command = "ban", Roles = {"ADMIN"} },
```

Admins and moderators can revive:

```lua
[17] = { Command = "revive", Roles = {"ADMIN", "MODERATOR"} },
```

Disable a command but keep the panel button:

```lua
[21] = { Command = false, Roles = {"ADMIN"} },
```

***

## Important Permission Indexes

* `[1]`: Open admin panel.
* `[2]`: Announce.
* `[3]`: Spawn wagon / horse menu.
* `[4]`: Noclip.
* `[5]`: Waypoint or coordinate teleport.
* `[11]`: Player blips.
* `[13]`: Unban.
* `[14]`: Spectate.
* `[17]`: Revive player.
* `[18]`: Heal player.
* `[19]`: Give money.
* `[20]`: Give gold.
* `[21]`: Give item.
* `[22]`: Give weapon.
* `[26]`: Kick.
* `[27]`: Warn.
* `[28]`: Ban.
* `[34]`: Admin jail.
* `[36]`: Admin stash.
* `[37]`: Open player inventory.
* `[38]`: Clear zone.
* `[39]`: Cuff / uncuff.
* `[40]`: Revive all.
* `[41]`: Heal all.
* `[42]`: Kick all.
* `[43]`: Remove one warning.
* `[44]`: Revive horse.
* `[45]`: Give horse.
* `[46]`: Give wagon.
* `[47]`: Delete identity card.
* `[48]`: Delete fake identity card.
* `[49]`: Create identity card.
* `[50]`: See nearby players.

***

## Ticket System

Ticket settings:

```lua
TicketSystem = true
ReportCommand = "report"
TpBack = true
ModelTicket = "cs_crackpotrobot"
Webhook = "YOUR_TICKET_WEBHOOK"
TicketSolved = "TICKET SOLVED"
TicketTaken = "TICKET TAKEN"
TicketNew = "NEW TICKET"
```

How it works:

1. A player uses the report command.
2. The report form opens.
3. Staff receive the ticket in the admin panel.
4. A staff member can take the ticket.
5. Staff can teleport to the player.
6. When solved, the ticket is marked as solved.
7. If `TpBack = true`, the staff member is teleported back.

To disable the system:

```lua
TicketSystem = false
```

***

## Admin Chat

Admin chat settings:

```lua
AdminChat = true
AdminChatHistoryLimit = 60
```

* `AdminChat`: Enables the admin chat page inside the panel.
* `AdminChatHistoryLimit`: Number of recent messages kept in memory.

The chat history is reset when the resource restarts.

***

## Admin Jail

Admin jail settings:

```lua
AdminJail = {2369.5132, -1492.2881, 45.9974}
JailRadius = 13.0
ReleaseJail = {2680.5466, -1449.5090, 46.3672}
```

* `AdminJail`: Position where jailed players are kept.
* `JailRadius`: Maximum allowed movement distance inside jail.
* `ReleaseJail`: Position where the player is sent after release.

Admin jail time is stored in the database and can persist through reconnects.

***

## Noclip

Noclip keys:

```lua
NoclipSpeed = 0xB2F377E8
NoclipStop = 0x760A9C6F
NoclipUp = 0xD9D0E1C0
NoclipDown = 0x8FFC75D6
```

Noclip speeds are configured in:

```lua
NoClip = {
    Speeds = {
        { speed = 0 },
        { speed = 0.5 },
        { speed = 2 },
        { speed = 5 },
        { speed = 10 },
        { speed = 15 },
    },
}
```

If you are not sure what a key hash does, leave it unchanged.

***

## Webhooks

SS-Admin uses two main webhook fields:

```lua
Webhook = "YOUR_TICKET_WEBHOOK"
WebHook = "YOUR_ADMIN_LOGS_WEBHOOK"
```

* `Webhook`: Ticket system logs.
* `WebHook`: General admin action logs.

Use separate Discord channels if you want ticket logs and admin action logs separated.

***

## Useful Commands

The exact command names are controlled by `Config.Permissions`.

Common default commands include:

* `/adminmenu`
* `/noclip`
* `/tp`
* `/reviveme`
* `/healme`
* `/fix`
* `/delveh`
* `/delhorse`
* `/activeblips`
* `/god`
* `/unban`
* `/spectate`
* `/freeze`
* `/kill`
* `/revive`
* `/heal`
* `/givemoney`
* `/givegold`
* `/giveitem`
* `/giveweapon`
* `/check`
* `/sjob`
* `/notify`
* `/kick`
* `/warn`
* `/ban`
* `/bring`
* `/goto`
* `/ajail`
* `/clearzone`
* `/cuff`
* `/reviveall`
* `/healall`
* `/kickall`
* `/unwarn`
* `/seeplayers`

***

## Exports

SS-Admin exposes report/ticket helper exports:

```lua
exports["SS-Admin"]:ReportList()
exports["SS-Admin"]:Report()
```

Use these only if another resource needs to open the report list or report form directly.

***

## Troubleshooting

### Admin Panel Does Not Open

Check:

* `SS-Core` is started before `SS-Admin`.
* The player has the correct Discord role or Steam identifier.
* Permission `[1]` includes the player's staff category.
* `OpenMenu` is not `false`, or `/adminmenu` is enabled.

### Discord Permissions Do Not Work

Check:

* `UseSteamPermissions = false`.
* Discord bot token is valid.
* The bot is inside the correct Discord server.
* `GuildId` is correct.
* Role IDs are copied correctly.
* The player has Discord linked to RedM identifiers.

### Steam Permissions Do Not Work

Check:

* `UseSteamPermissions = true`.
* The Steam identifier starts with `steam:`.
* The identifier is inside the correct role group.

### Player Cannot Join Because Of Whitelist

Check:

* `WhiteList = true`.
* `WhiteListRoles` contains the correct Discord role IDs.
* The player has one of those roles.
* The Discord bot can read guild member roles.

### Ticket System Does Not Log

Check:

* `TicketSystem = true`.
* `Webhook` contains a valid Discord webhook.
* The player is using the configured `ReportCommand`.

### Admin Voice Does Not Work

Check:

* `AdminVoice = true`.
* `pma-voice` is installed and started.
* Staff has permission to open the admin panel.

### Script Does Not Start

Check:

* Resource folder name is exactly `SS-Admin`.
* `oxmysql` is installed and started before `SS-Admin`.
* `SS-Core` is started before `SS-Admin`.
* SQL has been imported.
* `s/config.lua` exists and does not contain broken Lua syntax.

***

## Recommended Live Checklist

Before going live, confirm:

* SQL has been imported.
* `oxmysql` starts before `SS-Admin`.
* `SS-Core` starts before `SS-Admin`.
* Discord bot token and guild ID are configured if using Discord permissions.
* `UseSteamPermissions` is set correctly.
* Staff roles or Steam identifiers are configured.
* Whitelist is enabled or disabled intentionally.
* Ticket webhook is tested.
* Admin logs webhook is tested.
* `AdminVoice` is disabled if `pma-voice` is not installed.
* One admin account can open the panel.
* Ban, warn, revive, teleport, and ticket actions have been tested.

***

## Editing Rules For Beginners

When editing Lua:

* Strings use quotes: `"text"`.
* Table entries usually end with a comma: `,`.
* `true` enables a feature.
* `false` disables a feature.
* Numbers do not use quotes: `100`.
* Role IDs, Steam IDs, item names, and webhooks use quotes.
* Do not rename permission indexes.
* Do not paste Discord bot tokens into public messages.

Bad:

```lua
UseSteamPermissions = "false"
```

Good:

```lua
UseSteamPermissions = false
```

Bad:

```lua
[28] = { Command = "ban", Roles = {"ADMIN"} }
[29] = { Command = "bring", Roles = {"ADMIN"} }
```

Good:

```lua
[28] = { Command = "ban", Roles = {"ADMIN"} },
[29] = { Command = "bring", Roles = {"ADMIN"} },
```


# Change logs

All SS-Admin updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-Admin V4.7](/ss-admin/change-logs/ss-admin-v4.7)


# SS-Admin V4.7

## Update Summary

SS-Admin V4.7 introduces a more complete administration workflow with panel-based staff tools, expanded permissions, ticket handling, admin chat, admin jail persistence, moderation actions, and improved configuration documentation.

***

## Added

* Added full GitBook documentation for setup, configuration, permissions, ticket system, admin chat, admin jail, and troubleshooting.
* Added admin panel documentation covering player tools, moderation actions, economy actions, horse tools, wagon tools, and staff utilities.
* Added documentation for Discord role permissions and Steam identifier permissions.
* Added documentation for Discord whitelist setup.
* Added documentation for SQL import and database usage.
* Added documentation for `ReportList` and `Report` exports.

***

## Admin Panel & Permissions

* Documented the NUI admin panel workflow.
* Documented important permission indexes and how to safely restrict actions by role.
* Documented command-based and panel-based action access.
* Documented admin categories: `ADMIN`, `MODERATOR`, and `HELPER`.

***

## Ticket & Staff Systems

* Documented the player report command.
* Documented ticket statuses and staff handling flow.
* Documented admin chat behavior and history limit.
* Documented admin jail position, radius, release position, and database persistence.

***

## Config & Translations

* Documented `config.lua`, `s/config.lua`, `l/l.lua`, and `config.js`.
* Added setup notes for `EN`, `RO`, `IT`, `DE`, `FR`, `ES`, and `PT`.
* Added safe editing rules for server owners.

***

## Stability & Setup

* Added recommended start order for `oxmysql`, `SS-Core`, and `SS-Admin`.
* Added optional `pma-voice` setup notes for admin voice.
* Added troubleshooting for permissions, whitelist, Discord bot setup, ticket logs, admin voice, and startup issues.


# SS-Documents

SS-IdentityCard documentation

<figure><img src="/files/Epz3KryTLIKPOyZ5limu" alt=""><figcaption></figcaption></figure>

#### Overview

**SS-Documents** is an advanced system for managing official documents in RedM, designed to enhance roleplay experiences. As an extension of **SS-IdentityCard**, it allows creation, signing, and sharing of various legal documents like certificates, licenses, and statements. This plugin integrates seamlessly into roleplay, offering a Western-themed UI and realistic features for both lawful and unlawful scenarios. **SS-IdentityCard** is needed for operation.

#### Features and Functionality

* **Unlimited Document Creation**: Players can create customizable documents with titles, subtitles, and detailed sections.
* **Fillable Fields**: Input boxes, dates, and text areas that auto-save upon signing.
* **Job-Based Document Access**: Restrictions based on roles via the AllowedDocs config.

#### Document Creation System

Documents are job-restricted:

* **Governor**: Pardon Certificates, Political Affiliation forms.
* **Police**: Firearm Licenses.
* **Mayors**: Marriage, Employment, Divorce Documents.

#### Predefined Categories & Documents

Custom access categories:

* **Public**: Statements, reports, denunciations.
* **Police**: Firearm Licenses.
* **Mayor**: Sales declarations, debt notices.
* **Marshal**: Search Warrants.
* **Governor**: Political Certificates, Pardons.

#### Immersive UI & Features

* **Western UI**: Handwritten appearance for documents.
* **Translations Available**: Document categories and descriptions.
* **In-Game Navigation**: Menu for showing/viewing documents to/from nearby players.

#### Fully Configurable

* **Customization Options**: Document content, job permissions, category settings.
* **Configurable Items**: Example item like cocoa can initiate document creation.
* **Server-Side Saving**: Document status updates upon successful server save.


# Preview

Photos & Video Preview

<figure><img src="/files/EZklBcNNu8HZQQ4QiEbT" alt="IN-GAME UI"><figcaption></figcaption></figure>


# Configuration File

{% code overflow="wrap" %}

```lua
Config = {
    
PaperItem = "paperitem", -- Paper item to start write a new document
Align = "right", 
    
Texts = {
    ["main_menu"] = "Documents",
    ["main_menu_desc"] = "Useful Documents",

    --If you create a category of documents, create a TRANSLATE too, like if you create "medic", add ["medic"] = "Medic Documents" and ["medic_desc"] = "Medic Documents"
    ["public"] = "Public Documents",
    ["public_desc"] = "Official public documents",
    ["police"] = "Police Documents",
    ["police_desc"] = "Official police documents",
    ["primar"] = "Town Hall Documents",
    ["primar_desc"] = "Municipal documents",
    ["guvernator"] = "Government Documents",
    ["guvernator_desc"] = "Official government documents",
    ["maresal"] = "Marshal Documents",
    ["maresal_desc"] = "High-rank police documents",

    ["showdoc"] = "Show Document",
    ["showdoc_desc"] = "Show the document to someone",
    ["viewdoc"] = "View Document",
    ["viewdoc_desc"] = "View the document",
    ["nobody_around"] = "There is nobody around!",
    ["save_document"] = "Document signed and saved !",
},

    
AllowedDocs = {
	--["CATEGORY OF DOCS"] = {"Job1", "Job2"}
	["guvernator"] = {"PolitiaFederala", "Guvernator"},
	["primar"] = {"PolitiaFederala", "Guvernator", "PrimarRhodes", "PrimarValentine", "PrimarBlackWater"},
	["maresal"] = {"PolitiaFederala", "Guvernator", "Maresal"},
	["police"] = {"PolitiaFederala", "Maresal", "Detectiv", "PolitieFrontiera", "OfiterValentine", "SerifValentine", "OfiterAnnesburg", "SerifAnnesburg", "OfiterRhodes", "SerifRhodes", "OfiterBlackWater", "SerifBlackWater"},
	["medic"] = {"MedicRezidentRH", "MedicRezidentBW", "MedicRezidentVAL", "MedicRezidentSD", "MedicSpecialistRH", "MedicSpecialistBW", "MedicSpecialistVAL", "MedicSpecialistSD", "MedicPrimar", "Shaman", "OfiterMedicalVAL", "OfiterMedicalRH", "OfiterMedicalBW", "OfiterMedicalSD"},
},

Documents = {
    ["guvernator"] = {
        {
            Tittle = "POLITICAL AFFILIATION CERTIFICATE",
            subTittle = "Official document certifying active membership in a political party.",
            InformationSubTittle = "Validated and issued by the Territorial Electoral Council.",
            elements = {
                { label = "FULL NAME OF THE MEMBER:", type = "input", value = "",  },
                { label = "POLITICAL PARTY:", type = "input", value = "",  },
                { label = "POSITION OR STATUS:", type = "input", value = "",  },
                { label = "VALID UNTIL:", type = "date", value = "",  },
                { label = "NOTES", type = "textarea", value = "It is hereby confirmed that the above-mentioned citizen holds no criminal record and is legally eligible to participate in political activities. This certificate confirms their legal registration as an active member of a recognized political party within West Frontier territory.", can_be_emtpy = true }
            }
        },
        {
            Tittle = "PARDON CERTIFICATE",
            subTittle = "Official document regarding the annulment of a criminal sentence.",
            InformationTittle = "Issued by the competent authority under Law no. 105 - Pardon.",
            InformationSubTittle = "Through this document, the sentence imposed upon the mentioned individual is officially annulled, granting them release from custody and legal rehabilitation within West Frontier.",
            elements = {
                { label = "NAME OF THE CONVICT:", type = "input", value = "",  },
                { label = "DATE OF CONVICTION:", type = "date", value = "",  },
                { label = "REASON FOR CONVICTION:", type = "input", value = "",  },
                { label = "DATE OF PARDON:", type = "date", value = "",  },
                { label = "ADDITIONAL REMARKS", type = "textarea", value = "The citizen is hereby fully pardoned and has no remaining obligations toward the judicial system related to this conviction. Their criminal record shall be marked as 'legally pardoned'.", can_be_emtpy = true }
            }
        },
    },

    ["public"] = {
        {
            Tittle = "OFFICIAL STATEMENT",
            subTittle = "Legal statement given by a witness to an event.",
            InformationSubTittle = "The undersigned declares under their own responsibility that the information below is true, accurate, and corresponds to reality. This statement is given for official purposes and may be used as legal evidence before the territorial authorities of West Frontier.",
            elements = {
                { label = "Date:", type = "date", value = "",  },
                { label = "Event Description / Testimony", type = "textarea", value = "",  }
            }
        },
        {
            Tittle = "DENUNCIATION STATEMENT",
            subTittle = "Official report to legal authorities.",
            InformationSubTittle = "The person below declares, under personal signature, the facts or individuals involved in an illegal action.",
            elements = {
                { label = "PERSON'S LAST NAME:", type = "input", value = "",  },
                { label = "PERSON'S FIRST NAME:", type = "input", value = "",  },
                { label = "DATE OF EVENT:", type = "input", value = "",  },
                { label = "LOCATION OF INCIDENT:", type = "input", value = "",  },
                { label = "DESCRIPTION OF THE ACT:", type = "textarea", value = "",  },
            }
        }
    },

    ["primar"] = {
        {
            Tittle = "SALES DECLARATION",
            subTittle = "Sales agreement between two citizens.",
            InformationSubTittle = "This statement confirms the transfer of an asset between two parties, by mutual agreement.",
            elements = {
                { label = "BUYER'S NAME:", type = "input", value = "",  },
                { label = "SELLER'S NAME:", type = "input", value = "",  },
                { label = "SALE PRICE:", type = "input", value = "",  },
                { label = "TRANSACTION DATE:", type = "date", value = "",  },
                { label = "DESCRIPTION OF THE ASSET:", type = "textarea", value = "",  },
            }
        },
        {
            Tittle = "DEBT DECLARATION",
            subTittle = "Acknowledgment of debt between citizens.",
            InformationSubTittle = "The debtor acknowledges owing a financial debt to the creditor.",
            elements = {
                { label = "DEBTOR'S NAME:", type = "input", value = "",  },
                { label = "CREDITOR'S NAME:", type = "input", value = "",  },
                { label = "AMOUNT OWED:", type = "input", value = "",  },
                { label = "DUE DATE:", type = "date", value = "",  },
                { label = "NOTES:", type = "textarea", value = "", can_be_emtpy = true },
            }
        },
        {
            Tittle = "TEMPORARY EMPLOYMENT CONTRACT",
            subTittle = "Service agreement between two parties.",
            InformationSubTittle = "The undersigned parties agree to enter a contract for temporary employment.",
            elements = {
                { label = "EMPLOYER'S NAME:", type = "input", value = "",  },
                { label = "WORKER'S NAME:", type = "input", value = "",  },
                { label = "TYPE OF WORK:", type = "input", value = "",  },
                { label = "CONTRACT DURATION:", type = "input", value = "",  },
                { label = "AMOUNT PAID:", type = "input", value = "",  },
            }
        },
        {
            Tittle = "MARRIAGE CERTIFICATE",
            subTittle = "Legal agreement between two individuals to form a family.",
            InformationSubTittle = "By signing this document, both parties are legally married in accordance with local laws.",
            elements = {
                { label = "HUSBAND'S NAME:", type = "input", value = "",  },
                { label = "WIFE'S NAME:", type = "input", value = "",  },
                { label = "DATE OF MARRIAGE:", type = "input", value = "",  },
                { label = "CEREMONY LOCATION:", type = "input", value = "",  },
                { label = "WITNESS NAME:", type = "input", value = "",  },
                { label = "WITNESS NAME:", type = "input", value = "",  },
            }
        },
        {
            Tittle = "DIVORCE AGREEMENT",
            subTittle = "Mutual termination of marriage between two individuals.",
            InformationSubTittle = "The parties below freely and knowingly consent to the dissolution of their existing marriage.",
            elements = {
                { label = "HUSBAND'S NAME:", type = "input", value = "",  },
                { label = "WIFE'S NAME:", type = "input", value = "",  },
                { label = "DATE OF DIVORCE:", type = "input", value = "",  },
                { label = "SIGNING LOCATION:", type = "input", value = "",  },
                { label = "WITNESS NAME:", type = "input", value = "",  },
                { label = "WITNESS NAME:", type = "input", value = "",  },
            }
        },
    },

    ["maresal"] = {
        {
            Tittle = "SEARCH WARRANT",
            subTittle = "Official permission to conduct a search.",
            InformationSubTittle = "Issued under Article 3 of the West Frontier Constitution.",
            elements = {
                { label = "NAME OF PERSON/LOCATION TO BE SEARCHED:", type = "input", value = "",  },
                { label = "DATE OF AUTHORIZATION:", type = "date", value = "",  },
                { label = "DETAILS ABOUT THE SEARCH TARGET", type = "textarea", value = "",  }
            }
        },
    },

    ["police"] = {
        {
            Tittle = "FIREARM LICENSE",
            subTittle = "Special permit to carry a firearm issued by legal authorities.",
            InformationSubTittle = "Official document issued in accordance with territorial regulations.",
            elements = {
                { label = "HOLDER'S FIRST NAME:", type = "input", value = "",  },
                { label = "HOLDER'S LAST NAME:", type = "input", value = "",  },
                { label = "VALID UNTIL:", type = "date", value = "",  },
                { label = "FIREARM SERIAL NUMBER:", type = "input", value = "Optional",  },
                { label = "ADDITIONAL INFORMATION", type = "textarea", value = "The above-mentioned citizen is authorized and granted the legal right to own and use a firearm, under the conditions provided by law, until the stated expiration date.",  }
            }
        },
    },
} -- END DOCUMENTS
}



```

{% endcode %}


# Configuration Helps

The `config.lua` file for the SS-Documents RedM script defines the configuration settings for creating, managing, and accessing documents within the game. Below is an explanation and example code illustrating the key parts of this configuration:

#### Key Configuration Elements

* **PaperItem**: This property specifies the item required to write a new document, which is set to `"`paperitem`"`.
* **Align**: This property sets the text alignment for documents, currently set to `"right"`.
* **Texts**: A table containing text identifiers and their respective string values, used for menu descriptions and document types. This allows customization and localization of different document-related texts.
* **AllowedDocs**: A dictionary that links each document category to specific job roles allowed to access or generate these documents. For example, the `"police"` category can be accessed by roles like `"PolitiaFederala"` and `"Maresal"`.
* **Documents**: This table defines the different document types, with each category containing specific documents, their titles, subtitles, and required form elements.

This code snippet demonstrates how to access and utilize the configuration settings to retrieve menu texts, validate access for different job roles, and interact with document information.


# Change logs

* **18/03/2025**
  * Added compatibility with SS-JoinScene, so players can create ID when join for first time !
* **01/08/2024**
  * **IMIGRATION** - For Server that use Mexico or Guarma like another state ! Now on identitycard police can stamp identitycard of citizens with "IN" and "OUT" stamp from main state. Showing the identitycard now you can see the stamp of imigration ! <= "ENTER MAIN STATE" and => "EXIT MAIN STATE" See screenshot !
  * ![](/files/l84dfHukpu5xJUuyRHxy)


# SS-LuckyTicket

<figure><img src="/files/anCw1pbSscbIfz21RKRa" alt=""><figcaption><p>SS-LuckyTicket</p></figcaption></figure>

The *SS-LuckyTicket* script allows you to create customizable scratch tickets with various prize types and chances, adding a fun and interactive lottery-style feature to your server. Here’s a detailed guide to setting it up and maximizing its features.

#### Integrating with SS-Bank

* **SSBank**: Set to `true` if you have the *SS-Bank* script and want winning tickets to be redeemable as items at any bank location.

  * When `SSBank = true`, players will receive winning tickets as items in their inventory, which they can take to a bank to redeem.
  * When set to `false`, players receive their winnings instantly.

  <pre class="language-lua" data-overflow="wrap"><code class="lang-lua">SSBank = true  -- Options: true (redeem at bank) / false (instant payout)
  </code></pre>

#### 2. Configuring Tickets and Prizes

Each type of ticket (Bronze, Silver, and Gold) has customizable prize options with different winning chances. Adjust the prize amounts and probabilities based on your desired reward structure.

* **Tickets Table**: Each ticket type (`luckyticket`, `luckyticket2`, `luckyticket3`) represents a different tier: Bronze, Silver, and Gold.
  * Each prize option is represented by a prize value (money amount or item name) and a chance percentage.
  * The higher the ticket tier, the greater the potential rewards.

Here’s a breakdown:

**Bronze Ticket (`luckyticket`)**

| Prize     | Chance % | Description             |
| --------- | -------- | ----------------------- |
| `1`       | 15%      | Money amount (1 unit)   |
| `5`       | 10%      | Money amount (5 units)  |
| `25`      | 5%       | Money amount (25 units) |
| `goldbar` | 3%       | Item (Gold Bar)         |

**Silver Ticket (`luckyticket2`)**

| Prize       | Chance % | Description             |
| ----------- | -------- | ----------------------- |
| `5`         | 15%      | Money amount (5 units)  |
| `25`        | 10%      | Money amount (25 units) |
| `50`        | 5%       | Money amount (50 units) |
| `silverbar` | 3%       | Item (Silver Bar)       |

**Gold Ticket (`luckyticket3`)**

| Prize     | Chance % | Description              |
| --------- | -------- | ------------------------ |
| `25`      | 15%      | Money amount (25 units)  |
| `50`      | 10%      | Money amount (50 units)  |
| `100`     | 5%       | Money amount (100 units) |
| `goldbar` | 3%       | Item (Gold Bar)          |

Customize the prizes and chances in each tier based on your server’s economy and desired payout frequency.

#### 3. Customizing In-Game Notifications

The script uses various in-game notifications to communicate the results to players. Here’s a guide to the notification texts you can adjust:

* **"youwin"**: Message displayed upon winning, showing the prize amount.
* **"winnotifybank"**: Message shown when a player wins a ticket item (for *SS-Bank* redemption).
* **"winnotify"**: Notification displayed for instant cash wins.
* **"youlose"**: Message shown when a player does not win.
* **"notnearbank"**: Notification instructing players to visit a bank for ticket redemption.
* **"winonticket"** & **"loseonticket"**: Text shown directly on the scratch ticket (win/lose message).
* **"scratchInfo"**: Instructions for scratching the ticket.

Example of the configuration for `Translate` table:

```lua
Translate = {
    ["youwin"] = "WIN PRIZE: ",
    ["winnotifybank"] = "You win, redeem the prize at any Bank, Prize: ",
    ["winnotify"] = "CONGRATS! From this ticket, you win ",
    ["youlose"] = "TRY AGAIN, MAYBE MORE LUCK NEXT TIME...",
    ["notnearbank"] = "REDEEM this ticket at any Bank!",
    ["winonticket"] = "💲 ! CONGRATS !💲",
    ["loseonticket"] = "❌ ! YOU LOSE ! ❌",
    ["scratchInfo"] = "Scratch with the cursor, remember to scratch it to the end!",
}
```

#### 4. Custom Notification Function

To further personalize the experience, you can set custom notifications using the `NOTIFY(text)` function. This lets you modify how notifications appear to players.

Default example:

```lua
function NOTIFY(text)
    TriggerEvent("vorp:TipBottom", text, 5000) -- Sends a bottom screen notification for 5 seconds
end
```

Replace `"vorp:TipBottom"` with your server’s notification function if needed.

***

By following this guide, you’ll be able to configure *SS-LuckyTicket* to match your server’s economy, customize win/loss notifications, and adjust ticket redemption options to suit your preferences.


# Configuration File

{% code overflow="wrap" %}

```lua
-- Author Sirec Studio -- 
-- REPORT ANY BUGS ON https://discord.gg/9XNBaQSmMd --

Config = {
    
SSBank = true, -- true IF YOU HAVE SS-Bank AND GET THE WIN TICKET IN INVENTORY AS ITEM AND REDEEM IT AT BANK / false TO GET PRIZE INSTANTLY !    
    
Tickets = {
    ["luckyticket"] = { -- BRONZE TICKET
		[1] = {
			Prize = 1, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 15, -- % OF CHANCE
		},
		[2] = {
			Prize = 5, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 10, -- % OF CHANCE
		},
		[3] = {
			Prize = 25, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 5, -- % OF CHANCE
		},
		[4] = {
			Prize = "goldbar", -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 3, -- % OF CHANCE
		},
	},
    ["luckyticket2"] = { -- SILVER TICKET
		[1] = {
			Prize = 5, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 15, -- % OF CHANCE
		},
		[2] = {
			Prize = 25, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 10, -- % OF CHANCE
		},
		[3] = {
			Prize = 50, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 5, -- % OF CHANCE
		},
		[4] = {
			Prize = "silverbar", -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 3, -- % OF CHANCE
		},
	},
    ["luckyticket3"] = { -- GOLD TICKET
		[1] = {
			Prize = 25, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 15, -- % OF CHANCE
		},
		[2] = {
			Prize = 50, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 10, -- % OF CHANCE
		},
		[3] = {
			Prize = 100, -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 5, -- % OF CHANCE
		},
		[4] = {
			Prize = "goldbar", -- NUMBER FOR MONEY (EX: 10,) - ITEMNAME FOR ITEM (EX: "chocolate")
            Chance = 3, -- % OF CHANCE
		},
	},
},

Translate = {
	["youwin"] = "WIN PRIZE: ",
	['winnotifybank'] = 'You win, redeem the prize at any Bank, Prize: ',
	['winnotify'] = "CONGRATS !, From this ticket you win ",
	['youlose'] = 'TRY AGAIN, MAYBE MORE LUCK NEXT TIME...',
	["notnearbank"] = "REDEEM this ticket at any Bank !",
	['winonticket'] = '💲 ! CONGRATS !💲',
	['loseonticket'] = '❌ ! YOU LOSE ! ❌',
	['scratchInfo'] = 'Scratch with the cursor, remember to scratch it to the end! ',
	},
}    

function NOTIFY(text) --SET YOUR NOTIFICATIONS
	TriggerEvent("vorp:TipBottom", text, 5000) 
end 
```

{% endcode %}


# Use Custom Images

#### Using Custom Ticket Images in SS-LuckyTicket with Base64 Encoding

To use custom images for the scratch tickets in *SS-LuckyTicket*, follow these steps to convert your images to Base64 format and update the `imageDataScript.js` file accordingly.

**Step 1: Convert Custom Images to Base64**

1. **Prepare Your Images**: Design or select custom images for each ticket type (e.g., Bronze, Silver, Gold). Save these images in `.png` or `.jpg` format.
2. **Convert to Base64**:
   * Use an online tool, like [base64-image.de](https://www.base64-image.de/) or [Image to Base64](https://www.base64encode.org/), to convert each image.
   * Upload the image to the tool, generate the Base64 code, and copy the resulting string.

**Step 2: Update `imageDataScript.js`**

In `imageDataScript.js`, each ticket type (`luckyticket`, `luckyticket2`, etc.) has its Base64 image data stored as a string.

1. **Locate the Ticket Definitions**:
   * You’ll see entries like `imageData["luckyticket"]`, `imageData["luckyticket2"]`, etc.
   * Each entry holds a Base64 string that represents the image for that specific ticket.
2. **Replace Base64 Strings**:
   * Replace the existing Base64 string with your new custom Base64-encoded image data. Ensure you keep the `data:image/png;base64,` prefix, as shown in the existing structure.

Example for updating the Bronze Ticket (luckyticket):

{% code overflow="wrap" %}

```javascript
imageData["luckyticket"] = 'data:image/png;base64, <Your Custom Base64 Data Here>';
imageData["luckyticket2"] = 'data:image/png;base64, <Your Custom Base64 Data Here>';
imageData["luckyticket3"] = 'data:image/png;base64, <Your Custom Base64 Data Here>';
```

{% endcode %}

Replace `<Your Custom Base64 Data Here>` with the Base64 string from your converted image.

**Step 3: Save and Test**

1. **Save Changes**: After pasting your new Base64 strings, save `imageDataScript.js`.
2. **Restart the Resource**: Restart *SS-LuckyTicket* or the server to apply changes.
3. **Verify in Game**: Check each ticket type in the game to ensure the custom images display as expected.

***

Following these steps will allow users to replace the default ticket images with their own custom designs in *SS-LuckyTicket*.


# SS-Bank

SS-Bank System Script Documentation

<figure><img src="/files/4JLmOTDBWfahqz3DPmLx" alt=""><figcaption></figcaption></figure>

**Overview**

**SS-Bank** is the most comprehensive and immersive banking system designed for RedM, featuring an advanced suite of tools for player and director-level financial management. Built for both roleplay immersion and economic depth, SS-Bank offers full support for real-time player banking, gold market simulation, director control systems, salary automation, and secure stash interactions.

This modular system handles all aspects of in-game banking, from classic deposit/withdraw systems to check creation, salary distribution, loan processing, taxation, market price simulation, and gold trading. Players can manage both their **money and gold accounts**, request and repay loans, generate checks, and even access market data with dynamic pricing. Meanwhile, **bank directors** have access to backend controls to manage stashes, freeze accounts, issue salaries, oversee customers, and view logs with full transparency.

Whether you're looking to simulate a historical bank, introduce a functional economy, or roleplay a professional financial director, SS-Bank provides all the tools needed to build a living, breathing economy inside your RedM server.

### Core Banking System

* Full account system for **money and gold** (with separate balances).
* Support for **multiple bank branches** with NPC interaction and director job assignments.
* Each bank has customizable stash capacity, NPC model, distance, and interaction blip.
* **Blacklist item filter** to prevent depositing illegal or dangerous items.
* Directors can be assigned per bank using `Job` and positional configurations.

### Gold Market System

* Real-time **gold buying and selling** based on market prices.
* Fallback prices used if market API is offline (`DefaultBuyGold`, `DefaultSellGold`).
* Option to **manually alter gold market** prices with a custom divisor.
* Separate deposit and withdraw systems for **gold account**.
* Integrated **gold bar item** conversion and tracking.

### Loan Management

* Players can request loans if they meet job conditions and optional identity verification.
* Fully configurable **loan fee**, **repayment plan**, **maximum amount**, and **intervals**.
* Supports compatibility with `SS-IdentityCard` and `SS-Archives` for deeper integration.
* System automatically calculates **loan payback over time** based on configuration.

### Check System

* Players can generate **bank checks** with full detail: name, amount, memo, and expiration.
* Support for **blank/white checks** if no receiver is filled.
* Checks have a configurable cost and minimum value to prevent spam.
* **Custom check item** defined in config (ex: cocoa).
* Optional **alert system for police** if players attempt to deposit stolen/fake checks.

### Director & Staff Tools

* Configurable **director job** per bank.
* Access to a secure **customer stash** system.
* Full **customer view**: account details, gold, loans, transaction history.
* Ability to **freeze/unfreeze accounts** (if enabled).
* Director salary is auto-generated as a **percentage of total bank revenue** (from tax or config).
* Special **backend UI** for managing all financial and customer data.
* NPC-controlled access points and interaction distance to simulate real banking halls.

### Taxation & Salaries

* Enable server-wide **tax system** with configurable rate and intervals.
* Taxes apply to deposits, withdrawals, and salary income.
* Option to **automatically pay player salaries** on intervals (based on bank budget).
* Salary % is configurable and paid from the bank’s collected budget.
* Fully compatible with role-based economy systems.

### Security Stash System

* Secure access system via `SecurityButton`, with configurable stash size per bank.
* Restricted to bank jobs or director only.
* Optional **waiting animation** for immersive RP interaction.

### Transaction History

* Full **transaction log and history** system for director oversight.
* Option to auto-delete transaction history after X days to avoid database bloat.
* Easy access for directors via backend UI.

### Bank Checks & Customer Access

* Detailed **check printing** with signature, expiration, and memo fields.
* Players can print up to `MaxCheckRequests` checks.
* Blank checks can be gifted, traded, or used for in-character transactions.

### Customization & Extensibility

* Full support for multi-language files (`Language = "EN"`)
* Server era/year customizable (`ServerYear = 1899`)
* Optimized logging with optional webhook integration.
* Ready for integration with external systems: SS-IdentityCard, SS-Archives, SS-PoliceJob.
* Supports dynamic economy, historical roleplay, and custom banking strategies.


# Preview

{% tabs %}
{% tab title="Bank UI" %}

<figure><img src="/files/VcEoHuHmh0LuApzUbuXM" alt=""><figcaption><p>Bank UI</p></figcaption></figure>

{% endtab %}

{% tab title="Bank Check" %}

<figure><img src="/files/VMRoOk7bp78lgwjXmqmO" alt=""><figcaption><p>Check Bank UI</p></figcaption></figure>

{% endtab %}

{% tab title="Director UI" %}

<figure><img src="/files/2cyJYMuHY9mm7DIW6UjY" alt=""><figcaption><p>Bank Management from Director Backend</p></figcaption></figure>

{% endtab %}

{% tab title="Transactions" %}

<figure><img src="/files/FrOSHKug9q0DqgRcKxc7" alt=""><figcaption><p>Transactions UI from Director Backend</p></figcaption></figure>

{% endtab %}
{% endtabs %}


# Configuration File

### config.lua

{% code overflow="wrap" %}

```lua
-- Author: SIREC
-- Report any bugs on: https://discord.gg/9XNBaQSmMd

Config = {

    -- Logging and Development Settings
    WebHook = "", -- Webhook URL for logging
    Dev = true, -- Set to `true` for testing; `false` for production
    Language = "EN", -- Language (check `l/l.lua` for available options)
    WaitingAnime = false, -- Enable Random Waiting Animation while using bank ? 8 for female, 8 for male (RP Improve)
    ServerYear = 1899,

    -- Interaction Buttons
    BankButton = 0x760A9C6F, -- Open Bank Button
    SecurityButton = 0x9959A6F0, -- Open Security Stash Button
    ExchangeButton = 0xD9D0E1C0, -- Exchange Button
    CheckButton = 0x4BC9DABB, -- Ask checks buttont/t

    -- Account Management
    CanLock = false, -- Allow Director to freeze player accounts
    GoldBarItem = "goldbar", -- Item used for gold bar exchange
    
    -- Check Settings
	UseCheck = true, -- Enable check system ?
    MinAmount = 5, -- Min amount to sign a check, 0 di disable
    PricePerCheck = 2, -- Price to pay for every check, false to disable and being free
    CheckItem = "cocoa", -- Check item to use 
	MaxCheckRequests = 10, -- Max checks a player can ask
	AlertPolice = false, -- Alert Police when somebody try deposit a check of somebody else ?
    
    -- History Settings
    UseHistory = true, -- Enable Transaction history (You need have the sql for bank_history)
    DeleteAfterDays = 30, -- Auto delete transactions after X days ! (Helps cleaning database)
    
    
    -- Tax Settings
    UseTax = false, -- Enable taxes for players
    TaxTime = 7, -- Interval (days) for tax collection
    TaxPrice = 1, -- Tax percentage (e.g., 1% of $50,000 is $500)
    TaxWithdraw = 1, -- Tax percentage on withdrawals
    TaxDeposit = 1, -- Tax percentage on deposits

    -- Item Restrictions
    BlacklistItems = { -- Restricted items for banking
        "cigarette", "weed_leaves", "heroin", "opium", "morphine", "cigar", "joint",
        "weedbags", "hashish", "lockpick", "ammodynamite", "smallbomb", "bigbomb",
        "ammopoisonbottle", "handcuffs", "handcuffskey", "typhus_injection"
    },

    -- Loan Settings
    Loans = {
        SSArchives = false, -- Allow loans only if the player has no dossiers (requires SS-Archives)
        SSIdentityCard = false, -- Require an identity card for loans (requires SS-IdentityCard)
        Jobs = { -- Jobs allowed to take loans
            "Serif", "Maresal", "Judecator", "Guvernator", "PolitiaFederala", "Detectiv",
            "PolitieFrontiera", "VanatorRecompense", "Medic", "Shaman", "Armurier",
            "Miner", "Padurar", "AntrenorCai", "Fierar", "Bijutier", 
            "PrimarBlackWater", "PrimarRhodes"
        },
        Fee = 25, -- Loan fee percentage (e.g., 25% means $1,000 loan requires $1,250 payback)
        PayBacks = 20, -- Percentage deducted per loan installment
        LoanTime = 3, -- Interval (days) for loan repayments
        MaxLoan = 5000, -- Maximum loan amount a player can request
    },

    -- Salary Settings
    SalaryTime = 60, -- Interval (minutes) for salary payouts
    DirectorSalary = 0.5, -- Director salary as a percentage of bank budget (e.g., $20,000 in taxes = $100 salary)

    -- Bank Configurations
    Banks = {
        [1] = {
            Name = "NewHorizon Bank Rhodes", -- Bank Name
            Id = 1, -- Bank ID (used in SS-BankHeist)
            Active = true, -- Enable or disable this bank
            Bank = "Rhodes", -- Internal identifier (do not change)
            Stash = 300, -- Stash slot limit
            Pos = {1292.82, -1304.67, 76.14, -31.90}, -- Bank menu position
            Director = {1288.12, -1309.54, 77.16}, -- Director menu position
            Job = "PrimarRhodes", -- Required job for director
            Npc = "s_m_m_bankclerk_01", -- NPC model (set `false` to disable)
            Blip = -2128054417, -- Blip ID for map marker (`false` to disable)
            Distance = 2.5, -- Interaction distance
        },
        [2] = {
            Name = "NewHorizon Bank Sant Denise",
            Id = 2,
            Active = false,
            Bank = "Saint Denis",
            Stash = 300,
            Pos = {2645.07, -1294.01, 51.35, 21.85},
            Director = {-813.25, -1275.34, 42.74, -174.97},
            Job = "PrimarSaintDenis",
            Npc = "s_m_m_bankclerk_01",
            Blip = -2128054417,
            Distance = 2.5,
        },
        [3] = {
            Name = "NewHorizon Bank Valentine",
            Id = 3,
            Active = true,
            Bank = "Valentine",
            Stash = 300,
            Pos = {-308.01, 773.92, 117.80, 13.64},
            Director = {-308.85, 767.31, 118.49},
            Job = "bankVT",
            Npc = "s_m_m_bankclerk_01",
            Blip = -2128054417,
            Distance = 2.5,
        },
        [4] = {
            Name = "NewHorizon Bank Blackwater",
            Id = 4,
            Active = true,
            Bank = "Blackwater",
            Stash = 300,
            Pos = {-813.34, -1277.52, 43.64, 351.36},
            Director = {-820.71, -1278.61, 43.64, 349.08},
            Job = "bankBW",
            Npc = false,
            Blip = -2128054417,
            Distance = 1.5,
        },
    },
}

-- Notification Function
function NOTIFY(text)
    TriggerEvent("vorp:TipBottom", text, 5000) -- Display notification at the bottom for 5 seconds
end

-- Police Notification
function AlertPolice(bank, coords)
    local coords = {x = coords.x, y = coords.y, z = coords.z}
    local notify = "Notify of an possible FRAUD at Bank"..bank
    local bliptype = 1366733613
    local blipradius = 30.0
    local blipname = "Fraud Bank"
    local blipremove = 10
    exports["SS-PoliceJob"]:PoliceAlert(coords, notify, blipradius, bliptype, blipname, blipremove)
end    
```

{% endcode %}

### config.js

```javascript
TR = {
    loans_tittle: "LOANS REQUESTS",
    all_customers: "CUSTOMERS",
    dir_bank_account: "BANK BUGET",
    dir_salary: "DIRECTOR SALARY",
    trmoneyaccount: "MONEY ACCOUNT",
	trdepositmoney: "DEPOSIT",
    withdrawmoney: "WITHDRAW",
    trgoldaccount: "GOLD ACCOUNT",
	depositgold: "DEPOSIT",
	withdrawgold: "WITHDRAW",
	marketbuygold: "MARKET BUY GOLD",
    buygold: "BUY",
    marketsellgold: "MARKET SELL GOLD",
    sellgold: "SEL",
    unionbankloans: "UNION BANKS LOANS",
    activeloans: "YOUR ACTIVE LOANS",
    askloan: "ASK LOAN",
    wantloan: " wants ",
    loanaccept: "Accept",
    loandecline: "Decline",
    
    //NEW
    checkTittle: "Bank Check Of",
    checkPay: "PAY TO THE ORDER OF: ",
    checkReceive: "INTENDED TO: ",
    checkReceiverInfo: "Name or leave empty for white check",
    checkAmount: "AMOUNT: $",
    checkMemo: "MEMO: ",
    checkDescInfo: "Description of payment...",
    checkSignature: "SIGN HERE",
	checkDate: "DATE:",
    checkDays: "EXPIRE IN:",
    checkExpDays: "DAYS",
    customerInfos: "CUSTOMER FIRSTNAME AND LASTNAME:",
    customerInfoMoney: "CUSTOMER MONEY:",
    customerInfoGold: "CUSTOMER GOLD:",
    customerLoans: "CUSTOMER LOAN:",
    customerPayback: "CUSTOMER PAYBACK:",
    customerTransactions: "CUSTOMER TRANSACTIONS:",
    
    TableFirstname: "Firstname",
    TableLastname: "Lastname",
    TableGold: "Gold",
    TableMoney: "Money",
    TableLock: "Freeze",
    TableUnlock: "Release",
    TableStash: "Stash",
    TableDate: "Date/Time",
    TableAmount: "Amount",
    TableInfo: "Information",
    TableType: "Type",
    backButton: "BACK TO CUSTOMERS",
    
    // CONFIG
    UseHistory: true, // ENABLE Buttons and functions for history of transactions !
    DirectorOpenStash: true, // ALLOW DIRECTOR TO HAVE ACCESS TO STASH OF PEOPLE ?
	MarketGold: 5, // ALTER MARKET GOLD PRICE BY ( / 2) 2 means half price of market price !
    DefaultBuyGold: 17.60, // IF WEBSITE MARKET DOSEN'T RESPOND OR OFFLINE USE DEFAULT
    DefaultSellGold: 15.60, // IF WEBSITE MARKET DOSEN'T RESPOND OR OFFLINE USE DEFAULT
};
```


# Configuration Helps

SS-Bank Configuration Guide

**SS-Bank Configuration Guide**

Below are the customizable options available in the `config.lua` file:

### **General Settings**

* **`Dev`**: `true`\
  Enables developer/debug mode. Set to `false` on production servers.
* **`Language`**: `EN`\
  Language file used (must match a file inside `l/l.lua`).
* **`WebHook`**: `""`\
  Discord Webhook for logging bank transactions and actions.
* **`WaitingAnime`**: `false`\
  Enables a short idle animation when accessing bank menus (for immersion).
* **`ServerYear`**: `1899`\
  Used for check stamping and timeline simulation.

***

### Permissions and Features

* **`CanLock`**: `false`\
  Allows bank directors to freeze or unfreeze player accounts.
* **`UseCheck`**: `true`\
  Enables the bank check system.
* **`UseHistory`**: `true`\
  Enables transaction history tracking. Requires SQL table `bank_history`.
* **`SSArchives`**: `false`\
  If `true`, players with a criminal record cannot take loans (requires SS-Archives).
* **`SSIdentityCard`**: `false`\
  If `true`, players need a valid identity card to apply for loans (requires SS-IdentityCard).

***

### Bank Interaction Buttons

* **`BankButton`**: `0x760A9C6F`\
  Keybind for opening the standard bank menu.
* **`SecurityButton`**: `0x9959A6F0`\
  Keybind for accessing the secure stash (for directors only).
* **`ExchangeButton`**: `0xD9D0E1C0`\
  Keybind to open the currency/gold exchange interface.
* **`CheckButton`**: `0x4BC9DABB`\
  Keybind to access the check creation menu.

***

### Gold and Check System

* **`GoldBarItem`**: `"goldbar"`\
  Item name used for gold deposits/withdrawals.
* **`MinAmount`**: `5`\
  Minimum amount to write a check. Set to `0` to disable checks below this value.
* **`PricePerCheck`**: `2`\
  Cost in dollars for creating each check. Set to `false` for free checks.
* **`CheckItem`**: `"cocoa"`\
  Item given to players that represents a check.
* **`MaxCheckRequests`**: `10`\
  Maximum number of checks a player can generate.
* **`AlertPolice`**: `false`\
  If enabled, alerts police when someone tries to deposit a stolen check.

***

### Loan Configuration

* **`Fee`**: `25`\
  Percentage added on top of the requested loan. Example: a $1,000 loan with a 25% fee means total to repay = $1,250.
* **`PayBacks`**: `20`\
  Percentage of the original loan repaid on each installment. Example: 20% of $1,000 = $200 per interval.
* **`LoanTime`**: `3`\
  Number of **days** between each loan repayment.
* **`MaxLoan`**: `5000`\
  Maximum loan value a player can request.
* **`Jobs`**: `{ "civilian", "blacksmith", "farmer" }`\
  List of jobs allowed to take loans.

***

### Salary & Tax System

* **`SalaryTime`**: `60`\
  Time interval (in minutes) between salary payouts for the bank director.
* **`DirectorSalary`**: `0.5`\
  Percentage of total bank budget (from taxes) paid as director salary.\
  Example: If `DirectorSalary = 0.5` and bank has $20,000, payout = $100.
* **`UseTax`**: `false`\
  Enables tax system for withdrawals and deposits. Must be `true` to activate `Tax*` values below.
* **`TaxTime`**: `7`\
  Time interval (in days) between automatic tax collection.
* **`TaxPrice`**: `1`\
  Tax percentage for general income (used with `Salary` and budget logic).
* **`TaxWithdraw`**: `1`\
  Percentage taxed when a player withdraws money.
* **`TaxDeposit`**: `1`\
  Percentage taxed when a player deposits money.

***

### Transaction History

* **`UseHistory`**: `true`\
  Enables transaction logging and history (requires SQL table `bank_history`).
* **`DeleteAfterDays`**: `30`\
  Auto-deletes transactions older than the configured number of days (to prevent database overload).

***

### Item Blacklist

**`BlacklistItems`**\
A table of item names that cannot be deposited into the bank stash (for security).\
Example:

```lua
BlacklistItems = {
    "explosive",
    "dynamite",
    "illegal_documents"
}
```

***

### Bank Branches (Multi-Bank System)

Each entry inside `Banks = {}` defines a bank branch:

#### Example:

```lua
luaCopiaModifica[1] = {
    Name = "NewHorizon Bank Rhodes",
    Id = 1,
    Active = true,
    Bank = "Rhodes",
    Stash = 300,
    Pos = {1292.82, -1304.67, 76.14, -31.90},
    Director = {1288.12, -1309.54, 77.16},
    Job = "PrimarRhodes",
    Npc = "s_m_m_bankclerk_01",
    Blip = -2128054417,
    Distance = 2.5,
}
```

#### Description of fields:

* **`Name`**\
  Displayed name of the bank (appears on UI, receipts, and logs).
* **`Id`**\
  Unique identifier for the bank. Also used for integrations (e.g., SS-BankHeist).
* **`Active`**\
  Enables or disables this branch. If `false`, it won’t appear in-game.
* **`Bank`**\
  Internal name used in logs and backend. Do **not** rename unless you know what you're doing.
* **`Stash`**\
  Maximum number of slots in the bank’s secure stash.
* **`Pos`**\
  Coordinates and heading for the player interaction point (bank entrance).
* **`Director`**\
  Coordinates for the director UI menu (back office).
* **`Job`**\
  Required job to access director features for this branch.
* **`Npc`**\
  The ped model for the bank NPC. Set to `false` to disable.
* **`Blip`**\
  Map blip ID. Set to `false` to hide the bank on the map.
* **`Distance`**\
  Distance at which players can interact with the NPC/menu.


# Change logs

### 03/04/2025

* Realtime GOLD market prices FIXED !
* Sign Checks button FIXED !


# SQL

BANK USERS ( Main Sql )

```sql
CREATE TABLE IF NOT EXISTS `bank_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `identifier` varchar(50) NOT NULL,
  `charidentifier` int(11) NOT NULL,
  `money` double(22,2) DEFAULT 0.00,
  `gold` double(22,2) DEFAULT 0.00,
  `time` int(11) DEFAULT 0,
  `loan` int(11) DEFAULT 0,
  `loantime` int(11) DEFAULT 0,
  `payback` int(11) DEFAULT 0,
  `firstname` varchar(50) DEFAULT NULL,
  `lastname` varchar(50) DEFAULT NULL,
  `freeze` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=7421 DEFAULT CHARSET=latin1;
```

BANK CHECKS ( Only if you enable and use it )

```sql
CREATE TABLE IF NOT EXISTS `bank_checks` (
  `id` varchar(100) NOT NULL DEFAULT '0',
  `owner` varchar(500) DEFAULT NULL,
  `destinate` varchar(500) DEFAULT NULL,
  `date` varchar(50) DEFAULT NULL,
  `expire` varchar(50) DEFAULT NULL,
  `bank` varchar(50) DEFAULT NULL,
  `amount` int(11) DEFAULT NULL,
  `description` varchar(500) DEFAULT NULL,
  `timer` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
```

BANK HISTORY ( Only if you enable and use it )

```sql
CREATE TABLE IF NOT EXISTS `bank_history` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `charid` int(11) DEFAULT NULL,
  `info` varchar(500) DEFAULT NULL,
  `type` varchar(50) DEFAULT NULL,
  `amount` decimal(20,6) DEFAULT NULL,
  `bank` varchar(50) DEFAULT NULL,
  `date` varchar(50) DEFAULT NULL,
  `timer` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1;
```


# SS-JoinScene

SS-JoinScene documentation

<figure><img src="/files/5KpLo6GjFzNe1zvHoTac" alt=""><figcaption></figcaption></figure>

**Overview**

\
**SS-JoinScene** is a fully customizable and immersive **intro scene system** for FiveM, designed to provide a cinematic and engaging welcome experience for players joining the server. Whether it's a **new character introduction** with an AI-generated voice greeting or a **wakeup scene for returning players**, SS-JoinScene enhances roleplay immersion while allowing server owners to define their unique introductory atmosphere.

1. **Dynamic Intro Experience**
   * With **SS-JoinScene**, new players are greeted with a **custom intro scene** featuring **AI voice narration**, stating their name and the server’s name in a personalized message. This feature ensures every player receives a warm and immersive introduction upon their first login.

     For **returning players**, SS-JoinScene offers a **Wakeup Scene**, simulating a smooth transition back into the world. Players can spawn in one of the **major cities**, reinforcing immersion and continuity in the game world.
2. **Cinematic Character Introduction**
   * Fully **customizable intro video** for new players.
   * **AI-generated voice narration** that welcomes players using their **in-game name** and the server’s name.
   * Seamless transition into roleplay from the very first moment.
3. **Wakeup Scene for Returning Players**
   * Players rejoining the server will spawn using a **realistic wakeup scene**, enhancing immersion.
   * Configurable spawn locations in **major cities** like **Valentine, Blackwater, Rhodes, Saint Denis, Strawberry, Annesburg, Armadillo, and Tumbleweed**.
   * **Customizable wakeup title** (default: "A Few Hours Later").
4. **Configurable Identity System**
   * **Enforce character identity creation** before first login using the built-in **SS-IdentityCard** system.
   * Ensures all new players register their character details before entering the world.
5. **Server-Specific Customization**
   * **Owners can modify the welcome message** and AI narration text.
   * Choice of **male or female AI voice** with multiple voice options.
   * Customize spawn locations and intro video per city.
   * Easily enable or disable specific features via `config.lua`.
6. **Developer & Admin Utilities**
   * **Test your scenes in real-time** using `/testscene` (if enabled).
   * Lightweight and optimized for performance, ensuring smooth gameplay integration.
   * Easy-to-edit configuration file for hassle-free adjustments.


# Preview

Photos & Video Preview

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

<figure><img src="/files/hCYtuodeFNjFT6yNryJ2" alt=""><figcaption><p>WITHOUT SS-IDENTITYCARD ( Select directly the spawn point )</p></figcaption></figure>

<figure><img src="/files/pw2PQ9XuIsxE42cQdca2" alt=""><figcaption><p>WITH SS-IDENTITYCARD ( Create identity card before spawn )</p></figcaption></figure>


# Configuration File

{% code overflow="wrap" %}

```lua
-- Author 'SIREC' DISCORD USERNAME
-- REPORT ANY BUGS ON https://discord.gg/9XNBaQSmMd --

Config = {
    
Dev = true, -- IF true YOU CAN CHECK THE MAP WITH /testscene / IF false WILL DISABLE IT
UseVideoNewCharacter = true, -- INTRO FOR NEW CHARACTERS ?
SSIdentityCard = false, -- If true any new character will be forced to create an ID before join the server !

UseRejoinScene = true, -- WAKEUP SCENE WHEN JOIN ?
FewMomentLater = "Title_Gen_FewHoursLater",
AiVoiceNewChar = {
	Gender = "M", -- M or F
    Voice = 4, -- VOICES 5 MAX
    Text1 = "Hello ", -- > NAME > TEXT2
    Text2  = ", welcome to Sirec Studio server, this is an example welcome text, but any owner can set his own welcome text. Enjoy you stay...!",
},
    
Cities = {
    [1] = {coords = vector4(-167.455, 631.407, 114.032, 0.0), label = "Valentine", video = "default.mp4"}, --Valentine file or link !
	[2] = {coords = vector4(-798.759, -1205.143, 44.140, 0.0), label = "Blackwater", video = "default.mp4"}, --Annesburg file or link !
    [3] = {coords = vector4(1227.376, -1304.366, 76.904, 0.0), label = "Rhodes", video = "default.mp4"}, --Rhodes file or link !
    [4] = {coords = vector4(2683.544, -1444.589, 46.254, 0.0), label = "Saint Denis", video = "default.mp4"}, --Saint Denis file or link !
	[5] = {coords = vector4(-1776.22, -435.98, 155.00, 0.0), label = "Strawberry", video = "default.mp4"}, --Strawberry file or link !
	[6] = {coords = vector4(2945.909, 1281.752, 44.623, 0.0), label = "Annesburg", video = "default.mp4"}, --Annesburg file or link !
	[7] = {coords = vector4(-3739.4717, -2607.5571, -14.1842, 0.0), label = "Armadillo", video = "default.mp4"}, --Armadillo file or link !
	[8] = {coords = vector4(-5514.7397, -2918.6450, -2.6882, 0.0), label = "Tumbleweed", video = "default.mp4"}, --Tumbleweed file or link !
},
    
}
```

{% endcode %}


# Configuration Helps

### **Configuration Options**

Below are the customizable options available in the `config.lua` file:

#### **1. General Settings:**

* **Dev Mode:** `Dev = true` – Enables debug mode for testing. Set to `false` for production. If enabled, administrators can test the join scene using `/testscene`.
* **New Character Intro:** `UseVideoNewCharacter = true` – If `true`, new players will be welcomed with an **intro scene** and AI voice.
* **Identity Requirement:** `SSIdentityCard = true` – If `true`, all new players **must** create an identity card before joining the server.
* **Wakeup Scene:** `UseRejoinScene = true` – Enables the **wake-up scene** for returning players, ensuring a smooth transition into the world.

#### **2. AI Voice Configuration:**

* **Gender Selection:** `Gender = "M"` – Determines the AI voice gender (`M` for male, `F` for female).
* **Voice Type:** `Voice = 4` – Selects the AI voice variant (up to 5 different voices available).
* **Customizable Welcome Message:**
  * **Text1:** `"Hello "` – The opening text before the player's name.
  * **Text2:** `", welcome to Sirec Studio server..."` – The rest of the welcome message after the player’s name.
  * The server owner can fully customize this message.

#### **3. City Spawn Locations:**

When joining the server, players can spawn in one of the following cities. Each location can have a unique **video intro** file or link:

* **Valentine:** `vector4(-167.455, 631.407, 114.032, 0.0)`
* **Blackwater:** `vector4(-798.759, -1205.143, 44.140, 0.0)`
* **Rhodes:** `vector4(1227.376, -1304.366, 76.904, 0.0)`
* **Saint Denis:** `vector4(2683.544, -1444.589, 46.254, 0.0)`
* **Strawberry:** `vector4(-1776.22, -435.98, 155.00, 0.0)`
* **Annesburg:** `vector4(2945.909, 1281.752, 44.623, 0.0)`
* **Armadillo:** `vector4(-3739.4717, -2607.5571, -14.1842, 0.0)`
* **Tumbleweed:** `vector4(-5514.7397, -2918.6450, -2.6882, 0.0)`

Each city can be configured to have a **default or custom intro video** (`video = "default.mp4"`).


# Change logs

Read what's new and what was changed.

* **14/07/2024**
  * **AI VOICE** - Intro saying the player name with an welcome voice !

* **18/03/2025**
  * Added compatibility with **SS-IdentityCard**, so when enable after choice the spawn point thei will be forced to create an identity card before continue !
  * Added delay on show spawn points so player's can hear the welcome sound before continue with the intro videos.


# SS-Stable

SS-Stable documentation

<figure><img src="/files/7UrMYCrwQEGyXB23zn6A" alt=""><figcaption></figcaption></figure>

**Overview**

**SS-Stable** is the ultimate and most advanced stable management system for RedM, offering a complete suite of features for horse and wagon ownership, training, taming, breeding, equipment customization, selling, and more. Designed with immersion and realism in mind, this system transforms the way players interact with their horses and wagons, creating an unparalleled roleplay experience.

Whether you're running a large economy server or a smaller roleplay-focused community, SS-Stable provides the flexibility, depth, and performance to handle every aspect of stable life. From animated training routines and genetic-based breeding to an online marketplace and personal stables with individual inventories, every feature is carefully built to simulate a real horse world.

* **Complete Horse System**
  * Tame, train, and breed horses with custom EXP, age stages, and traits.
  * 7 horse life stages: Foal, Young, Training, Breedable, Adult, Old, Dead.
  * Breeding logic includes sex, age, race, and blacklist compatibility.
  * Foal gestation with configurable day-based stages (ride, train, adult).
* **Taming System**
  * Real reaction-based minigame to tame wild horses.
  * Taming tied to job roles and age requirements.
  * Horses can be sold or kept after successful taming.
  * Blacklist control for which horses can/cannot be tamed or sold.
* **Realistic Breeding System**
  * Cross-breeding allowed with 24 unique outcomes.
  * Gestation period, pregnancy penalties (stats), and newborn progression.
  * Inherits traits and race with configurable chance.
  * Full breeding blacklists per horse breed category.
* **Advanced Training**
  * Three training types: Steps, Action-based, and Manual Free Training.
  * Trainers gain EXP, with horses learning tricks at milestones.
  * EXP-based progression for stamina, speed, and abilities.
  * Job-lock for authorized training NPCs.
* **Horse Customization & Inventory**
  * Equip horses with saddles, bags, lanterns, masks, blankets, etc.
  * Full horse equipment menu with real stat effects (health, speed, etc.).
  * Save animal skins directly on horses.
  * Horseshoes system with KM-based durability and stat bonuses.
* **Wagon System**
  * Custom wagons with unique outfit/inventory slots.
  * Repair system using items and animations.
  * Wagon stash with drag & drop cargo, skins, and full interactions.
  * Wagon calling/sending restrictions based on cities/stables/housing.
* **Stable & Market Features**
  * Sell/buy/trade horses and wagons with full details and story.
  * Online horse market: players can sell horses even when offline.
  * Real in-game locations for stable services in multiple towns.
  * Job-locks for who can sell, tame, train, or access horse tools.
* **Key Extras**
  * Horse holster system.
  * Max horse ownership limits per player/group.
  * Blacklist control for selling/transferring specific breeds.
  * Unique camera previews for horses and wagons (360°).
  * Items and food with real-time stamina/health effects.
  * Legendary saddles, flaming horseshoes, extra stash bags, and much more.
  * Horses can protect their owner if trained (e.g., defend if cuffed or hogtied).
  * Realtime shared marketplace, even if owners are offline.


# Preview

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

<div><figure><img src="/files/gbJNPQQYXOylSh0m8xXs" alt=""><figcaption><p>WAGON BUY POINT</p></figcaption></figure> <figure><img src="/files/180jY0f11euUu6mB2VVg" alt=""><figcaption><p>MY HORSES</p></figcaption></figure> <figure><img src="/files/7EfXTtKqnwulXgDA7diY" alt=""><figcaption><p>HORSES BUY POINT</p></figcaption></figure></div>


# Configuration File

### config.lua

{% code overflow="wrap" %}

```lua
-- Author 'SIREC#0001'
-- REPORT ANY BUGS ON https://discord.gg/9XNBaQSmMd --

Config = {
Dev = true,
Metabolism = false, -- IF USE SS-METABOLISM SET TRUE
WebHook = "",
    
SearchAllow = {"Maresal", "Judecator", "Guvernator", "PolitiaFederala", "Detectiv", "PolitieFrontiera", "OfiterValentine", "SerifValentine", "OfiterAnnesburg", "SerifAnnesburg", "OfiterRhodes", "SerifRhodes", "OfiterBlackWater", "SerifBlackWater"}, -- JOBS THAT CAN SEARCH EVERYWHERE EVERYTIME
GradePolice = 9, -- THIS GRADE OR HIGHER CAN TAKE HORSES FROM MARKET FOR 0€ (THIS HELPS TO GET STOLED HORSES AND GIVE BACK TO OWNER)
----------------------------------------CONTROLS-------------------------------------------------   
StartDrinkButton = 0xC7B5340A,
StartMountButton = 0xC7B5340A,
StopTrainingButton = 0xFF8109D8,
StartBreedingButton = 0xFF8109D8,
HorsePutPelts = 0x06052D11,
HorseGetPelts = 0x760A9C6F,
HorseOpenStash = 0xE30CD707,
WagonSendAway = 0x06052D11,
WagonGetCargo = 0x760A9C6F,
WagonDropCargo = 0x4BC9DABB,
WagonOpenStash = 0xFF8109D8,
WagonOutfits = 0xDB096B85,
TransferHorse = 0x4BC9DABB, --0x06052D11, --0x4BC9DABB,
SellHorse = 0xFF8109D8,
ActiveIt = 0xC7B5340A,
CustomIt = 0x760A9C6F,
CallWagon = 0xF3830D8E,
CallHorse = 0x24978A28,
MarketWithdraw = 0x760A9C6F,
MarketBuy = 0xC7B5340A,
SellMarket = 0x9959A6F0,
SetTarpaulin = false, -- NEW 3.7

--------------------------------------EXTRA EQUIP--------------------------------------------------
ExtraEquip = {
	["extrabag"] = {Hash = 0xEE1C8EF2, Stash = 2}, -- EXTRA BAGS INVENTORY ( * Stash / Double The Actual Invenory) horsebags1 NEW 4.0
	["flameshoes"] = {Hash = "", Flame = true}, -- Flamming Shoes (Change only the item) NEW 4.0
	["horseloadout1"] = {Hash = 0x2459E0BD}, -- HUGE BAGS ON HORSE (You can add extra stash, but people can ABUSE it) NEW 4.0
	["horseloadout2"] = {Hash = 0x951FB0EB}, -- HUGE BAGS ON BACK HORSE (You can add extra stash, but people can ABUSE it) NEW 4.0
	["horseloasout3"] = {Hash = 0xDCC33A7C}, -- HUGE CHESTS ON HORSE (You can add extra stash, but people can ABUSE it) NEW 4.0
	["horseloadout4"] = {Hash = 0x4514190C}, -- HUGE MOONSHINE ON HORSE (You can add extra stash, but people can ABUSE it) NEW 4.0
	["horseloadout5"] = {Hash = 0x460A74C6}, -- HUGE HUNTING ON HORSE (You can add extra stash, but people can ABUSE it) NEW 4.0
	["horseloadout6"] = {Hash = 0x56F11EF7}, -- HUGE MINING TOOLS ON HORSE (You can add extra stash, but people can ABUSE it) NEW 4.0
	["horseloadout7"] = {Hash = 0xDA9244A3}, -- HUGE THINGS ON HORSE (You can add extra stash, but people can ABUSE it) NEW 4.0
	["horsearrow"] = {Hash = 0xABB8A3F1}, -- ARROWS IN HORSE NEW 4.0
	["horseblanket"] = {Hash = 0x9F275113}, -- HORSE SADDLE BLANKET  NEW 4.0
	["horsebag1"] = {Hash = 0x55CEE4B7}, -- SUGAR BAGS NEW 4.0
	["horsemask2"] = {Hash = 0x79DBC798}, -- Blanket Mask NEW 4.0
	["horsemask1"] = {Hash = 	0x5A510883}, -- COBRA MASK NEW 4.0
	["horseflag"] = {Hash = 0x03CE3847}, --FLAG ON HORSE NEW 4.0

	["horselantern"] = {Hash = 0xF08D4D50}, -- HORSE LANTERN NEW 4.0
	["horsetorch"] = {Hash = 0xEA0F04C9}, -- TORCH ON HORSE
	["legendarysaddle"] = {Hash = 0xD3C7AE66},  -- LEGENDARY SADDLE
	["blanketwolf"] = {Hash = 0xD28F9C56}, -- WOLF BLANKET
	["blanketbear"] = { Hash = 0xE0C338BD}, -- Blanket Bear
	["saddlestandard"] = {Hash = 0xC6AE9EAB},  -- Saddle Standard
},
    
------------------------------------- HORSE SETTINGS ---------------------------------------------

-- General Settings
UseDefaultStats = false, -- Use default stats for horses, or what you set in horses.lua ?
HorseEquipmentsWithGold = false, -- (true = Gold, false = Money) Set payment type for horse equipment.
TimeToDrink = 10000, -- Time (ms) it takes for the horse to drink.
DrinkAddHealth = 10, -- Amount of health added when the horse drinks.
DrinkAddStamina = 35, -- Amount of stamina added when the horse drinks.
AttackEnemies = 3500, -- Horse attacks enemies when called, if it has 3500 EXP. Set false to disable.
StandbySit = 60, -- Time (seconds) for the horse to sit down when idle. Set false to disable.

-- Visibility Settings
HideNameHorseToOthers = true, -- Hides the horse's name and shows its ID to other players.
ShowCustomNameToOthers = false, -- Shows custom text instead of the horse's name/ID to others. Set false to disable.

-- Horse Ownership Limits
MaxHorses = 5, -- Maximum horses for normal players.
TrainersMaxHorses = 8, -- Maximum horses for trainers.
ByPassLimit = { -- Groups that bypass horse ownership limits.
    ["vipbronze"] = 8,
    ["vipsilver"] = 10,
    ["vipgold"] = 12,
},

-- Horse Attributes
BuyHorseAge = {10, 25}, -- Random age range for new horses purchased from stables.
CallHorseOnlyInCities = false, -- Call horses only in cities or near stables. (true = cities only)
SendHorseOnlyInCities = false, -- Send horses away only in cities or near stables. (true = cities only)

-- Horse Cooldowns
ReCallCooldown = 1, -- Seconds before you can call the horse again. Set false to disable.
ReSendCooldown = 1, -- Seconds before you can send the horse away again. Set false to disable.

-- Behavior and Interaction
ChanceSendAway = 50, -- Percentage chance to send away unknown or agitated horses.
CallDistanceToRoads = 100.0, -- Maximum distance (in meters) to check for road spawn for wagons.
LassoHorse = true, -- Determines if horses can be lassoed.
ReviveItem = "horserevive", -- Item required to revive horses.
ChangeToSearchBags = 50, -- Chance (%) for the horse to fail searching players' bags (ex: 50% + horse level bonus).

-- Horse Market Settings
HorseSellPrice = 50, -- Percentage of original value when selling a horse.
BlacklistCities = {"Annesburg", "Blackwater", "Rhodes", "Siska", "StDenis", "Strawberry", "Valentine"}, -- Cities where certain actions are restricted.
TransferHorseBlacklist = { -- Horses that cannot be transferred.
    "a_c_horse_arabian_white",
    "a_c_horse_belgian_mealychestnut",
    "a_c_horse_thoroughbred_reversedappleblack",
    "a_c_horse_turkoman_grey",
    "a_c_horse_turkoman_silver",
},
SellHorseBlacklist = {}, -- Horses that cannot be sold.
SellMarketHorseBlacklist = { -- Horses that cannot be sold at the market.
    "a_c_horse_arabian_white",
    "a_c_horse_belgian_mealychestnut",
    "a_c_horse_thoroughbred_reversedappleblack",
    "a_c_horse_turkoman_grey",
    "a_c_horse_turkoman_silver",
},

-- Cities Where Horses Can Be Called/Sent
AllowedToCallCity = {"Annesburg", "Armadillo", "Blackwater", "Rhodes", "StDenis", "Strawberry", "Tumbleweed", "Valentine", "Vanhorn"},
AllowedToSendCity = {"Annesburg", "Armadillo", "Blackwater", "Rhodes", "StDenis", "Strawberry", "Tumbleweed", "Valentine", "Vanhorn"},

-- Horse Tricks
HorseTricksKey = 0x63A38F2C, -- Default is when you pat you horse the menu come's up !
HorseTricksCommand = "tricks", -- Horse tricks command, insert the command to enable or false to disable !
HorseTrickDistance = 15, -- Distance between player and horse to can make the horse do the tricks !
HorseTricks = {
    [1] = {Tittle = "Strange Walk", Anim = "horse_crossing_river_horse", Dict = "amb_creature_mammal@world_horse_crossing_river", Time = 5000, Flag = 0, Exp = 500},
    [2] = {Tittle = "Pasture", Anim = "base", Dict = "amb_creature_mammal@world_horse_grazing@base", Time = 30000, Flag = 0, Exp = 500},
    [3] = {Tittle = "Fake Injured", Anim = "base", Dict = "amb_creature_mammal@world_horse_injured_on_ground@base", Time = -1, Flag = 1, Exp = 3500},
    [4] = {Tittle = "Resting", Anim = "base", Dict = "amb_creature_mammal@world_horse_resting@base", Time = -1, Flag = 0, Exp = 1500},
    [5] = {Tittle = "Sleeping", Anim = "base", Dict = "amb_creature_mammal@world_horse_sleeping@base", Time = -1, Flag = 1, Exp = 2000},
    [6] = {Tittle = "Wallow", Anim = "base", Dict = "amb_creature_mammal@world_horse_wallow_shake@base", Time = 30000, Flag = 0, Exp = 4000},
    [7] = {Tittle = "Hop", Anim = "hop_with_rearing", Dict = "amb_creature_mammal@world_horse_rearing", Time = -1, Flag = 0, Exp = 4000},
},

-- Horse Thief
HidenStoledHorsesBlip = -1456209806, -- Blip of Abandoned Stable to bring stoled horses ( ONLY HORSETRAINERS JOBS CAN SEE IT )
HidenStoledHorses = {-5520.1357421875, -3044.590087890625, -3.38769245147705}, -- FALSE TO DISABLE / OR COORDS FOR ENABLE {x, y, z} !
HidenStoledHorsesName = "Grajd Abandonat", -- Blip name of abandoned stable
HorsesBlacklist = {"a_c_horse_arabian_white", "a_c_horse_belgian_mealychestnut", "a_c_horse_thoroughbred_reversedappleblack", "a_c_horse_turkoman_grey", "a_c_horse_turkoman_silver"},

-- Horse Food
Feed = { -- ITEMNAME / LABEL ITEM / BOOST / HEALTH AMOUNT / STAMINA AMOUNT
["corn"] = {label = "Porumb", boost = false, health = 30, stamina = 10, thirsty = 10, hungry = 45}, -- To disable stamina or health use false , Or set the amount ! 
["Wild_Carrot"] = {label = "Morcov",  boost = false, health = 10, stamina = 30, thirsty = 10, hungry = 45}, -- To disable stamina or health use false , Or set the amount ! 
["consumable_haycube"] =  {label = "HayCube",  boost = false, health = 20, stamina = 20, thirsty = 10, hungry = 45}, -- To disable stamina or health use false , Or set the amount ! 
["stim"] =  {label = "Stimulent Cal",  boost = true, health = 100, stamina = 100, thirsty = 10, hungry = 45}, --To disable stamina or health use false , Or set the amount ! 
},
    
------------------------------------- WAGON SETTINGS ---------------------------------------------

-- General Settings
WagonEquipmentsWithGold = false, -- (true = Gold, false = Money) Set payment type for wagon equipment.
WagonLowHealth = 100, -- Health threshold below which wagons become undrivable.
ActiveLastPosition = true, -- Save the last position (city, stable, house, or clan) and only allow calling wagons from there.

-- Outfit Settings
EnableOutfits = "xakra_clothingstores:OutfitsClothingStoreMenu", -- Trigger to open outfits menu. Set false to disable.

-- Housing and Clan Integration
SSHousing = false, -- If using SS-Housing, allow calling/sending wagons from the house.
SSClan = false, -- If using SS-Clan, allow calling/sending wagons from the clan.

-- Wagon Repair Settings
HammerRepair = "ironhammer", -- Item used to repair the wagon.
HammerRepairAnimation = {dict = "", anim = ""}, -- Animation dict and anim, only if scenario is false !
HammerRepairScenario = "PROP_HUMAN_REPAIR_WAGON_WHEEL_ON_LARGE", -- Scenario to use, put false to use animation instead !
HammerRepairTime = 5000, -- Time (ms) required to repair the wagon.
HammerAddWagonHealth = 250, -- Add 250 on every repair, max is 1000 ! Adjust how you like
HammerRepairNeeds = {"nails", 4, "Cuie"}, -- Required items to repair (e.g., {"ITEM", AMOUNT, "LABEL"}).

-- Location Restrictions
CallWagonOnlyInCities = true, -- Allow calling wagons only in cities or near stables.
SendWagonOnlyInCities = true, -- Allow sending wagons away only in cities or near stables.
WagonDistanceToRoads = 100.0, -- Maximum distance to check for roads when spawning a wagon. Set false to disable road checks.

-- Distance and Cooldowns
MaxDistanceToCall = 100.0, -- Maximum distance to call the wagon if it's already spawned. Otherwise, respawn it.

-- Market Settings
MaxMarketPrice = 2, -- Max price for horses when you sell in Market, horse price x 2, wich is double set as you like !
WagonSellPrice = 25, -- Percentage of the original price when selling a wagon. (NEW)
BlackListCityLockpick = {'Annesburg', 'Blackwater', 'Rhodes', 'Siska', 'StDenis', 'Strawberry', 'Valentine'}, -- Cities where lockpicking wagons is restricted.

-- Blacklists
TransferWagonBlacklist = { -- Wagons that cannot be transferred.
    "chuckwagon000X",
    "buggy01",
},
SellWagonBlacklist = { -- Wagons that cannot be sold.
    "chuckwagon000X",
    "buggy01",
},

---------------------------------------- TRAINING SETTINGS ----------------------------------------------
Experience = { -- Experience affects stamina generation and depletion ! 
	[5] = { -- Full Training 4000 EXP
		RegenStamina = 3.0, -- Regeneration x3.0
		DecreaseStamina = 1.0, -- Decrease stamina x1.0
                
	},
	[4] = { -- Effects over 3000 EXP
		RegenStamina = 2.5, -- Regeneration x2.5
		DecreaseStamina = 1.5, -- Decrease stamina x1.5
                
	},
	[3] = { -- Effects over 2000 EXP
		RegenStamina = 2.0, -- Regeneration x2.0
		DecreaseStamina = 2.0, -- Decrease stamina x2.0
                
	},
	[2] = { -- Effects over 1000 EXP
		RegenStamina = 1.5, -- Regeneration x1.5
		DecreaseStamina = 2.5, -- Decrease stamina x2.5
                
	},
	[1] = { -- Effects under 1000 EXP
		RegenStamina = 1.0, -- Regeneration x1.0
		DecreaseStamina = 3.0, -- Decrease stamina x3.0
                
	},
},

Training = {
    -- General Settings
    TrainerBookItem = "horselist", -- Item used by trainers to open a list with all horses and see if they are stolen (* near the serial means stolen).
    Jobs = {"HorseTrainerBW", "HorseTrainerRH", "HorseTrainerSD", "HorseTrainerVAL"}, -- Jobs for horse trainers.
    ShoesTime = 5000, -- Time (ms) for the horseshoe placement animation duration.
    Whip = "horsetrain", -- Whip item used to start training the horses.
    MinStamina = 20, -- If the horse's stamina drops below this value, the training will stop, and the trainer will fall off the horse!
    -- Training Notes:
    -- Training does not add stamina directly but will decrease stamina consumption and speed up its recovery.
    -- To add more stamina points, horseshoes must be equipped.
},

-- Training Type Selection
ChoiceTraining = false, -- (true = Allows choosing the training type when using the whip, false = Uses the training type set in each stable).

HorseTraining = {
    -- Type 1: Step Training (Walk/Run/Jump through markers)
    [1] = {
        ["Valentine"] = { -- Stable Name
            Enable = true, -- Enable/Disable this route.
            CurrentStepColor = {255, 0, 0}, -- Current step color (RGB).
            NextStepColor = {0, 0, 0}, -- Next step color (RGB).
            Exp = 150, -- EXP gained after completing the route.
            Steps = { -- Marker coordinates (Marker: 0x6903B113 for ground, 0xEC032ADD for circles).
                [1] = {-386.017578, 786.026368, 114.921630, 0.0, 0.0, 90.0, 0x6903B113},
                [2] = {-395.182404, 787.595582, 115.005860, 0.0, 0.0, 90.0, 0x6903B113},
                [3] = {-398.927460, 780.250550, 114.904786, 0.0, 0.0, 90.0, 0x6903B113},
                [4] = {-386.887908, 774.092286, 114.921630, 0.0, 0.0, 90.0, 0x6903B113},
                [5] = {-396.909882, 769.041748, 114.972168, 0.0, 0.0, 90.0, 0x6903B113},
                [6] = {-398.136260, 777.863708, 114.871094, 0.0, 0.0, 90.0, 0x6903B113},
                [7] = {-394.496704, 788.400024, 115.022706, 0.0, 0.0, 90.0, 0x6903B113},
                [8] = {-386.030762, 779.406616, 116.101074, 0.0, 0.0, 180.0, 0xEC032ADD},
                [9] = {-392.769226, 768.870300, 114.904786, 0.0, 0.0, 90.0, 0x6903B113},
                [10] = {-390.883514, 778.232972, 114.786866, 0.0, 0.0, 90.0, 0x6903B113},
            }
        },
        ["BlackWater"] = { -- Stable Name
            Enable = true, -- Enable/Disable this route.
            CurrentStepColor = {255, 0, 0}, -- Current step color (RGB).
            NextStepColor = {0, 0, 0}, -- Next step color (RGB).
            Exp = 150, -- EXP gained after completing the route.
            Steps = { -- Marker coordinates (Marker: 0x6903B113 for ground, 0xEC032ADD for circles).
                [1] = {-887.3292236328125, -1378.822509765625, 42.88726196289062, 0.0, 0.0, 90.0, 0x6903B113},
                [2] = {-889.078125, -1365.821044921875, 42.64348373413086, 0.0, 0.0, 90.0, 0x6903B113},
                [3] = {-889.0767211914062, -1351.7811279296875, 42.41520843505859, 0.0, 0.0, 90.0, 0x6903B113},
                [4] = {-872.6477661132812, -1351.5440673828125, 42.42537460327148, 0.0, 0.0, 90.0, 0x6903B113},
                [5] = {-863.9517211914062, -1343.7161865234375, 42.51334533691406, 0.0, 0.0, 90.0, 0x6903B113},
                [6] = {-859.0445556640625, -1321.2781982421875, 42.28737411499023, 0.0, 0.0, 90.0, 0x6903B113},
                [7] = {-847.3763427734375, -1334.6639404296875, 42.47765884399414, 0.0, 0.0, 90.0, 0x6903B113},
                [8] = {-848.0678100585938, -1359.25, 42.52935943603515, 0.0, 0.0, 90.0, 0x6903B113},
                [9] = {-855.635986328125, -1383.1864013671875, 42.64427337646484, 0.0, 0.0, 90.0, 0x6903B113},
                [10] = {-875.3466186523438, -1384.2388916015625, 42.6351676940918, 0.0, 0.0, 90.0, 0x6903B113},
            }
        },
    },

    -- Type 2: Random Action Training
    [2] = {
        Enable = true, -- Enable/Disable this type of training.
        StepsTime = {6, 9}, -- Time (seconds) between steps.
        StepsNeed = {5, 10}, -- Random number of steps required to complete the training.
        ExpWhenWalking = 10, -- EXP gained when walking with the horse.
        ExpWhenRunning = 15, -- EXP gained when running with the horse.
        ExpWhenRearUp = 15, -- EXP gained when rearing up.
        ExpWhenTurnRight = 30, -- EXP gained when turning right.
        ExpWhenTurnLeft = 30, -- EXP gained when turning left.
        ExpWhenDance = 20, -- EXP gained when making the horse dance.
        ExpWhenJumping = 15, -- EXP gained when jumping.
        Steps = {
            [1] = {action = "JUMP", waittime = 3, info = "You need to JUMP with your horse."},
            [2] = {action = "WALK", waittime = 4, info = "You need to WALK with your horse."},
            [3] = {action = "RUN", waittime = 5, info = "You need to RUN with your horse."},
            [4] = {action = "DANCE", waittime = 4, info = "You need to DANCE with your horse."},
            [5] = {action = "TURN LEFT", waittime = 2, info = "You need to TURN LEFT with your horse."},
            [6] = {action = "TURN RIGHT", waittime = 2, info = "You need to TURN RIGHT with your horse."},
            [7] = {action = "REAR UP", waittime = 5, info = "You need to REAR UP with your horse."},
        }
    },

    -- Type 3: Free Training
    [3] = {
        Enable = true, -- Enable/Disable this type of training.
        ExpWhenWalking = 0.01, -- EXP per step while walking.
        ExpWhenRunning = 0.03, -- EXP per step while running.
        ExpWhenSkid = 30, -- EXP for skidding.
        ExpWhenRearUp = 5, -- EXP for rearing up.
    },
},

-- Horseshoe Settings
Shoes = { -- Horseshoes increase stamina. Losing a horseshoe reduces stamina points.
    ["0"] = {label = "No Horseshoes", km = 0},
    ["ironhorseshoe"] = {label = "Iron Horseshoe", km = 20000},
    ["silverhorseshoe"] = {label = "Silver Horseshoe", km = 40000},
    ["goldhorseshoe"] = {label = "Gold Horseshoe", km = 80000},
},

---------------------------------------- BREEDING SETTINGS -------------------------------------------      

Breeding = {
    -- General Settings
    Jobs = {"HorseTrainerBW", "HorseTrainerRH", "HorseTrainerSD", "HorseTrainerVAL"}, -- Jobs allowed for breeding.
    AllowCross = true, -- If true, the foal will have a custom appearance (24 custom appearances available).
    Pill = "breedpills", -- The item (pill) required to start the breeding process (used for male horses in training zones).
    Brush = "horsebrush", -- The item (brush) used to clean horses.
    Chance = 50, -- Percentage chance to successfully start breeding (otherwise the horse will run away, and you must try again).
    BreedTime = 30000, -- Time (ms) the horse remains in the breeding animation if successful.
    ChanceFoal = 50, -- Percentage chance for the foal to inherit the father's race.
    ChanceSex = 50, -- Percentage chance for the foal to be male or female.
    BreedWaitTime = 10, -- Days to wait before the foal is born.
    Handicap = 2, -- Reduction factor for stamina, speed, and acceleration for pregnant female horses.
    CheckBreed = 1, -- Frequency (in hours) to check if breeding is complete.
    StartRiding = 4, -- Number of days before the foal can be ridden.
    StartBreeding = 6, -- Number of days before the foal can begin breeding.
    StartTraining = 8, -- Number of days before the foal can begin training.
    StartAdult = 10, -- Number of days before the foal becomes an adult and can equip items.
    StartOld = 75, -- Number of days before the horse becomes old (status changes to "Old" with a scale of 1.1).
    StartDead = 95, -- Number of days before the horse dies.
    StartDeleteIt = 100, -- Number of days before the horse is deleted from the server.
    StopBreeding = 60, -- Number of days after which the horse can no longer breed.
    EnableBlackLists = true, -- Enable breeding blacklists (false to allow all horses to breed freely).

    -- Breeding Blacklists
    -- Only horses within the same category can breed. If a horse is not listed in any category, it cannot breed.
    BlackLists = {
        -- Category 1: American Paint, Appaloosa, and other breeds
        [1] = {
            "a_c_horse_americanpaint_greyovero", "a_c_horse_americanpaint_overo", "a_c_horse_americanpaint_splashedwhite", 
            "a_c_horse_americanpaint_tobiano", "a_c_horse_americanstandardbred_silvertailbuckskin", 
            "a_c_horse_americanstandardbred_palominodapple", "a_c_horse_americanstandardbred_buckskin", 
            "a_c_horse_americanstandardbred_black", "a_c_horse_andalusian_darkbay", "a_c_horse_andalusian_perlino", 
            "a_c_horse_andalusian_rosegray", "a_c_horse_appaloosa_brownleopard", "a_c_horse_appaloosa_leopard", 
            "a_c_horse_appaloosa_fewspotted_pc", "a_c_horse_appaloosa_leopardblanket", "a_c_horse_appaloosa_blanket", 
            "a_c_horse_ardennes_strawberryroan", "a_c_horse_ardennes_irongreyroan", "a_c_horse_ardennes_bayroan", 
            "a_c_horse_belgian_blondchestnut", "a_c_horse_belgian_mealychestnut", "a_c_horse_dutchwarmblood_chocolateroan", 
            "a_c_horse_dutchwarmblood_sealbrown", "a_c_horse_dutchwarmblood_sootybuckskin", 
            "a_c_horse_hungarianhalfbred_darkdapplegrey", "a_c_horse_hungarianhalfbred_flaxenchestnut", 
            "a_c_horse_hungarianhalfbred_liverchestnut", "a_c_horse_hungarianhalfbred_piebaldtobiano", 
            "a_c_horse_kentuckysaddle_black", "a_c_horse_kentuckysaddle_buttermilkbuckskin_pc", 
            "a_c_horse_kentuckysaddle_chestnutpinto", "a_c_horse_kentuckysaddle_grey", "a_c_horse_kentuckysaddle_silverbay", 
            "a_c_horse_morgan_bay", "a_c_horse_morgan_bayroan", "a_c_horse_morgan_flaxenchestnut", 
            "a_c_horse_morgan_palomino", "a_c_horse_morgan_liverchestnut_pc", "A_C_Horse_MP_Mangy_Backup", 
            "a_c_horse_nokota_blueroan", "a_c_horse_nokota_reversedappleroan", "a_c_horse_nokota_whiteroan", 
            "a_c_horse_shire_darkbay", "a_c_horse_shire_lightgrey", "a_c_horse_shire_ravenblack", 
            "a_c_horse_suffolkpunch_redchestnut", "a_c_horse_suffolkpunch_sorrel", "a_c_horse_tennesseewalker_blackrabicano", 
            "a_c_horse_tennesseewalker_chestnut", "a_c_horse_tennesseewalker_dapplebay", "a_c_horse_tennesseewalker_flaxenroan", 
            "a_c_horse_tennesseewalker_goldpalomino_pc", "a_c_horse_tennesseewalker_mahoganybay", 
            "a_c_horse_tennesseewalker_redroan"
        },

        -- Category 2: Gypsy Cob, Kladruber, Thoroughbred, and similar breeds
        [2] = {
            "a_c_horse_gypsycob_splashedpiebald", "a_c_horse_gypsycob_splashedbay", "a_c_horse_gypsycob_palominoblagdon", 
            "a_c_horse_gypsycob_skewbald", "a_c_horse_gypsycob_piebald", "a_c_horse_gypsycob_whiteblagdon", 
            "a_c_horse_kladruber_black", "a_c_horse_kladruber_cremello", "a_c_horse_kladruber_dapplerosegrey", 
            "a_c_horse_kladruber_grey", "a_c_horse_kladruber_silver", "a_c_horse_kladruber_white", 
            "a_c_horse_thoroughbred_blackchestnut", "a_c_horse_thoroughbred_bloodbay", "a_c_horse_thoroughbred_brindle", 
            "a_c_horse_thoroughbred_dapplegrey", "a_c_horse_breton_sealbrown", "a_c_horse_breton_redroan", 
            "a_c_horse_breton_steelgrey", "a_c_horse_breton_grullodun", "a_c_horse_breton_mealydapplebay", 
            "a_c_horse_breton_sorrel", "a_c_horse_norfolkroadster_spottedtricolor", 
            "a_c_horse_norfolkroadster_speckledgrey", "a_c_horse_norfolkroadster_rosegrey", 
            "a_c_horse_norfolkroadster_piebaldroan", "a_c_horse_norfolkroadster_dappledbuckskin", 
            "a_c_horse_norfolkroadster_black"
        },

        -- Category 3: Arabian, Missouri Fox Trotter, Mustang, Turkoman, and similar breeds
        [3] = {
            "a_c_horse_arabian_rosegreybay", "a_c_horse_arabian_black", "a_c_horse_arabian_warpedbrindle_pc", 
            "a_c_horse_arabian_redchestnut", "a_c_horse_arabian_redchestnut_pc", "a_c_horse_arabian_grey", 
            "a_c_horse_gang_dutch", "a_c_horse_missourifoxtrotter_amberchampagne", 
            "a_c_horse_missourifoxtrotter_blacktovero", "a_c_horse_missourifoxtrotter_blueroan", 
            "a_c_horse_missourifoxtrotter_buckskinbrindle", "a_c_horse_missourifoxtrotter_dapplegrey", 
            "a_c_horse_missourifoxtrotter_sablechampagne", "a_c_horse_missourifoxtrotter_silverdapplepinto", 
            "a_c_horse_mustang_blackovero", "a_c_horse_mustang_buckskin", "a_c_horse_mustang_chestnuttovero", 
            "a_c_horse_mustang_goldendun", "a_c_horse_mustang_grullodun", "a_c_horse_mustang_reddunovero", 
            "a_c_horse_mustang_tigerstripedbay", "a_c_horse_mustang_wildbay", "a_c_horse_turkoman_black", 
            "a_c_horse_turkoman_chestnut", "a_c_horse_turkoman_darkbay", "a_c_horse_turkoman_gold", 
            "a_c_horse_turkoman_perlino", "a_c_horse_criollo_baybrindle", "a_c_horse_criollo_bayframeovero", 
            "a_c_horse_criollo_blueroanovero", "a_c_horse_criollo_dun", "a_c_horse_criollo_marblesabino", 
            "a_c_horse_criollo_sorrelovero"
        }
    }
},

------------------------------------ TAMING SETTINGS ------------------------------------------

Taming = {
    -- Allowed Jobs for Taming Horses
    Jobs = {
        "HorseTrainerBW", "HorseTrainerRH", "HorseTrainerSD", "HorseTrainerVAL", "Marshal", 
        "Judge", "Governor", "FederalPolice", "Detective", "BorderPolice", "Unemployed", 
        "Gunsmith", "Shaman", "Blacksmith", "BountyHunter", "Doctor", "MayorBlackWater", 
        "MayorRhodes", "MayorSaintDenis", "MayorValentine", "Jeweler", "Forester", 
        "Miner", "ValentineOfficer", "ValentineSheriff", "AnnesburgOfficer", 
        "AnnesburgSheriff", "RhodesOfficer", "RhodesSheriff", "BlackWaterOfficer", 
        "BlackWaterSheriff", "GunsmithBW", "GunsmithVAL", "GunsmithRH", "ResidentDoctorVAL", 
        "ResidentDoctorRH", "ResidentDoctorBW", "PrimaryDoctor", "SpecialistDoctorVAL", 
        "SpecialistDoctorRH", "SpecialistDoctorBW"
    },

    -- Taming Settings
    MaxFails = 2, -- Maximum number of failed attempts before the player is thrown off.
    MaxSucces = 6, -- Number of successful hits required to tame the horse.
    RandomTime = {500, 2500}, -- Random interval (in ms) to display the button prompt.
    ReactionTime = 800, -- Time (in ms) the player has to react to the prompt.
    TamingPrice = 70, -- Percentage of the horse's price required to tame it.
    SellPrice = 3, -- Percentage of the horse's price when selling it.
    TamingAge = {20, 30}, -- The age range (in days) of tamable horses.
},
    
------------------------------------- STABLES SETTINGS --------------------------------------------

    -- General Settings for Training and Breeding Zones
    TrainBreedZoneBlip = -271586249, -- Blip ID for the training and breeding zone
    TrainBreedZoneName = "Training Zone", -- Name of the training and breeding zone

    -- Stable Locations
    Stables = {
        ["1"] = { -- Valentine Stable
            Name = "Valentine",
            CamPos = {-382.25, 769.90, 118.45}, -- Camera Position for stable menu
            Blip = -1456209806, -- Blip ID for the stable location
            MySpot = {-369.6344, 791.5049, 115.0802, -175.34}, -- Location to spawn your horse
            ActiveMyWagon = true, -- Allow wagon usage at this stable
            MyWagonSpot = {-363.7694, 775.3442, 115.2707, -85.71}, -- Location to spawn wagons
            CustomPos = {-377.7004, 770.0306, 115.1071, 5.11}, -- Custom position for specific interactions
            TrainingType = 1, -- 1 = Step Circle, 2 = Follow Steps, 3 = Manual Training
            TrainingPos = {-393.4384, 777.8362, 115.6014}, -- Zone for training and breeding
            Distance = 15, -- Distance for interaction zones
            SellHorses = true, -- Allow horse selling
            SellSpots = {
                [1] = {Pos = {-366.3351, 782.8293, 115.0967, 1.53}}, -- Horse selling position
            },
            SellWagons = true, -- Allow wagon selling
            SellWagonsSpot = {-377.5419, 774.3201, 116.0970, -86.04}, -- Wagon selling position
            SellPlayersHorse = true, -- Enable horse market
            SellPlayersHorseSpot = {-372.0207, 782.5172, 115.0967, 1.53}, -- Horse market position
        },

        ["2"] = { -- BlackWater Stable
            Name = "BlackWater Stable",
            CamPos = {-875.02, -1382.39, 46.45},
            Blip = -1456209806,
            MySpot = {-867.5707, -1370.5565, 42.8182, 0.09},
            ActiveMyWagon = true,
            MyWagonSpot = {-892.8503, -1370.4193, 42.2997, 2.66},
            CustomPos = {-875.1373, -1376.1781, 42.7707, 88.55},
            TrainingType = 3,
            TrainingPos = {-874.5535, -1390.7340, 43.5835},
            Distance = 15,
            SellHorses = true,
            SellSpots = {
                [1] = {Pos = {-867.6696, -1361.9070, 42.7992, -177.77}},
            },
            SellWagons = true,
            SellWagonsSpot = {-883.2468, -1370.1073, 42.2370, -0.70},
            SellPlayersHorse = true,
            SellPlayersHorseSpot = {-861.0592, -1361.6440, 42.7821, -178.53},
        },

        ["3"] = { -- Rhodes Stable
            Name = "Rhodes Stable",
            CamPos = {1430.44, -1311.03, 80.42},
            Blip = -1456209806,
            MySpot = {1440.13, -1299.83, 76.96, 99.97},
            ActiveMyWagon = true,
            MyWagonSpot = {1448.53, -1280.57, 77.72, -162.73},
            CustomPos = {1429.28, -1305.60, 76.90, 102.55},
            TrainingType = 3,
            TrainingPos = {1428.16, -1267.97, 78.81},
            Distance = 15,
            SellHorses = true,
            SellSpots = {
                [1] = {Pos = {1435.69, -1286.11, 76.96, -110.77}},
            },
            SellWagons = true,
            SellWagonsSpot = {1441.68, -1282.59, 77.74, -159.39},
            SellPlayersHorse = true,
            SellPlayersHorseSpot = {1439.21, -1295.22, 76.97, -110.53},
        },

        ["4"] = { -- Van Horn Stable
            Name = "Van Horn Stable",
            CamPos = {2956.79, 763.07, 56.42},
            Blip = -1456209806,
            MySpot = {2961.48, 801.26, 50.61, 178.45},
            ActiveMyWagon = true,
            MyWagonSpot = {2957.07, 808.77, 50.39, 178.81},
            CustomPos = {2966.05, 764.14, 50.53, -2.92},
            TrainingType = 3,
            TrainingPos = {2976.17, 785.56, 51.25},
            Distance = 15,
            SellHorses = true,
            SellSpots = {
                [1] = {Pos = {2967.26, 801.24, 50.63, 165.42}},
            },
            SellWagons = true,
            SellWagonsSpot = {2950.71, 808.99, 51.34, -178.43},
            SellPlayersHorse = false,
            SellPlayersHorseSpot = {2973.10, 801.16, 50.59, -174.61},
        },

        ["5"] = { -- Saint Denis Stable
            Name = "Saint Denis Stable",
            CamPos = {2514.33, -1458.99, 48.39},
            Blip = -1456209806,
            MySpot = {2508.58, -1450.61, 45.58, 103.28},
            ActiveMyWagon = true,
            MyWagonSpot = {2496.29, -1437.53, 46.25, -179.84},
            CustomPos = {2509.19, -1459.23, 45.46, -178.20},
            TrainingType = 3,
            TrainingPos = {2502.48, -1450.64, 46.44},
            Distance = 15,
            SellHorses = true,
            SellSpots = {
                [1] = {Pos = {2508.46, -1444.40, 45.54, 89.69}},
            },
            SellWagons = true,
            SellWagonsSpot = {2487.55, -1446.53, 45.08, 179.40},
            SellPlayersHorse = true,
            SellPlayersHorseSpot = {2508.37, -1438.23, 45.49, 90.00},
        },
    },
}
function NOTIFY(text) --SET YOUR NOTIFYCATIONS
	local VORPCore = exports.vorp_core:GetCore()
	VORPCore.NotifyLeft(Config.Texts["tittle_notification"], text, "generic_textures", "tick", 5000, "COLOR_WHITE")
end 
```

{% endcode %}


# Configuration Helps

## SS-Stable Setup & Configuration Guide

SS-Stable is an advanced stable system for RedM. It handles personal horses, personal wagons, horse and wagon shops, equipment, training, breeding, taming, wagon cargo, repairs, animal cargo, markets, and optional integrations with other Sirec Studio scripts.

This guide is written for server owners who want to install, configure, and test the script safely, even without deep Lua knowledge.

***

## Features Overview

SS-Stable includes:

* Personal horse ownership: buy, store, call, and send away horses.
* Personal wagon ownership: buy, store, call, and send away wagons.
* Horse and wagon equipment shops.
* Horse and wagon preview inside stable zones.
* Horse equipment transfer using the `horseequipment` item.
* Horse food, water, tricks, pelts, and saddlebag inventory.
* Horse training, experience, horseshoes, and stamina behavior.
* Breeding, foals, age stages, and optional crossbreed visuals.
* Wild horse taming and selling.
* Player horse market and stable budget withdrawal.
* Wagon cargo for hunted animals and pelts.
* Wagon damage, repair, cargo blocking, and stash blocking when damaged.
* Multi-language support.
* Optional integrations with `SS-Clan`, `SS-Housing`, `SS-Metabolism`, lockpick systems, and outfit menus.

***

## Dependencies

### Required

* `SS-Core`
* `oxmysql`

### Used By Default

* `menuapi`
* `vorp_core`, used by the default `NOTIFY(text)` function.
* `SS-Inputs`, used for keyboard input prompts.

### Optional Integrations

* `SS-Clan`
* `SS-Housing`
* `SS-Metabolism`
* `SS-Lockpick`
* `outfits`, or another outfit menu trigger.

If you do not use an optional integration, disable it in `config.lua`.

***

## Installation

### 1. Add The Resource

Place the script in your server resources folder:

```
resources/[scripts]/SS-Stable
```

Keep the resource folder name exactly:

```
SS-Stable
```

### 2. Import SQL

Import the SQL file from:

```
EXTRA/ss_stable.sql
```

The main database tables are:

* `horses`
* `wagons`

The `horses` table stores ownership data, selected horse state, model, name, components, equipment, stats, shoes, age, breeding data, carried pelts, horse status, packed property data, and crossbreed values.

The `wagons` table stores ownership data, selected wagon state, model, name, components, damage/body data, cargo data, and stored city or area.

### 3. Add Inventory Items

Check every item name enabled in your config and make sure it exists in your inventory/database.

Important examples:

```lua
HorseEquipmentItem = "horseequipment"
ReviveItem = "horserevive"
HammerRepair = "ironhammer"
HammerRepairNeeds = {"nails", 4, "Cuie"}
```

If an item does not exist, the feature using that item will not work correctly.

### 4. Start Order

Recommended start order:

```cfg
ensure oxmysql
ensure SS-Core
ensure SS-Stable
```

If you use optional integrations, start them before `SS-Stable` when possible:

```cfg
ensure SS-Clan
ensure SS-Housing
ensure SS-Metabolism
ensure SS-Stable
```

### 5. Restart The Server

After importing SQL and checking the start order, restart the server and test the main stable flow in-game.

***

## Languages

Languages are configured in:

```
l/l.lua
```

Included languages:

* `EN`
* `IT`
* `ES`
* `FR`
* `DE`
* `PT`
* `RU`
* `RO`

Example:

```lua
Language = "RO"
```

***

## First Configuration

Open:

```
config.lua
```

The file is grouped into clear sections:

* General settings
* Controls
* Horse extra equipment
* Horse settings
* Wagon settings
* Training
* Breeding
* Taming
* Stable locations
* Notification function

### General Settings

```lua
Dev = true
Language = "EN"
Metabolism = false
WebHook = ""
```

* `Dev`: Use `true` while testing. Use `false` on live servers so the script waits for character selection.
* `Language`: Translation language used by the script.
* `Metabolism`: Set to `true` only if you use `SS-Metabolism`.
* `WebHook`: Discord webhook URL. Leave empty to disable webhook logs.

### Police & Search Settings

```lua
SearchAllow = {"Maresal", "Judecator"}
SearchAllowGrade = 4
GradePolice = 9
```

* `SearchAllow`: Jobs allowed to search horses and wagons with fewer restrictions.
* `SearchAllowGrade`: Minimum grade required for those jobs.
* `GradePolice`: Grade allowed to take market horses for free, useful for stolen horse recovery.

### Controls

Controls use RedM key hashes:

```lua
CallHorse = 0x24978A28
CallWagon = 0xF3830D8E
HorseOpenStash = 0xE30CD707
WagonOpenStash = 0xFF8109D8
```

Only change these values if you know the correct RedM control hash.

***

## Horse Systems

### Horse Equipment Transfer Item

SS-Stable supports one item that can store the main tack from one horse and apply it to another personal horse:

```lua
HorseEquipmentItem = "horseequipment"
```

Behavior:

* The player must be inside a stable area.
* The source horse must be a personal horse.
* The item stores main horse equipment as metadata.
* The item can apply that equipment to another personal horse.
* Mane, tail, mustache, and extra equipment are not included.
* Equipment cannot be applied to a horse that already has main equipment.

The item must exist in your inventory/database.

### Block Mount Without Saddle

```lua
BlockMount = true
```

* `true`: Managed horses without saddle/equipment cannot be mounted normally.
* `false`: Players can mount even if the horse has no equipment.

This helps prevent players from removing equipment only to protect saddlebag access while travelling.

### Extra Horse Equipment

Example:

```lua
ExtraEquip = {
    ["horseblanket"] = {Hash = 0x9F275113, Label = "Blanket"},
    ["horselantern"] = {Hash = 0xF08D4D50, Label = "Lantern"},
}
```

Fields:

* The key, for example `horseblanket`, is the usable item name.
* `Hash`: Metaped outfit hash applied to the horse.
* `Label`: Text shown in the menu.
* `Stash`: Optional extra inventory size behavior.
* `Flame`: Optional special visual behavior.

### Core Horse Settings

Important examples:

```lua
MaxHorses = 5
TrainersMaxHorses = 8
BuyHorseAge = {10, 25}
AttackEnemies = 3500
StandbySit = 60
CallHorseOnlyInCities = false
SendHorseOnlyInCities = false
```

* `MaxHorses`: Normal player horse limit.
* `TrainersMaxHorses`: Horse trainer limit.
* `BuyHorseAge`: Random age range for newly bought horses.
* `AttackEnemies`: Minimum EXP required for the horse to attack enemies when called. Use `false` to disable.
* `StandbySit`: Idle time before horses sit/rest. Use `false` to disable.
* `CallHorseOnlyInCities`: Restrict horse calling to allowed cities or stables.
* `SendHorseOnlyInCities`: Restrict sending horses away to allowed cities or stables.

### Horse Food

Example:

```lua
Feed = {
    ["corn"] = {label = "Porumb", boost = false, health = 30, stamina = 10, thirsty = 10, hungry = 45},
}
```

* The key is the item name.
* `label`: Display name.
* `boost`: Enables stronger effect behavior.
* `health`: Horse health restored.
* `stamina`: Horse stamina restored.
* `thirsty` and `hungry`: Used with metabolism integration.

### Horse Tricks

Example:

```lua
HorseTricksCommand = "tricks"
HorseTrickDistance = 15
HorseTricks = {
    [1] = {Tittle = "Pasture", Anim = "base", Dict = "amb_creature_mammal@world_horse_grazing@base", Time = 30000, Flag = 0, Exp = 500},
}
```

* `HorseTricksCommand`: Command used to open tricks. Use `false` to disable command access.
* `HorseTrickDistance`: Maximum distance between player and horse.
* `Exp`: Minimum horse EXP required for that trick.

***

## Wagon Systems

### Core Wagon Settings

Important examples:

```lua
WagonLowHealth = 100
BlockWagonIfDamage = true
ActiveLastPosition = true
CallWagonOnlyInCities = true
SendWagonOnlyInCities = true
WagonDistanceToRoads = 100.0
```

* `WagonLowHealth`: Health threshold where the wagon is considered heavily damaged.
* `BlockWagonIfDamage`: Use `false` to disable blocking, `true` to block under 500 health, or a number such as `300` for a custom threshold.
* `ActiveLastPosition`: Wagon can be recalled only from its saved area.
* `CallWagonOnlyInCities`: Restrict wagon calls to cities, stables, housing areas, or clan areas.
* `SendWagonOnlyInCities`: Restrict sending wagons away.
* `WagonDistanceToRoads`: Road search distance when spawning wagons.

### Wagon Repair

```lua
HammerRepair = "ironhammer"
HammerRepairScenario = "PROP_HUMAN_REPAIR_WAGON_WHEEL_ON_LARGE"
HammerRepairTime = 5000
HammerAddWagonHealth = 250
HammerRepairNeeds = {"nails", 4, "Cuie"}
```

* `HammerRepair`: Usable repair item.
* `HammerRepairScenario`: Scenario played while repairing.
* `HammerRepairTime`: Repair duration in milliseconds.
* `HammerAddWagonHealth`: Health added per repair.
* `HammerRepairNeeds`: Required item, amount, and display label.

### Optional Wagon Integrations

```lua
EnableOutfits
SSHousing = false
SSClan = false
```

* `EnableOutfits`: Event/trigger used to open wardrobe from wagon. Use `false` to disable.
* `SSHousing`: Set to `true` only if you use `SS-Housing`.
* `SSClan`: Set to `true` only if you use `SS-Clan`.

***

## Training, Breeding & Taming

### Training

Training is split into:

* Experience tiers
* Trainer jobs
* Training routes
* Random action training
* Free training
* Horseshoes

Trainer job example:

```lua
Training = {
    Jobs = {"HorseTrainerBW", "HorseTrainerRH", "HorseTrainerSD", "HorseTrainerVAL"},
    Whip = "horsetrain",
    TrainerBookItem = "horselist",
}
```

### Horseshoes

```lua
Shoes = {
    ["ironhorseshoe"] = {label = "Iron Horseshoe", km = 20000},
}
```

* The key is the item name.
* `label`: Display name shown to players.
* `km`: Distance before horseshoe degradation.

### Breeding

```lua
Breeding = {
    Jobs = {"HorseTrainerBW", "HorseTrainerRH"},
    AllowCross = true,
    Pill = "breedpills",
    Brush = "horsebrush",
    Chance = 50,
    BreedWaitTime = 10,
}
```

* `Jobs`: Jobs allowed to breed horses.
* `AllowCross`: Enables custom crossbreed visual values.
* `Pill`: Item used to start breeding.
* `Brush`: Item used to clean horses.
* `Chance`: Chance to start breeding.
* `BreedWaitTime`: Days until the foal is born.

Foal age stages:

```lua
StartRiding = 4
StartBreeding = 6
StartTraining = 8
StartAdult = 10
StartOld = 75
StartDead = 95
StartDeleteIt = 100
```

These values control when foals can be ridden, trained, equipped, become old, die, or are deleted.

### Taming

```lua
Taming = {
    MaxFails = 2,
    MaxSucces = 6,
    RandomTime = {500, 2500},
    ReactionTime = 800,
    TamingPrice = 70,
    SellPrice = 3,
    TamingAge = {20, 30},
}
```

* `MaxFails`: Failed button prompts before taming fails.
* `MaxSucces`: Successful prompts required.
* `RandomTime`: Random time between prompts.
* `ReactionTime`: Time allowed to press the correct prompt.
* `TamingPrice`: Price percentage needed to keep a tamed horse.
* `SellPrice`: Price percentage used when selling a tamed horse.
* `TamingAge`: Random age range for tamed horses.

***

## Stable Locations

Stable entries are configured in `config.lua`.

Example:

```lua
Stables = {
    ["1"] = {
        Name = "Valentine",
        CamPos = {-382.25, 769.90, 118.45},
        Blip = -1456209806,
        MySpot = {-369.63, 791.50, 115.08, -175.34},
        ActiveMyWagon = true,
        MyWagonSpot = {-363.76, 775.34, 115.27, -85.71},
        CustomPos = {-377.70, 770.03, 115.10, 5.11},
        TrainingType = 1,
        TrainingPos = {-393.43, 777.83, 115.60},
        Distance = 15,
        SellHorses = true,
        SellSpots = {
            [1] = {Pos = {-366.33, 782.82, 115.09, 1.53}},
        },
        SellWagons = true,
        SellWagonsSpot = {-377.54, 774.32, 116.09, -86.04},
        SellPlayersHorse = true,
        SellPlayersHorseSpot = {-372.02, 782.51, 115.09, 1.53},
    },
}
```

Important fields:

* `Name`: Stable name.
* `CamPos`: Camera position for UI/preview.
* `Blip`: Stable blip hash or `false`.
* `MySpot`: Personal horse spawn spot.
* `ActiveMyWagon`: Enables personal wagon spot.
* `MyWagonSpot`: Personal wagon spawn spot.
* `CustomPos`: Equipment/customization position.
* `TrainingType`: Training type used at this stable.
* `TrainingPos`: Training, breeding, and taming area.
* `Distance`: Zone radius.
* `SellHorses`: Enables horse shop.
* `SellSpots`: Horse shop preview spot.
* `SellWagons`: Enables wagon shop.
* `SellWagonsSpot`: Wagon shop preview spot.
* `SellPlayersHorse`: Enables player horse market.
* `SellPlayersHorseSpot`: Player horse market spot.

Keep interaction spots separated. If two spots overlap, prompts can overlap in-game.

### Add A New Stable

Copy an existing stable entry and change only the values:

```lua
["6"] = {
    Name = "Strawberry Stable",
    CamPos = {-1810.0, -560.0, 158.0},
    Blip = -1456209806,
    MySpot = {-1815.0, -558.0, 156.0, 90.0},
    ActiveMyWagon = true,
    MyWagonSpot = {-1820.0, -560.0, 156.0, 90.0},
    CustomPos = {-1812.0, -562.0, 156.0, 90.0},
    TrainingType = 3,
    TrainingPos = {-1830.0, -570.0, 156.0},
    Distance = 15,
    SellHorses = true,
    SellSpots = {
        [1] = {Pos = {-1816.0, -555.0, 156.0, 90.0}},
    },
    SellWagons = true,
    SellWagonsSpot = {-1824.0, -558.0, 156.0, 90.0},
    SellPlayersHorse = true,
    SellPlayersHorseSpot = {-1818.0, -552.0, 156.0, 90.0},
},
```

After adding a stable, restart the resource/server and test every interaction spot.

***

## Adding Shop Content

### Add A New Horse

Open:

```
cfg/horses.lua
```

Copy an existing horse entry in the correct category and change:

```lua
{
    Model = "a_c_horse_morgan_bay",
    Breed = "Morgan Bay",
    Category = "Morgan",
    PriceMoney = 100,
    PriceGold = 0,
    Description = "Basic riding horse.",
    Stats = {3, 3, 3, 3, 3},
    Crossbreed = 0,
}
```

Important:

* `Model` must be a valid RedM/RDR2 horse model.
* `Stats` order must match the script's expected horse stat order.
* `Crossbreed = 0` means default/no custom crossbreed.

### Add A New Wagon

Open:

```
cfg/wagons.lua
```

Copy an existing wagon entry and change:

```lua
{
    Model = "cart01",
    Label = "Small Cart",
    PriceMoney = 150,
    PriceGold = 0,
    Description = "Small utility cart.",
    Stash = 50,
    UtilityStash = 0,
}
```

Important:

* `Model` must be a valid wagon/vehicle model.
* `Stash` controls stash capacity.
* `UtilityStash` is used by utility/inventory logic if supported.

### Add Horse Equipment

Open:

```
cfg/horsesequip.lua
```

Use an existing entry as a template. Equipment categories can include saddle, bags, bedroll, blanket, stirrups, bridles, and other tack parts.

Typical equipment fields:

```lua
{
    Label = "Simple Saddle",
    PriceMoney = 50,
    PriceGold = 0,
    Hash = 0x12345678,
    Category = 1,
    Stats = {speed = 0, stamina = 0, health = 0, acc = 1, handling = 0},
}
```

Important:

* Use valid component hashes.
* Keep equipment order logical: blanket before saddle, saddle before bags.
* Test preview and called horses after adding new equipment.

### Add Wagon Equipment

Open:

```
cfg/wagonsequip.lua
```

Copy an existing color, livery, or prop entry and change values carefully.

### Add Animal Cargo

Open:

```
cfg/animals.lua
```

Animals and pelts must use correct model/hash and quality data. If quality data is wrong, players can see the wrong star quality when putting or removing animals from wagons.

***

## Exports

### Get Nearby Horse

```lua
local horse = exports["SS-Stable"]:GetHorse()
```

Returns nearby horse data, or `false`/`nil`.

### Get Nearby Wagon

```lua
local wagon = exports["SS-Stable"]:GetWagon()
```

Returns nearby wagon data, or `false`/`nil`.

### Get Active Personal Wagon

```lua
local myWagon = exports["SS-Stable"]:GetMyWagon()
```

Returns active personal wagon data, or `false`.

### Add Horse EXP

```lua
local added = exports["SS-Stable"]:AddHorseExp(50)
```

Returns:

* `true` if a nearby horse was found and EXP was sent to the server.
* `false` if no valid horse was nearby.

***

## Commands

Player-facing command:

```
/tricks
```

The command name depends on:

```lua
HorseTricksCommand = "tricks"
```

Dev/test commands can exist when `Config.Dev = true`. They are for testing only and should not be used on live servers.

***

## Notifications

At the bottom of `config.lua`:

```lua
function NOTIFY(text)
    local VORPCore = exports.vorp_core:GetCore()
    VORPCore.NotifyLeft(Config.Texts["tittle_notification"], text, "generic_textures", "tick", 5000, "COLOR_WHITE")
end
```

If your server uses another notification system, change only this function.

***

## Recommended Live Checklist

Before going live, confirm:

* SQL has been imported.
* `SS-Core` starts before `SS-Stable`.
* `Dev = false`.
* `Language` is selected.
* Optional integrations are disabled if missing.
* Inventory items are added.
* Horse shop works.
* Wagon shop works.
* Personal horse call/send works.
* Personal wagon call/send works.
* Horse equipment buying works.
* `horseequipment` item works.
* Wagon repair works.
* Wagon cargo works with different animal qualities.
* Horse training works.
* Breeding works.
* Taming works.

***

## Troubleshooting

### Stable Menu Does Not Appear

Check:

* Resource name is `SS-Stable`.
* `SS-Core` is started.
* `Config.Dev` is correct for your test/live flow.
* Player has selected a character.
* Stable coordinates are correct.
* Spots are not too far away or inside the ground.

### UI Opens But Stats Look Wrong

Check:

* Horse/wagon data in the database.
* `cfg/horses.lua` stats.
* Equipment stats.
* Browser cache or NUI refresh.

### Horse Does Not Spawn

Check:

* Horse model exists.
* Player is in an allowed call area.
* `CallHorseOnlyInCities`.
* `AllowedToCallCity`.
* Server/client console for model load timeout.

### Wagon Does Not Spawn

Check:

* Wagon model exists.
* Player is in an allowed call area.
* `CallWagonOnlyInCities`.
* `WagonDistanceToRoads`.
* `ActiveLastPosition`.
* `SS-Clan` and `SS-Housing` settings if used.

### Cannot Open Wagon Stash Or Cargo

Check:

* Wagon health.
* `BlockWagonIfDamage`.
* `WagonLowHealth`.
* Lockpick blacklist cities.
* Police/search permissions.

### Cannot Mount Horse

Check:

* `BlockMount`.
* Horse has saddle/equipment.
* Horse is old enough.
* Horse is not dead.

### Horse Equipment Item Does Not Work

Check:

* Item `horseequipment` exists in inventory/database.
* Player is inside a stable area.
* Horse is a personal horse.
* Target horse has no main equipment.
* Metadata is preserved by your inventory framework.

### Horse Food Does Not Work

Check:

* Item exists.
* Item is registered as usable server-side.
* Horse is nearby.
* `Feed` config entry exists.

### Wagon Repair Does Not Work

Check:

* `HammerRepair` item exists.
* Player is near the active wagon.
* Required repair items exist.
* Wagon has draft animals if your config/logic requires it.
* Wagon is not below recovery threshold.

### Translations Show Nil Or Wrong Text

Check:

* `Language`.
* `l/l.lua`.
* Missing translation keys.

***

## Editing Rules For Beginners

When editing Lua:

* Strings use quotes: `"text"`.
* Table entries usually end with a comma: `,`.
* `true` enables a feature.
* `false` disables a feature.
* Numbers do not use quotes: `100`.
* Item names usually use quotes: `"itemname"`.
* Coordinates usually look like `{x, y, z, heading}`.

Bad:

```lua
MaxHorses = "5"
```

Good:

```lua
MaxHorses = 5
```

Bad, if you do not actually use `SS-Housing`:

```lua
SSHousing = true
```

Good:

```lua
SSHousing = false
```

***

## Support

For bug reports and support:

```
https://discord.gg/9XNBaQSmMd
```


# Change logs

All SS-Stable updates are organized by version. Open a version page below to read the full changelog.

## Versions

* [SS-Stable V4.7](/ss-stable/change-logs/ss-stable-v4.7)
* [SS-Stable V4.6](/ss-stable/change-logs/ss-stable-v4.6)
* [SS-Stable V4.5](/ss-stable/change-logs/ss-stable-v4.5)
* [SS-Stable V4.4](/ss-stable/change-logs/ss-stable-v4.4)


# SS-Stable V4.7

## Update Summary

This update focuses on important bug fixes, stability improvements, optimization, and cleaner configuration across multiple SS-Stable systems.

***

## Fixes & Improvements

* Optimized the horse and wagon preview system.
* Fixed incorrect stats displayed in the UI for market, my horses, and preview screens.
* Fixed horse equipment visually disappearing when switching categories in the shop or stable.
* Fixed crossbreed visuals so they are applied correctly in preview, my horse preview, and called horses.
* Fixed the horseshoe system so the item is reserved and consumed correctly, preventing duplication through fast transfers.
* Fixed animal quality when animals are placed into or removed from wagons, keeping the correct star quality.
* Fixed wagon repair so it starts directly when using the repair item near the wagon, without spawning an extra hammer prop.

***

## Added

* Added wagon blocking when the wagon is too damaged, configurable through `BlockWagonIfDamage`.
* Wagon stash, cargo, outfits, and tarpaulin actions are now blocked when the wagon is too damaged.

***

## Horse Equipment System

* Added a new system for the `horseequipment` item.
* Players can remove the main equipment from a personal horse and save it as item metadata.
* Players can apply saved equipment to another personal horse.
* The system works only inside stable zones.
* Mane, tail, mustache, and extra equipment are not included.
* Equipment cannot be applied to a horse that already has main equipment.
* Fixed `bags` updates after removing or applying horse equipment.
* Search bags and inventory now update correctly without needing to send away and recall the horse.

***

## Config & Translations

* Reorganized and documented `config.lua` and the files inside `cfg` more clearly.
* Grouped settings more logically by system, including general, horse, wagon, and related sections.
* Added and fixed missing translations.
* Removed extra or unused translations where needed.
* Prepared translations in the same style as SS-IdentityCard for `EN`, `IT`, `ES`, `FR`, `DE`, `PT`, `RU`, and `RO`.

***

## Stability & Performance

* Reduced the risk of runtime issues.
* Improved idle/active wait logic for prompts and UI behavior.
* Added more defensive checks for entities, models, metadata, and native calls.


# SS-Stable V4.6

## New Features

* Added a new stamina experience control system. Horse stamina depletion and regeneration can now be adjusted with custom multipliers based on XP levels: under 1000 XP, over 1000 XP, over 2000 XP, over 3000 XP, and 4000 XP.
* Added 28 new custom horse coats, bringing the total number of custom coats to 54.
* Added horse tricks, which can be activated by command, by key, or by both. The default key behavior is triggered when the horse is locked and the player presses B.
* Added support for custom experience requirements on horse tricks, allowing each trick to require a specific XP level.
* Added SS-Admin functions. More details are available in the SS-Admin update.

***

## Fixes

* Fixed wagon repair so it correctly restores the entire wagon, including missing wheels.
* Fixed an issue where owned horse prices changed when scrolling through the owned horses list.

***

## Improvements

* Reworked the horse synchronization system. The old `-1` method, which synced to all players, caused major server overflow when calling or sending horses. It has been replaced with a new optimized sync system designed to prevent overflow.
* Optimized market refresh behavior. The market no longer auto-refreshes and now updates only when a player searches for horses near the market area, reducing unnecessary Client > Server and Server > Client data flow.
* Reorganized the config file and added more detailed explanations, making the setup easier to understand for both server owners and new customers.

***

## Changes

* Moved all translation strings out of `config.lua` into `translate/translate.lua`, keeping the configuration cleaner and more modular.
* Updated extra equipment support. A horse can now use up to 3 extra equipment items at the same time, such as extra stash, flaming horseshoes, and torch.
* Removed full wagon repair with wheels from SS-Stable. That repair flow now belongs to SS-WheelWright. SS-Stable keeps the hammer repair system, with configurable health amount, scenario, animation, required items, and item amount.
* Added a configurable maximum horse market price multiplier. This prevents players from listing horses at extremely high prices and leaving them on the market indefinitely.

***

## Preview

![](/files/16bSSjd7eFakAfvnGU41) ![](/files/bKZKKDlG7FuOwvaAshjr)

<figure><img src="/files/szJ6mkw0mrj2x2B8nMHR" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/aF2bxek0YR3abRVpmb6W" alt=""><figcaption></figcaption></figure>


# SS-Stable V4.5

## Update Summary

This update focuses on horse spawning, training, horseshoes, foal visuals, equipment behavior, inventory quality-of-life improvements, and new configuration options for horse drinking props and inventory limits.

***

## Fixes & Improvements

* Fixed an issue where calling a horse could sometimes duplicate the horse or trigger an F8 error.
* Fixed route-based training experience not being saved correctly.
* Fixed an issue that allowed players to equip more than 4 horseshoes on one horse.
* Fixed mount behavior for foals after new skins were added, ensuring foals correctly receive the new skin data.
* Fixed horse statistics when horses were created or loaded with different stat values.
* Fixed extra equipment removal when the buttons were not activating correctly.
* Improved inventory behavior while carrying an entity. Inventory buttons no longer appear during this action, making it easier to place players, animals, or skins on a horse.
* Fixed horse mane and tail visuals so modified values are visible correctly on the horse.
* Fixed stable and equipment preview behavior so horses with custom skins display correctly instead of showing the default horse.

***

## Added

* Added support for custom water props when horses drink water.
* Added a horse inventory limit option through `IgnoreItemsLimit`.
* Added improved horse tricks behavior. The `horsetricks` function can now work through a command, or through horse petting when the command is disabled in config.

***

## Config

### Drinking Props

You can now define which props are valid for horse drinking interactions:

```lua
DrinkingProps = {
    "p_watertrough02x",
    "p_watertrough01x",
    "p_watertrough03x",
    "p_watertrough01x_new",
    "p_watertroughsml01x",
}
```

### Horse Inventory Limit

Horse inventory behavior can now be controlled from config:

```lua
IgnoreItemsLimit = false
```

* `true`: Horse inventory ignores the normal item limit.
* `false`: Horse inventory follows the same item limit behavior as the player inventory.

### Horse Tricks Command

Horse tricks can be configured to use a command or a petting interaction:

```lua
HorseTricksCommand = false
```

* Set a command name to enable command-based horse tricks.
* Set to `false` to disable the command and use the configured interaction behavior instead.


# SS-Stable V4.4

## Update Summary

This is an important update for SS-Stable. It fixes several known issues and improves synchronization, market behavior, stamina control, translations, equipment handling, and documentation.

Please read the changelog carefully before updating. If anything is unclear, ask for support before applying the update on a live server.

***

## Fixes & Improvements

* Reworked the horse synchronization system. The previous `-1` sync method, which synced to all players, could cause major server overflow when calling or sending horses. It has been replaced with a new optimized sync system designed to prevent overflow.
* Fixed wagon repair so it correctly restores the entire wagon, including missing wheels.
* Fixed an issue where owned horse prices changed every time players scrolled through their owned horses.
* Optimized market refresh behavior. The market no longer auto-refreshes and now updates only when a player searches for horses near the market area, reducing unnecessary Client > Server and Server > Client data flow.

***

## Added

* Added a new stamina experience control system. Horse stamina depletion and regeneration can now be adjusted with custom multipliers based on XP levels: under 1000 XP, over 1000 XP, over 2000 XP, over 3000 XP, and 4000 XP.
* Added 28 new custom horse coats, bringing the total number of custom coats to 54.
* Added full SS-Stable documentation.

***

## Changes

* Moved all translation strings out of `config.lua` into `translate/translate.lua`, making the configuration cleaner, smaller, and more modular.
* Updated extra equipment support. A horse can now use up to 3 extra equipment items at the same time, such as extra stash, flaming horseshoes, and torch.

***

## Documentation

Full documentation for SS-Stable is available here:

```
https://docs.sirecstudio.com/ss-stable
```

If anything is missing or unclear, please report it so the documentation can be improved.


