1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-03 20:33:58 +00:00

Make turtle breaking a little more data driven

- Allow any tool to break an "instabreak" block (saplings, plants,
   TNT). Oddly this doesn't include bamboo or bamboo sapings (they're
   marked as instabreak, only to have their strength overridden again!),
   so we also provide a tag for additional blocks to allow.

 - Hoes and shovels now allow breaking any block for which this tool is
   effective.

 - Use block tags to drive any other block breaking capabilities. For
   instance, hoes can break pumpkins and cactuses despite not being
   effective.

This should get a little nicer in 1.17, as we can just use block tags
for everything.
This commit is contained in:
Jonathan Coates 2021-10-27 19:16:32 +01:00
parent 544bcaa599
commit ea7a218f4a
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
20 changed files with 292 additions and 124 deletions

View File

@ -21,7 +21,7 @@
"conditions": { "conditions": {
"items": [ "items": [
{ {
"tag": "computercraft:computer" "tag": "computercraft:wired_modem"
} }
] ]
} }

View File

@ -0,0 +1,8 @@
{
"replace": false,
"values": [
"computercraft:computer_normal",
"computercraft:computer_advanced",
"computercraft:computer_command"
]
}

View File

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"computercraft:monitor_normal",
"computercraft:monitor_advanced"
]
}

View File

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"computercraft:turtle_normal",
"computercraft:turtle_advanced"
]
}

View File

@ -0,0 +1,8 @@
{
"replace": false,
"values": [
"#minecraft:leaves",
"minecraft:bamboo",
"minecraft:bamboo_sapling"
]
}

View File

@ -0,0 +1,11 @@
{
"replace": false,
"values": [
"#minecraft:crops",
"minecraft:cactus",
"minecraft:melon",
"minecraft:pumpkin",
"minecraft:carved_pumpkin",
"minecraft:jack_o_lantern"
]
}

View File

@ -0,0 +1,9 @@
{
"replace": false,
"values": [
"minecraft:melon",
"minecraft:pumpkin",
"minecraft:carved_pumpkin",
"minecraft:jack_o_lantern"
]
}

View File

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"#minecraft:wool",
"minecraft:cobweb"
]
}

View File

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"computercraft:cable",
"computercraft:wired_modem_full"
]
}

View File

@ -0,0 +1,62 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.Registry;
import net.minecraft.block.Blocks;
import net.minecraft.data.BlockTagsProvider;
import net.minecraft.data.DataGenerator;
import net.minecraft.tags.BlockTags;
import net.minecraftforge.common.data.ExistingFileHelper;
import static dan200.computercraft.shared.ComputerCraftTags.Blocks.*;
public class BlockTagsGenerator extends BlockTagsProvider
{
public BlockTagsGenerator( DataGenerator generator, ExistingFileHelper helper )
{
super( generator, ComputerCraft.MOD_ID, helper );
}
@Override
@SuppressWarnings( "unchecked" )
protected void addTags()
{
// Items
tag( COMPUTER ).add(
Registry.ModBlocks.COMPUTER_NORMAL.get(),
Registry.ModBlocks.COMPUTER_ADVANCED.get(),
Registry.ModBlocks.COMPUTER_COMMAND.get()
);
tag( TURTLE ).add( Registry.ModBlocks.TURTLE_NORMAL.get(), Registry.ModBlocks.TURTLE_ADVANCED.get() );
tag( WIRED_MODEM ).add( Registry.ModBlocks.CABLE.get(), Registry.ModBlocks.WIRED_MODEM_FULL.get() );
tag( MONITOR ).add( Registry.ModBlocks.MONITOR_NORMAL.get(), Registry.ModBlocks.MONITOR_ADVANCED.get() );
tag( TURTLE_ALWAYS_BREAKABLE ).addTags( BlockTags.LEAVES ).add(
Blocks.BAMBOO, Blocks.BAMBOO_SAPLING // Bamboo isn't instabreak for some odd reason.
);
tag( TURTLE_SHOVEL_BREAKABLE ).add(
Blocks.MELON,
Blocks.PUMPKIN,
Blocks.CARVED_PUMPKIN,
Blocks.JACK_O_LANTERN
);
tag( TURTLE_HOE_BREAKABLE ).addTags(
BlockTags.CROPS
).add(
Blocks.CACTUS,
Blocks.MELON,
Blocks.PUMPKIN,
Blocks.CARVED_PUMPKIN,
Blocks.JACK_O_LANTERN
);
tag( TURTLE_SWORD_BREAKABLE ).addTags( BlockTags.WOOL ).add( Blocks.COBWEB );
}
}

