mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-05 00:17:33 +07:00
2x faster conveyor optimization
This commit is contained in:
parent
adbfb15932
commit
6fe2697185
@ -10,7 +10,6 @@ import arc.util.ArcAnnotate.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.traits.BuilderTrait.*;
|
import mindustry.entities.traits.BuilderTrait.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
@ -26,7 +25,6 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class Conveyor extends Block implements Autotiler{
|
public class Conveyor extends Block implements Autotiler{
|
||||||
private static final float itemSpace = 0.4f;
|
private static final float itemSpace = 0.4f;
|
||||||
private static final float minmove = 1f / (Short.MAX_VALUE - 2);
|
|
||||||
private static final int capacity = 4;
|
private static final int capacity = 4;
|
||||||
|
|
||||||
private final Vec2 tr1 = new Vec2();
|
private final Vec2 tr1 = new Vec2();
|
||||||
@ -99,6 +97,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
if(tile.front() != null && tile.front().entity != null){
|
if(tile.front() != null && tile.front().entity != null){
|
||||||
entity.next = tile.front().entity;
|
entity.next = tile.front().entity;
|
||||||
entity.nextc = entity.next instanceof ConveyorEntity ? (ConveyorEntity)entity.next : null;
|
entity.nextc = entity.next instanceof ConveyorEntity ? (ConveyorEntity)entity.next : null;
|
||||||
|
entity.aligned = entity.nextc != null && tile.rotation() == entity.next.tile.rotation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,17 +123,17 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawLayer(Tile tile){
|
public void drawLayer(Tile tile){
|
||||||
ConveyorEntity entity = tile.ent();
|
ConveyorEntity e = tile.ent();
|
||||||
byte rotation = tile.rotation();
|
byte rotation = tile.rotation();
|
||||||
|
|
||||||
for(int i = 0; i < entity.count; i++){
|
for(int i = 0; i < e.len; i++){
|
||||||
Item item = entity.ids[i];
|
Item item = e.ids[i];
|
||||||
tr1.trns(rotation * 90, tilesize, 0);
|
tr1.trns(rotation * 90, tilesize, 0);
|
||||||
tr2.trns(rotation * 90, -tilesize / 2f, entity.xs[i] * tilesize / 2f);
|
tr2.trns(rotation * 90, -tilesize / 2f, e.xs[i] * tilesize / 2f);
|
||||||
|
|
||||||
Draw.rect(item.icon(Cicon.medium),
|
Draw.rect(item.icon(Cicon.medium),
|
||||||
(tile.x * tilesize + tr1.x * entity.ys[i] + tr2.x),
|
(tile.x * tilesize + tr1.x * e.ys[i] + tr2.x),
|
||||||
(tile.y * tilesize + tr1.y * entity.ys[i] + tr2.y), itemSize, itemSize);
|
(tile.y * tilesize + tr1.y * e.ys[i] + tr2.y), itemSize, itemSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,71 +162,56 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
if(Math.abs(tile.worldx() - unit.x) < 1f) centerx = 0f;
|
if(Math.abs(tile.worldx() - unit.x) < 1f) centerx = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.count * itemSpace < 0.9f){
|
if(entity.len * itemSpace < 0.9f){
|
||||||
unit.applyImpulse((tx * speed + centerx) * entity.delta(), (ty * speed + centery) * entity.delta());
|
unit.applyImpulse((tx * speed + centerx) * entity.delta(), (ty * speed + centery) * entity.delta());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
ConveyorEntity entity = tile.ent();
|
ConveyorEntity e = tile.ent();
|
||||||
entity.minitem = 1f;
|
e.minitem = 1f;
|
||||||
@Nullable TileEntity next = entity.next;
|
e.mid = 0;
|
||||||
|
|
||||||
float nextMax = entity.nextc != null
|
//skip updates if possible
|
||||||
&& next.block.acceptItem(null, next.tile, tile) ?
|
if(e.items.total() == 0){
|
||||||
1f - Math.max(itemSpace - entity.nextc.minitem, 0) : 1f;
|
e.clogHeat = 0f;
|
||||||
int minremove = Integer.MAX_VALUE;
|
e.sleep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = entity.count - 1; i >= 0; i--){
|
float nextMax = e.nextc != null && tile.rotation() == e.nextc.tile.rotation() /** TODO may not accept due to blockage or team */ ? 1f - Math.max(itemSpace - e.nextc.minitem, 0) : 1f;
|
||||||
float nextpos = (i == entity.count - 1 ? 100f : entity.ys[i + 1]) - itemSpace;
|
|
||||||
float maxmove = Math.min(nextpos - pos.y, speed * entity.delta());
|
|
||||||
|
|
||||||
if(maxmove > minmove){
|
for(int i = e.len - 1; i >= 0; i--){
|
||||||
pos.y += maxmove;
|
float nextpos = (i == e.len - 1 ? 100f : e.ys[i + 1]) - itemSpace;
|
||||||
if(Mathf.equal(pos.x, 0, 0.1f)){
|
float maxmove = Math.min(nextpos - e.ys[i], speed * e.delta());
|
||||||
pos.x = 0f;
|
|
||||||
|
e.ys[i] += maxmove;
|
||||||
|
|
||||||
|
if(e.ys[i] > nextMax) e.ys[i] = nextMax;
|
||||||
|
if(e.ys[i] > 0.5 && i > 0) e.mid = i - 1;
|
||||||
|
e.xs[i] = Mathf.approachDelta(e.xs[i], 0, 0.1f);
|
||||||
|
|
||||||
|
if(e.ys[i] >= 0.9999f && offloadDir(tile, e.ids[i])){
|
||||||
|
//align X position if passing forwards
|
||||||
|
if(e.nextc != null && e.aligned){
|
||||||
|
e.nextc.xs[e.nextc.lastInserted] = e.xs[i];
|
||||||
}
|
}
|
||||||
pos.x = Mathf.lerpDelta(pos.x, 0, 0.1f);
|
//remove last item
|
||||||
}
|
e.len = Math.min(i, e.len);
|
||||||
|
e.items.remove(e.ids[i], 1);
|
||||||
pos.y = Mathf.clamp(pos.y, 0, nextMax);
|
}else if(e.ys[i] < e.minitem){
|
||||||
|
e.minitem = e.ys[i];
|
||||||
if(pos.y >= 0.9999f && offloadDir(tile, pos.item)){
|
|
||||||
if(next != null && next.block() instanceof Conveyor){
|
|
||||||
ConveyorEntity othere = next.ent();
|
|
||||||
|
|
||||||
ItemPos ni = pos2.set(othere.convey.get(othere.lastInserted), ItemPos.updateShorts);
|
|
||||||
|
|
||||||
if(next.rotation() == tile.rotation()){
|
|
||||||
ni.x = pos.x;
|
|
||||||
}
|
|
||||||
othere.convey.set(othere.lastInserted, ni.pack());
|
|
||||||
}
|
|
||||||
minremove = Math.min(i, minremove);
|
|
||||||
tile.entity.items.remove(pos.item, 1);
|
|
||||||
}else{
|
|
||||||
value = pos.pack();
|
|
||||||
|
|
||||||
if(pos.y < entity.minitem)
|
|
||||||
entity.minitem = pos.y;
|
|
||||||
entity.convey.set(i, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.minitem < itemSpace){
|
if(e.minitem < itemSpace){
|
||||||
entity.clogHeat = Mathf.lerpDelta(entity.clogHeat, 1f, 0.02f);
|
e.clogHeat = Mathf.lerpDelta(e.clogHeat, 1f, 0.02f);
|
||||||
}else{
|
}else{
|
||||||
entity.clogHeat = Mathf.lerpDelta(entity.clogHeat, 0f, 1f);
|
e.clogHeat = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.items.total() == 0){
|
e.noSleep();
|
||||||
entity.sleep();
|
|
||||||
}else{
|
|
||||||
entity.noSleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(minremove != Integer.MAX_VALUE) entity.convey.truncate(minremove);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -247,22 +231,21 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int removeStack(Tile tile, Item item, int amount){
|
public int removeStack(Tile tile, Item item, int amount){
|
||||||
ConveyorEntity entity = tile.ent();
|
ConveyorEntity e = tile.ent();
|
||||||
entity.noSleep();
|
e.noSleep();
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
|
|
||||||
for(int j = 0; j < amount; j++){
|
for(int j = 0; j < amount; j++){
|
||||||
for(int i = 0; i < entity.convey.size; i++){
|
for(int i = 0; i < e.len; i++){
|
||||||
long val = entity.convey.get(i);
|
if(e.ids[i] == item){
|
||||||
ItemPos pos = pos1.set(val, ItemPos.drawShorts);
|
e.remove(i);
|
||||||
if(pos.item == item){
|
e.items.remove(item, 1);
|
||||||
entity.convey.removeValue(val);
|
removed ++;
|
||||||
entity.items.remove(item, 1);
|
|
||||||
removed++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,52 +262,50 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleStack(Item item, int amount, Tile tile, Unit source){
|
public void handleStack(Item item, int amount, Tile tile, Unit source){
|
||||||
ConveyorEntity entity = tile.ent();
|
ConveyorEntity e = tile.ent();
|
||||||
|
|
||||||
for(int i = amount - 1; i >= 0; i--){
|
for(int i = amount - 1; i >= 0; i--){
|
||||||
long result = ItemPos.packItem(item, 0f, i * itemSpace);
|
e.add(0);
|
||||||
entity.convey.insert(0, result);
|
e.xs[0] = 0;
|
||||||
entity.items.add(item, 1);
|
e.ys[0] = i * itemSpace;
|
||||||
|
e.ids[0] = item;
|
||||||
|
e.items.add(item, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.noSleep();
|
e.noSleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptItem(Item item, Tile tile, Tile source){
|
public boolean acceptItem(Item item, Tile tile, Tile source){
|
||||||
|
ConveyorEntity e = tile.ent();
|
||||||
|
if(e.len >= capacity) return false;
|
||||||
int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.rotation());
|
int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.rotation());
|
||||||
float minitem = tile.<ConveyorEntity>ent().minitem;
|
return (((direction == 0) && e.minitem >= itemSpace) || ((direction % 2 == 1) && e.minitem > 0.5f + itemSpace)) && (source == null || !(source.block().rotate && (source.rotation() + 2) % 4 == tile.rotation()));
|
||||||
return (((direction == 0) && minitem >= itemSpace) ||
|
|
||||||
((direction % 2 == 1) && minitem > 0.52f)) && (source == null || !(source.block().rotate && (source.rotation() + 2) % 4 == tile.rotation()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleItem(Item item, Tile tile, Tile source){
|
public void handleItem(Item item, Tile tile, Tile source){
|
||||||
byte rotation = tile.rotation();
|
ConveyorEntity e = tile.ent();
|
||||||
|
if(e.len >= capacity) return;
|
||||||
|
|
||||||
int ch = Math.abs(source.relativeTo(tile.x, tile.y) - rotation);
|
byte r = tile.rotation();
|
||||||
int ang = ((source.relativeTo(tile.x, tile.y) - rotation));
|
int ang = ((source.relativeTo(tile.x, tile.y) - r));
|
||||||
|
float x = (ang == -1 || ang == 3) ? 1 : (ang == 1 || ang == -3) ? -1 : 0;
|
||||||
|
|
||||||
float pos = ch == 0 ? 0 : ch % 2 == 1 ? 0.5f : 1f;
|
e.noSleep();
|
||||||
float y = (ang == -1 || ang == 3) ? 1 : (ang == 1 || ang == -3) ? -1 : 0;
|
e.items.add(item, 1);
|
||||||
|
|
||||||
ConveyorEntity entity = tile.ent();
|
if(Math.abs(source.relativeTo(tile.x, tile.y) - r) == 0){ //idx = 0
|
||||||
entity.noSleep();
|
e.add(0);
|
||||||
long result = ItemPos.packItem(item, y * 0.9f, pos);
|
e.xs[0] = x;
|
||||||
|
e.ys[0] = 0;
|
||||||
tile.entity.items.add(item, 1);
|
e.ids[0] = item;
|
||||||
|
}else{ //idx = mid
|
||||||
for(int i = 0; i < entity.convey.size; i++){
|
e.add(e.mid);
|
||||||
if(compareItems(result, entity.convey.get(i)) < 0){
|
e.xs[e.mid] = x;
|
||||||
entity.convey.insert(i, result);
|
e.ys[e.mid] = 0.5f;
|
||||||
entity.lastInserted = (byte)i;
|
e.ids[e.mid] = item;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//this item must be greater than anything there...
|
|
||||||
entity.convey.add(result);
|
|
||||||
entity.lastInserted = (byte)(entity.convey.size - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ConveyorEntity extends TileEntity{
|
public static class ConveyorEntity extends TileEntity{
|
||||||
@ -333,12 +314,14 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
float[] xs = new float[capacity];
|
float[] xs = new float[capacity];
|
||||||
float[] ys = new float[capacity];
|
float[] ys = new float[capacity];
|
||||||
//amount of items, always < capacity
|
//amount of items, always < capacity
|
||||||
int count = 0;
|
int len = 0;
|
||||||
//next entity
|
//next entity
|
||||||
@Nullable TileEntity next;
|
@Nullable TileEntity next;
|
||||||
@Nullable ConveyorEntity nextc;
|
@Nullable ConveyorEntity nextc;
|
||||||
|
//whether the next conveyor's rotation == tile rotation
|
||||||
|
boolean aligned;
|
||||||
|
|
||||||
byte lastInserted;
|
int lastInserted, mid;
|
||||||
float minitem = 1;
|
float minitem = 1;
|
||||||
|
|
||||||
int blendbits;
|
int blendbits;
|
||||||
@ -346,53 +329,50 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
|
|
||||||
float clogHeat = 0f;
|
float clogHeat = 0f;
|
||||||
|
|
||||||
|
final void add(int o){
|
||||||
|
for(int i = Math.max(o + 1, len); i > o; i--){
|
||||||
|
ids[i] = ids[i - 1];
|
||||||
|
xs[i] = xs[i - 1];
|
||||||
|
ys[i] = ys[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
final void remove(int o){
|
||||||
|
for(int i = o; i < len - 1; i++){
|
||||||
|
ids[i] = ids[i + 1];
|
||||||
|
xs[i] = xs[i + 1];
|
||||||
|
ys[i] = ys[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput stream) throws IOException{
|
public void write(DataOutput stream) throws IOException{
|
||||||
super.write(stream);
|
super.write(stream);
|
||||||
stream.writeInt(count);
|
stream.writeInt(len);
|
||||||
|
|
||||||
for(int i = 0; i < count; i++){
|
for(int i = 0; i < len; i++){
|
||||||
stream.writeInt(ItemPos.toInt(convey.get(i)));
|
stream.writeInt(Pack.intBytes((byte)ids[i].id, (byte)(xs[i] * 127), (byte)(ys[i] * 255 - 128), (byte)0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInput stream, byte revision) throws IOException{
|
public void read(DataInput stream, byte revision) throws IOException{
|
||||||
super.read(stream, revision);
|
super.read(stream, revision);
|
||||||
count = 0;
|
len = Math.min(stream.readInt(), capacity);
|
||||||
int amount = stream.readInt();
|
|
||||||
convey.ensureCapacity(Math.min(amount, 10));
|
|
||||||
|
|
||||||
for(int i = 0; i < amount; i++){
|
for(int i = 0; i < len; i++){
|
||||||
convey.add(ItemPos.toLong(stream.readInt()));
|
int val = stream.readInt();
|
||||||
|
byte id = (byte)(val >> 24);
|
||||||
|
float x = (float)((byte)(val >> 16)) / 127f;
|
||||||
|
float y = ((float)((byte)(val >> 8)) + 128f) / 255f;
|
||||||
|
ids[i] = content.item(id);
|
||||||
|
xs[i] = x;
|
||||||
|
ys[i] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int toInt(int index){
|
|
||||||
short itemid = values[0];
|
|
||||||
float x = values[1] / (float)Short.MAX_VALUE;
|
|
||||||
float y = ((float)values[2]) / Short.MAX_VALUE + 1f;
|
|
||||||
|
|
||||||
byte[] bytes = writeByte;
|
|
||||||
bytes[0] = (byte)itemid;
|
|
||||||
bytes[1] = (byte)(x * 127);
|
|
||||||
bytes[2] = (byte)(y * 255 - 128);
|
|
||||||
|
|
||||||
return Pack.intBytes(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
static long toLong(int value){
|
|
||||||
byte[] values = Pack.bytes(value, writeByte);
|
|
||||||
|
|
||||||
short itemid = content.item(values[0]).id;
|
|
||||||
float x = values[1] / 127f;
|
|
||||||
float y = ((int)values[2] + 128) / 255f;
|
|
||||||
|
|
||||||
short[] shorts = writeShort;
|
|
||||||
shorts[0] = itemid;
|
|
||||||
shorts[1] = (short)(x * Short.MAX_VALUE);
|
|
||||||
shorts[2] = (short)((y - 1f) * Short.MAX_VALUE);
|
|
||||||
return Pack.longShorts(shorts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=aa8dafc3ff72c8f7776deb4597682e56b8697bc7
|
archash=649641d8936160221ce24c47f5b0ad10606de289
|
||||||
|
Loading…
Reference in New Issue
Block a user