1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-25 22:53:22 +00:00

Some datagen improvements

- Convert remaining recipes over to datagen.

 - Switch loot tables to use vanilla's loot table generator. It's
   honestly not too different, just the earlier system confused me too
   much :).

Alas, a positive diff because the JSON is so verbose. I've got a really
nice patch which makes the JSON more compact, but alas the Mixin doesn't
apply on 1.16 :(.
This commit is contained in:
Jonathan Coates 2022-10-22 10:48:30 +01:00
parent cb9731306c
commit ff89e5feeb
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
35 changed files with 536 additions and 325 deletions

View File

@ -0,0 +1,35 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"computercraft:computer_advanced_upgrade"
]
},
"criteria": {
"has_components": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"item": "computercraft:computer_normal"
},
{
"tag": "forge:ingots/gold"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "computercraft:computer_advanced_upgrade"
}
}
},
"requirements": [
[
"has_components",
"has_the_recipe"
]
]
}

View File

@ -0,0 +1,35 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"computercraft:pocket_computer_advanced_upgrade"
]
},
"criteria": {
"has_components": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"item": "computercraft:pocket_computer_normal"
},
{
"tag": "forge:ingots/gold"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "computercraft:pocket_computer_advanced_upgrade"
}
}
},
"requirements": [
[
"has_components",
"has_the_recipe"
]
]
}

View File

@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"computercraft:turtle_advanced"
]
},
"criteria": {
"has_computer": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"item": "computercraft:computer_normal"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "computercraft:turtle_advanced"
}
}
},
"requirements": [
[
"has_computer",
"has_the_recipe"
]
]
}

View File

@ -0,0 +1,35 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"computercraft:turtle_advanced_upgrade"
]
},
"criteria": {
"has_components": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
},
{
"tag": "forge:ingots/gold"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "computercraft:turtle_advanced_upgrade"
}
}
},
"requirements": [
[
"has_components",
"has_the_recipe"
]
]
}

View File

