Search in sources :

Example 1 with ISmeltingRecipe

use of org.lanternpowered.server.item.recipe.smelting.ISmeltingRecipe in project LanternServer by LanternPowered.

the class LanternFurnace method pulse.

@Override
public void pulse() {
    super.pulse();
    if (this.lastTick == -1) {
        this.lastTick = LanternGame.currentTimeTicks();
        return;
    }
    final long ticks = LanternGame.currentTimeTicks();
    long elapsed = ticks - this.lastTick;
    // This shouldn't happen
    if (elapsed == 0) {
        return;
    }
    this.lastTick = ticks;
    while (elapsed > 0) {
        int maxCookTime = 0;
        Optional<SmeltingResult> smeltingResult = Optional.empty();
        Optional<SmeltingRecipe> smeltingRecipe = Optional.empty();
        ItemStack itemStack = this.inventory.getInputSlot().getRawItemStack();
        final ItemStackSnapshot inputSlotItemSnapshot = itemStack == null ? null : itemStack.createSnapshot();
        if (inputSlotItemSnapshot != null) {
            // Check if the item can be smelted, this means finding a compatible
            // recipe and the output has to be empty.
            smeltingRecipe = Lantern.getRegistry().getSmeltingRecipeRegistry().findMatchingRecipe(inputSlotItemSnapshot);
            if (smeltingRecipe.isPresent()) {
                final int quantity = ((ISmeltingRecipe) smeltingRecipe.get()).getIngredient().getQuantity(inputSlotItemSnapshot);
                if (inputSlotItemSnapshot.getQuantity() >= quantity) {
                    smeltingResult = smeltingRecipe.get().getResult(inputSlotItemSnapshot);
                    // Check if the item can be smelted
                    if (smeltingResult.isPresent()) {
                        // Check if the result could be added to the output
                        final PeekedOfferTransactionResult peekResult = this.inventory.getOutputSlot().peekOffer(smeltingResult.get().getResult().createStack());
                        if (peekResult.isSuccess()) {
                            maxCookTime = ((ISmeltingRecipe) smeltingRecipe.get()).getSmeltTime(inputSlotItemSnapshot).orElse(200);
                        }
                    }
                }
            }
        }
        // The ticks that are elapsed in this loop, limit
        // this to one cooking cycle, this can only happen
        // if actually a item is being cooked
        long elapsed1 = elapsed;
        int elapsedCookTime = get(Keys.PASSED_COOK_TIME).get();
        int remainingCookTime = maxCookTime - elapsedCookTime;
        if (maxCookTime > 0 && elapsed1 > remainingCookTime) {
            elapsed1 = remainingCookTime;
        }
        elapsed -= elapsed1;
        // Burn items until the furnace is burning properly
        int maxBurnTime = get(Keys.MAX_BURN_TIME).get();
        int elapsedBurnTime = get(Keys.PASSED_BURN_TIME).get();
        int remainingBurnTime = maxBurnTime - elapsedBurnTime;
        long elapsed2 = elapsed1;
        while (elapsed2 >= remainingBurnTime) {
            elapsed2 -= remainingBurnTime;
            // Reset the max burn time
            maxBurnTime = 0;
            // Only burn a new item if the target item can be smelted
            itemStack = this.inventory.getFuelSlot().getRawItemStack();
            if (itemStack != null && maxCookTime > 0) {
                // Check for the next fuel item
                final ItemStackSnapshot itemStackSnapshot = itemStack.createSnapshot();
                final Optional<IFuel> result = Lantern.getRegistry().getFuelRegistry().findMatching(itemStackSnapshot);
                if (result.isPresent()) {
                    final OptionalInt optBurnTime = result.get().getBurnTime(itemStackSnapshot);
                    // We have a next matching burn item, check if we can poll one and then continue burning
                    if (optBurnTime.isPresent() && this.inventory.getFuelSlot().poll(1).isPresent()) {
                        maxBurnTime = optBurnTime.getAsInt();
                        remainingBurnTime = maxBurnTime;
                        elapsedBurnTime = 0;
                        // Put the rest item in the slot, if the slot is empty
                        if (this.inventory.getFuelSlot().size() == 0) {
                            final IIngredient ingredient = result.get().getIngredient();
                            final Optional<ItemStack> remainingItem = ingredient.getRemainingItem(itemStackSnapshot);
                            remainingItem.ifPresent(this.inventory.getFuelSlot()::setForced);
                        }
                    }
                }
            }
            if (maxBurnTime == 0) {
                break;
            }
        }
        elapsedBurnTime = maxBurnTime == 0 ? 0 : (int) (elapsedBurnTime + elapsed2);
        remainingBurnTime = maxBurnTime - elapsedBurnTime;
        offer(Keys.MAX_BURN_TIME, maxBurnTime);
        offer(Keys.PASSED_BURN_TIME, elapsedBurnTime);
        if (maxCookTime > 0) {
            // The furnace is still burning
            if (remainingBurnTime > 0) {
                // The item is smelted
                if (elapsed1 >= remainingCookTime) {
                    offer(Keys.MAX_COOK_TIME, 0);
                    offer(Keys.PASSED_COOK_TIME, 0);
                    final int quantity = ((ISmeltingRecipe) smeltingRecipe.get()).getIngredient().getQuantity(inputSlotItemSnapshot);
                    this.inventory.getOutputSlot().offer(smeltingResult.get().getResult().createStack());
                    this.inventory.getInputSlot().poll(quantity);
                    // Put the rest item in the slot
                    if (this.inventory.getInputSlot().size() == 0) {
                        final IIngredient ingredient = ((ISmeltingRecipe) smeltingRecipe.get()).getIngredient();
                        final Optional<ItemStack> remainingItem = ingredient.getRemainingItem(inputSlotItemSnapshot);
                        remainingItem.ifPresent(this.inventory.getInputSlot()::set);
                    }
                } else {
                    // Keep on smelting
                    offer(Keys.MAX_COOK_TIME, maxCookTime);
                    offer(Keys.PASSED_COOK_TIME, (int) (elapsedCookTime + elapsed1));
                    break;
                }
            } else if (elapsedCookTime > 0) {
                // Undo smelting progress
                final long time = elapsedCookTime - elapsed1 * 2;
                offer(Keys.MAX_COOK_TIME, time <= 0 ? 0 : maxCookTime);
                offer(Keys.PASSED_COOK_TIME, (int) (time <= 0 ? 0 : time));
                break;
            }
        } else {
            offer(Keys.MAX_COOK_TIME, 0);
            offer(Keys.PASSED_COOK_TIME, 0);
        }
    }
    BlockState blockState = getLocation().getBlock();
    final boolean burning = get(Keys.PASSED_BURN_TIME).get() < get(Keys.MAX_BURN_TIME).get();
    final boolean blockBurning = blockState.getType() == BlockTypes.LIT_FURNACE;
    if (burning != blockBurning) {
        blockState = (burning ? BlockTypes.LIT_FURNACE : BlockTypes.FURNACE).getDefaultState().withTrait(LanternEnumTraits.HORIZONTAL_FACING, blockState.getTraitValue(LanternEnumTraits.HORIZONTAL_FACING).get()).get();
        getLocation().setBlock(blockState);
    }
}
Also used : IIngredient(org.lanternpowered.server.item.recipe.IIngredient) PeekedOfferTransactionResult(org.lanternpowered.server.inventory.PeekedOfferTransactionResult) OptionalInt(java.util.OptionalInt) BlockState(org.spongepowered.api.block.BlockState) SmeltingRecipe(org.spongepowered.api.item.recipe.smelting.SmeltingRecipe) ISmeltingRecipe(org.lanternpowered.server.item.recipe.smelting.ISmeltingRecipe) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) IFuel(org.lanternpowered.server.item.recipe.fuel.IFuel) ISmeltingRecipe(org.lanternpowered.server.item.recipe.smelting.ISmeltingRecipe) ItemStack(org.spongepowered.api.item.inventory.ItemStack) SmeltingResult(org.spongepowered.api.item.recipe.smelting.SmeltingResult)

