Skip to content

Commit 000786a

Browse files
committed
Merge pull request dan200#560 from SquidDev-CC/ComputerCraft/hotfix/turtle-destroy
Rewrite turtle block destroying
2 parents 0bf1356 + 4d984dc commit 000786a

File tree

9 files changed

+221
-206
lines changed

9 files changed

+221
-206
lines changed

src/main/java/dan200/computercraft/ComputerCraft.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
import java.net.URISyntaxException;
9999
import java.net.URL;
100100
import java.util.*;
101+
import java.util.function.Consumer;
101102
import java.util.zip.ZipEntry;
102103
import java.util.zip.ZipFile;
103104

@@ -1124,13 +1125,18 @@ public static void addAllUpgradedTurtles( NonNullList<ItemStack> list )
11241125
turtleProxy.addAllUpgradedTurtles( list );
11251126
}
11261127

1127-
public static void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer )
1128+
public static void setDropConsumer( Entity entity, Consumer<ItemStack> consumer )
11281129
{
1129-
turtleProxy.setEntityDropConsumer( entity, consumer );
1130+
turtleProxy.setDropConsumer( entity, consumer );
11301131
}
11311132

1132-
public static void clearEntityDropConsumer( Entity entity )
1133+
public static void setDropConsumer( World world, BlockPos pos, Consumer<ItemStack> consumer )
11331134
{
1134-
turtleProxy.clearEntityDropConsumer( entity );
1135+
turtleProxy.setDropConsumer( world, pos, consumer );
1136+
}
1137+
1138+
public static void clearDropConsumer( )
1139+
{
1140+
turtleProxy.clearDropConsumer();
11351141
}
11361142
}

src/main/java/dan200/computercraft/shared/proxy/CCTurtleProxyCommon.java

Lines changed: 103 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
2222
import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe;
2323
import dan200.computercraft.shared.turtle.upgrades.*;
24-
import dan200.computercraft.shared.util.IEntityDropConsumer;
2524
import dan200.computercraft.shared.util.ImpostorRecipe;
2625
import dan200.computercraft.shared.util.InventoryUtil;
2726
import net.minecraft.block.Block;
@@ -33,33 +32,47 @@
3332
import net.minecraft.item.crafting.IRecipe;
3433
import net.minecraft.util.NonNullList;
3534
import net.minecraft.util.ResourceLocation;
35+
import net.minecraft.util.math.AxisAlignedBB;
36+
import net.minecraft.util.math.BlockPos;
37+
import net.minecraft.world.World;
3638
import net.minecraftforge.common.MinecraftForge;
3739
import net.minecraftforge.event.RegistryEvent;
40+
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
3841
import net.minecraftforge.event.entity.living.LivingDropsEvent;
42+
import net.minecraftforge.event.world.BlockEvent;
43+
import net.minecraftforge.fml.common.eventhandler.EventPriority;
3944
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
4045
import net.minecraftforge.fml.common.registry.EntityRegistry;
4146
import net.minecraftforge.fml.common.registry.GameRegistry;
4247
import net.minecraftforge.registries.IForgeRegistry;
4348

4449
import javax.annotation.Nonnull;
45-
import java.util.*;
50+
import java.lang.ref.WeakReference;
51+
import java.util.HashMap;
52+
import java.util.List;
53+
import java.util.Map;
54+
import java.util.function.Consumer;
4655

