# Custom Elevator Actions

The **ElevatorAction Builder API** allows developers to define custom elevator behavior that is triggered when an elevator is used. You can define actions, variables, icons, click logic, and execution behavior in a modular and extensible way.

---

## Getting Started

To begin creating a custom ElevatorAction, use:

```java
ElevatorAction.builder("your-action-key")
```

This initializes the builder with a unique `actionKey` that will identify your action.
The best time to register an ElevatorAction is whenever `ElevatorRegisterActionsEvent` is called on the Elevator Plugin startup.

---

## Builder Methods

The builder provides additional lifecycle hooks:

| Method                 | Description                                                             
|------------------------|-------------------------------------------------------------------------
| `.onExecute()`         | Called when the action is invoked (e.g., during elevator use)       
| `.onCheckConditions()` | Called when the action is invoked (e.g., during elevator use). Determines if player can use the elevator.
| `.addVariable()`       | Allows for the addition of variables to the action           
| `.onInit()`            | Optional setup logic when the action is registered                      
| `.register()`          | Finalizes and registers the action. The first argument should be an instance of your plugin. The remaining can take either an `ItemStack` or `ChatColor, DisplayName, Material` to define the GUI icon 

---

### Handling Execution

Use `.onExecute(executeContext -> { ... })` to define what will happen when the action occurs. Within the lambda, you will deal a `ElevatorActionExecuteContext` object.

### Handling ConditionCheck

Use `.onCheckConditions(executeContext -> { boolean })` to define whether a player is allowed to use an elevator. Within the lambda, you will deal a `ElevatorActionExecuteContext` object.

#### ElevatorActionExecuteContext

The execution context has four methods that will help you develop your action:

| Method            | Description                                                             
|-------------------|-------------------------------------------------------------------------
| `.getVariable()`  | Returns the value of the variable with the provided alias           
| `.getAction()`    | Returns the ElevatorAction object that this builder creates
| `.getPlayer()`    | Returns the player who has executed the action                    
| `.getEventData()` | EventData contains the Origin elevator, Destination elevator, and Direction

---

### Defining Variables

Use `.addVariable(defaultValue, variable -> { ... })` to define parameters your action needs. Within the lambda, you will configure a `ElevatorActionVariableBuilder` object.

#### Required Fields

Each variable must define the following:

- **Alias** – One or more strings the action string can use (e.g., `amount`, `amnt`)
- **Conversion** – A method that converts a `String` to your intended data type
- **Icon Type** – A `Material` representing the icon in GUI
- **Display Name** – The visible name for the icon
- **Setting Name** – Used to associate this variable with settings. Will default to the first provided alias if not explicitly set.

```java
variable.setAlias("amount", "amnt", "a");
variable.setConversion(Integer::valueOf);
variable.setIconType(Material.EXPERIENCE_BOTTLE);
variable.setDisplayName("Give Experience");
variable.setSettingName("amount");
```

#### Optional Enhancements

- `setIconDescription(String)` – Adds a description to the GUI item
- `addAction(String clickType, String actionDescription)` – Adds lore-style hover actions
- `onClick(Consumer<ElevatorActionExecuteContext>)` – Handles icon click events
- `allowPerEleCustomization()` – Enables the variable to appear in the per-elevator settings menu

#### Handling Variable Setting Click

Use `.onClick(clickContext -> { ... })` to define what will happen when the variable setting icon is clicked. Within the lambda, you will deal a `ElevatorSettingClickContext` object.

#### ElevatorSettingClickContext

The click context has five methods that will help you develop your action:

| Method               | Description                                                             
|----------------------|-------------------------------------------------------------------------
| `.setValue()`        | Sets the value of the variable
| `.close()`           | Will reopen the menu that had invoked this setting click
| `.getCurrentValue()` | Returns the current value of the variable
| `.getClickEvent()`   | Returns the InventoryClickEvent that had invoked this setting click
| `.getPlayer()`       | Returns the Player who had invoked this setting click

---

## Example: Give Experience Action

```java
ElevatorAction.builder("give-exp")
	.addVariable(1, variable -> {
		variable.setAlias("amount","amnt","a");
		variable.setConversion(Integer::valueOf);
		variable.setIconDescription("This option controls the amount of exp given to the player");
		variable.setIconType(Material.EXPERIENCE_BOTTLE);
		variable.setDisplayName("Give Experience");
		variable.setSettingName("amount");
		variable.addAction("Left Click", "Increase Amount");
		variable.addAction("Right Click", "Decrease Amount");
		variable.addAction("Shift Click", "Reset Amount");
		variable.onClick(data -> {
			if(data.getClickEvent().isShiftClick()) {
				data.setValue(1);
				data.close();
				return;
			}

			int newValue = data.getCurrentValue() + (data.getClickEvent().isLeftClick() ? 1 : -1);
			newValue = Math.min(Math.max(newValue, -1), 500);
			data.setValue(newValue);
			data.close();
		});
	})
	.addVariable(true, variable -> {
		variable.setAlias("mending", "mend", "m");
		variable.setConversion(Boolean::parseBoolean);
		variable.setIconDescription("This option controls whether the given exp can be used to mend gear");
		variable.setIconType(Material.STONE_PICKAXE);
		variable.setDisplayName("Allow Mending");
		variable.setSettingName("mending");
		variable.addAction("Left Click", "Toggle Mending");
		variable.onClick(data -> {
			data.setValue(!data.getCurrentValue());
			data.close();
		});
	})
	.onExecute(data -> {
		data.getPlayer().giveExp(data.getVariable("amount"), data.getVariable("mending"));
	})
	.register(myPlugin, ChatColor.GOLD.toString(), "Give Experience", Material.EXPERIENCE_BOTTLE);
```

> 🧪 Want to contribute more hooks? Feel free to fork the plugin and submit PRs via [GitHub](https://github.com/keehl254/Elevators)!

---

## See Also

- [Elevator Actions](/elevatoractions/)
- [Per-Elevator Customization](/customization/)
