Make BlockHandler more flexible and future-proof for incoming amber language features

This commit is contained in:
TheMode 2021-06-17 14:34:55 +02:00
parent de22a76e9f
commit 894b1a68a7
3 changed files with 155 additions and 19 deletions

View File

@ -615,7 +615,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
// checks that we are actually in the block, and not just here because of a rounding error
if (boundingBox.intersect(tmpPosition)) {
// TODO: replace with check with custom block bounding box
handler.handleContact(instance, tmpPosition, this);
handler.handleContact(BlockHandler.Touch.from(block, instance, tmpPosition, this));
}
}
}

View File

@ -148,8 +148,8 @@ public class InstanceContainer extends Instance {
}
setAlreadyChanged(blockPosition, block);
final BlockHandler previousHandler = chunk.getBlock(blockPosition)
.getHandler();
final Block previousBlock = chunk.getBlock(blockPosition);
final BlockHandler previousHandler = previousBlock.getHandler();
// Change id based on neighbors
block = executeBlockPlacementRule(block, blockPosition);
@ -165,12 +165,12 @@ public class InstanceContainer extends Instance {
if (previousHandler != null) {
// Previous destroy
previousHandler.onDestroy(this, blockPosition);
previousHandler.onDestroy(BlockHandler.Destroy.from(previousBlock, this, blockPosition));
}
final BlockHandler handler = block.getHandler();
if (handler != null) {
// New placement
handler.onPlace(this, blockPosition);
handler.onPlace(BlockHandler.Placement.from(block, this, blockPosition));
}
}
}

View File

@ -6,6 +6,7 @@ import net.minestom.server.instance.Instance;
import net.minestom.server.tag.Tag;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@ -21,42 +22,36 @@ public interface BlockHandler {
/**
* Called when a block has been placed.
*
* @param instance the instance of the block
* @param blockPosition the position of the block
* @param placement the placement details
*/
default void onPlace(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
default void onPlace(@NotNull Placement placement) {
}
/**
* Called when a block has been destroyed or replaced.
*
* @param instance the instance of the block
* @param blockPosition the position of the block
* @param destroy the destroy details
*/
default void onDestroy(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
default void onDestroy(@NotNull Destroy destroy) {
}
/**
* Handles interactions with this block. Can also block normal item use (containers should block when opening the
* menu, this prevents the player from placing a block when opening it for instance).
*
* @param player the player interacting
* @param hand the hand used to interact
* @param blockPosition the position of this block
* @param interaction the interaction details
* @return true if this block blocks normal item use, false otherwise
*/
default boolean onInteract(@NotNull Player player, @NotNull Player.Hand hand, @NotNull BlockPosition blockPosition) {
default boolean onInteract(@NotNull Interaction interaction) {
return false;
}
/**
* Defines custom behaviour for entities touching this block.
*
* @param instance the instance
* @param position the position at which the block is
* @param touching the entity currently touching the block
* @param touch the contact details
*/
default void handleContact(@NotNull Instance instance, @NotNull BlockPosition position, @NotNull Entity touching) {
default void handleContact(@NotNull Touch touch) {
}
default @NotNull Collection<Tag<?>> getBlockEntityTags() {
@ -75,4 +70,145 @@ public interface BlockHandler {
* @return the namespace id of this handler
*/
@NotNull NamespaceID getNamespaceId();
/**
* Represents an object forwarded to {@link #onPlace(Placement)}.
* <p>
* Will in the future rely on sealed classes (https://openjdk.java.net/jeps/409)
* and record pattern for the implementations (https://openjdk.java.net/jeps/405).
*/
@ApiStatus.NonExtendable
interface Placement {
@NotNull Block block();
@NotNull Instance instance();
@NotNull BlockPosition blockPosition();
static @NotNull Placement from(@NotNull Block block, @NotNull Instance instance, @NotNull BlockPosition blockPosition) {
return new Placement() {
@Override
public @NotNull Block block() {
return block;
}
@Override
public @NotNull Instance instance() {
return instance;
}
@Override
public @NotNull BlockPosition blockPosition() {
return blockPosition;
}
};
}
}
@ApiStatus.NonExtendable
interface Destroy {
@NotNull Block block();
@NotNull Instance instance();
@NotNull BlockPosition blockPosition();
static @NotNull Destroy from(@NotNull Block block, @NotNull Instance instance, @NotNull BlockPosition blockPosition) {
return new Destroy() {
@Override
public @NotNull Block block() {
return block;
}
@Override
public @NotNull Instance instance() {
return instance;
}
@Override
public @NotNull BlockPosition blockPosition() {
return blockPosition;
}
};
}
}
@ApiStatus.NonExtendable
interface Interaction {
@NotNull Block block();
@NotNull Instance instance();
@NotNull BlockPosition blockPosition();
@NotNull Player player();
@NotNull Player.Hand hand();
static @NotNull Interaction from(@NotNull Block block, @NotNull Instance instance, @NotNull BlockPosition blockPosition,
@NotNull Player player, @NotNull Player.Hand hand) {
return new Interaction() {
@Override
public @NotNull Block block() {
return block;
}
@Override
public @NotNull Instance instance() {
return instance;
}
@Override
public @NotNull BlockPosition blockPosition() {
return blockPosition;
}
@Override
public @NotNull Player player() {
return player;
}
@Override
public @NotNull Player.Hand hand() {
return hand;
}
};
}
}
@ApiStatus.NonExtendable
interface Touch {
@NotNull Block block();
@NotNull Instance instance();
@NotNull BlockPosition blockPosition();
@NotNull Entity touching();
static @NotNull Touch from(@NotNull Block block, @NotNull Instance instance, @NotNull BlockPosition blockPosition,
@NotNull Entity touching) {
return new Touch() {
@Override
public @NotNull Block block() {
return block;
}
@Override
public @NotNull Instance instance() {
return instance;
}
@Override
public @NotNull BlockPosition blockPosition() {
return blockPosition;
}
@Override
public @NotNull Entity touching() {
return touching;
}
};
}
}
}