Minestom/src/main/java/fr/themode/minestom/listener/BlockPlacementListener.java

119 lines
5.1 KiB
Java
Raw Normal View History

package fr.themode.minestom.listener;
2020-04-17 15:58:07 +02:00
import fr.themode.minestom.MinecraftServer;
2020-03-30 19:48:25 +02:00
import fr.themode.minestom.data.Data;
2020-04-21 15:31:41 +02:00
import fr.themode.minestom.entity.Entity;
2019-09-14 18:00:18 +02:00
import fr.themode.minestom.entity.GameMode;
import fr.themode.minestom.entity.Player;
2020-03-30 19:48:25 +02:00
import fr.themode.minestom.event.PlayerBlockInteractEvent;
2019-08-25 20:03:43 +02:00
import fr.themode.minestom.event.PlayerBlockPlaceEvent;
import fr.themode.minestom.instance.Chunk;
import fr.themode.minestom.instance.Instance;
2020-04-17 15:58:07 +02:00
import fr.themode.minestom.instance.block.Block;
import fr.themode.minestom.instance.block.BlockManager;
2020-03-30 19:48:25 +02:00
import fr.themode.minestom.instance.block.CustomBlock;
2020-04-17 15:58:07 +02:00
import fr.themode.minestom.instance.block.rule.BlockPlacementRule;
2019-08-29 02:15:52 +02:00
import fr.themode.minestom.inventory.PlayerInventory;
import fr.themode.minestom.item.ItemStack;
2020-03-29 20:58:30 +02:00
import fr.themode.minestom.item.Material;
2020-02-17 17:33:53 +01:00
import fr.themode.minestom.item.StackingRule;
import fr.themode.minestom.net.packet.client.play.ClientPlayerBlockPlacementPacket;
import fr.themode.minestom.net.packet.client.play.ClientPlayerDiggingPacket;
2019-08-21 16:50:52 +02:00
import fr.themode.minestom.utils.BlockPosition;
2019-09-01 06:18:41 +02:00
import fr.themode.minestom.utils.ChunkUtils;
2020-04-21 15:31:41 +02:00
import java.util.Set;
public class BlockPlacementListener {
2020-03-30 19:48:25 +02:00
private Instance instance;
public static void listener(ClientPlayerBlockPlacementPacket packet, Player player) {
2019-08-29 02:15:52 +02:00
PlayerInventory playerInventory = player.getInventory();
Player.Hand hand = packet.hand;
ClientPlayerDiggingPacket.BlockFace blockFace = packet.blockFace;
2019-08-21 16:50:52 +02:00
BlockPosition blockPosition = packet.blockPosition;
Instance instance = player.getInstance();
if (instance == null)
return;
2020-04-21 15:31:41 +02:00
// Interact at block
2020-03-30 19:48:25 +02:00
PlayerBlockInteractEvent playerBlockInteractEvent = new PlayerBlockInteractEvent(blockPosition, hand);
player.callCancellableEvent(PlayerBlockInteractEvent.class, playerBlockInteractEvent, () -> {
CustomBlock customBlock = instance.getCustomBlock(blockPosition);
if (customBlock != null) {
Data data = instance.getBlockData(blockPosition);
2020-04-05 17:46:29 +02:00
customBlock.onInteract(player, hand, blockPosition, data);
2020-03-30 19:48:25 +02:00
}
});
2020-04-21 15:31:41 +02:00
// Check if item at hand is a block
2019-08-29 02:15:52 +02:00
ItemStack usedItem = hand == Player.Hand.MAIN ? playerInventory.getItemInMainHand() : playerInventory.getItemInOffHand();
2020-03-29 20:58:30 +02:00
Material material = Material.fromId(usedItem.getMaterialId());
if (material != null && !material.isBlock()) {
2019-08-29 02:15:52 +02:00
return;
2019-09-01 06:18:41 +02:00
}
2019-08-29 02:15:52 +02:00
2020-04-21 15:31:41 +02:00
// Get the newly placed block position
int offsetX = blockFace == ClientPlayerDiggingPacket.BlockFace.WEST ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.EAST ? 1 : 0;
int offsetY = blockFace == ClientPlayerDiggingPacket.BlockFace.BOTTOM ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.TOP ? 1 : 0;
int offsetZ = blockFace == ClientPlayerDiggingPacket.BlockFace.NORTH ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.SOUTH ? 1 : 0;
2019-08-22 14:52:32 +02:00
blockPosition.add(offsetX, offsetY, offsetZ);
2020-04-21 15:31:41 +02:00
Chunk chunk = instance.getChunkAt(blockPosition);
Set<Entity> entities = instance.getChunkEntities(chunk);
boolean intersect = false;
for (Entity entity : entities) {
intersect = entity.getBoundingBox().intersect(blockPosition);
if (intersect)
break;
}
boolean refreshChunk = false;
if (material.isBlock() && !intersect) {
2019-08-31 07:54:53 +02:00
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent((short) 10, blockPosition, packet.hand);
2019-09-14 18:00:18 +02:00
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);
2020-04-17 15:58:07 +02:00
// BlockPlacementRule check
Block block = material.getBlock();
BlockManager blockManager = MinecraftServer.getBlockManager();
BlockPlacementRule blockPlacementRule = blockManager.getBlockPlacementRule(block);
boolean canPlace = true;
if (blockPlacementRule != null) {
canPlace = blockPlacementRule.canPlace(instance, blockPosition);
}
2019-08-31 07:54:53 +02:00
player.callEvent(PlayerBlockPlaceEvent.class, playerBlockPlaceEvent);
2020-04-17 15:58:07 +02:00
if (!playerBlockPlaceEvent.isCancelled() && canPlace) {
2020-04-10 12:45:04 +02:00
instance.setBlock(blockPosition, material.getBlock());
2019-08-31 07:54:53 +02:00
if (playerBlockPlaceEvent.doesConsumeBlock()) {
2020-02-17 17:33:53 +01:00
StackingRule stackingRule = usedItem.getStackingRule();
2020-04-17 21:34:01 +02:00
ItemStack newUsedItem = stackingRule.apply(usedItem, stackingRule.getAmount(usedItem) - 1);
2020-02-17 17:33:53 +01:00
2019-08-31 07:54:53 +02:00
if (hand == Player.Hand.OFF) {
2020-04-17 21:34:01 +02:00
playerInventory.setItemInOffHand(newUsedItem);
2019-08-31 07:54:53 +02:00
} else { // Main
2020-04-17 21:34:01 +02:00
playerInventory.setItemInMainHand(newUsedItem);
2019-08-31 07:54:53 +02:00
}
2019-08-29 02:15:52 +02:00
}
2019-08-31 07:54:53 +02:00
} else {
2020-04-21 15:31:41 +02:00
refreshChunk = true;
2019-08-29 02:15:52 +02:00
}
2020-04-20 18:46:39 +02:00
} else {
2020-04-21 15:31:41 +02:00
refreshChunk = true;
}
// Refresh chunk section if needed
if (refreshChunk) {
2020-04-20 18:46:39 +02:00
instance.sendChunkSectionUpdate(chunk, ChunkUtils.getSectionAt(blockPosition.getY()), player);
}
2020-04-21 15:31:41 +02:00
player.getInventory().refreshSlot(player.getHeldSlot());
}
}