Fluids in barrels and crucibles now affect mobs
This commit is contained in:
parent
e531abf6cc
commit
5b0ba2ef31
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -57,4 +62,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -26,6 +28,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.shapes.BooleanOp;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
|
|
@ -34,11 +37,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) {
|
||||
|
|
@ -87,4 +93,10 @@ 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
71
src/main/java/thedarkcolour/exdeorum/block/ETankBlock.java
Normal file
71
src/main/java/thedarkcolour/exdeorum/block/ETankBlock.java
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.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(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 && ForgeMod.MILK.isPresent() && fluidType == ForgeMod.MILK.get()) {
|
||||
living.curePotionEffects(new ItemStack(Items.MILK_BUCKET));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()) {
|
||||
|
|
@ -70,7 +77,7 @@ public class WitchWaterBlock extends LiquidBlock {
|
|||
zombieVillager.setTradeOffers(villager.getOffers().createTag());
|
||||
zombieVillager.setVillagerXp(villager.getVillagerXp());
|
||||
|
||||
net.minecraftforge.event.ForgeEventFactory.onLivingConvert(villager, zombieVillager);
|
||||
ForgeEventFactory.onLivingConvert(villager, zombieVillager);
|
||||
|
||||
villager.discard();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ import java.util.HashMap;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
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);
|
||||
|
|
@ -248,6 +248,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
|||
return this.solids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidTank getTank() {
|
||||
return this.tank;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,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;
|
||||
|
||||
|
|
@ -209,6 +209,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
this.item.setStackInSlot(0, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidTank getTank() {
|
||||
return this.tank;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.minecraftforge.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();
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ import net.minecraft.world.item.ItemDisplayContext;
|
|||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.block.BarrelBlock;
|
||||
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
|
||||
import thedarkcolour.exdeorum.client.RenderUtil;
|
||||
|
||||
|
|
@ -81,7 +82,7 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
|||
var level = 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;
|
||||
|
|
@ -98,7 +99,7 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
|||
}
|
||||
|
||||
if (barrel.transparent) {
|
||||
RenderUtil.renderFluidCuboid(buffers, stack, level, pos, 1 / 16f, y, 2.0f, light, r, g, b, fluid);
|
||||
RenderUtil.renderFluidCuboid(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);
|
||||
}
|
||||
|
|
@ -129,7 +130,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, BarrelBlock.BARREL_FLUID_TOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import net.minecraft.client.renderer.MultiBufferSource;
|
|||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import thedarkcolour.exdeorum.block.AbstractCrucibleBlock;
|
||||
import thedarkcolour.exdeorum.blockentity.AbstractCrucibleBlockEntity;
|
||||
import thedarkcolour.exdeorum.client.RenderUtil;
|
||||
|
||||
|
|
@ -46,14 +47,14 @@ 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;
|
||||
float y = Mth.lerp(liquid, AbstractCrucibleBlock.CRUCIBLE_FLUID_BOTTOM, AbstractCrucibleBlock.CRUCIBLE_FLUID_TOP);
|
||||
|
||||
int r = (color >> 16) & 0xff;
|
||||
int g = (color >> 8) & 0xff;
|
||||
int b = color & 0xff;
|
||||
|
||||
if (crucible.transparent) {
|
||||
RenderUtil.renderFluidCuboid(buffers, stack, level, pos, 4 / 16f, y, 2.0f, light, r, g, b, fluid);
|
||||
RenderUtil.renderFluidCuboid(buffers, stack, level, pos, AbstractCrucibleBlock.CRUCIBLE_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);
|
||||
}
|
||||
|
|
@ -72,7 +73,7 @@ public class CrucibleRenderer implements BlockEntityRenderer<AbstractCrucibleBlo
|
|||
if (color == -1) color = 0xffffff;
|
||||
|
||||
// todo 3D solids for transparent crucibles
|
||||
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, AbstractCrucibleBlock.CRUCIBLE_FLUID_TOP);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -51,15 +51,4 @@ public class PorcelainMilkBucket extends MilkBucketItem {
|
|||
public @Nullable ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
|
||||
return new PorcelainBucket.CapabilityProvider(stack);
|
||||
}
|
||||
|
||||
private static class CapabilityProvider extends PorcelainBucket.CapabilityProvider {
|
||||
public CapabilityProvider(@NotNull ItemStack container) {
|
||||
super(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidValid(int tank, @NotNull FluidStack stack) {
|
||||
return ForgeMod.MILK.isPresent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user