# Storage

## 📦 Storage Class

A container where the player can store items and currency.

> **Namespace:** `Esper.Inventool.Storing`\
> **Access:** `public`\
> **Type:** `class`\
> **Inherits:** `Vault`

***

### 📦 Fields

| Access   | Field                     | Type     | Description                                |
| -------- | ------------------------- | -------- | ------------------------------------------ |
| `public` | `id`                      | `string` | The storage ID.                            |
| `public` | `customTitle`             | `string` | A custom title.                            |
| `public` | `localizedCustomTitleKey` | `string` | The localization key for the custom title. |
| `public` | `hideCurrency`            | `bool`   | If the currency UI should be hidden.       |

***

### 🔍 Properties

| Access   | Property                | Type     | Description                                                   |
| -------- | ----------------------- | -------- | ------------------------------------------------------------- |
| `public` | `AllowItemDropping`     | `bool`   | If item dropping should be allowed (from inventory settings). |
| `public` | `ShowSubtypes`          | `bool`   | If item subtypes should be shown in the filter list.          |
| `public` | `DeleteItemsOnDrop`     | `bool`   | If items should be deleted on drop.                           |
| `public` | `NoFilterIcon`          | `Sprite` | Icon of the “no filter” button.                               |
| `public` | `NoFilterIconColorTint` | `Color`  | Color tint of the “no filter” icon.                           |

***

### 📢 Events

| Access          | Event                 | Type                             | Description                                |
| --------------- | --------------------- | -------------------------------- | ------------------------------------------ |
| `public static` | `onItemsUpdated`      | `UnityEvent`                     | Invoked when the item list is updated.     |
| `public static` | `onItemDeposited`     | `UnityEvent<ItemStack, Storage>` | Invoked when an item is deposited.         |
| `public static` | `onItemWithdrawn`     | `UnityEvent<ItemStack, Storage>` | Invoked when an item is withdrawn.         |
| `public static` | `onCurrencyDeposited` | `UnityEvent<Currency, Storage>`  | Invoked when currency is deposited.        |
| `public static` | `onCurrencyWithdrawn` | `UnityEvent<Currency, Storage>`  | Invoked when currency is withdrawn.        |
| `public static` | `onItemDropped`       | `UnityEvent<ItemStack, Storage>` | Invoked when an item is dropped.           |
| `public static` | `onActionFailed`      | `UnityEvent<StorageError>`       | Invoked when a storage action fails.       |
| `public static` | `onStorageOpened`     | `UnityEvent<Storage>`            | Invoked when the storage window is opened. |
| `public static` | `onStorageClosed`     | `UnityEvent<Storage>`            | Invoked when the storage window is closed. |

***

### 🧰 Methods

| Access            | Method                                                                  | Returns                | Description                                                                  |
| ----------------- | ----------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------- |
| `public static`   | `SetLoader(Func<string, InventoolSavableData> loader)`                  | `void`                 | Sets the sync loader and loads storages for active keepers.                  |
| `public static`   | `SetLoaderAsync(Func<string, Task<InventoolSavableData>> loaderAsync)`  | `void`                 | Sets the async loader and loads storages for active keepers.                 |
| `public`          | `CreateSavableData()`                                                   | `InventoolSavableData` | Creates savable data for items and currencies.                               |
| `public`          | `SetData(InventoolSavableData inventoolSavableData)`                    | `void`                 | Applies savable data, updating items and currencies and refreshing UI.       |
| `public`          | `Clear()`                                                               | `void`                 | Clears all items and currencies.                                             |
| `public`          | `Load()`                                                                | `Task`                 | Loads storage data using the configured loader (sync or async).              |
| `public`          | `ResetCurrencies()`                                                     | `void`                 | Resets all currencies to zero for all identities.                            |
| `public`          | `Deposit(Currency amount)`                                              | `void`                 | Stores currency and removes it from the inventory.                           |
| `public`          | `Withdraw(Currency amount)`                                             | `Currency`             | Withdraws currency, adds it to the inventory, or returns default on failure. |
| `public`          | `SetCurrency(Currency value)`                                           | `void`                 | Sets a relevant currency to a specified value.                               |
| `public`          | `HasSpaceForItem(ItemStack itemStack)`                                  | `bool`                 | Checks if there is space for an item stack.                                  |
| `public`          | `HasSpaceForItem(Item item, int quantity = 1)`                          | `bool`                 | Checks if there is space for an item by type and quantity.                   |
| `public override` | `DropItem(ItemStack itemStack, int amount = 0, bool useTimeout = true)` | `void`                 | Drops an item stack, optionally spawns a world drop, and invokes callbacks.  |
| `public`          | `SetItems(params ItemStack[] itemStacks)`                               | `void`                 | Sets items (overrides previous list).                                        |
| `public`          | `SetItems(List<ItemStack> itemStacks)`                                  | `void`                 | Sets items from a list (overrides previous list).                            |
| `public`          | `CanAddToExistingStack(ItemStack itemStack)`                            | `bool`                 | Checks if the item stack can be merged into existing stacks.                 |
| `public`          | `TryAddToExistingStack(ItemStack itemStack)`                            | `bool`                 | Tries to merge into existing stacks; may empty the source stack.             |
| `public`          | `Deposit(params ItemStack[] itemStacks)`                                | `void`                 | Deposits items, removes them from inventory, and triggers events.            |
| `public`          | `Deposit(List<ItemStack> itemStacks)`                                   | `void`                 | Deposits items from a list.                                                  |
| `public`          | `Withdraw(params ItemStack[] itemStacks)`                               | `void`                 | Withdraws items (adds to inventory) and triggers events.                     |
| `public`          | `Withdraw(List<ItemStack> itemStacks)`                                  | `void`                 | Withdraws items from a list.                                                 |

