mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-11-03 23:22:59 +00:00 
			
		
		
		
	Update to Minecraft 1.19
Oh my, a same day release! Well, if we use the AoE timezone. Entirely untested (well, aside from automated tests), I haven't even launched a client. In my defence, its just past midnight and I've been up since 4am.
This commit is contained in:
		@@ -122,7 +122,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/main/resources/META-INF/accesstransformer.cfg')
 | 
				
			||||||
    accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
 | 
					    accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
 | 
				
			||||||
@@ -158,9 +159,10 @@ dependencies {
 | 
				
			|||||||
    annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
 | 
					    annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    compileOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116:api")
 | 
					    compileOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116:api")
 | 
				
			||||||
    runtimeOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116")
 | 
					    // runtimeOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shade 'org.squiddev:Cobalt:0.5.5'
 | 
					    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-api:5.7.0'
 | 
				
			||||||
    testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
 | 
					    testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
 | 
				
			||||||
@@ -219,6 +221,8 @@ jar {
 | 
				
			|||||||
        ])
 | 
					        ])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    duplicatesStrategy(DuplicatesStrategy.WARN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
 | 
					    from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx3G
 | 
				
			|||||||
mod_version=1.100.5
 | 
					mod_version=1.100.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Minecraft properties (update mods.toml when changing)
 | 
					# Minecraft properties (update mods.toml when changing)
 | 
				
			||||||
mc_version=1.18.2
 | 
					mc_version=1.19
 | 
				
			||||||
mapping_version=2022.03.13
 | 
					mapping_version=2022.03.13
 | 
				
			||||||
forge_version=40.1.0
 | 
					forge_version=41.0.1
 | 
				
			||||||
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING
 | 
					# 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 )
 | 
					    public static InputStream getResourceFile( String domain, String subPath )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        var manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
 | 
					        var manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
 | 
				
			||||||
 | 
					        var resource = manager.getResource( new ResourceLocation( domain, subPath ) ).orElse( null );
 | 
				
			||||||
 | 
					        if( resource == null ) return null;
 | 
				
			||||||
        try
 | 
					        try
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
 | 
					            return resource.open();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch( IOException ignored )
 | 
					        catch( IOException ignored )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,6 @@ public abstract class PocketUpgradeDataProvider extends UpgradeDataProvider<IPoc
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public PocketUpgradeDataProvider( @Nonnull DataGenerator generator )
 | 
					    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.ItemStack;
 | 
				
			||||||
import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
 | 
					import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
 | 
				
			||||||
import net.minecraftforge.registries.DeferredRegister;
 | 
					import net.minecraftforge.registries.DeferredRegister;
 | 
				
			||||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
					import net.minecraftforge.registries.IForgeRegistry;
 | 
				
			||||||
import net.minecraftforge.registries.RegistryManager;
 | 
					import net.minecraftforge.registries.RegistryManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					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
 | 
					     * This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
 | 
				
			||||||
     * {@link RegistryManager#getRegistry(ResourceKey)}.
 | 
					     * {@link RegistryManager#getRegistry(ResourceKey)}.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see #registry()
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    ResourceKey<Registry<PocketUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_upgrade_serialiser" ) );
 | 
					    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}.
 | 
					     * The associated registry.
 | 
				
			||||||
     *
 | 
					     * @return The registry for pocket upgrade serialisers.
 | 
				
			||||||
     * @param <T> The type of the upgrade created by this serialiser.
 | 
					     * @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.item.Item;
 | 
				
			||||||
import net.minecraft.world.level.block.Block;
 | 
					import net.minecraft.world.level.block.Block;
 | 
				
			||||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
 | 
					import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.function.Consumer;
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
@@ -34,7 +35,7 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITur
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public TurtleUpgradeDataProvider( DataGenerator generator )
 | 
					    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 )
 | 
					        public void add( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> add )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            add.accept( new Upgrade<>( id, serialiser, s -> {
 | 
					            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( 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( damageMultiplier != null ) s.addProperty( "damageMultiplier", damageMultiplier );
 | 
				
			||||||
                if( breakable != null ) s.addProperty( "breakable", breakable.location().toString() );
 | 
					                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.RecipeSerializer;
 | 
				
			||||||
import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
 | 
					import net.minecraft.world.item.crafting.SimpleRecipeSerializer;
 | 
				
			||||||
import net.minecraftforge.registries.DeferredRegister;
 | 
					import net.minecraftforge.registries.DeferredRegister;
 | 
				
			||||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
					 | 
				
			||||||
import net.minecraftforge.registries.IForgeRegistry;
 | 
					import net.minecraftforge.registries.IForgeRegistry;
 | 
				
			||||||
import net.minecraftforge.registries.RegistryManager;
 | 
					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
 | 
					     * This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
 | 
				
			||||||
     * {@link RegistryManager#getRegistry(ResourceKey)}.
 | 
					     * {@link RegistryManager#getRegistry(ResourceKey)}.
 | 
				
			||||||
 | 
					     * @see #registry()
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    ResourceKey<Registry<TurtleUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade_serialiser" ) );
 | 
					    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}.
 | 
					     * The associated registry.
 | 
				
			||||||
     *
 | 
					     * @return The registry for pocket upgrade serialisers.
 | 
				
			||||||
     * @param <T> The type of the upgrade created by this serialiser.
 | 
					     * @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.api.turtle.TurtleUpgradeSerialiser;
 | 
				
			||||||
import dan200.computercraft.internal.upgrades.SerialiserWithCraftingItem;
 | 
					import dan200.computercraft.internal.upgrades.SerialiserWithCraftingItem;
 | 
				
			||||||
import dan200.computercraft.internal.upgrades.SimpleSerialiser;
 | 
					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.DataGenerator;
 | 
				
			||||||
import net.minecraft.data.DataProvider;
 | 
					import net.minecraft.data.DataProvider;
 | 
				
			||||||
import net.minecraft.data.HashCache;
 | 
					 | 
				
			||||||
import net.minecraft.resources.ResourceKey;
 | 
					 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.world.item.Item;
 | 
					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.LogManager;
 | 
				
			||||||
import org.apache.logging.log4j.Logger;
 | 
					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 DataGenerator generator;
 | 
				
			||||||
    private final String name;
 | 
					    private final String name;
 | 
				
			||||||
    private final String folder;
 | 
					    private final String folder;
 | 
				
			||||||
    private final ResourceKey<Registry<R>> registry;
 | 
					    private final IForgeRegistry<R> registry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private List<T> upgrades;
 | 
					    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.generator = generator;
 | 
				
			||||||
        this.name = name;
 | 
					        this.name = name;
 | 
				
			||||||
@@ -92,7 +91,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new Upgrade<>( id, serialiser, s ->
 | 
					        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 );
 | 
					    protected abstract void addUpgrades( @Nonnull Consumer<Upgrade<R>> addUpgrade );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @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" );
 | 
					        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() );
 | 
					            if( !seen.add( upgrade.id() ) ) throw new IllegalStateException( "Duplicate upgrade " + upgrade.id() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var json = new JsonObject();
 | 
					            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 );
 | 
					            upgrade.serialise().accept( json );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try
 | 
					            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 )
 | 
					            catch( IOException e )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -157,7 +156,7 @@ public abstract class UpgradeDataProvider<T extends IUpgradeBase, R extends Upgr
 | 
				
			|||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    public final R existingSerialiser( @Nonnull ResourceLocation id )
 | 
					    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 );
 | 
					        if( result == null ) throw new IllegalArgumentException( "No such serialiser " + registry );
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
 | 
				
			|||||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
 | 
					import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
 | 
				
			||||||
import net.minecraft.network.FriendlyByteBuf;
 | 
					import net.minecraft.network.FriendlyByteBuf;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,7 +24,7 @@ import javax.annotation.Nonnull;
 | 
				
			|||||||
 * @see TurtleUpgradeSerialiser
 | 
					 * @see TurtleUpgradeSerialiser
 | 
				
			||||||
 * @see PocketUpgradeSerialiser
 | 
					 * @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.
 | 
					     * 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 dan200.computercraft.shared.network.server.UploadFileMessage;
 | 
				
			||||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
 | 
					import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
					 | 
				
			||||||
import net.minecraft.world.entity.player.Inventory;
 | 
					import net.minecraft.world.entity.player.Inventory;
 | 
				
			||||||
import org.lwjgl.glfw.GLFW;
 | 
					import org.lwjgl.glfw.GLFW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,9 +36,9 @@ import java.util.List;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public abstract class ComputerScreenBase<T extends ContainerComputerBase> extends AbstractContainerScreen<T>
 | 
					public abstract class ComputerScreenBase<T extends ContainerComputerBase> extends AbstractContainerScreen<T>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private static final Component OK = new TranslatableComponent( "gui.ok" );
 | 
					    private static final Component OK = Component.translatable( "gui.ok" );
 | 
				
			||||||
    private static final Component CANCEL = new TranslatableComponent( "gui.cancel" );
 | 
					    private static final Component CANCEL = Component.translatable( "gui.cancel" );
 | 
				
			||||||
    private static final Component OVERWRITE = new TranslatableComponent( "gui.computercraft.upload.overwrite_button" );
 | 
					    private static final Component OVERWRITE = Component.translatable( "gui.computercraft.upload.overwrite_button" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected WidgetTerminal terminal;
 | 
					    protected WidgetTerminal terminal;
 | 
				
			||||||
    protected final ClientComputer computer;
 | 
					    protected final ClientComputer computer;
 | 
				
			||||||
@@ -158,7 +157,7 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
 | 
				
			|||||||
                String name = file.getFileName().toString();
 | 
					                String name = file.getFileName().toString();
 | 
				
			||||||
                if( name.length() > UploadFileMessage.MAX_FILE_NAME )
 | 
					                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;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -169,7 +168,7 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
 | 
				
			|||||||
                byte[] digest = FileUpload.getDigest( buffer );
 | 
					                byte[] digest = FileUpload.getDigest( buffer );
 | 
				
			||||||
                if( digest == null )
 | 
					                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;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -178,13 +177,13 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
 | 
				
			|||||||
            catch( IOException e )
 | 
					            catch( IOException e )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ComputerCraft.log.error( "Failed uploading files", 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 )
 | 
					        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;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ import net.minecraft.client.gui.Font;
 | 
				
			|||||||
import net.minecraft.client.gui.screens.Screen;
 | 
					import net.minecraft.client.gui.screens.Screen;
 | 
				
			||||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
 | 
					import net.minecraft.client.gui.screens.inventory.MenuAccess;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
					 | 
				
			||||||
import net.minecraft.util.FormattedCharSequence;
 | 
					import net.minecraft.util.FormattedCharSequence;
 | 
				
			||||||
import net.minecraft.world.entity.player.Inventory;
 | 
					import net.minecraft.world.entity.player.Inventory;
 | 
				
			||||||
import org.lwjgl.glfw.GLFW;
 | 
					import org.lwjgl.glfw.GLFW;
 | 
				
			||||||
@@ -112,7 +111,7 @@ public class NoTermComputerScreen<T extends ContainerComputerBase> extends Scree
 | 
				
			|||||||
        super.render( transform, mouseX, mouseY, partialTicks );
 | 
					        super.render( transform, mouseX, mouseY, partialTicks );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Font font = minecraft.font;
 | 
					        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;
 | 
					        float y = 10.0f;
 | 
				
			||||||
        for( FormattedCharSequence line : lines )
 | 
					        for( FormattedCharSequence line : lines )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ import dan200.computercraft.shared.computer.core.ClientComputer;
 | 
				
			|||||||
import net.minecraft.ChatFormatting;
 | 
					import net.minecraft.ChatFormatting;
 | 
				
			||||||
import net.minecraft.client.gui.components.AbstractWidget;
 | 
					import net.minecraft.client.gui.components.AbstractWidget;
 | 
				
			||||||
import net.minecraft.client.gui.screens.Screen;
 | 
					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 net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Arrays;
 | 
					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,
 | 
					            screen, x, y, ICON_WIDTH, ICON_HEIGHT, () -> computer.isOn() ? 15 : 1, 1, ICON_TEX_Y_DIFF,
 | 
				
			||||||
            TEXTURE, TEX_SIZE, TEX_SIZE, b -> toggleComputer( computer ),
 | 
					            TEXTURE, TEX_SIZE, TEX_SIZE, b -> toggleComputer( computer ),
 | 
				
			||||||
            () -> computer.isOn() ? Arrays.asList(
 | 
					            () -> computer.isOn() ? Arrays.asList(
 | 
				
			||||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_off" ),
 | 
					                Component.translatable( "gui.computercraft.tooltip.turn_off" ),
 | 
				
			||||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY )
 | 
					                Component.translatable( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY )
 | 
				
			||||||
            ) : Arrays.asList(
 | 
					            ) : Arrays.asList(
 | 
				
			||||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_on" ),
 | 
					                Component.translatable( "gui.computercraft.tooltip.turn_on" ),
 | 
				
			||||||
                new TranslatableComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( ChatFormatting.GRAY )
 | 
					                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,
 | 
					            screen, x, y, ICON_WIDTH, ICON_HEIGHT, 29, 1, ICON_TEX_Y_DIFF,
 | 
				
			||||||
            TEXTURE, TEX_SIZE, TEX_SIZE, b -> computer.queueEvent( "terminate" ),
 | 
					            TEXTURE, TEX_SIZE, TEX_SIZE, b -> computer.queueEvent( "terminate" ),
 | 
				
			||||||
            Arrays.asList(
 | 
					            Arrays.asList(
 | 
				
			||||||
                new TranslatableComponent( "gui.computercraft.tooltip.terminate" ),
 | 
					                Component.translatable( "gui.computercraft.tooltip.terminate" ),
 | 
				
			||||||
                new TranslatableComponent( "gui.computercraft.tooltip.terminate.key" ).withStyle( ChatFormatting.GRAY )
 | 
					                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.components.Button;
 | 
				
			||||||
import net.minecraft.client.gui.screens.Screen;
 | 
					import net.minecraft.client.gui.screens.Screen;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraftforge.common.util.NonNullSupplier;
 | 
					import net.minecraftforge.common.util.NonNullSupplier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,7 +52,7 @@ public class DynamicImageButton extends Button
 | 
				
			|||||||
        OnPress onPress, NonNullSupplier<List<Component>> tooltip
 | 
					        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.screen = screen;
 | 
				
			||||||
        this.textureWidth = textureWidth;
 | 
					        this.textureWidth = textureWidth;
 | 
				
			||||||
        this.textureHeight = textureHeight;
 | 
					        this.textureHeight = textureHeight;
 | 
				
			||||||
@@ -84,7 +83,7 @@ public class DynamicImageButton extends Button
 | 
				
			|||||||
    public Component getMessage()
 | 
					    public Component getMessage()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        List<Component> tooltip = this.tooltip.get();
 | 
					        List<Component> tooltip = this.tooltip.get();
 | 
				
			||||||
        return tooltip.isEmpty() ? TextComponent.EMPTY : tooltip.get( 0 );
 | 
					        return tooltip.isEmpty() ? Component.empty() : tooltip.get( 0 );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ import net.minecraft.client.Minecraft;
 | 
				
			|||||||
import net.minecraft.client.gui.components.AbstractWidget;
 | 
					import net.minecraft.client.gui.components.AbstractWidget;
 | 
				
			||||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
 | 
					import net.minecraft.client.gui.narration.NarrationElementOutput;
 | 
				
			||||||
import net.minecraft.client.renderer.MultiBufferSource;
 | 
					import net.minecraft.client.renderer.MultiBufferSource;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import org.lwjgl.glfw.GLFW;
 | 
					import org.lwjgl.glfw.GLFW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					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 )
 | 
					    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;
 | 
					        this.computer = computer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,7 +74,7 @@ public abstract class ItemMapLikeRenderer
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            transform.pushPose();
 | 
					            transform.pushPose();
 | 
				
			||||||
            transform.mulPose( Vector3f.ZP.rotationDegrees( offset * 10f ) );
 | 
					            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();
 | 
					            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 )
 | 
					    private void renderItemFirstPersonCenter( PoseStack transform, MultiBufferSource render, int combinedLight, float pitch, float equipProgress, float swingProgress, ItemStack stack )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Minecraft minecraft = Minecraft.getInstance();
 | 
					        Minecraft minecraft = Minecraft.getInstance();
 | 
				
			||||||
        ItemInHandRenderer renderer = minecraft.getItemInHandRenderer();
 | 
					        ItemInHandRenderer renderer = minecraft.getEntityRenderDispatcher().getItemInHandRenderer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Setup the appropriate transformations. This is just copied from the
 | 
					        // Setup the appropriate transformations. This is just copied from the
 | 
				
			||||||
        // corresponding method in ItemRenderer.
 | 
					        // 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.client.resources.model.ModelResourceLocation;
 | 
				
			||||||
import net.minecraft.core.Direction;
 | 
					import net.minecraft.core.Direction;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
 | 
					import net.minecraft.util.RandomSource;
 | 
				
			||||||
import net.minecraft.world.phys.BlockHitResult;
 | 
					import net.minecraft.world.phys.BlockHitResult;
 | 
				
			||||||
import net.minecraft.world.phys.HitResult;
 | 
					import net.minecraft.world.phys.HitResult;
 | 
				
			||||||
import net.minecraft.world.phys.Vec3;
 | 
					import net.minecraft.world.phys.Vec3;
 | 
				
			||||||
@@ -37,7 +38,6 @@ import net.minecraftforge.client.model.data.EmptyModelData;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Random;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class TileEntityTurtleRenderer implements BlockEntityRenderer<TileTurtle>
 | 
					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 COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_colour", "inventory" );
 | 
				
			||||||
    private static final ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "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;
 | 
					    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.renderer.texture.TextureAtlasSprite;
 | 
				
			||||||
import net.minecraft.client.resources.model.BakedModel;
 | 
					import net.minecraft.client.resources.model.BakedModel;
 | 
				
			||||||
import net.minecraft.core.Direction;
 | 
					import net.minecraft.core.Direction;
 | 
				
			||||||
 | 
					import net.minecraft.util.RandomSource;
 | 
				
			||||||
import net.minecraft.world.level.block.state.BlockState;
 | 
					import net.minecraft.world.level.block.state.BlockState;
 | 
				
			||||||
import net.minecraftforge.client.model.data.EmptyModelData;
 | 
					import net.minecraftforge.client.model.data.EmptyModelData;
 | 
				
			||||||
import net.minecraftforge.client.model.data.IModelData;
 | 
					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 net.minecraftforge.client.model.pipeline.TRSRTransformer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					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
 | 
					public class TurtleMultiModel implements BakedModel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -44,14 +48,14 @@ public class TurtleMultiModel implements BakedModel
 | 
				
			|||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    @Deprecated
 | 
					    @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 );
 | 
					        return getQuads( state, side, rand, EmptyModelData.INSTANCE );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    @Override
 | 
					    @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 )
 | 
					        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<>();
 | 
					        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.client.resources.model.ModelResourceLocation;
 | 
				
			||||||
import net.minecraft.core.Direction;
 | 
					import net.minecraft.core.Direction;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
 | 
					import net.minecraft.util.RandomSource;
 | 
				
			||||||
import net.minecraft.world.entity.LivingEntity;
 | 
					import net.minecraft.world.entity.LivingEntity;
 | 
				
			||||||
import net.minecraft.world.item.ItemStack;
 | 
					import net.minecraft.world.item.ItemStack;
 | 
				
			||||||
import net.minecraft.world.level.block.state.BlockState;
 | 
					import net.minecraft.world.level.block.state.BlockState;
 | 
				
			||||||
@@ -33,7 +34,6 @@ import javax.annotation.Nonnull;
 | 
				
			|||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Random;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class TurtleSmartItemModel implements BakedModel
 | 
					public class TurtleSmartItemModel implements BakedModel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -118,7 +118,7 @@ public class TurtleSmartItemModel implements BakedModel
 | 
				
			|||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    @Deprecated
 | 
					    @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 );
 | 
					        return familyModel.getQuads( state, facing, rand );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -126,7 +126,7 @@ public class TurtleSmartItemModel implements BakedModel
 | 
				
			|||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    @Deprecated
 | 
					    @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 );
 | 
					        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 dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
 | 
				
			||||||
import net.minecraft.client.resources.sounds.AbstractSoundInstance;
 | 
					import net.minecraft.client.resources.sounds.AbstractSoundInstance;
 | 
				
			||||||
import net.minecraft.client.resources.sounds.Sound;
 | 
					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.resources.sounds.TickableSoundInstance;
 | 
				
			||||||
import net.minecraft.client.sounds.AudioStream;
 | 
					import net.minecraft.client.sounds.AudioStream;
 | 
				
			||||||
import net.minecraft.client.sounds.SoundBufferLibrary;
 | 
					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 )
 | 
					    SpeakerSound( ResourceLocation sound, DfpwmStream stream, SpeakerPosition position, float volume, float pitch )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        super( sound, SoundSource.RECORDS );
 | 
					        super( sound, SoundSource.RECORDS, SoundInstance.createUnseededRandom() );
 | 
				
			||||||
        setPosition( position );
 | 
					        setPosition( position );
 | 
				
			||||||
        this.stream = stream;
 | 
					        this.stream = stream;
 | 
				
			||||||
        this.volume = volume;
 | 
					        this.volume = volume;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ import com.mojang.blaze3d.vertex.VertexFormat;
 | 
				
			|||||||
