SPIGOT-4560: Add HumanEntity.sleep and related APIs

This commit is contained in:
md_5 2019-01-02 14:41:31 +11:00
parent a83828623b
commit 8e65d8df6c
3 changed files with 121 additions and 52 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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<Plugin> getPluginWeakReference(@Nullable Plugin plugin) {
return (plugin == null) ? null : pluginWeakReferences.computeIfAbsent(plugin, WeakReference::new);