2020import dan200 .computercraft .shared .turtle .items .TurtleItemFactory ;
2121import dan200 .computercraft .shared .turtle .recipes .TurtleUpgradeRecipe ;
2222import dan200 .computercraft .shared .turtle .upgrades .*;
23- import dan200 .computercraft .shared .util .IEntityDropConsumer ;
2423import dan200 .computercraft .shared .util .ImpostorRecipe ;
2524import dan200 .computercraft .shared .util .InventoryUtil ;
2625import net .minecraft .block .Block ;
3231import net .minecraft .item .crafting .IRecipe ;
3332import net .minecraft .util .NonNullList ;
3433import net .minecraft .util .ResourceLocation ;
34+ import net .minecraft .util .math .AxisAlignedBB ;
35+ import net .minecraft .util .math .BlockPos ;
36+ import net .minecraft .world .World ;
3537import net .minecraftforge .common .MinecraftForge ;
3638import net .minecraftforge .event .RegistryEvent ;
39+ import net .minecraftforge .event .entity .EntityJoinWorldEvent ;
3740import net .minecraftforge .event .entity .living .LivingDropsEvent ;
41+ import net .minecraftforge .event .world .BlockEvent ;
42+ import net .minecraftforge .fml .common .eventhandler .EventPriority ;
3843import net .minecraftforge .fml .common .eventhandler .SubscribeEvent ;
3944import net .minecraftforge .fml .common .registry .EntityRegistry ;
4045import net .minecraftforge .fml .common .registry .GameRegistry ;
4146import net .minecraftforge .registries .IForgeRegistry ;
4247
4348import javax .annotation .Nonnull ;
44- import java .util .*;
49+ import java .lang .ref .WeakReference ;
50+ import java .util .HashMap ;
51+ import java .util .List ;
52+ import java .util .Map ;
53+ import java .util .function .Consumer ;
4554
4655public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
47- {
56+ {
4857 private Map <Integer , ITurtleUpgrade > m_legacyTurtleUpgrades ;
4958 private Map <String , ITurtleUpgrade > m_turtleUpgrades ;
50- private Map <Entity , IEntityDropConsumer > m_dropConsumers ;
59+
60+ private Consumer <ItemStack > dropConsumer ;
61+ private WeakReference <World > dropWorld ;
62+ private BlockPos dropPos ;
63+ private AxisAlignedBB dropBounds ;
64+ private WeakReference <Entity > dropEntity ;
5165
5266 public CCTurtleProxyCommon ()
5367 {
5468 m_legacyTurtleUpgrades = new HashMap <>();
5569 m_turtleUpgrades = new HashMap <>();
56- m_dropConsumers = new WeakHashMap <>();
5770 }
58-
71+
5972 // ICCTurtleProxy implementation
60-
61- @ Override
73+
74+ @ Override
6275 public void preInit ()
6376 {
6477 MinecraftForge .EVENT_BUS .register ( this );
@@ -74,8 +87,8 @@ public void preInit()
7487 // RecipeSorter.register( "computercraft:turtle", TurtleRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
7588 // RecipeSorter.register( "computercraft:turtle_upgrade", TurtleUpgradeRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
7689 }
77-
78- @ Override
90+
91+ @ Override
7992 public void init ()
8093 {
8194 registerForgeHandlers ();
@@ -93,7 +106,7 @@ public void registerTurtleUpgrade( ITurtleUpgrade upgrade )
93106 ComputerCraft .log .error ( message );
94107 throw new RuntimeException ( message );
95108 }
96-
109+
97110 // Register
98111 registerTurtleUpgradeInternal ( upgrade );
99112 }
@@ -109,7 +122,7 @@ public ITurtleUpgrade getTurtleUpgrade( int legacyId )
109122 {
110123 return m_legacyTurtleUpgrades .get ( legacyId );
111124 }
112-
125+
113126 @ Override
114127 public ITurtleUpgrade getTurtleUpgrade ( @ Nonnull ItemStack stack )
115128 {
@@ -125,7 +138,7 @@ public ITurtleUpgrade getTurtleUpgrade( @Nonnull ItemStack stack )
125138 }
126139 catch ( Exception e )
127140 {
128- ComputerCraft .log .error ("Error getting computer upgrade item" , e );
141+ ComputerCraft .log .error ( "Error getting computer upgrade item" , e );
129142 }
130143 }
131144 return null ;
@@ -147,7 +160,7 @@ public static boolean isUpgradeSuitableForFamily( ComputerFamily family, ITurtle
147160 return true ;
148161 }
149162 }
150-
163+
151164 private void addAllUpgradedTurtles ( ComputerFamily family , NonNullList <ItemStack > list )
152165 {
153166 ItemStack basicStack = TurtleItemFactory .create ( -1 , null , -1 , family , null , null , 0 , null );
@@ -168,7 +181,7 @@ private void addAllUpgradedTurtles( ComputerFamily family, NonNullList<ItemStack
168181
169182 private void addUpgradedTurtle ( ComputerFamily family , ITurtleUpgrade upgrade , List <ItemStack > list )
170183 {
171- if ( isUpgradeSuitableForFamily ( family , upgrade ) )
184+ if ( isUpgradeSuitableForFamily ( family , upgrade ) )
172185 {
173186 ItemStack stack = TurtleItemFactory .create ( -1 , null , -1 , family , upgrade , null , 0 , null );
174187 if ( !stack .isEmpty () )
@@ -177,54 +190,58 @@ private void addUpgradedTurtle( ComputerFamily family, ITurtleUpgrade upgrade, L
177190 }
178191 }
179192 }
180-
193+
181194 @ Override
182195 public void addAllUpgradedTurtles ( NonNullList <ItemStack > list )
183196 {
184197 addAllUpgradedTurtles ( ComputerFamily .Normal , list );
185198 addAllUpgradedTurtles ( ComputerFamily .Advanced , list );
186199 }
187-
200+
188201 @ Override
189- public void setEntityDropConsumer ( Entity entity , IEntityDropConsumer consumer )
202+ public void setDropConsumer ( Entity entity , Consumer < ItemStack > consumer )
190203 {
191- if ( !m_dropConsumers .containsKey ( entity ) )
192- {
193- boolean captured = entity .captureDrops ;
194-
195- if ( !captured )
196- {
197- entity .captureDrops = true ;
198- ArrayList <EntityItem > items = entity .capturedDrops ;
199-
200- if ( items == null || items .size () == 0 )
201- {
202- m_dropConsumers .put ( entity , consumer );
203- }
204- }
205- }
206- }
207-
204+ dropConsumer = consumer ;
205+ dropEntity = new WeakReference <>( entity );
206+ dropWorld = new WeakReference <>( entity .world );
207+ dropPos = null ;
208+ dropBounds = new AxisAlignedBB ( entity .getPosition () ).grow ( 2 , 2 , 2 );
209+
210+ entity .captureDrops = true ;
211+ }
212+
208213 @ Override
209- public void clearEntityDropConsumer ( Entity entity )
214+ public void setDropConsumer ( World world , BlockPos pos , Consumer < ItemStack > consumer )
210215 {
211- if ( m_dropConsumers .containsKey ( entity ) )
216+ dropConsumer = consumer ;
217+ dropEntity = null ;
218+ dropWorld = new WeakReference <>( world );
219+ dropPos = pos ;
220+ dropBounds = new AxisAlignedBB ( pos ).grow ( 2 , 2 , 2 );
221+ }
222+
223+ @ Override
224+ public void clearDropConsumer ()
225+ {
226+ if ( dropEntity != null )
212227 {
213- boolean captured = entity .captureDrops ;
214-
215- if ( captured )
228+ Entity entity = dropEntity .get ();
229+ if ( entity != null )
216230 {
217231 entity .captureDrops = false ;
218- ArrayList <EntityItem > items = entity .capturedDrops ;
219-
220- if ( items != null )
232+ if ( entity .capturedDrops != null )
221233 {
222- dispatchEntityDrops ( entity , items );
223- items .clear ();
234+ for ( EntityItem entityItem : entity . capturedDrops ) dropConsumer . accept ( entityItem . getItem () );
235+ entity . capturedDrops .clear ();
224236 }
225237 }
226- m_dropConsumers .remove ( entity );
227238 }
239+
240+ dropConsumer = null ;
241+ dropEntity = null ;
242+ dropWorld = null ;
243+ dropPos = null ;
244+ dropBounds = null ;
228245 }
229246
230247 private void registerTurtleUpgradeInternal ( ITurtleUpgrade upgrade )
@@ -288,7 +305,7 @@ public void registerItems( RegistryEvent.Register<Item> event )
288305 {
289306 IForgeRegistry <Item > registry = event .getRegistry ();
290307
291- registry .register ( new ItemTurtleLegacy ( ComputerCraft .Blocks .turtle ).setRegistryName ( new ResourceLocation ( ComputerCraft .MOD_ID , "turtle" ) ) );
308+ registry .register ( new ItemTurtleLegacy ( ComputerCraft .Blocks .turtle ).setRegistryName ( new ResourceLocation ( ComputerCraft .MOD_ID , "turtle" ) ) );
292309 registry .register ( new ItemTurtleNormal ( ComputerCraft .Blocks .turtleExpanded ).setRegistryName ( new ResourceLocation ( ComputerCraft .MOD_ID , "turtle_expanded" ) ) );
293310 registry .register ( new ItemTurtleAdvanced ( ComputerCraft .Blocks .turtleAdvanced ).setRegistryName ( new ResourceLocation ( ComputerCraft .MOD_ID , "turtle_advanced" ) ) );
294311 }
@@ -361,7 +378,7 @@ public void registerRecipes( RegistryEvent.Register<IRecipe> event )
361378 private void registerUpgrades ()
362379 {
363380 // Upgrades
364- ComputerCraft .Upgrades .wirelessModem = new TurtleModem ( false , new ResourceLocation ( "computercraft" , "wireless_modem" ), 1 );
381+ ComputerCraft .Upgrades .wirelessModem = new TurtleModem ( false , new ResourceLocation ( "computercraft" , "wireless_modem" ), 1 );
365382 registerTurtleUpgradeInternal ( ComputerCraft .Upgrades .wirelessModem );
366383
367384 ComputerCraft .Upgrades .craftingTable = new TurtleCraftingTable ( 2 );
@@ -446,38 +463,53 @@ private void registerTileEntities()
446463 GameRegistry .registerTileEntity ( TileTurtleExpanded .class , ComputerCraft .LOWER_ID + " : " + "turtleex" );
447464 GameRegistry .registerTileEntity ( TileTurtleAdvanced .class , ComputerCraft .LOWER_ID + " : " + "turtleadv" );
448465 }
449-
466+
450467 private void registerForgeHandlers ()
451468 {
452469 ForgeHandlers handlers = new ForgeHandlers ();
453470 MinecraftForge .EVENT_BUS .register ( handlers );
454471 }
455-
456- public class ForgeHandlers
472+
473+ private class ForgeHandlers
457474 {
458- private ForgeHandlers ()
475+ @ SubscribeEvent
476+ public void onEntityLivingDrops ( LivingDropsEvent event )
459477 {
478+ // Capture any mob drops for the current entity
479+ if ( dropEntity != null && event .getEntity () == dropEntity .get () )
480+ {
481+ List <EntityItem > drops = event .getDrops ();
482+ for ( EntityItem entityItem : drops ) dropConsumer .accept ( entityItem .getItem () );
483+ drops .clear ();
484+ }
460485 }
461486
462- // Forge event responses
463- @ SubscribeEvent
464- public void onEntityLivingDrops ( LivingDropsEvent event )
487+ @ SubscribeEvent (priority = EventPriority .LOWEST )
488+ public void onHarvestDrops ( BlockEvent .HarvestDropsEvent event )
465489 {
466- dispatchEntityDrops ( event .getEntity (), event .getDrops () );
490+ // Capture block drops for the current entity
491+ if ( dropWorld != null && dropWorld .get () == event .getWorld ()
492+ && dropPos != null && dropPos .equals ( event .getPos () ) )
493+ {
494+ for ( ItemStack item : event .getDrops () )
495+ {
496+ if ( event .getWorld ().rand .nextFloat () < event .getDropChance () ) dropConsumer .accept ( item );
497+ }
498+ event .getDrops ().clear ();
499+ }
467500 }
468- }
469-
470- private void dispatchEntityDrops ( Entity entity , java .util .List <EntityItem > drops )
471- {
472- IEntityDropConsumer consumer = m_dropConsumers .get ( entity );
473- if ( consumer != null )
501+
502+ @ SubscribeEvent (priority = EventPriority .LOWEST )
503+ public void onEntitySpawn ( EntityJoinWorldEvent event )
474504 {
475- // All checks have passed, lets dispatch the drops
476- for (EntityItem entityItem : drops )
505+ // Capture any nearby item spawns
506+ if ( dropWorld != null && dropWorld .get () == event .getWorld () && event .getEntity () instanceof EntityItem
507+ && dropBounds .contains ( event .getEntity ().getPositionVector () ) )
477508 {
478- consumer .consumeDrop ( entity , entityItem .getItem () );
509+ dropConsumer .accept ( ((EntityItem ) event .getEntity ()).getItem () );
510+ event .setCanceled ( true );
479511 }
480- drops .clear ();
481512 }
482513 }
514+
483515}
0 commit comments