Skip to content

Commit

Permalink
Add powered furnace block
Browse files Browse the repository at this point in the history
  • Loading branch information
Rearth committed Feb 24, 2024
1 parent f6582c2 commit 23791da
Show file tree
Hide file tree
Showing 17 changed files with 1,139 additions and 45 deletions.
29 changes: 11 additions & 18 deletions src/main/generated/.cache/19c08d24c255c2719fbb8ac01f9dff290b763461
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
// 1.20.4 2024-02-21T21:51:37.9684867 Oritech/Model Definitions
// 1.20.4 2024-02-23T22:04:26.5787369 Oritech/Model Definitions
c641d411ad252487b93d779cee9028b9ee920281 assets\oritech\blockstates\machine_core_basic.json
3d6f377b938592ac22aca17bd64561a6579ad217 assets\oritech\blockstates\grinder_block.json
90e28b721796ff7ee21c8eefe4525f03a251d2fb assets\oritech\models\block\machine_extender.json
16b697f4a40bfdcd8c39629776b97696e80681c7 assets\oritech\blockstates\machine_efficiency_addon.json
e9e01eaa866f29f36a31fd6872a4b1a499ce830b assets\oritech\models\item\machine_inventory_proxy_addon.json
b5ee97616ae0d2da17dfaecf45aa42f2cf19f691 assets\oritech\blockstates\machine_extender.json
eafe84c787830ab2a866e0878e9ed718d58659f5 assets\oritech\blockstates\banana_block.json
c9c5614f832a38e30b60d0a15d75292159b16455 assets\oritech\models\item\machine_speed_addon.json
25864df3cd7786f2bf4fe6fa9855b3cf366c28ca assets\oritech\models\item\banana.json
b8bc03092cb1eb686ede01daffc7421253af860c assets\oritech\models\item\machine_extender.json
746b98d721e5ae0d96dd769e71b786afa8c2d142 assets\oritech\models\item\banana_block.json
63f14855c688ce7ec236097ce232dd381cbc1538 assets\oritech\blockstates\addon_indicator_block.json
7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\machine_speed_addon.json
95eae9b13fb2835f15057d2fd4d9550192064ca4 assets\oritech\models\item\grinder_block.json
c641d411ad252487b93d779cee9028b9ee920281 assets\oritech\blockstates\machine_core_basic.json
6c9c0c9fbf5c26f5e8146a956b9e0567572acb45 assets\oritech\blockstates\machine_inventory_proxy_addon.json
f29468ff950a191567ab35557334666099ccd7cc assets\oritech\blockstates\assembler_block.json
964457f56e25b66dfef2160c8618bcaba2b640aa assets\oritech\blockstates\pulverizer_block.json
24c3ad5133727ec3d6d075af18fd96cf2687ec03 assets\oritech\models\block\machine_efficiency_addon.json
801af982fe394c02734dd407d3d6b960d9501dba assets\oritech\models\block\machine_speed_addon.json
505d30e3b61ee0ba1f2616e1226689e2cdb7ab58 assets\oritech\models\block\addon_indicator_block.json
e4497bad8afbd4f4b4e830d892284a05718b06dd assets\oritech\models\block\machine_core_basic.json
1b9cd3719105dc1e03398de41f2cab37337816fe assets\oritech\blockstates\machine_core_good.json
5462a2453fcdd2f8b99129894aec60f282d29ca9 assets\oritech\models\item\pulverizer_block.json
a3f9b72f6f36d42af4e5c3a87d7e180b2e36a2ed assets\oritech\models\item\machine_core_good.json
b5ee97616ae0d2da17dfaecf45aa42f2cf19f691 assets\oritech\blockstates\machine_extender.json
eafe84c787830ab2a866e0878e9ed718d58659f5 assets\oritech\blockstates\banana_block.json
a5651b8d4a27308b40c404f7cd3abcf9769b64b6 assets\oritech\models\item\machine_core_basic.json
469ea8a66c529fe26bc029c21092e7f062ed0e40 assets\oritech\models\block\banana_block.json
25864df3cd7786f2bf4fe6fa9855b3cf366c28ca assets\oritech\models\item\banana.json
d35ecef5df9198b12dc04267780c727c144b1959 assets\oritech\models\item\assembler_block.json
020ab18ae7f8883ba8928eb4a2d93defb0274c6b assets\oritech\models\block\machine_inventory_proxy_addon.json
823e02e06a2ca976d021d4ab1a0b63ffa6a89bea assets\oritech\models\item\machine_efficiency_addon.json
b8bc03092cb1eb686ede01daffc7421253af860c assets\oritech\models\item\machine_extender.json
746b98d721e5ae0d96dd769e71b786afa8c2d142 assets\oritech\models\item\banana_block.json
63f14855c688ce7ec236097ce232dd381cbc1538 assets\oritech\blockstates\addon_indicator_block.json
d54a0ed3dde3549c889fe4a585acb78301108fbe assets\oritech\blockstates\powedred_furnace_block.json
95eae9b13fb2835f15057d2fd4d9550192064ca4 assets\oritech\models\item\grinder_block.json
fe13536a509021e4ee1594cf477eb5ddd4e7d306 assets\oritech\models\item\powedred_furnace_block.json
3166a5959c87c4465c5eed82034d3178c4b8b518 assets\oritech\models\block\machine_core_good.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "oritech:block/powered_furnace_block"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public abstract class MachineBlockEntity extends BlockEntity
public static final RawAnimation WORKING = RawAnimation.begin().thenLoop("working");
protected final AnimatableInstanceCache animatableInstanceCache = GeckoLibUtil.createInstanceCache(this);
private final AnimationController<MachineBlockEntity> animationController = getAnimationController();
private int idleTicks = 0;