import com.mojang.math.Matrix4f;
 | 
					import com.mojang.math.Matrix4f;
 | 
				
			||||||
import net.minecraft.client.renderer.ShaderInstance;
 | 
					import net.minecraft.client.renderer.ShaderInstance;
 | 
				
			||||||
import org.lwjgl.opengl.GL15;
 | 
					import org.lwjgl.opengl.GL15;
 | 
				
			||||||
 | 
					import org.lwjgl.opengl.GL15C;
 | 
				
			||||||
import org.lwjgl.opengl.GL45C;
 | 
					import org.lwjgl.opengl.GL45C;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.nio.ByteBuffer;
 | 
					import java.nio.ByteBuffer;
 | 
				
			||||||
@@ -29,23 +30,38 @@ public class DirectVertexBuffer extends VertexBuffer
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        if( DirectBuffers.HAS_DSA )
 | 
					        if( DirectBuffers.HAS_DSA )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            RenderSystem.glDeleteBuffers( vertextBufferId );
 | 
					            RenderSystem.glDeleteBuffers( vertexBufferId );
 | 
				
			||||||
            if( DirectBuffers.ON_LINUX ) BufferUploader.reset(); // See comment on DirectBuffers.deleteBuffer.
 | 
					            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 )
 | 
					    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;
 | 
					        this.mode = mode;
 | 
				
			||||||
        actualIndexCount = indexCount = mode.indexCount( vertexCount );
 | 
					        actualIndexCount = indexCount = mode.indexCount( vertexCount );
 | 
				
			||||||
        indexType = VertexFormat.IndexType.SHORT;
 | 
					        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 )
 | 
					    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 dan200.computercraft.shared.util.IoUtil;
 | 
				
			||||||
import net.minecraft.ResourceLocationException;
 | 
					import net.minecraft.ResourceLocationException;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					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.Resource;
 | 
				
			||||||
import net.minecraft.server.packs.resources.ResourceManager;
 | 
					import net.minecraft.server.packs.resources.ResourceManager;
 | 
				
			||||||
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
 | 
					import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
 | 
				
			||||||
@@ -22,7 +21,6 @@ import net.minecraft.util.profiling.ProfilerFiller;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
import java.io.FileNotFoundException;
 | 
					 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.io.InputStream;
 | 
					import java.io.InputStream;
 | 
				
			||||||
import java.nio.channels.Channels;
 | 
					import java.nio.channels.Channels;
 | 
				
			||||||
@@ -94,7 +92,7 @@ public final class ResourceMount implements IMount
 | 
				
			|||||||
        String existingNamespace = null;
 | 
					        String existingNamespace = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        FileEntry newRoot = new FileEntry( new ResourceLocation( namespace, subPath ) );
 | 
					        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();
 | 
					            existingNamespace = file.getNamespace();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -202,10 +200,11 @@ public final class ResourceMount implements IMount
 | 
				
			|||||||
            byte[] contents = CONTENTS_CACHE.getIfPresent( file );
 | 
					            byte[] contents = CONTENTS_CACHE.getIfPresent( file );
 | 
				
			||||||
            if( contents != null ) return file.size = contents.length;
 | 
					            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;
 | 
					                int total = 0, read = 0;
 | 
				
			||||||
                do
 | 
					                do
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -234,9 +233,10 @@ public final class ResourceMount implements IMount
 | 
				
			|||||||
            byte[] contents = CONTENTS_CACHE.getIfPresent( file );
 | 
					            byte[] contents = CONTENTS_CACHE.getIfPresent( file );
 | 
				
			||||||
            if( contents != null ) return new ArrayByteChannel( contents );
 | 
					            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 );
 | 
					                if( stream.available() > MAX_CACHED_SIZE ) return Channels.newChannel( stream );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
@@ -251,9 +251,6 @@ public final class ResourceMount implements IMount
 | 
				
			|||||||
                CONTENTS_CACHE.put( file, contents );
 | 
					                CONTENTS_CACHE.put( file, contents );
 | 
				
			||||||
                return new ArrayByteChannel( contents );
 | 
					                return new ArrayByteChannel( contents );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch( FileNotFoundException ignored )
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        throw new IOException( "/" + path + ": No such file" );
 | 
					        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.core.Direction;
 | 
				
			||||||
import net.minecraft.data.DataGenerator;
 | 
					import net.minecraft.data.DataGenerator;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
 | 
					import net.minecraft.world.item.Item;
 | 
				
			||||||
import net.minecraft.world.level.block.Block;
 | 
					import net.minecraft.world.level.block.Block;
 | 
				
			||||||
