diff --git a/src/generated/resources/data/forge/tags/fluids/milk.json b/src/generated/resources/data/forge/tags/fluids/milk.json new file mode 100644 index 0000000000..6aea35f487 --- /dev/null +++ b/src/generated/resources/data/forge/tags/fluids/milk.json @@ -0,0 +1,13 @@ +{ + "replace": false, + "values": [ + { + "id": "minecraft:milk", + "required": false + }, + { + "id": "minecraft:flowing_milk", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 143021e37d..ed5ba2efdb 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -24,13 +24,19 @@ import net.minecraft.command.arguments.ArgumentTypes; import net.minecraft.command.arguments.IArgumentSerializer; import net.minecraft.entity.ai.attributes.Attribute; import net.minecraft.entity.ai.attributes.RangedAttribute; +import net.minecraft.fluid.Fluid; +import net.minecraft.item.Items; import net.minecraft.util.SoundEvent; import net.minecraft.world.storage.IServerConfiguration; import net.minecraft.world.storage.SaveFormat; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.common.data.ForgeFluidTagsProvider; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fluids.FluidAttributes; +import net.minecraftforge.fluids.ForgeFlowingFluid; import net.minecraftforge.fml.*; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.*; @@ -41,6 +47,8 @@ import net.minecraftforge.fml.loading.progress.StartupMessageManager; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.server.command.EnumArgument; import net.minecraftforge.server.command.ModIdArgument; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; @@ -98,12 +106,24 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook public static final RegistryObject REACH_DISTANCE = ATTRIBUTES.register("reach_distance", () -> new RangedAttribute("generic.reachDistance", 5.0D, 0.0D, 1024.0D).setShouldWatch(true)); + private static boolean enableMilkFluid = false; + public static final RegistryObject MILK = RegistryObject.of(new ResourceLocation("milk"), ForgeRegistries.FLUIDS); + public static final RegistryObject FLOWING_MILK = RegistryObject.of(new ResourceLocation("flowing_milk"), ForgeRegistries.FLUIDS); + private static ForgeMod INSTANCE; public static ForgeMod getInstance() { return INSTANCE; } + /** + * Run this method during mod constructor to enable milk and add it to the Minecraft milk bucket + */ + public static void enableMilkFluid() + { + enableMilkFluid = true; + } + public ForgeMod() { LOGGER.info(FORGEMOD,"Forge mod loading, version {}, for MC {} with MCP {}", ForgeVersion.getVersion(), MCPVersion.getMCVersion(), MCPVersion.getMCPVersion()); @@ -120,6 +140,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook modEventBus.addListener(this::preInit); modEventBus.addListener(this::gatherData); modEventBus.addListener(this::loadComplete); + modEventBus.addGenericListener(Fluid.class, this::registerFluids); modEventBus.register(this); ATTRIBUTES.register(modEventBus); MinecraftForge.EVENT_BUS.addListener(this::serverStopping); @@ -205,9 +226,11 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook if (event.includeServer()) { - ForgeBlockTagsProvider blockTags = new ForgeBlockTagsProvider(gen, event.getExistingFileHelper()); + ExistingFileHelper existingFileHelper = event.getExistingFileHelper(); + ForgeBlockTagsProvider blockTags = new ForgeBlockTagsProvider(gen, existingFileHelper); gen.addProvider(blockTags); - gen.addProvider(new ForgeItemTagsProvider(gen, blockTags, event.getExistingFileHelper())); + gen.addProvider(new ForgeItemTagsProvider(gen, blockTags, existingFileHelper)); + gen.addProvider(new ForgeFluidTagsProvider(gen, existingFileHelper)); gen.addProvider(new ForgeRecipeProvider(gen)); gen.addProvider(new ForgeLootTableProvider(gen)); } @@ -232,6 +255,20 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook } } + // done in an event instead of deferred to only enable if a mod requests it + public void registerFluids(RegistryEvent.Register event) + { + if (enableMilkFluid) + { + // set up attributes + FluidAttributes.Builder attributesBuilder = FluidAttributes.builder(new ResourceLocation("forge", "block/milk_still"), new ResourceLocation("forge", "block/milk_flowing")).density(1024).viscosity(1024); + ForgeFlowingFluid.Properties properties = new ForgeFlowingFluid.Properties(MILK, FLOWING_MILK, attributesBuilder).bucket(() -> Items.MILK_BUCKET); + // register fluids + event.getRegistry().register(new ForgeFlowingFluid.Source(properties).setRegistryName(MILK.getId())); + event.getRegistry().register(new ForgeFlowingFluid.Flowing(properties).setRegistryName(FLOWING_MILK.getId())); + } + } + @SubscribeEvent //ModBus, can't use addListener due to nested genetics. public void registerRecipeSerialziers(RegistryEvent.Register> event) { diff --git a/src/main/java/net/minecraftforge/common/Tags.java b/src/main/java/net/minecraftforge/common/Tags.java index 94c7aacf45..b6375f8111 100644 --- a/src/main/java/net/minecraftforge/common/Tags.java +++ b/src/main/java/net/minecraftforge/common/Tags.java @@ -20,9 +20,11 @@ package net.minecraftforge.common; import net.minecraft.block.Block; +import net.minecraft.fluid.Fluid; import net.minecraft.item.DyeColor; import net.minecraft.item.Item; import net.minecraft.tags.BlockTags; +import net.minecraft.tags.FluidTags; import net.minecraft.tags.ItemTags; import net.minecraft.util.ResourceLocation; import net.minecraft.tags.ITag.INamedTag; @@ -33,6 +35,7 @@ public class Tags { Blocks.init(); Items.init(); + Fluids.init(); } public static class Blocks @@ -287,6 +290,18 @@ public class Tags } } + public static class Fluids + { + private static void init() {} + + public static final IOptionalNamedTag MILK = tag("milk"); + + private static IOptionalNamedTag tag(String name) + { + return FluidTags.createOptional(new ResourceLocation("forge", name)); + } + } + public interface IOptionalNamedTag extends INamedTag { /** diff --git a/src/main/java/net/minecraftforge/common/data/ForgeFluidTagsProvider.java b/src/main/java/net/minecraftforge/common/data/ForgeFluidTagsProvider.java new file mode 100644 index 0000000000..d0cd54fad5 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/data/ForgeFluidTagsProvider.java @@ -0,0 +1,46 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * 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.common.data; + +import net.minecraft.data.DataGenerator; +import net.minecraft.data.FluidTagsProvider; +import net.minecraftforge.common.ForgeMod; + +import static net.minecraftforge.common.Tags.Fluids.MILK; + +public class ForgeFluidTagsProvider extends FluidTagsProvider +{ + public ForgeFluidTagsProvider(DataGenerator gen, ExistingFileHelper existingFileHelper) + { + super(gen, "forge", existingFileHelper); + } + + @Override + public void registerTags() + { + getOrCreateBuilder(MILK).addOptional(ForgeMod.MILK.getId()).addOptional(ForgeMod.FLOWING_MILK.getId()); + } + + @Override + public String getName() + { + return "Forge Fluid Tags"; + } +} diff --git a/src/main/java/net/minecraftforge/fluids/FluidUtil.java b/src/main/java/net/minecraftforge/fluids/FluidUtil.java index 76a0d1637c..74091ac9e1 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidUtil.java +++ b/src/main/java/net/minecraftforge/fluids/FluidUtil.java @@ -643,10 +643,6 @@ public class FluidUtil { return new ItemStack(Items.LAVA_BUCKET); } - else if (fluid.getRegistryName().equals(new ResourceLocation("milk"))) - { - return new ItemStack(Items.MILK_BUCKET); - } } return fluid.getAttributes().getBucket(fluidStack); diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java b/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java index 9962a0fa27..9e2b348f40 100644 --- a/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java +++ b/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java @@ -26,6 +26,7 @@ import net.minecraft.fluid.Fluids; import net.minecraft.item.*; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.ForgeMod; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.LazyOptional; @@ -60,7 +61,7 @@ public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvide public boolean canFillFluidType(FluidStack fluid) { - if (fluid.getFluid() == Fluids.WATER || fluid.getFluid() == Fluids.LAVA || fluid.getFluid().getRegistryName().equals(new ResourceLocation("milk"))) + if (fluid.getFluid() == Fluids.WATER || fluid.getFluid() == Fluids.LAVA) { return true; } @@ -75,6 +76,10 @@ public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvide { return new FluidStack(((BucketItem)item).getFluid(), FluidAttributes.BUCKET_VOLUME); } + else if (item instanceof MilkBucketItem && ForgeMod.MILK.isPresent()) + { + return new FluidStack(ForgeMod.MILK.get(), FluidAttributes.BUCKET_VOLUME); + } else { return FluidStack.EMPTY; diff --git a/src/main/resources/assets/forge/lang/en_us.json b/src/main/resources/assets/forge/lang/en_us.json index 0f72f24bde..26ec0271da 100644 --- a/src/main/resources/assets/forge/lang/en_us.json +++ b/src/main/resources/assets/forge/lang/en_us.json @@ -169,5 +169,8 @@ "forge.swimSpeed": "Swim Speed", "forge.nameTagDistance": "Nametag Render Distance", "forge.entity_gravity": "Entity Gravity", - "generic.reachDistance": "Reach Distance" + "generic.reachDistance": "Reach Distance", + + "fluid.minecraft.milk": "Milk", + "fluid.minecraft.flowing_milk": "Milk" } diff --git a/src/main/resources/assets/forge/textures/block/milk_flowing.png b/src/main/resources/assets/forge/textures/block/milk_flowing.png new file mode 100644 index 0000000000..c1f4279aa4 Binary files /dev/null and b/src/main/resources/assets/forge/textures/block/milk_flowing.png differ diff --git a/src/main/resources/assets/forge/textures/block/milk_flowing.png.mcmeta b/src/main/resources/assets/forge/textures/block/milk_flowing.png.mcmeta new file mode 100644 index 0000000000..7e77c64858 --- /dev/null +++ b/src/main/resources/assets/forge/textures/block/milk_flowing.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 2 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/forge/textures/block/milk_still.png b/src/main/resources/assets/forge/textures/block/milk_still.png new file mode 100644 index 0000000000..402a04b3c9 Binary files /dev/null and b/src/main/resources/assets/forge/textures/block/milk_still.png differ diff --git a/src/main/resources/assets/forge/textures/block/milk_still.png.mcmeta b/src/main/resources/assets/forge/textures/block/milk_still.png.mcmeta new file mode 100644 index 0000000000..8e55e43baf --- /dev/null +++ b/src/main/resources/assets/forge/textures/block/milk_still.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 3 + } +} diff --git a/src/test/java/net/minecraftforge/debug/fluid/MilkFluidTest.java b/src/test/java/net/minecraftforge/debug/fluid/MilkFluidTest.java new file mode 100644 index 0000000000..f2ea7b7445 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/fluid/MilkFluidTest.java @@ -0,0 +1,54 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * 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.debug.fluid; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.common.ForgeMod; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.fluids.FluidUtil; +import net.minecraftforge.fml.common.Mod; + +@Mod(MilkFluidTest.MODID) +public class MilkFluidTest +{ + protected static final String MODID = "milk_fluid_test"; + private static final boolean ENABLE = false; + + public MilkFluidTest() + { + if (ENABLE) + { + ForgeMod.enableMilkFluid(); + MinecraftForge.EVENT_BUS.addListener(MilkFluidTest::useMilk); + } + } + + private static void useMilk(PlayerInteractEvent event) + { + ItemStack stack = event.getItemStack(); + if (stack.getItem() == Items.MILK_BUCKET) + { + FluidUtil.getFluidContained(stack).ifPresent((fluid) -> event.getPlayer().sendStatusMessage(new StringTextComponent("Contains ").append(fluid.getDisplayName()), true)); + } + } +} diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index a7de59836a..d360239f8f 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -30,6 +30,8 @@ license="LGPL v2.1" modId="gravity_attribute_test" [[mods]] modId="new_fluid_test" +[[mods]] + modId="milk_fluid_test" [[mods]] modId="data_gen_test" [[mods]]