More cleanup, nearing completion of block refactor

This commit is contained in:
Anuken
2020-03-06 12:19:26 -05:00
parent 1c48c1a43e
commit 4744465986
47 changed files with 1405 additions and 1361 deletions
+39 -43
View File
@@ -13,7 +13,6 @@ import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import arc.util.io.*; import arc.util.io.*;
import arc.util.pooling.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.ctype.*; import mindustry.ctype.*;
@@ -28,7 +27,6 @@ import mindustry.world.*;
import mindustry.world.blocks.environment.*; import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.power.*; import mindustry.world.blocks.power.*;
import mindustry.world.consumers.*; import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.modules.*; import mindustry.world.modules.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@@ -134,6 +132,18 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
timeScaleDuration = Math.max(timeScaleDuration, duration); timeScaleDuration = Math.max(timeScaleDuration, duration);
} }
public Tilec nearby(int dx, int dy){
return world.ent(tile.x + dx, tile.y + dy);
}
public Tilec nearby(int rotation){
if(rotation == 0) return world.ent(tile.x + 1, tile.y);
if(rotation == 1) return world.ent(tile.x, tile.y + 1);
if(rotation == 2) return world.ent(tile.x - 1, tile.y);
if(rotation == 3) return world.ent(tile.x, tile.y - 1);
return null;
}
public byte relativeTo(Tile tile){ public byte relativeTo(Tile tile){
return relativeTo(tile.x, tile.y); return relativeTo(tile.x, tile.y);
} }
@@ -155,6 +165,22 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
return -1; return -1;
} }
public @Nullable Tilec front(){
return nearby((rotation() + 4) % 4);
}
public @Nullable Tilec right(){
return nearby((rotation() + 3) % 4);
}
public @Nullable Tilec back(){
return nearby((rotation() + 2) % 4);
}
public @Nullable Tilec left(){
return nearby((rotation() + 1) % 4);
}
public int pos(){ public int pos(){
return pos(); return pos();
} }
@@ -551,36 +577,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
public void drawSelect(){ public void drawSelect(){
} }
public float drawPlaceText(String text, int x, int y, boolean valid){
if(renderer.pixelator.enabled()) return 0;
Color color = valid ? Pal.accent : Pal.remove;
BitmapFont font = Fonts.outline;
GlyphLayout layout = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
boolean ints = font.usesIntegerPositions();
font.setUseIntegerPositions(false);
font.getData().setScale(1f / 4f / Scl.scl(1f));
layout.setText(font, text);
float width = layout.width;
font.setColor(color);
float dx = x * tilesize + block.offset(), dy = y * tilesize + block.offset() + block.size * tilesize / 2f + 3;
font.draw(text, dx, dy + layout.height + 1, Align.center);
dy -= 1f;
Lines.stroke(2f, Color.darkGray);
Lines.line(dx - layout.width / 2f - 2f, dy, dx + layout.width / 2f + 1.5f, dy);
Lines.stroke(1f, color);
Lines.line(dx - layout.width / 2f - 2f, dy, dx + layout.width / 2f + 1.5f, dy);
font.setUseIntegerPositions(ints);
font.setColor(Color.white);
font.getData().setScale(1f);
Draw.reset();
Pools.free(layout);
return width;
}
public void draw(){ public void draw(){
Draw.rect(block.region, x, y, block.rotate ? rotation() * 90 : 0); Draw.rect(block.region, x, y, block.rotate ? rotation() * 90 : 0);
} }
@@ -658,16 +654,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
} }
} }
public float sumAttribute(Attribute attr, int x, int y){
Tile tile = world.tile(x, y);
if(tile == null) return 0;
float sum = 0;
for(Tile other : tile.getLinkedTilesAs(block, tempTiles)){
sum += other.floor().attributes.get(attr);
}
return sum;
}
public float percentSolid(int x, int y){ public float percentSolid(int x, int y){
Tile tile = world.tile(x, y); Tile tile = world.tile(x, y);
if(tile == null) return 0; if(tile == null) return 0;
@@ -678,7 +664,17 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
return sum / block.size / block.size; return sum / block.size / block.size;
} }
/** Called when the block is tapped. This is equivalent to being configured with null. */ /** Called when arbitrary configuration is applied to a tile. */
public void configured(@Nullable Playerc player, @Nullable Object value){
//null is of type Void.class; anonymous classes use their superclass.
Class<?> type = value == null ? void.class : value.getClass().isAnonymousClass() ? value.getClass().getSuperclass() : value.getClass();
if(block.configurations.containsKey(type)){
block.configurations.get(type).get(tile, value);
}
}
/** Called when the block is tapped.*/
public void tapped(Playerc player){ public void tapped(Playerc player){
} }
+57 -13
View File
@@ -13,7 +13,7 @@ import arc.struct.Array;
import arc.struct.EnumSet; import arc.struct.EnumSet;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.ArcAnnotate.*; import arc.util.pooling.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.entities.*; import mindustry.entities.*;
@@ -31,7 +31,7 @@ import mindustry.world.meta.values.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.*; import java.util.*;
import static mindustry.Vars.tilesize; import static mindustry.Vars.*;
public class Block extends UnlockableContent{ public class Block extends UnlockableContent{
public static final int crackRegions = 8, maxCrackSize = 5; public static final int crackRegions = 8, maxCrackSize = 5;
@@ -157,7 +157,8 @@ public class Block extends UnlockableContent{
protected Prov<Tilec> entityType = null; //initialized later protected Prov<Tilec> entityType = null; //initialized later
protected TextureRegion[] cacheRegions = {}; protected TextureRegion[] cacheRegions = {};
protected Array<String> cacheRegionStrings = new Array<>(); protected Array<String> cacheRegionStrings = new Array<>();
protected ObjectMap<Class<?>, Cons2> configurations = new ObjectMap<>(); //TODO move
public ObjectMap<Class<?>, Cons2> configurations = new ObjectMap<>();
//TODO move //TODO move
protected TextureRegion[] generatedIcons; protected TextureRegion[] generatedIcons;
@@ -166,6 +167,7 @@ public class Block extends UnlockableContent{
//TODO move //TODO move
public static TextureRegion[][] cracks; public static TextureRegion[][] cracks;
protected static final Array<Tile> tempTiles = new Array<>();
/** Dump timer ID.*/ /** Dump timer ID.*/
protected final int timerDump = timers++; protected final int timerDump = timers++;
@@ -187,10 +189,62 @@ public class Block extends UnlockableContent{
} }
} }
public void drawLayer(Tile tile){
if(tile.entity != null) tile.entity.drawLayer();
}
public void drawLayer2(Tile tile){
if(tile.entity != null) tile.entity.drawLayer2();
}
/** Drawn when you are placing a block. */ /** Drawn when you are placing a block. */
public void drawPlace(int x, int y, int rotation, boolean valid){ public void drawPlace(int x, int y, int rotation, boolean valid){
} }
public float drawPlaceText(String text, int x, int y, boolean valid){
if(renderer.pixelator.enabled()) return 0;
Color color = valid ? Pal.accent : Pal.remove;
BitmapFont font = Fonts.outline;
GlyphLayout layout = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
boolean ints = font.usesIntegerPositions();
font.setUseIntegerPositions(false);
font.getData().setScale(1f / 4f / Scl.scl(1f));
layout.setText(font, text);
float width = layout.width;
font.setColor(color);
float dx = x * tilesize + offset(), dy = y * tilesize + offset() + size * tilesize / 2f + 3;
font.draw(text, dx, dy + layout.height + 1, Align.center);
dy -= 1f;
Lines.stroke(2f, Color.darkGray);
Lines.line(dx - layout.width / 2f - 2f, dy, dx + layout.width / 2f + 1.5f, dy);
Lines.stroke(1f, color);
Lines.line(dx - layout.width / 2f - 2f, dy, dx + layout.width / 2f + 1.5f, dy);
font.setUseIntegerPositions(ints);
font.setColor(Color.white);
font.getData().setScale(1f);
Draw.reset();
Pools.free(layout);
return width;
}
public float sumAttribute(Attribute attr, int x, int y){
Tile tile = world.tile(x, y);
if(tile == null) return 0;
float sum = 0;
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
sum += other.floor().attributes.get(attr);
}
return sum;
}
public String getDisplayName(Tile tile){
return tile.entity == null ? localizedName : tile.entity.getDisplayName();
}
/** @return a custom minimap color for this or 0 to use default colors. */ /** @return a custom minimap color for this or 0 to use default colors. */
public int minimapColor(Tile tile){ public int minimapColor(Tile tile){
return 0; return 0;
@@ -322,16 +376,6 @@ public class Block extends UnlockableContent{
} }
/** Called when arbitrary configuration is applied to a tile. */
public void configured(Tilec tile, @Nullable Playerc player, @Nullable Object value){
//null is of type Void.class; anonymous classes use their superclass.
Class<?> type = value == null ? void.class : value.getClass().isAnonymousClass() ? value.getClass().getSuperclass() : value.getClass();
if(configurations.containsKey(type)){
configurations.get(type).get(tile, value);
}
}
/** Configure when a null value is passed.*/ /** Configure when a null value is passed.*/
public void configClear(Cons<Tilec> cons){ public void configClear(Cons<Tilec> cons){
configurations.put(void.class, (tile, value) -> cons.get((Tilec)tile)); configurations.put(void.class, (tile, value) -> cons.get((Tilec)tile));
@@ -181,11 +181,11 @@ public class Conveyor extends Block implements Autotiler{
float centerx = 0f, centery = 0f; float centerx = 0f, centery = 0f;
if(Math.abs(tx) > Math.abs(ty)){ if(Math.abs(tx) > Math.abs(ty)){
centery = Mathf.clamp((tile.worldy() - unit.y()) / centerDstScl, -centerSpeed, centerSpeed); centery = Mathf.clamp((y - unit.y()) / centerDstScl, -centerSpeed, centerSpeed);
if(Math.abs(tile.worldy() - unit.y()) < 1f) centery = 0f; if(Math.abs(y - unit.y()) < 1f) centery = 0f;
}else{ }else{
centerx = Mathf.clamp((tile.worldx() - unit.x()) / centerDstScl, -centerSpeed, centerSpeed); centerx = Mathf.clamp((x - unit.x()) / centerDstScl, -centerSpeed, centerSpeed);
if(Math.abs(tile.worldx() - unit.x()) < 1f) centerx = 0f; if(Math.abs(x - unit.x()) < 1f) centerx = 0f;
} }
if(len * itemSpace < 0.9f){ if(len * itemSpace < 0.9f){
@@ -15,6 +15,7 @@ public class ExtendingItemBridge extends ItemBridge{
hasItems = true; hasItems = true;
} }
public class ExtendingItemBridgeEntity extends ItemBridgeEntity{
@Override @Override
public void drawLayer(){ public void drawLayer(){
Tile other = world.tile(link); Tile other = world.tile(link);
@@ -22,10 +23,10 @@ public class ExtendingItemBridge extends ItemBridge{
int i = tile.absoluteRelativeTo(other.x, other.y); int i = tile.absoluteRelativeTo(other.x, other.y);
float ex = other.worldx() - tile.worldx() - Geometry.d4[i].x * tilesize / 2f, float ex = other.worldx() - x - Geometry.d4[i].x * tilesize / 2f,
ey = other.worldy() - tile.worldy() - Geometry.d4[i].y * tilesize / 2f; ey = other.worldy() - y - Geometry.d4[i].y * tilesize / 2f;
float uptime = state.isEditor() ? 1f : uptime; float uptime = state.isEditor() ? 1f : this.uptime;
ex *= uptime; ex *= uptime;
ey *= uptime; ey *= uptime;
@@ -36,15 +37,15 @@ public class ExtendingItemBridge extends ItemBridge{
Lines.stroke(8f); Lines.stroke(8f);
Lines.line(bridgeRegion, Lines.line(bridgeRegion,
tile.worldx() + Geometry.d4[i].x * tilesize / 2f, x + Geometry.d4[i].x * tilesize / 2f,
tile.worldy() + Geometry.d4[i].y * tilesize / 2f, y + Geometry.d4[i].y * tilesize / 2f,
tile.worldx() + ex, x + ex,
tile.worldy() + ey, CapStyle.none, 0f); y + ey, CapStyle.none, 0f);
Draw.rect(endRegion, x, y, i * 90 + 90); Draw.rect(endRegion, x, y, i * 90 + 90);
Draw.rect(endRegion, Draw.rect(endRegion,
tile.worldx() + ex + Geometry.d4[i].x * tilesize / 2f, x + ex + Geometry.d4[i].x * tilesize / 2f,
tile.worldy() + ey + Geometry.d4[i].y * tilesize / 2f, i * 90 + 270); y + ey + Geometry.d4[i].y * tilesize / 2f, i * 90 + 270);
int dist = Math.max(Math.abs(other.x - tile.x), Math.abs(other.y - tile.y)); int dist = Math.max(Math.abs(other.x - tile.x), Math.abs(other.y - tile.y));
@@ -55,9 +56,10 @@ public class ExtendingItemBridge extends ItemBridge{
for(int a = 0; a < arrows; a++){ for(int a = 0; a < arrows; a++){
Draw.alpha(Mathf.absin(a / (float)arrows - time / 100f, 0.1f, 1f) * uptime * opacity); Draw.alpha(Mathf.absin(a / (float)arrows - time / 100f, 0.1f, 1f) * uptime * opacity);
Draw.rect(arrowRegion, Draw.rect(arrowRegion,
tile.worldx() + Geometry.d4[i].x * (tilesize / 2f + a * 6f + 2) * uptime, x + Geometry.d4[i].x * (tilesize / 2f + a * 6f + 2) * uptime,
tile.worldy() + Geometry.d4[i].y * (tilesize / 2f + a * 6f + 2) * uptime, i * 90f); y + Geometry.d4[i].y * (tilesize / 2f + a * 6f + 2) * uptime, i * 90f);
} }
Draw.reset(); Draw.reset();
} }
} }
}
@@ -170,7 +170,7 @@ public class ItemBridge extends Block{
@Override @Override
public boolean onConfigureTileTapped(Tilec other){ public boolean onConfigureTileTapped(Tilec other){
if(linkValid(tile, other)){ if(linkValid(tile, other.tile())){
if(link == other.pos()){ if(link == other.pos()){
tile.configure(-1); tile.configure(-1);
}else{ }else{
@@ -195,12 +195,12 @@ public class ItemBridge extends Block{
} }
} }
Tilec other = world.tile(link); Tile other = world.tile(link);
if(!linkValid(tile, other)){ if(!linkValid(tile, other)){
dump(tile); dump();
uptime = 0f; uptime = 0f;
}else{ }else{
((ItemBridgeEntity)world.tile(link).entity).incoming.add(tile.pos()); ((ItemBridgeEntity)other.entity).incoming.add(tile.pos());
if(consValid() && Mathf.zero(1f - efficiency())){ if(consValid() && Mathf.zero(1f - efficiency())){
uptime = Mathf.lerpDelta(uptime, 1f, 0.04f); uptime = Mathf.lerpDelta(uptime, 1f, 0.04f);
@@ -208,7 +208,7 @@ public class ItemBridge extends Block{
uptime = Mathf.lerpDelta(uptime, 0f, 0.02f); uptime = Mathf.lerpDelta(uptime, 0f, 0.02f);
} }
updateTransport(other); updateTransport(other.entity);
} }
} }
@@ -243,8 +243,8 @@ public class ItemBridge extends Block{
Lines.stroke(8f); Lines.stroke(8f);
Lines.line(bridgeRegion, Lines.line(bridgeRegion,
tile.worldx(), x,
tile.worldy(), y,
other.worldx(), other.worldx(),
other.worldy(), CapStyle.none, -tilesize / 2f); other.worldy(), CapStyle.none, -tilesize / 2f);
@@ -258,8 +258,8 @@ public class ItemBridge extends Block{
for(int a = 0; a < arrows; a++){ for(int a = 0; a < arrows; a++){
Draw.alpha(Mathf.absin(a / (float)arrows - time / 100f, 0.1f, 1f) * uptime * opacity); Draw.alpha(Mathf.absin(a / (float)arrows - time / 100f, 0.1f, 1f) * uptime * opacity);
Draw.rect(arrowRegion, Draw.rect(arrowRegion,
tile.worldx() + Geometry.d4[i].x * (tilesize / 2f + a * 4f + time % 4f), x + Geometry.d4[i].x * (tilesize / 2f + a * 4f + time % 4f),
tile.worldy() + Geometry.d4[i].y * (tilesize / 2f + a * 4f + time % 4f), i * 90f); y + Geometry.d4[i].y * (tilesize / 2f + a * 4f + time % 4f), i * 90f);
} }
Draw.reset(); Draw.reset();
} }
@@ -276,7 +276,7 @@ public class ItemBridge extends Block{
if(rel == rel2) return false; if(rel == rel2) return false;
}else{ }else{
return source.block() instanceof ItemBridge && source.<ItemBridgeEntity>ent().link == tile.pos() && items.total() < itemCapacity; return source.block() instanceof ItemBridge && ((ItemBridgeEntity)source).link == tile.pos() && items.total() < itemCapacity;
} }
return items.total() < itemCapacity; return items.total() < itemCapacity;
@@ -318,7 +318,7 @@ public class ItemBridge extends Block{
int rel2 = tile.relativeTo(source.tileX(), source.tileY()); int rel2 = tile.relativeTo(source.tileX(), source.tileY());
if(rel == rel2) return false; if(rel == rel2) return false;
}else if(!(source.block() instanceof ItemBridge && source.<ItemBridgeEntity>ent().link == tile.pos())){ }else if(!(source.block() instanceof ItemBridge && ((ItemBridgeEntity)source).link == tile.pos())){
return false; return false;
} }
@@ -329,7 +329,7 @@ public class ItemBridge extends Block{
public boolean canDump(Tilec to, Item item){ public boolean canDump(Tilec to, Item item){
Tile other = world.tile(link); Tile other = world.tile(link);
if(!linkValid(tile, other)){ if(!linkValid(tile, other)){
Tile edge = Edges.getFacingEdge(to, tile); Tile edge = Edges.getFacingEdge(to.tile(), tile);
int i = tile.absoluteRelativeTo(edge.x, edge.y); int i = tile.absoluteRelativeTo(edge.x, edge.y);
IntSetIterator it = incoming.iterator(); IntSetIterator it = incoming.iterator();
@@ -1,14 +1,11 @@
package mindustry.world.blocks.distribution; package mindustry.world.blocks.distribution;
import arc.util.Time; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.gen.BufferItem; import mindustry.type.*;
import mindustry.type.Item; import mindustry.world.*;
import mindustry.world.Block; import mindustry.world.meta.*;
import mindustry.world.DirectionalItemBuffer;
import mindustry.world.Tile;
import mindustry.world.meta.BlockGroup;
import static mindustry.Vars.content; import static mindustry.Vars.content;
@@ -49,15 +46,14 @@ public class Junction extends Block{
if(Time.time() >= time + speed || Time.time() < time){ if(Time.time() >= time + speed || Time.time() < time){
Item item = content.item(BufferItem.item(l)); Item item = content.item(BufferItem.item(l));
Tile dest = tile.getNearby(i); Tilec dest = nearby(i);
if(dest != null) dest = dest.link();
//skip blocks that don't want the item, keep waiting until they do //skip blocks that don't want the item, keep waiting until they do
if(dest == null || !dest.block().acceptItem(dest, tile, item) || dest.team() != team){ if(dest == null || !dest.acceptItem(this, item) || dest.team() != team){
continue; continue;
} }
dest.block().handleItem(dest, tile, item); dest.handleItem(this, item);
System.arraycopy(buffer.buffers[i], 1, buffer.buffers[i], 0, buffer.indexes[i] - 1); System.arraycopy(buffer.buffers[i], 1, buffer.buffers[i], 0, buffer.indexes[i] - 1);
buffer.indexes[i] --; buffer.indexes[i] --;
} }
@@ -66,18 +62,18 @@ public class Junction extends Block{
} }
@Override @Override
public void handleItem(Tile source, Item item){ public void handleItem(Tilec source, Item item){
int relative = source.relativeTo(tile.x, tile.y); int relative = source.relativeTo(tile.x, tile.y);
buffer.accept(relative, item); buffer.accept(relative, item);
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
int relative = source.relativeTo(tile.x, tile.y); int relative = source.relativeTo(tile.x, tile.y);
if(relative == -1 || !buffer.accepts(relative)) return false; if(relative == -1 || !buffer.accepts(relative)) return false;
Tile to = tile.getNearby(relative); Tilec to = nearby(relative);
return to != null && to.link().entity != null && to.team() == team; return to != null && to.team() == team;
} }
@Override @Override
@@ -212,7 +212,7 @@ public class MassDriver extends Block{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
//mass drivers that ouput only cannot accept items //mass drivers that ouput only cannot accept items
return tile.items.total() < itemCapacity && linkValid(tile); return tile.items.total() < itemCapacity && linkValid(tile);
} }
@@ -28,6 +28,11 @@ public class OverflowGate extends Block{
return true; return true;
} }
public class OverflowGateEntity extends TileEntity{
Item lastItem;
Tile lastInput;
float time;
@Override @Override
public int acceptStack(Item item, int amount, Teamc source){ public int acceptStack(Item item, int amount, Teamc source){
return 0; return 0;
@@ -35,7 +40,7 @@ public class OverflowGate extends Block{
@Override @Override
public int removeStack(Item item, int amount){ public int removeStack(Item item, int amount){
int result = super.removeStack(tile, item, amount); int result = super.removeStack(item, amount);
if(result != 0 && item == lastItem){ if(result != 0 && item == lastItem){
lastItem = null; lastItem = null;
} }
@@ -55,11 +60,11 @@ public class OverflowGate extends Block{
} }
time += 1f / speed * Time.delta(); time += 1f / speed * Time.delta();
Tile target = getTileTarget(tile, lastItem, lastInput, false); Tilec target = getTileTarget(lastItem, lastInput, false);
if(target != null && (time >= 1f)){ if(target != null && (time >= 1f)){
getTileTarget(tile, lastItem, lastInput, true); getTileTarget(lastItem, lastInput, true);
target.block().handleItem(target, Edges.getFacingEdge(tile, target), lastItem); target.handleItem(this, lastItem);
items.remove(lastItem, 1); items.remove(lastItem, 1);
lastItem = null; lastItem = null;
} }
@@ -67,33 +72,32 @@ public class OverflowGate extends Block{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return team == source.team() && lastItem == null && items.total() == 0; return team == source.team() && lastItem == null && items.total() == 0;
} }
@Override @Override
public void handleItem(Tile source, Item item){ public void handleItem(Tilec source, Item item){
items.add(item, 1); items.add(item, 1);
lastItem = item; lastItem = item;
time = 0f; time = 0f;
lastInput = source; lastInput = source.tile();
update(tile); updateTile();
} }
public Tile getTileTarget(Item item, Tile src, boolean flip){ public Tilec getTileTarget(Item item, Tile src, boolean flip){
int from = tile.relativeTo(src.x, src.y); int from = relativeTo(src.x, src.y);
if(from == -1) return null; if(from == -1) return null;
Tile to = tile.getNearby((from + 2) % 4); Tilec to = nearby((from + 2) % 4);
if(to == null) return null; if(to == null) return null;
Tile edge = Edges.getFacingEdge(tile, to); boolean canForward = to.acceptItem(this, item) && to.team() == team && !(to.block() instanceof OverflowGate);
boolean canForward = to.block().acceptItem(to, edge, item) && to.team() == team && !(to.block() instanceof OverflowGate);
if(!canForward || invert){ if(!canForward || invert){
Tile a = tile.getNearby(Mathf.mod(from - 1, 4)); Tilec a = nearby(Mathf.mod(from - 1, 4));
Tile b = tile.getNearby(Mathf.mod(from + 1, 4)); Tilec b = nearby(Mathf.mod(from + 1, 4));
boolean ac = a != null && a.block().acceptItem(a, edge, item) && !(a.block() instanceof OverflowGate) && a.team() == team; boolean ac = a != null && a.acceptItem(this, item) && !(a.block() instanceof OverflowGate) && a.team() == team;
boolean bc = b != null && b.block().acceptItem(b, edge, item) && !(b.block() instanceof OverflowGate) && b.team() == team; boolean bc = b != null && b.acceptItem(this, item) && !(b.block() instanceof OverflowGate) && b.team() == team;
if(!ac && !bc){ if(!ac && !bc){
return invert && canForward ? to : null; return invert && canForward ? to : null;
@@ -117,11 +121,6 @@ public class OverflowGate extends Block{
return to; return to;
} }
public class OverflowGateEntity extends TileEntity{
Item lastItem;
Tile lastInput;
float time;
@Override @Override
public byte version(){ public byte version(){
return 3; return 3;
@@ -1,12 +1,11 @@
package mindustry.world.blocks.distribution; package mindustry.world.blocks.distribution;
import arc.struct.Array; import arc.util.*;
import arc.util.Time;
import mindustry.content.*; import mindustry.content.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.type.Item; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.meta.BlockGroup; import mindustry.world.meta.*;
public class Router extends Block{ public class Router extends Block{
public float speed = 8f; public float speed = 8f;
@@ -21,6 +20,11 @@ public class Router extends Block{
unloadable = false; unloadable = false;
} }
public class RouterEntity extends TileEntity{
Item lastItem;
Tile lastInput;
float time;
@Override @Override
public void updateTile(){ public void updateTile(){
if(lastItem == null && items.total() > 0){ if(lastItem == null && items.total() > 0){
@@ -29,11 +33,11 @@ public class Router extends Block{
if(lastItem != null){ if(lastItem != null){
time += 1f / speed * Time.delta(); time += 1f / speed * Time.delta();
Tile target = getTileTarget(tile, lastItem, lastInput, false); Tilec target = getTileTarget(lastItem, lastInput, false);
if(target != null && (time >= 1f || !(target.block() instanceof Router))){ if(target != null && (time >= 1f || !(target.block() instanceof Router))){
getTileTarget(tile, lastItem, lastInput, true); getTileTarget(lastItem, lastInput, true);
target.block().handleItem(target, Edges.getFacingEdge(tile, target), lastItem); target.handleItem(this, lastItem);
items.remove(lastItem, 1); items.remove(lastItem, 1);
lastItem = null; lastItem = null;
} }
@@ -41,26 +45,25 @@ public class Router extends Block{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return team == source.team() && lastItem == null && items.total() == 0; return team == source.team() && lastItem == null && items.total() == 0;
} }
@Override @Override
public void handleItem(Tile source, Item item){ public void handleItem(Tilec source, Item item){
items.add(item, 1); items.add(item, 1);
lastItem = item; lastItem = item;
time = 0f; time = 0f;
lastInput = source; lastInput = source.tile();
} }
Tile getTileTarget(Item item, Tile from, boolean set){ Tilec getTileTarget(Item item, Tile from, boolean set){
Array<Tile> proximity = tile.proximity();
int counter = tile.rotation(); int counter = tile.rotation();
for(int i = 0; i < proximity.size; i++){ for(int i = 0; i < proximity.size; i++){
Tile other = proximity.get((i + counter) % proximity.size); Tilec other = proximity.get((i + counter) % proximity.size);
if(set) tile.rotation((byte)((tile.rotation() + 1) % proximity.size)); if(set) tile.rotation((byte)((tile.rotation() + 1) % proximity.size));
if(other == from && from.block() == Blocks.overflowGate) continue; if(other.tile() == from && from.block() == Blocks.overflowGate) continue;
if(other.block().acceptItem(other, Edges.getFacingEdge(tile, other), item)){ if(other.acceptItem(this, item)){
return other; return other;
} }
} }
@@ -69,16 +72,11 @@ public class Router extends Block{
@Override @Override
public int removeStack(Item item, int amount){ public int removeStack(Item item, int amount){
int result = super.removeStack(tile, item, amount); int result = super.removeStack(item, amount);
if(result != 0 && item == lastItem){ if(result != 0 && item == lastItem){
lastItem = null; lastItem = null;
} }
return result; return result;
} }
public class RouterEntity extends TileEntity{
Item lastItem;
Tile lastInput;
float time;
} }
} }
@@ -27,8 +27,13 @@ public class Sorter extends Block{
group = BlockGroup.transportation; group = BlockGroup.transportation;
configurable = true; configurable = true;
unloadable = false; unloadable = false;
config(Item.class, (tile, item) -> tile.<SorterEntity>ent().sortItem = item); config(Item.class, (tile, item) -> ((SorterEntity)tile).sortItem = item);
configClear(tile -> tile.<SorterEntity>ent().sortItem = null); configClear(tile -> ((SorterEntity)tile).sortItem = null);
}
@Override
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
drawRequestConfigCenter(req, (Item)req.config, "center");
} }
@Override @Override
@@ -36,6 +41,14 @@ public class Sorter extends Block{
return true; return true;
} }
@Override
public int minimapColor(Tile tile){
return tile.<SorterEntity>ent().sortItem == null ? 0 : tile.<SorterEntity>ent().sortItem.color.rgba();
}
public class SorterEntity extends TileEntity{
@Nullable Item sortItem;
@Override @Override
public void playerPlaced(){ public void playerPlaced(){
if(lastItem != null){ if(lastItem != null){
@@ -45,18 +58,13 @@ public class Sorter extends Block{
@Override @Override
public void configured(Playerc player, Object value){ public void configured(Playerc player, Object value){
super.configured(tile, player, value); super.configured(player, value);
if(!headless){ if(!headless){
renderer.minimap.update(tile); renderer.minimap.update(tile);
} }
} }
@Override
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
drawRequestConfigCenter(req, (Item)req.config, "center");
}
@Override @Override
public void draw(){ public void draw(){
super.draw(); super.draw();
@@ -64,54 +72,47 @@ public class Sorter extends Block{
if(sortItem == null) return; if(sortItem == null) return;
Draw.color(sortItem.color); Draw.color(sortItem.color);
Draw.rect("center", tile.worldx(), tile.worldy()); Draw.rect("center", x, y);
Draw.color(); Draw.color();
} }
@Override @Override
public int minimapColor(){ public boolean acceptItem(Tilec source, Item item){
return tile.<SorterEntity>ent().sortItem == null ? 0 : tile.<SorterEntity>ent().sortItem.color.rgba(); Tilec to = getTileTarget(item, source, false);
return to != null && to.acceptItem(this, item) && to.team() == team;
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public void handleItem(Tilec source, Item item){
Tile to = getTileTarget(item, tile, source, false); Tilec to = getTileTarget(item, source, true);
return to != null && to.block().acceptItem(to, tile, item) && to.team() == team; to.handleItem(this, item);
} }
@Override boolean isSame(Tilec other){
public void handleItem(Tile source, Item item){
Tile to = getTileTarget(item, tile, source, true);
to.block().handleItem(to, tile, item);
}
boolean isSame(Tile other){
//uncomment comment below to prevent sorter/gate chaining (hacky) //uncomment comment below to prevent sorter/gate chaining (hacky)
return other != null && (other.block() instanceof Sorter/* || other.block() instanceof OverflowGate */); return other != null && (other.block() instanceof Sorter/* || other.block() instanceof OverflowGate */);
} }
Tile getTileTarget(Item item, Tile dest, Tile source, boolean flip){ Tilec getTileTarget(Item item, Tilec source, boolean flip){
SorterEntity entity = dest.ent(); int dir = source.relativeTo(tile.x, tile.y);
int dir = source.relativeTo(dest.x, dest.y);
if(dir == -1) return null; if(dir == -1) return null;
Tile to; Tilec to;
if((item == sortItem) != invert){ if((item == sortItem) != invert){
//prevent 3-chains //prevent 3-chains
if(isSame(dest, source) && isSame(dest, dest.getNearby(dir))){ if(isSame(source) && isSame(nearby(dir))){
return null; return null;
} }
to = dest.getNearby(dir); to = nearby(dir);
}else{ }else{
Tile a = dest.getNearby(Mathf.mod(dir - 1, 4)); Tilec a = nearby(Mathf.mod(dir - 1, 4));
Tile b = dest.getNearby(Mathf.mod(dir + 1, 4)); Tilec b = nearby(Mathf.mod(dir + 1, 4));
boolean ac = a != null && !(a.block().instantTransfer && source.block().instantTransfer) && boolean ac = a != null && !(a.block().instantTransfer && source.block().instantTransfer) &&
a.block().acceptItem(a, dest, item); a.acceptItem(this, item);
boolean bc = b != null && !(b.block().instantTransfer && source.block().instantTransfer) && boolean bc = b != null && !(b.block().instantTransfer && source.block().instantTransfer) &&
b.block().acceptItem(b, dest, item); b.acceptItem(this, item);
if(ac && !bc){ if(ac && !bc){
to = a; to = a;
@@ -120,12 +121,12 @@ public class Sorter extends Block{
}else if(!bc){ }else if(!bc){
return null; return null;
}else{ }else{
if(dest.rotation() == 0){ if(rotation() == 0){
to = a; to = a;
if(flip) dest.rotation((byte)1); if(flip) rotation((byte)1);
}else{ }else{
to = b; to = b;
if(flip) dest.rotation((byte)0); if(flip) rotation((byte)0);
} }
} }
} }
@@ -138,9 +139,6 @@ public class Sorter extends Block{
ItemSelection.buildTable(table, content.items(), () -> sortItem, item -> tile.configure(lastItem = item)); ItemSelection.buildTable(table, content.items(), () -> sortItem, item -> tile.configure(lastItem = item));
} }
public class SorterEntity extends TileEntity{
@Nullable Item sortItem;
@Override @Override
public Item config(){ public Item config(){
return sortItem; return sortItem;
@@ -17,7 +17,7 @@ public class Cliff extends Block{
} }
@Override @Override
public void drawBase(){ public void drawBase(Tile tile){
int r = tile.rotation(); int r = tile.rotation();
for(int i = 0; i < 8; i++){ for(int i = 0; i < 8; i++){
if((r & (1 << i)) != 0){ if((r & (1 << i)) != 0){
@@ -30,7 +30,7 @@ public class Cliff extends Block{
} }
@Override @Override
public int minimapColor(){ public int minimapColor(Tile tile){
return Tmp.c1.set(tile.floor().mapColor).mul(1.2f).rgba(); return Tmp.c1.set(tile.floor().mapColor).mul(1.2f).rgba();
} }
} }
@@ -1,7 +1,8 @@
package mindustry.world.blocks.environment; package mindustry.world.blocks.environment;
import arc.graphics.g2d.Draw; import arc.graphics.g2d.*;
import arc.math.Mathf; import arc.math.*;
import mindustry.world.*;
public class DoubleOverlayFloor extends OverlayFloor{ public class DoubleOverlayFloor extends OverlayFloor{
@@ -10,7 +11,7 @@ public class DoubleOverlayFloor extends OverlayFloor{
} }
@Override @Override
public void draw(){ public void drawBase(Tile tile){
Draw.colorl(0.4f); Draw.colorl(0.4f);
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy() - 0.75f); Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy() - 0.75f);
Draw.color(); Draw.color();
@@ -153,7 +153,7 @@ public class Floor extends Block{
} }
@Override @Override
public void drawBase(){ public void drawBase(Tile tile){
Mathf.random.setSeed(tile.pos()); Mathf.random.setSeed(tile.pos());
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
@@ -170,17 +170,17 @@ public class Floor extends Block{
return drownTime > 0; return drownTime > 0;
} }
public void drawNonLayer(){ public void drawNonLayer(Tile tile){
Mathf.random.setSeed(tile.pos()); Mathf.random.setSeed(tile.pos());
drawEdges(tile, true); drawEdges(tile, true);
} }
protected void drawEdges(){ protected void drawEdges(Tile tile){
drawEdges(tile, false); drawEdges(tile, false);
} }
protected void drawEdges(boolean sameLayer){ protected void drawEdges(Tile tile, boolean sameLayer){
blenders.clear(); blenders.clear();
blended.clear(); blended.clear();
eq = 0; eq = 0;
@@ -216,7 +216,7 @@ public class Floor extends Block{
} }
//'new' style of edges with shadows instead of colors, not used currently //'new' style of edges with shadows instead of colors, not used currently
protected void drawEdgesFlat(boolean sameLayer){ protected void drawEdgesFlat(Tile tile, boolean sameLayer){
for(int i = 0; i < 4; i++){ for(int i = 0; i < 4; i++){
Tile other = tile.getNearby(i); Tile other = tile.getNearby(i);
if(other != null && doEdge(other.floor(), sameLayer)){ if(other != null && doEdge(other.floor(), sameLayer)){
@@ -79,7 +79,7 @@ public class OreBlock extends OverlayFloor{
} }
@Override @Override
public String getDisplayName(){ public String getDisplayName(Tile tile){
return itemDrop.localizedName; return itemDrop.localizedName;
} }
} }
@@ -12,7 +12,7 @@ public class OverlayFloor extends Floor{
} }
@Override @Override
public void drawBase(){ public void drawBase(Tile tile){
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
} }
} }
@@ -17,7 +17,7 @@ public class Rock extends Block{
} }
@Override @Override
public void draw(){ public void drawBase(Tile tile){
if(variants > 0){ if(variants > 0){
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
}else{ }else{
@@ -13,7 +13,7 @@ public class StaticTree extends StaticWall{
} }
@Override @Override
public void drawBase(){ public void drawBase(Tile tile){
TextureRegion r = Tmp.tr1; TextureRegion r = Tmp.tr1;
r.set(region); r.set(region);
int crop = (region.getWidth() - tilesize*4) / 2; int crop = (region.getWidth() - tilesize*4) / 2;
@@ -38,6 +38,6 @@ public class StaticTree extends StaticWall{
} }
} }
} }
Draw.rect(r, x + ox * Draw.scl, y + oy * Draw.scl); Draw.rect(r, tile.drawx() + ox * Draw.scl, tile.drawy() + oy * Draw.scl);
} }
} }
@@ -22,7 +22,7 @@ public class StaticWall extends Rock{
} }
@Override @Override
public void drawBase(){ public void drawBase(Tile tile){
int rx = tile.x / 2 * 2; int rx = tile.x / 2 * 2;
int ry = tile.y / 2 * 2; int ry = tile.y / 2 * 2;
@@ -16,10 +16,10 @@ public class TreeBlock extends Block{
} }
@Override @Override
public void drawBase(){} public void drawBase(Tile tile){}
@Override @Override
public void drawLayer(){ public void drawLayer(Tile tile){
Draw.rect(region, x, y, Mathf.randomSeed(tile.pos(), 0, 4) * 90); Draw.rect(region, tile.worldx(), tile.worldy(), Mathf.randomSeed(tile.pos(), 0, 4) * 90);
} }
} }
@@ -2,7 +2,7 @@ package mindustry.world.blocks.liquid;
import arc.*; import arc.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import mindustry.entities.AllDefs.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
@@ -20,24 +20,26 @@ public class ArmoredConduit extends Conduit{
capRegion = Core.atlas.find(name + "-cap"); capRegion = Core.atlas.find(name + "-cap");
} }
@Override
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.outputsLiquid && blendsArmored(rotation, otherx, othery, otherrot, otherblock);
}
public class ArmoredConduitEntity extends TileEntity{
@Override @Override
public void draw(){ public void draw(){
super.draw(); super.draw();
// draw the cap when a conduit would normally leak // draw the cap when a conduit would normally leak
Tile next = tile.front(); Tilec next = tile.front();
if(next != null && next.team() == team && next.block().hasLiquids) return; if(next != null && next.team() == team && next.block().hasLiquids) return;
Draw.rect(capRegion, x, y, tile.rotation() * 90); Draw.rect(capRegion, x, y, tile.rotation() * 90);
} }
@Override @Override
public boolean acceptLiquid(Tile source, Liquid liquid, float amount){ public boolean acceptLiquid(Tilec source, Liquid liquid, float amount){
return super.acceptLiquid(tile, source, liquid, amount) && (source.block() instanceof Conduit) || Edges.getFacingEdge(source, tile).relativeTo(tile) == tile.rotation(); return super.acceptLiquid(source, liquid, amount) && (source.block() instanceof Conduit) || Edges.getFacingEdge(source.tile(), tile).relativeTo(tile) == tile.rotation();
} }
@Override
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.outputsLiquid && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock);
} }
} }
@@ -75,7 +75,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
@Override @Override
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){ public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock); return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(rotation, otherx, othery, otherrot, otherblock);
} }
@Override @Override
@@ -106,7 +106,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
public void onProximityUpdate(){ public void onProximityUpdate(){
super.onProximityUpdate(); super.onProximityUpdate();
blendbits = buildBlending(tile, tile.rotation(), null, true)[0]; blendbits = buildBlending(rotation(), null, true)[0];
} }
@Override @Override
@@ -1,10 +1,8 @@
package mindustry.world.blocks.liquid; package mindustry.world.blocks.liquid;
import arc.math.*; import arc.math.*;
import arc.util.*; import mindustry.gen.*;
import mindustry.entities.AllDefs.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.distribution.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
@@ -20,16 +18,17 @@ public class LiquidBridge extends ItemBridge{
group = BlockGroup.liquids; group = BlockGroup.liquids;
} }
public class LiquidBridgeEntity extends ItemBridgeEntity{
@Override @Override
public void updateTile(){ public void updateTile(){
time += cycleSpeed * Time.delta(); time += cycleSpeed * delta();
time2 += (cycleSpeed - 1f) * Time.delta(); time2 += (cycleSpeed - 1f) * delta();
Tile other = world.tile(link); Tilec other = world.ent(link);
if(!linkValid(tile, other)){ if(other == null || !linkValid(tile, other.tile())){
tryDumpLiquid(tile, liquids.current()); dumpLiquid(liquids.current());
}else{ }else{
((ItemBridgeEntity)world.tile(link).entity).incoming.add(tile.pos()); ((ItemBridgeEntity)other).incoming.add(tile.pos());
if(consValid()){ if(consValid()){
float alpha = 0.04f; float alpha = 0.04f;
@@ -43,7 +42,7 @@ public class LiquidBridge extends ItemBridge{
if(uptime >= 0.5f){ if(uptime >= 0.5f){
if(tryMoveLiquid(tile, other, false, liquids.current()) > 0.1f){ if(moveLiquid(other, false, liquids.current()) > 0.1f){
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f); cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f);
}else{ }else{
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 1f, 0.01f); cycleSpeed = Mathf.lerpDelta(cycleSpeed, 1f, 0.01f);
@@ -53,7 +52,8 @@ public class LiquidBridge extends ItemBridge{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return false; return false;
} }
} }
}
@@ -1,10 +1,8 @@
package mindustry.world.blocks.liquid; package mindustry.world.blocks.liquid;
import arc.math.*; import arc.math.*;
import arc.util.*; import mindustry.gen.*;
import mindustry.entities.AllDefs.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.distribution.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
@@ -20,16 +18,17 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{
group = BlockGroup.liquids; group = BlockGroup.liquids;
} }
public class LiquidExtendingBridgeEntity extends ItemBridgeEntity{
@Override @Override
public void updateTile(){ public void updateTile(){
time += cycleSpeed * Time.delta(); time += cycleSpeed * delta();
time2 += (cycleSpeed - 1f) * Time.delta(); time2 += (cycleSpeed - 1f) * delta();
Tile other = world.tile(link); Tilec other = world.ent(link);
if(!linkValid(tile, other)){ if(other == null || !linkValid(tile, other.tile())){
tryDumpLiquid(tile, liquids.current()); dumpLiquid(liquids.current());
}else{ }else{
((ItemBridgeEntity)world.tile(link).entity).incoming.add(tile.pos()); ((ItemBridgeEntity)other).incoming.add(tile.pos());
if(consValid()){ if(consValid()){
uptime = Mathf.lerpDelta(uptime, 1f, 0.04f); uptime = Mathf.lerpDelta(uptime, 1f, 0.04f);
@@ -38,7 +37,7 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{
} }
if(uptime >= 0.5f){ if(uptime >= 0.5f){
if(tryMoveLiquid(tile, other, false, liquids.current()) > 0.1f){ if(moveLiquid(other, false, liquids.current()) > 0.1f){
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f); cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f);
}else{ }else{
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 1f, 0.01f); cycleSpeed = Mathf.lerpDelta(cycleSpeed, 1f, 0.01f);
@@ -48,7 +47,8 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return false; return false;
} }
} }
}
@@ -2,9 +2,8 @@ package mindustry.world.blocks.liquid;
import arc.*; import arc.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import mindustry.entities.AllDefs.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
public class LiquidJunction extends LiquidBlock{ public class LiquidJunction extends LiquidBlock{
@@ -25,24 +24,28 @@ public class LiquidJunction extends LiquidBlock{
bars.remove("liquid"); bars.remove("liquid");
} }
@Override
public void draw(){
Draw.rect(name, tile.worldx(), tile.worldy());
}
@Override @Override
public TextureRegion[] generateIcons(){ public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name)}; return new TextureRegion[]{Core.atlas.find(name)};
} }
public class LiquidJunctionEntity extends TileEntity{
@Override @Override
public Tile getLiquidDestination(Tile source, Liquid liquid){ public void draw(){
Draw.rect(region, x, y);
}
@Override
public Tilec getLiquidDestination(Tilec source, Liquid liquid){
int dir = source.relativeTo(tile.x, tile.y); int dir = source.relativeTo(tile.x, tile.y);
dir = (dir + 4) % 4; dir = (dir + 4) % 4;
Tile next = tile.getNearbyLink(dir); Tilec next = nearby(dir);
if(next == null || !next.block().acceptLiquid(next, tile, liquid, 0f) && !(next.block() instanceof LiquidJunction)){ if(next == null || !next.acceptLiquid(this, liquid, 0f) && !(next.block() instanceof LiquidJunction)){
return tile; return this;
} }
return next.block().getLiquidDestination(next, tile, liquid); return next.getLiquidDestination(this, liquid);
} }
} }
}
@@ -10,7 +10,6 @@ public class LiquidRouter extends LiquidBlock{
} }
public class LiquidRouterEntity extends LiquidBlockEntity{ public class LiquidRouterEntity extends LiquidBlockEntity{
@Override @Override
public void updateTile(){ public void updateTile(){
if(liquids.total() > 0.01f){ if(liquids.total() > 0.01f){
@@ -2,7 +2,7 @@ package mindustry.world.blocks.power;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import mindustry.world.*; import mindustry.gen.*;
import static mindustry.Vars.tilesize; import static mindustry.Vars.tilesize;
@@ -18,12 +18,14 @@ public class Battery extends PowerDistributor{
consumesPower = true; consumesPower = true;
} }
public class BatteryEntity extends TileEntity{
@Override @Override
public void draw(){ public void draw(){
Draw.color(emptyLightColor, fullLightColor, tile.power.status); Draw.color(emptyLightColor, fullLightColor, power.status);
Fill.square(x, y, tilesize * size / 2f - 1); Fill.square(x, y, tilesize * size / 2f - 1);
Draw.color(); Draw.color();
Draw.rect(reg(topRegion), x, y); Draw.rect(reg(topRegion), x, y);
} }
} }
}
@@ -12,11 +12,8 @@ import mindustry.game.EventType.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import java.io.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class ImpactReactor extends PowerGenerator{ public class ImpactReactor extends PowerGenerator{
@@ -52,7 +49,7 @@ public class ImpactReactor extends PowerGenerator{
bars.add("poweroutput", entity -> new Bar(() -> bars.add("poweroutput", entity -> new Bar(() ->
Core.bundle.format("bar.poweroutput", Core.bundle.format("bar.poweroutput",
Strings.fixed(Math.max(block().getPowerProduction(tile()) - consumes.getPower().usage, 0) * 60 * timeScale(), 1)), Strings.fixed(Math.max(entity.getPowerProduction() - consumes.getPower().usage, 0) * 60 * entity.timeScale(), 1)),
() -> Pal.powerBar, () -> Pal.powerBar,
() -> ((GeneratorEntity)entity).productionEfficiency)); () -> ((GeneratorEntity)entity).productionEfficiency));
} }
@@ -66,17 +63,26 @@ public class ImpactReactor extends PowerGenerator{
} }
} }
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)};
}
public class FusionReactorEntity extends GeneratorEntity{
public float warmup;
@Override @Override
public void updateTile(){ public void updateTile(){
if(consValid() && power.status >= 0.99f){ if(consValid() && power.status >= 0.99f){
boolean prevOut = getPowerProduction(tile) <= consumes.getPower().requestedPower(entity); boolean prevOut = getPowerProduction() <= consumes.getPower().requestedPower(this);
warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed); warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed);
if(Mathf.equal(warmup, 1f, 0.001f)){ if(Mathf.equal(warmup, 1f, 0.001f)){
warmup = 1f; warmup = 1f;
} }
if(!prevOut && (getPowerProduction(tile) > consumes.getPower().requestedPower(entity))){ if(!prevOut && (getPowerProduction() > consumes.getPower().requestedPower(this))){
Events.fire(Trigger.impactPower); Events.fire(Trigger.impactPower);
} }
@@ -117,11 +123,6 @@ public class ImpactReactor extends PowerGenerator{
renderer.lights.add(x, y, (110f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(plasma2).lerp(plasma1, Mathf.absin(7f, 0.2f)), 0.8f * fract); renderer.lights.add(x, y, (110f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(plasma2).lerp(plasma1, Mathf.absin(7f, 0.2f)), 0.8f * fract);
} }
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)};
}
@Override @Override
public void onDestroyed(){ public void onDestroyed(){
super.onDestroyed(); super.onDestroyed();
@@ -130,33 +131,30 @@ public class ImpactReactor extends PowerGenerator{
Sounds.explosionbig.at(tile); Sounds.explosionbig.at(tile);
Effects.shake(6f, 16f, tile.worldx(), tile.worldy()); Effects.shake(6f, 16f, x, y);
Fx.impactShockwave.at(tile.worldx(), tile.worldy()); Fx.impactShockwave.at(x, y);
for(int i = 0; i < 6; i++){ for(int i = 0; i < 6; i++){
Time.run(Mathf.random(80), () -> Fx.impactcloud.at(tile.worldx(), tile.worldy())); Time.run(Mathf.random(80), () -> Fx.impactcloud.at(x, y));
} }
Damage.damage(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4); Damage.damage(x, y, explosionRadius * tilesize, explosionDamage * 4);
for(int i = 0; i < 20; i++){ for(int i = 0; i < 20; i++){
Time.run(Mathf.random(80), () -> { Time.run(Mathf.random(80), () -> {
Tmp.v1.rnd(Mathf.random(40f)); Tmp.v1.rnd(Mathf.random(40f));
Fx.explosion.at(Tmp.v1.x + tile.worldx(), Tmp.v1.y + tile.worldy()); Fx.explosion.at(Tmp.v1.x + x, Tmp.v1.y + y);
}); });
} }
for(int i = 0; i < 70; i++){ for(int i = 0; i < 70; i++){
Time.run(Mathf.random(90), () -> { Time.run(Mathf.random(90), () -> {
Tmp.v1.rnd(Mathf.random(120f)); Tmp.v1.rnd(Mathf.random(120f));
Fx.impactsmoke.at(Tmp.v1.x + tile.worldx(), Tmp.v1.y + tile.worldy()); Fx.impactsmoke.at(Tmp.v1.x + x, Tmp.v1.y + y);
}); });
} }
} }
public class FusionReactorEntity extends GeneratorEntity{
public float warmup;
@Override @Override
public void write(Writes write){ public void write(Writes write){
super.write(write); super.write(write);
@@ -8,7 +8,6 @@ import arc.util.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.consumers.*; import mindustry.world.consumers.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
@@ -84,6 +83,18 @@ public class ItemLiquidGenerator extends PowerGenerator{
} }
} }
protected float getItemEfficiency(Item item){
return 0.0f;
}
protected float getLiquidEfficiency(Liquid liquid){
return 0.0f;
}
public class ItemLiquidGeneratorEntity extends GeneratorEntity{
public float explosiveness;
public float heat;
@Override @Override
public boolean productionValid(){ public boolean productionValid(){
return generateTime > 0; return generateTime > 0;
@@ -125,7 +136,7 @@ public class ItemLiquidGenerator extends PowerGenerator{
}else if(hasItems){ }else if(hasItems){
// No liquids accepted or none supplied, try using items if accepted // No liquids accepted or none supplied, try using items if accepted
if(generateTime <= 0f && items.total() > 0){ if(generateTime <= 0f && items.total() > 0){
generateEffect.at(tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f)); generateEffect.at(x + Mathf.range(3f), y + Mathf.range(3f));
Item item = items.take(); Item item = items.take();
productionEfficiency = getItemEfficiency(item); productionEfficiency = getItemEfficiency(item);
explosiveness = item.explosiveness; explosiveness = item.explosiveness;
@@ -139,7 +150,7 @@ public class ItemLiquidGenerator extends PowerGenerator{
//this block is run last so that in the event of a block destruction, no code relies on the block type //this block is run last so that in the event of a block destruction, no code relies on the block type
Core.app.post(() -> { Core.app.post(() -> {
damage(Mathf.random(11f)); damage(Mathf.random(11f));
explodeEffect.at(tile.worldx() + Mathf.range(size * tilesize / 2f), tile.worldy() + Mathf.range(size * tilesize / 2f)); explodeEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f));
}); });
} }
}else{ }else{
@@ -171,17 +182,5 @@ public class ItemLiquidGenerator extends PowerGenerator{
public void drawLight(){ public void drawLight(){
renderer.lights.add(x, y, (60f + Mathf.absin(10f, 5f)) * productionEfficiency * size, Color.orange, 0.5f); renderer.lights.add(x, y, (60f + Mathf.absin(10f, 5f)) * productionEfficiency * size, Color.orange, 0.5f);
} }
protected float getItemEfficiency(Item item){
return 0.0f;
}
protected float getLiquidEfficiency(Liquid liquid){
return 0.0f;
}
public class ItemLiquidGeneratorEntity extends GeneratorEntity{
public float explosiveness;
public float heat;
} }
} }
@@ -24,9 +24,12 @@ public class LightBlock extends Block{
update = true; update = true;
topRegion = reg("-top"); topRegion = reg("-top");
configurable = true; configurable = true;
config(Integer.class, (tile, value) -> tile.<LightEntity>ent().color = value); config(Integer.class, (tile, value) -> ((LightEntity)tile).color = value);
} }
public class LightEntity extends TileEntity{
public int color = Pal.accent.rgba();
@Override @Override
public void playerPlaced(){ public void playerPlaced(){
if(lastColor != 0){ if(lastColor != 0){
@@ -57,12 +60,9 @@ public class LightBlock extends Block{
@Override @Override
public void drawLight(){ public void drawLight(){
renderer.lights.add(x, y, radius, Tmp.c1.set(color), brightness * tile.efficiency()); renderer.lights.add(x, y, radius, Tmp.c1.set(color), brightness * efficiency());
} }
public class LightEntity extends TileEntity{
public int color = Pal.accent.rgba();
@Override @Override
public Integer config(){ public Integer config(){
return color; return color;
@@ -14,12 +14,9 @@ import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.consumers.*; import mindustry.world.consumers.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import java.io.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class NuclearReactor extends PowerGenerator{ public class NuclearReactor extends PowerGenerator{
@@ -72,6 +69,9 @@ public class NuclearReactor extends PowerGenerator{
bars.add("heat", entity -> new Bar("bar.heat", Pal.lightOrange, () -> ((NuclearReactorEntity)entity).heat)); bars.add("heat", entity -> new Bar("bar.heat", Pal.lightOrange, () -> ((NuclearReactorEntity)entity).heat));
} }
public class NuclearReactorEntity extends GeneratorEntity{
public float heat;
@Override @Override
public void updateTile(){ public void updateTile(){
ConsumeLiquid cliquid = consumes.get(ConsumeType.liquid); ConsumeLiquid cliquid = consumes.get(ConsumeType.liquid);
@@ -100,8 +100,8 @@ public class NuclearReactor extends PowerGenerator{
if(heat > smokeThreshold){ if(heat > smokeThreshold){
float smoke = 1.0f + (heat - smokeThreshold) / (1f - smokeThreshold); //ranges from 1.0 to 2.0 float smoke = 1.0f + (heat - smokeThreshold) / (1f - smokeThreshold); //ranges from 1.0 to 2.0
if(Mathf.chance(smoke / 20.0 * delta())){ if(Mathf.chance(smoke / 20.0 * delta())){
Fx.reactorsmoke.at(tile.worldx() + Mathf.range(size * tilesize / 2f), Fx.reactorsmoke.at(x + Mathf.range(size * tilesize / 2f),
tile.worldy() + Mathf.random(size * tilesize / 2f)); y + Mathf.random(size * tilesize / 2f));
} }
} }
@@ -123,25 +123,25 @@ public class NuclearReactor extends PowerGenerator{
if((fuel < 5 && heat < 0.5f) || !state.rules.reactorExplosions) return; if((fuel < 5 && heat < 0.5f) || !state.rules.reactorExplosions) return;
Effects.shake(6f, 16f, tile.worldx(), tile.worldy()); Effects.shake(6f, 16f, x, y);
Fx.nuclearShockwave.at(tile.worldx(), tile.worldy()); Fx.nuclearShockwave.at(x, y);
for(int i = 0; i < 6; i++){ for(int i = 0; i < 6; i++){
Time.run(Mathf.random(40), () -> Fx.nuclearcloud.at(tile.worldx(), tile.worldy())); Time.run(Mathf.random(40), () -> Fx.nuclearcloud.at(x, y));
} }
Damage.damage(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4); Damage.damage(x, y, explosionRadius * tilesize, explosionDamage * 4);
for(int i = 0; i < 20; i++){ for(int i = 0; i < 20; i++){
Time.run(Mathf.random(50), () -> { Time.run(Mathf.random(50), () -> {
tr.rnd(Mathf.random(40f)); tr.rnd(Mathf.random(40f));
Fx.explosion.at(tr.x + tile.worldx(), tr.y + tile.worldy()); Fx.explosion.at(tr.x + x, tr.y + y);
}); });
} }
for(int i = 0; i < 70; i++){ for(int i = 0; i < 70; i++){
Time.run(Mathf.random(80), () -> { Time.run(Mathf.random(80), () -> {
tr.rnd(Mathf.random(120f)); tr.rnd(Mathf.random(120f));
Fx.nuclearsmoke.at(tr.x + tile.worldx(), tr.y + tile.worldy()); Fx.nuclearsmoke.at(tr.x + x, tr.y + y);
}); });
} }
} }
@@ -174,10 +174,6 @@ public class NuclearReactor extends PowerGenerator{
Draw.reset(); Draw.reset();
} }
public class NuclearReactorEntity extends GeneratorEntity{
public float heat;
public float flash;
@Override @Override
public void write(Writes write){ public void write(Writes write){
super.write(write); super.write(write);
@@ -3,6 +3,7 @@ package mindustry.world.blocks.power;
import arc.Core; import arc.Core;
import arc.math.Mathf; import arc.math.Mathf;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.ui.Bar; import mindustry.ui.Bar;
import arc.util.Eachable; import arc.util.Eachable;
import mindustry.ui.Cicon; import mindustry.ui.Cicon;
@@ -11,6 +12,7 @@ import mindustry.world.Block;
import arc.graphics.g2d.Draw; import arc.graphics.g2d.Draw;
import mindustry.graphics.Pal; import mindustry.graphics.Pal;
import arc.graphics.g2d.TextureRegion; import arc.graphics.g2d.TextureRegion;
import mindustry.world.meta.*;
public class PowerDiode extends Block{ public class PowerDiode extends Block{
public TextureRegion arrow; public TextureRegion arrow;
@@ -21,6 +23,46 @@ public class PowerDiode extends Block{
update = true; update = true;
solid = true; solid = true;
insulated = true; insulated = true;
group = BlockGroup.power;
}
@Override
public void setBars(){
super.setBars();
bars.add("back", entity -> new Bar("bar.input", Pal.powerBar, () -> bar(entity.back())));
bars.add("front", entity -> new Bar("bar.output", Pal.powerBar, () -> bar(entity.front())));
}
@Override
public void load(){
super.load();
arrow = Core.atlas.find(name + "-arrow");
}
@Override
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list) {
TextureRegion reg = icon(Cicon.full);
Draw.rect(icon(Cicon.full), req.drawx(), req.drawy(),
reg.getWidth() * req.animScale * Draw.scl,
reg.getHeight() * req.animScale * Draw.scl,
0);
Draw.rect(arrow, req.drawx(), req.drawy(),
arrow.getWidth() * req.animScale * Draw.scl,
arrow.getHeight() * req.animScale * Draw.scl,
!rotate ? 0 : req.rotation * 90);
}
// battery % of the graph on either side, defaults to zero
public float bar(Tilec tile){
return (tile != null && tile.block().hasPower) ? tile.power().graph.getBatteryStored() / tile.power().graph.getTotalBatteryCapacity() : 0f;
}
public class PowerDiodeEntity extends TileEntity{
@Override
public void draw(){
Draw.rect(region, x, y, 0);
Draw.rect(arrow, x, y, rotate ? tile.rotation() * 90 : 0);
} }
@Override @Override
@@ -29,8 +71,8 @@ public class PowerDiode extends Block{
if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().team() != tile.front().team()) return; if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().team() != tile.front().team()) return;
PowerGraph backGraph = tile.back().power.graph; PowerGraph backGraph = tile.back().power().graph;
PowerGraph frontGraph = tile.front().power.graph; PowerGraph frontGraph = tile.front().power().graph;
if(backGraph == frontGraph) return; if(backGraph == frontGraph) return;
// 0f - 1f of battery capacity in use // 0f - 1f of battery capacity in use
@@ -48,42 +90,5 @@ public class PowerDiode extends Block{
frontGraph.chargeBatteries(amount); frontGraph.chargeBatteries(amount);
} }
} }
// battery % of the graph on either side, defaults to zero
public float bar(){
return (tile != null && tile.block().hasPower) ? tile.power.graph.getBatteryStored() / tile.power.graph.getTotalBatteryCapacity() : 0f;
}
@Override
public void setBars(){
super.setBars();
bars.add("back", entity -> new Bar("bar.input", Pal.powerBar, () -> bar(tile().back())));
bars.add("front", entity -> new Bar("bar.output", Pal.powerBar, () -> bar(tile().front())));
}
@Override
public void load(){
super.load();
arrow = Core.atlas.find(name + "-arrow");
}
@Override
public void draw(){
Draw.rect(region, x, y, 0);
Draw.rect(arrow, x, y, rotate ? tile.rotation() * 90 : 0);
}
@Override
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list) {
TextureRegion reg = icon(Cicon.full);
Draw.rect(icon(Cicon.full), req.drawx(), req.drawy(),
reg.getWidth() * req.animScale * Draw.scl,
reg.getHeight() * req.animScale * Draw.scl,
0);
Draw.rect(arrow, req.drawx(), req.drawy(),
arrow.getWidth() * req.animScale * Draw.scl,
arrow.getHeight() * req.animScale * Draw.scl,
!rotate ? 0 : req.rotation * 90);
} }
} }
@@ -1,17 +1,14 @@
package mindustry.world.blocks.power; package mindustry.world.blocks.power;
import arc.Core; import arc.*;
import arc.struct.EnumSet; import arc.struct.*;
import arc.util.Strings; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.Pal; import mindustry.graphics.*;
import mindustry.ui.Bar; import mindustry.ui.*;
import mindustry.world.Tile;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import java.io.*;
public class PowerGenerator extends PowerDistributor{ public class PowerGenerator extends PowerDistributor{
/** The amount of power produced per tick in case of an efficiency of 1.0, which represents 100%. */ /** The amount of power produced per tick in case of an efficiency of 1.0, which represents 100%. */
public float powerProduction; public float powerProduction;
@@ -37,17 +34,12 @@ public class PowerGenerator extends PowerDistributor{
if(hasPower && outputsPower && !consumes.hasPower()){ if(hasPower && outputsPower && !consumes.hasPower()){
bars.add("power", entity -> new Bar(() -> bars.add("power", entity -> new Bar(() ->
Core.bundle.format("bar.poweroutput", Core.bundle.format("bar.poweroutput",
Strings.fixed(block().getPowerProduction(tile()) * 60 * timeScale(), 1)), Strings.fixed(entity.getPowerProduction() * 60 * entity.timeScale(), 1)),
() -> Pal.powerBar, () -> Pal.powerBar,
() -> ((GeneratorEntity)entity).productionEfficiency)); () -> ((GeneratorEntity)entity).productionEfficiency));
} }
} }
@Override
public float getPowerProduction(){
return powerProduction * tile.<GeneratorEntity>ent().productionEfficiency;
}
@Override @Override
public boolean outputsItems(){ public boolean outputsItems(){
return false; return false;
@@ -58,6 +50,11 @@ public class PowerGenerator extends PowerDistributor{
/** The efficiency of the producer. An efficiency of 1.0 means 100% */ /** The efficiency of the producer. An efficiency of 1.0 means 100% */
public float productionEfficiency = 0.0f; public float productionEfficiency = 0.0f;
@Override
public float getPowerProduction(){
return powerProduction * productionEfficiency;
}
@Override @Override
public void write(Writes write){ public void write(Writes write){
super.write(write); super.write(write);
@@ -63,8 +63,7 @@ public class PowerGraph{
public float getPowerProduced(){ public float getPowerProduced(){
float powerProduced = 0f; float powerProduced = 0f;
for(Tilec producer : producers){ for(Tilec producer : producers){
if(producer.entity == null) continue; powerProduced += producer.getPowerProduction() * producer.delta();
powerProduced += producer.block().getPowerProduction(producer) * producer.delta();
} }
return powerProduced; return powerProduced;
} }
@@ -230,7 +229,7 @@ public class PowerGraph{
} }
public void add(Tilec tile){ public void add(Tilec tile){
if(tile.entity == null || tile.power() == null) return; if(tile == null || tile.power() == null) return;
tile.power().graph = this; tile.power().graph = this;
all.add(tile); all.add(tile);
@@ -253,7 +252,7 @@ public class PowerGraph{
while(queue.size > 0){ while(queue.size > 0){
Tilec child = queue.removeFirst(); Tilec child = queue.removeFirst();
add(child); add(child);
for(Tilec next : child.block().getPowerConnections(child, outArray2)){ for(Tilec next : child.getPowerConnections(outArray2)){
if(!closedSet.contains(next.pos())){ if(!closedSet.contains(next.pos())){
queue.addLast(next); queue.addLast(next);
closedSet.add(next.pos()); closedSet.add(next.pos());
@@ -275,7 +274,7 @@ public class PowerGraph{
closedSet.clear(); closedSet.clear();
//go through all the connections of this tile //go through all the connections of this tile
for(Tilec other : tile.block().getPowerConnections(tile, outArray1)){ for(Tilec other : tile.getPowerConnections(outArray1)){
//a graph has already been assigned to this tile from a previous call, skip it //a graph has already been assigned to this tile from a previous call, skip it
if(other.power().graph != this) continue; if(other.power().graph != this) continue;
@@ -293,7 +292,7 @@ public class PowerGraph{
//add it to the new branch graph //add it to the new branch graph
graph.add(child); graph.add(child);
//go through connections //go through connections
for(Tilec next : child.block().getPowerConnections(child, outArray2)){ for(Tilec next : child.getPowerConnections(outArray2)){
//make sure it hasn't looped back, and that the new graph being assigned hasn't already been assigned //make sure it hasn't looped back, and that the new graph being assigned hasn't already been assigned
//also skip closed tiles //also skip closed tiles
if(next != tile && next.power().graph != graph && !closedSet.contains(next.pos())){ if(next != tile && next.power().graph != graph && !closedSet.contains(next.pos())){
@@ -15,6 +15,7 @@ import mindustry.graphics.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import mindustry.world.modules.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@@ -36,49 +37,49 @@ public class PowerNode extends PowerBlock{
configurable = true; configurable = true;
consumesPower = false; consumesPower = false;
outputsPower = false; outputsPower = false;
config(Integer.class, (tile, value) -> { config(Integer.class, (entity, value) -> {
Tilec entity = tile.entity; PowerModule power = entity.power();
Tile other = world.tile(value); Tilec other = world.ent(value);
boolean contains = power.links.contains(value), valid = other != null && other.entity != null && other.power != null; boolean contains = power.links.contains(value), valid = other != null && other.power() != null;
if(contains){ if(contains){
//unlink //unlink
power.links.removeValue(value); power.links.removeValue(value);
if(valid) other.power.links.removeValue(tile.pos()); if(valid) other.power().links.removeValue(entity.pos());
PowerGraph newgraph = new PowerGraph(); PowerGraph newgraph = new PowerGraph();
//reflow from this point, covering all tiles on this side //reflow from this point, covering all tiles on this side
newgraph.reflow(tile); newgraph.reflow(entity);
if(valid && other.power.graph != newgraph){ if(valid && other.power().graph != newgraph){
//create new graph for other end //create new graph for other end
PowerGraph og = new PowerGraph(); PowerGraph og = new PowerGraph();
//reflow from other end //reflow from other end
og.reflow(other); og.reflow(other);
} }
}else if(linkValid(tile, other) && valid && power.links.size < maxNodes){ }else if(linkValid(entity, other) && valid && power.links.size < maxNodes){
if(!power.links.contains(other.pos())){ if(!power.links.contains(other.pos())){
power.links.add(other.pos()); power.links.add(other.pos());
} }
if(other.getTeamID() == tile.getTeamID()){ if(other.team() == entity.team()){
if(!other.power.links.contains(tile.pos())){ if(!other.power().links.contains(entity.pos())){
other.power.links.add(tile.pos()); other.power().links.add(entity.pos());
} }
} }
power.graph.add(other.power.graph); power.graph.add(other.power().graph);
} }
}); });
config(Point2[].class, (tile, value) -> { config(Point2[].class, (tile, value) -> {
tile.power.links.clear(); tile.power().links.clear();
for(Point2 p : value){ for(Point2 p : value){
if(tile.power.links.size < maxNodes){ if(tile.power().links.size < maxNodes){
tile.power.links.add(Point2.pack(p.x + tile.x, p.y + tile.y)); tile.power().links.add(Point2.pack(p.x + tile.tileX(), p.y + tile.tileY()));
} }
} }
}); });
@@ -97,23 +98,158 @@ public class PowerNode extends PowerBlock{
super.setBars(); super.setBars();
bars.add("power", entity -> new Bar(() -> bars.add("power", entity -> new Bar(() ->
Core.bundle.format("bar.powerbalance", Core.bundle.format("bar.powerbalance",
((power.graph.getPowerBalance() >= 0 ? "+" : "") + Strings.fixed(power.graph.getPowerBalance() * 60, 1))), ((entity.power().graph.getPowerBalance() >= 0 ? "+" : "") + Strings.fixed(entity.power().graph.getPowerBalance() * 60, 1))),
() -> Pal.powerBar, () -> Pal.powerBar,
() -> Mathf.clamp(power.graph.getLastPowerProduced() / power.graph.getLastPowerNeeded()))); () -> Mathf.clamp(entity.power().graph.getLastPowerProduced() / entity.power().graph.getLastPowerNeeded())));
bars.add("batteries", entity -> new Bar(() -> bars.add("batteries", entity -> new Bar(() ->
Core.bundle.format("bar.powerstored", Core.bundle.format("bar.powerstored",
(ui.formatAmount((int)power.graph.getBatteryStored())), ui.formatAmount((int)power.graph.getTotalBatteryCapacity())), (ui.formatAmount((int)entity.power().graph.getBatteryStored())), ui.formatAmount((int)entity.power().graph.getTotalBatteryCapacity())),
() -> Pal.powerBar, () -> Pal.powerBar,
() -> Mathf.clamp(power.graph.getBatteryStored() / power.graph.getTotalBatteryCapacity()))); () -> Mathf.clamp(entity.power().graph.getBatteryStored() / entity.power().graph.getTotalBatteryCapacity())));
} }
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.powerRange, laserRange, StatUnit.blocks);
stats.add(BlockStat.powerConnections, maxNodes, StatUnit.none);
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Tile tile = world.tile(x, y);
if(tile == null) return;
Lines.stroke(1f);
Draw.color(Pal.placing);
Drawf.circles(x * tilesize + offset(), y * tilesize + offset(), laserRange * tilesize);
getPotentialLinks(tile, other -> {
Drawf.square(other.drawx(), other.drawy(), other.block().size * tilesize / 2f + 2f, Pal.place);
insulators(tile.x, tile.y, other.x, other.y, cause -> {
Drawf.square(cause.drawx(), cause.drawy(), cause.block().size * tilesize / 2f + 2f, Pal.plastanium);
});
});
Draw.reset();
}
protected void drawLaser(float x1, float y1, float x2, float y2, float satisfaction, int size1, int size2){
int opacityPercentage = Core.settings.getInt("lasersopacity");
if(opacityPercentage == 0) return;
float opacity = opacityPercentage / 100f;
float angle1 = Angles.angle(x1, y1, x2, y2);
t1.trns(angle1, size1 * tilesize / 2f - 1.5f);
t2.trns(angle1 + 180f, size2 * tilesize / 2f - 1.5f);
x1 += t1.x;
y1 += t1.y;
x2 += t2.x;
y2 += t2.y;
float fract = 1f - satisfaction;
Draw.color(Color.white, Pal.powerLight, fract * 0.86f + Mathf.absin(3f, 0.1f));
Draw.alpha(opacity);
Drawf.laser(laser, laserEnd, x1, y1, x2, y2, 0.25f);
Draw.color();
}
protected boolean overlaps(float srcx, float srcy, Tile other, float range){
return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), other.getHitbox(Tmp.r1));
}
protected boolean overlaps(Tile src, Tile other, float range){
return overlaps(src.drawx(), src.drawy(), other, range);
}
public boolean overlaps(@Nullable Tile src, @Nullable Tile other){
if(src == null || other == null) return true;
return Intersector.overlaps(Tmp.cr1.set(src.worldx() + offset(), src.worldy() + offset(), laserRange * tilesize), Tmp.r1.setSize(size * tilesize).setCenter(other.worldx() + offset(), other.worldy() + offset()));
}
protected void getPotentialLinks(Tile tile, Cons<Tilec> others){
Boolf<Tilec> valid = other -> other != null && other.tile() != tile && other.power() != null &&
((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) &&
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.team() == player.team()
&& !other.proximity().contains(tile) && !graphs.contains(other.power().graph);
tempTiles.clear();
graphs.clear();
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
Tile other = world.ltile(x, y);
if(valid.get(other) && !tempTiles.contains(other)){
tempTiles.add(other);
}
});
tempTiles.sort((a, b) -> {
int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode);
if(type != 0) return type;
return Float.compare(a.dst2(tile), b.dst2(tile));
});
tempTiles.each(valid, t -> {
graphs.add(t.power.graph);
others.get(t);
});
}
@Override
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
if(req.config instanceof Point2[]){
for(Point2 point : (Point2[])req.config){
otherReq = null;
list.each(other -> {
if((other.x == req.x + point.x && other.y == req.y + point.y) && other != req){
otherReq = other;
}
});
if(otherReq == null || otherReq.block == null) return;
drawLaser(req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), 1f, size, otherReq.block.size);
}
}
}
public static boolean insulated(Tilec tile, Tilec other){
return insulated(tile.tileX(), tile.tileY(), other.tileX(), other.tileY());
}
public static boolean insulated(int x, int y, int x2, int y2){
returnValue = false;
insulators(x, y, x2, y2, cause -> returnValue = true);
return returnValue;
}
public static void insulators(int x, int y, int x2, int y2, Cons<Tilec> iterator){
world.raycastEach(x, y, x2, y2, (wx, wy) -> {
Tilec tile = world.ent(wx, wy);
if(tile != null && tile.block().insulated){
iterator.get(tile);
}
return false;
});
}
public class PowerNodeEntity extends TileEntity{
@Override @Override
public void placed(){ public void placed(){
if(net.client()) return; if(net.client()) return;
Boolf<Tile> valid = other -> other != null && other != tile && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(tile, other) Boolf<Tilec> valid = other -> other != null && other != tile && ((!other.block().outputsPower && other.block().consumesPower) ||
&& !other.proximity().contains(tile) && other.power.graph != tile.power.graph; (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(this, other)
&& !other.proximity().contains(this) && other.power().graph != power.graph;
tempTiles.clear(); tempTiles.clear();
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> { Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
@@ -139,40 +275,6 @@ public class PowerNode extends PowerBlock{
super.placed(); super.placed();
} }
private void getPotentialLinks(Cons<Tile> others){
Boolf<Tile> valid = other -> other != null && other != tile && other.entity != null && other.power != null &&
((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) &&
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.team() == player.team()
&& !other.proximity().contains(tile) && !graphs.contains(other.power.graph);
tempTiles.clear();
graphs.clear();
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
Tile other = world.ltile(x, y);
if(valid.get(other) && !tempTiles.contains(other)){
tempTiles.add(other);
}
});
tempTiles.sort((a, b) -> {
int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode);
if(type != 0) return type;
return Float.compare(a.dst2(tile), b.dst2(tile));
});
tempTiles.each(valid, t -> {
graphs.add(t.power.graph);
others.get(t);
});
}
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.powerRange, laserRange, StatUnit.blocks);
stats.add(BlockStat.powerConnections, maxNodes, StatUnit.none);
}
@Override @Override
public void updateTile(){ public void updateTile(){
tile.power.graph.update(); tile.power.graph.update();
@@ -248,27 +350,6 @@ public class PowerNode extends PowerBlock{
Draw.reset(); Draw.reset();
} }
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Tile tile = world.tile(x, y);
if(tile == null) return;
Lines.stroke(1f);
Draw.color(Pal.placing);
Drawf.circles(x * tilesize + offset(), y * tilesize + offset(), laserRange * tilesize);
getPotentialLinks(tile, other -> {
Drawf.square(other.drawx(), other.drawy(), other.block().size * tilesize / 2f + 2f, Pal.place);
insulators(tile.x, tile.y, other.x, other.y, cause -> {
Drawf.square(cause.drawx(), cause.drawy(), cause.block().size * tilesize / 2f + 2f, Pal.plastanium);
});
});
Draw.reset();
}
@Override @Override
public void drawLayer(){ public void drawLayer(){
if(Core.settings.getInt("lasersopacity") == 0) return; if(Core.settings.getInt("lasersopacity") == 0) return;
@@ -288,24 +369,6 @@ public class PowerNode extends PowerBlock{
Draw.reset(); Draw.reset();
} }
@Override
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
if(req.config instanceof Point2[]){
for(Point2 point : (Point2[])req.config){
otherReq = null;
list.each(other -> {
if((other.x == req.x + point.x && other.y == req.y + point.y) && other != req){
otherReq = other;
}
});
if(otherReq == null || otherReq.block == null) return;
drawLaser(req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), 1f, size, otherReq.block.size);
}
}
}
protected boolean linked(Tile other){ protected boolean linked(Tile other){
return tile.power.links.contains(other.pos()); return tile.power.links.contains(other.pos());
} }
@@ -326,70 +389,10 @@ public class PowerNode extends PowerBlock{
return false; return false;
} }
protected boolean overlaps(float srcx, float srcy, Tile other, float range){
return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), other.getHitbox(Tmp.r1));
}
protected boolean overlaps(Tile src, Tile other, float range){
return overlaps(src.drawx(), src.drawy(), other, range);
}
public boolean overlaps(@Nullable Tile src, @Nullable Tile other){
if(src == null || other == null) return true;
return Intersector.overlaps(Tmp.cr1.set(src.worldx() + offset(), src.worldy() + offset(), laserRange * tilesize), Tmp.r1.setSize(size * tilesize).setCenter(other.worldx() + offset(), other.worldy() + offset()));
}
protected void drawLaser(Tile target){ protected void drawLaser(Tile target){
drawLaser(x, y, target.drawx(), target.drawy(), tile.power.graph.getSatisfaction(), size, target.block().size); drawLaser(x, y, target.drawx(), target.drawy(), power.graph.getSatisfaction(), size, target.block().size);
} }
protected void drawLaser(float x1, float y1, float x2, float y2, float satisfaction, int size1, int size2){
int opacityPercentage = Core.settings.getInt("lasersopacity");
if(opacityPercentage == 0) return;
float opacity = opacityPercentage / 100f;
float angle1 = Angles.angle(x1, y1, x2, y2);
t1.trns(angle1, size1 * tilesize / 2f - 1.5f);
t2.trns(angle1 + 180f, size2 * tilesize / 2f - 1.5f);
x1 += t1.x;
y1 += t1.y;
x2 += t2.x;
y2 += t2.y;
float fract = 1f - satisfaction;
Draw.color(Color.white, Pal.powerLight, fract * 0.86f + Mathf.absin(3f, 0.1f));
Draw.alpha(opacity);
Drawf.laser(laser, laserEnd, x1, y1, x2, y2, 0.25f);
Draw.color();
}
public static boolean insulated(Tilec tile, Tilec other){
return insulated(tile.tileX(), tile.tileY(), other.tileX(), other.tileY());
}
public static boolean insulated(int x, int y, int x2, int y2){
returnValue = false;
insulators(x, y, x2, y2, cause -> returnValue = true);
return returnValue;
}
public static void insulators(int x, int y, int x2, int y2, Cons<Tile> iterator){
world.raycastEach(x, y, x2, y2, (wx, wy) -> {
Tile tile = world.ltile(wx, wy);
if(tile != null && tile.block() != null && tile.block().insulated){
iterator.get(tile);
}
return false;
});
}
public class PowerNodeEntity extends TileEntity{
@Override @Override
public Point2[] config(){ public Point2[] config(){
Point2[] out = new Point2[power.links.size]; Point2[] out = new Point2[power.links.size];
@@ -1,7 +1,6 @@
package mindustry.world.blocks.power; package mindustry.world.blocks.power;
import arc.struct.*; import arc.struct.*;
import mindustry.world.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static mindustry.Vars.state; import static mindustry.Vars.state;
@@ -10,20 +9,21 @@ public class SolarGenerator extends PowerGenerator{
public SolarGenerator(String name){ public SolarGenerator(String name){
super(name); super(name);
// Remove the BlockFlag.producer flag to make this a lower priority target than other generators. //remove the BlockFlag.producer flag to make this a lower priority target than other generators.
flags = EnumSet.of(); flags = EnumSet.of();
} }
@Override
public void updateTile(){
tile.<GeneratorEntity>ent().productionEfficiency = state.rules.solarPowerMultiplier < 0 ? (state.rules.lighting ? 1f - state.rules.ambientLight.a : 1f) : state.rules.solarPowerMultiplier;
}
@Override @Override
public void setStats(){ public void setStats(){
super.setStats(); super.setStats();
// Solar Generators don't really have an efficiency (yet), so for them 100% = 1.0f
stats.remove(generationType); stats.remove(generationType);
stats.add(generationType, powerProduction * 60.0f, StatUnit.powerSecond); stats.add(generationType, powerProduction * 60.0f, StatUnit.powerSecond);
} }
public class SolarGeneratorEntity extends GeneratorEntity{
@Override
public void updateTile(){
productionEfficiency = state.rules.solarPowerMultiplier < 0 ? (state.rules.lighting ? 1f - state.rules.ambientLight.a : 1f) : state.rules.solarPowerMultiplier;
}
}
} }
@@ -5,7 +5,6 @@ import arc.graphics.*;
import arc.math.*; import arc.math.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.Effects.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
@@ -26,6 +25,18 @@ public class ThermalGenerator extends PowerGenerator{
stats.add(BlockStat.tiles, attribute); stats.add(BlockStat.tiles, attribute);
} }
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
drawPlaceText(Core.bundle.formatFloat("bar.efficiency", sumAttribute(attribute, x, y) * 100, 1), x, y, valid);
}
@Override
public boolean canPlaceOn(Tile tile){
//make sure there's heat at this location
return tile.getLinkedTilesAs(this, tempTiles).sumf(other -> other.floor().attributes.get(attribute)) > 0.01f;
}
public class ThermalGeneratorEntity extends GeneratorEntity{
@Override @Override
public void updateTile(){ public void updateTile(){
if(productionEfficiency > 0.1f && Mathf.chance(0.05 * delta())){ if(productionEfficiency > 0.1f && Mathf.chance(0.05 * delta())){
@@ -33,11 +44,6 @@ public class ThermalGenerator extends PowerGenerator{
} }
} }
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
drawPlaceText(Core.bundle.formatFloat("bar.efficiency", sumAttribute(attribute, x, y) * 100, 1), x, y, valid);
}
@Override @Override
public void drawLight(){ public void drawLight(){
renderer.lights.add(x, y, (40f + Mathf.absin(10f, 5f)) * productionEfficiency * size, Color.scarlet, 0.4f); renderer.lights.add(x, y, (40f + Mathf.absin(10f, 5f)) * productionEfficiency * size, Color.scarlet, 0.4f);
@@ -54,12 +60,7 @@ public class ThermalGenerator extends PowerGenerator{
public float getPowerProduction(){ public float getPowerProduction(){
//in this case, productionEfficiency means 'total heat' //in this case, productionEfficiency means 'total heat'
//thus, it may be greater than 1.0 //thus, it may be greater than 1.0
return powerProduction * tile.<GeneratorEntity>ent().productionEfficiency; return powerProduction * productionEfficiency;
} }
@Override
public boolean canPlaceOn(){
//make sure there's heat at this location
return tile.getLinkedTilesAs(this, tempTiles).sumf(other -> other.floor().attributes.get(attribute)) > 0.01f;
} }
} }
@@ -6,7 +6,6 @@ import arc.math.*;
import arc.util.*; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.AllDefs.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
@@ -54,14 +54,14 @@ public class Incinerator extends Block{
} }
@Override @Override
public void handleItem(Tile source, Item item){ public void handleItem(Tilec source, Item item){
if(Mathf.chance(0.3)){ if(Mathf.chance(0.3)){
effect.at(x, y); effect.at(x, y);
} }
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return heat > 0.5f; return heat > 0.5f;
} }
@@ -24,15 +24,8 @@ public class ItemSource extends Block{
solid = true; solid = true;
group = BlockGroup.transportation; group = BlockGroup.transportation;
configurable = true; configurable = true;
config(Item.class, (tile, item) -> tile.<ItemSourceEntity>ent().outputItem = item); config(Item.class, (tile, item) -> ((ItemSourceEntity)tile).outputItem = item);
configClear(tile -> tile.<ItemSourceEntity>ent().outputItem = null); configClear(tile -> ((ItemSourceEntity)tile).outputItem = null);
}
@Override
public void playerPlaced(){
if(lastItem != null){
Core.app.post(() -> tile.configure(lastItem));
}
} }
@Override @Override
@@ -51,6 +44,16 @@ public class ItemSource extends Block{
return true; return true;
} }
public class ItemSourceEntity extends TileEntity{
Item outputItem;
@Override
public void playerPlaced(){
if(lastItem != null){
Core.app.post(() -> tile.configure(lastItem));
}
}
@Override @Override
public void draw(){ public void draw(){
super.draw(); super.draw();
@@ -58,7 +61,7 @@ public class ItemSource extends Block{
if(outputItem == null) return; if(outputItem == null) return;
Draw.color(outputItem.color); Draw.color(outputItem.color);
Draw.rect("center", tile.worldx(), tile.worldy()); Draw.rect("center", x, y);
Draw.color(); Draw.color();
} }
@@ -67,7 +70,7 @@ public class ItemSource extends Block{
if(outputItem == null) return; if(outputItem == null) return;
items.set(outputItem, 1); items.set(outputItem, 1);
tryDump(tile, outputItem); dump(outputItem);
items.set(outputItem, 0); items.set(outputItem, 0);
} }
@@ -77,13 +80,10 @@ public class ItemSource extends Block{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return false; return false;
} }
public class ItemSourceEntity extends TileEntity{
Item outputItem;
@Override @Override
public Item config(){ public Item config(){
return outputItem; return outputItem;
@@ -1,8 +1,8 @@
package mindustry.world.blocks.sandbox; package mindustry.world.blocks.sandbox;
import mindustry.type.Item; import mindustry.gen.*;
import mindustry.world.Block; import mindustry.type.*;
import mindustry.world.Tile; import mindustry.world.*;
public class ItemVoid extends Block{ public class ItemVoid extends Block{
@@ -11,12 +11,13 @@ public class ItemVoid extends Block{
update = solid = true; update = solid = true;
} }
public class ItemVoidEntity extends TileEntity{
@Override @Override
public void handleItem(Tile source, Item item){ public void handleItem(Tilec source, Item item){}
}
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return true; return true;
} }
} }
}
@@ -26,15 +26,8 @@ public class LiquidSource extends Block{
liquidCapacity = 100f; liquidCapacity = 100f;
configurable = true; configurable = true;
outputsLiquid = true; outputsLiquid = true;
config(Liquid.class, (tile, l) -> tile.<LiquidSourceEntity>ent().source = l); config(Liquid.class, (tile, l) -> ((LiquidSourceEntity)tile).source = l);
configClear(tile -> tile.<LiquidSourceEntity>ent().source = null); configClear(tile -> ((LiquidSourceEntity)tile).source = null);
}
@Override
public void playerPlaced(){
if(lastLiquid != null){
Core.app.post(() -> tile.configure(lastLiquid));
}
} }
@Override @Override
@@ -44,28 +37,31 @@ public class LiquidSource extends Block{
bars.remove("liquid"); bars.remove("liquid");
} }
@Override
public void updateTile(){
if(source == null){
tile.liquids.clear();
}else{
tile.liquids.add(source, liquidCapacity);
tryDumpLiquid(tile, source);
}
}
@Override @Override
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){ public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
drawRequestConfigCenter(req, (Content)req.config, "center"); drawRequestConfigCenter(req, (Content)req.config, "center");
} }
class LiquidSourceEntity extends TileEntity{
public @Nullable Liquid source = null;
@Override
public void updateTile(){
if(source == null){
liquids.clear();
}else{
liquids.add(source, liquidCapacity);
dumpLiquid(source);
}
}
@Override @Override
public void draw(){ public void draw(){
super.draw(); super.draw();
if(source != null){ if(source != null){
Draw.color(source.color); Draw.color(source.color);
Draw.rect("center", tile.worldx(), tile.worldy()); Draw.rect("center", x, y);
Draw.color(); Draw.color();
} }
} }
@@ -75,8 +71,12 @@ public class LiquidSource extends Block{
ItemSelection.buildTable(table, content.liquids(), () -> source, liquid -> tile.configure(lastLiquid = liquid)); ItemSelection.buildTable(table, content.liquids(), () -> source, liquid -> tile.configure(lastLiquid = liquid));
} }
class LiquidSourceEntity extends TileEntity{ @Override
public @Nullable Liquid source = null; public void playerPlaced(){
if(lastLiquid != null){
Core.app.post(() -> tile.configure(lastLiquid));
}
}
@Override @Override
public Liquid config(){ public Liquid config(){
@@ -1,5 +1,6 @@
package mindustry.world.blocks.sandbox; package mindustry.world.blocks.sandbox;
import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
@@ -18,12 +19,15 @@ public class LiquidVoid extends Block{
bars.remove("liquid"); bars.remove("liquid");
} }
public class LiquidVoidEntity extends TileEntity{
@Override @Override
public boolean acceptLiquid(Tile source, Liquid liquid, float amount){ public boolean acceptLiquid(Tilec source, Liquid liquid, float amount){
return true; return true;
} }
@Override @Override
public void handleLiquid(Tile source, Liquid liquid, float amount){} public void handleLiquid(Tilec source, Liquid liquid, float amount){
}
}
} }
@@ -1,7 +1,6 @@
package mindustry.world.blocks.sandbox; package mindustry.world.blocks.sandbox;
import mindustry.world.Tile; import mindustry.world.blocks.power.*;
import mindustry.world.blocks.power.PowerNode;
public class PowerSource extends PowerNode{ public class PowerSource extends PowerNode{
@@ -12,9 +11,11 @@ public class PowerSource extends PowerNode{
consumesPower = false; consumesPower = false;
} }
public class PowerSourceEntity extends PowerNodeEntity{
@Override @Override
public float getPowerProduction(){ public float getPowerProduction(){
return 10000f; return 10000f;
} }
}
} }
@@ -35,11 +35,11 @@ public class CoreBlock extends StorageBlock{
} }
@Remote(called = Loc.server) @Remote(called = Loc.server)
public static void onUnitRespawn(Playerc player){ public static void onUnitRespawn(Tilec tile, Playerc player){
if(player == null || tile.entity == null) return; if(player == null || tile == null) return;
//TODO really fix //TODO really fix
Fx.spawn.at(entity); Fx.spawn.at(tile);
//progress = 0; //progress = 0;
//spawnPlayer = player; //spawnPlayer = player;
//TODO fix //TODO fix
@@ -60,14 +60,26 @@ public class CoreBlock extends StorageBlock{
)); ));
} }
@Override
public boolean canBreak(Tile tile){
return false;
}
public class CoreEntity extends TileEntity{
// protected Playerc spawnPlayer;
//protected float progress;
protected float time;
protected float heat;
protected int storageCapacity;
@Override @Override
public void drawLight(){ public void drawLight(){
renderer.lights.add(x, y, 30f * size, Pal.accent, 0.5f + Mathf.absin(20f, 0.1f)); renderer.lights.add(x, y, 30f * size, Pal.accent, 0.5f + Mathf.absin(20f, 0.1f));
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return tile.items.get(item) < getMaximumAccepted(tile, item); return items.get(item) < getMaximumAccepted(item);
} }
@Override @Override
@@ -82,12 +94,12 @@ public class CoreBlock extends StorageBlock{
items(other.items()); items(other.items());
} }
} }
state.teams.registerCore(entity); state.teams.registerCore(this);
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0); storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
proximity().each(this::isContainer, t -> { proximity.each(this::isContainer, t -> {
t.items(items); t.items(items);
t.<StorageBlockEntity>ent().linkedCore = tile; ((StorageBlockEntity)t).linkedCore = tile;
}); });
for(Tilec other : state.teams.cores(team)){ for(Tilec other : state.teams.cores(team)){
@@ -109,23 +121,23 @@ public class CoreBlock extends StorageBlock{
@Override @Override
public void drawSelect(){ public void drawSelect(){
Lines.stroke(1f, Pal.accent); Lines.stroke(1f, Pal.accent);
Cons<Tile> outline = t -> { Cons<Tilec> outline = t -> {
for(int i = 0; i < 4; i++){ for(int i = 0; i < 4; i++){
Point2 p = Geometry.d8edge[i]; Point2 p = Geometry.d8edge[i];
float offset = -Math.max(t.block().size - 1, 0) / 2f * tilesize; float offset = -Math.max(t.block().size - 1, 0) / 2f * tilesize;
Draw.rect("block-select", t.drawx() + offset * p.x, t.drawy() + offset * p.y, i * 90); Draw.rect("block-select", t.x() + offset * p.x, t.y() + offset * p.y, i * 90);
} }
}; };
if(tile.proximity().contains(e -> isContainer(e) && e.items == tile.items)){ if(proximity.contains(e -> isContainer(e) && e.items() == items)){
outline.get(tile); outline.get(this);
} }
tile.proximity().each(e -> isContainer(e) && e.items == tile.items, outline); proximity.each(e -> isContainer(e) && e.items() == items, outline);
Draw.reset(); Draw.reset();
} }
public boolean isContainer(){ public boolean isContainer(Tilec tile){
return tile.entity instanceof StorageBlockEntity; return tile instanceof StorageBlockEntity;
} }
@Override @Override
@@ -137,40 +149,35 @@ public class CoreBlock extends StorageBlock{
} }
@Override @Override
public boolean canBreak(){ public void onRemoved(){
return false; int total = proximity.count(e -> e.items() != null && e.items() == items);
}
@Override
public void removed(){
int total = tile.proximity().count(e -> e.entity != null && e.items != null && e.items == tile.items);
float fract = 1f / total / state.teams.cores(team).size; float fract = 1f / total / state.teams.cores(team).size;
tile.proximity().each(e -> isContainer(e) && e.items == tile.items, t -> { proximity.each(e -> isContainer(e) && e.items() == items, t -> {
StorageBlockEntity ent = (StorageBlockEntity)t.entity; StorageBlockEntity ent = (StorageBlockEntity)t;
ent.linkedCore = null; ent.linkedCore = null;
ent.items(new ItemModule()); ent.items(new ItemModule());
for(Item item : content.items()){ for(Item item : content.items()){
ent.items().set(item, (int)(fract * tile.items.get(item))); ent.items().set(item, (int)(fract * items.get(item)));
} }
}); });
state.teams.unregisterCore(entity); state.teams.unregisterCore(this);
int max = itemCapacity * state.teams.cores(team).size; int max = itemCapacity * state.teams.cores(team).size;
for(Item item : content.items()){ for(Item item : content.items()){
tile.items.set(item, Math.min(tile.items.get(item), max)); items.set(item, Math.min(items.get(item), max));
} }
for(CoreEntity other : state.teams.cores(team)){ for(CoreEntity other : state.teams.cores(team)){
other.block().onProximityUpdate(other.tile()); other.onProximityUpdate();
} }
} }
@Override @Override
public void placed(){ public void placed(){
super.placed(); super.placed();
state.teams.registerCore(entity); state.teams.registerCore(this);
} }
@Override @Override
@@ -182,9 +189,9 @@ public class CoreBlock extends StorageBlock{
} }
@Override @Override
public void handleItem(Tile source, Item item){ public void handleItem(Tilec source, Item item){
if(net.server() || !net.active()){ if(net.server() || !net.active()){
super.handleItem(tile, source, item); super.handleItem(source, item);
if(state.rules.tutorial){ if(state.rules.tutorial){
Events.fire(new CoreItemDeliverEvent()); Events.fire(new CoreItemDeliverEvent());
} }
@@ -216,14 +223,8 @@ public class CoreBlock extends StorageBlock{
@Override @Override
public boolean shouldActiveSound(){ public boolean shouldActiveSound(){
return spawnPlayer != null; //TODO
return false;//spawnPlayer != null;
} }
public class CoreEntity extends TileEntity{
// protected Playerc spawnPlayer;
//protected float progress;
protected float time;
protected float heat;
protected int storageCapacity;
} }
} }
@@ -38,7 +38,7 @@ public class LaunchPad extends StorageBlock{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return item.type == ItemType.material && tile.items.total() < itemCapacity; return item.type == ItemType.material && tile.items.total() < itemCapacity;
} }
@@ -14,8 +14,8 @@ public abstract class StorageBlock extends Block{
} }
@Override @Override
public boolean acceptItem(Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return linkedCore != null ? linkedCore.block().acceptItem(linkedCore, source, item) : tile.items.get(item) < getMaximumAccepted(tile, item); return linkedCore != null ? linkedCore.acceptItem(linkedCore, source, item) : tile.items.get(item) < getMaximumAccepted(tile, item);
} }
@Override @Override
@@ -110,7 +110,7 @@ public class Unloader extends Block{
super.draw(); super.draw();
Draw.color(sortItem == null ? Color.clear : sortItem.color); Draw.color(sortItem == null ? Color.clear : sortItem.color);
Draw.rect("unloader-center", tile.worldx(), tile.worldy()); Draw.rect("unloader-center", x, y);
Draw.color(); Draw.color();
} }