View File

@ -7,6 +7,7 @@ package dan200.computercraft.data;
import dan200.computercraft.shared.Registry; import dan200.computercraft.shared.Registry;
import net.minecraft.data.DataGenerator; import net.minecraft.data.DataGenerator;
import net.minecraftforge.common.data.ExistingFileHelper;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
@ -20,9 +21,14 @@ public class Generators
Registry.registerLoot(); Registry.registerLoot();
DataGenerator generator = event.getGenerator(); DataGenerator generator = event.getGenerator();
generator.addProvider( new Recipes( generator ) ); ExistingFileHelper existingFiles = event.getExistingFileHelper();
generator.addProvider( new LootTables( generator ) );
generator.addProvider( new Tags( generator, event.getExistingFileHelper() ) ); generator.addProvider( new RecipeGenerator( generator ) );
generator.addProvider( new BlockModelProvider( generator, event.getExistingFileHelper() ) ); generator.addProvider( new LootTableGenerator( generator ) );
generator.addProvider( new BlockModelProvider( generator, existingFiles ) );
BlockTagsGenerator blockTags = new BlockTagsGenerator( generator, existingFiles );
generator.addProvider( blockTags );
generator.addProvider( new ItemTagsGenerator( generator, blockTags, existingFiles ) );
} }
} }

View File

