Fix progress bar for electric furnace
This commit is contained in:
parent
9035e4376a
commit
3e5965ad57
2 changed files with 165 additions and 93 deletions
|
@ -24,10 +24,13 @@
|
||||||
|
|
||||||
package techreborn.blockentity.machine.tier1;
|
package techreborn.blockentity.machine.tier1;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.recipe.RecipeType;
|
import net.minecraft.recipe.RecipeType;
|
||||||
|
import net.minecraft.recipe.SmeltingRecipe;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import reborncore.api.IToolDrop;
|
import reborncore.api.IToolDrop;
|
||||||
import reborncore.api.blockentity.InventoryProvider;
|
import reborncore.api.blockentity.InventoryProvider;
|
||||||
|
@ -36,105 +39,163 @@ import reborncore.client.containerBuilder.builder.BuiltContainer;
|
||||||
import reborncore.client.containerBuilder.builder.ContainerBuilder;
|
import reborncore.client.containerBuilder.builder.ContainerBuilder;
|
||||||
import reborncore.common.blocks.BlockMachineBase;
|
import reborncore.common.blocks.BlockMachineBase;
|
||||||
import reborncore.common.powerSystem.PowerAcceptorBlockEntity;
|
import reborncore.common.powerSystem.PowerAcceptorBlockEntity;
|
||||||
|
import reborncore.common.recipes.RecipeCrafter;
|
||||||
|
import reborncore.common.util.ItemUtils;
|
||||||
import reborncore.common.util.RebornInventory;
|
import reborncore.common.util.RebornInventory;
|
||||||
import techreborn.config.TechRebornConfig;
|
import techreborn.config.TechRebornConfig;
|
||||||
import techreborn.init.TRContent;
|
import techreborn.init.TRContent;
|
||||||
import techreborn.utils.RecipeUtils;
|
|
||||||
import techreborn.init.TRBlockEntities;
|
import techreborn.init.TRBlockEntities;
|
||||||
|
|
||||||
public class ElectricFurnaceBlockEntity extends PowerAcceptorBlockEntity
|
public class ElectricFurnaceBlockEntity extends PowerAcceptorBlockEntity
|
||||||
implements IToolDrop, InventoryProvider, IContainerProvider {
|
implements IToolDrop, InventoryProvider, IContainerProvider {
|
||||||
|
|
||||||
public RebornInventory<ElectricFurnaceBlockEntity> inventory = new RebornInventory<>(3, "ElectricFurnaceBlockEntity", 64, this);
|
public RebornInventory<ElectricFurnaceBlockEntity> inventory = new RebornInventory<>(3, "ElectricFurnaceBlockEntity", 64, this);
|
||||||
public int progress;
|
int inputSlot = 0;
|
||||||
public int fuelScale = 100;
|
int outputSlot = 1;
|
||||||
public int cost = 4;
|
int ticksSinceLastChange;
|
||||||
int input1 = 0;
|
private SmeltingRecipe currentRecipe;
|
||||||
int output = 1;
|
private int cookTime;
|
||||||
boolean wasBurning = false;
|
private int cookTimeTotal;
|
||||||
|
// Energy cost per tick of cooking
|
||||||
|
final int EnergyPerTick = 4;
|
||||||
|
|
||||||
public ElectricFurnaceBlockEntity() {
|
public ElectricFurnaceBlockEntity() {
|
||||||
super(TRBlockEntities.ELECTRIC_FURNACE );
|
super(TRBlockEntities.ELECTRIC_FURNACE );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int gaugeProgressScaled(int scale) {
|
private void setInvDirty(boolean isDiry) {
|
||||||
return progress * scale / (int) (fuelScale * (1.0 - getSpeedMultiplier()));
|
inventory.setChanged(isDiry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cookItems() {
|
private boolean isInvDirty() {
|
||||||
if (canSmelt()) {
|
return inventory.hasChanged();
|
||||||
final ItemStack itemstack = RecipeUtils.getMatchingRecipes(world, RecipeType.SMELTING, inventory.getInvStack(input1));
|
|
||||||
|
|
||||||
if (inventory.getInvStack(output).isEmpty()) {
|
|
||||||
inventory.setInvStack(output, itemstack.copy());
|
|
||||||
} else if (inventory.getInvStack(output).isItemEqualIgnoreDamage(itemstack)) {
|
|
||||||
inventory.getInvStack(output).increment(itemstack.getCount());
|
|
||||||
}
|
|
||||||
if (inventory.getInvStack(input1).getCount() > 1) {
|
|
||||||
inventory.shrinkSlot(input1, 1);
|
|
||||||
} else {
|
|
||||||
inventory.setInvStack(input1, ItemStack.EMPTY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canSmelt() {
|
private void updateCurrentRecipe() {
|
||||||
if (inventory.getInvStack(input1).isEmpty()) {
|
if (inventory.getInvStack(inputSlot).isEmpty()) {
|
||||||
|
resetCrafter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Optional<SmeltingRecipe> testRecipe = world.getRecipeManager().getFirstMatch(RecipeType.SMELTING, inventory, world);
|
||||||
|
if (!testRecipe.isPresent()) {
|
||||||
|
resetCrafter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!canAcceptOutput(testRecipe.get(), outputSlot)) {
|
||||||
|
resetCrafter();
|
||||||
|
}
|
||||||
|
currentRecipe = testRecipe.get();
|
||||||
|
cookTime = 0;
|
||||||
|
cookTimeTotal = Math.max((int) (currentRecipe.getCookTime() * (1.0 - getSpeedMultiplier())), 1);
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canAcceptOutput(SmeltingRecipe recipe, int slot) {
|
||||||
|
ItemStack recipeOutput = recipe.getOutput();
|
||||||
|
if (recipeOutput.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final ItemStack itemstack = RecipeUtils.getMatchingRecipes(world, RecipeType.SMELTING, inventory.getInvStack(input1));
|
if (inventory.getInvStack(slot).isEmpty()) {
|
||||||
if (itemstack.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (inventory.getInvStack(output).isEmpty()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!inventory.getInvStack(output).isItemEqualIgnoreDamage(itemstack)) {
|
if (ItemUtils.isItemEqual(inventory.getInvStack(slot), recipeOutput, true, true)) {
|
||||||
|
if (recipeOutput.getCount() + inventory.getInvStack(slot).getCount() <= recipeOutput.getMaxCount()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canCraftAgain() {
|
||||||
|
if (inventory.getInvStack(inputSlot).isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final int result = inventory.getInvStack(output).getCount() + itemstack.getCount();
|
if (currentRecipe == null) {
|
||||||
return result <= this.inventory.getStackLimit() && result <= itemstack.getMaxCount();
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBurning() {
|
|
||||||
return getEnergy() > getEuPerTick(cost);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getResultFor(ItemStack stack) {
|
|
||||||
final ItemStack result = RecipeUtils.getMatchingRecipes(world, RecipeType.SMELTING, stack);
|
|
||||||
if (!result.isEmpty()) {
|
|
||||||
return result.copy();
|
|
||||||
}
|
}
|
||||||
return ItemStack.EMPTY;
|
if (!canAcceptOutput(currentRecipe, outputSlot)) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
public void updateState() {
|
if (getEnergy() < currentRecipe.getCookTime() * getEuPerTick(EnergyPerTick)) {
|
||||||
if (wasBurning != (progress > 0)) {
|
return false;
|
||||||
// skips updating the block state for 1 tick, to prevent the machine from
|
|
||||||
// turning on/off rapidly causing fps drops
|
|
||||||
if (wasBurning && progress == 0 && canSmelt()) {
|
|
||||||
wasBurning = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final BlockState BlockStateContainer = world.getBlockState(pos);
|
|
||||||
if (BlockStateContainer.getBlock() instanceof BlockMachineBase) {
|
|
||||||
final BlockMachineBase blockMachineBase = (BlockMachineBase) BlockStateContainer.getBlock();
|
|
||||||
if (BlockStateContainer.get(BlockMachineBase.ACTIVE) != progress > 0)
|
|
||||||
blockMachineBase.setActive(progress > 0, world, pos);
|
|
||||||
}
|
|
||||||
wasBurning = (progress > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBurnTime() {
|
private void resetCrafter() {
|
||||||
return progress;
|
currentRecipe = null;
|
||||||
|
cookTime = 0;
|
||||||
|
cookTimeTotal = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBurnTime(final int burnTime) {
|
private void updateState() {
|
||||||
this.progress = burnTime;
|
Block furnaceBlock = getWorld().getBlockState(pos).getBlock();
|
||||||
|
|
||||||
|
if (furnaceBlock instanceof BlockMachineBase) {
|
||||||
|
BlockMachineBase blockMachineBase = (BlockMachineBase) furnaceBlock;
|
||||||
|
boolean isActive = isActive() || canCraftAgain();
|
||||||
|
blockMachineBase.setActive(isActive, world, pos);
|
||||||
|
}
|
||||||
|
world.updateListeners(pos, world.getBlockState(pos), world.getBlockState(pos), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasAllInputs(SmeltingRecipe recipe) {
|
||||||
|
if (recipe == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (inventory.getInvStack(inputSlot).isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Optional<SmeltingRecipe> testRecipe = world.getRecipeManager().getFirstMatch(RecipeType.SMELTING, inventory, world);
|
||||||
|
if (!testRecipe.isPresent()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void craftRecipe(SmeltingRecipe recipe) {
|
||||||
|
if (recipe == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!canAcceptOutput(recipe, outputSlot)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ItemStack outputStack = inventory.getInvStack(outputSlot);
|
||||||
|
if (outputStack.isEmpty()) {
|
||||||
|
inventory.setInvStack(outputSlot, recipe.getOutput().copy());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Just increment. We already checked stack match and stack size
|
||||||
|
outputStack.increment(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inventory.getInvStack(inputSlot).decrement(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getProgressScaled(int scale) {
|
||||||
|
if (cookTimeTotal != 0) {
|
||||||
|
return cookTime * scale / cookTimeTotal;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCookTime() {
|
||||||
|
return cookTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookTime(int cookTime) {
|
||||||
|
this.cookTime = cookTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCookTimeTotal() {
|
||||||
|
return cookTimeTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookTimeTotal(int cookTimeTotal) {
|
||||||
|
this.cookTimeTotal = cookTimeTotal;
|
||||||
|
}
|
||||||
// TilePowerAcceptor
|
// TilePowerAcceptor
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
@ -142,31 +203,42 @@ public class ElectricFurnaceBlockEntity extends PowerAcceptorBlockEntity
|
||||||
charge(2);
|
charge(2);
|
||||||
|
|
||||||
if (world.isClient) {
|
if (world.isClient) {
|
||||||
|
setInvDirty(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean burning = isBurning();
|
ticksSinceLastChange++;
|
||||||
boolean updateInventory = false;
|
// Force a has chanced every second
|
||||||
if (isBurning() && canSmelt()) {
|
if (ticksSinceLastChange == 20) {
|
||||||
updateState();
|
setInvDirty(true);
|
||||||
if (canUseEnergy(getEuPerTick(cost))) {
|
ticksSinceLastChange = 0;
|
||||||
useEnergy(getEuPerTick(cost));
|
}
|
||||||
progress++;
|
|
||||||
if (progress >= Math.max((int) (fuelScale * (1.0 - getSpeedMultiplier())), 5)) {
|
if (isInvDirty()) {
|
||||||
progress = 0;
|
if (currentRecipe == null) {
|
||||||
cookItems();
|
updateCurrentRecipe();
|
||||||
updateInventory = true;
|
}
|
||||||
|
if (currentRecipe != null && !hasAllInputs(currentRecipe)) {
|
||||||
|
resetCrafter();
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentRecipe != null) {
|
||||||
|
if (cookTime >= cookTimeTotal && hasAllInputs(currentRecipe)) {
|
||||||
|
craftRecipe(currentRecipe);
|
||||||
|
updateCurrentRecipe();
|
||||||
|
} else if (cookTime < cookTimeTotal) {
|
||||||
|
if (canUseEnergy(getEuPerTick(EnergyPerTick))) {
|
||||||
|
useEnergy(getEuPerTick(EnergyPerTick));
|
||||||
|
cookTime++;
|
||||||
|
if (cookTime == 1 || cookTime % 20 == 0 && RecipeCrafter.soundHanlder != null) {
|
||||||
|
RecipeCrafter.soundHanlder.playSound(false, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
updateState();
|
|
||||||
}
|
|
||||||
if (burning != isBurning()) {
|
|
||||||
updateInventory = true;
|
|
||||||
}
|
|
||||||
if (updateInventory) {
|
|
||||||
markDirty();
|
|
||||||
}
|
}
|
||||||
|
setInvDirty(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -211,6 +283,6 @@ public class ElectricFurnaceBlockEntity extends PowerAcceptorBlockEntity
|
||||||
public BuiltContainer createContainer(int syncID, final PlayerEntity player) {
|
public BuiltContainer createContainer(int syncID, final PlayerEntity player) {
|
||||||
return new ContainerBuilder("electricfurnace").player(player.inventory).inventory().hotbar().addInventory()
|
return new ContainerBuilder("electricfurnace").player(player.inventory).inventory().hotbar().addInventory()
|
||||||
.blockEntity(this).slot(0, 55, 45).outputSlot(1, 101, 45).energySlot(2, 8, 72).syncEnergyValue()
|
.blockEntity(this).slot(0, 55, 45).outputSlot(1, 101, 45).energySlot(2, 8, 72).syncEnergyValue()
|
||||||
.syncIntegerValue(this::getBurnTime, this::setBurnTime).addInventory().create(this, syncID);
|
.syncIntegerValue(this::getCookTime, this::setCookTime).syncIntegerValue(this::getCookTimeTotal, this::setCookTimeTotal).addInventory().create(this, syncID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class GuiElectricFurnace extends GuiBase<BuiltContainer> {
|
||||||
super.drawForeground(mouseX, mouseY);
|
super.drawForeground(mouseX, mouseY);
|
||||||
Layer layer = Layer.FOREGROUND;
|
Layer layer = Layer.FOREGROUND;
|
||||||
|
|
||||||
builder.drawProgressBar(this, blockEntity.gaugeProgressScaled(100), 100, 76, 48, mouseX, mouseY, GuiBuilder.ProgressDirection.RIGHT, layer);
|
builder.drawProgressBar(this, blockEntity.getProgressScaled(100), 100, 76, 48, mouseX, mouseY, GuiBuilder.ProgressDirection.RIGHT, layer);
|
||||||
builder.drawMultiEnergyBar(this, 9, 19, (int) blockEntity.getEnergy(), (int) blockEntity.getMaxPower(), mouseX, mouseY, 0, layer);
|
builder.drawMultiEnergyBar(this, 9, 19, (int) blockEntity.getEnergy(), (int) blockEntity.getMaxPower(), mouseX, mouseY, 0, layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue