Skip to content

Commit

Permalink
hortiloaders hotfix randomness (Anuken#6283)
Browse files Browse the repository at this point in the history
* hortiloaders hotfix randomness

Improved the unloaders' balance with multiple blocks having the same load

* deterministic lets go

Co-Authored-By: citrusMarmelade <[email protected]>

* update contributors

forgot to add them since they helped a lot for the previous commits/PRs

Co-authored-by: citrusMarmelade <[email protected]>
  • Loading branch information
hortiSquash and citrusMarmelade authored Nov 1, 2021
1 parent f5c0984 commit 134ef9e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
1 change: 1 addition & 0 deletions core/assets/contributors
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,4 @@ TranquillyUnpleasant
Darkness6030
hortiSquash
King-BR
citrusMarmelade
31 changes: 22 additions & 9 deletions core/src/mindustry/world/blocks/storage/Unloader.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ public class ContainerStat{
float loadFactor;
boolean canLoad;
boolean canUnload;
int index;
}

public int[] lastUsed;

@Override
public void updateTile(){
if(((unloadTimer += delta()) < speed) || (proximity.size < 2)) return;
Expand All @@ -80,21 +83,22 @@ public void updateTile(){
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
ContainerStat pb = possibleBlocks.get(pos);
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
Expand All @@ -106,16 +110,16 @@ public void updateTile(){
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
ContainerStat pb = possibleBlocks.get(pos);
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;
Expand All @@ -138,11 +142,13 @@ public void updateTile(){
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;
Expand All @@ -163,10 +169,17 @@ public void updateTile(){
}
}

//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;
}

Expand Down

0 comments on commit 134ef9e

Please sign in to comment.