mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-25 02:47: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 "me.shedaniel.cloth:config-2:${cloth_config_version}"
|
||||||
modImplementation "io.github.prospector:modmenu:${modmenu_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 "blue.endless:jankson:${jankson_version}"
|
||||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
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
|
fabric_loader_version=0.9.2+build.206
|
||||||
jankson_version=1.2.0
|
jankson_version=1.2.0
|
||||||
modmenu_version=1.14.6+
|
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.peripheral.modem.wireless.WirelessNetwork;
|
||||||
import dan200.computercraft.shared.util.IDAssigner;
|
import dan200.computercraft.shared.util.IDAssigner;
|
||||||
import dan200.computercraft.shared.wired.WiredNode;
|
import dan200.computercraft.shared.wired.WiredNode;
|
||||||
|
import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.resource.ReloadableResourceManager;
|
import net.minecraft.resource.ReloadableResourceManager;
|
||||||
@@ -40,7 +41,6 @@ import javax.annotation.Nonnull;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public final class ComputerCraftAPIImpl implements IComputerCraftAPI
|
public final class ComputerCraftAPIImpl implements IComputerCraftAPI
|
||||||
{
|
{
|
||||||
@@ -54,8 +54,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
|
|||||||
|
|
||||||
public static InputStream getResourceFile( String domain, String subPath )
|
public static InputStream getResourceFile( String domain, String subPath )
|
||||||
{
|
{
|
||||||
if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) {
|
MinecraftServer server = GameInstanceUtils.getServer();
|
||||||
ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServer) FabricLoader.getInstance().getGameInstance()).getDataPackManager();
|
if (server != null) {
|
||||||
|
ReloadableResourceManager manager = (ReloadableResourceManager) server.serverResourceManager.getResourceManager();
|
||||||
try {
|
try {
|
||||||
return manager.getResource(new Identifier(domain, subPath)).getInputStream();
|
return manager.getResource(new Identifier(domain, subPath)).getInputStream();
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
@@ -97,8 +98,10 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
|
|||||||
@Override
|
@Override
|
||||||
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
|
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
|
||||||
{
|
{
|
||||||
if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) {
|
MinecraftServer server = GameInstanceUtils.getServer();
|
||||||
ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServer) FabricLoader.getInstance().getGameInstance()).getDataPackManager();
|
if ( server != null )
|
||||||
|
{
|
||||||
|
ReloadableResourceManager manager = (ReloadableResourceManager) server.serverResourceManager.getResourceManager();
|
||||||
ResourceMount mount = ResourceMount.get(domain, subPath, manager);
|
ResourceMount mount = ResourceMount.get(domain, subPath, manager);
|
||||||
return mount.exists("") ? mount : null;
|
return mount.exists("") ? mount : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ package dan200.computercraft.shared;
|
|||||||
|
|
||||||
import static net.minecraft.util.registry.Registry.BLOCK_ENTITY_TYPE;
|
import static net.minecraft.util.registry.Registry.BLOCK_ENTITY_TYPE;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.common.ContainerHeldItem;
|
import dan200.computercraft.shared.common.ContainerHeldItem;
|
||||||
@@ -70,11 +72,11 @@ public final class ComputerCraftRegistry {
|
|||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
Object[] o = {
|
Object[] o = {
|
||||||
|
ModTiles.CABLE,
|
||||||
ModBlocks.CABLE,
|
ModBlocks.CABLE,
|
||||||
ModItems.CABLE,
|
ModItems.CABLE,
|
||||||
ModEntities.TURTLE_PLAYER,
|
ModEntities.TURTLE_PLAYER,
|
||||||
ModContainers.COMPUTER,
|
ModContainers.COMPUTER,
|
||||||
ModTiles.CABLE
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,33 +137,33 @@ public final class ComputerCraftRegistry {
|
|||||||
|
|
||||||
public static class ModTiles {
|
public static class ModTiles {
|
||||||
|
|
||||||
private static <T extends BlockEntity> BlockEntityType<T> ofBlock(Block block, String id, Function<BlockEntityType<T>, T> 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(block, 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_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_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));
|
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));
|
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));
|
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_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_ADVANCED = ofBlock(() ->ModBlocks.TURTLE_ADVANCED,"turtle_advanced",
|
||||||
f -> new TileTurtle(f, ComputerFamily.ADVANCED));
|
f -> new TileTurtle(f, ComputerFamily.ADVANCED));
|
||||||
|
|
||||||
public static final BlockEntityType<TileSpeaker> SPEAKER = ofBlock(ModBlocks.SPEAKER, "speaker",TileSpeaker::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<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<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<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<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));
|
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));
|
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.ComputerDataClientMessage;
|
||||||
import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage;
|
import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage;
|
||||||
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
|
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
|
||||||
|
import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
@@ -163,15 +164,16 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
if( hasOutputChanged() || force )
|
if( hasOutputChanged() || force )
|
||||||
{
|
{
|
||||||
// Send computer state to all clients
|
// Send computer state to all clients
|
||||||
if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer)
|
MinecraftServer server = GameInstanceUtils.getServer();
|
||||||
NetworkHandler.sendToAllPlayers((MinecraftServer) FabricLoader.getInstance().getGameInstance(), createComputerPacket() );
|
if ( server != null )
|
||||||
|
NetworkHandler.sendToAllPlayers(server, createComputerPacket() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasTerminalChanged() || force )
|
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.
|
// Send terminal state to clients who are currently interacting with the computer.
|
||||||
MinecraftServer server = (MinecraftServer) FabricLoader.getInstance().getGameInstance();
|
|
||||||
|
|
||||||
NetworkMessage packet = null;
|
NetworkMessage packet = null;
|
||||||
for (PlayerEntity player : server.getPlayerManager().getPlayerList()) {
|
for (PlayerEntity player : server.getPlayerManager().getPlayerList()) {
|
||||||
@@ -199,8 +201,9 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
public void broadcastDelete()
|
public void broadcastDelete()
|
||||||
{
|
{
|
||||||
// Send deletion to client
|
// Send deletion to client
|
||||||
if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer)
|
MinecraftServer server = GameInstanceUtils.getServer();
|
||||||
NetworkHandler.sendToAllPlayers((MinecraftServer) FabricLoader.getInstance().getGameInstance(), new ComputerDeletedClientMessage( getInstanceID() ) );
|
if ( server != null )
|
||||||
|
NetworkHandler.sendToAllPlayers(server, new ComputerDeletedClientMessage( getInstanceID() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setID( int id )
|
public void setID( int id )
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import net.minecraft.screen.ScreenHandler;
|
|||||||
import net.minecraft.screen.ScreenHandlerType;
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class ContainerComputerBase extends ScreenHandler implements IContainerComputer
|
public class ContainerComputerBase extends ScreenHandler implements IContainerComputer
|
||||||
@@ -28,13 +29,13 @@ public class ContainerComputerBase extends ScreenHandler implements IContainerCo
|
|||||||
{
|
{
|
||||||
super( type, id );
|
super( type, id );
|
||||||
this.canUse = canUse;
|
this.canUse = canUse;
|
||||||
this.computer = computer;
|
this.computer = Objects.requireNonNull(computer);
|
||||||
this.family = family;
|
this.family = family;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ContainerComputerBase(ScreenHandlerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, PacketByteBuf packetByteBuf)
|
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 )
|
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;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class ComputerContainerData implements ContainerData {
|
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 int id;
|
||||||
private ComputerFamily family;
|
private ComputerFamily family;
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ import java.util.function.Supplier;
|
|||||||
*/
|
*/
|
||||||
public final class FixedPointTileEntityType<T extends BlockEntity> extends BlockEntityType<T>
|
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 );
|
super( builder, Collections.emptySet(), null );
|
||||||
this.block = block;
|
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;
|
return new FixedPointSupplier<>( block, builder ).factory;
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ public final class FixedPointTileEntityType<T extends BlockEntity> extends Block
|
|||||||
@Override
|
@Override
|
||||||
public boolean supports( @Nonnull Block block )
|
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>
|
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;
|
final FixedPointTileEntityType<T> factory;
|
||||||
private final Function<BlockEntityType<T>, T> builder;
|
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 );
|
factory = new FixedPointTileEntityType<>( block, this );
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.WorldSavePath;
|
import net.minecraft.util.WorldSavePath;
|
||||||
@@ -42,7 +43,7 @@ public final class IDAssigner
|
|||||||
|
|
||||||
public static File getDir()
|
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()
|
private static MinecraftServer getCachedServer()
|
||||||
@@ -52,7 +53,7 @@ public final class IDAssigner
|
|||||||
MinecraftServer currentServer = server.get();
|
MinecraftServer currentServer = server.get();
|
||||||
if( currentServer == null ) return null;
|
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;
|
return currentServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,8 +63,9 @@ public final class IDAssigner
|
|||||||
if( currentServer == null )
|
if( currentServer == null )
|
||||||
{
|
{
|
||||||
// The server has changed, refetch our ID map
|
// The server has changed, refetch our ID map
|
||||||
if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer) {
|
if ( GameInstanceUtils.getServer() != null )
|
||||||
server = new WeakReference<>((MinecraftServer) FabricLoader.getInstance().getGameInstance());
|
{
|
||||||
|
server = new WeakReference<>( GameInstanceUtils.getServer() );
|
||||||
|
|
||||||
File dir = getDir();
|
File dir = getDir();
|
||||||
dir.mkdirs();
|
dir.mkdirs();
|
||||||
|
|||||||
@@ -15,3 +15,4 @@ accessible class net/minecraft/screen/ScreenHandlerType$Factory
|
|||||||
accessible method net/minecraft/client/render/model/json/ModelOverrideList <init> ()V
|
accessible method net/minecraft/client/render/model/json/ModelOverrideList <init> ()V
|
||||||
extendable class net/minecraft/util/math/Matrix4f
|
extendable class net/minecraft/util/math/Matrix4f
|
||||||
accessible method net/minecraft/util/WorldSavePath <init> (Ljava/lang/String;)V
|
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