mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-26 19:37:39 +00:00 
			
		
		
		
	make gui work
This commit is contained in:
		| @@ -41,6 +41,9 @@ dependencies { | ||||
|     modImplementation "me.shedaniel.cloth:config-2:${cloth_config_version}" | ||||
|     modImplementation "io.github.prospector:modmenu:${modmenu_version}" | ||||
|  | ||||
|     modApi "me.shedaniel.cloth.api:cloth-utils-v1:${project.cloth_api_version}" | ||||
|     include "me.shedaniel.cloth.api:cloth-utils-v1:${project.cloth_api_version}" | ||||
|  | ||||
|     implementation "blue.endless:jankson:${jankson_version}" | ||||
|     implementation 'com.google.code.findbugs:jsr305:3.0.2' | ||||
|  | ||||
|   | ||||
| @@ -11,3 +11,4 @@ fabric_api_version=0.19.0+build.398-1.16 | ||||
| fabric_loader_version=0.9.2+build.206 | ||||
| jankson_version=1.2.0 | ||||
| modmenu_version=1.14.6+ | ||||
| cloth_api_version=1.4.5 | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import dan200.computercraft.shared.peripheral.modem.wired.TileWiredModemFull; | ||||
| import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork; | ||||
| import dan200.computercraft.shared.util.IDAssigner; | ||||
| import dan200.computercraft.shared.wired.WiredNode; | ||||
| import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; | ||||
| import net.fabricmc.loader.api.FabricLoader; | ||||
| import net.minecraft.block.entity.BlockEntity; | ||||
| import net.minecraft.resource.ReloadableResourceManager; | ||||
| @@ -40,7 +41,6 @@ import javax.annotation.Nonnull; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.Optional; | ||||
|  | ||||
| public final class ComputerCraftAPIImpl implements IComputerCraftAPI | ||||
| { | ||||
| @@ -54,8 +54,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI | ||||
|  | ||||
|     public static InputStream getResourceFile( String domain, String subPath ) | ||||
|     { | ||||
|         if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) { | ||||
|             ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServer) FabricLoader.getInstance().getGameInstance()).getDataPackManager(); | ||||
|         MinecraftServer server = GameInstanceUtils.getServer(); | ||||
|         if (server != null) { | ||||
|             ReloadableResourceManager manager = (ReloadableResourceManager) server.serverResourceManager.getResourceManager(); | ||||
|             try { | ||||
|                 return manager.getResource(new Identifier(domain, subPath)).getInputStream(); | ||||
|             } catch (IOException ignored) { | ||||
| @@ -97,8 +98,10 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI | ||||
|     @Override | ||||
|     public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath ) | ||||
|     { | ||||
|         if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) { | ||||
|             ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServer) FabricLoader.getInstance().getGameInstance()).getDataPackManager(); | ||||
|         MinecraftServer server = GameInstanceUtils.getServer(); | ||||
|         if ( server != null ) | ||||
|         { | ||||
|             ReloadableResourceManager manager = (ReloadableResourceManager) server.serverResourceManager.getResourceManager(); | ||||
|             ResourceMount mount = ResourceMount.get(domain, subPath, manager); | ||||
|             return mount.exists("") ? mount : null; | ||||
|         } | ||||
|   | ||||
| @@ -8,8 +8,10 @@ package dan200.computercraft.shared; | ||||
|  | ||||
| import static net.minecraft.util.registry.Registry.BLOCK_ENTITY_TYPE; | ||||
|  | ||||
| import java.util.Objects; | ||||
| import java.util.function.BiFunction; | ||||
| import java.util.function.Function; | ||||
| import java.util.function.Supplier; | ||||
|  | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.shared.common.ContainerHeldItem; | ||||
| @@ -70,11 +72,11 @@ public final class ComputerCraftRegistry { | ||||
|  | ||||
|     public static void init() { | ||||
|         Object[] o = { | ||||
|             ModTiles.CABLE, | ||||
|             ModBlocks.CABLE, | ||||
|             ModItems.CABLE, | ||||
|             ModEntities.TURTLE_PLAYER, | ||||
|             ModContainers.COMPUTER, | ||||
|             ModTiles.CABLE | ||||
|         }; | ||||
|     } | ||||
|  | ||||
| @@ -135,33 +137,33 @@ public final class ComputerCraftRegistry { | ||||
|  | ||||
|     public static class ModTiles { | ||||
|  | ||||
|         private static <T extends BlockEntity> BlockEntityType<T> ofBlock(Block block, String id, Function<BlockEntityType<T>, T> factory) { | ||||
|             return Registry.register(BLOCK_ENTITY_TYPE, new Identifier(MOD_ID, id), FixedPointTileEntityType.create(block, factory)); | ||||
|         private static <T extends BlockEntity> BlockEntityType<T> ofBlock( Supplier<Block> block, String id, Function<BlockEntityType<T>, T> factory) { | ||||
|             return Registry.register(BLOCK_ENTITY_TYPE, new Identifier(MOD_ID, id), FixedPointTileEntityType.create( Objects.requireNonNull(block), factory)); | ||||
|         } | ||||
|  | ||||
|         public static final BlockEntityType<TileMonitor> MONITOR_NORMAL = ofBlock(ModBlocks.MONITOR_NORMAL, "monitor_normal",f -> new TileMonitor(f, false)); | ||||
|         public static final BlockEntityType<TileMonitor> MONITOR_ADVANCED = ofBlock(ModBlocks.MONITOR_ADVANCED, "monitor_advanced",f -> new TileMonitor(f, true)); | ||||
|         public static final BlockEntityType<TileMonitor> MONITOR_NORMAL = ofBlock(() ->ModBlocks.MONITOR_NORMAL, "monitor_normal",f -> new TileMonitor(f, false)); | ||||
|         public static final BlockEntityType<TileMonitor> MONITOR_ADVANCED = ofBlock(() ->ModBlocks.MONITOR_ADVANCED, "monitor_advanced",f -> new TileMonitor(f, true)); | ||||
|  | ||||
|         public static final BlockEntityType<TileComputer> COMPUTER_NORMAL = ofBlock(ModBlocks.COMPUTER_NORMAL,"computer_normal", | ||||
|         public static final BlockEntityType<TileComputer> COMPUTER_NORMAL = ofBlock(() ->ModBlocks.COMPUTER_NORMAL,"computer_normal", | ||||
|                                                                                     f -> new TileComputer(ComputerFamily.NORMAL, f)); | ||||
|         public static final BlockEntityType<TileComputer> COMPUTER_ADVANCED = ofBlock(ModBlocks.COMPUTER_ADVANCED,"computer_advanced", | ||||
|         public static final BlockEntityType<TileComputer> COMPUTER_ADVANCED = ofBlock(() ->ModBlocks.COMPUTER_ADVANCED,"computer_advanced", | ||||
|                                                                                       f -> new TileComputer(ComputerFamily.ADVANCED, f)); | ||||
|         public static final BlockEntityType<TileCommandComputer> COMPUTER_COMMAND = ofBlock(ModBlocks.COMPUTER_COMMAND, "computer_command", | ||||
|         public static final BlockEntityType<TileCommandComputer> COMPUTER_COMMAND = ofBlock(() ->ModBlocks.COMPUTER_COMMAND, "computer_command", | ||||
|                                                                                             f -> new TileCommandComputer(ComputerFamily.COMMAND, f)); | ||||
|  | ||||
|         public static final BlockEntityType<TileTurtle> TURTLE_NORMAL = ofBlock(ModBlocks.TURTLE_NORMAL, "turtle_normal",f -> new TileTurtle(f, ComputerFamily.NORMAL)); | ||||
|         public static final BlockEntityType<TileTurtle> TURTLE_ADVANCED = ofBlock(ModBlocks.TURTLE_ADVANCED,"turtle_advanced", | ||||
|         public static final BlockEntityType<TileTurtle> TURTLE_NORMAL = ofBlock(() ->ModBlocks.TURTLE_NORMAL, "turtle_normal",f -> new TileTurtle(f, ComputerFamily.NORMAL)); | ||||
|         public static final BlockEntityType<TileTurtle> TURTLE_ADVANCED = ofBlock(() ->ModBlocks.TURTLE_ADVANCED,"turtle_advanced", | ||||
|                                                                                   f -> new TileTurtle(f, ComputerFamily.ADVANCED)); | ||||
|  | ||||
|         public static final BlockEntityType<TileSpeaker> SPEAKER = ofBlock(ModBlocks.SPEAKER, "speaker",TileSpeaker::new); | ||||
|         public static final BlockEntityType<TileDiskDrive> DISK_DRIVE = ofBlock(ModBlocks.DISK_DRIVE, "disk_drive",TileDiskDrive::new); | ||||
|         public static final BlockEntityType<TilePrinter> PRINTER = ofBlock(ModBlocks.PRINTER, "printer",TilePrinter::new); | ||||
|         public static final BlockEntityType<TileWiredModemFull> WIRED_MODEM_FULL = ofBlock(ModBlocks.WIRED_MODEM_FULL,"wired_modem_full", TileWiredModemFull::new); | ||||
|         public static final BlockEntityType<TileCable> CABLE = ofBlock(ModBlocks.CABLE, "cable",TileCable::new); | ||||
|         public static final BlockEntityType<TileSpeaker> SPEAKER = ofBlock(() ->ModBlocks.SPEAKER, "speaker",TileSpeaker::new); | ||||
|         public static final BlockEntityType<TileDiskDrive> DISK_DRIVE = ofBlock(() ->ModBlocks.DISK_DRIVE, "disk_drive",TileDiskDrive::new); | ||||
|         public static final BlockEntityType<TilePrinter> PRINTER = ofBlock(() ->ModBlocks.PRINTER, "printer",TilePrinter::new); | ||||
|         public static final BlockEntityType<TileWiredModemFull> WIRED_MODEM_FULL = ofBlock(() ->ModBlocks.WIRED_MODEM_FULL,"wired_modem_full", TileWiredModemFull::new); | ||||
|         public static final BlockEntityType<TileCable> CABLE = ofBlock(() -> ModBlocks.CABLE, "cable",TileCable::new); | ||||
|  | ||||
|         public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_NORMAL = ofBlock(ModBlocks.WIRELESS_MODEM_NORMAL,"wireless_modem_normal", | ||||
|         public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_NORMAL = ofBlock(() ->ModBlocks.WIRELESS_MODEM_NORMAL,"wireless_modem_normal", | ||||
|                                                                                                f -> new TileWirelessModem(f, false)); | ||||
|         public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_ADVANCED = ofBlock(ModBlocks.WIRELESS_MODEM_ADVANCED,"wireless_modem_advanced", | ||||
|         public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_ADVANCED = ofBlock(() ->ModBlocks.WIRELESS_MODEM_ADVANCED,"wireless_modem_advanced", | ||||
|                                                                                                  f -> new TileWirelessModem(f, true)); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,7 @@ import dan200.computercraft.shared.network.NetworkMessage; | ||||
| import dan200.computercraft.shared.network.client.ComputerDataClientMessage; | ||||
| import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage; | ||||
| import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage; | ||||
| import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; | ||||
| import net.fabricmc.loader.api.FabricLoader; | ||||
| import net.minecraft.entity.player.PlayerEntity; | ||||
| import net.minecraft.nbt.CompoundTag; | ||||
| @@ -163,15 +164,16 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput | ||||
|         if( hasOutputChanged() || force ) | ||||
|         { | ||||
|             // Send computer state to all clients | ||||
|             if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) | ||||
|                 NetworkHandler.sendToAllPlayers((MinecraftServer) FabricLoader.getInstance().getGameInstance(), createComputerPacket() ); | ||||
|             MinecraftServer server = GameInstanceUtils.getServer(); | ||||
|             if ( server != null ) | ||||
|                 NetworkHandler.sendToAllPlayers(server, createComputerPacket() ); | ||||
|         } | ||||
|  | ||||
|         if( hasTerminalChanged() || force ) | ||||
|         { | ||||
|             if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) { | ||||
|             MinecraftServer server = GameInstanceUtils.getServer(); | ||||
|             if ( server != null ) { | ||||
|                 // Send terminal state to clients who are currently interacting with the computer. | ||||
|                 MinecraftServer server = (MinecraftServer) FabricLoader.getInstance().getGameInstance(); | ||||
|  | ||||
|                 NetworkMessage packet = null; | ||||
|                 for (PlayerEntity player : server.getPlayerManager().getPlayerList()) { | ||||
| @@ -199,8 +201,9 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput | ||||
|     public void broadcastDelete() | ||||
|     { | ||||
|         // Send deletion to client | ||||
|         if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) | ||||
|         NetworkHandler.sendToAllPlayers((MinecraftServer) FabricLoader.getInstance().getGameInstance(), new ComputerDeletedClientMessage( getInstanceID() ) ); | ||||
|         MinecraftServer server = GameInstanceUtils.getServer(); | ||||
|         if ( server != null ) | ||||
|             NetworkHandler.sendToAllPlayers(server, new ComputerDeletedClientMessage( getInstanceID() ) ); | ||||
|     } | ||||
|  | ||||
|     public void setID( int id ) | ||||
|   | ||||
| @@ -15,6 +15,7 @@ import net.minecraft.screen.ScreenHandler; | ||||
| import net.minecraft.screen.ScreenHandlerType; | ||||
| import javax.annotation.Nonnull; | ||||
| import javax.annotation.Nullable; | ||||
| import java.util.Objects; | ||||
| import java.util.function.Predicate; | ||||
|  | ||||
| public class ContainerComputerBase extends ScreenHandler implements IContainerComputer | ||||
| @@ -28,13 +29,13 @@ public class ContainerComputerBase extends ScreenHandler implements IContainerCo | ||||
|     { | ||||
|         super( type, id ); | ||||
|         this.canUse = canUse; | ||||
|         this.computer = computer; | ||||
|         this.computer = Objects.requireNonNull(computer); | ||||
|         this.family = family; | ||||
|     } | ||||
|  | ||||
|     protected ContainerComputerBase(ScreenHandlerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, PacketByteBuf packetByteBuf) | ||||
|     { | ||||
|         this( type, id, x -> true, getComputer( player, new ComputerContainerData((PacketByteBuf) packetByteBuf.copy()) ), new ComputerContainerData(packetByteBuf).getFamily() ); | ||||
|         this( type, id, x -> true, getComputer( player, new ComputerContainerData(new PacketByteBuf( packetByteBuf.copy() )) ), new ComputerContainerData(packetByteBuf).getFamily() ); | ||||
|     } | ||||
|  | ||||
|     protected static IComputer getComputer( PlayerInventory player, ComputerContainerData data ) | ||||
|   | ||||
| @@ -1,39 +0,0 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.shared.integration.crafttweaker; | ||||
|  | ||||
| import com.blamejared.crafttweaker.api.logger.ILogger; | ||||
|  | ||||
| /** | ||||
|  * Logger which tracks if it has any messages. | ||||
|  */ | ||||
| public final class TrackingLogger | ||||
| { | ||||
|     private final ILogger logger; | ||||
|     private boolean ok = true; | ||||
|  | ||||
|     public TrackingLogger( ILogger logger ) | ||||
|     { | ||||
|         this.logger = logger; | ||||
|     } | ||||
|  | ||||
|     public boolean isOk() | ||||
|     { | ||||
|         return ok; | ||||
|     } | ||||
|  | ||||
|     public void warning( String message ) | ||||
|     { | ||||
|         ok = false; | ||||
|         logger.warning( message ); | ||||
|     } | ||||
|  | ||||
|     public void error( String message ) | ||||
|     { | ||||
|         ok = false; | ||||
|         logger.error( message ); | ||||
|     } | ||||
| } | ||||
| @@ -1,71 +0,0 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.shared.integration.crafttweaker; | ||||
|  | ||||
| import com.blamejared.crafttweaker.api.CraftTweakerAPI; | ||||
| import com.blamejared.crafttweaker.api.annotations.ZenRegister; | ||||
| import com.blamejared.crafttweaker.api.item.IItemStack; | ||||
| import dan200.computercraft.shared.integration.crafttweaker.actions.AddTurtleTool; | ||||
| import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByItem; | ||||
| import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByName; | ||||
| import org.openzen.zencode.java.ZenCodeType; | ||||
|  | ||||
| @ZenRegister | ||||
| @ZenCodeType.Name( "dan200.computercraft.turtle" ) | ||||
| public class TurtleTweaker | ||||
| { | ||||
|     /** | ||||
|      * Remove a turtle upgrade with the given id. | ||||
|      * | ||||
|      * @param upgrade The ID of the to remove | ||||
|      */ | ||||
|     @ZenCodeType.Method | ||||
|     public static void removeUpgrade( String upgrade ) | ||||
|     { | ||||
|         CraftTweakerAPI.apply( new RemoveTurtleUpgradeByName( upgrade ) ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove a turtle upgrade crafted with the given item stack". | ||||
|      * | ||||
|      * @param stack The stack with which the upgrade is crafted. | ||||
|      */ | ||||
|     @ZenCodeType.Method | ||||
|     public static void removeUpgrade( IItemStack stack ) | ||||
|     { | ||||
|         CraftTweakerAPI.apply( new RemoveTurtleUpgradeByItem( stack.getInternal() ) ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add a new turtle tool with the given id, which crafts and acts using the given stack. | ||||
|      * | ||||
|      * @param id    The new upgrade's ID | ||||
|      * @param stack The stack used for crafting the upgrade and used by the turtle as a tool. | ||||
|      */ | ||||
|     @ZenCodeType.Method | ||||
|     public static void addTool( String id, IItemStack stack ) | ||||
|     { | ||||
|         addTool( id, stack, stack, "tool" ); | ||||
|     } | ||||
|  | ||||
|     @ZenCodeType.Method | ||||
|     public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack ) | ||||
|     { | ||||
|         addTool( id, craftingStack, toolStack, "tool" ); | ||||
|     } | ||||
|  | ||||
|     @ZenCodeType.Method | ||||
|     public static void addTool( String id, IItemStack stack, String kind ) | ||||
|     { | ||||
|         addTool( id, stack, stack, kind ); | ||||
|     } | ||||
|  | ||||
|     @ZenCodeType.Method | ||||
|     public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack, String kind ) | ||||
|     { | ||||
|         CraftTweakerAPI.apply( new AddTurtleTool( id, craftingStack.getInternal(), toolStack.getInternal(), kind ) ); | ||||
|     } | ||||
| } | ||||
| @@ -1,126 +0,0 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.shared.integration.crafttweaker.actions; | ||||
|  | ||||
| import com.blamejared.crafttweaker.api.actions.IUndoableAction; | ||||
| import com.blamejared.crafttweaker.api.logger.ILogger; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.turtle.ITurtleUpgrade; | ||||
| import dan200.computercraft.shared.TurtleUpgrades; | ||||
| import dan200.computercraft.shared.integration.crafttweaker.TrackingLogger; | ||||
| import dan200.computercraft.shared.turtle.upgrades.*; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.util.Identifier; | ||||
| import net.minecraftforge.fml.LogicalSide; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * Register a new turtle tool. | ||||
|  */ | ||||
| public class AddTurtleTool implements IUndoableAction | ||||
| { | ||||
|     private interface Factory | ||||
|     { | ||||
|         TurtleTool create( Identifier location, ItemStack craftItem, ItemStack toolItem ); | ||||
|     } | ||||
|  | ||||
|     private static final Map<String, Factory> kinds = new HashMap<>(); | ||||
|  | ||||
|     static | ||||
|     { | ||||
|         kinds.put( "tool", TurtleTool::new ); | ||||
|         kinds.put( "axe", TurtleAxe::new ); | ||||
|         kinds.put( "hoe", TurtleHoe::new ); | ||||
|         kinds.put( "shovel", TurtleShovel::new ); | ||||
|         kinds.put( "sword", TurtleSword::new ); | ||||
|     } | ||||
|  | ||||
|     private final String id; | ||||
|     private final ItemStack craftItem; | ||||
|     private final ItemStack toolItem; | ||||
|     private final String kind; | ||||
|  | ||||
|     private ITurtleUpgrade upgrade; | ||||
|  | ||||
|     public AddTurtleTool( String id, ItemStack craftItem, ItemStack toolItem, String kind ) | ||||
|     { | ||||
|         this.id = id; | ||||
|         this.craftItem = craftItem; | ||||
|         this.toolItem = toolItem; | ||||
|         this.kind = kind; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void apply() | ||||
|     { | ||||
|         ITurtleUpgrade upgrade = this.upgrade; | ||||
|         if( upgrade == null ) | ||||
|         { | ||||
|             Factory factory = kinds.get( kind ); | ||||
|             if( factory == null ) | ||||
|             { | ||||
|                 ComputerCraft.log.error( "Unknown turtle upgrade kind '{}' (this should have been rejected by verify!)", kind ); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             upgrade = this.upgrade = factory.create( new Identifier( id ), craftItem, toolItem ); | ||||
|         } | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             TurtleUpgrades.register( upgrade ); | ||||
|         } | ||||
|         catch( RuntimeException e ) | ||||
|         { | ||||
|             ComputerCraft.log.error( "Registration of turtle tool failed", e ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String describe() | ||||
|     { | ||||
|         return String.format( "Add new turtle %s '%s' (crafted with '%s', uses a '%s')", kind, id, craftItem, toolItem ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void undo() | ||||
|     { | ||||
|         if( upgrade != null ) TurtleUpgrades.remove( upgrade ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String describeUndo() | ||||
|     { | ||||
|         return String.format( "Removing turtle upgrade %s.", id ); | ||||
|     } | ||||
|  | ||||
|     public boolean validate( ILogger logger ) | ||||
|     { | ||||
|         TrackingLogger trackLog = new TrackingLogger( logger ); | ||||
|  | ||||
|         if( craftItem.isEmpty() ) trackLog.warning( "Crafting item stack is empty." ); | ||||
|  | ||||
|         if( craftItem.hasTag() && !craftItem.getTag().isEmpty() ) trackLog.warning( "Crafting item has NBT." ); | ||||
|         if( toolItem.isEmpty() ) trackLog.error( "Tool item stack is empty." ); | ||||
|  | ||||
|         if( !kinds.containsKey( kind ) ) trackLog.error( String.format( "Unknown kind '%s'.", kind ) ); | ||||
|  | ||||
|         if( TurtleUpgrades.get( id ) != null ) | ||||
|         { | ||||
|             trackLog.error( String.format( "An upgrade with the same name ('%s') has already been registered.", id ) ); | ||||
|         } | ||||
|  | ||||
|         return trackLog.isOk(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean shouldApplyOn( LogicalSide side ) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @@ -1,70 +0,0 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.shared.integration.crafttweaker.actions; | ||||
|  | ||||
| import com.blamejared.crafttweaker.api.actions.IUndoableAction; | ||||
| import com.blamejared.crafttweaker.api.logger.ILogger; | ||||
| import dan200.computercraft.api.turtle.ITurtleUpgrade; | ||||
| import dan200.computercraft.shared.TurtleUpgrades; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraftforge.fml.LogicalSide; | ||||
|  | ||||
| /** | ||||
|  * Removes a turtle upgrade crafted with the given stack. | ||||
|  */ | ||||
| public class RemoveTurtleUpgradeByItem implements IUndoableAction | ||||
| { | ||||
|     private final ItemStack stack; | ||||
|     private ITurtleUpgrade upgrade; | ||||
|  | ||||
|     public RemoveTurtleUpgradeByItem( ItemStack stack ) | ||||
|     { | ||||
|         this.stack = stack; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void apply() | ||||
|     { | ||||
|         ITurtleUpgrade upgrade = this.upgrade = TurtleUpgrades.get( stack ); | ||||
|         if( upgrade != null ) TurtleUpgrades.disable( upgrade ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String describe() | ||||
|     { | ||||
|         return String.format( "Remove turtle upgrades crafted with '%s'", stack ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void undo() | ||||
|     { | ||||
|         if( this.upgrade != null ) TurtleUpgrades.enable( upgrade ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String describeUndo() | ||||
|     { | ||||
|         return String.format( "Adding back turtle upgrades crafted with '%s'", stack ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean validate( ILogger logger ) | ||||
|     { | ||||
|         if( TurtleUpgrades.get( stack ) == null ) | ||||
|         { | ||||
|             logger.error( String.format( "Unknown turtle upgrade crafted with '%s'.", stack ) ); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean shouldApplyOn( LogicalSide side ) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @@ -1,69 +0,0 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.shared.integration.crafttweaker.actions; | ||||
|  | ||||
| import com.blamejared.crafttweaker.api.actions.IUndoableAction; | ||||
| import com.blamejared.crafttweaker.api.logger.ILogger; | ||||
| import dan200.computercraft.api.turtle.ITurtleUpgrade; | ||||
| import dan200.computercraft.shared.TurtleUpgrades; | ||||
| import net.minecraftforge.fml.LogicalSide; | ||||
|  | ||||
| /** | ||||
|  * Removes a turtle upgrade with the given id. | ||||
|  */ | ||||
| public class RemoveTurtleUpgradeByName implements IUndoableAction | ||||
| { | ||||
|     private final String id; | ||||
|     private ITurtleUpgrade upgrade; | ||||
|  | ||||
|     public RemoveTurtleUpgradeByName( String id ) | ||||
|     { | ||||
|         this.id = id; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void apply() | ||||
|     { | ||||
|         ITurtleUpgrade upgrade = this.upgrade = TurtleUpgrades.get( id ); | ||||
|         if( upgrade != null ) TurtleUpgrades.disable( upgrade ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String describe() | ||||
|     { | ||||
|         return String.format( "Remove turtle upgrade '%s'", id ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void undo() | ||||
|     { | ||||
|         if( this.upgrade != null ) TurtleUpgrades.enable( upgrade ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String describeUndo() | ||||
|     { | ||||
|         return String.format( "Adding back turtle upgrade '%s'", id ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean validate( ILogger logger ) | ||||
|     { | ||||
|         if( TurtleUpgrades.get( id ) == null ) | ||||
|         { | ||||
|             logger.error( String.format( "Unknown turtle upgrade '%s'.", id ) ); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean shouldApplyOn( LogicalSide side ) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @@ -1,156 +0,0 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.shared.integration.jei; | ||||
|  | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.pocket.IPocketUpgrade; | ||||
| import dan200.computercraft.api.turtle.ITurtleUpgrade; | ||||
| import dan200.computercraft.api.turtle.TurtleSide; | ||||
| import dan200.computercraft.shared.PocketUpgrades; | ||||
| import dan200.computercraft.shared.ComputerCraftRegistry; | ||||
| import dan200.computercraft.shared.TurtleUpgrades; | ||||
| import dan200.computercraft.shared.computer.core.ComputerFamily; | ||||
| import dan200.computercraft.shared.media.items.ItemDisk; | ||||
| import dan200.computercraft.shared.pocket.items.ItemPocketComputer; | ||||
| import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory; | ||||
| import dan200.computercraft.shared.turtle.items.ITurtleItem; | ||||
| import dan200.computercraft.shared.turtle.items.TurtleItemFactory; | ||||
| import mezz.jei.api.IModPlugin; | ||||
| import mezz.jei.api.JeiPlugin; | ||||
| import mezz.jei.api.constants.VanillaRecipeCategoryUid; | ||||
| import mezz.jei.api.constants.VanillaTypes; | ||||
| import mezz.jei.api.ingredients.subtypes.ISubtypeInterpreter; | ||||
| import mezz.jei.api.recipe.IRecipeManager; | ||||
| import mezz.jei.api.recipe.category.IRecipeCategory; | ||||
| import mezz.jei.api.registration.IAdvancedRegistration; | ||||
| import mezz.jei.api.registration.ISubtypeRegistration; | ||||
| import mezz.jei.api.runtime.IJeiRuntime; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.recipe.Recipe; | ||||
| import net.minecraft.util.Identifier; | ||||
| import javax.annotation.Nonnull; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import static dan200.computercraft.shared.integration.jei.RecipeResolver.MAIN_FAMILIES; | ||||
|  | ||||
| @JeiPlugin | ||||
| public class JEIComputerCraft implements IModPlugin | ||||
| { | ||||
|     @Nonnull | ||||
|     @Override | ||||
|     public Identifier getPluginUid() | ||||
|     { | ||||
|         return new Identifier( ComputerCraft.MOD_ID, "jei" ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void registerItemSubtypes( ISubtypeRegistration subtypeRegistry ) | ||||
|     { | ||||
|         subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.TURTLE_NORMAL.get(), turtleSubtype ); | ||||
|         subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.TURTLE_ADVANCED.get(), turtleSubtype ); | ||||
|  | ||||
|         subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL.get(), pocketSubtype ); | ||||
|         subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED.get(), pocketSubtype ); | ||||
|  | ||||
|         subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.DISK.get(), diskSubtype ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void registerAdvanced( IAdvancedRegistration registry ) | ||||
|     { | ||||
|         registry.addRecipeManagerPlugin( new RecipeResolver() ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onRuntimeAvailable( IJeiRuntime runtime ) | ||||
|     { | ||||
|         IRecipeManager registry = runtime.getRecipeManager(); | ||||
|  | ||||
|         // Register all turtles/pocket computers (not just vanilla upgrades) as upgrades on JEI. | ||||
|         List<ItemStack> upgradeItems = new ArrayList<>(); | ||||
|         for( ComputerFamily family : MAIN_FAMILIES ) | ||||
|         { | ||||
|             TurtleUpgrades.getUpgrades() | ||||
|                 .filter( x -> TurtleUpgrades.suitableForFamily( family, x ) ) | ||||
|                 .map( x -> TurtleItemFactory.create( -1, null, -1, family, null, x, 0, null ) ) | ||||
|                 .forEach( upgradeItems::add ); | ||||
|  | ||||
|             for( IPocketUpgrade upgrade : PocketUpgrades.getUpgrades() ) | ||||
|             { | ||||
|                 upgradeItems.add( PocketComputerItemFactory.create( -1, null, -1, family, upgrade ) ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         runtime.getIngredientManager().addIngredientsAtRuntime( VanillaTypes.ITEM, upgradeItems ); | ||||
|  | ||||
|         // Hide all upgrade recipes | ||||
|         IRecipeCategory<?> category = (IRecipeCategory<?>) registry.getRecipeCategory( VanillaRecipeCategoryUid.CRAFTING ); | ||||
|         if( category != null ) | ||||
|         { | ||||
|             for( Object wrapper : registry.getRecipes( category ) ) | ||||
|             { | ||||
|                 if( !(wrapper instanceof Recipe) ) continue; | ||||
|                 Identifier id = ((Recipe) wrapper).getId(); | ||||
|                 if( id.getNamespace().equals( ComputerCraft.MOD_ID ) | ||||
|                     && (id.getPath().startsWith( "generated/turtle_" ) || id.getPath().startsWith( "generated/pocket_" )) ) | ||||
|                 { | ||||
|                     registry.hideRecipe( wrapper, VanillaRecipeCategoryUid.CRAFTING ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Distinguishes turtles by upgrades and family. | ||||
|      */ | ||||
|     private static final ISubtypeInterpreter turtleSubtype = stack -> { | ||||
|         Item item = stack.getItem(); | ||||
|         if( !(item instanceof ITurtleItem) ) return ""; | ||||
|  | ||||
|         ITurtleItem turtle = (ITurtleItem) item; | ||||
|         StringBuilder name = new StringBuilder(); | ||||
|  | ||||
|         // Add left and right upgrades to the identifier | ||||
|         ITurtleUpgrade left = turtle.getUpgrade( stack, TurtleSide.LEFT ); | ||||
|         ITurtleUpgrade right = turtle.getUpgrade( stack, TurtleSide.RIGHT ); | ||||
|         if( left != null ) name.append( left.getUpgradeID() ); | ||||
|         if( left != null && right != null ) name.append( '|' ); | ||||
|         if( right != null ) name.append( right.getUpgradeID() ); | ||||
|  | ||||
|         return name.toString(); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Distinguishes pocket computers by upgrade and family. | ||||
|      */ | ||||
|     private static final ISubtypeInterpreter pocketSubtype = stack -> { | ||||
|         Item item = stack.getItem(); | ||||
|         if( !(item instanceof ItemPocketComputer) ) return ""; | ||||
|  | ||||
|         StringBuilder name = new StringBuilder(); | ||||
|  | ||||
|         // Add the upgrade to the identifier | ||||
|         IPocketUpgrade upgrade = ItemPocketComputer.getUpgrade( stack ); | ||||
|         if( upgrade != null ) name.append( upgrade.getUpgradeID() ); | ||||
|  | ||||
|         return name.toString(); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Distinguishes disks by colour. | ||||
|      */ | ||||
|     private static final ISubtypeInterpreter diskSubtype = stack -> { | ||||
|         Item item = stack.getItem(); | ||||
|         if( !(item instanceof ItemDisk) ) return ""; | ||||
|  | ||||
|         ItemDisk disk = (ItemDisk) item; | ||||
|  | ||||
|         int colour = disk.getColour( stack ); | ||||
|         return colour == -1 ? "" : String.format( "%06x", colour ); | ||||
|     }; | ||||
| } | ||||
| @@ -1,401 +0,0 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.shared.integration.jei; | ||||
|  | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.pocket.IPocketUpgrade; | ||||
| import dan200.computercraft.api.turtle.ITurtleUpgrade; | ||||
| import dan200.computercraft.api.turtle.TurtleSide; | ||||
| import dan200.computercraft.shared.PocketUpgrades; | ||||
| import dan200.computercraft.shared.TurtleUpgrades; | ||||
| import dan200.computercraft.shared.computer.core.ComputerFamily; | ||||
| import dan200.computercraft.shared.pocket.items.ItemPocketComputer; | ||||
| import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory; | ||||
| import dan200.computercraft.shared.turtle.items.ITurtleItem; | ||||
| import dan200.computercraft.shared.turtle.items.TurtleItemFactory; | ||||
| import dan200.computercraft.shared.util.InventoryUtil; | ||||
| import mezz.jei.api.constants.VanillaRecipeCategoryUid; | ||||
| import mezz.jei.api.recipe.IFocus; | ||||
| import mezz.jei.api.recipe.advanced.IRecipeManagerPlugin; | ||||
| import mezz.jei.api.recipe.category.IRecipeCategory; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.recipe.Ingredient; | ||||
| import net.minecraft.recipe.RecipeSerializer; | ||||
| import net.minecraft.recipe.ShapedRecipe; | ||||
| import net.minecraft.util.Identifier; | ||||
| import net.minecraft.util.collection.DefaultedList; | ||||
| import javax.annotation.Nonnull; | ||||
| import java.util.*; | ||||
|  | ||||
| import static net.minecraft.recipe.Ingredient.ofStacks; | ||||
| import static net.minecraft.util.collection.DefaultedList.copyOf; | ||||
|  | ||||
| class RecipeResolver implements IRecipeManagerPlugin | ||||
| { | ||||
|     static final ComputerFamily[] MAIN_FAMILIES = new ComputerFamily[] { ComputerFamily.NORMAL, ComputerFamily.ADVANCED }; | ||||
|  | ||||
|     private final Map<Item, List<UpgradeInfo>> upgradeItemLookup = new HashMap<>(); | ||||
|     private final List<UpgradeInfo> pocketUpgrades = new ArrayList<>(); | ||||
|     private final List<UpgradeInfo> turtleUpgrades = new ArrayList<>(); | ||||
|     private boolean initialised = false; | ||||
|  | ||||
|     /** | ||||
|      * Build a cache of items which are used for turtle and pocket computer upgrades. | ||||
|      */ | ||||
|     private void setupCache() | ||||
|     { | ||||
|         if( initialised ) return; | ||||
|         initialised = true; | ||||
|  | ||||
|         TurtleUpgrades.getUpgrades().forEach( upgrade -> { | ||||
|             ItemStack stack = upgrade.getCraftingItem(); | ||||
|             if( stack.isEmpty() ) return; | ||||
|  | ||||
|             UpgradeInfo info = new UpgradeInfo( stack, upgrade ); | ||||
|             upgradeItemLookup.computeIfAbsent( stack.getItem(), k -> new ArrayList<>( 1 ) ).add( info ); | ||||
|             turtleUpgrades.add( info ); | ||||
|         } ); | ||||
|  | ||||
|         for( IPocketUpgrade upgrade : PocketUpgrades.getUpgrades() ) | ||||
|         { | ||||
|             ItemStack stack = upgrade.getCraftingItem(); | ||||
|             if( stack.isEmpty() ) continue; | ||||
|  | ||||
|             UpgradeInfo info = new UpgradeInfo( stack, upgrade ); | ||||
|             upgradeItemLookup.computeIfAbsent( stack.getItem(), k -> new ArrayList<>( 1 ) ).add( info ); | ||||
|             pocketUpgrades.add( info ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private boolean hasUpgrade( @Nonnull ItemStack stack ) | ||||
|     { | ||||
|         if( stack.isEmpty() ) return false; | ||||
|  | ||||
|         setupCache(); | ||||
|         List<UpgradeInfo> upgrades = upgradeItemLookup.get( stack.getItem() ); | ||||
|         if( upgrades == null ) return false; | ||||
|  | ||||
|         for( UpgradeInfo upgrade : upgrades ) | ||||
|         { | ||||
|             ItemStack craftingStack = upgrade.stack; | ||||
|             if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) ) return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     @Nonnull | ||||
|     @Override | ||||
|     public <V> List<Identifier> getRecipeCategoryUids( @Nonnull IFocus<V> focus ) | ||||
|     { | ||||
|         V value = focus.getValue(); | ||||
|         if( !(value instanceof ItemStack) ) return Collections.emptyList(); | ||||
|  | ||||
|         ItemStack stack = (ItemStack) value; | ||||
|         switch( focus.getMode() ) | ||||
|         { | ||||
|             case INPUT: | ||||
|                 return stack.getItem() instanceof ITurtleItem || stack.getItem() instanceof ItemPocketComputer || | ||||
|                     hasUpgrade( stack ) | ||||
|                     ? Collections.singletonList( VanillaRecipeCategoryUid.CRAFTING ) | ||||
|                     : Collections.emptyList(); | ||||
|             case OUTPUT: | ||||
|                 return stack.getItem() instanceof ITurtleItem || stack.getItem() instanceof ItemPocketComputer | ||||
|                     ? Collections.singletonList( VanillaRecipeCategoryUid.CRAFTING ) | ||||
|                     : Collections.emptyList(); | ||||
|             default: | ||||
|                 return Collections.emptyList(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Nonnull | ||||
|     @Override | ||||
|     public <T, V> List<T> getRecipes( @Nonnull IRecipeCategory<T> recipeCategory, @Nonnull IFocus<V> focus ) | ||||
|     { | ||||
|         if( !(focus.getValue() instanceof ItemStack) || !recipeCategory.getUid().equals( VanillaRecipeCategoryUid.CRAFTING ) ) | ||||
|         { | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|  | ||||
|         ItemStack stack = (ItemStack) focus.getValue(); | ||||
|         switch( focus.getMode() ) | ||||
|         { | ||||
|             case INPUT: | ||||
|                 return cast( findRecipesWithInput( stack ) ); | ||||
|             case OUTPUT: | ||||
|                 return cast( findRecipesWithOutput( stack ) ); | ||||
|             default: | ||||
|                 return Collections.emptyList(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Nonnull | ||||
|     @Override | ||||
|     public <T> List<T> getRecipes( @Nonnull IRecipeCategory<T> recipeCategory ) | ||||
|     { | ||||
|         return Collections.emptyList(); | ||||
|     } | ||||
|  | ||||
|     @Nonnull | ||||
|     private List<Shaped> findRecipesWithInput( @Nonnull ItemStack stack ) | ||||
|     { | ||||
|         setupCache(); | ||||
|  | ||||
|         if( stack.getItem() instanceof ITurtleItem ) | ||||
|         { | ||||
|             // Suggest possible upgrades which can be applied to this turtle | ||||
|             ITurtleItem item = (ITurtleItem) stack.getItem(); | ||||
|             ITurtleUpgrade left = item.getUpgrade( stack, TurtleSide.LEFT ); | ||||
|             ITurtleUpgrade right = item.getUpgrade( stack, TurtleSide.RIGHT ); | ||||
|             if( left != null && right != null ) return Collections.emptyList(); | ||||
|  | ||||
|             List<Shaped> recipes = new ArrayList<>(); | ||||
|             Ingredient ingredient = ofStacks( stack ); | ||||
|             for( UpgradeInfo upgrade : turtleUpgrades ) | ||||
|             { | ||||
|                 // The turtle is facing towards us, so upgrades on the left are actually crafted on the right. | ||||
|                 if( left == null ) | ||||
|                 { | ||||
|                     recipes.add( horizontal( copyOf( Ingredient.EMPTY, ingredient, upgrade.ingredient ), turtleWith( stack, upgrade.turtle, right ) ) ); | ||||
|                 } | ||||
|  | ||||
|                 if( right == null ) | ||||
|                 { | ||||
|                     recipes.add( horizontal( copyOf( Ingredient.EMPTY, upgrade.ingredient, ingredient ), turtleWith( stack, left, upgrade.turtle ) ) ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return cast( recipes ); | ||||
|         } | ||||
|         else if( stack.getItem() instanceof ItemPocketComputer ) | ||||
|         { | ||||
|             // Suggest possible upgrades which can be applied to this turtle | ||||
|             IPocketUpgrade back = ItemPocketComputer.getUpgrade( stack ); | ||||
|             if( back != null ) return Collections.emptyList(); | ||||
|  | ||||
|             List<Shaped> recipes = new ArrayList<>(); | ||||
|             Ingredient ingredient = ofStacks( stack ); | ||||
|             for( UpgradeInfo upgrade : pocketUpgrades ) | ||||
|             { | ||||
|                 recipes.add( vertical( copyOf( Ingredient.EMPTY, ingredient, upgrade.ingredient ), pocketWith( stack, upgrade.pocket ) ) ); | ||||
|             } | ||||
|  | ||||
|             return recipes; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             List<UpgradeInfo> upgrades = upgradeItemLookup.get( stack.getItem() ); | ||||
|             if( upgrades == null ) return Collections.emptyList(); | ||||
|  | ||||
|             List<Shaped> recipes = null; | ||||
|             boolean multiple = false; | ||||
|             Ingredient ingredient = ofStacks( stack ); | ||||
|             for( UpgradeInfo upgrade : upgrades ) | ||||
|             { | ||||
|                 ItemStack craftingStack = upgrade.stack; | ||||
|                 if( craftingStack.isEmpty() || !InventoryUtil.areItemsSimilar( stack, craftingStack ) ) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if( recipes == null ) | ||||
|                 { | ||||
|                     recipes = upgrade.getRecipes(); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if( !multiple ) | ||||
|                     { | ||||
|                         multiple = true; | ||||
|                         recipes = new ArrayList<>( recipes ); | ||||
|                     } | ||||
|                     recipes.addAll( upgrade.getRecipes() ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return recipes == null ? Collections.emptyList() : recipes; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Nonnull | ||||
|     private static List<Shaped> findRecipesWithOutput( @Nonnull ItemStack stack ) | ||||
|     { | ||||
|         // Find which upgrade this item currently has, an so how we could build it. | ||||
|         if( stack.getItem() instanceof ITurtleItem ) | ||||
|         { | ||||
|             ITurtleItem item = (ITurtleItem) stack.getItem(); | ||||
|             List<Shaped> recipes = new ArrayList<>( 0 ); | ||||
|  | ||||
|             ITurtleUpgrade left = item.getUpgrade( stack, TurtleSide.LEFT ); | ||||
|             ITurtleUpgrade right = item.getUpgrade( stack, TurtleSide.RIGHT ); | ||||
|  | ||||
|             // The turtle is facing towards us, so upgrades on the left are actually crafted on the right. | ||||
|             if( left != null ) | ||||
|             { | ||||
|                 recipes.add( horizontal( | ||||
|                     copyOf( Ingredient.EMPTY, ofStacks( turtleWith( stack, null, right ) ), ofStacks( left.getCraftingItem() ) ), | ||||
|                     stack | ||||
|                 ) ); | ||||
|             } | ||||
|  | ||||
|             if( right != null ) | ||||
|             { | ||||
|                 recipes.add( horizontal( | ||||
|                     copyOf( Ingredient.EMPTY, ofStacks( right.getCraftingItem() ), ofStacks( turtleWith( stack, left, null ) ) ), | ||||
|                     stack | ||||
|                 ) ); | ||||
|             } | ||||
|  | ||||
|             return cast( recipes ); | ||||
|         } | ||||
|         else if( stack.getItem() instanceof ItemPocketComputer ) | ||||
|         { | ||||
|             List<Shaped> recipes = new ArrayList<>( 0 ); | ||||
|  | ||||
|             IPocketUpgrade back = ItemPocketComputer.getUpgrade( stack ); | ||||
|             if( back != null ) | ||||
|             { | ||||
|                 recipes.add( vertical( | ||||
|                     copyOf( Ingredient.EMPTY, ofStacks( back.getCraftingItem() ), ofStacks( pocketWith( stack, null ) ) ), | ||||
|                     stack | ||||
|                 ) ); | ||||
|             } | ||||
|  | ||||
|             return cast( recipes ); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @SuppressWarnings( { "unchecked", "rawtypes" } ) | ||||
|     private static <T, U> List<T> cast( List<U> from ) | ||||
|     { | ||||
|         return (List) from; | ||||
|     } | ||||
|  | ||||
|     private static ItemStack turtleWith( ItemStack stack, ITurtleUpgrade left, ITurtleUpgrade right ) | ||||
|     { | ||||
|         ITurtleItem item = (ITurtleItem) stack.getItem(); | ||||
|         return TurtleItemFactory.create( | ||||
|             item.getComputerID( stack ), item.getLabel( stack ), item.getColour( stack ), item.getFamily(), | ||||
|             left, right, item.getFuelLevel( stack ), item.getOverlay( stack ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     private static ItemStack pocketWith( ItemStack stack, IPocketUpgrade back ) | ||||
|     { | ||||
|         ItemPocketComputer item = (ItemPocketComputer) stack.getItem(); | ||||
|         return PocketComputerItemFactory.create( | ||||
|             item.getComputerID( stack ), item.getLabel( stack ), item.getColour( stack ), item.getFamily(), | ||||
|             back | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     private static Shaped vertical( DefaultedList<Ingredient> input, ItemStack result ) | ||||
|     { | ||||
|         return new Shaped( 1, input.size(), input, result ); | ||||
|     } | ||||
|  | ||||
|     private static Shaped horizontal( DefaultedList<Ingredient> input, ItemStack result ) | ||||
|     { | ||||
|         return new Shaped( input.size(), 1, input, result ); | ||||
|     } | ||||
|  | ||||
|     private static class Shaped extends ShapedRecipe | ||||
|     { | ||||
|         private static final Identifier ID = new Identifier( ComputerCraft.MOD_ID, "impostor" ); | ||||
|  | ||||
|         Shaped( int width, int height, DefaultedList<Ingredient> input, ItemStack output ) | ||||
|         { | ||||
|             super( ID, null, width, height, input, output ); | ||||
|         } | ||||
|  | ||||
|         @Nonnull | ||||
|         @Override | ||||
|         public Identifier getId() | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         @Nonnull | ||||
|         @Override | ||||
|         public RecipeSerializer<?> getSerializer() | ||||
|         { | ||||
|             throw new IllegalStateException( "Should not serialise the JEI recipe" ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static final class Upgrade<T> | ||||
|     { | ||||
|         final T upgrade; | ||||
|         final ItemStack stack; | ||||
|         final Ingredient ingredient; | ||||
|  | ||||
|         private Upgrade( T upgrade, ItemStack stack ) | ||||
|         { | ||||
|             this.upgrade = upgrade; | ||||
|             this.stack = stack; | ||||
|             ingredient = ofStacks( stack ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static class UpgradeInfo | ||||
|     { | ||||
|         final ItemStack stack; | ||||
|         final Ingredient ingredient; | ||||
|         final ITurtleUpgrade turtle; | ||||
|         final IPocketUpgrade pocket; | ||||
|         ArrayList<Shaped> recipes; | ||||
|  | ||||
|         UpgradeInfo( ItemStack stack, ITurtleUpgrade turtle ) | ||||
|         { | ||||
|             this.stack = stack; | ||||
|             ingredient = ofStacks( stack ); | ||||
|             this.turtle = turtle; | ||||
|             pocket = null; | ||||
|         } | ||||
|  | ||||
|         UpgradeInfo( ItemStack stack, IPocketUpgrade pocket ) | ||||
|         { | ||||
|             this.stack = stack; | ||||
|             ingredient = ofStacks( stack ); | ||||
|             turtle = null; | ||||
|             this.pocket = pocket; | ||||
|         } | ||||
|  | ||||
|         List<Shaped> getRecipes() | ||||
|         { | ||||
|             ArrayList<Shaped> recipes = this.recipes; | ||||
|             if( recipes != null ) return recipes; | ||||
|  | ||||
|             recipes = this.recipes = new ArrayList<>( 4 ); | ||||
|             for( ComputerFamily family : MAIN_FAMILIES ) | ||||
|             { | ||||
|                 if( turtle != null && TurtleUpgrades.suitableForFamily( family, turtle ) ) | ||||
|                 { | ||||
|                     recipes.add( horizontal( | ||||
|                         copyOf( Ingredient.EMPTY, ingredient, ofStacks( TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null ) ) ), | ||||
|                         TurtleItemFactory.create( -1, null, -1, family, null, turtle, 0, null ) | ||||
|                     ) ); | ||||
|                 } | ||||
|  | ||||
|                 if( pocket != null ) | ||||
|                 { | ||||
|                     recipes.add( vertical( | ||||
|                         copyOf( Ingredient.EMPTY, ingredient, ofStacks( PocketComputerItemFactory.create( -1, null, -1, family, null ) ) ), | ||||
|                         PocketComputerItemFactory.create( -1, null, -1, family, pocket ) | ||||
|                     ) ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             recipes.trimToSize(); | ||||
|             return recipes; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -14,7 +14,7 @@ import net.minecraft.network.PacketByteBuf; | ||||
| import net.minecraft.util.Identifier; | ||||
|  | ||||
| public class ComputerContainerData implements ContainerData { | ||||
|     private static final Identifier IDENTIFIER = new Identifier(ComputerCraft.MOD_ID, "computerContainerData"); | ||||
|     private static final Identifier IDENTIFIER = new Identifier(ComputerCraft.MOD_ID, "computer_container_data"); | ||||
|     private int id; | ||||
|     private ComputerFamily family; | ||||
|  | ||||
|   | ||||
| @@ -20,15 +20,15 @@ import java.util.function.Supplier; | ||||
|  */ | ||||
| public final class FixedPointTileEntityType<T extends BlockEntity> extends BlockEntityType<T> | ||||
| { | ||||
|     private final Block block; | ||||
|     private final Supplier<Block> block; | ||||
|  | ||||
|     private FixedPointTileEntityType( Block block, Supplier<T> builder ) | ||||
|     private FixedPointTileEntityType( Supplier<Block> block, Supplier<T> builder ) | ||||
|     { | ||||
|         super( builder, Collections.emptySet(), null ); | ||||
|         this.block = block; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BlockEntity> FixedPointTileEntityType<T> create( Block block, Function<BlockEntityType<T>, T> builder ) | ||||
|     public static <T extends BlockEntity> FixedPointTileEntityType<T> create( Supplier<Block> block, Function<BlockEntityType<T>, T> builder ) | ||||
|     { | ||||
|         return new FixedPointSupplier<>( block, builder ).factory; | ||||
|     } | ||||
| @@ -36,7 +36,7 @@ public final class FixedPointTileEntityType<T extends BlockEntity> extends Block | ||||
|     @Override | ||||
|     public boolean supports( @Nonnull Block block ) | ||||
|     { | ||||
|         return block == this.block; | ||||
|         return block == this.block.get(); | ||||
|     } | ||||
|  | ||||
|     private static final class FixedPointSupplier<T extends BlockEntity> implements Supplier<T> | ||||
| @@ -44,7 +44,7 @@ public final class FixedPointTileEntityType<T extends BlockEntity> extends Block | ||||
|         final FixedPointTileEntityType<T> factory; | ||||
|         private final Function<BlockEntityType<T>, T> builder; | ||||
|  | ||||
|         private FixedPointSupplier( Block block, Function<BlockEntityType<T>, T> builder ) | ||||
|         private FixedPointSupplier( Supplier<Block> block, Function<BlockEntityType<T>, T> builder ) | ||||
|         { | ||||
|             factory = new FixedPointTileEntityType<>( block, this ); | ||||
|             this.builder = builder; | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import com.google.gson.Gson; | ||||
| import com.google.gson.GsonBuilder; | ||||
| import com.google.gson.reflect.TypeToken; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; | ||||
| import net.fabricmc.loader.api.FabricLoader; | ||||
| import net.minecraft.server.MinecraftServer; | ||||
| import net.minecraft.util.WorldSavePath; | ||||
| @@ -42,7 +43,7 @@ public final class IDAssigner | ||||
|  | ||||
|     public static File getDir() | ||||
|     { | ||||
|         return FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer ? ((MinecraftServer) FabricLoader.getInstance().getGameInstance()).getSavePath( FOLDER ).toFile() : null; | ||||
|         return GameInstanceUtils.getServer().getSavePath( FOLDER ).toFile(); | ||||
|     } | ||||
|  | ||||
|     private static MinecraftServer getCachedServer() | ||||
| @@ -52,7 +53,7 @@ public final class IDAssigner | ||||
|         MinecraftServer currentServer = server.get(); | ||||
|         if( currentServer == null ) return null; | ||||
|  | ||||
|         if(FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer && currentServer != FabricLoader.getInstance().getGameInstance() ) return null; | ||||
|         if( currentServer != GameInstanceUtils.getServer() ) return null; | ||||
|         return currentServer; | ||||
|     } | ||||
|  | ||||
| @@ -62,8 +63,9 @@ public final class IDAssigner | ||||
|         if( currentServer == null ) | ||||
|         { | ||||
|             // The server has changed, refetch our ID map | ||||
|             if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) { | ||||
|                 server = new WeakReference<>((MinecraftServer) FabricLoader.getInstance().getGameInstance()); | ||||
|             if ( GameInstanceUtils.getServer() != null ) | ||||
|             { | ||||
|                 server = new WeakReference<>( GameInstanceUtils.getServer() ); | ||||
|  | ||||
|                 File dir = getDir(); | ||||
|                 dir.mkdirs(); | ||||
|   | ||||
| @@ -15,3 +15,4 @@ accessible class net/minecraft/screen/ScreenHandlerType$Factory | ||||
| accessible method net/minecraft/client/render/model/json/ModelOverrideList <init> ()V | ||||
| extendable class net/minecraft/util/math/Matrix4f | ||||
| accessible method net/minecraft/util/WorldSavePath <init> (Ljava/lang/String;)V | ||||
| accessible field net/minecraft/server/MinecraftServer serverResourceManager Lnet/minecraft/resource/ServerResourceManager; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 shedaniel
					shedaniel