Fluids & Biome Modifiers

This commit is contained in:
simibubi 2022-08-01 22:37:39 +02:00
parent 233d9b292e
commit 4d2526d1b6
24 changed files with 275 additions and 222 deletions

View file

@ -1,11 +1,13 @@
package com.simibubi.create; package com.simibubi.create;
import java.util.function.Consumer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.simibubi.create.AllTags.AllFluidTags; import com.simibubi.create.AllTags.AllFluidTags;
import com.simibubi.create.content.contraptions.fluids.VirtualFluid; import com.simibubi.create.content.contraptions.fluids.VirtualFluid;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluid; import com.simibubi.create.content.contraptions.fluids.potion.PotionFluid;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluid.PotionFluidAttributes; import com.simibubi.create.content.contraptions.fluids.potion.PotionFluid.PotionFluidType;
import com.simibubi.create.content.palettes.AllPaletteStoneTypes; import com.simibubi.create.content.palettes.AllPaletteStoneTypes;
import com.simibubi.create.foundation.data.CreateRegistrate; import com.simibubi.create.foundation.data.CreateRegistrate;
import com.tterrag.registrate.util.entry.FluidEntry; import com.tterrag.registrate.util.entry.FluidEntry;
@ -13,13 +15,16 @@ import com.tterrag.registrate.util.entry.FluidEntry;
import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.fluids.ForgeFlowingFluid; import net.minecraftforge.fluids.ForgeFlowingFluid;
public class AllFluids { public class AllFluids {
@ -27,7 +32,7 @@ public class AllFluids {
private static final CreateRegistrate REGISTRATE = Create.registrate(); private static final CreateRegistrate REGISTRATE = Create.registrate();
public static final FluidEntry<PotionFluid> POTION = public static final FluidEntry<PotionFluid> POTION =
REGISTRATE.virtualFluid("potion", PotionFluidAttributes::new, PotionFluid::new) REGISTRATE.virtualFluid("potion", PotionFluidType::new, PotionFluid::new)
.lang(f -> "fluid.create.potion", "Potion") .lang(f -> "fluid.create.potion", "Potion")
.register(); .register();
@ -39,9 +44,9 @@ public class AllFluids {
public static final FluidEntry<ForgeFlowingFluid.Flowing> HONEY = public static final FluidEntry<ForgeFlowingFluid.Flowing> HONEY =
REGISTRATE.standardFluid("honey", NoColorFluidAttributes::new) REGISTRATE.standardFluid("honey", NoColorFluidAttributes::new)
.lang(f -> "fluid.create.honey", "Honey") .lang(f -> "fluid.create.honey", "Honey")
.attributes(b -> b.viscosity(2000) .properties(b -> b.viscosity(2000)
.density(1400)) .density(1400))
.properties(p -> p.levelDecreasePerBlock(2) .fluidProperties(p -> p.levelDecreasePerBlock(2)
.tickRate(25) .tickRate(25)
.slopeFindDistance(3) .slopeFindDistance(3)
.explosionResistance(100f)) .explosionResistance(100f))
@ -56,9 +61,9 @@ public class AllFluids {
REGISTRATE.standardFluid("chocolate", NoColorFluidAttributes::new) REGISTRATE.standardFluid("chocolate", NoColorFluidAttributes::new)
.lang(f -> "fluid.create.chocolate", "Chocolate") .lang(f -> "fluid.create.chocolate", "Chocolate")
.tag(AllTags.forgeFluidTag("chocolate")) .tag(AllTags.forgeFluidTag("chocolate"))
.attributes(b -> b.viscosity(1500) .properties(b -> b.viscosity(1500)
.density(1400)) .density(1400))
.properties(p -> p.levelDecreasePerBlock(2) .fluidProperties(p -> p.levelDecreasePerBlock(2)
.tickRate(25) .tickRate(25)
.slopeFindDistance(3) .slopeFindDistance(3)
.explosionResistance(100f)) .explosionResistance(100f))
@ -92,21 +97,70 @@ public class AllFluids {
return null; return null;
} }
public static abstract class TintedFluidType extends FluidType {
protected static final int NO_TINT = 0xffffffff;
private ResourceLocation stillTexture;
private ResourceLocation flowingTexture;
public TintedFluidType(Properties properties, ResourceLocation stillTexture, ResourceLocation flowingTexture) {
super(properties);
}
@Override
public void initializeClient(Consumer<IClientFluidTypeExtensions> consumer) {
consumer.accept(new IClientFluidTypeExtensions() {
@Override
public ResourceLocation getFlowingTexture() {
return flowingTexture;
}
@Override
public ResourceLocation getStillTexture() {
return stillTexture;
}
@Override
public int getTintColor(FluidStack stack) {
return getTintColor(stack);
}
@Override
public int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
return getTintColor(state, getter, pos);
}
});
}
protected abstract int getTintColor(FluidStack stack);
protected abstract int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos);
}
/** /**
* Removing alpha from tint prevents optifine from forcibly applying biome * Removing alpha from tint prevents optifine from forcibly applying biome
* colors to modded fluids (Makes translucent fluids disappear) * colors to modded fluids (Makes translucent fluids disappear)
*/ */
private static class NoColorFluidAttributes extends FluidAttributes { private static class NoColorFluidAttributes extends TintedFluidType {
protected NoColorFluidAttributes(Builder builder, Fluid fluid) { public NoColorFluidAttributes(Properties properties, ResourceLocation stillTexture,
super(builder, fluid); ResourceLocation flowingTexture) {
super(properties, stillTexture, flowingTexture);
} }
@Override @Override
public int getColor(BlockAndTintGetter world, BlockPos pos) { public int getTintColor(FluidState state, BlockAndTintGetter world, BlockPos pos) {
return 0x00ffffff; return 0x00ffffff;
} }
@Override
protected int getTintColor(FluidStack stack) {
return NO_TINT;
}
} }
} }

View file

