From aa66440e8c91d0c9383217e88360830dc9748deb Mon Sep 17 00:00:00 2001 From: thedarkcolour <30441001+thedarkcolour@users.noreply.github.com> Date: Sat, 13 Jan 2024 11:06:53 -0800 Subject: [PATCH 1/7] Fixed mechanical sieve energy storage config option being ignored --- .../exdeorum/blockentity/MechanicalSieveBlockEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java index cfec52a1..3fdbca2e 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java @@ -75,7 +75,7 @@ public class MechanicalSieveBlockEntity extends AbstractSieveBlockEntity impleme super(EBlockEntities.MECHANICAL_SIEVE.get(), pos, state, owner -> new SieveLogic(owner, false, true)); this.inventory = new ItemHandler(22); - this.energy = new EnergyHelper(40000); + this.energy = new EnergyHelper(EConfig.SERVER.mechanicalSieveEnergyStorage.get()); this.capabilityInventory = LazyOptional.of(() -> this.inventory); this.capabilityEnergy = LazyOptional.of(() -> this.energy); From a56025fcc644e8f67782971878c9b4c53b188fef Mon Sep 17 00:00:00 2001 From: thedarkcolour <30441001+thedarkcolour@users.noreply.github.com> Date: Sat, 13 Jan 2024 21:40:07 -0800 Subject: [PATCH 2/7] Fully implemented the mechanical hammer in code --- .../exdeorum/block/MechanicalHammerBlock.java | 61 +++++ .../exdeorum/block/MechanicalSieveBlock.java | 4 +- .../exdeorum/block/SieveBlock.java | 2 +- .../AbstractMachineBlockEntity.java | 170 ++++++++++++ .../blockentity/AbstractSieveBlockEntity.java | 16 +- .../MechanicalHammerBlockEntity.java | 244 ++++++++++++++++++ .../blockentity/MechanicalHammerMenu.java | 116 +++++++++ .../MechanicalSieveBlockEntity.java | 157 +++-------- .../blockentity/logic/SieveLogic.java | 7 +- .../exdeorum/client/ClientHandler.java | 2 + .../client/screen/MechanicalHammerScreen.java | 94 +++++++ .../client/screen/MechanicalSieveScreen.java | 12 +- .../client/screen/RedstoneControlWidget.java | 12 +- .../exdeorum/client/ter/SieveRenderer.java | 17 +- .../compat/jei/ExDeorumJeiPlugin.java | 17 ++ .../compat/top/ExDeorumInfoProvider.java | 11 +- .../exdeorum/config/EConfig.java | 8 + .../thedarkcolour/exdeorum/data/English.java | 2 + .../exdeorum/data/TranslationKeys.java | 2 + .../exdeorum/loot/HammerLootModifier.java | 46 ++-- .../exdeorum/menu/AbstractMachineMenu.java | 121 +++++++++ .../exdeorum/menu/EContainerMenu.java | 31 --- .../exdeorum/menu/MechanicalSieveMenu.java | 87 +------ .../network/ClientMessageHandler.java | 4 +- .../exdeorum/recipe/RecipeUtil.java | 9 + .../exdeorum/recipe/sieve/SieveRecipe.java | 2 + .../exdeorum/registry/EBlockEntities.java | 2 + .../exdeorum/registry/EBlocks.java | 2 + .../exdeorum/registry/EItems.java | 2 + .../exdeorum/registry/EMenus.java | 2 + .../gui/container/mechanical_hammer.png | Bin 0 -> 3109 bytes .../textures/item/empty_slot_hammer.png | Bin 0 -> 2854 bytes 32 files changed, 974 insertions(+), 288 deletions(-) create mode 100644 src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java create mode 100644 src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java create mode 100644 src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java create mode 100644 src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerMenu.java create mode 100644 src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalHammerScreen.java create mode 100644 src/main/java/thedarkcolour/exdeorum/menu/AbstractMachineMenu.java delete mode 100644 src/main/java/thedarkcolour/exdeorum/menu/EContainerMenu.java create mode 100644 src/main/resources/assets/exdeorum/textures/gui/container/mechanical_hammer.png create mode 100644 src/main/resources/assets/exdeorum/textures/item/empty_slot_hammer.png diff --git a/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java new file mode 100644 index 00000000..08ac1d16 --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java @@ -0,0 +1,61 @@ +/* + * 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 . + */ + +package thedarkcolour.exdeorum.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; +import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity; +import thedarkcolour.exdeorum.registry.EBlockEntities; + +public class MechanicalHammerBlock extends EBlock { + public MechanicalHammerBlock(Properties properties) { + super(properties, EBlockEntities.MECHANICAL_HAMMER); + } + + @SuppressWarnings("unchecked") + @Nullable + @Override + public BlockEntityTicker getTicker(Level level, BlockState pState, BlockEntityType type) { + return type == EBlockEntities.MECHANICAL_HAMMER.get() && !level.isClientSide ? (BlockEntityTicker) new MechanicalHammerBlockEntity.ServerTicker<>() : null; + } + + // todo creative drop and tooltip + + @Override + public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { + if (!oldState.is(state.getBlock())) { + if (level.getBlockEntity(pos) instanceof MechanicalHammerBlockEntity hammer) { + hammer.checkPoweredState(level, pos); + } + } + } + + @Override + public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving) { + if (level.getBlockEntity(pos) instanceof MechanicalHammerBlockEntity hammer) { + hammer.checkPoweredState(level, pos); + } + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/block/MechanicalSieveBlock.java b/src/main/java/thedarkcolour/exdeorum/block/MechanicalSieveBlock.java index da3e56c3..48f7ca4f 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/MechanicalSieveBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/MechanicalSieveBlock.java @@ -69,7 +69,7 @@ public class MechanicalSieveBlock extends EBlock { @Nullable @Override public BlockEntityTicker getTicker(Level level, BlockState pState, BlockEntityType type) { - return type == EBlockEntities.MECHANICAL_SIEVE.get() && !level.isClientSide ? (BlockEntityTicker) new MechanicalSieveBlockEntity.ServerTicker() : null; + return type == EBlockEntities.MECHANICAL_SIEVE.get() && !level.isClientSide ? (BlockEntityTicker) new MechanicalSieveBlockEntity.ServerTicker<>() : null; } @Override @@ -93,7 +93,7 @@ public class MechanicalSieveBlock extends EBlock { public void playerWillDestroy(Level level, BlockPos pos, BlockState pState, Player player) { if (!level.isClientSide && player.isCreative() && level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { if (level.getBlockEntity(pos) instanceof MechanicalSieveBlockEntity sieve) { - if (!sieve.getMesh().isEmpty()) { + if (!sieve.getLogic().getMesh().isEmpty()) { var stack = new ItemStack(this); BlockItem.setBlockEntityData(stack, EBlockEntities.MECHANICAL_SIEVE.get(), sieve.saveWithoutMetadata()); var itemEntity = new ItemEntity(level, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, stack); diff --git a/src/main/java/thedarkcolour/exdeorum/block/SieveBlock.java b/src/main/java/thedarkcolour/exdeorum/block/SieveBlock.java index 37efda92..b85ca338 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/SieveBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/SieveBlock.java @@ -57,7 +57,7 @@ public class SieveBlock extends EBlock { if (!level.isClientSide) { if (!state.is(newState.getBlock())) { if (level.getBlockEntity(pos) instanceof SieveBlockEntity sieve) { - var mesh = sieve.getMesh(); + var mesh = sieve.getLogic().getMesh(); if (!mesh.isEmpty()) { dropItem(level, pos, mesh); diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java new file mode 100644 index 00000000..73072078 --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java @@ -0,0 +1,170 @@ +/* + * 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 . + */ + +package thedarkcolour.exdeorum.blockentity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.EnergyStorage; +import net.minecraftforge.network.NetworkHooks; +import thedarkcolour.exdeorum.blockentity.helper.EnergyHelper; +import thedarkcolour.exdeorum.blockentity.helper.ItemHelper; +import thedarkcolour.exdeorum.client.screen.RedstoneControlWidget; + +import javax.annotation.Nonnull; +import java.util.function.Function; + +public abstract class AbstractMachineBlockEntity> extends EBlockEntity implements MenuProvider { + public final ItemHelper inventory; + public final EnergyHelper energy; + protected int redstoneMode; + // not saved to NBT + protected boolean hasRedstonePower; + + private final LazyOptional capabilityInventory; + private final LazyOptional capabilityEnergy; + + @SuppressWarnings("unchecked") + public AbstractMachineBlockEntity(BlockEntityType type, BlockPos pos, BlockState state, Function inventory, int maxEnergy) { + super(type, pos, state); + + this.inventory = inventory.apply((M) this); + this.energy = new EnergyHelper(maxEnergy); + + this.capabilityInventory = LazyOptional.of(() -> this.inventory); + this.capabilityEnergy = LazyOptional.of(() -> this.energy); + } + + @Override + protected void saveAdditional(CompoundTag nbt) { + super.saveAdditional(nbt); + + nbt.put("inventory", this.inventory.serializeNBT()); + nbt.putInt("energy", this.energy.getEnergyStored()); + nbt.putInt("redstoneMode", this.redstoneMode); + } + + @Override + public void load(CompoundTag nbt) { + super.load(nbt); + + this.inventory.deserializeNBT(nbt.getCompound("inventory")); + this.energy.setStoredEnergy(nbt.getInt("energy")); + this.redstoneMode = Mth.clamp(nbt.getInt("redstoneMode"), 0, 2); + } + + @Override + public void onLoad() { + checkPoweredState(this.level, this.worldPosition); + } + + public void checkPoweredState(Level level, BlockPos pos) { + this.hasRedstonePower = level.hasNeighborSignal(pos); + } + + public void setRedstoneMode(int redstoneMode) { + this.redstoneMode = redstoneMode; + } + + public int getRedstoneMode() { + return this.redstoneMode; + } + + + @SuppressWarnings("NullableProblems") + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @javax.annotation.Nullable Direction side) { + if (cap == ForgeCapabilities.ENERGY) { + return this.capabilityEnergy.cast(); + } else if (cap == ForgeCapabilities.ITEM_HANDLER) { + return this.capabilityInventory.cast(); + } + + return super.getCapability(cap, side); + } + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + + this.capabilityEnergy.invalidate(); + this.capabilityInventory.invalidate(); + } + + @Override + public InteractionResult use(Level level, Player player, InteractionHand hand) { + if (player instanceof ServerPlayer serverPlayer) { + NetworkHooks.openScreen(serverPlayer, this, buffer -> { + buffer.writeBlockPos(getBlockPos()); + buffer.writeByte(this.redstoneMode); + }); + return InteractionResult.CONSUME; + } else { + return InteractionResult.SUCCESS; + } + } + + public boolean stillValid(Player player) { + if (this.level.getBlockEntity(this.worldPosition) != this) { + return false; + } else { + return player.distanceToSqr(this.worldPosition.getX() + 0.5, this.worldPosition.getY() + 0.5, this.worldPosition.getZ() + 0.5) <= 64.0; + } + } + protected abstract boolean isRunning(); + + protected abstract void tryStartRunning(); + + // Only called serverside + protected abstract void runMachineTick(); + + protected abstract int getEnergyConsumption(); + + public static class ServerTicker> implements BlockEntityTicker { + @Override + public void tick(Level level, BlockPos pos, BlockState state, M machine) { + if (machine.redstoneMode == RedstoneControlWidget.REDSTONE_MODE_IGNORED || ((machine.redstoneMode == RedstoneControlWidget.REDSTONE_MODE_UNPOWERED)) != machine.hasRedstonePower) { + var energyConsumption = machine.getEnergyConsumption(); + + if (machine.energy.getEnergyStored() >= energyConsumption) { + if (!machine.isRunning()) { + machine.tryStartRunning(); + } + if (machine.isRunning()) { + machine.energy.extractEnergy(energyConsumption, false); + machine.runMachineTick(); + } + } + } + } + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractSieveBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractSieveBlockEntity.java index a418163b..eb4bc286 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractSieveBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractSieveBlockEntity.java @@ -63,19 +63,9 @@ public abstract class AbstractSieveBlockEntity extends EBlockEntity implements S this.logic.loadNbt(nbt); } - // Used for rendering and for TOP - public ItemStack getMesh() { - return this.logic.getMesh(); - } - - // Used for rendering - public float getProgress() { - return this.logic.getProgress(); - } - - // Used for rendering - public ItemStack getContents() { - return this.logic.getContents(); + @Override + public SieveLogic getLogic() { + return this.logic; } @Override diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java new file mode 100644 index 00000000..bee00e16 --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java @@ -0,0 +1,244 @@ +/* + * 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 . + */ + +package thedarkcolour.exdeorum.blockentity; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import thedarkcolour.exdeorum.blockentity.helper.ItemHelper; +import thedarkcolour.exdeorum.config.EConfig; +import thedarkcolour.exdeorum.data.TranslationKeys; +import thedarkcolour.exdeorum.loot.HammerLootModifier; +import thedarkcolour.exdeorum.recipe.RecipeUtil; +import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe; +import thedarkcolour.exdeorum.registry.EBlockEntities; +import thedarkcolour.exdeorum.tag.EItemTags; + +public class MechanicalHammerBlockEntity extends AbstractMachineBlockEntity { + private static final Component TITLE = Component.translatable(TranslationKeys.MECHANICAL_HAMMER_SCREEN_TITLE); + private static final int INPUT_SLOT = 0; + private static final int HAMMER_SLOT = 1; + private static final int OUTPUT_SLOT = 2; + public static final int TOTAL_PROGRESS = 10_000_000; + // process should take 320 ticks or 10 seconds with no efficiency + private static final int PROGRESS_INTERVAL = TOTAL_PROGRESS / 200; + public static final int NOT_RUNNING = -1; + + // an integer from 0 to 10,000,000 instead of a decimal number which is inaccurate and buggy + private int progress = -1; + private float efficiency; + + public MechanicalHammerBlockEntity(BlockPos pos, BlockState state) { + super(EBlockEntities.MECHANICAL_HAMMER.get(), pos, state, ItemHandler::new, EConfig.SERVER.mechanicalHammerEnergyStorage.get()); + } + + public static boolean isValidInput(ItemStack stack) { + return RecipeUtil.getHammerRecipe(stack.getItem()) != null; + } + + @Override + protected void saveAdditional(CompoundTag nbt) { + super.saveAdditional(nbt); + + nbt.putInt("progress", this.progress); + } + + @Override + public void load(CompoundTag nbt) { + super.load(nbt); + + this.progress = nbt.getInt("progress"); + onHammerChanged(); + } + + @Override + public Component getDisplayName() { + return TITLE; + } + + @Override + public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player pPlayer) { + return new MechanicalHammerMenu(containerId, playerInventory, this); + } + + @Override + protected boolean isRunning() { + return this.progress != NOT_RUNNING; + } + + @Override + protected void tryStartRunning() { + var input = this.inventory.getStackInSlot(INPUT_SLOT); + + if (!input.isEmpty() && !this.inventory.getStackInSlot(HAMMER_SLOT).isEmpty()) { + if (canFitResultIntoOutput(input) != null) { + this.progress = 0; + } + } + } + + @Nullable + private HammerRecipe canFitResultIntoOutput(ItemStack input) { + var output = this.inventory.getStackInSlot(OUTPUT_SLOT); + + if (output.isEmpty() || output.getCount() < output.getMaxStackSize()) { + var recipe = RecipeUtil.getHammerRecipe(input.getItem()); + + if (recipe != null && (output.isEmpty() || matchesStack(recipe.result, output))) { + return recipe; + } + } + + return null; + } + + private static boolean matchesStack(Item item, ItemStack stack) { + return !stack.hasTag() && item == stack.getItem(); + } + + @Override + protected void runMachineTick() { + var input = this.inventory.getStackInSlot(INPUT_SLOT); + + if (!input.isEmpty() && !this.inventory.getStackInSlot(HAMMER_SLOT).isEmpty()) { + this.progress += PROGRESS_INTERVAL * this.efficiency; + + if (this.progress >= TOTAL_PROGRESS) { + var recipe = canFitResultIntoOutput(input); + + if (recipe != null) { + @SuppressWarnings("DataFlowIssue") + LootContext ctx = RecipeUtil.emptyLootContext((ServerLevel) this.level); + var resultCount = recipe.resultAmount.getInt(ctx); + resultCount += HammerLootModifier.calculateFortuneBonus(this.inventory.getStackInSlot(HAMMER_SLOT), ctx.getRandom(), resultCount == 0); + var output = this.inventory.getStackInSlot(OUTPUT_SLOT); + if (output.isEmpty()) { + this.inventory.setStackInSlot(OUTPUT_SLOT, new ItemStack(recipe.result, resultCount)); + } else { + output.setCount(Math.min(output.getMaxStackSize(), resultCount + output.getCount())); + } + input.shrink(1); + damageHammer(ctx.getRandom()); + + setChanged(); + } + + this.progress = NOT_RUNNING; + } + } + } + + private void damageHammer(RandomSource rand) { + var hammer = this.inventory.getStackInSlot(HAMMER_SLOT); + + if (hammer.isDamageableItem()) { + + if (hammer.hurt(1, rand, null)) { + hammer.shrink(1); + + if (hammer.isEmpty()) { + this.inventory.setStackInSlot(HAMMER_SLOT, ItemStack.EMPTY); + } + } + } + } + + private void onHammerChanged() { + var hammer = this.inventory.getStackInSlot(HAMMER_SLOT); + if (hammer.isEmpty()) { + this.progress = NOT_RUNNING; + } + this.efficiency = 1f + hammer.getEnchantmentLevel(Enchantments.BLOCK_EFFICIENCY) * 0.17f; + } + + @Override + protected int getEnergyConsumption() { + return EConfig.SERVER.mechanicalHammerEnergyConsumption.get(); + } + + // The value synced to the client for rendering the arrow in GUI + public int getGuiProgress() { + return Math.round((float)(24 * this.progress) / TOTAL_PROGRESS); + } + + public void setGuiProgress(int guiProgress) { + this.progress = (guiProgress * TOTAL_PROGRESS) / 24; + } + + public int getProgress() { + return this.progress; + } + + public void setProgress(int progress) { + this.progress = progress; + } + + private static class ItemHandler extends ItemHelper { + private final MechanicalHammerBlockEntity hammer; + + public ItemHandler(MechanicalHammerBlockEntity hammer) { + super(3); + this.hammer = hammer; + } + + @Override + public boolean isItemValid(int slot, @NotNull ItemStack stack) { + if (slot == INPUT_SLOT) { + return RecipeUtil.getHammerRecipe(stack.getItem()) != null; + } else if (slot == HAMMER_SLOT) { + return stack.is(EItemTags.HAMMERS); + } else { + return false; + } + } + + @Override + public int getSlotLimit(int slot) { + return slot == HAMMER_SLOT ? 1 : super.getSlotLimit(slot); + } + + @Override + public boolean canMachineExtract(int slot) { + return slot == OUTPUT_SLOT; + } + + @Override + protected void onContentsChanged(int slot) { + if (slot == HAMMER_SLOT) { + this.hammer.onHammerChanged(); + } else if (slot == INPUT_SLOT) { + if (getStackInSlot(INPUT_SLOT).isEmpty()) { + this.hammer.progress = NOT_RUNNING; + } + } + } + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerMenu.java b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerMenu.java new file mode 100644 index 00000000..c7dfa2c2 --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerMenu.java @@ -0,0 +1,116 @@ +/* + * 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 . + */ + +package thedarkcolour.exdeorum.blockentity; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.DataSlot; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.item.ItemStack; +import thedarkcolour.exdeorum.ExDeorum; +import thedarkcolour.exdeorum.menu.AbstractMachineMenu; +import thedarkcolour.exdeorum.registry.EMenus; +import thedarkcolour.exdeorum.tag.EItemTags; + +public class MechanicalHammerMenu extends AbstractMachineMenu { + private static final ResourceLocation EMPTY_SLOT_HAMMER = new ResourceLocation(ExDeorum.ID, "item/empty_slot_hammer"); + private static final int NUM_SLOTS = 3; + + public MechanicalHammerMenu(int containerId, Inventory playerInventory, FriendlyByteBuf data) { + this(containerId, playerInventory, (MechanicalHammerBlockEntity) readPayload(playerInventory, data)); + } + + public MechanicalHammerMenu(int containerId, Inventory playerInventory, MechanicalHammerBlockEntity machine) { + super(EMenus.MECHANICAL_HAMMER.get(), containerId, playerInventory, machine); + + // input slot + addSlot(machine.inventory.createSlot(0, 32, 35)); + // hammer slot + addSlot(machine.inventory.createSlot(1, 56, 35).setBackground(InventoryMenu.BLOCK_ATLAS, EMPTY_SLOT_HAMMER)); + // output slot + addSlot(machine.inventory.createSlot(2, 116, 35)); + + addPlayerSlots(playerInventory, 84); + + addDataSlot(new ProgressDataSlot()); + } + + @Override + public ItemStack quickMoveStack(Player player, int clickedSlot) { + var stack = ItemStack.EMPTY; + var slot = this.slots.get(clickedSlot); + + if (slot.hasItem()) { + var clickedStack = slot.getItem(); + stack = clickedStack.copy(); + + if (clickedSlot > 1 && clickedSlot <= NUM_SLOTS) { // moving out of output slots + if (!moveItemStackTo(clickedStack, NUM_SLOTS, PLAYER_SLOTS + NUM_SLOTS, true)) { + return ItemStack.EMPTY; + } + } else if (clickedSlot < 2) { // moving out of input/mesh slot + if (!moveItemStackTo(clickedStack, NUM_SLOTS, NUM_SLOTS + PLAYER_SLOTS, false)) { + return ItemStack.EMPTY; + } + } else if (MechanicalHammerBlockEntity.isValidInput(clickedStack)) { // attempting to move into input slot + if (!moveItemStackTo(clickedStack, 0, 1, false)) { + return ItemStack.EMPTY; + } + } else if (clickedStack.is(EItemTags.HAMMERS)) { // attempting to move into mesh slot + if (!moveItemStackTo(clickedStack, 1, 2, false)) { + return ItemStack.EMPTY; + } + } else if (clickedSlot < NUM_SLOTS + 27) { // attempting to move from inventory to hotbar + if (!moveItemStackTo(clickedStack, NUM_SLOTS + 27, NUM_SLOTS + PLAYER_SLOTS, false)) { + return ItemStack.EMPTY; + } + } else if (clickedSlot < NUM_SLOTS + PLAYER_SLOTS) { // attempting to move from hotbar to inventory + if (!moveItemStackTo(clickedStack, NUM_SLOTS, NUM_SLOTS + 27, false)) { + return ItemStack.EMPTY; + } + } + + if (clickedStack.isEmpty()) { + slot.set(ItemStack.EMPTY); + } + slot.setChanged(); + if (clickedStack.getCount() == stack.getCount()) { + return ItemStack.EMPTY; + } + slot.onTake(player, clickedStack); + broadcastChanges(); + } + + return stack; + } + + private class ProgressDataSlot extends DataSlot { + @Override + public int get() { + return MechanicalHammerMenu.this.machine.getGuiProgress(); + } + + @Override + public void set(int value) { + MechanicalHammerMenu.this.machine.setGuiProgress(value); + } + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java index 3fdbca2e..37de00f4 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalSieveBlockEntity.java @@ -19,35 +19,19 @@ package thedarkcolour.exdeorum.blockentity; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.energy.EnergyStorage; import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.network.NetworkHooks; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import thedarkcolour.exdeorum.blockentity.helper.EnergyHelper; import thedarkcolour.exdeorum.blockentity.helper.ItemHelper; import thedarkcolour.exdeorum.blockentity.logic.SieveLogic; -import thedarkcolour.exdeorum.client.screen.RedstoneControlWidget; import thedarkcolour.exdeorum.config.EConfig; import thedarkcolour.exdeorum.data.TranslationKeys; import thedarkcolour.exdeorum.menu.MechanicalSieveMenu; @@ -55,107 +39,70 @@ import thedarkcolour.exdeorum.recipe.RecipeUtil; import thedarkcolour.exdeorum.registry.EBlockEntities; import thedarkcolour.exdeorum.tag.EItemTags; -import javax.annotation.Nonnull; - -public class MechanicalSieveBlockEntity extends AbstractSieveBlockEntity implements MenuProvider { +public class MechanicalSieveBlockEntity extends AbstractMachineBlockEntity implements SieveLogic.Owner { private static final Component TITLE = Component.translatable(TranslationKeys.MECHANICAL_SIEVE_SCREEN_TITLE); private static final int INPUT_SLOT = 0; public static final int MESH_SLOT = 1; - public final ItemHelper inventory; - public final EnergyHelper energy; - private int redstoneMode; - // not saved to NBT - public boolean hasRedstonePower; - - private final LazyOptional capabilityInventory; - private final LazyOptional capabilityEnergy; + private final SieveLogic logic; public MechanicalSieveBlockEntity(BlockPos pos, BlockState state) { - super(EBlockEntities.MECHANICAL_SIEVE.get(), pos, state, owner -> new SieveLogic(owner, false, true)); + super(EBlockEntities.MECHANICAL_SIEVE.get(), pos, state, ItemHandler::new, EConfig.SERVER.mechanicalSieveEnergyStorage.get()); - this.inventory = new ItemHandler(22); - this.energy = new EnergyHelper(EConfig.SERVER.mechanicalSieveEnergyStorage.get()); - - this.capabilityInventory = LazyOptional.of(() -> this.inventory); - this.capabilityEnergy = LazyOptional.of(() -> this.energy); + this.logic = new SieveLogic(this, false, true); } @Override protected void saveAdditional(CompoundTag nbt) { super.saveAdditional(nbt); - nbt.put("inventory", this.inventory.serializeNBT()); - nbt.putInt("energy", this.energy.getEnergyStored()); - nbt.putInt("redstoneMode", this.redstoneMode); + this.logic.saveNbt(nbt); } @Override public void load(CompoundTag nbt) { super.load(nbt); - this.inventory.deserializeNBT(nbt.getCompound("inventory")); - this.energy.setStoredEnergy(nbt.getInt("energy")); - this.redstoneMode = Mth.clamp(nbt.getInt("redstoneMode"), 0, 2); + this.logic.loadNbt(nbt); } @Override - public void onLoad() { - checkPoweredState(this.level, this.worldPosition); + protected boolean isRunning() { + return !this.logic.getContents().isEmpty(); } @Override - public InteractionResult use(Level level, Player player, InteractionHand hand) { - if (player instanceof ServerPlayer serverPlayer) { - NetworkHooks.openScreen(serverPlayer, this, buffer -> { - buffer.writeBlockPos(getBlockPos()); - buffer.writeByte(this.redstoneMode); - }); - return InteractionResult.CONSUME; - } else { - return InteractionResult.SUCCESS; + protected void tryStartRunning() { + var input = this.inventory.getStackInSlot(INPUT_SLOT); + + if (this.logic.isValidInput(input)) { + this.logic.startSifting(AbstractSieveBlockEntity.singleCopy(input)); + input.shrink(1); } } - @Nonnull @Override - public LazyOptional getCapability(@Nonnull Capability cap, @javax.annotation.Nullable Direction side) { - if (cap == ForgeCapabilities.ENERGY) { - return this.capabilityEnergy.cast(); - } else if (cap == ForgeCapabilities.ITEM_HANDLER) { - return this.capabilityInventory.cast(); - } - - return super.getCapability(cap, side); + protected void runMachineTick() { + this.logic.sift(0.01f); } @Override - public void invalidateCaps() { - super.invalidateCaps(); - - this.capabilityEnergy.invalidate(); - this.capabilityInventory.invalidate(); + protected int getEnergyConsumption() { + return EConfig.SERVER.mechanicalSieveEnergyConsumption.get(); } - private void serverTick() { - if (this.redstoneMode == RedstoneControlWidget.REDSTONE_MODE_IGNORED || ((this.redstoneMode == RedstoneControlWidget.REDSTONE_MODE_UNPOWERED)) != this.hasRedstonePower) { - var energyConsumption = EConfig.SERVER.mechanicalSieveEnergyConsumption.get(); + @Override + public void writeVisualData(FriendlyByteBuf buffer) { + buffer.writeItem(this.logic.getMesh()); + buffer.writeFloat(this.logic.getProgress()); + buffer.writeItem(this.logic.getContents()); + } - if (this.energy.getEnergyStored() >= energyConsumption) { - if (this.logic.getContents().isEmpty()) { - var input = this.inventory.getStackInSlot(INPUT_SLOT); - - if (this.logic.isValidInput(input)) { - this.logic.startSifting(AbstractSieveBlockEntity.singleCopy(input)); - input.shrink(1); - } - } - if (!this.logic.getContents().isEmpty()) { - this.energy.extractEnergy(energyConsumption, false); - this.logic.sift(0.01f); - } - } - } + @Override + public void readVisualData(FriendlyByteBuf buffer) { + this.logic.setMesh(buffer.readItem(), false); + this.logic.setProgress(buffer.readFloat()); + this.logic.setContents(buffer.readItem()); } @Override @@ -205,43 +152,32 @@ public class MechanicalSieveBlockEntity extends AbstractSieveBlockEntity impleme return TITLE; } - @Nullable @Override public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player pPlayer) { return new MechanicalSieveMenu(containerId, playerInventory, this); } - public boolean stillValid(Player player) { - if (this.level.getBlockEntity(this.worldPosition) != this) { - return false; - } else { - return player.distanceToSqr(this.worldPosition.getX() + 0.5, this.worldPosition.getY() + 0.5, this.worldPosition.getZ() + 0.5) <= 64.0; - } - } - + @Override public SieveLogic getLogic() { return this.logic; } - public void setRedstoneMode(int redstoneMode) { - this.redstoneMode = redstoneMode; + @SuppressWarnings("DataFlowIssue") + @Override + public ServerLevel getServerLevel() { + return (ServerLevel) this.level; } - public int getRedstoneMode() { - return this.redstoneMode; - } + private static class ItemHandler extends ItemHelper { + private final MechanicalSieveBlockEntity sieve; - public void checkPoweredState(Level level, BlockPos pos) { - this.hasRedstonePower = level.hasNeighborSignal(pos); - } - - private class ItemHandler extends ItemHelper { - public ItemHandler(int size) { - super(size); + public ItemHandler(MechanicalSieveBlockEntity sieve) { + super(22); + this.sieve = sieve; } @Override - public boolean isItemValid(int slot, @NotNull ItemStack stack) { + public boolean isItemValid(int slot, ItemStack stack) { if (slot == INPUT_SLOT) { return !RecipeUtil.getSieveRecipes(getStackInSlot(1).getItem(), stack).isEmpty(); } else if (slot == MESH_SLOT) { @@ -264,20 +200,13 @@ public class MechanicalSieveBlockEntity extends AbstractSieveBlockEntity impleme @Override protected void onContentsChanged(int slot) { if (slot == MESH_SLOT) { - MechanicalSieveBlockEntity.this.logic.setMesh(MechanicalSieveBlockEntity.this.inventory.getStackInSlot(MESH_SLOT)); + this.sieve.logic.setMesh(this.sieve.inventory.getStackInSlot(MESH_SLOT)); } } @Override protected void onLoad() { - MechanicalSieveBlockEntity.this.logic.setMesh(MechanicalSieveBlockEntity.this.inventory.getStackInSlot(MESH_SLOT), false); - } - } - - public static class ServerTicker implements BlockEntityTicker { - @Override - public void tick(Level level, BlockPos pos, BlockState state, MechanicalSieveBlockEntity sieve) { - sieve.serverTick(); + this.sieve.logic.setMesh(this.sieve.inventory.getStackInSlot(MESH_SLOT), false); } } } diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/logic/SieveLogic.java b/src/main/java/thedarkcolour/exdeorum/blockentity/logic/SieveLogic.java index f2a6780a..6eed7556 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/logic/SieveLogic.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/logic/SieveLogic.java @@ -27,14 +27,11 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.LootParams; import thedarkcolour.exdeorum.config.EConfig; import thedarkcolour.exdeorum.recipe.RecipeUtil; import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe; import thedarkcolour.exdeorum.tag.EItemTags; -import java.util.Map; - public class SieveLogic { private final Owner owner; private final boolean saveMesh; @@ -80,7 +77,7 @@ public class SieveLogic { // Need epsilon because floating point decimals suck if (this.progress >= 1.0f - Mth.EPSILON) { var level = this.owner.getServerLevel(); - var context = new LootContext.Builder(new LootParams(level, Map.of(), Map.of(), 0)).create(null); + var context = RecipeUtil.emptyLootContext(level); var rand = level.random; var limitDrops = this.contents.getItem() == Items.MOSS_BLOCK && EConfig.SERVER.limitMossSieveDrops.get(); var handledAnyDrops = false; @@ -207,5 +204,7 @@ public class SieveLogic { boolean handleResultItem(ItemStack result, ServerLevel level, RandomSource rand); void markUpdated(); + + SieveLogic getLogic(); } } diff --git a/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java b/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java index 1e9a3062..6581ab5e 100644 --- a/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java +++ b/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java @@ -43,6 +43,7 @@ import net.minecraftforge.fml.event.config.ModConfigEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; 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; @@ -101,6 +102,7 @@ public class ClientHandler { event.enqueueWork(() -> { setRenderLayers(); MenuScreens.register(EMenus.MECHANICAL_SIEVE.get(), MechanicalSieveScreen::new); + MenuScreens.register(EMenus.MECHANICAL_HAMMER.get(), MechanicalHammerScreen::new); }); } diff --git a/src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalHammerScreen.java b/src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalHammerScreen.java new file mode 100644 index 00000000..e5b81434 --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalHammerScreen.java @@ -0,0 +1,94 @@ +/* + * 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 . + */ + +package thedarkcolour.exdeorum.client.screen; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Inventory; +import org.jetbrains.annotations.Nullable; +import thedarkcolour.exdeorum.ExDeorum; +import thedarkcolour.exdeorum.blockentity.MechanicalHammerMenu; +import thedarkcolour.exdeorum.config.EConfig; +import thedarkcolour.exdeorum.data.TranslationKeys; + +public class MechanicalHammerScreen extends AbstractContainerScreen { + private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(ExDeorum.ID, "textures/gui/container/mechanical_hammer.png"); + + public static final int RECIPE_CLICK_AREA_POS_X = 80; + public static final int RECIPE_CLICK_AREA_POS_Y = 34; + public static final int RECIPE_CLICK_AREA_WIDTH = 23; + public static final int RECIPE_CLICK_AREA_HEIGHT = 16; + + @Nullable + private RedstoneControlWidget redstoneControlWidget; + + public MechanicalHammerScreen(MechanicalHammerMenu menu, Inventory playerInventory, Component title) { + super(menu, playerInventory, title); + + this.imageWidth = 176; + this.imageHeight = 166; + } + + @Override + protected void init() { + super.init(); + + this.redstoneControlWidget = new RedstoneControlWidget(this.menu, BACKGROUND_TEXTURE, this.leftPos + this.imageWidth, this.topPos + 3); + addRenderableWidget(this.redstoneControlWidget); + } + + @Nullable + public RedstoneControlWidget getRedstoneControlWidget() { + return this.redstoneControlWidget; + } + + @Override + protected void renderBg(GuiGraphics graphics, float pPartialTick, int pMouseX, int pMouseY) { + int left = this.leftPos; + int top = this.topPos; + graphics.blit(BACKGROUND_TEXTURE, left, top, 0, 0, this.imageWidth, this.imageHeight); + + // energy bar + int energy = Mth.floor(54 * ((float) this.menu.prevEnergy / EConfig.SERVER.mechanicalSieveEnergyStorage.get())); + graphics.blit(BACKGROUND_TEXTURE, left + 10, top + 15 + 54 - energy, this.imageWidth, 16 + 54 - energy, 12, energy); + + // progress arrow + int progress = Math.min(23, this.menu.machine.getGuiProgress()); + graphics.blit(BACKGROUND_TEXTURE, left + RECIPE_CLICK_AREA_POS_X, top + RECIPE_CLICK_AREA_POS_Y, this.imageWidth, 0, progress, 16); + } + + @Override + public void render(GuiGraphics graphics, int mx, int my, float pPartialTick) { + renderBackground(graphics); + super.render(graphics, mx, my, pPartialTick); + renderTooltip(graphics, mx, my); + + int rx = mx - this.leftPos; + int ry = my - this.topPos; + + if (9 <= rx && rx < 23 && 14 <= ry && ry < 70) { + var energyTooltip = Component.translatable(TranslationKeys.ENERGY).append(Component.translatable(TranslationKeys.FRACTION_DISPLAY, this.menu.prevEnergy, EConfig.SERVER.mechanicalSieveEnergyStorage.get())).append(" FE"); + graphics.renderTooltip(Minecraft.getInstance().font, energyTooltip, mx, my); + } + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalSieveScreen.java b/src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalSieveScreen.java index d9a83842..cf084c5a 100644 --- a/src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalSieveScreen.java +++ b/src/main/java/thedarkcolour/exdeorum/client/screen/MechanicalSieveScreen.java @@ -40,14 +40,12 @@ public class MechanicalSieveScreen extends AbstractContainerScreen screen; private final ResourceLocation texture; private final int posX; private final int posY; @@ -68,7 +69,7 @@ public class RedstoneControlWidget implements GuiEventListener, NarratableEntry, // Last time (from currentTimeMillis) this button was clicked, used in animation lerp private long lastClicked = -1L; - public RedstoneControlWidget(MechanicalSieveScreen screen, ResourceLocation texture, int posX, int posY) { + public RedstoneControlWidget(AbstractMachineMenu screen, ResourceLocation texture, int posX, int posY) { this.screen = screen; this.texture = texture; this.posX = posX; @@ -106,7 +107,7 @@ public class RedstoneControlWidget implements GuiEventListener, NarratableEntry, var font = Minecraft.getInstance().font; if (this.expanded) { - var redstoneMode = this.screen.getMenu().sieve.getRedstoneMode(); + var redstoneMode = this.screen.machine.getRedstoneMode(); graphics.blit(this.texture, this.posX, this.posY, this.expandedU, this.expandedV, this.expandedWidth, this.expandedHeight); for (int i = 0; i < 3; ++i) { graphics.blit(this.texture, this.buttonsPosX + (i * 19), this.buttonsPosY, (redstoneMode == i ? this.tabU + 16 : this.tabU), this.tabV + this.tabHeight, 16, 16); @@ -157,9 +158,10 @@ public class RedstoneControlWidget implements GuiEventListener, NarratableEntry, return false; } + @SuppressWarnings("DataFlowIssue") private void setRedstoneMode(int redstoneMode) { - this.screen.getMenu().clickMenuButton(Minecraft.getInstance().player, redstoneMode); - Minecraft.getInstance().gameMode.handleInventoryButtonClick(this.screen.getMenu().containerId, redstoneMode); + this.screen.clickMenuButton(Minecraft.getInstance().player, redstoneMode); + Minecraft.getInstance().gameMode.handleInventoryButtonClick(this.screen.containerId, redstoneMode); } private void drawPartialConfig(GuiGraphics graphics) { diff --git a/src/main/java/thedarkcolour/exdeorum/client/ter/SieveRenderer.java b/src/main/java/thedarkcolour/exdeorum/client/ter/SieveRenderer.java index 8812ae51..e21c909f 100644 --- a/src/main/java/thedarkcolour/exdeorum/client/ter/SieveRenderer.java +++ b/src/main/java/thedarkcolour/exdeorum/client/ter/SieveRenderer.java @@ -23,31 +23,33 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; 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.world.item.BlockItem; import net.minecraft.world.item.Item; -import net.minecraftforge.registries.ForgeRegistries; -import thedarkcolour.exdeorum.blockentity.AbstractSieveBlockEntity; +import thedarkcolour.exdeorum.blockentity.EBlockEntity; +import thedarkcolour.exdeorum.blockentity.logic.SieveLogic; import thedarkcolour.exdeorum.client.RenderUtil; import java.util.HashMap; import java.util.Map; -public class SieveRenderer implements BlockEntityRenderer { +public class SieveRenderer implements BlockEntityRenderer { public static final Map MESH_TEXTURES = new HashMap<>(); @Override public void render(T sieve, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) { - var contents = sieve.getContents(); + var logic = sieve.getLogic(); + var contents = logic.getContents(); if (!contents.isEmpty() && contents.getItem() instanceof BlockItem blockItem) { var block = blockItem.getBlock(); - var percentage = sieve.getProgress(); + var percentage = logic.getProgress(); var face = RenderUtil.getTopFace(block); face.renderFlatSpriteLerp(buffers, stack, percentage, 0xff, 0xff, 0xff, light, 1.0f, 15f, 13f); } - var mesh = sieve.getMesh(); + var mesh = logic.getMesh(); if (!mesh.isEmpty()) { var builder = buffers.getBuffer(RenderType.cutoutMipped()); @@ -57,7 +59,8 @@ public class SieveRenderer implements BlockE if (MESH_TEXTURES.containsKey(meshItem)) { meshSprite = MESH_TEXTURES.get(meshItem); } else { - ResourceLocation registryName = ForgeRegistries.ITEMS.getKey(meshItem); + @SuppressWarnings("deprecation") + ResourceLocation registryName = BuiltInRegistries.ITEM.getKey(meshItem); ResourceLocation textureLoc = registryName.withPrefix("item/mesh/"); meshSprite = RenderUtil.blockAtlas.getSprite(textureLoc); MESH_TEXTURES.put(meshItem, meshSprite); diff --git a/src/main/java/thedarkcolour/exdeorum/compat/jei/ExDeorumJeiPlugin.java b/src/main/java/thedarkcolour/exdeorum/compat/jei/ExDeorumJeiPlugin.java index 604150a1..5c6f6d94 100644 --- a/src/main/java/thedarkcolour/exdeorum/compat/jei/ExDeorumJeiPlugin.java +++ b/src/main/java/thedarkcolour/exdeorum/compat/jei/ExDeorumJeiPlugin.java @@ -48,6 +48,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.ModList; import thedarkcolour.exdeorum.ExDeorum; import thedarkcolour.exdeorum.blockentity.LavaCrucibleBlockEntity; +import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen; import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen; import thedarkcolour.exdeorum.compat.GroupedSieveRecipe; import thedarkcolour.exdeorum.compat.ModIds; @@ -322,6 +323,22 @@ public class ExDeorumJeiPlugin implements IModPlugin { return List.of(); } }); + registration.addGuiContainerHandler(MechanicalHammerScreen.class, new IGuiContainerHandler<>() { + @Override + public Collection getGuiClickableAreas(MechanicalHammerScreen containerScreen, double mouseX, double mouseY) { + IGuiClickableArea clickableArea = IGuiClickableArea.createBasic(MechanicalHammerScreen.RECIPE_CLICK_AREA_POS_X, MechanicalHammerScreen.RECIPE_CLICK_AREA_POS_Y, MechanicalHammerScreen.RECIPE_CLICK_AREA_WIDTH, MechanicalHammerScreen.RECIPE_CLICK_AREA_HEIGHT, HAMMER); + return List.of(clickableArea); + } + + @Override + public List getGuiExtraAreas(MechanicalHammerScreen containerScreen) { + var widget = containerScreen.getRedstoneControlWidget(); + if (widget != null) { + return widget.getJeiBounds(); + } + return List.of(); + } + }); } private static > void addRecipes(IRecipeRegistration registration, RecipeType category, Supplier> type) { diff --git a/src/main/java/thedarkcolour/exdeorum/compat/top/ExDeorumInfoProvider.java b/src/main/java/thedarkcolour/exdeorum/compat/top/ExDeorumInfoProvider.java index 679e144f..85bce11f 100644 --- a/src/main/java/thedarkcolour/exdeorum/compat/top/ExDeorumInfoProvider.java +++ b/src/main/java/thedarkcolour/exdeorum/compat/top/ExDeorumInfoProvider.java @@ -80,14 +80,15 @@ public class ExDeorumInfoProvider implements IProbeInfoProvider { info.tank(crucible.getTank()); } } else if (te instanceof SieveBlockEntity sieve) { - if (!sieve.getContents().isEmpty()) { - info.text(CompoundText.create().style(TextStyleClass.LABEL).text("Progress: ").style(TextStyleClass.WARNING).text((Math.round(1000 * sieve.getProgress()) / 10) + "%")); + var logic = sieve.getLogic(); + if (!logic.getContents().isEmpty()) { + info.text(CompoundText.create().style(TextStyleClass.LABEL).text("Progress: ").style(TextStyleClass.WARNING).text((Math.round(1000 * logic.getProgress()) / 10) + "%")); } if (playerEntity.isShiftKeyDown()) { - var mesh = sieve.getMesh(); + var mesh = logic.getMesh(); info.horizontal(info.defaultLayoutStyle().spacing(10).alignment(ElementAlignment.ALIGN_CENTER)) - .item(sieve.getMesh(), info.defaultItemStyle().width(16).height(16)) - .text(CompoundText.create().info(sieve.getMesh().getDescriptionId())); + .item(mesh, info.defaultItemStyle().width(16).height(16)) + .text(CompoundText.create().info(mesh.getDescriptionId())); if (mesh.isEnchanted()) { var list = new ObjectArrayList(); var style = info.defaultTextStyle().height(10); diff --git a/src/main/java/thedarkcolour/exdeorum/config/EConfig.java b/src/main/java/thedarkcolour/exdeorum/config/EConfig.java index 86167f7f..95298e93 100644 --- a/src/main/java/thedarkcolour/exdeorum/config/EConfig.java +++ b/src/main/java/thedarkcolour/exdeorum/config/EConfig.java @@ -133,6 +133,8 @@ public class EConfig { public final BooleanValue allowWitchWaterEntityConversion; public final IntValue mechanicalSieveEnergyStorage; public final IntValue mechanicalSieveEnergyConsumption; + public final IntValue mechanicalHammerEnergyStorage; + public final IntValue mechanicalHammerEnergyConsumption; public Server(ForgeConfigSpec.Builder builder) { builder.comment("Server configuration for Ex Deorum").push("server"); @@ -179,6 +181,12 @@ public class EConfig { this.mechanicalSieveEnergyConsumption = builder .comment("The amount of FE/t a tick consumed by the mechanical sieve when sifting a block.") .defineInRange("mechanical_sieve_energy_consumption", 40, 0, Integer.MAX_VALUE); + this.mechanicalHammerEnergyStorage = builder + .comment("The maximum amount of FE the mechanical hammer can have in its energy storage.") + .defineInRange("mechanical_hammer_energy_storage", 40_000, 0, Integer.MAX_VALUE); + this.mechanicalHammerEnergyConsumption = builder + .comment("The amount of FE/t a tick consumed by the mechanical hammer when crushing a block.") + .defineInRange("mechanical_hammer_energy_consumption", 20, 0, Integer.MAX_VALUE); builder.pop(); } diff --git a/src/main/java/thedarkcolour/exdeorum/data/English.java b/src/main/java/thedarkcolour/exdeorum/data/English.java index 895cd19d..5becf370 100644 --- a/src/main/java/thedarkcolour/exdeorum/data/English.java +++ b/src/main/java/thedarkcolour/exdeorum/data/English.java @@ -78,6 +78,8 @@ class English { english.add(TranslationKeys.REDSTONE_CONTROL_MODES[RedstoneControlWidget.REDSTONE_MODE_POWERED], "Powered"); english.add(TranslationKeys.REDSTONE_CONTROL_LABEL, "Redstone Mode"); english.add(TranslationKeys.REDSTONE_CONTROL_MODE, "Mode: "); + english.add(TranslationKeys.MECHANICAL_HAMMER_SCREEN_TITLE, "Mechanical Hammer"); + english.add(TranslationKeys.MECHANICAL_HAMMER_SCREEN_TITLE, "Consuming %s FE/t"); english.addBlock(EBlocks.VEXING_ARCHWOOD_CRUCIBLE, "Vexing Archwood Crucible"); english.addBlock(EBlocks.CASCADING_ARCHWOOD_CRUCIBLE, "Cascading Archwood Crucible"); diff --git a/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java b/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java index 120d5a96..a74189fd 100644 --- a/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java +++ b/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java @@ -80,4 +80,6 @@ public class TranslationKeys { }; public static final String REDSTONE_CONTROL_LABEL = "gui." + ExDeorum.ID + ".redstone_control.label"; public static final String REDSTONE_CONTROL_MODE = "gui." + ExDeorum.ID + ".redstone_control.mode"; + public static final String MECHANICAL_HAMMER_SCREEN_TITLE = ExDeorum.ID + ".container.mechanical_hammer"; + public static final String MACHINE_FE_PER_TICK = "gui." + ExDeorum.ID + ".machine_fe_per_tick"; } diff --git a/src/main/java/thedarkcolour/exdeorum/loot/HammerLootModifier.java b/src/main/java/thedarkcolour/exdeorum/loot/HammerLootModifier.java index e639fae8..2c71ca66 100644 --- a/src/main/java/thedarkcolour/exdeorum/loot/HammerLootModifier.java +++ b/src/main/java/thedarkcolour/exdeorum/loot/HammerLootModifier.java @@ -21,6 +21,7 @@ package thedarkcolour.exdeorum.loot; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.util.RandomSource; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.enchantment.Enchantments; @@ -56,22 +57,8 @@ public class HammerLootModifier extends LootModifier { // fortune handling; more likely to boost drops if there are none to begin with if (context.hasParam(LootContextParams.TOOL)) { - var stack = context.getParam(LootContextParams.TOOL); - var fortune = stack.getEnchantmentLevel(Enchantments.BLOCK_FORTUNE); - - if (fortune != 0) { - var chance = context.getRandom().nextFloat(); - - if (resultAmount == 0) { - if (chance < 0.06 * fortune) { - resultAmount++; - } - } else { - if (chance < 0.03 * fortune) { - resultAmount++; - } - } - } + var hammer = context.getParam(LootContextParams.TOOL); + resultAmount += calculateFortuneBonus(hammer, context.getRandom(), resultAmount == 0); } if (resultAmount > 0) { @@ -89,5 +76,32 @@ public class HammerLootModifier extends LootModifier { public Codec codec() { return CODEC; } + + /** + * Calculates the bonus number of drops for a hammer enchanted with fortune. + * @param hammer The hammer in question + * @param rand RNG + * @param zeroBaseDrops Whether there were no drops to begin with + * @return The additional number of drops, to be added to the number of base drops + */ + public static int calculateFortuneBonus(ItemStack hammer, RandomSource rand, boolean zeroBaseDrops) { + var fortune = hammer.getEnchantmentLevel(Enchantments.BLOCK_FORTUNE); + + if (fortune != 0) { + var chance = rand.nextFloat(); + + if (zeroBaseDrops) { + if (chance < 0.06f * fortune) { + return 1; + } + } else { + if (chance < 0.03f * fortune) { + return 1; + } + } + } + + return 0; + } } diff --git a/src/main/java/thedarkcolour/exdeorum/menu/AbstractMachineMenu.java b/src/main/java/thedarkcolour/exdeorum/menu/AbstractMachineMenu.java new file mode 100644 index 00000000..16f7a35f --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/menu/AbstractMachineMenu.java @@ -0,0 +1,121 @@ +/* + * 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 . + */ + +package thedarkcolour.exdeorum.menu; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import org.jetbrains.annotations.Nullable; +import thedarkcolour.exdeorum.blockentity.AbstractMachineBlockEntity; +import thedarkcolour.exdeorum.network.NetworkHandler; + +public abstract class AbstractMachineMenu> extends AbstractContainerMenu { + protected static final int PLAYER_SLOTS = 36; // hotbar + inventory + + @Nullable + private final ServerPlayer player; + public final M machine; + + public int prevEnergy; + + protected AbstractMachineMenu(MenuType pMenuType, int pContainerId, Inventory playerInventory, M machine) { + super(pMenuType, pContainerId); + + this.machine = machine; + + if (playerInventory.player instanceof ServerPlayer serverPlayer) { + this.player = serverPlayer; + } else { + this.player = null; + } + } + + // todo find a better way to do this + @SuppressWarnings({"DataFlowIssue", "unchecked"}) + protected static > M readPayload(Inventory playerInventory, FriendlyByteBuf data) { + var machine = (M) playerInventory.player.level().getBlockEntity(data.readBlockPos()); + machine.setRedstoneMode(data.readByte()); + return machine; + } + + // Call after own slots have been added + protected final void addPlayerSlots(Inventory playerInventory, int startY) { + // Inventory + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, startY + i * 18)); + } + } + // Hotbar + for (int k = 0; k < 9; ++k) { + addSlot(new Slot(playerInventory, k, 8 + k * 18, startY + 58)); + } + } + + // When the server sends a menu property message, the client handles the synced property here. + public void setClientProperty(int index, int value) { + if (index == 0) { + this.prevEnergy = value; + } + } + + @Override + public void broadcastChanges() { + super.broadcastChanges(); + + if (this.player != null) { + syncProperties(this.player); + } + } + + @Override + public void broadcastFullState() { + super.broadcastFullState(); + + if (this.player != null) { + syncProperties(this.player); + } + } + + protected void syncProperties(ServerPlayer player) { + if (this.prevEnergy != this.machine.energy.getEnergyStored()) { + this.prevEnergy = this.machine.energy.getEnergyStored(); + + NetworkHandler.sendMenuProperty(player, this.containerId, 0, this.prevEnergy); + } + } + + @Override + public boolean clickMenuButton(Player pPlayer, int id) { + if (0 <= id && id < 3) { + this.machine.setRedstoneMode(id); + return true; + } + return false; + } + + @Override + public boolean stillValid(Player player) { + return this.machine.stillValid(player); + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/menu/EContainerMenu.java b/src/main/java/thedarkcolour/exdeorum/menu/EContainerMenu.java deleted file mode 100644 index f298089b..00000000 --- a/src/main/java/thedarkcolour/exdeorum/menu/EContainerMenu.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 . - */ - -package thedarkcolour.exdeorum.menu; - -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.MenuType; - -public abstract class EContainerMenu extends AbstractContainerMenu { - protected EContainerMenu(MenuType pMenuType, int pContainerId) { - super(pMenuType, pContainerId); - } - - // When the server sends a menu property message, the client handles the synced property here. - public abstract void setClientProperty(int index, int value); -} diff --git a/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java b/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java index 056283cc..069ee579 100644 --- a/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java +++ b/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java @@ -20,38 +20,24 @@ package thedarkcolour.exdeorum.menu; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.InventoryMenu; -import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import org.jetbrains.annotations.Nullable; import thedarkcolour.exdeorum.ExDeorum; import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity; -import thedarkcolour.exdeorum.network.NetworkHandler; import thedarkcolour.exdeorum.registry.EMenus; -public class MechanicalSieveMenu extends EContainerMenu { +public class MechanicalSieveMenu extends AbstractMachineMenu { private static final ResourceLocation EMPTY_SLOT_MESH = new ResourceLocation(ExDeorum.ID, "item/empty_slot_mesh"); private static final int NUM_SLOTS = 22; // input + mesh, 20 output slots - private static final int PLAYER_SLOTS = 36; // hotbar + inventory - - public final MechanicalSieveBlockEntity sieve; - @Nullable - private final ServerPlayer player; - - public int prevSieveEnergy; public MechanicalSieveMenu(int containerId, Inventory playerInventory, FriendlyByteBuf data) { - this(containerId, playerInventory, (MechanicalSieveBlockEntity) playerInventory.player.level().getBlockEntity(data.readBlockPos())); - this.sieve.setRedstoneMode(data.readByte()); + this(containerId, playerInventory, (MechanicalSieveBlockEntity) readPayload(playerInventory, data)); } public MechanicalSieveMenu(int containerId, Inventory playerInventory, MechanicalSieveBlockEntity sieve) { - super(EMenus.MECHANICAL_SIEVE.get(), containerId); - - this.sieve = sieve; + super(EMenus.MECHANICAL_SIEVE.get(), containerId, playerInventory, sieve); // input slot addSlot(sieve.inventory.createSlot(0, 26, 30)); @@ -63,54 +49,7 @@ public class MechanicalSieveMenu extends EContainerMenu { addSlot(sieve.inventory.createSlot(2 + r * 5 + c, 80 + c * 18, 15 + r * 18)); } } - // Player slots - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 7 + 84 + i * 18)); - } - } - for (int k = 0; k < 9; ++k) { - addSlot(new Slot(playerInventory, k, 8 + k * 18, 149)); - } - - if (playerInventory.player instanceof ServerPlayer serverPlayer) { - this.player = serverPlayer; - } else { - this.player = null; - } - } - - @Override - public void broadcastChanges() { - super.broadcastChanges(); - - if (this.player != null) { - if (this.prevSieveEnergy != this.sieve.energy.getEnergyStored()) { - this.prevSieveEnergy = this.sieve.energy.getEnergyStored(); - - NetworkHandler.sendMenuProperty(this.player, this.containerId, 0, this.prevSieveEnergy); - } - } - } - - @Override - public void broadcastFullState() { - super.broadcastFullState(); - - if (this.player != null) { - if (this.prevSieveEnergy != this.sieve.energy.getEnergyStored()) { - this.prevSieveEnergy = this.sieve.energy.getEnergyStored(); - - NetworkHandler.sendMenuProperty(this.player, this.containerId, 0, this.prevSieveEnergy); - } - } - } - - @Override - public void setClientProperty(int index, int value) { - if (index == 0) { - this.prevSieveEnergy = value; - } + addPlayerSlots(playerInventory, 91); } @Override @@ -130,11 +69,11 @@ public class MechanicalSieveMenu extends EContainerMenu { if (!moveItemStackTo(clickedStack, NUM_SLOTS, NUM_SLOTS + PLAYER_SLOTS, false)) { return ItemStack.EMPTY; } - } else if (this.sieve.getLogic().isValidInput(clickedStack)) { // attempting to move into input slot + } else if (this.machine.getLogic().isValidInput(clickedStack)) { // attempting to move into input slot if (!moveItemStackTo(clickedStack, 0, 1, false)) { return ItemStack.EMPTY; } - } else if (this.sieve.getLogic().isValidMesh(clickedStack)) { // attempting to move into mesh slot + } else if (this.machine.getLogic().isValidMesh(clickedStack)) { // attempting to move into mesh slot if (!moveItemStackTo(clickedStack, 1, 2, false)) { return ItemStack.EMPTY; } @@ -161,18 +100,4 @@ public class MechanicalSieveMenu extends EContainerMenu { return stack; } - - @Override - public boolean clickMenuButton(Player player, int id) { - if (0 <= id && id < 3) { - this.sieve.setRedstoneMode(id); - return false; - } - return false; - } - - @Override - public boolean stillValid(Player player) { - return this.sieve.stillValid(player); - } } diff --git a/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java b/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java index a9658ac2..5b76fcdf 100644 --- a/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java +++ b/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java @@ -23,7 +23,7 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.world.entity.player.Player; import thedarkcolour.exdeorum.blockentity.EBlockEntity; import thedarkcolour.exdeorum.client.ClientHandler; -import thedarkcolour.exdeorum.menu.EContainerMenu; +import thedarkcolour.exdeorum.menu.AbstractMachineMenu; public class ClientMessageHandler { public static boolean isInVoidWorld; @@ -54,7 +54,7 @@ public class ClientMessageHandler { public static void handleMenuProperty(MenuPropertyMessage msg) { Player player = Minecraft.getInstance().player; - if (player != null && player.containerMenu instanceof EContainerMenu menu && menu.containerId == msg.containerId()) { + if (player != null && player.containerMenu instanceof AbstractMachineMenu menu && menu.containerId == msg.containerId()) { menu.setClientProperty(msg.index(), msg.value()); } } diff --git a/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java b/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java index 423d42b8..63fba00f 100644 --- a/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java +++ b/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java @@ -24,6 +24,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.TagKey; import net.minecraft.util.GsonHelper; import net.minecraft.world.Container; @@ -36,7 +37,9 @@ import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootParams; import net.minecraft.world.level.storage.loot.providers.number.*; import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.fluids.FluidStack; @@ -55,6 +58,7 @@ import thedarkcolour.exdeorum.registry.ERecipeTypes; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Objects; public final class RecipeUtil { @@ -298,7 +302,12 @@ public final class RecipeUtil { } } + @SuppressWarnings("deprecation") public static boolean isTagEmpty(TagKey tag) { return BuiltInRegistries.ITEM.getTag(tag).map(set -> !set.iterator().hasNext()).orElse(PreferredOres.getPreferredOre(tag) == Items.AIR); } + + public static LootContext emptyLootContext(ServerLevel level) { + return new LootContext.Builder(new LootParams(level, Map.of(), Map.of(), 0)).create(null); + } } diff --git a/src/main/java/thedarkcolour/exdeorum/recipe/sieve/SieveRecipe.java b/src/main/java/thedarkcolour/exdeorum/recipe/sieve/SieveRecipe.java index 8a272197..76a89d5c 100644 --- a/src/main/java/thedarkcolour/exdeorum/recipe/sieve/SieveRecipe.java +++ b/src/main/java/thedarkcolour/exdeorum/recipe/sieve/SieveRecipe.java @@ -87,6 +87,7 @@ public class SieveRecipe extends ProbabilityRecipe { return new SieveRecipe(id, ingredient, mesh, result, resultAmount, byHandOnly); } + @SuppressWarnings("deprecation") @Override public @Nullable SieveRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) { Ingredient ingredient = Ingredient.fromNetwork(buffer); @@ -96,6 +97,7 @@ public class SieveRecipe extends ProbabilityRecipe { return new SieveRecipe(id, ingredient, mesh, result, resultAmount, buffer.readBoolean()); } + @SuppressWarnings("deprecation") @Override public void toNetwork(FriendlyByteBuf buffer, SieveRecipe recipe) { recipe.getIngredient().toNetwork(buffer); diff --git a/src/main/java/thedarkcolour/exdeorum/registry/EBlockEntities.java b/src/main/java/thedarkcolour/exdeorum/registry/EBlockEntities.java index d8da56c8..07fb03fe 100644 --- a/src/main/java/thedarkcolour/exdeorum/registry/EBlockEntities.java +++ b/src/main/java/thedarkcolour/exdeorum/registry/EBlockEntities.java @@ -26,6 +26,7 @@ import thedarkcolour.exdeorum.ExDeorum; import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity; import thedarkcolour.exdeorum.blockentity.InfestedLeavesBlockEntity; import thedarkcolour.exdeorum.blockentity.LavaCrucibleBlockEntity; +import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity; import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity; import thedarkcolour.exdeorum.blockentity.SieveBlockEntity; import thedarkcolour.exdeorum.blockentity.WaterCrucibleBlockEntity; @@ -156,4 +157,5 @@ public class EBlockEntities { EBlocks.CRYSTALLIZED_SIEVE.get() ).build(null)); public static final RegistryObject> MECHANICAL_SIEVE = BLOCK_ENTITIES.register("mechanical_sieve", () -> BlockEntityType.Builder.of(MechanicalSieveBlockEntity::new, EBlocks.MECHANICAL_SIEVE.get()).build(null)); + public static final RegistryObject> MECHANICAL_HAMMER = BLOCK_ENTITIES.register("mechanical_hammer", () -> BlockEntityType.Builder.of(MechanicalHammerBlockEntity::new, EBlocks.MECHANICAL_HAMMER.get()).build(null)); } diff --git a/src/main/java/thedarkcolour/exdeorum/registry/EBlocks.java b/src/main/java/thedarkcolour/exdeorum/registry/EBlocks.java index b300b0bf..905a4be7 100644 --- a/src/main/java/thedarkcolour/exdeorum/registry/EBlocks.java +++ b/src/main/java/thedarkcolour/exdeorum/registry/EBlocks.java @@ -121,6 +121,8 @@ public class EBlocks { public static final RegistryObject CRYSTALLIZED_SIEVE = registerSieve("crystallized_sieve", SoundType.GLASS); // Mechanical Sieve (todo add properties) public static final RegistryObject MECHANICAL_SIEVE = BLOCKS.register("mechanical_sieve", () -> new MechanicalSieveBlock(of())); + // Mechanical Hammer (todo add properties) + public static final RegistryObject MECHANICAL_HAMMER = BLOCKS.register("mechanical_hammer", () -> new MechanicalHammerBlock(of())); // Lava Crucibles public static final RegistryObject PORCELAIN_CRUCIBLE = registerLavaCrucible("porcelain_crucible", true, SoundType.STONE); diff --git a/src/main/java/thedarkcolour/exdeorum/registry/EItems.java b/src/main/java/thedarkcolour/exdeorum/registry/EItems.java index 03df6a7b..778ec879 100644 --- a/src/main/java/thedarkcolour/exdeorum/registry/EItems.java +++ b/src/main/java/thedarkcolour/exdeorum/registry/EItems.java @@ -225,6 +225,7 @@ public class EItems { public static final RegistryObject CRYSTALLIZED_SIEVE = registerItemBlock(EBlocks.CRYSTALLIZED_SIEVE); // Mechanical Sieves public static final RegistryObject MECHANICAL_SIEVE = registerItemBlock(EBlocks.MECHANICAL_SIEVE); + public static final RegistryObject MECHANICAL_HAMMER = registerItemBlock(EBlocks.MECHANICAL_HAMMER); // Lava Crucibles public static final RegistryObject PORCELAIN_CRUCIBLE = registerItemBlock(EBlocks.PORCELAIN_CRUCIBLE); @@ -365,6 +366,7 @@ public class EItems { output.accept(CRYSTALLIZED_SIEVE.get()); } output.accept(MECHANICAL_SIEVE.get()); + output.accept(MECHANICAL_HAMMER.get()); output.accept(PORCELAIN_CRUCIBLE.get()); output.accept(WARPED_CRUCIBLE.get()); diff --git a/src/main/java/thedarkcolour/exdeorum/registry/EMenus.java b/src/main/java/thedarkcolour/exdeorum/registry/EMenus.java index a8750394..f4d95353 100644 --- a/src/main/java/thedarkcolour/exdeorum/registry/EMenus.java +++ b/src/main/java/thedarkcolour/exdeorum/registry/EMenus.java @@ -25,10 +25,12 @@ import net.minecraftforge.network.IContainerFactory; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.RegistryObject; import thedarkcolour.exdeorum.ExDeorum; +import thedarkcolour.exdeorum.blockentity.MechanicalHammerMenu; import thedarkcolour.exdeorum.menu.MechanicalSieveMenu; public class EMenus { public static final DeferredRegister> MENUS = DeferredRegister.create(Registries.MENU, ExDeorum.ID); public static final RegistryObject> MECHANICAL_SIEVE = MENUS.register("mechanical_sieve", () -> new MenuType<>((IContainerFactory) MechanicalSieveMenu::new, FeatureFlags.DEFAULT_FLAGS)); + public static final RegistryObject> MECHANICAL_HAMMER = MENUS.register("mechanical_hammer", () -> new MenuType<>((IContainerFactory) MechanicalHammerMenu::new, FeatureFlags.DEFAULT_FLAGS)); } diff --git a/src/main/resources/assets/exdeorum/textures/gui/container/mechanical_hammer.png b/src/main/resources/assets/exdeorum/textures/gui/container/mechanical_hammer.png new file mode 100644 index 0000000000000000000000000000000000000000..3cc69158485c517b8d59912ccd2d61aa1703a417 GIT binary patch literal 3109 zcmds3>0c9R60Qz(C!G!fR8Sz?ha4H?5>~kq4mrHChytPzkrBiZF(Sy_AZP$NR9G&N zfQ$!%9LnebLO4{sQ4v8M4`du%7?BZ2yvR1}hnf8swtv;X>U!&`r>eT@!<#8suTVj#_`;S!<7vhYOs$!+Ap)@?rede1OJ0;_DU^fR-&- z0URtXEvpE)paAC;potO|G_ata1?N~$%YqyRXlrX9W(cuRM>|j6y z1GY0DoDRV#@cDcmkLT>{TtL840*(+6&wv^hTxLTX8(P`W!iJv};F1Cq;7~-szX&KK zAdvx4IP9W?0g(*Y$$+gGxVpN!xVV(CpqLT@k{M8^09}gEsR&Xwbg-eF4JAw{Wx;M7 zzNbUI0`w?Cw<44gP{slg4%_H(jDR#8$_bD)HMLQNsi$;ruOsh*>SroFj_o#{eq509Ll_ami-qJ7q^qZac2@_{M-fi|j1Jjyd* z4*DkIvonYaPo5F`|b<+{n)4A0(Z_eKVK!A_oG;Ur2L8Q2;J73UEWCZgZ)+ht#aYo;iKXwV!Cwurz)-&th8ZdTqe@u)AmO`AMI)v?NTF z#mc_YwT@Y-&$^Y8d#g4YbS+9k9omGQX&zch!fKuC`ADPv-t+TbIkHJ)Sc< zrM2~B+*!Z+p!3^qZ#;}m=wODMXf;<>H(Ze~-<46c)b?E9#kaqF7_<9fpW8Udpwk z_YC<*DAJz`=!t%l*DH(8irYg;w-Ko?74ev5To)xTOtj5R$;q>QBjZdrhR+9 zxa7r33h;TEL~4gz#|lvHjCaVd(oH=Q`MsEdhCsDpYV02&>eHB|@!=SDxac;rsA6>m zx=+EF5QmY4atA`mM`RON(*4ETUj$N7pEx?5^vovG4HGYzW>ZZjU@uNAK*}PoEoVvP!&E+ z0#m#IEsj|%zP}=Xw<4Li^hnOasjMCMu${C%kAgA(B{n7CExu_s@=u#3RcNv zbn&|(iP{%AMg_a9(KS6Pg;YyOXT*w&8&@8R%F9>#B9F&rmNc#_h^mmNC1l{SS*4AE z$D-;R)Fud}x2krpa+JG1qPO;iiQncZPfT3cR~E@Yq9<4-q!PLN3q}YLE{VPv$D}lW zAf%U)_M;7;Dy5B_sVmZYI#LzgDHe5xj6BUs%&U{UhrQP(W>T%HCv^u+EjgUU0yLG(33SC!nmklxj-S-`#= zQK?F)N@^j^&#Y>Q_h$7y_NXp6Ay>C5tl&$}uTtrs0qvz`!eAM(LRxXzuVcX2_<7D;{{o@yrK%O@} z9uJRHE;_Y0cIA%Hybf$0&BwlP6|dTTTlm=t6CvUGhPMRSSvT-buddEbE&p+95N!kk zdmc{OCkOH(=%x7J(7;a~xp#h>)ZhETV~Ix^qoz-@o@=Dke$n>j+_$-R z6hVCWqUm9gEIZ4!)F|Fcj~C_-*vi>8?NpUK3_7j#CQiRhTYfW%Og@;Yzd!1_HKb7n Y-cFewjlWi2psp9-<-W%4oQp8+Kh@hP@&Et; literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/exdeorum/textures/item/empty_slot_hammer.png b/src/main/resources/assets/exdeorum/textures/item/empty_slot_hammer.png new file mode 100644 index 0000000000000000000000000000000000000000..621a616f9b4e56dc9e1c25f7fb85f771b9635271 GIT binary patch literal 2854 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 Date: Sat, 13 Jan 2024 23:20:20 -0800 Subject: [PATCH 3/7] Save --- .../exdeorum/block/MechanicalHammerBlock.java | 11 ++++++++++- .../blockentity/MechanicalHammerBlockEntity.java | 4 ++++ .../exdeorum/blockstates/mechanical_hammer.json | 10 ++++++++++ .../exdeorum/models/block/mechanical_hammer_off.json | 8 ++++++++ .../exdeorum/models/block/mechanical_hammer_on.json | 8 ++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/assets/exdeorum/blockstates/mechanical_hammer.json create mode 100644 src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json create mode 100644 src/main/resources/assets/exdeorum/models/block/mechanical_hammer_on.json diff --git a/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java index 08ac1d16..431f3ac3 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java @@ -25,19 +25,28 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.jetbrains.annotations.Nullable; import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity; import thedarkcolour.exdeorum.registry.EBlockEntities; public class MechanicalHammerBlock extends EBlock { + public static final BooleanProperty RUNNING = BooleanProperty.create("running"); + public MechanicalHammerBlock(Properties properties) { super(properties, EBlockEntities.MECHANICAL_HAMMER); } + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(RUNNING); + } + @SuppressWarnings("unchecked") @Nullable @Override - public BlockEntityTicker getTicker(Level level, BlockState pState, BlockEntityType type) { + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { return type == EBlockEntities.MECHANICAL_HAMMER.get() && !level.isClientSide ? (BlockEntityTicker) new MechanicalHammerBlockEntity.ServerTicker<>() : null; } diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java index bee00e16..bde705b7 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java @@ -33,6 +33,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.storage.loot.LootContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import thedarkcolour.exdeorum.block.MechanicalHammerBlock; import thedarkcolour.exdeorum.blockentity.helper.ItemHelper; import thedarkcolour.exdeorum.config.EConfig; import thedarkcolour.exdeorum.data.TranslationKeys; @@ -101,6 +102,7 @@ public class MechanicalHammerBlockEntity extends AbstractMachineBlockEntity Date: Thu, 25 Jan 2024 11:23:43 -0800 Subject: [PATCH 4/7] Fix dupe glitch that was carried over from Mechanical Sieve --- .../java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java b/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java index 069ee579..79bee067 100644 --- a/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java +++ b/src/main/java/thedarkcolour/exdeorum/menu/MechanicalSieveMenu.java @@ -61,7 +61,7 @@ public class MechanicalSieveMenu extends AbstractMachineMenu 1 && clickedSlot <= NUM_SLOTS) { // moving out of output slots + if (clickedSlot > 1 && clickedSlot < NUM_SLOTS) { // moving out of output slots if (!moveItemStackTo(clickedStack, NUM_SLOTS, PLAYER_SLOTS + NUM_SLOTS, true)) { return ItemStack.EMPTY; } From 7a2d37a634bae9003a8f0bff5d277fd1491924aa Mon Sep 17 00:00:00 2001 From: thedarkcolour <30441001+thedarkcolour@users.noreply.github.com> Date: Fri, 26 Jan 2024 10:24:31 -0800 Subject: [PATCH 5/7] Placeholder models and balance changes (no longer requires hammer item) --- .../59eb3dbb5f86130e09b3c62d89b9525ee01cf52d | 3 ++- .../93943142017732f21fbc4fa325d116c728b69767 | 4 ++-- .../fc2b6ffd874afaa6f2f20b450921dbfbbc8b86bd | 3 ++- .../resources/assets/exdeorum/lang/en_us.json | 2 ++ .../models/item/mechanical_hammer.json | 3 +++ .../loot_tables/blocks/mechanical_hammer.json | 21 ++++++++++++++++++ .../exdeorum/block/MechanicalHammerBlock.java | 2 ++ .../MechanicalHammerBlockEntity.java | 20 ++++++++++++----- .../thedarkcolour/exdeorum/data/English.java | 1 - .../exdeorum/data/TranslationKeys.java | 1 - .../exdeorum/registry/EBlocks.java | 2 +- .../models/block/mechanical_hammer_off.json | 2 +- .../block/mechanical_hammer_front.png | Bin 0 -> 623 bytes .../block/mechanical_hammer_front_on.png | Bin 0 -> 748 bytes .../mechanical_hammer_front_on.png.mcmeta | 6 +++++ .../textures/block/mechanical_hammer_side.png | Bin 0 -> 612 bytes .../textures/block/mechanical_hammer_top.png | Bin 0 -> 691 bytes 17 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json create mode 100644 src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json create mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front.png create mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front_on.png create mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front_on.png.mcmeta create mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_side.png create mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_top.png diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d index 25abef90..2ee36603 100644 --- a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d +++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -1,4 +1,4 @@ -// 1.20.1 2024-01-10T20:18:25.7260241 Loot Tables +// 1.20.1 2024-01-25T14:16:46.237861 Loot Tables 105d8a61ea7145d7798146d385d4aad24fd1588d data/exdeorum/loot_tables/blocks/acacia_barrel.json 1e77127a82cbba0937bb02694f65cf1893aeffcb data/exdeorum/loot_tables/blocks/acacia_crucible.json fcc00910a8cc94bed6339d6833fcec53c501a0d7 data/exdeorum/loot_tables/blocks/acacia_sieve.json @@ -73,6 +73,7 @@ b38104ee25127d9c65ad9e323ed879f76df7a048 data/exdeorum/loot_tables/blocks/mangro 475b89fd8f09834652f80c93d8a6d0964d708ead data/exdeorum/loot_tables/blocks/maple_barrel.json 54f36187d7fb97dedc4680d14e2ad7d70b5c64af data/exdeorum/loot_tables/blocks/maple_crucible.json 7ffe80360af055f3977d05b5684a299886bcb756 data/exdeorum/loot_tables/blocks/maple_sieve.json +926a9224e747bf53eb81448c1abb55d73fce5092 data/exdeorum/loot_tables/blocks/mechanical_hammer.json a84508222cb36b07cb20ee31915d802bcc411149 data/exdeorum/loot_tables/blocks/mechanical_sieve.json cad973c873a2e50ccfac91e88eadb3c2462d39d1 data/exdeorum/loot_tables/blocks/oak_barrel.json f94bc97efbfd26ccf7dba32d414fb5e33decd5f6 data/exdeorum/loot_tables/blocks/oak_crucible.json diff --git a/src/generated/resources/.cache/93943142017732f21fbc4fa325d116c728b69767 b/src/generated/resources/.cache/93943142017732f21fbc4fa325d116c728b69767 index ec55f3e3..6237fdac 100644 --- a/src/generated/resources/.cache/93943142017732f21fbc4fa325d116c728b69767 +++ b/src/generated/resources/.cache/93943142017732f21fbc4fa325d116c728b69767 @@ -1,2 +1,2 @@ -// 1.20.1 2024-01-12T17:15:18.0568334 ModKit Language: en_us for mod 'exdeorum' -134e71f17cef95d72141a3d6431db5eb8438f3a0 assets/exdeorum/lang/en_us.json +// 1.20.1 2024-01-25T14:16:46.2316734 ModKit Language: en_us for mod 'exdeorum' +248ab1a837b9857fb1928e826cb02f9f142e8d96 assets/exdeorum/lang/en_us.json diff --git a/src/generated/resources/.cache/fc2b6ffd874afaa6f2f20b450921dbfbbc8b86bd b/src/generated/resources/.cache/fc2b6ffd874afaa6f2f20b450921dbfbbc8b86bd index 57425b7f..f3d7bef9 100644 --- a/src/generated/resources/.cache/fc2b6ffd874afaa6f2f20b450921dbfbbc8b86bd +++ b/src/generated/resources/.cache/fc2b6ffd874afaa6f2f20b450921dbfbbc8b86bd @@ -1,4 +1,4 @@ -// 1.20.1 2024-01-10T20:18:25.7240245 ModKit Item Models for mod 'exdeorum' +// 1.20.1 2024-01-25T14:16:46.2347562 ModKit Item Models for mod 'exdeorum' 4ba3bb2c6174ac3728a4b85e34681f118ec8eb34 assets/exdeorum/models/item/acacia_barrel.json c03ce41f7c071498fcbd5f5225e91dcb2f365fbb assets/exdeorum/models/item/acacia_crucible.json 3b4f1d45c0d9c4cd1d9a5cdf6ddc8d2c9791bca5 assets/exdeorum/models/item/acacia_sieve.json @@ -105,6 +105,7 @@ ff89dc05408074da0e9d41bfef91dfe975302403 assets/exdeorum/models/item/mahogany_cr c3f2af2a88cd97148b05efbd6e24fc2558fcc0b8 assets/exdeorum/models/item/maple_barrel.json cc045825c562e9133858ce5cfe6e6f1dcb747d8e assets/exdeorum/models/item/maple_crucible.json a64e9b9ce91ac6b2f36690a770afc52b8900a614 assets/exdeorum/models/item/maple_sieve.json +59cdfe2c26f9d4a16ab7e8e7a87c97403eafa562 assets/exdeorum/models/item/mechanical_hammer.json 1e2b482f5fc4d283f5ca12919b575f86dc4a9541 assets/exdeorum/models/item/mechanical_sieve.json d543d3e18bdcf2bf79a762b52cc61a4161124db1 assets/exdeorum/models/item/mycelium_spores.json 1f48b2ce3452ce5d02142c9f663ae7bdb7d1d934 assets/exdeorum/models/item/netherite_hammer.json diff --git a/src/generated/resources/assets/exdeorum/lang/en_us.json b/src/generated/resources/assets/exdeorum/lang/en_us.json index 16e4643d..4f527d21 100644 --- a/src/generated/resources/assets/exdeorum/lang/en_us.json +++ b/src/generated/resources/assets/exdeorum/lang/en_us.json @@ -84,6 +84,7 @@ "block.exdeorum.maple_barrel": "Maple Barrel", "block.exdeorum.maple_crucible": "Maple Crucible", "block.exdeorum.maple_sieve": "Maple Sieve", + "block.exdeorum.mechanical_hammer": "Mechanical Hammer", "block.exdeorum.mechanical_sieve": "Mechanical Sieve", "block.exdeorum.oak_barrel": "Oak Barrel", "block.exdeorum.oak_crucible": "Oak Crucible", @@ -118,6 +119,7 @@ "block.exdeorum.willow_crucible": "Willow Crucible", "block.exdeorum.willow_sieve": "Willow Sieve", "block.exdeorum.witch_water": "Witch Water", + "exdeorum.container.mechanical_hammer": "Mechanical Hammer", "exdeorum.container.mechanical_sieve": "Mechanical Sieve", "fluid_type.exdeorum.witch_water": "Witch Water", "generator.exdeorum.void_world": "Void World", diff --git a/src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json b/src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json new file mode 100644 index 00000000..17f008c8 --- /dev/null +++ b/src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json @@ -0,0 +1,3 @@ +{ + "parent": "exdeorum:block/mechanical_hammer" +} \ No newline at end of file diff --git a/src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json b/src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json new file mode 100644 index 00000000..96c595e8 --- /dev/null +++ b/src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "exdeorum:mechanical_hammer" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "exdeorum:blocks/mechanical_hammer" +} \ No newline at end of file diff --git a/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java index 431f3ac3..05dd2eec 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java @@ -36,6 +36,8 @@ public class MechanicalHammerBlock extends EBlock { public MechanicalHammerBlock(Properties properties) { super(properties, EBlockEntities.MECHANICAL_HAMMER); + + registerDefaultState(defaultBlockState().setValue(RUNNING, false)); } @Override diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java index bde705b7..4b161191 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/MechanicalHammerBlockEntity.java @@ -49,12 +49,12 @@ public class MechanicalHammerBlockEntity extends AbstractMachineBlockEntity= TOTAL_PROGRESS) { @@ -178,9 +182,13 @@ public class MechanicalHammerBlockEntity extends AbstractMachineBlockEntity CRYSTALLIZED_SIEVE = registerSieve("crystallized_sieve", SoundType.GLASS); // Mechanical Sieve (todo add properties) public static final RegistryObject MECHANICAL_SIEVE = BLOCKS.register("mechanical_sieve", () -> new MechanicalSieveBlock(of())); - // Mechanical Hammer (todo add properties) + // Mechanical Hammer public static final RegistryObject MECHANICAL_HAMMER = BLOCKS.register("mechanical_hammer", () -> new MechanicalHammerBlock(of())); // Lava Crucibles diff --git a/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json b/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json index b2d895cd..a56fbca2 100644 --- a/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json +++ b/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json @@ -1,7 +1,7 @@ { "parent": "minecraft:block/orientable", "textures": { - "front": "exdeorum:block/mechanical_hammer_front_off", + "front": "exdeorum:block/mechanical_hammer_front", "side": "exdeorum:block/mechanical_hammer_side", "top": "exdeorum:block/mechanical_hammer_top" } diff --git a/src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front.png b/src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front.png new file mode 100644 index 0000000000000000000000000000000000000000..b1be1bacd68d11d9aba0e8d1f4ffe29a3376625b GIT binary patch literal 623 zcmV-#0+9WQP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0t87!K~y+TWsyB^ z+E5gRv2ig58;sJF-w;-4Cbnj3R+0>?{1KMW4Jq9b3cm+LGp2G0feMU@1Q_r)?&Dfw z=^gGpAMZKmJ?|B|-LCKZsZ{E4I7pJ@I8HX3#SMahxF86*TyC{m5m8l@taLmcE0s#Q zTqeZPG>w}|Zrip&V1ThK3u8PU#|h5&r>CN>C-(n`-oNMb`-g}9elJB)MElKV^W)_O z8ni4Hi-5u~Ox#Q+BZ^|ZUS~L!BI6*f>pD3YlLqH`-r0p12GuM>UlAvn3l5vrUDt*2 z*(H@=w%cty4U1-!q6r~f3P_w?&=~o=ifx*v#2&D!R%=&RmG%11#l=V0bFH0q`RNh_ zG*nHUPNsBOnI^3znz47SR&`ugN~e>7g+d`bofr#scDTO&tmJZzZIhLj%Oy|rPdns7 zkfer2rBaC-7be_j6HiD*5eg26Lk#{aBg-G8xJ&YP5C#Vy&ez*pl!&7|++S{PTCEoJ z27^JP(STL2*K0PL%3vMk305M;exGmhMNwE07x}?W-`;k+9W}G}cj7-^Ut>xXsG0`X#bVKJx6|qLFT?oO>7c=AH0nG) z0-8)Fv`1o!h5Ng^m{kzquo;a{VTemm$!0y@N9!OAxnqFm{RJ)IbFL+(QU3q{002ov JPDHLkV1iZJ5NrSd literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front_on.png b/src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front_on.png new file mode 100644 index 0000000000000000000000000000000000000000..03af2409cc0ae0fd6fbd0210d7ebf6033bd0ae10 GIT binary patch literal 748 zcmVPx#1ZP1_K>z@;j|==^1poj6EKp2TMURhdU|?=g@tc#Z*y~V zudlDh#>Ugr)7RJ6&d$!fyu4XhSZHWybaZrtgoH^*NYGRb?Oh6DVq)!w3SVAc@S;Mu zx3_h5b!us9US3{&dwg&eSL|FiDP18p`f5vR#v;ayRfgXsHmu{tE;4= zqq4EFpP!$co12r8lAxcTsi~=5U0t-aw9CuO&CSil#l^tDz_GEhPEJl;TwJ)gxO{wk ze0zIQbc6MuOYHVw3Wn^SZN=m=Kzrw=8QBhH8X=$yktyNT1l#`QU zVPTt^nw^}Sj*X3ifq_<4Rf>s;O-xLnprE6pqo$^&goA^vtgL%_dRSOkOiWBlNl8UT zMNUmkNJvObOG{HyQX0SvqyPW_32;bRa{vGi!TE6m&!s8Fxek-v1r!1d72cWALQ?)1J#OKY+ub zI8~=paj9-iQ$64&lv1zP=krq2j3E;v!k`+c zVu2hP+F?YZpwcjM&h5)F7Fh-@uo5@ot81Q+x*pp|Y(g}-wVg`s?2>e*mDm@HgCxo3 z^7%sUkWxa9icl(7j!#a{sI|8p=L3`e~`dq|O~hZLE3h|ff1 z;=#ppEHY0IrWb6IZx3W;Hsis08~@)!)??ZaSr6F{8)GaYJp{&BWZwO-NoM-NnhbyR e1Nm<}M!heMh-`woR@^!O0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!T2#W=DKiX5Bh`JDWekR(ti7GsMXA(iG>QdK%?wNiaCp0cgpre)1~Kfg zF+I9tbXB}I%rwp6aHv9@+))ov*EG|z*Z?ki&{7dyEEcH7Hol5V0~i^oAf?_SUC~nY y<@p)so+LQj0Sp0f2{sHP23yL6PNXaf;`kqvaa6rUS1Sf*ZOGo6bs2~Xo#3&%>#-FG; z)dUxvb5GyX)m7E4ak*S@I-L?LD=S!CUB&Y9vYZU&Y&M(Z91aJTmX;)Vw^%IDFnM-% zhD1F66QxoKnRFUg*{nqJ@>25AlM}>ZF?s*z@KC@7AgvyIy+1{8 z&(GN3-^XAuko?xx7H)5Ead&rz69py=>~=dcnT!<-j|W-BOc<=MucKHfAfL}m@o+dqqtU?8(Gj}cE-IA@g25oF)hh1q?-4#Y!1wnz zE-o&_3k}U^Hk(rL_Vy;hf?BO6MFb@XWBjIGuZt&Es}&lz+byQCb3w5Pg+kKl>FEi{ zWD<{$k8-C378ev-e$z;^*$fS7Tq|wt==b}jkcOpFDe>ju;X&xKm>z9zZVI#0(^D9Y zMrcTb0Hpfz@*)ls==1YaK$&L&JNtb;BoYa^|5kYcSX^90R!!mc^;J-*|NZ@4m{2nd zsh<<+bUKJD?fi~Lqc9i@3SeOYaixc2;dn@yOTBv#zmT$nHd4_LJ5)MV|cc=r7Kxcf2-9J6KP(t zSd^vXMzTgE%+Jjsq{cGtkXHF4LlU4A;iSNP=;G9t>VgCX<|c1*)5zgjTDSFicNlVqyaNsi~jy*X*pk Z`w#P6>T7 Date: Thu, 1 Feb 2024 18:33:47 -0800 Subject: [PATCH 6/7] Added model (may change later, not very good but best I could come up with) --- .../models/item/mechanical_hammer.json | 2 +- .../blockstates/mechanical_hammer.json | 28 ++++++++++++++++-- .../models/block/mechanical_hammer_off.json | 5 ++-- .../models/block/mechanical_hammer_on.json | 5 ++-- .../block/mechanical_hammer_bottom.png | Bin 0 -> 712 bytes .../block/mechanical_hammer_front.png | Bin 623 -> 609 bytes .../block/mechanical_hammer_front_on.png | Bin 748 -> 647 bytes .../mechanical_hammer_front_on.png.mcmeta | 6 ---- .../textures/block/mechanical_hammer_side.png | Bin 612 -> 614 bytes .../textures/block/mechanical_hammer_top.pdn | Bin 0 -> 4966 bytes .../textures/block/mechanical_hammer_top.png | Bin 691 -> 701 bytes 11 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_bottom.png delete mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_front_on.png.mcmeta create mode 100644 src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_top.pdn diff --git a/src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json b/src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json index 17f008c8..a35353c0 100644 --- a/src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json +++ b/src/generated/resources/assets/exdeorum/models/item/mechanical_hammer.json @@ -1,3 +1,3 @@ { - "parent": "exdeorum:block/mechanical_hammer" + "parent": "exdeorum:block/mechanical_hammer_off" } \ No newline at end of file diff --git a/src/main/resources/assets/exdeorum/blockstates/mechanical_hammer.json b/src/main/resources/assets/exdeorum/blockstates/mechanical_hammer.json index 3fe455ff..c37f7512 100644 --- a/src/main/resources/assets/exdeorum/blockstates/mechanical_hammer.json +++ b/src/main/resources/assets/exdeorum/blockstates/mechanical_hammer.json @@ -1,10 +1,34 @@ { "variants": { - "running=false": { + "facing=east,running=false": { + "model": "exdeorum:block/mechanical_hammer_off", + "y": 90 + }, + "facing=east,running=true": { + "model": "exdeorum:block/mechanical_hammer_on", + "y": 90 + }, + "facing=north,running=false": { "model": "exdeorum:block/mechanical_hammer_off" }, - "running=true": { + "facing=north,running=true": { "model": "exdeorum:block/mechanical_hammer_on" + }, + "facing=south,running=false": { + "model": "exdeorum:block/mechanical_hammer_off", + "y": 180 + }, + "facing=south,running=true": { + "model": "exdeorum:block/mechanical_hammer_on", + "y": 180 + }, + "facing=west,running=false": { + "model": "exdeorum:block/mechanical_hammer_off", + "y": 270 + }, + "facing=west,running=true": { + "model": "exdeorum:block/mechanical_hammer_on", + "y": 270 } } } \ No newline at end of file diff --git a/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json b/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json index a56fbca2..139ca47a 100644 --- a/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json +++ b/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_off.json @@ -1,8 +1,9 @@ { - "parent": "minecraft:block/orientable", + "parent": "minecraft:block/orientable_with_bottom", "textures": { "front": "exdeorum:block/mechanical_hammer_front", "side": "exdeorum:block/mechanical_hammer_side", - "top": "exdeorum:block/mechanical_hammer_top" + "top": "exdeorum:block/mechanical_hammer_top", + "bottom": "exdeorum:block/mechanical_hammer_bottom" } } \ No newline at end of file diff --git a/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_on.json b/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_on.json index 93d6b3f4..0f2af075 100644 --- a/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_on.json +++ b/src/main/resources/assets/exdeorum/models/block/mechanical_hammer_on.json @@ -1,8 +1,9 @@ { - "parent": "minecraft:block/orientable", + "parent": "minecraft:block/orientable_with_bottom", "textures": { "front": "exdeorum:block/mechanical_hammer_front_on", "side": "exdeorum:block/mechanical_hammer_side", - "top": "exdeorum:block/mechanical_hammer_top" + "top": "exdeorum:block/mechanical_hammer_top", + "bottom": "exdeorum:block/mechanical_hammer_bottom" } } \ No newline at end of file diff --git a/src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_bottom.png b/src/main/resources/assets/exdeorum/textures/block/mechanical_hammer_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..6fb79de0a8718029e6b9fe479ee89f3a79c79c1b GIT binary patch literal 712 zcmV;(0yq7MP)Px#1ZP1_K>z@;j|==^1poj6M^H>uMNCXgQ&Lh)OG`*dNKQ>nMMXtQNl8&rQCL`5 zR#jE6udlJNu*1W{xVN{uxw*Bpw5qA8tE;P}q@+zuOiD^hx3{;Ln3&<=;l#wmo}QlN z<>k-M&!C{7;^N|xl9Io_zsJYNsi~<|R8&q*PPn+ZoSdBB-{0Wi;Kakjyt})-y}gu_ zl)1UNU0htk!NI`5z~kfN&d$!Jrl#KB-o?empP!$`#>U9V$fKg7>gwvVv$N39(A?bI z$;rvh&CS8Uz@ed`%*@QSwYAI3%fZ3HU0q#PR#v;ayPKPvwzjs)%F27qnwpxvzP^{2 zm#C+wl#`Rw)6>Gj!l9s`z`wt~y}g*1mx_srsHmu;qocC2vX73A{7hwU00009a7bBm z000id000id0mpBsWB>pG3Q0skR47vo(C0#eP#6HvPZVzmY9XN(fr!|Un??vlSYd7~ zEi-7+pxyib&PO;0AV$QAc!DI8fR+$N0ZP#{&7?D#EWNyvVspT)^7%q>ZC%(Xh*C)| zgHp*$YPHI5ZVB5vH4OvWt*ebaecx!B*1@5TfjiP2r`a-9!_b{$8iT?#PEIYieP#(x zM@V&{*KZBn!Z1Iw9mzAt2vA==FAXkQs@a)L&C4EiuV&-swX1gwetyII3gAGijnaH} z%HFo`>MRHNo_~-YpGvyJgjr2SfaTfq%QR45ZSSoj$_kVtCVc<+41(Hd7|y>q$Q8fC uD4K}g&u`!N{}52rLJdihOe_|N82kgL;w@K|%uwq900004EwQQG2a5*fZI)$$pp|&J zTv8yUun$4wG=H0=81wmDOsCU+zkhM@?ez5Q_4UueK`&0?^=fS$S|HHWY?+VKM_4$_ zDIkO6(z)akp(uo56ltoO?{;JmAPU1z_D7+r$XZ@F91d$mfww=^+|6e5-|+X#iva!g z{CpDx{$gRiXH`w3jNGf$3dKFwepjej5 zl`f4u_Yi${sOu^I2>7RG_C*u002ovPDHLkV1lR!4Cw#> delta 561 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 M07*qoM6N<$f+}u7sQ>@~ From c8463d7c9cd4895ab9455023a2bcfc377ec7a85f Mon Sep 17 00:00:00 2001 From: thedarkcolour <30441001+thedarkcolour@users.noreply.github.com> Date: Thu, 1 Feb 2024 18:55:56 -0800 Subject: [PATCH 7/7] Loot table, tooltip, recipe, JEI information, on and off states finished --- .../resources/assets/exdeorum/lang/en_us.json | 1 + .../recipes/misc/mechanical_hammer.json | 35 ++++++++++ .../loot_tables/blocks/mechanical_hammer.json | 5 ++ .../exdeorum/recipes/mechanical_hammer.json | 27 ++++++++ .../exdeorum/block/MechanicalHammerBlock.java | 65 ++++++++++++++++++- .../AbstractMachineBlockEntity.java | 4 ++ .../MechanicalHammerBlockEntity.java | 9 ++- .../compat/jei/ExDeorumJeiPlugin.java | 2 + .../exdeorum/data/BlockLoot.java | 5 ++ .../thedarkcolour/exdeorum/data/English.java | 2 + .../exdeorum/data/TranslationKeys.java | 2 + .../exdeorum/data/recipe/Recipes.java | 10 +++ 12 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 src/generated/resources/data/exdeorum/advancements/recipes/misc/mechanical_hammer.json create mode 100644 src/generated/resources/data/exdeorum/recipes/mechanical_hammer.json diff --git a/src/generated/resources/assets/exdeorum/lang/en_us.json b/src/generated/resources/assets/exdeorum/lang/en_us.json index 4f527d21..7ac9a366 100644 --- a/src/generated/resources/assets/exdeorum/lang/en_us.json +++ b/src/generated/resources/assets/exdeorum/lang/en_us.json @@ -146,6 +146,7 @@ "gui.exdeorum.redstone_control.unpowered": "Unpowered", "info.exdeorum.crimson_nylium_spores": "Use on netherrack to turn it into a crimson nylium block.", "info.exdeorum.grass_seeds": "Use on dirt to turn it into a grass block.", + "info.exdeorum.mechanical_hammer": "The Mechanical Hammer is a machine that, when supplied with Forge Energy (FE), will hammer blocks without a player having to do it themselves. It can operate without a hammer, but adding any hammer will double the speed, and efficiency enchantments on the hammer will further increase speed. It also supports three different modes of redstone control. Since Ex Deorum does not provide a way to generate FE, you will need another mod to provide power.", "info.exdeorum.mechanical_sieve": "The Mechanical Sieve is a machine that, when supplied with a mesh and Forge Energy (FE), will sift blocks without a player having to do it themselves. It also supports three different modes of redstone control. Since Ex Deorum does not provide a way to generate FE, you will need another mod to provide power.", "info.exdeorum.mycelium_spores": "Use on dirt to turn it into mycelium.", "info.exdeorum.sculk_core": "Use a sculk core on a Sculk Shrieker to enable it to spawn Wardens. Normally, Sculk Shriekers placed by players cannot spawn Wardens, so this item is useful for obtaining Sculk items in a SkyBlock world.", diff --git a/src/generated/resources/data/exdeorum/advancements/recipes/misc/mechanical_hammer.json b/src/generated/resources/data/exdeorum/advancements/recipes/misc/mechanical_hammer.json new file mode 100644 index 00000000..376331ae --- /dev/null +++ b/src/generated/resources/data/exdeorum/advancements/recipes/misc/mechanical_hammer.json @@ -0,0 +1,35 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "items": [ + "minecraft:hopper" + ] + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "exdeorum:mechanical_hammer" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "exdeorum:mechanical_hammer" + ] + }, + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json b/src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json index 96c595e8..674d4b46 100644 --- a/src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json +++ b/src/generated/resources/data/exdeorum/loot_tables/blocks/mechanical_hammer.json @@ -11,6 +11,11 @@ "entries": [ { "type": "minecraft:item", + "functions": [ + { + "function": "exdeorum:machine" + } + ], "name": "exdeorum:mechanical_hammer" } ], diff --git a/src/generated/resources/data/exdeorum/recipes/mechanical_hammer.json b/src/generated/resources/data/exdeorum/recipes/mechanical_hammer.json new file mode 100644 index 00000000..8313165b --- /dev/null +++ b/src/generated/resources/data/exdeorum/recipes/mechanical_hammer.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "#": { + "item": "minecraft:iron_block" + }, + "H": { + "item": "minecraft:hopper" + }, + "I": { + "item": "minecraft:iron_ingot" + }, + "T": { + "tag": "exdeorum:hammers" + } + }, + "pattern": [ + "III", + "ITI", + "#H#" + ], + "result": { + "item": "exdeorum:mechanical_hammer" + }, + "show_notification": true +} \ No newline at end of file diff --git a/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java index 05dd2eec..dd1565c0 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/MechanicalHammerBlock.java @@ -18,21 +18,40 @@ package thedarkcolour.exdeorum.block; +import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraftforge.items.ItemStackHandler; import org.jetbrains.annotations.Nullable; import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity; +import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity; +import thedarkcolour.exdeorum.config.EConfig; +import thedarkcolour.exdeorum.data.TranslationKeys; import thedarkcolour.exdeorum.registry.EBlockEntities; +import java.util.List; + public class MechanicalHammerBlock extends EBlock { public static final BooleanProperty RUNNING = BooleanProperty.create("running"); + public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; public MechanicalHammerBlock(Properties properties) { super(properties, EBlockEntities.MECHANICAL_HAMMER); @@ -42,7 +61,7 @@ public class MechanicalHammerBlock extends EBlock { @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(RUNNING); + builder.add(RUNNING, FACING); } @SuppressWarnings("unchecked") @@ -52,7 +71,49 @@ public class MechanicalHammerBlock extends EBlock { return type == EBlockEntities.MECHANICAL_HAMMER.get() && !level.isClientSide ? (BlockEntityTicker) new MechanicalHammerBlockEntity.ServerTicker<>() : null; } - // todo creative drop and tooltip + @Override + public void appendHoverText(ItemStack stack, @Nullable BlockGetter level, List tooltip, TooltipFlag flag) { + var nbt = BlockItem.getBlockEntityData(stack); + if (nbt != null) { + var inventoryNbt = nbt.getCompound("inventory"); + var inventory = new ItemStackHandler(); + inventory.deserializeNBT(inventoryNbt); + var hammer = inventory.getStackInSlot(MechanicalHammerBlockEntity.HAMMER_SLOT); + if (!hammer.isEmpty()) { + tooltip.add(Component.translatable(TranslationKeys.MECHANICAL_HAMMER_HAMMER_LABEL).withStyle(ChatFormatting.GRAY).append(Component.translatable(hammer.getDescriptionId()))); + } + var energy = nbt.getInt("energy"); + tooltip.add(Component.translatable(TranslationKeys.ENERGY).withStyle(ChatFormatting.GRAY).append(Component.translatable(TranslationKeys.FRACTION_DISPLAY, energy, EConfig.SERVER.mechanicalSieveEnergyStorage.get())).append(" FE")); + } + } + + @Override + public void playerWillDestroy(Level level, BlockPos pos, BlockState pState, Player player) { + if (!level.isClientSide && player.isCreative() && level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { + if (level.getBlockEntity(pos) instanceof MechanicalHammerBlockEntity sieve) { + if (!sieve.inventory.getStackInSlot(MechanicalHammerBlockEntity.HAMMER_SLOT).isEmpty()) { + var stack = new ItemStack(this); + BlockItem.setBlockEntityData(stack, EBlockEntities.MECHANICAL_HAMMER.get(), sieve.saveWithoutMetadata()); + var itemEntity = new ItemEntity(level, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, stack); + itemEntity.setDefaultPickUpDelay(); + level.addFreshEntity(itemEntity); + } + } + } + + super.playerWillDestroy(level, pos, pState, player); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + var nbt = BlockItem.getBlockEntityData(context.getItemInHand()); + var state = defaultBlockState(); + if (nbt != null && nbt.contains("progress") && nbt.getInt("progress") != MechanicalHammerBlockEntity.NOT_RUNNING) { + state = state.setValue(RUNNING, true); + } + + return state.setValue(FACING, context.getHorizontalDirection().getOpposite()); + } @Override public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java index 73072078..3007c4d4 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractMachineBlockEntity.java @@ -149,6 +149,8 @@ public abstract class AbstractMachineBlockEntity> implements BlockEntityTicker { @Override public void tick(Level level, BlockPos pos, BlockState state, M machine) { @@ -163,6 +165,8 @@ public abstract class AbstractMachineBlockEntity { private static final Component TITLE = Component.translatable(TranslationKeys.MECHANICAL_HAMMER_SCREEN_TITLE); private static final int INPUT_SLOT = 0; - private static final int HAMMER_SLOT = 1; + public static final int HAMMER_SLOT = 1; private static final int OUTPUT_SLOT = 2; public static final int TOTAL_PROGRESS = 10_000_000; // process should take 200 ticks or 10 seconds with no efficiency @@ -111,6 +111,13 @@ public class MechanicalHammerBlockEntity extends AbstractMachineBlockEntity(); diff --git a/src/main/java/thedarkcolour/exdeorum/data/BlockLoot.java b/src/main/java/thedarkcolour/exdeorum/data/BlockLoot.java index 7b3487a0..f154bf65 100644 --- a/src/main/java/thedarkcolour/exdeorum/data/BlockLoot.java +++ b/src/main/java/thedarkcolour/exdeorum/data/BlockLoot.java @@ -65,6 +65,11 @@ class BlockLoot extends BlockLootSubProvider { .setRolls(ConstantValue.exactly(1.0F)) .add(LootItem.lootTableItem(EItems.MECHANICAL_SIEVE.get()) .apply(MachineLootFunction.machineLoot()))))); + add(EBlocks.MECHANICAL_HAMMER.get(), LootTable.lootTable() + .withPool(applyExplosionCondition(EItems.MECHANICAL_HAMMER.get(), LootPool.lootPool() + .setRolls(ConstantValue.exactly(1.0F)) + .add(LootItem.lootTableItem(EItems.MECHANICAL_HAMMER.get()) + .apply(MachineLootFunction.machineLoot()))))); } @Override diff --git a/src/main/java/thedarkcolour/exdeorum/data/English.java b/src/main/java/thedarkcolour/exdeorum/data/English.java index 3b0edb2c..99328e6d 100644 --- a/src/main/java/thedarkcolour/exdeorum/data/English.java +++ b/src/main/java/thedarkcolour/exdeorum/data/English.java @@ -31,6 +31,7 @@ class English { english.add(TranslationKeys.VOID_WORLD_TYPE, "Void World"); english.add(TranslationKeys.FRACTION_DISPLAY, ": %s / %s"); english.add(TranslationKeys.MECHANICAL_SIEVE_MESH_LABEL, "Mesh: "); + english.add(TranslationKeys.MECHANICAL_HAMMER_HAMMER_LABEL, "Hammer: "); english.add(TranslationKeys.ENERGY, "Energy"); english.add(TranslationKeys.ROOT_ADVANCEMENT_TITLE, "Don't Look Down..."); @@ -55,6 +56,7 @@ class English { english.add(TranslationKeys.CRIMSON_NYLIUM_SPORES_JEI_INFO, "Use on netherrack to turn it into a crimson nylium block."); english.add(TranslationKeys.SCULK_CORE_JEI_INFO, "Use a sculk core on a Sculk Shrieker to enable it to spawn Wardens. Normally, Sculk Shriekers placed by players cannot spawn Wardens, so this item is useful for obtaining Sculk items in a SkyBlock world."); english.add(TranslationKeys.MECHANICAL_SIEVE_JEI_INFO, "The Mechanical Sieve is a machine that, when supplied with a mesh and Forge Energy (FE), will sift blocks without a player having to do it themselves. It also supports three different modes of redstone control. Since Ex Deorum does not provide a way to generate FE, you will need another mod to provide power."); + english.add(TranslationKeys.MECHANICAL_HAMMER_JEI_INFO, "The Mechanical Hammer is a machine that, when supplied with Forge Energy (FE), will hammer blocks without a player having to do it themselves. It can operate without a hammer, but adding any hammer will double the speed, and efficiency enchantments on the hammer will further increase speed. It also supports three different modes of redstone control. Since Ex Deorum does not provide a way to generate FE, you will need another mod to provide power."); english.add(TranslationKeys.BARREL_COMPOST_CATEGORY_TITLE, "Barrel Compost"); english.add(TranslationKeys.BARREL_COMPOST_RECIPE_VOLUME, "Compost: %s"); diff --git a/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java b/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java index 3632c768..cfcce5ce 100644 --- a/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java +++ b/src/main/java/thedarkcolour/exdeorum/data/TranslationKeys.java @@ -27,6 +27,7 @@ public class TranslationKeys { // ": %s / %s" public static final String FRACTION_DISPLAY = "item." + ExDeorum.ID + ".watering_can_fluid_display"; public static final String MECHANICAL_SIEVE_MESH_LABEL = "item." + ExDeorum.ID + ".mechanical_sieve.mesh_label"; + public static final String MECHANICAL_HAMMER_HAMMER_LABEL = "item." + ExDeorum.ID + ".mechanical_hammer.hammer_label"; public static final String ENERGY = "gui." + ExDeorum.ID + ".energy_label"; // Advancements @@ -53,6 +54,7 @@ public class TranslationKeys { public static final String CRIMSON_NYLIUM_SPORES_JEI_INFO = "info." + ExDeorum.ID + ".crimson_nylium_spores"; public static final String SCULK_CORE_JEI_INFO = "info." + ExDeorum.ID + ".sculk_core"; public static final String MECHANICAL_SIEVE_JEI_INFO = "info." + ExDeorum.ID + ".mechanical_sieve"; + public static final String MECHANICAL_HAMMER_JEI_INFO = "info." + ExDeorum.ID + ".mechanical_hammer"; // JEI recipe categories public static final String BARREL_COMPOST_CATEGORY_TITLE = "gui." + ExDeorum.ID + ".category.barrel_compost"; diff --git a/src/main/java/thedarkcolour/exdeorum/data/recipe/Recipes.java b/src/main/java/thedarkcolour/exdeorum/data/recipe/Recipes.java index b914ce89..3917f50d 100644 --- a/src/main/java/thedarkcolour/exdeorum/data/recipe/Recipes.java +++ b/src/main/java/thedarkcolour/exdeorum/data/recipe/Recipes.java @@ -291,6 +291,16 @@ public class Recipes { recipe.pattern("I I"); MKRecipeProvider.unlockedByHaving(recipe, Items.HOPPER); }); + recipes.shapedCrafting(RecipeCategory.MISC, EItems.MECHANICAL_HAMMER.get(), recipe -> { + recipe.define('#', Items.IRON_BLOCK); + recipe.define('H', Items.HOPPER); + recipe.define('T', EItemTags.HAMMERS); + recipe.define('I', Items.IRON_INGOT); + recipe.pattern("III"); + recipe.pattern("ITI"); + recipe.pattern("#H#"); + MKRecipeProvider.unlockedByHaving(recipe, Items.HOPPER); + }); } private static void modUShaped(MKRecipeProvider recipes, String modid, RegistryObject sides, RegistryObject middle, RegistryObject result) {