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.ITurtleCommand;
|
||||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
import dan200.computercraft.api.turtle.event.TurtleRefuelEvent;
|
||||||
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
|
|
||||||
import dan200.computercraft.shared.util.InventoryUtil;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntityFurnace;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class TurtleRefuelCommand implements ITurtleCommand
|
public class TurtleRefuelCommand implements ITurtleCommand
|
||||||
{
|
{
|
||||||
private final int m_limit;
|
private final int limit;
|
||||||
|
|
||||||
public TurtleRefuelCommand( int limit )
|
public TurtleRefuelCommand( int limit )
|
||||||
{
|
{
|
||||||
m_limit = limit;
|
this.limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||||
{
|
{
|
||||||
if( m_limit == 0 )
|
int slot = turtle.getSelectedSlot();
|
||||||
|
ItemStack stack = turtle.getInventory().getStackInSlot( slot );
|
||||||
|
if( stack.isEmpty() ) return TurtleCommandResult.failure( "No items to combust" );
|
||||||
|
|
||||||
|
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" );
|
||||||
|
|
||||||
|
if( limit != 0 )
|
||||||
{
|
{
|
||||||
// If limit is zero, just check the item is combustible
|
turtle.addFuel( event.getHandler().refuel( turtle, stack, slot, limit ) );
|
||||||
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" );
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getFuelPerItem( @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
return (TileEntityFurnace.getItemBurnTime( stack ) * 5) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TurtleCommandResult refuel( ITurtleAccess turtle, @Nonnull ItemStack stack, boolean testOnly )
|
|
||||||
{
|
|
||||||
// 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.playAnimation( TurtleAnimation.Wait );
|
turtle.playAnimation( TurtleAnimation.Wait );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user