@ -125,8 +125,6 @@ public class Create {
modEventBus.addListener(AllSoundEvents::register); modEventBus.addListener(AllSoundEvents::register);
modEventBus.addListener(AllEntityDataSerializers::register); modEventBus.addListener(AllEntityDataSerializers::register);
forgeEventBus.addListener(EventPriority.HIGH, SlidingDoorBlock::stopItQuark);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus)); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
Mods.CURIOS.executeIfInstalled(() -> Curios::init); Mods.CURIOS.executeIfInstalled(() -> Curios::init);
@ -156,6 +154,7 @@ public class Create {
gen.addProvider(true, new MechanicalCraftingRecipeGen(gen)); gen.addProvider(true, new MechanicalCraftingRecipeGen(gen));
gen.addProvider(true, new SequencedAssemblyRecipeGen(gen)); gen.addProvider(true, new SequencedAssemblyRecipeGen(gen));
ProcessingRecipeGen.registerAll(gen); ProcessingRecipeGen.registerAll(gen);
AllWorldFeatures.generateBiomeModifiers(event);
} }
public static CreateRegistrate registrate() { public static CreateRegistrate registrate() {

View file

@ -15,6 +15,11 @@ public class MechanicalCraftingInventory extends CraftingContainer {
public boolean stillValid(Player playerIn) { public boolean stillValid(Player playerIn) {
return false; return false;
} }
@Override
public ItemStack quickMoveStack(Player p_38941_, int p_38942_) {
return ItemStack.EMPTY;
}
}; };
public MechanicalCraftingInventory(GroupedItems items) { public MechanicalCraftingInventory(GroupedItems items) {

View file

@ -23,9 +23,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.NbtUtils;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
@ -197,19 +195,12 @@ public abstract class FluidManipulationBehaviour extends TileEntityBehaviour {
protected void playEffect(Level world, BlockPos pos, Fluid fluid, boolean fillSound) { protected void playEffect(Level world, BlockPos pos, Fluid fluid, boolean fillSound) {
BlockPos splooshPos = pos == null ? tileEntity.getBlockPos() : pos; BlockPos splooshPos = pos == null ? tileEntity.getBlockPos() : pos;
FluidStack stack = new FluidStack(fluid, 1);
SoundEvent soundevent = fillSound ? fluid.getAttributes() SoundEvent soundevent = fillSound ? FluidHelper.getFillSound(stack) : FluidHelper.getEmptySound(stack);
.getFillSound()
: fluid.getAttributes()
.getEmptySound();
if (soundevent == null)
soundevent = FluidHelper.isTag(fluid, FluidTags.LAVA)
? fillSound ? SoundEvents.BUCKET_FILL_LAVA : SoundEvents.BUCKET_EMPTY_LAVA
: fillSound ? SoundEvents.BUCKET_FILL : SoundEvents.BUCKET_EMPTY;
world.playSound(null, splooshPos, soundevent, SoundSource.BLOCKS, 0.3F, 1.0F); world.playSound(null, splooshPos, soundevent, SoundSource.BLOCKS, 0.3F, 1.0F);
if (world instanceof ServerLevel) if (world instanceof ServerLevel)
AllPackets.sendToNear(world, splooshPos, 10, new FluidSplashPacket(splooshPos, new FluidStack(fluid, 1))); AllPackets.sendToNear(world, splooshPos, 10, new FluidSplashPacket(splooshPos, stack));
} }
protected boolean canDrainInfinitely(Fluid fluid) { protected boolean canDrainInfinitely(Fluid fluid) {

View file

@ -11,15 +11,17 @@ import net.minecraft.client.particle.TextureSheetParticle;
import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.InventoryMenu;
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
public class FluidStackParticle extends TextureSheetParticle { public class FluidStackParticle extends TextureSheetParticle {
private final float uo; private final float uo;
private final float vo; private final float vo;
private FluidStack fluid; private FluidStack fluid;
private IClientFluidTypeExtensions clientFluid;
public static FluidStackParticle create(ParticleType<FluidParticleData> type, ClientLevel world, FluidStack fluid, double x, public static FluidStackParticle create(ParticleType<FluidParticleData> type, ClientLevel world, FluidStack fluid,
double y, double z, double vx, double vy, double vz) { double x, double y, double z, double vx, double vy, double vz) {
if (type == AllParticleTypes.BASIN_FLUID.get()) if (type == AllParticleTypes.BASIN_FLUID.get())
return new BasinFluidParticle(world, fluid, x, y, z, vx, vy, vz); return new BasinFluidParticle(world, fluid, x, y, z, vx, vy, vz);
return new FluidStackParticle(world, fluid, x, y, z, vx, vy, vz); return new FluidStackParticle(world, fluid, x, y, z, vx, vy, vz);
@ -28,20 +30,19 @@ public class FluidStackParticle extends TextureSheetParticle {
public FluidStackParticle(ClientLevel world, FluidStack fluid, double x, double y, double z, double vx, double vy, public FluidStackParticle(ClientLevel world, FluidStack fluid, double x, double y, double z, double vx, double vy,
double vz) { double vz) {
super(world, x, y, z, vx, vy, vz); super(world, x, y, z, vx, vy, vz);
clientFluid = IClientFluidTypeExtensions.of(fluid.getFluid());
this.fluid = fluid; this.fluid = fluid;
this.setSprite(Minecraft.getInstance() this.setSprite(Minecraft.getInstance()
.getTextureAtlas(InventoryMenu.BLOCK_ATLAS) .getTextureAtlas(InventoryMenu.BLOCK_ATLAS)
.apply(fluid.getFluid() .apply(clientFluid.getStillTexture(fluid)));
.getAttributes()
.getStillTexture()));
this.gravity = 1.0F; this.gravity = 1.0F;
this.rCol = 0.8F; this.rCol = 0.8F;
this.gCol = 0.8F; this.gCol = 0.8F;
this.bCol = 0.8F; this.bCol = 0.8F;
this.multiplyColor(fluid.getFluid() this.multiplyColor(clientFluid.getTintColor(fluid));
.getAttributes()
.getColor(fluid));
this.xd = vx; this.xd = vx;
this.yd = vy; this.yd = vy;
@ -58,8 +59,8 @@ public class FluidStackParticle extends TextureSheetParticle {
int skyLight = brightnessForRender >> 20; int skyLight = brightnessForRender >> 20;
int blockLight = (brightnessForRender >> 4) & 0xf; int blockLight = (brightnessForRender >> 4) & 0xf;
blockLight = Math.max(blockLight, fluid.getFluid() blockLight = Math.max(blockLight, fluid.getFluid()
.getAttributes() .getFluidType()
.getLuminosity(fluid)); .getLightLevel(fluid));
return (skyLight << 20) | (blockLight << 4); return (skyLight << 20) | (blockLight << 4);
} }
@ -97,10 +98,9 @@ public class FluidStackParticle extends TextureSheetParticle {
if (!onGround && level.random.nextFloat() < 1 / 8f) if (!onGround && level.random.nextFloat() < 1 / 8f)
return; return;
Color color = new Color(fluid.getFluid() Color color = new Color(clientFluid.getTintColor(fluid));
.getAttributes() level.addParticle(ParticleTypes.ENTITY_EFFECT, x, y, z, color.getRedAsFloat(), color.getGreenAsFloat(),
.getColor(fluid)); color.getBlueAsFloat());
level.addParticle(ParticleTypes.ENTITY_EFFECT, x, y, z, color.getRedAsFloat(), color.getGreenAsFloat(), color.getBlueAsFloat());
} }
protected boolean canEvaporate() { protected boolean canEvaporate() {

View file

@ -4,9 +4,11 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import com.simibubi.create.AllFluids; import com.simibubi.create.AllFluids;
import com.simibubi.create.AllFluids.TintedFluidType;
import com.simibubi.create.content.contraptions.fluids.VirtualFluid; import com.simibubi.create.content.contraptions.fluids.VirtualFluid;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -15,9 +17,9 @@ import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionUtils; import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.Potions; import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
@ -66,26 +68,26 @@ public class PotionFluid extends VirtualFluid {
REGULAR, SPLASH, LINGERING; REGULAR, SPLASH, LINGERING;
} }
public static class PotionFluidAttributes extends FluidAttributes { public static class PotionFluidType extends TintedFluidType {
public PotionFluidAttributes(Builder builder, Fluid fluid) { public PotionFluidType(Properties properties, ResourceLocation stillTexture, ResourceLocation flowingTexture) {
super(builder, fluid); super(properties, stillTexture, flowingTexture);
} }
@Override @Override
public int getColor(FluidStack stack) { public int getTintColor(FluidStack stack) {
CompoundTag tag = stack.getOrCreateTag(); CompoundTag tag = stack.getOrCreateTag();
int color = PotionUtils.getColor(PotionUtils.getAllEffects(tag)) | 0xff000000; int color = PotionUtils.getColor(PotionUtils.getAllEffects(tag)) | 0xff000000;
return color; return color;
} }
@Override @Override
public Component getDisplayName(FluidStack stack) { public Component getDescription(FluidStack stack) {
return Component.translatable(getTranslationKey(stack)); return Component.translatable(getDescriptionId(stack));
} }
@Override @Override
public String getTranslationKey(FluidStack stack) { public String getDescriptionId(FluidStack stack) {
CompoundTag tag = stack.getOrCreateTag(); CompoundTag tag = stack.getOrCreateTag();
ItemLike itemFromBottleType = ItemLike itemFromBottleType =
PotionFluidHandler.itemFromBottleType(NBTHelper.readEnum(tag, "Bottle", BottleType.class)); PotionFluidHandler.itemFromBottleType(NBTHelper.readEnum(tag, "Bottle", BottleType.class));
@ -94,6 +96,11 @@ public class PotionFluid extends VirtualFluid {
.getDescriptionId() + ".effect."); .getDescriptionId() + ".effect.");
} }
@Override
protected int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
return NO_TINT;
}
} }
} }

View file

@ -20,7 +20,6 @@ import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.util.StringRepresentable; import net.minecraft.util.StringRepresentable;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
@ -52,7 +51,6 @@ import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.common.util.ForgeSoundType; import net.minecraftforge.common.util.ForgeSoundType;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
@ -196,11 +194,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
Fluid fluid = fluidInTank.getFluid(); Fluid fluid = fluidInTank.getFluid();
fluidState = fluid.defaultFluidState() fluidState = fluid.defaultFluidState()
.createLegacyBlock(); .createLegacyBlock();
FluidAttributes attributes = fluid.getAttributes(); soundevent = FluidHelper.getEmptySound(fluidInTank);
soundevent = attributes.getEmptySound();
if (soundevent == null)
soundevent =
FluidHelper.isTag(fluid, FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
} }
if (exchange == FluidExchange.TANK_TO_ITEM) { if (exchange == FluidExchange.TANK_TO_ITEM) {
@ -211,11 +205,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
Fluid fluid = prevFluidInTank.getFluid(); Fluid fluid = prevFluidInTank.getFluid();
fluidState = fluid.defaultFluidState() fluidState = fluid.defaultFluidState()
.createLegacyBlock(); .createLegacyBlock();
soundevent = fluid.getAttributes() soundevent = FluidHelper.getFillSound(prevFluidInTank);
.getFillSound();
if (soundevent == null)
soundevent =
FluidHelper.isTag(fluid, FluidTags.LAVA) ? SoundEvents.BUCKET_FILL_LAVA : SoundEvents.BUCKET_FILL;
} }
if (soundevent != null && !onClient) { if (soundevent != null && !onClient) {
@ -237,7 +227,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
float level = (float) fluidInTank.getAmount() / fluidTank.getTankCapacity(0); float level = (float) fluidInTank.getAmount() / fluidTank.getTankCapacity(0);
boolean reversed = fluidInTank.getFluid() boolean reversed = fluidInTank.getFluid()
.getAttributes() .getFluidType()
.isLighterThanAir(); .isLighterThanAir();
if (reversed) if (reversed)
level = 1 - level; level = 1 - level;

View file

@ -55,7 +55,7 @@ public class FluidTankRenderer extends SafeTileEntityRenderer<FluidTankTileEntit
return; return;
boolean top = fluidStack.getFluid() boolean top = fluidStack.getFluid()
.getAttributes() .getFluidType()
.isLighterThanAir(); .isLighterThanAir();
float xMin = tankHullWidth; float xMin = tankHullWidth;

View file

@ -30,8 +30,8 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
@ -140,9 +140,9 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
if (!hasLevel()) if (!hasLevel())
return; return;
FluidAttributes attributes = newFluidStack.getFluid() FluidType attributes = newFluidStack.getFluid()
.getAttributes(); .getFluidType();
int luminosity = (int) (attributes.getLuminosity(newFluidStack) / 1.2f); int luminosity = (int) (attributes.getLightLevel(newFluidStack) / 1.2f);
boolean reversed = attributes.isLighterThanAir(); boolean reversed = attributes.isLighterThanAir();
int maxY = (int) ((getFillState() * height) + 1); int maxY = (int) ((getFillState() * height) + 1);
@ -315,7 +315,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
for (int xOffset = 0; xOffset < width; xOffset++) for (int xOffset = 0; xOffset < width; xOffset++)
for (int zOffset = 0; zOffset < width; zOffset++) for (int zOffset = 0; zOffset < width; zOffset++)
if (level.getBlockEntity( if (level.getBlockEntity(
worldPosition.offset(xOffset, yOffset, zOffset))instanceof FluidTankTileEntity fte) worldPosition.offset(xOffset, yOffset, zOffset)) instanceof FluidTankTileEntity fte)
fte.refreshCapability(); fte.refreshCapability();
} }

View file

@ -33,8 +33,6 @@ import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.Event.Result;
public class SlidingDoorBlock extends DoorBlock implements IWrenchable, ITE<SlidingDoorTileEntity> { public class SlidingDoorBlock extends DoorBlock implements IWrenchable, ITE<SlidingDoorTileEntity> {
@ -52,24 +50,6 @@ public class SlidingDoorBlock extends DoorBlock implements IWrenchable, ITE<Slid
public static final BooleanProperty VISIBLE = BooleanProperty.create("visible"); public static final BooleanProperty VISIBLE = BooleanProperty.create("visible");
@Deprecated // Remove in 1.19 - Fixes incompatibility with Quarks double door module
public static void stopItQuark(PlayerInteractEvent.RightClickBlock event) {
Player player = event.getEntity();
Level world = event.getLevel();
if (!world.isClientSide || player.isDiscrete() || event.isCanceled() || event.getResult() == Result.DENY
|| event.getUseBlock() == Result.DENY)
return;
BlockPos pos = event.getPos();
BlockState blockState = world.getBlockState(pos);
if (blockState.getBlock()instanceof SlidingDoorBlock sdb) {
event.setCanceled(true);
event.setCancellationResult(blockState.use(world, player, event.getHand(), event.getHitVec()));
}
}
public SlidingDoorBlock(Properties p_52737_) { public SlidingDoorBlock(Properties p_52737_) {
super(p_52737_); super(p_52737_);
} }

View file

@ -466,6 +466,11 @@ public class BlueprintEntity extends HangingEntity
public boolean stillValid(Player playerIn) { public boolean stillValid(Player playerIn) {
return false; return false;
} }
@Override
public ItemStack quickMoveStack(Player p_38941_, int p_38942_) {
return ItemStack.EMPTY;
}
}; };
public BlueprintCraftingInventory(Map<Integer, ItemStack> items) { public BlueprintCraftingInventory(Map<Integer, ItemStack> items) {

View file

@ -20,7 +20,6 @@ import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.WorldAttached; import com.simibubi.create.foundation.utility.WorldAttached;
import com.simibubi.create.foundation.utility.recipe.RecipeFinder; import com.simibubi.create.foundation.utility.recipe.RecipeFinder;
import com.simibubi.create.foundation.worldgen.AllWorldFeatures;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -57,8 +56,6 @@ import net.minecraftforge.event.level.BlockEvent.FluidPlaceBlockEvent;
import net.minecraftforge.event.level.ChunkEvent; import net.minecraftforge.event.level.ChunkEvent;
import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.event.server.ServerStoppingEvent; import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.event.world.BiomeLoadingEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ -211,11 +208,6 @@ public class CommonEvents {
CapabilityMinecartController.startTracking(event); CapabilityMinecartController.startTracking(event);
} }
@SubscribeEvent(priority = EventPriority.HIGH)
public static void onBiomeLoad(BiomeLoadingEvent event) {
AllWorldFeatures.reload(event);
}
public static void leftClickEmpty(ServerPlayer player) { public static void leftClickEmpty(ServerPlayer player) {
ItemStack stack = player.getMainHandItem(); ItemStack stack = player.getMainHandItem();
if (stack.getItem() instanceof ZapperItem) { if (stack.getItem() instanceof ZapperItem) {

View file

@ -7,7 +7,6 @@ import java.util.IdentityHashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -24,7 +23,6 @@ import com.tterrag.registrate.builders.BlockEntityBuilder.BlockEntityFactory;
import com.tterrag.registrate.builders.Builder; import com.tterrag.registrate.builders.Builder;
import com.tterrag.registrate.builders.FluidBuilder; import com.tterrag.registrate.builders.FluidBuilder;
import com.tterrag.registrate.util.entry.RegistryEntry; import com.tterrag.registrate.util.entry.RegistryEntry;
import com.tterrag.registrate.util.nullness.NonNullBiFunction;
import com.tterrag.registrate.util.nullness.NonNullConsumer; import com.tterrag.registrate.util.nullness.NonNullConsumer;
import com.tterrag.registrate.util.nullness.NonNullFunction; import com.tterrag.registrate.util.nullness.NonNullFunction;
import com.tterrag.registrate.util.nullness.NonNullSupplier; import com.tterrag.registrate.util.nullness.NonNullSupplier;
@ -41,10 +39,8 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour.Properties; import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.ForgeFlowingFluid; import net.minecraftforge.fluids.ForgeFlowingFluid;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@ -77,8 +73,8 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
} }
@Override @Override
protected <R, T extends R> RegistryEntry<T> accept(String name, protected <R, T extends R> RegistryEntry<T> accept(String name, ResourceKey<? extends Registry<R>> type,
ResourceKey<? extends Registry<R>> type, Builder<R, T, ?, ?> builder, NonNullSupplier<? extends T> creator, Builder<R, T, ?, ?> builder, NonNullSupplier<? extends T> creator,
NonNullFunction<RegistryObject<T>, ? extends RegistryEntry<T>> entryFactory) { NonNullFunction<RegistryObject<T>, ? extends RegistryEntry<T>> entryFactory) {
RegistryEntry<T> ret = super.accept(name, type, builder, creator, entryFactory); RegistryEntry<T> ret = super.accept(name, type, builder, creator, entryFactory);
sectionLookup.put(ret, currentSection()); sectionLookup.put(ret, currentSection());
@ -164,19 +160,16 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
/* Fluids */ /* Fluids */
public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name, public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name,
BiFunction<FluidAttributes.Builder, Fluid, FluidAttributes> attributesFactory, FluidBuilder.FluidTypeFactory typeFactory, NonNullFunction<ForgeFlowingFluid.Properties, T> factory) {
NonNullFunction<ForgeFlowingFluid.Properties, T> factory) {
return entry(name, return entry(name,
c -> new VirtualFluidBuilder<>(self(), self(), name, c, Create.asResource("fluid/" + name + "_still"), c -> new VirtualFluidBuilder<>(self(), self(), name, c, Create.asResource("fluid/" + name + "_still"),
Create.asResource("fluid/" + name + "_flow"), attributesFactory, factory)); Create.asResource("fluid/" + name + "_flow"), typeFactory, factory));
} }
public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name, ResourceLocation still, ResourceLocation flow, public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name,
BiFunction<FluidAttributes.Builder, Fluid, FluidAttributes> attributesFactory, ResourceLocation still, ResourceLocation flow, FluidBuilder.FluidTypeFactory typeFactory,
NonNullFunction<ForgeFlowingFluid.Properties, T> factory) { NonNullFunction<ForgeFlowingFluid.Properties, T> factory) {
return entry(name, return entry(name, c -> new VirtualFluidBuilder<>(self(), self(), name, c, still, flow, typeFactory, factory));
c -> new VirtualFluidBuilder<>(self(), self(), name, c, still,
flow, attributesFactory, factory));
} }
public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name) { public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name) {
@ -185,10 +178,10 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
Create.asResource("fluid/" + name + "_flow"), null, VirtualFluid::new)); Create.asResource("fluid/" + name + "_flow"), null, VirtualFluid::new));
} }
public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name, ResourceLocation still, ResourceLocation flow) { public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name, ResourceLocation still,
ResourceLocation flow) {
return entry(name, return entry(name,
c -> new VirtualFluidBuilder<>(self(), self(), name, c, still, c -> new VirtualFluidBuilder<>(self(), self(), name, c, still, flow, null, VirtualFluid::new));
flow, null, VirtualFluid::new));
} }
public FluidBuilder<ForgeFlowingFluid.Flowing, CreateRegistrate> standardFluid(String name) { public FluidBuilder<ForgeFlowingFluid.Flowing, CreateRegistrate> standardFluid(String name) {
@ -196,9 +189,9 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
} }
public FluidBuilder<ForgeFlowingFluid.Flowing, CreateRegistrate> standardFluid(String name, public FluidBuilder<ForgeFlowingFluid.Flowing, CreateRegistrate> standardFluid(String name,
NonNullBiFunction<FluidAttributes.Builder, Fluid, FluidAttributes> attributesFactory) { FluidBuilder.FluidTypeFactory typeFactory) {
return fluid(name, Create.asResource("fluid/" + name + "_still"), Create.asResource("fluid/" + name + "_flow"), return fluid(name, Create.asResource("fluid/" + name + "_still"), Create.asResource("fluid/" + name + "_flow"),
attributesFactory); typeFactory);
} }
/* Util */ /* Util */

