Implement Forge's new Fluid API (#280)

* (Untested) fixes for the new Forge Fluid API
* Migrate ArchitecturyFlowingFluid to FluidTypes
* Add overlay textures, fix compile issues
* Fix Supplier import
* Add FluidState variant of get texture and color methods
* Deprecate combined render properties getter in favour of separate stack- and state-aware getters
* Add overlay texture override to SimpleArchitecturyFluidAttributes
* Update common/src/main/java/dev/architectury/core/fluid/ArchitecturyFluidAttributes.java

Co-authored-by: shedaniel <daniel@shedaniel.me>
Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>

[norelease]
This commit is contained in:
Max
2022-06-16 11:59:08 +02:00
committed by GitHub
parent a997cd44c1
commit 7d86eba267
7 changed files with 304 additions and 126 deletions

View File

@@ -20,6 +20,7 @@
package dev.architectury.core.fluid.forge.imitator;
import com.google.common.base.MoreObjects;
import com.google.common.base.Suppliers;
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -37,26 +38,29 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.fluids.ForgeFlowingFluid;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
import java.util.function.Supplier;
public abstract class ArchitecturyFlowingFluid extends ForgeFlowingFluid {
private final ArchitecturyFluidAttributes attributes;
private final Supplier<FluidType> forgeType;
ArchitecturyFlowingFluid(ArchitecturyFluidAttributes attributes) {
super(toForgeProperties(attributes));
this.attributes = attributes;
this.forgeType = Suppliers.memoize(() -> {
return new ArchitecturyFluidAttributesForge(FluidType.Properties.create(), this, attributes);
});
}
private static Properties toForgeProperties(ArchitecturyFluidAttributes attributes) {
FluidAttributes.Builder forgeAttributes = new FluidAttributes.Builder(attributes.getSourceTexture(), attributes.getFlowingTexture(), (builder, fluid) ->
new ArchitecturyFluidAttributesForge(builder, fluid, attributes)) {
};
Properties forge = new Properties(attributes::getSourceFluid, attributes::getFlowingFluid, forgeAttributes);
if (attributes.canConvertToSource()) forge.canMultiply();
Properties forge = new Properties(Suppliers.memoize(() -> {
return new ArchitecturyFluidAttributesForge(FluidType.Properties.create(), attributes.getSourceFluid(), attributes);
}), attributes::getSourceFluid, attributes::getFlowingFluid);
forge.slopeFindDistance(attributes.getSlopeFindDistance());
forge.levelDecreasePerBlock(attributes.getDropOff());
forge.bucket(() -> MoreObjects.firstNonNull(attributes.getBucketItem(), Items.AIR));
@@ -66,6 +70,11 @@ public abstract class ArchitecturyFlowingFluid extends ForgeFlowingFluid {
return forge;
}
@Override
public FluidType getFluidType() {
return forgeType.get();
}
@Override
public Fluid getFlowing() {
return attributes.getFlowingFluid();

View File

@@ -27,125 +27,159 @@ import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraft.world.level.material.FluidState;
import net.minecraftforge.client.IFluidTypeRenderProperties;
import net.minecraftforge.common.SoundAction;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.Nullable;
class ArchitecturyFluidAttributesForge extends FluidAttributes {
import java.util.function.Consumer;
import static net.minecraftforge.common.SoundActions.BUCKET_EMPTY;
import static net.minecraftforge.common.SoundActions.BUCKET_FILL;
class ArchitecturyFluidAttributesForge extends FluidType {
private final ArchitecturyFluidAttributes attributes;
private final String defaultTranslationKey;
public ArchitecturyFluidAttributesForge(Builder builder, Fluid fluid, ArchitecturyFluidAttributes attributes) {
super(addArchIntoBuilder(builder, attributes), fluid);
public ArchitecturyFluidAttributesForge(Properties builder, Fluid fluid, ArchitecturyFluidAttributes attributes) {
super(addArchIntoBuilder(builder, attributes));
this.attributes = attributes;
this.defaultTranslationKey = Util.makeDescriptionId("fluid", ForgeRegistries.FLUIDS.getKey(fluid));
}
private static Builder addArchIntoBuilder(Builder builder, ArchitecturyFluidAttributes attributes) {
builder.luminosity(attributes.getLuminosity())
private static Properties addArchIntoBuilder(Properties builder, ArchitecturyFluidAttributes attributes) {
builder.lightLevel(attributes.getLuminosity())
.density(attributes.getDensity())
.temperature(attributes.getTemperature())
.rarity(attributes.getRarity())
.canConvertToSource(attributes.canConvertToSource())
.viscosity(attributes.getViscosity());
if (attributes.isLighterThanAir()) builder.gaseous();
return builder;
}
@Override
public ResourceLocation getStillTexture() {
return attributes.getSourceTexture();
public ItemStack getBucket(FluidStack stack) {
Item item = attributes.getBucketItem();
return item == null ? super.getBucket(stack) : new ItemStack(item);
}
@Override
public ResourceLocation getStillTexture(FluidStack stack) {
return attributes.getSourceTexture(stack == null ? null : FluidStackHooksForge.fromForge(stack));
public void initializeClient(Consumer<IFluidTypeRenderProperties> consumer) {
consumer.accept(new IFluidTypeRenderProperties() {
@Override
public int getColorTint() {
return attributes.getColor();
}
@Override
public ResourceLocation getStillTexture() {
return attributes.getSourceTexture();
}
@Override
public ResourceLocation getFlowingTexture() {
return attributes.getFlowingTexture();
}
@Override
@Nullable
public ResourceLocation getOverlayTexture() {
return attributes.getOverlayTexture();
}
@Override
public ResourceLocation getStillTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
return attributes.getSourceTexture(state, getter, pos);
}
@Override
public ResourceLocation getFlowingTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
return attributes.getFlowingTexture(state, getter, pos);
}
@Override
@Nullable
public ResourceLocation getOverlayTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
return attributes.getOverlayTexture(state, getter, pos);
}
@Override
public int getColorTint(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
return attributes.getColor(state, getter, pos);
}
@Override
public int getColorTint(FluidStack stack) {
return attributes.getColor(convertSafe(stack));
}
@Override
public ResourceLocation getStillTexture(FluidStack stack) {
return attributes.getSourceTexture(convertSafe(stack));
}
@Override
public ResourceLocation getFlowingTexture(FluidStack stack) {
return attributes.getFlowingTexture(convertSafe(stack));
}
@Override
@Nullable
public ResourceLocation getOverlayTexture(FluidStack stack) {
return attributes.getOverlayTexture(convertSafe(stack));
}
});
}
@Override
public ResourceLocation getStillTexture(BlockAndTintGetter level, BlockPos pos) {
return attributes.getSourceTexture(null, level, pos);
public int getLightLevel(FluidStack stack) {
return attributes.getLuminosity(convertSafe(stack));
}
@Override
public ResourceLocation getFlowingTexture() {
return attributes.getFlowingTexture();
}
@Override
public ResourceLocation getFlowingTexture(FluidStack stack) {
return attributes.getFlowingTexture(stack == null ? null : FluidStackHooksForge.fromForge(stack));
}
@Override
public ResourceLocation getFlowingTexture(BlockAndTintGetter level, BlockPos pos) {
return attributes.getFlowingTexture(null, level, pos);
}
@Override
public int getColor() {
return attributes.getColor();
}
@Override
public int getColor(FluidStack stack) {
return attributes.getColor(stack == null ? null : FluidStackHooksForge.fromForge(stack));
}
@Override
public int getColor(BlockAndTintGetter level, BlockPos pos) {
return attributes.getColor(null, level, pos);
}
@Override
public int getLuminosity(FluidStack stack) {
return attributes.getLuminosity(stack == null ? null : FluidStackHooksForge.fromForge(stack));
}
@Override
public int getLuminosity(BlockAndTintGetter level, BlockPos pos) {
return attributes.getLuminosity(null, level, pos);
public int getLightLevel(FluidState state, BlockAndTintGetter level, BlockPos pos) {
return attributes.getLuminosity(convertSafe(state), level, pos);
}
@Override
public int getDensity(FluidStack stack) {
return attributes.getDensity(stack == null ? null : FluidStackHooksForge.fromForge(stack));
return attributes.getDensity(convertSafe(stack));
}
@Override
public int getDensity(BlockAndTintGetter level, BlockPos pos) {
return attributes.getDensity(null, level, pos);
public int getDensity(FluidState state, BlockAndTintGetter level, BlockPos pos) {
return attributes.getDensity(convertSafe(state), level, pos);
}
@Override
public int getTemperature(FluidStack stack) {
return attributes.getTemperature(stack == null ? null : FluidStackHooksForge.fromForge(stack));
return attributes.getTemperature(convertSafe(stack));
}
@Override
public int getTemperature(BlockAndTintGetter level, BlockPos pos) {
return attributes.getTemperature(null, level, pos);
public int getTemperature(FluidState state, BlockAndTintGetter level, BlockPos pos) {
return attributes.getTemperature(convertSafe(state), level, pos);
}
@Override
public int getViscosity(FluidStack stack) {
return attributes.getViscosity(stack == null ? null : FluidStackHooksForge.fromForge(stack));
return attributes.getViscosity(convertSafe(stack));
}
@Override
public int getViscosity(BlockAndTintGetter level, BlockPos pos) {
return attributes.getViscosity(null, level, pos);
}
@Override
public boolean isGaseous(FluidStack stack) {
return attributes.isLighterThanAir(stack == null ? null : FluidStackHooksForge.fromForge(stack));
}
@Override
public boolean isGaseous(BlockAndTintGetter level, BlockPos pos) {
return attributes.isLighterThanAir(null, level, pos);
public int getViscosity(FluidState state, BlockAndTintGetter level, BlockPos pos) {
return attributes.getViscosity(convertSafe(state), level, pos);
}
@Override
@@ -155,56 +189,77 @@ class ArchitecturyFluidAttributesForge extends FluidAttributes {
@Override
public Rarity getRarity(FluidStack stack) {
return attributes.getRarity(stack == null ? null : FluidStackHooksForge.fromForge(stack));
return attributes.getRarity(convertSafe(stack));
}
@Override
public Rarity getRarity(BlockAndTintGetter level, BlockPos pos) {
return attributes.getRarity(null, level, pos);
public Component getDescription() {
return attributes.getName();
}
@Override
public Component getDisplayName(FluidStack stack) {
return attributes.getName(stack == null ? null : FluidStackHooksForge.fromForge(stack));
public Component getDescription(FluidStack stack) {
return attributes.getName(convertSafe(stack));
}
@Override
public String getTranslationKey() {
public String getDescriptionId() {
return MoreObjects.firstNonNull(attributes.getTranslationKey(), defaultTranslationKey);
}
@Override
public String getTranslationKey(FluidStack stack) {
return MoreObjects.firstNonNull(attributes.getTranslationKey(stack == null ? null : FluidStackHooksForge.fromForge(stack)), defaultTranslationKey);
public String getDescriptionId(FluidStack stack) {
return MoreObjects.firstNonNull(attributes.getTranslationKey(convertSafe(stack)), defaultTranslationKey);
}
@Override
public SoundEvent getFillSound() {
return attributes.getFillSound();
@Nullable
public SoundEvent getSound(SoundAction action) {
return getSound((FluidStack) null, action);
}
@Override
public SoundEvent getFillSound(FluidStack stack) {
return attributes.getFillSound(stack == null ? null : FluidStackHooksForge.fromForge(stack));
@Nullable
public SoundEvent getSound(@Nullable FluidStack stack, SoundAction action) {
var archStack = convertSafe(stack);
if (BUCKET_FILL.equals(action)) {
return attributes.getFillSound(archStack);
} else if (BUCKET_EMPTY.equals(action)) {
return attributes.getEmptySound(archStack);
}
return null;
}
@Override
public SoundEvent getFillSound(BlockAndTintGetter level, BlockPos pos) {
return attributes.getFillSound(null, level, pos);
@Nullable
public SoundEvent getSound(@Nullable Player player, BlockGetter getter, BlockPos pos, SoundAction action) {
if (getter instanceof BlockAndTintGetter level) {
if (BUCKET_FILL.equals(action)) {
return attributes.getFillSound(null, level, pos);
} else if (BUCKET_EMPTY.equals(action)) {
return attributes.getEmptySound(null, level, pos);
}
}
return getSound((FluidStack) null, action);
}
@Override
public SoundEvent getEmptySound() {
return attributes.getEmptySound();
public boolean canConvertToSource(FluidStack stack) {
return attributes.canConvertToSource();
}
@Override
public SoundEvent getEmptySound(FluidStack stack) {
return attributes.getEmptySound(stack == null ? null : FluidStackHooksForge.fromForge(stack));
public boolean canConvertToSource(FluidState state, LevelReader reader, BlockPos pos) {
return attributes.canConvertToSource();
}
@Override
public SoundEvent getEmptySound(BlockAndTintGetter level, BlockPos pos) {
return attributes.getEmptySound(null, level, pos);
@Nullable
public dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidStack stack) {
return stack == null ? null : FluidStackHooksForge.fromForge(stack);
}
@Nullable
public dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidState state) {
return state == null ? null : dev.architectury.fluid.FluidStack.create(state.getType(), dev.architectury.fluid.FluidStack.bucketAmount());
}
}

View File

@@ -35,15 +35,16 @@ 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 net.minecraftforge.client.RenderProperties;
import org.jetbrains.annotations.Nullable;
public class FluidStackHooksImpl {
public static Component getName(FluidStack stack) {
return stack.getFluid().getAttributes().getDisplayName(FluidStackHooksForge.toForge(stack));
return stack.getFluid().getFluidType().getDescription(FluidStackHooksForge.toForge(stack));
}
public static String getTranslationKey(FluidStack stack) {
return stack.getFluid().getAttributes().getTranslationKey(FluidStackHooksForge.toForge(stack));
return stack.getFluid().getFluidType().getDescriptionId(FluidStackHooksForge.toForge(stack));
}
public static FluidStack read(FriendlyByteBuf buf) {
@@ -70,7 +71,7 @@ public class FluidStackHooksImpl {
@Nullable
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
if (state.getType() == Fluids.EMPTY) return null;
ResourceLocation texture = state.getType().getAttributes().getStillTexture(level, pos);
ResourceLocation texture = RenderProperties.get(state).getStillTexture(state, level, pos);
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
}
@@ -78,7 +79,7 @@ public class FluidStackHooksImpl {
@Nullable
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return null;
ResourceLocation texture = stack.getFluid().getAttributes().getStillTexture(FluidStackHooksForge.toForge(stack));
ResourceLocation texture = RenderProperties.get(stack.getFluid()).getStillTexture(FluidStackHooksForge.toForge(stack));
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
}
@@ -86,7 +87,7 @@ public class FluidStackHooksImpl {
@Nullable
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
if (fluid == Fluids.EMPTY) return null;
ResourceLocation texture = fluid.getAttributes().getStillTexture();
ResourceLocation texture = RenderProperties.get(fluid).getStillTexture();
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
}
@@ -94,7 +95,7 @@ public class FluidStackHooksImpl {
@Nullable
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
if (state.getType() == Fluids.EMPTY) return null;
ResourceLocation texture = state.getType().getAttributes().getFlowingTexture(level, pos);
ResourceLocation texture = RenderProperties.get(state).getFlowingTexture(state, level, pos);
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
}
@@ -102,7 +103,7 @@ public class FluidStackHooksImpl {
@Nullable
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return null;
ResourceLocation texture = stack.getFluid().getAttributes().getFlowingTexture(FluidStackHooksForge.toForge(stack));
ResourceLocation texture = RenderProperties.get(stack.getFluid()).getFlowingTexture(FluidStackHooksForge.toForge(stack));
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
}
@@ -110,61 +111,65 @@ public class FluidStackHooksImpl {
@Nullable
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
if (fluid == Fluids.EMPTY) return null;
ResourceLocation texture = fluid.getAttributes().getFlowingTexture();
ResourceLocation texture = RenderProperties.get(fluid).getFlowingTexture();
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
}
@OnlyIn(Dist.CLIENT)
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
if (state.getType() == Fluids.EMPTY) return -1;
return state.getType().getAttributes().getColor(level, pos);
return RenderProperties.get(state).getColorTint(state, level, pos);
}
@OnlyIn(Dist.CLIENT)
public static int getColor(FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return -1;
return stack.getFluid().getAttributes().getColor(FluidStackHooksForge.toForge(stack));
return RenderProperties.get(stack.getFluid()).getColorTint(FluidStackHooksForge.toForge(stack));
}
@OnlyIn(Dist.CLIENT)
public static int getColor(Fluid fluid) {
if (fluid == Fluids.EMPTY) return -1;
return fluid.getAttributes().getColor();
return RenderProperties.get(fluid).getColorTint();
}
public static int getLuminosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return fluid.getFluid().getAttributes().getLuminosity(FluidStackHooksForge.toForge(fluid));
return fluid.getFluid().getFluidType().getLightLevel(FluidStackHooksForge.toForge(fluid));
}
@Deprecated(forRemoval = true)
public static int getLuminosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
if (level != null && pos != null) {
return fluid.getAttributes().getLuminosity(level, pos);
var state = level.getFluidState(pos);
return fluid.getFluidType().getLightLevel(state, level, pos);
}
return fluid.getAttributes().getLuminosity();
return fluid.getFluidType().getLightLevel();
}
public static int getTemperature(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return fluid.getFluid().getAttributes().getTemperature(FluidStackHooksForge.toForge(fluid));
return fluid.getFluid().getFluidType().getTemperature(FluidStackHooksForge.toForge(fluid));
}
public static int getTemperature(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
if (level != null && pos != null) {
return fluid.getAttributes().getTemperature(level, pos);
var state = level.getFluidState(pos);
return fluid.getFluidType().getTemperature(state, level, pos);
}
return fluid.getAttributes().getTemperature();
return fluid.getFluidType().getTemperature();
}
public static int getViscosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return fluid.getFluid().getAttributes().getViscosity(FluidStackHooksForge.toForge(fluid));
return fluid.getFluid().getFluidType().getViscosity(FluidStackHooksForge.toForge(fluid));
}
public static int getViscosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
if (level != null && pos != null) {
return fluid.getAttributes().getViscosity(level, pos);
var state = level.getFluidState(pos);
return fluid.getFluidType().getViscosity(state, level, pos);
}
return fluid.getAttributes().getViscosity();
return fluid.getFluidType().getViscosity();
}
}