@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"computercraft:turtle_normal"
]
},
"criteria": {
"has_computer": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"item": "computercraft:computer_normal"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "computercraft:turtle_normal"
}
}
},
"requirements": [
[
"has_computer",
"has_the_recipe"
]
]
}

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "cable",
"rolls": 1,
"entries": [
{
@ -24,7 +23,6 @@
]
},
{
"name": "wired_modem",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,11 +2,16 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"functions": [
{
"function": "minecraft:copy_name",
"source": "block_entity"
}
],
"name": "computercraft:disk_drive"
}
],

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,11 +2,16 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"functions": [
{
"function": "minecraft:copy_name",
"source": "block_entity"
}
],
"name": "computercraft:printer"
}
],

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -2,7 +2,6 @@
"type": "minecraft:block",
"pools": [
{
"name": "main",
"rolls": 1,
"entries": [
{

View File

@ -0,0 +1,20 @@
{
"type": "computercraft:computer_upgrade",
"pattern": [
"###",
"#C#",
"# #"
],
"key": {
"#": {
"tag": "forge:ingots/gold"
},
"C": {
"item": "computercraft:computer_advanced"
}
},
"result": {
"item": "computercraft:computer_advanced"
},
"family": "ADVANCED"
}

View File

@ -0,0 +1,20 @@
{
"type": "computercraft:computer_upgrade",
"pattern": [
"###",
"#C#",
"# #"
],
"key": {
"#": {
"tag": "forge:ingots/gold"
},
"C": {
"item": "computercraft:pocket_computer_normal"
}
},
"result": {
"item": "computercraft:pocket_computer_advanced"
},
"family": "ADVANCED"
}

View File

@ -0,0 +1,23 @@
{
"type": "computercraft:turtle",
"pattern": [
"###",
"#C#",
"#I#"
],
"key": {
"#": {
"tag": "forge:ingots/gold"
},
"C": {
"item": "computercraft:computer_advanced"
},
"I": {
"tag": "forge:chests/wooden"
}
},
"result": {
"item": "computercraft:turtle_advanced"
},
"family": "ADVANCED"
}

View File

@ -0,0 +1,23 @@
{
"type": "computercraft:computer_upgrade",
"pattern": [
"###",
"#C#",
" B "
],
"key": {
"#": {
"tag": "forge:ingots/gold"
},
"C": {
"item": "computercraft:computer_advanced"
},
"B": {
"tag": "forge:storage_blocks/gold"
}
},
"result": {
"item": "computercraft:turtle_advanced"
},
"family": "ADVANCED"
}

View File

@ -0,0 +1,23 @@
{
"type": "computercraft:turtle",
"pattern": [
"###",
"#C#",
"#I#"
],
"key": {
"#": {
"tag": "forge:ingots/iron"
},
"C": {
"item": "computercraft:computer_normal"
},
"I": {
"tag": "forge:chests/wooden"
}
},
"result": {
"item": "computercraft:turtle_normal"
},
"family": "NORMAL"
}

View File

@ -5,6 +5,7 @@
*/
package dan200.computercraft.data;
import com.mojang.datafixers.util.Pair;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.CommonHooks;
import dan200.computercraft.shared.Registry;
@ -16,14 +17,22 @@
import net.minecraft.advancements.criterion.StatePropertiesPredicate;
import net.minecraft.block.Block;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.LootTableProvider;
import net.minecraft.loot.*;
import net.minecraft.loot.conditions.Alternative;
import net.minecraft.loot.conditions.BlockStateProperty;
import net.minecraft.loot.conditions.ILootCondition;
import net.minecraft.loot.conditions.SurvivesExplosion;
import net.minecraft.loot.functions.CopyName;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.RegistryObject;
import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class LootTableGenerator extends LootTableProvider
{
@ -32,17 +41,32 @@ public LootTableGenerator( DataGenerator generator )
super( generator );
}
@Nonnull
@Override
protected void registerLoot( BiConsumer<ResourceLocation, LootTable> add )
protected List<Pair<Supplier<Consumer<BiConsumer<ResourceLocation, LootTable.Builder>>>, LootParameterSet>> getTables()
{
basicDrop( add, Registry.ModBlocks.DISK_DRIVE );
basicDrop( add, Registry.ModBlocks.MONITOR_NORMAL );
basicDrop( add, Registry.ModBlocks.MONITOR_ADVANCED );
basicDrop( add, Registry.ModBlocks.PRINTER );
basicDrop( add, Registry.ModBlocks.SPEAKER );
basicDrop( add, Registry.ModBlocks.WIRED_MODEM_FULL );
basicDrop( add, Registry.ModBlocks.WIRELESS_MODEM_NORMAL );
basicDrop( add, Registry.ModBlocks.WIRELESS_MODEM_ADVANCED );
return Arrays.asList(
Pair.of( () -> LootTableGenerator::registerBlocks, LootParameterSets.BLOCK ),
Pair.of( () -> LootTableGenerator::registerGeneric, LootParameterSets.ALL_PARAMS )
);
}
@Override
protected void validate( Map<ResourceLocation, LootTable> map, @Nonnull ValidationTracker validationtracker )
{
map.forEach( ( id, table ) -> LootTableManager.validate( validationtracker, id, table ) );
}
private static void registerBlocks( BiConsumer<ResourceLocation, LootTable.Builder> add )
{
namedBlockDrop( add, Registry.ModBlocks.DISK_DRIVE );
selfDrop( add, Registry.ModBlocks.MONITOR_NORMAL );
selfDrop( add, Registry.ModBlocks.MONITOR_ADVANCED );
namedBlockDrop( add, Registry.ModBlocks.PRINTER );
selfDrop( add, Registry.ModBlocks.SPEAKER );
selfDrop( add, Registry.ModBlocks.WIRED_MODEM_FULL );
selfDrop( add, Registry.ModBlocks.WIRELESS_MODEM_NORMAL );
selfDrop( add, Registry.ModBlocks.WIRELESS_MODEM_ADVANCED );
computerDrop( add, Registry.ModBlocks.COMPUTER_NORMAL );
computerDrop( add, Registry.ModBlocks.COMPUTER_ADVANCED );
@ -52,9 +76,7 @@ protected void registerLoot( BiConsumer<ResourceLocation, LootTable> add )
add.accept( Registry.ModBlocks.CABLE.get().getLootTable(), LootTable
.lootTable()
.setParamSet( LootParameterSets.BLOCK )
.withPool( LootPool.lootPool()
.name( "cable" )
.setRolls( ConstantRange.exactly( 1 ) )
.add( ItemLootEntry.lootTableItem( Registry.ModItems.CABLE.get() ) )
.when( SurvivesExplosion.survivesExplosion() )
@ -63,7 +85,6 @@ protected void registerLoot( BiConsumer<ResourceLocation, LootTable> add )
)
)
.withPool( LootPool.lootPool()
.name( "wired_modem" )
.setRolls( ConstantRange.exactly( 1 ) )
.add( ItemLootEntry.lootTableItem( Registry.ModItems.WIRED_MODEM.get() ) )
.when( SurvivesExplosion.survivesExplosion() )
@ -71,44 +92,55 @@ protected void registerLoot( BiConsumer<ResourceLocation, LootTable> add )
.setProperties( StatePropertiesPredicate.Builder.properties().hasProperty( BlockCable.MODEM, CableModemVariant.None ) )
.invert()
)
) );
}
private static void registerGeneric( BiConsumer<ResourceLocation, LootTable.Builder> add )
{
add.accept( CommonHooks.LOOT_TREASURE_DISK, LootTable.lootTable() );
}
private static void selfDrop( BiConsumer<ResourceLocation, LootTable.Builder> add, Supplier<? extends Block> wrapper )
{
blockDrop( add, wrapper, ItemLootEntry.lootTableItem( wrapper.get() ), SurvivesExplosion.survivesExplosion() );
}
private static void namedBlockDrop( BiConsumer<ResourceLocation, LootTable.Builder> add, Supplier<? extends Block> wrapper )
{
blockDrop(
add, wrapper,
ItemLootEntry.lootTableItem( wrapper.get() ).apply( CopyName.copyName( CopyName.Source.BLOCK_ENTITY ) ),
SurvivesExplosion.survivesExplosion()
);
}
private static void computerDrop( BiConsumer<ResourceLocation, LootTable.Builder> add, Supplier<? extends Block> block )
{
blockDrop(
add, block,
DynamicLootEntry.dynamicEntry( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ),
Alternative.alternative(
BlockNamedEntityLootCondition.BUILDER,
HasComputerIdLootCondition.BUILDER,
PlayerCreativeLootCondition.BUILDER.invert()
)
.build() );
add.accept( CommonHooks.LOOT_TREASURE_DISK, LootTable
.lootTable()
.setParamSet( LootParameterSets.ALL_PARAMS )
.build() );
);
}
private static <T extends Block> void basicDrop( BiConsumer<ResourceLocation, LootTable> add, RegistryObject<T> wrapper )
private static void blockDrop(
BiConsumer<ResourceLocation, LootTable.Builder> add, Supplier<? extends Block> wrapper,
LootEntry.Builder<?> drop,
ILootCondition.IBuilder condition
)
{
Block block = wrapper.get();
add.accept( block.getLootTable(), LootTable
.lootTable()
.setParamSet( LootParameterSets.BLOCK )
.withPool( LootPool.lootPool()
.name( "main" )
.setRolls( ConstantRange.exactly( 1 ) )
.add( ItemLootEntry.lootTableItem( block ) )
.when( SurvivesExplosion.survivesExplosion() )
).build() );
}
private static <T extends Block> void computerDrop( BiConsumer<ResourceLocation, LootTable> add, RegistryObject<T> wrapper )
{
Block block = wrapper.get();
add.accept( block.getLootTable(), LootTable
.lootTable()
.setParamSet( LootParameterSets.BLOCK )
.withPool( LootPool.lootPool()
.name( "main" )
.setRolls( ConstantRange.exactly( 1 ) )
.add( DynamicLootEntry.dynamicEntry( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ) )
.when( Alternative.alternative(
BlockNamedEntityLootCondition.BUILDER,
HasComputerIdLootCondition.BUILDER,
PlayerCreativeLootCondition.BUILDER.invert()
) )
).build() );
.add( drop )
.when( condition )
)
);
}
}

