136 lines
7.5 KiB
Diff
136 lines
7.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: lexikiq <noellekiq@gmail.com>
|
|
Date: Mon, 10 May 2021 02:50:34 -0400
|
|
Subject: [PATCH] Add CraftItemStack#canPlaceOn
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/item/ItemBlock.java b/src/main/java/net/minecraft/world/item/ItemBlock.java
|
|
index 59d52c252b2e59923b8e513dd4d2e1ec9ce34dc7..25326f1124773ca4956a72a9b2998513748f7b85 100644
|
|
--- a/src/main/java/net/minecraft/world/item/ItemBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/item/ItemBlock.java
|
|
@@ -173,6 +173,7 @@ public class ItemBlock extends Item {
|
|
}).orElse(iblockdata);
|
|
}
|
|
|
|
+ public boolean canPlaceOn(BlockActionContext blockActionContext, IBlockData iBlockData) {return b(blockActionContext, iBlockData);} // Parchment - OBFHELPER
|
|
protected boolean b(BlockActionContext blockactioncontext, IBlockData iblockdata) {
|
|
EntityHuman entityhuman = blockactioncontext.getEntity();
|
|
VoxelShapeCollision voxelshapecollision = entityhuman == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a((Entity) entityhuman);
|
|
diff --git a/src/main/java/net/minecraft/world/item/context/BlockActionContext.java b/src/main/java/net/minecraft/world/item/context/BlockActionContext.java
|
|
index 2cb451db6ca23290f700dc428a7622f64fb90b97..1763ada73e4ef422f95eb5c3f42f19d7600261a6 100644
|
|
--- a/src/main/java/net/minecraft/world/item/context/BlockActionContext.java
|
|
+++ b/src/main/java/net/minecraft/world/item/context/BlockActionContext.java
|
|
@@ -24,7 +24,7 @@ public class BlockActionContext extends ItemActionContext {
|
|
this(itemactioncontext.getWorld(), itemactioncontext.getEntity(), itemactioncontext.getHand(), itemactioncontext.getItemStack(), itemactioncontext.i());
|
|
}
|
|
|
|
- protected BlockActionContext(World world, @Nullable EntityHuman entityhuman, EnumHand enumhand, ItemStack itemstack, MovingObjectPositionBlock movingobjectpositionblock) {
|
|
+ public BlockActionContext(World world, @Nullable EntityHuman entityhuman, EnumHand enumhand, ItemStack itemstack, MovingObjectPositionBlock movingobjectpositionblock) { // Parchment
|
|
super(world, entityhuman, enumhand, itemstack, movingobjectpositionblock);
|
|
this.a = true;
|
|
this.b = movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection());
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
index 09d7a86b5f6cffdf6664ad657dd4f8dd8eabdd70..e709c910e3e9a09c26b44225a0d6c809502e4b67 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
@@ -3,21 +3,41 @@ package org.bukkit.craftbukkit.inventory;
|
|
import static org.bukkit.craftbukkit.inventory.CraftMetaItem.*;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import java.util.Map;
|
|
+import me.lexikiq.HasHumanEntity;
|
|
+import me.lexikiq.OptionalHumanEntity;
|
|
+import net.minecraft.core.EnumDirection;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.nbt.NBTTagList;
|
|
+import net.minecraft.world.EnumHand;
|
|
+import net.minecraft.world.entity.player.EntityHuman;
|
|
import net.minecraft.world.item.Item;
|
|
+import net.minecraft.world.item.Items;
|
|
import net.minecraft.world.item.enchantment.EnchantmentManager;
|
|
+import net.minecraft.world.item.ItemBlock;
|
|
+import net.minecraft.world.item.context.BlockActionContext;
|
|
+import net.minecraft.world.phys.MovingObjectPositionBlock;
|
|
+import net.minecraft.world.phys.Vec3D;
|
|
import org.apache.commons.lang.Validate;
|
|
+import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
+import org.bukkit.World;
|
|
+import org.bukkit.block.Block;
|
|
+import org.bukkit.block.BlockFace;
|
|
import org.bukkit.configuration.serialization.DelegateDeserialization;
|
|
+import org.bukkit.craftbukkit.CraftWorld;
|
|
import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
|
|
+import org.bukkit.craftbukkit.block.CraftBlock;
|
|
+import org.bukkit.craftbukkit.entity.CraftEntity;
|
|
import org.bukkit.craftbukkit.util.CraftLegacy;
|
|
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
|
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
|
import org.bukkit.enchantments.Enchantment;
|
|
+import org.bukkit.entity.HumanEntity;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
|
import org.bukkit.material.MaterialData;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
|
|
@DelegateDeserialization(ItemStack.class)
|
|
public final class CraftItemStack extends ItemStack {
|
|
@@ -105,6 +125,57 @@ public final class CraftItemStack extends ItemStack {
|
|
setItemMeta(itemMeta);
|
|
}
|
|
|
|
+ // Parchment start
|
|
+ /**
|
|
+ * Determines if this item can be placed on a block. Must be run synchronously. Factors in player location,
|
|
+ * nearby entities, and more.
|
|
+ * @param world world in which the block is being placed
|
|
+ * @param _player optional player placing the block
|
|
+ * @param block block to check against
|
|
+ * @param face cardinal direction
|
|
+ * @return if the item can be placed
|
|
+ */
|
|
+ public boolean canPlaceOn(World world, @Nullable OptionalHumanEntity _player, Block block, BlockFace face) {
|
|
+ Validate.notNull(world, "'world' must not be null");
|
|
+ Validate.notNull(block, "'block' must not be null");
|
|
+ Validate.notNull(face, "'face' must not be null");
|
|
+
|
|
+ if (block.getType().isEmpty() || block.isLiquid()) return false;
|
|
+ HumanEntity player = _player != null ? _player.getPlayer() : null;
|
|
+ if (!(world instanceof CraftWorld)) return false;
|
|
+ if (!face.isCartesian()) throw new IllegalArgumentException("Face must be cartesian");
|
|
+ if (!(block instanceof CraftBlock)) return false;
|
|
+ if (player != null && !(player instanceof CraftEntity)) return false;
|
|
+ EntityHuman human = player != null ? (EntityHuman) ((CraftEntity) player).getHandle() : null;
|
|
+ CraftBlock craftBlock = (CraftBlock) block;
|
|
+ CraftBlock relativeBlock = (CraftBlock) block.getRelative(face);
|
|
+ if (!relativeBlock.isReplaceable())
|
|
+ return false;
|
|
+ Location playerLoc = player != null ? player.getLocation() : relativeBlock.getLocation();
|
|
+ EnumDirection direction = EnumDirection.valueOf(face.name());
|
|
+
|
|
+ Item item = handle != null ? handle.getItem() : Items.AIR;
|
|
+ if (!(item instanceof ItemBlock)) return false;
|
|
+ ItemBlock itemBlock = (ItemBlock) item;
|
|
+
|
|
+ BlockActionContext context = new BlockActionContext(((CraftWorld) world).getHandle(), human, EnumHand.MAIN_HAND, asNMSCopy(this), new MovingObjectPositionBlock(new Vec3D(playerLoc.getX(), playerLoc.getY(), playerLoc.getZ()), direction, craftBlock.getPosition(), false));
|
|
+ return itemBlock.canPlaceOn(context, itemBlock.getBlock().getPlacedState(context));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Determines if this item can be placed on a block. Must be run synchronously. Factors in player location,
|
|
+ * nearby entities, and more.
|
|
+ * @param player player placing the block
|
|
+ * @param block block to check against
|
|
+ * @param face cardinal direction
|
|
+ * @return if the item can be placed
|
|
+ */
|
|
+ public boolean canPlaceOn(@NotNull HasHumanEntity player, Block block, BlockFace face) {
|
|
+ Validate.notNull(player, "'player' must not be null");
|
|
+ return canPlaceOn(player.getPlayer().getWorld(), player, block, face);
|
|
+ }
|
|
+ // Parchment end
|
|
+
|
|
@Override
|
|
public MaterialData getData() {
|
|
return handle != null ? CraftMagicNumbers.getMaterialData(handle.getItem()) : super.getData();
|