View file

@ -1,7 +1,5 @@
package com.simibubi.create.foundation.data; package com.simibubi.create.foundation.data;
import java.util.function.BiFunction;
import com.tterrag.registrate.AbstractRegistrate; import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.builders.BuilderCallback; import com.tterrag.registrate.builders.BuilderCallback;
import com.tterrag.registrate.builders.FluidBuilder; import com.tterrag.registrate.builders.FluidBuilder;
@ -9,8 +7,6 @@ import com.tterrag.registrate.util.nullness.NonNullFunction;
import com.tterrag.registrate.util.nullness.NonNullSupplier; import com.tterrag.registrate.util.nullness.NonNullSupplier;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.ForgeFlowingFluid; import net.minecraftforge.fluids.ForgeFlowingFluid;
import net.minecraftforge.fluids.ForgeFlowingFluid.Properties; import net.minecraftforge.fluids.ForgeFlowingFluid.Properties;
@ -20,10 +16,9 @@ import net.minecraftforge.fluids.ForgeFlowingFluid.Properties;
public class VirtualFluidBuilder<T extends ForgeFlowingFluid, P> extends FluidBuilder<T, P> { public class VirtualFluidBuilder<T extends ForgeFlowingFluid, P> extends FluidBuilder<T, P> {
public VirtualFluidBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, public VirtualFluidBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback,
ResourceLocation stillTexture, ResourceLocation flowingTexture, ResourceLocation stillTexture, ResourceLocation flowingTexture, FluidBuilder.FluidTypeFactory typeFactory,
BiFunction<FluidAttributes.Builder, Fluid, FluidAttributes> attributesFactory,
NonNullFunction<Properties, T> factory) { NonNullFunction<Properties, T> factory) {
super(owner, parent, name, callback, stillTexture, flowingTexture, attributesFactory, factory); super(owner, parent, name, callback, stillTexture, flowingTexture, typeFactory, factory);
source(factory); source(factory);
} }