View File

@ -1,91 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import com.google.common.collect.Multimap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dan200.computercraft.ComputerCraft;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DirectoryCache;
import net.minecraft.data.IDataProvider;
import net.minecraft.loot.LootParameterSets;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.LootTableManager;
import net.minecraft.loot.ValidationTracker;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* An alternative to {@link net.minecraft.data.LootTableProvider}, with a more flexible interface.
*/
public abstract class LootTableProvider implements IDataProvider
{
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
private final DataGenerator generator;
public LootTableProvider( DataGenerator generator )
{
this.generator = generator;
}
@Override
public void run( @Nonnull DirectoryCache cache )
{
Map<ResourceLocation, LootTable> tables = new HashMap<>();
ValidationTracker validation = new ValidationTracker( LootParameterSets.ALL_PARAMS, x -> null, tables::get );
registerLoot( ( id, table ) -> {
if( tables.containsKey( id ) ) validation.reportProblem( "Duplicate loot tables for " + id );
tables.put( id, table );
} );
tables.forEach( ( key, value ) -> LootTableManager.validate( validation, key, value ) );
Multimap<String, String> problems = validation.getProblems();
if( !problems.isEmpty() )
{
problems.forEach( ( child, problem ) ->
ComputerCraft.log.warn( "Found validation problem in " + child + ": " + problem ) );
throw new IllegalStateException( "Failed to validate loot tables, see logs" );
}
tables.forEach( ( key, value ) -> {
Path path = getPath( key );
try
{
IDataProvider.save( GSON, cache, LootTableManager.serialize( value ), path );
}
catch( IOException e )
{
ComputerCraft.log.error( "Couldn't save loot table {}", path, e );
}
} );
}
protected abstract void registerLoot( BiConsumer<ResourceLocation, LootTable> add );
@Nonnull
@Override
public String getName()
{
return "LootTables";
}
private Path getPath( ResourceLocation id )
{
return generator.getOutputFolder()
.resolve( "data" ).resolve( id.getNamespace() ).resolve( "loot_tables" )
.resolve( id.getPath() + ".json" );
}
}

