1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-11-05 01:26:20 +00:00

Prepare the public API for multi-loader support

Well, sort of. For now, we just mark a whole bunch of stuff as
@Deprecated.
This commit is contained in:
Jonathan Coates 2022-11-01 21:05:24 +00:00
parent 629abb65e3
commit c1bf9f0b24
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
43 changed files with 396 additions and 167 deletions

View File

@ -19,15 +19,17 @@ import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.TurtleRefuelHandler;
import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.asm.GenericMethod;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.shared.computer.core.ResourceMount;
import dan200.computercraft.impl.ComputerCraftAPIService;
import dan200.computercraft.impl.TurtleRefuelHandlers;
import dan200.computercraft.impl.detail.DetailRegistryImpl;
import dan200.computercraft.shared.BundledRedstone;
import dan200.computercraft.shared.MediaProviders;
import dan200.computercraft.shared.Peripherals;
import dan200.computercraft.shared.computer.core.ResourceMount;
import dan200.computercraft.shared.computer.core.ServerContext;
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
import dan200.computercraft.shared.peripheral.generic.data.BlockData;
@ -205,6 +207,12 @@ public final class ComputerCraftAPIImpl implements ComputerCraftAPIService
return tile == null ? LazyOptional.empty() : tile.getCapability( CAPABILITY_WIRED_ELEMENT, side );
}
@Override
public void registerRefuelHandler( @Nonnull TurtleRefuelHandler handler )
{
TurtleRefuelHandlers.register( handler );
}
@Override
public DetailRegistry<ItemStack> getItemStackDetailRegistry()
{

View File

@ -21,6 +21,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.TurtleRefuelHandler;
import dan200.computercraft.impl.ComputerCraftAPIService;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -37,7 +38,7 @@ import javax.annotation.Nullable;
/**
* The static entry point to the ComputerCraft API.
* <p>
* Members in this class must be called after mod_ComputerCraft has been initialised, but may be called before it is
* Members in this class must be called after ComputerCraft has been initialised, but may be called before it is
* fully loaded.
*/
public final class ComputerCraftAPI
@ -122,7 +123,9 @@ public final class ComputerCraftAPI
* @param provider The peripheral provider to register.
* @see IPeripheral
* @see IPeripheralProvider
* @deprecated Use {@link ForgeComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)} instead.
*/
@Deprecated( forRemoval = true )
public static void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
{
getInstance().registerPeripheralProvider( provider );
@ -144,7 +147,9 @@ public final class ComputerCraftAPI
*
* @param capability The capability to register.
* @see GenericSource
* @deprecated Use {@link ForgeComputerCraftAPI} instead.
*/
@Deprecated( forRemoval = true )
public static void registerGenericCapability( @Nonnull Capability<?> capability )
{
getInstance().registerGenericCapability( capability );
@ -212,7 +217,7 @@ public final class ComputerCraftAPI
* @param <T> The type of object that this provider can provide details for.
* @deprecated Use {@link DetailRegistry#addProvider(IDetailProvider)} to register your provider.
*/
@Deprecated
@Deprecated( forRemoval = true )
public static <T> void registerDetailProvider( @Nonnull Class<T> type, @Nonnull IDetailProvider<T> provider )
{
getInstance().registerDetailProvider( type, provider );
@ -239,13 +244,20 @@ public final class ComputerCraftAPI
* @param side The side to extract the network element from
* @return The element's node
* @see IWiredElement#getNode()
* @deprecated Use {@link ForgeComputerCraftAPI#getWiredElementAt(BlockGetter, BlockPos, Direction)}
*/
@Nonnull
@Deprecated( forRemoval = true )
public static LazyOptional<IWiredElement> getWiredElementAt( @Nonnull BlockGetter world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return getInstance().getWiredElementAt( world, pos, side );
}
public static void registerRefuelHandler( @Nonnull TurtleRefuelHandler handler )
{
getInstance().registerRefuelHandler( handler );
}
@Nonnull
private static ComputerCraftAPIService getInstance()
{

View File

@ -0,0 +1,73 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api;
import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.impl.ComputerCraftAPIService;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
/**
* The forge-specific entrypoint for ComputerCraft's API.
*/
public final class ForgeComputerCraftAPI
{
private ForgeComputerCraftAPI()
{
}
/**
* Registers a peripheral provider to convert blocks into {@link IPeripheral} implementations.
*
* @param provider The peripheral provider to register.
* @see IPeripheral
* @see IPeripheralProvider
*/
public static void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
{
getInstance().registerPeripheralProvider( provider );
}
/**
* Registers a capability that can be used by generic peripherals.
*
* @param capability The capability to register.
* @see GenericSource
*/
public static void registerGenericCapability( @Nonnull Capability<?> capability )
{
getInstance().registerGenericCapability( capability );
}
/**
* Get the wired network element for a block in world.
*
* @param world The world the block exists in
* @param pos The position the block exists in
* @param side The side to extract the network element from
* @return The element's node
* @see IWiredElement#getNode()
*/
@Nonnull
public static LazyOptional<IWiredElement> getWiredElementAt( @Nonnull BlockGetter world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return getInstance().getWiredElementAt( world, pos, side );
}
@Nonnull
private static ComputerCraftAPIService getInstance()
{
return ComputerCraftAPIService.get();
}
}

View File

@ -14,7 +14,7 @@ import java.util.Map;
* <p>
* These are used by computer methods such as {@code turtle.getItemDetail()} or {@code turtle.inspect()}.
* <p>
* Specific instances of this registry are available from {@link DetailRegistries} and loader-specific versions
* Specific instances of this registry are available from {@link VanillaDetailRegistries} and loader-specific versions
* also in this package.
*
* @param <T> The type of object that this registry provides details for.

View File

@ -0,0 +1,20 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.detail;
import dan200.computercraft.impl.ComputerCraftAPIService;
import net.minecraftforge.fluids.FluidStack;
/**
* {@link DetailRegistry}s for Forge-specific types.
*/
public class ForgeDetailRegistries
{
/**
* Provides details for {@link FluidStack}.
*/
public static final DetailRegistry<FluidStack> FLUID_STACK = ComputerCraftAPIService.get().getFluidStackDetailRegistry();
}

View File

@ -8,12 +8,11 @@ package dan200.computercraft.api.detail;
import dan200.computercraft.impl.ComputerCraftAPIService;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.fluids.FluidStack;
/**
* {@link DetailRegistry}s for built-in Minecraft types.
*/
public class DetailRegistries
public class VanillaDetailRegistries
{
/**
* Provides details for {@link ItemStack}s.
@ -25,8 +24,4 @@ public class DetailRegistries
*/
public static final DetailRegistry<BlockReference> BLOCK_IN_WORLD = ComputerCraftAPIService.get().getBlockInWorldDetailRegistry();
/**
* Provides details for {@link FluidStack}.
*/
public static final DetailRegistry<FluidStack> FLUID_STACK = ComputerCraftAPIService.get().getFluidStackDetailRegistry();
}

View File

@ -6,6 +6,7 @@
package dan200.computercraft.api.lua;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.ForgeComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.core.asm.LuaMethod;
@ -42,7 +43,7 @@ import javax.annotation.Nonnull;
* }</pre>
*
* @see ComputerCraftAPI#registerGenericSource(GenericSource)
* @see ComputerCraftAPI#registerGenericCapability(Capability) New capabilities (those not built into Forge) must be
* @see ForgeComputerCraftAPI#registerGenericCapability(Capability) New capabilities (those not built into Forge) must be
* explicitly given to the generic peripheral system, as there is no way to enumerate all capabilities.
*/
public interface GenericSource

View File

@ -5,6 +5,7 @@
*/
package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.ForgeComputerCraftAPI;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
@ -31,7 +32,7 @@ public interface IPeripheralProvider
* @param pos The position the block is at.
* @param side The side to get the peripheral from.
* @return A peripheral, or {@link LazyOptional#empty()} if there is not a peripheral here you'd like to handle.
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
* @see ForgeComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/
@Nonnull
LazyOptional<IPeripheral> getPeripheral( @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction side );

View File

@ -25,6 +25,6 @@ public abstract class PocketUpgradeDataProvider extends UpgradeDataProvider<IPoc
{
public PocketUpgradeDataProvider( @Nonnull DataGenerator generator )
{
super( generator, "Pocket Computer Upgrades", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.registry() );
super( generator, "Pocket Computer Upgrades", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.REGISTRY_ID );
}
}

View File

@ -40,8 +40,6 @@ public interface PocketUpgradeSerialiser<T extends IPocketUpgrade> extends Upgra
* <p>
* This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
* {@link RegistryManager#getRegistry(ResourceKey)}.
*
* @see #registry()
*/
ResourceKey<Registry<PocketUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_upgrade_serialiser" ) );
@ -50,7 +48,9 @@ public interface PocketUpgradeSerialiser<T extends IPocketUpgrade> extends Upgra
*
* @return The registry for pocket upgrade serialisers.
* @see #REGISTRY_ID
* @deprecated Use {@link #REGISTRY_ID} directly.
*/
@Deprecated( forRemoval = true )
static IForgeRegistry<PocketUpgradeSerialiser<?>> registry()
{
return RegistryManager.ACTIVE.getRegistry( REGISTRY_ID );

View File

@ -44,6 +44,20 @@ public interface ITurtleAccess
@Nonnull
BlockPos getPosition();
/**
* Determine if this turtle has been removed.
* <p>
* It's possible for a turtle to be removed while a {@link ITurtleCommand} is executed, for instance if interacting
* with a block causes the turtle to be blown up. It's recommended you check the turtle is still present before
* trying to interact with it again.
* <p>
* If a turtle has been removed {@link #getLevel()} and {@link #getPosition()} will continue to function as before.
* All other methods will fail.
*
* @return Whether this turtle has been removed.
*/
boolean isRemoved();
/**
* Attempt to move this turtle to a new position.
* <p>
@ -161,9 +175,10 @@ public interface ITurtleAccess
* @return This turtle's inventory
* @see #getInventory()
* @see IItemHandlerModifiable
* @see net.minecraftforge.items.CapabilityItemHandler#ITEM_HANDLER_CAPABILITY
* @deprecated Use {@link #getInventory()} directly.
*/
@Nonnull
@Deprecated( forRemoval = true )
IItemHandlerModifiable getItemHandler();
/**

View File

@ -0,0 +1,35 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
import dan200.computercraft.api.ComputerCraftAPI;
import net.minecraft.world.item.ItemStack;
import java.util.OptionalInt;
/**
* A function called when a turtle attempts to refuel via {@code turtle.refuel()}. This may be used to provide
* alternative fuel sources, such as consuming RF batteries.
*
* @see ComputerCraftAPI#registerRefuelHandler(TurtleRefuelHandler)
*/
public interface TurtleRefuelHandler
{
/**
* 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.
* <p>
* This value may be zero. In this case, you should still detect if the item can be handled (returning
* {@code OptionalInt#of(0)} if so), but should <em>NOT</em> modify the stack or inventory.
* @return The amount of fuel gained, or {@link OptionalInt#empty()} if this handler does not accept the given item.
*/
OptionalInt refuel( ITurtleAccess turtle, ItemStack stack, int slot, int limit );
}

View File

@ -35,7 +35,7 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITur
public TurtleUpgradeDataProvider( DataGenerator generator )
{
super( generator, "Turtle Upgrades", "computercraft/turtle_upgrades", TurtleUpgradeSerialiser.registry() );
super( generator, "Turtle Upgrades", "computercraft/turtle_upgrades", TurtleUpgradeSerialiser.REGISTRY_ID );
}
/**

View File

@ -78,8 +78,6 @@ public interface TurtleUpgradeSerialiser<T extends ITurtleUpgrade> extends Upgra
* <p>
* This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
* {@link RegistryManager#getRegistry(ResourceKey)}.
*
* @see #registry()
*/
ResourceKey<Registry<TurtleUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade_serialiser" ) );
@ -88,7 +86,9 @@ public interface TurtleUpgradeSerialiser<T extends ITurtleUpgrade> extends Upgra
*
* @return The registry for pocket upgrade serialisers.
* @see #REGISTRY_ID
* @deprecated Use {@link #REGISTRY_ID} directly.
*/
@Deprecated( forRemoval = true )
static IForgeRegistry<TurtleUpgradeSerialiser<?>> registry()
{
return RegistryManager.ACTIVE.getRegistry( REGISTRY_ID );

View File

@ -16,7 +16,10 @@ import java.util.Objects;
* so sever specific methods on {@link ITurtleAccess} are safe to use.
* <p>
* You should generally not need to subscribe to this event, preferring one of the more specific classes.
*
* @deprecated No longer needed, see {@link TurtleRefuelEvent}.
*/
@Deprecated( forRemoval = true )
public abstract class TurtleEvent extends Event
{
private final ITurtleAccess turtle;

View File

@ -6,6 +6,7 @@
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleRefuelHandler;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nonnull;
@ -16,7 +17,10 @@ import java.util.Objects;
* Fired when a turtle attempts to refuel from an item.
* <p>
* One may use {@link #setHandler(Handler)} to register a custom fuel provider for a given item.
*
* @deprecated Use {@link TurtleRefuelHandler} instead.
*/
@Deprecated( forRemoval = true )
public class TurtleRefuelEvent extends TurtleEvent
{
private final ItemStack stack;

View File

@ -10,13 +10,15 @@ import com.google.gson.JsonParseException;
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
import dan200.computercraft.internal.upgrades.SerialiserWithCraftingItem;
import dan200.computercraft.internal.upgrades.SimpleSerialiser;
import net.minecraft.core.Registry;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DataProvider;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.registries.RegistryManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -28,8 +30,8 @@ import java.util.function.Consumer;
import java.util.function.Function;
/**
* A data generator/provider for turtle and pocket computer upgrades. This should not be extended direclty, instead see
* the other sub-classes.
* A data generator/provider for turtle and pocket computer upgrades. This should not be extended directly, instead see
* the other subclasses.
*
* @param <T> The base class of upgrades.
* @param <R> The upgrade serialiser to register for.
@ -41,11 +43,11 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
private final DataGenerator generator;
private final String name;
private final String folder;
private final IForgeRegistry<R> registry;
private final ResourceKey<Registry<R>> registry;
private List<T> upgrades;
protected UpgradeDataProvider( @Nonnull DataGenerator generator, @Nonnull String name, @Nonnull String folder, @Nonnull IForgeRegistry<R> registry )
protected UpgradeDataProvider( @Nonnull DataGenerator generator, @Nonnull String name, @Nonnull String folder, @Nonnull ResourceKey<Registry<R>> registry )
{
this.generator = generator;
this.name = name;
@ -94,7 +96,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
/**
* Add all turtle or pocket computer upgrades.
*
* <p>
* <strong>Example usage:</strong>
* <pre>{@code
* protected void addUpgrades(@Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgrade) {
@ -109,6 +111,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
@Override
public final void run( @Nonnull CachedOutput cache ) throws IOException
{
var registry = RegistryManager.ACTIVE.getRegistry( this.registry );
Path base = generator.getOutputFolder().resolve( "data" );
Set<ResourceLocation> seen = new HashSet<>();
@ -153,7 +156,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
@Nonnull
public final R existingSerialiser( @Nonnull ResourceLocation id )
{
var result = registry.getValue( id );
var result = RegistryManager.ACTIVE.getRegistry( registry ).getValue( id );
if( result == null ) throw new IllegalArgumentException( "No such serialiser " + registry );
return result;
}

View File

@ -19,6 +19,7 @@ import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.TurtleRefuelHandler;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
@ -83,6 +84,8 @@ public interface ComputerCraftAPIService
@Nonnull
LazyOptional<IWiredElement> getWiredElementAt( @Nonnull BlockGetter world, @Nonnull BlockPos pos, @Nonnull Direction side );
void registerRefuelHandler( @Nonnull TurtleRefuelHandler handler );
DetailRegistry<ItemStack> getItemStackDetailRegistry();
DetailRegistry<BlockReference> getBlockInWorldDetailRegistry();

View File

@ -0,0 +1,68 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.impl;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleRefuelHandler;
import dan200.computercraft.api.turtle.event.TurtleRefuelEvent;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import java.util.List;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Registry of {@link TurtleRefuelHandler}s.
*/
public final class TurtleRefuelHandlers
{
private static final List<TurtleRefuelHandler> handlers = new CopyOnWriteArrayList<>();
static
{
// Register a fallback handler for our event.
handlers.add( ( turtle, stack, slot, limit ) -> {
@SuppressWarnings( "removal" ) TurtleRefuelEvent event = new TurtleRefuelEvent( turtle, stack );
MinecraftForge.EVENT_BUS.post( event );
if( event.getHandler() == null ) return OptionalInt.empty();
if( limit == 0 ) return OptionalInt.of( 0 );
return OptionalInt.of( event.getHandler().refuel( turtle, stack, slot, limit ) );
} );
}
private TurtleRefuelHandlers()
{
}
public static void register( TurtleRefuelHandler handler )
{
Objects.requireNonNull( handler, "handler cannot be null" );
handlers.add( handler );
}
public static OptionalInt refuel( ITurtleAccess turtle, ItemStack stack, int slot, int limit )
{
for( var handler : handlers )
{
var fuel = handler.refuel( turtle, stack, slot, limit );
if( fuel.isPresent() )
{
var refuelled = fuel.getAsInt();
if( refuelled < 0 ) throw new IllegalStateException( handler + " returned a negative value" );
if( limit == 0 && refuelled != 0 )
{
throw new IllegalStateException( handler + " refuelled despite given a limit of 0" );
}
return fuel;
}
}
return OptionalInt.empty();
}
}

View File

@ -8,7 +8,9 @@ package dan200.computercraft.shared;
import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.detail.DetailRegistries;
import dan200.computercraft.api.ForgeComputerCraftAPI;
import dan200.computercraft.api.detail.ForgeDetailRegistries;
import dan200.computercraft.api.detail.VanillaDetailRegistries;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
@ -409,13 +411,13 @@ public final class Registry
// Register generic capabilities. This can technically be done off-thread, but we need it to happen
// after Forge's common setup, so this is easiest.
ComputerCraftAPI.registerGenericCapability( ForgeCapabilities.ITEM_HANDLER );
ComputerCraftAPI.registerGenericCapability( ForgeCapabilities.ENERGY );
ComputerCraftAPI.registerGenericCapability( ForgeCapabilities.FLUID_HANDLER );
ForgeComputerCraftAPI.registerGenericCapability( ForgeCapabilities.ITEM_HANDLER );
ForgeComputerCraftAPI.registerGenericCapability( ForgeCapabilities.ENERGY );
ForgeComputerCraftAPI.registerGenericCapability( ForgeCapabilities.FLUID_HANDLER );
DetailRegistries.ITEM_STACK.addProvider( ItemData::fill );
DetailRegistries.BLOCK_IN_WORLD.addProvider( BlockData::fill );
DetailRegistries.FLUID_STACK.addProvider( FluidData::fill );
VanillaDetailRegistries.ITEM_STACK.addProvider( ItemData::fill );
VanillaDetailRegistries.BLOCK_IN_WORLD.addProvider( BlockData::fill );
ForgeDetailRegistries.FLUID_STACK.addProvider( FluidData::fill );
CauldronInteraction.WATER.put( ModItems.TURTLE_NORMAL.get(), ItemTurtle.CAULDRON_INTERACTION );
CauldronInteraction.WATER.put( ModItems.TURTLE_ADVANCED.get(), ItemTurtle.CAULDRON_INTERACTION );

View File

@ -9,7 +9,7 @@ import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.detail.BlockReference;
import dan200.computercraft.api.detail.DetailRegistries;
import dan200.computercraft.api.detail.VanillaDetailRegistries;
import dan200.computercraft.api.lua.*;
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
import dan200.computercraft.shared.util.NBTUtil;
@ -77,7 +77,7 @@ public class CommandAPI implements ILuaAPI
{
// Get the details of the block
BlockReference block = new BlockReference( world, pos );
Map<String, Object> table = DetailRegistries.BLOCK_IN_WORLD.getDetails( block );
Map<String, Object> table = VanillaDetailRegistries.BLOCK_IN_WORLD.getDetails( block );
BlockEntity tile = block.blockEntity();
if( tile != null ) table.put( "nbt", NBTUtil.toLua( tile.saveWithFullMetadata() ) );

View File

@ -72,8 +72,8 @@ public class UpgradesLoadedMessage implements NetworkMessage
@Override
public void toBytes( @Nonnull FriendlyByteBuf buf )
{
toBytes( buf, TurtleUpgradeSerialiser.registry(), turtleUpgrades );
toBytes( buf, PocketUpgradeSerialiser.registry(), pocketUpgrades );
toBytes( buf, RegistryManager.ACTIVE.getRegistry( TurtleUpgradeSerialiser.REGISTRY_ID ), turtleUpgrades );
toBytes( buf, RegistryManager.ACTIVE.getRegistry( PocketUpgradeSerialiser.REGISTRY_ID ), pocketUpgrades );
}
private <R extends UpgradeSerialiser<? extends T>, T extends IUpgradeBase> void toBytes(

View File

@ -6,7 +6,7 @@
package dan200.computercraft.shared.peripheral.generic.methods;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.detail.DetailRegistries;
import dan200.computercraft.api.detail.ForgeDetailRegistries;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.GenericPeripheral;
@ -74,7 +74,7 @@ public class FluidMethods implements GenericPeripheral
for( int i = 0; i < size; i++ )
{
FluidStack stack = fluids.getFluidInTank( i );
if( !stack.isEmpty() ) result.put( i + 1, DetailRegistries.FLUID_STACK.getBasicDetails( stack ) );
if( !stack.isEmpty() ) result.put( i + 1, ForgeDetailRegistries.FLUID_STACK.getBasicDetails( stack ) );
}
return result;

View File

@ -6,7 +6,7 @@
package dan200.computercraft.shared.peripheral.generic.methods;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.detail.DetailRegistries;
import dan200.computercraft.api.detail.VanillaDetailRegistries;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
@ -99,7 +99,7 @@ public class InventoryMethods implements GenericPeripheral
for( int i = 0; i < size; i++ )
{
ItemStack stack = inventory.getStackInSlot( i );
if( !stack.isEmpty() ) result.put( i + 1, DetailRegistries.ITEM_STACK.getBasicDetails( stack ) );
if( !stack.isEmpty() ) result.put( i + 1, VanillaDetailRegistries.ITEM_STACK.getBasicDetails( stack ) );
}
return result;
@ -149,7 +149,7 @@ public class InventoryMethods implements GenericPeripheral
assertBetween( slot, 1, inventory.getSlots(), "Slot out of range (%s)" );
ItemStack stack = inventory.getStackInSlot( slot - 1 );
return stack.isEmpty() ? null : DetailRegistries.ITEM_STACK.getDetails( stack );
return stack.isEmpty() ? null : VanillaDetailRegistries.ITEM_STACK.getDetails( stack );
}
/**

View File

@ -6,7 +6,7 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.collect.ImmutableMap;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.ForgeComputerCraftAPI;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.util.WaterloggableHelpers;
@ -86,7 +86,7 @@ public class BlockCable extends BlockGeneric implements SimpleWaterloggedBlock
{
if( !state.getValue( CABLE ) ) return false;
if( state.getValue( MODEM ).getFacing() == direction ) return true;
return ComputerCraftAPI.getWiredElementAt( world, pos.relative( direction ), direction.getOpposite() ).isPresent();
return ForgeComputerCraftAPI.getWiredElementAt( world, pos.relative( direction ), direction.getOpposite() ).isPresent();
}
@Nonnull

View File

@ -6,7 +6,7 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.base.Objects;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.ForgeComputerCraftAPI;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
@ -346,7 +346,7 @@ public class TileCable extends TileGeneric
BlockPos offset = current.relative( facing );
if( !world.isLoaded( offset ) ) continue;
LazyOptional<IWiredElement> element = ComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() );
LazyOptional<IWiredElement> element = ForgeComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() );
if( !element.isPresent() ) continue;
element.addListener( connectedNodeChanged );

View File

@ -6,7 +6,7 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.base.Objects;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.ForgeComputerCraftAPI;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
@ -308,7 +308,7 @@ public class TileWiredModemFull extends TileGeneric
BlockPos offset = current.relative( facing );
if( !world.isLoaded( offset ) ) continue;
LazyOptional<IWiredElement> element = ComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() );
LazyOptional<IWiredElement> element = ForgeComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() );
if( !element.isPresent() ) continue;
element.addListener( connectedNodeChanged );

View File

@ -5,20 +5,15 @@
*/
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 dan200.computercraft.api.turtle.TurtleRefuelHandler;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import javax.annotation.Nonnull;
import java.util.OptionalInt;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
public final class FurnaceRefuelHandler implements TurtleRefuelHandler
{
private static final FurnaceRefuelHandler INSTANCE = new FurnaceRefuelHandler();
@ -27,37 +22,29 @@ public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
}
@Override
public int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack currentStack, int slot, int limit )
public OptionalInt refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack currentStack, int slot, int limit )
{
int fuelPerItem = getFuelPerItem( currentStack );
if( fuelPerItem <= 0 ) return OptionalInt.empty();
if( limit == 0 ) return OptionalInt.of( 0 );
int fuelSpaceLeft = turtle.getFuelLimit() - turtle.getFuelLevel();
int fuelPerItem = getFuelPerItem( turtle.getItemHandler().getStackInSlot( slot ) );
int fuelItemLimit = (int) Math.ceil( fuelSpaceLeft / (double) fuelPerItem );
if( limit > fuelItemLimit ) limit = fuelItemLimit;
ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false );
ItemStack stack = turtle.getInventory().removeItem( slot, limit );
int fuelToGive = fuelPerItem * stack.getCount();
// Store the replacement item in the inventory
ItemStack replacementStack = ForgeHooks.getCraftingRemainingItem( stack );
if( !replacementStack.isEmpty() )
{
ItemStack remainder = InventoryUtil.storeItems( replacementStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( !remainder.isEmpty() )
{
WorldUtil.dropItemStack( remainder, turtle.getLevel(), turtle.getPosition(), turtle.getDirection().getOpposite() );
}
}
if( !replacementStack.isEmpty() ) TurtleUtil.storeItemOrDrop( turtle, replacementStack );
return fuelToGive;
turtle.getInventory().setChanged();
return OptionalInt.of( fuelToGive );
}
private static int getFuelPerItem( @Nonnull ItemStack stack )
{
return (ForgeHooks.getBurnTime( stack, null ) * 5) / 100;
}
@SubscribeEvent
public static void onTurtleRefuel( TurtleRefuelEvent event )
{
if( event.getHandler() == null && getFuelPerItem( event.getStack() ) > 0 ) event.setHandler( INSTANCE );
}
}

View File

@ -0,0 +1,50 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.turtle;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.shared.util.DropConsumer;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.world.item.ItemStack;
import java.util.function.Function;
public class TurtleUtil
{
/**
* Store an item in this turtle, or drop it if there is room remaining.
*
* @param turtle The turtle to store items into.
* @param stack The stack to store.
*/
public static void storeItemOrDrop( ITurtleAccess turtle, ItemStack stack )
{
if( stack.isEmpty() ) return;
if( turtle.isRemoved() )
{
WorldUtil.dropItemStack( stack, turtle.getLevel(), turtle.getPosition(), null );
return;
}
// Put the remainder back in the turtle
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder.isEmpty() ) return;
WorldUtil.dropItemStack( remainder, turtle.getLevel(), turtle.getPosition(), turtle.getDirection().getOpposite() );
}
public static Function<ItemStack, ItemStack> dropConsumer( ITurtleAccess turtle )
{
return stack -> turtle.isRemoved() ? stack : InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
}
public static void stopConsuming( ITurtleAccess turtle )
{
var direction = turtle.isRemoved() ? null : turtle.getDirection().getOpposite();
DropConsumer.clearAndDrop( turtle.getLevel(), turtle.getPosition(), direction );
}
}

View File

@ -5,7 +5,7 @@
*/
package dan200.computercraft.shared.turtle.apis;
import dan200.computercraft.api.detail.DetailRegistries;
import dan200.computercraft.api.detail.VanillaDetailRegistries;
import dan200.computercraft.api.lua.*;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleCommand;
@ -820,7 +820,7 @@ public class TurtleAPI implements ILuaAPI
if( stack.isEmpty() ) return new Object[] { null };
Map<String, Object> table = detailed
? DetailRegistries.ITEM_STACK.getDetails( stack )
? VanillaDetailRegistries.ITEM_STACK.getDetails( stack )
: ItemData.fillBasicSafe( new HashMap<>(), stack );
return new Object[] { table };

View File

@ -287,6 +287,12 @@ public class TurtleBrain implements ITurtleAccess
return owner.getBlockPos();
}
@Override
public boolean isRemoved()
{
return owner.isRemoved();
}
@Override
public boolean teleportTo( @Nonnull Level world, @Nonnull BlockPos pos )
{

View File

@ -9,9 +9,8 @@ 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.shared.turtle.TurtleUtil;
import dan200.computercraft.shared.turtle.upgrades.TurtleInventoryCrafting;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nonnull;
@ -36,14 +35,7 @@ public class TurtleCraftCommand implements ITurtleCommand
if( results == null ) return TurtleCommandResult.failure( "No matching recipes" );
// Store or drop any remainders
for( ItemStack stack : results )
{
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( !remainder.isEmpty() )
{
WorldUtil.dropItemStack( remainder, turtle.getLevel(), turtle.getPosition(), turtle.getDirection() );
}
}
for( ItemStack stack : results ) TurtleUtil.storeItemOrDrop( turtle, stack );
if( !results.isEmpty() ) turtle.playAnimation( TurtleAnimation.WAIT );
return TurtleCommandResult.success();

View File

@ -45,11 +45,12 @@ public class TurtleDropCommand implements ITurtleCommand
Direction direction = this.direction.toWorldDir( turtle );
// Get things to drop
ItemStack stack = InventoryUtil.takeItems( quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
ItemStack stack = turtle.getInventory().removeItem( turtle.getSelectedSlot(), quantity );
if( stack.isEmpty() )
{
return TurtleCommandResult.failure( "No items to drop" );
}
turtle.getInventory().setChanged();
// Get inventory for thing in front
Level world = turtle.getLevel();

View File

@ -7,11 +7,8 @@ package dan200.computercraft.shared.turtle.core;
import dan200.computercraft.api.turtle.*;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.core.BlockPos;
import dan200.computercraft.shared.turtle.TurtleUtil;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
@ -31,8 +28,7 @@ public class TurtleEquipCommand implements ITurtleCommand
// Determine the upgrade to equipLeft
ITurtleUpgrade newUpgrade;
ItemStack newUpgradeStack;
IItemHandler inventory = turtle.getItemHandler();
ItemStack selectedStack = inventory.getStackInSlot( turtle.getSelectedSlot() );
ItemStack selectedStack = turtle.getInventory().getItem( turtle.getSelectedSlot() );
if( !selectedStack.isEmpty() )
{
newUpgradeStack = selectedStack.copy();
@ -59,22 +55,8 @@ public class TurtleEquipCommand implements ITurtleCommand
}
// Do the swapping:
if( newUpgradeStack != null )
{
// Consume new upgrades item
InventoryUtil.takeItems( 1, inventory, turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
}
if( oldUpgradeStack != null )
{
// Store old upgrades item
ItemStack remainder = InventoryUtil.storeItems( oldUpgradeStack, inventory, turtle.getSelectedSlot() );
if( !remainder.isEmpty() )
{
// If there's no room for the items, drop them
BlockPos position = turtle.getPosition();
WorldUtil.dropItemStack( remainder, turtle.getLevel(), position, turtle.getDirection() );
}
}
if( newUpgradeStack != null ) turtle.getInventory().removeItem( turtle.getSelectedSlot(), 1 );
if( oldUpgradeStack != null ) TurtleUtil.storeItemOrDrop( turtle, oldUpgradeStack );
turtle.setUpgrade( side, newUpgrade );
// Animate

View File

@ -6,7 +6,7 @@
package dan200.computercraft.shared.turtle.core;
import dan200.computercraft.api.detail.BlockReference;
import dan200.computercraft.api.detail.DetailRegistries;
import dan200.computercraft.api.detail.VanillaDetailRegistries;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleCommand;
import dan200.computercraft.api.turtle.TurtleCommandResult;
@ -41,7 +41,7 @@ public class TurtleInspectCommand implements ITurtleCommand
BlockReference block = new BlockReference( world, newPosition );
if( block.state().isAir() ) return TurtleCommandResult.failure( "No block to inspect" );
Map<String, Object> table = DetailRegistries.BLOCK_IN_WORLD.getDetails( block );
Map<String, Object> table = VanillaDetailRegistries.BLOCK_IN_WORLD.getDetails( block );
return TurtleCommandResult.success( new Object[] { table } );

View File

@ -11,6 +11,7 @@ import dan200.computercraft.api.turtle.ITurtleCommand;
import dan200.computercraft.api.turtle.TurtleAnimation;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.shared.TurtlePermissions;
import dan200.computercraft.shared.turtle.TurtleUtil;
import dan200.computercraft.shared.util.DropConsumer;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
@ -124,7 +125,6 @@ public class TurtlePlaceCommand implements ITurtleCommand
{
// See if there is an entity present
final Level world = turtle.getLevel();
final BlockPos position = turtle.getPosition();
Vec3 turtlePos = turtlePlayer.position();
Vec3 rayDir = turtlePlayer.getViewVector( 1.0f );
Pair<Entity, Vec3> hit = WorldUtil.rayTraceEntities( world, turtlePos, rayDir, 1.5 );
@ -139,7 +139,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
boolean placed = doDeployOnEntity( stack, turtlePlayer, hitEntity, hitPos );
DropConsumer.clearAndDrop( world, position, turtle.getDirection().getOpposite() );
TurtleUtil.stopConsuming( turtle );
return placed;
}

View File

@ -8,9 +8,8 @@ package dan200.computercraft.shared.turtle.core;
import com.mojang.authlib.GameProfile;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.shared.turtle.TurtleUtil;
import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
@ -157,39 +156,33 @@ public final class TurtlePlayer extends FakePlayer
getInventory().clearContent();
int currentSlot = turtle.getSelectedSlot();
int slots = turtle.getItemHandler().getSlots();
int slots = turtle.getInventory().getContainerSize();
// Load up the fake inventory
getInventory().selected = 0;
for( int i = 0; i < slots; i++ )
{
getInventory().setItem( i, turtle.getItemHandler().getStackInSlot( (currentSlot + i) % slots ) );
getInventory().setItem( i, turtle.getInventory().getItem( (currentSlot + i) % slots ) );
}
}
public void unloadInventory( ITurtleAccess turtle )
{
int currentSlot = turtle.getSelectedSlot();
int slots = turtle.getItemHandler().getSlots();
int slots = turtle.getInventory().getContainerSize();
// Load up the fake inventory
getInventory().selected = 0;
for( int i = 0; i < slots; i++ )
{
turtle.getItemHandler().setStackInSlot( (currentSlot + i) % slots, getInventory().getItem( i ) );
turtle.getInventory().setItem( (currentSlot + i) % slots, getInventory().getItem( i ) );
}
// Store (or drop) anything else we found
BlockPos dropPosition = turtle.getPosition();
Direction dropDirection = turtle.getDirection().getOpposite();
int totalSize = getInventory().getContainerSize();
for( int i = slots; i < totalSize; i++ )
{
ItemStack remainder = InventoryUtil.storeItems( getInventory().getItem( i ), turtle.getItemHandler(), turtle.getSelectedSlot() );
if( !remainder.isEmpty() )
{
WorldUtil.dropItemStack( remainder, turtle.getLevel(), dropPosition, dropDirection );
}
TurtleUtil.storeItemOrDrop( turtle, getInventory().getItem( i ) );
}
getInventory().setChanged();

View File

@ -9,9 +9,8 @@ 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.TurtleRefuelEvent;
import dan200.computercraft.impl.TurtleRefuelHandlers;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import javax.annotation.Nonnull;
@ -32,13 +31,13 @@ public class TurtleRefuelCommand implements ITurtleCommand
ItemStack stack = turtle.getInventory().getItem( slot );
if( stack.isEmpty() ) return TurtleCommandResult.failure( "No items to combust" );
TurtleRefuelEvent event = new TurtleRefuelEvent( turtle, stack );
MinecraftForge.EVENT_BUS.post( event );
if( event.getHandler() == null ) return TurtleCommandResult.failure( "Items not combustible" );
var refuelled = TurtleRefuelHandlers.refuel( turtle, stack, slot, limit );
if( refuelled.isEmpty() ) return TurtleCommandResult.failure( "Items not combustible" );
if( limit != 0 )
var newFuel = refuelled.getAsInt();
if( newFuel != 0 )
{
turtle.addFuel( event.getHandler().refuel( turtle, stack, slot, limit ) );
turtle.addFuel( newFuel );
turtle.playAnimation( TurtleAnimation.WAIT );
}

View File

@ -30,7 +30,7 @@ public class TurtleTransferToCommand implements ITurtleCommand
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
{
// Take stack
ItemStack stack = InventoryUtil.takeItems( quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
ItemStack stack = turtle.getInventory().removeItem( turtle.getSelectedSlot(), quantity );
if( stack.isEmpty() )
{
turtle.playAnimation( TurtleAnimation.WAIT );

View File

@ -9,11 +9,10 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftTags;
import dan200.computercraft.api.turtle.*;
import dan200.computercraft.shared.TurtlePermissions;
import dan200.computercraft.shared.turtle.core.TurtleBrain;
import dan200.computercraft.shared.turtle.TurtleUtil;
import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand;
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import dan200.computercraft.shared.util.DropConsumer;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -42,7 +41,6 @@ import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.function.Function;
import static net.minecraft.nbt.Tag.TAG_COMPOUND;
import static net.minecraft.nbt.Tag.TAG_LIST;
@ -117,8 +115,6 @@ public class TurtleTool extends AbstractTurtleUpgrade
// Create a fake player, and orient it appropriately
Level world = turtle.getLevel();
BlockPos position = turtle.getPosition();
BlockEntity turtleTile = turtle instanceof TurtleBrain ? ((TurtleBrain) turtle).getOwner() : world.getBlockEntity( position );
if( turtleTile == null ) return TurtleCommandResult.failure( "Turtle has vanished from existence." );
final TurtlePlayer turtlePlayer = TurtlePlayer.getWithPosition( turtle, position, direction );
@ -141,7 +137,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
}
// Start claiming entity drops
DropConsumer.set( hitEntity, turtleDropConsumer( turtleTile, turtle ) );
DropConsumer.set( hitEntity, TurtleUtil.dropConsumer( turtle ) );
// Attack the entity
boolean attacked = false;
@ -166,7 +162,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
}
// Stop claiming drops
stopConsuming( turtleTile, turtle );
TurtleUtil.stopConsuming( turtle );
// Put everything we collected into the turtles inventory, then return
if( attacked )
@ -181,8 +177,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
private TurtleCommandResult dig( ITurtleAccess turtle, Direction direction )
{
// TODO: HOE_TILL really, if it's ever implemented
if( item.canPerformAction( ToolActions.SHOVEL_FLATTEN ) || item.canPerformAction( ToolActions.HOE_DIG ) )
if( item.canPerformAction( ToolActions.SHOVEL_FLATTEN ) || item.canPerformAction( ToolActions.HOE_TILL ) )
{
if( TurtlePlaceCommand.deployCopiedItem( item.copy(), turtle, direction, null, null ) )
{
@ -193,8 +188,6 @@ public class TurtleTool extends AbstractTurtleUpgrade
// Get ready to dig
Level world = turtle.getLevel();
BlockPos turtlePosition = turtle.getPosition();
BlockEntity turtleTile = turtle instanceof TurtleBrain ? ((TurtleBrain) turtle).getOwner() : world.getBlockEntity( turtlePosition );
if( turtleTile == null ) return TurtleCommandResult.failure( "Turtle has vanished from existence." );
BlockPos blockPosition = turtlePosition.relative( direction );
if( world.isEmptyBlock( blockPosition ) || WorldUtil.isLiquidBlock( world, blockPosition ) )
@ -227,7 +220,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
if( !breakable.isSuccess() ) return breakable;
// Consume the items the block drops
DropConsumer.set( world, blockPosition, turtleDropConsumer( turtleTile, turtle ) );
DropConsumer.set( world, blockPosition, TurtleUtil.dropConsumer( turtle ) );
BlockEntity tile = world.getBlockEntity( blockPosition );
@ -246,23 +239,12 @@ public class TurtleTool extends AbstractTurtleUpgrade
state.getBlock().playerDestroy( world, turtlePlayer, blockPosition, state, tile, turtlePlayer.getMainHandItem() );
}
stopConsuming( turtleTile, turtle );
TurtleUtil.stopConsuming( turtle );
return TurtleCommandResult.success();
}
private static Function<ItemStack, ItemStack> turtleDropConsumer( BlockEntity tile, ITurtleAccess turtle )
{
return drop -> tile.isRemoved() ? drop : InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
}
private static void stopConsuming( BlockEntity tile, ITurtleAccess turtle )
{
Direction direction = tile.isRemoved() ? null : turtle.getDirection().getOpposite();
DropConsumer.clearAndDrop( turtle.getLevel(), turtle.getPosition(), direction );
}
protected boolean isTriviallyBreakable( BlockGetter reader, BlockPos pos, BlockState state )
{
return state.is( ComputerCraftTags.Blocks.TURTLE_ALWAYS_BREAKABLE )

View File

@ -127,12 +127,6 @@ public final class InventoryUtil
// Methods for taking out of inventories
@Nonnull
public static ItemStack takeItems( int count, IItemHandler inventory, int begin )
{
return takeItems( count, inventory, 0, inventory.getSlots(), begin );
}
@Nonnull
public static ItemStack takeItems( int count, IItemHandler inventory )
{

View File

@ -6,7 +6,7 @@
package dan200.computercraft.gametest
import dan200.computercraft.api.detail.BasicItemDetailProvider
import dan200.computercraft.api.detail.DetailRegistries
import dan200.computercraft.api.detail.VanillaDetailRegistries
import dan200.computercraft.api.lua.ObjectArguments
import dan200.computercraft.core.apis.PeripheralAPI
import dan200.computercraft.gametest.api.*
@ -172,7 +172,7 @@ class Turtle_Test {
fun Item_detail_provider(helper: GameTestHelper) = helper.sequence {
// Register a dummy provider for printout items
thenExecute {
DetailRegistries.ITEM_STACK.addProvider(
VanillaDetailRegistries.ITEM_STACK.addProvider(
object :
BasicItemDetailProvider<ItemPrintout>("printout", ItemPrintout::class.java) {
override fun provideDetails(data: MutableMap<in String, Any>, stack: ItemStack, item: ItemPrintout) {

View File

@ -174,7 +174,7 @@ fun GameTestHelper.assertContainerExactly(pos: BlockPos, items: List<ItemStack>)
}
}
private fun getName(type: BlockEntityType<*>): ResourceLocation = ForgeRegistries.BLOCK_ENTITIES.getKey(type)!!
private fun getName(type: BlockEntityType<*>): ResourceLocation = ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(type)!!
/**
* Get a [BlockEntity] of a specific type.