Add fluid block and flowing fluid (#251)

[ci skip]

Squash of the following commits:

* Add way to register fluids and fluid attributes, WIP UNTESTED
* Move to correct package
* Update forge/build.gradle
* Add bucket item wrapper and add test mod
* Make it easier to declare attributes by suppliers
* Fix fabric support
* Change SimpleArchitecturyFluidAttributes to accept Supplier<Optional<T>>
* Make ArchitecturyLiquidBlock and ArchitecturyBucketItem accept Supplier
* Update testmod
* Link javadocs in the builder to make it easier to check
* Add ArchitecturyMobBucketItem and fix caps on ArchitecturyBucketItem
* Make SimpleArchitecturyFluidAttributes accept wildcard fluids
* getContainingFluid -> getContainedFluid
* Add supplier variant of the methods

Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>
Co-authored-by: Max <maxh2709@gmail.com>
This commit is contained in:
shedaniel
2022-05-06 19:51:25 +08:00
committed by GitHub
parent 3532d24577
commit bd9b3e73e4
23 changed files with 2368 additions and 44 deletions

View File

@@ -0,0 +1,42 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 dev.architectury.core.fluid.fabric;
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) {
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) {
FluidVariantRendering.register(fluid, new ArchitecturyFluidRenderingFabric(attributes));
FluidRenderHandlerRegistry.INSTANCE.register(fluid, new ArchitecturyFluidRenderingFabric(attributes));
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 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;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
class ArchitecturyFluidAttributesFabric implements FluidVariantAttributeHandler {
private final ArchitecturyFluidAttributes attributes;
public ArchitecturyFluidAttributesFabric(ArchitecturyFluidAttributes attributes) {
this.attributes = attributes;
}
@Override
public Component getName(FluidVariant variant) {
return attributes.getName(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()));
}
@Override
public Optional<SoundEvent> getFillSound(FluidVariant variant) {
return Optional.ofNullable(attributes.getFillSound(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount())));
}
@Override
public Optional<SoundEvent> getEmptySound(FluidVariant variant) {
return Optional.ofNullable(attributes.getEmptySound(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount())));
}
@Override
public int getLuminance(FluidVariant variant) {
return attributes.getLuminosity(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()));
}
@Override
public int getTemperature(FluidVariant variant) {
return attributes.getTemperature(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()));
}
@Override
public int getViscosity(FluidVariant variant, @Nullable Level world) {
return attributes.getViscosity(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()), world, null);
}
@Override
public boolean isLighterThanAir(FluidVariant variant) {
return attributes.isLighterThanAir(FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount()));
}
}

View File

@@ -0,0 +1,80 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 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.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;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.material.FluidState;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
@SuppressWarnings("UnstableApiUsage")
@Environment(EnvType.CLIENT)
class ArchitecturyFluidRenderingFabric implements FluidVariantRenderHandler, FluidRenderHandler {
private final ArchitecturyFluidAttributes attributes;
private final TextureAtlasSprite[] sprites = new TextureAtlasSprite[2];
private final TextureAtlasSprite[] spritesOther = new TextureAtlasSprite[2];
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));
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 TextureAtlasSprite[] getFluidSprites(@Nullable BlockAndTintGetter view, @Nullable BlockPos pos, FluidState state) {
FluidStack stack = FluidStack.create(state.getType(), FluidStack.bucketAmount());
Function<ResourceLocation, TextureAtlasSprite> atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
spritesOther[0] = atlas.apply(attributes.getSourceTexture(stack, view, pos));
spritesOther[1] = atlas.apply(attributes.getFlowingTexture(stack, view, pos));
return spritesOther;
}
@Override
public int getFluidColor(@Nullable BlockAndTintGetter view, @Nullable BlockPos pos, FluidState state) {
return attributes.getColor(FluidStack.create(state.getType(), FluidStack.bucketAmount()), view, pos);
}
}

View File

