# Installation

#### 📦 Installation Instructions for K9 Script System

To ensure the proper functioning of the K9 Script System, you need to follow these installation instructions carefully. This system has some essential dependencies that must be installed first.

***

#### 🛠️ Asset Dependencies

This asset has some mandatory dependencies that are crucial for its operation. If you do not have these dependencies, your asset may start with errors or fail to function correctly.

***

#### Dependencies & Direct Links

| **Dependency**   | **Direct Link**                                                                                         |
| ---------------- | ------------------------------------------------------------------------------------------------------- |
| **ox\_lib**      | [Download ox\_lib](https://github.com/overextended/ox_lib/releases) *(Do not download the source code)* |
| **oxmysql**      | [Download oxmysql](https://github.com/overextended/oxmysql/releases)                                    |
| **qbcore**       | [Download qbcore](https://github.com/qbcore-framework/qb-core)                                          |
| **qb-inventory** | [Download qb-inventory](https://github.com/qbcore-framework/qb-inventory)                               |
| **qb-target**    | [Download qb-target](https://github.com/qbcore-framework/qb-target)                                     |

Alternatively, for **ESX**, use the following dependencies:

* [**es\_extended (ESX Base)**](https://github.com/esx-framework/esx_core)
* [**ox\_inventory**](https://github.com/overextended/ox_inventory)
* [**ox\_target**](https://github.com/overextended/ox_target)

***

🗄️ Database Setup

Run the following SQL command inside your database to set up the necessary table for the K9 Script System. This step is crucial for the proper functioning of the asset, so please do not skip it.

<details>

<summary>Click to view SQL Code</summary>

```sql
CREATE TABLE IF NOT EXISTS `evo_k9_dogs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `citizenid` varchar(50) NOT NULL,
  `name` varchar(50) NOT NULL,
  `model` varchar(50) DEFAULT NULL,
  `colour` int(11) DEFAULT 0,
  `vest` int(11) DEFAULT 0,
  `health` int(11) DEFAULT 200 CHECK (`health` <= 200),
  `hunger` int(11) DEFAULT 100 CHECK (`hunger` <= 100),
  `thirst` int(11) DEFAULT 100 CHECK (`thirst` <= 100),
  `rep` int(11) DEFAULT 0,
  `stamina` int(11) DEFAULT 0 CHECK (`stamina` <= 100),
  `smell` int(11) DEFAULT 0 CHECK (`smell` <= 100),
  `attack` int(11) DEFAULT 0 CHECK (`attack` <= 100),
  `ui_position` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '{"x": 0, "y": 0}' CHECK (json_valid(`ui_position`)),
  `vestname` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
```

</details>

***

#### 📦 Install Items in inventory

This system includes areas for dog-related activities, which will require specific items to be added to your inventory. Below is the code snippet to add the necessary items for the K9 Script System.

<details>

<summary>Click to view Items for qb-inventory Code</summary>

```lua
k9glowstick = { 
    name = 'k9glowstick', 
    label = 'Dog Glow Stick', 
    weight = 0, 
    type = 'item', 
    image = 'k9glowstick.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'A glow for your k9' 
},

k9weed = { 
    name = 'k9weed', 
    label = 'K9 Weed', 
    weight = 0.5, 
    type = 'item', 
    image = 'k9weed.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'Plant weed to train your k9 smell power' 
},

attacktrain = { 
    name = 'attacktrain', 
    label = 'Attack Training', 
    weight = 1, 
    type = 'item', 
    image = 'attacktrain.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'Training tool for k9 attack drills' 
},

staminatrain = { 
    name = 'staminatrain', 
    label = 'Stamina Training', 
    weight = 1, 
    type = 'item', 
    image = 'staminatrain.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'Training tool to boost k9 stamina' 
},

k9revivekit = { 
    name = 'k9revivekit', 
    label = 'Revivekit For K9', 
    weight = 1, 
    type = 'item', 
    image = 'k9revivekit.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'Revivekit for your k9 dog' 
},

k9food = { 
    name = 'k9food', 
    label = 'K9 Food', 
    weight = 1, 
    type = 'item', 
    image = 'k9food.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'Food For Your K9 Dog' 
},

k9drink = { 
    name = 'k9drink', 
    label = 'K9 Drink', 
    weight = 1, 
    type = 'item', 
    image = 'k9drink.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'Drink For Your K9 Dog' 
},

k9cage = { 
    name = 'k9cage', 
    label = 'K9 Cage', 
    weight = 1, 
    type = 'item', 
    image = 'k9cage.png', 
    unique = false, 
    useable = true, 
    shouldClose = true, 
    combinable = nil, 
    description = 'Cage For Your K9 Dog' 
},
```

</details>

<details>

<summary>Click to view Items for ox_inventory Code</summary>

```lua
["k9glowstick"] = {
    label = "Dog Glow Stick",
    weight = 0,
    stack = false,
    close = true,
    description = "A glow for your k9",
    client = {
        image = "k9glowstick.png",
    }
},

["k9weed"] = {
    label = "K9 Weed",
    weight = 0.5,
    stack = false,
    close = true,
    description = "Plant weed to train your k9 smell power",
    client = {
        image = "k9weed.png",
    }
},

["attacktrain"] = {
    label = "Attack Training",
    weight = 1,
    stack = false,
    close = true,
    description = "Training tool for k9 attack drills",
    client = {
        image = "attacktrain.png",
    }
},

["staminatrain"] = {
    label = "Stamina Training",
    weight = 1,
    stack = false,
    close = true,
    description = "Training tool to boost k9 stamina",
    client = {
        image = "staminatrain.png",
    }
},

["k9revivekit"] = {
    label = "Revivekit For K9",
    weight = 1,
    stack = false,
    close = true,
    description = "Revivekit for your k9 dog",
    client = {
        image = "k9revivekit.png",
    }
},

["k9food"] = {
    label = "K9 Food",
    weight = 1,
    stack = false,
    close = true,
    description = "Food For Your K9 Dog",
    client = {
        image = "k9food.png",
    }
},

["k9drink"] = {
    label = "K9 Drink",
    weight = 1,
    stack = false,
    close = true,
    description = "Drink For Your K9 Dog",
    client = {
        image = "k9drink.png",
    }
},

["k9cage"] = {
    label = "K9 Cage",
    weight = 1,
    stack = false,
    close = true,
    description = "Cage For Your K9 Dog",
    client = {
        image = "k9cage.png",
    }
},
```

</details>

***

#### 🖼️ Images Installation

In the **evo-k9** folder, navigate to the **images** directory and install all images into your inventory.

For example, in **qb-inventory**, you should place the images in the following location:

👉 **qb-inventory\html\images**

Make sure all image files are correctly placed in this folder to ensure they are accessible in your K9 Script System. 🐾

***

**📝 Inventory Integration**

You have to add the following code in your `inventory`

if you are using ox\_inventory => `modules/inventory/server.lua`

&#x20;add it after `loadInventoryData` function  (line: 196)

<details>

<summary>Click to expand the code for ox_inventory</summary>

```lua
local function evok9getVehicleNetIdByPlate(plate)
    local vehicles = GetAllVehicles()
    for _, vehicle in ipairs(vehicles) do
        local vehiclePlate = GetVehicleNumberPlateText(vehicle)
        if vehiclePlate:find(plate) then
            local netid = NetworkGetNetworkIdFromEntity(vehicle)
            return netid
        end
    end
    return nil
end

---@param data table -- The inventory data, including id, type, and entity information
---@param player table -- The player data (optional)
---@return table | nil -- Returns the list of items or nil if no items found
local function evok9PrintAndReturnInventoryItems(data, player)
    local inventory = setmetatable(Inventory, {
        __call = function(self, inv, player)
            if not inv then
                return self
            elseif type(inv) == 'table' then
                if inv.__index then return inv end

                return not inv.owner and Inventories[inv.id] or loadInventoryData(inv, player)
            end

            return Inventories[inv] or loadInventoryData({ id = inv }, player)
        end
    })(data, player)

    if inventory.items then
        local items = {}

        for slot, item in pairs(inventory.items) do
            table.insert(items, {name = item.name, count = item.count or 1})
        end
        return items
    else
        return nil
    end
end

exports('evok9PrintAndReturnInventoryItems', evok9PrintAndReturnInventoryItems)


---@param plate string -- The plate of the vehicle
---@return table | nil -- Returns the list of items or nil if no items found
local function evok9getVehicleTrunkItemsByPlate(plate)
    local netid = evok9getVehicleNetIdByPlate(plate)
    if netid then
        local data = {
            id = "trunk" .. plate,
            type = "trunk",
            netid = netid,
        }
        
        local items = evok9PrintAndReturnInventoryItems(data)
        if items then
            for _, item in ipairs(items) do
            end
        end
        return items
    else
        return nil
    end
end

exports('evok9getVehicleTrunkItemsByPlate', evok9getVehicleTrunkItemsByPlate)


---@param plate string -- The vehicle plate number
---@return table -- Returns the list of items in the glovebox or nil if not found
local function evok9getVehicleGloveboxItemsByPlate(plate)
    local netid = evok9getVehicleNetIdByPlate(plate)
    if netid then
        local data = {
            id = "glovebox" .. plate,
            type = "glovebox",
            netid = netid,
        }
        return evok9PrintAndReturnInventoryItems(data)
    else
        return nil
    end
end

exports('evok9getVehicleGloveboxItemsByPlate', evok9getVehicleGloveboxItemsByPlate)
```

</details>

if you are using qb-inventory =>  `server/functions.lua`

<details>

<summary>Click to expand the code <em>new</em> qb-inventory</summary>

```lua
--- @param source number The player's server ID.
--- @param identifier string|nil The identifier of the inventory to open.
--- @param data table|nil Additional data for initializing the inventory.
function evok9CheckInventoryItems(identifier, data)
    if not identifier then
        print("No identifier provided.")
        return nil
    end

    if type(identifier) ~= 'string' then
        print("Invalid identifier provided.")
        return nil
    end

    local inventory
    if identifier:sub(1, 7) == "player-" then
        local playerId = tonumber(identifier:sub(8))
        local Player = QBCore.Functions.GetPlayer(playerId)
        if Player then
            inventory = Player.PlayerData.items
        else
            print("Player not found.")
            return nil
        end
    else
        inventory = Inventories[identifier]
        if not inventory then
            inventory = InitializeInventory(identifier, data)
        end
        inventory = inventory.items
    end

    local formattedInventory = {
        name = identifier,
        label = (inventory and inventory.label) or (data and data.label) or identifier,
        maxweight = (inventory and inventory.maxweight) or (data and data.maxweight) or Config.StashSize.maxweight,
        slots = (inventory and inventory.slots) or (data and data.slots) or Config.StashSize.slots,
        inventory = inventory
    }

    if formattedInventory.inventory then
        return formattedInventory.inventory
    else
        print("No items found in inventory: " .. identifier)
        return nil
    end
end

exports('evok9CheckInventoryItems', evok9CheckInventoryItems)


--- @param source number The player's server ID.
--- @param identifier string|nil The identifier of the inventory to open.
--- @param data table|nil Additional data for initializing the inventory.
function evok9CheckPlayerInventoryItems(playerId)
    local Player = QBCore.Functions.GetPlayer(playerId)
    if not Player then
        print("Player not found.")
        return nil
    end

    return Player.PlayerData.items
end

exports('evok9CheckPlayerInventoryItems', function(playerId)
    return evok9CheckPlayerInventoryItems(playerId)
end)
```

</details>

***

#### 📌 Final Steps

Make sure you follow these instructions carefully to ensure the K9 Script System is installed correctly on your server. Enjoy training your K9 companion and enhancing your gameplay experience!


---

# 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://evo-development.gitbook.io/evo-development-docs/products/k9/installation.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.
