# xakra\_building

## Requirements

* [vorp\_core](https://github.com/VORPCORE/vorp-core-lua)
* [vorp\_inventory](https://github.com/VORPCORE/vorp_inventory-v2)
* [oxmysql](https://github.com/overextended/oxmysql)
* [lockpick](https://github.com/XakraD/lockpick)

***

## Installation

1. Copy the script into a folder (to choose) from the 'resources' folder.
2. Add 'ensure xakra\_building' in the 'resources.cfg' document.
3. Execute the queries in the database of the 'sql/table.sql' file to create the table needed for the script to work (only run the section of your framework), the queries to execute are separated by the framework.
4. Change the framework in the fxmanifest file (important if you use REDEM).
5. Check the config.lua file and configure to adapt the script, change the language, change the framework, the list of items and objects, enable or disable options, the prompt keys, etc...

***

## Config & Framework

<details open>

<summary>config.lua</summary>

{% code expandable="true" %}

```lua
Config = {}

Config.defaultlang = 'es'   -- Language

Config.Webhook = ''

-- Keys: https://github.com/femga/rdr3_discoveries/tree/master/Controls
Config.Keys = {
    Right = 0xDEB34313,    -- RIGHT ARROW
    Left = 0xA65EBAB4, -- LEFT ARROW
    Ahead = 0x6319DB71,    -- UP ARROW
    Aback = 0x05CA7C52,    -- DOWN ARROW
    Up = 0x1ECA87D4,   -- Q
    Down = 0x018C47CF, -- E
    Speed = 0x8AAA0AD4,    -- LEFT ALT
    Mode = 0xA1ABB953, -- G
    Cancel = 0x156F7119,   -- BACKSPACE
    Build = 0x43DBF61F,    -- ENTER
    Modular = 0x620A6C5E,    -- V

    DelBuild = 0x018C47CF, -- E

    MoveBuild = 0x018C47CF, -- E

    OpenDoor = 0x760A9C6F, -- G

    OpenChest = 0x760A9C6F, -- G
}

Config.MoveBuildingCommand = 'movebuild'    -- Command to delete player share building
Config.DelBuildingCommand = 'delbuild'  -- Command to enable delete mode
Config.ShareBuildingCommand = 'sharebuild'  -- Command to share building
Config.DelShareBuildingCommand = 'delsharebuild'    -- Command to delete player share building

Config.CrosshairColor = { r = 18, g = 133, b = 14 } -- List RGB (Color of the sight of the commands to move and delete, min = 0, max = 255) or false

Config.TextColor = { r = 18, g = 133, b = 14 } -- Color of the text of the commands to move and delete, min = 0, max = 255

Config.Speeds = {   -- Building movement speeds
    1,
    2.5,
    4,
    5.5,
}

-- List of zones that cannot be built
Config.ZonesNotBuilding = {
    { coords = vector3(2941.61, 1346.21, 44.1), radius = 400.0 }, -- ANNESBURG
    { coords = vector3(1347.07, -1251.19, 79.17), radius = 400.0 }, -- RHODES
    { coords = vector3(3049.33, 508.34, 44.42), radius = 400.0 },   -- VAN HORN
    { coords = vector3(2615.95, -1222.37, 53.34), radius = 700.0 }, -- SAINT DENIS
    { coords = vector3(-282.13, 717.68, 114.32), radius = 400.0 }, -- VALENTINE
    { coords = vector3(-1809.37, -390.41, 161.61), radius = 300.0 }, -- STRAWBERRY
    { coords = vector3(-801.42, -1304.05, 43.48), radius = 300.0 }, -- BLACKWATER
    { coords = vector3(-3669.82, -2596.38, -14.32), radius = 400.0 },   -- ARMADILLO
    { coords = vector3(-5526.51, -2971.92, -1.4), radius = 400.0 },   -- TUMBLEWEED
}

-- Smoke color when building, removing and destroying
Config.SmokeEnable = true
Config.SmokeColor = { r = 79, g = 124, b = 0 }  -- RGB Color (min = 0, max = 255)

-- List of objects that work as doors
Config.ObjectDoors = {
    -- { object = 'Name object model', lock = true or false (Can be opened with a lockpick), right = true or false (Side on which the door opens) },
	{ object = 'val_p_door_lckd_1' },
    { object = 's_clothingcasedoor01x' },
    { object = 's_door_val_bankvault' },
    { object = 'p_doornbd39x_destruct', lock = true },
}

Config.CheckInvDeleting = true  -- true (When trying to delete a chest it will check if it has items or weapons in storage) or false

Config.Inventory = {
    Groups = {  -- Groups that will have full permissions (.group)
        'admin',
        -- 'example',
    },
	Blacklist = {
		'opium',
		'WEAPON_SNIPERRIFLE_CARCANO',
	},
	MaxItems = {
		iron = 100,
		wood = 150,
	},
    MaxItemsModels = {
        s_re_rcboatbox01x = {
            iron = 5,
            wood = 100,
        },
        -- example = {
        --     iron = 50,
        --     wood = 10,
        -- },
    },
	DisableWeapons = false,
}

Config.Lockpick = {
    Item = 'lockpick',  -- Name of the item required and consumed when picking
    Chests = true,  -- enable/disable steal chests whit lockpick
    ChestCommand = 'testigo Se ha visto a una persona ganzuar un cofre',  -- 'witness command' or false
    Doors = true,  -- enable/disable open doors whit lockpick
    DoorCommand = 'testigo Se ha visto a una persona ganzuar una puerta',  -- 'witness command' or false
    JobsRequired = {
        amount = 2, -- number of players with one of the required jobs from the list or false
        jobs = {    -- List of jobs required to use the lock pick
            'sheriff',
            -- 'example',
        },
    },
}

-- List of objects that work as chests
Config.ObjectChests = {
    -- { object = 'OBJECT MODEL NAME', capacity = 'CHEST CAPACITY', lock = 'enable or disable that can be opened with a lockpick' },
	{ object = 's_re_rcboatbox01x', capacity = 50 },
    { object = 'p_chest01x', capacity = 200 },
    { object = 's_lootablebedchest', capacity = 500, lock = true },
}

Config.BuildingsHealth = {
    Enable = true,   -- true/false Enable or disable the item health system
    Radio = 7, -- number (Radius to show the health of the objects) or false (Disable seeing health on objects)
    Color = {  -- Health bar colors
        BackgroundBar = { r = 25, g = 25, b = 25 }, -- min = 0, max = 255
        Bar = { r = 0, g = 128, b = 0 },    -- min = 0, max = 255
    },
    JobsRequired = {
        amount = 2, -- number (amount of players with one of the required jobs from the list) or false
        jobs = {    -- List of jobs required to break buildings
            'sheriff',
            -- 'example',
        },
    },
    BreakCommand = 'testigo Se ha visto a alguien romper una construcción',  -- 'witness command' or false
    ZonesNotHealth = {  -- Zones that players cannot destroy buildings
        { coords = vector3(1421.14, 322.07, 88.4), radius = 100.0 }, -- EMERALD RANCH
        { coords = vector3(-2376.92, -2391.35, 61.37), radius = 100.0 }, -- MACFARLANE'S RANCH
        { coords = vector3(456.11, 2230.73, 247.35), radius = 100.0 }, -- WAPITI INDIAN RESERVATION
        { coords = vector3(-1094.7, 722.21, 104.91), radius = 100.0 }, -- CATTAIL POND
    },
}

Config.SpawnDistance = 100  -- number (distance that objects will be created and deleted)

Config.ItemsBuilding = {
    -- {
    --     item = 'example',
    --     object = 'example_object',
    --     health = false,
    --     jobs = { 'example1', 'example2' },
    --     objects = { 'mlo1', 'mlo2' },
    --     unfreeze = true or false,
    --     veg = number or false,
    --     limit = number or false,
    --     jobsLimit = { ['example1'] = number or false, ['example2'] = number or false },
    --     GroupOnlyDelete = true or false,
    --     modular = 'lateral', 'vertical' or 'grid',
    -- },

-- ===================== CHESTS ====================  
    { item = 'boatbox01', object = 's_re_rcboatbox01x', health = false },
    { item = 'chest01', object = 'p_chest01x', health = false },
    { item = 'lootchest', object = 's_lootablebedchest', health = false },

-- ===================== WALLS ====================  
    { item = 'plankwall2', object = 'p_plankwall_02', health = 6000 },
    { item = 'fencewall1', object = 'p_fence_wall01x', health = 6000 },
    { item = 'fencewall2', object = 'p_fence_wall02x', health = 6000 },
    { item = 'barricadewood', object = 'p_barricadewood_lrg01x', health = 10000, veg = 2 },
    { item = 'barricade', object = 'p_barricade03x', health = 10000, veg = 3 },
    { item = 'fortmercerbarricade', object = 'p_fortmercerbarricade01x', health = 12000 },
    { item = 'cornwindow', object = 'p_corn_uwindow_02', health = 6000 },
    { item = 'woodramp01', object = 'p_woodramp01x_sea', health = 6000 },

-- ===================== POSSE TENTS ====================  
    { item = 'possetentbountyhunter7', object = 'mp005_s_posse_tent_bountyhunter07x', health = 12000, veg = 5 },
    { item = 'possetentbountyhunter2', object = 'mp005_s_posse_tent_bountyhunter02x', health = 12000, veg = 5 },
    { item = 'possetentbountyhunter6', object = 'mp005_s_posse_tent_bountyhunter06x', health = 12000, veg = 5 },
    { item = 'possetentcollector4', object = 'mp005_s_posse_tent_collector04x', health = 12000, veg = 5 },

-- ===================== FURNITURES ==================== 
    { item = 'tablemil', object = 'p_cratetablemil01x', health = true },  
    { item = 'table11', object = 'p_table11x', health = true },
    { item = 'saloontable', object = 'p_cs_mtsaloontable', health = true },

    { item = 'chairrustic1', object = 'p_chairrusticsav01x', health = true },  
    { item = 'chairoffice2', object = 'p_chairoffice02x', health = true },
    { item = 'chairrustic5', object = 'p_chairrustic05x', health = true },
    { item = 'seatbench1', object = 'p_seatbench01x', health = true },
    { item = 'bench1', object = 'p_benchch01x', health = true },

    { item = 'bed10', object = 'p_bed10x', health = true },
    { item = 'bed12', object = 'p_bed12x', health = true },
    { item = 'bed01', object = 's_bedarthur01x', health = true },
    { item = 'bed21', object = 'p_bed21x', health = true },

-- ===================== DOORS ====================  
    { item = 'door1', object = 'val_p_door_lckd_1', health = 12000 },
    { item = 'casedoor', object = 's_clothingcasedoor01x', health = 20000 },
    { item = 'bankdoor', object = 's_door_val_bankvault', health = 12000 },
    { item = 'doornbd', object = 'p_doornbd39x_destruct', health = 4000 },
    
-- ===================== LIGHTS ====================  
    { item = 'torchpostal', object = 'p_torchpostalwayson01x', health = true },
    { item = 's_interact_torch', object = 's_interact_torch', health = true },
    { item = 'lamp', object = 'p_lampkerosene01xint', health = true },
    { item = 'lamphang', object = 'p_lamphangnbx01x', health = true },
    
-- ===================== OTHERS ==================== 
    { item = 'hitchingpost', object = 'p_hitchingpost01x', health = 6000}, 
    { item = 'ladder1', object = 'p_beechers_ladder01x', health = 12000 },
    { item = 'waterpump', object = 'p_waterpump01x', health = 6000 },
    { item = 'campfirecombined', object = 'p_campfirecombined03x', health = false, veg = 2 },
}
```

{% endcode %}

</details>

<details open>

<summary>framework</summary>

client.lua

{% code expandable="true" %}

```lua
TriggerEvent("getCore", function(core)
    VORPcore = core
end)

function NotifyLeft(title, subtitle, dict, icon , time, color)
    VORPcore.NotifyLeft(title, subtitle, dict, icon , time, color)
end

function AddWebhook(title, webhook, description, color, name, logo, footerlogo, avatar)
    VORPcore.AddWebhook(title, webhook, description, color, name, logo, footerlogo, avatar)
end

function openInventory(id, inv, capacity)
    TriggerEvent('vorp_inventory:ReloadHideoutInventory', json.encode({itemList = inv, action = 'setSecondInventoryItems'}))
    TriggerEvent('vorp_inventory:OpenHideoutInventory', _U('ChestLabel').." "..id, id, capacity)
end

function UseLokpick()
    return exports['lockpick'].lockpick()   -- return true or false
end

-- TriggerEvent('xakra_building:SelectDoor', DoorEntity)    -- Event to open doors to be able to use it in other targeting scripts
```

{% endcode %}

server.lua

{% code expandable="true" %}

```lua
TriggerEvent("getCore", function(core)
    VORPcore = core
end)

function NotifyLeft(source, title, subtitle, dict, icon , time, color)
    VORPcore.NotifyLeft(source, title, subtitle, dict, icon , time, color)
end

function GetCharacter(source)
    -- .job
    -- .identifier
    -- .charIdentifier
    return VORPcore.getUser(source).getUsedCharacter
end

function GetCharacterJob(source)
    return Player(source).state.Character and Player(source).state.Character.Job 
end

function RegisterUsableItem(item, cb)
    -- data.source
    exports.vorp_inventory:registerUsableItem(item, function(data)
        cb(data)
    end)
end

function getItemCount(source, item, metadata, callback)
    return exports.vorp_inventory:getItemCount(source, callback, item, metadata)
end

function canCarryItems(source, amount)
    return exports.vorp_inventory:canCarryItems(source, amount)
end

function canCarryItem(source, item, amount, callback)
    return exports.vorp_inventory:canCarryItem(source, item, amount, callback)
end

function subItem(source, item, amount, metadata, callback)
    exports.vorp_inventory:subItem(source, item, amount, metadata, callback)
end

function addItem(source, item, amount, metadata)
    exports.vorp_inventory:addItem(source, item, amount, metadata)
end

function openInventory(source, id, inv, capacity)
    TriggerClientEvent('vorp_inventory:ReloadHideoutInventory', source, json.encode({itemList = inv, action = 'setSecondInventoryItems'}))
    TriggerClientEvent('vorp_inventory:OpenHideoutInventory', source, _U('ChestLabel').." "..id, id, capacity)
end

function CloseInv(source, invId)
    exports.vorp_inventory:closeInventory(source, invId)
end

function AddWebhook(title, webhook, description, color, name, logo, footerlogo, avatar)
    VORPcore.AddWebhook(title, webhook, description, color, name, logo, footerlogo, avatar)
end
```

{% endcode %}

</details>


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://xakra-scripts.gitbook.io/xakra-scripts-docs/redm-docs/xakra_building.md?ask=<question>
```

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

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