mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +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:
		| @@ -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 ) | ||||
|         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 | ||||
|             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.addFuel( event.getHandler().refuel( turtle, stack, slot, limit ) ); | ||||
|             turtle.playAnimation( TurtleAnimation.Wait ); | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 SquidDev
					SquidDev