First attempt at replacing placement rules

This commit is contained in:
TheMode 2021-08-31 19:37:27 +02:00
parent 2c0cd4ff7a
commit 540ddd8daf
6 changed files with 116 additions and 85 deletions

View File

@ -0,0 +1,59 @@
package net.minestom.server.event.generic;
import net.minestom.server.coordinate.Point;
import net.minestom.server.event.trait.BlockEvent;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.RecursiveEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler;
import org.jetbrains.annotations.NotNull;
public class BlockPlaceEvent implements RecursiveEvent, BlockEvent, CancellableEvent {
private final BlockHandler.Placement placement;
public BlockPlaceEvent(BlockHandler.Placement placement) {
this.placement = placement;
}
public BlockHandler.Placement getPlacement() {
return placement;
}
/**
* Gets the block which will be placed.
*
* @return the block to place
*/
@Override
public @NotNull Block getBlock() {
return placement.getBlock();
}
/**
* Changes the block to be placed.
*
* @param block the new block
*/
public void setBlock(@NotNull Block block) {
this.placement.setBlock(block);
}
/**
* Gets the block position.
*
* @return the block position
*/
public @NotNull Point getBlockPosition() {
return placement.getBlockPosition();
}
@Override
public boolean isCancelled() {
return placement.isCancelled();
}
@Override
public void setCancelled(boolean cancel) {
this.placement.setCancelled(cancel);
}
}

View File