4756
public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
48-
{
57+
{
4958
private Map<Integer, ITurtleUpgrade> m_legacyTurtleUpgrades;
5059
private Map<String, ITurtleUpgrade> m_turtleUpgrades;
51-
private Map<Entity, IEntityDropConsumer> m_dropConsumers;
60+
61+
private Consumer<ItemStack> dropConsumer;
62+
private WeakReference<World> dropWorld;
63+
private BlockPos dropPos;
64+
private AxisAlignedBB dropBounds;
65+
private WeakReference<Entity> dropEntity;
5266

5367
public CCTurtleProxyCommon()
5468
{
5569
m_legacyTurtleUpgrades = new HashMap<>();
5670
m_turtleUpgrades = new HashMap<>();
57-
m_dropConsumers = new WeakHashMap<>();
5871
}
59-
72+
6073
// ICCTurtleProxy implementation
61-
62-
@Override
74+
75+
@Override
6376
public void preInit()
6477
{
6578
MinecraftForge.EVENT_BUS.register( this );
@@ -75,8 +88,8 @@ public void preInit()
7588
// RecipeSorter.register( "computercraft:turtle", TurtleRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
7689
// RecipeSorter.register( "computercraft:turtle_upgrade", TurtleUpgradeRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
7790
}
78-
79-
@Override
91+
92+
@Override
8093
public void init()
8194
{
8295
registerForgeHandlers();
@@ -94,7 +107,7 @@ public void registerTurtleUpgrade( ITurtleUpgrade upgrade )
94107
ComputerCraft.log.error( message );
95108
throw new RuntimeException( message );
96109
}
97-
110+
98111
// Register
99112
registerTurtleUpgradeInternal( upgrade );
100113
}
@@ -110,7 +123,7 @@ public ITurtleUpgrade getTurtleUpgrade( int legacyId )
110123
{
111124
return m_legacyTurtleUpgrades.get( legacyId );
112125
}
113-
126+
114127
@Override
115128
public ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack stack )
116129
{
@@ -126,7 +139,7 @@ public ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack stack )
126139
}
127140
catch( Exception e )
128141
{
129-
ComputerCraft.log.error("Error getting computer upgrade item", e);
142+
ComputerCraft.log.error( "Error getting computer upgrade item", e );
130143
}
131144
}
132145
return null;
@@ -148,7 +161,7 @@ public static boolean isUpgradeSuitableForFamily( ComputerFamily family, ITurtle
148161
return true;
149162
}
150163
}
151-
164+
152165
private void addAllUpgradedTurtles( ComputerFamily family, NonNullList<ItemStack> list )
153166
{
154167
ItemStack basicStack = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
@@ -169,7 +182,7 @@ private void addAllUpgradedTurtles( ComputerFamily family, NonNullList<ItemStack
169182

170183
private void addUpgradedTurtle( ComputerFamily family, ITurtleUpgrade upgrade, List<ItemStack> list )
171184
{
172-
if ( isUpgradeSuitableForFamily( family, upgrade ) )
185+
if( isUpgradeSuitableForFamily( family, upgrade ) )
173186
{
174187
ItemStack stack = TurtleItemFactory.create( -1, null, -1, family, upgrade, null, 0, null );
175188
if( !stack.isEmpty() )
@@ -178,54 +191,58 @@ private void addUpgradedTurtle( ComputerFamily family, ITurtleUpgrade upgrade, L
178191
}
179192
}
180193
}
181-
194+
182195
@Override
183196
public void addAllUpgradedTurtles( NonNullList<ItemStack> list )
184197
{
185198
addAllUpgradedTurtles( ComputerFamily.Normal, list );
186199
addAllUpgradedTurtles( ComputerFamily.Advanced, list );
187200
}
188-
201+
189202
@Override
190-
public void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer )
203+
public void setDropConsumer( Entity entity, Consumer<ItemStack> consumer )
191204
{
192-
if( !m_dropConsumers.containsKey( entity ) )
193-
{
194-
boolean captured = entity.captureDrops;
195-
196-
if( !captured )
197-
{
198-
entity.captureDrops = true;
199-
ArrayList<EntityItem> items = entity.capturedDrops;
200-
201-
if( items == null || items.size() == 0 )
202-
{
203-
m_dropConsumers.put( entity, consumer );
204-
}
205-
}
206-
}
207-
}
208-
205+
dropConsumer = consumer;
206+
dropEntity = new WeakReference<>( entity );
207+
dropWorld = new WeakReference<>( entity.world );
208+
dropPos = null;
209+
dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 );
210+
211+
entity.captureDrops = true;
212+
}
213+
209214
@Override
210-
public void clearEntityDropConsumer( Entity entity )
215+
public void setDropConsumer( World world, BlockPos pos, Consumer<ItemStack> consumer )
211216
{
212-
if( m_dropConsumers.containsKey( entity ) )
217+
dropConsumer = consumer;
218+
dropEntity = null;
219+
dropWorld = new WeakReference<>( world );
220+
dropPos = pos;
221+
dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 );
222+
}
223+
224+
@Override
225+
public void clearDropConsumer()
226+
{
227+
if( dropEntity != null )
213228
{
214-
boolean captured = entity.captureDrops;
215-
216-
if( captured )
229+
Entity entity = dropEntity.get();
230+
if( entity != null )
217231
{
218232
entity.captureDrops = false;
219-
ArrayList<EntityItem> items = entity.capturedDrops;
220-
221-
if( items != null )
233+
if( entity.capturedDrops != null )
222234
{
223-
dispatchEntityDrops( entity, items );
224-
items.clear();
235+
for( EntityItem entityItem : entity.capturedDrops ) dropConsumer.accept( entityItem.getItem() );
236+
entity.capturedDrops.clear();
225237
}
226238
}
227-
m_dropConsumers.remove( entity );
228239
}
240+
241+
dropConsumer = null;
242+
dropEntity = null;
243+
dropWorld = null;
244+
dropPos = null;
245+
dropBounds = null;
229246
}
230247

