mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Merge remote-tracking branch 'architectury/1.18.2' into 1.19
# Conflicts: # gradle.properties # testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.block;
|
||||
|
||||
import dev.architectury.platform.Platform;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyLiquidBlock extends LiquidBlock {
|
||||
public ArchitecturyLiquidBlock(Supplier<? extends FlowingFluid> fluid, Properties properties) {
|
||||
super(checkPlatform(fluid).get(), properties);
|
||||
}
|
||||
|
||||
private static <T> T checkPlatform(T obj) {
|
||||
if (Platform.isForge()) {
|
||||
throw new IllegalStateException("This class should've been replaced on Forge!");
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import dev.architectury.platform.Platform;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class ArchitecturyFlowingFluid extends FlowingFluid {
|
||||
private final ArchitecturyFluidAttributes attributes;
|
||||
|
||||
ArchitecturyFlowingFluid(ArchitecturyFluidAttributes attributes) {
|
||||
checkPlatform(null);
|
||||
this.attributes = attributes;
|
||||
if (Platform.isFabric()) {
|
||||
addFabricFluidAttributes(this, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T checkPlatform(T obj) {
|
||||
if (Platform.isForge()) {
|
||||
throw new IllegalStateException("This class should've been replaced on Forge!");
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
private static void addFabricFluidAttributes(FlowingFluid fluid, ArchitecturyFluidAttributes properties) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fluid getFlowing() {
|
||||
return attributes.getFlowingFluid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fluid getSource() {
|
||||
return attributes.getSourceFluid();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canConvertToSource() {
|
||||
return attributes.canConvertToSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state) {
|
||||
// Same implementation as in WaterFluid.
|
||||
BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(pos) : null;
|
||||
Block.dropResources(state, level, pos, blockEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSlopeFindDistance(LevelReader level) {
|
||||
return attributes.getSlopeFindDistance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDropOff(LevelReader level) {
|
||||
return attributes.getDropOff(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getBucket() {
|
||||
Item item = attributes.getBucketItem();
|
||||
return item == null ? Items.AIR : item;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBeReplacedWith(FluidState state, BlockGetter level, BlockPos pos, Fluid fluid, Direction direction) {
|
||||
// Same implementation as in WaterFluid.
|
||||
return direction == Direction.DOWN && !this.isSame(fluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTickDelay(LevelReader level) {
|
||||
return attributes.getTickDelay(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getExplosionResistance() {
|
||||
return attributes.getExplosionResistance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createLegacyBlock(FluidState state) {
|
||||
LiquidBlock block = attributes.getBlock();
|
||||
if (block == null) return Blocks.AIR.defaultBlockState();
|
||||
return block.defaultBlockState().setValue(LiquidBlock.LEVEL, getLegacyLevel(state));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Optional<SoundEvent> getPickupSound() {
|
||||
return Optional.ofNullable(attributes.getFillSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSame(Fluid fluid) {
|
||||
return fluid == getSource() || fluid == getFlowing();
|
||||
}
|
||||
|
||||
public static class Source extends ArchitecturyFlowingFluid {
|
||||
public Source(ArchitecturyFluidAttributes attributes) {
|
||||
super(attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(FluidState state) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSource(FluidState state) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Flowing extends ArchitecturyFlowingFluid {
|
||||
public Flowing(ArchitecturyFluidAttributes attributes) {
|
||||
super(attributes);
|
||||
this.registerDefaultState(this.getStateDefinition().any().setValue(LEVEL, 7));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createFluidStateDefinition(StateDefinition.Builder<Fluid, FluidState> builder) {
|
||||
super.createFluidStateDefinition(builder);
|
||||
builder.add(LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(FluidState state) {
|
||||
return state.getValue(LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSource(FluidState state) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Attributes of a fluid.
|
||||
*
|
||||
* @see SimpleArchitecturyFluidAttributes
|
||||
*/
|
||||
public interface ArchitecturyFluidAttributes {
|
||||
/**
|
||||
* Returns the translation key of the name of this fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the translation key
|
||||
*/
|
||||
@Nullable
|
||||
String getTranslationKey(@Nullable FluidStack stack);
|
||||
|
||||
/**
|
||||
* Returns the translation key of the name of this fluid.
|
||||
*
|
||||
* @return the translation key
|
||||
*/
|
||||
@Nullable
|
||||
default String getTranslationKey() {
|
||||
return getTranslationKey(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the name
|
||||
*/
|
||||
default Component getName(@Nullable FluidStack stack) {
|
||||
return new TranslatableComponent(getTranslationKey(stack));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this fluid.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
default Component getName() {
|
||||
return getName(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flowing fluid.
|
||||
*
|
||||
* @return the flowing fluid
|
||||
*/
|
||||
Fluid getFlowingFluid();
|
||||
|
||||
/**
|
||||
* Returns the still fluid.
|
||||
*
|
||||
* @return the still fluid
|
||||
*/
|
||||
Fluid getSourceFluid();
|
||||
|
||||
/**
|
||||
* Returns whether this fluid can be converted to a source block when a flowing fluid is adjacent to two source blocks.
|
||||
* A fluid that can be converted to a source block means that the fluid can be multiplied infinitely.
|
||||
*
|
||||
* @return whether this fluid can be converted to a source block
|
||||
*/
|
||||
boolean canConvertToSource();
|
||||
|
||||
/**
|
||||
* Returns the maximum distance this fluid will consider as a flowable hole candidate.
|
||||
*
|
||||
* @param level the level, can be {@code null}
|
||||
* @return the maximum distance
|
||||
* @see net.minecraft.world.level.material.WaterFluid#getSlopeFindDistance(LevelReader)
|
||||
* @see net.minecraft.world.level.material.LavaFluid#getSlopeFindDistance(LevelReader)
|
||||
*/
|
||||
int getSlopeFindDistance(@Nullable LevelReader level);
|
||||
|
||||
/**
|
||||
* Returns the maximum distance this fluid will consider as a flowable hole candidate.
|
||||
*
|
||||
* @return the maximum distance
|
||||
* @see net.minecraft.world.level.material.WaterFluid#getSlopeFindDistance(LevelReader)
|
||||
* @see net.minecraft.world.level.material.LavaFluid#getSlopeFindDistance(LevelReader)
|
||||
*/
|
||||
default int getSlopeFindDistance() {
|
||||
return getSlopeFindDistance(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drop in fluid level per block travelled.
|
||||
*
|
||||
* @param level the level, can be {@code null}
|
||||
* @return the drop in fluid level per block travelled
|
||||
* @see net.minecraft.world.level.material.WaterFluid#getDropOff(LevelReader)
|
||||
* @see net.minecraft.world.level.material.LavaFluid#getDropOff(LevelReader)
|
||||
*/
|
||||
int getDropOff(@Nullable LevelReader level);
|
||||
|
||||
/**
|
||||
* Returns the drop in fluid level per block travelled.
|
||||
*
|
||||
* @return the drop in fluid level per block travelled
|
||||
* @see net.minecraft.world.level.material.WaterFluid#getDropOff(LevelReader)
|
||||
* @see net.minecraft.world.level.material.LavaFluid#getDropOff(LevelReader)
|
||||
*/
|
||||
default int getDropOff() {
|
||||
return getDropOff(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filled bucket item for this fluid.
|
||||
*
|
||||
* @return the filled bucket item
|
||||
*/
|
||||
@Nullable
|
||||
Item getBucketItem();
|
||||
|
||||
/**
|
||||
* Returns the tick delay between each flow update.
|
||||
*
|
||||
* @param level the level, can be {@code null}
|
||||
* @return the tick delay
|
||||
* @see net.minecraft.world.level.material.WaterFluid#getTickDelay(LevelReader)
|
||||
* @see net.minecraft.world.level.material.LavaFluid#getTickDelay(LevelReader)
|
||||
*/
|
||||
int getTickDelay(@Nullable LevelReader level);
|
||||
|
||||
/**
|
||||
* Returns the tick delay between each flow update.
|
||||
*
|
||||
* @return the tick delay
|
||||
* @see net.minecraft.world.level.material.WaterFluid#getTickDelay(LevelReader)
|
||||
* @see net.minecraft.world.level.material.LavaFluid#getTickDelay(LevelReader)
|
||||
*/
|
||||
default int getTickDelay() {
|
||||
return getTickDelay(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the explosion resistance of this fluid.
|
||||
*
|
||||
* @return the explosion resistance
|
||||
* @see net.minecraft.world.level.material.WaterFluid#getExplosionResistance()
|
||||
* @see net.minecraft.world.level.material.LavaFluid#getExplosionResistance()
|
||||
*/
|
||||
float getExplosionResistance();
|
||||
|
||||
/**
|
||||
* Returns the block form of this fluid.
|
||||
*
|
||||
* @return the block form
|
||||
* @see net.minecraft.world.level.block.Blocks#WATER
|
||||
* @see net.minecraft.world.level.block.Blocks#LAVA
|
||||
*/
|
||||
@Nullable
|
||||
LiquidBlock getBlock();
|
||||
|
||||
/**
|
||||
* Returns the texture location of this fluid in its source form.
|
||||
* <p>
|
||||
* The vanilla water location is {@code "block/water_still"}.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the texture location
|
||||
*/
|
||||
ResourceLocation getSourceTexture(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the texture location of this fluid in its source form.
|
||||
* <p>
|
||||
* The vanilla water location is {@code "block/water_still"}.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the texture location
|
||||
*/
|
||||
default ResourceLocation getSourceTexture(@Nullable FluidStack stack) {
|
||||
return getSourceTexture(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the texture location of this fluid in its source form.
|
||||
* <p>
|
||||
* The vanilla water location is {@code "block/water_still"}.
|
||||
*
|
||||
* @return the texture location
|
||||
*/
|
||||
default ResourceLocation getSourceTexture() {
|
||||
return getSourceTexture(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the texture location of this fluid in its flowing form.
|
||||
* <p>
|
||||
* The vanilla water location is {@code "block/water_flow"}.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the texture location
|
||||
*/
|
||||
ResourceLocation getFlowingTexture(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the texture location of this fluid in its flowing form.
|
||||
* <p>
|
||||
* The vanilla water location is {@code "block/water_flow"}.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the texture location
|
||||
*/
|
||||
default ResourceLocation getFlowingTexture(@Nullable FluidStack stack) {
|
||||
return getFlowingTexture(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the texture location of this fluid in its flowing form.
|
||||
* <p>
|
||||
* The vanilla water location is {@code "block/water_flow"}.
|
||||
*
|
||||
* @return the texture location
|
||||
*/
|
||||
default ResourceLocation getFlowingTexture() {
|
||||
return getFlowingTexture(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the color
|
||||
*/
|
||||
int getColor(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the color of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the color
|
||||
*/
|
||||
default int getColor(@Nullable FluidStack stack) {
|
||||
return getColor(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of the fluid.
|
||||
*
|
||||
* @return the color
|
||||
*/
|
||||
default int getColor() {
|
||||
return getColor(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the luminosity of the fluid, this is between 0 and 15.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the luminosity
|
||||
*/
|
||||
int getLuminosity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the luminosity of the fluid, this is between 0 and 15.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the luminosity
|
||||
*/
|
||||
default int getLuminosity(@Nullable FluidStack stack) {
|
||||
return getLuminosity(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the luminosity of the fluid, this is between 0 and 15.
|
||||
*
|
||||
* @return the luminosity
|
||||
*/
|
||||
default int getLuminosity() {
|
||||
return getLuminosity(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the density of the fluid, this is 1000 for water and 3000 for lava on forge.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the density
|
||||
*/
|
||||
int getDensity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the density of the fluid, this is 1000 for water and 3000 for lava on forge.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the density
|
||||
*/
|
||||
default int getDensity(@Nullable FluidStack stack) {
|
||||
return getDensity(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the density of the fluid, this is 1000 for water and 3000 for lava on forge.
|
||||
*
|
||||
* @return the density
|
||||
*/
|
||||
default int getDensity() {
|
||||
return getDensity(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the temperature of the fluid.
|
||||
* The temperature is in kelvin, for example, 300 kelvin is equal to room temperature.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the temperature
|
||||
*/
|
||||
int getTemperature(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the temperature of the fluid.
|
||||
* The temperature is in kelvin, for example, 300 kelvin is equal to room temperature.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the temperature
|
||||
*/
|
||||
default int getTemperature(@Nullable FluidStack stack) {
|
||||
return getTemperature(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the temperature of the fluid.
|
||||
* The temperature is in kelvin, for example, 300 kelvin is equal to room temperature.
|
||||
*
|
||||
* @return the temperature
|
||||
*/
|
||||
default int getTemperature() {
|
||||
return getTemperature(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the viscosity of the fluid. A lower viscosity means that the fluid will flow faster.
|
||||
* The default value is 1000 for water.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the viscosity
|
||||
*/
|
||||
int getViscosity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the viscosity of the fluid. A lower viscosity means that the fluid will flow faster.
|
||||
* The default value is 1000 for water.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the viscosity
|
||||
*/
|
||||
default int getViscosity(@Nullable FluidStack stack) {
|
||||
return getViscosity(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the viscosity of the fluid. A lower viscosity means that the fluid will flow faster.
|
||||
* The default value is 1000 for water.
|
||||
*
|
||||
* @return the viscosity
|
||||
*/
|
||||
default int getViscosity() {
|
||||
return getViscosity(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this fluid is lighter than air. This is used to determine whether the fluid should be rendered
|
||||
* upside down like gas.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return {@code true} if the fluid is lighter than air
|
||||
*/
|
||||
boolean isLighterThanAir(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns whether this fluid is lighter than air. This is used to determine whether the fluid should be rendered
|
||||
* upside down like gas.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return {@code true} if the fluid is lighter than air
|
||||
*/
|
||||
default boolean isLighterThanAir(@Nullable FluidStack stack) {
|
||||
return isLighterThanAir(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this fluid is lighter than air. This is used to determine whether the fluid should be rendered
|
||||
* upside down like gas.
|
||||
*
|
||||
* @return {@code true} if the fluid is lighter than air
|
||||
*/
|
||||
default boolean isLighterThanAir() {
|
||||
return isLighterThanAir(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rarity of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the rarity
|
||||
*/
|
||||
Rarity getRarity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the rarity of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the rarity
|
||||
*/
|
||||
default Rarity getRarity(@Nullable FluidStack stack) {
|
||||
return getRarity(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rarity of the fluid.
|
||||
*
|
||||
* @return the rarity
|
||||
*/
|
||||
default Rarity getRarity() {
|
||||
return getRarity(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fill sound of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the fill sound
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_FILL
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_FILL_LAVA
|
||||
*/
|
||||
@Nullable
|
||||
SoundEvent getFillSound(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the fill sound of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the fill sound
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_FILL
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_FILL_LAVA
|
||||
*/
|
||||
@Nullable
|
||||
default SoundEvent getFillSound(@Nullable FluidStack stack) {
|
||||
return getFillSound(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fill sound of the fluid.
|
||||
*
|
||||
* @return the fill sound
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_FILL
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_FILL_LAVA
|
||||
*/
|
||||
@Nullable
|
||||
default SoundEvent getFillSound() {
|
||||
return getFillSound(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the empty sound of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @param level the level, can be {@code null}
|
||||
* @param pos the position, can be {@code null}
|
||||
* @return the empty sound
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_EMPTY
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_EMPTY_LAVA
|
||||
*/
|
||||
@Nullable
|
||||
SoundEvent getEmptySound(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos);
|
||||
|
||||
/**
|
||||
* Returns the empty sound of the fluid.
|
||||
*
|
||||
* @param stack the fluid stack, can be {@code null}
|
||||
* @return the empty sound
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_EMPTY
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_EMPTY_LAVA
|
||||
*/
|
||||
@Nullable
|
||||
default SoundEvent getEmptySound(@Nullable FluidStack stack) {
|
||||
return getEmptySound(stack, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the empty sound of the fluid.
|
||||
*
|
||||
* @return the empty sound
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_EMPTY
|
||||
* @see net.minecraft.sounds.SoundEvents#BUCKET_EMPTY_LAVA
|
||||
*/
|
||||
@Nullable
|
||||
default SoundEvent getEmptySound() {
|
||||
return getEmptySound(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import dev.architectury.registry.registries.Registries;
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SimpleArchitecturyFluidAttributes implements ArchitecturyFluidAttributes {
|
||||
private final Supplier<? extends Fluid> flowingFluid;
|
||||
private final Supplier<? extends Fluid> sourceFluid;
|
||||
private boolean canConvertToSource = false;
|
||||
private int slopeFindDistance = 4;
|
||||
private int dropOff = 1;
|
||||
private Supplier<? extends Optional<Item>> bucketItem = Optional::empty;
|
||||
private int tickDelay = 5;
|
||||
private float explosionResistance = 100.0F;
|
||||
private Supplier<? extends Optional<? extends LiquidBlock>> block = Optional::empty;
|
||||
@Nullable
|
||||
private ResourceLocation sourceTexture;
|
||||
@Nullable
|
||||
private ResourceLocation flowingTexture;
|
||||
private int color = 0xffffff;
|
||||
private int luminosity = 0;
|
||||
private int density = 1000;
|
||||
private int temperature = 300;
|
||||
private int viscosity = 1000;
|
||||
private boolean lighterThanAir = false;
|
||||
private Rarity rarity = Rarity.COMMON;
|
||||
@Nullable
|
||||
private SoundEvent fillSound = SoundEvents.BUCKET_FILL;
|
||||
@Nullable
|
||||
private SoundEvent emptySound = SoundEvents.BUCKET_EMPTY;
|
||||
private final Supplier<String> defaultTranslationKey = Suppliers.memoize(() -> Util.makeDescriptionId("fluid", Registries.getId(getSourceFluid(), Registry.FLUID_REGISTRY)));
|
||||
|
||||
public static SimpleArchitecturyFluidAttributes ofSupplier(Supplier<? extends Supplier<? extends Fluid>> flowingFluid, Supplier<? extends Supplier<? extends Fluid>> sourceFluid) {
|
||||
return of(() -> flowingFluid.get().get(), () -> sourceFluid.get().get());
|
||||
}
|
||||
|
||||
|
||||
public static SimpleArchitecturyFluidAttributes of(Supplier<? extends Fluid> flowingFluid, Supplier<? extends Fluid> sourceFluid) {
|
||||
return new SimpleArchitecturyFluidAttributes(flowingFluid, sourceFluid);
|
||||
}
|
||||
|
||||
protected SimpleArchitecturyFluidAttributes(Supplier<? extends Fluid> flowingFluid, Supplier<? extends Fluid> sourceFluid) {
|
||||
this.flowingFluid = flowingFluid;
|
||||
this.sourceFluid = sourceFluid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#canConvertToSource()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes convertToSource(boolean canConvertToSource) {
|
||||
this.canConvertToSource = canConvertToSource;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getSlopeFindDistance(LevelReader)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes slopeFindDistance(int slopeFindDistance) {
|
||||
this.slopeFindDistance = slopeFindDistance;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getDropOff(LevelReader)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes dropOff(int dropOff) {
|
||||
this.dropOff = dropOff;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getBucketItem()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes bucketItemSupplier(Supplier<RegistrySupplier<Item>> bucketItem) {
|
||||
return bucketItem(() -> bucketItem.get().toOptional());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getBucketItem()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes bucketItem(RegistrySupplier<Item> bucketItem) {
|
||||
return bucketItem(bucketItem::toOptional);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getBucketItem()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes bucketItem(Supplier<? extends Optional<Item>> bucketItem) {
|
||||
this.bucketItem = Objects.requireNonNull(bucketItem);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getTickDelay(LevelReader)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes tickDelay(int tickDelay) {
|
||||
this.tickDelay = tickDelay;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getExplosionResistance()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes explosionResistance(float explosionResistance) {
|
||||
this.explosionResistance = explosionResistance;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getBlock()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes blockSupplier(Supplier<RegistrySupplier<? extends LiquidBlock>> block) {
|
||||
return block(() -> block.get().toOptional());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getBlock()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes block(RegistrySupplier<? extends LiquidBlock> block) {
|
||||
return block(block::toOptional);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getBlock()
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes block(Supplier<? extends Optional<? extends LiquidBlock>> block) {
|
||||
this.block = Objects.requireNonNull(block);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getSourceTexture(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes sourceTexture(ResourceLocation sourceTexture) {
|
||||
this.sourceTexture = sourceTexture;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getFlowingTexture(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes flowingTexture(ResourceLocation flowingTexture) {
|
||||
this.flowingTexture = flowingTexture;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getColor(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes color(int color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getLuminosity(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes luminosity(int luminosity) {
|
||||
this.luminosity = luminosity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getDensity(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes density(int density) {
|
||||
this.density = density;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getTemperature(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes temperature(int temperature) {
|
||||
this.temperature = temperature;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getViscosity(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes viscosity(int viscosity) {
|
||||
this.viscosity = viscosity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#isLighterThanAir(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes lighterThanAir(boolean lighterThanAir) {
|
||||
this.lighterThanAir = lighterThanAir;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getRarity(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes rarity(Rarity rarity) {
|
||||
this.rarity = rarity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getFillSound(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes fillSound(SoundEvent fillSound) {
|
||||
this.fillSound = fillSound;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ArchitecturyFluidAttributes#getEmptySound(FluidStack, BlockAndTintGetter, BlockPos)
|
||||
*/
|
||||
public SimpleArchitecturyFluidAttributes emptySound(SoundEvent emptySound) {
|
||||
this.emptySound = emptySound;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getTranslationKey(@Nullable FluidStack stack) {
|
||||
return defaultTranslationKey.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Fluid getFlowingFluid() {
|
||||
return flowingFluid.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Fluid getSourceFluid() {
|
||||
return sourceFluid.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConvertToSource() {
|
||||
return canConvertToSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlopeFindDistance(@Nullable LevelReader level) {
|
||||
return slopeFindDistance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDropOff(@Nullable LevelReader level) {
|
||||
return dropOff;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Item getBucketItem() {
|
||||
return bucketItem.get().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTickDelay(@Nullable LevelReader level) {
|
||||
return tickDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getExplosionResistance() {
|
||||
return explosionResistance;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public LiquidBlock getBlock() {
|
||||
return block.get().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getSourceTexture(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return sourceTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return flowingTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLuminosity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return luminosity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDensity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return density;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTemperature(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViscosity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return viscosity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLighterThanAir(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return lighterThanAir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rarity getRarity(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return rarity;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public SoundEvent getFillSound(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return fillSound;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public SoundEvent getEmptySound(@Nullable FluidStack stack, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos) {
|
||||
return emptySound;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.item;
|
||||
|
||||
import dev.architectury.hooks.fluid.FluidBucketHooks;
|
||||
import dev.architectury.platform.Platform;
|
||||
import net.minecraft.world.item.BucketItem;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyBucketItem extends BucketItem {
|
||||
public ArchitecturyBucketItem(Supplier<? extends Fluid> fluid, Properties properties) {
|
||||
super(checkPlatform(fluid).get(), properties);
|
||||
}
|
||||
|
||||
private static <T> T checkPlatform(T obj) {
|
||||
if (Platform.isForge()) {
|
||||
throw new IllegalStateException("This class should've been replaced on Forge!");
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public final Fluid getContainedFluid() {
|
||||
return FluidBucketHooks.getFluid(this);
|
||||
}
|
||||
}
|
||||
@@ -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.item;
|
||||
|
||||
import dev.architectury.platform.Platform;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.MobBucketItem;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyMobBucketItem extends MobBucketItem {
|
||||
public ArchitecturyMobBucketItem(Supplier<? extends EntityType<?>> entity, Supplier<? extends Fluid> fluid, Supplier<? extends SoundEvent> sound, Properties properties) {
|
||||
super(checkPlatform(entity).get(), fluid.get(), sound.get(), properties);
|
||||
}
|
||||
|
||||
private static <T> T checkPlatform(T obj) {
|
||||
if (Platform.isForge()) {
|
||||
throw new IllegalStateException("This class should've been replaced on Forge!");
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.item;
|
||||
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.item.RecordItem;
|
||||
|
||||
public class ArchitecturyRecordItem extends RecordItem {
|
||||
private final RegistrySupplier<SoundEvent> sound;
|
||||
|
||||
public ArchitecturyRecordItem(int analogOutput, RegistrySupplier<SoundEvent> sound, Properties properties) {
|
||||
super(analogOutput, sound.orElse(null), properties);
|
||||
this.sound = sound;
|
||||
|
||||
if (!sound.isPresent()) {
|
||||
RecordItem.BY_NAME.remove(null);
|
||||
|
||||
sound.listen(soundEvent -> {
|
||||
RecordItem.BY_NAME.put(soundEvent, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getSound() {
|
||||
return sound.get();
|
||||
}
|
||||
}
|
||||
@@ -20,29 +20,62 @@
|
||||
package dev.architectury.fluid;
|
||||
|
||||
import dev.architectury.hooks.fluid.FluidStackHooks;
|
||||
import dev.architectury.utils.NbtType;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
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.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class FluidStack {
|
||||
private static final FluidStackAdapter<Object> ADAPTER = adapt(FluidStack::getValue, FluidStack::new);
|
||||
private static final FluidStack EMPTY = create(Fluids.EMPTY, 0);
|
||||
private long amount;
|
||||
@Nullable
|
||||
private CompoundTag tag;
|
||||
private Supplier<Fluid> fluid;
|
||||
|
||||
private Object value;
|
||||
|
||||
private FluidStack(Supplier<Fluid> fluid, long amount, CompoundTag tag) {
|
||||
this.fluid = Objects.requireNonNull(fluid);
|
||||
this.amount = amount;
|
||||
this.tag = tag == null ? null : tag.copy();
|
||||
this(ADAPTER.create(fluid, amount, tag));
|
||||
}
|
||||
|
||||
private FluidStack(Object value) {
|
||||
this.value = Objects.requireNonNull(value);
|
||||
}
|
||||
|
||||
private Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
private static FluidStackAdapter<Object> adapt(Function<FluidStack, Object> toValue, Function<Object, FluidStack> fromValue) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public interface FluidStackAdapter<T> {
|
||||
T create(Supplier<Fluid> fluid, long amount, CompoundTag tag);
|
||||
|
||||
Supplier<Fluid> getRawFluidSupplier(T object);
|
||||
|
||||
Fluid getFluid(T object);
|
||||
|
||||
long getAmount(T object);
|
||||
|
||||
void setAmount(T object, long amount);
|
||||
|
||||
CompoundTag getTag(T value);
|
||||
|
||||
void setTag(T value, CompoundTag tag);
|
||||
|
||||
T copy(T value);
|
||||
|
||||
int hashCode(T value);
|
||||
}
|
||||
|
||||
public static FluidStack empty() {
|
||||
@@ -73,67 +106,72 @@ public final class FluidStack {
|
||||
return FluidStackHooks.bucketAmount();
|
||||
}
|
||||
|
||||
public final Fluid getFluid() {
|
||||
public Fluid getFluid() {
|
||||
return isEmpty() ? Fluids.EMPTY : getRawFluid();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final Fluid getRawFluid() {
|
||||
return fluid.get();
|
||||
public Fluid getRawFluid() {
|
||||
return ADAPTER.getFluid(value);
|
||||
}
|
||||
|
||||
public final Supplier<Fluid> getRawFluidSupplier() {
|
||||
return fluid;
|
||||
public Supplier<Fluid> getRawFluidSupplier() {
|
||||
return ADAPTER.getRawFluidSupplier(value);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return getRawFluid() == Fluids.EMPTY || amount <= 0;
|
||||
return getRawFluid() == Fluids.EMPTY || ADAPTER.getAmount(value) <= 0;
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return isEmpty() ? 0 : amount;
|
||||
return isEmpty() ? 0 : ADAPTER.getAmount(value);
|
||||
}
|
||||
|
||||
public void setAmount(long amount) {
|
||||
this.amount = amount;
|
||||
ADAPTER.setAmount(value, amount);
|
||||
}
|
||||
|
||||
public void grow(long amount) {
|
||||
setAmount(this.amount + amount);
|
||||
setAmount(getAmount() + amount);
|
||||
}
|
||||
|
||||
public void shrink(long amount) {
|
||||
setAmount(this.amount - amount);
|
||||
setAmount(getAmount() - amount);
|
||||
}
|
||||
|
||||
public boolean hasTag() {
|
||||
return tag != null;
|
||||
return getTag() != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompoundTag getTag() {
|
||||
return tag;
|
||||
return ADAPTER.getTag(value);
|
||||
}
|
||||
|
||||
public void setTag(@Nullable CompoundTag tag) {
|
||||
this.tag = tag;
|
||||
ADAPTER.setTag(value, tag);
|
||||
}
|
||||
|
||||
public CompoundTag getOrCreateTag() {
|
||||
if (tag == null)
|
||||
setTag(new CompoundTag());
|
||||
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) {
|
||||
getOrCreateTag();
|
||||
CompoundTag tag = getOrCreateTag();
|
||||
var child = tag.getCompound(childName);
|
||||
if (!tag.contains(childName, Tag.TAG_COMPOUND)) {
|
||||
tag.put(childName, child);
|
||||
@@ -142,6 +180,7 @@ public final class FluidStack {
|
||||
}
|
||||
|
||||
public void removeChildTag(String childName) {
|
||||
CompoundTag tag = getTag();
|
||||
if (tag != null)
|
||||
tag.remove(childName);
|
||||
}
|
||||
@@ -155,21 +194,16 @@ public final class FluidStack {
|
||||
}
|
||||
|
||||
public FluidStack copy() {
|
||||
return new FluidStack(fluid, amount, tag);
|
||||
return new FluidStack(ADAPTER.copy(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
var code = 1;
|
||||
code = 31 * code + getFluid().hashCode();
|
||||
code = 31 * code + Long.hashCode(amount);
|
||||
if (tag != null)
|
||||
code = 31 * code + tag.hashCode();
|
||||
return code;
|
||||
public int hashCode() {
|
||||
return ADAPTER.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object o) {
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof FluidStack)) {
|
||||
return false;
|
||||
}
|
||||
@@ -180,8 +214,14 @@ public final class FluidStack {
|
||||
return getFluid() == other.getFluid() && getAmount() == other.getAmount() && isTagEqual(other);
|
||||
}
|
||||
|
||||
private boolean isTagEqual(FluidStack other) {
|
||||
return tag == null ? other.tag == null : other.tag != null && tag.equals(other.tag);
|
||||
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 static FluidStack read(FriendlyByteBuf buf) {
|
||||
@@ -199,4 +239,15 @@ public final class FluidStack {
|
||||
public CompoundTag write(CompoundTag tag) {
|
||||
return FluidStackHooks.write(this, tag);
|
||||
}
|
||||
|
||||
public FluidStack copyWithAmount(long amount) {
|
||||
if (isEmpty()) return this;
|
||||
return new FluidStack(getRawFluidSupplier(), amount, getTag());
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void init() {
|
||||
// classloading my beloved 😍
|
||||
// please don't use this by the way
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,16 @@ package dev.architectury.hooks.item.tool;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.world.item.HoeItem;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public final class HoeItemHooks {
|
||||
@@ -48,10 +52,25 @@ public final class HoeItemHooks {
|
||||
* @param predicate context predicate
|
||||
* @param action action to run
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static void addTillable(Block input, Predicate<UseOnContext> predicate, Consumer<UseOnContext> action) {
|
||||
if (HoeItem.TILLABLES instanceof ImmutableMap) {
|
||||
HoeItem.TILLABLES = new HashMap<>(HoeItem.TILLABLES);
|
||||
}
|
||||
HoeItem.TILLABLES.put(input, new Pair<>(predicate, action));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new tilling action.
|
||||
*
|
||||
* @param input input block
|
||||
* @param predicate context predicate
|
||||
* @param action action to run
|
||||
* @param newState the new block state
|
||||
*/
|
||||
@ExpectPlatform
|
||||
public static void addTillable(Block input, Predicate<UseOnContext> predicate, Consumer<UseOnContext> action, Function<UseOnContext, BlockState> newState) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
38
common/src/main/java/dev/architectury/utils/Amount.java
Normal file
38
common/src/main/java/dev/architectury/utils/Amount.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
public class Amount {
|
||||
/**
|
||||
* Converts a long to an int while dropping overflowed values.
|
||||
*
|
||||
* @param amount the long to convert
|
||||
* @return the int value
|
||||
*/
|
||||
public static int toInt(long amount) {
|
||||
if (amount >= Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else if (amount <= Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
return (int) amount;
|
||||
}
|
||||
}
|
||||
@@ -120,6 +120,7 @@ transitive-accessible class net/minecraft/client/renderer/RenderType$OutlineProp
|
||||
accessible field net/minecraft/world/item/SpawnEggItem BY_ID Ljava/util/Map;
|
||||
accessible field net/minecraft/world/item/SpawnEggItem defaultType Lnet/minecraft/world/entity/EntityType;
|
||||
mutable field net/minecraft/world/item/SpawnEggItem defaultType Lnet/minecraft/world/entity/EntityType;
|
||||
accessible field net/minecraft/world/item/RecordItem BY_NAME Ljava/util/Map;
|
||||
accessible field net/minecraft/client/particle/ParticleEngine textureAtlas Lnet/minecraft/client/renderer/texture/TextureAtlas;
|
||||
accessible class net/minecraft/client/particle/ParticleEngine$MutableSpriteSet
|
||||
accessible field net/minecraft/client/particle/ParticleEngine$MutableSpriteSet sprites Ljava/util/List;
|
||||
|
||||
@@ -102,7 +102,7 @@ curseforge {
|
||||
if (project.hasProperty("CURSE_API_KEY") || System.getenv("CURSE_API_KEY") != null) {
|
||||
apiKey = project.hasProperty("CURSE_API_KEY") ? project.property("CURSE_API_KEY") : System.getenv("CURSE_API_KEY")
|
||||
project {
|
||||
id = "419697"
|
||||
id = "419699"
|
||||
releaseType = "$rootProject.cf_type"
|
||||
changelogType = "html"
|
||||
changelog = releaseChangelog()
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
static {
|
||||
dev.architectury.fluid.FluidStack.init();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.architectury.hooks.item.tool.fabric;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.world.item.HoeItem;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class HoeItemHooksImpl {
|
||||
public static void addTillable(Block input, Predicate<UseOnContext> predicate, Consumer<UseOnContext> action, Function<UseOnContext, BlockState> newState) {
|
||||
if (HoeItem.TILLABLES instanceof ImmutableMap) {
|
||||
HoeItem.TILLABLES = new HashMap<>(HoeItem.TILLABLES);
|
||||
}
|
||||
HoeItem.TILLABLES.put(input, new Pair<>(predicate, useOnContext -> {
|
||||
action.accept(useOnContext);
|
||||
BlockState state = newState.apply(useOnContext);
|
||||
useOnContext.getLevel().setBlock(useOnContext.getClickedPos(), state, 11);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package dev.architectury.registry.registries.fabric;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
@@ -34,6 +35,7 @@ import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -48,7 +50,8 @@ public class RegistriesImpl {
|
||||
|
||||
private static void listen(ResourceKey<?> resourceKey, ResourceLocation id, Consumer<?> listener) {
|
||||
if (LISTENED_REGISTRIES.add(resourceKey)) {
|
||||
RegistryEntryAddedCallback.event(Registry.REGISTRY.get(resourceKey.location())).register((rawId, entryId, object) -> {
|
||||
Registry<?> registry = MoreObjects.firstNonNull(Registry.REGISTRY.get(resourceKey.location()), BuiltinRegistries.REGISTRY.get(resourceKey.location()));
|
||||
RegistryEntryAddedCallback.event(registry).register((rawId, entryId, object) -> {
|
||||
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, entryId);
|
||||
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
|
||||
((Consumer<Object>) consumer).accept(object);
|
||||
@@ -67,7 +70,7 @@ public class RegistriesImpl {
|
||||
public static <T> ResourceLocation getId(T object, ResourceKey<Registry<T>> fallback) {
|
||||
if (fallback == null)
|
||||
return null;
|
||||
return getId(object, (Registry<T>) Registry.REGISTRY.get(fallback.location()));
|
||||
return getId(object, (Registry<T>) MoreObjects.firstNonNull(Registry.REGISTRY.get(fallback.location()), BuiltinRegistries.REGISTRY.get(fallback.location())));
|
||||
}
|
||||
|
||||
public static <T> ResourceLocation getId(T object, Registry<T> fallback) {
|
||||
@@ -85,7 +88,7 @@ public class RegistriesImpl {
|
||||
|
||||
@Override
|
||||
public <T> Registrar<T> get(ResourceKey<Registry<T>> key) {
|
||||
return new RegistrarImpl<>(modId, (Registry<T>) Registry.REGISTRY.get(key.location()));
|
||||
return new RegistrarImpl<>(modId, (Registry<T>) MoreObjects.firstNonNull(Registry.REGISTRY.get(key.location()), BuiltinRegistries.REGISTRY.get(key.location())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -49,6 +49,17 @@ shadowJar {
|
||||
|
||||
configurations = [project.configurations.shadowCommon]
|
||||
classifier "dev-shadow"
|
||||
|
||||
// Replace classes with forge's version
|
||||
exclude "dev/architectury/core/block/ArchitecturyLiquidBlock.class"
|
||||
exclude "dev/architectury/core/fluid/ArchitecturyFlowingFluid.class"
|
||||
exclude 'dev/architectury/core/fluid/ArchitecturyFlowingFluid$Source.class'
|
||||
exclude 'dev/architectury/core/fluid/ArchitecturyFlowingFluid$Flowing.class'
|
||||
exclude 'dev/architectury/core/item/ArchitecturyBucketItem.class'
|
||||
exclude 'dev/architectury/core/item/ArchitecturyMobBucketItem.class'
|
||||
relocate "dev.architectury.core.block.forge.imitator", "dev.architectury.core.block"
|
||||
relocate "dev.architectury.core.fluid.forge.imitator", "dev.architectury.core.fluid"
|
||||
relocate "dev.architectury.core.item.forge.imitator", "dev.architectury.core.item"
|
||||
}
|
||||
|
||||
remapJar {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.block.forge.imitator;
|
||||
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyLiquidBlock extends LiquidBlock {
|
||||
public ArchitecturyLiquidBlock(Supplier<? extends FlowingFluid> fluid, Properties properties) {
|
||||
super(fluid, properties);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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.forge.imitator;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
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.ForgeFlowingFluid;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class ArchitecturyFlowingFluid extends ForgeFlowingFluid {
|
||||
private final ArchitecturyFluidAttributes attributes;
|
||||
|
||||
ArchitecturyFlowingFluid(ArchitecturyFluidAttributes attributes) {
|
||||
super(toForgeProperties(attributes));
|
||||
this.attributes = 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();
|
||||
forge.slopeFindDistance(attributes.getSlopeFindDistance());
|
||||
forge.levelDecreasePerBlock(attributes.getDropOff());
|
||||
forge.bucket(() -> MoreObjects.firstNonNull(attributes.getBucketItem(), Items.AIR));
|
||||
forge.tickRate(attributes.getTickDelay());
|
||||
forge.explosionResistance(attributes.getExplosionResistance());
|
||||
forge.block(() -> MoreObjects.firstNonNull(attributes.getBlock(), (LiquidBlock) Blocks.WATER));
|
||||
return forge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fluid getFlowing() {
|
||||
return attributes.getFlowingFluid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fluid getSource() {
|
||||
return attributes.getSourceFluid();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canConvertToSource() {
|
||||
return attributes.canConvertToSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state) {
|
||||
// Same implementation as in WaterFluid.
|
||||
BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(pos) : null;
|
||||
Block.dropResources(state, level, pos, blockEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSlopeFindDistance(LevelReader level) {
|
||||
return attributes.getSlopeFindDistance(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDropOff(LevelReader level) {
|
||||
return attributes.getDropOff(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getBucket() {
|
||||
Item item = attributes.getBucketItem();
|
||||
return item == null ? Items.AIR : item;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBeReplacedWith(FluidState state, BlockGetter level, BlockPos pos, Fluid fluid, Direction direction) {
|
||||
// Same implementation as in WaterFluid.
|
||||
return direction == Direction.DOWN && !this.isSame(fluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTickDelay(LevelReader level) {
|
||||
return attributes.getTickDelay(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getExplosionResistance() {
|
||||
return attributes.getExplosionResistance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createLegacyBlock(FluidState state) {
|
||||
LiquidBlock block = attributes.getBlock();
|
||||
if (block == null) return Blocks.AIR.defaultBlockState();
|
||||
return block.defaultBlockState().setValue(LiquidBlock.LEVEL, getLegacyLevel(state));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Optional<SoundEvent> getPickupSound() {
|
||||
return Optional.ofNullable(attributes.getFillSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSame(Fluid fluid) {
|
||||
return fluid == getSource() || fluid == getFlowing();
|
||||
}
|
||||
|
||||
public static class Source extends ArchitecturyFlowingFluid {
|
||||
public Source(ArchitecturyFluidAttributes attributes) {
|
||||
super(attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(FluidState state) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSource(FluidState state) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Flowing extends ArchitecturyFlowingFluid {
|
||||
public Flowing(ArchitecturyFluidAttributes attributes) {
|
||||
super(attributes);
|
||||
this.registerDefaultState(this.getStateDefinition().any().setValue(LEVEL, 7));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createFluidStateDefinition(StateDefinition.Builder<Fluid, FluidState> builder) {
|
||||
super.createFluidStateDefinition(builder);
|
||||
builder.add(LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(FluidState state) {
|
||||
return state.getValue(LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSource(FluidState state) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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.forge.imitator;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
|
||||
import dev.architectury.hooks.fluid.forge.FluidStackHooksForge;
|
||||
import net.minecraft.Util;
|
||||
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.item.Rarity;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.fluids.FluidAttributes;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
class ArchitecturyFluidAttributesForge extends FluidAttributes {
|
||||
private final ArchitecturyFluidAttributes attributes;
|
||||
private final String defaultTranslationKey;
|
||||
|
||||
public ArchitecturyFluidAttributesForge(Builder builder, Fluid fluid, ArchitecturyFluidAttributes attributes) {
|
||||
super(addArchIntoBuilder(builder, attributes), fluid);
|
||||
this.attributes = attributes;
|
||||
this.defaultTranslationKey = Util.makeDescriptionId("fluid", fluid.getRegistryName());
|
||||
}
|
||||
|
||||
private static Builder addArchIntoBuilder(Builder builder, ArchitecturyFluidAttributes attributes) {
|
||||
builder.luminosity(attributes.getLuminosity())
|
||||
.density(attributes.getDensity())
|
||||
.temperature(attributes.getTemperature())
|
||||
.viscosity(attributes.getViscosity());
|
||||
if (attributes.isLighterThanAir()) builder.gaseous();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture() {
|
||||
return attributes.getSourceTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture(FluidStack stack) {
|
||||
return attributes.getSourceTexture(stack == null ? null : FluidStackHooksForge.fromForge(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture(BlockAndTintGetter level, BlockPos pos) {
|
||||
return attributes.getSourceTexture(null, level, pos);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDensity(FluidStack stack) {
|
||||
return attributes.getDensity(stack == null ? null : FluidStackHooksForge.fromForge(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDensity(BlockAndTintGetter level, BlockPos pos) {
|
||||
return attributes.getDensity(null, level, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTemperature(FluidStack stack) {
|
||||
return attributes.getTemperature(stack == null ? null : FluidStackHooksForge.fromForge(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTemperature(BlockAndTintGetter level, BlockPos pos) {
|
||||
return attributes.getTemperature(null, level, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViscosity(FluidStack stack) {
|
||||
return attributes.getViscosity(stack == null ? null : FluidStackHooksForge.fromForge(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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rarity getRarity() {
|
||||
return attributes.getRarity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rarity getRarity(FluidStack stack) {
|
||||
return attributes.getRarity(stack == null ? null : FluidStackHooksForge.fromForge(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rarity getRarity(BlockAndTintGetter level, BlockPos pos) {
|
||||
return attributes.getRarity(null, level, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getDisplayName(FluidStack stack) {
|
||||
return attributes.getName(stack == null ? null : FluidStackHooksForge.fromForge(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey() {
|
||||
return MoreObjects.firstNonNull(attributes.getTranslationKey(), defaultTranslationKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(FluidStack stack) {
|
||||
return MoreObjects.firstNonNull(attributes.getTranslationKey(stack == null ? null : FluidStackHooksForge.fromForge(stack)), defaultTranslationKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getFillSound() {
|
||||
return attributes.getFillSound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getFillSound(FluidStack stack) {
|
||||
return attributes.getFillSound(stack == null ? null : FluidStackHooksForge.fromForge(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getFillSound(BlockAndTintGetter level, BlockPos pos) {
|
||||
return attributes.getFillSound(null, level, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getEmptySound() {
|
||||
return attributes.getEmptySound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getEmptySound(FluidStack stack) {
|
||||
return attributes.getEmptySound(stack == null ? null : FluidStackHooksForge.fromForge(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getEmptySound(BlockAndTintGetter level, BlockPos pos) {
|
||||
return attributes.getEmptySound(null, level, pos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.item.forge.imitator;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.BucketItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyBucketItem extends BucketItem {
|
||||
public ArchitecturyBucketItem(Supplier<? extends Fluid> fluid, Properties properties) {
|
||||
super(fluid, properties);
|
||||
}
|
||||
|
||||
public final Fluid getContainedFluid() {
|
||||
return getFluid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
|
||||
return this.getClass() == ArchitecturyBucketItem.class ? new FluidBucketWrapper(stack) : super.initCapabilities(stack, nbt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.item.forge.imitator;
|
||||
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.MobBucketItem;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyMobBucketItem extends MobBucketItem {
|
||||
public ArchitecturyMobBucketItem(Supplier<? extends EntityType<?>> entity, Supplier<? extends Fluid> fluid, Supplier<? extends SoundEvent> sound, Properties properties) {
|
||||
super(entity, fluid, sound, properties);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.forge;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static dev.architectury.utils.Amount.toInt;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public enum FluidStackImpl implements dev.architectury.fluid.FluidStack.FluidStackAdapter<FluidStack> {
|
||||
INSTANCE;
|
||||
|
||||
static {
|
||||
dev.architectury.fluid.FluidStack.init();
|
||||
}
|
||||
|
||||
public static Function<dev.architectury.fluid.FluidStack, Object> toValue;
|
||||
public static Function<Object, dev.architectury.fluid.FluidStack> fromValue;
|
||||
|
||||
public static dev.architectury.fluid.FluidStack.FluidStackAdapter<Object> adapt(Function<dev.architectury.fluid.FluidStack, Object> toValue, Function<Object, dev.architectury.fluid.FluidStack> fromValue) {
|
||||
FluidStackImpl.toValue = toValue;
|
||||
FluidStackImpl.fromValue = fromValue;
|
||||
return (dev.architectury.fluid.FluidStack.FluidStackAdapter<Object>) (dev.architectury.fluid.FluidStack.FluidStackAdapter<?>) INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack create(Supplier<Fluid> fluid, long amount, CompoundTag tag) {
|
||||
return new FluidStack(fluid.get(), toInt(amount), tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<Fluid> getRawFluidSupplier(FluidStack object) {
|
||||
return object.getRawFluid().delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fluid getFluid(FluidStack object) {
|
||||
return object.getFluid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAmount(FluidStack object) {
|
||||
return object.getAmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(FluidStack object, long amount) {
|
||||
object.setAmount(toInt(amount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTag(FluidStack value) {
|
||||
return value.getTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTag(FluidStack value, CompoundTag tag) {
|
||||
value.setTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack copy(FluidStack value) {
|
||||
return value.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(FluidStack value) {
|
||||
var code = 1;
|
||||
code = 31 * code + value.getFluid().hashCode();
|
||||
code = 31 * code + value.getAmount();
|
||||
var tag = value.getTag();
|
||||
if (tag != null)
|
||||
code = 31 * code + tag.hashCode();
|
||||
return code;
|
||||
}
|
||||
}
|
||||
@@ -20,16 +20,17 @@
|
||||
package dev.architectury.hooks.fluid.forge;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import dev.architectury.fluid.forge.FluidStackImpl;
|
||||
|
||||
public final class FluidStackHooksForge {
|
||||
private FluidStackHooksForge() {
|
||||
}
|
||||
|
||||
public static FluidStack fromForge(net.minecraftforge.fluids.FluidStack stack) {
|
||||
return FluidStack.create(stack.getFluid().delegate, stack.getAmount(), stack.getTag());
|
||||
return FluidStackImpl.fromValue.apply(stack);
|
||||
}
|
||||
|
||||
public static net.minecraftforge.fluids.FluidStack toForge(FluidStack stack) {
|
||||
return new net.minecraftforge.fluids.FluidStack(stack.getRawFluid(), (int) stack.getAmount(), stack.getTag());
|
||||
return (net.minecraftforge.fluids.FluidStack) FluidStackImpl.toValue.apply(stack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.architectury.hooks.item.tool.forge;
|
||||
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.ToolActions;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class HoeItemHooksImpl {
|
||||
public static void addTillable(Block input, Predicate<UseOnContext> predicate, Consumer<UseOnContext> action, Function<UseOnContext, BlockState> function) {
|
||||
MinecraftForge.EVENT_BUS.<BlockEvent.BlockToolModificationEvent>addListener(event -> {
|
||||
UseOnContext context = event.getContext();
|
||||
if (ToolActions.HOE_TILL == event.getToolAction() && context.getItemInHand().canPerformAction(ToolActions.HOE_TILL)
|
||||
&& event.getState().is(input) && predicate.test(context)) {
|
||||
if (!event.isSimulated()) {
|
||||
action.accept(context);
|
||||
}
|
||||
|
||||
event.setFinalState(function.apply(context));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import dev.architectury.registry.registries.options.RegistrarOption;
|
||||
import dev.architectury.registry.registries.options.StandardRegistrarOption;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -42,8 +43,9 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.registries.*;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
@@ -134,11 +136,18 @@ public class RegistriesImpl {
|
||||
}
|
||||
|
||||
public static class RegistryProviderImpl implements Registries.RegistryProvider {
|
||||
private static final Map<ResourceKey<Registry<?>>, Registrar<?>> CUSTOM_REGS = new HashMap<>();
|
||||
private final String modId;
|
||||
private final Supplier<IEventBus> eventBus;
|
||||
private final Map<ResourceKey<? extends Registry<?>>, Data> registry = new HashMap<>();
|
||||
private final Multimap<ResourceKey<Registry<?>>, Consumer<Registrar<?>>> listeners = HashMultimap.create();
|
||||
|
||||
record RegistryBuilderEntry(RegistryBuilder<?> builder, Consumer<IForgeRegistry<?>> forgeRegistry) {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<RegistryBuilderEntry> builders = new ArrayList<>();
|
||||
|
||||
public RegistryProviderImpl(String modId) {
|
||||
this.modId = modId;
|
||||
this.eventBus = Suppliers.memoize(() -> {
|
||||
@@ -161,11 +170,13 @@ public class RegistriesImpl {
|
||||
ForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(registryKey.location());
|
||||
if (registry == null) {
|
||||
Registry<T> ts = (Registry<T>) Registry.REGISTRY.get(registryKey.location());
|
||||
if (ts == null) {
|
||||
throw new IllegalArgumentException("Registry " + registryKey + " does not exist!");
|
||||
} else {
|
||||
if (ts == null) ts = (Registry<T>) BuiltinRegistries.REGISTRY.get(registryKey.location());
|
||||
if (ts != null) {
|
||||
return get(ts);
|
||||
}
|
||||
Registrar<?> customReg = RegistryProviderImpl.CUSTOM_REGS.get(registryKey);
|
||||
if (customReg != null) return (Registrar<T>) customReg;
|
||||
throw new IllegalArgumentException("Registry " + registryKey + " does not exist!");
|
||||
}
|
||||
return get(registry);
|
||||
}
|
||||
@@ -191,7 +202,7 @@ public class RegistriesImpl {
|
||||
public <T> RegistrarBuilder<T> builder(Class<T> type, ResourceLocation registryId) {
|
||||
return new RegistryBuilderWrapper<>(this, new net.minecraftforge.registries.RegistryBuilder<>()
|
||||
.setName(registryId)
|
||||
.setType((Class) type));
|
||||
.setType((Class) type), registryId);
|
||||
}
|
||||
|
||||
public class EventListener {
|
||||
@@ -325,25 +336,48 @@ public class RegistriesImpl {
|
||||
LISTENERS.removeAll(id);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleEvent(NewRegistryEvent event) {
|
||||
if (builders != null) {
|
||||
for (RegistryBuilderEntry builder : builders) {
|
||||
event.create((RegistryBuilder) builder.builder(), (Consumer) builder.forgeRegistry());
|
||||
}
|
||||
builders = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RegistryBuilderWrapper<T> implements RegistrarBuilder<T> {
|
||||
private final RegistryProviderImpl provider;
|
||||
private final net.minecraftforge.registries.RegistryBuilder<?> builder;
|
||||
private final ResourceLocation registryId;
|
||||
private boolean saveToDisk = false;
|
||||
private boolean syncToClients = false;
|
||||
|
||||
public RegistryBuilderWrapper(RegistryProviderImpl provider, net.minecraftforge.registries.RegistryBuilder<?> builder) {
|
||||
public RegistryBuilderWrapper(RegistryProviderImpl provider, RegistryBuilder<?> builder, ResourceLocation registryId) {
|
||||
this.provider = provider;
|
||||
this.builder = builder;
|
||||
this.registryId = registryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registrar<T> build() {
|
||||
if (!syncToClients) builder.disableSync();
|
||||
if (!saveToDisk) builder.disableSaving();
|
||||
return provider.get(builder.create());
|
||||
if (provider.builders == null) {
|
||||
throw new IllegalStateException("Cannot create registries when registries are already aggregated!");
|
||||
}
|
||||
final var registrarRef = new Registrar<?>[1];
|
||||
var registrar = new DelegatedRegistrar(provider.modId, () -> java.util.Objects.requireNonNull(registrarRef[0], "Registry not yet initialized!"), registryId);
|
||||
var entry = new RegistryProviderImpl.RegistryBuilderEntry(builder, forgeRegistry -> {
|
||||
registrarRef[0] = provider.get(forgeRegistry);
|
||||
registrar.onRegister();
|
||||
});
|
||||
provider.builders.add(entry);
|
||||
RegistryProviderImpl.CUSTOM_REGS.put(registrar.key(), registrar);
|
||||
return registrar;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -565,7 +599,7 @@ public class RegistriesImpl {
|
||||
|
||||
@Override
|
||||
public <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
|
||||
RegistryObject registryObject = RegistryObject.of(id, delegate);
|
||||
RegistryObject registryObject = RegistryObject.create(id, delegate);
|
||||
registry.computeIfAbsent(key(), type -> new Data())
|
||||
.register(delegate, registryObject, () -> supplier.get().setRegistryName(id));
|
||||
Registrar<T> registrar = this;
|
||||
@@ -686,4 +720,141 @@ public class RegistriesImpl {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class DelegatedRegistrar<T> implements Registrar<T> {
|
||||
private final String modId;
|
||||
private final Supplier<Registrar<T>> delegate;
|
||||
private final ResourceLocation registryId;
|
||||
private List<Runnable> onRegister = new ArrayList<>();
|
||||
|
||||
public DelegatedRegistrar(String modId, Supplier<Registrar<T>> delegate, ResourceLocation registryId) {
|
||||
this.modId = modId;
|
||||
this.delegate = delegate;
|
||||
this.registryId = registryId;
|
||||
}
|
||||
|
||||
public void onRegister() {
|
||||
if (onRegister != null) {
|
||||
for (Runnable runnable : onRegister) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
onRegister = null;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return onRegister == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistrySupplier<T> delegate(ResourceLocation id) {
|
||||
if (isReady()) return delegate.get().delegate(id);
|
||||
return new RegistrySupplier<T>() {
|
||||
@Override
|
||||
public Registries getRegistries() {
|
||||
return Registries.get(modId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registrar<T> getRegistrar() {
|
||||
return DelegatedRegistrar.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getRegistryId() {
|
||||
return DelegatedRegistrar.this.key().location();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return isReady() && delegate.get().contains(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return isReady() ? delegate.get().get(id) : null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
|
||||
if (isReady()) return delegate.get().register(id, supplier);
|
||||
onRegister.add(() -> delegate.get().register(id, supplier));
|
||||
return (RegistrySupplier<E>) delegate(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getId(T obj) {
|
||||
return !isReady() ? null : delegate.get().getId(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawId(T obj) {
|
||||
return !isReady() ? -1 : delegate.get().getRawId(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ResourceKey<T>> getKey(T obj) {
|
||||
return !isReady() ? Optional.empty() : delegate.get().getKey(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T get(ResourceLocation id) {
|
||||
return !isReady() ? null : delegate.get().get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T byRawId(int rawId) {
|
||||
return !isReady() ? null : delegate.get().byRawId(rawId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(ResourceLocation id) {
|
||||
return isReady() && delegate.get().contains(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(T obj) {
|
||||
return isReady() && delegate.get().containsValue(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ResourceLocation> getIds() {
|
||||
return isReady() ? delegate.get().getIds() : Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Map.Entry<ResourceKey<T>, T>> entrySet() {
|
||||
return isReady() ? delegate.get().entrySet() : Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceKey<? extends Registry<T>> key() {
|
||||
return isReady() ? delegate.get().key() : ResourceKey.createRegistryKey(registryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listen(ResourceLocation id, Consumer<T> callback) {
|
||||
if (isReady()) {
|
||||
delegate.get().listen(id, callback);
|
||||
} else {
|
||||
onRegister.add(() -> delegate.get().listen(id, callback));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return isReady() ? delegate.get().iterator() : Collections.emptyIterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ cf_type=beta
|
||||
|
||||
archives_base_name=architectury
|
||||
archives_base_name_snapshot=architectury-snapshot
|
||||
base_version=5.3
|
||||
base_version=5.4
|
||||
maven_group=dev.architectury
|
||||
|
||||
fabric_loader_version=0.14.3
|
||||
fabric_api_version=0.52.1+1.19
|
||||
mod_menu_version=3.1.0
|
||||
|
||||
forge_version=40.0.1
|
||||
forge_version=40.1.14
|
||||
|
||||
@@ -30,28 +30,21 @@ import net.minecraft.world.level.block.Blocks;
|
||||
public final class TestBlockInteractions {
|
||||
private TestBlockInteractions() {
|
||||
}
|
||||
|
||||
|
||||
public static void init() {
|
||||
AxeItemHooks.addStrippable(Blocks.QUARTZ_PILLAR, Blocks.OAK_LOG);
|
||||
ShovelItemHooks.addFlattenable(Blocks.IRON_ORE, Blocks.DIAMOND_BLOCK.defaultBlockState());
|
||||
HoeItemHooks.addTillable(Blocks.COAL_BLOCK, ctx -> {
|
||||
if (!ctx.getLevel().isNight()) {
|
||||
if (!ctx.getLevel().isClientSide) {
|
||||
Player player = ctx.getPlayer();
|
||||
if (player != null)
|
||||
player.sendSystemMessage(Component.literal("These dark arts can only be done at night!"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return ctx.getLevel().isNight();
|
||||
}, ctx -> {
|
||||
BlockPos pos = ctx.getClickedPos();
|
||||
ctx.getLevel().setBlock(pos, Blocks.DIAMOND_BLOCK.defaultBlockState(), 3);
|
||||
if (!ctx.getLevel().isClientSide) {
|
||||
Player player = ctx.getPlayer();
|
||||
if (player != null)
|
||||
player.sendSystemMessage(Component.literal("Thou has successfully committed the dark arts of alchemy!!"));
|
||||
}
|
||||
}, ctx -> {
|
||||
return Blocks.DIAMOND_BLOCK.defaultBlockState();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,17 @@
|
||||
|
||||
package dev.architectury.test.registry;
|
||||
|
||||
import dev.architectury.core.RegistryEntry;
|
||||
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
|
||||
import dev.architectury.core.fluid.SimpleArchitecturyFluidAttributes;
|
||||
import dev.architectury.core.item.ArchitecturySpawnEggItem;
|
||||
import dev.architectury.hooks.item.food.FoodPropertiesHooks;
|
||||
import dev.architectury.hooks.level.entity.EntityHooks;
|
||||
import dev.architectury.registry.block.BlockProperties;
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.registry.level.entity.EntityAttributeRegistry;
|
||||
import dev.architectury.registry.registries.DeferredRegister;
|
||||
import dev.architectury.registry.registries.Registrar;
|
||||
import dev.architectury.registry.registries.Registries;
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import dev.architectury.test.TestMod;
|
||||
import dev.architectury.test.entity.TestEntity;
|
||||
@@ -33,6 +38,7 @@ import dev.architectury.test.registry.objects.EquippableTickingItem;
|
||||
import dev.architectury.test.tab.TestCreativeTabs;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectCategory;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
@@ -46,20 +52,50 @@ import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static dev.architectury.test.TestMod.SINK;
|
||||
|
||||
public class TestRegistries {
|
||||
public static final class TestInt extends RegistryEntry<TestInt> {
|
||||
public final int value;
|
||||
|
||||
public TestInt(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Registrar<TestInt> INTS = Registries.get(TestMod.MOD_ID).<TestInt>builder(new ResourceLocation(TestMod.MOD_ID, "ints"))
|
||||
.syncToClients()
|
||||
.build();
|
||||
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(TestMod.MOD_ID, Registry.ITEM_REGISTRY);
|
||||
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(TestMod.MOD_ID, Registry.BLOCK_REGISTRY);
|
||||
public static final DeferredRegister<Fluid> FLUIDS = DeferredRegister.create(TestMod.MOD_ID, Registry.FLUID_REGISTRY);
|
||||
public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(TestMod.MOD_ID, Registry.ENTITY_TYPE_REGISTRY);
|
||||
public static final DeferredRegister<MobEffect> MOB_EFFECTS = DeferredRegister.create(TestMod.MOD_ID, Registry.MOB_EFFECT_REGISTRY);
|
||||
public static final DeferredRegister<RecipeSerializer<?>> RECIPE_SERIALIZERS = DeferredRegister.create(TestMod.MOD_ID, Registry.RECIPE_SERIALIZER_REGISTRY);
|
||||
public static final DeferredRegister<RecipeType<?>> RECIPE_TYPES = DeferredRegister.create(TestMod.MOD_ID, Registry.RECIPE_TYPE_REGISTRY);
|
||||
|
||||
public static final ArchitecturyFluidAttributes TEST_FLUID_ATTRIBUTES = SimpleArchitecturyFluidAttributes.ofSupplier(() -> TestRegistries.TEST_FLUID_FLOWING, () -> TestRegistries.TEST_FLUID)
|
||||
.convertToSource(true)
|
||||
.flowingTexture(new ResourceLocation("block/water_flow"))
|
||||
.sourceTexture(new ResourceLocation("block/water_still"))
|
||||
.blockSupplier(() -> TestRegistries.TEST_FLUID_BLOCK)
|
||||
.bucketItemSupplier(() -> TestRegistries.TEST_FLUID_BUCKET)
|
||||
.color(0xFF0000);
|
||||
|
||||
public static final RegistrySupplier<TestInt> TEST_INT = INTS.register(new ResourceLocation(TestMod.MOD_ID, "test_int"), () -> new TestInt(1));
|
||||
public static final RegistrySupplier<TestInt> TEST_INT_2 = INTS.register(new ResourceLocation(TestMod.MOD_ID, "test_int_2"), () -> new TestInt(2));
|
||||
|
||||
public static final RegistrySupplier<MobEffect> TEST_EFFECT = MOB_EFFECTS.register("test_effect", () ->
|
||||
new MobEffect(MobEffectCategory.NEUTRAL, 0x123456) {
|
||||
});
|
||||
@@ -80,10 +116,21 @@ public class TestRegistries {
|
||||
new ArchitecturySpawnEggItem(TestRegistries.TEST_ENTITY_2, 0xFFFFFFFF, 0xFF000000,
|
||||
new Item.Properties().tab(TestCreativeTabs.TEST_TAB)));
|
||||
|
||||
public static final RegistrySupplier<Item> TEST_FLUID_BUCKET = ITEMS.register("test_fluid_bucket", () -> {
|
||||
try {
|
||||
// In example mod the forge class isn't being replaced, this is not required in mods depending on architectury
|
||||
return (Item) Class.forName(!Platform.isForge() ? "dev.architectury.core.item.ArchitecturyBucketItem" : "dev.architectury.core.item.forge.imitator.ArchitecturyBucketItem")
|
||||
.getDeclaredConstructor(Supplier.class, Item.Properties.class)
|
||||
.newInstance(TestRegistries.TEST_FLUID, new Item.Properties().tab(TestCreativeTabs.TEST_TAB));
|
||||
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
public static final RegistrySupplier<Block> TEST_BLOCK = BLOCKS.register("test_block", () ->
|
||||
new Block(BlockProperties.copy(Blocks.STONE)));
|
||||
new Block(BlockBehaviour.Properties.copy(Blocks.STONE)));
|
||||
public static final RegistrySupplier<Block> COLLISION_BLOCK = BLOCKS.register("collision_block", () ->
|
||||
new Block(BlockProperties.copy(Blocks.STONE)) {
|
||||
new Block(BlockBehaviour.Properties.copy(Blocks.STONE)) {
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockGetter bg, BlockPos pos, CollisionContext ctx) {
|
||||
SINK.accept(EntityHooks.fromCollision(ctx) + " is colliding with " + state);
|
||||
@@ -91,6 +138,39 @@ public class TestRegistries {
|
||||
}
|
||||
});
|
||||
|
||||
public static final RegistrySupplier<LiquidBlock> TEST_FLUID_BLOCK = BLOCKS.register("test_fluid", () -> {
|
||||
try {
|
||||
// In example mod the forge class isn't being replaced, this is not required in mods depending on architectury
|
||||
return (LiquidBlock) Class.forName(!Platform.isForge() ? "dev.architectury.core.block.ArchitecturyLiquidBlock" : "dev.architectury.core.block.forge.imitator.ArchitecturyLiquidBlock")
|
||||
.getDeclaredConstructor(Supplier.class, BlockBehaviour.Properties.class)
|
||||
.newInstance(TestRegistries.TEST_FLUID, BlockBehaviour.Properties.copy(Blocks.WATER).noCollission().strength(100.0F).noDrops());
|
||||
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
public static final RegistrySupplier<Fluid> TEST_FLUID = FLUIDS.register("test_fluid", () -> {
|
||||
try {
|
||||
// In example mod the forge class isn't being replaced, this is not required in mods depending on architectury
|
||||
return (FlowingFluid) Class.forName(!Platform.isForge() ? "dev.architectury.core.fluid.ArchitecturyFlowingFluid$Source" : "dev.architectury.core.fluid.forge.imitator.ArchitecturyFlowingFluid$Source")
|
||||
.getDeclaredConstructor(ArchitecturyFluidAttributes.class)
|
||||
.newInstance(TestRegistries.TEST_FLUID_ATTRIBUTES);
|
||||
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
public static final RegistrySupplier<Fluid> TEST_FLUID_FLOWING = FLUIDS.register("test_fluid_flowing", () -> {
|
||||
try {
|
||||
// In example mod the forge class isn't being replaced, this is not required in mods depending on architectury
|
||||
return (FlowingFluid) Class.forName(!Platform.isForge() ? "dev.architectury.core.fluid.ArchitecturyFlowingFluid$Flowing" : "dev.architectury.core.fluid.forge.imitator.ArchitecturyFlowingFluid$Flowing")
|
||||
.getDeclaredConstructor(ArchitecturyFluidAttributes.class)
|
||||
.newInstance(TestRegistries.TEST_FLUID_ATTRIBUTES);
|
||||
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
public static final RegistrySupplier<Item> TEST_BLOCK_ITEM = ITEMS.register("test_block", () ->
|
||||
new BlockItem(TEST_BLOCK.get(), new Item.Properties().tab(TestCreativeTabs.TEST_TAB)));
|
||||
public static final RegistrySupplier<Item> COLLISION_BLOCK_ITEM = ITEMS.register("collision_block", () ->
|
||||
@@ -110,6 +190,7 @@ public class TestRegistries {
|
||||
|
||||
public static void initialize() {
|
||||
MOB_EFFECTS.register();
|
||||
FLUIDS.register();
|
||||
BLOCKS.register();
|
||||
ITEMS.register();
|
||||
ENTITY_TYPES.register();
|
||||
|
||||
Reference in New Issue
Block a user