@ -1,72 +1,34 @@
package net.minestom.server.event.player;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Player;
import net.minestom.server.event.trait.BlockEvent;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.generic.BlockPlaceEvent;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.BlockHandler;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player tries placing a block.
*/
public class PlayerBlockPlaceEvent implements PlayerEvent, BlockEvent, CancellableEvent {
public class PlayerBlockPlaceEvent extends BlockPlaceEvent implements PlayerEvent {
private final Player player;
private Block block;
private final BlockFace blockFace;
private final Point blockPosition;
private final Player.Hand hand;
private boolean consumeBlock;
private boolean cancelled;
public PlayerBlockPlaceEvent(@NotNull Player player, @NotNull Block block,
@NotNull BlockFace blockFace,
@NotNull Point blockPosition, @NotNull Player.Hand hand) {
this.player = player;
this.block = block;
this.blockFace = blockFace;
this.blockPosition = blockPosition;
this.hand = hand;
this.consumeBlock = true;
}
/**
* Gets the block which will be placed.
*
* @return the block to place
*/
@Override
public @NotNull Block getBlock() {
return block;
}
/**
* Changes the block to be placed.
*
* @param block the new block
*/
public void setBlock(@NotNull Block block) {
this.block = block;
public PlayerBlockPlaceEvent(BlockHandler.PlayerPlacement placement) {
super(placement);
this.player = placement.getPlayer();
this.blockFace = placement.getBlockFace();
this.hand = placement.getHand();
}
public @NotNull BlockFace getBlockFace() {
return blockFace;
}
/**
* Gets the block position.
*
* @return the block position
*/
public @NotNull Point getBlockPosition() {
return blockPosition;
}
/**
* Gets the hand with which the player is trying to place.
*
@ -94,16 +56,6 @@ public class PlayerBlockPlaceEvent implements PlayerEvent, BlockEvent, Cancellab
return consumeBlock;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public @NotNull Player getPlayer() {
return player;

View File

@ -0,0 +1,10 @@
package net.minestom.server.event.server;
import net.minestom.server.event.generic.BlockPlaceEvent;
import net.minestom.server.instance.block.BlockHandler;
public class ServerBlockPlaceEvent extends BlockPlaceEvent {
public ServerBlockPlaceEvent(BlockHandler.Placement placement) {
super(placement);
}
}

View File

@ -5,12 +5,16 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.GlobalHandles;
import net.minestom.server.event.generic.BlockPlaceEvent;
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.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.event.server.ServerBlockPlaceEvent;
import net.minestom.server.instance.batch.ChunkGenerationBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler;
@ -157,6 +161,20 @@ public class InstanceContainer extends Instance {
final Point blockPosition = placement.getBlockPosition();
final Chunk chunk = getChunkAt(blockPosition);
if (!ChunkUtils.isLoaded(chunk)) return false;
BlockPlaceEvent event;
if (placement instanceof BlockHandler.PlayerPlacement) {
BlockHandler.PlayerPlacement playerPlacement = (BlockHandler.PlayerPlacement) placement;
Player player = playerPlacement.getPlayer();
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(playerPlacement);
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);
event = playerBlockPlaceEvent;
} else {
event = new ServerBlockPlaceEvent(placement);
}
EventDispatcher.call(event);
if (event.isCancelled()) return false;
UNSAFE_setBlock(chunk, blockPosition.blockX(), blockPosition.blockY(), blockPosition.blockZ(),
placement.getBlock(), placement, null);
return true;

View File

@ -88,10 +88,12 @@ public interface BlockHandler {
*/
@ApiStatus.NonExtendable
class Placement {
private final Block block;
private Block block;
private final Instance instance;
private final Point blockPosition;
private boolean cancelled;
@ApiStatus.Internal
public Placement(Block block, Instance instance, Point blockPosition) {
this.block = block;
@ -103,6 +105,10 @@ public interface BlockHandler {
return block;
}
public void setBlock(@NotNull Block block) {
this.block = block;
}
public @NotNull Instance getInstance() {
return instance;
}
@ -110,6 +116,14 @@ public interface BlockHandler {
public @NotNull Point getBlockPosition() {
return blockPosition;
}
public boolean isCancelled() {
return cancelled;
}
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
}
final class PlayerPlacement extends Placement {

View File

@ -9,7 +9,6 @@ import net.minestom.server.entity.Player;
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerBlockInteractEvent;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.event.player.PlayerUseItemOnBlockEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
@ -17,7 +16,6 @@ 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.BlockManager;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
@ -136,35 +134,15 @@ public class BlockPlacementListener {
refresh(player, chunk);
return;
}
// BlockPlaceEvent check
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(player, placedBlock, blockFace, placementPosition, packet.hand);
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);
EventDispatcher.call(playerBlockPlaceEvent);
if (playerBlockPlaceEvent.isCancelled()) {
refresh(player, chunk);
return;
}
// BlockPlacementRule check
Block resultBlock = playerBlockPlaceEvent.getBlock();
final BlockPlacementRule blockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(resultBlock);
if (blockPlacementRule != null) {
// Get id from block placement rule instead of the event
resultBlock = blockPlacementRule.blockPlace(instance, resultBlock, blockFace, blockPosition, player);
}
if (resultBlock == null) {
refresh(player, chunk);
return;
}
// Place the block
instance.placeBlock(new BlockHandler.PlayerPlacement(resultBlock, instance, placementPosition, player, hand, blockFace,
instance.placeBlock(new BlockHandler.PlayerPlacement(placedBlock, instance, placementPosition, player, hand, blockFace,
packet.cursorPositionX, packet.cursorPositionY, packet.cursorPositionZ));
// Block consuming
if (playerBlockPlaceEvent.doesConsumeBlock()) {
// Consume the block in the player's hand
final ItemStack newUsedItem = usedItem.getStackingRule().apply(usedItem, usedItem.getAmount() - 1);
playerInventory.setItemInHand(hand, newUsedItem);
}
//if (playerBlockPlaceEvent.doesConsumeBlock()) {
// // Consume the block in the player's hand
// final ItemStack newUsedItem = usedItem.getStackingRule().apply(usedItem, usedItem.getAmount() - 1);
// playerInventory.setItemInHand(hand, newUsedItem);
//}
}
private static void refresh(Player player, Chunk chunk) {