mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-13 05:19:59 +00:00
Update to MC 1.20.6
- Update EMI and REI integration, and fix some issues with the upgrade crafting hooks. - Just use smooth stone for recipes, not #c:stone. We're mirroring redstone's crafting recipes here. - Some cleanup to printouts. - Remote upgrade data generators - these can be replaced with the standard registry data generators. - Remove the API's PlatformHelper - we no longer have any platform-specific code in the API.
This commit is contained in:
parent
94c864759d
commit
2c0d8263d3
@ -30,11 +30,6 @@ subsystems {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
|
||||
implementation("net.neoforged:neoforge:${libs.findVersion("neoForge").get()}")
|
||||
}
|
||||
|
||||
MinecraftConfigurations.setup(project)
|
||||
|
||||
extensions.configure(CCTweakedExtension::class.java) {
|
||||
|
@ -56,7 +56,6 @@ repositories {
|
||||
includeGroup("mezz.jei")
|
||||
includeGroup("org.teavm")
|
||||
includeModule("com.terraformersmc", "modmenu")
|
||||
includeModule("me.lucko", "fabric-permissions-api")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,4 +13,4 @@ isUnstable=true
|
||||
modVersion=1.110.3
|
||||
|
||||
# Minecraft properties: We want to configure this here so we can read it in settings.gradle
|
||||
mcVersion=1.20.5
|
||||
mcVersion=1.20.6
|
||||
|
@ -7,14 +7,14 @@
|
||||
# Minecraft
|
||||
# MC version is specified in gradle.properties, as we need that in settings.gradle.
|
||||
# Remember to update corresponding versions in fabric.mod.json/neoforge.mods.toml
|
||||
fabric-api = "0.97.6+1.20.5"
|
||||
fabric-api = "0.98.0+1.20.6"
|
||||
fabric-loader = "0.15.10"
|
||||
neoForge = "20.5.20-beta"
|
||||
neoForge = "20.6.48-beta"
|
||||
neoForgeSpi = "8.0.1"
|
||||
mixin = "0.8.5"
|
||||
parchment = "2024.04.14"
|
||||
parchmentMc = "1.20.4"
|
||||
yarn = "1.20.5+build.1"
|
||||
parchment = "2024.05.01"
|
||||
parchmentMc = "1.20.6"
|
||||
yarn = "1.20.6+build.1"
|
||||
|
||||
# Core dependencies (these versions are tied to the version Minecraft uses)
|
||||
fastutil = "8.5.12"
|
||||
@ -36,14 +36,14 @@ kotlin-coroutines = "1.7.3"
|
||||
nightConfig = "3.6.7"
|
||||
|
||||
# Minecraft mods
|
||||
emi = "1.0.30+1.20.4"
|
||||
fabricPermissions = "0.3.20230723"
|
||||
emi = "1.1.5+1.20.6"
|
||||
fabricPermissions = "0.3.1"
|
||||
iris = "1.6.14+1.20.4"
|
||||
jei = "17.3.0.48"
|
||||
modmenu = "9.0.0"
|
||||
moreRed = "4.0.0.4"
|
||||
oculus = "1.2.5"
|
||||
rei = "14.0.688"
|
||||
rei = "15.0.728"
|
||||
rubidium = "0.6.1"
|
||||
sodium = "mc1.20-0.4.10"
|
||||
mixinExtra = "0.3.5"
|
||||
|
@ -21,4 +21,16 @@ tasks.javadoc {
|
||||
|
||||
// Include the core-api in our javadoc export. This is wrong, but it means we can export a single javadoc dump.
|
||||
source(project(":core-api").sourceSets.main.map { it.allJava })
|
||||
|
||||
options {
|
||||
this as StandardJavadocDocletOptions
|
||||
addBooleanOption("-allow-script-in-comments", true)
|
||||
bottom(
|
||||
"""
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@v1.29.0/components/prism-core.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@v1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
||||
<link href=" https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css " rel="stylesheet">
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,14 @@
|
||||
|
||||
package dan200.computercraft.api.pocket;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.upgrades.UpgradeBase;
|
||||
import dan200.computercraft.api.upgrades.UpgradeType;
|
||||
import dan200.computercraft.impl.ComputerCraftAPIService;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -21,11 +23,11 @@ import javax.annotation.Nullable;
|
||||
* {@link UpgradeType} instance, which are then registered in a registry.
|
||||
* <p>
|
||||
* You then write a JSON file in your mod's {@literal data/} folder. This is then parsed when the world is loaded, and
|
||||
* the upgrade automatically registered. It is recommended this is done via {@linkplain PocketUpgradeDataProvider data
|
||||
* generators}.
|
||||
* the upgrade automatically registered. It is recommended this is done via
|
||||
* <a href="../upgrades/UpgradeType.html#datagen">data generators</a>.
|
||||
*
|
||||
* <h2>Example</h2>
|
||||
* <pre>{@code
|
||||
* {@snippet lang="java" :
|
||||
* // We use Forge's DeferredRegister to register our upgrade type. Fabric mods may register their type directly.
|
||||
* static final DeferredRegister<UpgradeType<? extends IPocketUpgrade>> POCKET_UPGRADES = DeferredRegister.create(IPocketUpgrade.typeRegistry(), "my_mod");
|
||||
*
|
||||
@ -35,19 +37,19 @@ import javax.annotation.Nullable;
|
||||
*
|
||||
* // Then in your constructor
|
||||
* POCKET_UPGRADES.register(bus);
|
||||
* }</pre>
|
||||
* }
|
||||
* <p>
|
||||
* We can then define a new upgrade using JSON by placing the following in
|
||||
* {@code data/<my_mod>/computercraft/pocket_upgrades/<my_upgrade_id>.json}.
|
||||
* <pre>{@code
|
||||
* {@code data/<my_mod>/computercraft/pocket_upgrade/<my_upgrade_id>.json}.
|
||||
* {@snippet lang="json" :
|
||||
* {
|
||||
* "type": my_mod:my_upgrade",
|
||||
* "type": "my_mod:my_upgrade"
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* {@link PocketUpgradeDataProvider} provides a data provider to aid with generating these JSON files.
|
||||
*/
|
||||
public interface IPocketUpgrade extends UpgradeBase {
|
||||
ResourceKey<Registry<IPocketUpgrade>> REGISTRY = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "pocket_upgrade"));
|
||||
|
||||
/**
|
||||
* The registry key for pocket upgrade types.
|
||||
*
|
||||
|
@ -1,30 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.api.pocket;
|
||||
|
||||
import dan200.computercraft.api.upgrades.UpgradeDataProvider;
|
||||
import dan200.computercraft.api.upgrades.UpgradeType;
|
||||
import dan200.computercraft.impl.ComputerCraftAPIService;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.PackOutput;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A data provider to generate pocket computer upgrades.
|
||||
* <p>
|
||||
* This should be subclassed and registered to a {@link DataGenerator.PackGenerator}. Override the
|
||||
* {@link #addUpgrades(Consumer)} function, construct each upgrade, and pass them off to the provided consumer to
|
||||
* generate them.
|
||||
*
|
||||
* @see IPocketUpgrade
|
||||
* @see UpgradeType
|
||||
*/
|
||||
public abstract class PocketUpgradeDataProvider extends UpgradeDataProvider<IPocketUpgrade> {
|
||||
public PocketUpgradeDataProvider(PackOutput output) {
|
||||
super(output, "Pocket Computer Upgrades", RegistryHelper.POCKET_UPGRADE, ComputerCraftAPIService.get().pocketUpgradeCodec());
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.upgrades.UpgradeBase;
|
||||
import dan200.computercraft.api.upgrades.UpgradeType;
|
||||
@ -12,6 +13,7 @@ import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -23,11 +25,11 @@ import javax.annotation.Nullable;
|
||||
* {@link UpgradeType} instance, which are then registered in a registry.
|
||||
* <p>
|
||||
* You then write a JSON file in your mod's {@literal data/} folder. This is then parsed when the world is loaded, and
|
||||
* the upgrade automatically registered. It is recommended this is done via {@linkplain TurtleUpgradeDataProvider data
|
||||
* generators}.
|
||||
* the upgrade automatically registered. It is recommended this is done via
|
||||
* <a href="../upgrades/UpgradeType.html#datagen">data generators</a>.
|
||||
*
|
||||
* <h2>Example</h2>
|
||||
* <pre>{@code
|
||||
* {@snippet lang="java" :
|
||||
* // We use Forge's DeferredRegister to register our upgrade type. Fabric mods may register their type directly.
|
||||
* static final DeferredRegister<UpgradeType<? extends ITurtleUpgrade>> TURTLE_UPGRADES = DeferredRegister.create(ITurtleUpgrade.typeRegistry(), "my_mod");
|
||||
*
|
||||
@ -37,28 +39,38 @@ import javax.annotation.Nullable;
|
||||
*
|
||||
* // Then in your constructor
|
||||
* TURTLE_UPGRADES.register(bus);
|
||||
* }</pre>
|
||||
* }
|
||||
* <p>
|
||||
* We can then define a new upgrade using JSON by placing the following in
|
||||
* {@literal data/<my_mod>/computercraft/turtle_upgrades/<my_upgrade_id>.json}}.
|
||||
*
|
||||
* <pre>{@code
|
||||
* {@code data/<my_mod>/computercraft/turtle_upgrade/<my_upgrade_id>.json}.
|
||||
* <p>
|
||||
* {@snippet lang="json" :
|
||||
* {
|
||||
* "type": "my_mod:my_upgrade"
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* {@link TurtleUpgradeDataProvider} provides a data provider to aid with generating these JSON files.
|
||||
* }
|
||||
* <p>
|
||||
* Finally, we need to register a model for our upgrade, see
|
||||
* {@link dan200.computercraft.api.client.turtle.TurtleUpgradeModeller} for more information.
|
||||
*
|
||||
* <pre>{@code
|
||||
* // Register our model inside FMLClientSetupEvent
|
||||
* ComputerCraftAPIClient.registerTurtleUpgradeModeller(MY_UPGRADE.get(), TurtleUpgradeModeller.flatItem())
|
||||
* }</pre>
|
||||
*/
|
||||
public interface ITurtleUpgrade extends UpgradeBase {
|
||||
/**
|
||||
* The registry in which turtle upgrades are stored.
|
||||
*/
|
||||
ResourceKey<Registry<ITurtleUpgrade>> REGISTRY = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "turtle_upgrade"));
|
||||
|
||||
/**
|
||||
* Create a {@link ResourceKey} for a turtle upgrade given a {@link ResourceLocation}.
|
||||
* <p>
|
||||
* This should only be called from within data generation code. Do not hard code references to your upgrades!
|
||||
*
|
||||
* @param id The id of the turtle upgrade.
|
||||
* @return The upgrade registry key.
|
||||
*/
|
||||
static ResourceKey<ITurtleUpgrade> createKey(ResourceLocation id) {
|
||||
return ResourceKey.create(REGISTRY, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* The registry key for turtle upgrade types.
|
||||
*
|
||||
|
@ -0,0 +1,157 @@
|
||||
// SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftTags;
|
||||
import dan200.computercraft.api.upgrades.UpgradeBase;
|
||||
import dan200.computercraft.impl.ComputerCraftAPIService;
|
||||
import dan200.computercraft.impl.upgrades.TurtleToolSpec;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.data.worldgen.BootstrapContext;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A builder for custom turtle tool upgrades.
|
||||
* <p>
|
||||
* This can be used from your <a href="../upgrades/UpgradeType.html#datagen">data generator</a> code in order to
|
||||
* register turtle tools for your mod's tools.
|
||||
*
|
||||
* <h2>Example:</h2>
|
||||
* {@snippet lang = "java":
|
||||
* import net.minecraft.data.worldgen.BootstrapContext;
|
||||
* import net.minecraft.resources.ResourceLocation;
|
||||
* import net.minecraft.world.item.Items;
|
||||
*
|
||||
* public void registerTool(BootstrapContext<ITurtleUpgrade> upgrades) {
|
||||
* TurtleToolBuilder.tool(new ResourceLocation("my_mod", "wooden_pickaxe"), Items.WOODEN_PICKAXE).register(upgrades);
|
||||
* }
|
||||
*}
|
||||
*/
|
||||
public final class TurtleToolBuilder {
|
||||
private final ResourceKey<ITurtleUpgrade> id;
|
||||
private final Item item;
|
||||
private Component adjective;
|
||||
private float damageMultiplier = TurtleToolSpec.DEFAULT_DAMAGE_MULTIPLIER;
|
||||
private @Nullable TagKey<Block> breakable;
|
||||
private boolean allowEnchantments = false;
|
||||
private TurtleToolDurability consumeDurability = TurtleToolDurability.NEVER;
|
||||
|
||||
private TurtleToolBuilder(ResourceKey<ITurtleUpgrade> id, Item item) {
|
||||
this.id = id;
|
||||
adjective = Component.translatable(UpgradeBase.getDefaultAdjective(id.location()));
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public static TurtleToolBuilder tool(ResourceLocation id, Item item) {
|
||||
return new TurtleToolBuilder(ITurtleUpgrade.createKey(id), item);
|
||||
}
|
||||
|
||||
public static TurtleToolBuilder tool(ResourceKey<ITurtleUpgrade> id, Item item) {
|
||||
return new TurtleToolBuilder(id, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id for this turtle tool.
|
||||
*
|
||||
* @return The upgrade id.
|
||||
*/
|
||||
public ResourceKey<ITurtleUpgrade> id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a custom adjective for this tool. By default this takes its adjective from the upgrade id.
|
||||
*
|
||||
* @param adjective The new adjective to use.
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public TurtleToolBuilder adjective(Component adjective) {
|
||||
this.adjective = adjective;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of damage a swing of this tool will do. This is multiplied by {@link Attributes#ATTACK_DAMAGE} to
|
||||
* get the final damage.
|
||||
*
|
||||
* @param damageMultiplier The damage multiplier.
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public TurtleToolBuilder damageMultiplier(float damageMultiplier) {
|
||||
this.damageMultiplier = damageMultiplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that this upgrade allows items which have been {@linkplain ItemStack#isEnchanted() enchanted} or have
|
||||
* {@linkplain DataComponents#ATTRIBUTE_MODIFIERS custom attribute modifiers}.
|
||||
*
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public TurtleToolBuilder allowEnchantments() {
|
||||
allowEnchantments = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set when the tool will consume durability.
|
||||
*
|
||||
* @param durability The durability predicate.
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public TurtleToolBuilder consumeDurability(TurtleToolDurability durability) {
|
||||
consumeDurability = durability;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a list of breakable blocks. If not given, the tool can break all blocks. If given, only blocks
|
||||
* in this tag, those in {@link ComputerCraftTags.Blocks#TURTLE_ALWAYS_BREAKABLE} and "insta-mine" ones can
|
||||
* be broken.
|
||||
*
|
||||
* @param breakable The tag containing all blocks breakable by this item.
|
||||
* @return The tool builder, for further use.
|
||||
* @see ComputerCraftTags.Blocks
|
||||
*/
|
||||
public TurtleToolBuilder breakable(TagKey<Block> breakable) {
|
||||
this.breakable = breakable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the turtle tool upgrade.
|
||||
*
|
||||
* @return The constructed upgrade.
|
||||
*/
|
||||
public ITurtleUpgrade build() {
|
||||
return ComputerCraftAPIService.get().createTurtleTool(new TurtleToolSpec(
|
||||
adjective,
|
||||
item,
|
||||
damageMultiplier,
|
||||
allowEnchantments,
|
||||
consumeDurability,
|
||||
Optional.ofNullable(breakable)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build this upgrade and register it for datagen.
|
||||
*
|
||||
* @param upgrades The registry this upgrade should be added to.
|
||||
*/
|
||||
public void register(BootstrapContext<ITurtleUpgrade> upgrades) {
|
||||
upgrades.register(id(), build());
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
/**
|
||||
* Indicates if an equipped turtle item will consume durability.
|
||||
*
|
||||
* @see TurtleUpgradeDataProvider.ToolBuilder#consumeDurability(TurtleToolDurability)
|
||||
* @see TurtleToolBuilder#consumeDurability(TurtleToolDurability)
|
||||
*/
|
||||
public enum TurtleToolDurability implements StringRepresentable {
|
||||
/**
|
||||
|
@ -1,151 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftTags;
|
||||
import dan200.computercraft.api.upgrades.UpgradeBase;
|
||||
import dan200.computercraft.api.upgrades.UpgradeDataProvider;
|
||||
import dan200.computercraft.impl.ComputerCraftAPIService;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.impl.upgrades.TurtleToolSpec;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A data provider to generate turtle upgrades.
|
||||
* <p>
|
||||
* This should be subclassed and registered to a {@link DataGenerator.PackGenerator}. Override the
|
||||
* {@link #addUpgrades(Consumer)} function, construct each upgrade, and pass them off to the provided consumer to
|
||||
* generate them.
|
||||
*
|
||||
* @see ITurtleUpgrade
|
||||
*/
|
||||
public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITurtleUpgrade> {
|
||||
public TurtleUpgradeDataProvider(PackOutput output) {
|
||||
super(output, "Turtle Upgrades", RegistryHelper.TURTLE_UPGRADE, ComputerCraftAPIService.get().turtleUpgradeCodec());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new turtle tool upgrade, such as a pickaxe or shovel.
|
||||
*
|
||||
* @param id The ID of this tool.
|
||||
* @param item The item used for tool actions. Note, this doesn't inherit all properties of the tool, you may need
|
||||
* to specify {@link ToolBuilder#damageMultiplier(float)} and {@link ToolBuilder#breakable(TagKey)}.
|
||||
* @return A tool builder,
|
||||
*/
|
||||
public final ToolBuilder tool(ResourceLocation id, Item item) {
|
||||
return new ToolBuilder(id, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for custom turtle tool upgrades.
|
||||
*
|
||||
* @see #tool(ResourceLocation, Item)
|
||||
*/
|
||||
public final class ToolBuilder {
|
||||
private final ResourceLocation id;
|
||||
private final Item item;
|
||||
private Component adjective;
|
||||
private @Nullable Item craftingItem;
|
||||
private float damageMultiplier = TurtleToolSpec.DEFAULT_DAMAGE_MULTIPLIER;
|
||||
private @Nullable TagKey<Block> breakable;
|
||||
private boolean allowEnchantments = false;
|
||||
private TurtleToolDurability consumeDurability = TurtleToolDurability.NEVER;
|
||||
|
||||
ToolBuilder(ResourceLocation id, Item item) {
|
||||
this.id = id;
|
||||
adjective = Component.translatable(UpgradeBase.getDefaultAdjective(id));
|
||||
this.item = item;
|
||||
craftingItem = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a custom adjective for this tool. By default this takes its adjective from the upgrade id.
|
||||
*
|
||||
* @param adjective The new adjective to use.
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public ToolBuilder adjective(Component adjective) {
|
||||
this.adjective = adjective;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of damage a swing of this tool will do. This is multiplied by {@link Attributes#ATTACK_DAMAGE} to
|
||||
* get the final damage.
|
||||
*
|
||||
* @param damageMultiplier The damage multiplier.
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public ToolBuilder damageMultiplier(float damageMultiplier) {
|
||||
this.damageMultiplier = damageMultiplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that this upgrade allows items which have been {@linkplain ItemStack#isEnchanted() enchanted} or have
|
||||
* {@linkplain DataComponents#ATTRIBUTE_MODIFIERS custom attribute modifiers}.
|
||||
*
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public ToolBuilder allowEnchantments() {
|
||||
allowEnchantments = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set when the tool will consume durability.
|
||||
*
|
||||
* @param durability The durability predicate.
|
||||
* @return The tool builder, for further use.
|
||||
*/
|
||||
public ToolBuilder consumeDurability(TurtleToolDurability durability) {
|
||||
consumeDurability = durability;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a list of breakable blocks. If not given, the tool can break all blocks. If given, only blocks
|
||||
* in this tag, those in {@link ComputerCraftTags.Blocks#TURTLE_ALWAYS_BREAKABLE} and "insta-mine" ones can
|
||||
* be broken.
|
||||
*
|
||||
* @param breakable The tag containing all blocks breakable by this item.
|
||||
* @return The tool builder, for further use.
|
||||
* @see ComputerCraftTags.Blocks
|
||||
*/
|
||||
public ToolBuilder breakable(TagKey<Block> breakable) {
|
||||
this.breakable = breakable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register this as an upgrade.
|
||||
*
|
||||
* @param add The callback given to {@link #addUpgrades(Consumer)}.
|
||||
*/
|
||||
public void add(Consumer<Upgrade<ITurtleUpgrade>> add) {
|
||||
upgrade(id, ComputerCraftAPIService.get().createTurtleTool(new TurtleToolSpec(
|
||||
adjective,
|
||||
item,
|
||||
damageMultiplier,
|
||||
allowEnchantments,
|
||||
consumeDurability,
|
||||
Optional.ofNullable(breakable)
|
||||
))).add(add);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.api.upgrades;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import dan200.computercraft.impl.PlatformHelper;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A data generator/provider for turtle and pocket computer upgrades. This should not be extended directly, instead see
|
||||
* the other subclasses.
|
||||
*
|
||||
* @param <T> The base class of upgrades.
|
||||
*/
|
||||
public abstract class UpgradeDataProvider<T extends UpgradeBase> implements DataProvider {
|
||||
private final PackOutput output;
|
||||
private final String name;
|
||||
private final ResourceKey<Registry<T>> registryName;
|
||||
private final Codec<T> codec;
|
||||
|
||||
private @Nullable Map<ResourceKey<T>, T> upgrades;
|
||||
|
||||
@ApiStatus.Internal
|
||||
protected UpgradeDataProvider(PackOutput output, String name, ResourceKey<Registry<T>> registryName, Codec<T> codec) {
|
||||
this.output = output;
|
||||
this.name = name;
|
||||
this.registryName = registryName;
|
||||
this.codec = codec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new upgrade.
|
||||
*
|
||||
* @param id The ID of the upgrade to create.
|
||||
* @param upgrade The upgrade to add.
|
||||
* @return The constructed upgrade, ready to be passed off to {@link #addUpgrades(Consumer)}'s consumer.
|
||||
*/
|
||||
protected final Upgrade<T> upgrade(ResourceLocation id, T upgrade) {
|
||||
return new Upgrade<>(id, upgrade, j -> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all turtle or pocket computer upgrades.
|
||||
* <p>
|
||||
* <strong>Example usage:</strong>
|
||||
* <pre>{@code
|
||||
* protected void addUpgrades(Consumer<Upgrade<ITurtleUpgrade>> addUpgrade) {
|
||||
* upgrade(new ResourceLocation("mymod", "speaker"), new TurtleSpeaker(new ItemStack(Items.NOTE_BLOCK))).add(addUpgrade);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param addUpgrade A callback used to register an upgrade.
|
||||
*/
|
||||
protected abstract void addUpgrades(Consumer<Upgrade<T>> addUpgrade);
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> run(CachedOutput cache) {
|
||||
var base = output.createPathProvider(PackOutput.Target.DATA_PACK, registryName.location().getNamespace() + "/" + registryName.location().getPath());
|
||||
|
||||
Map<ResourceKey<T>, T> upgrades = new LinkedHashMap<>();
|
||||
|
||||
List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||
addUpgrades(upgrade -> {
|
||||
var id = ResourceKey.create(registryName, upgrade.id);
|
||||
if (upgrades.containsKey(id)) throw new IllegalStateException("Duplicate upgrade " + upgrade.id);
|
||||
|
||||
var json = (JsonObject) codec.encodeStart(JsonOps.INSTANCE, upgrade.upgrade).getOrThrow();
|
||||
upgrade.serialise.accept(json);
|
||||
|
||||
futures.add(DataProvider.saveStable(cache, json, base.json(upgrade.id)));
|
||||
|
||||
upgrades.put(id, upgrade.upgrade);
|
||||
});
|
||||
|
||||
this.upgrades = Collections.unmodifiableMap(upgrades);
|
||||
|
||||
return Util.sequenceFailFast(futures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered upgrades.
|
||||
*
|
||||
* @return The map of registered upgrades.
|
||||
*/
|
||||
public Map<ResourceKey<T>, T> getGeneratedUpgrades() {
|
||||
var upgrades = this.upgrades;
|
||||
if (upgrades == null) throw new IllegalStateException("Upgrades are not available yet");
|
||||
return upgrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructed upgrade instance, produced {@link #addUpgrades(Consumer)}.
|
||||
*
|
||||
* @param <T> The type of upgrade.
|
||||
*/
|
||||
public static final class Upgrade<T extends UpgradeBase> {
|
||||
private final ResourceLocation id;
|
||||
private final T upgrade;
|
||||
private final Consumer<JsonObject> serialise;
|
||||
|
||||
private Upgrade(ResourceLocation id, T upgrade, Consumer<JsonObject> serialise) {
|
||||
this.id = id;
|
||||
this.upgrade = upgrade;
|
||||
this.serialise = serialise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for registering an upgrade.
|
||||
*
|
||||
* @param add The callback given to {@link #addUpgrades(Consumer)}
|
||||
*/
|
||||
public void add(Consumer<Upgrade<T>> add) {
|
||||
add.accept(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new {@link Upgrade} which requires the given mod to be present.
|
||||
* <p>
|
||||
* This uses mod-loader-specific hooks (Forge's crafting conditions and Fabric's resource conditions). If using
|
||||
* this in a multi-loader setup, you must generate resources separately for the two loaders.
|
||||
*
|
||||
* @param modId The id of the mod.
|
||||
* @return A new upgrade instance.
|
||||
*/
|
||||
public Upgrade<T> requireMod(String modId) {
|
||||
return new Upgrade<>(id, upgrade, json -> {
|
||||
PlatformHelper.get().addRequiredModCondition(json, modId);
|
||||
serialise.accept(json);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -6,11 +6,10 @@ package dan200.computercraft.api.upgrades;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.pocket.PocketUpgradeDataProvider;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeDataProvider;
|
||||
import dan200.computercraft.impl.upgrades.UpgradeTypeImpl;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.data.registries.RegistryPatchGenerator;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunction;
|
||||
@ -33,8 +32,35 @@ import java.util.function.Function;
|
||||
* {@link IPocketUpgrade#typeRegistry()}).
|
||||
* <p>
|
||||
* In order to register the actual upgrade, a JSON file referencing your upgrade type should be added to a datapack. It
|
||||
* is recommended to do this via the data generators (see {@link TurtleUpgradeDataProvider} and
|
||||
* {@link PocketUpgradeDataProvider}).
|
||||
* is recommended to do this via the data generators.
|
||||
*
|
||||
* <h2 id="datagen">Data Generation</h2>
|
||||
* As turtle and pocket upgrades are just loaded using vanilla's dynamic loaders, one may use the same data generation
|
||||
* tools as you would for any other dynamic registry.
|
||||
* <p>
|
||||
* This can typically be done by extending vanilla's built-in registries using {@link RegistryPatchGenerator}, and then
|
||||
* writing out the new registries using {@code net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider}
|
||||
* on Fabric or {@code net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider} on Forge.
|
||||
* <p>
|
||||
* {@snippet lang="java" :
|
||||
* import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
* import net.minecraft.Util;
|
||||
* import net.minecraft.core.HolderLookup;
|
||||
* import net.minecraft.core.RegistrySetBuilder;
|
||||
* import net.minecraft.data.DataGenerator;
|
||||
* import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider;
|
||||
*
|
||||
* import java.util.concurrent.CompletableFuture;
|
||||
*
|
||||
* public void generate(DataGenerator.PackGenerator output, CompletableFuture<HolderLookup.Provider> registries) {
|
||||
* var newRegistries = RegistryPatchGenerator.createLookup(registries, Util.make(new RegistrySetBuilder(), builder -> {
|
||||
* builder.add(ITurtleUpgrade.REGISTRY, upgrades -> {
|
||||
* upgrades.register(ITurtleUpgrade.createKey(new ResourceLocation("my_mod", "my_upgrade")), new MyUpgrade());
|
||||
* });
|
||||
* }));
|
||||
* output.addProvider(o -> new DatapackBuiltinEntriesProvider(o, newRegistries, Set.of("my_mod")));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param <T> The upgrade subclass that this upgrade type represents.
|
||||
* @see ITurtleUpgrade
|
||||
|
@ -1,54 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import dan200.computercraft.api.upgrades.UpgradeDataProvider;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Abstraction layer for Forge and Fabric. See implementations for more details.
|
||||
* <p>
|
||||
* Do <strong>NOT</strong> directly reference this class. It exists for internal use by the API.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public interface PlatformHelper {
|
||||
/**
|
||||
* Get the current {@link PlatformHelper} instance.
|
||||
*
|
||||
* @return The current instance.
|
||||
*/
|
||||
static PlatformHelper get() {
|
||||
var instance = Instance.INSTANCE;
|
||||
return instance == null ? Services.raise(PlatformHelper.class, Instance.ERROR) : instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a resource condition which requires a mod to be loaded. This should be used by data providers such as
|
||||
* {@link UpgradeDataProvider}.
|
||||
*
|
||||
* @param object The JSON object we're generating.
|
||||
* @param modId The mod ID that we require.
|
||||
*/
|
||||
void addRequiredModCondition(JsonObject object, String modId);
|
||||
|
||||
final class Instance {
|
||||
static final @Nullable PlatformHelper INSTANCE;
|
||||
static final @Nullable Throwable ERROR;
|
||||
|
||||
static {
|
||||
// We don't want class initialisation to fail here (as that results in confusing errors). Instead, capture
|
||||
// the error and rethrow it when accessing. This should be JITted away in the common case.
|
||||
var helper = Services.tryLoad(PlatformHelper.class);
|
||||
INSTANCE = helper.instance();
|
||||
ERROR = helper.error();
|
||||
}
|
||||
|
||||
private Instance() {
|
||||
}
|
||||
}
|
||||
}
|
@ -6,12 +6,15 @@ package dan200.computercraft.client.integration.emi;
|
||||
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.integration.RecipeModHelpers;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
import dan200.computercraft.shared.turtle.items.TurtleItem;
|
||||
import dev.emi.emi.api.EmiEntrypoint;
|
||||
import dev.emi.emi.api.EmiPlugin;
|
||||
import dev.emi.emi.api.EmiRegistry;
|
||||
import dev.emi.emi.api.stack.Comparison;
|
||||
import dev.emi.emi.api.stack.EmiStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import java.util.function.BiPredicate;
|
||||
@ -25,6 +28,10 @@ public class EMIComputerCraft implements EmiPlugin {
|
||||
|
||||
registry.setDefaultComparison(ModRegistry.Items.POCKET_COMPUTER_NORMAL.get(), pocketComparison);
|
||||
registry.setDefaultComparison(ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get(), pocketComparison);
|
||||
|
||||
for (var stack : RecipeModHelpers.getExtraStacks(Minecraft.getInstance().level.registryAccess())) {
|
||||
registry.addEmiStack(EmiStack.of(stack));
|
||||
}
|
||||
}
|
||||
|
||||
private static final Comparison turtleComparison = compareStacks((left, right)
|
||||
|
@ -11,14 +11,12 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.api.upgrades.UpgradeType;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.impl.UpgradeManager;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -32,14 +30,6 @@ public final class TurtleUpgradeModellers {
|
||||
private static final Map<UpgradeType<? extends ITurtleUpgrade>, TurtleUpgradeModeller<?>> turtleModels = new ConcurrentHashMap<>();
|
||||
private static volatile boolean fetchedModels;
|
||||
|
||||
/**
|
||||
* In order to avoid a double lookup of {@link ITurtleUpgrade} to {@link UpgradeManager.UpgradeWrapper} to
|
||||
* {@link TurtleUpgradeModeller}, we maintain a cache here.
|
||||
* <p>
|
||||
* Turtle upgrades may be removed as part of datapack reloads, so we use a weak map to avoid the memory leak.
|
||||
*/
|
||||
private static final WeakHashMap<ITurtleUpgrade, TurtleUpgradeModeller<?>> modelCache = new WeakHashMap<>();
|
||||
|
||||
private TurtleUpgradeModellers() {
|
||||
}
|
||||
|
||||
@ -57,20 +47,17 @@ public final class TurtleUpgradeModellers {
|
||||
}
|
||||
|
||||
public static TransformedModel getModel(ITurtleUpgrade upgrade, ITurtleAccess access, TurtleSide side) {
|
||||
@SuppressWarnings("unchecked")
|
||||
var modeller = (TurtleUpgradeModeller<ITurtleUpgrade>) modelCache.computeIfAbsent(upgrade, TurtleUpgradeModellers::getModeller);
|
||||
return modeller.getModel(upgrade, access, side, access.getUpgradeData(side));
|
||||
return getModeller(upgrade).getModel(upgrade, access, side, access.getUpgradeData(side));
|
||||
}
|
||||
|
||||
public static TransformedModel getModel(ITurtleUpgrade upgrade, DataComponentPatch data, TurtleSide side) {
|
||||
@SuppressWarnings("unchecked")
|
||||
var modeller = (TurtleUpgradeModeller<ITurtleUpgrade>) modelCache.computeIfAbsent(upgrade, TurtleUpgradeModellers::getModeller);
|
||||
return modeller.getModel(upgrade, null, side, data);
|
||||
return getModeller(upgrade).getModel(upgrade, null, side, data);
|
||||
}
|
||||
|
||||
private static TurtleUpgradeModeller<?> getModeller(ITurtleUpgrade upgrade) {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends ITurtleUpgrade> TurtleUpgradeModeller<T> getModeller(T upgrade) {
|
||||
var modeller = turtleModels.get(upgrade.getType());
|
||||
return modeller == null ? NULL_TURTLE_MODELLER : modeller;
|
||||
return (TurtleUpgradeModeller<T>) (modeller == null ? NULL_TURTLE_MODELLER : modeller);
|
||||
}
|
||||
|
||||
public static Stream<ResourceLocation> getDependencies() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"pattern": [" # ", "#R#", " # "],
|
||||
"result": {"count": 6, "id": "computercraft:cable"}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "G": {"tag": "c:glass_panes"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "G": {"tag": "c:glass_panes"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"pattern": ["###", "#R#", "#G#"],
|
||||
"result": {"count": 1, "id": "computercraft:computer_normal"}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"pattern": ["###", "#R#", "#R#"],
|
||||
"result": {"count": 1, "id": "computercraft:disk_drive"}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "G": {"tag": "c:glass_panes"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "G": {"tag": "c:glass_panes"}},
|
||||
"pattern": ["###", "#G#", "###"],
|
||||
"result": {"count": 1, "id": "computercraft:monitor_normal"}
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "A": {"item": "minecraft:golden_apple"}, "G": {"tag": "c:glass_panes"}},
|
||||
"key": {
|
||||
"#": {"item": "minecraft:stone"},
|
||||
"A": {"item": "minecraft:golden_apple"},
|
||||
"G": {"tag": "c:glass_panes"}
|
||||
},
|
||||
"pattern": ["###", "#A#", "#G#"],
|
||||
"result": {"count": 1, "id": "computercraft:pocket_computer_normal"}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "D": {"tag": "c:dyes"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "D": {"tag": "c:dyes"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"pattern": ["###", "#R#", "#D#"],
|
||||
"result": {"count": 1, "id": "computercraft:printer"}
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "N": {"item": "minecraft:note_block"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"key": {
|
||||
"#": {"item": "minecraft:stone"},
|
||||
"N": {"item": "minecraft:note_block"},
|
||||
"R": {"tag": "c:dusts/redstone"}
|
||||
},
|
||||
"pattern": ["###", "#N#", "#R#"],
|
||||
"result": {"count": 1, "id": "computercraft:speaker"}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "R": {"tag": "c:dusts/redstone"}},
|
||||
"pattern": ["###", "#R#", "###"],
|
||||
"result": {"count": 1, "id": "computercraft:wired_modem"}
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.RegistrySetBuilder;
|
||||
import net.minecraft.data.DataProvider;
|
||||
@ -20,7 +22,6 @@ import net.minecraft.world.level.block.Block;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@ -32,25 +33,25 @@ public final class DataProviders {
|
||||
}
|
||||
|
||||
public static void add(GeneratorSink generator) {
|
||||
var turtleUpgrades = generator.add(TurtleUpgradeProvider::new);
|
||||
var pocketUpgrades = generator.add(PocketUpgradeProvider::new);
|
||||
var fullRegistryPatch = RegistryPatchGenerator.createLookup(
|
||||
generator.registries(),
|
||||
Util.make(new RegistrySetBuilder(), builder -> {
|
||||
builder.add(ITurtleUpgrade.REGISTRY, TurtleUpgradeProvider::addUpgrades);
|
||||
builder.add(IPocketUpgrade.REGISTRY, PocketUpgradeProvider::addUpgrades);
|
||||
}));
|
||||
var fullRegistries = fullRegistryPatch.thenApply(RegistrySetBuilder.PatchedRegistries::full);
|
||||
|
||||
generator.add((out, registries) -> {
|
||||
var builder = new RegistrySetBuilder();
|
||||
builder.add(ModRegistry.TURTLE_UPGRADE, bs -> turtleUpgrades.getGeneratedUpgrades().forEach(bs::register));
|
||||
builder.add(ModRegistry.POCKET_UPGRADE, bs -> pocketUpgrades.getGeneratedUpgrades().forEach(bs::register));
|
||||
|
||||
return new RecipeProvider(out, generator.createPatchedRegistries(registries, builder).thenApply(RegistrySetBuilder.PatchedRegistries::full));
|
||||
});
|
||||
generator.registries(fullRegistryPatch);
|
||||
generator.add(out -> new RecipeProvider(out, fullRegistries));
|
||||
|
||||
var blockTags = generator.blockTags(TagProvider::blockTags);
|
||||
generator.itemTags(TagProvider::itemTags, blockTags);
|
||||
|
||||
generator.add((out, registries) -> new net.minecraft.data.loot.LootTableProvider(out, Set.of(), LootTableProvider.getTables(), registries));
|
||||
generator.add(out -> new net.minecraft.data.loot.LootTableProvider(out, Set.of(), LootTableProvider.getTables(), fullRegistries));
|
||||
|
||||
generator.add(out -> new ModelProvider(out, BlockModelProvider::addBlockModels, ItemModelProvider::addItemModels));
|
||||
|
||||
generator.add(out -> new LanguageProvider(out, turtleUpgrades, pocketUpgrades));
|
||||
generator.add(out -> new LanguageProvider(out, fullRegistries));
|
||||
|
||||
// Unfortunately we rely on some client-side classes in this code. We just load in the client side data provider
|
||||
// and invoke that.
|
||||
@ -63,9 +64,9 @@ public final class DataProviders {
|
||||
}
|
||||
|
||||
public interface GeneratorSink {
|
||||
<T extends DataProvider> T add(DataProvider.Factory<T> factory);
|
||||
CompletableFuture<HolderLookup.Provider> registries();
|
||||
|
||||
<T extends DataProvider> T add(BiFunction<PackOutput, CompletableFuture<HolderLookup.Provider>, T> factory);
|
||||
<T extends DataProvider> T add(DataProvider.Factory<T> factory);
|
||||
|
||||
<T> void addFromCodec(String name, PackType type, String directory, Codec<T> codec, Consumer<BiConsumer<ResourceLocation, T>> output);
|
||||
|
||||
@ -74,16 +75,10 @@ public final class DataProviders {
|
||||
TagsProvider<Item> itemTags(Consumer<TagProvider.ItemTagConsumer> tags, TagsProvider<Block> blocks);
|
||||
|
||||
/**
|
||||
* Extend our registries with additional entries.
|
||||
* Build new dynamic registries and save them to a pack.
|
||||
*
|
||||
* @param registries The existing registries.
|
||||
* @param patch The new registries to apply.
|
||||
* @return The built registries.
|
||||
* @param registries The patched registries to write.
|
||||
*/
|
||||
default CompletableFuture<RegistrySetBuilder.PatchedRegistries> createPatchedRegistries(
|
||||
CompletableFuture<HolderLookup.Provider> registries, RegistrySetBuilder patch
|
||||
) {
|
||||
return RegistryPatchGenerator.createLookup(registries, patch);
|
||||
}
|
||||
void registries(CompletableFuture<RegistrySetBuilder.PatchedRegistries> registries);
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ package dan200.computercraft.data;
|
||||
import com.google.gson.JsonObject;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.ComputerCraftTags;
|
||||
import dan200.computercraft.api.pocket.PocketUpgradeDataProvider;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeDataProvider;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.core.metrics.Metric;
|
||||
import dan200.computercraft.core.metrics.Metrics;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
@ -17,6 +17,7 @@ import dan200.computercraft.shared.computer.metrics.basic.Aggregate;
|
||||
import dan200.computercraft.shared.computer.metrics.basic.AggregatedMetric;
|
||||
import dan200.computercraft.shared.config.ConfigFile;
|
||||
import dan200.computercraft.shared.config.ConfigSpec;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
@ -34,27 +35,28 @@ import java.util.stream.Stream;
|
||||
|
||||
public final class LanguageProvider implements DataProvider {
|
||||
private final PackOutput output;
|
||||
private final TurtleUpgradeDataProvider turtleUpgrades;
|
||||
private final PocketUpgradeDataProvider pocketUpgrades;
|
||||
private final CompletableFuture<HolderLookup.Provider> registries;
|
||||
|
||||
private final Map<String, String> translations = new HashMap<>();
|
||||
|
||||
public LanguageProvider(PackOutput output, TurtleUpgradeDataProvider turtleUpgrades, PocketUpgradeDataProvider pocketUpgrades) {
|
||||
public LanguageProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries) {
|
||||
this.output = output;
|
||||
this.turtleUpgrades = turtleUpgrades;
|
||||
this.pocketUpgrades = pocketUpgrades;
|
||||
this.registries = registries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> run(CachedOutput cachedOutput) {
|
||||
addTranslations();
|
||||
getExpectedKeys().forEach(x -> {
|
||||
if (!translations.containsKey(x)) throw new IllegalStateException("No translation for " + x);
|
||||
});
|
||||
|
||||
var json = new JsonObject();
|
||||
for (var pair : translations.entrySet()) json.addProperty(pair.getKey(), pair.getValue());
|
||||
return DataProvider.saveStable(cachedOutput, json, output.getOutputFolder().resolve("assets/" + ComputerCraftAPI.MOD_ID + "/lang/en_us.json"));
|
||||
return registries.thenCompose(registries -> {
|
||||
getExpectedKeys(registries).forEach(x -> {
|
||||
if (!translations.containsKey(x)) throw new IllegalStateException("No translation for " + x);
|
||||
});
|
||||
|
||||
var json = new JsonObject();
|
||||
for (var pair : translations.entrySet()) json.addProperty(pair.getKey(), pair.getValue());
|
||||
return DataProvider.saveStable(cachedOutput, json, output.getOutputFolder().resolve("assets/" + ComputerCraftAPI.MOD_ID + "/lang/en_us.json"));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -280,7 +282,7 @@ public final class LanguageProvider implements DataProvider {
|
||||
addConfigEntry(ConfigSpec.uploadNagDelay, "Upload nag delay");
|
||||
}
|
||||
|
||||
private Stream<String> getExpectedKeys() {
|
||||
private Stream<String> getExpectedKeys(HolderLookup.Provider registries) {
|
||||
return Stream.of(
|
||||
BuiltInRegistries.BLOCK.holders()
|
||||
.filter(x -> x.key().location().getNamespace().equals(ComputerCraftAPI.MOD_ID))
|
||||
@ -288,8 +290,8 @@ public final class LanguageProvider implements DataProvider {
|
||||
BuiltInRegistries.ITEM.holders()
|
||||
.filter(x -> x.key().location().getNamespace().equals(ComputerCraftAPI.MOD_ID))
|
||||
.map(x -> x.value().getDescriptionId()),
|
||||
turtleUpgrades.getGeneratedUpgrades().values().stream().flatMap(x -> getTranslationKeys(x.getAdjective())),
|
||||
pocketUpgrades.getGeneratedUpgrades().values().stream().flatMap(x -> getTranslationKeys(x.getAdjective())),
|
||||
registries.lookupOrThrow(ITurtleUpgrade.REGISTRY).listElements().flatMap(x -> getTranslationKeys(x.value().getAdjective())),
|
||||
registries.lookupOrThrow(IPocketUpgrade.REGISTRY).listElements().flatMap(x -> getTranslationKeys(x.value().getAdjective())),
|
||||
Metric.metrics().values().stream().map(x -> AggregatedMetric.TRANSLATION_PREFIX + x.name() + ".name"),
|
||||
ConfigSpec.serverSpec.entries().map(ConfigFile.Entry::translationKey),
|
||||
ConfigSpec.clientSpec.entries().map(ConfigFile.Entry::translationKey),
|
||||
|
@ -5,7 +5,7 @@
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
|
@ -6,30 +6,23 @@ package dan200.computercraft.data;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.pocket.PocketUpgradeDataProvider;
|
||||
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
|
||||
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.worldgen.BootstrapContext;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static dan200.computercraft.shared.ModRegistry.Items;
|
||||
|
||||
class PocketUpgradeProvider extends PocketUpgradeDataProvider {
|
||||
PocketUpgradeProvider(PackOutput output) {
|
||||
super(output);
|
||||
class PocketUpgradeProvider {
|
||||
public static void addUpgrades(BootstrapContext<IPocketUpgrade> upgrades) {
|
||||
upgrades.register(id("speaker"), new PocketSpeaker(new ItemStack(Items.SPEAKER.get())));
|
||||
upgrades.register(id("wireless_modem_normal"), new PocketModem(new ItemStack(Items.WIRELESS_MODEM_NORMAL.get()), false));
|
||||
upgrades.register(id("wireless_modem_advanced"), new PocketModem(new ItemStack(Items.WIRELESS_MODEM_ADVANCED.get()), true));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addUpgrades(Consumer<Upgrade<IPocketUpgrade>> addUpgrade) {
|
||||
upgrade(id("speaker"), new PocketSpeaker(new ItemStack(Items.SPEAKER.get()))).add(addUpgrade);
|
||||
upgrade(id("wireless_modem_normal"), new PocketModem(new ItemStack(Items.WIRELESS_MODEM_NORMAL.get()), false)).add(addUpgrade);
|
||||
upgrade(id("wireless_modem_advanced"), new PocketModem(new ItemStack(Items.WIRELESS_MODEM_ADVANCED.get()), true)).add(addUpgrade);
|
||||
}
|
||||
|
||||
private static ResourceLocation id(String id) {
|
||||
return new ResourceLocation(ComputerCraftAPI.MOD_ID, id);
|
||||
private static ResourceKey<IPocketUpgrade> id(String id) {
|
||||
return ResourceKey.create(IPocketUpgrade.REGISTRY, new ResourceLocation(ComputerCraftAPI.MOD_ID, id));
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,13 @@ import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.upgrades.UpgradeData;
|
||||
import dan200.computercraft.core.util.Colour;
|
||||
import dan200.computercraft.data.recipe.ShapedSpecBuilder;
|
||||
import dan200.computercraft.data.recipe.ShapelessSpecBuilder;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.common.ClearColourRecipe;
|
||||
import dan200.computercraft.shared.common.ColourableRecipe;
|
||||
@ -54,14 +56,12 @@ import net.minecraft.world.item.crafting.CraftingBookCategory;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static dan200.computercraft.api.ComputerCraftTags.Items.COMPUTER;
|
||||
import static dan200.computercraft.api.ComputerCraftTags.Items.WIRED_MODEM;
|
||||
@ -119,7 +119,7 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.requires(Items.PAPER)
|
||||
.requires(DyeItem.byColor(ofColour(colour)))
|
||||
.group("computercraft:disk")
|
||||
.unlockedBy("has_drive", inventoryChange(ModRegistry.Blocks.DISK_DRIVE.get()))
|
||||
.unlockedBy("has_drive", inventoryChange(ModRegistry.Items.DISK_DRIVE.get()))
|
||||
.build(ImpostorShapelessRecipe::new)
|
||||
.save(output, new ResourceLocation(ComputerCraftAPI.MOD_ID, "disk_" + (colour.ordinal() + 1)));
|
||||
}
|
||||
@ -139,7 +139,7 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
for (var turtleItem : turtleItems()) {
|
||||
var name = RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, turtleItem);
|
||||
|
||||
registries.lookup(ModRegistry.TURTLE_UPGRADE).map(HolderLookup::listElements).orElse(Stream.empty()).forEach(upgradeHolder -> {
|
||||
registries.lookupOrThrow(ITurtleUpgrade.REGISTRY).listElements().forEach(upgradeHolder -> {
|
||||
var upgrade = upgradeHolder.value();
|
||||
ShapedSpecBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, DataComponentUtil.createStack(turtleItem, ModRegistry.DataComponents.RIGHT_TURTLE_UPGRADE.get(), UpgradeData.ofDefault(upgradeHolder)))
|
||||
@ -171,7 +171,7 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
for (var pocket : pocketComputerItems()) {
|
||||
var name = RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, pocket).withPath(x -> x.replace("pocket_computer_", "pocket_"));
|
||||
|
||||
registries.lookup(ModRegistry.POCKET_UPGRADE).map(HolderLookup::listElements).orElse(Stream.empty()).forEach(upgradeHolder -> {
|
||||
registries.lookupOrThrow(IPocketUpgrade.REGISTRY).listElements().forEach(upgradeHolder -> {
|
||||
var upgrade = upgradeHolder.value();
|
||||
ShapedSpecBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, DataComponentUtil.createStack(pocket, ModRegistry.DataComponents.POCKET_UPGRADE.get(), UpgradeData.ofDefault(upgradeHolder)))
|
||||
@ -238,25 +238,25 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.pattern(" # ")
|
||||
.pattern("#R#")
|
||||
.pattern(" # ")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('R', ingredients.redstone())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.unlockedBy("has_modem", inventoryChange(WIRED_MODEM))
|
||||
.save(add);
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.COMPUTER_NORMAL.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_NORMAL.get())
|
||||
.pattern("###")
|
||||
.pattern("#R#")
|
||||
.pattern("#G#")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('R', ingredients.redstone())
|
||||
.define('G', ingredients.glassPane())
|
||||
.unlockedBy("has_redstone", inventoryChange(itemPredicate(ingredients.redstone())))
|
||||
.save(add);
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.COMPUTER_ADVANCED.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_ADVANCED.get())
|
||||
.pattern("###")
|
||||
.pattern("#R#")
|
||||
.pattern("#G#")
|
||||
@ -278,18 +278,18 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.save(add, new ResourceLocation(ComputerCraftAPI.MOD_ID, "computer_advanced_upgrade"));
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.COMPUTER_COMMAND.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_COMMAND.get())
|
||||
.pattern("###")
|
||||
.pattern("#R#")
|
||||
.pattern("#G#")
|
||||
.define('#', ingredients.goldIngot())
|
||||
.define('R', Blocks.COMMAND_BLOCK)
|
||||
.define('R', Items.COMMAND_BLOCK)
|
||||
.define('G', ingredients.glassPane())
|
||||
.unlockedBy("has_components", inventoryChange(Blocks.COMMAND_BLOCK))
|
||||
.unlockedBy("has_components", inventoryChange(Items.COMMAND_BLOCK))
|
||||
.save(add);
|
||||
|
||||
ShapedSpecBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.TURTLE_NORMAL.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_NORMAL.get())
|
||||
.pattern("###")
|
||||
.pattern("#C#")
|
||||
.pattern("#I#")
|
||||
@ -301,7 +301,7 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.save(add);
|
||||
|
||||
ShapedSpecBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.TURTLE_ADVANCED.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_ADVANCED.get())
|
||||
.pattern("###")
|
||||
.pattern("#C#")
|
||||
.pattern("#I#")
|
||||
@ -313,7 +313,7 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.save(add);
|
||||
|
||||
ShapedSpecBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.TURTLE_ADVANCED.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_ADVANCED.get())
|
||||
.pattern("###")
|
||||
.pattern("#C#")
|
||||
.pattern(" B ")
|
||||
@ -325,27 +325,27 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.save(add, new ResourceLocation(ComputerCraftAPI.MOD_ID, "turtle_advanced_upgrade"));
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.DISK_DRIVE.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.DISK_DRIVE.get())
|
||||
.pattern("###")
|
||||
.pattern("#R#")
|
||||
.pattern("#R#")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('R', ingredients.redstone())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.save(add);
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.MONITOR_NORMAL.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.MONITOR_NORMAL.get())
|
||||
.pattern("###")
|
||||
.pattern("#G#")
|
||||
.pattern("###")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('G', ingredients.glassPane())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.save(add);
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.MONITOR_ADVANCED.get(), 4)
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.MONITOR_ADVANCED.get(), 4)
|
||||
.pattern("###")
|
||||
.pattern("#G#")
|
||||
.pattern("###")
|
||||
@ -359,7 +359,7 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.pattern("###")
|
||||
.pattern("#A#")
|
||||
.pattern("#G#")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('A', Items.GOLDEN_APPLE)
|
||||
.define('G', ingredients.glassPane())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
@ -390,23 +390,23 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.save(add, new ResourceLocation(ComputerCraftAPI.MOD_ID, "pocket_computer_advanced_upgrade"));
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.PRINTER.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.PRINTER.get())
|
||||
.pattern("###")
|
||||
.pattern("#R#")
|
||||
.pattern("#D#")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('R', ingredients.redstone())
|
||||
.define('D', ingredients.dye())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.save(add);
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.SPEAKER.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.SPEAKER.get())
|
||||
.pattern("###")
|
||||
.pattern("#N#")
|
||||
.pattern("#R#")
|
||||
.define('#', ingredients.stone())
|
||||
.define('N', Blocks.NOTE_BLOCK)
|
||||
.define('#', Items.STONE)
|
||||
.define('N', Items.NOTE_BLOCK)
|
||||
.define('R', ingredients.redstone())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.save(add);
|
||||
@ -416,42 +416,42 @@ final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
||||
.pattern("###")
|
||||
.pattern("#R#")
|
||||
.pattern("###")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('R', ingredients.redstone())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.unlockedBy("has_cable", inventoryChange(ModRegistry.Items.CABLE.get()))
|
||||
.save(add);
|
||||
|
||||
ShapelessRecipeBuilder
|
||||
.shapeless(RecipeCategory.REDSTONE, ModRegistry.Blocks.WIRED_MODEM_FULL.get())
|
||||
.shapeless(RecipeCategory.REDSTONE, ModRegistry.Items.WIRED_MODEM_FULL.get())
|
||||
.requires(ModRegistry.Items.WIRED_MODEM.get())
|
||||
.unlockedBy("has_modem", inventoryChange(WIRED_MODEM))
|
||||
.save(add, new ResourceLocation(ComputerCraftAPI.MOD_ID, "wired_modem_full_from"));
|
||||
ShapelessRecipeBuilder
|
||||
.shapeless(RecipeCategory.REDSTONE, ModRegistry.Items.WIRED_MODEM.get())
|
||||
.requires(ModRegistry.Blocks.WIRED_MODEM_FULL.get())
|
||||
.requires(ModRegistry.Items.WIRED_MODEM_FULL.get())
|
||||
.unlockedBy("has_modem", inventoryChange(WIRED_MODEM))
|
||||
.save(add, new ResourceLocation(ComputerCraftAPI.MOD_ID, "wired_modem_full_to"));
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.WIRELESS_MODEM_NORMAL.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRELESS_MODEM_NORMAL.get())
|
||||
.pattern("###")
|
||||
.pattern("#E#")
|
||||
.pattern("###")
|
||||
.define('#', ingredients.stone())
|
||||
.define('#', Items.STONE)
|
||||
.define('E', ingredients.enderPearl())
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.save(add);
|
||||
|
||||
ShapedRecipeBuilder
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.WIRELESS_MODEM_ADVANCED.get())
|
||||
.shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get())
|
||||
.pattern("###")
|
||||
.pattern("#E#")
|
||||
.pattern("###")
|
||||
.define('#', ingredients.goldIngot())
|
||||
.define('E', Items.ENDER_EYE)
|
||||
.unlockedBy("has_computer", inventoryChange(COMPUTER))
|
||||
.unlockedBy("has_wireless", inventoryChange(ModRegistry.Blocks.WIRELESS_MODEM_NORMAL.get()))
|
||||
.unlockedBy("has_wireless", inventoryChange(ModRegistry.Items.WIRELESS_MODEM_NORMAL.get()))
|
||||
.save(add);
|
||||
|
||||
ShapelessSpecBuilder
|
||||
|
@ -5,7 +5,7 @@
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftTags;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.integration.ExternalModTags;
|
||||
import net.minecraft.core.Registry;
|
||||
|
@ -5,45 +5,40 @@
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.ComputerCraftTags.Blocks;
|
||||
import dan200.computercraft.api.ComputerCraftTags;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeDataProvider;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.turtle.upgrades.TurtleCraftingTable;
|
||||
import dan200.computercraft.shared.turtle.upgrades.TurtleModem;
|
||||
import dan200.computercraft.shared.turtle.upgrades.TurtleSpeaker;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.worldgen.BootstrapContext;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import static dan200.computercraft.api.turtle.TurtleToolBuilder.tool;
|
||||
|
||||
class TurtleUpgradeProvider extends TurtleUpgradeDataProvider {
|
||||
TurtleUpgradeProvider(PackOutput output) {
|
||||
super(output);
|
||||
class TurtleUpgradeProvider {
|
||||
public static void addUpgrades(BootstrapContext<ITurtleUpgrade> upgrades) {
|
||||
upgrades.register(id("speaker"), new TurtleSpeaker(new ItemStack(ModRegistry.Items.SPEAKER.get())));
|
||||
upgrades.register(vanilla("crafting_table"), new TurtleCraftingTable(new ItemStack(Items.CRAFTING_TABLE)));
|
||||
upgrades.register(id("wireless_modem_normal"), new TurtleModem(new ItemStack(ModRegistry.Items.WIRELESS_MODEM_NORMAL.get()), false));
|
||||
upgrades.register(id("wireless_modem_advanced"), new TurtleModem(new ItemStack(ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get()), true));
|
||||
|
||||
tool(vanilla("diamond_axe").location(), Items.DIAMOND_AXE).damageMultiplier(6.0f).register(upgrades);
|
||||
tool(vanilla("diamond_pickaxe"), Items.DIAMOND_PICKAXE).register(upgrades);
|
||||
tool(vanilla("diamond_hoe"), Items.DIAMOND_HOE).breakable(ComputerCraftTags.Blocks.TURTLE_HOE_BREAKABLE).register(upgrades);
|
||||
tool(vanilla("diamond_shovel"), Items.DIAMOND_SHOVEL).breakable(ComputerCraftTags.Blocks.TURTLE_SHOVEL_BREAKABLE).register(upgrades);
|
||||
tool(vanilla("diamond_sword"), Items.DIAMOND_SWORD).breakable(ComputerCraftTags.Blocks.TURTLE_SWORD_BREAKABLE).damageMultiplier(9.0f).register(upgrades);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addUpgrades(Consumer<Upgrade<ITurtleUpgrade>> addUpgrade) {
|
||||
upgrade(id("speaker"), new TurtleSpeaker(new ItemStack(ModRegistry.Items.SPEAKER.get()))).add(addUpgrade);
|
||||
upgrade(vanilla("crafting_table"), new TurtleCraftingTable(new ItemStack(Items.CRAFTING_TABLE))).add(addUpgrade);
|
||||
upgrade(id("wireless_modem_normal"), new TurtleModem(new ItemStack(ModRegistry.Items.WIRELESS_MODEM_NORMAL.get()), false)).add(addUpgrade);
|
||||
upgrade(id("wireless_modem_advanced"), new TurtleModem(new ItemStack(ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get()), true)).add(addUpgrade);
|
||||
|
||||
tool(vanilla("diamond_axe"), Items.DIAMOND_AXE).damageMultiplier(6.0f).add(addUpgrade);
|
||||
tool(vanilla("diamond_pickaxe"), Items.DIAMOND_PICKAXE).add(addUpgrade);
|
||||
tool(vanilla("diamond_hoe"), Items.DIAMOND_HOE).breakable(Blocks.TURTLE_HOE_BREAKABLE).add(addUpgrade);
|
||||
tool(vanilla("diamond_shovel"), Items.DIAMOND_SHOVEL).breakable(Blocks.TURTLE_SHOVEL_BREAKABLE).add(addUpgrade);
|
||||
tool(vanilla("diamond_sword"), Items.DIAMOND_SWORD).breakable(Blocks.TURTLE_SWORD_BREAKABLE).damageMultiplier(9.0f).add(addUpgrade);
|
||||
private static ResourceKey<ITurtleUpgrade> id(String id) {
|
||||
return ITurtleUpgrade.createKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, id));
|
||||
}
|
||||
|
||||
private static ResourceLocation id(String id) {
|
||||
return new ResourceLocation(ComputerCraftAPI.MOD_ID, id);
|
||||
}
|
||||
|
||||
private static ResourceLocation vanilla(String id) {
|
||||
private static ResourceKey<ITurtleUpgrade> vanilla(String id) {
|
||||
// Naughty, please don't do this. Mostly here for some semblance of backwards compatibility.
|
||||
return new ResourceLocation("minecraft", id);
|
||||
return ITurtleUpgrade.createKey(new ResourceLocation("minecraft", id));
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,10 @@
|
||||
package dan200.computercraft.impl;
|
||||
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
|
||||
public final class PocketUpgrades {
|
||||
private static final UpgradeManager<IPocketUpgrade> registry = new UpgradeManager<>(
|
||||
IPocketUpgrade.typeRegistry(), ModRegistry.POCKET_UPGRADE, IPocketUpgrade::getType
|
||||
IPocketUpgrade.typeRegistry(), IPocketUpgrade.REGISTRY, IPocketUpgrade::getType
|
||||
);
|
||||
|
||||
private PocketUpgrades() {
|
||||
|
@ -5,11 +5,10 @@
|
||||
package dan200.computercraft.impl;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
|
||||
public final class TurtleUpgrades {
|
||||
private static final UpgradeManager<ITurtleUpgrade> registry = new UpgradeManager<>(
|
||||
ITurtleUpgrade.typeRegistry(), ModRegistry.TURTLE_UPGRADE, ITurtleUpgrade::getType
|
||||
ITurtleUpgrade.typeRegistry(), ITurtleUpgrade.REGISTRY, ITurtleUpgrade::getType
|
||||
);
|
||||
|
||||
private TurtleUpgrades() {
|
||||
|
@ -18,7 +18,6 @@ import dan200.computercraft.api.upgrades.UpgradeData;
|
||||
import dan200.computercraft.api.upgrades.UpgradeType;
|
||||
import dan200.computercraft.core.util.Colour;
|
||||
import dan200.computercraft.impl.PocketUpgrades;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.command.UserLevel;
|
||||
import dan200.computercraft.shared.command.arguments.ComputerArgumentType;
|
||||
import dan200.computercraft.shared.command.arguments.RepeatArgumentType;
|
||||
@ -91,7 +90,6 @@ import net.minecraft.commands.synchronization.ArgumentTypeInfo;
|
||||
import net.minecraft.commands.synchronization.SingletonArgumentInfo;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.cauldron.CauldronInteraction;
|
||||
import net.minecraft.core.component.DataComponentType;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
@ -99,7 +97,6 @@ import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.flag.FeatureFlags;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
@ -130,9 +127,6 @@ public final class ModRegistry {
|
||||
private ModRegistry() {
|
||||
}
|
||||
|
||||
public static final ResourceKey<Registry<ITurtleUpgrade>> TURTLE_UPGRADE = RegistryHelper.TURTLE_UPGRADE;
|
||||
public static final ResourceKey<Registry<IPocketUpgrade>> POCKET_UPGRADE = RegistryHelper.POCKET_UPGRADE;
|
||||
|
||||
public static final class Blocks {
|
||||
static final RegistrationHelper<Block> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.BLOCK);
|
||||
|
||||
@ -602,7 +596,7 @@ public final class ModRegistry {
|
||||
|
||||
private static void addTurtle(CreativeModeTab.Output out, TurtleItem turtle, HolderLookup.Provider registries) {
|
||||
out.accept(new ItemStack(turtle));
|
||||
registries.lookupOrThrow(TURTLE_UPGRADE).listElements()
|
||||
registries.lookupOrThrow(ITurtleUpgrade.REGISTRY).listElements()
|
||||
.filter(ModRegistry::isOurUpgrade)
|
||||
.map(x -> DataComponentUtil.createStack(turtle, DataComponents.RIGHT_TURTLE_UPGRADE.get(), UpgradeData.ofDefault(x)))
|
||||
.forEach(out::accept);
|
||||
@ -610,7 +604,7 @@ public final class ModRegistry {
|
||||
|
||||
private static void addPocket(CreativeModeTab.Output out, PocketComputerItem pocket, HolderLookup.Provider registries) {
|
||||
out.accept(new ItemStack(pocket));
|
||||
registries.lookupOrThrow(POCKET_UPGRADE).listElements()
|
||||
registries.lookupOrThrow(IPocketUpgrade.REGISTRY).listElements()
|
||||
.filter(ModRegistry::isOurUpgrade)
|
||||
.map(x -> DataComponentUtil.createStack(pocket, DataComponents.POCKET_UPGRADE.get(), UpgradeData.ofDefault(x))).forEach(out::accept);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import com.google.gson.JsonObject;
|
||||
import com.mojang.brigadier.Message;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package dan200.computercraft.shared.details;
|
||||
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.tags.TagKey;
|
||||
|
@ -5,6 +5,8 @@
|
||||
package dan200.computercraft.shared.integration;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.upgrades.UpgradeData;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
@ -60,14 +62,14 @@ public final class RecipeModHelpers {
|
||||
List<ItemStack> upgradeItems = new ArrayList<>();
|
||||
for (var turtleSupplier : TURTLES) {
|
||||
var turtle = turtleSupplier.get();
|
||||
forEachRegistry(registries, ModRegistry.TURTLE_UPGRADE, upgrade ->
|
||||
forEachRegistry(registries, ITurtleUpgrade.REGISTRY, upgrade ->
|
||||
upgradeItems.add(DataComponentUtil.createStack(turtle, ModRegistry.DataComponents.RIGHT_TURTLE_UPGRADE.get(), UpgradeData.ofDefault(upgrade)))
|
||||
);
|
||||
}
|
||||
|
||||
for (var pocketSupplier : POCKET_COMPUTERS) {
|
||||
var pocket = pocketSupplier.get();
|
||||
forEachRegistry(registries, ModRegistry.POCKET_UPGRADE, upgrade ->
|
||||
forEachRegistry(registries, IPocketUpgrade.REGISTRY, upgrade ->
|
||||
upgradeItems.add(DataComponentUtil.createStack(pocket, ModRegistry.DataComponents.POCKET_UPGRADE.get(), UpgradeData.ofDefault(upgrade)))
|
||||
);
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class UpgradeRecipeGenerator<T> {
|
||||
if (initialised) return;
|
||||
initialised = true;
|
||||
|
||||
forEachRegistry(registries, ModRegistry.TURTLE_UPGRADE, holder -> {
|
||||
forEachRegistry(registries, ITurtleUpgrade.REGISTRY, holder -> {
|
||||
var upgrade = holder.value();
|
||||
var stack = upgrade.getCraftingItem();
|
||||
if (stack.isEmpty()) return;
|
||||
@ -67,7 +67,7 @@ public class UpgradeRecipeGenerator<T> {
|
||||
turtleUpgrades.add(info);
|
||||
});
|
||||
|
||||
forEachRegistry(registries, ModRegistry.POCKET_UPGRADE, holder -> {
|
||||
forEachRegistry(registries, IPocketUpgrade.REGISTRY, holder -> {
|
||||
var upgrade = holder.value();
|
||||
var stack = upgrade.getCraftingItem();
|
||||
if (stack.isEmpty()) return;
|
||||
@ -223,13 +223,13 @@ public class UpgradeRecipeGenerator<T> {
|
||||
var newStack = stack.copyWithCount(1);
|
||||
newStack.set(ModRegistry.DataComponents.LEFT_TURTLE_UPGRADE.get(), left);
|
||||
newStack.set(ModRegistry.DataComponents.RIGHT_TURTLE_UPGRADE.get(), right);
|
||||
return stack;
|
||||
return newStack;
|
||||
}
|
||||
|
||||
private static ItemStack pocketWith(ItemStack stack, @Nullable UpgradeData<IPocketUpgrade> back) {
|
||||
var newStack = stack.copyWithCount(1);
|
||||
newStack.set(ModRegistry.DataComponents.POCKET_UPGRADE.get(), back);
|
||||
return stack;
|
||||
return newStack;
|
||||
}
|
||||
|
||||
private T pocket(Ingredient upgrade, Ingredient pocketComputer, ItemStack result) {
|
||||
|
@ -8,7 +8,9 @@ import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.core.component.DataComponentHolder;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
|
||||
@ -93,6 +95,10 @@ public record PrintoutData(String title, List<Line> lines) {
|
||||
return DataResult.success(lines);
|
||||
}
|
||||
|
||||
public static PrintoutData getOrEmpty(DataComponentHolder holder) {
|
||||
return holder.getOrDefault(ModRegistry.DataComponents.PRINTOUT.get(), EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of pages in this printout.
|
||||
*
|
||||
|
@ -35,7 +35,7 @@ public class PrintoutItem extends Item {
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> list, TooltipFlag options) {
|
||||
var title = getTitle(stack);
|
||||
var title = PrintoutData.getOrEmpty(stack).title();
|
||||
if (!title.isEmpty()) list.add(Component.literal(title));
|
||||
}
|
||||
|
||||
@ -51,14 +51,4 @@ public class PrintoutItem extends Item {
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static String getTitle(ItemStack stack) {
|
||||
var nbt = stack.get(ModRegistry.DataComponents.PRINTOUT.get());
|
||||
return nbt == null ? "" : nbt.title();
|
||||
}
|
||||
|
||||
public static int getPageCount(ItemStack stack) {
|
||||
var nbt = stack.get(ModRegistry.DataComponents.PRINTOUT.get());
|
||||
return nbt == null ? 1 : nbt.pages();
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public final class PrintoutRecipe extends CustomRecipe {
|
||||
if (stack.getItem() instanceof PrintoutItem printout && printout.getType() != PrintoutItem.Type.BOOK) {
|
||||
if (printouts == null) printouts = new ItemStack[9];
|
||||
printouts[numPrintouts] = stack;
|
||||
numPages += PrintoutItem.getPageCount(stack);
|
||||
numPages += PrintoutData.getOrEmpty(stack).pages();
|
||||
numPrintouts++;
|
||||
printoutFound = true;
|
||||
} else if (stack.getItem() == Items.PAPER) {
|
||||
@ -104,7 +104,7 @@ public final class PrintoutRecipe extends CustomRecipe {
|
||||
}
|
||||
}
|
||||
|
||||
var title = PrintoutItem.getTitle(printouts[0]);
|
||||
var title = PrintoutData.getOrEmpty(printouts[0]).title();
|
||||
|
||||
return DataComponentUtil.createStack(
|
||||
leatherFound ? ModRegistry.Items.PRINTED_BOOK.get() : ModRegistry.Items.PRINTED_PAGES.get(),
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem.wired;
|
||||
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -11,7 +11,6 @@ import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
|
||||
import dan200.computercraft.shared.container.BasicContainer;
|
||||
import dan200.computercraft.shared.container.BasicWorldlyContainer;
|
||||
import dan200.computercraft.shared.media.items.PrintoutData;
|
||||
import dan200.computercraft.shared.media.items.PrintoutItem;
|
||||
import dan200.computercraft.shared.util.ColourUtils;
|
||||
import dan200.computercraft.shared.util.DataComponentUtil;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@ -172,8 +171,7 @@ public final class PrinterBlockEntity extends AbstractContainerBlockEntity imple
|
||||
|
||||
static boolean isPaper(ItemStack stack) {
|
||||
var item = stack.getItem();
|
||||
return item == Items.PAPER
|
||||
|| (item instanceof PrintoutItem printout && printout.getType() == PrintoutItem.Type.PAGE);
|
||||
return item == Items.PAPER || item == ModRegistry.Items.PRINTED_PAGE.get();
|
||||
}
|
||||
|
||||
private boolean canInputPage() {
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
package dan200.computercraft.shared.platform;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import dan200.computercraft.api.network.wired.WiredElement;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.impl.Services;
|
||||
import dan200.computercraft.shared.config.ConfigFile;
|
||||
import dan200.computercraft.shared.network.container.ContainerData;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
@ -47,26 +47,19 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* This extends {@linkplain dan200.computercraft.impl.PlatformHelper the API's loader abstraction layer}, adding
|
||||
* additional methods used by the actual mod.
|
||||
* Abstraction layer for Forge and Fabric. See implementations for more details.
|
||||
*/
|
||||
public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper {
|
||||
public interface PlatformHelper {
|
||||
/**
|
||||
* Get the current {@link PlatformHelper} instance.
|
||||
*
|
||||
* @return The current instance.
|
||||
*/
|
||||
static PlatformHelper get() {
|
||||
return (PlatformHelper) dan200.computercraft.impl.PlatformHelper.get();
|
||||
var instance = Instance.INSTANCE;
|
||||
return instance == null ? Services.raise(PlatformHelper.class, Instance.ERROR) : instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we're running in a development environment.
|
||||
*
|
||||
* @return If we're running in a development environment.
|
||||
*/
|
||||
boolean isDevelopmentEnvironment();
|
||||
|
||||
/**
|
||||
* Create a new config builder.
|
||||
*
|
||||
@ -83,16 +76,6 @@ public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper
|
||||
*/
|
||||
<T> RegistrationHelper<T> createRegistrationHelper(ResourceKey<Registry<T>> registry);
|
||||
|
||||
/**
|
||||
* Determine if this resource should be loaded, based on platform-specific loot conditions.
|
||||
* <p>
|
||||
* This should only be called from the {@code apply} stage of a reload listener.
|
||||
*
|
||||
* @param object The root JSON object of this resource.
|
||||
* @return If this resource should be loaded.
|
||||
*/
|
||||
boolean shouldLoadResource(JsonObject object);
|
||||
|
||||
/**
|
||||
* Register a new argument type.
|
||||
*
|
||||
@ -328,4 +311,21 @@ public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper
|
||||
* @see ServerPlayerGameMode#useItemOn(ServerPlayer, Level, ItemStack, InteractionHand, BlockHitResult)
|
||||
*/
|
||||
InteractionResult useOn(ServerPlayer player, ItemStack stack, BlockHitResult hit, Predicate<BlockState> canUseBlock);
|
||||
|
||||
|
||||
final class Instance {
|
||||
static final @Nullable PlatformHelper INSTANCE;
|
||||
static final @Nullable Throwable ERROR;
|
||||
|
||||
static {
|
||||
// We don't want class initialisation to fail here (as that results in confusing errors). Instead, capture
|
||||
// the error and rethrow it when accessing. This should be JITted away in the common case.
|
||||
var helper = Services.tryLoad(PlatformHelper.class);
|
||||
INSTANCE = helper.instance();
|
||||
ERROR = helper.error();
|
||||
}
|
||||
|
||||
private Instance() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import net.minecraft.world.item.crafting.Ingredient;
|
||||
* @param redstone All {@link Items#REDSTONE} items.
|
||||
* @param string All {@link Items#STRING} items.
|
||||
* @param leather All {@link Items#LEATHER} items.
|
||||
* @param stone All {@link Items#STONE} items.
|
||||
* @param glassPane All {@link Items#GLASS_PANE} items.
|
||||
* @param goldIngot All {@link Items#GOLD_INGOT} items.
|
||||
* @param goldBlock All {@link Items#GOLD_BLOCK} items.
|
||||
@ -26,7 +25,6 @@ public record RecipeIngredients(
|
||||
Ingredient redstone,
|
||||
Ingredient string,
|
||||
Ingredient leather,
|
||||
Ingredient stone,
|
||||
Ingredient glassPane,
|
||||
Ingredient goldIngot,
|
||||
Ingredient goldBlock,
|
||||
|
@ -6,7 +6,7 @@ package dan200.computercraft.shared.recipe;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
|
@ -2,11 +2,8 @@
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.impl;
|
||||
package dan200.computercraft.shared.util;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
@ -18,9 +15,6 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class RegistryHelper {
|
||||
public static final ResourceKey<Registry<ITurtleUpgrade>> TURTLE_UPGRADE = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "turtle_upgrade"));
|
||||
public static final ResourceKey<Registry<IPocketUpgrade>> POCKET_UPGRADE = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "pocket_upgrade"));
|
||||
|
||||
private RegistryHelper() {
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package dan200.computercraft.shared.util;
|
||||
|
||||
import com.mojang.serialization.*;
|
||||
import com.mojang.serialization.codecs.KeyDispatchCodec;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
"uniforms": [
|
||||
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "IViewRotMat", "type": "matrix3x3", "count": 9, "values": [ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
|
||||
{ "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
|
||||
{ "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
|
||||
|
@ -5,7 +5,6 @@
|
||||
package dan200.computercraft;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import dan200.computercraft.api.network.wired.WiredElement;
|
||||
@ -48,13 +47,8 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@AutoService({ PlatformHelper.class, dan200.computercraft.impl.PlatformHelper.class, ComputerCraftAPIService.class })
|
||||
@AutoService({ PlatformHelper.class, ComputerCraftAPIService.class })
|
||||
public class TestPlatformHelper extends AbstractComputerCraftAPI implements PlatformHelper {
|
||||
@Override
|
||||
public boolean isDevelopmentEnvironment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigFile.Builder createConfigBuilder() {
|
||||
throw new UnsupportedOperationException("Cannot create config file inside tests");
|
||||
@ -65,16 +59,6 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat
|
||||
throw new UnsupportedOperationException("Cannot query registry inside tests");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLoadResource(JsonObject object) {
|
||||
throw new UnsupportedOperationException("Cannot use resource conditions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredModCondition(JsonObject object, String modId) {
|
||||
throw new UnsupportedOperationException("Cannot use resource conditions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends ArgumentType<?>, T extends ArgumentTypeInfo.Template<A>, I extends ArgumentTypeInfo<A, T>> I registerArgumentTypeInfo(Class<A> klass, I info) {
|
||||
throw new UnsupportedOperationException("Cannot register ArgumentTypeInfo inside tests");
|
||||
|
@ -17,7 +17,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.data.PrettyJsonWriter;
|
||||
import dan200.computercraft.gametest.core.TestHooks;
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package dan200.computercraft.export;
|
||||
|
||||
import dan200.computercraft.impl.RegistryHelper;
|
||||
import dan200.computercraft.shared.util.RegistryHelper;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -233,7 +233,7 @@ class Turtle_Test {
|
||||
val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access
|
||||
val upgrade = turtle.getUpgrade(TurtleSide.LEFT)
|
||||
assertEquals(
|
||||
helper.level.registryAccess().registryOrThrow(ModRegistry.TURTLE_UPGRADE)
|
||||
helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY)
|
||||
.get(ResourceLocation("cctest", "wooden_pickaxe")),
|
||||
upgrade,
|
||||
"Upgrade is a wooden pickaxe",
|
||||
@ -262,7 +262,7 @@ class Turtle_Test {
|
||||
helper.assertUpgradeItem(
|
||||
ItemStack(Items.WOODEN_PICKAXE),
|
||||
UpgradeData.ofDefault(
|
||||
helper.level.registryAccess().registryOrThrow(ModRegistry.TURTLE_UPGRADE)
|
||||
helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY)
|
||||
.getHolder(ResourceLocation("cctest", "wooden_pickaxe")).orElseThrow(),
|
||||
),
|
||||
)
|
||||
@ -283,7 +283,7 @@ class Turtle_Test {
|
||||
val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access
|
||||
val upgrade = turtle.getUpgrade(TurtleSide.LEFT)
|
||||
assertEquals(
|
||||
helper.level.registryAccess().registryOrThrow(ModRegistry.TURTLE_UPGRADE)
|
||||
helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY)
|
||||
.get(ResourceLocation("cctest", "netherite_pickaxe")),
|
||||
upgrade,
|
||||
"Upgrade is a netherite pickaxe",
|
||||
|
@ -5,8 +5,8 @@
|
||||
package dan200.computercraft.gametest.api
|
||||
|
||||
import dan200.computercraft.gametest.core.MinecraftExtensions
|
||||
import dan200.computercraft.impl.RegistryHelper
|
||||
import dan200.computercraft.mixin.gametest.GameTestSequenceAccessor
|
||||
import dan200.computercraft.shared.util.RegistryHelper
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.Screenshot
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess
|
||||
|
@ -6,10 +6,10 @@ package dan200.computercraft.gametest.api
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral
|
||||
import dan200.computercraft.gametest.core.ManagedComputers
|
||||
import dan200.computercraft.impl.RegistryHelper
|
||||
import dan200.computercraft.mixin.gametest.GameTestInfoAccessor
|
||||
import dan200.computercraft.mixin.gametest.GameTestSequenceAccessor
|
||||
import dan200.computercraft.shared.platform.PlatformHelper
|
||||
import dan200.computercraft.shared.util.RegistryHelper
|
||||
import dan200.computercraft.test.core.computer.LuaTaskContext
|
||||
import dan200.computercraft.test.shared.ItemStackMatcher.isStack
|
||||
import net.minecraft.commands.arguments.blocks.BlockInput
|
||||
|
@ -7,15 +7,22 @@ package dan200.computercraft.client.integration.rei;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.ModRegistry;
|
||||
import dan200.computercraft.shared.integration.RecipeModHelpers;
|
||||
import dan200.computercraft.shared.platform.RegistryEntry;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
|
||||
import dan200.computercraft.shared.turtle.items.TurtleItem;
|
||||
import dev.architectury.event.EventResult;
|
||||
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
|
||||
import me.shedaniel.rei.api.client.registry.display.DisplayRegistry;
|
||||
import me.shedaniel.rei.api.client.registry.entry.CollapsibleEntryRegistry;
|
||||
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
|
||||
import me.shedaniel.rei.api.common.display.basic.BasicDisplay;
|
||||
import me.shedaniel.rei.api.common.entry.comparison.ItemComparatorRegistry;
|
||||
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
|
||||
import me.shedaniel.rei.api.common.util.EntryStacks;
|
||||
import me.shedaniel.rei.plugin.common.BuiltinPlugin;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
|
||||
/**
|
||||
* REI integration for ComputerCraft.
|
||||
@ -40,15 +47,30 @@ public class REIComputerCraft implements REIClientPlugin {
|
||||
var upgrade = PocketComputerItem.getUpgradeWithData(stack);
|
||||
return upgrade == null ? 1 : upgrade.holder().key().location().hashCode();
|
||||
}, ModRegistry.Items.POCKET_COMPUTER_NORMAL.get(), ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get());
|
||||
|
||||
registry.register((context, stack) -> DyedItemColor.getOrDefault(stack, -1), ModRegistry.Items.DISK.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEntries(EntryRegistry registry) {
|
||||
for (var stack : RecipeModHelpers.getExtraStacks(RecipeModHelpers.getEmptyRegistryAccess())) {
|
||||
for (var stack : RecipeModHelpers.getExtraStacks(BasicDisplay.registryAccess())) {
|
||||
registry.addEntry(EntryStacks.of(stack));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCollapsibleEntries(CollapsibleEntryRegistry registry) {
|
||||
addCollapsableGroup(registry, ModRegistry.Items.TURTLE_NORMAL);
|
||||
addCollapsableGroup(registry, ModRegistry.Items.TURTLE_ADVANCED);
|
||||
addCollapsableGroup(registry, ModRegistry.Items.POCKET_COMPUTER_NORMAL);
|
||||
addCollapsableGroup(registry, ModRegistry.Items.POCKET_COMPUTER_ADVANCED);
|
||||
}
|
||||
|
||||
private static void addCollapsableGroup(CollapsibleEntryRegistry registry, RegistryEntry<? extends Item> holder) {
|
||||
var item = holder.get();
|
||||
registry.group(holder.id(), new ItemStack(item).getDisplayName(), VanillaEntryTypes.ITEM, x -> x.getValue().is(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDisplays(DisplayRegistry registry) {
|
||||
registry.registerDisplayGenerator(BuiltinPlugin.CRAFTING, new UpgradeDisplayGenerator());
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
package dan200.computercraft.client.integration.rei;
|
||||
|
||||
import dan200.computercraft.shared.integration.RecipeModHelpers;
|
||||
import dan200.computercraft.shared.integration.UpgradeRecipeGenerator;
|
||||
import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator;
|
||||
import me.shedaniel.rei.api.common.display.basic.BasicDisplay;
|
||||
@ -24,7 +23,7 @@ import java.util.Optional;
|
||||
* Provides custom recipe and usage hints for pocket/turtle upgrades.
|
||||
*/
|
||||
class UpgradeDisplayGenerator implements DynamicDisplayGenerator<DefaultCraftingDisplay<?>> {
|
||||
private final UpgradeRecipeGenerator<DefaultCraftingDisplay<?>> resolver = new UpgradeRecipeGenerator<>(GeneratedShapedDisplay::new, RecipeModHelpers.getEmptyRegistryAccess());
|
||||
private final UpgradeRecipeGenerator<DefaultCraftingDisplay<?>> resolver = new UpgradeRecipeGenerator<>(GeneratedShapedDisplay::new, BasicDisplay.registryAccess());
|
||||
|
||||
@Override
|
||||
public Optional<List<DefaultCraftingDisplay<?>>> getRecipeFor(EntryStack<?> entry) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "E": {"item": "minecraft:ender_pearl"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "E": {"item": "minecraft:ender_pearl"}},
|
||||
"pattern": ["###", "#E#", "###"],
|
||||
"result": {"count": 1, "id": "computercraft:wireless_modem_normal"}
|
||||
}
|
||||
|
@ -5,41 +5,40 @@
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricCodecDataProvider;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistries;
|
||||
import net.minecraft.core.*;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.RegistrySetBuilder;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.tags.TagsProvider;
|
||||
import net.minecraft.resources.RegistryDataLoader;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class FabricDataGenerators implements DataGeneratorEntrypoint {
|
||||
@Override
|
||||
public void onInitializeDataGenerator(FabricDataGenerator generator) {
|
||||
var pack = new PlatformGeneratorsImpl(generator.createPack());
|
||||
var pack = new PlatformGeneratorsImpl(generator.createPack(), generator.getRegistries());
|
||||
DataProviders.add(pack);
|
||||
}
|
||||
|
||||
private record PlatformGeneratorsImpl(FabricDataGenerator.Pack generator) implements DataProviders.GeneratorSink {
|
||||
private record PlatformGeneratorsImpl(
|
||||
FabricDataGenerator.Pack generator, CompletableFuture<HolderLookup.Provider> registries
|
||||
) implements DataProviders.GeneratorSink {
|
||||
public <T extends DataProvider> T addWithFabricOutput(FabricDataGenerator.Pack.Factory<T> factory) {
|
||||
return generator.addProvider((FabricDataOutput p) -> new PrettyDataProvider<>(factory.create(p))).provider();
|
||||
}
|
||||
@ -53,11 +52,6 @@ public class FabricDataGenerators implements DataGeneratorEntrypoint {
|
||||
return addWithFabricOutput(factory::create);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends DataProvider> T add(BiFunction<PackOutput, CompletableFuture<HolderLookup.Provider>, T> factory) {
|
||||
return addWithRegistries(factory::apply);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void addFromCodec(String name, PackType type, String directory, Codec<T> codec, Consumer<BiConsumer<ResourceLocation, T>> output) {
|
||||
addWithRegistries((out, registries) -> {
|
||||
@ -111,61 +105,24 @@ public class FabricDataGenerators implements DataGeneratorEntrypoint {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<RegistrySetBuilder.PatchedRegistries> createPatchedRegistries(CompletableFuture<HolderLookup.Provider> registries, RegistrySetBuilder patch) {
|
||||
return registries.thenApply(oldRegistries -> {
|
||||
var factory = new Cloner.Factory();
|
||||
DynamicRegistries.getDynamicRegistries().forEach(registryData -> registryData.runWithArguments(factory::addCodec));
|
||||
return patch.buildPatch(RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY), new DynamicRegistryLookup(oldRegistries), factory);
|
||||
public void registries(CompletableFuture<RegistrySetBuilder.PatchedRegistries> registries) {
|
||||
addWithFabricOutput(out -> new FabricDynamicRegistryProvider(out, registries.thenApply(RegistrySetBuilder.PatchedRegistries::patches)) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Registries";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HolderLookup.Provider registries, Entries entries) {
|
||||
for (var reg : DynamicRegistries.getDynamicRegistries()) {
|
||||
registries.lookupOrThrow(reg.key()).listElements().forEach(x -> register(entries, x));
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void register(Entries entries, Holder.Reference<T> reference) {
|
||||
entries.add(reference.key(), reference.value());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link HolderLookup.Provider} implementation that adds any Fabric dynamic registry, if missing.
|
||||
*
|
||||
* @param parent The parent registry.
|
||||
*/
|
||||
private record DynamicRegistryLookup(HolderLookup.Provider parent) implements HolderLookup.Provider {
|
||||
@Override
|
||||
public Stream<ResourceKey<? extends Registry<?>>> listRegistries() {
|
||||
return Stream.concat(
|
||||
parent.listRegistries(),
|
||||
DynamicRegistries.getDynamicRegistries().stream().map(RegistryDataLoader.RegistryData::key)
|
||||
).distinct();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<HolderLookup.RegistryLookup<T>> lookup(ResourceKey<? extends Registry<? extends T>> registryKey) {
|
||||
return parent.lookup(registryKey).or(() -> Optional.of(new EmptyRegistry<>(registryKey)));
|
||||
}
|
||||
}
|
||||
|
||||
private record EmptyRegistry<T>(
|
||||
ResourceKey<? extends Registry<? extends T>> key
|
||||
) implements HolderLookup.RegistryLookup<T> {
|
||||
@Override
|
||||
public Lifecycle registryLifecycle() {
|
||||
return Lifecycle.stable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Holder.Reference<T>> listElements() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<HolderSet.Named<T>> listTags() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Holder.Reference<T>> get(ResourceKey<T> resourceKey) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HolderSet.Named<T>> get(TagKey<T> tagKey) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.detail.FabricDetailRegistries;
|
||||
import dan200.computercraft.api.network.wired.WiredElementLookup;
|
||||
import dan200.computercraft.api.peripheral.PeripheralLookup;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.impl.Peripherals;
|
||||
import dan200.computercraft.impl.PocketUpgrades;
|
||||
import dan200.computercraft.impl.TurtleUpgrades;
|
||||
@ -66,8 +68,8 @@ public class ComputerCraft {
|
||||
|
||||
FabricRegistryBuilder.createSimple(RecipeFunction.REGISTRY).attribute(RegistryAttribute.SYNCED).buildAndRegister();
|
||||
|
||||
DynamicRegistries.registerSynced(ModRegistry.TURTLE_UPGRADE, TurtleUpgrades.instance().upgradeCodec());
|
||||
DynamicRegistries.registerSynced(ModRegistry.POCKET_UPGRADE, PocketUpgrades.instance().upgradeCodec());
|
||||
DynamicRegistries.registerSynced(ITurtleUpgrade.REGISTRY, TurtleUpgrades.instance().upgradeCodec());
|
||||
DynamicRegistries.registerSynced(IPocketUpgrade.REGISTRY, PocketUpgrades.instance().upgradeCodec());
|
||||
|
||||
ModRegistry.register();
|
||||
ModRegistry.registerMainThread();
|
||||
|
@ -5,11 +5,8 @@
|
||||
package dan200.computercraft.shared.platform;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.network.wired.WiredElement;
|
||||
import dan200.computercraft.api.network.wired.WiredElementLookup;
|
||||
@ -27,14 +24,11 @@ import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
|
||||
import net.fabricmc.fabric.api.lookup.v1.block.BlockApiCache;
|
||||
import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup;
|
||||
import net.fabricmc.fabric.api.registry.FuelRegistry;
|
||||
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceCondition;
|
||||
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType;
|
||||
import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@ -49,7 +43,6 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
@ -79,13 +72,8 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@AutoService(dan200.computercraft.impl.PlatformHelper.class)
|
||||
@AutoService(PlatformHelper.class)
|
||||
public class PlatformHelperImpl implements PlatformHelper {
|
||||
@Override
|
||||
public boolean isDevelopmentEnvironment() {
|
||||
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigFile.Builder createConfigBuilder() {
|
||||
return new FabricConfigFile.Builder();
|
||||
@ -103,22 +91,6 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
return new RegistrationHelperImpl<>(getRegistry(registry));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLoadResource(JsonObject object) {
|
||||
return true; // Done by default in Fabric, so can be skipped
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredModCondition(JsonObject object, String modId) {
|
||||
var conditions = GsonHelper.getAsJsonArray(object, ResourceConditions.CONDITIONS_KEY, null);
|
||||
if (conditions == null) {
|
||||
conditions = new JsonArray();
|
||||
object.add(ResourceConditions.CONDITIONS_KEY, conditions);
|
||||
}
|
||||
|
||||
conditions.add(ResourceCondition.CODEC.encodeStart(JsonOps.INSTANCE, ResourceConditions.allModsLoaded(modId)).getOrThrow());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends ArgumentType<?>, T extends ArgumentTypeInfo.Template<A>, I extends ArgumentTypeInfo<A, T>> I registerArgumentTypeInfo(Class<A> klass, I info) {
|
||||
ArgumentTypeInfosAccessor.classMap().put(klass, info);
|
||||
@ -171,7 +143,6 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
Ingredient.of(ConventionalItemTags.REDSTONE_DUSTS),
|
||||
Ingredient.of(ConventionalItemTags.STRINGS),
|
||||
Ingredient.of(Items.LEATHER),
|
||||
Ingredient.of(ConventionalItemTags.STONES),
|
||||
Ingredient.of(ConventionalItemTags.GLASS_PANES),
|
||||
Ingredient.of(ConventionalItemTags.GOLD_INGOTS),
|
||||
Ingredient.of(ConventionalItemTags.STORAGE_BLOCKS_GOLD),
|
||||
|
@ -47,7 +47,7 @@
|
||||
"depends": {
|
||||
"fabricloader": ">=0.15.10",
|
||||
"fabric-api": ">=0.97.3",
|
||||
"minecraft": ">=1.20.5 <1.20.7"
|
||||
"minecraft": "=1.20.6"
|
||||
},
|
||||
"accessWidener": "computercraft.accesswidener"
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ cct.inlineProject(":common-api")
|
||||
|
||||
dependencies {
|
||||
api(project(":core-api"))
|
||||
|
||||
// FIXME: This should be implementation (and in the common Forge config)
|
||||
// but NeoGradle does weird things and we end up with two Forge deps on the
|
||||
// classpath - https://github.com/neoforged/NeoGradle/issues/162.
|
||||
compileOnly("net.neoforged:neoforge:${libs.versions.neoForge.get()}")
|
||||
}
|
||||
|
||||
tasks.javadoc {
|
||||
|
@ -89,7 +89,7 @@ runs {
|
||||
}
|
||||
|
||||
val gameTestClient by registering {
|
||||
configure(runTypes.client)
|
||||
configure(runTypes.named("client"))
|
||||
|
||||
workingDirectory(file("run/testClient"))
|
||||
configureForGameTest()
|
||||
@ -121,6 +121,8 @@ dependencies {
|
||||
compileOnly(libs.bundles.externalMods.forge.compile)
|
||||
runtimeOnly(libs.bundles.externalMods.forge.runtime) { cct.exclude(this) }
|
||||
|
||||
implementation("net.neoforged:neoforge:${libs.versions.neoForge.get()}")
|
||||
|
||||
// Depend on our other projects.
|
||||
api(commonClasses(project(":forge-api"))) { cct.exclude(this) }
|
||||
clientApi(clientClasses(project(":forge-api"))) { cct.exclude(this) }
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"type": "computercraft:impostor_shapeless",
|
||||
"category": "redstone",
|
||||
"ingredients": [{"tag": "c:leather"}, {"item": "computercraft:printed_page"}, {"tag": "c:strings"}],
|
||||
"ingredients": [{"tag": "c:leathers"}, {"item": "computercraft:printed_page"}, {"tag": "c:strings"}],
|
||||
"result": {"count": 1, "id": "computercraft:printed_book"}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "redstone",
|
||||
"key": {"#": {"tag": "c:stones"}, "E": {"tag": "c:ender_pearls"}},
|
||||
"key": {"#": {"item": "minecraft:stone"}, "E": {"tag": "c:ender_pearls"}},
|
||||
"pattern": ["###", "#E#", "###"],
|
||||
"result": {"count": 1, "id": "computercraft:wireless_modem_normal"}
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ public final class ComputerCraft {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerDynamicRegistries(DataPackRegistryEvent.NewRegistry event) {
|
||||
event.dataPackRegistry(ModRegistry.TURTLE_UPGRADE, TurtleUpgrades.instance().upgradeCodec(), TurtleUpgrades.instance().upgradeCodec());
|
||||
event.dataPackRegistry(ModRegistry.POCKET_UPGRADE, PocketUpgrades.instance().upgradeCodec(), PocketUpgrades.instance().upgradeCodec());
|
||||
event.dataPackRegistry(ITurtleUpgrade.REGISTRY, TurtleUpgrades.instance().upgradeCodec(), TurtleUpgrades.instance().upgradeCodec());
|
||||
event.dataPackRegistry(IPocketUpgrade.REGISTRY, PocketUpgrades.instance().upgradeCodec(), PocketUpgrades.instance().upgradeCodec());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -7,6 +7,7 @@ package dan200.computercraft.data;
|
||||
import com.mojang.serialization.Codec;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.RegistrySetBuilder;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.DataProvider;
|
||||
@ -21,13 +22,13 @@ import net.minecraft.world.level.block.Block;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.common.data.BlockTagsProvider;
|
||||
import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import net.neoforged.neoforge.common.data.JsonCodecProvider;
|
||||
import net.neoforged.neoforge.data.event.GatherDataEvent;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD)
|
||||
@ -48,11 +49,6 @@ public class Generators {
|
||||
return generator.addProvider(p -> new PrettyDataProvider<>(factory.create(p))).provider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends DataProvider> T add(BiFunction<PackOutput, CompletableFuture<HolderLookup.Provider>, T> factory) {
|
||||
return generator.addProvider(p -> new PrettyDataProvider<>(factory.apply(p, registries))).provider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void addFromCodec(String name, PackType type, String directory, Codec<T> codec, Consumer<BiConsumer<ResourceLocation, T>> output) {
|
||||
add(out -> {
|
||||
@ -99,5 +95,10 @@ public class Generators {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registries(CompletableFuture<RegistrySetBuilder.PatchedRegistries> registries) {
|
||||
add(out -> new DatapackBuiltinEntriesProvider(out, registries, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,8 @@
|
||||
package dan200.computercraft.shared.platform;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.network.wired.WiredElement;
|
||||
@ -32,7 +29,6 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
@ -54,16 +50,12 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.bus.api.Event;
|
||||
import net.neoforged.fml.loading.FMLLoader;
|
||||
import net.neoforged.neoforge.capabilities.BlockCapability;
|
||||
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.common.CommonHooks;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
import net.neoforged.neoforge.common.ToolActions;
|
||||
import net.neoforged.neoforge.common.conditions.ConditionalOps;
|
||||
import net.neoforged.neoforge.common.conditions.ICondition;
|
||||
import net.neoforged.neoforge.common.conditions.ModLoadedCondition;
|
||||
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
|
||||
import net.neoforged.neoforge.event.EventHooks;
|
||||
import net.neoforged.neoforge.items.wrapper.InvWrapper;
|
||||
@ -78,13 +70,8 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@AutoService(dan200.computercraft.impl.PlatformHelper.class)
|
||||
@AutoService(PlatformHelper.class)
|
||||
public class PlatformHelperImpl implements PlatformHelper {
|
||||
@Override
|
||||
public boolean isDevelopmentEnvironment() {
|
||||
return !FMLLoader.isProduction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigFile.Builder createConfigBuilder() {
|
||||
return new ForgeConfigFile.Builder();
|
||||
@ -95,23 +82,6 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
return new RegistrationHelperImpl<>(DeferredRegister.create(registry, ComputerCraftAPI.MOD_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLoadResource(JsonObject object) {
|
||||
return ICondition.conditionsMatched(JsonOps.INSTANCE, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredModCondition(JsonObject object, String modId) {
|
||||
// FIXME: Test this, though maybe this should be implemented a different way anyway?
|
||||
var conditions = GsonHelper.getAsJsonArray(object, ConditionalOps.DEFAULT_CONDITIONS_KEY, null);
|
||||
if (conditions == null) {
|
||||
conditions = new JsonArray();
|
||||
object.add(ConditionalOps.DEFAULT_CONDITIONS_KEY, conditions);
|
||||
}
|
||||
|
||||
conditions.add(ICondition.CODEC.encodeStart(JsonOps.INSTANCE, new ModLoadedCondition(modId)).getOrThrow());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends ArgumentType<?>, T extends ArgumentTypeInfo.Template<A>, I extends ArgumentTypeInfo<A, T>> I registerArgumentTypeInfo(Class<A> klass, I info) {
|
||||
return ArgumentTypeInfos.registerByClass(klass, info);
|
||||
@ -169,7 +139,6 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
Ingredient.of(Tags.Items.DUSTS_REDSTONE),
|
||||
Ingredient.of(Tags.Items.STRINGS),
|
||||
Ingredient.of(Tags.Items.LEATHERS),
|
||||
Ingredient.of(Tags.Items.STONES),
|
||||
Ingredient.of(Tags.Items.GLASS_PANES),
|
||||
Ingredient.of(Tags.Items.INGOTS_GOLD),
|
||||
Ingredient.of(Tags.Items.STORAGE_BLOCKS_GOLD),
|
||||
|
@ -26,7 +26,7 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a
|
||||
[[dependencies.computercraft]]
|
||||
modId="neoforge"
|
||||
type="required"
|
||||
versionRange="[${neoVersion},20.6)"
|
||||
versionRange="[${neoVersion},20.7)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user