Fluids in barrels and crucibles now affect mobs

This commit is contained in:
thedarkcolour 2024-06-12 12:03:23 -07:00
parent e6135d804a
commit 76293f5e70
No known key found for this signature in database
GPG Key ID: 6599A8E0516C8F38
9 changed files with 132 additions and 13 deletions

View File

@ -19,6 +19,8 @@
package thedarkcolour.exdeorum.block;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -33,7 +35,10 @@ import thedarkcolour.exdeorum.registry.EBlockEntities;
import java.util.function.Supplier;
public abstract class AbstractCrucibleBlock extends EBlock {
public abstract class AbstractCrucibleBlock extends ETankBlock {
public static final float CRUCIBLE_FLUID_BOTTOM = 4.0f / 16f;
public static final float CRUCIBLE_FLUID_TOP = 14.0f / 16f;
public AbstractCrucibleBlock(Properties properties, Supplier<? extends BlockEntityType<?>> blockEntityType) {
super(properties, blockEntityType);
}
@ -58,4 +63,10 @@ public abstract class AbstractCrucibleBlock extends EBlock {
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState pState, BlockEntityType<T> type) {
return (type == EBlockEntities.WATER_CRUCIBLE.get() || type == EBlockEntities.LAVA_CRUCIBLE.get()) ? (BlockEntityTicker<T>) new AbstractCrucibleBlockEntity.Ticker() : null;
}
@Override
protected boolean isEntityInFluid(Level level, BlockPos pos, Entity entity, float fillRatio) {
var fluidTop = Mth.lerp(fillRatio, CRUCIBLE_FLUID_BOTTOM, CRUCIBLE_FLUID_TOP);
return entity.getY() < pos.getY() + fluidTop && entity.getBoundingBox().maxY > pos.getY() + CRUCIBLE_FLUID_BOTTOM;
}
}

View File

@ -19,6 +19,8 @@
package thedarkcolour.exdeorum.block;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
@ -34,11 +36,14 @@ import org.jetbrains.annotations.Nullable;
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
import thedarkcolour.exdeorum.registry.EBlockEntities;
public class BarrelBlock extends EBlock {
public class BarrelBlock extends ETankBlock {
public static final float BARREL_FLUID_BOTTOM = 1f / 16f;
public static final float BARREL_FLUID_TOP = 14f / 16f;
public static final VoxelShape SHAPE = Shapes.join(
box(1, 0, 1, 15, 16, 15),
box(2, 1, 2, 14, 16, 14),
BooleanOp.ONLY_FIRST
box(1, 0, 1, 15, 16, 15),
box(2, 1, 2, 14, 16, 14),
BooleanOp.ONLY_FIRST
);
public BarrelBlock(Properties properties) {
@ -88,6 +93,12 @@ public class BarrelBlock extends EBlock {
}
}
@Override
protected boolean isEntityInFluid(Level level, BlockPos pos, Entity entity, float fillRatio) {
var fluidTop = Mth.lerp(fillRatio, BARREL_FLUID_BOTTOM, BARREL_FLUID_TOP);
return entity.getBoundingBox().intersects(pos.getX() + 0.125, pos.getY() + BARREL_FLUID_BOTTOM, pos.getZ() + 0.125, pos.getX() + 0.875, pos.getY() + fluidTop, pos.getZ() + 0.875);
}
@Override
public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) {
var lightManager = level.getAuxLightManager(pos);

View File

@ -0,0 +1,53 @@
package thedarkcolour.exdeorum.block;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluids;
import net.neoforged.neoforge.common.EffectCures;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.fluids.FluidStack;
import thedarkcolour.exdeorum.blockentity.ETankBlockEntity;
import thedarkcolour.exdeorum.registry.EFluids;
import java.util.function.Supplier;
// Base class for blocks that hold fluids (crucible, barrel)
public abstract class ETankBlock extends EBlock {
public ETankBlock(BlockBehaviour.Properties properties, Supplier<? extends BlockEntityType<?>> blockEntityType) {
super(properties, blockEntityType);
}
@Override
public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
if (!level.isClientSide && level.getBlockEntity(pos) instanceof ETankBlockEntity blockEntity) {
var tank = blockEntity.getTank();
var fluid = tank.getFluid();
if (!fluid.isEmpty() && isEntityInFluid(level, pos, entity, (float) fluid.getAmount() / tank.getCapacity())) {
entityInFluidLogic(level, entity, fluid);
}
}
}
protected abstract boolean isEntityInFluid(Level level, BlockPos pos, Entity entity, float fillRatio);
// Only call this on the server
public static void entityInFluidLogic(Level level, Entity entity, FluidStack fluid) {
var fluidType = fluid.getFluid();
if (fluidType == Fluids.LAVA) {
entity.lavaHurt();
} else if (fluidType == EFluids.WITCH_WATER.get()) {
WitchWaterBlock.witchWaterEntityEffects(level, entity);
} else if (fluidType.getFluidType().canExtinguish(entity)) {
entity.extinguishFire();
} else if (entity instanceof LivingEntity living && NeoForgeMod.MILK.isBound() && fluidType == NeoForgeMod.MILK.get()) {
living.removeEffectsCuredBy(EffectCures.MILK);
}
}
}

View File

@ -49,7 +49,14 @@ public class WitchWaterBlock extends LiquidBlock {
@Override
public void entityInside(BlockState pState, Level level, BlockPos pPos, Entity entity) {
if (!level.isClientSide && entity.isAlive()) {
if (!level.isClientSide) {
witchWaterEntityEffects(level, entity);
}
}
// Only call on server
public static void witchWaterEntityEffects(Level level, Entity entity) {
if (entity.isAlive()) {
var entityType = entity.getType();
if (EConfig.SERVER.allowWitchWaterEntityConversion.get()) {

View File

@ -58,7 +58,7 @@ import thedarkcolour.exdeorum.registry.EItems;
import java.util.HashMap;
import java.util.function.Consumer;
public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
public abstract class AbstractCrucibleBlockEntity extends ETankBlockEntity {
public static final Lazy<HashMap<Item, Block>> MELT_OVERRIDES = Lazy.concurrentOf(() -> {
var map = new HashMap<Item, Block>();
addMeltOverrides(map);
@ -244,6 +244,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
return this.solids;
}
@Override
public FluidTank getTank() {
return this.tank;
}

View File

@ -66,7 +66,7 @@ import thedarkcolour.exdeorum.recipe.barrel.FluidTransformationRecipe;
import thedarkcolour.exdeorum.registry.EBlockEntities;
import thedarkcolour.exdeorum.registry.ESounds;
public class BarrelBlockEntity extends EBlockEntity {
public class BarrelBlockEntity extends ETankBlockEntity {
private static final int MOSS_SPREAD_RANGE = 2;
private static final int MAX_CAPACITY = 1000;
@ -203,6 +203,7 @@ public class BarrelBlockEntity extends EBlockEntity {
this.item.setStackInSlot(0, item);
}
@Override
public FluidTank getTank() {
return this.tank;
}

View File

@ -0,0 +1,33 @@
/*
* Ex Deorum
* Copyright (c) 2024 thedarkcolour
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package thedarkcolour.exdeorum.blockentity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.fluids.IFluidTank;
// Base class for blocks that hold fluids (crucible, barrel)
public abstract class ETankBlockEntity extends EBlockEntity {
public ETankBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
public abstract IFluidTank getTank();
}

View File

@ -35,6 +35,7 @@ import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemDisplayContext;
import net.neoforged.neoforge.client.model.data.ModelData;
import thedarkcolour.exdeorum.ExDeorum;
import thedarkcolour.exdeorum.block.BarrelBlock;
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
import thedarkcolour.exdeorum.client.RenderUtil;
import thedarkcolour.exdeorum.config.EConfig;
@ -84,7 +85,7 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
var level = Objects.requireNonNull(barrel.getLevel());
var pos = barrel.getBlockPos();
var percentage = fluidStack.getAmount() / 1000.0f;
var y = Mth.lerp(percentage, 1.0f, 14.0f) / 16f;
var y = Mth.lerp(percentage, BarrelBlock.BARREL_FLUID_BOTTOM, BarrelBlock.BARREL_FLUID_TOP);
var inputFluidColor = RenderUtil.getFluidColor(fluid, level, pos);
// Split into RGB components
var r = (inputFluidColor >> 16) & 0xff;
@ -101,7 +102,7 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
}
if (barrel.transparent) {
RenderUtil.renderFluidCube(buffers, stack, level, pos, 1 / 16f, y, 2.0f, light, r, g, b, fluid);
RenderUtil.renderFluidCube(buffers, stack, level, pos, BarrelBlock.BARREL_FLUID_BOTTOM, y, 2.0f, light, r, g, b, fluid);
} else {
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, r, g, b, fluid);
}
@ -131,7 +132,7 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
g = (int) Mth.lerp(compostProgress, g, 169); // default green is
b = (int) Mth.lerp(compostProgress, b, 109); // default green is
RenderUtil.renderFlatSpriteLerp(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f);
RenderUtil.renderFlatSpriteLerp(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, BarrelBlock.BARREL_FLUID_BOTTOM * 16f, BarrelBlock.BARREL_FLUID_TOP * 16f);
}
}
}

View File

@ -23,6 +23,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.util.Mth;
import thedarkcolour.exdeorum.block.AbstractCrucibleBlock;
import thedarkcolour.exdeorum.blockentity.AbstractCrucibleBlockEntity;
import thedarkcolour.exdeorum.client.RenderUtil;
@ -45,7 +46,7 @@ public class CrucibleRenderer implements BlockEntityRenderer<AbstractCrucibleBlo
if (liquid != 0) {
var fluid = fluidStack.getFluid();
var color = RenderUtil.getFluidColor(fluid, level, pos);
float y = Mth.lerp(liquid, 4.0f, 14.0f) / 16f;
var y = Mth.lerp(liquid, AbstractCrucibleBlock.CRUCIBLE_FLUID_BOTTOM, AbstractCrucibleBlock.CRUCIBLE_FLUID_TOP);
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, fluid);
}
@ -62,7 +63,7 @@ public class CrucibleRenderer implements BlockEntityRenderer<AbstractCrucibleBlo
if (color == -1) color = 0xffffff;
face.renderFlatSpriteLerp(buffers, stack, solids, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, light, 2.0f, 4.0f, 14.0f);
face.renderFlatSpriteLerp(buffers, stack, solids, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, light, 2.0f, AbstractCrucibleBlock.CRUCIBLE_FLUID_BOTTOM * 16f, AbstractCrucibleBlock.CRUCIBLE_FLUID_TOP * 16f);
}
}