diff --git a/core/assets/contributors b/core/assets/contributors index 85c23f7c7d..f740969d67 100644 --- a/core/assets/contributors +++ b/core/assets/contributors @@ -130,3 +130,4 @@ TranquillyUnpleasant Darkness6030 hortiSquash King-BR +citrusMarmelade diff --git a/core/src/mindustry/world/blocks/storage/Unloader.java b/core/src/mindustry/world/blocks/storage/Unloader.java index abd4b4a99c..bf70385092 100644 --- a/core/src/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/mindustry/world/blocks/storage/Unloader.java @@ -64,8 +64,11 @@ public class Unloader extends Block{ float loadFactor; boolean canLoad; boolean canUnload; + int index; } + public int[] lastUsed; + @Override public void updateTile(){ if(((unloadTimer += delta()) < speed) || (proximity.size < 2)) return; @@ -80,14 +83,14 @@ public class Unloader extends Block{ for(int i = tmp; i < proximity.size; i++){ possibleBlocks.set(i, new ContainerStat()); } + lastUsed = new int[proximity.size]; } if(sortItem != null){ item = sortItem; - for(int j = 0; j < proximity.size; j++){ - int pos = (offset + j) % proximity.size; - var other = proximity.get(j); + for(int pos = 0; pos < proximity.size; pos++){ + var other = proximity.get(pos); boolean interactable = other.interactable(team); //set the stats of all buildings in possibleBlocks @@ -95,6 +98,7 @@ public class Unloader extends Block{ pb.building = other; pb.canUnload = interactable && other.canUnload() && other.items != null && other.items.has(sortItem); pb.canLoad = interactable && !(other.block instanceof StorageBlock) && other.acceptItem(this, sortItem); + pb.index = pos; } }else{ //select the next item for nulloaders @@ -106,9 +110,8 @@ public class Unloader extends Block{ boolean isDistinct = false; Item possibleItem = content.item(total); - for(int j = 0; j < proximity.size; j++){ - int pos = (offset + j) % proximity.size; - var other = proximity.get(j); + for(int pos = 0; pos < proximity.size; pos++){ + var other = proximity.get(pos); boolean interactable = other.interactable(team); //set the stats of all buildings in possibleBlocks while we are at it @@ -116,6 +119,7 @@ public class Unloader extends Block{ pb.building = other; pb.canUnload = interactable && other.canUnload() && other.items != null && other.items.has(possibleItem); pb.canLoad = interactable && !(other.block instanceof StorageBlock) && other.acceptItem(this, possibleItem); + pb.index = pos; //the part handling framerate issues and slow conveyor belts, to avoid skipping items if(hasProvider && pb.canLoad) isDistinct = true; @@ -138,11 +142,13 @@ public class Unloader extends Block{ pb.loadFactor = (other.getMaximumAccepted(item) == 0) || (other.items == null) ? 0 : other.items.get(item) / (float)other.getMaximumAccepted(item); } - //sort so it gives full priority to blocks that can give but not receive (stackConveyors and Storage), and then by load + //sort so it gives full priority to blocks that can give but not receive (stackConveyors and Storage), and then by load, and then by last use possibleBlocks.sort(Structs.comps( Structs.comparingBool(e -> e.building.block.highUnloadPriority), - Structs.comparingFloat(e -> e.loadFactor) - )); + Structs.comps( + Structs.comparingFloat(e -> e.loadFactor), + Structs.comparingInt(e -> -lastUsed[e.index]) + ))); ContainerStat dumpingFrom = null; ContainerStat dumpingTo = null; @@ -163,10 +169,17 @@ public class Unloader extends Block{ } } + //increment the priority if not used + for(int i = 0; i < possibleBlocks.size; i++){ + lastUsed[i] = (lastUsed[i] + 1 ) % 2147483647; + } + //trade the items if(dumpingFrom != null && dumpingTo != null && (dumpingFrom.loadFactor != dumpingTo.loadFactor || dumpingFrom.building.block.highUnloadPriority)){ dumpingTo.building.handleItem(this, item); dumpingFrom.building.removeStack(item, 1); + lastUsed[dumpingFrom.index] = 0; + lastUsed[dumpingTo.index] = 0; any = true; }