From fae5ff67ed4369d2a53f75615c6896e6b4a02175 Mon Sep 17 00:00:00 2001 From: Bartek Bok Date: Sat, 9 Jan 2016 22:39:12 +0100 Subject: [PATCH] Allow sleeping without bed --- .../entity/player/EntityPlayer.java.patch | 50 +++++--- .../event/ForgeEventFactory.java | 14 +++ .../player/SleepingLocationCheckEvent.java | 28 +++++ .../test/NoBedSleepingTest.java | 113 ++++++++++++++++++ 4 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java create mode 100644 src/test/java/net/minecraftforge/test/NoBedSleepingTest.java diff --git a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch b/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch index cdf492a0c..20055aad9 100644 --- a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch +++ b/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch @@ -296,9 +296,12 @@ if (!this.field_70170_p.field_72995_K) { if (this.func_70608_bn() || !this.func_70089_S()) -@@ -1352,7 +1440,7 @@ +@@ -1350,9 +1438,9 @@ - if (this.field_70170_p.func_175667_e(p_180469_1_)) + this.func_70105_a(0.2F, 0.2F); + +- if (this.field_70170_p.func_175667_e(p_180469_1_)) ++ if (this.field_70170_p.func_175667_e(p_180469_1_) && field_70170_p.func_180495_p(p_180469_1_).func_177230_c().isBed(field_70170_p, p_180469_1_, this)) { - EnumFacing enumfacing = (EnumFacing)this.field_70170_p.func_180495_p(p_180469_1_).func_177229_b(BlockDirectional.field_176387_N); + EnumFacing enumfacing = this.field_70170_p.func_180495_p(p_180469_1_).func_177230_c().getBedDirection(field_70170_p, p_180469_1_); @@ -323,12 +326,23 @@ if (blockpos == null) { -@@ -1448,14 +1537,14 @@ +@@ -1430,6 +1519,10 @@ + + this.func_70107_b((double)((float)blockpos.func_177958_n() + 0.5F), (double)((float)blockpos.func_177956_o() + 0.1F), (double)((float)blockpos.func_177952_p() + 0.5F)); + } ++ else ++ { ++ p_70999_3_ = false; ++ } + + this.field_71083_bS = false; + +@@ -1448,14 +1541,14 @@ private boolean func_175143_p() { - return this.field_70170_p.func_180495_p(this.field_71081_bT).func_177230_c() == Blocks.field_150324_C; -+ return this.field_70170_p.func_180495_p(this.field_71081_bT).func_177230_c().isBed(field_70170_p, field_71081_bT, this); ++ return net.minecraftforge.event.ForgeEventFactory.fireSleepingLocationCheck(this, field_71081_bT); } public static BlockPos func_180467_a(World p_180467_0_, BlockPos p_180467_1_, boolean p_180467_2_) @@ -340,7 +354,7 @@ { if (!p_180467_2_) { -@@ -1470,7 +1559,7 @@ +@@ -1470,16 +1563,16 @@ } else { @@ -349,16 +363,18 @@ } } -@@ -1479,7 +1568,7 @@ + @SideOnly(Side.CLIENT) + public float func_71051_bG() { - if (this.field_71081_bT != null) +- if (this.field_71081_bT != null) ++ if (this.field_71081_bT != null && field_70170_p.func_180495_p(field_71081_bT).func_177230_c().isBed(field_70170_p, field_71081_bT, this)) { - EnumFacing enumfacing = (EnumFacing)this.field_70170_p.func_180495_p(this.field_71081_bT).func_177229_b(BlockDirectional.field_176387_N); + EnumFacing enumfacing = this.field_70170_p.func_180495_p(this.field_71081_bT).func_177230_c().getBedDirection(field_70170_p, field_71081_bT); switch (enumfacing) { -@@ -1519,16 +1608,24 @@ +@@ -1519,16 +1612,24 @@ public BlockPos func_180470_cg() { @@ -385,7 +401,7 @@ if (p_180473_1_ != null) { this.field_71077_c = p_180473_1_; -@@ -1712,6 +1809,10 @@ +@@ -1712,6 +1813,10 @@ super.func_180430_e(p_180430_1_, p_180430_2_); } @@ -396,7 +412,7 @@ } protected void func_71061_d_() -@@ -1735,6 +1836,7 @@ +@@ -1735,6 +1840,7 @@ } EntityList.EntityEggInfo entitylist$entityegginfo = (EntityList.EntityEggInfo)EntityList.field_75627_a.get(Integer.valueOf(EntityList.func_75619_a(p_70074_1_))); @@ -404,7 +420,7 @@ if (entitylist$entityegginfo != null) { -@@ -1847,6 +1949,8 @@ +@@ -1847,6 +1953,8 @@ { if (p_71008_1_ != this.field_71074_e) { @@ -413,7 +429,7 @@ this.field_71074_e = p_71008_1_; this.field_71072_f = p_71008_2_; -@@ -1918,6 +2022,10 @@ +@@ -1918,6 +2026,10 @@ this.field_181016_an = p_71049_1_.field_181016_an; this.field_181017_ao = p_71049_1_.field_181017_ao; this.field_181018_ap = p_71049_1_.field_181018_ap; @@ -424,7 +440,7 @@ } else if (this.field_70170_p.func_82736_K().func_82766_b("keepInventory")) { -@@ -1931,6 +2039,18 @@ +@@ -1931,6 +2043,18 @@ this.field_175152_f = p_71049_1_.field_175152_f; this.field_71078_a = p_71049_1_.field_71078_a; this.func_70096_w().func_75692_b(10, Byte.valueOf(p_71049_1_.func_70096_w().func_75683_a(10))); @@ -443,7 +459,7 @@ } protected boolean func_70041_e_() -@@ -1968,7 +2088,14 @@ +@@ -1968,7 +2092,14 @@ public void func_70062_b(int p_70062_1_, ItemStack p_70062_2_) { @@ -459,7 +475,7 @@ } @SideOnly(Side.CLIENT) -@@ -2013,7 +2140,10 @@ +@@ -2013,7 +2144,10 @@ public IChatComponent func_145748_c_() { @@ -471,7 +487,7 @@ ichatcomponent.func_150256_b().func_150241_a(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/msg " + this.func_70005_c_() + " ")); ichatcomponent.func_150256_b().func_150209_a(this.func_174823_aP()); ichatcomponent.func_150256_b().func_179989_a(this.func_70005_c_()); -@@ -2022,7 +2152,7 @@ +@@ -2022,7 +2156,7 @@ public float func_70047_e() { @@ -480,7 +496,7 @@ if (this.func_70608_bn()) { -@@ -2155,6 +2285,136 @@ +@@ -2155,6 +2289,136 @@ this.field_175153_bG = p_175150_1_; } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index 108408914..1d51ff412 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -65,6 +65,7 @@ import net.minecraftforge.event.entity.player.PlayerSetSpawnEvent; import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; import net.minecraftforge.event.entity.player.PlayerUseItemEvent; import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; +import net.minecraftforge.event.entity.player.SleepingLocationCheckEvent; import net.minecraftforge.event.entity.player.UseHoeEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent.NeighborNotifyEvent; @@ -500,4 +501,17 @@ public class ForgeEventFactory MinecraftForge.EVENT_BUS.post(event); return event.getCapabilities().size() > 0 ? new CapabilityDispatcher(event.getCapabilities(), parent) : null; } + + public static boolean fireSleepingLocationCheck(EntityPlayer player, BlockPos sleepingLocation) + { + SleepingLocationCheckEvent evt = new SleepingLocationCheckEvent(player, sleepingLocation); + MinecraftForge.EVENT_BUS.post(evt); + + Result canContinueSleep = evt.getResult(); + if (canContinueSleep == Result.DEFAULT) + return player.worldObj.getBlockState(player.playerLocation).getBlock().isBed(player.worldObj, player.playerLocation, player); + else + return canContinueSleep == Result.ALLOW; + } + } diff --git a/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java b/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java new file mode 100644 index 000000000..0dbd832e1 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java @@ -0,0 +1,28 @@ +package net.minecraftforge.event.entity.player; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.BlockPos; +import net.minecraftforge.fml.common.eventhandler.Event.HasResult; + +/** + * This event is fired when game checks, if sleeping player should be still considered "in bed".
+ * Failing this check will cause player to wake up.
+ * + * This event has a result. {@link HasResult}
+ * + * setResult(ALLOW) informs game that player is still "in bed"
+ * setResult(DEFAULT) causes game to check {@link net.minecraft.block.Block#isBed(net.minecraft.world.IBlockAccess, BlockPos, net.minecraft.entity.Entity)} instead + */ +@HasResult +public class SleepingLocationCheckEvent extends PlayerEvent +{ + + public final BlockPos sleepingLocation; + + public SleepingLocationCheckEvent(EntityPlayer player, BlockPos sleepingLocation) + { + super(player); + this.sleepingLocation = sleepingLocation; + } + +} diff --git a/src/test/java/net/minecraftforge/test/NoBedSleepingTest.java b/src/test/java/net/minecraftforge/test/NoBedSleepingTest.java new file mode 100644 index 000000000..c231fcd2c --- /dev/null +++ b/src/test/java/net/minecraftforge/test/NoBedSleepingTest.java @@ -0,0 +1,113 @@ +package net.minecraftforge.test; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayer.EnumStatus; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraftforge.common.IExtendedEntityProperties; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.EntityEvent.EntityConstructing; +import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; +import net.minecraftforge.event.entity.player.SleepingLocationCheckEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.Event.Result; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry; + +@Mod(modid = NoBedSleepingTest.MODID, version = NoBedSleepingTest.VERSION) +public class NoBedSleepingTest +{ + public static final String MODID = "ForgeDebugNoBedSleeping"; + public static final String VERSION = "1.0"; + + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent event) + { + GameRegistry.registerItem(ItemSleepingPill.instance, ItemSleepingPill.name); + MinecraftForge.EVENT_BUS.register(new EventHandler()); + } + + public static class EventHandler + { + @SubscribeEvent + public void onEntityConstruct(EntityConstructing evt) + { + evt.entity.registerExtendedProperties(ExtendedPropertySleeping.name, new ExtendedPropertySleeping()); + } + + @SubscribeEvent + public void onBedCheck(SleepingLocationCheckEvent evt) + { + final IExtendedEntityProperties property = evt.entityPlayer.getExtendedProperties(ExtendedPropertySleeping.name); + if (property instanceof ExtendedPropertySleeping && ((ExtendedPropertySleeping) property).isSleeping) + evt.setResult(Result.ALLOW); + } + + @SubscribeEvent + public void onWakeUp(PlayerWakeUpEvent evt) + { + final IExtendedEntityProperties property = evt.entityPlayer.getExtendedProperties(ExtendedPropertySleeping.name); + if (property instanceof ExtendedPropertySleeping) + ((ExtendedPropertySleeping) property).isSleeping = false; + } + } + + public static class ExtendedPropertySleeping implements IExtendedEntityProperties + { + private static final String TAG_NAME = "IsSleepingExt"; + + public static final String name = "is_sleeping"; + + public boolean isSleeping; + + @Override + public void saveNBTData(NBTTagCompound compound) + { + compound.setBoolean(TAG_NAME, isSleeping); + } + + @Override + public void loadNBTData(NBTTagCompound compound) + { + this.isSleeping = compound.getBoolean(TAG_NAME); + } + + @Override + public void init(Entity entity, World world) + { + } + + } + + public static class ItemSleepingPill extends Item + { + public static final ItemSleepingPill instance = new ItemSleepingPill(); + public static final String name = "sleeping_pill"; + + private ItemSleepingPill() + { + setCreativeTab(CreativeTabs.tabMisc); + setUnlocalizedName(MODID + ":" + name); + } + + public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn) + { + if (!worldIn.isRemote) + { + final EnumStatus result = playerIn.trySleep(playerIn.getPosition()); + if (result == EnumStatus.OK) + { + final IExtendedEntityProperties property = playerIn.getExtendedProperties(ExtendedPropertySleeping.name); + if (property instanceof ExtendedPropertySleeping) + ((ExtendedPropertySleeping) property).isSleeping = true; + } + } + return itemStackIn; + } + } +}