Fix SPIGOT-2806 for silent chests, various other issues

* Fixed anychest message spam
* Changed AnySilentContainer again to reduce duplicate checks
 * #isAnyContainerNeeded should be checked before calling #activateContainer
 * reorganized ifs for doublechest creation into reverse-order if elses to prevent creating extras when someone's broken Minecraft and put 3+ adjacent to each other
* Fixed incorrect block being checked for anychest in 1.11
* Progress on SilentContainerShulkerBox (we're getting there!)

anychest and silentchest aren't quite at 100% after all these changes, but it won't be a priority to revisit logic until shulker boxes are done
This commit is contained in:
Jikoo
2016-11-22 03:30:34 -05:00
parent 476171911a
commit 454467c20e
42 changed files with 407 additions and 370 deletions

View File

@@ -19,6 +19,8 @@ package com.lishid.openinv.internal.v1_11_R1;
import com.lishid.openinv.internal.IAnySilentContainer;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
// Volatile
@@ -49,12 +51,16 @@ import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
public class AnySilentContainer implements IAnySilentContainer {
@Override
public boolean isAnySilentContainer(org.bukkit.block.BlockState block) {
return block instanceof org.bukkit.block.Chest || block instanceof org.bukkit.block.ShulkerBox;
public boolean isAnySilentContainer(org.bukkit.block.Block block) {
if (block.getType() == Material.ENDER_CHEST) {
return true;
}
BlockState state = block.getState();
return state instanceof org.bukkit.block.Chest || state instanceof org.bukkit.block.ShulkerBox;
}
@Override
public boolean activateContainer(Player p, boolean anychest, boolean silentchest, int x, int y, int z) {
public boolean activateContainer(Player p, boolean silentchest, int x, int y, int z) {
EntityPlayer player = ((CraftPlayer) p).getHandle();
World world = player.world;
@@ -79,10 +85,6 @@ public class AnySilentContainer implements IAnySilentContainer {
continue;
}
if (!anychest && isBlockedChest(world, localBlock, localBlockPosition)) {
return false;
}
TileEntity localTileEntity = world.getTileEntity(localBlockPosition);
if (!(localTileEntity instanceof TileEntityChest)) {
continue;
@@ -110,17 +112,21 @@ public class AnySilentContainer implements IAnySilentContainer {
}
if (block instanceof BlockShulkerBox) {
if (!anychest && isBlockedShulkerBox(world, blockPosition, block)) {
return false;
}
player.b(StatisticList.ae);
if (silentchest && tile instanceof TileEntityShulkerBox) {
// TODO: This fixes sound, but the box is then silent for anyone until the tile entity is recreated
SilentContainerShulkerBox.increaseOpenQuantity((TileEntityShulkerBox) tile);
container = new SilentContainerShulkerBox(player.inventory, ((IInventory) tile), player);
SilentContainerShulkerBox.decreaseOpenQuantity((TileEntityShulkerBox) tile);
// 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);
}
container = new SilentContainerShulkerBox(player.inventory, (IInventory) tile, player);
// Reset value to start
SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile, value);
}
}
@@ -203,7 +209,7 @@ public class AnySilentContainer implements IAnySilentContainer {
return false;
}
return world.getType(blockPosition).m() || hasOcelotOnTop(world, blockPosition);
return world.getType(blockPosition.up()).m() || hasOcelotOnTop(world, blockPosition);
}
private boolean hasOcelotOnTop(World world, BlockPosition blockPosition) {
@@ -226,7 +232,7 @@ public class AnySilentContainer implements IAnySilentContainer {
@Deprecated
@Override
public boolean activateChest(Player player, boolean anychest, boolean silentchest, int x, int y, int z) {
return !activateContainer(player, anychest, silentchest, x, y, z);
return !activateContainer(player, silentchest, x, y, z);
}
/**

View File

@@ -37,9 +37,10 @@ public class SilentContainerChest extends ContainerChest {
// Don't send close signal twice, might screw up
PlayerInventory playerinventory = entityHuman.inventory;
if (!playerinventory.getCarried().isEmpty()) {
entityHuman.drop(playerinventory.getCarried(), false);
if (playerinventory.getCarried() != ItemStack.a) {
ItemStack carried = playerinventory.getCarried();
playerinventory.setCarried(ItemStack.a);
entityHuman.drop(carried, false);
}
}
}

View File

@@ -21,29 +21,41 @@ public class SilentContainerShulkerBox extends ContainerShulkerBox {
return h;
}
public static void increaseOpenQuantity(TileEntityShulkerBox containerShulkerBox) {
public static void setOpenValue(TileEntityShulkerBox tileShulkerBox, Object value) {
try {
exposeOpenStatus().set(containerShulkerBox, ((Integer) exposeOpenStatus().get(containerShulkerBox)) + 1);
exposeOpenStatus().set(tileShulkerBox, value);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void decreaseOpenQuantity(TileEntityShulkerBox containerShulkerBox) {
public static Integer getOpenValue(TileEntityShulkerBox tileShulkerBox) {
try {
exposeOpenStatus().set(containerShulkerBox, ((Integer) exposeOpenStatus().get(containerShulkerBox)) - 1);
return (Integer) exposeOpenStatus().get(tileShulkerBox);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
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()) {