From 4acc8341d0bfb41c165aafb6ca83f2a2f8321c09 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 25 Jan 2021 17:32:56 +0800 Subject: [PATCH 1/4] Add ItemStackHooks --- .../architectury/hooks/ItemStackHooks.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 common/src/main/java/me/shedaniel/architectury/hooks/ItemStackHooks.java diff --git a/common/src/main/java/me/shedaniel/architectury/hooks/ItemStackHooks.java b/common/src/main/java/me/shedaniel/architectury/hooks/ItemStackHooks.java new file mode 100644 index 00000000..c6755140 --- /dev/null +++ b/common/src/main/java/me/shedaniel/architectury/hooks/ItemStackHooks.java @@ -0,0 +1,56 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021 shedaniel + * + * This program 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; either + * version 3 of the License, or (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package me.shedaniel.architectury.hooks; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; + +public final class ItemStackHooks { + private ItemStackHooks() {} + + public static ItemStack copyWithCount(ItemStack stack, int count) { + ItemStack copy = stack.copy(); + copy.setCount(count); + return copy; + } + + public static void giveItem(ServerPlayer player, ItemStack stack) { + boolean bl = player.inventory.add(stack); + if (bl && stack.isEmpty()) { + stack.setCount(1); + ItemEntity entity = player.drop(stack, false); + if (entity != null) { + entity.makeFakeItem(); + } + + player.level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 0.2F, ((player.getRandom().nextFloat() - player.getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F); + player.inventoryMenu.broadcastChanges(); + } else { + ItemEntity entity = player.drop(stack, false); + if (entity != null) { + entity.setNoPickUpDelay(); + entity.setOwner(player.getUUID()); + } + } + } +} From bb33552a4965f10019c30fb24968bf56c6d309f0 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 25 Jan 2021 17:33:10 +0800 Subject: [PATCH 2/4] Fix #25 --- .../fabric/client/MixinEffectInstance.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinEffectInstance.java b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinEffectInstance.java index 838e8d31..bee02c1e 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinEffectInstance.java +++ b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinEffectInstance.java @@ -1,3 +1,22 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021 shedaniel + * + * This program 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; either + * version 3 of the License, or (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package me.shedaniel.architectury.mixin.fabric.client; import com.mojang.blaze3d.shaders.Program; @@ -10,7 +29,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Unique -@Mixin(EffectInstance.class) +@Mixin(value = EffectInstance.class, priority = 1050) public class MixinEffectInstance { @Redirect( method = "", From 492521dfe3b3893a2fd7022d51841e97e53f0c71 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 25 Jan 2021 17:52:39 +0800 Subject: [PATCH 3/4] Add PlayerEvent#CHANGE_DIMENSION --- build.gradle | 6 +++--- .../shedaniel/architectury/event/events/PlayerEvent.java | 6 ++++++ .../architectury/mixin/fabric/MixinServerPlayer.java | 6 ++++++ .../architectury/event/forge/EventHandlerImplCommon.java | 7 +++++++ .../me/shedaniel/architectury/test/events/DebugEvents.java | 3 +++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 4252a8f0..3218f0b1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { - id "architectury-plugin" version "2.0.57" - id "forgified-fabric-loom" version "0.6.49" apply false + id "architectury-plugin" version "2.0.61" + id "forgified-fabric-loom" version "0.6.53" apply false id "org.cadixdev.licenser" version "0.5.0" id "com.jfrog.bintray" version "1.8.4" id "com.matthewprenger.cursegradle" version "1.4.0" apply false @@ -30,7 +30,7 @@ allprojects { isSnapshot = System.getenv("PR_NUM") != null } - def runNumber = (System.getenv("GITHUB_RUN_NUMBER") == null ? (((short) new Random().nextInt()).abs() + 1000).toString() : System.getenv("GITHUB_RUN_NUMBER")) + def runNumber = (System.getenv("GITHUB_RUN_NUMBER") == null ? "9999" : System.getenv("GITHUB_RUN_NUMBER")) if (!ext.isSnapshot) { version = rootProject.base_version + "." + runNumber diff --git a/common/src/main/java/me/shedaniel/architectury/event/events/PlayerEvent.java b/common/src/main/java/me/shedaniel/architectury/event/events/PlayerEvent.java index e426ca51..451bf92d 100644 --- a/common/src/main/java/me/shedaniel/architectury/event/events/PlayerEvent.java +++ b/common/src/main/java/me/shedaniel/architectury/event/events/PlayerEvent.java @@ -24,6 +24,7 @@ import me.shedaniel.architectury.event.EventFactory; import me.shedaniel.architectury.utils.IntValue; import net.minecraft.advancements.Advancement; import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.Container; import net.minecraft.world.InteractionResult; @@ -45,6 +46,7 @@ public interface PlayerEvent { Event SMELT_ITEM = EventFactory.createLoop(); Event PICKUP_ITEM_PRE = EventFactory.createInteractionResult(); Event PICKUP_ITEM_POST = EventFactory.createLoop(); + Event CHANGE_DIMENSION = EventFactory.createLoop(); Event DROP_ITEM = EventFactory.createLoop(); Event OPEN_MENU = EventFactory.createLoop(); Event CLOSE_MENU = EventFactory.createLoop(); @@ -86,6 +88,10 @@ public interface PlayerEvent { void pickup(Player player, ItemEntity entity, ItemStack stack); } + interface ChangeDimension { + void change(ServerPlayer player, ResourceKey oldLevel, ResourceKey newLevel); + } + interface DropItem { InteractionResult drop(Player player, ItemEntity entity); } diff --git a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinServerPlayer.java b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinServerPlayer.java index c638ca8b..09680175 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinServerPlayer.java +++ b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinServerPlayer.java @@ -20,6 +20,7 @@ package me.shedaniel.architectury.mixin.fabric; import me.shedaniel.architectury.event.events.PlayerEvent; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.Container; import net.minecraft.world.MenuProvider; @@ -57,4 +58,9 @@ public class MixinServerPlayer { private void doCloseContainer(CallbackInfo ci) { PlayerEvent.CLOSE_MENU.invoker().close((ServerPlayer) (Object) this, ((ServerPlayer) (Object) this).containerMenu); } + + @Inject(method = "triggerDimensionChangeTriggers", at = @At("HEAD")) + private void changeDimension(ServerLevel serverLevel, CallbackInfo ci) { + PlayerEvent.CHANGE_DIMENSION.invoker().change((ServerPlayer) (Object) this, serverLevel.dimension(), ((ServerPlayer) (Object) this).level.dimension()); + } } diff --git a/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplCommon.java b/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplCommon.java index 95459c66..72309483 100644 --- a/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplCommon.java +++ b/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplCommon.java @@ -322,6 +322,13 @@ public class EventHandlerImplCommon { LifecycleEvent.SERVER_BEFORE_START.invoker().stateChanged(event.getServer()); } + @SubscribeEvent + public static void event(PlayerChangedDimensionEvent event) { + if (event.getPlayer() instanceof ServerPlayer) { + PlayerEvent.CHANGE_DIMENSION.invoker().change((ServerPlayer) event.getPlayer(), event.getFrom(), event.getTo()); + } + } + public static class ModBasedEventHandler { } diff --git a/testmod-common/src/main/java/me/shedaniel/architectury/test/events/DebugEvents.java b/testmod-common/src/main/java/me/shedaniel/architectury/test/events/DebugEvents.java index 3acf5dc1..2447d448 100644 --- a/testmod-common/src/main/java/me/shedaniel/architectury/test/events/DebugEvents.java +++ b/testmod-common/src/main/java/me/shedaniel/architectury/test/events/DebugEvents.java @@ -165,6 +165,9 @@ public class DebugEvents { PlayerEvent.CLOSE_MENU.register((player, menu) -> { SINK.accept(player.getScoreboardName() + " closes " + toSimpleName(menu) + logSide(player.level)); }); + PlayerEvent.CHANGE_DIMENSION.register((player, oldLevel, newLevel) -> { + SINK.accept(player.getScoreboardName() + " switched from " + oldLevel.location() + " to " + newLevel.location() + logSide(player.level)); + }); } public static String toShortString(Vec3i pos) { From dc702a01e6f4ab99c045599558e0b6707f01dd8b Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 25 Jan 2021 17:53:26 +0800 Subject: [PATCH 4/4] FluidStackHooks in getting the rendering information for the fluids (#26) --- .../architectury/hooks/FluidStackHooks.java | 69 ++++++++++++++ .../hooks/fabric/FluidStackHooksImpl.java | 90 +++++++++++++++++++ .../hooks/forge/FluidStackHooksImpl.java | 79 ++++++++++++++++ 3 files changed, 238 insertions(+) diff --git a/common/src/main/java/me/shedaniel/architectury/hooks/FluidStackHooks.java b/common/src/main/java/me/shedaniel/architectury/hooks/FluidStackHooks.java index 09a7a819..07328cb2 100644 --- a/common/src/main/java/me/shedaniel/architectury/hooks/FluidStackHooks.java +++ b/common/src/main/java/me/shedaniel/architectury/hooks/FluidStackHooks.java @@ -22,9 +22,18 @@ package me.shedaniel.architectury.hooks; import me.shedaniel.architectury.annotations.ExpectPlatform; import me.shedaniel.architectury.fluid.FluidStack; import me.shedaniel.architectury.utils.Fraction; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class FluidStackHooks { private FluidStackHooks() {} @@ -80,4 +89,64 @@ public class FluidStackHooks { public static Fraction bucketAmount() { throw new AssertionError(); } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@NotNull FluidStack stack) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@NotNull Fluid fluid) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@NotNull FluidStack stack) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@NotNull Fluid fluid) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + public static int getColor(@NotNull FluidStack stack) { + throw new AssertionError(); + } + + @ExpectPlatform + @Environment(EnvType.CLIENT) + public static int getColor(@NotNull Fluid fluid) { + throw new AssertionError(); + } } diff --git a/fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/FluidStackHooksImpl.java b/fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/FluidStackHooksImpl.java index 860bb2aa..85c02f78 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/FluidStackHooksImpl.java +++ b/fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/FluidStackHooksImpl.java @@ -26,14 +26,22 @@ import me.shedaniel.architectury.utils.Fraction; import me.shedaniel.architectury.utils.NbtType; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Objects; @@ -103,4 +111,86 @@ public class FluidStackHooksImpl { public static Fraction bucketAmount() { return Fraction.ofWhole(1); } + + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + if (state.getType() == Fluids.EMPTY) return null; + TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(state.getType()).getFluidSprites(level, pos, state); + if (sprites == null) return null; + return sprites[0]; + } + + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@NotNull FluidStack stack) { + if (stack.getFluid() == Fluids.EMPTY) return null; + TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(stack.getFluid()).getFluidSprites(null, null, stack.getFluid().defaultFluidState()); + if (sprites == null) return null; + return sprites[0]; + } + + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@NotNull Fluid fluid) { + if (fluid == Fluids.EMPTY) return null; + TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(fluid).getFluidSprites(null, null, fluid.defaultFluidState()); + if (sprites == null) return null; + return sprites[0]; + } + + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + if (state.getType() == Fluids.EMPTY) return null; + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType()); + if (handler == null) return null; + TextureAtlasSprite[] sprites = handler.getFluidSprites(level, pos, state); + if (sprites == null) return null; + return sprites[1]; + } + + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@NotNull FluidStack stack) { + if (stack.getFluid() == Fluids.EMPTY) return null; + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(stack.getFluid()); + if (handler == null) return null; + TextureAtlasSprite[] sprites = handler.getFluidSprites(null, null, stack.getFluid().defaultFluidState()); + if (sprites == null) return null; + return sprites[1]; + } + + @Environment(EnvType.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@NotNull Fluid fluid) { + if (fluid == Fluids.EMPTY) return null; + TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(fluid).getFluidSprites(null, null, fluid.defaultFluidState()); + if (sprites == null) return null; + return sprites[1]; + } + + @Environment(EnvType.CLIENT) + public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + if (state.getType() == Fluids.EMPTY) return -1; + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType()); + if (handler == null) return -1; + return handler.getFluidColor(level, pos, state); + } + + @Environment(EnvType.CLIENT) + public static int getColor(@NotNull FluidStack stack) { + if (stack.getFluid() == Fluids.EMPTY) return -1; + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(stack.getFluid()); + if (handler == null) return -1; + return handler.getFluidColor(null, null, stack.getFluid().defaultFluidState()); + } + + @Environment(EnvType.CLIENT) + public static int getColor(@NotNull Fluid fluid) { + if (fluid == Fluids.EMPTY) return -1; + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(fluid); + if (handler == null) return -1; + return handler.getFluidColor(null, null, fluid.defaultFluidState()); + } } diff --git a/forge/src/main/java/me/shedaniel/architectury/hooks/forge/FluidStackHooksImpl.java b/forge/src/main/java/me/shedaniel/architectury/hooks/forge/FluidStackHooksImpl.java index fcf7c7a1..7bdef3d3 100644 --- a/forge/src/main/java/me/shedaniel/architectury/hooks/forge/FluidStackHooksImpl.java +++ b/forge/src/main/java/me/shedaniel/architectury/hooks/forge/FluidStackHooksImpl.java @@ -21,9 +21,22 @@ package me.shedaniel.architectury.hooks.forge; import me.shedaniel.architectury.fluid.FluidStack; import me.shedaniel.architectury.utils.Fraction; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class FluidStackHooksImpl { public static Component getName(FluidStack stack) { @@ -53,4 +66,70 @@ public class FluidStackHooksImpl { public static Fraction bucketAmount() { return Fraction.ofWhole(1000); } + + @OnlyIn(Dist.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + if (state.getType() == Fluids.EMPTY) return null; + ResourceLocation texture = state.getType().getAttributes().getStillTexture(level, pos); + return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + } + + @OnlyIn(Dist.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@NotNull FluidStack stack) { + if (stack.getFluid() == Fluids.EMPTY) return null; + ResourceLocation texture = stack.getFluid().getAttributes().getStillTexture(FluidStackHooksForge.toForge(stack)); + return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + } + + @OnlyIn(Dist.CLIENT) + @Nullable + public static TextureAtlasSprite getStillTexture(@NotNull Fluid fluid) { + if (fluid == Fluids.EMPTY) return null; + ResourceLocation texture = fluid.getAttributes().getStillTexture(); + return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + } + + @OnlyIn(Dist.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + if (state.getType() == Fluids.EMPTY) return null; + ResourceLocation texture = state.getType().getAttributes().getFlowingTexture(level, pos); + return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + } + + @OnlyIn(Dist.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@NotNull FluidStack stack) { + if (stack.getFluid() == Fluids.EMPTY) return null; + ResourceLocation texture = stack.getFluid().getAttributes().getFlowingTexture(FluidStackHooksForge.toForge(stack)); + return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + } + + @OnlyIn(Dist.CLIENT) + @Nullable + public static TextureAtlasSprite getFlowingTexture(@NotNull Fluid fluid) { + if (fluid == Fluids.EMPTY) return null; + ResourceLocation texture = fluid.getAttributes().getFlowingTexture(); + return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); + } + + @OnlyIn(Dist.CLIENT) + public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) { + if (state.getType() == Fluids.EMPTY) return -1; + return state.getType().getAttributes().getColor(level, pos); + } + + @OnlyIn(Dist.CLIENT) + public static int getColor(@NotNull FluidStack stack) { + if (stack.getFluid() == Fluids.EMPTY) return -1; + return stack.getFluid().getAttributes().getColor(FluidStackHooksForge.toForge(stack)); + } + + @OnlyIn(Dist.CLIENT) + public static int getColor(@NotNull Fluid fluid) { + if (fluid == Fluids.EMPTY) return -1; + return fluid.getAttributes().getColor(); + } }