mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-11-03 23:22:59 +00:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			mc-1.18.x
			...
			v1.19-1.10
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					92c613a7a2 | ||
| 
						 | 
					8fc7820a12 | ||
| 
						 | 
					a2e3d9d9bd | ||
| 
						 | 
					755f8eff93 | ||
| 
						 | 
					a879efc3d0 | ||
| 
						 | 
					a913232e62 | ||
| 
						 | 
					5382d34d29 | ||
| 
						 | 
					8f7719a8dc | 
							
								
								
									
										12
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								build.gradle
									
									
									
									
									
								
							@@ -109,7 +109,8 @@ minecraft {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
 | 
			
		||||
    // mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
 | 
			
		||||
    mappings channel: 'official', version: mc_version
 | 
			
		||||
 | 
			
		||||
    accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
 | 
			
		||||
    accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
 | 
			
		||||
@@ -148,10 +149,12 @@ dependencies {
 | 
			
		||||
    minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
 | 
			
		||||
    annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
 | 
			
		||||
 | 
			
		||||
    extraModsCompileOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116:api")
 | 
			
		||||
    extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116")
 | 
			
		||||
    extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-forge-api:11.0.0.206")
 | 
			
		||||
    extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-common-api:11.0.0.206")
 | 
			
		||||
    extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.19-forge:11.0.0.206")
 | 
			
		||||
 | 
			
		||||
    shade 'org.squiddev:Cobalt:0.5.5'
 | 
			
		||||
    shade 'io.netty:netty-codec-http:4.1.76.Final'
 | 
			
		||||
 | 
			
		||||
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
 | 
			
		||||
    testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
 | 
			
		||||
@@ -223,6 +226,7 @@ shadowJar {
 | 
			
		||||
    archiveClassifier.set("")
 | 
			
		||||
    configurations = [project.configurations.shade]
 | 
			
		||||
    relocate("org.squiddev.cobalt", "cc.tweaked.internal.cobalt")
 | 
			
		||||
    relocate("io.netty.handler.codec.http", "cc.tweaked.internal.netty")
 | 
			
		||||
    minimize()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -491,7 +495,7 @@ def checkRelease = tasks.register("checkRelease") {
 | 
			
		||||
}
 | 
			
		||||
check.dependsOn(checkRelease)
 | 
			
		||||
 | 
			
		||||
def isStable = true
 | 
			
		||||
def isStable = false
 | 
			
		||||
 | 
			
		||||
curseforge {
 | 
			
		||||
    apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ kotlin.stdlib.default.dependency=false
 | 
			
		||||
mod_version=1.100.8
 | 
			
		||||
 | 
			
		||||
# Minecraft properties (update mods.toml when changing)
 | 
			
		||||
mc_version=1.18.2
 | 
			
		||||
mc_version=1.19
 | 
			
		||||
mapping_version=2022.03.13
 | 
			
		||||
forge_version=40.1.0
 | 
			
		||||
forge_version=41.0.38
 | 
			
		||||
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING
 | 
			
		||||
 
 | 
			
		||||
@@ -61,9 +61,11 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
 | 
			
		||||
    public static InputStream getResourceFile( String domain, String subPath )
 | 
			
		||||
    {
 | 
			
		||||
        var manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
 | 
			
		||||
        var resource = manager.getResource( new ResourceLocation( domain, subPath ) ).orElse( null );
 | 
			
		||||
        if( resource == null ) return null;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
 | 
			
		||||
            return resource.open();
 | 
			
		||||
        }
 | 
			
		||||
        catch( IOException ignored )
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,6 @@ public abstract class PocketUpgradeDataProvider extends UpgradeDataProvider<IPoc
 | 
			
		||||
{
 | 
			
		||||
    public PocketUpgradeDataProvider( @Nonnull DataGenerator generator )
 | 
			
		||||
    {
 | 
			
		||||
        super( generator, "Pocket Computer Upgrades", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.REGISTRY_ID );
 | 
			
		||||
        super( generator, "Pocket Computer Upgrades", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.registry() );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
 | 
			
		||||
import net.minecraftforge.registries.DeferredRegister;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistry;
 | 
			
		||||
import net.minecraftforge.registries.RegistryManager;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -40,16 +40,19 @@ public interface PocketUpgradeSerialiser<T extends IPocketUpgrade> extends Upgra
 | 
			
		||||
     *
 | 
			
		||||
     * This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
 | 
			
		||||
     * {@link RegistryManager#getRegistry(ResourceKey)}.
 | 
			
		||||
     *
 | 
			
		||||
     * @see #registry()
 | 
			
		||||
     */
 | 
			
		||||
    ResourceKey<Registry<PocketUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_upgrade_serialiser" ) );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A convenient base class to inherit to implement {@link PocketUpgradeSerialiser}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param <T> The type of the upgrade created by this serialiser.
 | 
			
		||||
     * The associated registry.
 | 
			
		||||
     * @return The registry for pocket upgrade serialisers.
 | 
			
		||||
     * @see #REGISTRY_ID
 | 
			
		||||
     */
 | 
			
		||||
    abstract class Base<T extends IPocketUpgrade> extends ForgeRegistryEntry<PocketUpgradeSerialiser<?>> implements PocketUpgradeSerialiser<T>
 | 
			
		||||
    static IForgeRegistry<PocketUpgradeSerialiser<?>> registry()
 | 
			
		||||
    {
 | 
			
		||||
        return RegistryManager.ACTIVE.getRegistry( REGISTRY_ID );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.level.block.Block;
 | 
			
		||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
@@ -34,7 +35,7 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITur
 | 
			
		||||
 | 
			
		||||
    public TurtleUpgradeDataProvider( DataGenerator generator )
 | 
			
		||||
    {
 | 
			
		||||
        super( generator, "Turtle Upgrades", "computercraft/turtle_upgrades", TurtleUpgradeSerialiser.REGISTRY_ID );
 | 
			
		||||
        super( generator, "Turtle Upgrades", "computercraft/turtle_upgrades", TurtleUpgradeSerialiser.registry() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -137,9 +138,9 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITur
 | 
			
		||||
        public void add( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> add )
 | 
			
		||||
        {
 | 
			
		||||
            add.accept( new Upgrade<>( id, serialiser, s -> {
 | 
			
		||||
                s.addProperty( "item", toolItem.getRegistryName().toString() );
 | 
			
		||||
                s.addProperty( "item", ForgeRegistries.ITEMS.getKey( toolItem ).toString() );
 | 
			
		||||
                if( adjective != null ) s.addProperty( "adjective", adjective );
 | 
			
		||||
                if( craftingItem != null ) s.addProperty( "craftItem", craftingItem.getRegistryName().toString() );
 | 
			
		||||
                if( craftingItem != null ) s.addProperty( "craftItem", ForgeRegistries.ITEMS.getKey( craftingItem ).toString() );
 | 
			
		||||
                if( damageMultiplier != null ) s.addProperty( "damageMultiplier", damageMultiplier );
 | 
			
		||||
                if( breakable != null ) s.addProperty( "breakable", breakable.location().toString() );
 | 
			
		||||
            } ) );
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@ import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.crafting.RecipeSerializer;
 | 
			
		||||
import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
 | 
			
		||||
import net.minecraftforge.registries.DeferredRegister;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistry;
 | 
			
		||||
import net.minecraftforge.registries.RegistryManager;
 | 
			
		||||
 | 
			
		||||
@@ -68,16 +67,18 @@ public interface TurtleUpgradeSerialiser<T extends ITurtleUpgrade> extends Upgra
 | 
			
		||||
     *
 | 
			
		||||
     * This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
 | 
			
		||||
     * {@link RegistryManager#getRegistry(ResourceKey)}.
 | 
			
		||||
     * @see #registry()
 | 
			
		||||
     */
 | 
			
		||||
    ResourceKey<Registry<TurtleUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade_serialiser" ) );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A convenient base class to inherit to implement {@link TurtleUpgradeSerialiser}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param <T> The type of the upgrade created by this serialiser.
 | 
			
		||||
     * The associated registry.
 | 
			
		||||
     * @return The registry for pocket upgrade serialisers.
 | 
			
		||||
     * @see #REGISTRY_ID
 | 
			
		||||
     */
 | 
			
		||||
    abstract class Base<T extends ITurtleUpgrade> extends ForgeRegistryEntry<TurtleUpgradeSerialiser<?>> implements TurtleUpgradeSerialiser<T>
 | 
			
		||||
    static IForgeRegistry<TurtleUpgradeSerialiser<?>> registry()
 | 
			
		||||
    {
 | 
			
		||||
        return RegistryManager.ACTIVE.getRegistry( REGISTRY_ID );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -12,14 +12,13 @@ import com.google.gson.JsonParseException;
 | 
			
		||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
 | 
			
		||||
import dan200.computercraft.internal.upgrades.SerialiserWithCraftingItem;
 | 
			
		||||
import dan200.computercraft.internal.upgrades.SimpleSerialiser;
 | 
			
		||||
import net.minecraft.core.Registry;
 | 
			
		||||
import net.minecraft.data.CachedOutput;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.data.DataProvider;
 | 
			
		||||
import net.minecraft.data.HashCache;
 | 
			
		||||
import net.minecraft.resources.ResourceKey;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraftforge.registries.RegistryManager;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistry;
 | 
			
		||||
import org.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
 | 
			
		||||
@@ -45,11 +44,11 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
 | 
			
		||||
    private final DataGenerator generator;
 | 
			
		||||
    private final String name;
 | 
			
		||||
    private final String folder;
 | 
			
		||||
    private final ResourceKey<Registry<R>> registry;
 | 
			
		||||
    private final IForgeRegistry<R> registry;
 | 
			
		||||
 | 
			
		||||
    private List<T> upgrades;
 | 
			
		||||
 | 
			
		||||
    protected UpgradeDataProvider( @Nonnull DataGenerator generator, @Nonnull String name, @Nonnull String folder, @Nonnull ResourceKey<Registry<R>> registry )
 | 
			
		||||
    protected UpgradeDataProvider( @Nonnull DataGenerator generator, @Nonnull String name, @Nonnull String folder, @Nonnull IForgeRegistry<R> registry )
 | 
			
		||||
    {
 | 
			
		||||
        this.generator = generator;
 | 
			
		||||
        this.name = name;
 | 
			
		||||
@@ -92,7 +91,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new Upgrade<>( id, serialiser, s ->
 | 
			
		||||
            s.addProperty( "item", Objects.requireNonNull( item.getRegistryName(), "Item is not registered" ).toString() )
 | 
			
		||||
            s.addProperty( "item", Objects.requireNonNull( ForgeRegistries.ITEMS.getKey( item ), "Item is not registered" ).toString() )
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -111,7 +110,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
 | 
			
		||||
    protected abstract void addUpgrades( @Nonnull Consumer<Upgrade<R>> addUpgrade );
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public final void run( @Nonnull HashCache cache ) throws IOException
 | 
			
		||||
    public final void run( @Nonnull CachedOutput cache ) throws IOException
 | 
			
		||||
    {
 | 
			
		||||
        Path base = generator.getOutputFolder().resolve( "data" );
 | 
			
		||||
 | 
			
		||||
@@ -121,12 +120,12 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
 | 
			
		||||
            if( !seen.add( upgrade.id() ) ) throw new IllegalStateException( "Duplicate upgrade " + upgrade.id() );
 | 
			
		||||
 | 
			
		||||
            var json = new JsonObject();
 | 
			
		||||
            json.addProperty( "type", Objects.requireNonNull( upgrade.serialiser().getRegistryName(), "Serialiser has not been registered" ).toString() );
 | 
			
		||||
            json.addProperty( "type", Objects.requireNonNull( registry.getKey( upgrade.serialiser() ), "Serialiser has not been registered" ).toString() );
 | 
			
		||||
            upgrade.serialise().accept( json );
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                DataProvider.save( GSON, cache, json, base.resolve( upgrade.id().getNamespace() + "/" + folder + "/" + upgrade.id().getPath() + ".json" ) );
 | 
			
		||||
                DataProvider.saveStable( cache, json, base.resolve( upgrade.id().getNamespace() + "/" + folder + "/" + upgrade.id().getPath() + ".json" ) );
 | 
			
		||||
            }
 | 
			
		||||
            catch( IOException e )
 | 
			
		||||
            {
 | 
			
		||||
@@ -157,7 +156,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public final R existingSerialiser( @Nonnull ResourceLocation id )
 | 
			
		||||
    {
 | 
			
		||||
        var result = RegistryManager.ACTIVE.getRegistry( registry ).getValue( id );
 | 
			
		||||
        var result = registry.getValue( id );
 | 
			
		||||
        if( result == null ) throw new IllegalArgumentException( "No such serialiser " + registry );
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
 | 
			
		||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
 | 
			
		||||
import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
@@ -25,7 +24,7 @@ import javax.annotation.Nonnull;
 | 
			
		||||
 * @see TurtleUpgradeSerialiser
 | 
			
		||||
 * @see PocketUpgradeSerialiser
 | 
			
		||||
 */
 | 
			
		||||
public interface UpgradeSerialiser<T extends IUpgradeBase, R extends UpgradeSerialiser<?, R>> extends IForgeRegistryEntry<R>
 | 
			
		||||
public interface UpgradeSerialiser<T extends IUpgradeBase, R extends UpgradeSerialiser<?, R>>
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Read this upgrade from a JSON file in a datapack.
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ import dan200.computercraft.shared.network.server.ContinueUploadMessage;
 | 
			
		||||
import dan200.computercraft.shared.network.server.UploadFileMessage;
 | 
			
		||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.world.entity.player.Inventory;
 | 
			
		||||
import org.lwjgl.glfw.GLFW;
 | 
			
		||||
 | 
			
		||||
@@ -37,9 +36,9 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
public abstract class ComputerScreenBase<T extends ContainerComputerBase> extends AbstractContainerScreen<T>
 | 
			
		||||
{
 | 
			
		||||
    private static final Component OK = new TranslatableComponent( "gui.ok" );
 | 
			
		||||
    private static final Component CANCEL = new TranslatableComponent( "gui.cancel" );
 | 
			
		||||
    private static final Component OVERWRITE = new TranslatableComponent( "gui.computercraft.upload.overwrite_button" );
 | 
			
		||||
    private static final Component OK = Component.translatable( "gui.ok" );
 | 
			
		||||
    private static final Component CANCEL = Component.translatable( "gui.cancel" );
 | 
			
		||||
    private static final Component OVERWRITE = Component.translatable( "gui.computercraft.upload.overwrite_button" );
 | 
			
		||||
 | 
			
		||||
    protected WidgetTerminal terminal;
 | 
			
		||||
    protected final ClientComputer computer;
 | 
			
		||||
@@ -158,7 +157,7 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
 | 
			
		||||
                String name = file.getFileName().toString();
 | 
			
		||||
                if( name.length() > UploadFileMessage.MAX_FILE_NAME )
 | 
			
		||||
                {
 | 
			
		||||
                    alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.name_too_long" ) );
 | 
			
		||||
                    alert( UploadResult.FAILED_TITLE, Component.translatable( "gui.computercraft.upload.failed.name_too_long" ) );
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -169,7 +168,7 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
 | 
			
		||||
                byte[] digest = FileUpload.getDigest( buffer );
 | 
			
		||||
                if( digest == null )
 | 
			
		||||
                {
 | 
			
		||||
                    alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.corrupted" ) );
 | 
			
		||||
                    alert( UploadResult.FAILED_TITLE, Component.translatable( "gui.computercraft.upload.failed.corrupted" ) );
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -178,13 +177,13 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
 | 
			
		||||
            catch( IOException e )
 | 
			
		||||
            {
 | 
			
		||||
                ComputerCraft.log.error( "Failed uploading files", e );
 | 
			
		||||
                alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.generic", "Cannot compute checksum" ) );
 | 
			
		||||
                alert( UploadResult.FAILED_TITLE, Component.translatable( "gui.computercraft.upload.failed.generic", "Cannot compute checksum" ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( toUpload.size() > UploadFileMessage.MAX_FILES )
 | 
			
		||||
        {
 | 
			
		||||
            alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.too_many_files" ) );
 | 
			
		||||
            alert( UploadResult.FAILED_TITLE, Component.translatable( "gui.computercraft.upload.failed.too_many_files" ) );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ import net.minecraft.client.gui.Font;
 | 
			
		||||
import net.minecraft.client.gui.screens.Screen;
 | 
			
		||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.util.FormattedCharSequence;
 | 
			
		||||
import net.minecraft.world.entity.player.Inventory;
 | 
			
		||||
import org.lwjgl.glfw.GLFW;
 | 
			
		||||
@@ -112,7 +111,7 @@ public class NoTermComputerScreen<T extends ContainerComputerBase> extends Scree
 | 
			
		||||
        super.render( transform, mouseX, mouseY, partialTicks );
 | 
			
		||||
 | 
			
		||||
        Font font = minecraft.font;
 | 
			
		||||
        List<FormattedCharSequence> lines = font.split( new TranslatableComponent( "gui.computercraft.pocket_computer_overlay" ), (int) (width * 0.8) );
 | 
			
		||||
        List<FormattedCharSequence> lines = font.split( Component.translatable( "gui.computercraft.pocket_computer_overlay" ), (int) (width * 0.8) );
 | 
			
		||||
        float y = 10.0f;
 | 
			
		||||
        for( FormattedCharSequence line : lines )
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ import dan200.computercraft.shared.computer.core.ClientComputer;
 | 
			
		||||
import net.minecraft.ChatFormatting;
 | 
			
		||||
import net.minecraft.client.gui.components.AbstractWidget;
 | 
			
		||||
import net.minecraft.client.gui.screens.Screen;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
@@ -53,11 +53,11 @@ public final class ComputerSidebar
 | 
			
		||||
            screen, x, y, ICON_WIDTH, ICON_HEIGHT, () -> computer.isOn() ? 15 : 1, 1, ICON_TEX_Y_DIFF,
 | 
			
		||||
            TEXTURE, TEX_SIZE, TEX_SIZE, b -> toggleComputer( computer ),
 | 
			
		||||
            () -> computer.isOn() ? Arrays.asList(
 | 
			
		||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_off" ),
 | 
			
		||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY )
 | 
			
		||||
                Component.translatable( "gui.computercraft.tooltip.turn_off" ),
 | 
			
		||||
                Component.translatable( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY )
 | 
			
		||||
            ) : Arrays.asList(
 | 
			
		||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_on" ),
 | 
			
		||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY )
 | 
			
		||||
                Component.translatable( "gui.computercraft.tooltip.turn_on" ),
 | 
			
		||||
                Component.translatable( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY )
 | 
			
		||||
            )
 | 
			
		||||
        ) );
 | 
			
		||||
 | 
			
		||||
@@ -67,8 +67,8 @@ public final class ComputerSidebar
 | 
			
		||||
            screen, x, y, ICON_WIDTH, ICON_HEIGHT, 29, 1, ICON_TEX_Y_DIFF,
 | 
			
		||||
            TEXTURE, TEX_SIZE, TEX_SIZE, b -> computer.queueEvent( "terminate" ),
 | 
			
		||||
            Arrays.asList(
 | 
			
		||||
                new TranslatableComponent( "gui.computercraft.tooltip.terminate" ),
 | 
			
		||||
                new TranslatableComponent( "gui.computercraft.tooltip.terminate.key" ).withStyle( ChatFormatting.GRAY )
 | 
			
		||||
                Component.translatable( "gui.computercraft.tooltip.terminate" ),
 | 
			
		||||
                Component.translatable( "gui.computercraft.tooltip.terminate.key" ).withStyle( ChatFormatting.GRAY )
 | 
			
		||||
            )
 | 
			
		||||
        ) );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ import com.mojang.blaze3d.vertex.PoseStack;
 | 
			
		||||
import net.minecraft.client.gui.components.Button;
 | 
			
		||||
import net.minecraft.client.gui.screens.Screen;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraftforge.common.util.NonNullSupplier;
 | 
			
		||||
 | 
			
		||||
@@ -53,7 +52,7 @@ public class DynamicImageButton extends Button
 | 
			
		||||
        OnPress onPress, NonNullSupplier<List<Component>> tooltip
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
        super( x, y, width, height, TextComponent.EMPTY, onPress );
 | 
			
		||||
        super( x, y, width, height, Component.empty(), onPress );
 | 
			
		||||
        this.screen = screen;
 | 
			
		||||
        this.textureWidth = textureWidth;
 | 
			
		||||
        this.textureHeight = textureHeight;
 | 
			
		||||
@@ -84,7 +83,7 @@ public class DynamicImageButton extends Button
 | 
			
		||||
    public Component getMessage()
 | 
			
		||||
    {
 | 
			
		||||
        List<Component> tooltip = this.tooltip.get();
 | 
			
		||||
        return tooltip.isEmpty() ? TextComponent.EMPTY : tooltip.get( 0 );
 | 
			
		||||
        return tooltip.isEmpty() ? Component.empty() : tooltip.get( 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.gui.components.AbstractWidget;
 | 
			
		||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
 | 
			
		||||
import net.minecraft.client.renderer.MultiBufferSource;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import org.lwjgl.glfw.GLFW;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -51,7 +51,7 @@ public class WidgetTerminal extends AbstractWidget
 | 
			
		||||
 | 
			
		||||
    public WidgetTerminal( @Nonnull ClientComputer computer, int x, int y, int termWidth, int termHeight )
 | 
			
		||||
    {
 | 
			
		||||
        super( x, y, termWidth * FONT_WIDTH + MARGIN * 2, termHeight * FONT_HEIGHT + MARGIN * 2, TextComponent.EMPTY );
 | 
			
		||||
        super( x, y, termWidth * FONT_WIDTH + MARGIN * 2, termHeight * FONT_HEIGHT + MARGIN * 2, Component.empty() );
 | 
			
		||||
 | 
			
		||||
        this.computer = computer;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ public abstract class ItemMapLikeRenderer
 | 
			
		||||
        {
 | 
			
		||||
            transform.pushPose();
 | 
			
		||||
            transform.mulPose( Vector3f.ZP.rotationDegrees( offset * 10f ) );
 | 
			
		||||
            minecraft.getItemInHandRenderer().renderPlayerArm( transform, render, combinedLight, equipProgress, swingProgress, side );
 | 
			
		||||
            minecraft.getEntityRenderDispatcher().getItemInHandRenderer().renderPlayerArm( transform, render, combinedLight, equipProgress, swingProgress, side );
 | 
			
		||||
            transform.popPose();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -111,7 +111,7 @@ public abstract class ItemMapLikeRenderer
 | 
			
		||||
    private void renderItemFirstPersonCenter( PoseStack transform, MultiBufferSource render, int combinedLight, float pitch, float equipProgress, float swingProgress, ItemStack stack )
 | 
			
		||||
    {
 | 
			
		||||
        Minecraft minecraft = Minecraft.getInstance();
 | 
			
		||||
        ItemInHandRenderer renderer = minecraft.getItemInHandRenderer();
 | 
			
		||||
        ItemInHandRenderer renderer = minecraft.getEntityRenderDispatcher().getItemInHandRenderer();
 | 
			
		||||
 | 
			
		||||
        // Setup the appropriate transformations. This is just copied from the
 | 
			
		||||
        // corresponding method in ItemRenderer.
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@ import net.minecraft.client.resources.model.ModelManager;
 | 
			
		||||
import net.minecraft.client.resources.model.ModelResourceLocation;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.RandomSource;
 | 
			
		||||
import net.minecraft.world.phys.BlockHitResult;
 | 
			
		||||
import net.minecraft.world.phys.HitResult;
 | 
			
		||||
import net.minecraft.world.phys.Vec3;
 | 
			
		||||
@@ -37,7 +38,6 @@ import net.minecraftforge.client.model.data.EmptyModelData;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
public class TileEntityTurtleRenderer implements BlockEntityRenderer<TileTurtle>
 | 
			
		||||
{
 | 
			
		||||
@@ -46,7 +46,7 @@ public class TileEntityTurtleRenderer implements BlockEntityRenderer<TileTurtle>
 | 
			
		||||
    private static final ModelResourceLocation COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_colour", "inventory" );
 | 
			
		||||
    private static final ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "inventory" );
 | 
			
		||||
 | 
			
		||||
    private final Random random = new Random( 0 );
 | 
			
		||||
    private final RandomSource random = RandomSource.create( 0 );
 | 
			
		||||
 | 
			
		||||
    private final BlockEntityRenderDispatcher renderer;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import net.minecraft.client.renderer.block.model.ItemOverrides;
 | 
			
		||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
 | 
			
		||||
import net.minecraft.client.resources.model.BakedModel;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.util.RandomSource;
 | 
			
		||||
import net.minecraft.world.level.block.state.BlockState;
 | 
			
		||||
import net.minecraftforge.client.model.data.EmptyModelData;
 | 
			
		||||
import net.minecraftforge.client.model.data.IModelData;
 | 
			
		||||
@@ -19,7 +20,10 @@ import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
 | 
			
		||||
import net.minecraftforge.client.model.pipeline.TRSRTransformer;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.EnumMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class TurtleMultiModel implements BakedModel
 | 
			
		||||
{
 | 
			
		||||
@@ -44,14 +48,14 @@ public class TurtleMultiModel implements BakedModel
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull Random rand )
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull RandomSource rand )
 | 
			
		||||
    {
 | 
			
		||||
        return getQuads( state, side, rand, EmptyModelData.INSTANCE );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull Random rand, @Nonnull IModelData data )
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull RandomSource rand, @Nonnull IModelData data )
 | 
			
		||||
    {
 | 
			
		||||
        if( side != null )
 | 
			
		||||
        {
 | 
			
		||||
@@ -65,7 +69,7 @@ public class TurtleMultiModel implements BakedModel
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<BakedQuad> buildQuads( BlockState state, Direction side, Random rand )
 | 
			
		||||
    private List<BakedQuad> buildQuads( BlockState state, Direction side, RandomSource rand )
 | 
			
		||||
    {
 | 
			
		||||
        ArrayList<BakedQuad> quads = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@ import net.minecraft.client.resources.model.ModelManager;
 | 
			
		||||
import net.minecraft.client.resources.model.ModelResourceLocation;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.RandomSource;
 | 
			
		||||
import net.minecraft.world.entity.LivingEntity;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.level.block.state.BlockState;
 | 
			
		||||
@@ -33,7 +34,6 @@ import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
public class TurtleSmartItemModel implements BakedModel
 | 
			
		||||
{
 | 
			
		||||
@@ -118,7 +118,7 @@ public class TurtleSmartItemModel implements BakedModel
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull Random rand )
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand )
 | 
			
		||||
    {
 | 
			
		||||
        return familyModel.getQuads( state, facing, rand );
 | 
			
		||||
    }
 | 
			
		||||
@@ -126,7 +126,7 @@ public class TurtleSmartItemModel implements BakedModel
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull Random rand, @Nonnull IModelData data )
 | 
			
		||||
    public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand, @Nonnull IModelData data )
 | 
			
		||||
    {
 | 
			
		||||
        return familyModel.getQuads( state, facing, rand, data );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import com.mojang.blaze3d.audio.Channel;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
 | 
			
		||||
import net.minecraft.client.resources.sounds.AbstractSoundInstance;
 | 
			
		||||
import net.minecraft.client.resources.sounds.Sound;
 | 
			
		||||
import net.minecraft.client.resources.sounds.SoundInstance;
 | 
			
		||||
import net.minecraft.client.resources.sounds.TickableSoundInstance;
 | 
			
		||||
import net.minecraft.client.sounds.AudioStream;
 | 
			
		||||
import net.minecraft.client.sounds.SoundBufferLibrary;
 | 
			
		||||
@@ -32,7 +33,7 @@ public class SpeakerSound extends AbstractSoundInstance implements TickableSound
 | 
			
		||||
 | 
			
		||||
    SpeakerSound( ResourceLocation sound, DfpwmStream stream, SpeakerPosition position, float volume, float pitch )
 | 
			
		||||
    {
 | 
			
		||||
        super( sound, SoundSource.RECORDS );
 | 
			
		||||
        super( sound, SoundSource.RECORDS, SoundInstance.createUnseededRandom() );
 | 
			
		||||
        setPosition( position );
 | 
			
		||||
        this.stream = stream;
 | 
			
		||||
        this.volume = volume;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import com.mojang.blaze3d.vertex.VertexFormat;
 | 
			
		||||
import com.mojang.math.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.ShaderInstance;
 | 
			
		||||
import org.lwjgl.opengl.GL15;
 | 
			
		||||
import org.lwjgl.opengl.GL15C;
 | 
			
		||||
import org.lwjgl.opengl.GL45C;
 | 
			
		||||
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
@@ -29,23 +30,38 @@ public class DirectVertexBuffer extends VertexBuffer
 | 
			
		||||
    {
 | 
			
		||||
        if( DirectBuffers.HAS_DSA )
 | 
			
		||||
        {
 | 
			
		||||
            RenderSystem.glDeleteBuffers( vertextBufferId );
 | 
			
		||||
            RenderSystem.glDeleteBuffers( vertexBufferId );
 | 
			
		||||
            if( DirectBuffers.ON_LINUX ) BufferUploader.reset(); // See comment on DirectBuffers.deleteBuffer.
 | 
			
		||||
            vertextBufferId = GL45C.glCreateBuffers();
 | 
			
		||||
            vertexBufferId = GL45C.glCreateBuffers();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void upload( int vertexCount, VertexFormat.Mode mode, VertexFormat format, ByteBuffer buffer )
 | 
			
		||||
    {
 | 
			
		||||
        RenderSystem.assertOnRenderThread();
 | 
			
		||||
        bind();
 | 
			
		||||
 | 
			
		||||
        DirectBuffers.setBufferData( GL15.GL_ARRAY_BUFFER, vertextBufferId, buffer, GL15.GL_STATIC_DRAW );
 | 
			
		||||
 | 
			
		||||
        this.format = format;
 | 
			
		||||
        this.mode = mode;
 | 
			
		||||
        actualIndexCount = indexCount = mode.indexCount( vertexCount );
 | 
			
		||||
        indexType = VertexFormat.IndexType.SHORT;
 | 
			
		||||
        sequentialIndices = true;
 | 
			
		||||
 | 
			
		||||
        RenderSystem.assertOnRenderThread();
 | 
			
		||||
 | 
			
		||||
        DirectBuffers.setBufferData( GL15.GL_ARRAY_BUFFER, vertexBufferId, buffer, GL15.GL_STATIC_DRAW );
 | 
			
		||||
        if( format != this.format )
 | 
			
		||||
        {
 | 
			
		||||
            if( this.format != null ) this.format.clearBufferState();
 | 
			
		||||
 | 
			
		||||
            GL15C.glBindBuffer( GL15C.GL_ARRAY_BUFFER, vertexBufferId );
 | 
			
		||||
            format.setupBufferState();
 | 
			
		||||
            GL15C.glBindBuffer( GL15C.GL_ARRAY_BUFFER, 0 );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        RenderSystem.AutoStorageIndexBuffer indexBuffer = RenderSystem.getSequentialBuffer( mode );
 | 
			
		||||
        if( indexBuffer != sequentialIndices || !indexBuffer.hasStorage( indexCount ) )
 | 
			
		||||
        {
 | 
			
		||||
            indexBuffer.bind( indexCount );
 | 
			
		||||
            sequentialIndices = indexBuffer;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void drawWithShader( Matrix4f modelView, Matrix4f projection, ShaderInstance shader, int indexCount )
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,6 @@ import dan200.computercraft.core.apis.handles.ArrayByteChannel;
 | 
			
		||||
import dan200.computercraft.shared.util.IoUtil;
 | 
			
		||||
import net.minecraft.ResourceLocationException;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
 | 
			
		||||
import net.minecraft.server.packs.resources.Resource;
 | 
			
		||||
import net.minecraft.server.packs.resources.ResourceManager;
 | 
			
		||||
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
 | 
			
		||||
@@ -22,7 +21,6 @@ import net.minecraft.util.profiling.ProfilerFiller;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.nio.channels.Channels;
 | 
			
		||||
@@ -94,7 +92,7 @@ public final class ResourceMount implements IMount
 | 
			
		||||
        String existingNamespace = null;
 | 
			
		||||
 | 
			
		||||
        FileEntry newRoot = new FileEntry( new ResourceLocation( namespace, subPath ) );
 | 
			
		||||
        for( ResourceLocation file : manager.listResources( subPath, s -> true ) )
 | 
			
		||||
        for( ResourceLocation file : manager.listResources( subPath, s -> true ).keySet() )
 | 
			
		||||
        {
 | 
			
		||||
            existingNamespace = file.getNamespace();
 | 
			
		||||
 | 
			
		||||
@@ -202,10 +200,11 @@ public final class ResourceMount implements IMount
 | 
			
		||||
            byte[] contents = CONTENTS_CACHE.getIfPresent( file );
 | 
			
		||||
            if( contents != null ) return file.size = contents.length;
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            Resource resource = manager.getResource( file.identifier ).orElse( null );
 | 
			
		||||
            if( resource == null ) return file.size = 0;
 | 
			
		||||
 | 
			
		||||
            try( InputStream s = resource.open() )
 | 
			
		||||
            {
 | 
			
		||||
                Resource resource = manager.getResource( file.identifier );
 | 
			
		||||
                InputStream s = resource.getInputStream();
 | 
			
		||||
                int total = 0, read = 0;
 | 
			
		||||
                do
 | 
			
		||||
                {
 | 
			
		||||
@@ -234,9 +233,10 @@ public final class ResourceMount implements IMount
 | 
			
		||||
            byte[] contents = CONTENTS_CACHE.getIfPresent( file );
 | 
			
		||||
            if( contents != null ) return new ArrayByteChannel( contents );
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            var resource = manager.getResource( file.identifier ).orElse( null );
 | 
			
		||||
            if( resource != null )
 | 
			
		||||
            {
 | 
			
		||||
                InputStream stream = manager.getResource( file.identifier ).getInputStream();
 | 
			
		||||
                InputStream stream = resource.open();
 | 
			
		||||
                if( stream.available() > MAX_CACHED_SIZE ) return Channels.newChannel( stream );
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
@@ -251,9 +251,6 @@ public final class ResourceMount implements IMount
 | 
			
		||||
                CONTENTS_CACHE.put( file, contents );
 | 
			
		||||
                return new ArrayByteChannel( contents );
 | 
			
		||||
            }
 | 
			
		||||
            catch( FileNotFoundException ignored )
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new IOException( "/" + path + ": No such file" );
 | 
			
		||||
 
 | 
			
		||||
@@ -17,10 +17,11 @@ import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.level.block.Block;
 | 
			
		||||
import net.minecraftforge.client.model.generators.*;
 | 
			
		||||
import net.minecraftforge.common.data.ExistingFileHelper;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
@@ -206,7 +207,7 @@ class BlockModelProvider extends BlockStateProvider
 | 
			
		||||
        for( MonitorEdgeState edge : BlockMonitor.STATE.getPossibleValues() )
 | 
			
		||||
        {
 | 
			
		||||
            String suffix = edge == MonitorEdgeState.NONE ? "" : "_" + edge.getSerializedName();
 | 
			
		||||
            ModelFile model = models().getBuilder( extend( block.getRegistryName(), suffix ) );
 | 
			
		||||
            ModelFile model = models().getBuilder( extendedName( block, suffix ) );
 | 
			
		||||
 | 
			
		||||
            for( Direction facing : BlockMonitor.FACING.getPossibleValues() )
 | 
			
		||||
            {
 | 
			
		||||
@@ -260,20 +261,26 @@ class BlockModelProvider extends BlockStateProvider
 | 
			
		||||
 | 
			
		||||
    private static ResourceLocation blockTexture( Block block, String suffix )
 | 
			
		||||
    {
 | 
			
		||||
        ResourceLocation id = block.getRegistryName();
 | 
			
		||||
        ResourceLocation id = ForgeRegistries.BLOCKS.getKey( block );
 | 
			
		||||
        return new ResourceLocation( id.getNamespace(), "block/" + id.getPath() + suffix );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private String name( @Nonnull IForgeRegistryEntry<?> term )
 | 
			
		||||
    private <T> String name( @Nonnull Block term )
 | 
			
		||||
    {
 | 
			
		||||
        return Objects.requireNonNull( term.getRegistryName() ).toString();
 | 
			
		||||
        return Objects.requireNonNull( ForgeRegistries.BLOCKS.getKey( term ) ).toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private String extendedName( @Nonnull IForgeRegistryEntry<?> term, @Nonnull String suffix )
 | 
			
		||||
    private <T> String name( @Nonnull Item term )
 | 
			
		||||
    {
 | 
			
		||||
        return extend( Objects.requireNonNull( term.getRegistryName() ), suffix );
 | 
			
		||||
        return Objects.requireNonNull( ForgeRegistries.ITEMS.getKey( term ) ).toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private String extendedName( @Nonnull Block term, @Nonnull String suffix )
 | 
			
		||||
    {
 | 
			
		||||
        return extend( Objects.requireNonNull( ForgeRegistries.BLOCKS.getKey( term ) ), suffix );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -25,15 +25,15 @@ public class Generators
 | 
			
		||||
 | 
			
		||||
        var turtleUpgrades = new TurtleUpgradeGenerator( generator );
 | 
			
		||||
        var pocketUpgrades = new PocketUpgradeGenerator( generator );
 | 
			
		||||
        generator.addProvider( turtleUpgrades );
 | 
			
		||||
        generator.addProvider( pocketUpgrades );
 | 
			
		||||
        generator.addProvider( event.includeServer(), turtleUpgrades );
 | 
			
		||||
        generator.addProvider( event.includeServer(), pocketUpgrades );
 | 
			
		||||
 | 
			
		||||
        generator.addProvider( new RecipeGenerator( generator, turtleUpgrades, pocketUpgrades ) );
 | 
			
		||||
        generator.addProvider( new LootTableGenerator( generator ) );
 | 
			
		||||
        generator.addProvider( new BlockModelProvider( generator, existingFiles ) );
 | 
			
		||||
        generator.addProvider( event.includeServer(), new RecipeGenerator( generator, turtleUpgrades, pocketUpgrades ) );
 | 
			
		||||
        generator.addProvider( event.includeServer(), new LootTableGenerator( generator ) );
 | 
			
		||||
        generator.addProvider( event.includeClient(), new BlockModelProvider( generator, existingFiles ) );
 | 
			
		||||
 | 
			
		||||
        BlockTagsGenerator blockTags = new BlockTagsGenerator( generator, existingFiles );
 | 
			
		||||
        generator.addProvider( blockTags );
 | 
			
		||||
        generator.addProvider( new ItemTagsGenerator( generator, blockTags, existingFiles ) );
 | 
			
		||||
        generator.addProvider( event.includeServer(), blockTags );
 | 
			
		||||
        generator.addProvider( event.includeServer(), new ItemTagsGenerator( generator, blockTags, existingFiles ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,9 @@ import com.google.common.collect.Multimap;
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.GsonBuilder;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import net.minecraft.data.CachedOutput;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.data.DataProvider;
 | 
			
		||||
import net.minecraft.data.HashCache;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.LootTable;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.LootTables;
 | 
			
		||||
@@ -40,7 +40,7 @@ abstract class LootTableProvider implements DataProvider
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run( @Nonnull HashCache cache )
 | 
			
		||||
    public void run( @Nonnull CachedOutput cache )
 | 
			
		||||
    {
 | 
			
		||||
        Map<ResourceLocation, LootTable> tables = new HashMap<>();
 | 
			
		||||
        ValidationContext validation = new ValidationContext( LootContextParamSets.ALL_PARAMS, x -> null, tables::get );
 | 
			
		||||
@@ -64,7 +64,7 @@ abstract class LootTableProvider implements DataProvider
 | 
			
		||||
            Path path = getPath( key );
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                DataProvider.save( GSON, cache, LootTables.serialize( value ), path );
 | 
			
		||||
                DataProvider.saveStable( cache, LootTables.serialize( value ), path );
 | 
			
		||||
            }
 | 
			
		||||
            catch( IOException e )
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
 | 
			
		||||
import net.minecraft.world.level.ItemLike;
 | 
			
		||||
import net.minecraft.world.level.block.Blocks;
 | 
			
		||||
import net.minecraftforge.common.Tags;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
@@ -393,6 +394,6 @@ class RecipeGenerator extends RecipeProvider
 | 
			
		||||
 | 
			
		||||
    private static void addSpecial( Consumer<FinishedRecipe> add, SimpleRecipeSerializer<?> special )
 | 
			
		||||
    {
 | 
			
		||||
        SpecialRecipeBuilder.special( special ).save( add, special.getRegistryName().toString() );
 | 
			
		||||
        SpecialRecipeBuilder.special( special ).save( add, ForgeRegistries.RECIPE_SERIALIZERS.getKey( special ).toString() );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@ import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.GsonHelper;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.function.BiFunction;
 | 
			
		||||
@@ -25,7 +24,7 @@ import java.util.function.BiFunction;
 | 
			
		||||
 * @param <R> The serialiser for this upgrade category, either {@code TurtleUpgradeSerialiser<?>} or {@code PocketUpgradeSerialiser<?>}.
 | 
			
		||||
 * @param <T> The upgrade that this class can serialise and deserialise.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class SerialiserWithCraftingItem<T extends IUpgradeBase, R extends UpgradeSerialiser<?, R>> extends ForgeRegistryEntry<R> implements UpgradeSerialiser<T, R>
 | 
			
		||||
public abstract class SerialiserWithCraftingItem<T extends IUpgradeBase, R extends UpgradeSerialiser<?, R>> implements UpgradeSerialiser<T, R>
 | 
			
		||||
{
 | 
			
		||||
    private final BiFunction<ResourceLocation, ItemStack, T> factory;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ import dan200.computercraft.api.upgrades.IUpgradeBase;
 | 
			
		||||
import dan200.computercraft.api.upgrades.UpgradeSerialiser;
 | 
			
		||||
import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
@@ -23,7 +22,7 @@ import java.util.function.Function;
 | 
			
		||||
 * @param <R> The serialiser for this upgrade category, either {@code TurtleUpgradeSerialiser<?>} or {@code PocketUpgradeSerialiser<?>}.
 | 
			
		||||
 * @param <T> The upgrade that this class can serialise and deserialise.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class SimpleSerialiser<T extends IUpgradeBase, R extends UpgradeSerialiser<?, R>> extends ForgeRegistryEntry<R> implements UpgradeSerialiser<T, R>
 | 
			
		||||
public abstract class SimpleSerialiser<T extends IUpgradeBase, R extends UpgradeSerialiser<?, R>> implements UpgradeSerialiser<T, R>
 | 
			
		||||
{
 | 
			
		||||
    private final Function<ResourceLocation, T> constructor;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,19 +19,19 @@ import net.minecraft.client.renderer.block.ModelBlockRenderer;
 | 
			
		||||
import net.minecraft.client.renderer.texture.OverlayTexture;
 | 
			
		||||
import net.minecraft.client.resources.model.BakedModel;
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.util.RandomSource;
 | 
			
		||||
import net.minecraft.world.level.BlockAndTintGetter;
 | 
			
		||||
import net.minecraft.world.level.block.state.BlockState;
 | 
			
		||||
import net.minecraft.world.phys.BlockHitResult;
 | 
			
		||||
import net.minecraft.world.phys.HitResult;
 | 
			
		||||
import net.minecraftforge.client.model.data.IModelData;
 | 
			
		||||
import org.spongepowered.asm.mixin.Final;
 | 
			
		||||
import org.spongepowered.asm.mixin.Mixin;
 | 
			
		||||
import org.spongepowered.asm.mixin.Shadow;
 | 
			
		||||
import org.spongepowered.asm.mixin.injection.At;
 | 
			
		||||
import org.spongepowered.asm.mixin.injection.Inject;
 | 
			
		||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 | 
			
		||||
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides custom block breaking progress for modems, so it only applies to the current part.
 | 
			
		||||
 *
 | 
			
		||||
@@ -41,18 +41,16 @@ import java.util.Random;
 | 
			
		||||
public class BlockRenderDispatcherMixin
 | 
			
		||||
{
 | 
			
		||||
    @Shadow
 | 
			
		||||
    private final Random random;
 | 
			
		||||
    @Shadow
 | 
			
		||||
    private final BlockModelShaper blockModelShaper;
 | 
			
		||||
    @Shadow
 | 
			
		||||
    private final ModelBlockRenderer modelRenderer;
 | 
			
		||||
    @Final
 | 
			
		||||
    private RandomSource random;
 | 
			
		||||
 | 
			
		||||
    public BlockRenderDispatcherMixin( Random random, BlockModelShaper blockModelShaper, ModelBlockRenderer modelRenderer )
 | 
			
		||||
    {
 | 
			
		||||
        this.random = random;
 | 
			
		||||
        this.blockModelShaper = blockModelShaper;
 | 
			
		||||
        this.modelRenderer = modelRenderer;
 | 
			
		||||
    }
 | 
			
		||||
    @Shadow
 | 
			
		||||
    @Final
 | 
			
		||||
    private BlockModelShaper blockModelShaper;
 | 
			
		||||
 | 
			
		||||
    @Shadow
 | 
			
		||||
    @Final
 | 
			
		||||
    private ModelBlockRenderer modelRenderer;
 | 
			
		||||
 | 
			
		||||
    @Inject(
 | 
			
		||||
        method = "name=/^renderBreakingTexture/ desc=/IModelData;\\)V$/",
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,6 @@ import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.dedicated.DedicatedServer;
 | 
			
		||||
import net.minecraft.world.entity.EntityType;
 | 
			
		||||
import net.minecraft.world.inventory.AbstractContainerMenu;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.LootPool;
 | 
			
		||||
@@ -33,6 +32,8 @@ import net.minecraftforge.event.server.ServerStartingEvent;
 | 
			
		||||
import net.minecraftforge.event.server.ServerStoppedEvent;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
import net.minecraftforge.fml.common.Mod;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
import net.minecraftforge.registries.MissingMappingsEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
@@ -162,12 +163,12 @@ public final class CommonHooks
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    public static void onMissingEntityMappingsEvent( RegistryEvent.MissingMappings<EntityType<?>> event )
 | 
			
		||||
    public static void onMissingEntityMappingsEvent( MissingMappingsEvent event )
 | 
			
		||||
    {
 | 
			
		||||
        ResourceLocation id = new ResourceLocation( ComputerCraft.MOD_ID, "turtle_player" );
 | 
			
		||||
        for( RegistryEvent.MissingMappings.Mapping<EntityType<?>> mapping : event.getMappings( ComputerCraft.MOD_ID ) )
 | 
			
		||||
        for( var mapping : event.getMappings( ForgeRegistries.BLOCKS.getRegistryKey(), ComputerCraft.MOD_ID ) )
 | 
			
		||||
        {
 | 
			
		||||
            if( mapping.key.equals( id ) ) mapping.ignore();
 | 
			
		||||
            if( mapping.getKey().equals( id ) ) mapping.ignore();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared;
 | 
			
		||||
 | 
			
		||||
import com.electronwill.nightconfig.core.CommentedConfig;
 | 
			
		||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
 | 
			
		||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
 | 
			
		||||
import com.google.common.base.CaseFormat;
 | 
			
		||||
import com.google.common.base.Converter;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
@@ -291,7 +289,7 @@ public final class Config
 | 
			
		||||
        ModLoadingContext.get().registerConfig( ModConfig.Type.CLIENT, clientSpec );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sync()
 | 
			
		||||
    private static void syncServer()
 | 
			
		||||
    {
 | 
			
		||||
        // General
 | 
			
		||||
        ComputerCraft.computerSpaceLimit = computerSpaceLimit.get();
 | 
			
		||||
@@ -343,26 +341,31 @@ public final class Config
 | 
			
		||||
        ComputerCraft.pocketTermHeight = pocketTermHeight.get();
 | 
			
		||||
        ComputerCraft.monitorWidth = monitorWidth.get();
 | 
			
		||||
        ComputerCraft.monitorHeight = monitorHeight.get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        // Client
 | 
			
		||||
    private static void syncClient()
 | 
			
		||||
    {
 | 
			
		||||
        ComputerCraft.monitorRenderer = monitorRenderer.get();
 | 
			
		||||
        ComputerCraft.monitorDistance = monitorDistance.get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void sync( ModConfig config )
 | 
			
		||||
    {
 | 
			
		||||
        if( !config.getModId().equals( ComputerCraft.MOD_ID ) ) return;
 | 
			
		||||
        if( config.getType() == ModConfig.Type.SERVER ) syncServer();
 | 
			
		||||
        if( config.getType() == ModConfig.Type.CLIENT ) syncClient();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    public static void sync( ModConfigEvent.Loading event )
 | 
			
		||||
    {
 | 
			
		||||
        sync();
 | 
			
		||||
        sync( event.getConfig() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    public static void sync( ModConfigEvent.Reloading event )
 | 
			
		||||
    {
 | 
			
		||||
        // Ensure file configs are reloaded. Forge should probably do this, so worth checking in the future.
 | 
			
		||||
        CommentedConfig config = event.getConfig().getConfigData();
 | 
			
		||||
        if( config instanceof CommentedFileConfig loadable ) loadable.load();
 | 
			
		||||
 | 
			
		||||
        sync();
 | 
			
		||||
        sync( event.getConfig() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static final Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE );
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared;
 | 
			
		||||
 | 
			
		||||
import com.mojang.brigadier.arguments.ArgumentType;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.api.ComputerCraftAPI;
 | 
			
		||||
import dan200.computercraft.api.media.IMedia;
 | 
			
		||||
@@ -12,7 +13,7 @@ import dan200.computercraft.api.network.wired.IWiredElement;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
			
		||||
import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
 | 
			
		||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
 | 
			
		||||
import dan200.computercraft.shared.command.arguments.ArgumentSerializers;
 | 
			
		||||
import dan200.computercraft.shared.command.arguments.*;
 | 
			
		||||
import dan200.computercraft.shared.common.ColourableRecipe;
 | 
			
		||||
import dan200.computercraft.shared.common.ContainerHeldItem;
 | 
			
		||||
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
 | 
			
		||||
@@ -70,6 +71,9 @@ import dan200.computercraft.shared.util.CreativeTabMain;
 | 
			
		||||
import dan200.computercraft.shared.util.FixedPointTileEntityType;
 | 
			
		||||
import dan200.computercraft.shared.util.ImpostorRecipe;
 | 
			
		||||
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypeInfos;
 | 
			
		||||
import net.minecraft.commands.synchronization.SingletonArgumentInfo;
 | 
			
		||||
import net.minecraft.core.cauldron.CauldronInteraction;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.inventory.MenuType;
 | 
			
		||||
@@ -77,7 +81,6 @@ import net.minecraft.world.item.BlockItem;
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.RecordItem;
 | 
			
		||||
import net.minecraft.world.item.crafting.RecipeSerializer;
 | 
			
		||||
import net.minecraft.world.level.block.Block;
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntity;
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntityType;
 | 
			
		||||
@@ -86,7 +89,6 @@ import net.minecraft.world.level.material.Material;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
 | 
			
		||||
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
 | 
			
		||||
import net.minecraftforge.energy.CapabilityEnergy;
 | 
			
		||||
import net.minecraftforge.event.RegistryEvent;
 | 
			
		||||
import net.minecraftforge.eventbus.api.IEventBus;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
 | 
			
		||||
@@ -308,38 +310,62 @@ public final class Registry
 | 
			
		||||
            () -> ContainerData.toType( ViewComputerContainerData::new, ContainerViewComputer::new ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static class ModArgumentTypes
 | 
			
		||||
    {
 | 
			
		||||
        static final DeferredRegister<ArgumentTypeInfo<?, ?>> ARGUMENT_TYPES = DeferredRegister.create( net.minecraft.core.Registry.COMMAND_ARGUMENT_TYPE_REGISTRY, ComputerCraft.MOD_ID );
 | 
			
		||||
 | 
			
		||||
        @SuppressWarnings( "unchecked" )
 | 
			
		||||
        private static <T extends ArgumentType<?>> void registerUnsafe( String name, Class<T> type, ArgumentTypeInfo<?, ?> serializer )
 | 
			
		||||
        {
 | 
			
		||||
            ARGUMENT_TYPES.register( name, () -> ArgumentTypeInfos.registerByClass( type, (ArgumentTypeInfo<T, ?>)serializer ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static <T extends ArgumentType<?>> void register( String name, Class<T> type, ArgumentTypeInfo<T, ?> serializer )
 | 
			
		||||
        {
 | 
			
		||||
            ARGUMENT_TYPES.register( name, () -> ArgumentTypeInfos.registerByClass( type, serializer ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static <T extends ArgumentType<?>> void register( String name, Class<T> type, T instance )
 | 
			
		||||
        {
 | 
			
		||||
            register( name, type, SingletonArgumentInfo.contextFree( () -> instance ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static
 | 
			
		||||
        {
 | 
			
		||||
            register( "tracking_field", TrackingFieldArgumentType.class, TrackingFieldArgumentType.trackingField() );
 | 
			
		||||
            register( "computer", ComputerArgumentType.class, ComputerArgumentType.oneComputer() );
 | 
			
		||||
            register( "computers", ComputersArgumentType.class, new ComputersArgumentType.Info() );
 | 
			
		||||
            registerUnsafe( "repeat", RepeatArgumentType.class, new RepeatArgumentType.Info() );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    public static void registerRegistries( NewRegistryEvent event )
 | 
			
		||||
    {
 | 
			
		||||
        @SuppressWarnings( "unchecked" )
 | 
			
		||||
        Class<TurtleUpgradeSerialiser<?>> turtleType = (Class<TurtleUpgradeSerialiser<?>>) (Class<?>) TurtleUpgradeSerialiser.class;
 | 
			
		||||
        event.create( new RegistryBuilder<TurtleUpgradeSerialiser<?>>()
 | 
			
		||||
            .setName( TurtleUpgradeSerialiser.REGISTRY_ID.location() )
 | 
			
		||||
            .setType( turtleType )
 | 
			
		||||
            .disableSaving().disableSync() );
 | 
			
		||||
 | 
			
		||||
        @SuppressWarnings( "unchecked" )
 | 
			
		||||
        Class<PocketUpgradeSerialiser<?>> pocketType = (Class<PocketUpgradeSerialiser<?>>) (Class<?>) PocketUpgradeSerialiser.class;
 | 
			
		||||
        event.create( new RegistryBuilder<PocketUpgradeSerialiser<?>>()
 | 
			
		||||
            .setName( PocketUpgradeSerialiser.REGISTRY_ID.location() )
 | 
			
		||||
            .setType( pocketType )
 | 
			
		||||
            .disableSaving().disableSync() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    public static void registerRecipeSerializers( RegistryEvent.Register<RecipeSerializer<?>> event )
 | 
			
		||||
    public static void registerRecipeSerializers( RegisterEvent event )
 | 
			
		||||
    {
 | 
			
		||||
        event.getRegistry().registerAll(
 | 
			
		||||
            ColourableRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "colour" ) ),
 | 
			
		||||
            ComputerUpgradeRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer_upgrade" ) ),
 | 
			
		||||
            PocketComputerUpgradeRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer_upgrade" ) ),
 | 
			
		||||
            DiskRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ) ),
 | 
			
		||||
            PrintoutRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printout" ) ),
 | 
			
		||||
            TurtleRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ),
 | 
			
		||||
            TurtleUpgradeRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade" ) ),
 | 
			
		||||
            ImpostorShapelessRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shapeless" ) ),
 | 
			
		||||
            ImpostorRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shaped" ) )
 | 
			
		||||
        );
 | 
			
		||||
        event.register( ForgeRegistries.RECIPE_SERIALIZERS.getRegistryKey(), registry -> {
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "colour" ), ColourableRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "computer_upgrade" ), ComputerUpgradeRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer_upgrade" ), PocketComputerUpgradeRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ), DiskRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "printout" ), PrintoutRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ), TurtleRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade" ), TurtleUpgradeRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shapeless" ), ImpostorShapelessRecipe.SERIALIZER );
 | 
			
		||||
            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shaped" ), ImpostorRecipe.SERIALIZER );
 | 
			
		||||
        } );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
@@ -356,7 +382,6 @@ public final class Registry
 | 
			
		||||
 | 
			
		||||
        event.enqueueWork( () -> {
 | 
			
		||||
            registerProviders();
 | 
			
		||||
            ArgumentSerializers.register();
 | 
			
		||||
            registerLoot();
 | 
			
		||||
        } );
 | 
			
		||||
 | 
			
		||||
@@ -412,5 +437,6 @@ public final class Registry
 | 
			
		||||
        ModTurtleSerialisers.SERIALISERS.register( bus );
 | 
			
		||||
        ModPocketUpgradeSerialisers.SERIALISERS.register( bus );
 | 
			
		||||
        ModContainers.CONTAINERS.register( bus );
 | 
			
		||||
        ModArgumentTypes.ARGUMENT_TYPES.register( bus );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,6 @@ import net.minecraft.commands.CommandSourceStack;
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.MutableComponent;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket;
 | 
			
		||||
import net.minecraft.server.level.ServerLevel;
 | 
			
		||||
import net.minecraft.server.level.ServerPlayer;
 | 
			
		||||
@@ -231,7 +229,7 @@ public final class CommandComputerCraft
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public Component getDisplayName()
 | 
			
		||||
                        {
 | 
			
		||||
                            return new TranslatableComponent( "gui.computercraft.view_computer" );
 | 
			
		||||
                            return Component.translatable( "gui.computercraft.view_computer" );
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        @Nonnull
 | 
			
		||||
@@ -287,7 +285,7 @@ public final class CommandComputerCraft
 | 
			
		||||
 | 
			
		||||
    private static Component linkComputer( CommandSourceStack source, ServerComputer serverComputer, int computerId )
 | 
			
		||||
    {
 | 
			
		||||
        MutableComponent out = new TextComponent( "" );
 | 
			
		||||
        MutableComponent out = Component.literal( "" );
 | 
			
		||||
 | 
			
		||||
        // Append the computer instance
 | 
			
		||||
        if( serverComputer == null )
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ package dan200.computercraft.shared.command;
 | 
			
		||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
 | 
			
		||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 | 
			
		||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
 | 
			
		||||
public final class Exceptions
 | 
			
		||||
{
 | 
			
		||||
@@ -27,16 +27,16 @@ public final class Exceptions
 | 
			
		||||
 | 
			
		||||
    private static SimpleCommandExceptionType translated( String key )
 | 
			
		||||
    {
 | 
			
		||||
        return new SimpleCommandExceptionType( new TranslatableComponent( key ) );
 | 
			
		||||
        return new SimpleCommandExceptionType( Component.translatable( key ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static DynamicCommandExceptionType translated1( String key )
 | 
			
		||||
    {
 | 
			
		||||
        return new DynamicCommandExceptionType( x -> new TranslatableComponent( key, x ) );
 | 
			
		||||
        return new DynamicCommandExceptionType( x -> Component.translatable( key, x ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Dynamic2CommandExceptionType translated2( String key )
 | 
			
		||||
    {
 | 
			
		||||
        return new Dynamic2CommandExceptionType( ( x, y ) -> new TranslatableComponent( key, x, y ) );
 | 
			
		||||
        return new Dynamic2CommandExceptionType( ( x, y ) -> Component.translatable( key, x, y ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,40 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of ComputerCraft - http://www.computercraft.info
 | 
			
		||||
 * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
 | 
			
		||||
 * Send enquiries to dratcliffe@gmail.com
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared.command.arguments;
 | 
			
		||||
 | 
			
		||||
import com.mojang.brigadier.arguments.ArgumentType;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentSerializer;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypes;
 | 
			
		||||
import net.minecraft.commands.synchronization.EmptyArgumentSerializer;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
 | 
			
		||||
public final class ArgumentSerializers
 | 
			
		||||
{
 | 
			
		||||
    @SuppressWarnings( "unchecked" )
 | 
			
		||||
    private static <T extends ArgumentType<?>> void registerUnsafe( ResourceLocation id, Class<T> type, ArgumentSerializer<?> serializer )
 | 
			
		||||
    {
 | 
			
		||||
        ArgumentTypes.register( id.toString(), type, (ArgumentSerializer<T>) serializer );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static <T extends ArgumentType<?>> void register( ResourceLocation id, Class<T> type, ArgumentSerializer<T> serializer )
 | 
			
		||||
    {
 | 
			
		||||
        ArgumentTypes.register( id.toString(), type, serializer );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static <T extends ArgumentType<?>> void register( ResourceLocation id, T instance )
 | 
			
		||||
    {
 | 
			
		||||
        registerUnsafe( id, instance.getClass(), new EmptyArgumentSerializer<>( () -> instance ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void register()
 | 
			
		||||
    {
 | 
			
		||||
        register( new ResourceLocation( ComputerCraft.MOD_ID, "tracking_field" ), TrackingFieldArgumentType.trackingField() );
 | 
			
		||||
        register( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ), ComputerArgumentType.oneComputer() );
 | 
			
		||||
        register( new ResourceLocation( ComputerCraft.MOD_ID, "computers" ), ComputersArgumentType.class, new ComputersArgumentType.Serializer() );
 | 
			
		||||
        registerUnsafe( new ResourceLocation( ComputerCraft.MOD_ID, "repeat" ), RepeatArgumentType.class, new RepeatArgumentType.Serializer() );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of ComputerCraft - http://www.computercraft.info
 | 
			
		||||
 * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
 | 
			
		||||
 * Send enquiries to dratcliffe@gmail.com
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared.command.arguments;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.mojang.brigadier.Message;
 | 
			
		||||
import com.mojang.brigadier.arguments.ArgumentType;
 | 
			
		||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
 | 
			
		||||
import net.minecraft.core.Registry;
 | 
			
		||||
import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utilities for working with arguments.
 | 
			
		||||
 *
 | 
			
		||||
 * @see net.minecraft.commands.synchronization.ArgumentUtils
 | 
			
		||||
 */
 | 
			
		||||
public class ArgumentUtils
 | 
			
		||||
{
 | 
			
		||||
    public static <A extends ArgumentType<?>> JsonObject serializeToJson( ArgumentTypeInfo.Template<A> template )
 | 
			
		||||
    {
 | 
			
		||||
        JsonObject object = new JsonObject();
 | 
			
		||||
        object.addProperty( "type", "argument" );
 | 
			
		||||
        object.addProperty( "parser", Registry.COMMAND_ARGUMENT_TYPE.getKey( template.type() ).toString() );
 | 
			
		||||
 | 
			
		||||
        var properties = new JsonObject();
 | 
			
		||||
        serializeToJson( properties, template.type(), template );
 | 
			
		||||
        if( properties.size() > 0 ) object.add( "properties", properties );
 | 
			
		||||
 | 
			
		||||
        return object;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings( "unchecked" )
 | 
			
		||||
    private static <A extends ArgumentType<?>, T extends ArgumentTypeInfo.Template<A>> void serializeToJson( JsonObject jsonObject, ArgumentTypeInfo<A, T> argumentTypeInfo, ArgumentTypeInfo.Template<A> template )
 | 
			
		||||
    {
 | 
			
		||||
        argumentTypeInfo.serializeToJson( (T) template, jsonObject );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <A extends ArgumentType<?>> void serializeToNetwork( FriendlyByteBuf buffer, ArgumentTypeInfo.Template<A> template )
 | 
			
		||||
    {
 | 
			
		||||
        serializeToNetwork( buffer, template.type(), template );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings( "unchecked" )
 | 
			
		||||
    private static <A extends ArgumentType<?>, T extends ArgumentTypeInfo.Template<A>> void serializeToNetwork( FriendlyByteBuf buffer, ArgumentTypeInfo<A, T> type, ArgumentTypeInfo.Template<A> template )
 | 
			
		||||
    {
 | 
			
		||||
        buffer.writeVarInt( Registry.COMMAND_ARGUMENT_TYPE.getId( type ) );
 | 
			
		||||
        type.serializeToNetwork( (T) template, buffer );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ArgumentTypeInfo.Template<?> deserialize( FriendlyByteBuf buffer )
 | 
			
		||||
    {
 | 
			
		||||
        var type = Registry.COMMAND_ARGUMENT_TYPE.byId( buffer.readVarInt() );
 | 
			
		||||
        Objects.requireNonNull( type, "Unknown argument type" );
 | 
			
		||||
        return type.deserializeFromNetwork( buffer );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Component getMessage( Message message )
 | 
			
		||||
    {
 | 
			
		||||
        return message instanceof Component component ? component : Component.literal( message.getString() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Component getMessage( SimpleCommandExceptionType exception )
 | 
			
		||||
    {
 | 
			
		||||
        return getMessage( exception.create().getRawMessage() );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -15,9 +15,11 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ServerComputer;
 | 
			
		||||
import net.minecraft.commands.CommandBuildContext;
 | 
			
		||||
import net.minecraft.commands.CommandSourceStack;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentSerializer;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
 | 
			
		||||
import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
@@ -171,27 +173,48 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Serializer implements ArgumentSerializer<ComputersArgumentType>
 | 
			
		||||
    public static class Info implements ArgumentTypeInfo<ComputersArgumentType, Template>
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void serializeToNetwork( @Nonnull ComputersArgumentType arg, @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        public void serializeToNetwork( @Nonnull ComputersArgumentType.Template arg, @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        {
 | 
			
		||||
            buf.writeBoolean( arg.requireSome );
 | 
			
		||||
            buf.writeBoolean( arg.requireSome() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public ComputersArgumentType deserializeFromNetwork( @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        public ComputersArgumentType.Template deserializeFromNetwork( @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        {
 | 
			
		||||
            return buf.readBoolean() ? SOME : MANY;
 | 
			
		||||
            boolean requiresSome = buf.readBoolean();
 | 
			
		||||
            return new ComputersArgumentType.Template( this, requiresSome );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void serializeToJson( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json )
 | 
			
		||||
        public void serializeToJson( @Nonnull ComputersArgumentType.Template arg, @Nonnull JsonObject json )
 | 
			
		||||
        {
 | 
			
		||||
            json.addProperty( "requireSome", arg.requireSome );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public ComputersArgumentType.Template unpack( @NotNull ComputersArgumentType argumentType )
 | 
			
		||||
        {
 | 
			
		||||
            return new ComputersArgumentType.Template( this, argumentType.requireSome );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public record Template(Info info, boolean requireSome) implements ArgumentTypeInfo.Template<ComputersArgumentType>
 | 
			
		||||
    {
 | 
			
		||||
        @Override
 | 
			
		||||
        public ComputersArgumentType instantiate( @NotNull CommandBuildContext context )
 | 
			
		||||
        {
 | 
			
		||||
            return requireSome ? SOME : MANY;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public Info type()
 | 
			
		||||
        {
 | 
			
		||||
            return info;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @FunctionalInterface
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@
 | 
			
		||||
package dan200.computercraft.shared.command.arguments;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.mojang.brigadier.Message;
 | 
			
		||||
import com.mojang.brigadier.StringReader;
 | 
			
		||||
import com.mojang.brigadier.arguments.ArgumentType;
 | 
			
		||||
import com.mojang.brigadier.context.CommandContext;
 | 
			
		||||
@@ -14,11 +13,12 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
 | 
			
		||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 | 
			
		||||
import com.mojang.brigadier.suggestion.Suggestions;
 | 
			
		||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentSerializer;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypes;
 | 
			
		||||
import net.minecraft.commands.CommandBuildContext;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
 | 
			
		||||
import net.minecraft.commands.synchronization.ArgumentTypeInfos;
 | 
			
		||||
import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
@@ -125,41 +125,57 @@ public final class RepeatArgumentType<T, U> implements ArgumentType<List<T>>
 | 
			
		||||
        return child.getExamples();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Serializer implements ArgumentSerializer<RepeatArgumentType<?, ?>>
 | 
			
		||||
    public static class Info implements ArgumentTypeInfo<RepeatArgumentType<?, ?>, Template>
 | 
			
		||||
    {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void serializeToNetwork( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        public void serializeToNetwork( @Nonnull RepeatArgumentType.Template arg, @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        {
 | 
			
		||||
            buf.writeBoolean( arg.flatten );
 | 
			
		||||
            ArgumentTypes.serialize( buf, arg.child );
 | 
			
		||||
            buf.writeComponent( getMessage( arg ) );
 | 
			
		||||
            ArgumentUtils.serializeToNetwork( buf, arg.child );
 | 
			
		||||
            buf.writeComponent( ArgumentUtils.getMessage( arg.some ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        @SuppressWarnings( { "unchecked", "rawtypes" } )
 | 
			
		||||
        public RepeatArgumentType<?, ?> deserializeFromNetwork( @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        public RepeatArgumentType.Template deserializeFromNetwork( @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
        {
 | 
			
		||||
            boolean isList = buf.readBoolean();
 | 
			
		||||
            ArgumentType<?> child = ArgumentTypes.deserialize( buf );
 | 
			
		||||
            var child = ArgumentUtils.deserialize( buf );
 | 
			
		||||
            Component message = buf.readComponent();
 | 
			
		||||
            BiConsumer<List<Object>, ?> appender = isList ? ( list, x ) -> list.addAll( (Collection) x ) : List::add;
 | 
			
		||||
            return new RepeatArgumentType( child, appender, isList, new SimpleCommandExceptionType( message ) );
 | 
			
		||||
            return new RepeatArgumentType.Template( this, child, isList, new SimpleCommandExceptionType( message ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void serializeToJson( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json )
 | 
			
		||||
        public RepeatArgumentType.Template unpack( RepeatArgumentType<?, ?> argumentType )
 | 
			
		||||
        {
 | 
			
		||||
            json.addProperty( "flatten", arg.flatten );
 | 
			
		||||
            json.addProperty( "child", "<<cannot serialize>>" ); // TODO: Potentially serialize this using reflection.
 | 
			
		||||
            json.addProperty( "error", Component.Serializer.toJson( getMessage( arg ) ) );
 | 
			
		||||
            return new RepeatArgumentType.Template( this, ArgumentTypeInfos.unpack( argumentType.child ), argumentType.flatten, argumentType.some );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static Component getMessage( RepeatArgumentType<?, ?> arg )
 | 
			
		||||
        @Override
 | 
			
		||||
        public void serializeToJson( @Nonnull RepeatArgumentType.Template arg, @Nonnull JsonObject json )
 | 
			
		||||
        {
 | 
			
		||||
            Message message = arg.some.create().getRawMessage();
 | 
			
		||||
            if( message instanceof Component ) return (Component) message;
 | 
			
		||||
            return new TextComponent( message.getString() );
 | 
			
		||||
            json.addProperty( "flatten", arg.flatten );
 | 
			
		||||
            json.add( "child", ArgumentUtils.serializeToJson( arg.child ) );
 | 
			
		||||
            json.addProperty( "error", Component.Serializer.toJson( ArgumentUtils.getMessage( arg.some ) ) );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public record Template(
 | 
			
		||||
        Info info, ArgumentTypeInfo.Template<?> child, boolean flatten, SimpleCommandExceptionType some
 | 
			
		||||
    ) implements ArgumentTypeInfo.Template<RepeatArgumentType<?, ?>>
 | 
			
		||||
    {
 | 
			
		||||
        @Override
 | 
			
		||||
        @SuppressWarnings( { "unchecked", "rawtypes" } )
 | 
			
		||||
        public RepeatArgumentType<?, ?> instantiate( @NotNull CommandBuildContext commandBuildContext )
 | 
			
		||||
        {
 | 
			
		||||
            var child = child().instantiate( commandBuildContext );
 | 
			
		||||
            return flatten ? RepeatArgumentType.someFlat( (ArgumentType) child, some() ) : RepeatArgumentType.some( child, some() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public ArgumentTypeInfo<RepeatArgumentType<?, ?>, ?> type()
 | 
			
		||||
        {
 | 
			
		||||
            return info;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@ import net.minecraft.commands.CommandSourceStack;
 | 
			
		||||
import net.minecraft.network.chat.ClickEvent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.MutableComponent;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
@@ -174,7 +173,7 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
 | 
			
		||||
        temp.addChild( node );
 | 
			
		||||
        String usage = dispatcher.getSmartUsage( temp, context.getSource() ).get( node ).substring( node.getName().length() );
 | 
			
		||||
 | 
			
		||||
        MutableComponent output = new TextComponent( "" )
 | 
			
		||||
        MutableComponent output = Component.literal( "" )
 | 
			
		||||
            .append( coloured( "/" + command + usage, HEADER ) )
 | 
			
		||||
            .append( " " )
 | 
			
		||||
            .append( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ public final class ChatHelpers
 | 
			
		||||
 | 
			
		||||
    public static MutableComponent coloured( String text, ChatFormatting colour )
 | 
			
		||||
    {
 | 
			
		||||
        return new TextComponent( text == null ? "" : text ).withStyle( colour );
 | 
			
		||||
        return Component.literal( text == null ? "" : text ).withStyle( colour );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends MutableComponent> T coloured( T component, ChatFormatting colour )
 | 
			
		||||
@@ -31,22 +31,22 @@ public final class ChatHelpers
 | 
			
		||||
 | 
			
		||||
    public static MutableComponent text( String text )
 | 
			
		||||
    {
 | 
			
		||||
        return new TextComponent( text == null ? "" : text );
 | 
			
		||||
        return Component.literal( text == null ? "" : text );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MutableComponent translate( String text )
 | 
			
		||||
    {
 | 
			
		||||
        return new TranslatableComponent( text == null ? "" : text );
 | 
			
		||||
        return Component.translatable( text == null ? "" : text );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MutableComponent translate( String text, Object... args )
 | 
			
		||||
    {
 | 
			
		||||
        return new TranslatableComponent( text == null ? "" : text, args );
 | 
			
		||||
        return Component.translatable( text == null ? "" : text, args );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MutableComponent list( Component... children )
 | 
			
		||||
    {
 | 
			
		||||
        MutableComponent component = new TextComponent( "" );
 | 
			
		||||
        MutableComponent component = Component.literal( "" );
 | 
			
		||||
        for( Component child : children )
 | 
			
		||||
        {
 | 
			
		||||
            component.append( child );
 | 
			
		||||
@@ -90,10 +90,10 @@ public final class ChatHelpers
 | 
			
		||||
 | 
			
		||||
    public static MutableComponent copy( String text )
 | 
			
		||||
    {
 | 
			
		||||
        TextComponent name = new TextComponent( text );
 | 
			
		||||
        MutableComponent name = Component.literal( text );
 | 
			
		||||
        Style style = name.getStyle()
 | 
			
		||||
            .withClickEvent( new ClickEvent( ClickEvent.Action.COPY_TO_CLIPBOARD, text ) )
 | 
			
		||||
            .withHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslatableComponent( "gui.computercraft.tooltip.copy" ) ) );
 | 
			
		||||
            .withHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, Component.translatable( "gui.computercraft.tooltip.copy" ) ) );
 | 
			
		||||
        return name.withStyle( style );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ package dan200.computercraft.shared.command.text;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.commands.CommandSourceStack;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -27,7 +26,7 @@ public class ServerTableFormatter implements TableFormatter
 | 
			
		||||
    {
 | 
			
		||||
        int extraWidth = width - getWidth( component );
 | 
			
		||||
        if( extraWidth <= 0 ) return null;
 | 
			
		||||
        return new TextComponent( StringUtils.repeat( ' ', extraWidth ) );
 | 
			
		||||
        return Component.literal( StringUtils.repeat( ' ', extraWidth ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ package dan200.computercraft.shared.command.text;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.ChatFormatting;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.MutableComponent;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -76,7 +76,7 @@ public interface TableFormatter
 | 
			
		||||
 | 
			
		||||
        if( headers != null )
 | 
			
		||||
        {
 | 
			
		||||
            TextComponent line = new TextComponent( "" );
 | 
			
		||||
            MutableComponent line = Component.literal( "" );
 | 
			
		||||
            for( int i = 0; i < columns - 1; i++ )
 | 
			
		||||
            {
 | 
			
		||||
                line.append( headers[i] );
 | 
			
		||||
@@ -97,7 +97,7 @@ public interface TableFormatter
 | 
			
		||||
 | 
			
		||||
        for( Component[] row : table.getRows() )
 | 
			
		||||
        {
 | 
			
		||||
            TextComponent line = new TextComponent( "" );
 | 
			
		||||
            MutableComponent line = Component.literal( "" );
 | 
			
		||||
            for( int i = 0; i < columns - 1; i++ )
 | 
			
		||||
            {
 | 
			
		||||
                line.append( row[i] );
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ package dan200.computercraft.shared.common;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.server.level.ServerLevel;
 | 
			
		||||
import net.minecraft.util.RandomSource;
 | 
			
		||||
import net.minecraft.world.InteractionHand;
 | 
			
		||||
import net.minecraft.world.InteractionResult;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
@@ -23,7 +24,6 @@ import net.minecraftforge.registries.RegistryObject;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
public abstract class BlockGeneric extends BaseEntityBlock
 | 
			
		||||
{
 | 
			
		||||
@@ -73,7 +73,7 @@ public abstract class BlockGeneric extends BaseEntityBlock
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public void tick( @Nonnull BlockState state, ServerLevel world, @Nonnull BlockPos pos, @Nonnull Random rand )
 | 
			
		||||
    public void tick( @Nonnull BlockState state, ServerLevel world, @Nonnull BlockPos pos, @Nonnull RandomSource rand )
 | 
			
		||||
    {
 | 
			
		||||
        BlockEntity te = world.getBlockEntity( pos );
 | 
			
		||||
        if( te instanceof TileGeneric generic ) generic.blockTick();
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,13 @@ public class ContainerHeldItem extends AbstractContainerMenu
 | 
			
		||||
        return stack;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ItemStack quickMoveStack( @Nonnull Player player, int slot )
 | 
			
		||||
    {
 | 
			
		||||
        return ItemStack.EMPTY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean stillValid( @Nonnull Player player )
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -162,7 +162,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
 | 
			
		||||
                popResource( world, pos, item );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            state.spawnAfterBreak( serverWorld, pos, player.getMainHandItem() );
 | 
			
		||||
            state.spawnAfterBreak( serverWorld, pos, player.getMainHandItem(), true );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,6 @@ import net.minecraft.commands.CommandSource;
 | 
			
		||||
import net.minecraft.commands.CommandSourceStack;
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.level.ServerLevel;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
@@ -27,7 +25,6 @@ import net.minecraft.world.phys.Vec3;
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public class TileCommandComputer extends TileComputer
 | 
			
		||||
{
 | 
			
		||||
@@ -51,7 +48,7 @@ public class TileCommandComputer extends TileComputer
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void sendMessage( @Nonnull Component textComponent, @Nonnull UUID id )
 | 
			
		||||
        public void sendSystemMessage( @Nonnull Component textComponent )
 | 
			
		||||
        {
 | 
			
		||||
            output.put( output.size() + 1, textComponent.getString() );
 | 
			
		||||
        }
 | 
			
		||||
@@ -101,7 +98,7 @@ public class TileCommandComputer extends TileComputer
 | 
			
		||||
        return new CommandSourceStack( receiver,
 | 
			
		||||
            Vec3.atCenterOf( worldPosition ), Vec2.ZERO,
 | 
			
		||||
            (ServerLevel) getLevel(), 2,
 | 
			
		||||
            name, new TextComponent( name ),
 | 
			
		||||
            name, Component.literal( name ),
 | 
			
		||||
            getLevel().getServer(), null
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
@@ -125,12 +122,12 @@ public class TileCommandComputer extends TileComputer
 | 
			
		||||
        MinecraftServer server = player.getServer();
 | 
			
		||||
        if( server == null || !server.isCommandBlockEnabled() )
 | 
			
		||||
        {
 | 
			
		||||
            player.displayClientMessage( new TranslatableComponent( "advMode.notEnabled" ), true );
 | 
			
		||||
            player.displayClientMessage( Component.translatable( "advMode.notEnabled" ), true );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        else if( ComputerCraft.commandRequireCreative ? !player.canUseGameMasterBlocks() : !server.getPlayerList().isOp( player.getGameProfile() ) )
 | 
			
		||||
        {
 | 
			
		||||
            player.displayClientMessage( new TranslatableComponent( "advMode.notAllowed" ), true );
 | 
			
		||||
            player.displayClientMessage( Component.translatable( "advMode.notAllowed" ), true );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,8 +22,6 @@ import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
 | 
			
		||||
import net.minecraft.world.*;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
@@ -439,8 +437,8 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
 | 
			
		||||
    public Component getName()
 | 
			
		||||
    {
 | 
			
		||||
        return hasCustomName()
 | 
			
		||||
            ? new TextComponent( label )
 | 
			
		||||
            : new TranslatableComponent( getBlockState().getBlock().getDescriptionId() );
 | 
			
		||||
            ? Component.literal( label )
 | 
			
		||||
            : Component.translatable( getBlockState().getBlock().getDescriptionId() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -453,7 +451,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
 | 
			
		||||
    @Override
 | 
			
		||||
    public Component getCustomName()
 | 
			
		||||
    {
 | 
			
		||||
        return hasCustomName() ? new TextComponent( label ) : null;
 | 
			
		||||
        return hasCustomName() ? Component.literal( label ) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,9 @@ import dan200.computercraft.shared.util.InvisibleSlot;
 | 
			
		||||
import net.minecraft.world.entity.player.Inventory;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
import net.minecraft.world.inventory.MenuType;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.function.Predicate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -38,4 +40,11 @@ public class ComputerMenuWithoutInventory extends ContainerComputerBase
 | 
			
		||||
    {
 | 
			
		||||
        for( int i = 0; i < 9; i++ ) addSlot( new InvisibleSlot( player, i ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ItemStack quickMoveStack( @Nonnull Player player, int slot )
 | 
			
		||||
    {
 | 
			
		||||
        return ItemStack.EMPTY;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ import dan200.computercraft.shared.computer.upload.UploadResult;
 | 
			
		||||
import dan200.computercraft.shared.network.NetworkHandler;
 | 
			
		||||
import dan200.computercraft.shared.network.client.UploadResultMessage;
 | 
			
		||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.server.level.ServerPlayer;
 | 
			
		||||
import net.minecraft.world.entity.player.Inventory;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
@@ -154,7 +154,7 @@ public abstract class ContainerComputerBase extends AbstractContainerMenu implem
 | 
			
		||||
            if( !upload.checksumMatches() )
 | 
			
		||||
            {
 | 
			
		||||
                ComputerCraft.log.warn( "Checksum failed to match for {}.", upload.getName() );
 | 
			
		||||
                return new UploadResultMessage( UploadResult.ERROR, new TranslatableComponent( "gui.computercraft.upload.failed.corrupted" ) );
 | 
			
		||||
                return new UploadResultMessage( UploadResult.ERROR, Component.translatable( "gui.computercraft.upload.failed.corrupted" ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -170,7 +170,7 @@ public abstract class ContainerComputerBase extends AbstractContainerMenu implem
 | 
			
		||||
                {
 | 
			
		||||
                    return new UploadResultMessage(
 | 
			
		||||
                        UploadResult.ERROR,
 | 
			
		||||
                        new TranslatableComponent( "gui.computercraft.upload.failed.overwrite_dir", upload.getName() )
 | 
			
		||||
                        Component.translatable( "gui.computercraft.upload.failed.overwrite_dir", upload.getName() )
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -184,7 +184,7 @@ public abstract class ContainerComputerBase extends AbstractContainerMenu implem
 | 
			
		||||
                toUpload = files;
 | 
			
		||||
                return new UploadResultMessage(
 | 
			
		||||
                    UploadResult.CONFIRM_OVERWRITE,
 | 
			
		||||
                    new TranslatableComponent( "gui.computercraft.upload.overwrite.detail", joiner.toString() )
 | 
			
		||||
                    Component.translatable( "gui.computercraft.upload.overwrite.detail", joiner.toString() )
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -202,13 +202,13 @@ public abstract class ContainerComputerBase extends AbstractContainerMenu implem
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new UploadResultMessage(
 | 
			
		||||
                UploadResult.SUCCESS, new TranslatableComponent( "gui.computercraft.upload.success.msg", files.size() )
 | 
			
		||||
                UploadResult.SUCCESS, Component.translatable( "gui.computercraft.upload.success.msg", files.size() )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        catch( FileSystemException | IOException e )
 | 
			
		||||
        {
 | 
			
		||||
            ComputerCraft.log.error( "Error uploading files", e );
 | 
			
		||||
            return new UploadResultMessage( UploadResult.ERROR, new TranslatableComponent( "gui.computercraft.upload.failed.generic", e.getMessage() ) );
 | 
			
		||||
            return new UploadResultMessage( UploadResult.ERROR, Component.translatable( "gui.computercraft.upload.failed.generic", e.getMessage() ) );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ package dan200.computercraft.shared.computer.items;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.shared.computer.blocks.BlockComputer;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -23,7 +23,7 @@ public class ItemComputer extends ItemComputerBase
 | 
			
		||||
    {
 | 
			
		||||
        ItemStack result = new ItemStack( this );
 | 
			
		||||
        if( id >= 0 ) result.getOrCreateTag().putInt( NBT_ID, id );
 | 
			
		||||
        if( label != null ) result.setHoverName( new TextComponent( label ) );
 | 
			
		||||
        if( label != null ) result.setHoverName( Component.literal( label ) );
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,6 @@ import dan200.computercraft.shared.computer.blocks.BlockComputerBase;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
import net.minecraft.ChatFormatting;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.world.item.BlockItem;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.TooltipFlag;
 | 
			
		||||
@@ -42,7 +40,7 @@ public abstract class ItemComputerBase extends BlockItem implements IComputerIte
 | 
			
		||||
            int id = getComputerID( stack );
 | 
			
		||||
            if( id >= 0 )
 | 
			
		||||
            {
 | 
			
		||||
                list.add( new TranslatableComponent( "gui.computercraft.tooltip.computer_id", id )
 | 
			
		||||
                list.add( Component.translatable( "gui.computercraft.tooltip.computer_id", id )
 | 
			
		||||
                    .withStyle( ChatFormatting.GRAY ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -67,7 +65,7 @@ public abstract class ItemComputerBase extends BlockItem implements IComputerIte
 | 
			
		||||
    {
 | 
			
		||||
        if( label != null )
 | 
			
		||||
        {
 | 
			
		||||
            stack.setHoverName( new TextComponent( label ) );
 | 
			
		||||
            stack.setHoverName( Component.literal( label ) );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ package dan200.computercraft.shared.computer.recipe;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
import dan200.computercraft.shared.util.BasicRecipeSerializer;
 | 
			
		||||
import dan200.computercraft.shared.util.RecipeUtil;
 | 
			
		||||
import net.minecraft.core.NonNullList;
 | 
			
		||||
import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
@@ -15,6 +14,7 @@ import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.GsonHelper;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.crafting.Ingredient;
 | 
			
		||||
import net.minecraft.world.item.crafting.RecipeSerializer;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
@@ -33,7 +33,7 @@ public abstract class ComputerFamilyRecipe extends ComputerConvertRecipe
 | 
			
		||||
        return family;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public abstract static class Serializer<T extends ComputerFamilyRecipe> extends BasicRecipeSerializer<T>
 | 
			
		||||
    public abstract static class Serializer<T extends ComputerFamilyRecipe> implements RecipeSerializer<T>
 | 
			
		||||
    {
 | 
			
		||||
        protected abstract T create( ResourceLocation identifier, String group, int width, int height, NonNullList<Ingredient> ingredients, ItemStack result, ComputerFamily family );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@
 | 
			
		||||
package dan200.computercraft.shared.computer.upload;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
 | 
			
		||||
public enum UploadResult
 | 
			
		||||
{
 | 
			
		||||
@@ -14,12 +13,12 @@ public enum UploadResult
 | 
			
		||||
    ERROR,
 | 
			
		||||
    CONFIRM_OVERWRITE;
 | 
			
		||||
 | 
			
		||||
    public static final Component SUCCESS_TITLE = new TranslatableComponent( "gui.computercraft.upload.success" );
 | 
			
		||||
    public static final Component SUCCESS_TITLE = Component.translatable( "gui.computercraft.upload.success" );
 | 
			
		||||
 | 
			
		||||
    public static final Component FAILED_TITLE = new TranslatableComponent( "gui.computercraft.upload.failed" );
 | 
			
		||||
    public static final Component COMPUTER_OFF_MSG = new TranslatableComponent( "gui.computercraft.upload.failed.computer_off" );
 | 
			
		||||
    public static final Component OUT_OF_SPACE_MSG = new TranslatableComponent( "gui.computercraft.upload.failed.out_of_space" );
 | 
			
		||||
    public static final Component TOO_MUCH_MSG = new TranslatableComponent( "gui.computercraft.upload.failed.too_much" );
 | 
			
		||||
    public static final Component FAILED_TITLE = Component.translatable( "gui.computercraft.upload.failed" );
 | 
			
		||||
    public static final Component COMPUTER_OFF_MSG = Component.translatable( "gui.computercraft.upload.failed.computer_off" );
 | 
			
		||||
    public static final Component OUT_OF_SPACE_MSG = Component.translatable( "gui.computercraft.upload.failed.out_of_space" );
 | 
			
		||||
    public static final Component TOO_MUCH_MSG = Component.translatable( "gui.computercraft.upload.failed.too_much" );
 | 
			
		||||
 | 
			
		||||
    public static final Component UPLOAD_OVERWRITE = new TranslatableComponent( "gui.computercraft.upload.overwrite" );
 | 
			
		||||
    public static final Component UPLOAD_OVERWRITE = Component.translatable( "gui.computercraft.upload.overwrite" );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,21 +20,22 @@ 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.RecipeTypes;
 | 
			
		||||
import mezz.jei.api.constants.VanillaTypes;
 | 
			
		||||
import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter;
 | 
			
		||||
import mezz.jei.api.recipe.IRecipeLookup;
 | 
			
		||||
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.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.crafting.Recipe;
 | 
			
		||||
import net.minecraft.world.item.crafting.CraftingRecipe;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.shared.integration.jei.RecipeResolver.MAIN_FAMILIES;
 | 
			
		||||
@@ -52,13 +53,13 @@ public class JEIComputerCraft implements IModPlugin
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerItemSubtypes( ISubtypeRegistration subtypeRegistry )
 | 
			
		||||
    {
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.TURTLE_NORMAL.get(), turtleSubtype );
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.TURTLE_ADVANCED.get(), turtleSubtype );
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( VanillaTypes.ITEM_STACK, Registry.ModItems.TURTLE_NORMAL.get(), turtleSubtype );
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( VanillaTypes.ITEM_STACK, Registry.ModItems.TURTLE_ADVANCED.get(), turtleSubtype );
 | 
			
		||||
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.POCKET_COMPUTER_NORMAL.get(), pocketSubtype );
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(), pocketSubtype );
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( VanillaTypes.ITEM_STACK, Registry.ModItems.POCKET_COMPUTER_NORMAL.get(), pocketSubtype );
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( VanillaTypes.ITEM_STACK, Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(), pocketSubtype );
 | 
			
		||||
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.DISK.get(), diskSubtype );
 | 
			
		||||
        subtypeRegistry.registerSubtypeInterpreter( VanillaTypes.ITEM_STACK, Registry.ModItems.DISK.get(), diskSubtype );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -89,27 +90,22 @@ public class JEIComputerCraft implements IModPlugin
 | 
			
		||||
 | 
			
		||||
        if( !upgradeItems.isEmpty() )
 | 
			
		||||
        {
 | 
			
		||||
            runtime.getIngredientManager().addIngredientsAtRuntime( VanillaTypes.ITEM, upgradeItems );
 | 
			
		||||
            runtime.getIngredientManager().addIngredientsAtRuntime( VanillaTypes.ITEM_STACK, upgradeItems );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Hide all upgrade recipes
 | 
			
		||||
        IRecipeCategory<?> category = registry.getRecipeCategory( VanillaRecipeCategoryUid.CRAFTING, false );
 | 
			
		||||
        if( category != null )
 | 
			
		||||
        {
 | 
			
		||||
            for( Object wrapper : registry.getRecipes( category, List.of(), false ) )
 | 
			
		||||
            {
 | 
			
		||||
                if( !(wrapper instanceof Recipe) ) continue;
 | 
			
		||||
                ResourceLocation id = ((Recipe<?>) wrapper).getId();
 | 
			
		||||
                if( !id.getNamespace().equals( ComputerCraft.MOD_ID ) ) continue;
 | 
			
		||||
        IRecipeLookup<CraftingRecipe> category = registry.createRecipeLookup( RecipeTypes.CRAFTING );
 | 
			
		||||
        category.get().forEach( wrapper -> {
 | 
			
		||||
            ResourceLocation id = wrapper.getId();
 | 
			
		||||
            if( !id.getNamespace().equals( ComputerCraft.MOD_ID ) ) return;
 | 
			
		||||
 | 
			
		||||
                String path = id.getPath();
 | 
			
		||||
                if( path.startsWith( "turtle_normal/" ) || path.startsWith( "turtle_advanced/" )
 | 
			
		||||
                    || path.startsWith( "pocket_normal/" ) || path.startsWith( "pocket_advanced/" ) )
 | 
			
		||||
                {
 | 
			
		||||
                    registry.hideRecipe( wrapper, VanillaRecipeCategoryUid.CRAFTING );
 | 
			
		||||
                }
 | 
			
		||||
            String path = id.getPath();
 | 
			
		||||
            if( path.startsWith( "turtle_normal/" ) || path.startsWith( "turtle_advanced/" )
 | 
			
		||||
                || path.startsWith( "pocket_normal/" ) || path.startsWith( "pocket_advanced/" ) )
 | 
			
		||||
            {
 | 
			
		||||
                registry.hideRecipes( RecipeTypes.CRAFTING, Collections.singleton( wrapper ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        } );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -6,10 +6,10 @@
 | 
			
		||||
package dan200.computercraft.shared.integration.jei;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.api.upgrades.IUpgradeBase;
 | 
			
		||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
 | 
			
		||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
 | 
			
		||||
import dan200.computercraft.api.turtle.TurtleSide;
 | 
			
		||||
import dan200.computercraft.api.upgrades.IUpgradeBase;
 | 
			
		||||
import dan200.computercraft.shared.PocketUpgrades;
 | 
			
		||||
import dan200.computercraft.shared.TurtleUpgrades;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
@@ -17,8 +17,9 @@ 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.constants.VanillaRecipeCategoryUid;
 | 
			
		||||
import mezz.jei.api.constants.RecipeTypes;
 | 
			
		||||
import mezz.jei.api.recipe.IFocus;
 | 
			
		||||
import mezz.jei.api.recipe.RecipeType;
 | 
			
		||||
import mezz.jei.api.recipe.advanced.IRecipeManagerPlugin;
 | 
			
		||||
import mezz.jei.api.recipe.category.IRecipeCategory;
 | 
			
		||||
import net.minecraft.core.NonNullList;
 | 
			
		||||
@@ -95,7 +96,7 @@ class RecipeResolver implements IRecipeManagerPlugin
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public <V> List<ResourceLocation> getRecipeCategoryUids( @Nonnull IFocus<V> focus )
 | 
			
		||||
    public <V> List<RecipeType<?>> getRecipeTypes( @Nonnull IFocus<V> focus )
 | 
			
		||||
    {
 | 
			
		||||
        V value = focus.getTypedValue().getIngredient();
 | 
			
		||||
        if( !(value instanceof ItemStack stack) ) return Collections.emptyList();
 | 
			
		||||
@@ -105,11 +106,11 @@ class RecipeResolver implements IRecipeManagerPlugin
 | 
			
		||||
            case INPUT:
 | 
			
		||||
                return stack.getItem() instanceof ITurtleItem || stack.getItem() instanceof ItemPocketComputer ||
 | 
			
		||||
                    hasUpgrade( stack )
 | 
			
		||||
                    ? Collections.singletonList( VanillaRecipeCategoryUid.CRAFTING )
 | 
			
		||||
                    ? Collections.singletonList( RecipeTypes.CRAFTING )
 | 
			
		||||
                    : Collections.emptyList();
 | 
			
		||||
            case OUTPUT:
 | 
			
		||||
                return stack.getItem() instanceof ITurtleItem || stack.getItem() instanceof ItemPocketComputer
 | 
			
		||||
                    ? Collections.singletonList( VanillaRecipeCategoryUid.CRAFTING )
 | 
			
		||||
                    ? Collections.singletonList( RecipeTypes.CRAFTING )
 | 
			
		||||
                    : Collections.emptyList();
 | 
			
		||||
            default:
 | 
			
		||||
                return Collections.emptyList();
 | 
			
		||||
@@ -120,7 +121,7 @@ class RecipeResolver implements IRecipeManagerPlugin
 | 
			
		||||
    @Override
 | 
			
		||||
    public <T, V> List<T> getRecipes( @Nonnull IRecipeCategory<T> recipeCategory, @Nonnull IFocus<V> focus )
 | 
			
		||||
    {
 | 
			
		||||
        if( !(focus.getTypedValue().getIngredient() instanceof ItemStack stack) || !recipeCategory.getUid().equals( VanillaRecipeCategoryUid.CRAFTING ) )
 | 
			
		||||
        if( !(focus.getTypedValue().getIngredient() instanceof ItemStack stack) || recipeCategory.getRecipeType() != RecipeTypes.CRAFTING )
 | 
			
		||||
        {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,6 @@ import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.core.NonNullList;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
@@ -53,7 +51,7 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
 | 
			
		||||
    @Override
 | 
			
		||||
    public void fillItemCategory( @Nonnull CreativeModeTab tabs, @Nonnull NonNullList<ItemStack> list )
 | 
			
		||||
    {
 | 
			
		||||
        if( !allowdedIn( tabs ) ) return;
 | 
			
		||||
        if( !allowedIn( tabs ) ) return;
 | 
			
		||||
        for( int colour = 0; colour < 16; colour++ )
 | 
			
		||||
        {
 | 
			
		||||
            list.add( createFromIDAndColour( -1, null, Colour.VALUES[colour].getHex() ) );
 | 
			
		||||
@@ -68,7 +66,7 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
 | 
			
		||||
            int id = getDiskID( stack );
 | 
			
		||||
            if( id >= 0 )
 | 
			
		||||
            {
 | 
			
		||||
                list.add( new TranslatableComponent( "gui.computercraft.tooltip.disk_id", id )
 | 
			
		||||
                list.add( Component.translatable( "gui.computercraft.tooltip.disk_id", id )
 | 
			
		||||
                    .withStyle( ChatFormatting.GRAY ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -91,7 +89,7 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
 | 
			
		||||
    {
 | 
			
		||||
        if( label != null )
 | 
			
		||||
        {
 | 
			
		||||
            stack.setHoverName( new TextComponent( label ) );
 | 
			
		||||
            stack.setHoverName( Component.literal( label ) );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ import dan200.computercraft.shared.common.ContainerHeldItem;
 | 
			
		||||
import dan200.computercraft.shared.network.container.HeldItemContainerData;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.world.InteractionHand;
 | 
			
		||||
import net.minecraft.world.InteractionResult;
 | 
			
		||||
import net.minecraft.world.InteractionResultHolder;
 | 
			
		||||
@@ -53,7 +52,7 @@ public class ItemPrintout extends Item
 | 
			
		||||
    public void appendHoverText( @Nonnull ItemStack stack, Level world, @Nonnull List<Component> list, @Nonnull TooltipFlag options )
 | 
			
		||||
    {
 | 
			
		||||
        String title = getTitle( stack );
 | 
			
		||||
        if( title != null && !title.isEmpty() ) list.add( new TextComponent( title ) );
 | 
			
		||||
        if( title != null && !title.isEmpty() ) list.add( Component.literal( title ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.core.NonNullList;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
@@ -49,7 +48,7 @@ public class ItemTreasureDisk extends Item implements IMedia
 | 
			
		||||
    public void appendHoverText( @Nonnull ItemStack stack, @Nullable Level world, @Nonnull List<Component> list, @Nonnull TooltipFlag tooltipOptions )
 | 
			
		||||
    {
 | 
			
		||||
        String label = getTitle( stack );
 | 
			
		||||
        if( !label.isEmpty() ) list.add( new TextComponent( label ) );
 | 
			
		||||
        if( !label.isEmpty() ) list.add( Component.literal( label ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
package dan200.computercraft.shared.media.items;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.api.media.IMedia;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.sounds.SoundEvent;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
@@ -37,7 +37,7 @@ public final class RecordMedia implements IMedia
 | 
			
		||||
        Item item = stack.getItem();
 | 
			
		||||
        if( !(item instanceof RecordItem) ) return null;
 | 
			
		||||
 | 
			
		||||
        return new TranslatableComponent( item.getDescriptionId() + ".desc" ).getString();
 | 
			
		||||
        return Component.translatable( item.getDescriptionId() + ".desc" ).getString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -9,11 +9,12 @@ import dan200.computercraft.shared.network.NetworkMessage;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.network.FriendlyByteBuf;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.sounds.SoundEvent;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.api.distmarker.OnlyIn;
 | 
			
		||||
import net.minecraftforge.network.NetworkEvent;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
@@ -71,7 +72,7 @@ public class PlayRecordClientMessage implements NetworkMessage
 | 
			
		||||
        {
 | 
			
		||||
            buf.writeBoolean( true );
 | 
			
		||||
            buf.writeUtf( name );
 | 
			
		||||
            buf.writeRegistryId( soundEvent );
 | 
			
		||||
            buf.writeRegistryId( ForgeRegistries.SOUND_EVENTS, soundEvent );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -81,6 +82,6 @@ public class PlayRecordClientMessage implements NetworkMessage
 | 
			
		||||
    {
 | 
			
		||||
        Minecraft mc = Minecraft.getInstance();
 | 
			
		||||
        mc.levelRenderer.playStreamingMusic( soundEvent, pos, null );
 | 
			
		||||
        if( name != null ) mc.gui.setNowPlaying( new TextComponent( name ) );
 | 
			
		||||
        if( name != null ) mc.gui.setNowPlaying( Component.literal( name ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -72,12 +72,12 @@ public class UpgradesLoadedMessage implements NetworkMessage
 | 
			
		||||
    @Override
 | 
			
		||||
    public void toBytes( @Nonnull FriendlyByteBuf buf )
 | 
			
		||||
    {
 | 
			
		||||
        toBytes( buf, turtleUpgrades );
 | 
			
		||||
        toBytes( buf, pocketUpgrades );
 | 
			
		||||
        toBytes( buf, TurtleUpgradeSerialiser.registry(), turtleUpgrades );
 | 
			
		||||
        toBytes( buf, PocketUpgradeSerialiser.registry(), pocketUpgrades );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <R extends UpgradeSerialiser<? extends T, R>, T extends IUpgradeBase> void toBytes(
 | 
			
		||||
        @Nonnull FriendlyByteBuf buf, Map<String, UpgradeManager.UpgradeWrapper<R, T>> upgrades
 | 
			
		||||
        @Nonnull FriendlyByteBuf buf, IForgeRegistry<R> registry, Map<String, UpgradeManager.UpgradeWrapper<R, T>> upgrades
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
        buf.writeVarInt( upgrades.size() );
 | 
			
		||||
@@ -85,11 +85,12 @@ public class UpgradesLoadedMessage implements NetworkMessage
 | 
			
		||||
        {
 | 
			
		||||
            buf.writeUtf( entry.getKey() );
 | 
			
		||||
 | 
			
		||||
            var serialiser = entry.getValue().serialiser();
 | 
			
		||||
            @SuppressWarnings( "unchecked" )
 | 
			
		||||
            var serialiser = (UpgradeSerialiser<T, R>) entry.getValue().serialiser();
 | 
			
		||||
            var unwrapedSerialiser = (UpgradeSerialiser<T, R>) serialiser;
 | 
			
		||||
 | 
			
		||||
            buf.writeResourceLocation( Objects.requireNonNull( serialiser.getRegistryName(), "Serialiser is not registered!" ) );
 | 
			
		||||
            serialiser.toNetwork( buf, entry.getValue().upgrade() );
 | 
			
		||||
            buf.writeResourceLocation( Objects.requireNonNull( registry.getKey( serialiser ), "Serialiser is not registered!" ) );
 | 
			
		||||
            unwrapedSerialiser.toNetwork( buf, entry.getValue().upgrade() );
 | 
			
		||||
 | 
			
		||||
            buf.writeUtf( entry.getValue().modId() );
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.server.level.ServerPlayer;
 | 
			
		||||
import net.minecraft.sounds.SoundEvent;
 | 
			
		||||
import net.minecraft.world.*;
 | 
			
		||||
@@ -563,7 +562,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
 | 
			
		||||
    @Override
 | 
			
		||||
    public Component getName()
 | 
			
		||||
    {
 | 
			
		||||
        return customName != null ? customName : new TranslatableComponent( getBlockState().getBlock().getDescriptionId() );
 | 
			
		||||
        return customName != null ? customName : Component.translatable( getBlockState().getBlock().getDescriptionId() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ import dan200.computercraft.api.peripheral.IDynamicPeripheral;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntity;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -29,7 +30,7 @@ class GenericPeripheral implements IDynamicPeripheral
 | 
			
		||||
 | 
			
		||||
    GenericPeripheral( BlockEntity tile, String name, Set<String> additionalTypes, List<SaturatedMethod> methods )
 | 
			
		||||
    {
 | 
			
		||||
        ResourceLocation type = tile.getType().getRegistryName();
 | 
			
		||||
        ResourceLocation type = ForgeRegistries.BLOCK_ENTITIES.getKey( tile.getType() );
 | 
			
		||||
        this.tile = tile;
 | 
			
		||||
        this.type = name != null ? name : (type != null ? type.toString() : "unknown");
 | 
			
		||||
        this.additionalTypes = additionalTypes;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ package dan200.computercraft.shared.peripheral.generic.data;
 | 
			
		||||
import dan200.computercraft.api.detail.BlockReference;
 | 
			
		||||
import net.minecraft.world.level.block.state.BlockState;
 | 
			
		||||
import net.minecraft.world.level.block.state.properties.Property;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
@@ -20,7 +21,7 @@ public class BlockData
 | 
			
		||||
    {
 | 
			
		||||
        BlockState state = block.state();
 | 
			
		||||
 | 
			
		||||
        data.put( "name", DataHelpers.getId( state.getBlock() ) );
 | 
			
		||||
        data.put( "name", DataHelpers.getId( ForgeRegistries.BLOCKS, state.getBlock() ) );
 | 
			
		||||
 | 
			
		||||
        Map<Object, Object> stateTable = new HashMap<>();
 | 
			
		||||
        for( Map.Entry<Property<?>, ? extends Comparable<?>> entry : state.getValues().entrySet() )
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ package dan200.computercraft.shared.peripheral.generic.data;
 | 
			
		||||
import net.minecraft.core.Holder;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.tags.TagKey;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistry;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -33,9 +33,9 @@ public final class DataHelpers
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public static String getId( @Nonnull IForgeRegistryEntry<?> entry )
 | 
			
		||||
    public static <T> String getId( @Nonnull IForgeRegistry<T> registry, T entry )
 | 
			
		||||
    {
 | 
			
		||||
        ResourceLocation id = entry.getRegistryName();
 | 
			
		||||
        ResourceLocation id = registry.getKey( entry );
 | 
			
		||||
        return id == null ? null : id.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
package dan200.computercraft.shared.peripheral.generic.data;
 | 
			
		||||
 | 
			
		||||
import net.minecraftforge.fluids.FluidStack;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
@@ -15,7 +16,7 @@ public class FluidData
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static <T extends Map<? super String, Object>> T fillBasic( @Nonnull T data, @Nonnull FluidStack stack )
 | 
			
		||||
    {
 | 
			
		||||
        data.put( "name", DataHelpers.getId( stack.getFluid() ) );
 | 
			
		||||
        data.put( "name", DataHelpers.getId( ForgeRegistries.FLUIDS, stack.getFluid() ) );
 | 
			
		||||
        data.put( "amount", stack.getAmount() );
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ import net.minecraft.world.item.EnchantedBookItem;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.enchantment.Enchantment;
 | 
			
		||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -29,7 +30,7 @@ public class ItemData
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static <T extends Map<? super String, Object>> T fillBasicSafe( @Nonnull T data, @Nonnull ItemStack stack )
 | 
			
		||||
    {
 | 
			
		||||
        data.put( "name", DataHelpers.getId( stack.getItem() ) );
 | 
			
		||||
        data.put( "name", DataHelpers.getId( ForgeRegistries.ITEMS, stack.getItem() ) );
 | 
			
		||||
        data.put( "count", stack.getCount() );
 | 
			
		||||
 | 
			
		||||
        return data;
 | 
			
		||||
@@ -163,7 +164,7 @@ public class ItemData
 | 
			
		||||
            Enchantment enchantment = entry.getKey();
 | 
			
		||||
            Integer level = entry.getValue();
 | 
			
		||||
            HashMap<String, Object> enchant = new HashMap<>( 3 );
 | 
			
		||||
            enchant.put( "name", DataHelpers.getId( enchantment ) );
 | 
			
		||||
            enchant.put( "name", DataHelpers.getId( ForgeRegistries.ENCHANTMENTS, enchantment ) );
 | 
			
		||||
            enchant.put( "level", level );
 | 
			
		||||
            enchant.put( "displayName", enchantment.getFullname( level ).getString() );
 | 
			
		||||
            enchants.add( enchant );
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,6 @@ import dan200.computercraft.api.lua.LuaException;
 | 
			
		||||
import net.minecraft.ResourceLocationException;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistry;
 | 
			
		||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
@@ -42,7 +41,7 @@ final class ArgumentHelpers
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static <T extends IForgeRegistryEntry<T>> T getRegistryEntry( String name, String typeName, IForgeRegistry<T> registry ) throws LuaException
 | 
			
		||||
    public static <T> T getRegistryEntry( String name, String typeName, IForgeRegistry<T> registry ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        ResourceLocation id;
 | 
			
		||||
        try
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ public abstract class ItemBlockCable extends BlockItem
 | 
			
		||||
    @Override
 | 
			
		||||
    public void fillItemCategory( @Nonnull CreativeModeTab group, @Nonnull NonNullList<ItemStack> list )
 | 
			
		||||
    {
 | 
			
		||||
        if( allowdedIn( group ) ) list.add( new ItemStack( this ) );
 | 
			
		||||
        if( allowedIn( group ) ) list.add( new ItemStack( this ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ import dan200.computercraft.shared.util.TickScheduler;
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.world.InteractionHand;
 | 
			
		||||
import net.minecraft.world.InteractionResult;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
@@ -269,12 +269,12 @@ public class TileCable extends TileGeneric
 | 
			
		||||
        {
 | 
			
		||||
            if( oldName != null )
 | 
			
		||||
            {
 | 
			
		||||
                player.displayClientMessage( new TranslatableComponent( "chat.computercraft.wired_modem.peripheral_disconnected",
 | 
			
		||||
                player.displayClientMessage( Component.translatable( "chat.computercraft.wired_modem.peripheral_disconnected",
 | 
			
		||||
                    ChatHelpers.copy( oldName ) ), false );
 | 
			
		||||
            }
 | 
			
		||||
            if( newName != null )
 | 
			
		||||
            {
 | 
			
		||||
                player.displayClientMessage( new TranslatableComponent( "chat.computercraft.wired_modem.peripheral_connected",
 | 
			
		||||
                player.displayClientMessage( Component.translatable( "chat.computercraft.wired_modem.peripheral_connected",
 | 
			
		||||
                    ChatHelpers.copy( newName ) ), false );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,8 @@ import dan200.computercraft.shared.util.TickScheduler;
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.MutableComponent;
 | 
			
		||||
import net.minecraft.world.InteractionHand;
 | 
			
		||||
import net.minecraft.world.InteractionResult;
 | 
			
		||||
import net.minecraft.world.entity.player.Player;
 | 
			
		||||
@@ -223,14 +223,14 @@ public class TileWiredModemFull extends TileGeneric
 | 
			
		||||
        List<String> names = new ArrayList<>( peripherals );
 | 
			
		||||
        names.sort( Comparator.naturalOrder() );
 | 
			
		||||
 | 
			
		||||
        TextComponent base = new TextComponent( "" );
 | 
			
		||||
        MutableComponent base = Component.literal( "" );
 | 
			
		||||
        for( int i = 0; i < names.size(); i++ )
 | 
			
		||||
        {
 | 
			
		||||
            if( i > 0 ) base.append( ", " );
 | 
			
		||||
            base.append( ChatHelpers.copy( names.get( i ) ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        player.displayClientMessage( new TranslatableComponent( kind, base ), false );
 | 
			
		||||
        player.displayClientMessage( Component.translatable( kind, base ), false );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.core.NonNullList;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.server.level.ServerPlayer;
 | 
			
		||||
import net.minecraft.world.*;
 | 
			
		||||
import net.minecraft.world.entity.player.Inventory;
 | 
			
		||||
@@ -492,7 +491,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
 | 
			
		||||
    @Override
 | 
			
		||||
    public Component getName()
 | 
			
		||||
    {
 | 
			
		||||
        return customName != null ? customName : new TranslatableComponent( getBlockState().getBlock().getDescriptionId() );
 | 
			
		||||
        return customName != null ? customName : Component.translatable( getBlockState().getBlock().getDescriptionId() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ import net.minecraft.sounds.SoundSource;
 | 
			
		||||
import net.minecraft.world.level.Level;
 | 
			
		||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
 | 
			
		||||
import net.minecraft.world.phys.Vec3;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
@@ -89,7 +90,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
                lastPlayTime = clock;
 | 
			
		||||
                server.getPlayerList().broadcast(
 | 
			
		||||
                    null, pos.x, pos.y, pos.z, sound.volume * 16, level.dimension(),
 | 
			
		||||
                    new ClientboundCustomSoundPacket( sound.location, SoundSource.RECORDS, pos, sound.volume, sound.pitch )
 | 
			
		||||
                    new ClientboundCustomSoundPacket( sound.location, SoundSource.RECORDS, pos, sound.volume, sound.pitch, level.getRandom().nextLong() )
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            pendingNotes.clear();
 | 
			
		||||
@@ -241,7 +242,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
        synchronized( pendingNotes )
 | 
			
		||||
        {
 | 
			
		||||
            if( pendingNotes.size() >= ComputerCraft.maxNotesPerTick ) return false;
 | 
			
		||||
            pendingNotes.add( new PendingSound( instrument.getSoundEvent().getRegistryName(), volume, (float) Math.pow( 2.0, (pitch - 12.0) / 12.0 ) ) );
 | 
			
		||||
            pendingNotes.add( new PendingSound( ForgeRegistries.SOUND_EVENTS.getKey( instrument.getSoundEvent() ), volume, (float) Math.pow( 2.0, (pitch - 12.0) / 12.0 ) ) );
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ public record SpeakerPosition(@Nullable Level level, @Nonnull Vec3 position, @Nu
 | 
			
		||||
    public Message asMessage()
 | 
			
		||||
    {
 | 
			
		||||
        if( level == null ) throw new NullPointerException( "Cannot send a position without a level" );
 | 
			
		||||
        return new Message( level.dimension().getRegistryName(), position, entity == null ? OptionalInt.empty() : OptionalInt.of( entity.getId() ) );
 | 
			
		||||
        return new Message( level.dimension().location(), position, entity == null ? OptionalInt.empty() : OptionalInt.of( entity.getId() ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class Message
 | 
			
		||||
@@ -80,7 +80,7 @@ public record SpeakerPosition(@Nullable Level level, @Nonnull Vec3 position, @Nu
 | 
			
		||||
        {
 | 
			
		||||
            Minecraft minecraft = Minecraft.getInstance();
 | 
			
		||||
            Level level = minecraft.level;
 | 
			
		||||
            if( level != null && !level.dimension().getRegistryName().equals( this.level ) ) level = null;
 | 
			
		||||
            if( level != null && !level.dimension().location().equals( this.level ) ) level = null;
 | 
			
		||||
 | 
			
		||||
            return new SpeakerPosition(
 | 
			
		||||
                level, position,
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,6 @@ import net.minecraft.ChatFormatting;
 | 
			
		||||
import net.minecraft.core.NonNullList;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.world.Container;
 | 
			
		||||
import net.minecraft.world.InteractionHand;
 | 
			
		||||
import net.minecraft.world.InteractionResult;
 | 
			
		||||
@@ -67,7 +65,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
			
		||||
    {
 | 
			
		||||
        ItemStack result = new ItemStack( this );
 | 
			
		||||
        if( id >= 0 ) result.getOrCreateTag().putInt( NBT_ID, id );
 | 
			
		||||
        if( label != null ) result.setHoverName( new TextComponent( label ) );
 | 
			
		||||
        if( label != null ) result.setHoverName( Component.literal( label ) );
 | 
			
		||||
        if( upgrade != null ) result.getOrCreateTag().putString( NBT_UPGRADE, upgrade.getUpgradeID().toString() );
 | 
			
		||||
        if( colour != -1 ) result.getOrCreateTag().putInt( NBT_COLOUR, colour );
 | 
			
		||||
        return result;
 | 
			
		||||
@@ -76,7 +74,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
			
		||||
    @Override
 | 
			
		||||
    public void fillItemCategory( @Nonnull CreativeModeTab group, @Nonnull NonNullList<ItemStack> stacks )
 | 
			
		||||
    {
 | 
			
		||||
        if( !allowdedIn( group ) ) return;
 | 
			
		||||
        if( !allowedIn( group ) ) return;
 | 
			
		||||
        stacks.add( create( -1, null, -1, null ) );
 | 
			
		||||
        PocketUpgrades.getVanillaUpgrades().map( x -> create( -1, null, -1, x ) ).forEach( stacks::add );
 | 
			
		||||
    }
 | 
			
		||||
@@ -182,8 +180,8 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
			
		||||
        IPocketUpgrade upgrade = getUpgrade( stack );
 | 
			
		||||
        if( upgrade != null )
 | 
			
		||||
        {
 | 
			
		||||
            return new TranslatableComponent( baseString + ".upgraded",
 | 
			
		||||
                new TranslatableComponent( upgrade.getUnlocalisedAdjective() )
 | 
			
		||||
            return Component.translatable( baseString + ".upgraded",
 | 
			
		||||
                Component.translatable( upgrade.getUnlocalisedAdjective() )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
@@ -201,7 +199,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
			
		||||
            int id = getComputerID( stack );
 | 
			
		||||
            if( id >= 0 )
 | 
			
		||||
            {
 | 
			
		||||
                list.add( new TranslatableComponent( "gui.computercraft.tooltip.computer_id", id )
 | 
			
		||||
                list.add( Component.translatable( "gui.computercraft.tooltip.computer_id", id )
 | 
			
		||||
                    .withStyle( ChatFormatting.GRAY ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -332,7 +330,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
			
		||||
    {
 | 
			
		||||
        if( label != null )
 | 
			
		||||
        {
 | 
			
		||||
            stack.setHoverName( new TextComponent( label ) );
 | 
			
		||||
            stack.setHoverName( Component.literal( label ) );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ import dan200.computercraft.shared.util.InventoryUtil;
 | 
			
		||||
import dan200.computercraft.shared.util.WorldUtil;
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.core.Direction;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.protocol.game.ServerboundInteractPacket;
 | 
			
		||||
import net.minecraft.world.InteractionHand;
 | 
			
		||||
import net.minecraft.world.InteractionResult;
 | 
			
		||||
@@ -284,7 +284,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Item item = stack.getItem();
 | 
			
		||||
        if( item instanceof BucketItem || item instanceof BoatItem || item instanceof WaterLilyBlockItem || item instanceof BottleItem )
 | 
			
		||||
        if( item instanceof BucketItem || item instanceof BoatItem || item instanceof PlaceOnWaterBlockItem || item instanceof BottleItem )
 | 
			
		||||
        {
 | 
			
		||||
            InteractionResult actionResult = ForgeHooks.onItemRightClick( turtlePlayer, InteractionHand.MAIN_HAND );
 | 
			
		||||
            if( actionResult != null && actionResult != InteractionResult.PASS ) return actionResult;
 | 
			
		||||
@@ -311,13 +311,13 @@ public class TurtlePlaceCommand implements ITurtleCommand
 | 
			
		||||
            {
 | 
			
		||||
                String line = split[i - firstLine];
 | 
			
		||||
                signTile.setMessage( i, line.length() > 15
 | 
			
		||||
                    ? new TextComponent( line.substring( 0, 15 ) )
 | 
			
		||||
                    : new TextComponent( line )
 | 
			
		||||
                    ? Component.literal( line.substring( 0, 15 ) )
 | 
			
		||||
                    : Component.literal( line )
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                signTile.setMessage( i, new TextComponent( "" ) );
 | 
			
		||||
                signTile.setMessage( i, Component.literal( "" ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        signTile.setChanged();
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,6 @@ import net.minecraft.core.NonNullList;
 | 
			
		||||
import net.minecraft.core.cauldron.CauldronInteraction;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.InteractionResult;
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab;
 | 
			
		||||
@@ -41,7 +39,7 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem
 | 
			
		||||
    {
 | 
			
		||||
        // Build the stack
 | 
			
		||||
        ItemStack stack = new ItemStack( this );
 | 
			
		||||
        if( label != null ) stack.setHoverName( new TextComponent( label ) );
 | 
			
		||||
        if( label != null ) stack.setHoverName( Component.literal( label ) );
 | 
			
		||||
        if( id >= 0 ) stack.getOrCreateTag().putInt( NBT_ID, id );
 | 
			
		||||
        IColouredItem.setColourBasic( stack, colour );
 | 
			
		||||
        if( fuelLevel > 0 ) stack.getOrCreateTag().putInt( NBT_FUEL, fuelLevel );
 | 
			
		||||
@@ -63,9 +61,7 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem
 | 
			
		||||
    @Override
 | 
			
		||||
    public void fillItemCategory( @Nonnull CreativeModeTab group, @Nonnull NonNullList<ItemStack> list )
 | 
			
		||||
    {
 | 
			
		||||
        if( !allowdedIn( group ) ) return;
 | 
			
		||||
 | 
			
		||||
        ComputerFamily family = getFamily();
 | 
			
		||||
        if( !allowedIn( group ) ) return;
 | 
			
		||||
 | 
			
		||||
        list.add( create( -1, null, -1, null, null, 0, null ) );
 | 
			
		||||
        TurtleUpgrades.getVanillaUpgrades()
 | 
			
		||||
@@ -82,26 +78,26 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem
 | 
			
		||||
        ITurtleUpgrade right = getUpgrade( stack, TurtleSide.RIGHT );
 | 
			
		||||
        if( left != null && right != null )
 | 
			
		||||
        {
 | 
			
		||||
            return new TranslatableComponent( baseString + ".upgraded_twice",
 | 
			
		||||
                new TranslatableComponent( right.getUnlocalisedAdjective() ),
 | 
			
		||||
                new TranslatableComponent( left.getUnlocalisedAdjective() )
 | 
			
		||||
            return Component.translatable( baseString + ".upgraded_twice",
 | 
			
		||||
                Component.translatable( right.getUnlocalisedAdjective() ),
 | 
			
		||||
                Component.translatable( left.getUnlocalisedAdjective() )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        else if( left != null )
 | 
			
		||||
        {
 | 
			
		||||
            return new TranslatableComponent( baseString + ".upgraded",
 | 
			
		||||
                new TranslatableComponent( left.getUnlocalisedAdjective() )
 | 
			
		||||
            return Component.translatable( baseString + ".upgraded",
 | 
			
		||||
                Component.translatable( left.getUnlocalisedAdjective() )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        else if( right != null )
 | 
			
		||||
        {
 | 
			
		||||
            return new TranslatableComponent( baseString + ".upgraded",
 | 
			
		||||
                new TranslatableComponent( right.getUnlocalisedAdjective() )
 | 
			
		||||
            return Component.translatable( baseString + ".upgraded",
 | 
			
		||||
                Component.translatable( right.getUnlocalisedAdjective() )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return new TranslatableComponent( baseString );
 | 
			
		||||
            return Component.translatable( baseString );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
public final class TurtleToolSerialiser extends TurtleUpgradeSerialiser.Base<TurtleTool>
 | 
			
		||||
public final class TurtleToolSerialiser implements TurtleUpgradeSerialiser<TurtleTool>
 | 
			
		||||
{
 | 
			
		||||
    public static final TurtleToolSerialiser INSTANCE = new TurtleToolSerialiser();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of ComputerCraft - http://www.computercraft.info
 | 
			
		||||
 * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
 | 
			
		||||
 * Send enquiries to dratcliffe@gmail.com
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared.util;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.world.item.crafting.Recipe;
 | 
			
		||||
import net.minecraft.world.item.crafting.RecipeSerializer;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link RecipeSerializer} which implements all the Forge registry entries.
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> The reciep serializer
 | 
			
		||||
 */
 | 
			
		||||
public abstract class BasicRecipeSerializer<T extends Recipe<?>> extends ForgeRegistryEntry<RecipeSerializer<?>> implements RecipeSerializer<T>
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
@@ -57,7 +57,7 @@ public final class ImpostorRecipe extends ShapedRecipe
 | 
			
		||||
        return SERIALIZER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final RecipeSerializer<ImpostorRecipe> SERIALIZER = new BasicRecipeSerializer<>()
 | 
			
		||||
    public static final RecipeSerializer<ImpostorRecipe> SERIALIZER = new RecipeSerializer<ImpostorRecipe>()
 | 
			
		||||
    {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ public final class ImpostorShapelessRecipe extends ShapelessRecipe
 | 
			
		||||
        return SERIALIZER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final RecipeSerializer<ImpostorShapelessRecipe> SERIALIZER = new BasicRecipeSerializer<>()
 | 
			
		||||
    public static final RecipeSerializer<ImpostorShapelessRecipe> SERIALIZER = new RecipeSerializer<ImpostorShapelessRecipe>()
 | 
			
		||||
    {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ public com.mojang.blaze3d.audio.Channel m_83652_(I)V # pumpBuffers
 | 
			
		||||
public net.minecraft.client.sounds.SoundEngine f_120223_ # executor
 | 
			
		||||
 | 
			
		||||
# DirectVertexBuffer
 | 
			
		||||
protected com.mojang.blaze3d.vertex.VertexBuffer f_166859_ # vertextBufferId
 | 
			
		||||
protected com.mojang.blaze3d.vertex.VertexBuffer f_231217_ # vertexBufferId
 | 
			
		||||
protected com.mojang.blaze3d.vertex.VertexBuffer f_166861_ # indexType
 | 
			
		||||
protected com.mojang.blaze3d.vertex.VertexBuffer f_166863_ # indexCount
 | 
			
		||||
protected com.mojang.blaze3d.vertex.VertexBuffer f_166864_ # mode
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
modLoader="javafml"
 | 
			
		||||
loaderVersion="[40,41)"
 | 
			
		||||
loaderVersion="[41,42)"
 | 
			
		||||
 | 
			
		||||
issueTrackerURL="https://github.com/cc-tweaked/CC-Tweaked/issues"
 | 
			
		||||
logoFile="pack.png"
 | 
			
		||||
@@ -21,6 +21,6 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a
 | 
			
		||||
[[dependencies.computercraft]]
 | 
			
		||||
    modId="forge"
 | 
			
		||||
    mandatory=true
 | 
			
		||||
    versionRange="[40.1.0,41)"
 | 
			
		||||
    versionRange="[41.0.38,42)"
 | 
			
		||||
    ordering="NONE"
 | 
			
		||||
    side="BOTH"
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,11 @@
 | 
			
		||||
Several bug fixes:
 | 
			
		||||
* Fix NPE within disk drive and printer code.
 | 
			
		||||
 | 
			
		||||
# New features in CC: Tweaked 1.100.7
 | 
			
		||||
 | 
			
		||||
* Fix failing to launch outside of a dev environment.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# New features in CC: Tweaked 1.100.6
 | 
			
		||||
 | 
			
		||||
* Various documentation improvements (MCJack123, FayneAldan).
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.ingame.mod.TestMod;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.core.NonNullList;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
@@ -52,7 +52,7 @@ public class Exporter
 | 
			
		||||
        Path output = new File( event.getMessage().substring( prefix.length() ).trim() ).getAbsoluteFile().toPath();
 | 
			
		||||
        if( !Files.isDirectory( output ) )
 | 
			
		||||
        {
 | 
			
		||||
            Minecraft.getInstance().gui.getChat().addMessage( new TextComponent( "Output path does not exist" ) );
 | 
			
		||||
            Minecraft.getInstance().gui.getChat().addMessage( Component.literal( "Output path does not exist" ) );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -66,7 +66,7 @@ public class Exporter
 | 
			
		||||
            throw new UncheckedIOException( e );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Minecraft.getInstance().gui.getChat().addMessage( new TextComponent( "Export finished!" ) );
 | 
			
		||||
        Minecraft.getInstance().gui.getChat().addMessage( Component.literal( "Export finished!" ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void export( Path root, ImageRenderer renderer ) throws IOException
 | 
			
		||||
@@ -76,16 +76,19 @@ public class Exporter
 | 
			
		||||
        Set<Item> items = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
        // First find all CC items
 | 
			
		||||
        for( Item item : ForgeRegistries.ITEMS.getValues() )
 | 
			
		||||
        for( Item item : ForgeRegistries.ITEMS )
 | 
			
		||||
        {
 | 
			
		||||
            if( item.getRegistryName().getNamespace().equals( ComputerCraft.MOD_ID ) ) items.add( item );
 | 
			
		||||
            if( ForgeRegistries.ITEMS.getKey( item ).getNamespace().equals( ComputerCraft.MOD_ID ) ) items.add( item );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Now find all CC recipes.
 | 
			
		||||
        for( CraftingRecipe recipe : Minecraft.getInstance().level.getRecipeManager().getAllRecipesFor( RecipeType.CRAFTING ) )
 | 
			
		||||
        {
 | 
			
		||||
            ItemStack result = recipe.getResultItem();
 | 
			
		||||
            if( !result.getItem().getRegistryName().getNamespace().equals( ComputerCraft.MOD_ID ) ) continue;
 | 
			
		||||
            if( !ForgeRegistries.ITEMS.getKey( result.getItem() ).getNamespace().equals( ComputerCraft.MOD_ID ) )
 | 
			
		||||
            {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if( result.hasTag() )
 | 
			
		||||
            {
 | 
			
		||||
                ComputerCraft.log.warn( "Skipping recipe {} as it has NBT", recipe.getId() );
 | 
			
		||||
@@ -134,9 +137,9 @@ public class Exporter
 | 
			
		||||
        for( Item item : items )
 | 
			
		||||
        {
 | 
			
		||||
            ItemStack stack = new ItemStack( item );
 | 
			
		||||
            dump.itemNames.put( item.getRegistryName().toString(), stack.getHoverName().getString() );
 | 
			
		||||
            ResourceLocation location = ForgeRegistries.ITEMS.getKey( item );
 | 
			
		||||
 | 
			
		||||
            ResourceLocation location = item.getRegistryName();
 | 
			
		||||
            dump.itemNames.put( location.toString(), stack.getHoverName().getString() );
 | 
			
		||||
            renderer.captureRender( itemDir.resolve( location.getNamespace() ).resolve( location.getPath() + ".png" ),
 | 
			
		||||
                () -> Minecraft.getInstance().getItemRenderer().renderAndDecorateFakeItem( stack, 0, 0 )
 | 
			
		||||
            );
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.Items;
 | 
			
		||||
import net.minecraft.world.item.crafting.Ingredient;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
@@ -25,7 +26,7 @@ public class JsonDump
 | 
			
		||||
 | 
			
		||||
        public Recipe( ItemStack output )
 | 
			
		||||
        {
 | 
			
		||||
            this.output = output.getItem().getRegistryName().toString();
 | 
			
		||||
            this.output = ForgeRegistries.ITEMS.getKey( output.getItem() ).toString();
 | 
			
		||||
            count = output.getCount();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -42,7 +43,7 @@ public class JsonDump
 | 
			
		||||
                if( !canonicalItem.contains( item ) ) continue;
 | 
			
		||||
 | 
			
		||||
                trackedItems.add( item );
 | 
			
		||||
                inputs[pos] = new String[] { item.getRegistryName().toString() };
 | 
			
		||||
                inputs[pos] = new String[] { ForgeRegistries.ITEMS.getKey( item ).toString() };
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +52,7 @@ public class JsonDump
 | 
			
		||||
            {
 | 
			
		||||
                Item item = items[i].getItem();
 | 
			
		||||
                trackedItems.add( item );
 | 
			
		||||
                itemIds[i] = item.getRegistryName().toString();
 | 
			
		||||
                itemIds[i] = ForgeRegistries.ITEMS.getKey( item ).toString();
 | 
			
		||||
            }
 | 
			
		||||
            Arrays.sort( itemIds );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,10 +10,12 @@ import net.minecraft.gametest.framework.GameTestAssertException
 | 
			
		||||
import net.minecraft.gametest.framework.GameTestAssertPosException
 | 
			
		||||
import net.minecraft.gametest.framework.GameTestHelper
 | 
			
		||||
import net.minecraft.gametest.framework.GameTestSequence
 | 
			
		||||
import net.minecraft.resources.ResourceLocation
 | 
			
		||||
import net.minecraft.world.entity.decoration.ArmorStand
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntity
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntityType
 | 
			
		||||
import net.minecraft.world.level.block.state.BlockState
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries
 | 
			
		||||
import java.nio.file.Files
 | 
			
		||||
import java.util.concurrent.CompletableFuture
 | 
			
		||||
import java.util.concurrent.ExecutionException
 | 
			
		||||
@@ -135,12 +137,14 @@ fun GameTestHelper.sequence(run: GameTestSequence.() -> GameTestSequence) {
 | 
			
		||||
    run(startSequence()).thenSucceed()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private fun getName(type: BlockEntityType<*>): ResourceLocation = ForgeRegistries.BLOCK_ENTITIES.getKey(type)!!
 | 
			
		||||
 | 
			
		||||
fun <T : BlockEntity> GameTestHelper.getBlockEntity(pos: BlockPos, type: BlockEntityType<T>): T {
 | 
			
		||||
    val tile = getBlockEntity(pos)
 | 
			
		||||
    @Suppress("UNCHECKED_CAST")
 | 
			
		||||
    return when {
 | 
			
		||||
        tile == null -> throw GameTestAssertPosException("Expected ${type.registryName}, but no tile was there", absolutePos(pos), pos, 0)
 | 
			
		||||
        tile.type != type -> throw GameTestAssertPosException("Expected ${type.registryName} but got ${tile.type.registryName}", absolutePos(pos), pos, 0)
 | 
			
		||||
        tile == null -> throw GameTestAssertPosException("Expected ${getName(type)}, but no tile was there", absolutePos(pos), pos, 0)
 | 
			
		||||
        tile.type != type -> throw GameTestAssertPosException("Expected ${getName(type)} but got ${getName(tile.type)}", absolutePos(pos), pos, 0)
 | 
			
		||||
        else -> tile as T
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ import net.minecraft.gametest.framework.StructureUtils;
 | 
			
		||||
import net.minecraft.gametest.framework.TestCommand;
 | 
			
		||||
import net.minecraft.gametest.framework.TestFunction;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.network.chat.TextComponent;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.level.ServerPlayer;
 | 
			
		||||
import net.minecraft.world.entity.Entity;
 | 
			
		||||
@@ -88,7 +88,7 @@ class CCTestCommand
 | 
			
		||||
                ArmorStand armorStand = EntityType.ARMOR_STAND.create( player.getLevel() );
 | 
			
		||||
                armorStand.readAdditionalSaveData( nbt );
 | 
			
		||||
                armorStand.copyPosition( player );
 | 
			
		||||
                armorStand.setCustomName( new TextComponent( info.getTestName() ) );
 | 
			
		||||
                armorStand.setCustomName( Component.literal( info.getTestName() ) );
 | 
			
		||||
                player.getLevel().addFreshEntity( armorStand );
 | 
			
		||||
                return 0;
 | 
			
		||||
            } ) )
 | 
			
		||||
@@ -137,7 +137,7 @@ class CCTestCommand
 | 
			
		||||
 | 
			
		||||
    private static int error( CommandSourceStack source, String message )
 | 
			
		||||
    {
 | 
			
		||||
        source.sendFailure( new TextComponent( message ).withStyle( ChatFormatting.RED ) );
 | 
			
		||||
        source.sendFailure( Component.literal( message ).withStyle( ChatFormatting.RED ) );
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,20 +10,6 @@ import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.ParticleStatus;
 | 
			
		||||
import net.minecraft.client.gui.screens.TitleScreen;
 | 
			
		||||
import net.minecraft.client.tutorial.TutorialSteps;
 | 
			
		||||
import net.minecraft.core.Registry;
 | 
			
		||||
import net.minecraft.core.RegistryAccess;
 | 
			
		||||
import net.minecraft.world.Difficulty;
 | 
			
		||||
import net.minecraft.world.level.DataPackConfig;
 | 
			
		||||
import net.minecraft.world.level.GameRules;
 | 
			
		||||
import net.minecraft.world.level.GameType;
 | 
			
		||||
import net.minecraft.world.level.LevelSettings;
 | 
			
		||||
import net.minecraft.world.level.biome.Biomes;
 | 
			
		||||
import net.minecraft.world.level.block.Blocks;
 | 
			
		||||
import net.minecraft.world.level.dimension.DimensionType;
 | 
			
		||||
import net.minecraft.world.level.levelgen.FlatLevelSource;
 | 
			
		||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
 | 
			
		||||
import net.minecraft.world.level.levelgen.flat.FlatLayerInfo;
 | 
			
		||||
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.client.event.ScreenEvent;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
@@ -31,11 +17,6 @@ import net.minecraftforge.fml.common.Mod;
 | 
			
		||||
import org.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
import static net.minecraft.world.level.levelgen.WorldGenSettings.withOverworld;
 | 
			
		||||
 | 
			
		||||
@Mod.EventBusSubscriber( modid = TestMod.MOD_ID, value = Dist.CLIENT )
 | 
			
		||||
public final class ClientHooks
 | 
			
		||||
{
 | 
			
		||||
@@ -61,13 +42,14 @@ public final class ClientHooks
 | 
			
		||||
        Minecraft minecraft = Minecraft.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Clear some options before we get any further.
 | 
			
		||||
        minecraft.options.autoJump = false;
 | 
			
		||||
        minecraft.options.renderClouds = CloudStatus.OFF;
 | 
			
		||||
        minecraft.options.particles = ParticleStatus.MINIMAL;
 | 
			
		||||
        minecraft.options.autoJump().set( false );
 | 
			
		||||
        minecraft.options.cloudStatus().set( CloudStatus.OFF );
 | 
			
		||||
        minecraft.options.particles().set( ParticleStatus.MINIMAL );
 | 
			
		||||
        minecraft.options.tutorialStep = TutorialSteps.NONE;
 | 
			
		||||
        minecraft.options.renderDistance = 6;
 | 
			
		||||
        minecraft.options.gamma = 1.0;
 | 
			
		||||
        minecraft.options.renderDistance().set( 6 );
 | 
			
		||||
        minecraft.options.gamma().set( 1.0 );
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        if( minecraft.getLevelSource().levelExists( "test" ) )
 | 
			
		||||
        {
 | 
			
		||||
            LOG.info( "World exists, loading it" );
 | 
			
		||||
@@ -102,5 +84,6 @@ public final class ClientHooks
 | 
			
		||||
            );
 | 
			
		||||
            Minecraft.getInstance().createLevel( "test", settings, registries, generator );
 | 
			
		||||
        }
 | 
			
		||||
        */
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user