mirror of
https://github.com/architectury/architectury-api.git
synced 2026-04-02 05:27:42 -05:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user