import net.minecraftforge.client.model.generators.*;
 | 
					import net.minecraftforge.client.model.generators.*;
 | 
				
			||||||
import net.minecraftforge.common.data.ExistingFileHelper;
 | 
					import net.minecraftforge.common.data.ExistingFileHelper;
 | 
				
			||||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.Objects;
 | 
					import java.util.Objects;
 | 
				
			||||||
@@ -206,7 +207,7 @@ class BlockModelProvider extends BlockStateProvider
 | 
				
			|||||||
        for( MonitorEdgeState edge : BlockMonitor.STATE.getPossibleValues() )
 | 
					        for( MonitorEdgeState edge : BlockMonitor.STATE.getPossibleValues() )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            String suffix = edge == MonitorEdgeState.NONE ? "" : "_" + edge.getSerializedName();
 | 
					            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() )
 | 
					            for( Direction facing : BlockMonitor.FACING.getPossibleValues() )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -260,20 +261,26 @@ class BlockModelProvider extends BlockStateProvider
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private static ResourceLocation blockTexture( Block block, String suffix )
 | 
					    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 );
 | 
					        return new ResourceLocation( id.getNamespace(), "block/" + id.getPath() + suffix );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @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
 | 
					    @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
 | 
					    @Nonnull
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,15 +25,15 @@ public class Generators
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        var turtleUpgrades = new TurtleUpgradeGenerator( generator );
 | 
					        var turtleUpgrades = new TurtleUpgradeGenerator( generator );
 | 
				
			||||||
        var pocketUpgrades = new PocketUpgradeGenerator( generator );
 | 
					        var pocketUpgrades = new PocketUpgradeGenerator( generator );
 | 
				
			||||||
        generator.addProvider( turtleUpgrades );
 | 
					        generator.addProvider( event.includeServer(), turtleUpgrades );
 | 
				
			||||||
        generator.addProvider( pocketUpgrades );
 | 
					        generator.addProvider( event.includeServer(), pocketUpgrades );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        generator.addProvider( new RecipeGenerator( generator, turtleUpgrades, pocketUpgrades ) );
 | 
					        generator.addProvider( event.includeServer(), new RecipeGenerator( generator, turtleUpgrades, pocketUpgrades ) );
 | 
				
			||||||
        generator.addProvider( new LootTableGenerator( generator ) );
 | 
					        generator.addProvider( event.includeServer(), new LootTableGenerator( generator ) );
 | 
				
			||||||
        generator.addProvider( new BlockModelProvider( generator, existingFiles ) );
 | 
					        generator.addProvider( event.includeClient(), new BlockModelProvider( generator, existingFiles ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        BlockTagsGenerator blockTags = new BlockTagsGenerator( generator, existingFiles );
 | 
					        BlockTagsGenerator blockTags = new BlockTagsGenerator( generator, existingFiles );
 | 
				
			||||||
        generator.addProvider( blockTags );
 | 
					        generator.addProvider( event.includeServer(), blockTags );
 | 
				
			||||||
        generator.addProvider( new ItemTagsGenerator( generator, blockTags, existingFiles ) );
 | 
					        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.Gson;
 | 
				
			||||||
import com.google.gson.GsonBuilder;
 | 
					import com.google.gson.GsonBuilder;
 | 
				
			||||||
import dan200.computercraft.ComputerCraft;
 | 
					import dan200.computercraft.ComputerCraft;
 | 
				
			||||||
 | 
					import net.minecraft.data.CachedOutput;
 | 
				
			||||||
import net.minecraft.data.DataGenerator;
 | 
					import net.minecraft.data.DataGenerator;
 | 
				
			||||||
import net.minecraft.data.DataProvider;
 | 
					import net.minecraft.data.DataProvider;
 | 
				
			||||||
import net.minecraft.data.HashCache;
 | 
					 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.world.level.storage.loot.LootTable;
 | 
					import net.minecraft.world.level.storage.loot.LootTable;
 | 
				
			||||||
import net.minecraft.world.level.storage.loot.LootTables;
 | 
					import net.minecraft.world.level.storage.loot.LootTables;
 | 
				
			||||||
@@ -40,7 +40,7 @@ abstract class LootTableProvider implements DataProvider
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void run( @Nonnull HashCache cache )
 | 
					    public void run( @Nonnull CachedOutput cache )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Map<ResourceLocation, LootTable> tables = new HashMap<>();
 | 
					        Map<ResourceLocation, LootTable> tables = new HashMap<>();
 | 
				
			||||||
        ValidationContext validation = new ValidationContext( LootContextParamSets.ALL_PARAMS, x -> null, tables::get );
 | 
					        ValidationContext validation = new ValidationContext( LootContextParamSets.ALL_PARAMS, x -> null, tables::get );
 | 
				
			||||||
@@ -64,7 +64,7 @@ abstract class LootTableProvider implements DataProvider
 | 
				
			|||||||
            Path path = getPath( key );
 | 
					            Path path = getPath( key );
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                DataProvider.save( GSON, cache, LootTables.serialize( value ), path );
 | 
					                DataProvider.saveStable( cache, LootTables.serialize( value ), path );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch( IOException e )
 | 
					            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.ItemLike;
 | 
				
			||||||
import net.minecraft.world.level.block.Blocks;
 | 
					import net.minecraft.world.level.block.Blocks;
 | 
				
			||||||
import net.minecraftforge.common.Tags;
 | 
					import net.minecraftforge.common.Tags;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.Locale;
 | 
					import java.util.Locale;
 | 
				
			||||||
@@ -393,6 +394,6 @@ class RecipeGenerator extends RecipeProvider
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private static void addSpecial( Consumer<FinishedRecipe> add, SimpleRecipeSerializer<?> special )
 | 
					    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.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.util.GsonHelper;
 | 
					import net.minecraft.util.GsonHelper;
 | 
				
			||||||
import net.minecraft.world.item.ItemStack;
 | 
					import net.minecraft.world.item.ItemStack;
 | 
				
			||||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.function.BiFunction;
 | 
					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 <R> The serialiser for this upgrade category, either {@code TurtleUpgradeSerialiser<?>} or {@code PocketUpgradeSerialiser<?>}.
 | 
				
			||||||
 * @param <T> The upgrade that this class can serialise and deserialise.
 | 
					 * @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;
 | 
					    private final BiFunction<ResourceLocation, ItemStack, T> factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ import dan200.computercraft.api.upgrades.IUpgradeBase;
 | 
				
			|||||||
import dan200.computercraft.api.upgrades.UpgradeSerialiser;
 | 
					import dan200.computercraft.api.upgrades.UpgradeSerialiser;
 | 
				
			||||||
import net.minecraft.network.FriendlyByteBuf;
 | 
					import net.minecraft.network.FriendlyByteBuf;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraftforge.registries.ForgeRegistryEntry;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.function.Function;
 | 
					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 <R> The serialiser for this upgrade category, either {@code TurtleUpgradeSerialiser<?>} or {@code PocketUpgradeSerialiser<?>}.
 | 
				
			||||||
 * @param <T> The upgrade that this class can serialise and deserialise.
 | 
					 * @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;
 | 
					    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.renderer.texture.OverlayTexture;
 | 
				
			||||||
import net.minecraft.client.resources.model.BakedModel;
 | 
					import net.minecraft.client.resources.model.BakedModel;
 | 
				
			||||||
import net.minecraft.core.BlockPos;
 | 
					import net.minecraft.core.BlockPos;
 | 
				
			||||||
 | 
					import net.minecraft.util.RandomSource;
 | 
				
			||||||
import net.minecraft.world.level.BlockAndTintGetter;
 | 
					import net.minecraft.world.level.BlockAndTintGetter;
 | 
				
			||||||
import net.minecraft.world.level.block.state.BlockState;
 | 
					import net.minecraft.world.level.block.state.BlockState;
 | 
				
			||||||
import net.minecraft.world.phys.BlockHitResult;
 | 
					import net.minecraft.world.phys.BlockHitResult;
 | 
				
			||||||
import net.minecraft.world.phys.HitResult;
 | 
					import net.minecraft.world.phys.HitResult;
 | 
				
			||||||
import net.minecraftforge.client.model.data.IModelData;
 | 
					import net.minecraftforge.client.model.data.IModelData;
 | 
				
			||||||
 | 
					import org.spongepowered.asm.mixin.Final;
 | 
				
			||||||
import org.spongepowered.asm.mixin.Mixin;
 | 
					import org.spongepowered.asm.mixin.Mixin;
 | 
				
			||||||
import org.spongepowered.asm.mixin.Shadow;
 | 
					import org.spongepowered.asm.mixin.Shadow;
 | 
				
			||||||
import org.spongepowered.asm.mixin.injection.At;
 | 
					import org.spongepowered.asm.mixin.injection.At;
 | 
				
			||||||
import org.spongepowered.asm.mixin.injection.Inject;
 | 
					import org.spongepowered.asm.mixin.injection.Inject;
 | 
				
			||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 | 
					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.
 | 
					 * 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
 | 
					public class BlockRenderDispatcherMixin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    @Shadow
 | 
					    @Shadow
 | 
				
			||||||
    private final Random random;
 | 
					    @Final
 | 
				
			||||||
    @Shadow
 | 
					    private RandomSource random;
 | 
				
			||||||
    private final BlockModelShaper blockModelShaper;
 | 
					 | 
				
			||||||
    @Shadow
 | 
					 | 
				
			||||||
    private final ModelBlockRenderer modelRenderer;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public BlockRenderDispatcherMixin( Random random, BlockModelShaper blockModelShaper, ModelBlockRenderer modelRenderer )
 | 
					    @Shadow
 | 
				
			||||||
    {
 | 
					    @Final
 | 
				
			||||||
        this.random = random;
 | 
					    private BlockModelShaper blockModelShaper;
 | 
				
			||||||
        this.blockModelShaper = blockModelShaper;
 | 
					
 | 
				
			||||||
        this.modelRenderer = modelRenderer;
 | 
					    @Shadow
 | 
				
			||||||
    }
 | 
					    @Final
 | 
				
			||||||
 | 
					    private ModelBlockRenderer modelRenderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Inject(
 | 
					    @Inject(
 | 
				
			||||||
        method = "name=/^renderBreakingTexture/ desc=/IModelData;\\)V$/",
 | 
					        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.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.server.MinecraftServer;
 | 
					import net.minecraft.server.MinecraftServer;
 | 
				
			||||||
import net.minecraft.server.dedicated.DedicatedServer;
 | 
					import net.minecraft.server.dedicated.DedicatedServer;
 | 
				
			||||||
import net.minecraft.world.entity.EntityType;
 | 
					 | 
				
			||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
 | 
					import net.minecraft.world.inventory.AbstractContainerMenu;
 | 
				
			||||||
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
 | 
					import net.minecraft.world.level.storage.loot.BuiltInLootTables;
 | 
				
			||||||
import net.minecraft.world.level.storage.loot.LootPool;
 | 
					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.event.server.ServerStoppedEvent;
 | 
				
			||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
					import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
				
			||||||
import net.minecraftforge.fml.common.Mod;
 | 
					import net.minecraftforge.fml.common.Mod;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.MissingMappingsEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.HashSet;
 | 
					import java.util.HashSet;
 | 
				
			||||||
@@ -162,12 +163,12 @@ public final class CommonHooks
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @SubscribeEvent
 | 
					    @SubscribeEvent
 | 
				
			||||||
    public static void onMissingEntityMappingsEvent( RegistryEvent.MissingMappings<EntityType<?>> event )
 | 
					    public static void onMissingEntityMappingsEvent( MissingMappingsEvent event )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ResourceLocation id = new ResourceLocation( ComputerCraft.MOD_ID, "turtle_player" );
 | 
					        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,6 +5,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
package dan200.computercraft.shared;
 | 
					package dan200.computercraft.shared;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.mojang.brigadier.arguments.ArgumentType;
 | 
				
			||||||
import dan200.computercraft.ComputerCraft;
 | 
					import dan200.computercraft.ComputerCraft;
 | 
				
			||||||
import dan200.computercraft.api.ComputerCraftAPI;
 | 
					import dan200.computercraft.api.ComputerCraftAPI;
 | 
				
			||||||
import dan200.computercraft.api.media.IMedia;
 | 
					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.peripheral.IPeripheral;
 | 
				
			||||||
import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
 | 
					import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
 | 
				
			||||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
 | 
					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.ColourableRecipe;
 | 
				
			||||||
import dan200.computercraft.shared.common.ContainerHeldItem;
 | 
					import dan200.computercraft.shared.common.ContainerHeldItem;
 | 
				
			||||||
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
 | 
					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.FixedPointTileEntityType;
 | 
				
			||||||
import dan200.computercraft.shared.util.ImpostorRecipe;
 | 
					import dan200.computercraft.shared.util.ImpostorRecipe;
 | 
				
			||||||
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
 | 
					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.core.cauldron.CauldronInteraction;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.world.inventory.MenuType;
 | 
					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.CreativeModeTab;
 | 
				
			||||||
import net.minecraft.world.item.Item;
 | 
					import net.minecraft.world.item.Item;
 | 
				
			||||||
import net.minecraft.world.item.RecordItem;
 | 
					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.Block;
 | 
				
			||||||
import net.minecraft.world.level.block.entity.BlockEntity;
 | 
					import net.minecraft.world.level.block.entity.BlockEntity;
 | 
				
			||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
 | 
					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.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
 | 
				
			||||||
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
 | 
					import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
 | 
				
			||||||
import net.minecraftforge.energy.CapabilityEnergy;
 | 
					import net.minecraftforge.energy.CapabilityEnergy;
 | 
				
			||||||
import net.minecraftforge.event.RegistryEvent;
 | 
					 | 
				
			||||||
import net.minecraftforge.eventbus.api.IEventBus;
 | 
					import net.minecraftforge.eventbus.api.IEventBus;
 | 
				
			||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
					import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
				
			||||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
 | 
					import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
 | 
				
			||||||
@@ -308,38 +310,62 @@ public final class Registry
 | 
				
			|||||||
            () -> ContainerData.toType( ViewComputerContainerData::new, ContainerViewComputer::new ) );
 | 
					            () -> 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
 | 
					    @SubscribeEvent
 | 
				
			||||||
    public static void registerRegistries( NewRegistryEvent event )
 | 
					    public static void registerRegistries( NewRegistryEvent event )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        @SuppressWarnings( "unchecked" )
 | 
					 | 
				
			||||||
        Class<TurtleUpgradeSerialiser<?>> turtleType = (Class<TurtleUpgradeSerialiser<?>>) (Class<?>) TurtleUpgradeSerialiser.class;
 | 
					 | 
				
			||||||
        event.create( new RegistryBuilder<TurtleUpgradeSerialiser<?>>()
 | 
					        event.create( new RegistryBuilder<TurtleUpgradeSerialiser<?>>()
 | 
				
			||||||
            .setName( TurtleUpgradeSerialiser.REGISTRY_ID.location() )
 | 
					            .setName( TurtleUpgradeSerialiser.REGISTRY_ID.location() )
 | 
				
			||||||
            .setType( turtleType )
 | 
					 | 
				
			||||||
            .disableSaving().disableSync() );
 | 
					            .disableSaving().disableSync() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @SuppressWarnings( "unchecked" )
 | 
					 | 
				
			||||||
        Class<PocketUpgradeSerialiser<?>> pocketType = (Class<PocketUpgradeSerialiser<?>>) (Class<?>) PocketUpgradeSerialiser.class;
 | 
					 | 
				
			||||||
        event.create( new RegistryBuilder<PocketUpgradeSerialiser<?>>()
 | 
					        event.create( new RegistryBuilder<PocketUpgradeSerialiser<?>>()
 | 
				
			||||||
            .setName( PocketUpgradeSerialiser.REGISTRY_ID.location() )
 | 
					            .setName( PocketUpgradeSerialiser.REGISTRY_ID.location() )
 | 
				
			||||||
            .setType( pocketType )
 | 
					 | 
				
			||||||
            .disableSaving().disableSync() );
 | 
					            .disableSaving().disableSync() );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @SubscribeEvent
 | 
					    @SubscribeEvent
 | 
				
			||||||
    public static void registerRecipeSerializers( RegistryEvent.Register<RecipeSerializer<?>> event )
 | 
					    public static void registerRecipeSerializers( RegisterEvent event )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        event.getRegistry().registerAll(
 | 
					        event.register( ForgeRegistries.RECIPE_SERIALIZERS.getRegistryKey(), registry -> {
 | 
				
			||||||
            ColourableRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "colour" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "colour" ), ColourableRecipe.SERIALIZER );
 | 
				
			||||||
            ComputerUpgradeRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer_upgrade" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "computer_upgrade" ), ComputerUpgradeRecipe.SERIALIZER );
 | 
				
			||||||
            PocketComputerUpgradeRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer_upgrade" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer_upgrade" ), PocketComputerUpgradeRecipe.SERIALIZER );
 | 
				
			||||||
            DiskRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ), DiskRecipe.SERIALIZER );
 | 
				
			||||||
            PrintoutRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printout" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "printout" ), PrintoutRecipe.SERIALIZER );
 | 
				
			||||||
            TurtleRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ), TurtleRecipe.SERIALIZER );
 | 
				
			||||||
            TurtleUpgradeRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade" ), TurtleUpgradeRecipe.SERIALIZER );
 | 
				
			||||||
            ImpostorShapelessRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shapeless" ) ),
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shapeless" ), ImpostorShapelessRecipe.SERIALIZER );
 | 
				
			||||||
            ImpostorRecipe.SERIALIZER.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shaped" ) )
 | 
					            registry.register( new ResourceLocation( ComputerCraft.MOD_ID, "impostor_shaped" ), ImpostorRecipe.SERIALIZER );
 | 
				
			||||||
        );
 | 
					        } );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @SubscribeEvent
 | 
					    @SubscribeEvent
 | 
				
			||||||
