Add the compressed sieve
This commit is contained in:
parent
e0e419f3fe
commit
892a769ee6
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
|
|
||||||
|
public class CompressedSieveBlock extends SieveBlock {
|
||||||
|
public static final VoxelShape SHAPE = Shapes.or(
|
||||||
|
box(0, 8, 0, 16, 14, 16),
|
||||||
|
box(1, 0, 1, 3, 8, 3),
|
||||||
|
box(13, 0, 1, 15, 8, 3),
|
||||||
|
box(1, 0, 13, 3, 8, 15),
|
||||||
|
box(13, 0, 13, 15, 8, 15)
|
||||||
|
);
|
||||||
|
|
||||||
|
public CompressedSieveBlock(Properties properties) {
|
||||||
|
super(properties, EBlockEntities.COMPRESSED_SIEVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
|
||||||
|
return SHAPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,13 +22,18 @@ import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.Shapes;
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
||||||
import thedarkcolour.exdeorum.blockentity.SieveBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.SieveBlockEntity;
|
||||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class SieveBlock extends EBlock {
|
public class SieveBlock extends EBlock {
|
||||||
public static final VoxelShape SHAPE = Shapes.or(
|
public static final VoxelShape SHAPE = Shapes.or(
|
||||||
box(0, 11, 0, 16, 16, 16),
|
box(0, 11, 0, 16, 16, 16),
|
||||||
|
|
@ -42,14 +47,13 @@ public class SieveBlock extends EBlock {
|
||||||
super(properties, EBlockEntities.SIEVE);
|
super(properties, EBlockEntities.SIEVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected SieveBlock(Properties properties, Supplier<? extends BlockEntityType<?>> blockEntityType) {
|
||||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
super(properties, blockEntityType);
|
||||||
return SHAPE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||||
return new SieveBlockEntity(pos, state);
|
return SHAPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -22,19 +22,29 @@ import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraftforge.common.util.FakePlayer;
|
||||||
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
||||||
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public abstract class AbstractSieveBlockEntity extends EBlockEntity implements SieveLogic.Owner {
|
public abstract class AbstractSieveBlockEntity extends EBlockEntity implements SieveLogic.Owner {
|
||||||
protected final SieveLogic logic;
|
protected final SieveLogic logic;
|
||||||
|
private final float sieveInterval;
|
||||||
|
|
||||||
public AbstractSieveBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state, Function<SieveLogic.Owner, SieveLogic> logic) {
|
public AbstractSieveBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state, float sieveInterval, Function<SieveLogic.Owner, SieveLogic> logic) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
|
|
||||||
|
this.sieveInterval = sieveInterval;
|
||||||
this.logic = logic.apply(this);
|
this.logic = logic.apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,6 +54,16 @@ public abstract class AbstractSieveBlockEntity extends EBlockEntity implements S
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleResultItem(ItemStack result, ServerLevel level, RandomSource rand) {
|
||||||
|
var pos = this.worldPosition;
|
||||||
|
var itemEntity = new ItemEntity(level, pos.getX() + 0.5, pos.getY() + 1.5, pos.getZ() + 0.5, result);
|
||||||
|
itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
|
||||||
|
level.addFreshEntity(itemEntity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DataFlowIssue")
|
||||||
@Override
|
@Override
|
||||||
public ServerLevel getServerLevel() {
|
public ServerLevel getServerLevel() {
|
||||||
return (ServerLevel) this.level;
|
return (ServerLevel) this.level;
|
||||||
|
|
@ -81,4 +101,143 @@ public abstract class AbstractSieveBlockEntity extends EBlockEntity implements S
|
||||||
this.logic.setProgress(buffer.readFloat());
|
this.logic.setProgress(buffer.readFloat());
|
||||||
this.logic.setContents(buffer.readItem());
|
this.logic.setContents(buffer.readItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
||||||
|
ItemStack playerItem = player.getItemInHand(hand);
|
||||||
|
boolean isClientSide = level.isClientSide;
|
||||||
|
|
||||||
|
// Try insert mesh
|
||||||
|
if (this.logic.getMesh().isEmpty()) {
|
||||||
|
if (this.logic.isValidMesh(playerItem)) {
|
||||||
|
if (!isClientSide) {
|
||||||
|
this.logic.setMesh(singleCopy(playerItem));
|
||||||
|
|
||||||
|
if (!player.getAbilities().instabuild) {
|
||||||
|
playerItem.shrink(1);
|
||||||
|
}
|
||||||
|
return InteractionResult.CONSUME;
|
||||||
|
} else {
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.logic.getContents().isEmpty()) {
|
||||||
|
// remove mesh with sneak right click
|
||||||
|
if (player.isShiftKeyDown() && player.getMainHandItem().isEmpty()) {
|
||||||
|
popOutMesh(level, this.worldPosition, this.logic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isClientSide) {
|
||||||
|
// Insert an item
|
||||||
|
if (this.logic.getContents().isEmpty()) {
|
||||||
|
// If the input has any sieve drops, insert it into the mesh
|
||||||
|
if (this.logic.isValidInput(playerItem)) {
|
||||||
|
playerItem = insertContents(player, hand, this.logic);
|
||||||
|
var realPlayer = !(player instanceof FakePlayer);
|
||||||
|
|
||||||
|
// prevent machines placing in multiple sieves if nerf is off to avoid confusion
|
||||||
|
if ((realPlayer || !EConfig.SERVER.nerfAutomatedSieves.get()) && canUseSimultaneously()) {
|
||||||
|
int range = EConfig.SERVER.simultaneousSieveUsageRange.get();
|
||||||
|
var cursor = this.worldPosition.mutable().move(-range, 0, -range);
|
||||||
|
var selfType = getType();
|
||||||
|
|
||||||
|
// Fill adjacent sieves
|
||||||
|
otherSieves:
|
||||||
|
for (int x = -range; x <= range; x++) {
|
||||||
|
for (int z = -range; z <= range; z++) {
|
||||||
|
if (playerItem.isEmpty()) {
|
||||||
|
break otherSieves;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x | z) != 0) {
|
||||||
|
if (level.getBlockEntity(cursor) instanceof AbstractSieveBlockEntity other && other.getType() == selfType) {
|
||||||
|
var otherLogic = other.logic;
|
||||||
|
|
||||||
|
if (otherLogic.getContents().isEmpty()) {
|
||||||
|
if (this.logic.getMesh().getItem() == otherLogic.getMesh().getItem()) {
|
||||||
|
playerItem = insertContents(player, hand, otherLogic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor.move(0, 0, 1);
|
||||||
|
}
|
||||||
|
cursor.move(1, 0, (-2 * range) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var time = level.getGameTime();
|
||||||
|
var realPlayer = !(player instanceof FakePlayer);
|
||||||
|
|
||||||
|
if ((realPlayer || !EConfig.SERVER.nerfAutomatedSieves.get()) && canUseSimultaneously()) {
|
||||||
|
int range = EConfig.SERVER.simultaneousSieveUsageRange.get();
|
||||||
|
var cursor = this.worldPosition.mutable().move(-range, 0, -range);
|
||||||
|
var selfType = getType();
|
||||||
|
|
||||||
|
// Sieve with adjacent sieves
|
||||||
|
for (int x = -range; x <= range; x++) {
|
||||||
|
for (int z = -range; z <= range; z++) {
|
||||||
|
if (level.getBlockEntity(cursor) instanceof AbstractSieveBlockEntity other && other.getType() == selfType) {
|
||||||
|
var otherLogic = other.logic;
|
||||||
|
|
||||||
|
if (!otherLogic.getContents().isEmpty()) {
|
||||||
|
if (this.logic.getMesh().getItem() == otherLogic.getMesh().getItem()) {
|
||||||
|
otherLogic.sift(this.sieveInterval, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor.move(0, 0, 1);
|
||||||
|
}
|
||||||
|
cursor.move(1, 0, (-2 * range) - 1);
|
||||||
|
}
|
||||||
|
} else if (realPlayer || EConfig.SERVER.automatedSieves.get()) {
|
||||||
|
this.logic.sift(this.sieveInterval, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return InteractionResult.sidedSuccess(isClientSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fills the sieve (assumes contents is EMPTY) and returns the remaining item, putting it in the player's hand
|
||||||
|
public static ItemStack insertContents(Player player, InteractionHand hand, SieveLogic logic) {
|
||||||
|
var consume = !player.getAbilities().instabuild;
|
||||||
|
var playerItem = player.getItemInHand(hand);
|
||||||
|
|
||||||
|
if (consume) {
|
||||||
|
if (playerItem.getCount() == 1) {
|
||||||
|
logic.startSifting(playerItem);
|
||||||
|
player.setItemInHand(hand, ItemStack.EMPTY);
|
||||||
|
playerItem = ItemStack.EMPTY;
|
||||||
|
} else {
|
||||||
|
logic.startSifting(singleCopy(playerItem));
|
||||||
|
playerItem.shrink(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logic.startSifting(singleCopy(playerItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
return playerItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not call on client side
|
||||||
|
public static void popOutMesh(Level level, BlockPos sievePos, SieveLogic logic) {
|
||||||
|
if (!level.isClientSide) {
|
||||||
|
// Pop out item
|
||||||
|
var itemEntity = new ItemEntity(level, sievePos.getX() + 0.5, sievePos.getY() + 1.5, sievePos.getZ() + 0.5, logic.getMesh());
|
||||||
|
var rand = level.random;
|
||||||
|
itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
|
||||||
|
level.addFreshEntity(itemEntity);
|
||||||
|
|
||||||
|
// Empty contents
|
||||||
|
logic.setMesh(ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canUseSimultaneously() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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.state.BlockState;
|
||||||
|
import thedarkcolour.exdeorum.blockentity.logic.CompressedSieveLogic;
|
||||||
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
|
|
||||||
|
public class CompressedSieveBlockEntity extends AbstractSieveBlockEntity {
|
||||||
|
private static final float COMPRESSED_SIEVE_INTERVAL = 0.075f;
|
||||||
|
|
||||||
|
public CompressedSieveBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
super(EBlockEntities.COMPRESSED_SIEVE.get(), pos, state, COMPRESSED_SIEVE_INTERVAL, owner -> new CompressedSieveLogic(owner, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -49,7 +49,7 @@ public class MechanicalSieveBlockEntity extends AbstractMachineBlockEntity<Mecha
|
||||||
public MechanicalSieveBlockEntity(BlockPos pos, BlockState state) {
|
public MechanicalSieveBlockEntity(BlockPos pos, BlockState state) {
|
||||||
super(EBlockEntities.MECHANICAL_SIEVE.get(), pos, state, ItemHandler::new, EConfig.SERVER.mechanicalSieveEnergyStorage.get());
|
super(EBlockEntities.MECHANICAL_SIEVE.get(), pos, state, ItemHandler::new, EConfig.SERVER.mechanicalSieveEnergyStorage.get());
|
||||||
|
|
||||||
this.logic = new SieveLogic(this, false, true);
|
this.logic = new SieveLogic(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,7 @@
|
||||||
package thedarkcolour.exdeorum.blockentity;
|
package thedarkcolour.exdeorum.blockentity;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.InteractionHand;
|
|
||||||
import net.minecraft.world.InteractionResult;
|
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.common.util.FakePlayer;
|
|
||||||
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
|
|
@ -37,140 +28,11 @@ public class SieveBlockEntity extends AbstractSieveBlockEntity {
|
||||||
public static final float SIEVE_INTERVAL = 0.1f;
|
public static final float SIEVE_INTERVAL = 0.1f;
|
||||||
|
|
||||||
public SieveBlockEntity(BlockPos pos, BlockState state) {
|
public SieveBlockEntity(BlockPos pos, BlockState state) {
|
||||||
super(EBlockEntities.SIEVE.get(), pos, state, (owner) -> new SieveLogic(owner, true, false));
|
super(EBlockEntities.SIEVE.get(), pos, state, SIEVE_INTERVAL, owner -> new SieveLogic(owner, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleResultItem(ItemStack result, ServerLevel level, RandomSource rand) {
|
protected boolean canUseSimultaneously() {
|
||||||
var pos = this.worldPosition;
|
return EConfig.SERVER.simultaneousSieveUsage.get();
|
||||||
var itemEntity = new ItemEntity(level, pos.getX() + 0.5, pos.getY() + 1.5, pos.getZ() + 0.5, result);
|
|
||||||
itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
|
|
||||||
level.addFreshEntity(itemEntity);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
|
||||||
ItemStack playerItem = player.getItemInHand(hand);
|
|
||||||
boolean isClientSide = level.isClientSide;
|
|
||||||
|
|
||||||
// Try insert mesh
|
|
||||||
if (this.logic.getMesh().isEmpty()) {
|
|
||||||
if (this.logic.isValidMesh(playerItem)) {
|
|
||||||
if (!isClientSide) {
|
|
||||||
this.logic.setMesh(singleCopy(playerItem));
|
|
||||||
|
|
||||||
if (!player.getAbilities().instabuild) {
|
|
||||||
playerItem.shrink(1);
|
|
||||||
}
|
|
||||||
return InteractionResult.CONSUME;
|
|
||||||
} else {
|
|
||||||
return InteractionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (this.logic.getContents().isEmpty()) {
|
|
||||||
// remove mesh with sneak right click
|
|
||||||
if (player.isShiftKeyDown() && player.getMainHandItem().isEmpty()) {
|
|
||||||
popOutMesh(level, this.worldPosition, this.logic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isClientSide) {
|
|
||||||
// Insert an item
|
|
||||||
if (this.logic.getContents().isEmpty()) {
|
|
||||||
// If the input has any sieve drops, insert it into the mesh
|
|
||||||
if (this.logic.isValidInput(playerItem)) {
|
|
||||||
playerItem = insertContents(player, hand, this.logic);
|
|
||||||
|
|
||||||
if (EConfig.SERVER.simultaneousSieveUsage.get()) {
|
|
||||||
int range = EConfig.SERVER.simultaneousSieveUsageRange.get();
|
|
||||||
var cursor = this.worldPosition.mutable().move(-range, 0, -range);
|
|
||||||
|
|
||||||
// Fill adjacent sieves
|
|
||||||
otherSieves:
|
|
||||||
for (int x = -range; x <= range; x++) {
|
|
||||||
for (int z = -range; z <= range; z++) {
|
|
||||||
if (playerItem.isEmpty()) {
|
|
||||||
break otherSieves;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x | z) != 0) {
|
|
||||||
if (level.getBlockEntity(cursor) instanceof SieveBlockEntity other) {
|
|
||||||
if (other.logic.getContents().isEmpty()) {
|
|
||||||
if (this.logic.getMesh().getItem() == other.logic.getMesh().getItem()) {
|
|
||||||
playerItem = insertContents(player, hand, other.logic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor.move(0, 0, 1);
|
|
||||||
}
|
|
||||||
cursor.move(1, 0, (-2 * range) - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var time = level.getGameTime();
|
|
||||||
var realPlayer = !(player instanceof FakePlayer);
|
|
||||||
|
|
||||||
if ((realPlayer || !EConfig.SERVER.nerfAutomatedSieves.get()) && EConfig.SERVER.simultaneousSieveUsage.get()) {
|
|
||||||
int range = EConfig.SERVER.simultaneousSieveUsageRange.get();
|
|
||||||
var cursor = this.worldPosition.mutable().move(-range, 0, -range);
|
|
||||||
|
|
||||||
// Sieve with adjacent sieves
|
|
||||||
for (int x = -range; x <= range; x++) {
|
|
||||||
for (int z = -range; z <= range; z++) {
|
|
||||||
if (level.getBlockEntity(cursor) instanceof SieveBlockEntity other) {
|
|
||||||
if (!other.logic.getContents().isEmpty()) {
|
|
||||||
if (this.logic.getMesh().getItem() == other.logic.getMesh().getItem()) {
|
|
||||||
other.logic.sift(SIEVE_INTERVAL, time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor.move(0, 0, 1);
|
|
||||||
}
|
|
||||||
cursor.move(1, 0, (-2 * range) - 1);
|
|
||||||
}
|
|
||||||
} else if (realPlayer || EConfig.SERVER.automatedSieves.get()) {
|
|
||||||
this.logic.sift(SIEVE_INTERVAL, time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return InteractionResult.sidedSuccess(isClientSide);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fills the sieve (assumes contents is EMPTY) and returns the remaining item, putting it in the player's hand
|
|
||||||
public static ItemStack insertContents(Player player, InteractionHand hand, SieveLogic logic) {
|
|
||||||
var consume = !player.getAbilities().instabuild;
|
|
||||||
var playerItem = player.getItemInHand(hand);
|
|
||||||
|
|
||||||
if (consume) {
|
|
||||||
if (playerItem.getCount() == 1) {
|
|
||||||
logic.startSifting(playerItem);
|
|
||||||
player.setItemInHand(hand, ItemStack.EMPTY);
|
|
||||||
playerItem = ItemStack.EMPTY;
|
|
||||||
} else {
|
|
||||||
logic.startSifting(singleCopy(playerItem));
|
|
||||||
playerItem.shrink(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logic.startSifting(singleCopy(playerItem));
|
|
||||||
}
|
|
||||||
|
|
||||||
return playerItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not call on client side
|
|
||||||
public static void popOutMesh(Level level, BlockPos sievePos, SieveLogic logic) {
|
|
||||||
if (!level.isClientSide) {
|
|
||||||
// Pop out item
|
|
||||||
var itemEntity = new ItemEntity(level, sievePos.getX() + 0.5, sievePos.getY() + 1.5, sievePos.getZ() + 0.5, logic.getMesh());
|
|
||||||
var rand = level.random;
|
|
||||||
itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
|
|
||||||
level.addFreshEntity(itemEntity);
|
|
||||||
|
|
||||||
// Empty contents
|
|
||||||
logic.setMesh(ItemStack.EMPTY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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.logic;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CompressedSieveLogic extends SieveLogic {
|
||||||
|
public CompressedSieveLogic(Owner owner, boolean mechanical) {
|
||||||
|
super(owner, mechanical);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<? extends SieveRecipe> getDropsFor(ItemStack contents) {
|
||||||
|
return RecipeUtil.getCompressedSieveRecipes(this.mesh.getItem(), contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -32,15 +32,16 @@ import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
import thedarkcolour.exdeorum.tag.EItemTags;
|
import thedarkcolour.exdeorum.tag.EItemTags;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class SieveLogic {
|
public class SieveLogic {
|
||||||
private final Owner owner;
|
private final Owner owner;
|
||||||
private final boolean saveMesh;
|
|
||||||
private final boolean mechanical;
|
private final boolean mechanical;
|
||||||
|
|
||||||
// block currently being sifted
|
// block currently being sifted
|
||||||
private ItemStack contents = ItemStack.EMPTY;
|
private ItemStack contents = ItemStack.EMPTY;
|
||||||
// mesh
|
// mesh
|
||||||
private ItemStack mesh = ItemStack.EMPTY;
|
protected ItemStack mesh = ItemStack.EMPTY;
|
||||||
// from 0.0 to 1.0
|
// from 0.0 to 1.0
|
||||||
private float progress;
|
private float progress;
|
||||||
private float efficiency;
|
private float efficiency;
|
||||||
|
|
@ -48,9 +49,8 @@ public class SieveLogic {
|
||||||
private long lastTime = 0;
|
private long lastTime = 0;
|
||||||
private final long minInterval;
|
private final long minInterval;
|
||||||
|
|
||||||
public SieveLogic(Owner owner, boolean saveMesh, boolean mechanical) {
|
public SieveLogic(Owner owner, boolean mechanical) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.saveMesh = saveMesh;
|
|
||||||
this.mechanical = mechanical;
|
this.mechanical = mechanical;
|
||||||
this.minInterval = EConfig.SERVER.sieveIntervalTicks.get();
|
this.minInterval = EConfig.SERVER.sieveIntervalTicks.get();
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +60,7 @@ public class SieveLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValidInput(ItemStack stack) {
|
public boolean isValidInput(ItemStack stack) {
|
||||||
return !RecipeUtil.getSieveRecipes(this.mesh.getItem(), stack).isEmpty();
|
return !getDropsFor(stack).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValidMesh(ItemStack stack) {
|
public boolean isValidMesh(ItemStack stack) {
|
||||||
|
|
@ -91,7 +91,7 @@ public class SieveLogic {
|
||||||
var handledAnyDrops = false;
|
var handledAnyDrops = false;
|
||||||
var hasDrops = false;
|
var hasDrops = false;
|
||||||
|
|
||||||
for (SieveRecipe recipe : RecipeUtil.getSieveRecipes(this.mesh.getItem(), this.contents)) {
|
for (SieveRecipe recipe : getDropsFor(this.contents)) {
|
||||||
var amount = getResultAmount(recipe, context, rand);
|
var amount = getResultAmount(recipe, context, rand);
|
||||||
|
|
||||||
// Split overflowing stacks (64+) into multiple stacks
|
// Split overflowing stacks (64+) into multiple stacks
|
||||||
|
|
@ -124,6 +124,10 @@ public class SieveLogic {
|
||||||
this.owner.markUpdated();
|
this.owner.markUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<? extends SieveRecipe> getDropsFor(ItemStack contents) {
|
||||||
|
return RecipeUtil.getSieveRecipes(this.mesh.getItem(), contents);
|
||||||
|
}
|
||||||
|
|
||||||
protected int getResultAmount(SieveRecipe recipe, LootContext context, RandomSource rand) {
|
protected int getResultAmount(SieveRecipe recipe, LootContext context, RandomSource rand) {
|
||||||
if (recipe.byHandOnly && this.mechanical) return 0;
|
if (recipe.byHandOnly && this.mechanical) return 0;
|
||||||
|
|
||||||
|
|
@ -160,7 +164,7 @@ public class SieveLogic {
|
||||||
if (!this.contents.isEmpty()) {
|
if (!this.contents.isEmpty()) {
|
||||||
nbt.put("contents", this.contents.serializeNBT());
|
nbt.put("contents", this.contents.serializeNBT());
|
||||||
}
|
}
|
||||||
if (this.saveMesh && !this.mesh.isEmpty()) {
|
if (!this.mechanical && !this.mesh.isEmpty()) {
|
||||||
nbt.put("mesh", this.mesh.save(new CompoundTag()));
|
nbt.put("mesh", this.mesh.save(new CompoundTag()));
|
||||||
}
|
}
|
||||||
nbt.putFloat("progress", this.progress);
|
nbt.putFloat("progress", this.progress);
|
||||||
|
|
@ -177,7 +181,7 @@ public class SieveLogic {
|
||||||
} else {
|
} else {
|
||||||
this.progress = nbt.getFloat("progress");
|
this.progress = nbt.getFloat("progress");
|
||||||
}
|
}
|
||||||
if (this.saveMesh) {
|
if (!this.mechanical) {
|
||||||
if (nbt.contains("mesh")) {
|
if (nbt.contains("mesh")) {
|
||||||
setMesh(ItemStack.of(nbt.getCompound("mesh")), false);
|
setMesh(ItemStack.of(nbt.getCompound("mesh")), false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,7 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
||||||
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
||||||
import thedarkcolour.exdeorum.client.ter.BarrelRenderer;
|
import thedarkcolour.exdeorum.client.ter.*;
|
||||||
import thedarkcolour.exdeorum.client.ter.CrucibleRenderer;
|
|
||||||
import thedarkcolour.exdeorum.client.ter.InfestedLeavesRenderer;
|
|
||||||
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
|
||||||
import thedarkcolour.exdeorum.compat.ModIds;
|
import thedarkcolour.exdeorum.compat.ModIds;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
import thedarkcolour.exdeorum.network.ClientMessageHandler;
|
import thedarkcolour.exdeorum.network.ClientMessageHandler;
|
||||||
|
|
@ -136,8 +133,9 @@ public class ClientHandler {
|
||||||
event.registerBlockEntityRenderer(EBlockEntities.BARREL.get(), BarrelRenderer::new);
|
event.registerBlockEntityRenderer(EBlockEntities.BARREL.get(), BarrelRenderer::new);
|
||||||
event.registerBlockEntityRenderer(EBlockEntities.LAVA_CRUCIBLE.get(), ctx -> new CrucibleRenderer());
|
event.registerBlockEntityRenderer(EBlockEntities.LAVA_CRUCIBLE.get(), ctx -> new CrucibleRenderer());
|
||||||
event.registerBlockEntityRenderer(EBlockEntities.WATER_CRUCIBLE.get(), ctx -> new CrucibleRenderer());
|
event.registerBlockEntityRenderer(EBlockEntities.WATER_CRUCIBLE.get(), ctx -> new CrucibleRenderer());
|
||||||
event.registerBlockEntityRenderer(EBlockEntities.SIEVE.get(), ctx -> new SieveRenderer<>());
|
event.registerBlockEntityRenderer(EBlockEntities.SIEVE.get(), ctx -> new SieveRenderer<>(0.75f, 15f));
|
||||||
event.registerBlockEntityRenderer(EBlockEntities.MECHANICAL_SIEVE.get(), ctx -> new SieveRenderer<>());
|
event.registerBlockEntityRenderer(EBlockEntities.MECHANICAL_SIEVE.get(), ctx -> new SieveRenderer<>(0.75f, 15f));
|
||||||
|
event.registerBlockEntityRenderer(EBlockEntities.COMPRESSED_SIEVE.get(), ctx -> new CompressedSieveRenderer<>(0.5625f, 16f));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerShaders(RegisterShadersEvent event) {
|
private static void registerShaders(RegisterShadersEvent event) {
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,17 @@
|
||||||
package thedarkcolour.exdeorum.client;
|
package thedarkcolour.exdeorum.client;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface RenderFace {
|
public interface RenderFace {
|
||||||
void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd);
|
void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd);
|
||||||
|
|
||||||
boolean isMissingTexture();
|
boolean isMissingTexture();
|
||||||
|
|
||||||
|
void renderCuboid(MultiBufferSource buffers, PoseStack stack, float minY, float maxY, int r, int g, int b, int light, float edge);
|
||||||
|
|
||||||
record Single(RenderType renderType, TextureAtlasSprite sprite, boolean isMissingTexture) implements RenderFace {
|
record Single(RenderType renderType, TextureAtlasSprite sprite, boolean isMissingTexture) implements RenderFace {
|
||||||
public Single(RenderType renderType, TextureAtlasSprite sprite) {
|
public Single(RenderType renderType, TextureAtlasSprite sprite) {
|
||||||
this(renderType, sprite, RenderUtil.isMissingTexture(sprite));
|
this(renderType, sprite, RenderUtil.isMissingTexture(sprite));
|
||||||
|
|
@ -40,23 +39,35 @@ public interface RenderFace {
|
||||||
public void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd) {
|
public void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd) {
|
||||||
RenderUtil.renderFlatSpriteLerp(buffers.getBuffer(this.renderType), stack, percentage, r, g, b, this.sprite, light, edge, yStart, yEnd);
|
RenderUtil.renderFlatSpriteLerp(buffers.getBuffer(this.renderType), stack, percentage, r, g, b, this.sprite, light, edge, yStart, yEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderCuboid(MultiBufferSource buffers, PoseStack stack, float minY, float maxY, int r, int g, int b, int light, float edge) {
|
||||||
|
RenderUtil.renderCuboid(buffers.getBuffer(this.renderType), stack, minY, maxY, r, g, b, this.sprite, light, edge);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record Composite(List<Pair<RenderType, TextureAtlasSprite>> layers, boolean isMissingTexture) implements RenderFace {
|
record Composite(CompositeLayer[] layers, boolean isMissingTexture) implements RenderFace {
|
||||||
public Composite(List<Pair<RenderType, TextureAtlasSprite>> layers) {
|
public Composite(CompositeLayer[] layers) {
|
||||||
this(layers, areAnyMissing(layers));
|
this(layers, areAnyMissing(layers));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd) {
|
public void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd) {
|
||||||
for (var layer : this.layers) {
|
for (var layer : this.layers) {
|
||||||
RenderUtil.renderFlatSpriteLerp(buffers.getBuffer(layer.first()), stack, percentage, r, g, b, layer.second(), light, edge, yStart, yEnd);
|
RenderUtil.renderFlatSpriteLerp(buffers.getBuffer(layer.renderType), stack, percentage, r, g, b, layer.sprite, light, edge, yStart, yEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean areAnyMissing(List<Pair<RenderType, TextureAtlasSprite>> layers) {
|
@Override
|
||||||
|
public void renderCuboid(MultiBufferSource buffers, PoseStack stack, float minY, float maxY, int r, int g, int b, int light, float edge) {
|
||||||
|
for (var layer : this.layers) {
|
||||||
|
RenderUtil.renderCuboid(buffers.getBuffer(layer.renderType), stack, minY, maxY, r, g, b, layer.sprite, light, edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean areAnyMissing(CompositeLayer[] layers) {
|
||||||
for (var layer : layers) {
|
for (var layer : layers) {
|
||||||
if (RenderUtil.isMissingTexture(layer.second())) {
|
if (RenderUtil.isMissingTexture(layer.sprite)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,4 +75,6 @@ public interface RenderFace {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record CompositeLayer(RenderType renderType, TextureAtlasSprite sprite) {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,25 +18,20 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.client;
|
package thedarkcolour.exdeorum.client;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
|
||||||
import net.irisshaders.iris.api.v0.IrisApi;
|
import net.irisshaders.iris.api.v0.IrisApi;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.*;
|
||||||
import net.minecraft.client.renderer.RenderStateShard;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.renderer.ShaderInstance;
|
|
||||||
import net.minecraft.client.renderer.Sheets;
|
|
||||||
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
|
|
@ -48,7 +43,6 @@ import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||||
import net.minecraftforge.client.model.CompositeModel;
|
import net.minecraftforge.client.model.CompositeModel;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
import net.minecraftforge.client.model.data.ModelData;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
||||||
|
|
@ -117,14 +111,15 @@ public class RenderUtil {
|
||||||
if (model instanceof CompositeModel.Baked composite) {
|
if (model instanceof CompositeModel.Baked composite) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
ImmutableMap<String, BakedModel> children = (ImmutableMap<String, BakedModel>) COMPOSITE_MODEL_CHILDREN.get(composite);
|
ImmutableMap<String, BakedModel> children = (ImmutableMap<String, BakedModel>) COMPOSITE_MODEL_CHILDREN.get(composite);
|
||||||
var builder = new ImmutableList.Builder<Pair<RenderType, TextureAtlasSprite>>();
|
RenderFace.CompositeLayer[] layers = new RenderFace.CompositeLayer[children.size()];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
for (var childModel : children.values()) {
|
for (var childModel : children.values()) {
|
||||||
var singleFace = getFaceFromModel(block, rand, childModel);
|
var singleFace = getFaceFromModel(block, rand, childModel);
|
||||||
builder.add(Pair.of(singleFace.renderType(), singleFace.sprite()));
|
layers[i++] = new RenderFace.CompositeLayer(singleFace.renderType(), singleFace.sprite());
|
||||||
}
|
}
|
||||||
|
|
||||||
face = new RenderFace.Composite(builder.build());
|
face = new RenderFace.Composite(layers);
|
||||||
} else {
|
} else {
|
||||||
face = getFaceFromModel(block, rand, model);
|
face = getFaceFromModel(block, rand, model);
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +142,7 @@ public class RenderUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextureAtlasSprite getTopTexture(Block block, BakedModel model) {
|
private static TextureAtlasSprite getTopTexture(Block block, BakedModel model) {
|
||||||
var registryName = ForgeRegistries.BLOCKS.getKey(block);
|
var registryName = BuiltInRegistries.BLOCK.getKey(block);
|
||||||
var sprite = blockAtlas.getSprite(registryName.withPrefix("block/"));
|
var sprite = blockAtlas.getSprite(registryName.withPrefix("block/"));
|
||||||
// for stuff like azalea bush, retry to get the top texture
|
// for stuff like azalea bush, retry to get the top texture
|
||||||
if (isMissingTexture(sprite)) {
|
if (isMissingTexture(sprite)) {
|
||||||
|
|
@ -209,6 +204,10 @@ public class RenderUtil {
|
||||||
//vMin = sprite.getV0();
|
//vMin = sprite.getV0();
|
||||||
//vMax = sprite.getV(8);
|
//vMax = sprite.getV(8);
|
||||||
|
|
||||||
|
// Adjust UV based on height of cuboid, rendering from the top down to the bottom of the texture
|
||||||
|
float f = sprite.getV1() - sprite.getV0();
|
||||||
|
vMax = sprite.getV0() + f * (maxY - minY);
|
||||||
|
|
||||||
// South face
|
// South face
|
||||||
normal = poseNormal.transform(new Vector3f(0, 0, 1));
|
normal = poseNormal.transform(new Vector3f(0, 0, 1));
|
||||||
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
|
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
|
@ -265,6 +264,68 @@ public class RenderUtil {
|
||||||
builder.vertex(pose, edgeMax, y, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
|
builder.vertex(pose, edgeMax, y, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo use ambient occlusion
|
||||||
|
// Renders a cuboid using the same side sprite on all six sides
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
|
public static void renderCuboid(VertexConsumer builder, PoseStack stack, float minY, float maxY, int r, int g, int b, TextureAtlasSprite sprite, int light, float edge) {
|
||||||
|
var pose = stack.last().pose();
|
||||||
|
var poseNormal = stack.last().normal();
|
||||||
|
|
||||||
|
Vector3f normal;
|
||||||
|
float uMin = sprite.getU0();
|
||||||
|
float uMax = sprite.getU1();
|
||||||
|
float vMin = sprite.getV0();
|
||||||
|
float vMax = sprite.getV1();
|
||||||
|
|
||||||
|
float edgeMin = edge / 16f;
|
||||||
|
float edgeMax = 1f - edge / 16f;
|
||||||
|
|
||||||
|
int lightU = light & '\uffff';
|
||||||
|
int lightV = light >> 16 & '\uffff';
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
normal = poseNormal.transform(new Vector3f(0, 1, 0));
|
||||||
|
builder.vertex(pose, edgeMin, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, maxY, edgeMax).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, maxY, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
// Bottom face
|
||||||
|
normal = poseNormal.transform(new Vector3f(0, -1, 0));
|
||||||
|
builder.vertex(pose, edgeMin, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, minY, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, minY, edgeMax).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
|
||||||
|
// Adjust UV based on height of cuboid, rendering from the top down to the bottom of the texture
|
||||||
|
float f = sprite.getV1() - sprite.getV0();
|
||||||
|
vMax = sprite.getV0() + f * (maxY - minY);
|
||||||
|
|
||||||
|
// South face
|
||||||
|
normal = poseNormal.transform(new Vector3f(0, 0, -1));
|
||||||
|
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, maxY, edgeMax).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, minY, edgeMax).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
// North face
|
||||||
|
normal = poseNormal.transform(new Vector3f(0, 0, -1));
|
||||||
|
builder.vertex(pose, edgeMin, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, maxY, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, minY, edgeMin).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
// East face
|
||||||
|
normal = poseNormal.transform(new Vector3f(1, 0, 0));
|
||||||
|
builder.vertex(pose, edgeMax, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMax, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
// West face
|
||||||
|
normal = poseNormal.transform(new Vector3f(-1, 0, 0));
|
||||||
|
builder.vertex(pose, edgeMin, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
builder.vertex(pose, edgeMin, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(lightU, lightV).normal(normal.x, normal.y, normal.z).endVertex();
|
||||||
|
}
|
||||||
|
|
||||||
public static Color getRainbowColor(long time, float partialTicks) {
|
public static Color getRainbowColor(long time, float partialTicks) {
|
||||||
return Color.getHSBColor((180 * Mth.sin((time + partialTicks) / 16.0f) - 180) / 360.0f, 0.7f, 0.8f);
|
return Color.getHSBColor((180 * Mth.sin((time + partialTicks) / 16.0f) - 180) / 360.0f, 0.7f, 0.8f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.client.ter;
|
||||||
|
|
||||||
|
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
||||||
|
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
||||||
|
|
||||||
|
// mesh y = 10 / 16
|
||||||
|
public class CompressedSieveRenderer<T extends EBlockEntity & SieveLogic.Owner> extends SieveRenderer<T> {
|
||||||
|
public CompressedSieveRenderer(float meshHeight, float contentsMaxY) {
|
||||||
|
super(meshHeight, contentsMaxY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldContentsRender3d(T sieve) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
||||||
|
|
@ -37,6 +38,16 @@ import java.util.Map;
|
||||||
public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements BlockEntityRenderer<T> {
|
public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements BlockEntityRenderer<T> {
|
||||||
public static final Map<Item, TextureAtlasSprite> MESH_TEXTURES = new HashMap<>();
|
public static final Map<Item, TextureAtlasSprite> MESH_TEXTURES = new HashMap<>();
|
||||||
|
|
||||||
|
private final float meshHeight;
|
||||||
|
private final float contentsMinY;
|
||||||
|
private final float contentsMaxY;
|
||||||
|
|
||||||
|
public SieveRenderer(float meshHeight, float contentsMaxY) {
|
||||||
|
this.meshHeight = meshHeight;
|
||||||
|
this.contentsMinY = meshHeight * 16f + 1f;
|
||||||
|
this.contentsMaxY = contentsMaxY;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(T sieve, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
|
public void render(T sieve, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
|
||||||
var logic = sieve.getLogic();
|
var logic = sieve.getLogic();
|
||||||
|
|
@ -46,7 +57,12 @@ public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements
|
||||||
var block = blockItem.getBlock();
|
var block = blockItem.getBlock();
|
||||||
var percentage = logic.getProgress();
|
var percentage = logic.getProgress();
|
||||||
var face = RenderUtil.getTopFace(block);
|
var face = RenderUtil.getTopFace(block);
|
||||||
face.renderFlatSpriteLerp(buffers, stack, percentage, 0xff, 0xff, 0xff, light, 1.0f, 15f, 13f);
|
|
||||||
|
if (shouldContentsRender3d(sieve)) {
|
||||||
|
face.renderCuboid(buffers, stack, this.contentsMinY / 16f, Mth.lerp(percentage, this.contentsMaxY, this.contentsMinY) / 16f, 0xff, 0xff, 0xff, light, 1.0f);
|
||||||
|
} else {
|
||||||
|
face.renderFlatSpriteLerp(buffers, stack, percentage, 0xff, 0xff, 0xff, light, 1.0f, this.contentsMaxY, this.contentsMinY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var mesh = logic.getMesh();
|
var mesh = logic.getMesh();
|
||||||
|
|
@ -66,11 +82,16 @@ public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements
|
||||||
MESH_TEXTURES.put(meshItem, meshSprite);
|
MESH_TEXTURES.put(meshItem, meshSprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderUtil.renderFlatSprite(builder, stack, 0.75f, 0xff, 0xff, 0xff, meshSprite, light, 1f);
|
RenderUtil.renderFlatSprite(builder, stack, this.meshHeight, 0xff, 0xff, 0xff, meshSprite, light, 1f);
|
||||||
|
|
||||||
if (mesh.hasFoil()) {
|
if (mesh.hasFoil()) {
|
||||||
RenderUtil.renderFlatSprite(buffers.getBuffer(RenderType.glint()), stack, 0.75f, 0xff, 0xff, 0xff, meshSprite, light, 1f);
|
RenderUtil.renderFlatSprite(buffers.getBuffer(RenderType.glint()), stack, this.meshHeight, 0xff, 0xff, 0xff, meshSprite, light, 1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo return true for transparent sieves
|
||||||
|
protected boolean shouldContentsRender3d(T sieve) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.material;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.SoundType;
|
||||||
|
import thedarkcolour.exdeorum.block.CompressedSieveBlock;
|
||||||
|
|
||||||
|
public class CompressedSieveMaterial extends SieveMaterial {
|
||||||
|
protected CompressedSieveMaterial(SoundType soundType, float strength, boolean needsCorrectTool, String requiredModId) {
|
||||||
|
super(soundType, strength, needsCorrectTool, requiredModId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Block createBlock() {
|
||||||
|
return new CompressedSieveBlock(props().noOcclusion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,7 @@ import thedarkcolour.exdeorum.compat.ModIds;
|
||||||
public class DefaultMaterials {
|
public class DefaultMaterials {
|
||||||
public static final MaterialRegistry<BarrelMaterial> BARRELS = new MaterialRegistry<>("barrel");
|
public static final MaterialRegistry<BarrelMaterial> BARRELS = new MaterialRegistry<>("barrel");
|
||||||
public static final MaterialRegistry<SieveMaterial> SIEVES = new MaterialRegistry<>("sieve");
|
public static final MaterialRegistry<SieveMaterial> SIEVES = new MaterialRegistry<>("sieve");
|
||||||
|
public static final MaterialRegistry<CompressedSieveMaterial> COMPRESSED_SIEVES = new MaterialRegistry<>("compressed_sieve");
|
||||||
public static final MaterialRegistry<AbstractCrucibleMaterial> LAVA_CRUCIBLES = new MaterialRegistry<>("lava_crucible", "crucible");
|
public static final MaterialRegistry<AbstractCrucibleMaterial> LAVA_CRUCIBLES = new MaterialRegistry<>("lava_crucible", "crucible");
|
||||||
public static final MaterialRegistry<AbstractCrucibleMaterial> WATER_CRUCIBLES = new MaterialRegistry<>("water_crucible", "crucible");
|
public static final MaterialRegistry<AbstractCrucibleMaterial> WATER_CRUCIBLES = new MaterialRegistry<>("water_crucible", "crucible");
|
||||||
|
|
||||||
|
|
@ -105,6 +106,17 @@ public class DefaultMaterials {
|
||||||
public static final SieveMaterial MAPLE_SIEVE = addDefaultSieve("maple", SoundType.WOOD, ModIds.BLUE_SKIES);
|
public static final SieveMaterial MAPLE_SIEVE = addDefaultSieve("maple", SoundType.WOOD, ModIds.BLUE_SKIES);
|
||||||
public static final SieveMaterial CRYSTALLIZED_SIEVE = addDefaultSieve("crystallized", SoundType.GLASS, true, ModIds.BLUE_SKIES);
|
public static final SieveMaterial CRYSTALLIZED_SIEVE = addDefaultSieve("crystallized", SoundType.GLASS, true, ModIds.BLUE_SKIES);
|
||||||
|
|
||||||
|
// Ex Deorum
|
||||||
|
public static final CompressedSieveMaterial OAK_COMPRESSED_SIEVE = addDefaultCompressedSieve("oak", SoundType.WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial SPRUCE_COMPRESSED_SIEVE = addDefaultCompressedSieve("spruce", SoundType.WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial BIRCH_COMPRESSED_SIEVE = addDefaultCompressedSieve("birch", SoundType.WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial JUNGLE_COMPRESSED_SIEVE = addDefaultCompressedSieve("jungle", SoundType.WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial ACACIA_COMPRESSED_SIEVE = addDefaultCompressedSieve("acacia", SoundType.WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial DARK_OAK_COMPRESSED_SIEVE = addDefaultCompressedSieve("dark_oak", SoundType.WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial MANGROVE_COMPRESSED_SIEVE = addDefaultCompressedSieve("mangrove", SoundType.WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial CHERRY_COMPRESSED_SIEVE = addDefaultCompressedSieve("cherry", SoundType.CHERRY_WOOD, ExDeorum.ID);
|
||||||
|
public static final CompressedSieveMaterial BAMBOO_COMPRESSED_SIEVE = addDefaultCompressedSieve("bamboo", SoundType.BAMBOO_WOOD, ExDeorum.ID);
|
||||||
|
|
||||||
// Ex Deorum
|
// Ex Deorum
|
||||||
public static final LavaCrucibleMaterial PORCELAIN_CRUCIBLE = addDefaultLavaCrucible("porcelain", SoundType.STONE, 2.0f, false, MapColor.TERRACOTTA_WHITE, ExDeorum.ID, false);
|
public static final LavaCrucibleMaterial PORCELAIN_CRUCIBLE = addDefaultLavaCrucible("porcelain", SoundType.STONE, 2.0f, false, MapColor.TERRACOTTA_WHITE, ExDeorum.ID, false);
|
||||||
public static final LavaCrucibleMaterial WARPED_CRUCIBLE = addDefaultLavaCrucible("warped", SoundType.STEM, 1.5f, false, MapColor.CRIMSON_STEM, ExDeorum.ID, false);
|
public static final LavaCrucibleMaterial WARPED_CRUCIBLE = addDefaultLavaCrucible("warped", SoundType.STEM, 1.5f, false, MapColor.CRIMSON_STEM, ExDeorum.ID, false);
|
||||||
|
|
@ -171,6 +183,16 @@ public class DefaultMaterials {
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static CompressedSieveMaterial addDefaultCompressedSieve(String name, SoundType soundType, String requiredModID) {
|
||||||
|
return addDefaultCompressedSieve(name, soundType, 2.0f, false, requiredModID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompressedSieveMaterial addDefaultCompressedSieve(String name, SoundType soundType, float strength, boolean needsCorrectTool, String requiredModId) {
|
||||||
|
var material = new CompressedSieveMaterial(soundType, strength, needsCorrectTool, requiredModId);
|
||||||
|
COMPRESSED_SIEVES.register(name, material);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
private static LavaCrucibleMaterial addDefaultLavaCrucible(String name, SoundType soundType, float strength, boolean needsCorrectTool, MapColor color, String requiredModId, boolean transparent) {
|
private static LavaCrucibleMaterial addDefaultLavaCrucible(String name, SoundType soundType, float strength, boolean needsCorrectTool, MapColor color, String requiredModId, boolean transparent) {
|
||||||
var material = new LavaCrucibleMaterial(soundType, strength, needsCorrectTool, color.id, requiredModId, transparent);
|
var material = new LavaCrucibleMaterial(soundType, strength, needsCorrectTool, color.id, requiredModId, transparent);
|
||||||
LAVA_CRUCIBLES.register(name, material);
|
LAVA_CRUCIBLES.register(name, material);
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ import thedarkcolour.exdeorum.recipe.cache.*;
|
||||||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||||
|
import thedarkcolour.exdeorum.recipe.sieve.CompressedSieveRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.ENumberProviders;
|
import thedarkcolour.exdeorum.registry.ENumberProviders;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
@ -86,7 +87,8 @@ public final class RecipeUtil {
|
||||||
private static SingleIngredientRecipeCache<CrucibleRecipe> lavaCrucibleRecipeCache;
|
private static SingleIngredientRecipeCache<CrucibleRecipe> lavaCrucibleRecipeCache;
|
||||||
private static SingleIngredientRecipeCache<CrucibleRecipe> waterCrucibleRecipeCache;
|
private static SingleIngredientRecipeCache<CrucibleRecipe> waterCrucibleRecipeCache;
|
||||||
private static SingleIngredientRecipeCache<HammerRecipe> hammerRecipeCache;
|
private static SingleIngredientRecipeCache<HammerRecipe> hammerRecipeCache;
|
||||||
private static SieveRecipeCache sieveRecipeCache;
|
private static SieveRecipeCache<SieveRecipe> sieveRecipeCache;
|
||||||
|
private static SieveRecipeCache<CompressedSieveRecipe> compressedSieveRecipeCache;
|
||||||
private static BarrelFluidMixingRecipeCache barrelFluidMixingRecipeCache;
|
private static BarrelFluidMixingRecipeCache barrelFluidMixingRecipeCache;
|
||||||
private static FluidTransformationRecipeCache fluidTransformationRecipeCache;
|
private static FluidTransformationRecipeCache fluidTransformationRecipeCache;
|
||||||
private static CrookRecipeCache crookRecipeCache;
|
private static CrookRecipeCache crookRecipeCache;
|
||||||
|
|
@ -97,7 +99,8 @@ public final class RecipeUtil {
|
||||||
lavaCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.LAVA_CRUCIBLE);
|
lavaCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.LAVA_CRUCIBLE);
|
||||||
waterCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.WATER_CRUCIBLE);
|
waterCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.WATER_CRUCIBLE);
|
||||||
hammerRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.HAMMER).trackAllRecipes();
|
hammerRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.HAMMER).trackAllRecipes();
|
||||||
sieveRecipeCache = new SieveRecipeCache(recipes);
|
sieveRecipeCache = new SieveRecipeCache<>(recipes, ERecipeTypes.SIEVE);
|
||||||
|
compressedSieveRecipeCache = new SieveRecipeCache<>(recipes, ERecipeTypes.COMPRESSED_SIEVE);
|
||||||
barrelFluidMixingRecipeCache = new BarrelFluidMixingRecipeCache(recipes);
|
barrelFluidMixingRecipeCache = new BarrelFluidMixingRecipeCache(recipes);
|
||||||
fluidTransformationRecipeCache = new FluidTransformationRecipeCache(recipes);
|
fluidTransformationRecipeCache = new FluidTransformationRecipeCache(recipes);
|
||||||
crookRecipeCache = new CrookRecipeCache(recipes);
|
crookRecipeCache = new CrookRecipeCache(recipes);
|
||||||
|
|
@ -121,6 +124,10 @@ public final class RecipeUtil {
|
||||||
return sieveRecipeCache.getRecipe(mesh, item);
|
return sieveRecipeCache.getRecipe(mesh, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<CompressedSieveRecipe> getCompressedSieveRecipes(Item mesh, ItemStack item) {
|
||||||
|
return compressedSieveRecipeCache.getRecipe(mesh, item);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static CrucibleRecipe getLavaCrucibleRecipe(ItemStack item) {
|
public static CrucibleRecipe getLavaCrucibleRecipe(ItemStack item) {
|
||||||
return lavaCrucibleRecipeCache.getRecipe(item);
|
return lavaCrucibleRecipeCache.getRecipe(item);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.RecipeManager;
|
import net.minecraft.world.item.crafting.RecipeManager;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
@ -30,17 +31,20 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class SieveRecipeCache {
|
public class SieveRecipeCache<T extends SieveRecipe> {
|
||||||
private RecipeManager recipeManager;
|
private RecipeManager recipeManager;
|
||||||
|
private final Supplier<? extends RecipeType<T>> recipeType;
|
||||||
@Nullable
|
@Nullable
|
||||||
private Map<Item, MeshRecipeCache> meshCaches;
|
private Map<Item, MeshRecipeCache<T>> meshCaches;
|
||||||
|
|
||||||
public SieveRecipeCache(RecipeManager recipeManager) {
|
public SieveRecipeCache(RecipeManager recipeManager, Supplier<? extends RecipeType<T>> recipeType) {
|
||||||
this.recipeManager = recipeManager;
|
this.recipeManager = recipeManager;
|
||||||
|
this.recipeType = recipeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SieveRecipe> getRecipe(Item mesh, ItemStack input) {
|
public List<T> getRecipe(Item mesh, ItemStack input) {
|
||||||
if (this.meshCaches == null) {
|
if (this.meshCaches == null) {
|
||||||
buildRecipes();
|
buildRecipes();
|
||||||
}
|
}
|
||||||
|
|
@ -50,13 +54,13 @@ public class SieveRecipeCache {
|
||||||
|
|
||||||
private void buildRecipes() {
|
private void buildRecipes() {
|
||||||
// Group recipes based on their mesh
|
// Group recipes based on their mesh
|
||||||
var tempMap = new HashMap<Item, List<SieveRecipe>>();
|
var tempMap = new HashMap<Item, List<T>>();
|
||||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.SIEVE.get()).values()) {
|
for (var recipe : this.recipeManager.byType(this.recipeType.get()).values()) {
|
||||||
tempMap.computeIfAbsent(recipe.mesh, k -> new ArrayList<>()).add(recipe);
|
tempMap.computeIfAbsent(recipe.mesh, k -> new ArrayList<>()).add(recipe);
|
||||||
}
|
}
|
||||||
this.meshCaches = new HashMap<>();
|
this.meshCaches = new HashMap<>();
|
||||||
for (var mesh : tempMap.entrySet()) {
|
for (var mesh : tempMap.entrySet()) {
|
||||||
this.meshCaches.put(mesh.getKey(), new MeshRecipeCache(mesh.getValue()));
|
this.meshCaches.put(mesh.getKey(), new MeshRecipeCache<>(mesh.getValue()));
|
||||||
}
|
}
|
||||||
this.recipeManager = null;
|
this.recipeManager = null;
|
||||||
}
|
}
|
||||||
|
|
@ -66,12 +70,12 @@ public class SieveRecipeCache {
|
||||||
// conveying this information in JEI would be difficult (ex. Bottle drops from Sand, but only if the Sand has a
|
// conveying this information in JEI would be difficult (ex. Bottle drops from Sand, but only if the Sand has a
|
||||||
// certain enchantment). Thirdly, I do not see anybody needing this use case, and if they do, they should contact
|
// certain enchantment). Thirdly, I do not see anybody needing this use case, and if they do, they should contact
|
||||||
// me on GitHub or Discord so that I can get around to actually implementing it.
|
// me on GitHub or Discord so that I can get around to actually implementing it.
|
||||||
private static class MeshRecipeCache {
|
private static class MeshRecipeCache<T extends SieveRecipe> {
|
||||||
private final Map<Item, List<SieveRecipe>> simpleRecipes;
|
private final Map<Item, List<T>> simpleRecipes;
|
||||||
|
|
||||||
private MeshRecipeCache(List<SieveRecipe> recipes) {
|
private MeshRecipeCache(List<T> recipes) {
|
||||||
this.simpleRecipes = new HashMap<>();
|
this.simpleRecipes = new HashMap<>();
|
||||||
var temp = new HashMap<Item, ImmutableList.Builder<SieveRecipe>>();
|
var temp = new HashMap<Item, ImmutableList.Builder<T>>();
|
||||||
|
|
||||||
for (var recipe : recipes) {
|
for (var recipe : recipes) {
|
||||||
for (var item : recipe.ingredient.getItems()) {
|
for (var item : recipe.ingredient.getItems()) {
|
||||||
|
|
@ -84,7 +88,7 @@ public class SieveRecipeCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SieveRecipe> getRecipes(ItemStack input) {
|
public List<T> getRecipes(ItemStack input) {
|
||||||
var result = this.simpleRecipes.get(input.getItem());
|
var result = this.simpleRecipes.get(input.getItem());
|
||||||
return result == null ? List.of() : result;
|
return result == null ? List.of() : result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.recipe.sieve;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
|
public class CompressedSieveRecipe extends SieveRecipe {
|
||||||
|
public CompressedSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly) {
|
||||||
|
super(id, ingredient, mesh, result, resultAmount, byHandOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getSerializer() {
|
||||||
|
return ERecipeSerializers.COMPRESSED_SIEVE.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeType<?> getType() {
|
||||||
|
return ERecipeTypes.COMPRESSED_SIEVE.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Serializer extends SieveRecipe.AbstractSerializer<CompressedSieveRecipe> {
|
||||||
|
@Override
|
||||||
|
protected CompressedSieveRecipe createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly) {
|
||||||
|
return new CompressedSieveRecipe(id, ingredient, mesh, result, resultAmount, byHandOnly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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.recipe.sieve;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
|
|
||||||
|
public class FinishedCompressedSieveRecipe extends FinishedSieveRecipe{
|
||||||
|
public FinishedCompressedSieveRecipe(ResourceLocation id, Item mesh, Ingredient ingredient, Item result, NumberProvider resultAmount) {
|
||||||
|
super(id, mesh, ingredient, result, resultAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getType() {
|
||||||
|
return ERecipeSerializers.COMPRESSED_SIEVE.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,10 +19,8 @@
|
||||||
package thedarkcolour.exdeorum.recipe.sieve;
|
package thedarkcolour.exdeorum.recipe.sieve;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.mojang.datafixers.util.Either;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.TagKey;
|
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
|
@ -34,10 +32,10 @@ import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
public class FinishedSieveRecipe extends EFinishedRecipe {
|
public class FinishedSieveRecipe extends EFinishedRecipe {
|
||||||
private final Ingredient ingredient;
|
private final Ingredient ingredient;
|
||||||
private final Item mesh;
|
private final Item mesh;
|
||||||
private final Either<Item, TagKey<Item>> result;
|
private final Item result;
|
||||||
private final NumberProvider resultAmount;
|
private final NumberProvider resultAmount;
|
||||||
|
|
||||||
public FinishedSieveRecipe(ResourceLocation id, Item mesh, Ingredient ingredient, Either<Item, TagKey<Item>> result, NumberProvider resultAmount) {
|
public FinishedSieveRecipe(ResourceLocation id, Item mesh, Ingredient ingredient, Item result, NumberProvider resultAmount) {
|
||||||
super(id);
|
super(id);
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
this.ingredient = ingredient;
|
this.ingredient = ingredient;
|
||||||
|
|
@ -45,15 +43,12 @@ public class FinishedSieveRecipe extends EFinishedRecipe {
|
||||||
this.resultAmount = resultAmount;
|
this.resultAmount = resultAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void serializeRecipeData(JsonObject object) {
|
public void serializeRecipeData(JsonObject object) {
|
||||||
object.add("ingredient", this.ingredient.toJson());
|
object.add("ingredient", this.ingredient.toJson());
|
||||||
object.addProperty("mesh", BuiltInRegistries.ITEM.getKey(this.mesh).toString());
|
object.addProperty("mesh", BuiltInRegistries.ITEM.getKey(this.mesh).toString());
|
||||||
this.result.ifLeft(item -> {
|
object.addProperty("result", BuiltInRegistries.ITEM.getKey(this.result).toString());
|
||||||
object.addProperty("result", BuiltInRegistries.ITEM.getKey(item).toString());
|
|
||||||
}).ifRight(tag -> {
|
|
||||||
object.addProperty("result_tag", tag.location().toString());
|
|
||||||
});
|
|
||||||
object.add("result_amount", LootDataType.PREDICATE.parser().toJsonTree(this.resultAmount));
|
object.add("result_amount", LootDataType.PREDICATE.parser().toJsonTree(this.resultAmount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,11 +63,11 @@ public class SieveRecipe extends ProbabilityRecipe {
|
||||||
return ERecipeTypes.SIEVE.get();
|
return ERecipeTypes.SIEVE.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class AbstractSerializer implements RecipeSerializer<SieveRecipe> {
|
public static abstract class AbstractSerializer<T extends SieveRecipe> implements RecipeSerializer<T> {
|
||||||
protected abstract SieveRecipe createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly);
|
protected abstract T createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SieveRecipe fromJson(ResourceLocation id, JsonObject json) {
|
public T fromJson(ResourceLocation id, JsonObject json) {
|
||||||
Ingredient ingredient = RecipeUtil.readIngredient(json, "ingredient");
|
Ingredient ingredient = RecipeUtil.readIngredient(json, "ingredient");
|
||||||
Item mesh = RecipeUtil.readItem(json, "mesh");
|
Item mesh = RecipeUtil.readItem(json, "mesh");
|
||||||
Item result;
|
Item result;
|
||||||
|
|
@ -93,7 +93,7 @@ public class SieveRecipe extends ProbabilityRecipe {
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public @Nullable SieveRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
public @Nullable T fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||||
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
||||||
Item mesh = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
Item mesh = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
||||||
Item result = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
Item result = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
||||||
|
|
@ -103,7 +103,7 @@ public class SieveRecipe extends ProbabilityRecipe {
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void toNetwork(FriendlyByteBuf buffer, SieveRecipe recipe) {
|
public void toNetwork(FriendlyByteBuf buffer, T recipe) {
|
||||||
recipe.getIngredient().toNetwork(buffer);
|
recipe.getIngredient().toNetwork(buffer);
|
||||||
buffer.writeId(BuiltInRegistries.ITEM, recipe.mesh);
|
buffer.writeId(BuiltInRegistries.ITEM, recipe.mesh);
|
||||||
buffer.writeId(BuiltInRegistries.ITEM, recipe.result);
|
buffer.writeId(BuiltInRegistries.ITEM, recipe.result);
|
||||||
|
|
@ -112,7 +112,7 @@ public class SieveRecipe extends ProbabilityRecipe {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Serializer extends AbstractSerializer {
|
public static class Serializer extends AbstractSerializer<SieveRecipe> {
|
||||||
@Override
|
@Override
|
||||||
protected SieveRecipe createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly) {
|
protected SieveRecipe createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly) {
|
||||||
return new SieveRecipe(id, ingredient, mesh, result, resultAmount, byHandOnly);
|
return new SieveRecipe(id, ingredient, mesh, result, resultAmount, byHandOnly);
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ public class EBlockEntities {
|
||||||
public static final RegistryObject<BlockEntityType<WaterCrucibleBlockEntity>> WATER_CRUCIBLE = BLOCK_ENTITIES.register("water_crucible", () -> DefaultMaterials.WATER_CRUCIBLES.createBlockEntityType(WaterCrucibleBlockEntity::new));
|
public static final RegistryObject<BlockEntityType<WaterCrucibleBlockEntity>> WATER_CRUCIBLE = BLOCK_ENTITIES.register("water_crucible", () -> DefaultMaterials.WATER_CRUCIBLES.createBlockEntityType(WaterCrucibleBlockEntity::new));
|
||||||
public static final RegistryObject<BlockEntityType<BarrelBlockEntity>> BARREL = BLOCK_ENTITIES.register("barrel", () -> DefaultMaterials.BARRELS.createBlockEntityType(BarrelBlockEntity::new));
|
public static final RegistryObject<BlockEntityType<BarrelBlockEntity>> BARREL = BLOCK_ENTITIES.register("barrel", () -> DefaultMaterials.BARRELS.createBlockEntityType(BarrelBlockEntity::new));
|
||||||
public static final RegistryObject<BlockEntityType<SieveBlockEntity>> SIEVE = BLOCK_ENTITIES.register("sieve", () -> DefaultMaterials.SIEVES.createBlockEntityType(SieveBlockEntity::new));
|
public static final RegistryObject<BlockEntityType<SieveBlockEntity>> SIEVE = BLOCK_ENTITIES.register("sieve", () -> DefaultMaterials.SIEVES.createBlockEntityType(SieveBlockEntity::new));
|
||||||
|
public static final RegistryObject<BlockEntityType<CompressedSieveBlockEntity>> COMPRESSED_SIEVE = BLOCK_ENTITIES.register("compressed_sieve", () -> DefaultMaterials.COMPRESSED_SIEVES.createBlockEntityType(CompressedSieveBlockEntity::new));
|
||||||
public static final RegistryObject<BlockEntityType<MechanicalSieveBlockEntity>> MECHANICAL_SIEVE = BLOCK_ENTITIES.register("mechanical_sieve", () -> BlockEntityType.Builder.of(MechanicalSieveBlockEntity::new, EBlocks.MECHANICAL_SIEVE.get()).build(null));
|
public static final RegistryObject<BlockEntityType<MechanicalSieveBlockEntity>> MECHANICAL_SIEVE = BLOCK_ENTITIES.register("mechanical_sieve", () -> BlockEntityType.Builder.of(MechanicalSieveBlockEntity::new, EBlocks.MECHANICAL_SIEVE.get()).build(null));
|
||||||
public static final RegistryObject<BlockEntityType<MechanicalHammerBlockEntity>> MECHANICAL_HAMMER = BLOCK_ENTITIES.register("mechanical_hammer", () -> BlockEntityType.Builder.of(MechanicalHammerBlockEntity::new, EBlocks.MECHANICAL_HAMMER.get()).build(null));
|
public static final RegistryObject<BlockEntityType<MechanicalHammerBlockEntity>> MECHANICAL_HAMMER = BLOCK_ENTITIES.register("mechanical_hammer", () -> BlockEntityType.Builder.of(MechanicalHammerBlockEntity::new, EBlocks.MECHANICAL_HAMMER.get()).build(null));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleHeatRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleHeatRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||||
|
import thedarkcolour.exdeorum.recipe.sieve.CompressedSieveRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
|
|
||||||
public class ERecipeSerializers {
|
public class ERecipeSerializers {
|
||||||
|
|
@ -50,6 +51,7 @@ public class ERecipeSerializers {
|
||||||
public static final RegistryObject<RecipeSerializer<CrucibleRecipe>> WATER_CRUCIBLE = RECIPE_SERIALIZERS.register("water_crucible", () -> new CrucibleRecipe.Serializer(ERecipeTypes.WATER_CRUCIBLE.get()));
|
public static final RegistryObject<RecipeSerializer<CrucibleRecipe>> WATER_CRUCIBLE = RECIPE_SERIALIZERS.register("water_crucible", () -> new CrucibleRecipe.Serializer(ERecipeTypes.WATER_CRUCIBLE.get()));
|
||||||
|
|
||||||
public static final RegistryObject<RecipeSerializer<SieveRecipe>> SIEVE = RECIPE_SERIALIZERS.register("sieve", SieveRecipe.Serializer::new);
|
public static final RegistryObject<RecipeSerializer<SieveRecipe>> SIEVE = RECIPE_SERIALIZERS.register("sieve", SieveRecipe.Serializer::new);
|
||||||
|
public static final RegistryObject<RecipeSerializer<CompressedSieveRecipe>> COMPRESSED_SIEVE = RECIPE_SERIALIZERS.register("compressed_sieve", CompressedSieveRecipe.Serializer::new);
|
||||||
|
|
||||||
public static final RegistryObject<RecipeSerializer<?>> TAG_RESULT = RECIPE_SERIALIZERS.register("tag_result", TagResultRecipe.Serializer::new);
|
public static final RegistryObject<RecipeSerializer<?>> TAG_RESULT = RECIPE_SERIALIZERS.register("tag_result", TagResultRecipe.Serializer::new);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleHeatRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleHeatRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||||
|
import thedarkcolour.exdeorum.recipe.sieve.CompressedSieveRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
|
|
||||||
public class ERecipeTypes {
|
public class ERecipeTypes {
|
||||||
|
|
@ -49,4 +50,5 @@ public class ERecipeTypes {
|
||||||
public static final RegistryObject<RecipeType<CrucibleHeatRecipe>> CRUCIBLE_HEAT_SOURCE = RECIPE_TYPES.register("crucible_heat_source", () -> RecipeType.simple(ERecipeTypes.CRUCIBLE_HEAT_SOURCE.getId()));
|
public static final RegistryObject<RecipeType<CrucibleHeatRecipe>> CRUCIBLE_HEAT_SOURCE = RECIPE_TYPES.register("crucible_heat_source", () -> RecipeType.simple(ERecipeTypes.CRUCIBLE_HEAT_SOURCE.getId()));
|
||||||
|
|
||||||
public static final RegistryObject<RecipeType<SieveRecipe>> SIEVE = RECIPE_TYPES.register("sieve", () -> RecipeType.simple(ERecipeTypes.SIEVE.getId()));
|
public static final RegistryObject<RecipeType<SieveRecipe>> SIEVE = RECIPE_TYPES.register("sieve", () -> RecipeType.simple(ERecipeTypes.SIEVE.getId()));
|
||||||
|
public static final RegistryObject<RecipeType<CompressedSieveRecipe>> COMPRESSED_SIEVE = RECIPE_TYPES.register("compressed_sieve", () -> RecipeType.simple(ERecipeTypes.COMPRESSED_SIEVE.getId()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user