BlockFluidBase.java 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package me.km.fluids;
  2. import java.util.Random;
  3. import javax.annotation.Nonnull;
  4. import me.km.KajetansMod;
  5. import me.km.utils.ReflectionUtils;
  6. import net.minecraft.block.Block;
  7. import net.minecraft.block.material.Material;
  8. import net.minecraft.block.state.IBlockState;
  9. import net.minecraft.creativetab.CreativeTabs;
  10. import net.minecraft.init.Blocks;
  11. import net.minecraft.init.SoundEvents;
  12. import net.minecraft.util.EnumFacing;
  13. import net.minecraft.util.EnumParticleTypes;
  14. import net.minecraft.util.SoundCategory;
  15. import net.minecraft.util.math.BlockPos;
  16. import net.minecraft.world.World;
  17. import net.minecraftforge.fluids.BlockFluidClassic;
  18. import net.minecraftforge.fluids.Fluid;
  19. public abstract class BlockFluidBase extends BlockFluidClassic
  20. {
  21. public BlockFluidBase(Fluid fluid, Material material)
  22. {
  23. super(fluid, material);
  24. this.setRegistryName(fluid.getName());
  25. super.setUnlocalizedName(fluid.getUnlocalizedName());
  26. super.setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
  27. }
  28. public void registerBlockModel()
  29. {
  30. KajetansMod.proxy.registerFluidModel(this);
  31. }
  32. @Override
  33. public void updateTick(@Nonnull World w, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull Random rand)
  34. {
  35. if(!isSourceBlock(w, pos))
  36. {
  37. int adjacentSourceBlocks =
  38. (isSourceBlock(w, pos.north()) ? 1 : 0) +
  39. (isSourceBlock(w, pos.south()) ? 1 : 0) +
  40. (isSourceBlock(w, pos.east()) ? 1 : 0) +
  41. (isSourceBlock(w, pos.west()) ? 1 : 0);
  42. if (adjacentSourceBlocks >= 2 && (w.getBlockState(pos.up(densityDir)).getMaterial().isSolid() || isSourceBlock(w, pos.up(densityDir))))
  43. {
  44. w.setBlockState(pos, state.withProperty(LEVEL, 0));
  45. }
  46. }
  47. int quantaRemaining = quantaPerBlock - state.getValue(LEVEL);
  48. int expQuanta;
  49. // check adjacent block levels if non-source
  50. if(quantaRemaining < quantaPerBlock)
  51. {
  52. if (w.getBlockState(pos.add( 0, -densityDir, 0)).getBlock() == this ||
  53. w.getBlockState(pos.add(-1, -densityDir, 0)).getBlock() == this ||
  54. w.getBlockState(pos.add( 1, -densityDir, 0)).getBlock() == this ||
  55. w.getBlockState(pos.add( 0, -densityDir, -1)).getBlock() == this ||
  56. w.getBlockState(pos.add( 0, -densityDir, 1)).getBlock() == this)
  57. {
  58. expQuanta = quantaPerBlock - 1;
  59. }
  60. else
  61. {
  62. int maxQuanta = -100;
  63. maxQuanta = getLargerQuanta(w, pos.add(-1, 0, 0), maxQuanta);
  64. maxQuanta = getLargerQuanta(w, pos.add( 1, 0, 0), maxQuanta);
  65. maxQuanta = getLargerQuanta(w, pos.add( 0, 0, -1), maxQuanta);
  66. maxQuanta = getLargerQuanta(w, pos.add( 0, 0, 1), maxQuanta);
  67. expQuanta = maxQuanta - 1;
  68. }
  69. // decay calculation
  70. if(expQuanta != quantaRemaining)
  71. {
  72. quantaRemaining = expQuanta;
  73. if(expQuanta <= 0)
  74. {
  75. w.setBlockToAir(pos);
  76. }
  77. else
  78. {
  79. w.setBlockState(pos, state.withProperty(LEVEL, quantaPerBlock - expQuanta), 2);
  80. w.scheduleUpdate(pos, this, tickRate);
  81. w.notifyNeighborsOfStateChange(pos, this, false);
  82. }
  83. }
  84. }
  85. // This is a "source" block, set meta to zero, and send a server only update
  86. else if(quantaRemaining >= quantaPerBlock)
  87. {
  88. w.setBlockState(pos, this.getDefaultState(), 2);
  89. }
  90. // Flow vertically if possible
  91. if(canDisplace(w, pos.up(densityDir)))
  92. {
  93. BlockPos bpos = pos.up(densityDir);
  94. Block b = w.getBlockState(bpos).getBlock();
  95. if(b == Blocks.LAVA || b == Blocks.WATER || b == Blocks.FLOWING_LAVA || b == Blocks.FLOWING_WATER ||
  96. (b != this && b instanceof net.minecraftforge.fluids.BlockFluidBase))
  97. {
  98. w.setBlockState(bpos, getFlownOnMixingBlock(b, ReflectionUtils.getBlockMaterial(b)));
  99. this.triggerMixEffects(w, bpos);
  100. return;
  101. }
  102. flowIntoBlock(w, pos.up(densityDir), 1);
  103. return;
  104. }
  105. // Flow outward if possible
  106. int flowMeta = quantaPerBlock - quantaRemaining + 1;
  107. if(flowMeta >= quantaPerBlock)
  108. {
  109. return;
  110. }
  111. if(isSourceBlock(w, pos) || !isFlowingVertically(w, pos))
  112. {
  113. if(w.getBlockState(pos.down(densityDir)).getBlock() == this)
  114. {
  115. flowMeta = 1;
  116. }
  117. boolean flowTo[] = getOptimalFlowDirections(w, pos);
  118. if(flowTo[0]) flowIntoBlock(w, pos.add(-1, 0, 0), flowMeta);
  119. if(flowTo[1]) flowIntoBlock(w, pos.add( 1, 0, 0), flowMeta);
  120. if(flowTo[2]) flowIntoBlock(w, pos.add( 0, 0, -1), flowMeta);
  121. if(flowTo[3]) flowIntoBlock(w, pos.add( 0, 0, 1), flowMeta);
  122. }
  123. }
  124. @Override
  125. public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state)
  126. {
  127. checkForMixing(worldIn, pos, state);
  128. super.onBlockAdded(worldIn, pos, state);
  129. }
  130. @Override
  131. public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos)
  132. {
  133. checkForMixing(worldIn, pos, state);
  134. super.neighborChanged(state, worldIn, pos, blockIn, fromPos);
  135. }
  136. private boolean checkForMixing(World worldIn, BlockPos pos, IBlockState state)
  137. {
  138. boolean flag = false;
  139. Block b = null;
  140. for (EnumFacing enumfacing : EnumFacing.values())
  141. {
  142. if (enumfacing != EnumFacing.DOWN)
  143. {
  144. b = worldIn.getBlockState(pos.offset(enumfacing)).getBlock();
  145. if(b == Blocks.LAVA || b == Blocks.WATER || b == Blocks.FLOWING_LAVA || b == Blocks.FLOWING_WATER ||
  146. (b != this && b instanceof net.minecraftforge.fluids.BlockFluidBase))
  147. {
  148. flag = true;
  149. break;
  150. }
  151. }
  152. }
  153. if(flag)
  154. {
  155. Integer integer = state.getValue(LEVEL);
  156. if (integer == 0)
  157. {
  158. worldIn.setBlockState(pos, getStrongMixingBlock(b, ReflectionUtils.getBlockMaterial(b)));
  159. this.triggerMixEffects(worldIn, pos);
  160. return true;
  161. }
  162. else
  163. {
  164. worldIn.setBlockState(pos, getWeakMixingBlock(b, ReflectionUtils.getBlockMaterial(b)));
  165. this.triggerMixEffects(worldIn, pos);
  166. return true;
  167. }
  168. }
  169. return false;
  170. }
  171. protected abstract IBlockState getStrongMixingBlock(Block b, Material m);
  172. protected abstract IBlockState getWeakMixingBlock(Block b, Material m);
  173. protected abstract IBlockState getFlownOnMixingBlock(Block b, Material m);
  174. protected void triggerMixEffects(World worldIn, BlockPos pos)
  175. {
  176. double d0 = pos.getX();
  177. double d1 = pos.getY();
  178. double d2 = pos.getZ();
  179. worldIn.playSound(null, pos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (worldIn.rand.nextFloat() - worldIn.rand.nextFloat()) * 0.8F);
  180. for (int i = 0; i < 8; ++i)
  181. {
  182. worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0 + Math.random(), d1 + 1.2d, d2 + Math.random(), 0, 0, 0, new int[0]);
  183. }
  184. }
  185. }