Example 2 with ISmeltingRecipe

use of org.lanternpowered.server.item.recipe.smelting.ISmeltingRecipe in project LanternServer by LanternPowered.

the class LanternFurnace method smelt.

@Override
public boolean smelt() {
    final ItemStack itemStack = this.inventory.getInputSlot().getRawItemStack();
    if (itemStack != null) {
        // Check if the item can be smelted, this means finding a compatible
        // recipe and the output has to be empty.
        final ItemStackSnapshot itemStackSnapshot = itemStack.createSnapshot();
        final Optional<SmeltingRecipe> smeltingRecipe = Lantern.getRegistry().getSmeltingRecipeRegistry().findMatchingRecipe(itemStackSnapshot);
        final Optional<SmeltingResult> smeltingResult = smeltingRecipe.flatMap(recipe -> recipe.getResult(itemStackSnapshot));
        // Check if the item can be smelted
        if (smeltingResult.isPresent()) {
            final int quantity = ((ISmeltingRecipe) smeltingRecipe.get()).getIngredient().getQuantity(itemStackSnapshot);
            if (itemStack.getQuantity() >= quantity) {
                final ItemStack result = smeltingResult.get().getResult().createStack();
                // Check if the result could be added to the output
                final PeekedOfferTransactionResult peekResult = this.inventory.getOutputSlot().peekOffer(result);
                if (peekResult.isSuccess()) {
                    this.inventory.getInputSlot().poll(quantity);
                    this.inventory.getOutputSlot().offer(result);
                    return true;
                }
            }
        }
    }
    return false;
}
Also used : SmeltingRecipe(org.spongepowered.api.item.recipe.smelting.SmeltingRecipe) ISmeltingRecipe(org.lanternpowered.server.item.recipe.smelting.ISmeltingRecipe) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) PeekedOfferTransactionResult(org.lanternpowered.server.inventory.PeekedOfferTransactionResult) ItemStack(org.spongepowered.api.item.inventory.ItemStack) SmeltingResult(org.spongepowered.api.item.recipe.smelting.SmeltingResult)

Aggregations

PeekedOfferTransactionResult (org.lanternpowered.server.inventory.PeekedOfferTransactionResult)2 ISmeltingRecipe (org.lanternpowered.server.item.recipe.smelting.ISmeltingRecipe)2 ItemStack (org.spongepowered.api.item.inventory.ItemStack)2 ItemStackSnapshot (org.spongepowered.api.item.inventory.ItemStackSnapshot)2 SmeltingRecipe (org.spongepowered.api.item.recipe.smelting.SmeltingRecipe)2 SmeltingResult (org.spongepowered.api.item.recipe.smelting.SmeltingResult)2 OptionalInt (java.util.OptionalInt)1 IIngredient (org.lanternpowered.server.item.recipe.IIngredient)1 IFuel (org.lanternpowered.server.item.recipe.fuel.IFuel)1 BlockState (org.spongepowered.api.block.BlockState)1