Skip to content

Commit

Permalink
Almost entirely functional silent shulker boxes
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Jikoo committed Nov 24, 2016
1 parent 454467c commit fcc9a4c
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 46 deletions.
2 changes: 1 addition & 1 deletion OpenInv/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<artifactId>openinv</artifactId>
<name>OpenInv</name>
<version>2.5.3-SNAPSHOT</version>
<version>2.5.4</version>

<profiles>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
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
public boolean activateChest(Player player, boolean anychest, boolean silentchest, int x, int y, int z);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.bukkit.block.Block;
import org.bukkit.entity.Player;

@SuppressWarnings("deprecation")
public interface IAnySilentContainer extends IAnySilentChest {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@

import com.lishid.openinv.internal.IAnySilentContainer;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

// Volatile
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
import net.minecraft.server.v1_11_R1.Block;
import net.minecraft.server.v1_11_R1.BlockChest;
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.BlockShulkerBox;
import net.minecraft.server.v1_11_R1.Container;
Expand Down Expand Up @@ -62,16 +65,22 @@ public boolean isAnySilentContainer(org.bukkit.block.Block block) {
@Override
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();
World world = player.world;
BlockPosition blockPosition = new BlockPosition(x, y, z);
final World world = player.world;
final BlockPosition blockPosition = new BlockPosition(x, y, z);
Object tile = world.getTileEntity(blockPosition);

if (tile == null) {
return false;
}

Block block = world.getType(new BlockPosition(x, y, z)).getBlock();
Block block = world.getType(blockPosition).getBlock();
Container container = null;

if (block instanceof BlockChest) {
Expand Down Expand Up @@ -115,41 +124,56 @@ else if (blockChest.g == Type.TRAP) {
player.b(StatisticList.ae);

if (silentchest && tile instanceof TileEntityShulkerBox) {
// TODO: End state allows for silent opening by other players while open (not close)
// increases by 1 when animation is scheduled to complete, even though animation does not occur
// Can't set value lower than 0, it corrects.
// 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);
}
// Set value to current + 1. Ensures consistency later when resetting.
SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile,
SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile) + 1);

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;
final IInventory iInventory = (IInventory) tile;

if (!silentchest || container == null) {
player.openContainer((IInventory) tile);
player.openContainer(iInventory);
returnValue = true;
} else {
try {
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.windowId = windowId;
player.activeContainer.addSlotListener(player);
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) {
e.printStackTrace();
p.sendMessage(ChatColor.RED + "Error while sending silent chest.");
}
}


return returnValue;
}

Expand All @@ -164,16 +188,31 @@ public boolean isAnyContainerNeeded(Player p, int x, int y, int z) {
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
if (world.getType(new BlockPosition(x, y + 1, z)).m() || hasOcelotOnTop(world, blockPosition)) {
if (isBlockedChest(world, blockPosition)) {
return true;
}

// Check for matching adjacent chests that are blocked or have an ocelot on top
for (EnumDirection localEnumDirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) {
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;
}
}
Expand All @@ -198,17 +237,14 @@ private boolean isBlockedShulkerBox(World world, BlockPosition blockPosition, Bl
.a(enumDirection.getAdjacentX(), enumDirection.getAdjacentY(),
enumDirection.getAdjacentZ());

return !(world.b(axisAlignedBB.a(blockPosition.shift(enumDirection))));
return world.b(axisAlignedBB.a(blockPosition.shift(enumDirection)));
}

return true;
return false;
}

private boolean isBlockedChest(World world, Block block, BlockPosition blockPosition) {
if (world.getType(blockPosition).getBlock() == block) {
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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,13 @@ public static Integer getOpenValue(TileEntityShulkerBox tileShulkerBox) {
}
}

private final TileEntityShulkerBox tile;

public SilentContainerShulkerBox(PlayerInventory playerInventory, IInventory iInventory,
EntityHuman entityHuman) {
super(playerInventory, iInventory, entityHuman);
if (iInventory instanceof TileEntityShulkerBox) {
tile = (TileEntityShulkerBox) iInventory;
} else {
tile = null;
}
}

@Override
public void b(EntityHuman entityHuman) {
if (tile != null) {
setOpenValue(tile, tile.getViewers().size());
}

PlayerInventory playerinventory = entityHuman.inventory;

if (!playerinventory.getCarried().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import org.bukkit.craftbukkit.v1_7_R2.CraftServer;

@SuppressWarnings("deprecation") // Deprecated methods are used properly and will not change.
public class PlayerDataManager implements IPlayerDataManager {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public void onEnable() {
accessor = new InternalAccessor(this);
// Version check
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.");
pm.disablePlugin(this);
return;
Expand Down
10 changes: 5 additions & 5 deletions OpenInvPlugin/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,30 @@ commands:
aliases: [oi, inv, open]
description: Open a player's inventory
permission: OpenInv.*;OpenInv.openinv
usage: |
usage: |-
/<command> - Open last person's inventory
/<command> <Player> - Open a player's inventory
openender:
aliases: [oe]
description: Opens the enderchest of a player
permission: OpenInv.*;OpenInv.openender
usage: |
usage: |-
/<command> <Player> - Opens a player's enderchest
searchinv:
aliases: [si]
description: Search and list players having a specific item
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.
silentchest:
aliases: [sc, silent]
description: Toggle silent chest function, which hides the animation of a chest when opened or closed, and suppresses the sound.
permission: OpenInv.*;OpenInv.silent
usage: |
usage: |-
/<command> [Check] - Checks whether silent chest is enabled
anychest:
aliases: [ac]
description: Toggle anychest function, which allows opening of blocked chests.
permission: OpenInv.*;OpenInv.anychest
usage: |
usage: |-
/<command> [Check] - Checks whether anychest is enabled

0 comments on commit fcc9a4c

Please sign in to comment.