From b0c9d7cce9fec1419c60fcf074f94427579e6fc7 Mon Sep 17 00:00:00 2001 From: David Quintana Date: Wed, 11 Sep 2019 16:00:32 +0200 Subject: [PATCH] Some (sadly breaking) improvements to the Fluid API (#6110) * Some (sadly breaking) improvements to the API, after feedback and concerns provided by users: - Moved calculation of the translation key to the FluidAttributes constructor, so that builders can be shared between still & flowing sub-fluids. - Moved biome-based coloring to a dedicated FluidAttributes.Water variant, which is not used by default. - Added logic to automatically gather fluid textures into the list of textures to bake. - Patched BucketItem and FlowingFluidBlock to avoid eager access to the fluid objects. - Added a ForgeFlowingFluid class, as a more user-friendly way to construct a new FlowingFluid. --- .../block/FlowingFluidBlock.java.patch | 68 ++++- .../renderer/FluidBlockRenderer.java.patch | 4 +- .../renderer/model/ModelBakery.java.patch | 17 +- .../net/minecraft/fluid/Fluid.java.patch | 22 +- .../net/minecraft/item/BucketItem.java.patch | 33 ++- .../client/ForgeHooksClient.java | 14 +- .../client/model/ModelDynBucket.java | 2 +- .../net/minecraftforge/common/ForgeHooks.java | 28 +- .../fluids/FluidAttributes.java | 85 +++--- .../net/minecraftforge/fluids/FluidStack.java | 2 +- .../fluids/ForgeFlowingFluid.java | 263 ++++++++++++++++++ .../capability/CapabilityFluidHandler.java | 46 +-- .../fluids/capability/IFluidHandler.java | 2 +- .../minecraftforge/fml/RegistryObject.java | 2 +- .../registries/IRegistryDelegate.java | 4 +- .../META-INF/fieldtomethodtransformers.js | 24 ++ .../debug/fluid/NewFluidTest.java | 198 ++----------- 17 files changed, 537 insertions(+), 277 deletions(-) create mode 100644 src/main/java/net/minecraftforge/fluids/ForgeFlowingFluid.java diff --git a/patches/minecraft/net/minecraft/block/FlowingFluidBlock.java.patch b/patches/minecraft/net/minecraft/block/FlowingFluidBlock.java.patch index de1c3e4a6..931283c01 100644 --- a/patches/minecraft/net/minecraft/block/FlowingFluidBlock.java.patch +++ b/patches/minecraft/net/minecraft/block/FlowingFluidBlock.java.patch @@ -1,6 +1,49 @@ --- a/net/minecraft/block/FlowingFluidBlock.java +++ b/net/minecraft/block/FlowingFluidBlock.java -@@ -121,13 +121,13 @@ +@@ -30,9 +30,11 @@ + + public class FlowingFluidBlock extends Block implements IBucketPickupHandler { + public static final IntegerProperty field_176367_b = BlockStateProperties.field_208132_ag; +- protected final FlowingFluid field_204517_c; ++ private final FlowingFluid field_204517_c; + private final List field_212565_c; + ++ // Forge: Use the constructor that takes a supplier ++ @Deprecated + protected FlowingFluidBlock(FlowingFluid p_i49014_1_, Block.Properties p_i49014_2_) { + super(p_i49014_2_); + this.field_204517_c = p_i49014_1_; +@@ -45,8 +47,21 @@ + + this.field_212565_c.add(p_i49014_1_.func_207207_a(8, true)); + this.func_180632_j(this.field_176227_L.func_177621_b().func_206870_a(field_176367_b, Integer.valueOf(0))); ++ fluidStateCacheInitialized = true; ++ supplier = p_i49014_1_.delegate; + } + ++ /** ++ * @param supplier A fluid supplier such as {@link net.minecraftforge.fml.RegistryObject} ++ */ ++ public FlowingFluidBlock(java.util.function.Supplier supplier, Block.Properties p_i48368_1_) { ++ super(p_i48368_1_); ++ this.field_204517_c = null; ++ this.field_212565_c = Lists.newArrayList(); ++ this.func_180632_j(this.field_176227_L.func_177621_b().func_206870_a(field_176367_b, Integer.valueOf(0))); ++ this.supplier = supplier; ++ } ++ + public void func_196265_a(BlockState p_196265_1_, World p_196265_2_, BlockPos p_196265_3_, Random p_196265_4_) { + p_196265_2_.func_204610_c(p_196265_3_).func_206891_b(p_196265_2_, p_196265_3_, p_196265_4_); + } +@@ -61,6 +76,7 @@ + + public IFluidState func_204507_t(BlockState p_204507_1_) { + int i = p_204507_1_.func_177229_b(field_176367_b); ++ if (!fluidStateCacheInitialized) initFluidStateCache(); + return this.field_212565_c.get(Math.min(i, 8)); + } + +@@ -121,13 +137,13 @@ if (flag) { IFluidState ifluidstate = p_204515_1_.func_204610_c(p_204515_2_); if (ifluidstate.func_206889_d()) { @@ -16,3 +59,26 @@ this.func_180688_d(p_204515_1_, p_204515_2_); return false; } +@@ -160,4 +176,22 @@ + } + + } ++ ++ // Forge start ++ private final java.util.function.Supplier supplier; ++ public FlowingFluid getFluid() { ++ return (FlowingFluid)supplier.get(); ++ } ++ ++ private boolean fluidStateCacheInitialized; ++ protected void initFluidStateCache() { ++ this.field_212565_c.add(getFluid().func_207204_a(false)); ++ ++ for(int i = 1; i < 8; ++i) { ++ this.field_212565_c.add(getFluid().func_207207_a(8 - i, false)); ++ } ++ ++ this.field_212565_c.add(getFluid().func_207207_a(8, true)); ++ fluidStateCacheInitialized = true; ++ } + } diff --git a/patches/minecraft/net/minecraft/client/renderer/FluidBlockRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/FluidBlockRenderer.java.patch index 058dc1307..9e2072009 100644 --- a/patches/minecraft/net/minecraft/client/renderer/FluidBlockRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/FluidBlockRenderer.java.patch @@ -1,15 +1,13 @@ --- a/net/minecraft/client/renderer/FluidBlockRenderer.java +++ b/net/minecraft/client/renderer/FluidBlockRenderer.java -@@ -58,8 +58,10 @@ +@@ -58,8 +58,8 @@ public boolean func_217638_a(IEnviromentBlockReader p_217638_1_, BlockPos p_217638_2_, BufferBuilder p_217638_3_, IFluidState p_217638_4_) { boolean flag = p_217638_4_.func_206884_a(FluidTags.field_206960_b); - TextureAtlasSprite[] atextureatlassprite = flag ? this.field_178272_a : this.field_178271_b; - int i = flag ? 16777215 : BiomeColors.func_217612_c(p_217638_1_, p_217638_2_); + TextureAtlasSprite[] atextureatlassprite = net.minecraftforge.client.ForgeHooksClient.getFluidSprites(p_217638_1_, p_217638_2_, p_217638_4_); -+ if (atextureatlassprite == null) atextureatlassprite = flag ? this.field_178272_a : this.field_178271_b; + int i = p_217638_4_.func_206886_c().getAttributes().getColor(p_217638_1_, p_217638_2_); -+ if (i < 0) i = flag ? 16777215 : BiomeColors.func_217612_c(p_217638_1_, p_217638_2_); float f = (float)(i >> 16 & 255) / 255.0F; float f1 = (float)(i >> 8 & 255) / 255.0F; float f2 = (float)(i & 255) / 255.0F; diff --git a/patches/minecraft/net/minecraft/client/renderer/model/ModelBakery.java.patch b/patches/minecraft/net/minecraft/client/renderer/model/ModelBakery.java.patch index 99a427737..cf326a00a 100644 --- a/patches/minecraft/net/minecraft/client/renderer/model/ModelBakery.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/model/ModelBakery.java.patch @@ -9,7 +9,7 @@ private final Map field_217851_H = Maps.newHashMap(); private final Map field_217852_I = Maps.newHashMap(); private final AtlasTexture.SheetData field_217853_J; -@@ -142,6 +142,12 @@ +@@ -142,12 +142,19 @@ p_i51735_4_.func_219895_b("special"); this.func_217843_a(new ModelResourceLocation("minecraft:trident_in_hand#inventory")); @@ -22,7 +22,14 @@ p_i51735_4_.func_219895_b("textures"); Set set = Sets.newLinkedHashSet(); Set set1 = this.field_217851_H.values().stream().flatMap((p_217838_2_) -> { -@@ -288,7 +294,7 @@ + return p_217838_2_.func_209559_a(this::func_209597_a, set).stream(); + }).collect(Collectors.toSet()); + set1.addAll(field_177602_b); ++ net.minecraftforge.client.ForgeHooksClient.gatherFluidTextures(set1); + set.forEach((p_217833_0_) -> { + field_177603_c.warn("Unable to resolve texture reference: {}", (Object)p_217833_0_); + }); +@@ -288,7 +295,7 @@ { lvt_13_5_ = this.field_177598_f.func_199004_b(resourcelocation1).stream().map((p_217839_1_) -> { try (InputStream inputstream = p_217839_1_.func_199027_b()) { @@ -31,7 +38,7 @@ return pair2; } catch (Exception exception1) { throw new ModelBakery.BlockStateDefinitionException(String.format("Exception loading blockstate definition: '%s' in resourcepack: '%s': %s", p_217839_1_.func_199029_a(), p_217839_1_.func_199026_d(), exception1.getMessage())); -@@ -404,7 +410,12 @@ +@@ -404,7 +411,12 @@ @Nullable public IBakedModel func_217845_a(ResourceLocation p_217845_1_, ISprite p_217845_2_) { @@ -45,7 +52,7 @@ if (this.field_217850_G.containsKey(triple)) { return this.field_217850_G.get(triple); } else { -@@ -412,11 +423,11 @@ +@@ -412,11 +424,11 @@ if (iunbakedmodel instanceof BlockModel) { BlockModel blockmodel = (BlockModel)iunbakedmodel; if (blockmodel.func_178310_f() == field_177606_o) { @@ -59,7 +66,7 @@ this.field_217850_G.put(triple, ibakedmodel); return ibakedmodel; } -@@ -471,6 +482,10 @@ +@@ -471,6 +483,10 @@ return this.field_225367_M; } diff --git a/patches/minecraft/net/minecraft/fluid/Fluid.java.patch b/patches/minecraft/net/minecraft/fluid/Fluid.java.patch index 825abc00c..a670923c7 100644 --- a/patches/minecraft/net/minecraft/fluid/Fluid.java.patch +++ b/patches/minecraft/net/minecraft/fluid/Fluid.java.patch @@ -9,7 +9,7 @@ public static final ObjectIntIdentityMap field_207201_d = new ObjectIntIdentityMap<>(); protected final StateContainer field_207202_e; private IFluidState field_207200_b; -@@ -102,4 +102,40 @@ +@@ -102,4 +102,26 @@ } public abstract VoxelShape func_215664_b(IFluidState p_215664_1_, IBlockReader p_215664_2_, BlockPos p_215664_3_); @@ -24,29 +24,15 @@ + * Creates the fluid attributes object, which will contain all the extended values for the fluid that aren't part of the vanilla system. + * Do not call this from outside. To retrieve the values use {@link Fluid#getAttributes()} + */ -+ protected net.minecraftforge.fluids.FluidAttributes createAttributes(Fluid fluid) ++ protected net.minecraftforge.fluids.FluidAttributes createAttributes() + { -+ if (fluid instanceof EmptyFluid) -+ return net.minecraftforge.fluids.FluidAttributes.builder("empty", null, null) -+ .vanillaColor().density(0).temperature(0).luminosity(0).viscosity(0).density(0).build(); -+ if (fluid instanceof WaterFluid) -+ return net.minecraftforge.fluids.FluidAttributes.builder("water", -+ new net.minecraft.util.ResourceLocation("block/water_still"), -+ new net.minecraft.util.ResourceLocation("block/water_flow")) -+ .overlay(new net.minecraft.util.ResourceLocation("block/water_overlay")) -+ .vanillaColor().build(); -+ if (fluid instanceof LavaFluid) -+ return net.minecraftforge.fluids.FluidAttributes.builder("lava", -+ new net.minecraft.util.ResourceLocation("block/lava_still"), -+ new net.minecraft.util.ResourceLocation("block/lava_flow")) -+ .vanillaColor().luminosity(15).density(3000).viscosity(6000).temperature(1300).build(); -+ throw new RuntimeException("Mod fluids must override createAttributes."); ++ return net.minecraftforge.common.ForgeHooks.createVanillaFluidAttributes(this); + } + + private net.minecraftforge.fluids.FluidAttributes forgeFluidAttributes; + public final net.minecraftforge.fluids.FluidAttributes getAttributes() { + if (forgeFluidAttributes == null) -+ forgeFluidAttributes = createAttributes(this); ++ forgeFluidAttributes = createAttributes(); + return forgeFluidAttributes; + } } diff --git a/patches/minecraft/net/minecraft/item/BucketItem.java.patch b/patches/minecraft/net/minecraft/item/BucketItem.java.patch index 416a39120..d253969e7 100644 --- a/patches/minecraft/net/minecraft/item/BucketItem.java.patch +++ b/patches/minecraft/net/minecraft/item/BucketItem.java.patch @@ -1,6 +1,26 @@ --- a/net/minecraft/item/BucketItem.java +++ b/net/minecraft/item/BucketItem.java -@@ -38,6 +38,8 @@ +@@ -30,14 +30,28 @@ + public class BucketItem extends Item { + private final Fluid field_77876_a; + ++ // Forge: Use the other constructor that takes a Supplier ++ @Deprecated + public BucketItem(Fluid p_i49025_1_, Item.Properties p_i49025_2_) { + super(p_i49025_2_); + this.field_77876_a = p_i49025_1_; ++ this.fluidSupplier = p_i49025_1_.delegate; + } + ++ /** ++ * @param supplier A fluid supplier such as {@link net.minecraftforge.fml.RegistryObject} ++ */ ++ public BucketItem(java.util.function.Supplier supplier, Item.Properties builder) { ++ super(builder); ++ this.field_77876_a = null; ++ this.fluidSupplier = supplier; ++ } ++ public ActionResult func_77659_a(World p_77659_1_, PlayerEntity p_77659_2_, Hand p_77659_3_) { ItemStack itemstack = p_77659_2_.func_184586_b(p_77659_3_); RayTraceResult raytraceresult = func_219968_a(p_77659_1_, p_77659_2_, this.field_77876_a == Fluids.field_204541_a ? RayTraceContext.FluidMode.SOURCE_ONLY : RayTraceContext.FluidMode.NONE); @@ -9,24 +29,24 @@ if (raytraceresult.func_216346_c() == RayTraceResult.Type.MISS) { return new ActionResult<>(ActionResultType.PASS, itemstack); } else if (raytraceresult.func_216346_c() != RayTraceResult.Type.BLOCK) { -@@ -52,7 +54,10 @@ +@@ -52,7 +66,10 @@ Fluid fluid = ((IBucketPickupHandler)blockstate1.func_177230_c()).func_204508_a(p_77659_1_, blockpos, blockstate1); if (fluid != Fluids.field_204541_a) { p_77659_2_.func_71029_a(Stats.field_75929_E.func_199076_b(this)); - p_77659_2_.func_184185_a(fluid.func_207185_a(FluidTags.field_206960_b) ? SoundEvents.field_187633_N : SoundEvents.field_187630_M, 1.0F, 1.0F); + -+ SoundEvent soundevent = field_77876_a.getAttributes().getEmptySound(); ++ SoundEvent soundevent = this.field_77876_a.getAttributes().getEmptySound(); + if(soundevent == null) soundevent = fluid.func_207185_a(FluidTags.field_206960_b) ? SoundEvents.field_187633_N : SoundEvents.field_187630_M; + p_77659_2_.func_184185_a(soundevent, 1.0F, 1.0F); ItemStack itemstack1 = this.func_150910_a(itemstack, p_77659_2_, fluid.func_204524_b()); if (!p_77659_1_.field_72995_K) { CriteriaTriggers.field_204813_j.func_204817_a((ServerPlayerEntity)p_77659_2_, new ItemStack(fluid.func_204524_b())); -@@ -147,7 +152,18 @@ +@@ -147,7 +164,19 @@ } protected void func_203791_b(@Nullable PlayerEntity p_203791_1_, IWorld p_203791_2_, BlockPos p_203791_3_) { - SoundEvent soundevent = this.field_77876_a.func_207185_a(FluidTags.field_206960_b) ? SoundEvents.field_187627_L : SoundEvents.field_187624_K; -+ SoundEvent soundevent = field_77876_a.getAttributes().getEmptySound(); ++ SoundEvent soundevent = this.field_77876_a.getAttributes().getEmptySound(); + if(soundevent == null) soundevent = this.field_77876_a.func_207185_a(FluidTags.field_206960_b) ? SoundEvents.field_187627_L : SoundEvents.field_187624_K; p_203791_2_.func_184133_a(p_203791_1_, p_203791_3_, soundevent, SoundCategory.BLOCKS, 1.0F, 1.0F); } @@ -39,5 +59,6 @@ + return super.initCapabilities(stack, nbt); + } + -+ public Fluid getFluid() { return field_77876_a; } ++ private final java.util.function.Supplier fluidSupplier; ++ public Fluid getFluid() { return fluidSupplier.get(); } } diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index 7c7313750..6d2a56a7f 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -146,6 +146,7 @@ import net.minecraftforge.resource.ReloadRequirements; import net.minecraftforge.resource.SelectiveReloadStateHandler; import net.minecraftforge.resource.VanillaResourceType; import net.minecraftforge.versions.forge.ForgeVersion; +import net.minecraftforge.registries.ForgeRegistries; public class ForgeHooksClient { @@ -380,9 +381,9 @@ public class ForgeHooksClient } @SuppressWarnings("deprecation") - public static Matrix4f getMatrix(net.minecraft.client.renderer.model.ItemTransformVec3f transform) + public static Matrix4f getMatrix(ItemTransformVec3f transform) { - javax.vecmath.Matrix4f m = new javax.vecmath.Matrix4f(), t = new javax.vecmath.Matrix4f(); + Matrix4f m = new Matrix4f(), t = new Matrix4f(); m.setIdentity(); m.setTranslation(TRSRTransformation.toVecmath(transform.translation)); t.setIdentity(); @@ -569,6 +570,13 @@ public class ForgeHooksClient }; } + public static void gatherFluidTextures(Set textures) + { + ForgeRegistries.FLUIDS.getValues().stream() + .flatMap(f -> f.getAttributes().getTextures()) + .forEach(textures::add); + } + private static class LightGatheringTransformer extends QuadGatheringTransformer { private static final VertexFormat FORMAT = new VertexFormat().addElement(DefaultVertexFormats.TEX_2F).addElement(DefaultVertexFormats.TEX_2S); @@ -702,7 +710,7 @@ public class ForgeHooksClient private static void drawSegment(ItemRenderer ri, int baseColor, ItemStack stack, List segment, int bl, int sl, boolean shade, boolean updateLighting, boolean updateShading) { BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer(); - bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.ITEM); + bufferbuilder.begin(GL_QUADS, DefaultVertexFormats.ITEM); float lastBl = GLX.lastBrightnessX; float lastSl = GLX.lastBrightnessY; diff --git a/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java b/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java index 188deed6a..981fb7755 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java +++ b/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java @@ -442,7 +442,7 @@ public final class ModelDynBucket implements IUnbakedModel BakedDynBucket model = (BakedDynBucket)originalModel; Fluid fluid = fluidStack.getFluid(); - String name = fluid.getAttributes().getName(); + String name = fluid.getRegistryName().toString(); if (!model.cache.containsKey(name)) { diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 77cd21524..ed03a2f82 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -45,6 +45,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import net.minecraft.advancements.Advancement; import net.minecraft.block.Block; +import net.minecraft.fluid.*; import net.minecraft.util.CachedBlockInfo; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; @@ -59,9 +60,7 @@ import net.minecraft.entity.item.minecart.ContainerMinecartEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.fluid.IFluidState; import net.minecraft.block.Blocks; -import net.minecraft.fluid.Fluids; import net.minecraft.inventory.container.RepairContainer; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; @@ -141,6 +140,7 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.NoteBlockEvent; import net.minecraftforge.eventbus.api.Event.Result; +import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.registries.DataSerializerEntry; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistry; @@ -831,6 +831,30 @@ public class ForgeHooks return ret; } + public static FluidAttributes createVanillaFluidAttributes(Fluid fluid) + { + if (fluid instanceof EmptyFluid) + return net.minecraftforge.fluids.FluidAttributes.builder( + new net.minecraft.util.ResourceLocation("white"), + new net.minecraft.util.ResourceLocation("white")) + .translationKey("block.minecraft.air") + .color(0).density(0).temperature(0).luminosity(0).viscosity(0).build(fluid); + if (fluid instanceof WaterFluid) + return net.minecraftforge.fluids.FluidAttributes.Water.builder( + new net.minecraft.util.ResourceLocation("block/water_still"), + new net.minecraft.util.ResourceLocation("block/water_flow")) + .overlay(new net.minecraft.util.ResourceLocation("block/water_overlay")) + .translationKey("block.minecraft.water") + .color(0x3F76E4).build(fluid); + if (fluid instanceof LavaFluid) + return net.minecraftforge.fluids.FluidAttributes.builder( + new net.minecraft.util.ResourceLocation("block/lava_still"), + new net.minecraft.util.ResourceLocation("block/lava_flow")) + .translationKey("block.minecraft.lava") + .luminosity(15).density(3000).viscosity(6000).temperature(1300).build(fluid); + throw new RuntimeException("Mod fluids must override createAttributes."); + } + private static class LootTableContext { public final ResourceLocation name; diff --git a/src/main/java/net/minecraftforge/fluids/FluidAttributes.java b/src/main/java/net/minecraftforge/fluids/FluidAttributes.java index 60f39c550..415f20314 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidAttributes.java +++ b/src/main/java/net/minecraftforge/fluids/FluidAttributes.java @@ -22,30 +22,25 @@ package net.minecraftforge.fluids; import javax.annotation.Nullable; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; +import net.minecraft.fluid.Fluid; import net.minecraft.fluid.IFluidState; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.*; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.IEnviromentBlockReader; -import java.util.Locale; -import java.util.function.Supplier; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; -import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.SoundEvents; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.translation.LanguageMap; -import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraft.item.Rarity; +import net.minecraft.world.biome.BiomeColors; /** * Minecraft Forge Fluid Implementation @@ -67,10 +62,6 @@ public class FluidAttributes { public static final int BUCKET_VOLUME = 1000; - /** The unique identification name for this fluid. */ - private final String fluidName; - - /** The translation key of this fluid. */ private String translationKey; private final ResourceLocation stillTexture; @@ -141,10 +132,9 @@ public class FluidAttributes */ private final int color; - protected FluidAttributes(Builder builder) + protected FluidAttributes(Builder builder, Fluid fluid) { - this.fluidName = builder.name; - this.translationKey = builder.translationKey; + this.translationKey = builder.translationKey != null ? builder.translationKey : Util.makeTranslationKey("fluid", fluid.getRegistryName()); this.stillTexture = builder.stillTexture; this.flowingTexture = builder.flowingTexture; this.overlayTexture = builder.overlayTexture; @@ -159,11 +149,6 @@ public class FluidAttributes this.rarity = builder.rarity; } - public final String getName() - { - return this.fluidName; - } - public ItemStack getBucket(FluidStack stack) { return new ItemStack(stack.getFluid().getFilledBucket()); @@ -240,7 +225,7 @@ public class FluidAttributes } /** - * A FluidStack sensitive version of getUnlocalizedName + * A FluidStack sensitive version of getTranslationKey */ public String getTranslationKey(FluidStack stack) { @@ -248,11 +233,11 @@ public class FluidAttributes } /** - * Returns the unlocalized name of this fluid. + * Returns the translation key of this fluid. */ public String getTranslationKey() { - return "fluid." + this.translationKey; + return this.translationKey; } /* Default Accessors */ @@ -343,17 +328,23 @@ public class FluidAttributes public SoundEvent getFillSound(IEnviromentBlockReader world, BlockPos pos) { return getFillSound(); } public SoundEvent getEmptySound(IEnviromentBlockReader world, BlockPos pos) { return getEmptySound(); } - public static Builder builder(String name, ResourceLocation stillTexture, ResourceLocation flowingTexture) { - return new Builder(name, stillTexture, flowingTexture); + public static Builder builder(ResourceLocation stillTexture, ResourceLocation flowingTexture) { + return new Builder(stillTexture, flowingTexture, FluidAttributes::new); + } + + public Stream getTextures() + { + if (overlayTexture != null) + return Stream.of(stillTexture, flowingTexture, overlayTexture); + return Stream.of(stillTexture, flowingTexture); } public static class Builder { - private final String name; private final ResourceLocation stillTexture; private final ResourceLocation flowingTexture; private ResourceLocation overlayTexture; - private int color = 0xFFFFFF; + private int color = 0xFFFFFFFF; private String translationKey; private SoundEvent fillSound; private SoundEvent emptySound; @@ -363,12 +354,12 @@ public class FluidAttributes private int viscosity = 1000; private boolean isGaseous; private Rarity rarity = Rarity.COMMON; + private BiFunction factory; - protected Builder(String name, ResourceLocation stillTexture, ResourceLocation flowingTexture) { - this.name = name.toLowerCase(Locale.ENGLISH); + protected Builder(ResourceLocation stillTexture, ResourceLocation flowingTexture, BiFunction factory) { + this.factory = factory; this.stillTexture = stillTexture; this.flowingTexture = flowingTexture; - this.translationKey = "fluid." + this.name + ".name"; } public final Builder translationKey(String translationKey) @@ -383,12 +374,6 @@ public class FluidAttributes return this; } - public final Builder vanillaColor() - { - this.color = -1; - return this; - } - public final Builder overlay(ResourceLocation texture) { overlayTexture = texture; @@ -444,9 +429,27 @@ public class FluidAttributes return this; } - public FluidAttributes build() + public FluidAttributes build(Fluid fluid) { - return new FluidAttributes(this); + return factory.apply(this, fluid); + } + } + + public static class Water extends FluidAttributes + { + protected Water(Builder builder, Fluid fluid) + { + super(builder, fluid); + } + + @Override + public int getColor(IEnviromentBlockReader world, BlockPos pos) + { + return BiomeColors.getWaterColor(world, pos); + } + + public static Builder builder(ResourceLocation stillTexture, ResourceLocation flowingTexture) { + return new Builder(stillTexture, flowingTexture, Water::new); } } } diff --git a/src/main/java/net/minecraftforge/fluids/FluidStack.java b/src/main/java/net/minecraftforge/fluids/FluidStack.java index e6eac704f..0a7251e4b 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidStack.java +++ b/src/main/java/net/minecraftforge/fluids/FluidStack.java @@ -161,7 +161,7 @@ public class FluidStack } protected void updateEmpty() { - isEmpty = getRawFluid() == Fluids.EMPTY || amount == 0; + isEmpty = getRawFluid() == Fluids.EMPTY || amount <= 0; } public int getAmount() diff --git a/src/main/java/net/minecraftforge/fluids/ForgeFlowingFluid.java b/src/main/java/net/minecraftforge/fluids/ForgeFlowingFluid.java new file mode 100644 index 000000000..b2d82d220 --- /dev/null +++ b/src/main/java/net/minecraftforge/fluids/ForgeFlowingFluid.java @@ -0,0 +1,263 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fluids; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.FlowingFluidBlock; +import net.minecraft.fluid.FlowingFluid; +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.IFluidState; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.state.StateContainer; +import net.minecraft.tags.FluidTags; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorld; +import net.minecraft.world.IWorldReader; + +import javax.annotation.Nullable; +import java.util.function.Supplier; + +public abstract class ForgeFlowingFluid extends FlowingFluid +{ + private final Supplier flowing; + private final Supplier still; + @Nullable + private final Supplier bucket; + @Nullable + private final Supplier block; + private final FluidAttributes.Builder builder; + private final boolean canMultiply; + private final int slopeFindDistance; + private final int levelDecreasePerBlock; + private final float explosionResistance; + private final BlockRenderLayer renderLayer; + private final int tickRate; + + protected ForgeFlowingFluid(Properties properties) + { + this.flowing = properties.flowing; + this.still = properties.still; + this.builder = properties.attributes; + this.canMultiply = properties.canMultiply; + this.bucket = properties.bucket; + this.block = properties.block; + this.slopeFindDistance = properties.slopeFindDistance; + this.levelDecreasePerBlock = properties.levelDecreasePerBlock; + this.explosionResistance = properties.explosionResistance; + this.renderLayer = properties.renderLayer; + this.tickRate = properties.tickRate; + } + + @Override + public Fluid getFlowingFluid() + { + return flowing.get(); + } + + @Override + public Fluid getStillFluid() + { + return still.get(); + } + + @Override + protected boolean canSourcesMultiply() + { + return canMultiply; + } + + @Override + protected void beforeReplacingBlock(IWorld worldIn, BlockPos pos, BlockState state) + { + TileEntity tileentity = state.getBlock().hasTileEntity() ? worldIn.getTileEntity(pos) : null; + Block.spawnDrops(state, worldIn.getWorld(), pos, tileentity); + } + + @Override + protected int getSlopeFindDistance(IWorldReader worldIn) + { + return slopeFindDistance; + } + + @Override + protected int getLevelDecreasePerBlock(IWorldReader worldIn) + { + return levelDecreasePerBlock; + } + + @Override + public BlockRenderLayer getRenderLayer() + { + return renderLayer; + } + + @Override + public Item getFilledBucket() + { + return bucket != null ? bucket.get() : Items.AIR; + } + + @Override + protected boolean func_215665_a(IFluidState state, IBlockReader world, BlockPos pos, Fluid fluidIn, Direction direction) + { + // Based on the water implementation, may need to be overriden for mod fluids that shouldn't behave like water. + return direction == Direction.DOWN && !isEquivalentTo(fluidIn); + } + + @Override + public int getTickRate(IWorldReader world) + { + return tickRate; + } + + @Override + protected float getExplosionResistance() + { + return explosionResistance; + } + + @Override + protected BlockState getBlockState(IFluidState state) + { + if (block != null) + return block.get().getDefaultState().with(FlowingFluidBlock.LEVEL, getLevelFromState(state)); + return Blocks.AIR.getDefaultState(); + } + + @Override + public boolean isEquivalentTo(Fluid fluidIn) { + return fluidIn == still.get() || fluidIn == flowing.get(); + } + + @Override + protected FluidAttributes createAttributes() + { + return builder.build(this); + } + + public static class Flowing extends ForgeFlowingFluid + { + public Flowing(Properties properties) + { + super(properties); + setDefaultState(getStateContainer().getBaseState().with(LEVEL_1_8, 7)); + } + + protected void fillStateContainer(StateContainer.Builder builder) { + super.fillStateContainer(builder); + builder.add(LEVEL_1_8); + } + + public int getLevel(IFluidState state) { + return state.get(LEVEL_1_8); + } + + public boolean isSource(IFluidState state) { + return false; + } + } + + public static class Source extends ForgeFlowingFluid + { + public Source(Properties properties) + { + super(properties); + } + + public int getLevel(IFluidState state) { + return 8; + } + + public boolean isSource(IFluidState state) { + return true; + } + } + + public static class Properties + { + private Supplier still; + private Supplier flowing; + private FluidAttributes.Builder attributes; + private boolean canMultiply; + private Supplier bucket; + private Supplier block; + private int slopeFindDistance = 4; + private int levelDecreasePerBlock = 1; + private float explosionResistance = 1; + private BlockRenderLayer renderLayer = BlockRenderLayer.TRANSLUCENT; + private int tickRate = 5; + + public Properties(Supplier still, Supplier flowing, FluidAttributes.Builder attributes) + { + this.still = still; + this.flowing = flowing; + this.attributes = attributes; + } + + public Properties canMultiply() + { + canMultiply = true; + return this; + } + + public Properties bucket(Supplier bucket) + { + this.bucket = bucket; + return this; + } + + public Properties block(Supplier block) + { + this.block = block; + return this; + } + + public Properties slopeFindDistance(int slopeFindDistance) + { + this.slopeFindDistance = slopeFindDistance; + return this; + } + + public Properties levelDecreasePerBlock(int levelDecreasePerBlock) + { + this.levelDecreasePerBlock = levelDecreasePerBlock; + return this; + } + + public Properties explosionResistance(float explosionResistance) + { + this.explosionResistance = explosionResistance; + return this; + } + + public Properties renderLayer(BlockRenderLayer layer) + { + this.renderLayer = layer; + return this; + } + } +} diff --git a/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java b/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java index 4b87e6d3d..48182177d 100644 --- a/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java +++ b/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java @@ -19,10 +19,10 @@ package net.minecraftforge.fluids.capability; -import net.minecraft.item.Items; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.INBT; +import net.minecraft.item.Items; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.INBT; import net.minecraft.util.Direction; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; @@ -39,7 +39,7 @@ public class CapabilityFluidHandler @CapabilityInject(IFluidHandlerItem.class) public static Capability FLUID_HANDLER_ITEM_CAPABILITY = null; - public static void register() + public static void register() { CapabilityManager.INSTANCE.register(IFluidHandler.class, new DefaultFluidHandlerStorage<>(), () -> new FluidTank(FluidAttributes.BUCKET_VOLUME)); @@ -48,27 +48,27 @@ public class CapabilityFluidHandler private static class DefaultFluidHandlerStorage implements Capability.IStorage { @Override - public INBT writeNBT(Capability capability, T instance, Direction side) - { - if (!(instance instanceof FluidTank)) - throw new RuntimeException("Cannot serialize to an instance that isn't the default implementation"); - CompoundNBT nbt = new CompoundNBT(); - FluidTank tank = (FluidTank) instance; - FluidStack fluid = tank.getFluid(); - fluid.writeToNBT(nbt); - nbt.putInt("Capacity", tank.getCapacity()); - return nbt; - } + public INBT writeNBT(Capability capability, T instance, Direction side) + { + if (!(instance instanceof FluidTank)) + throw new RuntimeException("Cannot serialize to an instance that isn't the default implementation"); + CompoundNBT nbt = new CompoundNBT(); + FluidTank tank = (FluidTank) instance; + FluidStack fluid = tank.getFluid(); + fluid.writeToNBT(nbt); + nbt.putInt("Capacity", tank.getCapacity()); + return nbt; + } @Override - public void readNBT(Capability capability, T instance, Direction side, INBT nbt) - { - if (!(instance instanceof FluidTank)) - throw new RuntimeException("Cannot deserialize to an instance that isn't the default implementation"); - CompoundNBT tags = (CompoundNBT) nbt; - FluidTank tank = (FluidTank) instance; - tank.setCapacity(tags.getInt("Capacity")); - tank.readFromNBT(tags); - } + public void readNBT(Capability capability, T instance, Direction side, INBT nbt) + { + if (!(instance instanceof FluidTank)) + throw new RuntimeException("Cannot deserialize to an instance that isn't the default implementation"); + CompoundNBT tags = (CompoundNBT) nbt; + FluidTank tank = (FluidTank) instance; + tank.setCapacity(tags.getInt("Capacity")); + tank.readFromNBT(tags); + } } } diff --git a/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java b/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java index 81b584427..4b3f41535 100644 --- a/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java +++ b/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java @@ -65,7 +65,7 @@ public interface IFluidHandler *

* * @param tank Tank to query. - * @return FluidStack in a given tank. NULL if the tank is empty. + * @return FluidStack in a given tank. FluidStack.EMPTY if the tank is empty. */ @Nonnull FluidStack getFluidInTank(int tank); diff --git a/src/main/java/net/minecraftforge/fml/RegistryObject.java b/src/main/java/net/minecraftforge/fml/RegistryObject.java index 5f13b76b1..6b2240b64 100644 --- a/src/main/java/net/minecraftforge/fml/RegistryObject.java +++ b/src/main/java/net/minecraftforge/fml/RegistryObject.java @@ -35,7 +35,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; -public final class RegistryObject> +public final class RegistryObject> implements Supplier { private final ResourceLocation name; @Nullable diff --git a/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java b/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java index c216f3c3c..f4ddc656d 100644 --- a/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java +++ b/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java @@ -21,6 +21,8 @@ package net.minecraftforge.registries; import net.minecraft.util.ResourceLocation; +import java.util.function.Supplier; + /** * A registry delegate for holding references to items or blocks @@ -31,7 +33,7 @@ import net.minecraft.util.ResourceLocation; * * @param the type of thing we're holding onto */ -public interface IRegistryDelegate { +public interface IRegistryDelegate extends Supplier { /** * Get the referent pointed at by this delegate. This will be the currently active item or block, and will change * as world saves come and go. Note that item.delegate.get() may NOT be the same object as item, due to item and diff --git a/src/main/resources/META-INF/fieldtomethodtransformers.js b/src/main/resources/META-INF/fieldtomethodtransformers.js index 340b45dae..dfa2824a6 100644 --- a/src/main/resources/META-INF/fieldtomethodtransformers.js +++ b/src/main/resources/META-INF/fieldtomethodtransformers.js @@ -11,6 +11,30 @@ function initializeCoreMod() { asmapi.redirectFieldToMethod(classNode, fn, asmapi.mapMethod('func_188419_a')) return classNode; } + }, + 'flowingfluidblock': { + 'target': { + 'type': 'CLASS', + 'name': 'net.minecraft.block.FlowingFluidBlock' + }, + 'transformer': function(classNode) { + var asmapi=Java.type('net.minecraftforge.coremod.api.ASMAPI') + var fn = asmapi.mapField('field_204517_c') // fluid field - remap to mcp if necessary + asmapi.redirectFieldToMethod(classNode, fn, 'getFluid') // forge added method, doesn't need mapping + return classNode; + } + }, + 'bucketitem': { + 'target': { + 'type': 'CLASS', + 'name': 'net.minecraft.item.BucketItem' + }, + 'transformer': function(classNode) { + var asmapi=Java.type('net.minecraftforge.coremod.api.ASMAPI') + var fn = asmapi.mapField('field_77876_a') // containerFluid (wrongly named containedBlock) field - remap to mcp if necessary + asmapi.redirectFieldToMethod(classNode, fn, 'getFluid') // forge added method, doesn't need mapping + return classNode; + } } } } diff --git a/src/test/java/net/minecraftforge/debug/fluid/NewFluidTest.java b/src/test/java/net/minecraftforge/debug/fluid/NewFluidTest.java index b1535d422..eb2372178 100644 --- a/src/test/java/net/minecraftforge/debug/fluid/NewFluidTest.java +++ b/src/test/java/net/minecraftforge/debug/fluid/NewFluidTest.java @@ -27,81 +27,59 @@ import net.minecraft.block.material.Material; import net.minecraft.fluid.FlowingFluid; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluids; -import net.minecraft.fluid.IFluidState; -import net.minecraft.inventory.container.ContainerType; import net.minecraft.item.*; -import net.minecraft.state.StateContainer; -import net.minecraft.tags.FluidTags; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockReader; -import net.minecraft.world.IEnviromentBlockReader; -import net.minecraft.world.IWorld; -import net.minecraft.world.IWorldReader; -import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fluids.ForgeFlowingFluid; +import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.ObjectHolder; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; import org.apache.commons.lang3.Validate; -@Mod("new_fluid_test") +@Mod(NewFluidTest.MODID) public class NewFluidTest { + public static final String MODID = "new_fluid_test"; + public static final ResourceLocation FLUID_STILL = new ResourceLocation("minecraft:block/brown_mushroom_block"); public static final ResourceLocation FLUID_FLOWING = new ResourceLocation("minecraft:block/mushroom_stem"); - @ObjectHolder("forge:test_fluid") - public static FlowingFluid test_fluid; + public static final DeferredRegister BLOCKS = new DeferredRegister<>(ForgeRegistries.BLOCKS, MODID); + public static final DeferredRegister ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, MODID); + public static final DeferredRegister FLUIDS = new DeferredRegister<>(ForgeRegistries.FLUIDS, MODID); - @ObjectHolder("forge:test_fluid_flowing") - public static Fluid test_fluid_flowing; + public static RegistryObject test_fluid = FLUIDS.register("test_fluid", () -> + new ForgeFlowingFluid.Source(NewFluidTest.test_fluid_properties) + ); + public static RegistryObject test_fluid_flowing = FLUIDS.register("test_fluid_flowing", () -> + new ForgeFlowingFluid.Flowing(NewFluidTest.test_fluid_properties) + ); - @ObjectHolder("forge:test_fluid_bucket") - public static Item test_fluid_bucket; + public static RegistryObject test_fluid_block = BLOCKS.register("test_fluid_block", () -> + new FlowingFluidBlock(test_fluid, Block.Properties.create(Material.WATER).doesNotBlockMovement().hardnessAndResistance(100.0F).noDrops()) + ); + public static RegistryObject test_fluid_bucket = ITEMS.register("test_fluid_bucket", () -> + new BucketItem(test_fluid, new Item.Properties().containerItem(Items.BUCKET).maxStackSize(1).group(ItemGroup.MISC)) + ); - @ObjectHolder("forge:test_fluid_block") - public static Block test_fluid_block; + public static final ForgeFlowingFluid.Properties test_fluid_properties = + new ForgeFlowingFluid.Properties(test_fluid, test_fluid_flowing, FluidAttributes.builder(FLUID_STILL, FLUID_FLOWING).color(0x1080FF)) + .bucket(test_fluid_bucket).block(test_fluid_block); public NewFluidTest() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); - modEventBus.addGenericListener(Block.class, this::registerBlocks); - modEventBus.addGenericListener(Item.class, this::registerItems); - modEventBus.addGenericListener(Fluid.class, this::registerFluids); modEventBus.addListener(this::loadComplete); - } - public void registerBlocks(RegistryEvent.Register event) - { - (test_fluid = new MyFlowingFluid.Source()).setRegistryName("forge:test_fluid"); - test_fluid_flowing = new MyFlowingFluid.Flowing().setRegistryName("forge:test_fluid_flowing"); - - event.getRegistry().registerAll( - new FlowingFluidBlock(test_fluid, Block.Properties.create(Material.WATER).doesNotBlockMovement().hardnessAndResistance(100.0F).noDrops()) - {} - .setRegistryName("forge:test_fluid_block") - ); - } - - public void registerItems(RegistryEvent.Register event) - { - event.getRegistry().registerAll( - new BucketItem(test_fluid, new Item.Properties().containerItem(Items.BUCKET).maxStackSize(1).group(ItemGroup.MISC)).setRegistryName("forge:test_fluid_bucket") - ); - } - - public void registerFluids(RegistryEvent.Register event) - { - event.getRegistry().registerAll(test_fluid, test_fluid_flowing); + BLOCKS.register(modEventBus); + ITEMS.register(modEventBus); + FLUIDS.register(modEventBus); } public void loadComplete(FMLLoadCompleteEvent event) @@ -113,124 +91,4 @@ public class NewFluidTest ItemStack stack = Fluids.WATER.getAttributes().getBucket(new FluidStack(Fluids.WATER, 1)); Validate.isTrue(stack.getItem() == Fluids.WATER.getFilledBucket()); } - - private static final FluidAttributes ATTRIBUTES = FluidAttributes.builder("test_fluid", FLUID_STILL, FLUID_FLOWING).build(); - - private static abstract class MyFlowingFluid extends FlowingFluid - { - @Override - public Fluid getFlowingFluid() - { - return test_fluid_flowing; - } - - @Override - public Fluid getStillFluid() - { - return test_fluid; - } - - @Override - protected boolean canSourcesMultiply() - { - return false; - } - - @Override - protected void beforeReplacingBlock(IWorld worldIn, BlockPos pos, BlockState state) - { - // copied from the WaterFluid implementation - TileEntity tileentity = state.getBlock().hasTileEntity() ? worldIn.getTileEntity(pos) : null; - Block.spawnDrops(state, worldIn.getWorld(), pos, tileentity); - } - - @Override - protected int getSlopeFindDistance(IWorldReader worldIn) - { - return 4; - } - - @Override - protected int getLevelDecreasePerBlock(IWorldReader worldIn) - { - return 1; - } - - @Override - public BlockRenderLayer getRenderLayer() - { - return BlockRenderLayer.TRANSLUCENT; - } - - @Override - public Item getFilledBucket() - { - return test_fluid_bucket; - } - - @Override - protected boolean func_215665_a(IFluidState p_215665_1_, IBlockReader p_215665_2_, BlockPos p_215665_3_, Fluid p_215665_4_, Direction p_215665_5_) - { - return p_215665_5_ == Direction.DOWN && !p_215665_4_.isIn(FluidTags.WATER); - } - - @Override - public int getTickRate(IWorldReader p_205569_1_) - { - return 5; - } - - @Override - protected float getExplosionResistance() - { - return 1; - } - - @Override - protected BlockState getBlockState(IFluidState state) - { - return test_fluid_block.getDefaultState().with(FlowingFluidBlock.LEVEL, getLevelFromState(state)); - } - - @Override - public boolean isEquivalentTo(Fluid fluidIn) { - return fluidIn == test_fluid || fluidIn == test_fluid_flowing; - } - - @Override - protected FluidAttributes createAttributes(Fluid fluid) - { - return ATTRIBUTES; - } - - public static class Flowing extends MyFlowingFluid - { - { - setDefaultState(getStateContainer().getBaseState().with(LEVEL_1_8, 7)); - } - - protected void fillStateContainer(StateContainer.Builder builder) { - super.fillStateContainer(builder); - builder.add(LEVEL_1_8); - } - - public int getLevel(IFluidState p_207192_1_) { - return p_207192_1_.get(LEVEL_1_8); - } - - public boolean isSource(IFluidState state) { - return false; - } - } - - public static class Source extends MyFlowingFluid { - public int getLevel(IFluidState p_207192_1_) { - return 8; - } - - public boolean isSource(IFluidState state) { - return true; - } - } - } }