hcu-items/docs/creating_new_content.md

4.3 KiB

Content Creation Guide

This project provides a framework for adding new items and features (components) using the HcuItems plugin.

Event handling is uniformly managed by the EventListener, which delegates to appropriate classes based on information in the item's PersistentDataContainer (PDC).

Architecture Overview

All events (right-click, damage, movement, etc.) are received by the EventListener.

The EventListener delegates processing through the following steps:

  1. Retrieves the item involved in the event.
  2. Checks the item's PDC.
    • If an AbstractItem ID (hcu_items:id) exists → Retrieves the item definition from ItemRegistry and executes.
    • If a component key (hcu_items:component_id) exists → Retrieves the component definition from ComponentRegistry and executes.

1. Creating an AbstractItem (Custom Item)

Use this when creating an item with completely unique behavior.

Steps

  1. Create a new class that inherits from the AbstractItem class.
  2. Specify a unique ID in the constructor.
  3. Implement the buildItem method to define the item's appearance (Material, Name, Lore, etc.).
  4. Override necessary event handlers (onInteract, onPlayerMove, etc.).
  5. Register by calling ItemRegistry.register(YourItem()) in App.kt's onEnable.
class MyCustomItem : AbstractItem("my_custom_item") {
    override fun buildItem(tier: Tier): ItemStack {
        return ItemStack(Material.DIAMOND_SWORD).apply {
            // Meta configuration
        }
    }

    override fun onInteract(event: PlayerInteractEvent) {
        event.player.sendMessage("Used custom item!")
    }
}

2. Creating a CustomComponent (Adding Features to Existing Items)

Use this when adding common features (e.g., glider, passive effects) to existing items or items that meet specific conditions.

Steps

  1. Create a class that inherits from AbstractComponent and implements CustomComponent (or EquippableComponent).
  2. Specify a unique component ID in the constructor.
  3. Implement the apply method with logic to apply the component to the item (key registration to PDC is automatic, but describe if additional metadata is needed).
  4. Override necessary event handlers.
  5. Register by calling ComponentRegistry.register(YourComponent(this)) in App.kt's onEnable.
class MyComponent(plugin: App) : AbstractComponent(plugin, "my_component") {
    override fun onInteract(event: PlayerInteractEvent) {
        event.player.sendMessage("Component interaction!")
    }
}

Event Mechanism

AbstractComponent generates a NamespacedKey during initialization and writes this key to the item's PDC during apply.

When the EventListener confirms this key exists in the item's PDC, it calls your component's event handler.

Notes

  • AbstractItem and CustomComponent can coexist. A single item can be an AbstractItem and have multiple CustomComponents.
  • Within event handlers, appropriately control event.isCancelled as needed.

3. Configuration Management

The project uses a centralized Config object to manage configuration values from config.yml. This allows for easy adjustment of values (like cooldowns) without code changes.

Accessing Configuration

To access configuration values, simply access the public properties of the Config object:

import net.hareworks.hcu.items.config.Config

// Example usage
val cooldown = Cooldown(Config.blinkCooldown)

Adding New Config Values

  1. Add Property to Config Object: Add a new property to net.hareworks.hcu.items.config.Config.kt.
  2. Update Load Method: Read the value from plugin.config in the load method.
  3. Update Defaults: Add the default value in the saveDefaults method.
object Config {
    // 1. Add Property
    var newFeatureEnabled: Boolean = true

    fun load(plugin: JavaPlugin) {
        // ... existing code ...
        
        // 2. Load Value
        newFeatureEnabled = config.getBoolean("components.new_feature.enabled", true)
        
        // ... existing code ...
    }

    private fun saveDefaults(plugin: JavaPlugin, config: FileConfiguration) {
        // ... existing code ...
        
        // 3. Set Default
        config.addDefault("components.new_feature.enabled", true)
        
        // ... existing code ...
    }
}