@ -0,0 +1,42 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.ComputerCraftTags.Blocks;
import dan200.computercraft.shared.Registry;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.ItemTagsProvider;
import net.minecraft.item.Item;
import net.minecraft.tags.ITag;
import net.minecraftforge.common.data.ExistingFileHelper;
import static dan200.computercraft.shared.ComputerCraftTags.Items.*;
public class ItemTagsGenerator extends ItemTagsProvider
{
private static final ITag.INamedTag<Item> PIGLIN_LOVED = net.minecraft.tags.ItemTags.PIGLIN_LOVED;
public ItemTagsGenerator( DataGenerator generator, BlockTagsGenerator blockTags, ExistingFileHelper helper )
{
super( generator, blockTags, ComputerCraft.MOD_ID, helper );
}
@Override
protected void addTags()
{
copy( Blocks.COMPUTER, COMPUTER );
copy( Blocks.TURTLE, TURTLE );
tag( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
copy( Blocks.MONITOR, MONITOR );
tag( PIGLIN_LOVED ).add(
Registry.ModItems.COMPUTER_ADVANCED.get(), Registry.ModItems.TURTLE_ADVANCED.get(),
Registry.ModItems.WIRELESS_MODEM_ADVANCED.get(), Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(),
Registry.ModItems.MONITOR_ADVANCED.get()
);
}
}

View File

@ -25,9 +25,9 @@ import net.minecraftforge.fml.RegistryObject;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
public class LootTables extends LootTableProvider public class LootTableGenerator extends LootTableProvider
{ {
public LootTables( DataGenerator generator ) public LootTableGenerator( DataGenerator generator )
{ {
super( generator ); super( generator );
} }

View File

@ -6,7 +6,6 @@
package dan200.computercraft.data; package dan200.computercraft.data;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.data.Tags.CCTags;
import dan200.computercraft.shared.PocketUpgrades; import dan200.computercraft.shared.PocketUpgrades;
import dan200.computercraft.shared.Registry; import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.TurtleUpgrades; import dan200.computercraft.shared.TurtleUpgrades;
@ -39,9 +38,12 @@ import javax.annotation.Nonnull;
import java.util.Locale; import java.util.Locale;
import java.util.function.Consumer; import java.util.function.Consumer;
public class Recipes extends RecipeProvider import static dan200.computercraft.shared.ComputerCraftTags.Items.COMPUTER;
import static dan200.computercraft.shared.ComputerCraftTags.Items.WIRED_MODEM;
public class RecipeGenerator extends RecipeProvider
{ {
public Recipes( DataGenerator generator ) public RecipeGenerator( DataGenerator generator )
{ {
super( generator ); super( generator );
} }
@ -162,8 +164,8 @@ public class Recipes extends RecipeProvider
.pattern( " # " ) .pattern( " # " )
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE ) .define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.unlockedBy( "has_modem", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_modem", inventoryChange( WIRED_MODEM ) )
.save( add ); .save( add );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -206,7 +208,7 @@ public class Recipes extends RecipeProvider
.pattern( "#R#" ) .pattern( "#R#" )
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE ) .define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.save( add ); .save( add );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -216,7 +218,7 @@ public class Recipes extends RecipeProvider
.pattern( "###" ) .pattern( "###" )
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'G', Tags.Items.GLASS_PANES ) .define( 'G', Tags.Items.GLASS_PANES )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.save( add ); .save( add );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -226,7 +228,7 @@ public class Recipes extends RecipeProvider
.pattern( "###" ) .pattern( "###" )
.define( '#', Tags.Items.INGOTS_GOLD ) .define( '#', Tags.Items.INGOTS_GOLD )
.define( 'G', Tags.Items.GLASS_PANES ) .define( 'G', Tags.Items.GLASS_PANES )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.save( add ); .save( add );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -237,7 +239,7 @@ public class Recipes extends RecipeProvider
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'A', Items.GOLDEN_APPLE ) .define( 'A', Items.GOLDEN_APPLE )
.define( 'G', Tags.Items.GLASS_PANES ) .define( 'G', Tags.Items.GLASS_PANES )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.unlockedBy( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) ) .unlockedBy( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.save( add ); .save( add );
@ -249,7 +251,7 @@ public class Recipes extends RecipeProvider
.define( '#', Tags.Items.INGOTS_GOLD ) .define( '#', Tags.Items.INGOTS_GOLD )
.define( 'A', Items.GOLDEN_APPLE ) .define( 'A', Items.GOLDEN_APPLE )
.define( 'G', Tags.Items.GLASS_PANES ) .define( 'G', Tags.Items.GLASS_PANES )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.unlockedBy( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) ) .unlockedBy( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.save( add ); .save( add );
@ -261,7 +263,7 @@ public class Recipes extends RecipeProvider
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE ) .define( 'R', Tags.Items.DUSTS_REDSTONE )
.define( 'D', Tags.Items.DYES ) .define( 'D', Tags.Items.DYES )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.save( add ); .save( add );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -272,7 +274,7 @@ public class Recipes extends RecipeProvider
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'N', Blocks.NOTE_BLOCK ) .define( 'N', Blocks.NOTE_BLOCK )
.define( 'R', Tags.Items.DUSTS_REDSTONE ) .define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.save( add ); .save( add );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -282,19 +284,19 @@ public class Recipes extends RecipeProvider
.pattern( "###" ) .pattern( "###" )
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'R', Tags.Items.DUSTS_REDSTONE ) .define( 'R', Tags.Items.DUSTS_REDSTONE )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.unlockedBy( "has_cable", inventoryChange( Registry.ModItems.CABLE.get() ) ) .unlockedBy( "has_cable", inventoryChange( Registry.ModItems.CABLE.get() ) )
.save( add ); .save( add );
ShapelessRecipeBuilder ShapelessRecipeBuilder
.shapeless( Registry.ModBlocks.WIRED_MODEM_FULL.get() ) .shapeless( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.requires( Registry.ModItems.WIRED_MODEM.get() ) .requires( Registry.ModItems.WIRED_MODEM.get() )
.unlockedBy( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) ) .unlockedBy( "has_modem", inventoryChange( WIRED_MODEM ) )
.save( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_from" ) ); .save( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_from" ) );
ShapelessRecipeBuilder ShapelessRecipeBuilder
.shapeless( Registry.ModItems.WIRED_MODEM.get() ) .shapeless( Registry.ModItems.WIRED_MODEM.get() )
.requires( Registry.ModBlocks.WIRED_MODEM_FULL.get() ) .requires( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.unlockedBy( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) ) .unlockedBy( "has_modem", inventoryChange( WIRED_MODEM ) )
.save( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_to" ) ); .save( add, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full_to" ) );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -304,7 +306,7 @@ public class Recipes extends RecipeProvider
.pattern( "###" ) .pattern( "###" )
.define( '#', Tags.Items.STONE ) .define( '#', Tags.Items.STONE )
.define( 'E', Tags.Items.ENDER_PEARLS ) .define( 'E', Tags.Items.ENDER_PEARLS )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.save( add ); .save( add );
ShapedRecipeBuilder ShapedRecipeBuilder
@ -314,7 +316,7 @@ public class Recipes extends RecipeProvider
.pattern( "###" ) .pattern( "###" )
.define( '#', Tags.Items.INGOTS_GOLD ) .define( '#', Tags.Items.INGOTS_GOLD )
.define( 'E', Items.ENDER_EYE ) .define( 'E', Items.ENDER_EYE )
.unlockedBy( "has_computer", inventoryChange( CCTags.COMPUTER ) ) .unlockedBy( "has_computer", inventoryChange( COMPUTER ) )
.unlockedBy( "has_wireless", inventoryChange( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() ) ) .unlockedBy( "has_wireless", inventoryChange( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() ) )
.save( add ); .save( add );