231248
private void registerTurtleUpgradeInternal( ITurtleUpgrade upgrade )
@@ -289,7 +306,7 @@ public void registerItems( RegistryEvent.Register<Item> event )
289306
{
290307
IForgeRegistry<Item> registry = event.getRegistry();
291308

292-
registry.register( new ItemTurtleLegacy( ComputerCraft.Blocks.turtle).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ) );
309+
registry.register( new ItemTurtleLegacy( ComputerCraft.Blocks.turtle ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ) );
293310
registry.register( new ItemTurtleNormal( ComputerCraft.Blocks.turtleExpanded ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_expanded" ) ) );
294311
registry.register( new ItemTurtleAdvanced( ComputerCraft.Blocks.turtleAdvanced ).setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) ) );
295312
}
@@ -362,7 +379,7 @@ public void registerRecipes( RegistryEvent.Register<IRecipe> event )
362379
private void registerUpgrades()
363380
{
364381
// Upgrades
365-
ComputerCraft.Upgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
382+
ComputerCraft.Upgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
366383
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.wirelessModem );
367384

368385
ComputerCraft.Upgrades.craftingTable = new TurtleCraftingTable( 2 );
@@ -447,26 +464,54 @@ private void registerTileEntities()
447464
GameRegistry.registerTileEntity( TileTurtleExpanded.class, ComputerCraft.LOWER_ID + " : " + "turtleex" );
448465
GameRegistry.registerTileEntity( TileTurtleAdvanced.class, ComputerCraft.LOWER_ID + " : " + "turtleadv" );
449466
}
450-
467+
451468
private void registerForgeHandlers()
452469
{
453470
ForgeHandlers handlers = new ForgeHandlers();
454471
MinecraftForge.EVENT_BUS.register( handlers );
455472
}
456-
457-
public class ForgeHandlers
473+
474+
private class ForgeHandlers
458475
{
459-
private ForgeHandlers()
476+
@SubscribeEvent(priority = EventPriority.LOWEST)
477+
public void onEntityLivingDrops( LivingDropsEvent event )
460478
{
479+
// Capture any mob drops for the current entity
480+
if( dropEntity != null && event.getEntity() == dropEntity.get() )
481+
{
482+
List<EntityItem> drops = event.getDrops();
483+
for( EntityItem entityItem : drops ) dropConsumer.accept( entityItem.getItem() );
484+
drops.clear();
485+
}
461486
}
462487

463-
// Forge event responses
464-
@SubscribeEvent
465-
public void onEntityLivingDrops( LivingDropsEvent event )
488+
@SubscribeEvent(priority = EventPriority.LOWEST)
489+
public void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
466490
{
467-
dispatchEntityDrops( event.getEntity(), event.getDrops() );
491+
// Capture block drops for the current entity
492+
if( dropWorld != null && dropWorld.get() == event.getWorld()
493+
&& dropPos != null && dropPos.equals( event.getPos() ) )
494+
{
495+
for( ItemStack item : event.getDrops() )
496+
{
497+
if( event.getWorld().rand.nextFloat() < event.getDropChance() ) dropConsumer.accept( item );
498+
}
499+
event.getDrops().clear();
500+
}
468501
}
469-
502+
503+
@SubscribeEvent(priority = EventPriority.LOWEST)
504+
public void onEntitySpawn( EntityJoinWorldEvent event )
505+
{
506+
// Capture any nearby item spawns
507+
if( dropWorld != null && dropWorld.get() == event.getWorld() && event.getEntity() instanceof EntityItem
508+
&& dropBounds.contains( event.getEntity().getPositionVector() ) )
509+
{
510+
dropConsumer.accept( ((EntityItem) event.getEntity()).getItem() );
511+
event.setCanceled( true );
512+
}
513+
}
514+
470515
@SubscribeEvent
471516
public void onTurtleAction( TurtleActionEvent event) {
472517
if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) )
@@ -475,18 +520,5 @@ public void onTurtleAction( TurtleActionEvent event) {
475520
}
476521
}
477522
}
478-
479-
private void dispatchEntityDrops( Entity entity, java.util.List<EntityItem> drops )
480-
{
481-
IEntityDropConsumer consumer = m_dropConsumers.get( entity );
482-
if( consumer != null )
483-
{
484-
// All checks have passed, lets dispatch the drops
485-
for(EntityItem entityItem : drops)
486-
{
487-
consumer.consumeDrop( entity, entityItem.getItem() );
488-
}
489-
drops.clear();
490-
}
491-
}
523+
492524
}

