11package net .evmodder .evmod .keybinds ;
22
3+ import net .evmodder .evmod .Configs ;
34import net .evmodder .evmod .Main ;
45import net .evmodder .evmod .apis .ClickUtils .ActionType ;
56import net .evmodder .evmod .apis .ClickUtils .InvAction ;
@@ -183,15 +184,16 @@ private void copyMapArtInBundles(final ArrayDeque<InvAction> clicks, final ItemS
183184 final BundleContentsComponent [] bundles = Arrays .stream (slotsWithBundles )
184185 .mapToObj (i -> slots [i ].get (DataComponentTypes .BUNDLE_CONTENTS )).toArray (BundleContentsComponent []::new );
185186 final int SRC_BUNDLES = (int )Arrays .stream (bundles ).filter (Predicate .not (BundleContentsComponent ::isEmpty )).count ();
186- final int emptyBundles = bundles .length - SRC_BUNDLES ;
187- if (emptyBundles == 1 ){Main .LOGGER .warn ("MapCopyBundle: Could not find an auxiliary bundle" ); return ;}
187+ final boolean USE_TEMP_BUNDLE = !Configs .Hotkeys .MAP_COPY_BUNDLE_BETA .getBooleanValue ();
188+ final int USABLE_EMPTY_BUNDLES = bundles .length - SRC_BUNDLES - (USE_TEMP_BUNDLE ? 1 : 0 );
189+ if (USABLE_EMPTY_BUNDLES <= 0 ){Main .LOGGER .warn ("MapCopyBundle: Could not find a usable empty bundle" ); return ;}
188190 int LAST_EMPTY_SLOT = lastEmptySlot (slots , f .HOTBAR_END , f .INV_START );
189191 if (LAST_EMPTY_SLOT == -1 && Arrays .stream (bundles ).anyMatch (b -> b .stream ().anyMatch (s -> s .getCount () > 1 ))){
190192 Main .LOGGER .warn ("MapCopyBundle: Unable to copy bundles containing maps with stackSize>1 without an empty inv slot" );
191193 return ;
192194 }
193- final int DESTS_PER_SRC = SRC_BUNDLES >= emptyBundles ? 999 : ( emptyBundles - 1 ) /SRC_BUNDLES ;
194- Main .LOGGER .warn ("MapCopyBundle: source bundles: " +SRC_BUNDLES +", empty bundles: " +emptyBundles
195+ final int DESTS_PER_SRC = SRC_BUNDLES > USABLE_EMPTY_BUNDLES ? 999 : USABLE_EMPTY_BUNDLES /SRC_BUNDLES ;
196+ Main .LOGGER .warn ("MapCopyBundle: source bundles: " +SRC_BUNDLES +", (potential)destination bundles: " +USABLE_EMPTY_BUNDLES
195197 +", dest-per-src: " +DESTS_PER_SRC +", last-empty-slot: " +LAST_EMPTY_SLOT );
196198
197199 TreeMap <Integer , List <Integer >> bundlesToCopy = new TreeMap <>(); // source bundle -> destination bundles (slotsWithBundles)
@@ -207,7 +209,7 @@ private void copyMapArtInBundles(final ArrayDeque<InvAction> clicks, final ItemS
207209// Main.LOGGER.info("looking for dest bundles for "+slots[s1].getName().getString()+" in slot "+s1);
208210
209211 if (name1 != null ){ // Match by name (1st priority)
210- for (int j =0 ; j <slotsWithBundles .length && usedDests .size ()+ 1 < emptyBundles && copyDests .size ()<DESTS_PER_SRC ; ++j ){
212+ for (int j =0 ; j <slotsWithBundles .length && usedDests .size ()< USABLE_EMPTY_BUNDLES && copyDests .size ()<DESTS_PER_SRC ; ++j ){
211213 if (bundles [j ].isEmpty () && name1 .equals (getCustomNameOrNull (slots [slotsWithBundles [j ]])) && usedDests .add (j ))
212214 {
213215 Main .LOGGER .info ("MapCopyBundle: matching-name copy dest " +s1 +"->" +slotsWithBundles [j ]);
@@ -216,7 +218,7 @@ private void copyMapArtInBundles(final ArrayDeque<InvAction> clicks, final ItemS
216218 }
217219 }
218220 if (copyDests .isEmpty () && slots [s1 ].getItem () != Items .BUNDLE ){ // Match by non-default color (2nd priority)
219- for (int j =0 ; j <slotsWithBundles .length && usedDests .size ()+ 1 < emptyBundles && copyDests .size ()<DESTS_PER_SRC ; ++j ){
221+ for (int j =0 ; j <slotsWithBundles .length && usedDests .size ()< USABLE_EMPTY_BUNDLES && copyDests .size ()<DESTS_PER_SRC ; ++j ){
220222 if (bundles [j ].isEmpty () && slots [s1 ].getItem () == slots [slotsWithBundles [j ]].getItem ()
221223 && (name1 == null || getCustomNameOrNull (slots [slotsWithBundles [j ]]) == null ) && usedDests .add (j ))
222224 {
@@ -226,7 +228,7 @@ private void copyMapArtInBundles(final ArrayDeque<InvAction> clicks, final ItemS
226228 }
227229 }
228230 // If the above methods failed, loosen the src-bundle requirements a bit
229- if (copyDests .isEmpty ()) for (int j =0 ; j <slotsWithBundles .length && usedDests .size ()+ 1 < emptyBundles && copyDests .size ()<DESTS_PER_SRC ; ++j ){
231+ if (copyDests .isEmpty ()) for (int j =0 ; j <slotsWithBundles .length && usedDests .size ()< USABLE_EMPTY_BUNDLES && copyDests .size ()<DESTS_PER_SRC ; ++j ){
230232 final int s2 = slotsWithBundles [j ];
231233 if (!bundles [j ].isEmpty ()) continue ;
232234 if (name1 != null && getCustomNameOrNull (slots [s2 ]) != null && !name1 .equals (getCustomNameOrNull (slots [s2 ]))) continue ;
@@ -248,37 +250,49 @@ private void copyMapArtInBundles(final ArrayDeque<InvAction> clicks, final ItemS
248250 }
249251 if (bundlesToCopy .isEmpty ()){Main .LOGGER .warn ("MapCopyBundle: No bundles found to copy" ); return ;}
250252
251- HashSet <Integer > unusedBundles = new HashSet <Integer >(slotsWithBundles .length );
252- for (int i =0 ; i <slotsWithBundles .length ; ++i ) unusedBundles .add (i );
253- for (var e : bundlesToCopy .entrySet ()){unusedBundles .remove (e .getKey ()); unusedBundles .removeAll (e .getValue ());}
254- assert unusedBundles .size () >= 1 ;
255-
256- final int [] unusedBundleSlots = unusedBundles .stream ().mapToInt (Integer ::intValue ).map (i -> slotsWithBundles [i ]).toArray ();
257- final boolean anyUnnamedDst = bundlesToCopy .values ().stream ().anyMatch (d -> d .stream ().anyMatch (i -> slots [slotsWithBundles [i ]].getCustomName () == null ));
258- final PrioAndSlot pas = Arrays .stream (unusedBundleSlots ).mapToObj (i ->
259- // Lower score is better
260- new PrioAndSlot (
261- (!anyUnnamedDst && slots [i ].getCustomName () != null ? 4 : 0 )
262- + (srcBundleTypes .contains (slots [i ].getItem ()) ? 2 : 0 )
263- + (dstBundleTypes .contains (slots [i ].getItem ()) ? 1 : 0 ), i )).min (Comparator .naturalOrder ()).get ();
264- Main .LOGGER .info ("MapCopyBundle: Intermediary bundle: slot=" +pas .slot +", uniquelyUnnamed=" +((pas .p &4 )==0 )
265- +", uniqueFromSrcType=" +((pas .p &2 )==0 )+", uniqueFromDstType=" +((pas .p &1 )==0 ));
266-
267- final int tempBundleSlot = pas .slot ;
253+ final int tempBundleSlot ;
254+ if (!USE_TEMP_BUNDLE ) tempBundleSlot = -1 ;
255+ else {
256+ HashSet <Integer > unusedBundles = new HashSet <Integer >(slotsWithBundles .length );
257+ for (int i =0 ; i <slotsWithBundles .length ; ++i ) unusedBundles .add (i );
258+ for (var e : bundlesToCopy .entrySet ()){unusedBundles .remove (e .getKey ()); unusedBundles .removeAll (e .getValue ());}
259+ assert unusedBundles .size () >= 1 ;
260+ final int [] unusedBundleSlots = unusedBundles .stream ().mapToInt (Integer ::intValue ).map (i -> slotsWithBundles [i ]).toArray ();
261+ final boolean anyUnnamedDst = bundlesToCopy .values ().stream ().anyMatch (d -> d .stream ().anyMatch (i -> slots [slotsWithBundles [i ]].getCustomName () == null ));
262+ final PrioAndSlot pas = Arrays .stream (unusedBundleSlots ).mapToObj (i ->
263+ // Lower score is better
264+ new PrioAndSlot (
265+ (!anyUnnamedDst && slots [i ].getCustomName () != null ? 4 : 0 )
266+ + (srcBundleTypes .contains (slots [i ].getItem ()) ? 2 : 0 )
267+ + (dstBundleTypes .contains (slots [i ].getItem ()) ? 1 : 0 ), i )).min (Comparator .naturalOrder ()).get ();
268+ tempBundleSlot = pas .slot ;
269+ Main .LOGGER .info ("MapCopyBundle: Intermediary bundle: slot=" +pas .slot +", uniquelyUnnamed=" +((pas .p &4 )==0 )
270+ +", uniqueFromSrcType=" +((pas .p &2 )==0 )+", uniqueFromDstType=" +((pas .p &1 )==0 ));
271+ }
272+
273+ final boolean BUNDLE_SELECT_REVERSE = !USE_TEMP_BUNDLE && Configs .Generic .BUNDLE_SELECT_REVERSED .getBooleanValue ();
268274 for (var entry : bundlesToCopy .entrySet ()){
275+ BundleContentsComponent content = bundles [entry .getKey ()];
269276// Main.LOGGER.info("MapCopyBundle: Copying map bundle in slot "+k+", "+slots[k].getName().getString()+" to slots: "+bundlesToCopy.get(k));
270- for (int _0 =0 ; _0 <bundles [ entry . getKey ()] .size (); ++_0 ){
277+ if ( USE_TEMP_BUNDLE ) for (int _0 =0 ; _0 <content .size (); ++_0 ){
271278 clicks .add (new InvAction (slotsWithBundles [entry .getKey ()], 1 , ActionType .CLICK )); // Take last map from src bundle
272279 clicks .add (new InvAction (tempBundleSlot , 0 , ActionType .CLICK )); // Place map in temp bundle
273280 }
274281// Main.LOGGER.info("MapCopyBundle: Move to intermediary bundle complete, beginning copy");
275282
276283 //2+4+2 vs 2+3+2
277284 //bundles[k].stream().mapToInt(stack -> stack.getCount()).forEach(count -> {
278- for (int i =0 ; i <bundles [ entry . getKey ()] .size (); ++i ){
279- final int count = bundles [ entry . getKey ()] .get (i ).getCount ();
285+ for (int i =0 ; i <content .size (); ++i ){
286+ final int count = content .get (i ).getCount ();
280287
281- clicks .add (new InvAction (tempBundleSlot , 1 , ActionType .CLICK )); // Take last map from temp bundle
288+ if (USE_TEMP_BUNDLE ) clicks .add (new InvAction (tempBundleSlot , 1 , ActionType .CLICK )); // Take map from temp bundle
289+ else {
290+ final int innerBundleSlot = BUNDLE_SELECT_REVERSE ? content .size ()-1 : 0 ;
291+ // final int innerBundleSlot = BUNDLE_SELECT_REVERSE ? content.size()-(i+1) : i;
292+ // final int innerBundleSlot = BUNDLE_SELECT_REVERSE ? i : content.size()-(i+1);
293+ clicks .add (new InvAction (slotsWithBundles [entry .getKey ()], innerBundleSlot , ActionType .BUNDLE_SELECT )); // Select 1st map in bundle
294+ clicks .add (new InvAction (slotsWithBundles [entry .getKey ()], 1 , ActionType .CLICK )); // Take map from src bundle
295+ }
282296 clicks .add (new InvAction (f .INPUT_START , 0 , ActionType .CLICK )); // Place in crafter
283297 boolean didShiftCraft = false ;
284298 //Main.LOGGER.info("MapCopyBundle: Coping map item into "+bundlesToCopy.get(k).size()+" dest bundles");
0 commit comments