2121import dan200 .computercraft .shared .turtle .items .TurtleItemFactory ;
2222import dan200 .computercraft .shared .turtle .recipes .TurtleUpgradeRecipe ;
2323import dan200 .computercraft .shared .turtle .upgrades .*;
24- import dan200 .computercraft .shared .util .IEntityDropConsumer ;
2524import dan200 .computercraft .shared .util .ImpostorRecipe ;
2625import dan200 .computercraft .shared .util .InventoryUtil ;
2726import net .minecraft .block .Block ;
3332import net .minecraft .item .crafting .IRecipe ;
3433import net .minecraft .util .NonNullList ;
3534import net .minecraft .util .ResourceLocation ;
35+ import net .minecraft .util .math .AxisAlignedBB ;
36+ import net .minecraft .util .math .BlockPos ;
37+ import net .minecraft .world .World ;
3638import net .minecraftforge .common .MinecraftForge ;
3739import net .minecraftforge .event .RegistryEvent ;
40+ import net .minecraftforge .event .entity .EntityJoinWorldEvent ;
3841import net .minecraftforge .event .entity .living .LivingDropsEvent ;
42+ import net .minecraftforge .event .world .BlockEvent ;
43+ import net .minecraftforge .fml .common .eventhandler .EventPriority ;
3944import net .minecraftforge .fml .common .eventhandler .SubscribeEvent ;
4045import net .minecraftforge .fml .common .registry .EntityRegistry ;
4146import net .minecraftforge .fml .common .registry .GameRegistry ;
4247import net .minecraftforge .registries .IForgeRegistry ;
4348
4449import 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
4756public 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}
0 commit comments