# Adding Custom Shells

## 0r\_houses - Custom Shell Integration Guide

This guide explains step-by-step how to integrate your custom shell (player-specific interior objects) systems into the **0r\_houses** system. Whether you are using `K4MB1 Shells`, `loaf_housing`, or your own custom shell scripts, you can use this infrastructure to add shell houses into 0r\_houses.

***

### Step 1: Defining a New House Theme

First, open the `config/house_themes.lua` file. We will add a new "Shell" theme to the section where we define normal house themes.

It is extremely important to add the **`IsShell = true`** value to tell the script that this is a **Shell**. You can also define custom variables like `ShellModel` which you will send to your custom shell creation code.

```lua
Config.HouseThemes["MyCustomTheme"] = {
    Name = 'MyCustomTheme', -- Unique Theme Name
    Label = 'Ultra Luxury Shell House', -- Name Displayed in Menus
    IsShell = true, -- YOU MUST ABSOLUTELY SET THIS TO TRUE
    ShellModel = 'shell_luxury_01', -- Object name or hash you will use in your shell code
    Garage = false,
    EmptyIpl = false,
    ManageMenuItem = 'bkr_prop_clubhouse_laptop_01a',
    MapHasTintColor = false,
    OnlyIPL = false,
    Image = 'newloft.png', -- Name of the image file in the web/assets/ folder
    
    -- Note: Since shells spawn at dynamic coordinates,
    -- we will calculate stash and wardrobe values dynamically inside client_editable.lua.
    -- You can write empty values or offsets (differences) here for a start.
    stashes = {
        [1] = {
            name = 'Bedroom Stash',
            offset = vector3(-1.5, 2.0, 0.5), -- Distance to the center of the shell for calculation
            stashWeight = 50,
            Lock = true,
        }
    },
    wardrobes = {
        vector3(-2.5, 1.5, 0.5) -- Distance to the center of the shell for calculation
    }
}
```

***

### Step 2: Spawning the Shell (When the Player Enters)

The moment the player enters the house, the **`Config.CreateCustomShell`** function at the bottom of the `config/client_editable.lua` file is automatically triggered.

This function has two main tasks:

1. Placing (spawning) the shell object into the world.
2. Returning the **coordinate of the point where the player will stand inside (as vector3 or vector4)** so the player can teleport into the shell.

In the example below, a hypothetical shell script is used for the spawn process:

```lua
Config.CreateCustomShell = function(houseId, houseData, themeData)
    -- 1. Let's get our shell model
    local modelStr = themeData.ShellModel
    
    -- 2. Send a request to your shell script and spawn the shell.
    -- This is just an example, use your own script's export!
    -- Example: local spawnCoord = {x = 100.0, y = 100.0, z = -50.0}
    local shellObj, shellCenterCoord = exports['my_shell_script']:CreateShell(modelStr)
    
    -- If it doesn't spawn, we cancel the process by returning nil
    if not shellCenterCoord then return nil end
    
    -- 3. Let's dynamically update the house coordinates when the player falls inside.
    -- Let's adjust the Stash placement relative to the center of the shell
    if themeData.stashes and themeData.stashes[1] then
        houseData.coords.stashes = {
            [1] = {
                name = themeData.stashes[1].name,
                -- We add the offset amount from the theme config to the shell center coordinate
                coord = vec3(
                    shellCenterCoord.x + themeData.stashes[1].offset.x, 
                    shellCenterCoord.y + themeData.stashes[1].offset.y, 
                    shellCenterCoord.z + themeData.stashes[1].offset.z
                ),
                stashWeight = themeData.stashes[1].stashWeight,
                Lock = themeData.stashes[1].Lock
            }
        }
    end
    
    -- Let's adjust the Wardrobe placement
    if themeData.wardrobes and themeData.wardrobes[1] then
        houseData.coords.wardrobes = {
            vec3(
                shellCenterCoord.x + themeData.wardrobes[1].x, 
                shellCenterCoord.y + themeData.wardrobes[1].y, 
                shellCenterCoord.z + themeData.wardrobes[1].z
            )
        }
    end
    
    -- 4. We are returning the actual point where the player will be teleported!
    -- The player will enter the game at the shell center coordinate.
    return vec4(shellCenterCoord.x, shellCenterCoord.y, shellCenterCoord.z, 0.0) 
end
```

***

### Step 3: Deleting the Shell (When the Player Exits)

When the player leaves the house, the **`Config.DeleteCustomShell`** function in `config/client_editable.lua` is triggered to avoid exhausting the game and to increase performance.

Here, you need to delete the shell object you created in the previous step:

```lua
Config.DeleteCustomShell = function(houseId, houseData, themeData)
    -- Remove the shell from the world via your shell script's export.
    -- Example:
    exports['my_shell_script']:RemoveShell()
    
    -- Note: If you created the object yourself with CreateObject, 
    -- you can keep that object in a variable (e.g. ActiveShells[houseId] = obj)
    -- and delete it with the DeleteEntity(obj) function.
end
```

#### Summary:

1. Create your theme as **`IsShell = true`** in `house_themes.lua`.
2. Call your shell script via `Config.CreateCustomShell` in `client_editable.lua`, update the coordinates of house items (stash/wardrobe) relative to the shell, and return the entry point.
3. Clean up the shell when leaving the house via `Config.DeleteCustomShell` in `client_editable.lua`.


---

# 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://docs.0resmon.org/0resmon/0r-resources/0r-houses/adding-custom-shells.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.
