mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-12 11:10:29 +00:00
Convert turtle refuelling into an event
This should allow us (or other mods) to register custom refuel handlers should they so wish.
This commit is contained in:
parent
c4b371b124
commit
6ed03e1fcd
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to refuel from an item.
|
||||
*
|
||||
* One may use {@link #setCanceled(boolean, String)} to prevent refueling from this specific item. Additionally, you
|
||||
* may use {@link #setHandler(Handler)} to register a custom fuel provider.
|
||||
*/
|
||||
public class TurtleRefuelEvent extends TurtleActionEvent
|
||||
{
|
||||
private final ItemStack stack;
|
||||
private Handler handler;
|
||||
|
||||
public TurtleRefuelEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack )
|
||||
{
|
||||
super( turtle, TurtleAction.REFUEL );
|
||||
|
||||
Objects.requireNonNull( turtle, "turtle cannot be null" );
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stack we are attempting to refuel from.
|
||||
*
|
||||
* Do not modify the returned stack - all modifications should be done within the {@link Handler}.
|
||||
*
|
||||
* @return The stack to refuel from.
|
||||
*/
|
||||
public ItemStack getStack()
|
||||
{
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the refuel handler for this stack.
|
||||
*
|
||||
* @return The refuel handler, or {@code null} if none has currently been set.
|
||||
* @see #setHandler(Handler)
|
||||
*/
|
||||
@Nullable
|
||||
public Handler getHandler()
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the refuel handler for this stack.
|
||||
*
|
||||
* You should call this if you can actually refuel from this item, and ideally only if there are no existing
|
||||
* handlers.
|
||||
*
|
||||
* @param handler The new refuel handler.
|
||||
* @see #getHandler()
|
||||
*/
|
||||
public void setHandler( @Nullable Handler handler )
|
||||
{
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles refuelling a turtle from a specific item.
|
||||
*/
|
||||
public interface Handler
|
||||
{
|
||||
/**
|
||||
* Refuel a turtle using an item.
|
||||
*
|
||||
* @param turtle The turtle to refuel.
|
||||
* @param stack The stack to refuel with.
|
||||
* @param slot The slot the stack resides within. This may be used to modify the inventory afterwards.
|
||||
* @param limit The maximum number of refuel operations to perform. This will often correspond to the number of
|
||||
* items to consume.
|
||||
* @return The amount of fuel gained.
|
||||
*/
|
||||
int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int slot, int limit );
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.event.TurtleRefuelEvent;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntityFurnace;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
|
||||
public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
|
||||
{
|
||||
private static final FurnaceRefuelHandler INSTANCE = new FurnaceRefuelHandler();
|
||||
|
||||
private FurnaceRefuelHandler()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack currentStack, int slot, int limit )
|
||||
{
|
||||
ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false );
|
||||
int fuelToGive = getFuelPerItem( stack ) * stack.getCount();
|
||||
|
||||
// Store the replacement item in the inventory
|
||||
ItemStack replacementStack = stack.getItem().getContainerItem( stack );
|
||||
if( !replacementStack.isEmpty() )
|
||||
{
|
||||
ItemStack remainder = InventoryUtil.storeItems( replacementStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
if( !remainder.isEmpty() )
|
||||
{
|
||||
WorldUtil.dropItemStack( remainder, turtle.getWorld(), turtle.getPosition(), turtle.getDirection().getOpposite() );
|
||||
}
|
||||
}
|
||||
|
||||
return fuelToGive;
|
||||
}
|
||||
|
||||
|
||||
private static int getFuelPerItem( @Nonnull ItemStack stack )
|
||||
{
|
||||
return (TileEntityFurnace.getItemBurnTime( stack ) * 5) / 100;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onTurtleRefuel( TurtleRefuelEvent event )
|
||||
{
|
||||
if( event.getHandler() == null && getFuelPerItem( event.getStack() ) > 0 ) event.setHandler( INSTANCE );
|
||||
}
|
||||
}
|
@ -10,92 +10,36 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.api.turtle.event.TurtleRefuelEvent;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntityFurnace;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class TurtleRefuelCommand implements ITurtleCommand
|
||||
{
|
||||
private final int m_limit;
|
||||
private final int limit;
|
||||
|
||||
public TurtleRefuelCommand( int limit )
|
||||
{
|
||||
m_limit = limit;
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
if( m_limit == 0 )
|
||||
{
|
||||
// If limit is zero, just check the item is combustible
|
||||
ItemStack dummyStack = turtle.getInventory().getStackInSlot( turtle.getSelectedSlot() );
|
||||
if( !dummyStack.isEmpty() )
|
||||
{
|
||||
return refuel( turtle, dummyStack, true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, refuel for real
|
||||
// Remove items from inventory
|
||||
ItemStack stack = InventoryUtil.takeItems( m_limit, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
TurtleCommandResult result = refuel( turtle, stack, false );
|
||||
if( !result.isSuccess() )
|
||||
{
|
||||
// If the items weren't burnt, put them back
|
||||
InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return TurtleCommandResult.failure( "No items to combust" );
|
||||
}
|
||||
int slot = turtle.getSelectedSlot();
|
||||
ItemStack stack = turtle.getInventory().getStackInSlot( slot );
|
||||
if( stack.isEmpty() ) return TurtleCommandResult.failure( "No items to combust" );
|
||||
|
||||
private int getFuelPerItem( @Nonnull ItemStack stack )
|
||||
{
|
||||
return (TileEntityFurnace.getItemBurnTime( stack ) * 5) / 100;
|
||||
}
|
||||
TurtleRefuelEvent event = new TurtleRefuelEvent( turtle, stack );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) ) return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
if( event.getHandler() == null ) return TurtleCommandResult.failure( "Items not combustible" );
|
||||
|
||||
private TurtleCommandResult refuel( ITurtleAccess turtle, @Nonnull ItemStack stack, boolean testOnly )
|
||||
if( limit != 0 )
|
||||
{
|
||||
// Check if item is fuel
|
||||
int fuelPerItem = getFuelPerItem( stack );
|
||||
if( fuelPerItem <= 0 )
|
||||
{
|
||||
return TurtleCommandResult.failure( "Items not combustible" );
|
||||
}
|
||||
|
||||
TurtleActionEvent event = new TurtleActionEvent( turtle, TurtleAction.REFUEL );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
if( !testOnly )
|
||||
{
|
||||
// Determine fuel to give and replacement item to leave behind
|
||||
int fuelToGive = fuelPerItem * stack.getCount();
|
||||
ItemStack replacementStack = stack.getItem().getContainerItem( stack );
|
||||
|
||||
// Update fuel level
|
||||
turtle.addFuel( fuelToGive );
|
||||
|
||||
// Store the replacement item in the inventory
|
||||
if( !replacementStack.isEmpty() )
|
||||
{
|
||||
InventoryUtil.storeItems( replacementStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
}
|
||||
|
||||
// Animate
|
||||
turtle.addFuel( event.getHandler().refuel( turtle, stack, slot, limit ) );
|
||||
turtle.playAnimation( TurtleAnimation.Wait );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user