@@ -356,7 +382,6 @@ public final class Registry
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        event.enqueueWork( () -> {
 | 
					        event.enqueueWork( () -> {
 | 
				
			||||||
            registerProviders();
 | 
					            registerProviders();
 | 
				
			||||||
            ArgumentSerializers.register();
 | 
					 | 
				
			||||||
            registerLoot();
 | 
					            registerLoot();
 | 
				
			||||||
        } );
 | 
					        } );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -412,5 +437,6 @@ public final class Registry
 | 
				
			|||||||
        ModTurtleSerialisers.SERIALISERS.register( bus );
 | 
					        ModTurtleSerialisers.SERIALISERS.register( bus );
 | 
				
			||||||
        ModPocketUpgradeSerialisers.SERIALISERS.register( bus );
 | 
					        ModPocketUpgradeSerialisers.SERIALISERS.register( bus );
 | 
				
			||||||
        ModContainers.CONTAINERS.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.core.BlockPos;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.MutableComponent;
 | 
					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.network.protocol.game.ClientboundPlayerPositionPacket;
 | 
				
			||||||
import net.minecraft.server.level.ServerLevel;
 | 
					import net.minecraft.server.level.ServerLevel;
 | 
				
			||||||
import net.minecraft.server.level.ServerPlayer;
 | 
					import net.minecraft.server.level.ServerPlayer;
 | 
				
			||||||
@@ -231,7 +229,7 @@ public final class CommandComputerCraft
 | 
				
			|||||||
                        @Override
 | 
					                        @Override
 | 
				
			||||||
                        public Component getDisplayName()
 | 
					                        public Component getDisplayName()
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            return new TranslatableComponent( "gui.computercraft.view_computer" );
 | 
					                            return Component.translatable( "gui.computercraft.view_computer" );
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        @Nonnull
 | 
					                        @Nonnull
 | 
				
			||||||
@@ -287,7 +285,7 @@ public final class CommandComputerCraft
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private static Component linkComputer( CommandSourceStack source, ServerComputer serverComputer, int computerId )
 | 
					    private static Component linkComputer( CommandSourceStack source, ServerComputer serverComputer, int computerId )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MutableComponent out = new TextComponent( "" );
 | 
					        MutableComponent out = Component.literal( "" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Append the computer instance
 | 
					        // Append the computer instance
 | 
				
			||||||
        if( serverComputer == null )
 | 
					        if( serverComputer == null )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ package dan200.computercraft.shared.command;
 | 
				
			|||||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
 | 
					import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
 | 
				
			||||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 | 
					import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 | 
				
			||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 | 
					import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 | 
				
			||||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final class Exceptions
 | 
					public final class Exceptions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -27,16 +27,16 @@ public final class Exceptions
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private static SimpleCommandExceptionType translated( String key )
 | 
					    private static SimpleCommandExceptionType translated( String key )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return new SimpleCommandExceptionType( new TranslatableComponent( key ) );
 | 
					        return new SimpleCommandExceptionType( Component.translatable( key ) );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static DynamicCommandExceptionType translated1( String 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 )
 | 
					    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.ComputerCraft;
 | 
				
			||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
					import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
				
			||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
 | 
					import dan200.computercraft.shared.computer.core.ServerComputer;
 | 
				
			||||||
 | 
					import net.minecraft.commands.CommandBuildContext;
 | 
				
			||||||
import net.minecraft.commands.CommandSourceStack;
 | 
					import net.minecraft.commands.CommandSourceStack;
 | 
				
			||||||
import net.minecraft.commands.synchronization.ArgumentSerializer;
 | 
					import net.minecraft.commands.synchronization.ArgumentTypeInfo;
 | 
				
			||||||
import net.minecraft.network.FriendlyByteBuf;
 | 
					import net.minecraft.network.FriendlyByteBuf;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.*;
 | 
					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
 | 
					        @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
 | 
					        @Nonnull
 | 
				
			||||||
        @Override
 | 
					        @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
 | 
					        @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 );
 | 
					            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
 | 
					    @FunctionalInterface
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,6 @@
 | 
				
			|||||||
package dan200.computercraft.shared.command.arguments;
 | 
					package dan200.computercraft.shared.command.arguments;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.gson.JsonObject;
 | 
					import com.google.gson.JsonObject;
 | 
				
			||||||
import com.mojang.brigadier.Message;
 | 
					 | 
				
			||||||
import com.mojang.brigadier.StringReader;
 | 
					import com.mojang.brigadier.StringReader;
 | 
				
			||||||
import com.mojang.brigadier.arguments.ArgumentType;
 | 
					import com.mojang.brigadier.arguments.ArgumentType;
 | 
				
			||||||
import com.mojang.brigadier.context.CommandContext;
 | 
					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.exceptions.SimpleCommandExceptionType;
 | 
				
			||||||
import com.mojang.brigadier.suggestion.Suggestions;
 | 
					import com.mojang.brigadier.suggestion.Suggestions;
 | 
				
			||||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 | 
					import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 | 
				
			||||||
import net.minecraft.commands.synchronization.ArgumentSerializer;
 | 
					import net.minecraft.commands.CommandBuildContext;
 | 
				
			||||||
import net.minecraft.commands.synchronization.ArgumentTypes;
 | 
					import net.minecraft.commands.synchronization.ArgumentTypeInfo;
 | 
				
			||||||
 | 
					import net.minecraft.commands.synchronization.ArgumentTypeInfos;
 | 
				
			||||||
import net.minecraft.network.FriendlyByteBuf;
 | 
					import net.minecraft.network.FriendlyByteBuf;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
@@ -125,41 +125,57 @@ public final class RepeatArgumentType<T, U> implements ArgumentType<List<T>>
 | 
				
			|||||||
        return child.getExamples();
 | 
					        return child.getExamples();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static class Serializer implements ArgumentSerializer<RepeatArgumentType<?, ?>>
 | 
					    public static class Info implements ArgumentTypeInfo<RepeatArgumentType<?, ?>, Template>
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void serializeToNetwork( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull FriendlyByteBuf buf )
 | 
					        public void serializeToNetwork( @Nonnull RepeatArgumentType.Template arg, @Nonnull FriendlyByteBuf buf )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            buf.writeBoolean( arg.flatten );
 | 
					            buf.writeBoolean( arg.flatten );
 | 
				
			||||||
            ArgumentTypes.serialize( buf, arg.child );
 | 
					            ArgumentUtils.serializeToNetwork( buf, arg.child );
 | 
				
			||||||
            buf.writeComponent( getMessage( arg ) );
 | 
					            buf.writeComponent( ArgumentUtils.getMessage( arg.some ) );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Nonnull
 | 
					        @Nonnull
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        @SuppressWarnings( { "unchecked", "rawtypes" } )
 | 
					        public RepeatArgumentType.Template deserializeFromNetwork( @Nonnull FriendlyByteBuf buf )
 | 
				
			||||||
        public RepeatArgumentType<?, ?> deserializeFromNetwork( @Nonnull FriendlyByteBuf buf )
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            boolean isList = buf.readBoolean();
 | 
					            boolean isList = buf.readBoolean();
 | 
				
			||||||
            ArgumentType<?> child = ArgumentTypes.deserialize( buf );
 | 
					            var child = ArgumentUtils.deserialize( buf );
 | 
				
			||||||
            Component message = buf.readComponent();
 | 
					            Component message = buf.readComponent();
 | 
				
			||||||
            BiConsumer<List<Object>, ?> appender = isList ? ( list, x ) -> list.addAll( (Collection) x ) : List::add;
 | 
					            return new RepeatArgumentType.Template( this, child, isList, new SimpleCommandExceptionType( message ) );
 | 
				
			||||||
            return new RepeatArgumentType( child, appender, isList, new SimpleCommandExceptionType( message ) );
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void serializeToJson( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json )
 | 
					        public RepeatArgumentType.Template unpack( RepeatArgumentType<?, ?> argumentType )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            json.addProperty( "flatten", arg.flatten );
 | 
					            return new RepeatArgumentType.Template( this, ArgumentTypeInfos.unpack( argumentType.child ), argumentType.flatten, argumentType.some );
 | 
				
			||||||
            json.addProperty( "child", "<<cannot serialize>>" ); // TODO: Potentially serialize this using reflection.
 | 
					 | 
				
			||||||
            json.addProperty( "error", Component.Serializer.toJson( getMessage( arg ) ) );
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static Component getMessage( RepeatArgumentType<?, ?> arg )
 | 
					        @Override
 | 
				
			||||||
 | 
					        public void serializeToJson( @Nonnull RepeatArgumentType.Template arg, @Nonnull JsonObject json )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Message message = arg.some.create().getRawMessage();
 | 
					            json.addProperty( "flatten", arg.flatten );
 | 
				
			||||||
            if( message instanceof Component ) return (Component) message;
 | 
					            json.add( "child", ArgumentUtils.serializeToJson( arg.child ) );
 | 
				
			||||||
            return new TextComponent( message.getString() );
 | 
					            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.ClickEvent;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.MutableComponent;
 | 
					import net.minecraft.network.chat.MutableComponent;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
