java.lang.Object
nl.pim16aap2.animatedarchitecture.core.tooluser.ToolUser
Direct Known Subclasses:
Creator, PowerBlockInspector, PowerBlockRelocator

public abstract class ToolUser extends Object
This class is responsible for guiding the player through a process using the tool. This process is defined by a Procedure that is populated with Steps.

The procedure can be used to guide the player through the process of creating a structure, or any other process that uses any kind of input.

The main way to interact with this class is the handleInput(Object) method. This method takes the provided input and applies it to the current step in the procedure. The expected input type and behavior depend on the currently-active step.

The handleInput(Object) method is thread-safe and will handle input in a synchronized manner. This means that only one input can be processed at a time. If multiple inputs are provided, they will be processed in the order they were received. The lock is not thread-specific, so subclasses should be careful around threading issues. If a subclass needs to perform multiple operations that require the lock, it should use the runWithLock(Supplier) method.

  • Field Details

  • Constructor Details

    • ToolUser

      protected ToolUser(ToolUser.Context context, IPlayer player)
      Creates a new ToolUser for the given player.

      Do not forget to call init() after creating the object. Preferably, this should be done in the constructor.

      Parameters:
      context - The context to use.
      player - The player to create the ToolUser for.
  • Method Details

    • init

      protected void init()
      Basic initialization executed that should be called after the constructor.

      This method will initialize the Procedure using the steps generated by generateSteps() and register this ToolUser with the ToolUserManager.

      If this method is not called, the ToolUser will be considered uninitialized and any method that requires the procedure (e.g. handling input) will throw an exception.

      If this method is called more than once, an exception will be thrown.

      Throws:
      IllegalStateException - If this method is called more than once.
      RuntimeException - If the procedure could not be instantiated.
    • generateSteps

      protected abstract List<Step> generateSteps() throws InstantiationException
      Generates the list of Steps that together will make up the procedure.
      Returns:
      The list of Steps that together will make up the procedure.
      Throws:
      InstantiationException - When a step's factory is incomplete or otherwise invalid.
    • cleanUpProcess

      protected final void cleanUpProcess()
      Takes care of the final part of the process. This unregisters this ToolUser and removes the tool from the player's inventory (if they still have it).
    • abort

      public void abort()
      Aborts the process this ToolUser is currently in.

      By default, this method only calls cleanUpProcess(). Subclasses can override this method to add additional behavior.

    • giveTool

      protected final void giveTool(String nameKey, String loreKey, @Nullable @Nullable Text text)
      Adds the AnimatedArchitecture tool from the player's inventory.
      Parameters:
      nameKey - The localization key of the name of the tool.
      loreKey - The localization key of the lore of the tool.
      text - The message to send to the player after giving them the tool.
    • removeTool

      protected final void removeTool()
      Removes the AnimatedArchitecture tool from the player's inventory.
    • getCurrentStepMessage

      public Text getCurrentStepMessage()
      Gets the message for the current step.
      Returns:
      The message of the current step if possible. Otherwise, an empty String is returned.
    • prepareCurrentStep

      @CheckReturnValue protected CompletableFuture<Boolean> prepareCurrentStep()
      Prepares the next step. For example by sending the player some instructions about what they should do.

      This should be used after proceeding to the next step.

      Returns:
      A CompletableFuture that will be completed when the current step is prepared.

      If the step does not wait for user input, the returned future will be the result of handleInputWithLock(Object). Otherwise, it will be completed with true.

      Throws:
      IllegalStateException - If the lock is not held. See acquireInputLock().
    • skipToStep

      protected CompletableFuture<Boolean> skipToStep(Step goalStep)
      See Procedure.skipToStep(Step).

      After successfully skipping to the target step, the newly-selected step will be prepared. See prepareCurrentStep().

      Parameters:
      goalStep - The step to skip to.
      Returns:
      A CompletableFuture that will be completed an exception if the step could not be found, or the result of prepareCurrentStep() otherwise.
      Throws:
      IllegalStateException - If the lock is not held. See acquireInputLock().
    • handleInputWithLock

      @CheckReturnValue protected final CompletableFuture<Boolean> handleInputWithLock(@Nullable @Nullable Object obj)
      Handles user input for the given step.

      This method assumes that the input lock is already held. If the caller does not hold the lock, they should use either handleInput(Object) or runWithLock(Supplier).

      This method is intended for use by subclasses or step executors that need to provide input as part of their operation and therefore already hold the lock.

      Parameters:
      obj - The input to handle. What actual type is expected depends on the step.
      Returns:
      A completable future that will either complete with true if the step was completed successfully, or false if it was not.
      Throws:
      IllegalStateException - If the lock is not held.
    • handleInput

      public final CompletableFuture<Boolean> handleInput(@Nullable @Nullable Object obj)
      Handles some kind of input for the given step.
      Parameters:
      obj - The input to handle. What actual type is expected depends on the step.
      Returns:
      True if the input was processed successfully.
    • runWithLock

      protected final <T> CompletableFuture<T> runWithLock(Supplier<CompletableFuture<T>> supplier)
      Runs the provided supplier while holding the input lock.

      This method will acquire the input lock, run the supplier, and then release the input lock.

      If the supplier throws an exception, the lock will still be released.

      Type Parameters:
      T - The type of the result of the supplier.
      Parameters:
      supplier - The supplier to run.
      Returns:
      The result of the supplier.
    • sendMessage

      protected void sendMessage(@Nullable @Nullable Step step)
      Sends the localized message of the given step to the player that owns this object.
      Parameters:
      step - The step to send the message for.
    • sendMessage

      protected void sendMessage()
      Sends the localized message of the current step to the player that owns this object.
    • getCurrentStep

      public final Optional<Step> getCurrentStep()
      Gets the Step in the procedure this ToolUser is currently at.
      Returns:
      The current Step in the procedure.
    • playerHasAccessToLocation

      public CompletableFuture<Boolean> playerHasAccessToLocation(ILocation loc)
      Checks if a player is allowed to break the block in a given location.

      If the player is not allowed to break blocks in the location, a message will be sent to them (provided the name of the compat isn't empty).

      Parameters:
      loc - The location to check.
      Returns:
      True if the player is allowed to break the block at the given location.
    • playerHasAccessToCuboid

      public CompletableFuture<Optional<Cuboid>> playerHasAccessToCuboid(Cuboid cuboid, IWorld world)
      Checks if a player is allowed to break all blocks in a given cuboid.

      If the player is not allowed to break one or more blocks in the cuboid, a message will be sent to them. (provided the name of the compat isn't empty).

      Parameters:
      cuboid - The cuboid to check.
      world - The world to check in.
      Returns:
      The cuboid if the player is allowed to break all blocks in it, or an empty Optional otherwise.
    • isActive

      public final boolean isActive()
      Keeps track of whether this ToolUser is active or not.
      Returns:
      true if this tool user is active.
    • setPlayerHasTool

      protected final boolean setPlayerHasTool(boolean playerHasTool)
      Sets the playerHasTool field.
      Parameters:
      playerHasTool - The new value.
      Returns:
      The old value.
    • playerHasTool

      public final boolean playerHasTool()
      Accessor for playerHasTool.
      Returns:
      The value of playerHasTool.
    • getAllSteps

      protected final List<Step> getAllSteps()
      Returns:
      All the steps in the procedure including any that may have been completed/skipped already.
    • goToNextStep

      protected final void goToNextStep()
      Proceeds to the next step in the procedure.

      This method assumes that the lock is held. See acquireInputLock().

      This method is a wrapper around Procedure.goToNextStep().

      Throws:
      IllegalStateException - If the lock is not held. See acquireInputLock().
    • insertStep

      protected final void insertStep(String name)
      Inserts an existing, named step at the current position.

      This method assumes that the lock is held. See acquireInputLock().

      This method is a wrapper around Procedure.insertStep(String).

      Parameters:
      name - The name of the step to insert.
      Throws:
      NoSuchElementException - If no step can be found by that name.
      IllegalStateException - If the lock is not held. See acquireInputLock().
    • assertLockHeld

      protected final void assertLockHeld()
      Ensures that the input lock is held.
      Throws:
      IllegalStateException - If the lock is not held.
    • toMinimalString

      public String toMinimalString()
      Returns a minimal string representation of this object.

      This method is intended for logging purposes, as the full string representation may be too verbose.

      Returns:
      A minimal string representation of this object.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • getPlayer

      public IPlayer getPlayer()