BlockModBed.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. package me.km.blocks;
  2. import java.util.Random;
  3. import javax.annotation.Nullable;
  4. import net.minecraft.block.Block;
  5. import net.minecraft.block.BlockBed;
  6. import net.minecraft.block.BlockHorizontal;
  7. import net.minecraft.block.SoundType;
  8. import net.minecraft.block.material.EnumPushReaction;
  9. import net.minecraft.block.material.MapColor;
  10. import net.minecraft.block.material.Material;
  11. import net.minecraft.block.properties.IProperty;
  12. import net.minecraft.block.properties.PropertyBool;
  13. import net.minecraft.block.properties.PropertyEnum;
  14. import net.minecraft.block.state.BlockFaceShape;
  15. import net.minecraft.block.state.BlockStateContainer;
  16. import net.minecraft.block.state.IBlockState;
  17. import net.minecraft.entity.Entity;
  18. import net.minecraft.entity.EntityLivingBase;
  19. import net.minecraft.entity.player.EntityPlayer;
  20. import net.minecraft.entity.player.EntityPlayerMP;
  21. import net.minecraft.init.Biomes;
  22. import net.minecraft.init.Items;
  23. import net.minecraft.item.Item;
  24. import net.minecraft.item.ItemStack;
  25. import net.minecraft.tileentity.TileEntity;
  26. import net.minecraft.util.BlockRenderLayer;
  27. import net.minecraft.util.EnumBlockRenderType;
  28. import net.minecraft.util.EnumFacing;
  29. import net.minecraft.util.EnumHand;
  30. import net.minecraft.util.Mirror;
  31. import net.minecraft.util.Rotation;
  32. import net.minecraft.util.math.AxisAlignedBB;
  33. import net.minecraft.util.math.BlockPos;
  34. import net.minecraft.util.text.TextComponentTranslation;
  35. import net.minecraft.world.IBlockAccess;
  36. import net.minecraft.world.World;
  37. import net.minecraftforge.fml.relauncher.Side;
  38. import net.minecraftforge.fml.relauncher.SideOnly;
  39. public abstract class BlockModBed extends BlockHorizontal
  40. {
  41. public static final PropertyEnum<BlockBed.EnumPartType> PART = PropertyEnum.<BlockBed.EnumPartType>create("part", BlockBed.EnumPartType.class);
  42. public static final PropertyBool OCCUPIED = PropertyBool.create("occupied");
  43. protected String name;
  44. private SoundType type;
  45. private final Item drop;
  46. public BlockModBed(String name, String local, Item drop)
  47. {
  48. super(Material.CLOTH);
  49. this.setDefaultState(this.blockState.getBaseState().withProperty(PART, BlockBed.EnumPartType.FOOT)
  50. .withProperty(OCCUPIED, false));
  51. this.isBlockContainer = true;
  52. this.name = name;
  53. this.setRegistryName(name);
  54. super.setUnlocalizedName(local);
  55. this.type = SoundType.CLOTH;
  56. this.drop = drop;
  57. super.setHardness(0.2F);
  58. super.disableStats();
  59. }
  60. @Override
  61. public final BlockModBed setSoundType(SoundType sound)
  62. {
  63. this.type = sound;
  64. return this;
  65. }
  66. @Override
  67. public final SoundType getSoundType(IBlockState state, World w, BlockPos pos, Entity ent)
  68. {
  69. return type;
  70. }
  71. @Override
  72. public final boolean isBed(IBlockState state, IBlockAccess w, BlockPos pos, Entity p)
  73. {
  74. return true;
  75. }
  76. public float getLayingHigh()
  77. {
  78. return 0.6875f;
  79. }
  80. @Override
  81. public MapColor getMapColor(IBlockState state, IBlockAccess w, BlockPos pos)
  82. {
  83. return MapColor.CLOTH;
  84. }
  85. @Override
  86. public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
  87. {
  88. if(w.isRemote)
  89. {
  90. return true;
  91. }
  92. else
  93. {
  94. if(state.getValue(PART) != BlockBed.EnumPartType.HEAD)
  95. {
  96. pos = pos.offset(state.getValue(FACING));
  97. state = w.getBlockState(pos);
  98. if(state.getBlock() != this)
  99. {
  100. return true;
  101. }
  102. }
  103. if(w.provider.canRespawnHere() && w.getBiome(pos) != Biomes.HELL)
  104. {
  105. if((state.getValue(OCCUPIED)))
  106. {
  107. EntityPlayer entityplayer = this.getPlayerInBed(w, pos);
  108. if(entityplayer != null)
  109. {
  110. p.sendStatusMessage(new TextComponentTranslation("tile.bed.occupied", new Object[0]), true);
  111. return true;
  112. }
  113. state = state.withProperty(OCCUPIED, false);
  114. w.setBlockState(pos, state, 4);
  115. }
  116. EntityPlayer.SleepResult sleep = p.trySleep(pos);
  117. if(sleep == EntityPlayer.SleepResult.OK)
  118. {
  119. state = state.withProperty(OCCUPIED, true);
  120. // set players real position
  121. // subtracting normal bedsize, adding custom
  122. p.setPosition(p.posX, p.posY - 0.4375f + getLayingHigh(), p.posZ);
  123. // this is for evil servers which render the position wrong
  124. if(p instanceof EntityPlayerMP)
  125. {
  126. ((EntityPlayerMP) p).connection.setPlayerLocation(p.posX, p.posY, p.posZ, p.rotationYaw, p.rotationPitch);
  127. }
  128. // end
  129. w.setBlockState(pos, state, 4);
  130. return true;
  131. }
  132. else
  133. {
  134. switch (sleep)
  135. {
  136. case NOT_POSSIBLE_NOW:
  137. p.sendStatusMessage(new TextComponentTranslation("tile.bed.noSleep", new Object[0]), true);
  138. break;
  139. case NOT_SAFE:
  140. p.sendStatusMessage(new TextComponentTranslation("tile.bed.notSafe", new Object[0]), true);
  141. break;
  142. case TOO_FAR_AWAY:
  143. p.sendStatusMessage(new TextComponentTranslation("tile.bed.tooFarAway", new Object[0]), true);
  144. break;
  145. }
  146. return true;
  147. }
  148. }
  149. else
  150. {
  151. w.setBlockToAir(pos);
  152. BlockPos blockpos = pos.offset(state.getValue(FACING).getOpposite());
  153. if(w.getBlockState(blockpos).getBlock() == this)
  154. {
  155. w.setBlockToAir(blockpos);
  156. }
  157. w.newExplosion(null, pos.getX() + 0.5d, pos.getY() + 0.5d, pos.getZ() + 0.5d, 5, true, true);
  158. return true;
  159. }
  160. }
  161. }
  162. @Nullable
  163. private EntityPlayer getPlayerInBed(World w, BlockPos pos)
  164. {
  165. for(EntityPlayer p : w.playerEntities)
  166. {
  167. if (p.isPlayerSleeping() && p.bedLocation.equals(pos))
  168. {
  169. return p;
  170. }
  171. }
  172. return null;
  173. }
  174. @Override
  175. public boolean isFullCube(IBlockState state)
  176. {
  177. return false;
  178. }
  179. @Override
  180. public boolean isOpaqueCube(IBlockState state)
  181. {
  182. return false;
  183. }
  184. @Override
  185. public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance)
  186. {
  187. super.onFallenUpon(worldIn, pos, entityIn, fallDistance * 0.5F);
  188. }
  189. @Override
  190. public void onLanded(World w, Entity ent)
  191. {
  192. if(ent.isSneaking())
  193. {
  194. super.onLanded(w, ent);
  195. }
  196. else if(ent.motionY < 0)
  197. {
  198. ent.motionY = -ent.motionY * 0.66d;
  199. if(!(ent instanceof EntityLivingBase))
  200. {
  201. ent.motionY *= 0.8d;
  202. }
  203. }
  204. }
  205. @Override
  206. public void neighborChanged(IBlockState state, World w, BlockPos pos, Block blockIn, BlockPos fromPos)
  207. {
  208. EnumFacing enumfacing = (EnumFacing)state.getValue(FACING);
  209. if(state.getValue(PART) == BlockBed.EnumPartType.FOOT)
  210. {
  211. if(w.getBlockState(pos.offset(enumfacing)).getBlock() != this)
  212. {
  213. w.setBlockToAir(pos);
  214. }
  215. }
  216. else if(w.getBlockState(pos.offset(enumfacing.getOpposite())).getBlock() != this)
  217. {
  218. if(!w.isRemote)
  219. {
  220. this.dropBlockAsItem(w, pos, state, 0);
  221. }
  222. w.setBlockToAir(pos);
  223. }
  224. }
  225. @Override
  226. public Item getItemDropped(IBlockState state, Random rand, int fortune)
  227. {
  228. return state.getValue(PART) == BlockBed.EnumPartType.FOOT ? Items.AIR : drop;
  229. }
  230. @Override
  231. public abstract AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos);
  232. @SideOnly(Side.CLIENT)
  233. @Override
  234. public boolean hasCustomBreakingProgress(IBlockState state)
  235. {
  236. return true;
  237. }
  238. @Nullable
  239. public static BlockPos getSafeExitLocation(World w, BlockPos pos, int tries)
  240. {
  241. return net.minecraft.block.BlockBed.getSafeExitLocation(w, pos, tries);
  242. }
  243. @Override
  244. public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune)
  245. {
  246. if(state.getValue(PART) == BlockBed.EnumPartType.HEAD)
  247. {
  248. spawnAsEntity(worldIn, pos, new ItemStack(drop));
  249. }
  250. }
  251. @Override
  252. public EnumPushReaction getMobilityFlag(IBlockState state)
  253. {
  254. return EnumPushReaction.DESTROY;
  255. }
  256. @SideOnly(Side.CLIENT)
  257. @Override
  258. public BlockRenderLayer getBlockLayer()
  259. {
  260. return BlockRenderLayer.CUTOUT;
  261. }
  262. @Override
  263. public EnumBlockRenderType getRenderType(IBlockState state)
  264. {
  265. return EnumBlockRenderType.MODEL;
  266. }
  267. @Override
  268. public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state)
  269. {
  270. return new ItemStack(drop);
  271. }
  272. @Override
  273. public void onBlockHarvested(World w, BlockPos pos, IBlockState state, EntityPlayer player)
  274. {
  275. if(player.capabilities.isCreativeMode &&
  276. state.getValue(PART) == BlockBed.EnumPartType.FOOT)
  277. {
  278. BlockPos blockpos = pos.offset((EnumFacing)state.getValue(FACING));
  279. if(w.getBlockState(blockpos).getBlock() == this)
  280. {
  281. w.setBlockToAir(blockpos);
  282. }
  283. }
  284. }
  285. @Override
  286. public void harvestBlock(World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity te, ItemStack stack)
  287. {
  288. super.harvestBlock(worldIn, player, pos, state, null, stack);
  289. }
  290. @Override
  291. public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
  292. {
  293. super.breakBlock(worldIn, pos, state);
  294. }
  295. @Override
  296. public IBlockState getStateFromMeta(int meta)
  297. {
  298. EnumFacing f = EnumFacing.getHorizontal(meta);
  299. return (meta & 8) > 0 ? this.getDefaultState()
  300. .withProperty(PART, BlockBed.EnumPartType.HEAD)
  301. .withProperty(FACING, f)
  302. .withProperty(OCCUPIED, (meta & 4) > 0) :
  303. this.getDefaultState().withProperty(PART, BlockBed.EnumPartType.FOOT)
  304. .withProperty(FACING, f);
  305. }
  306. @Override
  307. public IBlockState getActualState(IBlockState state, IBlockAccess w, BlockPos pos)
  308. {
  309. if(state.getValue(PART) == BlockBed.EnumPartType.FOOT)
  310. {
  311. IBlockState iblockstate = w.getBlockState(pos.offset(state.getValue(FACING)));
  312. if(iblockstate.getBlock() == this)
  313. {
  314. state = state.withProperty(OCCUPIED, iblockstate.getValue(OCCUPIED));
  315. }
  316. }
  317. return state;
  318. }
  319. @Override
  320. public IBlockState withRotation(IBlockState state, Rotation rot)
  321. {
  322. return state.withProperty(FACING, rot.rotate(state.getValue(FACING)));
  323. }
  324. @Override
  325. public IBlockState withMirror(IBlockState state, Mirror mirrorIn)
  326. {
  327. return state.withRotation(mirrorIn.toRotation(state.getValue(FACING)));
  328. }
  329. @Override
  330. public int getMetaFromState(IBlockState state)
  331. {
  332. int i = 0;
  333. i = i | (state.getValue(FACING)).getHorizontalIndex();
  334. if(state.getValue(PART) == BlockBed.EnumPartType.HEAD)
  335. {
  336. i |= 8;
  337. if (state.getValue(OCCUPIED))
  338. {
  339. i |= 4;
  340. }
  341. }
  342. return i;
  343. }
  344. @Override
  345. public BlockFaceShape getBlockFaceShape(IBlockAccess p_193383_1_, IBlockState p_193383_2_, BlockPos p_193383_3_, EnumFacing p_193383_4_)
  346. {
  347. return BlockFaceShape.UNDEFINED;
  348. }
  349. @Override
  350. protected BlockStateContainer createBlockState()
  351. {
  352. return new BlockStateContainer(this, new IProperty[] {FACING, PART, OCCUPIED});
  353. }
  354. @SideOnly(Side.CLIENT)
  355. public static boolean isHeadPiece(int metadata)
  356. {
  357. return (metadata & 8) != 0;
  358. }
  359. }