# Custom Elevator Effects

Elevators includes an Effect Elevator Action that can trigger visual effects whenever an elevator is used. You can extend this system by implementing your own custom effects, allowing for unique and immersive visual experiences on your server.

For more details on how these effects fit into the Effect Action, visit the Effect Action Documentation.


# Getting Started

To create a new custom visual effect, extend the ElevatorEffect class:

public class CustomEffect extends ElevatorEffect {

    public CustomEffect() {
        super("CUSTOM", yourEffectItemStack);
    }

    @Override
    public void playEffect(ElevatorEventData teleportResult, Elevator elevator) {
        // Your custom effect logic here
    }
}
  • Effect Key: The first argument in super("CUSTOM", ...) is a unique key to identify your effect.
  • Effect Icon: The second argument is an ItemStack that represents your effect in the GUI.

# Core Method: playEffect

The heart of any custom effect is the playEffect method:

@Override
public void playEffect(ElevatorEventData teleportResult, Elevator elevator) {
    // This is where your effect logic goes.
    // Use elevator location, player data, etc. to spawn particles, sounds, or more.
}

You can access helpful data:

Info Method Usage
teleportResult.getDirection() Returns 1 for up, -1 for down.
teleportResult.getOrigin() Returns the Elevator object that the player teleported from.
teleportResult.getDestination() Returns the Elevator object that the player teleported to.
teleportResult.getStandOnAddition() Returns the additional distance added on to the Destination Elevator Location Y to support obstruction such as slabs.
elevator.getLocation() Returns the current elevator location.
elevator.getElevatorType() Returns the type object of the Elevator.
elevator.getDyeColor() Returns the DyeColor of the Elevator.

# Customization Tips

  • Particle Colors: Use this.getParticleColor(elevator) to get the Color that matches the ShulkerBox color.
  • Scheduling: Use Elevators.getFoliaLib() for safe task scheduling across threads.
  • ElevatorEventData: Leverage the ElevatorEventData argument to create dynamic effects based on direction, player, and destination.

# Registering Your Custom Effect

Once you have defined your custom effect class, you must register it with the plugin’s effect system:

ElevatorEffectService.registerVisualEffect(new CustomEffect());

This tells the plugin to include your custom effect in the Effect Action and GUI.


# Example: Arrow Effect

Here’s a full example of a custom effect called ArrowEffect, which spawns arrow-shaped particle paths:

public class ArrowEffect extends ElevatorEffect {

    public ArrowEffect() {
        super("ARROW", ItemStackHelper.createItem("Arrow", Material.TIPPED_ARROW, 1));
    }

    @Override
    public void playEffect(ElevatorEventData teleportResult, Elevator elevator) {
        byte direction = teleportResult.getDirection();
        Color particleColor = this.getParticleColor(elevator);

        Location locClone = getEffectLocation(elevator).getBlock().getLocation();
        locClone.add(0.5, direction == 1 ? 1 : 3, 0.5);

        List<Location> spawnPositions = new ArrayList<>();

        for(int i = 0; i < 20; i++)
            spawnPositions.add(locClone.add(0, direction * 0.1, 0).clone());

        for(int i = 5; i >= 0; i--) {
            for(int z = 0; z < 2; z++) {
                Location clone = locClone.clone();
                double y = direction == 1 ? -i * 0.1 : i * 0.1;

                if(z == 0) {
                    clone.add(-i * 0.1, y, 0);
                    spawnPositions.add(clone.clone());
                    clone.add(i * 0.2, 0, 0);
                } else {
                    clone.add(0, y, -i * 0.1);
                    spawnPositions.add(clone.clone());
                    clone.add(0, 0, i * 0.2);
                }
                spawnPositions.add(clone.clone());
            }
        }

        for(int i = 0; i < 10; i++) {
            Elevators.getFoliaLib().getScheduler().runAtLocationLater(elevator.getLocation(), task -> {
                for(Location location1 : spawnPositions)
                    Objects.requireNonNull(location1.getWorld())
                        .spawnParticle(Particle.REDSTONE, location1, 1, 0, 0, 0, 1,
                            new Particle.DustOptions(particleColor, 1));
            }, i * 2);
        }
    }
}

# Summary

  • Extend ElevatorEffect
  • Define your unique key & effect icon
  • Override playEffect with your custom logic
  • Register your new effect with the plugin

🧪 Want to contribute more effects? Feel free to fork the plugin and submit PRs via GitHub!