View File

@ -5,6 +5,7 @@
*/
package dan200.computercraft.data;
import com.google.gson.JsonObject;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.PocketUpgrades;
import dan200.computercraft.shared.Registry;
@ -12,11 +13,13 @@
import dan200.computercraft.shared.common.ColourableRecipe;
import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.recipe.ComputerUpgradeRecipe;
import dan200.computercraft.shared.media.recipes.DiskRecipe;
import dan200.computercraft.shared.media.recipes.PrintoutRecipe;
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe;
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
import dan200.computercraft.shared.turtle.recipes.TurtleRecipe;
import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.ImpostorRecipe;
@ -79,10 +82,11 @@ private void diskColours( @Nonnull Consumer<IFinishedRecipe> add )
.requires( DyeItem.byColor( ofColour( colour ) ) )
.group( "computercraft:disk" )
.unlockedBy( "has_drive", inventoryChange( Registry.ModBlocks.DISK_DRIVE.get() ) )
.save( RecipeWrapper.wrap(
ImpostorShapelessRecipe.SERIALIZER, add,
x -> x.putInt( IColouredItem.NBT_COLOUR, colour.getHex() )
), new ResourceLocation( ComputerCraft.MOD_ID, "disk_" + (colour.ordinal() + 1) ) );
.save(
RecipeWrapper.wrap( ImpostorShapelessRecipe.SERIALIZER, add )
.withResultTag( x -> x.putInt( IColouredItem.NBT_COLOUR, colour.getHex() ) ),
new ResourceLocation( ComputerCraft.MOD_ID, "disk_" + (colour.ordinal() + 1) )
);
}
}
@ -111,7 +115,7 @@ private void turtleUpgrades( @Nonnull Consumer<IFinishedRecipe> add )
.unlockedBy( "has_items",
inventoryChange( base.getItem(), upgrade.getCraftingItem().getItem() ) )
.save(
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add, result.getTag() ),
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add ).withResultTag( result.getTag() ),
new ResourceLocation( ComputerCraft.MOD_ID, String.format( "turtle_%s/%s/%s",
nameId, upgrade.getUpgradeID().getNamespace(), upgrade.getUpgradeID().getPath()
) )
@ -146,7 +150,7 @@ private void pocketUpgrades( @Nonnull Consumer<IFinishedRecipe> add )
.unlockedBy( "has_items",
inventoryChange( base.getItem(), upgrade.getCraftingItem().getItem() ) )
.save(
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add, result.getTag() ),
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add ).withResultTag( result.getTag() ),
new ResourceLocation( ComputerCraft.MOD_ID, String.format( "pocket_%s/%s/%s",
nameId, upgrade.getUpgradeID().getNamespace(), upgrade.getUpgradeID().getPath()
) )
@ -190,6 +194,19 @@ private void basicRecipes( @Nonnull Consumer<IFinishedRecipe> add )
.unlockedBy( "has_components", inventoryChange( Items.REDSTONE, Items.GOLD_INGOT ) )
.save( add );
ShapedRecipeBuilder
.shaped( Registry.ModItems.COMPUTER_ADVANCED.get() )
.pattern( "###" )
.pattern( "#C#" )
.pattern( "# #" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'C', Registry.ModItems.COMPUTER_ADVANCED.get() )
.unlockedBy( "has_components", inventoryChange( itemPredicate( Registry.ModItems.COMPUTER_NORMAL.get() ), itemPredicate( Tags.Items.INGOTS_GOLD ) ) )
.save(
RecipeWrapper.wrap( ComputerUpgradeRecipe.SERIALIZER, add ).withExtraData( family( ComputerFamily.ADVANCED ) ),
new ResourceLocation( ComputerCraft.MOD_ID, "computer_advanced_upgrade" )
);
ShapedRecipeBuilder
.shaped( Registry.ModBlocks.COMPUTER_COMMAND.get() )
.pattern( "###" )
@ -201,6 +218,42 @@ private void basicRecipes( @Nonnull Consumer<IFinishedRecipe> add )
.unlockedBy( "has_components", inventoryChange( Blocks.COMMAND_BLOCK ) )
.save( add );
ShapedRecipeBuilder
.shaped( Registry.ModBlocks.TURTLE_NORMAL.get() )
.pattern( "###" )
.pattern( "#C#" )
.pattern( "#I#" )
.define( '#', Tags.Items.INGOTS_IRON )
.define( 'C', Registry.ModItems.COMPUTER_NORMAL.get() )
.define( 'I', Tags.Items.CHESTS_WOODEN )
.unlockedBy( "has_computer", inventoryChange( Registry.ModItems.COMPUTER_NORMAL.get() ) )
.save( RecipeWrapper.wrap( TurtleRecipe.SERIALIZER, add ).withExtraData( family( ComputerFamily.NORMAL ) ) );
ShapedRecipeBuilder
.shaped( Registry.ModBlocks.TURTLE_ADVANCED.get() )
.pattern( "###" )
.pattern( "#C#" )
.pattern( "#I#" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'C', Registry.ModItems.COMPUTER_ADVANCED.get() )
.define( 'I', Tags.Items.CHESTS_WOODEN )
.unlockedBy( "has_computer", inventoryChange( Registry.ModItems.COMPUTER_NORMAL.get() ) )
.save( RecipeWrapper.wrap( TurtleRecipe.SERIALIZER, add ).withExtraData( family( ComputerFamily.ADVANCED ) ) );
ShapedRecipeBuilder
.shaped( Registry.ModBlocks.TURTLE_ADVANCED.get() )
.pattern( "###" )
.pattern( "#C#" )
.pattern( " B " )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'C', Registry.ModItems.COMPUTER_ADVANCED.get() )
.define( 'B', Tags.Items.STORAGE_BLOCKS_GOLD )
.unlockedBy( "has_components", inventoryChange( itemPredicate( Registry.ModItems.TURTLE_NORMAL.get() ), itemPredicate( Tags.Items.INGOTS_GOLD ) ) )
.save(
RecipeWrapper.wrap( ComputerUpgradeRecipe.SERIALIZER, add ).withExtraData( family( ComputerFamily.ADVANCED ) ),
new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced_upgrade" )
);
ShapedRecipeBuilder
.shaped( Registry.ModBlocks.DISK_DRIVE.get() )
.pattern( "###" )
@ -255,6 +308,19 @@ private void basicRecipes( @Nonnull Consumer<IFinishedRecipe> add )
.unlockedBy( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.save( add );
ShapedRecipeBuilder
.shaped( Registry.ModItems.POCKET_COMPUTER_ADVANCED.get() )
.pattern( "###" )
.pattern( "#C#" )
.pattern( "# #" )
.define( '#', Tags.Items.INGOTS_GOLD )
.define( 'C', Registry.ModItems.POCKET_COMPUTER_NORMAL.get() )
.unlockedBy( "has_components", inventoryChange( itemPredicate( Registry.ModItems.POCKET_COMPUTER_NORMAL.get() ), itemPredicate( Tags.Items.INGOTS_GOLD ) ) )
.save(
RecipeWrapper.wrap( ComputerUpgradeRecipe.SERIALIZER, add ).withExtraData( family( ComputerFamily.ADVANCED ) ),
new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer_advanced_upgrade" )
);
ShapedRecipeBuilder
.shaped( Registry.ModBlocks.PRINTER.get() )
.pattern( "###" )
@ -326,7 +392,8 @@ private void basicRecipes( @Nonnull Consumer<IFinishedRecipe> add )
.requires( Registry.ModItems.MONITOR_NORMAL.get() )
.unlockedBy( "has_monitor", inventoryChange( Registry.ModItems.MONITOR_NORMAL.get() ) )
.save(
RecipeWrapper.wrap( IRecipeSerializer.SHAPELESS_RECIPE, add, playerHead( "Cloudhunter", "6d074736-b1e9-4378-a99b-bd8777821c9c" ) ),
RecipeWrapper.wrap( IRecipeSerializer.SHAPELESS_RECIPE, add )
.withResultTag( playerHead( "Cloudhunter", "6d074736-b1e9-4378-a99b-bd8777821c9c" ) ),
new ResourceLocation( ComputerCraft.MOD_ID, "skull_cloudy" )
);
@ -336,7 +403,8 @@ private void basicRecipes( @Nonnull Consumer<IFinishedRecipe> add )
.requires( Registry.ModItems.COMPUTER_ADVANCED.get() )
.unlockedBy( "has_computer", inventoryChange( Registry.ModItems.COMPUTER_ADVANCED.get() ) )
.save(
RecipeWrapper.wrap( IRecipeSerializer.SHAPELESS_RECIPE, add, playerHead( "dan200", "f3c8d69b-0776-4512-8434-d1b2165909eb" ) ),
RecipeWrapper.wrap( IRecipeSerializer.SHAPELESS_RECIPE, add )
.withResultTag( playerHead( "dan200", "f3c8d69b-0776-4512-8434-d1b2165909eb" ) ),
new ResourceLocation( ComputerCraft.MOD_ID, "skull_dan200" )
);
@ -363,7 +431,7 @@ private static DyeColor ofColour( Colour colour )
private static InventoryChangeTrigger.Instance inventoryChange( ITag<Item> stack )
{
return InventoryChangeTrigger.Instance.hasItems( ItemPredicate.Builder.item().of( stack ).build() );
return InventoryChangeTrigger.Instance.hasItems( itemPredicate( stack ) );
}
private static InventoryChangeTrigger.Instance inventoryChange( IItemProvider... stack )
@ -371,6 +439,21 @@ private static InventoryChangeTrigger.Instance inventoryChange( IItemProvider...
return InventoryChangeTrigger.Instance.hasItems( stack );
}
private static InventoryChangeTrigger.Instance inventoryChange( ItemPredicate... items )
{
return InventoryChangeTrigger.Instance.hasItems( items );
}
private static ItemPredicate itemPredicate( IItemProvider item )
{
return ItemPredicate.Builder.item().of( item ).build();
}
private static ItemPredicate itemPredicate( ITag<Item> item )
{
return ItemPredicate.Builder.item().of( item ).build();
}
private static CompoundNBT playerHead( String name, String uuid )
{
CompoundNBT owner = new CompoundNBT();
@ -382,6 +465,11 @@ private static CompoundNBT playerHead( String name, String uuid )
return tag;
}
private static Consumer<JsonObject> family( ComputerFamily family )
{
return json -> json.addProperty( "family", family.toString() );
}
private static void addSpecial( Consumer<IFinishedRecipe> add, SpecialRecipeSerializer<?> special )
{
CustomRecipeBuilder.special( special ).save( add, special.getRegistryName().toString() );

View File

@ -14,78 +14,106 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
* Adapter for recipes which overrides the serializer and adds custom item NBT.
*/
public final class RecipeWrapper implements IFinishedRecipe
final class RecipeWrapper implements Consumer<IFinishedRecipe>
{
private final IFinishedRecipe recipe;
private final CompoundNBT resultData;
private final Consumer<IFinishedRecipe> add;
private final IRecipeSerializer<?> serializer;
private final List<Consumer<JsonObject>> extend = new ArrayList<>( 0 );
private RecipeWrapper( IFinishedRecipe recipe, CompoundNBT resultData, IRecipeSerializer<?> serializer )
RecipeWrapper( Consumer<IFinishedRecipe> add, IRecipeSerializer<?> serializer )
{
this.resultData = resultData;
this.recipe = recipe;
this.add = add;
this.serializer = serializer;
}
public static Consumer<IFinishedRecipe> wrap( IRecipeSerializer<?> serializer, Consumer<IFinishedRecipe> original )
public static RecipeWrapper wrap( IRecipeSerializer<?> serializer, Consumer<IFinishedRecipe> original )
{
return x -> original.accept( new RecipeWrapper( x, null, serializer ) );
return new RecipeWrapper( original, serializer );
}
public static Consumer<IFinishedRecipe> wrap( IRecipeSerializer<?> serializer, Consumer<IFinishedRecipe> original, CompoundNBT resultData )
public RecipeWrapper withExtraData( Consumer<JsonObject> extra )
{
return x -> original.accept( new RecipeWrapper( x, resultData, serializer ) );
extend.add( extra );
return this;
}
public static Consumer<IFinishedRecipe> wrap( IRecipeSerializer<?> serializer, Consumer<IFinishedRecipe> original, Consumer<CompoundNBT> resultData )
public RecipeWrapper withResultTag( @Nullable CompoundNBT resultTag )
{
if( resultTag == null ) return this;
extend.add( json -> {
JsonObject object = JSONUtils.getAsJsonObject( json, "result" );
object.addProperty( "nbt", resultTag.toString() );
} );
return this;
}
public RecipeWrapper withResultTag( Consumer<CompoundNBT> resultTag )
{
CompoundNBT tag = new CompoundNBT();
resultData.accept( tag );
return x -> original.accept( new RecipeWrapper( x, tag, serializer ) );
resultTag.accept( tag );
return withResultTag( tag );
}
@Override
public void serializeRecipeData( @Nonnull JsonObject jsonObject )
public void accept( IFinishedRecipe finishedRecipe )
{
recipe.serializeRecipeData( jsonObject );
add.accept( new RecipeImpl( finishedRecipe, serializer, extend ) );
}
if( resultData != null )
private static final class RecipeImpl implements IFinishedRecipe
{
private final IFinishedRecipe recipe;
private final IRecipeSerializer<?> serializer;
private final List<Consumer<JsonObject>> extend;
private RecipeImpl( IFinishedRecipe recipe, IRecipeSerializer<?> serializer, List<Consumer<JsonObject>> extend )
{
JsonObject object = JSONUtils.getAsJsonObject( jsonObject, "result" );
object.addProperty( "nbt", resultData.toString() );
this.recipe = recipe;
this.serializer = serializer;
this.extend = extend;
}
@Override
public void serializeRecipeData( @Nonnull JsonObject jsonObject )
{
recipe.serializeRecipeData( jsonObject );
for( Consumer<JsonObject> extender : extend ) extender.accept( jsonObject );
}
@Nonnull
@Override
public ResourceLocation getId()
{
return recipe.getId();
}
@Nonnull
@Override
public IRecipeSerializer<?> getType()
{
return serializer;
}
@Nullable
@Override
public JsonObject serializeAdvancement()
{
return recipe.serializeAdvancement();
}
@Nullable
@Override
public ResourceLocation getAdvancementId()
{
return recipe.getAdvancementId();
}
}
@Nonnull
@Override
public ResourceLocation getId()
{
return recipe.getId();
}
@Nonnull
@Override
public IRecipeSerializer<?> getType()
{
return serializer;
}
@Nullable
@Override
public JsonObject serializeAdvancement()
{
return recipe.serializeAdvancement();
}
@Nullable
@Override
public ResourceLocation getAdvancementId()
{
return recipe.getAdvancementId();
}
}

View File

@ -1,24 +0,0 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [ "computercraft:turtle_advanced" ]
},
"criteria": {
"has_advanced": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [ { "item": "computercraft:computer_advanced" } ]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": { "recipe": "computercraft:turtle_advanced" }
}
},
"requirements": [
[
"has_advanced",
"has_the_recipe"
]
]
}