// crafting / processing
protected int progress;
Expand Down Expand Up @@ -92,12 +91,12 @@ public void tick(World world, BlockPos pos, BlockState state, MachineBlockEntity

if (recipeCandidate.isPresent() && canOutputRecipe(recipeCandidate.get().value())) {
// this is separate so that progress is not reset when out of energy
if (hasEnoughEnergy(recipeCandidate.get().value())) {
if (hasEnoughEnergy()) {
var activeRecipe = recipeCandidate.get().value();
currentRecipe = activeRecipe;

// check energy
useEnergy(activeRecipe);
useEnergy();

// increase progress
progress++;
Expand All @@ -120,20 +119,20 @@ public void tick(World world, BlockPos pos, BlockState state, MachineBlockEntity
}
}

private boolean hasEnoughEnergy(OritechRecipe recipe) {
protected boolean hasEnoughEnergy() {
return energyStorage.amount > calculateEnergyUsage();
}

@SuppressWarnings("lossy-conversions")
private void useEnergy(OritechRecipe recipe) {
protected void useEnergy() {
energyStorage.amount -= calculateEnergyUsage();
}

private float calculateEnergyUsage() {
return energyPerTick * getEfficiencyMultiplier() * (1 / getSpeedMultiplier());
}

private void updateNetwork() {
protected void updateNetwork() {

if (!networkDirty) return;

Expand Down Expand Up @@ -175,6 +174,8 @@ private void craftItem(OritechRecipe activeRecipe, List<ItemStack> outputInvento

var results = activeRecipe.getResults();
var inputs = activeRecipe.getInputs();

// create outputs
for (int i = 0; i < results.size(); i++) {
var result = results.get(i);
var slot = outputInventory.get(i);
Expand All @@ -187,6 +188,7 @@ private void craftItem(OritechRecipe activeRecipe, List<ItemStack> outputInvento
}
}

// remove inputs
for (int i = 0; i < inputs.size(); i++) {
var taken = Inventories.splitStack(inputInventory, i, 1); // amount is not configurable, because ingredient doesn't parse amount in recipe
}
Expand All @@ -197,12 +199,12 @@ private boolean checkCraftingFinished(OritechRecipe activeRecipe) {
return progress >= activeRecipe.getTime() * getSpeedMultiplier();
}

private void resetProgress() {
protected void resetProgress() {
progress = 0;
markNetDirty();
}

private void markNetDirty() {
protected void markNetDirty() {
networkDirty = true;
markDirty();
}
Expand All @@ -221,14 +223,20 @@ private boolean canOutputRecipe(OritechRecipe recipe) {

if (outSlot.isEmpty()) continue;

if (!result.getItem().equals(outSlot.getItem())) return false; // type mismatches
if (outSlot.getCount() + result.getCount() > outSlot.getMaxCount()) return false; // count too high
if (!canAddToSlot(result, outSlot)) return false;

}

return true;
}

protected boolean canAddToSlot(ItemStack input, ItemStack slot) {
if (slot.isEmpty()) return true;
if (!slot.getItem().equals(input.getItem())) return false; // type mismatch
if (slot.getCount() + input.getCount() > slot.getMaxCount()) return false; // count too high
return true;
}

private Optional<RecipeEntry<OritechRecipe>> getRecipe() {
return Objects.requireNonNull(world).getRecipeManager().getFirstMatch(getOwnRecipeType(), getInputInventory(), world);
}
Expand Down Expand Up @@ -448,17 +456,8 @@ public AnimationController<MachineBlockEntity> getAnimationController() {

if (isActive(getCachedState())) {

if (getProgress() == 0) {
idleTicks++;
} else {
idleTicks = 0;
}

if (idleTicks < 3) {
var recipeTicks = getCurrentRecipe().getTime() * getSpeedMultiplier();
var animationTicks = 60f; // 3s
var animSpeed = animationTicks / recipeTicks;
state.getController().setAnimationSpeed(animSpeed);
if (progress > 0) {
state.getController().setAnimationSpeed(getAnimationSpeed());
return state.setAndContinue(WORKING);
} else {
return state.setAndContinue(IDLE);
Expand All @@ -469,6 +468,16 @@ public AnimationController<MachineBlockEntity> getAnimationController() {
});
}

protected float getAnimationSpeed() {
var recipeTicks = getRecipeDuration() * getSpeedMultiplier();
var animationTicks = 60f; // 3s
return animationTicks / recipeTicks;
}

protected int getRecipeDuration() {
return getCurrentRecipe().getTime();
}

@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return animatableInstanceCache;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package rearth.oritech.block.custom.machines;

import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.entity.BlockEntity;
import org.jetbrains.annotations.NotNull;
import rearth.oritech.block.base.block.MultiblockMachine;
import rearth.oritech.block.entity.machines.GrinderBlockEntity;
import rearth.oritech.block.entity.machines.PoweredFurnaceBlockEntity;

public class PoweredFurnaceBlock extends MultiblockMachine implements BlockEntityProvider {

public PoweredFurnaceBlock(Settings settings) {
super(settings);
}

@Override
public @NotNull Class<? extends BlockEntity> getBlockEntityType() {
return PoweredFurnaceBlockEntity.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package rearth.oritech.block.entity.machines;

import net.minecraft.block.BlockState;
import net.minecraft.recipe.RecipeType;
import net.minecraft.recipe.SmeltingRecipe;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import rearth.oritech.block.base.entity.MachineBlockEntity;
import rearth.oritech.block.base.entity.MultiblockMachineEntity;
import rearth.oritech.client.init.ModScreens;
import rearth.oritech.init.BlockEntitiesContent;
import rearth.oritech.init.recipes.OritechRecipeType;
import rearth.oritech.init.recipes.RecipeContent;
import rearth.oritech.util.InventorySlotAssignment;

import java.util.List;
import java.util.Objects;

public class PoweredFurnaceBlockEntity extends MultiblockMachineEntity {

private final float FURNACE_SPEED_MULTIPLIER = 0.5f;

public PoweredFurnaceBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntitiesContent.POWERED_FURNACE_ENTITY, pos, state, 30);
}

@Override
protected OritechRecipeType getOwnRecipeType() {
return RecipeContent.ASSEMBLER;
} // not used in this special case

@Override
public void tick(World world, BlockPos pos, BlockState state, MachineBlockEntity blockEntity) {

if (world.isClient || !isActive(state)) return;

var recipeCandidate = world.getRecipeManager().getFirstMatch(RecipeType.SMELTING, getInputInventory(), world);

if (recipeCandidate.isPresent() && canAddToSlot(recipeCandidate.get().value().getResult(world.getRegistryManager()), this.getItems().get(1))) {
if (hasEnoughEnergy()) {

var activeRecipe = recipeCandidate.get().value();
useEnergy();
progress++;

if (furnaceCraftingFinished(activeRecipe)) {
craftFurnaceItem(activeRecipe);
resetProgress();
}

markNetDirty();

}
} else {
// this happens if either the input slot is empty, or the output slot is blocked
if (progress > 0) resetProgress();
}

if (networkDirty) {
updateNetwork();
}
}

private void craftFurnaceItem(SmeltingRecipe activeRecipe) {
var result = activeRecipe.getResult(world.getRegistryManager());
var outSlot = inventory.get(1);
var inSlot = inventory.get(0);

inSlot.decrement(1);
if (outSlot.isEmpty()) {
inventory.set(1, result.copy());
} else {
outSlot.increment(result.getCount());
}

}

private boolean furnaceCraftingFinished(SmeltingRecipe activeRecipe) {
return progress >= activeRecipe.getCookingTime() * getSpeedMultiplier();
}

@SuppressWarnings("OptionalIsPresent")
@Override
public float getProgress() {
if (progress == 0) return 0;

var recipeCandidate = Objects.requireNonNull(world).getRecipeManager().getFirstMatch(RecipeType.SMELTING, getInputInventory(), world);
if (recipeCandidate.isPresent()) {
return (float) progress / getRecipeDuration();
}

return 0;
}

@SuppressWarnings("OptionalIsPresent")
@Override
protected int getRecipeDuration() {
var recipeCandidate = Objects.requireNonNull(world).getRecipeManager().getFirstMatch(RecipeType.SMELTING, getInputInventory(), world);
if (recipeCandidate.isPresent()) {
return (int) (recipeCandidate.get().value().getCookingTime() * getSpeedMultiplier());
}

return 1;
}

@Override
public float getSpeedMultiplier() {
return super.getSpeedMultiplier() * FURNACE_SPEED_MULTIPLIER;
}

@Override
public InventorySlotAssignment getSlots() {
return new InventorySlotAssignment(0, 1, 1, 1);
}

@Override
public boolean inputOptionsEnabled() {
return false;
}

@Override
public List<GuiSlot> getGuiSlots() {
return List.of(
new GuiSlot(0, 80, 11),
new GuiSlot(1, 80, 59));
}

@Override
public ScreenHandlerType<?> getScreenHandlerType() {
return ModScreens.POWERED_FURNACE_SCREEN;
}

@Override
public int getInventorySize() {
return 2;
}

@Override
public List<Vec3i> getCorePositions() {
return List.of(
new Vec3i(0, 1,0)
);
}

@Override
public List<Vec3i> getAddonSlots() {

return List.of(
new Vec3i(0, -1,0)
);
}
}
1 change: 1 addition & 0 deletions src/main/java/rearth/oritech/client/init/ModRenderers.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public static void registerRenderers() {
BlockEntityRendererFactories.register(BlockEntitiesContent.PULVERIZER_ENTITY, ctx -> new MachineRenderer<>("models/pulverizer_block"));
BlockEntityRendererFactories.register(BlockEntitiesContent.GRINDER_ENTITY, ctx -> new MachineRenderer<>("models/grinder_block"));
BlockEntityRendererFactories.register(BlockEntitiesContent.ASSEMBLER_ENTITY, ctx -> new MachineRenderer<>("models/assembler_block"));
BlockEntityRendererFactories.register(BlockEntitiesContent.POWERED_FURNACE_ENTITY, ctx -> new MachineRenderer<>("models/powered_furnace_block"));

Oritech.LOGGER.info("Registering Entities Renderers for " + Oritech.MOD_ID);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/rearth/oritech/client/init/ModScreens.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ public class ModScreens implements AutoRegistryContainer<ScreenHandlerType<?>> {
public static final ExtendedScreenHandlerType<UpgradableMachineScreenHandler> PULVERIZER_SCREEN = new ExtendedScreenHandlerType<>(UpgradableMachineScreenHandler::new);
public static final ExtendedScreenHandlerType<UpgradableMachineScreenHandler> GRINDER_SCREEN = new ExtendedScreenHandlerType<>(UpgradableMachineScreenHandler::new);
public static final ExtendedScreenHandlerType<UpgradableMachineScreenHandler> ASSEMBLER_SCREEN = new ExtendedScreenHandlerType<>(UpgradableMachineScreenHandler::new);
public static final ExtendedScreenHandlerType<UpgradableMachineScreenHandler> POWERED_FURNACE_SCREEN = new ExtendedScreenHandlerType<>(UpgradableMachineScreenHandler::new);
public static final ExtendedScreenHandlerType<InventoryProxyScreenHandler> INVENTORY_PROXY_SCREEN = new ExtendedScreenHandlerType<>(InventoryProxyScreenHandler::new);

public static void assignScreens() {
HandledScreens.register(PULVERIZER_SCREEN, UpgradableMachineScreen::new);
HandledScreens.register(GRINDER_SCREEN, UpgradableMachineScreen::new);
HandledScreens.register(ASSEMBLER_SCREEN, UpgradableMachineScreen::new);
HandledScreens.register(POWERED_FURNACE_SCREEN, UpgradableMachineScreen::new);
HandledScreens.register(INVENTORY_PROXY_SCREEN, InventoryProxyScreen::new);
}

Expand Down
Loading

0 comments on commit 23791da

Please sign in to comment.