Re-add fluid variants

The implementations in FluidStack regarding components is a stab for what the future api could be, and will definitely change.

Signed-off-by: shedaniel <daniel@shedaniel.me>
This commit is contained in:
shedaniel
2024-03-02 04:14:46 +09:00
parent 7b65d8da73
commit 8d0fdbdbd1
8 changed files with 281 additions and 190 deletions

View File

@@ -19,29 +19,38 @@
package dev.architectury.fluid;
import com.google.common.collect.Iterators;
import com.mojang.serialization.Codec;
import dev.architectury.hooks.fluid.FluidStackHooks;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.core.Holder;
import net.minecraft.core.component.*;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.Fluids;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public final class FluidStack {
public final class FluidStack implements DataComponentHolder {
private static final FluidStackAdapter<Object> ADAPTER = adapt(FluidStack::getValue, FluidStack::new);
private static final FluidStack EMPTY = create(Fluids.EMPTY, 0);
public static final Codec<FluidStack> CODEC = ADAPTER.codec();
public static final StreamCodec<RegistryFriendlyByteBuf, FluidStack> STREAM_CODEC = ADAPTER.streamCodec();
private Object value;
private final Object value;
private FluidStack(Supplier<Fluid> fluid, long amount, CompoundTag tag) {
this(ADAPTER.create(fluid, amount, tag));
private FluidStack(Supplier<Fluid> fluid, long amount, DataComponentPatch patch) {
this(ADAPTER.create(fluid, amount, patch));
}
private FluidStack(Object value) {
@@ -57,9 +66,103 @@ public final class FluidStack {
throw new AssertionError();
}
@Override
public DataComponentMap getComponents() {
return new DataComponentMap() {
@Nullable
@Override
public <T> T get(DataComponentType<? extends T> type) {
return getPatch().get(type).orElse(null);
}
@Override
public Set<DataComponentType<?>> keySet() {
return new AbstractSet<>() {
@Override
public Iterator<DataComponentType<?>> iterator() {
return Iterators.transform(getPatch().entrySet().iterator(), Map.Entry::getKey);
}
@Override
public int size() {
return getPatch().entrySet().size();
}
@Override
public boolean contains(Object o) {
if (!(o instanceof DataComponentType<?> type)) return false;
return getPatch().get(type).isPresent();
}
};
}
};
}
public <T> T set(DataComponentType<? super T> dataComponentType, @Nullable T object) {
T previous = (T) get(dataComponentType);
DataComponentPatch.Builder builder = DataComponentPatch.builder();
for (TypedDataComponent<?> component : getComponents()) {
if (component.type() != dataComponentType) {
builder.set(component);
}
}
if (object != null) {
builder.set(dataComponentType, object);
}
setPatch(builder.build());
return previous;
}
@Nullable
public <T, U> T update(DataComponentType<T> dataComponentType, T object, U object2, BiFunction<T, U, T> biFunction) {
return this.set(dataComponentType, biFunction.apply(this.getOrDefault(dataComponentType, object), object2));
}
@Nullable
public <T> T update(DataComponentType<T> dataComponentType, T object, UnaryOperator<T> unaryOperator) {
return this.set(dataComponentType, unaryOperator.apply(this.getOrDefault(dataComponentType, object)));
}
@Nullable
public <T> T remove(DataComponentType<? extends T> dataComponentType) {
return this.set(dataComponentType, null);
}
public void applyComponents(DataComponentPatch dataComponentPatch) {
DataComponentPatch.Builder builder = DataComponentPatch.builder();
for (TypedDataComponent<?> component : getComponents()) {
builder.set(component);
}
for (Map.Entry<DataComponentType<?>, Optional<?>> entry : dataComponentPatch.entrySet()) {
if (entry.getValue().isPresent()) {
//noinspection rawtypes
builder.set((DataComponentType) entry.getKey(), entry.getValue().get());
} else {
builder.remove(entry.getKey());
}
}
setPatch(builder.build());
}
public void applyComponents(DataComponentMap dataComponentMap) {
DataComponentPatch.Builder builder = DataComponentPatch.builder();
for (TypedDataComponent<?> component : getComponents()) {
builder.set(component);
}
for (TypedDataComponent<?> entry : dataComponentMap) {
if (entry.value() != null) {
//noinspection rawtypes
builder.set((DataComponentType) entry.type(), entry.value());
} else {
builder.remove(entry.type());
}
}
setPatch(builder.build());
}
@ApiStatus.Internal
public interface FluidStackAdapter<T> {
T create(Supplier<Fluid> fluid, long amount, CompoundTag tag);
T create(Supplier<Fluid> fluid, long amount, @Nullable DataComponentPatch patch);
Supplier<Fluid> getRawFluidSupplier(T object);
@@ -69,37 +172,51 @@ public final class FluidStack {
void setAmount(T object, long amount);
CompoundTag getTag(T value);
DataComponentPatch getPatch(T value);
void setTag(T value, CompoundTag tag);
void setPatch(T value, DataComponentPatch patch);
T copy(T value);
int hashCode(T value);
Codec<FluidStack> codec();
StreamCodec<RegistryFriendlyByteBuf, FluidStack> streamCodec();
}
public static FluidStack empty() {
return EMPTY;
}
public static FluidStack create(Fluid fluid, long amount, @Nullable CompoundTag tag) {
return create(() -> fluid, amount, tag);
public static FluidStack create(Fluid fluid, long amount, DataComponentPatch patch) {
if (fluid == Fluids.EMPTY || amount <= 0) return empty();
return create(() -> fluid, amount, patch);
}
public static FluidStack create(Fluid fluid, long amount) {
return create(fluid, amount, null);
return create(fluid, amount, DataComponentPatch.EMPTY);
}
public static FluidStack create(Supplier<Fluid> fluid, long amount, @Nullable CompoundTag tag) {
return new FluidStack(fluid, amount, tag);
public static FluidStack create(Supplier<Fluid> fluid, long amount, DataComponentPatch patch) {
if (amount <= 0) return empty();
return new FluidStack(fluid, amount, patch);
}
public static FluidStack create(Supplier<Fluid> fluid, long amount) {
return create(fluid, amount, null);
return create(fluid, amount, DataComponentPatch.EMPTY);
}
public static FluidStack create(Holder<Fluid> fluid, long amount, DataComponentPatch patch) {
return create(fluid.value(), amount, patch);
}
public static FluidStack create(Holder<Fluid> fluid, long amount) {
return create(fluid.value(), amount, DataComponentPatch.EMPTY);
}
public static FluidStack create(FluidStack stack, long amount) {
return create(stack.getRawFluidSupplier(), amount, stack.getTag());
return create(stack.getRawFluidSupplier(), amount, stack.getPatch());
}
public static long bucketAmount() {
@@ -139,50 +256,12 @@ public final class FluidStack {
setAmount(getAmount() - amount);
}
public boolean hasTag() {
return getTag() != null;
public DataComponentPatch getPatch() {
return ADAPTER.getPatch(value);
}
@Nullable
public CompoundTag getTag() {
return ADAPTER.getTag(value);
}
public void setTag(@Nullable CompoundTag tag) {
ADAPTER.setTag(value, tag);
}
public CompoundTag getOrCreateTag() {
CompoundTag tag = getTag();
if (tag == null) {
tag = new CompoundTag();
setTag(tag);
return tag;
}
return tag;
}
@Nullable
public CompoundTag getChildTag(String childName) {
CompoundTag tag = getTag();
if (tag == null)
return null;
return tag.getCompound(childName);
}
public CompoundTag getOrCreateChildTag(String childName) {
CompoundTag tag = getOrCreateTag();
var child = tag.getCompound(childName);
if (!tag.contains(childName, Tag.TAG_COMPOUND)) {
tag.put(childName, child);
}
return child;
}
public void removeChildTag(String childName) {
CompoundTag tag = getTag();
if (tag != null)
tag.remove(childName);
public void setPatch(DataComponentPatch patch) {
ADAPTER.setPatch(value, patch);
}
public Component getName() {
@@ -211,17 +290,17 @@ public final class FluidStack {
}
public boolean isFluidStackEqual(FluidStack other) {
return getFluid() == other.getFluid() && getAmount() == other.getAmount() && isTagEqual(other);
return getFluid() == other.getFluid() && getAmount() == other.getAmount() && isComponentEqual(other);
}
public boolean isFluidEqual(FluidStack other) {
return getFluid() == other.getFluid();
}
public boolean isTagEqual(FluidStack other) {
var tag = getTag();
var otherTag = other.getTag();
return Objects.equals(tag, otherTag);
public boolean isComponentEqual(FluidStack other) {
var patch = getPatch();
var otherPatch = other.getPatch();
return Objects.equals(patch, otherPatch);
}
public static FluidStack read(FriendlyByteBuf buf) {
@@ -242,7 +321,7 @@ public final class FluidStack {
public FluidStack copyWithAmount(long amount) {
if (isEmpty()) return this;
return new FluidStack(getRawFluidSupplier(), amount, getTag());
return new FluidStack(getRawFluidSupplier(), amount, getPatch());
}
@ApiStatus.Internal

View File

@@ -23,17 +23,19 @@ import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
import dev.architectury.utils.Env;
import dev.architectury.utils.EnvExecutor;
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes;
import net.minecraft.world.level.material.FlowingFluid;
public class ArchitecturyFlowingFluidImpl {
public static void addFabricFluidAttributes(FlowingFluid fluid, ArchitecturyFluidAttributes attributes) {
// TODO: FluidVariantAttributes.register(fluid, new ArchitecturyFluidAttributesFabric(attributes));
FluidVariantAttributes.register(fluid, new ArchitecturyFluidAttributesFabric(attributes));
EnvExecutor.runInEnv(Env.CLIENT, () -> () -> Client.run(fluid, attributes));
}
private static class Client {
private static void run(FlowingFluid fluid, ArchitecturyFluidAttributes attributes) {
// TODO: FluidVariantRendering.register(fluid, new ArchitecturyFluidRenderingFabric(attributes));
FluidVariantRendering.register(fluid, new ArchitecturyFluidRenderingFabric(attributes));
FluidRenderHandlerRegistry.INSTANCE.register(fluid, new ArchitecturyFluidRenderingFabric(attributes));
}
}

View File

@@ -22,6 +22,8 @@ package dev.architectury.core.fluid.fabric;
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
import dev.architectury.fluid.FluidStack;
import dev.architectury.hooks.fluid.fabric.FluidStackHooksFabric;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributeHandler;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.level.Level;
@@ -30,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
class ArchitecturyFluidAttributesFabric {} /*implements FluidVariantAttributeHandler {
class ArchitecturyFluidAttributesFabric implements FluidVariantAttributeHandler {
private final ArchitecturyFluidAttributes attributes;
public ArchitecturyFluidAttributesFabric(ArchitecturyFluidAttributes attributes) {
@@ -71,4 +73,4 @@ class ArchitecturyFluidAttributesFabric {} /*implements FluidVariantAttributeHan
public boolean isLighterThanAir(FluidVariant variant) {
return attributes.isLighterThanAir(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()));
}
}*/
}

View File

@@ -25,6 +25,8 @@ import dev.architectury.hooks.fluid.fabric.FluidStackHooksFabric;
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.transfer.v1.client.fluid.FluidVariantRenderHandler;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@@ -38,40 +40,46 @@ import java.util.function.Function;
@SuppressWarnings("UnstableApiUsage")
@Environment(EnvType.CLIENT)
class ArchitecturyFluidRenderingFabric implements /*FluidVariantRenderHandler,*/ FluidRenderHandler {
class ArchitecturyFluidRenderingFabric implements FluidVariantRenderHandler, FluidRenderHandler {
private final ArchitecturyFluidAttributes attributes;
private final TextureAtlasSprite[] sprites = new TextureAtlasSprite[3];
private final TextureAtlasSprite[] spritesOther = new TextureAtlasSprite[3];
private final TextureAtlasSprite[] sprites = new TextureAtlasSprite[2];
private final TextureAtlasSprite[] spritesOverlaid = new TextureAtlasSprite[3];
private final TextureAtlasSprite[] spritesOther = new TextureAtlasSprite[2];
private final TextureAtlasSprite[] spritesOtherOverlaid = new TextureAtlasSprite[3];
public ArchitecturyFluidRenderingFabric(ArchitecturyFluidAttributes attributes) {
this.attributes = attributes;
}
// @Override
// @Nullable
// public TextureAtlasSprite[] getSprites(FluidVariant variant) {
// FluidStack stack = FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount());
// Function<ResourceLocation, TextureAtlasSprite> atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
// sprites[0] = atlas.apply(attributes.getSourceTexture(stack));
// sprites[1] = atlas.apply(attributes.getFlowingTexture(stack));
// ResourceLocation overlayTexture = attributes.getOverlayTexture(stack);
// sprites[2] = overlayTexture == null ? null : atlas.apply(overlayTexture);
// return sprites;
// }
@Override
@Nullable
public TextureAtlasSprite[] getSprites(FluidVariant variant) {
FluidStack stack = FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount());
Function<ResourceLocation, TextureAtlasSprite> atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
ResourceLocation overlayTexture = attributes.getOverlayTexture(stack);
TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.apply(overlayTexture);
TextureAtlasSprite[] sprites = overlaySprite == null ? this.sprites : spritesOverlaid;
sprites[0] = atlas.apply(attributes.getSourceTexture(stack));
sprites[1] = atlas.apply(attributes.getFlowingTexture(stack));
if (overlaySprite != null) sprites[2] = overlaySprite;
return sprites;
}
// @Override
// public int getColor(FluidVariant variant, @Nullable BlockAndTintGetter view, @Nullable BlockPos pos) {
// return attributes.getColor(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()), view, pos);
// }
@Override
public int getColor(FluidVariant variant, @Nullable BlockAndTintGetter view, @Nullable BlockPos pos) {
return attributes.getColor(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()), view, pos);
}
@Override
public TextureAtlasSprite[] getFluidSprites(@Nullable BlockAndTintGetter view, @Nullable BlockPos pos, FluidState state) {
Function<ResourceLocation, TextureAtlasSprite> atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
spritesOther[0] = atlas.apply(attributes.getSourceTexture(state, view, pos));
spritesOther[1] = atlas.apply(attributes.getFlowingTexture(state, view, pos));
ResourceLocation overlayTexture = attributes.getOverlayTexture(state, view, pos);
spritesOther[2] = overlayTexture == null ? null : atlas.apply(overlayTexture);
return spritesOther;
TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.apply(overlayTexture);
TextureAtlasSprite[] sprites = overlaySprite == null ? this.spritesOther : spritesOtherOverlaid;
sprites[0] = atlas.apply(attributes.getSourceTexture(state, view, pos));
sprites[1] = atlas.apply(attributes.getFlowingTexture(state, view, pos));
if (overlaySprite != null) sprites[2] = overlaySprite;
return sprites;
}
@Override

View File

@@ -19,11 +19,23 @@
package dev.architectury.fluid.fabric;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import dev.architectury.fluid.FluidStack;
import net.minecraft.nbt.CompoundTag;
import io.netty.buffer.ByteBuf;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.material.Fluid;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.Function;
@@ -48,33 +60,32 @@ public enum FluidStackImpl implements FluidStack.FluidStackAdapter<FluidStackImp
}
public static class Pair {
//public FluidVariant variant;
public Fluid variant;
public FluidVariant variant;
public long amount;
public Pair(Fluid/*Variant*/ variant, long amount) {
public Pair(FluidVariant variant, long amount) {
this.variant = variant;
this.amount = amount;
}
}
@Override
public FluidStackImpl.Pair create(Supplier<Fluid> fluid, long amount, CompoundTag tag) {
public FluidStackImpl.Pair create(Supplier<Fluid> fluid, long amount, @Nullable DataComponentPatch patch) {
Fluid fluidType = Objects.requireNonNull(fluid).get();
if (fluidType instanceof FlowingFluid flowingFluid) {
fluidType = flowingFluid.getSource();
}
return new Pair(fluidType/*, tag == null ? null : tag.copy())*/, amount);
return new Pair(FluidVariant.of(fluidType, patch == null ? DataComponentPatch.EMPTY : patch), amount);
}
@Override
public Supplier<Fluid> getRawFluidSupplier(FluidStackImpl.Pair object) {
return () -> object.variant;
return () -> object.variant.getFluid();
}
@Override
public Fluid getFluid(FluidStackImpl.Pair object) {
return object.variant;
return object.variant.getFluid();
}
@Override
@@ -87,19 +98,18 @@ public enum FluidStackImpl implements FluidStack.FluidStackAdapter<FluidStackImp
object.amount = amount;
}
@Override
public CompoundTag getTag(FluidStackImpl.Pair value) {
return null; // value.variant.getNbt();
public DataComponentPatch getPatch(FluidStackImpl.Pair value) {
return value.variant.getComponents();
}
@Override
public void setTag(FluidStackImpl.Pair value, CompoundTag tag) {
// value.variant = FluidVariant.of(value.variant.getFluid(), tag);
public void setPatch(FluidStackImpl.Pair value, DataComponentPatch patch) {
value.variant = FluidVariant.of(value.variant.getFluid(), patch);
}
@Override
public FluidStackImpl.Pair copy(FluidStackImpl.Pair value) {
return new Pair(value.variant/*FluidVariant.of(value.variant.getFluid(), value.variant.copyNbt())*/, value.amount);
return new Pair(value.variant, value.amount);
}
@Override
@@ -108,9 +118,30 @@ public enum FluidStackImpl implements FluidStack.FluidStackAdapter<FluidStackImp
var code = 1;
code = 31 * code + pair.variant.hashCode();
code = 31 * code + Long.hashCode(pair.amount);
// var tag = pair.variant.getNbt();
// if (tag != null)
// code = 31 * code + tag.hashCode();
var patch = pair.variant.getComponents();
if (patch != null)
code = 31 * code + patch.hashCode();
return code;
}
@Override
public Codec<FluidStack> codec() {
return RecordCodecBuilder.create(instance -> instance.group(
BuiltInRegistries.FLUID.holderByNameCodec().fieldOf("fluid").forGetter(stack -> stack.getFluid().builtInRegistryHolder()),
ExtraCodecs.validate(Codec.LONG, value -> {
return value.compareTo(0L) >= 0 && value.compareTo(Long.MAX_VALUE) <= 0
? DataResult.success(value)
: DataResult.error(() -> "Value must be non-negative: " + value);
}).fieldOf("amount").forGetter(FluidStack::getAmount),
DataComponentPatch.CODEC.fieldOf("components").forGetter(FluidStack::getPatch)
).apply(instance, FluidStack::create));
}
@Override
public StreamCodec<RegistryFriendlyByteBuf, FluidStack> streamCodec() {
return StreamCodec.composite(ByteBufCodecs.holderRegistry(Registries.FLUID), stack -> stack.getFluid().builtInRegistryHolder(),
StreamCodec.of(ByteBuf::writeLong, ByteBuf::readLong), FluidStack::getAmount,
DataComponentPatch.STREAM_CODEC, FluidStack::getPatch,
FluidStack::create);
}
}

View File

@@ -21,22 +21,23 @@ package dev.architectury.hooks.fluid.fabric;
import dev.architectury.fluid.FluidStack;
import dev.architectury.fluid.fabric.FluidStackImpl;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView;
@SuppressWarnings("UnstableApiUsage")
public final class FluidStackHooksFabric {
private FluidStackHooksFabric() {
}
// TODO
// public static FluidStack fromFabric(StorageView<FluidVariant> storageView) {
// return fromFabric(storageView.getResource(), storageView.getAmount());
// }
public static FluidStack fromFabric(StorageView<FluidVariant> storageView) {
return fromFabric(storageView.getResource(), storageView.getAmount());
}
// public static FluidStack fromFabric(FluidVariant variant, long amount) {
// return FluidStackImpl.fromValue.apply(new FluidStackImpl.Pair(variant, amount));
// }
public static FluidStack fromFabric(FluidVariant variant, long amount) {
return FluidStackImpl.fromValue.apply(new FluidStackImpl.Pair(variant, amount));
}
// public static FluidVariant toFabric(FluidStack stack) {
// return ((FluidStackImpl.Pair) FluidStackImpl.toValue.apply(stack)).variant;
// }
public static FluidVariant toFabric(FluidStack stack) {
return ((FluidStackImpl.Pair) FluidStackImpl.toValue.apply(stack)).variant;
}
}

View File

@@ -19,40 +19,39 @@
package dev.architectury.hooks.fluid.fabric;
import com.mojang.logging.LogUtils;
import dev.architectury.fluid.FluidStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes;
import net.minecraft.Util;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.material.FlowingFluid;
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.Nullable;
import org.slf4j.Logger;
import java.util.Objects;
import java.util.Optional;
public class FluidStackHooksImpl {
private static final Logger LOGGER = LogUtils.getLogger();
public static Component getName(FluidStack stack) {
var block = stack.getFluid().defaultFluidState().createLegacyBlock().getBlock();
if (!stack.isEmpty() && block == Blocks.AIR) {
return Component.translatable(Util.makeDescriptionId("block", BuiltInRegistries.FLUID.getKey(stack.getFluid())));
} else {
return block.getName();
}
// TODO: return FluidVariantAttributes.getName(FluidStackHooksFabric.toFabric(stack));
return FluidVariantAttributes.getName(FluidStackHooksFabric.toFabric(stack));
}
public static String getTranslationKey(FluidStack stack) {
@@ -60,45 +59,25 @@ public class FluidStackHooksImpl {
return "block." + id.getNamespace() + "." + id.getPath();
}
public static FluidStack read(FriendlyByteBuf buf) {
var fluid = Objects.requireNonNull(BuiltInRegistries.FLUID.get(buf.readResourceLocation()));
var amount = buf.readVarLong();
var tag = buf.readNbt();
if (fluid == Fluids.EMPTY) return FluidStack.empty();
return FluidStack.create(fluid, amount, tag);
public static FluidStack read(RegistryFriendlyByteBuf buf) {
return FluidStack.STREAM_CODEC.decode(buf);
}
public static void write(FluidStack stack, FriendlyByteBuf buf) {
buf.writeResourceLocation(BuiltInRegistries.FLUID.getKey(stack.getFluid()));
buf.writeVarLong(stack.getAmount());
buf.writeNbt(stack.getTag());
public static void write(FluidStack stack, RegistryFriendlyByteBuf buf) {
FluidStack.STREAM_CODEC.encode(buf, stack);
}
public static FluidStack read(CompoundTag tag) {
if (tag == null || !tag.contains("id", Tag.TAG_STRING)) {
return FluidStack.empty();
}
var fluid = BuiltInRegistries.FLUID.get(new ResourceLocation(tag.getString("id")));
if (fluid == null || fluid == Fluids.EMPTY) {
return FluidStack.empty();
}
var amount = tag.getLong("amount");
var stack = FluidStack.create(fluid, amount);
if (tag.contains("tag", Tag.TAG_COMPOUND)) {
stack.setTag(tag.getCompound("tag"));
}
return stack;
public static Optional<FluidStack> read(HolderLookup.Provider provider, Tag tag) {
return FluidStack.CODEC.parse(provider.createSerializationContext(NbtOps.INSTANCE), tag)
.resultOrPartial(string -> LOGGER.error("Tried to load invalid fluid stack: '{}'", string));
}
public static CompoundTag write(FluidStack stack, CompoundTag tag) {
tag.putString("id", BuiltInRegistries.FLUID.getKey(stack.getFluid()).toString());
tag.putLong("amount", stack.getAmount());
if (stack.hasTag()) {
tag.put("tag", stack.getTag());
}
return tag;
public static FluidStack readOptional(HolderLookup.Provider provider, CompoundTag tag) {
return tag.isEmpty() ? FluidStack.empty() : read(provider, tag).orElse(FluidStack.empty());
}
public static Tag write(HolderLookup.Provider provider, FluidStack stack, Tag tag) {
return Util.getOrThrow(FluidStack.CODEC.encode(stack, provider.createSerializationContext(NbtOps.INSTANCE), tag), IllegalStateException::new);
}
public static long bucketAmount() {
@@ -119,17 +98,15 @@ public class FluidStackHooksImpl {
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
return getStillTexture(null, null, stack.getFluid().defaultFluidState());
// var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
// return sprites == null ? null : sprites[0];
var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
return sprites == null ? null : sprites[0];
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
return getStillTexture(null, null, fluid.defaultFluidState());
// var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
// return sprites == null ? null : sprites[0];
var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
return sprites == null ? null : sprites[0];
}
@Environment(EnvType.CLIENT)
@@ -146,17 +123,15 @@ public class FluidStackHooksImpl {
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
return getFlowingTexture(null, null, stack.getFluid().defaultFluidState());
// var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
// return sprites == null ? null : sprites[1];
var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
return sprites == null ? null : sprites[1];
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
return getFlowingTexture(null, null, fluid.defaultFluidState());
// var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
// return sprites == null ? null : sprites[1];
var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
return sprites == null ? null : sprites[1];
}
@Environment(EnvType.CLIENT)
@@ -169,8 +144,7 @@ public class FluidStackHooksImpl {
@Environment(EnvType.CLIENT)
public static int getColor(FluidStack stack) {
return getColor(stack.getFluid());
// return FluidVariantRendering.getColor(FluidStackHooksFabric.toFabric(stack));
return FluidVariantRendering.getColor(FluidStackHooksFabric.toFabric(stack));
}
@Environment(EnvType.CLIENT)
@@ -182,32 +156,26 @@ public class FluidStackHooksImpl {
}
public static int getLuminosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return fluid.getFluid().defaultFluidState().createLegacyBlock().getLightEmission();
// return FluidVariantAttributes.getLuminance(FluidStackHooksFabric.toFabric(fluid));
return FluidVariantAttributes.getLuminance(FluidStackHooksFabric.toFabric(fluid));
}
public static int getLuminosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
return fluid.defaultFluidState().createLegacyBlock().getLightEmission();
// return FluidVariantAttributes.getLuminance(FluidVariant.of(fluid));
return FluidVariantAttributes.getLuminance(FluidVariant.of(fluid));
}
public static int getTemperature(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return 300;
// return FluidVariantAttributes.getTemperature(FluidStackHooksFabric.toFabric(fluid));
return FluidVariantAttributes.getTemperature(FluidStackHooksFabric.toFabric(fluid));
}
public static int getTemperature(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
return 300;
// return FluidVariantAttributes.getTemperature(FluidVariant.of(fluid));
return FluidVariantAttributes.getTemperature(FluidVariant.of(fluid));
}
public static int getViscosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return fluid.getFluid() instanceof FlowingFluid flowingFluid && level != null ? flowingFluid.getTickDelay(level) * 200 : 1000;
// return FluidVariantAttributes.getViscosity(FluidStackHooksFabric.toFabric(fluid), level);
return FluidVariantAttributes.getViscosity(FluidStackHooksFabric.toFabric(fluid), level);
}
public static int getViscosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
return fluid instanceof FlowingFluid flowingFluid && level != null ? flowingFluid.getTickDelay(level) * 200 : 1000;
// return FluidVariantAttributes.getViscosity(FluidVariant.of(fluid), level);
return FluidVariantAttributes.getViscosity(FluidVariant.of(fluid), level);
}
}

View File

@@ -14,7 +14,7 @@ base_version=12.0
maven_group=dev.architectury
fabric_loader_version=0.15.7
fabric_api_version=0.96.5+1.20.5
fabric_api_version=0.96.6+1.20.5
mod_menu_version=9.0.0
forge_version=49.0.14