***

### 🧩 Nested Types

#### `public enum StorageError`

| Name                  | Description                                               |
| --------------------- | --------------------------------------------------------- |
| `Unknown`             | An unknown error.                                         |
| `NoSpace`             | No slot space available for the item.                     |
| `AlreadyExists`       | Item already exists in the storage.                       |
| `EmptyStack`          | Attempted to add an empty item stack.                     |
| `NotEnoughCurrency`   | Attempted to withdraw more currency than available.       |
| `NonexistentCurrency` | Attempted to withdraw a currency type that doesn’t exist. |
| `Unaccepted`          | Attempted to deposit an unaccepted item.                  |

## Items

### Setting Items

You can set items with the `SetItems` method. This will remove all previous items in the inventory.

```csharp
myStorage.SetItems(myItemStackList);
```

### Depositing Items

With the `Deposit` method, you can add a single or a list of item stacks to the storage. This will remove the item(s) from the inventory.

```csharp
myStorage.Deposit(myItemStack);
```

### Remove Items

With the `Withdraw` method, you can remove a single or a list of item stacks from the storage. This will add the item(s) to the inventory.

```csharp
myStorage.Withdraw(myItemStack);
```

### Getting Items

You can get the full list of items with the `itemStacks` and `keyItems` fields.

#### Get All Items in a Specific Page

```csharp
// Get item stacks in the first page (page numbers start at 0)
var itemStacks = myStorage.GetAllItemsInPage(0);
```

#### Get All Items in the Current Page

```csharp
var itemStacks = myStorage.GetAllItemsInCurrentPage();
```

#### Checking If An Item Can Fit

You can check if an item will fit in the storage with the `HasSpaceForItem` method.

```csharp
bool result = Inventool.Inventory.HasSpaceForItem(myItem);
```

### Checking Items

You can use the `Contains` method to check and see if the player has an instance of an item in their storage. You can use an `Item` object, the item ID, or the item name to perform this check.

```csharp
// Check if the player has an item called 'Door Key'
bool result = myStorage.Contains("Door Key");
```

### Drop Items

To drop a specific item (remove it from the storage), use the `DropItem` method. This may create an instance of an [item-drop](https://stylishesper.gitbook.io/inventool/scripting/api/items/item-drop "mention") in the game world.

```csharp
myStorage.DropItem(itemStackToDrop);
```

## Currencies

You can access the full list of currencies with the `myStorage.currencies` field.

### Depositing a Currency

A currency can be deposited with the `Deposit` method.

```csharp
myStorage.Deposit(myCurrency);
```

### Withdrawing a Currency

A currency can be withdrawn from the storage with the `Withdraw` method.

```csharp
myStorage.Withdraw(myCurrency);
```

### Resetting

You can reset all currencies to their starting values with the `ResetCurrencies` method.

```csharp
myStorage.ResetCurrencies();
```

## Pages & Organization

Storage items are organized in grid-based pages. Whether your inventory 1 page or 100, the logic is the same.

### Reorganization

You can reorganize the storage with the `Reorganize` method. **This will also recreate all pages.**

```csharp
myStorage.Reorganize();
```

If you'd only like to regroup item stacks, use the `Regroup` method.

```csharp
myStorage.Regroup();
```

### Filters

Storage items can be filtered with an [item-type](https://stylishesper.gitbook.io/inventool/scripting/api/items/item-type "mention"). Items that don't match the filter will not be returned when using the `GetAllItemsInPage` or `GetAllItemsInCurrentPage` methods. If the `ItemType` is a parent, items with the parent type or any of it's child types **will not** be filtered out.

#### Set the Item Filter

```csharp
myStorage.SetItemFilter(ItemType);
```

#### Remove Item Filter

```csharp
myStorage.RemoveItemFilter();
```

### Page Sizes

#### Setting the Size

You can set the page size by editing the `minPageSize` or `pageSize` fields. When these are changed, the storage may need to be reorganized.

```csharp
// 6x6 inventory grid
myStorage.pageSize = new Vector2Int(6, 6);
myStorage.Reorganize();
```

### Pagination

#### Current Page

The current page number is stored in the `currentPage` field.

You can flip to the next page with the `NextPage` method.

```csharp
myStorage.NextPage();
```

Similarly, you can flip to the previous page with `PreviousPage` method.

```csharp
myStorage.PreviousPage();
```

Alternatively, you can set the current page (page numbers start at 0).

```csharp
myStorage.SetPage(0);
```

## Customize Accepted Items

You can customize the items accepted with the `canAcceptItem` function.

#### Example

```csharp
myStorage.canAcceptItem = itemStack =>
{
    if (itemStack.item.itemType.displayName == "My Item Type")
    {
        return true;
    }

    return false;
};
```
