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.Level;
|
||||
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.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
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.registry.EBlockEntities;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SieveBlock extends EBlock {
|
||||
public static final VoxelShape SHAPE = Shapes.or(
|
||||
box(0, 11, 0, 16, 16, 16),
|
||||
|
|
@ -42,14 +47,13 @@ public class SieveBlock extends EBlock {
|
|||
super(properties, EBlockEntities.SIEVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return SHAPE;
|
||||
protected SieveBlock(Properties properties, Supplier<? extends BlockEntityType<?>> blockEntityType) {
|
||||
super(properties, blockEntityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new SieveBlockEntity(pos, state);
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,19 +22,29 @@ import net.minecraft.core.BlockPos;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
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.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class AbstractSieveBlockEntity extends EBlockEntity implements SieveLogic.Owner {
|
||||
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);
|
||||
|
||||
this.sieveInterval = sieveInterval;
|
||||
this.logic = logic.apply(this);
|
||||
}
|
||||
|
||||
|
|
@ -44,6 +54,16 @@ public abstract class AbstractSieveBlockEntity extends EBlockEntity implements S
|
|||
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
|
||||
public ServerLevel getServerLevel() {
|
||||
return (ServerLevel) this.level;
|
||||
|
|
@ -81,4 +101,143 @@ public abstract class AbstractSieveBlockEntity extends EBlockEntity implements S
|
|||
this.logic.setProgress(buffer.readFloat());
|
||||
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) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -19,16 +19,7 @@
|
|||
package thedarkcolour.exdeorum.blockentity;
|
||||
|
||||
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.minecraftforge.common.util.FakePlayer;
|
||||
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||
|
|
@ -37,140 +28,11 @@ public class SieveBlockEntity extends AbstractSieveBlockEntity {
|
|||
public static final float SIEVE_INTERVAL = 0.1f;
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
protected boolean canUseSimultaneously() {
|
||||
return EConfig.SERVER.simultaneousSieveUsage.get();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.tag.EItemTags;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SieveLogic {
|
||||
private final Owner owner;
|
||||
private final boolean saveMesh;
|
||||
private final boolean mechanical;
|
||||
|
||||
// block currently being sifted
|
||||
private ItemStack contents = ItemStack.EMPTY;
|
||||
// mesh
|
||||
private ItemStack mesh = ItemStack.EMPTY;
|
||||
protected ItemStack mesh = ItemStack.EMPTY;
|
||||
// from 0.0 to 1.0
|
||||
private float progress;
|
||||
private float efficiency;
|
||||
|
|
@ -48,9 +49,8 @@ public class SieveLogic {
|
|||
private long lastTime = 0;
|
||||
private final long minInterval;
|
||||
|
||||
public SieveLogic(Owner owner, boolean saveMesh, boolean mechanical) {
|
||||
public SieveLogic(Owner owner, boolean mechanical) {
|
||||
this.owner = owner;
|
||||
this.saveMesh = saveMesh;
|
||||
this.mechanical = mechanical;
|
||||
this.minInterval = EConfig.SERVER.sieveIntervalTicks.get();
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ public class SieveLogic {
|
|||
}
|
||||
|
||||
public boolean isValidInput(ItemStack stack) {
|
||||
return !RecipeUtil.getSieveRecipes(this.mesh.getItem(), stack).isEmpty();
|
||||
return !getDropsFor(stack).isEmpty();
|
||||
}
|
||||
|
||||
public boolean isValidMesh(ItemStack stack) {
|
||||
|
|
@ -91,7 +91,7 @@ public class SieveLogic {
|
|||
var handledAnyDrops = 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);
|
||||
|
||||
// Split overflowing stacks (64+) into multiple stacks
|
||||
|
|
@ -124,6 +124,10 @@ public class SieveLogic {
|
|||
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) {
|
||||
if (recipe.byHandOnly && this.mechanical) return 0;
|
||||
|
||||
|
|
@ -160,7 +164,7 @@ public class SieveLogic {
|
|||
if (!this.contents.isEmpty()) {
|
||||
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.putFloat("progress", this.progress);
|
||||
|
|
@ -177,7 +181,7 @@ public class SieveLogic {
|
|||
} else {
|
||||
this.progress = nbt.getFloat("progress");
|
||||
}
|
||||
if (this.saveMesh) {
|
||||
if (!this.mechanical) {
|
||||
if (nbt.contains("mesh")) {
|
||||
setMesh(ItemStack.of(nbt.getCompound("mesh")), false);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -45,10 +45,7 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
|||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
||||
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
||||
import thedarkcolour.exdeorum.client.ter.BarrelRenderer;
|
||||
import thedarkcolour.exdeorum.client.ter.CrucibleRenderer;
|
||||
import thedarkcolour.exdeorum.client.ter.InfestedLeavesRenderer;
|
||||
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
||||
import thedarkcolour.exdeorum.client.ter.*;
|
||||
import thedarkcolour.exdeorum.compat.ModIds;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.network.ClientMessageHandler;
|
||||
|
|
@ -136,8 +133,9 @@ public class ClientHandler {
|
|||
event.registerBlockEntityRenderer(EBlockEntities.BARREL.get(), BarrelRenderer::new);
|
||||
event.registerBlockEntityRenderer(EBlockEntities.LAVA_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.MECHANICAL_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<>(0.75f, 15f));
|
||||
event.registerBlockEntityRenderer(EBlockEntities.COMPRESSED_SIEVE.get(), ctx -> new CompressedSieveRenderer<>(0.5625f, 16f));
|
||||
}
|
||||
|
||||
private static void registerShaders(RegisterShadersEvent event) {
|
||||
|
|
|
|||
|
|
@ -19,18 +19,17 @@
|
|||
package thedarkcolour.exdeorum.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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);
|
||||
|
||||
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 {
|
||||
public Single(RenderType renderType, TextureAtlasSprite 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) {
|
||||
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 {
|
||||
public Composite(List<Pair<RenderType, TextureAtlasSprite>> layers) {
|
||||
record Composite(CompositeLayer[] layers, boolean isMissingTexture) implements RenderFace {
|
||||
public Composite(CompositeLayer[] layers) {
|
||||
this(layers, areAnyMissing(layers));
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {
|
||||
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) {
|
||||
if (RenderUtil.isMissingTexture(layer.second())) {
|
||||
if (RenderUtil.isMissingTexture(layer.sprite)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -64,4 +75,6 @@ public interface RenderFace {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
record CompositeLayer(RenderType renderType, TextureAtlasSprite sprite) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,25 +18,20 @@
|
|||
|
||||
package thedarkcolour.exdeorum.client;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
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.*;
|
||||
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
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.model.CompositeModel;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import org.joml.Vector3f;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
||||
|
|
@ -117,14 +111,15 @@ public class RenderUtil {
|
|||
if (model instanceof CompositeModel.Baked composite) {
|
||||
@SuppressWarnings("unchecked")
|
||||
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()) {
|
||||
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 {
|
||||
face = getFaceFromModel(block, rand, model);
|
||||
}
|
||||
|
|
@ -147,7 +142,7 @@ public class RenderUtil {
|
|||
}
|
||||
|
||||
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/"));
|
||||
// for stuff like azalea bush, retry to get the top texture
|
||||
if (isMissingTexture(sprite)) {
|
||||
|
|
@ -209,6 +204,10 @@ public class RenderUtil {
|
|||
//vMin = sprite.getV0();
|
||||
//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
|
||||
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();
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
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 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
|
||||
public void render(T sieve, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
|
||||
var logic = sieve.getLogic();
|
||||
|
|
@ -46,7 +57,12 @@ public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements
|
|||
var block = blockItem.getBlock();
|
||||
var percentage = logic.getProgress();
|
||||
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();
|
||||
|
|
@ -66,11 +82,16 @@ public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements
|
|||
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()) {
|
||||
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 static final MaterialRegistry<BarrelMaterial> BARRELS = new MaterialRegistry<>("barrel");
|
||||
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> 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 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
|
||||
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);
|
||||
|
|
@ -171,6 +183,16 @@ public class DefaultMaterials {
|
|||
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) {
|
||||
var material = new LavaCrucibleMaterial(soundType, strength, needsCorrectTool, color.id, requiredModId, transparent);
|
||||
LAVA_CRUCIBLES.register(name, material);
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import thedarkcolour.exdeorum.recipe.cache.*;
|
|||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.CompressedSieveRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||
import thedarkcolour.exdeorum.registry.ENumberProviders;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
|
@ -86,7 +87,8 @@ public final class RecipeUtil {
|
|||
private static SingleIngredientRecipeCache<CrucibleRecipe> lavaCrucibleRecipeCache;
|
||||
private static SingleIngredientRecipeCache<CrucibleRecipe> waterCrucibleRecipeCache;
|
||||
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 FluidTransformationRecipeCache fluidTransformationRecipeCache;
|
||||
private static CrookRecipeCache crookRecipeCache;
|
||||
|
|
@ -97,7 +99,8 @@ public final class RecipeUtil {
|
|||
lavaCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.LAVA_CRUCIBLE);
|
||||
waterCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.WATER_CRUCIBLE);
|
||||
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);
|
||||
fluidTransformationRecipeCache = new FluidTransformationRecipeCache(recipes);
|
||||
crookRecipeCache = new CrookRecipeCache(recipes);
|
||||
|
|
@ -121,6 +124,10 @@ public final class RecipeUtil {
|
|||
return sieveRecipeCache.getRecipe(mesh, item);
|
||||
}
|
||||
|
||||
public static List<CompressedSieveRecipe> getCompressedSieveRecipes(Item mesh, ItemStack item) {
|
||||
return compressedSieveRecipeCache.getRecipe(mesh, item);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CrucibleRecipe getLavaCrucibleRecipe(ItemStack 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.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
|
@ -30,17 +31,20 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SieveRecipeCache {
|
||||
public class SieveRecipeCache<T extends SieveRecipe> {
|
||||
private RecipeManager recipeManager;
|
||||
private final Supplier<? extends RecipeType<T>> recipeType;
|
||||
@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.recipeType = recipeType;
|
||||
}
|
||||
|
||||
public List<SieveRecipe> getRecipe(Item mesh, ItemStack input) {
|
||||
public List<T> getRecipe(Item mesh, ItemStack input) {
|
||||
if (this.meshCaches == null) {
|
||||
buildRecipes();
|
||||
}
|
||||
|
|
@ -50,13 +54,13 @@ public class SieveRecipeCache {
|
|||
|
||||
private void buildRecipes() {
|
||||
// Group recipes based on their mesh
|
||||
var tempMap = new HashMap<Item, List<SieveRecipe>>();
|
||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.SIEVE.get()).values()) {
|
||||
var tempMap = new HashMap<Item, List<T>>();
|
||||
for (var recipe : this.recipeManager.byType(this.recipeType.get()).values()) {
|
||||
tempMap.computeIfAbsent(recipe.mesh, k -> new ArrayList<>()).add(recipe);
|
||||
}
|
||||
this.meshCaches = new HashMap<>();
|
||||
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;
|
||||
}
|
||||
|
|
@ -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
|
||||
// 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.
|
||||
private static class MeshRecipeCache {
|
||||
private final Map<Item, List<SieveRecipe>> simpleRecipes;
|
||||
private static class MeshRecipeCache<T extends SieveRecipe> {
|
||||
private final Map<Item, List<T>> simpleRecipes;
|
||||
|
||||
private MeshRecipeCache(List<SieveRecipe> recipes) {
|
||||
private MeshRecipeCache(List<T> recipes) {
|
||||
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 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());
|
||||
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;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
|
|
@ -34,10 +32,10 @@ import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|||
public class FinishedSieveRecipe extends EFinishedRecipe {
|
||||
private final Ingredient ingredient;
|
||||
private final Item mesh;
|
||||
private final Either<Item, TagKey<Item>> result;
|
||||
private final Item result;
|
||||
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);
|
||||
this.mesh = mesh;
|
||||
this.ingredient = ingredient;
|
||||
|
|
@ -45,15 +43,12 @@ public class FinishedSieveRecipe extends EFinishedRecipe {
|
|||
this.resultAmount = resultAmount;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void serializeRecipeData(JsonObject object) {
|
||||
object.add("ingredient", this.ingredient.toJson());
|
||||
object.addProperty("mesh", BuiltInRegistries.ITEM.getKey(this.mesh).toString());
|
||||
this.result.ifLeft(item -> {
|
||||
object.addProperty("result", BuiltInRegistries.ITEM.getKey(item).toString());
|
||||
}).ifRight(tag -> {
|
||||
object.addProperty("result_tag", tag.location().toString());
|
||||
});
|
||||
object.addProperty("result", BuiltInRegistries.ITEM.getKey(this.result).toString());
|
||||
object.add("result_amount", LootDataType.PREDICATE.parser().toJsonTree(this.resultAmount));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,11 +63,11 @@ public class SieveRecipe extends ProbabilityRecipe {
|
|||
return ERecipeTypes.SIEVE.get();
|
||||
}
|
||||
|
||||
public static abstract class AbstractSerializer implements RecipeSerializer<SieveRecipe> {
|
||||
protected abstract SieveRecipe createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly);
|
||||
public static abstract class AbstractSerializer<T extends SieveRecipe> implements RecipeSerializer<T> {
|
||||
protected abstract T createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean byHandOnly);
|
||||
|
||||
@Override
|
||||
public SieveRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
public T fromJson(ResourceLocation id, JsonObject json) {
|
||||
Ingredient ingredient = RecipeUtil.readIngredient(json, "ingredient");
|
||||
Item mesh = RecipeUtil.readItem(json, "mesh");
|
||||
Item result;
|
||||
|
|
@ -93,7 +93,7 @@ public class SieveRecipe extends ProbabilityRecipe {
|
|||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public @Nullable SieveRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
public @Nullable T fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
||||
Item mesh = 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")
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, SieveRecipe recipe) {
|
||||
public void toNetwork(FriendlyByteBuf buffer, T recipe) {
|
||||
recipe.getIngredient().toNetwork(buffer);
|
||||
buffer.writeId(BuiltInRegistries.ITEM, recipe.mesh);
|
||||
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
|
||||
protected SieveRecipe createSieveRecipe(ResourceLocation id, Ingredient ingredient, Item mesh, Item result, NumberProvider resultAmount, boolean 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<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<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<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.CrucibleRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.CompressedSieveRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||
|
||||
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<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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
|||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleHeatRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.CompressedSieveRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||
|
||||
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<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