Skip to content

Repository files navigation

TheChest.Inventories

NuGet Version Coverage

TheChest.Inventories is a library for managing inventories and slots in generic item collections. It provides a flexible and extensible framework for inventory systems, with support for stackable items, event-driven operations, and lazy-loaded inventory management.

Table of Contents

Key Features

  • Generic inventory support: Works with any generic item type for maximum flexibility
  • Slot-based system: Stores items in single-item or stackable slots
  • Three inventory types:
    • Standard Inventory<T> for single-item slots
    • StackInventory<T> for stackable items
    • LazyStackInventory<T> for lazy-loaded stackable items
  • Event system: Comprehensive events for add, remove, move, and replace operations
  • Extensible interfaces: Enable custom inventory implementations
  • Core operations: Add, remove, move, and retrieve items with flexible APIs
  • Validation: Built-in methods to check operations before execution

Project Structure

  • Inventory<T>

    • Generic inventory implementation using single-item slots
    • Uses InventorySlot<T> to represent each slot
    • Best for: Game inventories with single-item slots, fixed-size collections
    • Learn more
  • StackInventory<T>

    • Generic inventory for stackable items
    • Uses InventoryStackSlot<T> to represent slots holding multiple units of the same item
    • Best for: Resource management, currency systems, consumable items
    • Learn more
  • LazyStackInventory<T>

    • Stackable inventory with lazy item loading
    • Uses InventoryLazyStackSlot<T> to represent slots that can return items on demand
    • Best for: Large collections, on-demand item generation, performance optimization
    • Learn more

Installation

Via NuGet

Add the NuGet package source:

nuget source add -n TheChest https://nuget.pkg.github.com/The-Chest/index.json

Install the package:

nuget install TheChest.Inventories

Via DLL

You can also download the DLL directly and reference it in your project.

Quick Start

using TheChest.Inventories.Containers;
using TheChest.Inventories.Slots.Interfaces;

// Create slots
var slots = new IInventorySlot<string>[10];
for (int i = 0; i < slots.Length; i++)
{
    slots[i] = new InventorySlot<string>();
}

// Create inventory
var inventory = new Inventory<string>(slots);

// Add an item
if (inventory.CanAdd("Item1"))
{
    inventory.Add("Item1");
}

Architecture

Class Diagrams

Event System

Detailed documentation on the event system for each inventory type:

Usage Example

A basic inventory for items that occupy one slot each:

using TheChest.Inventories.Containers;
using TheChest.Inventories.Slots.Interfaces;

// Initialize slots
var slots = new IInventorySlot<string>[10];
for (int i = 0; i < slots.Length; i++)
{
    slots[i] = new InventorySlot<string>();
}

// Create inventory
var inventory = new Inventory<string>(slots);

// Add items
inventory.Add("Sword");
inventory.Add("Shield");

// Retrieve items
var item = inventory.Get(0);

// Check inventory
int count = inventory.Count("Sword");

Working with Events

Listen to inventory changes through events:

using TheChest.Inventories.Containers;
using TheChest.Inventories.Slots.Interfaces;

var slots = new IInventorySlot<string>[10];
for (int i = 0; i < slots.Length; i++)
{
    slots[i] = new InventorySlot<string>();
}

var inventory = new Inventory<string>(slots);

// Subscribe to add events
inventory.OnAdd += (sender, args) =>
{
    foreach (var action in args.Data)
    {
        Console.WriteLine($"Item {action.Item} added to slot {action.Index}");
    }
};

// Subscribe to get events
inventory.OnGet += (sender, args) =>
{
    foreach (var action in args.Data)
    {
        Console.WriteLine($"Item {action.Item} retrieved from slot {action.Index}");
    }
};

// Subscribe to move events
inventory.OnMove += (sender, args) =>
{
    Console.WriteLine($"Item moved from {args.Data.Origin} to {args.Data.Target}");
};

// Subscribe to replace events
inventory.OnReplace += (sender, args) =>
{
    Console.WriteLine($"Item replaced at slot {args.Data.Index}");
};

// Operations will now trigger events
inventory.Add("Sword");
var item = inventory.Get(0);

Error Handling

Always validate operations before executing:

using TheChest.Inventories.Containers;
using TheChest.Inventories.Slots.Interfaces;

var slots = new IInventorySlot<string>[10];
for (int i = 0; i < slots.Length; i++)
{
    slots[i] = new InventorySlot<string>();
}

var inventory = new Inventory<string>(slots);

// Check if we can add before adding
if (inventory.CanAdd("Item"))
{
    inventory.Add("Item");
}
else
{
    Console.WriteLine("Inventory is full!");
}

// Check if we can move before moving
if (inventory.CanMove(0, 5))
{
    inventory.Move(0, 5);
}
else
{
    Console.WriteLine("Cannot move item to that slot");
}

// Use Try methods for safer operations
if (inventory.TryReplace("NewItem", 0, out var oldItem))
{
    Console.WriteLine($"Replaced {oldItem} with NewItem");
}
else
{
    Console.WriteLine("Failed to replace item");
}

Features

Event Patterns

All inventory types support a comprehensive event system:

  • OnGet - Fires when items are retrieved
  • OnAdd - Fires when items are added
  • OnMove - Fires when items are moved between slots
  • OnReplace - Fires when items are replaced

See Inventory Events for detailed examples.

Stacking and Capacity

Different inventory types handle stacking differently:

  • Inventory: One item per slot
  • StackInventory: Multiple items per slot with a defined max stack
  • LazyStackInventory: Multiple items per slot, loaded on demand

Performance Considerations

  • Use Inventory<T> for simple, single-item slot scenarios
  • Use StackInventory<T> for smaller collections with stackable items
  • Use LazyStackInventory<T> when working with large collections that don't need to be fully loaded
  • Always use CanX methods to validate operations before executing them
  • Subscribe to events selectively to avoid performance overhead

Extension and Customization

Extending Built-in Classes

You can extend the built-in inventory classes to add custom functionality:

Implementing Custom Inventories

Create fully custom implementations by implementing the interfaces:

Additional Resources

Future Plans

Future version plans are available on the GitHub Project Board.

Releases

Packages

Used by

Contributors

Languages