Almost entirely functional silent shulker boxes
For whatever reason, the shulker box EnumDirection isn't being retrieved properly, so AnyChest will only trigger on shulker boxes that would not be able to open if placed downwards (opening upwards). Silentchest and anychest will work, though. Suppressed a few deprecation warnings that don't make sense to keep. If you do use my fork of OpenInv's API, it's not yet stable (specifically, IAnySilentContainer), and will change a little more as I polish things up.
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<artifactId>openinv</artifactId>
|
<artifactId>openinv</artifactId>
|
||||||
<name>OpenInv</name>
|
<name>OpenInv</name>
|
||||||
<version>2.5.3-SNAPSHOT</version>
|
<version>2.5.4</version>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ import org.bukkit.entity.Player;
|
|||||||
public interface IAnySilentChest {
|
public interface IAnySilentChest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link IAnySilentContainer#activateContainer(Player, boolean, boolean, int, int, int)}.
|
* @deprecated Use {@link IAnySilentContainer#activateContainer(Player, boolean, int, int, int)}.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean activateChest(Player player, boolean anychest, boolean silentchest, int x, int y, int z);
|
public boolean activateChest(Player player, boolean anychest, boolean silentchest, int x, int y, int z);
|
||||||
|
@@ -3,6 +3,7 @@ package com.lishid.openinv.internal;
|
|||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public interface IAnySilentContainer extends IAnySilentChest {
|
public interface IAnySilentContainer extends IAnySilentChest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -18,16 +18,19 @@ package com.lishid.openinv.internal.v1_11_R1;
|
|||||||
|
|
||||||
import com.lishid.openinv.internal.IAnySilentContainer;
|
import com.lishid.openinv.internal.IAnySilentContainer;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
// Volatile
|
// Volatile
|
||||||
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
|
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
|
||||||
import net.minecraft.server.v1_11_R1.Block;
|
import net.minecraft.server.v1_11_R1.Block;
|
||||||
import net.minecraft.server.v1_11_R1.BlockChest;
|
import net.minecraft.server.v1_11_R1.BlockChest;
|
||||||
import net.minecraft.server.v1_11_R1.BlockChest.Type;
|
import net.minecraft.server.v1_11_R1.BlockChest.Type;
|
||||||
|
import net.minecraft.server.v1_11_R1.BlockEnderChest;
|
||||||
import net.minecraft.server.v1_11_R1.BlockPosition;
|
import net.minecraft.server.v1_11_R1.BlockPosition;
|
||||||
import net.minecraft.server.v1_11_R1.BlockShulkerBox;
|
import net.minecraft.server.v1_11_R1.BlockShulkerBox;
|
||||||
import net.minecraft.server.v1_11_R1.Container;
|
import net.minecraft.server.v1_11_R1.Container;
|
||||||
@@ -62,16 +65,22 @@ public class AnySilentContainer implements IAnySilentContainer {
|
|||||||
@Override
|
@Override
|
||||||
public boolean activateContainer(Player p, boolean silentchest, int x, int y, int z) {
|
public boolean activateContainer(Player p, boolean silentchest, int x, int y, int z) {
|
||||||
|
|
||||||
|
// TODO backport to all modules? TODO change new API to activateContainer(Player, Block)? Use BlockState instead?
|
||||||
|
if (silentchest && p.getWorld().getBlockAt(x, y, z).getType() == Material.ENDER_CHEST) {
|
||||||
|
p.openInventory(p.getEnderChest());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
EntityPlayer player = ((CraftPlayer) p).getHandle();
|
EntityPlayer player = ((CraftPlayer) p).getHandle();
|
||||||
World world = player.world;
|
final World world = player.world;
|
||||||
BlockPosition blockPosition = new BlockPosition(x, y, z);
|
final BlockPosition blockPosition = new BlockPosition(x, y, z);
|
||||||
Object tile = world.getTileEntity(blockPosition);
|
Object tile = world.getTileEntity(blockPosition);
|
||||||
|
|
||||||
if (tile == null) {
|
if (tile == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block block = world.getType(new BlockPosition(x, y, z)).getBlock();
|
Block block = world.getType(blockPosition).getBlock();
|
||||||
Container container = null;
|
Container container = null;
|
||||||
|
|
||||||
if (block instanceof BlockChest) {
|
if (block instanceof BlockChest) {
|
||||||
@@ -115,41 +124,56 @@ public class AnySilentContainer implements IAnySilentContainer {
|
|||||||
player.b(StatisticList.ae);
|
player.b(StatisticList.ae);
|
||||||
|
|
||||||
if (silentchest && tile instanceof TileEntityShulkerBox) {
|
if (silentchest && tile instanceof TileEntityShulkerBox) {
|
||||||
// TODO: End state allows for silent opening by other players while open (not close)
|
// Set value to current + 1. Ensures consistency later when resetting.
|
||||||
// increases by 1 when animation is scheduled to complete, even though animation does not occur
|
SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile,
|
||||||
// Can't set value lower than 0, it corrects.
|
SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile) + 1);
|
||||||
// Could schedule a reset for a couple seconds later when the animation finishes.
|
|
||||||
// Could say "that's good enough" and get some rest
|
|
||||||
int value = SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile);
|
|
||||||
if (value < 1) {
|
|
||||||
SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile, 2);
|
|
||||||
}
|
|
||||||
container = new SilentContainerShulkerBox(player.inventory, (IInventory) tile, player);
|
container = new SilentContainerShulkerBox(player.inventory, (IInventory) tile, player);
|
||||||
// Reset value to start
|
|
||||||
SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(tile instanceof IInventory)) {
|
||||||
|
// TODO anyenderchest
|
||||||
|
p.sendMessage(ChatColor.RED + "Unhandled non-IInventory for block!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
boolean returnValue = false;
|
boolean returnValue = false;
|
||||||
|
final IInventory iInventory = (IInventory) tile;
|
||||||
|
|
||||||
if (!silentchest || container == null) {
|
if (!silentchest || container == null) {
|
||||||
player.openContainer((IInventory) tile);
|
player.openContainer(iInventory);
|
||||||
returnValue = true;
|
returnValue = true;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
int windowId = player.nextContainerCounter();
|
int windowId = player.nextContainerCounter();
|
||||||
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, "minecraft:chest", ((IInventory) tile).getScoreboardDisplayName(), ((IInventory) tile).getSize()));
|
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, iInventory.getName(), iInventory.getScoreboardDisplayName(), iInventory.getSize()));
|
||||||
player.activeContainer = container;
|
player.activeContainer = container;
|
||||||
player.activeContainer.windowId = windowId;
|
player.activeContainer.windowId = windowId;
|
||||||
player.activeContainer.addSlotListener(player);
|
player.activeContainer.addSlotListener(player);
|
||||||
returnValue = true;
|
returnValue = true;
|
||||||
|
if (tile instanceof TileEntityShulkerBox) {
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// TODO hacky
|
||||||
|
Object tile = world.getTileEntity(blockPosition);
|
||||||
|
if (!(tile instanceof TileEntityShulkerBox)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TileEntityShulkerBox box = (TileEntityShulkerBox) tile;
|
||||||
|
// Reset back - we added 1, and calling TileEntityShulkerBox#startOpen adds 1 more.
|
||||||
|
SilentContainerShulkerBox.setOpenValue(box,
|
||||||
|
SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile) - 2);
|
||||||
|
}
|
||||||
|
}.runTaskLater(Bukkit.getPluginManager().getPlugin("OpenInv"), 2);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
p.sendMessage(ChatColor.RED + "Error while sending silent chest.");
|
p.sendMessage(ChatColor.RED + "Error while sending silent chest.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,16 +188,31 @@ public class AnySilentContainer implements IAnySilentContainer {
|
|||||||
return isBlockedShulkerBox(world, blockPosition, block);
|
return isBlockedShulkerBox(world, blockPosition, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For reference, loot at net.minecraft.server.BlockChest
|
if (block instanceof BlockEnderChest) {
|
||||||
|
// Ender chests are not blocked by ocelots.
|
||||||
|
return world.getType(new BlockPosition(x, y + 1, z)).m();
|
||||||
|
}
|
||||||
|
|
||||||
// Check if chest is blocked or has an ocelot on top
|
// Check if chest is blocked or has an ocelot on top
|
||||||
if (world.getType(new BlockPosition(x, y + 1, z)).m() || hasOcelotOnTop(world, blockPosition)) {
|
if (isBlockedChest(world, blockPosition)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for matching adjacent chests that are blocked or have an ocelot on top
|
// Check for matching adjacent chests that are blocked or have an ocelot on top
|
||||||
for (EnumDirection localEnumDirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) {
|
for (EnumDirection localEnumDirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) {
|
||||||
BlockPosition localBlockPosition = blockPosition.shift(localEnumDirection);
|
BlockPosition localBlockPosition = blockPosition.shift(localEnumDirection);
|
||||||
if (isBlockedChest(world, block, localBlockPosition)) {
|
Block localBlock = world.getType(localBlockPosition).getBlock();
|
||||||
|
|
||||||
|
if (localBlock != block) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileEntity localTileEntity = world.getTileEntity(localBlockPosition);
|
||||||
|
if (!(localTileEntity instanceof TileEntityChest)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlockedChest(world, localBlockPosition)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,17 +237,14 @@ public class AnySilentContainer implements IAnySilentContainer {
|
|||||||
.a(enumDirection.getAdjacentX(), enumDirection.getAdjacentY(),
|
.a(enumDirection.getAdjacentX(), enumDirection.getAdjacentY(),
|
||||||
enumDirection.getAdjacentZ());
|
enumDirection.getAdjacentZ());
|
||||||
|
|
||||||
return !(world.b(axisAlignedBB.a(blockPosition.shift(enumDirection))));
|
return world.b(axisAlignedBB.a(blockPosition.shift(enumDirection)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isBlockedChest(World world, Block block, BlockPosition blockPosition) {
|
|
||||||
if (world.getType(blockPosition).getBlock() == block) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isBlockedChest(World world, BlockPosition blockPosition) {
|
||||||
|
// For reference, loot at net.minecraft.server.BlockChest
|
||||||
return world.getType(blockPosition.up()).m() || hasOcelotOnTop(world, blockPosition);
|
return world.getType(blockPosition.up()).m() || hasOcelotOnTop(world, blockPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,24 +38,13 @@ public class SilentContainerShulkerBox extends ContainerShulkerBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final TileEntityShulkerBox tile;
|
|
||||||
|
|
||||||
public SilentContainerShulkerBox(PlayerInventory playerInventory, IInventory iInventory,
|
public SilentContainerShulkerBox(PlayerInventory playerInventory, IInventory iInventory,
|
||||||
EntityHuman entityHuman) {
|
EntityHuman entityHuman) {
|
||||||
super(playerInventory, iInventory, entityHuman);
|
super(playerInventory, iInventory, entityHuman);
|
||||||
if (iInventory instanceof TileEntityShulkerBox) {
|
|
||||||
tile = (TileEntityShulkerBox) iInventory;
|
|
||||||
} else {
|
|
||||||
tile = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void b(EntityHuman entityHuman) {
|
public void b(EntityHuman entityHuman) {
|
||||||
if (tile != null) {
|
|
||||||
setOpenValue(tile, tile.getViewers().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerInventory playerinventory = entityHuman.inventory;
|
PlayerInventory playerinventory = entityHuman.inventory;
|
||||||
|
|
||||||
if (!playerinventory.getCarried().isEmpty()) {
|
if (!playerinventory.getCarried().isEmpty()) {
|
||||||
|
@@ -30,6 +30,7 @@ import net.minecraft.util.com.mojang.authlib.GameProfile;
|
|||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_7_R2.CraftServer;
|
import org.bukkit.craftbukkit.v1_7_R2.CraftServer;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Deprecated methods are used properly and will not change.
|
||||||
public class PlayerDataManager implements IPlayerDataManager {
|
public class PlayerDataManager implements IPlayerDataManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -107,7 +107,7 @@ public class OpenInv extends JavaPlugin {
|
|||||||
accessor = new InternalAccessor(this);
|
accessor = new InternalAccessor(this);
|
||||||
// Version check
|
// Version check
|
||||||
if (!accessor.initialize(getServer())) {
|
if (!accessor.initialize(getServer())) {
|
||||||
getLogger().info("Your version of CraftBukkit (" + accessor.getVersion() + ")is not supported.");
|
getLogger().info("Your version of CraftBukkit (" + accessor.getVersion() + ") is not supported.");
|
||||||
getLogger().info("Please look for an updated version of OpenInv.");
|
getLogger().info("Please look for an updated version of OpenInv.");
|
||||||
pm.disablePlugin(this);
|
pm.disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
|
@@ -10,30 +10,30 @@ commands:
|
|||||||
aliases: [oi, inv, open]
|
aliases: [oi, inv, open]
|
||||||
description: Open a player's inventory
|
description: Open a player's inventory
|
||||||
permission: OpenInv.*;OpenInv.openinv
|
permission: OpenInv.*;OpenInv.openinv
|
||||||
usage: |
|
usage: |-
|
||||||
/<command> - Open last person's inventory
|
/<command> - Open last person's inventory
|
||||||
/<command> <Player> - Open a player's inventory
|
/<command> <Player> - Open a player's inventory
|
||||||
openender:
|
openender:
|
||||||
aliases: [oe]
|
aliases: [oe]
|
||||||
description: Opens the enderchest of a player
|
description: Opens the enderchest of a player
|
||||||
permission: OpenInv.*;OpenInv.openender
|
permission: OpenInv.*;OpenInv.openender
|
||||||
usage: |
|
usage: |-
|
||||||
/<command> <Player> - Opens a player's enderchest
|
/<command> <Player> - Opens a player's enderchest
|
||||||
searchinv:
|
searchinv:
|
||||||
aliases: [si]
|
aliases: [si]
|
||||||
description: Search and list players having a specific item
|
description: Search and list players having a specific item
|
||||||
permission: OpenInv.*;OpenInv.search
|
permission: OpenInv.*;OpenInv.search
|
||||||
usage: |
|
usage: |-
|
||||||
/<command> <Item> [MinAmount] - Item can be the Item ID or the CraftBukkit Item Name, MinAmount is the minimum amount to be considered.
|
/<command> <Item> [MinAmount] - Item can be the Item ID or the CraftBukkit Item Name, MinAmount is the minimum amount to be considered.
|
||||||
silentchest:
|
silentchest:
|
||||||
aliases: [sc, silent]
|
aliases: [sc, silent]
|
||||||
description: Toggle silent chest function, which hides the animation of a chest when opened or closed, and suppresses the sound.
|
description: Toggle silent chest function, which hides the animation of a chest when opened or closed, and suppresses the sound.
|
||||||
permission: OpenInv.*;OpenInv.silent
|
permission: OpenInv.*;OpenInv.silent
|
||||||
usage: |
|
usage: |-
|
||||||
/<command> [Check] - Checks whether silent chest is enabled
|
/<command> [Check] - Checks whether silent chest is enabled
|
||||||
anychest:
|
anychest:
|
||||||
aliases: [ac]
|
aliases: [ac]
|
||||||
description: Toggle anychest function, which allows opening of blocked chests.
|
description: Toggle anychest function, which allows opening of blocked chests.
|
||||||
permission: OpenInv.*;OpenInv.anychest
|
permission: OpenInv.*;OpenInv.anychest
|
||||||
usage: |
|
usage: |-
|
||||||
/<command> [Check] - Checks whether anychest is enabled
|
/<command> [Check] - Checks whether anychest is enabled
|
||||||
|
Reference in New Issue
Block a user