View File

@ -1,61 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.Registry;
import net.minecraft.data.BlockTagsProvider;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.ItemTagsProvider;
import net.minecraft.item.Item;
import net.minecraft.tags.ITag;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.data.ExistingFileHelper;
import static dan200.computercraft.data.Tags.CCTags.*;
public class Tags extends ItemTagsProvider
{
private static final ITag.INamedTag<Item> PIGLIN_LOVED = ItemTags.PIGLIN_LOVED;
public static class CCTags
{
public static final ITag.INamedTag<Item> COMPUTER = item( "computer" );
public static final ITag.INamedTag<Item> TURTLE = item( "turtle" );
public static final ITag.INamedTag<Item> WIRED_MODEM = item( "wired_modem" );
public static final ITag.INamedTag<Item> MONITOR = item( "monitor" );
}
public Tags( DataGenerator generator, ExistingFileHelper helper )
{
super( generator, new BlockTagsProvider( generator, ComputerCraft.MOD_ID, helper ), ComputerCraft.MOD_ID, helper );
}
@Override
protected void addTags()
{
tag( COMPUTER ).add(
Registry.ModItems.COMPUTER_NORMAL.get(),
Registry.ModItems.COMPUTER_ADVANCED.get(),
Registry.ModItems.COMPUTER_COMMAND.get()
);
tag( TURTLE ).add( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
tag( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
tag( MONITOR ).add( Registry.ModItems.MONITOR_NORMAL.get(), Registry.ModItems.MONITOR_ADVANCED.get() );
tag( PIGLIN_LOVED ).add(
Registry.ModItems.COMPUTER_ADVANCED.get(), Registry.ModItems.TURTLE_ADVANCED.get(),
Registry.ModItems.WIRELESS_MODEM_ADVANCED.get(), Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(),
Registry.ModItems.MONITOR_ADVANCED.get()
);
}
private static ITag.INamedTag<Item> item( String name )
{
return ItemTags.bind( new ResourceLocation( ComputerCraft.MOD_ID, name ).toString() );
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared;
import dan200.computercraft.ComputerCraft;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ITag;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.ResourceLocation;
public class ComputerCraftTags
{
public static class Items
{
public static final ITag.INamedTag<Item> COMPUTER = make( "computer" );
public static final ITag.INamedTag<Item> TURTLE = make( "turtle" );
public static final ITag.INamedTag<Item> WIRED_MODEM = make( "wired_modem" );
public static final ITag.INamedTag<Item> MONITOR = make( "monitor" );
private static ITag.INamedTag<Item> make( String name )
{
return ItemTags.bind( new ResourceLocation( ComputerCraft.MOD_ID, name ).toString() );
}
}
public static class Blocks
{
public static final ITag.INamedTag<Block> COMPUTER = make( "computer" );
public static final ITag.INamedTag<Block> TURTLE = make( "turtle" );
public static final ITag.INamedTag<Block> WIRED_MODEM = make( "wired_modem" );
public static final ITag.INamedTag<Block> MONITOR = make( "monitor" );
public static final ITag.INamedTag<Block> TURTLE_ALWAYS_BREAKABLE = make( "turtle_always_breakable" );
public static final ITag.INamedTag<Block> TURTLE_SHOVEL_BREAKABLE = make( "turtle_shovel_harvestable" );
public static final ITag.INamedTag<Block> TURTLE_SWORD_BREAKABLE = make( "turtle_sword_harvestable" );
public static final ITag.INamedTag<Block> TURTLE_HOE_BREAKABLE = make( "turtle_hoe_harvestable" );
private static ITag.INamedTag<Block> make( String name )
{
return BlockTags.bind( new ResourceLocation( ComputerCraft.MOD_ID, name ).toString() );
}
}
}

View File

@ -9,16 +9,17 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.TurtleVerb; import dan200.computercraft.api.turtle.TurtleVerb;
import dan200.computercraft.shared.ComputerCraftTags;
import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand; import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand;
import dan200.computercraft.shared.turtle.core.TurtlePlayer; import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.ToolType;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -40,17 +41,15 @@ public class TurtleHoe extends TurtleTool
} }
@Override @Override
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) protected TurtleCommandResult checkBlockBreakable( BlockState state, World world, BlockPos pos, TurtlePlayer player )
{ {
if( !super.canBreakBlock( state, world, pos, player ) ) return false; TurtleCommandResult result = super.checkBlockBreakable( state, world, pos, player );
if( !result.isSuccess() ) return result;
Material material = state.getMaterial(); return state.isToolEffective( ToolType.HOE )
return material == Material.PLANT || || state.is( ComputerCraftTags.Blocks.TURTLE_HOE_BREAKABLE )
material == Material.CACTUS || || isTriviallyBreakable( world, pos, state )
material == Material.VEGETABLE || ? result : INEFFECTIVE;
material == Material.LEAVES ||
material == Material.WATER_PLANT ||
material == Material.REPLACEABLE_PLANT;
} }
@Nonnull @Nonnull

View File

@ -9,16 +9,17 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.TurtleVerb; import dan200.computercraft.api.turtle.TurtleVerb;
import dan200.computercraft.shared.ComputerCraftTags;
import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand; import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand;
import dan200.computercraft.shared.turtle.core.TurtlePlayer; import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.ToolType;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -40,21 +41,15 @@ public class TurtleShovel extends TurtleTool
} }
@Override @Override
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) protected TurtleCommandResult checkBlockBreakable( BlockState state, World world, BlockPos pos, TurtlePlayer player )
{ {
if( !super.canBreakBlock( state, world, pos, player ) ) return false; TurtleCommandResult result = super.checkBlockBreakable( state, world, pos, player );
if( !result.isSuccess() ) return result;
Material material = state.getMaterial(); return state.isToolEffective( ToolType.SHOVEL )
return material == Material.DIRT || || state.is( ComputerCraftTags.Blocks.TURTLE_SHOVEL_BREAKABLE )
material == Material.SAND || || isTriviallyBreakable( world, pos, state )
material == Material.TOP_SNOW || ? result : INEFFECTIVE;
material == Material.CLAY ||
material == Material.SNOW ||
material == Material.PLANT ||
material == Material.CACTUS ||
material == Material.VEGETABLE ||
material == Material.LEAVES ||
material == Material.REPLACEABLE_PLANT;
} }
@Nonnull @Nonnull

