mirror of
https://github.com/ChestShop-authors/ChestShop-3.git
synced 2024-09-27 14:13:05 +02:00
Fix sign bounding box issue in adventure mode
This commit is contained in:
parent
d82faa1f7a
commit
9d33d2c09c
@ -1,7 +1,10 @@
|
|||||||
package com.Acrobot.Breeze.Utils;
|
package com.Acrobot.Breeze.Utils;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.Chest;
|
import org.bukkit.block.Chest;
|
||||||
import org.bukkit.block.DoubleChest;
|
import org.bukkit.block.DoubleChest;
|
||||||
import org.bukkit.block.Sign;
|
import org.bukkit.block.Sign;
|
||||||
@ -9,6 +12,11 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.material.Attachable;
|
import org.bukkit.material.Attachable;
|
||||||
|
import org.bukkit.material.Directional;
|
||||||
|
import org.bukkit.material.MaterialData;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Acrobot
|
* @author Acrobot
|
||||||
@ -68,4 +76,100 @@ public class BlockUtil {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final BoundingBox BLOCK = new BoundingBox(new Vector(), new Vector(1, 1, 1));
|
||||||
|
private static final Map<Material, BoundingBox> BOXES = ImmutableMap.of(
|
||||||
|
Material.WALL_SIGN, new BoundingBox(new Vector(0, 0.28125, 0), new Vector(1, 0.78125, 0.125)), // Default direction is South
|
||||||
|
Material.SIGN_POST, new BoundingBox(new Vector(0.25, 0, 0.25), new Vector(0.75, 1, 0.75))
|
||||||
|
);
|
||||||
|
|
||||||
|
public static BoundingBox getBoundingBox(Block block) {
|
||||||
|
BoundingBox box = BOXES.getOrDefault(block.getType(), BLOCK);
|
||||||
|
|
||||||
|
MaterialData data = block.getState().getData();
|
||||||
|
if (data instanceof Directional) {
|
||||||
|
Directional directional = (Directional) data;
|
||||||
|
box = box.getFacing(directional.getFacing());
|
||||||
|
}
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BoundingBox {
|
||||||
|
private final Vector minimumPoint;
|
||||||
|
private final Vector maximumPoint;
|
||||||
|
|
||||||
|
BoundingBox(Vector minimumPoint, Vector maximumPoint) {
|
||||||
|
while (minimumPoint.getX() < 0 || maximumPoint.getX() < 0) {
|
||||||
|
minimumPoint.setX(1 + minimumPoint.getX());
|
||||||
|
maximumPoint.setX(1 + maximumPoint.getX());
|
||||||
|
}
|
||||||
|
while (minimumPoint.getY() < 0 || maximumPoint.getY() < 0) {
|
||||||
|
minimumPoint.setY(1 + minimumPoint.getY());
|
||||||
|
maximumPoint.setY(1 + maximumPoint.getY());
|
||||||
|
}
|
||||||
|
while (minimumPoint.getZ() < 0 || maximumPoint.getZ() < 0) {
|
||||||
|
minimumPoint.setZ(1 + minimumPoint.getZ());
|
||||||
|
maximumPoint.setZ(1 + maximumPoint.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.minimumPoint = min(minimumPoint, maximumPoint);
|
||||||
|
this.maximumPoint = max(minimumPoint, maximumPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector min(Vector v1, Vector v2) {
|
||||||
|
return new Vector(Math.min(v1.getX(), v2.getX()), Math.min(v1.getY(), v2.getY()), Math.min(v1.getZ(), v2.getZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector max(Vector v1, Vector v2) {
|
||||||
|
return new Vector(Math.max(v1.getX(), v2.getX()), Math.max(v1.getY(), v2.getY()), Math.max(v1.getZ(), v2.getZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a certain vector hits the hitbox of a block.
|
||||||
|
* Only really checks for Signs as we don't need the rest
|
||||||
|
*
|
||||||
|
* @param source The start location including the direction
|
||||||
|
* @param block The block to check
|
||||||
|
* @param distance The maximum distance from the source location to check for
|
||||||
|
* @param precision The precision of the steps of the trace
|
||||||
|
* @return Does the vector intercept the box?
|
||||||
|
*/
|
||||||
|
public boolean intercepts(Location source, Block block, double distance, double precision) {
|
||||||
|
if (source.distanceSquared(block.getLocation()) > distance * distance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Vector posMin = block.getLocation().toVector().add(minimumPoint);
|
||||||
|
Vector posMax = block.getLocation().toVector().add(maximumPoint);
|
||||||
|
Vector direction = source.getDirection();
|
||||||
|
for (double d = 0; d < distance; d += precision) {
|
||||||
|
Location check = source.clone().add(direction.clone().multiply(d));
|
||||||
|
if (check.getX() >= posMin.getX() && check.getX() < posMax.getX()
|
||||||
|
&& check.getY() >= posMin.getY() && check.getY() < posMax.getY()
|
||||||
|
&& check.getZ() >= posMin.getZ() && check.getZ() < posMax.getZ()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox getFacing(BlockFace face) {
|
||||||
|
Vector minPoint = minimumPoint.clone();
|
||||||
|
Vector maxPoint = maximumPoint.clone();
|
||||||
|
if (face == BlockFace.NORTH || face == BlockFace.EAST || face == BlockFace.SOUTH || face == BlockFace.WEST) {
|
||||||
|
if (face.getModX() == 0) {
|
||||||
|
minPoint.setX(face.getModZ() * minimumPoint.getX());
|
||||||
|
maxPoint.setX(face.getModZ() * maximumPoint.getX());
|
||||||
|
minPoint.setZ(face.getModZ() * minimumPoint.getZ());
|
||||||
|
maxPoint.setZ(face.getModZ() * maximumPoint.getZ());
|
||||||
|
} else if (face.getModZ() == 0) {
|
||||||
|
minPoint.setX(face.getModX() * minimumPoint.getZ());
|
||||||
|
maxPoint.setX(face.getModX() * maximumPoint.getZ());
|
||||||
|
minPoint.setZ(face.getModX() * minimumPoint.getX());
|
||||||
|
maxPoint.setZ(face.getModX() * maximumPoint.getX());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new BoundingBox(minPoint, maxPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package com.Acrobot.ChestShop.Listeners.Player;
|
package com.Acrobot.ChestShop.Listeners.Player;
|
||||||
|
|
||||||
import com.Acrobot.Breeze.Utils.*;
|
import com.Acrobot.Breeze.Utils.BlockUtil;
|
||||||
|
import com.Acrobot.Breeze.Utils.InventoryUtil;
|
||||||
|
import com.Acrobot.Breeze.Utils.MaterialUtil;
|
||||||
|
import com.Acrobot.Breeze.Utils.NumberUtil;
|
||||||
|
import com.Acrobot.Breeze.Utils.PriceUtil;
|
||||||
import com.Acrobot.ChestShop.Configuration.Messages;
|
import com.Acrobot.ChestShop.Configuration.Messages;
|
||||||
import com.Acrobot.ChestShop.Configuration.Properties;
|
import com.Acrobot.ChestShop.Configuration.Properties;
|
||||||
import com.Acrobot.ChestShop.Containers.AdminInventory;
|
import com.Acrobot.ChestShop.Containers.AdminInventory;
|
||||||
@ -29,20 +33,22 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.PlayerAnimationEvent;
|
import org.bukkit.event.player.PlayerAnimationEvent;
|
||||||
import org.bukkit.event.player.PlayerAnimationType;
|
import org.bukkit.event.player.PlayerAnimationType;
|
||||||
import org.bukkit.event.player.PlayerEvent;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.material.Directional;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static com.Acrobot.Breeze.Utils.BlockUtil.isChest;
|
import static com.Acrobot.Breeze.Utils.BlockUtil.isChest;
|
||||||
import static com.Acrobot.Breeze.Utils.BlockUtil.isSign;
|
import static com.Acrobot.Breeze.Utils.BlockUtil.isSign;
|
||||||
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType;
|
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType;
|
||||||
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType.BUY;
|
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType.BUY;
|
||||||
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType.SELL;
|
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType.SELL;
|
||||||
import static com.Acrobot.ChestShop.Signs.ChestShopSign.*;
|
import static com.Acrobot.ChestShop.Signs.ChestShopSign.ITEM_LINE;
|
||||||
|
import static com.Acrobot.ChestShop.Signs.ChestShopSign.NAME_LINE;
|
||||||
|
import static com.Acrobot.ChestShop.Signs.ChestShopSign.PRICE_LINE;
|
||||||
|
import static com.Acrobot.ChestShop.Signs.ChestShopSign.QUANTITY_LINE;
|
||||||
import static org.bukkit.event.block.Action.LEFT_CLICK_BLOCK;
|
import static org.bukkit.event.block.Action.LEFT_CLICK_BLOCK;
|
||||||
import static org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK;
|
import static org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK;
|
||||||
|
|
||||||
@ -57,7 +63,7 @@ public class PlayerInteract implements Listener {
|
|||||||
if (block == null)
|
if (block == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Make sure that event isn't handled twice when the adventure mdoe workaround is used
|
// Make sure that event isn't handled twice when the adventure mode workaround is used
|
||||||
if (event.getPlayer().getGameMode() != GameMode.ADVENTURE || event.getAction() != Action.LEFT_CLICK_BLOCK) {
|
if (event.getPlayer().getGameMode() != GameMode.ADVENTURE || event.getAction() != Action.LEFT_CLICK_BLOCK) {
|
||||||
handleEvent(event, event.getPlayer(), block, event.getAction());
|
handleEvent(event, event.getPlayer(), block, event.getAction());
|
||||||
}
|
}
|
||||||
@ -70,6 +76,9 @@ public class PlayerInteract implements Listener {
|
|||||||
Block block = event.getPlayer().getTargetBlock((Set<Material>) null, 5);
|
Block block = event.getPlayer().getTargetBlock((Set<Material>) null, 5);
|
||||||
if (block == null)
|
if (block == null)
|
||||||
return;
|
return;
|
||||||
|
if (isSign(block) && !BlockUtil.getBoundingBox(block).intercepts(event.getPlayer().getEyeLocation(), block, 8, 0.1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleEvent(event, event.getPlayer(), block, Action.LEFT_CLICK_BLOCK);
|
handleEvent(event, event.getPlayer(), block, Action.LEFT_CLICK_BLOCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user