View file

@ -19,11 +19,12 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidType;
public abstract class ProcessingRecipeGen extends CreateRecipeProvider { public abstract class ProcessingRecipeGen extends CreateRecipeProvider {
protected static final List<ProcessingRecipeGen> GENERATORS = new ArrayList<>(); protected static final List<ProcessingRecipeGen> GENERATORS = new ArrayList<>();
protected static final int BUCKET = FluidAttributes.BUCKET_VOLUME; protected static final int BUCKET = FluidType.BUCKET_VOLUME;
protected static final int BOTTLE = 250; protected static final int BOTTLE = 250;
public static void registerAll(DataGenerator gen) { public static void registerAll(DataGenerator gen) {

View file

@ -15,6 +15,9 @@ import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.nbt.TagParser; import net.minecraft.nbt.TagParser;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.tags.FluidTags;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.util.GsonHelper; import net.minecraft.util.GsonHelper;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
@ -26,6 +29,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.material.Fluids;
import net.minecraftforge.common.SoundActions;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.ForgeFlowingFluid; import net.minecraftforge.fluids.ForgeFlowingFluid;
@ -62,6 +66,26 @@ public class FluidHelper {
return isTag(fluid.getFluid(), tag); return isTag(fluid.getFluid(), tag);
} }
public static SoundEvent getFillSound(FluidStack fluid) {
SoundEvent soundevent = fluid.getFluid()
.getFluidType()
.getSound(fluid, SoundActions.BUCKET_FILL);
if (soundevent == null)
soundevent =
FluidHelper.isTag(fluid, FluidTags.LAVA) ? SoundEvents.BUCKET_FILL_LAVA : SoundEvents.BUCKET_FILL;
return soundevent;
}
public static SoundEvent getEmptySound(FluidStack fluid) {
SoundEvent soundevent = fluid.getFluid()
.getFluidType()
.getSound(fluid, SoundActions.BUCKET_EMPTY);
if (soundevent == null)
soundevent =
FluidHelper.isTag(fluid, FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
return soundevent;
}
public static boolean hasBlockState(Fluid fluid) { public static boolean hasBlockState(Fluid fluid) {
BlockState blockState = fluid.defaultFluidState() BlockState blockState = fluid.defaultFluidState()
.createLegacyBlock(); .createLegacyBlock();
@ -157,7 +181,8 @@ public class FluidHelper {
player.setItemInHand(handIn, emptyingResult.getSecond()); player.setItemInHand(handIn, emptyingResult.getSecond());
else { else {
player.setItemInHand(handIn, copyOfHeld); player.setItemInHand(handIn, copyOfHeld);
player.getInventory().placeItemBackInInventory(emptyingResult.getSecond()); player.getInventory()
.placeItemBackInInventory(emptyingResult.getSecond());
} }
} }
return true; return true;
@ -196,7 +221,8 @@ public class FluidHelper {
tank.drain(copy, FluidAction.EXECUTE); tank.drain(copy, FluidAction.EXECUTE);
if (!player.isCreative()) if (!player.isCreative())
player.getInventory().placeItemBackInInventory(out); player.getInventory()
.placeItemBackInInventory(out);
te.notifyUpdate(); te.notifyUpdate();
return true; return true;
} }

View file

@ -25,8 +25,9 @@ import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidType;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class FluidRenderer { public class FluidRenderer {
@ -43,15 +44,16 @@ public class FluidRenderer {
public static void renderFluidStream(FluidStack fluidStack, Direction direction, float radius, float progress, public static void renderFluidStream(FluidStack fluidStack, Direction direction, float radius, float progress,
boolean inbound, VertexConsumer builder, PoseStack ms, int light) { boolean inbound, VertexConsumer builder, PoseStack ms, int light) {
Fluid fluid = fluidStack.getFluid(); Fluid fluid = fluidStack.getFluid();
FluidAttributes fluidAttributes = fluid.getAttributes(); IClientFluidTypeExtensions clientFluid = IClientFluidTypeExtensions.of(fluid);
FluidType fluidAttributes = fluid.getFluidType();
Function<ResourceLocation, TextureAtlasSprite> spriteAtlas = Minecraft.getInstance() Function<ResourceLocation, TextureAtlasSprite> spriteAtlas = Minecraft.getInstance()
.getTextureAtlas(InventoryMenu.BLOCK_ATLAS); .getTextureAtlas(InventoryMenu.BLOCK_ATLAS);
TextureAtlasSprite flowTexture = spriteAtlas.apply(fluidAttributes.getFlowingTexture(fluidStack)); TextureAtlasSprite flowTexture = spriteAtlas.apply(clientFluid.getFlowingTexture(fluidStack));
TextureAtlasSprite stillTexture = spriteAtlas.apply(fluidAttributes.getStillTexture(fluidStack)); TextureAtlasSprite stillTexture = spriteAtlas.apply(clientFluid.getStillTexture(fluidStack));
int color = fluidAttributes.getColor(fluidStack); int color = clientFluid.getTintColor(fluidStack);
int blockLightIn = (light >> 4) & 0xF; int blockLightIn = (light >> 4) & 0xF;
int luminosity = Math.max(blockLightIn, fluidAttributes.getLuminosity(fluidStack)); int luminosity = Math.max(blockLightIn, fluidAttributes.getLightLevel(fluidStack));
light = (light & 0xF00000) | luminosity << 4; light = (light & 0xF00000) | luminosity << 4;
if (inbound) if (inbound)
@ -74,42 +76,40 @@ public class FluidRenderer {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
ms.pushPose(); ms.pushPose();
renderFlowingTiledFace(Direction.SOUTH, hMin, yMin, hMax, yMax, h, renderFlowingTiledFace(Direction.SOUTH, hMin, yMin, hMax, yMax, h, builder, ms, light, color, flowTexture);
builder, ms, light, color, flowTexture);
ms.popPose(); ms.popPose();
msr.rotateY(90); msr.rotateY(90);
} }
if (progress != 1) if (progress != 1)
renderStillTiledFace(Direction.DOWN, hMin, hMin, hMax, hMax, yMin, renderStillTiledFace(Direction.DOWN, hMin, hMin, hMax, hMax, yMin, builder, ms, light, color, stillTexture);
builder, ms, light, color, stillTexture);
ms.popPose(); ms.popPose();
} }
public static void renderFluidBox(FluidStack fluidStack, float xMin, float yMin, float zMin, float xMax, public static void renderFluidBox(FluidStack fluidStack, float xMin, float yMin, float zMin, float xMax, float yMax,
float yMax, float zMax, MultiBufferSource buffer, PoseStack ms, int light, boolean renderBottom) { float zMax, MultiBufferSource buffer, PoseStack ms, int light, boolean renderBottom) {
renderFluidBox(fluidStack, xMin, yMin, zMin, xMax, yMax, zMax, getFluidBuilder(buffer), ms, light, renderBottom); renderFluidBox(fluidStack, xMin, yMin, zMin, xMax, yMax, zMax, getFluidBuilder(buffer), ms, light,
renderBottom);
} }
public static void renderFluidBox(FluidStack fluidStack, float xMin, float yMin, float zMin, float xMax, public static void renderFluidBox(FluidStack fluidStack, float xMin, float yMin, float zMin, float xMax, float yMax,
float yMax, float zMax, VertexConsumer builder, PoseStack ms, int light, boolean renderBottom) { float zMax, VertexConsumer builder, PoseStack ms, int light, boolean renderBottom) {
Fluid fluid = fluidStack.getFluid(); Fluid fluid = fluidStack.getFluid();
FluidAttributes fluidAttributes = fluid.getAttributes(); IClientFluidTypeExtensions clientFluid = IClientFluidTypeExtensions.of(fluid);
FluidType fluidAttributes = fluid.getFluidType();
TextureAtlasSprite fluidTexture = Minecraft.getInstance() TextureAtlasSprite fluidTexture = Minecraft.getInstance()
.getTextureAtlas(InventoryMenu.BLOCK_ATLAS) .getTextureAtlas(InventoryMenu.BLOCK_ATLAS)
.apply(fluidAttributes.getStillTexture(fluidStack)); .apply(clientFluid.getStillTexture(fluidStack));
int color = fluidAttributes.getColor(fluidStack); int color = clientFluid.getTintColor(fluidStack);
int blockLightIn = (light >> 4) & 0xF; int blockLightIn = (light >> 4) & 0xF;
int luminosity = Math.max(blockLightIn, fluidAttributes.getLuminosity(fluidStack)); int luminosity = Math.max(blockLightIn, fluidAttributes.getLightLevel(fluidStack));
light = (light & 0xF00000) | luminosity << 4; light = (light & 0xF00000) | luminosity << 4;
Vec3 center = new Vec3(xMin + (xMax - xMin) / 2, yMin + (yMax - yMin) / 2, zMin + (zMax - zMin) / 2); Vec3 center = new Vec3(xMin + (xMax - xMin) / 2, yMin + (yMax - yMin) / 2, zMin + (zMax - zMin) / 2);
ms.pushPose(); ms.pushPose();
if (fluidStack.getFluid() if (fluidAttributes.isLighterThanAir())
.getAttributes()
.isLighterThanAir())
TransformStack.cast(ms) TransformStack.cast(ms)
.translate(center) .translate(center)
.rotateX(180) .rotateX(180)
@ -123,36 +123,36 @@ public class FluidRenderer {
if (side.getAxis() if (side.getAxis()
.isHorizontal()) { .isHorizontal()) {
if (side.getAxis() == Axis.X) { if (side.getAxis() == Axis.X) {
renderStillTiledFace(side, zMin, yMin, zMax, yMax, positive ? xMax : xMin, renderStillTiledFace(side, zMin, yMin, zMax, yMax, positive ? xMax : xMin, builder, ms, light,
builder, ms, light, color, fluidTexture); color, fluidTexture);
} else { } else {
renderStillTiledFace(side, xMin, yMin, xMax, yMax, positive ? zMax : zMin, renderStillTiledFace(side, xMin, yMin, xMax, yMax, positive ? zMax : zMin, builder, ms, light,
builder, ms, light, color, fluidTexture); color, fluidTexture);
} }
} else { } else {
renderStillTiledFace(side, xMin, zMin, xMax, zMax, positive ? yMax : yMin, renderStillTiledFace(side, xMin, zMin, xMax, zMax, positive ? yMax : yMin, builder, ms, light, color,
builder, ms, light, color, fluidTexture); fluidTexture);
} }
} }
ms.popPose(); ms.popPose();
} }
public static void renderStillTiledFace(Direction dir, float left, float down, float right, float up, public static void renderStillTiledFace(Direction dir, float left, float down, float right, float up, float depth,
float depth, VertexConsumer builder, PoseStack ms, int light, int color, TextureAtlasSprite texture) { VertexConsumer builder, PoseStack ms, int light, int color, TextureAtlasSprite texture) {
FluidRenderer.renderTiledFace(dir, left, down, right, up, depth, builder, ms, light, color, texture, 1); FluidRenderer.renderTiledFace(dir, left, down, right, up, depth, builder, ms, light, color, texture, 1);
} }
public static void renderFlowingTiledFace(Direction dir, float left, float down, float right, float up, public static void renderFlowingTiledFace(Direction dir, float left, float down, float right, float up, float depth,
float depth, VertexConsumer builder, PoseStack ms, int light, int color, TextureAtlasSprite texture) { VertexConsumer builder, PoseStack ms, int light, int color, TextureAtlasSprite texture) {
FluidRenderer.renderTiledFace(dir, left, down, right, up, depth, builder, ms, light, color, texture, 0.5f); FluidRenderer.renderTiledFace(dir, left, down, right, up, depth, builder, ms, light, color, texture, 0.5f);
} }
public static void renderTiledFace(Direction dir, float left, float down, float right, float up, public static void renderTiledFace(Direction dir, float left, float down, float right, float up, float depth,
float depth, VertexConsumer builder, PoseStack ms, int light, int color, TextureAtlasSprite texture, VertexConsumer builder, PoseStack ms, int light, int color, TextureAtlasSprite texture, float textureScale) {
float textureScale) {
boolean positive = dir.getAxisDirection() == Direction.AxisDirection.POSITIVE; boolean positive = dir.getAxisDirection() == Direction.AxisDirection.POSITIVE;
boolean horizontal = dir.getAxis().isHorizontal(); boolean horizontal = dir.getAxis()
.isHorizontal();
boolean x = dir.getAxis() == Axis.X; boolean x = dir.getAxis() == Axis.X;
float shrink = texture.uvShrinkRatio() * 0.25f * textureScale; float shrink = texture.uvShrinkRatio() * 0.25f * textureScale;

View file

@ -45,7 +45,7 @@ public class FluidMovementActorScenes {
Capability<IFluidHandler> fhc = CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY; Capability<IFluidHandler> fhc = CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY;
Class<FluidTankTileEntity> type = FluidTankTileEntity.class; Class<FluidTankTileEntity> type = FluidTankTileEntity.class;
ItemStack bucket = AllFluids.CHOCOLATE.get() ItemStack bucket = AllFluids.CHOCOLATE.get()
.getAttributes() .getFluidType()
.getBucket(chocolate); .getBucket(chocolate);
scene.world.modifyTileEntity(st, type, te -> te.getCapability(fhc) scene.world.modifyTileEntity(st, type, te -> te.getCapability(fhc)

View file

@ -199,7 +199,7 @@ public class FluidTankScenes {
scene.idle(90); scene.idle(90);
ItemStack chocBucket = AllFluids.CHOCOLATE.get() ItemStack chocBucket = AllFluids.CHOCOLATE.get()
.getAttributes() .getFluidType()
.getBucket(new FluidStack(FluidHelper.convertToStill(AllFluids.CHOCOLATE.get()), 1000)); .getBucket(new FluidStack(FluidHelper.convertToStill(AllFluids.CHOCOLATE.get()), 1000));
scene.world.createItemOnBeltLike(util.grid.at(3, 1, 0), Direction.WEST, chocBucket); scene.world.createItemOnBeltLike(util.grid.at(3, 1, 0), Direction.WEST, chocBucket);
scene.idle(40); scene.idle(40);

View file

@ -527,7 +527,7 @@ public class PipeScenes {
FluidStack chocolate = new FluidStack(FluidHelper.convertToStill(AllFluids.CHOCOLATE.get()), 1000); FluidStack chocolate = new FluidStack(FluidHelper.convertToStill(AllFluids.CHOCOLATE.get()), 1000);
ItemStack bucket = AllFluids.CHOCOLATE.get() ItemStack bucket = AllFluids.CHOCOLATE.get()
.getAttributes() .getFluidType()
.getBucket(chocolate); .getBucket(chocolate);
ItemStack milkBucket = new ItemStack(Items.MILK_BUCKET); ItemStack milkBucket = new ItemStack(Items.MILK_BUCKET);
scene.overlay.showControls(new InputWindowElement(filterVec, Pointing.DOWN).rightClick() scene.overlay.showControls(new InputWindowElement(filterVec, Pointing.DOWN).rightClick()

View file

@ -70,7 +70,7 @@ public class SpoutScenes {
scene.idle(20); scene.idle(20);
FluidStack honey = new FluidStack(FluidHelper.convertToStill(AllFluids.HONEY.get()), 1000); FluidStack honey = new FluidStack(FluidHelper.convertToStill(AllFluids.HONEY.get()), 1000);
ItemStack bucket = AllFluids.HONEY.get() ItemStack bucket = AllFluids.HONEY.get()
.getAttributes() .getFluidType()
.getBucket(honey); .getBucket(honey);
scene.overlay.showControls( scene.overlay.showControls(
new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.NORTH), Pointing.RIGHT) new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.NORTH), Pointing.RIGHT)

View file

@ -2,41 +2,47 @@ package com.simibubi.create.foundation.worldgen;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.gson.JsonElement;
import com.mojang.serialization.JsonOps;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.data.BuiltinRegistries; import net.minecraft.data.BuiltinRegistries;
import net.minecraft.data.DataGenerator;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome.BiomeCategory; import net.minecraft.tags.BiomeTags;
import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.GenerationStep.Decoration; import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
import net.minecraft.world.level.levelgen.placement.PlacedFeature; import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder; import net.minecraftforge.common.data.JsonCodecProvider;
import net.minecraftforge.event.world.BiomeLoadingEvent; import net.minecraftforge.common.world.BiomeModifier;
import net.minecraftforge.common.world.ForgeBiomeModifiers.AddFeaturesBiomeModifier;
import net.minecraftforge.data.event.GatherDataEvent;
import net.minecraftforge.registries.ForgeRegistries.Keys;
import net.minecraftforge.registries.RegisterEvent; import net.minecraftforge.registries.RegisterEvent;
public class AllWorldFeatures { public class AllWorldFeatures {
public static final Map<ResourceLocation, ConfigDrivenFeatureEntry> ENTRIES = new HashMap<>(); public static final Map<ResourceLocation, ConfigDrivenFeatureEntry> ENTRIES = new HashMap<>();
private static final BiomeFilter OVERWORLD_BIOMES =
(r, b) -> b != BiomeCategory.NETHER && b != BiomeCategory.THEEND && b != BiomeCategory.NONE;
private static final BiomeFilter NETHER_BIOMES = (r, b) -> b == BiomeCategory.NETHER;
// //
public static final ConfigDrivenFeatureEntry ZINC_ORE = public static final ConfigDrivenFeatureEntry ZINC_ORE =
register("zinc_ore", 12, 8, OVERWORLD_BIOMES).between(-63, 70) register("zinc_ore", 12, 8, BiomeTags.IS_OVERWORLD).between(-63, 70)
.withBlocks(Couple.create(AllBlocks.ZINC_ORE, AllBlocks.DEEPSLATE_ZINC_ORE)); .withBlocks(Couple.create(AllBlocks.ZINC_ORE, AllBlocks.DEEPSLATE_ZINC_ORE));
public static final ConfigDrivenFeatureEntry STRIATED_ORES_OVERWORLD = public static final ConfigDrivenFeatureEntry STRIATED_ORES_OVERWORLD =
register("striated_ores_overworld", 32, 1 / 12f, OVERWORLD_BIOMES).between(-30, 70) register("striated_ores_overworld", 32, 1 / 12f, BiomeTags.IS_OVERWORLD).between(-30, 70)
.withLayerPattern(AllLayerPatterns.SCORIA) .withLayerPattern(AllLayerPatterns.SCORIA)
.withLayerPattern(AllLayerPatterns.CINNABAR) .withLayerPattern(AllLayerPatterns.CINNABAR)
.withLayerPattern(AllLayerPatterns.MAGNETITE) .withLayerPattern(AllLayerPatterns.MAGNETITE)
@ -45,16 +51,16 @@ public class AllWorldFeatures {
.withLayerPattern(AllLayerPatterns.OCHRESTONE); .withLayerPattern(AllLayerPatterns.OCHRESTONE);
public static final ConfigDrivenFeatureEntry STRIATED_ORES_NETHER = public static final ConfigDrivenFeatureEntry STRIATED_ORES_NETHER =
register("striated_ores_nether", 32, 1 / 12f, NETHER_BIOMES).between(40, 90) register("striated_ores_nether", 32, 1 / 12f, BiomeTags.IS_NETHER).between(40, 90)
.withLayerPattern(AllLayerPatterns.SCORIA_NETHER) .withLayerPattern(AllLayerPatterns.SCORIA_NETHER)
.withLayerPattern(AllLayerPatterns.SCORCHIA_NETHER); .withLayerPattern(AllLayerPatterns.SCORCHIA_NETHER);
// //
private static ConfigDrivenFeatureEntry register(String id, int clusterSize, float frequency, private static ConfigDrivenFeatureEntry register(String id, int clusterSize, float frequency,
BiomeFilter biomeFilter) { TagKey<Biome> biomeTag) {
ConfigDrivenFeatureEntry configDrivenFeatureEntry = new ConfigDrivenFeatureEntry(id, clusterSize, frequency); ConfigDrivenFeatureEntry configDrivenFeatureEntry = new ConfigDrivenFeatureEntry(id, clusterSize, frequency);
configDrivenFeatureEntry.biomeFilter = biomeFilter; configDrivenFeatureEntry.biomeTag = biomeTag;
ENTRIES.put(Create.asResource(id), configDrivenFeatureEntry); ENTRIES.put(Create.asResource(id), configDrivenFeatureEntry);
return configDrivenFeatureEntry; return configDrivenFeatureEntry;
} }
@ -80,17 +86,6 @@ public class AllWorldFeatures {
}); });
} }
public static void reload(BiomeLoadingEvent event) {
BiomeGenerationSettingsBuilder generation = event.getGeneration();
Decoration decoStep = GenerationStep.Decoration.UNDERGROUND_ORES;
ENTRIES.values()
.forEach(entry -> {
ConfigDrivenFeatureEntry value = entry;
if (value.biomeFilter.test(event.getName(), event.getCategory()))
generation.addFeature(decoStep, value.placedFeature);
});
}
public static void fillConfig(ForgeConfigSpec.Builder builder) { public static void fillConfig(ForgeConfigSpec.Builder builder) {
ENTRIES.values() ENTRIES.values()
.forEach(entry -> { .forEach(entry -> {
@ -114,4 +109,21 @@ public class AllWorldFeatures {
Registry.register(Registry.PLACEMENT_MODIFIERS, "create_config_driven", () -> ConfigDrivenDecorator.CODEC); Registry.register(Registry.PLACEMENT_MODIFIERS, "create_config_driven", () -> ConfigDrivenDecorator.CODEC);
} }
public static void generateBiomeModifiers(GatherDataEvent event) {
Map<ResourceLocation, BiomeModifier> modifiers = new HashMap<>();
RegistryOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, RegistryAccess.builtinCopy());
for (Entry<ResourceLocation, ConfigDrivenFeatureEntry> entry : ENTRIES.entrySet()) {
ConfigDrivenFeatureEntry feature = entry.getValue();
HolderSet<Biome> biomes = new HolderSet.Named<>(ops.registry(Registry.BIOME_REGISTRY)
.get(), feature.biomeTag);
modifiers.put(entry.getKey(), new AddFeaturesBiomeModifier(biomes, HolderSet.direct(feature.placedFeature),
Decoration.UNDERGROUND_ORES));
}
DataGenerator generator = event.getGenerator();
generator.addProvider(event.includeServer(), JsonCodecProvider.forDatapackRegistry(generator,
event.getExistingFileHelper(), Create.ID, ops, Keys.BIOME_MODIFIERS, modifiers));
}
} }

View file

@ -1,10 +1,11 @@
package com.simibubi.create.foundation.worldgen; package com.simibubi.create.foundation.worldgen;
import java.util.function.BiPredicate; import java.util.function.Function;
import net.minecraft.resources.ResourceLocation; import net.minecraft.core.HolderSet;
import net.minecraft.world.level.biome.Biome.BiomeCategory; import net.minecraft.resources.RegistryOps;
import net.minecraft.world.level.biome.Biome;
public interface BiomeFilter extends BiPredicate<ResourceLocation, BiomeCategory> { public interface BiomeFilter extends Function<RegistryOps<?>, HolderSet<Biome>> {
} }

View file

@ -12,6 +12,8 @@ import com.tterrag.registrate.util.nullness.NonNullSupplier;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.data.worldgen.features.OreFeatures; import net.minecraft.data.worldgen.features.OreFeatures;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
@ -22,7 +24,7 @@ import net.minecraftforge.common.ForgeConfigSpec;
public class ConfigDrivenFeatureEntry extends ConfigBase { public class ConfigDrivenFeatureEntry extends ConfigBase {
public final String id; public final String id;
public BiomeFilter biomeFilter; public TagKey<Biome> biomeTag;
private NonNullSupplier<? extends Block> block; private NonNullSupplier<? extends Block> block;
private NonNullSupplier<? extends Block> deepblock; private NonNullSupplier<? extends Block> deepblock;