View File

@ -5,9 +5,10 @@
*/ */
package dan200.computercraft.shared.turtle.upgrades; package dan200.computercraft.shared.turtle.upgrades;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.shared.ComputerCraftTags;
import dan200.computercraft.shared.turtle.core.TurtlePlayer; import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -32,16 +33,14 @@ public class TurtleSword extends TurtleTool
} }
@Override @Override
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) protected TurtleCommandResult checkBlockBreakable( BlockState state, World world, BlockPos pos, TurtlePlayer player )
{ {
if( !super.canBreakBlock( state, world, pos, player ) ) return false; TurtleCommandResult result = super.checkBlockBreakable( state, world, pos, player );
if( !result.isSuccess() ) return result;
Material material = state.getMaterial(); return state.is( ComputerCraftTags.Blocks.TURTLE_SWORD_BREAKABLE )
return material == Material.PLANT || || isTriviallyBreakable( world, pos, state )
material == Material.LEAVES || ? result : INEFFECTIVE;
material == Material.REPLACEABLE_PLANT ||
material == Material.WOOL ||
material == Material.WEB;
} }
@Override @Override

View File

@ -10,6 +10,7 @@ import dan200.computercraft.api.client.TransformedModel;
import dan200.computercraft.api.turtle.*; import dan200.computercraft.api.turtle.*;
import dan200.computercraft.api.turtle.event.TurtleAttackEvent; import dan200.computercraft.api.turtle.event.TurtleAttackEvent;
import dan200.computercraft.api.turtle.event.TurtleBlockEvent; import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
import dan200.computercraft.shared.ComputerCraftTags;
import dan200.computercraft.shared.TurtlePermissions; import dan200.computercraft.shared.TurtlePermissions;
import dan200.computercraft.shared.turtle.core.TurtleBrain; import dan200.computercraft.shared.turtle.core.TurtleBrain;
import dan200.computercraft.shared.turtle.core.TurtlePlayer; import dan200.computercraft.shared.turtle.core.TurtlePlayer;
@ -34,6 +35,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.TransformationMatrix; import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
@ -48,6 +50,9 @@ import java.util.function.Function;
public class TurtleTool extends AbstractTurtleUpgrade public class TurtleTool extends AbstractTurtleUpgrade
{ {
protected static final TurtleCommandResult UNBREAKABLE = TurtleCommandResult.failure( "Unbreakable block detected" );
protected static final TurtleCommandResult INEFFECTIVE = TurtleCommandResult.failure( "Cannot break block with this tool" );
protected final ItemStack item; protected final ItemStack item;
public TurtleTool( ResourceLocation id, String adjective, Item item ) public TurtleTool( ResourceLocation id, String adjective, Item item )
@ -109,13 +114,14 @@ public class TurtleTool extends AbstractTurtleUpgrade
} }
} }
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) protected TurtleCommandResult checkBlockBreakable( BlockState state, World world, BlockPos pos, TurtlePlayer player )
{ {
Block block = state.getBlock(); Block block = state.getBlock();
return !state.isAir() return !state.isAir()
&& block != Blocks.BEDROCK && block != Blocks.BEDROCK
&& state.getDestroyProgress( player, world, pos ) > 0 && state.getDestroyProgress( player, world, pos ) > 0
&& block.canEntityDestroy( state, world, pos, player ); && block.canEntityDestroy( state, world, pos, player )
? TurtleCommandResult.success() : UNBREAKABLE;
} }
protected float getDamageMultiplier() protected float getDamageMultiplier()
@ -166,6 +172,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
{ {
float damage = (float) turtlePlayer.getAttributeValue( Attributes.ATTACK_DAMAGE ); float damage = (float) turtlePlayer.getAttributeValue( Attributes.ATTACK_DAMAGE );
damage *= getDamageMultiplier(); damage *= getDamageMultiplier();
ComputerCraft.log.info( "Dealing {} damage", damage );
if( damage > 0.0f ) if( damage > 0.0f )
{ {
DamageSource source = DamageSource.playerAttack( turtlePlayer ); DamageSource source = DamageSource.playerAttack( turtlePlayer );
@ -238,10 +245,8 @@ public class TurtleTool extends AbstractTurtleUpgrade
} }
// Check if we can break the block // Check if we can break the block
if( !canBreakBlock( state, world, blockPosition, turtlePlayer ) ) TurtleCommandResult breakable = checkBlockBreakable( state, world, blockPosition, turtlePlayer );
{ if( !breakable.isSuccess() ) return breakable;
return TurtleCommandResult.failure( "Unbreakable block detected" );
}
// Fire the dig event, checking whether it was cancelled. // Fire the dig event, checking whether it was cancelled.
TurtleBlockEvent.Dig digEvent = new TurtleBlockEvent.Dig( turtle, turtlePlayer, world, blockPosition, state, this, side ); TurtleBlockEvent.Dig digEvent = new TurtleBlockEvent.Dig( turtle, turtlePlayer, world, blockPosition, state, this, side );
@ -302,4 +307,11 @@ public class TurtleTool extends AbstractTurtleUpgrade
} ) ); } ) );
} }
} }
protected boolean isTriviallyBreakable( IWorldReader reader, BlockPos pos, BlockState state )
{
return state.is( ComputerCraftTags.Blocks.TURTLE_ALWAYS_BREAKABLE )
// Allow breaking any "instabreak" block.
|| (state.getDestroySpeed( reader, pos ) == 0 && state.getHarvestLevel() <= 0);
}
} }