From 8e65d8df6cce009a76d0cb05e396f1bdc8c87c81 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 2 Jan 2019 14:41:31 +1100 Subject: [PATCH] SPIGOT-4560: Add HumanEntity.sleep and related APIs --- nms-patches/EntityHuman.patch | 20 +-- .../craftbukkit/entity/CraftHumanEntity.java | 122 ++++++++++++++++-- .../craftbukkit/entity/CraftPlayer.java | 31 ----- 3 files changed, 121 insertions(+), 52 deletions(-) diff --git a/nms-patches/EntityHuman.patch b/nms-patches/EntityHuman.patch index 63e7278b1f..8ddfc54e2b 100644 --- a/nms-patches/EntityHuman.patch +++ b/nms-patches/EntityHuman.patch @@ -330,7 +330,7 @@ return EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE; } -@@ -1140,6 +1267,26 @@ +@@ -1140,6 +1267,30 @@ } } } @@ -338,9 +338,13 @@ + } + + public EntityHuman.EnumBedResult a(BlockPosition blockposition) { ++ // CraftBukkit start - moved checks into separate method above, add force ++ return this.a(blockposition, false); ++ } ++ ++ public EntityHuman.EnumBedResult a(BlockPosition blockposition, boolean force) { + EnumDirection enumdirection = (EnumDirection) this.world.getType(blockposition).get(BlockFacingHorizontal.FACING); -+ // CraftBukkit start - moved checks into separate method above -+ EntityHuman.EnumBedResult bedResult = this.getBedResult(blockposition, enumdirection); ++ EntityHuman.EnumBedResult bedResult = force ? EnumBedResult.OK : this.getBedResult(blockposition, enumdirection); + + if (bedResult == EntityHuman.EnumBedResult.OTHER_PROBLEM) { + return bedResult; // return immediately if the result is not bypassable by plugins @@ -357,7 +361,7 @@ if (this.isPassenger()) { this.stopRiding(); -@@ -1206,6 +1353,24 @@ +@@ -1206,6 +1357,24 @@ this.world.everyoneSleeping(); } @@ -382,7 +386,7 @@ this.sleepTicks = flag ? 0 : 100; if (flag2) { this.setRespawnPosition(this.bedPosition, false); -@@ -1257,9 +1422,11 @@ +@@ -1257,9 +1426,11 @@ if (blockposition != null) { this.e = blockposition; this.f = flag; @@ -394,7 +398,7 @@ } } -@@ -1325,7 +1492,11 @@ +@@ -1325,7 +1496,11 @@ this.motY = d3 * 0.6D; this.aU = f3; this.fallDistance = 0.0F; @@ -407,7 +411,7 @@ } else { super.a(f, f1, f2); } -@@ -1625,13 +1796,17 @@ +@@ -1625,13 +1800,17 @@ } protected void releaseShoulderEntities() { @@ -430,7 +434,7 @@ if (!this.world.isClientSide && !nbttagcompound.isEmpty()) { Entity entity = EntityTypes.a(nbttagcompound, this.world); -@@ -1640,9 +1815,10 @@ +@@ -1640,9 +1819,10 @@ } entity.setPosition(this.locX, this.locY + 0.699999988079071D, this.locZ); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index be00d79e85..030c4d235a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -5,23 +5,46 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Set; - -import net.minecraft.server.*; - +import net.minecraft.server.BlockAnvil; +import net.minecraft.server.BlockBed; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.BlockWorkbench; +import net.minecraft.server.ChatComponentText; +import net.minecraft.server.Container; +import net.minecraft.server.CraftingManager; +import net.minecraft.server.Entity; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.EntityMinecartHopper; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.EntityTypes; +import net.minecraft.server.EnumMainHand; +import net.minecraft.server.IBlockData; +import net.minecraft.server.IInventory; +import net.minecraft.server.IMerchant; +import net.minecraft.server.IRecipe; +import net.minecraft.server.ITileEntityContainer; +import net.minecraft.server.ITileInventory; +import net.minecraft.server.ItemCooldown; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.PacketPlayInCloseWindow; +import net.minecraft.server.PacketPlayOutOpenWindow; +import net.minecraft.server.TileEntity; +import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBrewingStand; +import net.minecraft.server.TileEntityDispenser; +import net.minecraft.server.TileEntityDropper; +import net.minecraft.server.TileEntityEnchantTable; +import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.TileEntityShulkerBox; import org.bukkit.GameMode; import org.bukkit.Location; -import org.bukkit.inventory.MainHand; -import org.bukkit.inventory.Merchant; import org.bukkit.Material; import org.bukkit.NamespacedKey; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Villager; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; +import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.inventory.CraftContainer; import org.bukkit.craftbukkit.inventory.CraftInventory; @@ -29,10 +52,18 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer; import org.bukkit.craftbukkit.inventory.CraftInventoryView; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftMerchant; -import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Villager; +import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MainHand; +import org.bukkit.inventory.Merchant; +import org.bukkit.inventory.PlayerInventory; import org.bukkit.permissions.PermissibleBase; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionAttachment; @@ -97,6 +128,71 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return getHandle().sleepTicks; } + @Override + public Location getBedSpawnLocation() { + World world = getServer().getWorld(getHandle().spawnWorld); + BlockPosition bed = getHandle().getBed(); + + if (world != null && bed != null) { + bed = EntityHuman.getBed(((CraftWorld) world).getHandle(), bed, getHandle().isRespawnForced()); + if (bed != null) { + return new Location(world, bed.getX(), bed.getY(), bed.getZ()); + } + } + return null; + } + + @Override + public void setBedSpawnLocation(Location location) { + setBedSpawnLocation(location, false); + } + + @Override + public void setBedSpawnLocation(Location location, boolean override) { + if (location == null) { + getHandle().setRespawnPosition(null, override); + } else { + getHandle().setRespawnPosition(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), override); + getHandle().spawnWorld = location.getWorld().getName(); + } + } + + @Override + public boolean sleep(Location location, boolean force) { + Preconditions.checkArgument(location != null, "Location == null"); + Preconditions.checkArgument(location.getWorld().equals(getWorld()), "Cannot sleep across worlds"); + + BlockPosition blockposition = new BlockPosition(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + IBlockData iblockdata = getHandle().world.getType(blockposition); + if (!(iblockdata.getBlock() instanceof BlockBed)) { + return false; + } + + if (getHandle().a(blockposition) != EntityHuman.EnumBedResult.OK) { + return false; + } + + // From BlockBed + iblockdata = (IBlockData) iblockdata.set(BlockBed.OCCUPIED, true); + getHandle().world.setTypeAndData(blockposition, iblockdata, 4); + + return true; + } + + @Override + public void wakeup(boolean setSpawnLocation) { + Preconditions.checkState(isSleeping(), "Cannot wakeup if not sleeping"); + + getHandle().a(true, true, setSpawnLocation); + } + + @Override + public Location getBedLocation() { + Preconditions.checkState(isSleeping(), "Not sleeping"); + + return new Location(getWorld(), getHandle().bedPosition.getX(), getHandle().bedPosition.getY(), getHandle().bedPosition.getZ()); + } + @Override public String getName() { return getHandle().getName(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index b72fd02217..6613599a3f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -34,7 +34,6 @@ import net.minecraft.server.BlockPosition; import net.minecraft.server.ChatComponentText; import net.minecraft.server.Container; import net.minecraft.server.Entity; -import net.minecraft.server.EntityHuman; import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityPlayer; import net.minecraft.server.EntityTracker; @@ -75,7 +74,6 @@ import org.bukkit.BanList; import org.bukkit.Statistic; import org.bukkit.Material; import org.bukkit.Statistic.Type; -import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.conversations.Conversation; @@ -961,35 +959,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { getHandle().getFoodData().foodLevel = value; } - @Override - public Location getBedSpawnLocation() { - World world = getServer().getWorld(getHandle().spawnWorld); - BlockPosition bed = getHandle().getBed(); - - if (world != null && bed != null) { - bed = EntityHuman.getBed(((CraftWorld) world).getHandle(), bed, getHandle().isRespawnForced()); - if (bed != null) { - return new Location(world, bed.getX(), bed.getY(), bed.getZ()); - } - } - return null; - } - - @Override - public void setBedSpawnLocation(Location location) { - setBedSpawnLocation(location, false); - } - - @Override - public void setBedSpawnLocation(Location location, boolean override) { - if (location == null) { - getHandle().setRespawnPosition(null, override); - } else { - getHandle().setRespawnPosition(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), override); - getHandle().spawnWorld = location.getWorld().getName(); - } - } - @Nullable private static WeakReference getPluginWeakReference(@Nullable Plugin plugin) { return (plugin == null) ? null : pluginWeakReferences.computeIfAbsent(plugin, WeakReference::new);