mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-08-05 21:33:54 +00:00
Rewrite turtle block destroying
- Try to make drop capturing a little more generic. This now allows for capturing a block's drop at a given position, as well as any drop within a bounding box (for things which don't play nicely). - Use as much of Minecraft's block breaking logic as possible, hopefully simplifying things and making it more consistent with other mods.
This commit is contained in:
parent
914df8b0c7
commit
4d984dc5ee
@ -48,7 +48,10 @@ import dan200.computercraft.shared.proxy.IComputerCraftProxy;
|
|||||||
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
||||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||||
import dan200.computercraft.shared.turtle.upgrades.*;
|
import dan200.computercraft.shared.turtle.upgrades.*;
|
||||||
import dan200.computercraft.shared.util.*;
|
import dan200.computercraft.shared.util.CreativeTabMain;
|
||||||
|
import dan200.computercraft.shared.util.IDAssigner;
|
||||||
|
import dan200.computercraft.shared.util.InventoryUtil;
|
||||||
|
import dan200.computercraft.shared.util.WorldUtil;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@ -85,6 +88,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
@ -1015,13 +1019,18 @@ public class ComputerCraft
|
|||||||
turtleProxy.addAllUpgradedTurtles( list );
|
turtleProxy.addAllUpgradedTurtles( list );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer )
|
public static void setDropConsumer( Entity entity, Consumer<ItemStack> consumer )
|
||||||
{
|
{
|
||||||
turtleProxy.setEntityDropConsumer( entity, consumer );
|
turtleProxy.setDropConsumer( entity, consumer );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearEntityDropConsumer( Entity entity )
|
public static void setDropConsumer( World world, BlockPos pos, Consumer<ItemStack> consumer )
|
||||||
{
|
{
|
||||||
turtleProxy.clearEntityDropConsumer( entity );
|
turtleProxy.setDropConsumer( world, pos, consumer );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearDropConsumer( )
|
||||||
|
{
|
||||||
|
turtleProxy.clearDropConsumer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
|
|||||||
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
|
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
|
||||||
import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe;
|
import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe;
|
||||||
import dan200.computercraft.shared.turtle.upgrades.*;
|
import dan200.computercraft.shared.turtle.upgrades.*;
|
||||||
import dan200.computercraft.shared.util.IEntityDropConsumer;
|
|
||||||
import dan200.computercraft.shared.util.ImpostorRecipe;
|
import dan200.computercraft.shared.util.ImpostorRecipe;
|
||||||
import dan200.computercraft.shared.util.InventoryUtil;
|
import dan200.computercraft.shared.util.InventoryUtil;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@ -32,33 +31,47 @@ import net.minecraft.item.ItemStack;
|
|||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.RegistryEvent;
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
|
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
||||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||||
import net.minecraftforge.registries.IForgeRegistry;
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.*;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
||||||
{
|
{
|
||||||
private Map<Integer, ITurtleUpgrade> m_legacyTurtleUpgrades;
|
private Map<Integer, ITurtleUpgrade> m_legacyTurtleUpgrades;
|
||||||
private Map<String, ITurtleUpgrade> m_turtleUpgrades;
|
private Map<String, ITurtleUpgrade> m_turtleUpgrades;
|
||||||
private Map<Entity, IEntityDropConsumer> m_dropConsumers;
|
|
||||||
|
private Consumer<ItemStack> dropConsumer;
|
||||||
|
private WeakReference<World> dropWorld;
|
||||||
|
private BlockPos dropPos;
|
||||||
|
private AxisAlignedBB dropBounds;
|
||||||
|
private WeakReference<Entity> dropEntity;
|
||||||
|
|
||||||
public CCTurtleProxyCommon()
|
public CCTurtleProxyCommon()
|
||||||
{
|
{
|
||||||
m_legacyTurtleUpgrades = new HashMap<>();
|
m_legacyTurtleUpgrades = new HashMap<>();
|
||||||
m_turtleUpgrades = new HashMap<>();
|
m_turtleUpgrades = new HashMap<>();
|
||||||
m_dropConsumers = new WeakHashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ICCTurtleProxy implementation
|
// ICCTurtleProxy implementation
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preInit()
|
public void preInit()
|
||||||
{
|
{
|
||||||
MinecraftForge.EVENT_BUS.register( this );
|
MinecraftForge.EVENT_BUS.register( this );
|
||||||
@ -74,8 +87,8 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
// RecipeSorter.register( "computercraft:turtle", TurtleRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
|
// RecipeSorter.register( "computercraft:turtle", TurtleRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
|
||||||
// RecipeSorter.register( "computercraft:turtle_upgrade", TurtleUpgradeRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
|
// RecipeSorter.register( "computercraft:turtle_upgrade", TurtleUpgradeRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
registerForgeHandlers();
|
registerForgeHandlers();
|
||||||
@ -93,7 +106,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
ComputerCraft.log.error( message );
|
ComputerCraft.log.error( message );
|
||||||
throw new RuntimeException( message );
|
throw new RuntimeException( message );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register
|
// Register
|
||||||
registerTurtleUpgradeInternal( upgrade );
|
registerTurtleUpgradeInternal( upgrade );
|
||||||
}
|
}
|
||||||
@ -109,7 +122,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
{
|
{
|
||||||
return m_legacyTurtleUpgrades.get( legacyId );
|
return m_legacyTurtleUpgrades.get( legacyId );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack stack )
|
public ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
@ -125,7 +138,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
ComputerCraft.log.error("Error getting computer upgrade item", e);
|
ComputerCraft.log.error( "Error getting computer upgrade item", e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -147,7 +160,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAllUpgradedTurtles( ComputerFamily family, NonNullList<ItemStack> list )
|
private void addAllUpgradedTurtles( ComputerFamily family, NonNullList<ItemStack> list )
|
||||||
{
|
{
|
||||||
ItemStack basicStack = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
|
ItemStack basicStack = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
|
||||||
@ -168,7 +181,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
|
|
||||||
private void addUpgradedTurtle( ComputerFamily family, ITurtleUpgrade upgrade, List<ItemStack> list )
|
private void addUpgradedTurtle( ComputerFamily family, ITurtleUpgrade upgrade, List<ItemStack> list )
|
||||||
{
|
{
|
||||||
if ( isUpgradeSuitableForFamily( family, upgrade ) )
|
if( isUpgradeSuitableForFamily( family, upgrade ) )
|
||||||
{
|
{
|
||||||
ItemStack stack = TurtleItemFactory.create( -1, null, -1, family, upgrade, null, 0, null );
|
ItemStack stack = TurtleItemFactory.create( -1, null, -1, family, upgrade, null, 0, null );
|
||||||
if( !stack.isEmpty() )
|
if( !stack.isEmpty() )
|
||||||
@ -177,54 +190,58 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAllUpgradedTurtles( NonNullList<ItemStack> list )
|
public void addAllUpgradedTurtles( NonNullList<ItemStack> list )
|
||||||
{
|
{
|
||||||
addAllUpgradedTurtles( ComputerFamily.Normal, list );
|
addAllUpgradedTurtles( ComputerFamily.Normal, list );
|
||||||
addAllUpgradedTurtles( ComputerFamily.Advanced, list );
|
addAllUpgradedTurtles( ComputerFamily.Advanced, list );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer )
|
public void setDropConsumer( Entity entity, Consumer<ItemStack> consumer )
|
||||||
{
|
{
|
||||||
if( !m_dropConsumers.containsKey( entity ) )
|
dropConsumer = consumer;
|
||||||
{
|
dropEntity = new WeakReference<>( entity );
|
||||||
boolean captured = entity.captureDrops;
|
dropWorld = new WeakReference<>( entity.world );
|
||||||
|
dropPos = null;
|
||||||
if( !captured )
|
dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 );
|
||||||
{
|
|
||||||
entity.captureDrops = true;
|
entity.captureDrops = true;
|
||||||
ArrayList<EntityItem> items = entity.capturedDrops;
|
}
|
||||||
|
|
||||||
if( items == null || items.size() == 0 )
|
|
||||||
{
|
|
||||||
m_dropConsumers.put( entity, consumer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearEntityDropConsumer( Entity entity )
|
public void setDropConsumer( World world, BlockPos pos, Consumer<ItemStack> consumer )
|
||||||
{
|
{
|
||||||
if( m_dropConsumers.containsKey( entity ) )
|
dropConsumer = consumer;
|
||||||
|
dropEntity = null;
|
||||||
|
dropWorld = new WeakReference<>( world );
|
||||||
|
dropPos = pos;
|
||||||
|
dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearDropConsumer()
|
||||||
|
{
|
||||||
|
if( dropEntity != null )
|
||||||
{
|
{
|
||||||
boolean captured = entity.captureDrops;
|
Entity entity = dropEntity.get();
|
||||||
|
if( entity != null )
|
||||||
if( captured )
|
|
||||||
{
|
{
|
||||||
entity.captureDrops = false;
|
entity.captureDrops = false;
|
||||||
ArrayList<EntityItem> items = entity.capturedDrops;
|
if( entity.capturedDrops != null )
|
||||||
|
|
||||||
if( items != null )
|
|
||||||
{
|
{
|
||||||
dispatchEntityDrops( entity, items );
|
for( EntityItem entityItem : entity.capturedDrops ) dropConsumer.accept( entityItem.getItem() );
|
||||||
items.clear();
|
entity.capturedDrops.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_dropConsumers.remove( entity );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dropConsumer = null;
|
||||||
|
dropEntity = null;
|
||||||
|
dropWorld = null;
|
||||||
|
dropPos = null;
|
||||||
|
dropBounds = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerTurtleUpgradeInternal( ITurtleUpgrade upgrade )
|
private void registerTurtleUpgradeInternal( ITurtleUpgrade upgrade )
|
||||||
@ -288,7 +305,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
{
|
{
|
||||||
IForgeRegistry<Item> registry = event.getRegistry();
|
IForgeRegistry<Item> registry = event.getRegistry();
|
||||||
|
|
||||||
registry.register( new ItemTurtleLegacy( ComputerCraft.Blocks.turtle).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ) );
|
registry.register( new ItemTurtleLegacy( ComputerCraft.Blocks.turtle ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ) );
|
||||||
registry.register( new ItemTurtleNormal( ComputerCraft.Blocks.turtleExpanded ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_expanded" ) ) );
|
registry.register( new ItemTurtleNormal( ComputerCraft.Blocks.turtleExpanded ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_expanded" ) ) );
|
||||||
registry.register( new ItemTurtleAdvanced( ComputerCraft.Blocks.turtleAdvanced ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) ) );
|
registry.register( new ItemTurtleAdvanced( ComputerCraft.Blocks.turtleAdvanced ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) ) );
|
||||||
}
|
}
|
||||||
@ -361,7 +378,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
private void registerUpgrades()
|
private void registerUpgrades()
|
||||||
{
|
{
|
||||||
// Upgrades
|
// Upgrades
|
||||||
ComputerCraft.Upgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
|
ComputerCraft.Upgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
|
||||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.wirelessModem );
|
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.wirelessModem );
|
||||||
|
|
||||||
ComputerCraft.Upgrades.craftingTable = new TurtleCraftingTable( 2 );
|
ComputerCraft.Upgrades.craftingTable = new TurtleCraftingTable( 2 );
|
||||||
@ -446,38 +463,53 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
|||||||
GameRegistry.registerTileEntity( TileTurtleExpanded.class, ComputerCraft.LOWER_ID + " : " + "turtleex" );
|
GameRegistry.registerTileEntity( TileTurtleExpanded.class, ComputerCraft.LOWER_ID + " : " + "turtleex" );
|
||||||
GameRegistry.registerTileEntity( TileTurtleAdvanced.class, ComputerCraft.LOWER_ID + " : " + "turtleadv" );
|
GameRegistry.registerTileEntity( TileTurtleAdvanced.class, ComputerCraft.LOWER_ID + " : " + "turtleadv" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerForgeHandlers()
|
private void registerForgeHandlers()
|
||||||
{
|
{
|
||||||
ForgeHandlers handlers = new ForgeHandlers();
|
ForgeHandlers handlers = new ForgeHandlers();
|
||||||
MinecraftForge.EVENT_BUS.register( handlers );
|
MinecraftForge.EVENT_BUS.register( handlers );
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ForgeHandlers
|
|
||||||
{
|
|
||||||
private ForgeHandlers()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forge event responses
|
private class ForgeHandlers
|
||||||
|
{
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onEntityLivingDrops( LivingDropsEvent event )
|
public void onEntityLivingDrops( LivingDropsEvent event )
|
||||||
{
|
{
|
||||||
dispatchEntityDrops( event.getEntity(), event.getDrops() );
|
// Capture any mob drops for the current entity
|
||||||
}
|
if( dropEntity != null && event.getEntity() == dropEntity.get() )
|
||||||
}
|
|
||||||
|
|
||||||
private void dispatchEntityDrops( Entity entity, java.util.List<EntityItem> drops )
|
|
||||||
{
|
|
||||||
IEntityDropConsumer consumer = m_dropConsumers.get( entity );
|
|
||||||
if( consumer != null )
|
|
||||||
{
|
|
||||||
// All checks have passed, lets dispatch the drops
|
|
||||||
for(EntityItem entityItem : drops)
|
|
||||||
{
|
{
|
||||||
consumer.consumeDrop( entity, entityItem.getItem() );
|
List<EntityItem> drops = event.getDrops();
|
||||||
|
for( EntityItem entityItem : drops ) dropConsumer.accept( entityItem.getItem() );
|
||||||
|
drops.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||||
|
public void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
|
||||||
|
{
|
||||||
|
// Capture block drops for the current entity
|
||||||
|
if( dropWorld != null && dropWorld.get() == event.getWorld()
|
||||||
|
&& dropPos != null && dropPos.equals( event.getPos() ) )
|
||||||
|
{
|
||||||
|
for( ItemStack item : event.getDrops() )
|
||||||
|
{
|
||||||
|
if( event.getWorld().rand.nextFloat() < event.getDropChance() ) dropConsumer.accept( item );
|
||||||
|
}
|
||||||
|
event.getDrops().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||||
|
public void onEntitySpawn( EntityJoinWorldEvent event )
|
||||||
|
{
|
||||||
|
// Capture any nearby item spawns
|
||||||
|
if( dropWorld != null && dropWorld.get() == event.getWorld() && event.getEntity() instanceof EntityItem
|
||||||
|
&& dropBounds.contains( event.getEntity().getPositionVector() ) )
|
||||||
|
{
|
||||||
|
dropConsumer.accept( ((EntityItem) event.getEntity()).getItem() );
|
||||||
|
event.setCanceled( true );
|
||||||
}
|
}
|
||||||
drops.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,14 @@
|
|||||||
package dan200.computercraft.shared.proxy;
|
package dan200.computercraft.shared.proxy;
|
||||||
|
|
||||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||||
import dan200.computercraft.shared.util.IEntityDropConsumer;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public interface ICCTurtleProxy
|
public interface ICCTurtleProxy
|
||||||
{
|
{
|
||||||
@ -25,6 +27,7 @@ public interface ICCTurtleProxy
|
|||||||
ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack item );
|
ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack item );
|
||||||
void addAllUpgradedTurtles( NonNullList<ItemStack> list );
|
void addAllUpgradedTurtles( NonNullList<ItemStack> list );
|
||||||
|
|
||||||
void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer );
|
void setDropConsumer( Entity entity, Consumer<ItemStack> consumer );
|
||||||
void clearEntityDropConsumer( Entity entity );
|
void setDropConsumer( World world, BlockPos pos, Consumer<ItemStack> consumer );
|
||||||
|
void clearDropConsumer();
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
|||||||
// Start claiming entity drops
|
// Start claiming entity drops
|
||||||
Entity hitEntity = hit.getKey();
|
Entity hitEntity = hit.getKey();
|
||||||
Vec3d hitPos = hit.getValue();
|
Vec3d hitPos = hit.getValue();
|
||||||
ComputerCraft.setEntityDropConsumer( hitEntity, ( entity, drop ) ->
|
ComputerCraft.setDropConsumer( hitEntity, ( drop ) ->
|
||||||
{
|
{
|
||||||
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||||
if( !remainder.isEmpty() )
|
if( !remainder.isEmpty() )
|
||||||
@ -268,7 +268,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop claiming drops
|
// Stop claiming drops
|
||||||
ComputerCraft.clearEntityDropConsumer( hitEntity );
|
ComputerCraft.clearDropConsumer();
|
||||||
|
|
||||||
// Put everything we collected into the turtles inventory, then return
|
// Put everything we collected into the turtles inventory, then return
|
||||||
ItemStack remainder = turtlePlayer.unloadInventory( turtle );
|
ItemStack remainder = turtlePlayer.unloadInventory( turtle );
|
||||||
|
@ -11,13 +11,14 @@ 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.turtle.core.TurtlePlaceCommand;
|
import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand;
|
||||||
|
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -30,20 +31,16 @@ public class TurtleHoe extends TurtleTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBreakBlock( World world, BlockPos pos )
|
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||||
{
|
{
|
||||||
if( super.canBreakBlock( world, pos ) )
|
if( !super.canBreakBlock( state, world, pos, player ) ) return false;
|
||||||
{
|
|
||||||
IBlockState state = world.getBlockState( pos );
|
Material material = state.getMaterial();
|
||||||
Material material = state.getMaterial( );
|
return material == Material.PLANTS ||
|
||||||
return
|
material == Material.CACTUS ||
|
||||||
material == Material.PLANTS ||
|
material == Material.GOURD ||
|
||||||
material == Material.CACTUS ||
|
material == Material.LEAVES ||
|
||||||
material == Material.GOURD ||
|
material == Material.VINE;
|
||||||
material == Material.LEAVES ||
|
|
||||||
material == Material.VINE;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -11,6 +11,7 @@ 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.turtle.core.TurtlePlaceCommand;
|
import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand;
|
||||||
|
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
@ -30,26 +31,22 @@ public class TurtleShovel extends TurtleTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBreakBlock( World world, BlockPos pos )
|
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||||
{
|
{
|
||||||
if( super.canBreakBlock( world, pos ) )
|
if( !super.canBreakBlock( state, world, pos, player ) ) return false;
|
||||||
{
|
|
||||||
IBlockState state = world.getBlockState( pos );
|
Material material = state.getMaterial();
|
||||||
Material material = state.getMaterial( );
|
return material == Material.GROUND ||
|
||||||
return
|
material == Material.SAND ||
|
||||||
material == Material.GROUND ||
|
material == Material.SNOW ||
|
||||||
material == Material.SAND ||
|
material == Material.CLAY ||
|
||||||
material == Material.SNOW ||
|
material == Material.CRAFTED_SNOW ||
|
||||||
material == Material.CLAY ||
|
material == Material.GRASS ||
|
||||||
material == Material.CRAFTED_SNOW ||
|
material == Material.PLANTS ||
|
||||||
material == Material.GRASS ||
|
material == Material.CACTUS ||
|
||||||
material == Material.PLANTS ||
|
material == Material.GOURD ||
|
||||||
material == Material.CACTUS ||
|
material == Material.LEAVES ||
|
||||||
material == Material.GOURD ||
|
material == Material.VINE;
|
||||||
material == Material.LEAVES ||
|
|
||||||
material == Material.VINE;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -5,11 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
package dan200.computercraft.shared.turtle.upgrades;
|
package dan200.computercraft.shared.turtle.upgrades;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class TurtleSword extends TurtleTool
|
public class TurtleSword extends TurtleTool
|
||||||
@ -20,20 +22,16 @@ public class TurtleSword extends TurtleTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBreakBlock( World world, BlockPos pos )
|
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||||
{
|
{
|
||||||
if( super.canBreakBlock( world, pos ) )
|
if( !super.canBreakBlock( state, world, pos, player ) ) return false;
|
||||||
{
|
|
||||||
IBlockState state = world.getBlockState( pos );
|
Material material = state.getMaterial();
|
||||||
Material material = state.getMaterial( );
|
return material == Material.PLANTS ||
|
||||||
return
|
material == Material.LEAVES ||
|
||||||
material == Material.PLANTS ||
|
material == Material.VINE ||
|
||||||
material == Material.LEAVES ||
|
material == Material.CLOTH ||
|
||||||
material == Material.VINE ||
|
material == Material.WEB;
|
||||||
material == Material.CLOTH ||
|
|
||||||
material == Material.WEB;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,21 +21,17 @@ import net.minecraft.client.renderer.block.model.IBakedModel;
|
|||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.SharedMonsterAttributes;
|
import net.minecraft.entity.SharedMonsterAttributes;
|
||||||
import net.minecraft.entity.item.EntityArmorStand;
|
import net.minecraft.entity.item.EntityArmorStand;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
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.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldServer;
|
|
||||||
import net.minecraftforge.common.ForgeHooks;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.ForgeEventFactory;
|
|
||||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
||||||
import net.minecraftforge.event.world.BlockEvent;
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
@ -44,7 +40,9 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.vecmath.Matrix4f;
|
import javax.vecmath.Matrix4f;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class TurtleTool implements ITurtleUpgrade
|
public class TurtleTool implements ITurtleUpgrade
|
||||||
{
|
{
|
||||||
@ -103,7 +101,7 @@ public class TurtleTool implements ITurtleUpgrade
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
@SideOnly( Side.CLIENT )
|
@SideOnly(Side.CLIENT)
|
||||||
public Pair<IBakedModel, Matrix4f> getModel( ITurtleAccess turtle, @Nonnull TurtleSide side )
|
public Pair<IBakedModel, Matrix4f> getModel( ITurtleAccess turtle, @Nonnull TurtleSide side )
|
||||||
{
|
{
|
||||||
float xOffset = (side == TurtleSide.Left) ? -0.40625f : 0.40625f;
|
float xOffset = (side == TurtleSide.Left) ? -0.40625f : 0.40625f;
|
||||||
@ -141,26 +139,20 @@ public class TurtleTool implements ITurtleUpgrade
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canBreakBlock( World world, BlockPos pos )
|
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||||
{
|
{
|
||||||
IBlockState state = world.getBlockState( pos );
|
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
return !block.isAir( state, world, pos ) && block != Blocks.BEDROCK && state.getBlockHardness( world, pos ) > -1.0F;
|
return !block.isAir( state, world, pos )
|
||||||
|
&& block != Blocks.BEDROCK
|
||||||
|
&& state.getPlayerRelativeBlockHardness( player, world, pos ) > 0
|
||||||
|
&& block.canEntityDestroy( state, world, pos, player );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canHarvestBlock( World world, BlockPos pos )
|
|
||||||
{
|
|
||||||
Block block = world.getBlockState( pos ).getBlock();
|
|
||||||
TurtlePlayer turtlePlayer = new TurtlePlayer( (WorldServer)world );
|
|
||||||
turtlePlayer.loadInventory( m_item.copy() );
|
|
||||||
return ForgeHooks.canHarvestBlock( block, turtlePlayer, world, pos );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected float getDamageMultiplier()
|
protected float getDamageMultiplier()
|
||||||
{
|
{
|
||||||
return 3.0f;
|
return 3.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TurtleCommandResult attack( final ITurtleAccess turtle, EnumFacing direction )
|
private TurtleCommandResult attack( final ITurtleAccess turtle, EnumFacing direction )
|
||||||
{
|
{
|
||||||
// Create a fake player, and orient it appropriately
|
// Create a fake player, and orient it appropriately
|
||||||
@ -180,21 +172,15 @@ public class TurtleTool implements ITurtleUpgrade
|
|||||||
|
|
||||||
// Start claiming entity drops
|
// Start claiming entity drops
|
||||||
Entity hitEntity = hit.getKey();
|
Entity hitEntity = hit.getKey();
|
||||||
ComputerCraft.setEntityDropConsumer( hitEntity, ( entity, drop ) ->
|
List<ItemStack> extra = new ArrayList<>( );
|
||||||
{
|
ComputerCraft.setDropConsumer( hitEntity, turtleDropConsumer( turtle, extra ) );
|
||||||
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
|
||||||
if( !remainder.isEmpty() )
|
|
||||||
{
|
|
||||||
WorldUtil.dropItemStack( remainder, world, position, turtle.getDirection().getOpposite() );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Attack the entity
|
// Attack the entity
|
||||||
boolean attacked = false;
|
boolean attacked = false;
|
||||||
if( hitEntity.canBeAttackedWithItem() && !hitEntity.hitByEntity( turtlePlayer )
|
if( hitEntity.canBeAttackedWithItem() && !hitEntity.hitByEntity( turtlePlayer )
|
||||||
&& !MinecraftForge.EVENT_BUS.post( new AttackEntityEvent( turtlePlayer, hitEntity ) ) )
|
&& !MinecraftForge.EVENT_BUS.post( new AttackEntityEvent( turtlePlayer, hitEntity ) ) )
|
||||||
{
|
{
|
||||||
float damage = (float)turtlePlayer.getEntityAttribute( SharedMonsterAttributes.ATTACK_DAMAGE ).getAttributeValue();
|
float damage = (float) turtlePlayer.getEntityAttribute( SharedMonsterAttributes.ATTACK_DAMAGE ).getAttributeValue();
|
||||||
damage *= getDamageMultiplier();
|
damage *= getDamageMultiplier();
|
||||||
if( damage > 0.0f )
|
if( damage > 0.0f )
|
||||||
{
|
{
|
||||||
@ -220,7 +206,7 @@ public class TurtleTool implements ITurtleUpgrade
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop claiming drops
|
// Stop claiming drops
|
||||||
ComputerCraft.clearEntityDropConsumer( hitEntity );
|
stopConsuming( turtle, extra );
|
||||||
|
|
||||||
// Put everything we collected into the turtles inventory, then return
|
// Put everything we collected into the turtles inventory, then return
|
||||||
if( attacked )
|
if( attacked )
|
||||||
@ -232,68 +218,71 @@ public class TurtleTool implements ITurtleUpgrade
|
|||||||
|
|
||||||
return TurtleCommandResult.failure( "Nothing to attack here" );
|
return TurtleCommandResult.failure( "Nothing to attack here" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction )
|
private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction )
|
||||||
{
|
{
|
||||||
// Get ready to dig
|
// Get ready to dig
|
||||||
World world = turtle.getWorld();
|
World world = turtle.getWorld();
|
||||||
BlockPos position = turtle.getPosition();
|
BlockPos turtlePosition = turtle.getPosition();
|
||||||
BlockPos newPosition = WorldUtil.moveCoords( position, direction );
|
BlockPos blockPosition = WorldUtil.moveCoords( turtlePosition, direction );
|
||||||
|
|
||||||
if( WorldUtil.isBlockInWorld( world, newPosition ) &&
|
if( WorldUtil.isBlockInWorld( world, blockPosition ) &&
|
||||||
!world.isAirBlock( newPosition ) &&
|
!world.isAirBlock( blockPosition ) &&
|
||||||
!WorldUtil.isLiquidBlock( world, newPosition ) )
|
!WorldUtil.isLiquidBlock( world, blockPosition ) )
|
||||||
{
|
{
|
||||||
TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, position, direction );
|
IBlockState state = world.getBlockState( blockPosition );
|
||||||
|
|
||||||
|
TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, turtlePosition, direction );
|
||||||
|
turtlePlayer.loadInventory( m_item.copy() );
|
||||||
|
|
||||||
if( ComputerCraft.turtlesObeyBlockProtection )
|
if( ComputerCraft.turtlesObeyBlockProtection )
|
||||||
{
|
{
|
||||||
// Check spawn protection
|
// Check spawn protection
|
||||||
|
if( MinecraftForge.EVENT_BUS.post( new BlockEvent.BreakEvent( world, blockPosition, world.getBlockState( blockPosition ), turtlePlayer ) ) )
|
||||||
if( MinecraftForge.EVENT_BUS.post( new BlockEvent.BreakEvent( world, newPosition, world.getBlockState( newPosition ), turtlePlayer ) ) )
|
|
||||||
{
|
{
|
||||||
return TurtleCommandResult.failure( "Cannot break protected block" );
|
return TurtleCommandResult.failure( "Cannot break protected block" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !ComputerCraft.isBlockEditable( world, newPosition, turtlePlayer ) )
|
if( !ComputerCraft.isBlockEditable( world, blockPosition, turtlePlayer ) )
|
||||||
{
|
{
|
||||||
return TurtleCommandResult.failure( "Cannot break protected block" );
|
return TurtleCommandResult.failure( "Cannot break protected block" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we can break the block
|
// Check if we can break the block
|
||||||
if( !canBreakBlock( world, newPosition ) )
|
if( !canBreakBlock( state, world, blockPosition, turtlePlayer ) )
|
||||||
{
|
{
|
||||||
return TurtleCommandResult.failure( "Unbreakable block detected" );
|
return TurtleCommandResult.failure( "Unbreakable block detected" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consume the items the block drops
|
// Consume the items the block drops
|
||||||
if( canHarvestBlock( world, newPosition ) )
|
List<ItemStack> extra = new ArrayList<>( );
|
||||||
{
|
ComputerCraft.setDropConsumer( world, blockPosition, turtleDropConsumer( turtle, extra ) );
|
||||||
List<ItemStack> items = getBlockDropped( world, newPosition, turtlePlayer );
|
|
||||||
if( items != null && items.size() > 0 )
|
TileEntity tile = world.getTileEntity( blockPosition );
|
||||||
{
|
|
||||||
for( ItemStack stack : items )
|
// Much of this logic comes from PlayerInteractionManager#tryHarvestBlock, so it's a good idea
|
||||||
{
|
// to consult there before making any changes.
|
||||||
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
|
||||||
if( !remainder.isEmpty() )
|
// Play the destruction sound
|
||||||
{
|
world.playEvent( 2001, blockPosition, Block.getStateId( state ) );
|
||||||
// If there's no room for the items, drop them
|
|
||||||
WorldUtil.dropItemStack( remainder, world, position, direction );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy the block
|
// Destroy the block
|
||||||
IBlockState previousState = world.getBlockState( newPosition );
|
boolean canHarvest = state.getBlock().canHarvestBlock( world, blockPosition, turtlePlayer );
|
||||||
world.playEvent(2001, newPosition, Block.getStateId(previousState));
|
boolean canBreak = state.getBlock().removedByPlayer( state, world, blockPosition, turtlePlayer, canHarvest );
|
||||||
world.setBlockToAir( newPosition );
|
if( canBreak ) state.getBlock().onBlockDestroyedByPlayer( world, blockPosition, state );
|
||||||
|
if( canHarvest )
|
||||||
|
{
|
||||||
|
state.getBlock().harvestBlock( world, turtlePlayer, blockPosition, state, tile, turtlePlayer.getHeldItemMainhand() );
|
||||||
|
}
|
||||||
|
|
||||||
|
stopConsuming( turtle, extra );
|
||||||
|
|
||||||
// Remember the previous block
|
// Remember the previous block
|
||||||
if( turtle instanceof TurtleBrain )
|
if( turtle instanceof TurtleBrain )
|
||||||
{
|
{
|
||||||
TurtleBrain brain = (TurtleBrain)turtle;
|
TurtleBrain brain = (TurtleBrain) turtle;
|
||||||
brain.saveBlockChange( newPosition, previousState );
|
brain.saveBlockChange( blockPosition, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
return TurtleCommandResult.success();
|
return TurtleCommandResult.success();
|
||||||
@ -302,21 +291,21 @@ public class TurtleTool implements ITurtleUpgrade
|
|||||||
return TurtleCommandResult.failure( "Nothing to dig here" );
|
return TurtleCommandResult.failure( "Nothing to dig here" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ItemStack> getBlockDropped( World world, BlockPos pos, EntityPlayer player )
|
private Consumer<ItemStack> turtleDropConsumer( ITurtleAccess turtle, List<ItemStack> extra )
|
||||||
{
|
{
|
||||||
IBlockState state = world.getBlockState( pos );
|
return ( drop ) ->
|
||||||
Block block = state.getBlock();
|
|
||||||
NonNullList<ItemStack> drops = NonNullList.create();
|
|
||||||
block.getDrops( drops, world, pos, world.getBlockState( pos ), 0 );
|
|
||||||
double chance = ForgeEventFactory.fireBlockHarvesting( drops, world, pos, state, 0, 1, false, player );
|
|
||||||
|
|
||||||
for( int i = drops.size() - 1; i >= 0; i-- )
|
|
||||||
{
|
{
|
||||||
if( world.rand.nextFloat() > chance )
|
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||||
{
|
if( !remainder.isEmpty() ) extra.add( remainder );
|
||||||
drops.remove( i );
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void stopConsuming( ITurtleAccess turtle, List<ItemStack> extra )
|
||||||
|
{
|
||||||
|
ComputerCraft.clearDropConsumer();
|
||||||
|
for( ItemStack remainder : extra )
|
||||||
|
{
|
||||||
|
WorldUtil.dropItemStack( remainder, turtle.getWorld(), turtle.getPosition(), turtle.getDirection().getOpposite() );
|
||||||
}
|
}
|
||||||
return drops;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.shared.util;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public interface IEntityDropConsumer
|
|
||||||
{
|
|
||||||
void consumeDrop( Entity dropper, @Nonnull ItemStack drop );
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user