@@ -174,7 +173,7 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
 | 
				
			|||||||
        temp.addChild( node );
 | 
					        temp.addChild( node );
 | 
				
			||||||
        String usage = dispatcher.getSmartUsage( temp, context.getSource() ).get( node ).substring( node.getName().length() );
 | 
					        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( coloured( "/" + command + usage, HEADER ) )
 | 
				
			||||||
            .append( " " )
 | 
					            .append( " " )
 | 
				
			||||||
            .append( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
 | 
					            .append( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ public final class ChatHelpers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public static MutableComponent coloured( String text, ChatFormatting colour )
 | 
					    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 )
 | 
					    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 )
 | 
					    public static MutableComponent text( String text )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return new TextComponent( text == null ? "" : text );
 | 
					        return Component.literal( text == null ? "" : text );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static MutableComponent translate( String 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 )
 | 
					    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 )
 | 
					    public static MutableComponent list( Component... children )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MutableComponent component = new TextComponent( "" );
 | 
					        MutableComponent component = Component.literal( "" );
 | 
				
			||||||
        for( Component child : children )
 | 
					        for( Component child : children )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            component.append( child );
 | 
					            component.append( child );
 | 
				
			||||||
@@ -90,10 +90,10 @@ public final class ChatHelpers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public static MutableComponent copy( String text )
 | 
					    public static MutableComponent copy( String text )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        TextComponent name = new TextComponent( text );
 | 
					        MutableComponent name = Component.literal( text );
 | 
				
			||||||
        Style style = name.getStyle()
 | 
					        Style style = name.getStyle()
 | 
				
			||||||
            .withClickEvent( new ClickEvent( ClickEvent.Action.COPY_TO_CLIPBOARD, text ) )
 | 
					            .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 );
 | 
					        return name.withStyle( style );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@ package dan200.computercraft.shared.command.text;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import net.minecraft.commands.CommandSourceStack;
 | 
					import net.minecraft.commands.CommandSourceStack;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					 | 
				
			||||||
import org.apache.commons.lang3.StringUtils;
 | 
					import org.apache.commons.lang3.StringUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -27,7 +26,7 @@ public class ServerTableFormatter implements TableFormatter
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        int extraWidth = width - getWidth( component );
 | 
					        int extraWidth = width - getWidth( component );
 | 
				
			||||||
        if( extraWidth <= 0 ) return null;
 | 
					        if( extraWidth <= 0 ) return null;
 | 
				
			||||||
        return new TextComponent( StringUtils.repeat( ' ', extraWidth ) );
 | 
					        return Component.literal( StringUtils.repeat( ' ', extraWidth ) );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ package dan200.computercraft.shared.command.text;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import net.minecraft.ChatFormatting;
 | 
					import net.minecraft.ChatFormatting;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					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 org.apache.commons.lang3.StringUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -76,7 +76,7 @@ public interface TableFormatter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if( headers != null )
 | 
					        if( headers != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            TextComponent line = new TextComponent( "" );
 | 
					            MutableComponent line = Component.literal( "" );
 | 
				
			||||||
            for( int i = 0; i < columns - 1; i++ )
 | 
					            for( int i = 0; i < columns - 1; i++ )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                line.append( headers[i] );
 | 
					                line.append( headers[i] );
 | 
				
			||||||
@@ -97,7 +97,7 @@ public interface TableFormatter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        for( Component[] row : table.getRows() )
 | 
					        for( Component[] row : table.getRows() )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            TextComponent line = new TextComponent( "" );
 | 
					            MutableComponent line = Component.literal( "" );
 | 
				
			||||||
            for( int i = 0; i < columns - 1; i++ )
 | 
					            for( int i = 0; i < columns - 1; i++ )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                line.append( row[i] );
 | 
					                line.append( row[i] );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ package dan200.computercraft.shared.common;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import net.minecraft.core.BlockPos;
 | 
					import net.minecraft.core.BlockPos;
 | 
				
			||||||
import net.minecraft.server.level.ServerLevel;
 | 
					import net.minecraft.server.level.ServerLevel;
 | 
				
			||||||
 | 
					import net.minecraft.util.RandomSource;
 | 
				
			||||||
import net.minecraft.world.InteractionHand;
 | 
					import net.minecraft.world.InteractionHand;
 | 
				
			||||||
import net.minecraft.world.InteractionResult;
 | 
					import net.minecraft.world.InteractionResult;
 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
@@ -23,7 +24,6 @@ import net.minecraftforge.registries.RegistryObject;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
import java.util.Random;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public abstract class BlockGeneric extends BaseEntityBlock
 | 
					public abstract class BlockGeneric extends BaseEntityBlock
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -73,7 +73,7 @@ public abstract class BlockGeneric extends BaseEntityBlock
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    @Deprecated
 | 
					    @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 );
 | 
					        BlockEntity te = world.getBlockEntity( pos );
 | 
				
			||||||
        if( te instanceof TileGeneric generic ) generic.blockTick();
 | 
					        if( te instanceof TileGeneric generic ) generic.blockTick();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,6 +43,13 @@ public class ContainerHeldItem extends AbstractContainerMenu
 | 
				
			|||||||
        return stack;
 | 
					        return stack;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public ItemStack quickMoveStack( @Nonnull Player player, int slot )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return ItemStack.EMPTY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean stillValid( @Nonnull Player player )
 | 
					    public boolean stillValid( @Nonnull Player player )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -162,7 +162,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
 | 
				
			|||||||
                popResource( world, pos, item );
 | 
					                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.commands.CommandSourceStack;
 | 
				
			||||||
import net.minecraft.core.BlockPos;
 | 
					import net.minecraft.core.BlockPos;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					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.MinecraftServer;
 | 
				
			||||||
import net.minecraft.server.level.ServerLevel;
 | 
					import net.minecraft.server.level.ServerLevel;
 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
@@ -27,7 +25,6 @@ import net.minecraft.world.phys.Vec3;
 | 
				
			|||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.UUID;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class TileCommandComputer extends TileComputer
 | 
					public class TileCommandComputer extends TileComputer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -51,7 +48,7 @@ public class TileCommandComputer extends TileComputer
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void sendMessage( @Nonnull Component textComponent, @Nonnull UUID id )
 | 
					        public void sendSystemMessage( @Nonnull Component textComponent )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            output.put( output.size() + 1, textComponent.getString() );
 | 
					            output.put( output.size() + 1, textComponent.getString() );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -101,7 +98,7 @@ public class TileCommandComputer extends TileComputer
 | 
				
			|||||||
        return new CommandSourceStack( receiver,
 | 
					        return new CommandSourceStack( receiver,
 | 
				
			||||||
            Vec3.atCenterOf( worldPosition ), Vec2.ZERO,
 | 
					            Vec3.atCenterOf( worldPosition ), Vec2.ZERO,
 | 
				
			||||||
            (ServerLevel) getLevel(), 2,
 | 
					            (ServerLevel) getLevel(), 2,
 | 
				
			||||||
            name, new TextComponent( name ),
 | 
					            name, Component.literal( name ),
 | 
				
			||||||
            getLevel().getServer(), null
 | 
					            getLevel().getServer(), null
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -125,12 +122,12 @@ public class TileCommandComputer extends TileComputer
 | 
				
			|||||||
        MinecraftServer server = player.getServer();
 | 
					        MinecraftServer server = player.getServer();
 | 
				
			||||||
        if( server == null || !server.isCommandBlockEnabled() )
 | 
					        if( server == null || !server.isCommandBlockEnabled() )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            player.displayClientMessage( new TranslatableComponent( "advMode.notEnabled" ), true );
 | 
					            player.displayClientMessage( Component.translatable( "advMode.notEnabled" ), true );
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( ComputerCraft.commandRequireCreative ? !player.canUseGameMasterBlocks() : !server.getPlayerList().isOp( player.getGameProfile() ) )
 | 
					        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;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,8 +22,6 @@ import net.minecraft.core.BlockPos;
 | 
				
			|||||||
import net.minecraft.core.Direction;
 | 
					import net.minecraft.core.Direction;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					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.network.protocol.game.ClientboundBlockEntityDataPacket;
 | 
				
			||||||
import net.minecraft.world.*;
 | 
					import net.minecraft.world.*;
 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
@@ -438,8 +436,8 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
 | 
				
			|||||||
    public Component getName()
 | 
					    public Component getName()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return hasCustomName()
 | 
					        return hasCustomName()
 | 
				
			||||||
            ? new TextComponent( label )
 | 
					            ? Component.literal( label )
 | 
				
			||||||
            : new TranslatableComponent( getBlockState().getBlock().getDescriptionId() );
 | 
					            : Component.translatable( getBlockState().getBlock().getDescriptionId() );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
@@ -452,7 +450,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Component getCustomName()
 | 
					    public Component getCustomName()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return hasCustomName() ? new TextComponent( label ) : null;
 | 
					        return hasCustomName() ? Component.literal( label ) : null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,9 @@ import dan200.computercraft.shared.util.InvisibleSlot;
 | 
				
			|||||||
import net.minecraft.world.entity.player.Inventory;
 | 
					import net.minecraft.world.entity.player.Inventory;
 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
import net.minecraft.world.inventory.MenuType;
 | 
					import net.minecraft.world.inventory.MenuType;
 | 
				
			||||||
 | 
					import net.minecraft.world.item.ItemStack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.function.Predicate;
 | 
					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 ) );
 | 
					        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.NetworkHandler;
 | 
				
			||||||
import dan200.computercraft.shared.network.client.UploadResultMessage;
 | 
					import dan200.computercraft.shared.network.client.UploadResultMessage;
 | 
				
			||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
 | 
					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.server.level.ServerPlayer;
 | 
				
			||||||
import net.minecraft.world.entity.player.Inventory;
 | 
					import net.minecraft.world.entity.player.Inventory;
 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
