mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 16:37:38 +01:00
Block event changes (#1675)
* Add cursor position to interact events * Add block face to digging events * Expose interact position in interact event
This commit is contained in:
parent
8eb089bf3e
commit
c995f9c3a9
@ -6,6 +6,7 @@ import net.minestom.server.event.trait.BlockEvent;
|
||||
import net.minestom.server.event.trait.CancellableEvent;
|
||||
import net.minestom.server.event.trait.PlayerInstanceEvent;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PlayerBlockBreakEvent implements PlayerInstanceEvent, BlockEvent, CancellableEvent {
|
||||
@ -14,16 +15,19 @@ public class PlayerBlockBreakEvent implements PlayerInstanceEvent, BlockEvent, C
|
||||
private final Block block;
|
||||
private Block resultBlock;
|
||||
private final Point blockPosition;
|
||||
private final BlockFace blockFace;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerBlockBreakEvent(@NotNull Player player,
|
||||
@NotNull Block block, @NotNull Block resultBlock, @NotNull Point blockPosition) {
|
||||
@NotNull Block block, @NotNull Block resultBlock, @NotNull Point blockPosition,
|
||||
@NotNull BlockFace blockFace) {
|
||||
this.player = player;
|
||||
|
||||
this.block = block;
|
||||
this.resultBlock = resultBlock;
|
||||
this.blockPosition = blockPosition;
|
||||
this.blockFace = blockFace;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,6 +49,15 @@ public class PlayerBlockBreakEvent implements PlayerInstanceEvent, BlockEvent, C
|
||||
return resultBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the face at which the block was broken
|
||||
*
|
||||
* @return the block face
|
||||
*/
|
||||
public @NotNull BlockFace getBlockFace() {
|
||||
return blockFace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the result of the event.
|
||||
*
|
||||
|
@ -30,7 +30,7 @@ public class PlayerBlockInteractEvent implements PlayerInstanceEvent, BlockEvent
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerBlockInteractEvent(@NotNull Player player, @NotNull Player.Hand hand,
|
||||
@NotNull Block block, @NotNull Point blockPosition,
|
||||
@NotNull Block block, @NotNull Point blockPosition, @NotNull Point cursorPosition,
|
||||
@NotNull BlockFace blockFace) {
|
||||
this.player = player;
|
||||
this.hand = hand;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.trait.PlayerInstanceEvent;
|
||||
@ -13,11 +14,19 @@ public class PlayerEntityInteractEvent implements PlayerInstanceEvent {
|
||||
private final Player player;
|
||||
private final Entity entityTarget;
|
||||
private final Player.Hand hand;
|
||||
private final Point interactPosition;
|
||||
|
||||
public PlayerEntityInteractEvent(@NotNull Player player, @NotNull Entity entityTarget, @NotNull Player.Hand hand) {
|
||||
public PlayerEntityInteractEvent(@NotNull Player player, @NotNull Entity entityTarget, @NotNull Player.Hand hand,
|
||||
@NotNull Point interactPosition) {
|
||||
this.player = player;
|
||||
this.entityTarget = entityTarget;
|
||||
this.hand = hand;
|
||||
this.interactPosition = interactPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,8 +49,14 @@ public class PlayerEntityInteractEvent implements PlayerInstanceEvent {
|
||||
return hand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Player getPlayer() {
|
||||
return player;
|
||||
/**
|
||||
* Gets the position at which the entity was interacted
|
||||
*
|
||||
* @see net.minestom.server.network.packet.client.play.ClientInteractEntityPacket.InteractAt
|
||||
* @return the interaction position
|
||||
*/
|
||||
@NotNull
|
||||
public Point getInteractPosition() {
|
||||
return interactPosition;
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import net.minestom.server.event.trait.BlockEvent;
|
||||
import net.minestom.server.event.trait.CancellableEvent;
|
||||
import net.minestom.server.event.trait.PlayerInstanceEvent;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -21,13 +22,16 @@ public class PlayerStartDiggingEvent implements PlayerInstanceEvent, BlockEvent,
|
||||
private final Player player;
|
||||
private final Block block;
|
||||
private final Point blockPosition;
|
||||
private final BlockFace blockFace;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerStartDiggingEvent(@NotNull Player player, @NotNull Block block, @NotNull Point blockPosition) {
|
||||
public PlayerStartDiggingEvent(@NotNull Player player, @NotNull Block block, @NotNull Point blockPosition,
|
||||
@NotNull BlockFace blockFace) {
|
||||
this.player = player;
|
||||
this.block = block;
|
||||
this.blockPosition = blockPosition;
|
||||
this.blockFace = blockFace;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,6 +53,15 @@ public class PlayerStartDiggingEvent implements PlayerInstanceEvent, BlockEvent,
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the face you are digging
|
||||
*
|
||||
* @return the block face
|
||||
*/
|
||||
public @NotNull BlockFace getBlockFace() {
|
||||
return blockFace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
|
@ -21,7 +21,8 @@ public class PlayerUseItemOnBlockEvent implements PlayerInstanceEvent, ItemEvent
|
||||
|
||||
public PlayerUseItemOnBlockEvent(@NotNull Player player, @NotNull Player.Hand hand,
|
||||
@NotNull ItemStack itemStack,
|
||||
@NotNull Point position, @NotNull BlockFace blockFace) {
|
||||
@NotNull Point position, @NotNull Point cursorPosition,
|
||||
@NotNull BlockFace blockFace) {
|
||||
this.player = player;
|
||||
this.hand = hand;
|
||||
this.itemStack = itemStack;
|
||||
|
@ -20,6 +20,7 @@ import net.minestom.server.event.EventNode;
|
||||
import net.minestom.server.event.instance.InstanceTickEvent;
|
||||
import net.minestom.server.event.trait.InstanceEvent;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.instance.generator.Generator;
|
||||
import net.minestom.server.network.packet.server.play.BlockActionPacket;
|
||||
@ -150,7 +151,7 @@ public abstract class Instance implements Block.Getter, Block.Setter,
|
||||
* @return true if the block has been broken, false if it has been cancelled
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public abstract boolean breakBlock(@NotNull Player player, @NotNull Point blockPosition);
|
||||
public abstract boolean breakBlock(@NotNull Player player, @NotNull Point blockPosition, @NotNull BlockFace blockFace);
|
||||
|
||||
/**
|
||||
* Forces the generation of a {@link Chunk}, even if no file and {@link ChunkGenerator} are defined.
|
||||
|
@ -11,6 +11,7 @@ import net.minestom.server.event.instance.InstanceChunkLoadEvent;
|
||||
import net.minestom.server.event.instance.InstanceChunkUnloadEvent;
|
||||
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.instance.block.rule.BlockPlacementRule;
|
||||
import net.minestom.server.instance.generator.Generator;
|
||||
@ -175,7 +176,7 @@ public class InstanceContainer extends Instance {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean breakBlock(@NotNull Player player, @NotNull Point blockPosition) {
|
||||
public boolean breakBlock(@NotNull Player player, @NotNull Point blockPosition, @NotNull BlockFace blockFace) {
|
||||
final Chunk chunk = getChunkAt(blockPosition);
|
||||
Check.notNull(chunk, "You cannot break blocks in a null chunk!");
|
||||
if (chunk.isReadOnly()) return false;
|
||||
@ -190,7 +191,7 @@ public class InstanceContainer extends Instance {
|
||||
chunk.sendChunk(player);
|
||||
return false;
|
||||
}
|
||||
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(player, block, Block.AIR, blockPosition);
|
||||
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(player, block, Block.AIR, blockPosition, blockFace);
|
||||
EventDispatcher.call(blockBreakEvent);
|
||||
final boolean allowed = !blockBreakEvent.isCancelled();
|
||||
if (allowed) {
|
||||
|
@ -3,6 +3,7 @@ package net.minestom.server.instance;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.instance.generator.Generator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -35,8 +36,8 @@ public class SharedInstance extends Instance {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean breakBlock(@NotNull Player player, @NotNull Point blockPosition) {
|
||||
return instanceContainer.breakBlock(player, blockPosition);
|
||||
public boolean breakBlock(@NotNull Player player, @NotNull Point blockPosition, @NotNull BlockFace blockFace) {
|
||||
return instanceContainer.breakBlock(player, blockPosition, blockFace);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -194,14 +194,16 @@ public interface BlockHandler {
|
||||
private final Block block;
|
||||
private final Instance instance;
|
||||
private final Point blockPosition;
|
||||
private final Point cursorPosition;
|
||||
private final Player player;
|
||||
private final Player.Hand hand;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public Interaction(Block block, Instance instance, Point blockPosition, Player player, Player.Hand hand) {
|
||||
public Interaction(Block block, Instance instance, Point blockPosition, Point cursorPosition, Player player, Player.Hand hand) {
|
||||
this.block = block;
|
||||
this.instance = instance;
|
||||
this.blockPosition = blockPosition;
|
||||
this.cursorPosition = cursorPosition;
|
||||
this.player = player;
|
||||
this.hand = hand;
|
||||
}
|
||||
@ -218,6 +220,10 @@ public interface BlockHandler {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public @NotNull Point getCursorPosition() {
|
||||
return cursorPosition;
|
||||
}
|
||||
|
||||
public @NotNull Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.minestom.server.listener;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.collision.CollisionUtils;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
import net.minestom.server.entity.Player;
|
||||
@ -49,15 +50,17 @@ public class BlockPlacementListener {
|
||||
final ItemStack usedItem = player.getItemInHand(hand);
|
||||
final Block interactedBlock = instance.getBlock(blockPosition);
|
||||
|
||||
final Point cursorPosition = new Vec(packet.cursorPositionX(), packet.cursorPositionY(), packet.cursorPositionZ());
|
||||
|
||||
// Interact at block
|
||||
// FIXME: onUseOnBlock
|
||||
PlayerBlockInteractEvent playerBlockInteractEvent = new PlayerBlockInteractEvent(player, hand, interactedBlock, blockPosition, blockFace);
|
||||
PlayerBlockInteractEvent playerBlockInteractEvent = new PlayerBlockInteractEvent(player, hand, interactedBlock, blockPosition, cursorPosition, blockFace);
|
||||
EventDispatcher.call(playerBlockInteractEvent);
|
||||
boolean blockUse = playerBlockInteractEvent.isBlockingItemUse();
|
||||
if (!playerBlockInteractEvent.isCancelled()) {
|
||||
final var handler = interactedBlock.handler();
|
||||
if (handler != null) {
|
||||
blockUse |= !handler.onInteract(new BlockHandler.Interaction(interactedBlock, instance, blockPosition, player, hand));
|
||||
blockUse |= !handler.onInteract(new BlockHandler.Interaction(interactedBlock, instance, blockPosition, cursorPosition, player, hand));
|
||||
}
|
||||
}
|
||||
if (blockUse) {
|
||||
@ -68,7 +71,7 @@ public class BlockPlacementListener {
|
||||
final Material useMaterial = usedItem.material();
|
||||
if (!useMaterial.isBlock()) {
|
||||
// Player didn't try to place a block but interacted with one
|
||||
PlayerUseItemOnBlockEvent event = new PlayerUseItemOnBlockEvent(player, hand, usedItem, blockPosition, blockFace);
|
||||
PlayerUseItemOnBlockEvent event = new PlayerUseItemOnBlockEvent(player, hand, usedItem, blockPosition, cursorPosition, blockFace);
|
||||
EventDispatcher.call(event);
|
||||
return;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import net.minestom.server.event.player.PlayerStartDiggingEvent;
|
||||
import net.minestom.server.event.player.PlayerSwapItemEvent;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.inventory.PlayerInventory;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.StackingRule;
|
||||
@ -29,13 +30,13 @@ public final class PlayerDiggingListener {
|
||||
DiggingResult diggingResult = null;
|
||||
if (status == ClientPlayerDiggingPacket.Status.STARTED_DIGGING) {
|
||||
if (!instance.isChunkLoaded(blockPosition)) return;
|
||||
diggingResult = startDigging(player, instance, blockPosition);
|
||||
diggingResult = startDigging(player, instance, blockPosition, packet.blockFace());
|
||||
} else if (status == ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING) {
|
||||
if (!instance.isChunkLoaded(blockPosition)) return;
|
||||
diggingResult = cancelDigging(instance, blockPosition);
|
||||
} else if (status == ClientPlayerDiggingPacket.Status.FINISHED_DIGGING) {
|
||||
if (!instance.isChunkLoaded(blockPosition)) return;
|
||||
diggingResult = finishDigging(player, instance, blockPosition);
|
||||
diggingResult = finishDigging(player, instance, blockPosition, packet.blockFace());
|
||||
} else if (status == ClientPlayerDiggingPacket.Status.DROP_ITEM_STACK) {
|
||||
dropStack(player);
|
||||
} else if (status == ClientPlayerDiggingPacket.Status.DROP_ITEM) {
|
||||
@ -51,7 +52,7 @@ public final class PlayerDiggingListener {
|
||||
}
|
||||
}
|
||||
|
||||
private static DiggingResult startDigging(Player player, Instance instance, Point blockPosition) {
|
||||
private static DiggingResult startDigging(Player player, Instance instance, Point blockPosition, BlockFace blockFace) {
|
||||
final Block block = instance.getBlock(blockPosition);
|
||||
final GameMode gameMode = player.getGameMode();
|
||||
|
||||
@ -61,19 +62,19 @@ public final class PlayerDiggingListener {
|
||||
}
|
||||
|
||||
if (gameMode == GameMode.CREATIVE) {
|
||||
return breakBlock(instance, player, blockPosition, block);
|
||||
return breakBlock(instance, player, blockPosition, block, blockFace);
|
||||
}
|
||||
|
||||
// Survival digging
|
||||
// FIXME: verify mineable tag and enchantment
|
||||
final boolean instantBreak = player.isInstantBreak() || block.registry().hardness() == 0;
|
||||
if (!instantBreak) {
|
||||
PlayerStartDiggingEvent playerStartDiggingEvent = new PlayerStartDiggingEvent(player, block, blockPosition);
|
||||
PlayerStartDiggingEvent playerStartDiggingEvent = new PlayerStartDiggingEvent(player, block, blockPosition, blockFace);
|
||||
EventDispatcher.call(playerStartDiggingEvent);
|
||||
return new DiggingResult(block, !playerStartDiggingEvent.isCancelled());
|
||||
}
|
||||
// Client only send a single STARTED_DIGGING when insta-break is enabled
|
||||
return breakBlock(instance, player, blockPosition, block);
|
||||
return breakBlock(instance, player, blockPosition, block, blockFace);
|
||||
}
|
||||
|
||||
private static DiggingResult cancelDigging(Instance instance, Point blockPosition) {
|
||||
@ -81,14 +82,14 @@ public final class PlayerDiggingListener {
|
||||
return new DiggingResult(block, true);
|
||||
}
|
||||
|
||||
private static DiggingResult finishDigging(Player player, Instance instance, Point blockPosition) {
|
||||
private static DiggingResult finishDigging(Player player, Instance instance, Point blockPosition, BlockFace blockFace) {
|
||||
final Block block = instance.getBlock(blockPosition);
|
||||
|
||||
if (shouldPreventBreaking(player, block)) {
|
||||
return new DiggingResult(block, false);
|
||||
}
|
||||
|
||||
return breakBlock(instance, player, blockPosition, block);
|
||||
return breakBlock(instance, player, blockPosition, block, blockFace);
|
||||
}
|
||||
|
||||
private static boolean shouldPreventBreaking(@NotNull Player player, Block block) {
|
||||
@ -155,9 +156,9 @@ public final class PlayerDiggingListener {
|
||||
|
||||
private static DiggingResult breakBlock(Instance instance,
|
||||
Player player,
|
||||
Point blockPosition, Block previousBlock) {
|
||||
Point blockPosition, Block previousBlock, BlockFace blockFace) {
|
||||
// Unverified block break, client is fully responsible
|
||||
final boolean success = instance.breakBlock(player, blockPosition);
|
||||
final boolean success = instance.breakBlock(player, blockPosition, blockFace);
|
||||
final Block updatedBlock = instance.getBlock(blockPosition);
|
||||
if (!success) {
|
||||
if (previousBlock.isSolid()) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.minestom.server.listener;
|
||||
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.LivingEntity;
|
||||
import net.minestom.server.entity.Player;
|
||||
@ -12,7 +14,7 @@ public class UseEntityListener {
|
||||
|
||||
public static void useEntityListener(ClientInteractEntityPacket packet, Player player) {
|
||||
final Entity entity = Entity.getEntity(packet.targetId());
|
||||
if (entity == null || !entity.isViewer(player) || player.getDistance(entity) > 6)
|
||||
if (entity == null || !entity.isViewer(player) || player.getDistanceSquared(entity) > 6 * 6)
|
||||
return;
|
||||
|
||||
ClientInteractEntityPacket.Type type = packet.type();
|
||||
@ -21,7 +23,8 @@ public class UseEntityListener {
|
||||
return;
|
||||
EventDispatcher.call(new EntityAttackEvent(player, entity));
|
||||
} else if (type instanceof ClientInteractEntityPacket.InteractAt interactAt) {
|
||||
EventDispatcher.call(new PlayerEntityInteractEvent(player, entity, interactAt.hand()));
|
||||
Point interactPosition = new Vec(interactAt.targetX(), interactAt.targetY(), interactAt.targetZ());
|
||||
EventDispatcher.call(new PlayerEntityInteractEvent(player, entity, interactAt.hand(), interactPosition));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user