View File

@ -1,24 +0,0 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [ "computercraft:turtle_normal" ]
},
"criteria": {
"has_normal": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [ { "item": "computercraft:computer_normal" } ]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": { "recipe": "computercraft:turtle_normal" }
}
},
"requirements": [
[
"has_normal",
"has_the_recipe"
]
]
}

View File

@ -1,14 +0,0 @@
{
"type": "computercraft:computer_upgrade",
"pattern": [
"###",
"#C#",
"# #"
],
"key": {
"#": { "tag": "forge:ingots/gold" },
"C": { "item": "computercraft:computer_normal" }
},
"family": "advanced",
"result": { "item": "computercraft:computer_advanced" }
}

View File

@ -1,14 +0,0 @@
{
"type": "computercraft:computer_upgrade",
"pattern": [
"###",
"#C#",
"# #"
],
"key": {
"#": { "tag": "forge:ingots/gold" },
"C": { "item": "computercraft:pocket_computer_normal" }
},
"family": "advanced",
"result": { "item": "computercraft:pocket_computer_advanced" }
}

View File

@ -1,15 +0,0 @@
{
"type": "computercraft:turtle",
"pattern": [
"###",
"#C#",
"#I#"
],
"key": {
"#": { "tag": "forge:ingots/gold" },
"C": { "item": "computercraft:computer_advanced" },
"I": { "tag": "forge:chests/wooden" }
},
"family": "advanced",
"result": { "item": "computercraft:turtle_advanced" }
}

View File

@ -1,15 +0,0 @@
{
"type": "computercraft:computer_upgrade",
"pattern": [
"###",
"#C#",
" B "
],
"key": {
"#": { "tag": "forge:ingots/gold" },
"B": { "tag": "forge:storage_blocks/gold" },
"C": { "item": "computercraft:turtle_normal" }
},
"family": "advanced",
"result": { "item": "computercraft:turtle_advanced" }
}

View File

@ -1,15 +0,0 @@
{
"type": "computercraft:turtle",
"pattern": [
"###",
"#C#",
"#I#"
],
"key": {
"#": { "tag": "forge:ingots/iron" },
"C": { "item": "computercraft:computer_normal" },
"I": { "tag": "forge:chests/wooden" }
},
"family": "normal",
"result": { "item": "computercraft:turtle_normal" }
}