@@ -154,7 +154,7 @@ public abstract class ContainerComputerBase extends AbstractContainerMenu implem
 | 
				
			|||||||
            if( !upload.checksumMatches() )
 | 
					            if( !upload.checksumMatches() )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ComputerCraft.log.warn( "Checksum failed to match for {}.", upload.getName() );
 | 
					                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(
 | 
					                    return new UploadResultMessage(
 | 
				
			||||||
                        UploadResult.ERROR,
 | 
					                        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;
 | 
					                toUpload = files;
 | 
				
			||||||
                return new UploadResultMessage(
 | 
					                return new UploadResultMessage(
 | 
				
			||||||
                    UploadResult.CONFIRM_OVERWRITE,
 | 
					                    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(
 | 
					            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 )
 | 
					        catch( FileSystemException | IOException e )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ComputerCraft.log.error( "Error uploading files", 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.blocks.BlockComputer;
 | 
				
			||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
					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 net.minecraft.world.item.ItemStack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
@@ -23,7 +23,7 @@ public class ItemComputer extends ItemComputerBase
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        ItemStack result = new ItemStack( this );
 | 
					        ItemStack result = new ItemStack( this );
 | 
				
			||||||
        if( id >= 0 ) result.getOrCreateTag().putInt( NBT_ID, id );
 | 
					        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;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,8 +13,6 @@ import dan200.computercraft.shared.computer.blocks.BlockComputerBase;
 | 
				
			|||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
					import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
				
			||||||
import net.minecraft.ChatFormatting;
 | 
					import net.minecraft.ChatFormatting;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					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.BlockItem;
 | 
				
			||||||
import net.minecraft.world.item.ItemStack;
 | 
					import net.minecraft.world.item.ItemStack;
 | 
				
			||||||
import net.minecraft.world.item.TooltipFlag;
 | 
					import net.minecraft.world.item.TooltipFlag;
 | 
				
			||||||
@@ -42,7 +40,7 @@ public abstract class ItemComputerBase extends BlockItem implements IComputerIte
 | 
				
			|||||||
            int id = getComputerID( stack );
 | 
					            int id = getComputerID( stack );
 | 
				
			||||||
            if( id >= 0 )
 | 
					            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 ) );
 | 
					                    .withStyle( ChatFormatting.GRAY ) );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -67,7 +65,7 @@ public abstract class ItemComputerBase extends BlockItem implements IComputerIte
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        if( label != null )
 | 
					        if( label != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            stack.setHoverName( new TextComponent( label ) );
 | 
					            stack.setHoverName( Component.literal( label ) );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@ package dan200.computercraft.shared.computer.recipe;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import com.google.gson.JsonObject;
 | 
					import com.google.gson.JsonObject;
 | 
				
			||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
					import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
				
			||||||
import dan200.computercraft.shared.util.BasicRecipeSerializer;
 | 
					 | 
				
			||||||
import dan200.computercraft.shared.util.RecipeUtil;
 | 
					import dan200.computercraft.shared.util.RecipeUtil;
 | 
				
			||||||
import net.minecraft.core.NonNullList;
 | 
					import net.minecraft.core.NonNullList;
 | 
				
			||||||
import net.minecraft.network.FriendlyByteBuf;
 | 
					import net.minecraft.network.FriendlyByteBuf;
 | 
				
			||||||
@@ -15,6 +14,7 @@ import net.minecraft.resources.ResourceLocation;
 | 
				
			|||||||
import net.minecraft.util.GsonHelper;
 | 
					import net.minecraft.util.GsonHelper;
 | 
				
			||||||
import net.minecraft.world.item.ItemStack;
 | 
					import net.minecraft.world.item.ItemStack;
 | 
				
			||||||
import net.minecraft.world.item.crafting.Ingredient;
 | 
					import net.minecraft.world.item.crafting.Ingredient;
 | 
				
			||||||
 | 
					import net.minecraft.world.item.crafting.RecipeSerializer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,7 +33,7 @@ public abstract class ComputerFamilyRecipe extends ComputerConvertRecipe
 | 
				
			|||||||
        return family;
 | 
					        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 );
 | 
					        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;
 | 
					package dan200.computercraft.shared.computer.upload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public enum UploadResult
 | 
					public enum UploadResult
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -14,12 +13,12 @@ public enum UploadResult
 | 
				
			|||||||
    ERROR,
 | 
					    ERROR,
 | 
				
			||||||
    CONFIRM_OVERWRITE;
 | 
					    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 FAILED_TITLE = Component.translatable( "gui.computercraft.upload.failed" );
 | 
				
			||||||
    public static final Component COMPUTER_OFF_MSG = new TranslatableComponent( "gui.computercraft.upload.failed.computer_off" );
 | 
					    public static final Component COMPUTER_OFF_MSG = Component.translatable( "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 OUT_OF_SPACE_MSG = Component.translatable( "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 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" );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,6 @@ import net.minecraft.core.BlockPos;
 | 
				
			|||||||
import net.minecraft.core.NonNullList;
 | 
					import net.minecraft.core.NonNullList;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					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.entity.player.Player;
 | 
				
			||||||
import net.minecraft.world.item.CreativeModeTab;
 | 
					import net.minecraft.world.item.CreativeModeTab;
 | 
				
			||||||
import net.minecraft.world.item.Item;
 | 
					import net.minecraft.world.item.Item;
 | 
				
			||||||
@@ -53,7 +51,7 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void fillItemCategory( @Nonnull CreativeModeTab tabs, @Nonnull NonNullList<ItemStack> list )
 | 
					    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++ )
 | 
					        for( int colour = 0; colour < 16; colour++ )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            list.add( createFromIDAndColour( -1, null, Colour.VALUES[colour].getHex() ) );
 | 
					            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 );
 | 
					            int id = getDiskID( stack );
 | 
				
			||||||
            if( id >= 0 )
 | 
					            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 ) );
 | 
					                    .withStyle( ChatFormatting.GRAY ) );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -91,7 +89,7 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        if( label != null )
 | 
					        if( label != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            stack.setHoverName( new TextComponent( label ) );
 | 
					            stack.setHoverName( Component.literal( label ) );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ import dan200.computercraft.shared.common.ContainerHeldItem;
 | 
				
			|||||||
import dan200.computercraft.shared.network.container.HeldItemContainerData;
 | 
					import dan200.computercraft.shared.network.container.HeldItemContainerData;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					 | 
				
			||||||
import net.minecraft.world.InteractionHand;
 | 
					import net.minecraft.world.InteractionHand;
 | 
				
			||||||
import net.minecraft.world.InteractionResult;
 | 
					import net.minecraft.world.InteractionResult;
 | 
				
			||||||
import net.minecraft.world.InteractionResultHolder;
 | 
					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 )
 | 
					    public void appendHoverText( @Nonnull ItemStack stack, Level world, @Nonnull List<Component> list, @Nonnull TooltipFlag options )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        String title = getTitle( stack );
 | 
					        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
 | 
					    @Nonnull
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ import net.minecraft.core.BlockPos;
 | 
				
			|||||||
import net.minecraft.core.NonNullList;
 | 
					import net.minecraft.core.NonNullList;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
import net.minecraft.world.item.CreativeModeTab;
 | 
					import net.minecraft.world.item.CreativeModeTab;
 | 
				
			||||||
import net.minecraft.world.item.Item;
 | 
					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 )
 | 
					    public void appendHoverText( @Nonnull ItemStack stack, @Nullable Level world, @Nonnull List<Component> list, @Nonnull TooltipFlag tooltipOptions )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        String label = getTitle( stack );
 | 
					        String label = getTitle( stack );
 | 
				
			||||||
        if( !label.isEmpty() ) list.add( new TextComponent( label ) );
 | 
					        if( !label.isEmpty() ) list.add( Component.literal( label ) );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
package dan200.computercraft.shared.media.items;
 | 
					package dan200.computercraft.shared.media.items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import dan200.computercraft.api.media.IMedia;
 | 
					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.sounds.SoundEvent;
 | 
				
			||||||
import net.minecraft.world.item.Item;
 | 
					import net.minecraft.world.item.Item;
 | 
				
			||||||
import net.minecraft.world.item.ItemStack;
 | 
					import net.minecraft.world.item.ItemStack;
 | 
				
			||||||
@@ -37,7 +37,7 @@ public final class RecordMedia implements IMedia
 | 
				
			|||||||
        Item item = stack.getItem();
 | 
					        Item item = stack.getItem();
 | 
				
			||||||
        if( !(item instanceof RecordItem) ) return null;
 | 
					        if( !(item instanceof RecordItem) ) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new TranslatableComponent( item.getDescriptionId() + ".desc" ).getString();
 | 
					        return Component.translatable( item.getDescriptionId() + ".desc" ).getString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,11 +9,12 @@ import dan200.computercraft.shared.network.NetworkMessage;
 | 
				
			|||||||
import net.minecraft.client.Minecraft;
 | 
					import net.minecraft.client.Minecraft;
 | 
				
			||||||
import net.minecraft.core.BlockPos;
 | 
					import net.minecraft.core.BlockPos;
 | 
				
			||||||
import net.minecraft.network.FriendlyByteBuf;
 | 
					import net.minecraft.network.FriendlyByteBuf;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.sounds.SoundEvent;
 | 
					import net.minecraft.sounds.SoundEvent;
 | 
				
			||||||
import net.minecraftforge.api.distmarker.Dist;
 | 
					import net.minecraftforge.api.distmarker.Dist;
 | 
				
			||||||
import net.minecraftforge.api.distmarker.OnlyIn;
 | 
					import net.minecraftforge.api.distmarker.OnlyIn;
 | 
				
			||||||
import net.minecraftforge.network.NetworkEvent;
 | 
					import net.minecraftforge.network.NetworkEvent;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -71,7 +72,7 @@ public class PlayRecordClientMessage implements NetworkMessage
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            buf.writeBoolean( true );
 | 
					            buf.writeBoolean( true );
 | 
				
			||||||
            buf.writeUtf( name );
 | 
					            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();
 | 
					        Minecraft mc = Minecraft.getInstance();
 | 
				
			||||||
        mc.levelRenderer.playStreamingMusic( soundEvent, pos, null );
 | 
					        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
 | 
					    @Override
 | 
				
			||||||
    public void toBytes( @Nonnull FriendlyByteBuf buf )
 | 
					    public void toBytes( @Nonnull FriendlyByteBuf buf )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        toBytes( buf, turtleUpgrades );
 | 
					        toBytes( buf, TurtleUpgradeSerialiser.registry(), turtleUpgrades );
 | 
				
			||||||
        toBytes( buf, pocketUpgrades );
 | 
					        toBytes( buf, PocketUpgradeSerialiser.registry(), pocketUpgrades );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private <R extends UpgradeSerialiser<? extends T, R>, T extends IUpgradeBase> void toBytes(
 | 
					    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() );
 | 
					        buf.writeVarInt( upgrades.size() );
 | 
				
			||||||
@@ -85,11 +85,12 @@ public class UpgradesLoadedMessage implements NetworkMessage
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            buf.writeUtf( entry.getKey() );
 | 
					            buf.writeUtf( entry.getKey() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var serialiser = entry.getValue().serialiser();
 | 
				
			||||||
            @SuppressWarnings( "unchecked" )
 | 
					            @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!" ) );
 | 
					            buf.writeResourceLocation( Objects.requireNonNull( registry.getKey( serialiser ), "Serialiser is not registered!" ) );
 | 
				
			||||||
            serialiser.toNetwork( buf, entry.getValue().upgrade() );
 | 
					            unwrapedSerialiser.toNetwork( buf, entry.getValue().upgrade() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            buf.writeUtf( entry.getValue().modId() );
 | 
					            buf.writeUtf( entry.getValue().modId() );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,6 @@ import net.minecraft.core.BlockPos;
 | 
				
			|||||||
import net.minecraft.core.Direction;
 | 
					import net.minecraft.core.Direction;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
					 | 
				
			||||||
import net.minecraft.server.level.ServerPlayer;
 | 
					import net.minecraft.server.level.ServerPlayer;
 | 
				
			||||||
import net.minecraft.sounds.SoundEvent;
 | 
					import net.minecraft.sounds.SoundEvent;
 | 
				
			||||||
import net.minecraft.world.*;
 | 
					import net.minecraft.world.*;
 | 
				
			||||||
@@ -563,7 +562,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Component getName()
 | 
					    public Component getName()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return customName != null ? customName : new TranslatableComponent( getBlockState().getBlock().getDescriptionId() );
 | 
					        return customName != null ? customName : Component.translatable( getBlockState().getBlock().getDescriptionId() );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ import dan200.computercraft.api.peripheral.IDynamicPeripheral;
 | 
				
			|||||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
					import dan200.computercraft.api.peripheral.IPeripheral;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.world.level.block.entity.BlockEntity;
 | 
					import net.minecraft.world.level.block.entity.BlockEntity;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -29,7 +30,7 @@ class GenericPeripheral implements IDynamicPeripheral
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    GenericPeripheral( BlockEntity tile, String name, Set<String> additionalTypes, List<SaturatedMethod> methods )
 | 
					    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.tile = tile;
 | 
				
			||||||
        this.type = name != null ? name : (type != null ? type.toString() : "unknown");
 | 
					        this.type = name != null ? name : (type != null ? type.toString() : "unknown");
 | 
				
			||||||
        this.additionalTypes = additionalTypes;
 | 
					        this.additionalTypes = additionalTypes;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ package dan200.computercraft.shared.peripheral.generic.data;
 | 
				
			|||||||
import dan200.computercraft.api.detail.BlockReference;
 | 
					import dan200.computercraft.api.detail.BlockReference;
 | 
				
			||||||
import net.minecraft.world.level.block.state.BlockState;
 | 
					import net.minecraft.world.level.block.state.BlockState;
 | 
				
			||||||
import net.minecraft.world.level.block.state.properties.Property;
 | 
					import net.minecraft.world.level.block.state.properties.Property;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
@@ -20,7 +21,7 @@ public class BlockData
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        BlockState state = block.state();
 | 
					        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<>();
 | 
					        Map<Object, Object> stateTable = new HashMap<>();
 | 
				
			||||||
        for( Map.Entry<Property<?>, ? extends Comparable<?>> entry : state.getValues().entrySet() )
 | 
					        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.core.Holder;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.tags.TagKey;
 | 
					import net.minecraft.tags.TagKey;
 | 
				
			||||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
					import net.minecraftforge.registries.IForgeRegistry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -33,9 +33,9 @@ public final class DataHelpers
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nullable
 | 
					    @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();
 | 
					        return id == null ? null : id.toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@
 | 
				
			|||||||
package dan200.computercraft.shared.peripheral.generic.data;
 | 
					package dan200.computercraft.shared.peripheral.generic.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.minecraftforge.fluids.FluidStack;
 | 
					import net.minecraftforge.fluids.FluidStack;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
@@ -15,7 +16,7 @@ public class FluidData
 | 
				
			|||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    public static <T extends Map<? super String, Object>> T fillBasic( @Nonnull T data, @Nonnull FluidStack stack )
 | 
					    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() );
 | 
					        data.put( "amount", stack.getAmount() );
 | 
				
			||||||
        return data;
 | 
					        return data;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ import net.minecraft.world.item.EnchantedBookItem;
 | 
				
			|||||||
import net.minecraft.world.item.ItemStack;
 | 
					import net.minecraft.world.item.ItemStack;
 | 
				
			||||||
import net.minecraft.world.item.enchantment.Enchantment;
 | 
					import net.minecraft.world.item.enchantment.Enchantment;
 | 
				
			||||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
 | 
					import net.minecraft.world.item.enchantment.EnchantmentHelper;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -29,7 +30,7 @@ public class ItemData
 | 
				
			|||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    public static <T extends Map<? super String, Object>> T fillBasicSafe( @Nonnull T data, @Nonnull ItemStack stack )
 | 
					    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() );
 | 
					        data.put( "count", stack.getCount() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return data;
 | 
					        return data;
 | 
				
			||||||
@@ -163,7 +164,7 @@ public class ItemData
 | 
				
			|||||||
            Enchantment enchantment = entry.getKey();
 | 
					            Enchantment enchantment = entry.getKey();
 | 
				
			||||||
            Integer level = entry.getValue();
 | 
					            Integer level = entry.getValue();
 | 
				
			||||||
            HashMap<String, Object> enchant = new HashMap<>( 3 );
 | 
					            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( "level", level );
 | 
				
			||||||
            enchant.put( "displayName", enchantment.getFullname( level ).getString() );
 | 
					            enchant.put( "displayName", enchantment.getFullname( level ).getString() );
 | 
				
			||||||
            enchants.add( enchant );
 | 
					            enchants.add( enchant );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,6 @@ import dan200.computercraft.api.lua.LuaException;
 | 
				
			|||||||
import net.minecraft.ResourceLocationException;
 | 
					import net.minecraft.ResourceLocationException;
 | 
				
			||||||
import net.minecraft.resources.ResourceLocation;
 | 
					import net.minecraft.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraftforge.registries.IForgeRegistry;
 | 
					import net.minecraftforge.registries.IForgeRegistry;
 | 
				
			||||||
import net.minecraftforge.registries.IForgeRegistryEntry;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,7 +41,7 @@ final class ArgumentHelpers
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @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;
 | 
					        ResourceLocation id;
 | 
				
			||||||
        try
 | 
					        try
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,7 +63,7 @@ public abstract class ItemBlockCable extends BlockItem
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void fillItemCategory( @Nonnull CreativeModeTab group, @Nonnull NonNullList<ItemStack> list )
 | 
					    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
 | 
					    @Nonnull
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ import dan200.computercraft.shared.util.TickScheduler;
 | 
				
			|||||||
import net.minecraft.core.BlockPos;
 | 
					import net.minecraft.core.BlockPos;
 | 
				
			||||||
import net.minecraft.core.Direction;
 | 
					import net.minecraft.core.Direction;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					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.InteractionHand;
 | 
				
			||||||
import net.minecraft.world.InteractionResult;
 | 
					import net.minecraft.world.InteractionResult;
 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
@@ -269,12 +269,12 @@ public class TileCable extends TileGeneric
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if( oldName != null )
 | 
					            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 );
 | 
					                    ChatHelpers.copy( oldName ) ), false );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if( newName != null )
 | 
					            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 );
 | 
					                    ChatHelpers.copy( newName ) ), false );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,8 @@ import dan200.computercraft.shared.util.TickScheduler;
 | 
				
			|||||||