src/main/java/dan200/computercraft/shared/proxy/ICCTurtleProxy.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
package dan200.computercraft.shared.proxy;
88

99
import dan200.computercraft.api.turtle.ITurtleUpgrade;
10-
import dan200.computercraft.shared.util.IEntityDropConsumer;
1110
import net.minecraft.entity.Entity;
1211
import net.minecraft.item.ItemStack;
1312
import net.minecraft.util.NonNullList;
13+
import net.minecraft.util.math.BlockPos;
14+
import net.minecraft.world.World;
1415

1516
import javax.annotation.Nonnull;
17+
import java.util.function.Consumer;
1618

1719
public interface ICCTurtleProxy
1820
{
@@ -25,6 +27,7 @@ public interface ICCTurtleProxy
2527
ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack item );
2628
void addAllUpgradedTurtles( NonNullList<ItemStack> list );
2729

28-
void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer );
29-
void clearEntityDropConsumer( Entity entity );
30+
void setDropConsumer( Entity entity, Consumer<ItemStack> consumer );
31+
void setDropConsumer( World world, BlockPos pos, Consumer<ItemStack> consumer );
32+
void clearDropConsumer();
3033
}

src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ private static ItemStack deployOnEntity( @Nonnull ItemStack stack, final ITurtle
241241
// Start claiming entity drops
242242
Entity hitEntity = hit.getKey();
243243
Vec3d hitPos = hit.getValue();
244-
ComputerCraft.setEntityDropConsumer( hitEntity, ( entity, drop ) ->
244+
ComputerCraft.setDropConsumer( hitEntity, ( drop ) ->
245245
{
246246
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
247247
if( !remainder.isEmpty() )
@@ -285,7 +285,7 @@ else if( hitEntity instanceof EntityLivingBase )
285285
}
286286

287287
// Stop claiming drops
288-
ComputerCraft.clearEntityDropConsumer( hitEntity );
288+
ComputerCraft.clearDropConsumer();
289289

290290
// Put everything we collected into the turtles inventory, then return
291291
ItemStack remainder = turtlePlayer.unloadInventory( turtle );

0 commit comments

Comments
 (0)