@@ -0,0 +1,112 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 dev.architectury.fluid.fabric;
import dev.architectury.fluid.FluidStack;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.material.Fluid;
import org.jetbrains.annotations.ApiStatus;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
@ApiStatus.Internal
@SuppressWarnings("UnstableApiUsage")
public enum FluidStackImpl implements FluidStack.FluidStackAdapter<FluidStackImpl.Pair> {
INSTANCE;
public static Function<FluidStack, Object> toValue;
public static Function<Object, FluidStack> fromValue;
public static FluidStack.FluidStackAdapter<Object> adapt(Function<FluidStack, Object> toValue, Function<Object, dev.architectury.fluid.FluidStack> fromValue) {
FluidStackImpl.toValue = toValue;
FluidStackImpl.fromValue = fromValue;
return (FluidStack.FluidStackAdapter<Object>) (FluidStack.FluidStackAdapter<?>) INSTANCE;
}
public static class Pair {
public FluidVariant variant;
public 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) {
Fluid fluidType = Objects.requireNonNull(fluid).get();
if (fluidType instanceof FlowingFluid flowingFluid) {
fluidType = flowingFluid.getSource();
}
return new Pair(FluidVariant.of(fluidType, tag == null ? null : tag.copy()), amount);
}
@Override
public Supplier<Fluid> getRawFluidSupplier(FluidStackImpl.Pair object) {
return object.variant::getFluid;
}
@Override
public Fluid getFluid(FluidStackImpl.Pair object) {
return object.variant.getFluid();
}
@Override
public long getAmount(FluidStackImpl.Pair object) {
return object.amount;
}
@Override
public void setAmount(FluidStackImpl.Pair object, long amount) {
object.amount = amount;
}
@Override
public CompoundTag getTag(FluidStackImpl.Pair value) {
return value.variant.getNbt();
}
@Override
public void setTag(FluidStackImpl.Pair value, CompoundTag tag) {
value.variant = FluidVariant.of(value.variant.getFluid(), tag);
}
@Override
public FluidStackImpl.Pair copy(FluidStackImpl.Pair value) {
return new Pair(FluidVariant.of(value.variant.getFluid(), value.variant.copyNbt()), value.amount);
}
@Override
public int hashCode(FluidStackImpl.Pair value) {
var pair = (Pair) value;
var code = 1;
code = 31 * code + pair.variant.getFluid().hashCode();
code = 31 * code + Long.hashCode(pair.amount);
var tag = pair.variant.getNbt();
if (tag != null)
code = 31 * code + tag.hashCode();
return code;
}
}

View File

@@ -0,0 +1,43 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 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() {
}
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 FluidVariant toFabric(FluidStack stack) {
return ((FluidStackImpl.Pair) FluidStackImpl.toValue.apply(stack)).variant;
}
}

View File

@@ -44,7 +44,7 @@ import java.util.Objects;
public class FluidStackHooksImpl {
public static Component getName(FluidStack stack) {
return FluidVariantAttributes.getName(FluidVariant.of(stack.getFluid(), stack.getTag()));
return FluidVariantAttributes.getName(FluidStackHooksFabric.toFabric(stack));
}
public static String getTranslationKey(FluidStack stack) {
@@ -188,7 +188,7 @@ public class FluidStackHooksImpl {
}
public static int getLuminosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return FluidVariantAttributes.getLuminance(FluidVariant.of(fluid.getFluid(), fluid.getTag()));
return FluidVariantAttributes.getLuminance(FluidStackHooksFabric.toFabric(fluid));
}
public static int getLuminosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
@@ -196,7 +196,7 @@ public class FluidStackHooksImpl {
}
public static int getTemperature(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return FluidVariantAttributes.getTemperature(FluidVariant.of(fluid.getFluid(), fluid.getTag()));
return FluidVariantAttributes.getTemperature(FluidStackHooksFabric.toFabric(fluid));
}
public static int getTemperature(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {
@@ -204,7 +204,7 @@ public class FluidStackHooksImpl {
}
public static int getViscosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
return FluidVariantAttributes.getViscosity(FluidVariant.of(fluid.getFluid(), fluid.getTag()), level);
return FluidVariantAttributes.getViscosity(FluidStackHooksFabric.toFabric(fluid), level);
}
public static int getViscosity(Fluid fluid, @Nullable Level level, @Nullable BlockPos pos) {