import net.minecraft.core.BlockPos;
 | 
					import net.minecraft.core.BlockPos;
 | 
				
			||||||
import net.minecraft.core.Direction;
 | 
					import net.minecraft.core.Direction;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.TextComponent;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
					import net.minecraft.network.chat.MutableComponent;
 | 
				
			||||||
import net.minecraft.world.InteractionHand;
 | 
					import net.minecraft.world.InteractionHand;
 | 
				
			||||||
import net.minecraft.world.InteractionResult;
 | 
					import net.minecraft.world.InteractionResult;
 | 
				
			||||||
import net.minecraft.world.entity.player.Player;
 | 
					import net.minecraft.world.entity.player.Player;
 | 
				
			||||||
@@ -222,14 +222,14 @@ public class TileWiredModemFull extends TileGeneric
 | 
				
			|||||||
        List<String> names = new ArrayList<>( peripherals );
 | 
					        List<String> names = new ArrayList<>( peripherals );
 | 
				
			||||||
        names.sort( Comparator.naturalOrder() );
 | 
					        names.sort( Comparator.naturalOrder() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TextComponent base = new TextComponent( "" );
 | 
					        MutableComponent base = Component.literal( "" );
 | 
				
			||||||
        for( int i = 0; i < names.size(); i++ )
 | 
					        for( int i = 0; i < names.size(); i++ )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if( i > 0 ) base.append( ", " );
 | 
					            if( i > 0 ) base.append( ", " );
 | 
				
			||||||
            base.append( ChatHelpers.copy( names.get( i ) ) );
 | 
					            base.append( ChatHelpers.copy( names.get( i ) ) );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        player.displayClientMessage( new TranslatableComponent( kind, base ), false );
 | 
					        player.displayClientMessage( Component.translatable( kind, base ), false );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ import net.minecraft.core.Direction;
 | 
				
			|||||||
import net.minecraft.core.NonNullList;
 | 
					import net.minecraft.core.NonNullList;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					import net.minecraft.network.chat.Component;
 | 
				
			||||||
import net.minecraft.network.chat.TranslatableComponent;
 | 
					 | 
				
			||||||
import net.minecraft.server.level.ServerPlayer;
 | 
					import net.minecraft.server.level.ServerPlayer;
 | 
				
			||||||
import net.minecraft.world.*;
 | 
					import net.minecraft.world.*;
 | 
				
			||||||
import net.minecraft.world.entity.player.Inventory;
 | 
					import net.minecraft.world.entity.player.Inventory;
 | 
				
			||||||
@@ -492,7 +491,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Component getName()
 | 
					    public Component getName()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return customName != null ? customName : new TranslatableComponent( getBlockState().getBlock().getDescriptionId() );
 | 
					        return customName != null ? customName : Component.translatable( getBlockState().getBlock().getDescriptionId() );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,7 @@ import net.minecraft.sounds.SoundSource;
 | 
				
			|||||||
import net.minecraft.world.level.Level;
 | 
					import net.minecraft.world.level.Level;
 | 
				
			||||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
 | 
					import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
 | 
				
			||||||
import net.minecraft.world.phys.Vec3;
 | 
					import net.minecraft.world.phys.Vec3;
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
@@ -84,7 +85,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
				
			|||||||
                lastPlayTime = clock;
 | 
					                lastPlayTime = clock;
 | 
				
			||||||
                server.getPlayerList().broadcast(
 | 
					                server.getPlayerList().broadcast(
 | 
				
			||||||
                    null, pos.x, pos.y, pos.z, sound.volume * 16, level.dimension(),
 | 
					                    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();
 | 
					            pendingNotes.clear();
 | 
				
			||||||
@@ -236,7 +237,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
				
			|||||||
        synchronized( pendingNotes )
 | 
					        synchronized( pendingNotes )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if( pendingNotes.size() >= ComputerCraft.maxNotesPerTick ) return false;
 | 
					            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;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,7 @@ public record SpeakerPosition(@Nullable Level level, @Nonnull Vec3 position, @Nu
 | 
				
			|||||||
    public Message asMessage()
 | 
					    public Message asMessage()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if( level == null ) throw new NullPointerException( "Cannot send a position without a level" );
 | 
					        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
 | 
					    public static final class Message
 | 
				
			||||||
@@ -80,7 +80,7 @@ public record SpeakerPosition(@Nullable Level level, @Nonnull Vec3 position, @Nu
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Minecraft minecraft = Minecraft.getInstance();
 | 
					            Minecraft minecraft = Minecraft.getInstance();
 | 
				
			||||||
            Level level = minecraft.level;
 | 
					            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(
 | 
					            return new SpeakerPosition(
 | 
				
			||||||
                level, position,
 | 
					                level, position,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,6 @@ import net.minecraft.ChatFormatting;
 | 
				
			|||||||
import net.minecraft.core.NonNullList;
 | 
					import net.minecraft.core.NonNullList;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					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.Container;
 | 
				
			||||||
import net.minecraft.world.InteractionHand;
 | 
					import net.minecraft.world.InteractionHand;
 | 
				
			||||||
import net.minecraft.world.InteractionResult;
 | 
					import net.minecraft.world.InteractionResult;
 | 
				
			||||||
@@ -67,7 +65,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        ItemStack result = new ItemStack( this );
 | 
					        ItemStack result = new ItemStack( this );
 | 
				
			||||||
        if( id >= 0 ) result.getOrCreateTag().putInt( NBT_ID, id );
 | 
					        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( upgrade != null ) result.getOrCreateTag().putString( NBT_UPGRADE, upgrade.getUpgradeID().toString() );
 | 
				
			||||||
        if( colour != -1 ) result.getOrCreateTag().putInt( NBT_COLOUR, colour );
 | 
					        if( colour != -1 ) result.getOrCreateTag().putInt( NBT_COLOUR, colour );
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
@@ -76,7 +74,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void fillItemCategory( @Nonnull CreativeModeTab group, @Nonnull NonNullList<ItemStack> stacks )
 | 
					    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 ) );
 | 
					        stacks.add( create( -1, null, -1, null ) );
 | 
				
			||||||
        PocketUpgrades.getVanillaUpgrades().map( x -> create( -1, null, -1, x ) ).forEach( stacks::add );
 | 
					        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 );
 | 
					        IPocketUpgrade upgrade = getUpgrade( stack );
 | 
				
			||||||
        if( upgrade != null )
 | 
					        if( upgrade != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new TranslatableComponent( baseString + ".upgraded",
 | 
					            return Component.translatable( baseString + ".upgraded",
 | 
				
			||||||
                new TranslatableComponent( upgrade.getUnlocalisedAdjective() )
 | 
					                Component.translatable( upgrade.getUnlocalisedAdjective() )
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
@@ -201,7 +199,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
				
			|||||||
            int id = getComputerID( stack );
 | 
					            int id = getComputerID( stack );
 | 
				
			||||||
            if( id >= 0 )
 | 
					            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 ) );
 | 
					                    .withStyle( ChatFormatting.GRAY ) );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -332,7 +330,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        if( label != null )
 | 
					        if( label != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            stack.setHoverName( new TextComponent( label ) );
 | 
					            stack.setHoverName( Component.literal( label ) );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ import dan200.computercraft.shared.util.InventoryUtil;
 | 
				
			|||||||
import dan200.computercraft.shared.util.WorldUtil;
 | 
					import dan200.computercraft.shared.util.WorldUtil;
 | 
				
			||||||
import net.minecraft.core.BlockPos;
 | 
					import net.minecraft.core.BlockPos;
 | 
				
			||||||
import net.minecraft.core.Direction;
 | 
					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.network.protocol.game.ServerboundInteractPacket;
 | 
				
			||||||
import net.minecraft.world.InteractionHand;
 | 
					import net.minecraft.world.InteractionHand;
 | 
				
			||||||
import net.minecraft.world.InteractionResult;
 | 
					import net.minecraft.world.InteractionResult;
 | 
				
			||||||
@@ -284,7 +284,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Item item = stack.getItem();
 | 
					        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 );
 | 
					            InteractionResult actionResult = ForgeHooks.onItemRightClick( turtlePlayer, InteractionHand.MAIN_HAND );
 | 
				
			||||||
            if( actionResult != null && actionResult != InteractionResult.PASS ) return actionResult;
 | 
					            if( actionResult != null && actionResult != InteractionResult.PASS ) return actionResult;
 | 
				
			||||||
@@ -311,13 +311,13 @@ public class TurtlePlaceCommand implements ITurtleCommand
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                String line = split[i - firstLine];
 | 
					                String line = split[i - firstLine];
 | 
				
			||||||
                signTile.setMessage( i, line.length() > 15
 | 
					                signTile.setMessage( i, line.length() > 15
 | 
				
			||||||
                    ? new TextComponent( line.substring( 0, 15 ) )
 | 
					                    ? Component.literal( line.substring( 0, 15 ) )
 | 
				
			||||||
                    : new TextComponent( line )
 | 
					                    : Component.literal( line )
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                signTile.setMessage( i, new TextComponent( "" ) );
 | 
					                signTile.setMessage( i, Component.literal( "" ) );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        signTile.setChanged();
 | 
					        signTile.setChanged();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,6 @@ import net.minecraft.core.NonNullList;
 | 
				
			|||||||
import net.minecraft.core.cauldron.CauldronInteraction;
 | 
					import net.minecraft.core.cauldron.CauldronInteraction;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					import net.minecraft.nbt.CompoundTag;
 | 
				
			||||||
import net.minecraft.network.chat.Component;
 | 
					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.resources.ResourceLocation;
 | 
				
			||||||
import net.minecraft.world.InteractionResult;
 | 
					import net.minecraft.world.InteractionResult;
 | 
				
			||||||
import net.minecraft.world.item.CreativeModeTab;
 | 
					import net.minecraft.world.item.CreativeModeTab;
 | 
				
			||||||
@@ -41,7 +39,7 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        // Build the stack
 | 
					        // Build the stack
 | 
				
			||||||
        ItemStack stack = new ItemStack( this );
 | 
					        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 );
 | 
					        if( id >= 0 ) stack.getOrCreateTag().putInt( NBT_ID, id );
 | 
				
			||||||
        IColouredItem.setColourBasic( stack, colour );
 | 
					        IColouredItem.setColourBasic( stack, colour );
 | 
				
			||||||
        if( fuelLevel > 0 ) stack.getOrCreateTag().putInt( NBT_FUEL, fuelLevel );
 | 
					        if( fuelLevel > 0 ) stack.getOrCreateTag().putInt( NBT_FUEL, fuelLevel );
 | 
				
			||||||
@@ -63,9 +61,7 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void fillItemCategory( @Nonnull CreativeModeTab group, @Nonnull NonNullList<ItemStack> list )
 | 
					    public void fillItemCategory( @Nonnull CreativeModeTab group, @Nonnull NonNullList<ItemStack> list )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if( !allowdedIn( group ) ) return;
 | 
					        if( !allowedIn( group ) ) return;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        ComputerFamily family = getFamily();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        list.add( create( -1, null, -1, null, null, 0, null ) );
 | 
					        list.add( create( -1, null, -1, null, null, 0, null ) );
 | 
				
			||||||
        TurtleUpgrades.getVanillaUpgrades()
 | 
					        TurtleUpgrades.getVanillaUpgrades()
 | 
				
			||||||
@@ -82,26 +78,26 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem
 | 
				
			|||||||
        ITurtleUpgrade right = getUpgrade( stack, TurtleSide.RIGHT );
 | 
					        ITurtleUpgrade right = getUpgrade( stack, TurtleSide.RIGHT );
 | 
				
			||||||
        if( left != null && right != null )
 | 
					        if( left != null && right != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new TranslatableComponent( baseString + ".upgraded_twice",
 | 
					            return Component.translatable( baseString + ".upgraded_twice",
 | 
				
			||||||
                new TranslatableComponent( right.getUnlocalisedAdjective() ),
 | 
					                Component.translatable( right.getUnlocalisedAdjective() ),
 | 
				
			||||||
                new TranslatableComponent( left.getUnlocalisedAdjective() )
 | 
					                Component.translatable( left.getUnlocalisedAdjective() )
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( left != null )
 | 
					        else if( left != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new TranslatableComponent( baseString + ".upgraded",
 | 
					            return Component.translatable( baseString + ".upgraded",
 | 
				
			||||||
                new TranslatableComponent( left.getUnlocalisedAdjective() )
 | 
					                Component.translatable( left.getUnlocalisedAdjective() )
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( right != null )
 | 
					        else if( right != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new TranslatableComponent( baseString + ".upgraded",
 | 
					            return Component.translatable( baseString + ".upgraded",
 | 
				
			||||||
                new TranslatableComponent( right.getUnlocalisedAdjective() )
 | 
					                Component.translatable( right.getUnlocalisedAdjective() )
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new TranslatableComponent( baseString );
 | 
					            return Component.translatable( baseString );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ import net.minecraftforge.registries.ForgeRegistries;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					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();
 | 
					    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;
 | 
					        return SERIALIZER;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final RecipeSerializer<ImpostorRecipe> SERIALIZER = new BasicRecipeSerializer<>()
 | 
					    public static final RecipeSerializer<ImpostorRecipe> SERIALIZER = new RecipeSerializer<ImpostorRecipe>()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        @Nonnull
 | 
					        @Nonnull
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,7 @@ public final class ImpostorShapelessRecipe extends ShapelessRecipe
 | 
				
			|||||||
        return SERIALIZER;
 | 
					        return SERIALIZER;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final RecipeSerializer<ImpostorShapelessRecipe> SERIALIZER = new BasicRecipeSerializer<>()
 | 
					    public static final RecipeSerializer<ImpostorShapelessRecipe> SERIALIZER = new RecipeSerializer<ImpostorShapelessRecipe>()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        @Nonnull
 | 
					        @Nonnull
 | 
				
			||||||
        @Override
 | 
					        @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
 | 
					public net.minecraft.client.sounds.SoundEngine f_120223_ # executor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# DirectVertexBuffer
 | 
					# 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_166861_ # indexType
 | 
				
			||||||
protected com.mojang.blaze3d.vertex.VertexBuffer f_166863_ # indexCount
 | 
					protected com.mojang.blaze3d.vertex.VertexBuffer f_166863_ # indexCount
 | 
				
			||||||
protected com.mojang.blaze3d.vertex.VertexBuffer f_166864_ # mode
 | 
					protected com.mojang.blaze3d.vertex.VertexBuffer f_166864_ # mode
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
modLoader="javafml"
 | 
					modLoader="javafml"
 | 
				
			||||||
loaderVersion="[40,41)"
 | 
					loaderVersion="[41,42)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
issueTrackerURL="https://github.com/cc-tweaked/CC-Tweaked/issues"
 | 
					issueTrackerURL="https://github.com/cc-tweaked/CC-Tweaked/issues"
 | 
				
			||||||
logoFile="pack.png"
 | 
					logoFile="pack.png"
 | 
				
			||||||
@@ -21,6 +21,6 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a
 | 
				
			|||||||
[[dependencies.computercraft]]
 | 
					[[dependencies.computercraft]]
 | 
				
			||||||
    modId="forge"
 | 
					    modId="forge"
 | 
				
			||||||
    mandatory=true
 | 
					    mandatory=true
 | 
				
			||||||
    versionRange="[40.1.0,41)"
 | 
					    versionRange="[41.0.1,42)"
 | 
				
			||||||
    ordering="NONE"
 | 
					    ordering="NONE"
 | 
				
			||||||
    side="BOTH"
 | 
					    side="BOTH"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,10 +10,12 @@ import net.minecraft.gametest.framework.GameTestAssertException
 | 
				
			|||||||
import net.minecraft.gametest.framework.GameTestAssertPosException
 | 
					import net.minecraft.gametest.framework.GameTestAssertPosException
 | 
				
			||||||
import net.minecraft.gametest.framework.GameTestHelper
 | 
					import net.minecraft.gametest.framework.GameTestHelper
 | 
				
			||||||
import net.minecraft.gametest.framework.GameTestSequence
 | 
					import net.minecraft.gametest.framework.GameTestSequence
 | 
				
			||||||
 | 
					import net.minecraft.resources.ResourceLocation
 | 
				
			||||||
import net.minecraft.world.entity.decoration.ArmorStand
 | 
					import net.minecraft.world.entity.decoration.ArmorStand
 | 
				
			||||||
import net.minecraft.world.level.block.entity.BlockEntity
 | 
					import net.minecraft.world.level.block.entity.BlockEntity
 | 
				
			||||||
import net.minecraft.world.level.block.entity.BlockEntityType
 | 
					import net.minecraft.world.level.block.entity.BlockEntityType
 | 
				
			||||||
import net.minecraft.world.level.block.state.BlockState
 | 
					import net.minecraft.world.level.block.state.BlockState
 | 
				
			||||||
 | 
					import net.minecraftforge.registries.ForgeRegistries
 | 
				
			||||||
import java.nio.file.Files
 | 
					import java.nio.file.Files
 | 
				
			||||||
import java.util.concurrent.CompletableFuture
 | 
					import java.util.concurrent.CompletableFuture
 | 
				
			||||||
import java.util.concurrent.ExecutionException
 | 
					import java.util.concurrent.ExecutionException
 | 
				
			||||||
@@ -135,12 +137,14 @@ fun GameTestHelper.sequence(run: GameTestSequence.() -> GameTestSequence) {
 | 
				
			|||||||
    run(startSequence()).thenSucceed()
 | 
					    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 {
 | 
					fun <T : BlockEntity> GameTestHelper.getBlockEntity(pos: BlockPos, type: BlockEntityType<T>): T {
 | 
				
			||||||
    val tile = getBlockEntity(pos)
 | 
					    val tile = getBlockEntity(pos)
 | 
				
			||||||
    @Suppress("UNCHECKED_CAST")
 | 
					    @Suppress("UNCHECKED_CAST")
 | 
				
			||||||
    return when {
 | 
					    return when {
 | 
				
			||||||
        tile == null -> throw GameTestAssertPosException("Expected ${type.registryName}, but no tile was there", 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 ${type.registryName} but got ${tile.type.registryName}", 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
 | 
					        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.TestCommand;
 | 
				
			||||||
import net.minecraft.gametest.framework.TestFunction;
 | 
					import net.minecraft.gametest.framework.TestFunction;
 | 
				
			||||||
import net.minecraft.nbt.CompoundTag;
 | 
					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.MinecraftServer;
 | 
				
			||||||
import net.minecraft.server.level.ServerPlayer;
 | 
					import net.minecraft.server.level.ServerPlayer;
 | 
				
			||||||
import net.minecraft.world.entity.Entity;
 | 
					import net.minecraft.world.entity.Entity;
 | 
				
			||||||
@@ -88,7 +88,7 @@ class CCTestCommand
 | 
				
			|||||||
                ArmorStand armorStand = EntityType.ARMOR_STAND.create( player.getLevel() );
 | 
					                ArmorStand armorStand = EntityType.ARMOR_STAND.create( player.getLevel() );
 | 
				
			||||||
                armorStand.readAdditionalSaveData( nbt );
 | 
					                armorStand.readAdditionalSaveData( nbt );
 | 
				
			||||||
                armorStand.copyPosition( player );
 | 
					                armorStand.copyPosition( player );
 | 
				
			||||||
                armorStand.setCustomName( new TextComponent( info.getTestName() ) );
 | 
					                armorStand.setCustomName( Component.literal( info.getTestName() ) );
 | 
				
			||||||
                player.getLevel().addFreshEntity( armorStand );
 | 
					                player.getLevel().addFreshEntity( armorStand );
 | 
				
			||||||
                return 0;
 | 
					                return 0;
 | 
				
			||||||
            } ) )
 | 
					            } ) )
 | 
				
			||||||
@@ -137,7 +137,7 @@ class CCTestCommand
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private static int error( CommandSourceStack source, String message )
 | 
					    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;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,20 +10,6 @@ import net.minecraft.client.Minecraft;
 | 
				
			|||||||
import net.minecraft.client.ParticleStatus;
 | 
					import net.minecraft.client.ParticleStatus;
 | 
				
			||||||
import net.minecraft.client.gui.screens.TitleScreen;
 | 
					import net.minecraft.client.gui.screens.TitleScreen;
 | 
				
			||||||
import net.minecraft.client.tutorial.TutorialSteps;
 | 
					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.api.distmarker.Dist;
 | 
				
			||||||
import net.minecraftforge.client.event.ScreenEvent;
 | 
					import net.minecraftforge.client.event.ScreenEvent;
 | 
				
			||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
					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.LogManager;
 | 
				
			||||||
import org.apache.logging.log4j.Logger;
 | 
					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 )
 | 
					@Mod.EventBusSubscriber( modid = TestMod.MOD_ID, value = Dist.CLIENT )
 | 
				
			||||||
public final class ClientHooks
 | 
					public final class ClientHooks
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -61,13 +42,14 @@ public final class ClientHooks
 | 
				
			|||||||
        Minecraft minecraft = Minecraft.getInstance();
 | 
					        Minecraft minecraft = Minecraft.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Clear some options before we get any further.
 | 
					        // Clear some options before we get any further.
 | 
				
			||||||
        minecraft.options.autoJump = false;
 | 
					        minecraft.options.autoJump().set( false );
 | 
				
			||||||
        minecraft.options.renderClouds = CloudStatus.OFF;
 | 
					        minecraft.options.cloudStatus().set( CloudStatus.OFF );
 | 
				
			||||||
        minecraft.options.particles = ParticleStatus.MINIMAL;
 | 
					        minecraft.options.particles().set( ParticleStatus.MINIMAL );
 | 
				
			||||||
        minecraft.options.tutorialStep = TutorialSteps.NONE;
 | 
					        minecraft.options.tutorialStep = TutorialSteps.NONE;
 | 
				
			||||||
        minecraft.options.renderDistance = 6;
 | 
					        minecraft.options.renderDistance().set( 6 );
 | 
				
			||||||
        minecraft.options.gamma = 1.0;
 | 
					        minecraft.options.gamma().set( 1.0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
        if( minecraft.getLevelSource().levelExists( "test" ) )
 | 
					        if( minecraft.getLevelSource().levelExists( "test" ) )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LOG.info( "World exists, loading it" );
 | 
					            LOG.info( "World exists, loading it" );
 | 
				
			||||||
@@ -102,5 +84,6 @@ public final class ClientHooks
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
            Minecraft.getInstance().createLevel( "test", settings, registries, generator );
 | 
					            Minecraft.getInstance().createLevel( "test", settings, registries, generator );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user