Many internal changes

This commit is contained in:
Anuken 2020-03-04 13:32:31 -05:00
parent aeae286273
commit cf31293d7b
30 changed files with 286 additions and 293 deletions

View File

@ -216,7 +216,7 @@ public class Pathfinder implements Runnable{
//add targets
for(int i = 0; i < path.targets.size; i++){
int pos = path.targets.get(i);
int tx = Pos.x(pos), ty = Pos.y(pos);
int tx = Point2.x(pos), ty = Point2.y(pos);
path.weights[tx][ty] = 0;
path.searches[tx][ty] = (short)path.search;
@ -253,7 +253,7 @@ public class Pathfinder implements Runnable{
//add targets
for(int i = 0; i < path.targets.size; i++){
int pos = path.targets.get(i);
path.weights[Pos.x(pos)][Pos.y(pos)] = 0;
path.weights[Point2.x(pos)][Point2.y(pos)] = 0;
path.frontier.addFirst(pos);
}
@ -283,7 +283,7 @@ public class Pathfinder implements Runnable{
if(other != null && (path.weights[dx][dy] > cost + other.cost || path.searches[dx][dy] < path.search) && passable(dx, dy, path.team)){
if(other.cost < 0) throw new IllegalArgumentException("Tile cost cannot be negative! " + other);
path.frontier.addFirst(Pos.get(dx, dy));
path.frontier.addFirst(Point2.pack(dx, dy));
path.weights[dx][dy] = cost + other.cost;
path.searches[dx][dy] = (short)path.search;
}

View File

@ -86,7 +86,7 @@ public class World{
public @Nullable
Tile tile(int pos){
return tiles == null ? null : tile(Pos.x(pos), Pos.y(pos));
return tiles == null ? null : tile(Point2.x(pos), Point2.y(pos));
}
public @Nullable Tile tile(int x, int y){
@ -396,8 +396,8 @@ public class World{
for(int i = 0; i < multiblocks.size; i++){
int pos = multiblocks.get(i);
int x = Pos.x(pos);
int y = Pos.y(pos);
int x = Point2.x(pos);
int y = Point2.y(pos);
Tile tile = tiles.getn(x, y);
Block result = tile.block();

View File

@ -164,13 +164,13 @@ public enum EditorTool{
int x1;
stack.clear();
stack.add(Pos.get(x, y));
stack.add(Point2.pack(x, y));
try{
while(stack.size > 0 && stack.size < width*height){
int popped = stack.pop();
x = Pos.x(popped);
y = Pos.y(popped);
x = Point2.x(popped);
y = Point2.y(popped);
x1 = x;
while(x1 >= 0 && tester.get(editor.tile(x1, y))) x1--;
@ -180,14 +180,14 @@ public enum EditorTool{
filler.get(editor.tile(x1, y));
if(!spanAbove && y > 0 && tester.get(editor.tile(x1, y - 1))){
stack.add(Pos.get(x1, y - 1));
stack.add(Point2.pack(x1, y - 1));
spanAbove = true;
}else if(spanAbove && !tester.get(editor.tile(x1, y - 1))){
spanAbove = false;
}
if(!spanBelow && y < height - 1 && tester.get(editor.tile(x1, y + 1))){
stack.add(Pos.get(x1, y + 1));
stack.add(Point2.pack(x1, y + 1));
spanBelow = true;
}else if(spanBelow && y < height - 1 && !tester.get(editor.tile(x1, y + 1))){
spanBelow = false;

View File

@ -1,6 +1,7 @@
package mindustry.entities;
import arc.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
@ -34,14 +35,14 @@ public class Fires{
}
public static Firec get(int x, int y){
return map.get(Pos.get(x, y));
return map.get(Point2.pack(x, y));
}
public static boolean has(int x, int y){
if(!Structs.inBounds(x, y, world.width(), world.height()) || !map.containsKey(Pos.get(x, y))){
if(!Structs.inBounds(x, y, world.width(), world.height()) || !map.containsKey(Point2.pack(x, y))){
return false;
}
Firec fire = map.get(Pos.get(x, y));
Firec fire = map.get(Point2.pack(x, y));
return fire.isAdded() && fire.fin() < 1f && fire.tile() != null && fire.tile().x == x && fire.tile().y == y;
}

View File

@ -233,15 +233,12 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
}
/** Tile configuration. Defaults to null. Used for block rebuilding. */
@Nullable
@Override
public Object config(){
return null;
}
/** Sets the config object and casts it. Does nothing by default. */
public void setConfig(Object config){
}
@Override
public void remove(){
if(sound != null){

View File

@ -1,5 +1,6 @@
package mindustry.entities.units;
import arc.func.*;
import arc.math.geom.*;
import arc.util.ArcAnnotate.*;
import mindustry.world.*;
@ -51,6 +52,28 @@ public class BuildRequest{
}
public static Object pointConfig(Object config, Cons<Point2> cons){
if(config instanceof Point2){
config = ((Point2)config).cpy();
cons.get((Point2)config);
}else if(config instanceof Point2[]){
Point2[] result = new Point2[((Point2[])config).length];
int i = 0;
for(Point2 p : (Point2[])config){
result[i] = p.cpy();
cons.get(result[i++]);
}
config = result;
}
return config;
}
/** If this requests's config is a Point2 or an array of Point2s, this returns a copy of them for transformation.
* Otherwise does nothing. */
public void pointConfig(Cons<Point2> cons){
this.config = pointConfig(this.config, cons);
}
public BuildRequest copy(){
BuildRequest copy = new BuildRequest();
copy.x = x;

View File

@ -2,20 +2,20 @@ package mindustry.game;
import arc.*;
import arc.assets.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.files.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.*;
import arc.util.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import arc.util.io.*;
import arc.util.io.Streams.*;
import arc.util.serialization.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.ctype.ContentType;
import mindustry.ctype.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.Schematic.*;
@ -24,8 +24,12 @@ import mindustry.input.Placement.*;
import mindustry.io.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.distribution.*;
import mindustry.world.blocks.power.*;
import mindustry.world.blocks.production.*;
import mindustry.world.blocks.sandbox.*;
import mindustry.world.blocks.storage.*;
import mindustry.world.blocks.units.*;
import java.io.*;
import java.util.zip.*;
@ -127,7 +131,7 @@ public class Schematics implements Loadable{
}
return s;
}catch(IOException e){
}catch(Throwable e){
Log.err(e);
}
return null;
@ -261,11 +265,9 @@ public class Schematics implements Loadable{
tile.set(st.block, state.rules.defaultTeam);
tile.rotation(st.rotation);
if(st.config instanceof Point2){
tile.configureAny(Pos.get(tile.x - st.x + ((Point2)st.config).x, tile.y - st.y + ((Point2)st.config).y));
}else{
tile.configureAny(st.config);
}
Object config = BuildRequest.pointConfig(st.config, point -> point.add(tile.x - st.x, tile.y - st.y));
tile.configureAny(config);
if(st.block instanceof Drill){
tile.getLinkedTiles(t -> t.setOverlay(Blocks.oreCopper));
@ -348,10 +350,7 @@ public class Schematics implements Loadable{
if(tile != null && tile.entity != null && !counted.contains(tile.pos()) && !(tile.block() instanceof BuildBlock)
&& (tile.entity.block().isVisible() || (tile.entity.block() instanceof CoreBlock && Core.settings.getBool("coreselect")))){
Object config = tile.entity.config();
if(config instanceof Point2){
config = Pos.get(((Point2)config).x + offsetX, ((Point2)config).y + offsetY);
}
Object config = BuildRequest.pointConfig(tile.entity.config(), point -> point.add(offsetX, offsetY));
tiles.add(new Stile(tile.block(), tile.x + offsetX, tile.y + offsetY, config, tile.rotation()));
counted.add(tile.pos());
@ -423,10 +422,10 @@ public class Schematics implements Loadable{
for(int i = 0; i < total; i++){
Block block = blocks.get(stream.readByte());
int position = stream.readInt();
Object config = ver == 0 ? stream.readInt() : TypeIO.readObject(Reads.get(stream));
Object config = ver == 0 ? mapConfig(block, stream.readInt()) : TypeIO.readObject(Reads.get(stream));
byte rotation = stream.readByte();
if(block != Blocks.air){
tiles.add(new Stile(block, Pos.x(position), Pos.y(position), config, rotation));
tiles.add(new Stile(block, Point2.x(position), Point2.y(position), config, rotation));
}
}
@ -466,12 +465,22 @@ public class Schematics implements Loadable{
//write each tile
for(Stile tile : schematic.tiles){
stream.writeByte(blocks.orderedItems().indexOf(tile.block));
stream.writeInt(Pos.get(tile.x, tile.y));
stream.writeInt(Point2.pack((int)tile.x, (int)tile.y));
TypeIO.writeObject(Writes.get(stream), tile.config);
stream.writeByte(tile.rotation);
}
}
}
/** Maps legacy int configs to new config objects. */
private static Object mapConfig(Block block, int value){
if(block instanceof Sorter || block instanceof Unloader || block instanceof ItemSource) return content.item(value);
if(block instanceof MassDriver || block instanceof ItemBridge) return Point2.unpack(value);
if(block instanceof LiquidSource) return content.liquid(value);
if(block instanceof LightBlock || block instanceof CommandCenter) return value;
return null;
}
//endregion
}

View File

@ -4,6 +4,7 @@ import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.struct.IntSet.*;
import arc.util.*;
@ -32,7 +33,7 @@ public class FloorRenderer implements Disposable{
/**Queues up a cache change for a tile. Only runs in render loop. */
public void recacheTile(Tile tile){
recacheSet.add(Pos.get(tile.x / chunksize, tile.y / chunksize));
recacheSet.add(Point2.pack(tile.x / chunksize, tile.y / chunksize));
}
public void drawFloor(){
@ -106,7 +107,7 @@ public class FloorRenderer implements Disposable{
IntSetIterator iterator = recacheSet.iterator();
while(iterator.hasNext){
int chunk = iterator.next();
cacheChunk(Pos.x(chunk), Pos.y(chunk));
cacheChunk(Point2.x(chunk), Point2.y(chunk));
}
recacheSet.clear();

View File

@ -264,9 +264,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
int ox = schemOriginX(), oy = schemOriginY();
requests.each(req -> {
//rotate config position
if(req.config instanceof Point2){
int cx = ((Point2)req.config).x - req.originalX, cy = ((Point2)req.config).y - req.originalY;
req.pointConfig(p -> {
int cx = p.x - req.originalX, cy = p.y - req.originalY;
int lx = cx;
if(direction >= 0){
@ -276,8 +275,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
cx = cy;
cy = -lx;
}
req.config = new Point2(cx + req.originalX, cy + req.originalY);
}
p.set(cx + req.originalX, cy + req.originalY);
});
//rotate actual request, centered on its multiblock position
float wx = (req.x - ox) * tilesize + req.block.offset(), wy = (req.y - oy) * tilesize + req.block.offset();
@ -307,17 +306,17 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
req.y = (int)((value - req.block.offset()) / tilesize);
}
if(req.config instanceof Point2){
req.pointConfig(p -> {
int corigin = x ? req.originalWidth/2 : req.originalHeight/2;
int nvalue = -((x ? ((Point2)req.config).x : ((Point2)req.config).y) - corigin) + corigin;
int nvalue = -((x ? p.x : p.y) - corigin) + corigin;
if(x){
req.originalX = -(req.originalX - corigin) + corigin;
req.config = Pos.get(nvalue, ((Point2)req.config).y);
p.x = nvalue;
}else{
req.originalY = -(req.originalY - corigin) + corigin;
req.config = Pos.get(((Point2)req.config).x, nvalue);
p.y = nvalue;
}
}
});
//flip rotation
if(x == (req.rotation % 2 == 0)){
@ -450,9 +449,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
for(BuildRequest req : requests){
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
BuildRequest copy = req.copy();
if(copy.hasConfig && copy.config instanceof Point2){
copy.config = Pos.get(((Point2)copy.config).x + copy.x - copy.originalX, ((Point2)copy.config).x + copy.y - copy.originalY);
}
copy.pointConfig(p -> p.add(copy.x - copy.originalX, copy.y - copy.originalY));
player.builder().addBuild(copy);
}
}

View File

@ -222,9 +222,7 @@ public class MobileInput extends InputHandler implements GestureListener{
BuildRequest other = getRequest(request.x, request.y, request.block.size, null);
BuildRequest copy = request.copy();
if(copy.hasConfig && copy.config instanceof Point2){
copy.config = Pos.get(((Point2)copy.config).x + copy.x - copy.originalX, ((Point2)copy.config).y + copy.y - copy.originalY);
}
copy.pointConfig(p -> p.add(copy.x - copy.originalX, copy.y - copy.originalY));
if(other == null){
player.builder().addBuild(copy);

View File

@ -107,7 +107,7 @@ public class Placement{
found = true;
break;
}
closed.add(Pos.get(next.x, next.y));
closed.add(Point2.pack((int)next.x, (int)next.y));
for(Point2 point : Geometry.d4){
int newx = next.x + point.x, newy = next.y + point.y;
Tile child = world.tile(newx, newy);
@ -129,11 +129,11 @@ public class Placement{
Tile current = end;
while(current != start && total++ < nodeLimit){
if(current == null) return false;
int newPos = parents.get(current.pos(), Pos.invalid);
int newPos = parents.get(current.pos(), -1);
if(newPos == Pos.invalid) return false;
if(newPos == -1) return false;
points.add(Pools.obtain(Point2.class, Point2::new).set(Pos.x(newPos), Pos.y(newPos)));
points.add(Pools.obtain(Point2.class, Point2::new).set(Point2.x(newPos), Point2.y(newPos)));
current = world.tile(newPos);
}

View File

@ -25,6 +25,8 @@ import static mindustry.Vars.*;
@TypeIOHandler
public class TypeIO{
//TODO read/write enums like commands!
public static void writeObject(Writes write, Object object){
if(object == null){
write.b((byte)0);
@ -57,6 +59,12 @@ public class TypeIO{
write.b((byte)7);
write.i(((Point2)object).x);
write.i(((Point2)object).y);
}else if(object instanceof Point2[]){
write.b((byte)8);
write.b(((Point2[])object).length);
for(int i = 0; i < ((Point2[])object).length; i++){
write.i(((Point2[])object)[i].pack());
}
}else{
throw new IllegalArgumentException("Unknown object type: " + object.getClass());
}
@ -73,6 +81,7 @@ public class TypeIO{
case 5: return content.getByID(ContentType.all[read.b()], read.s());
case 6: short length = read.s(); IntArray arr = new IntArray(); for(int i = 0; i < length; i ++) arr.add(read.i()); return arr;
case 7: return new Point2(read.i(), read.i());
case 8: byte len = read.b(); Point2[] out = new Point2[len]; for(int i = 0; i < len; i ++) out[i] = Point2.unpack(read.i()); return out;
default: throw new IllegalArgumentException("Unknown object type: " + type);
}
}
@ -86,7 +95,7 @@ public class TypeIO{
}
public static void writeTile(Writes write, Tile tile){
write.i(tile == null ? Pos.get(-1, -1) : tile.pos());
write.i(tile == null ? Point2.pack(-1, -1) : tile.pos());
}
public static Tile readTile(Reads read){
@ -105,7 +114,7 @@ public class TypeIO{
write.s((short)requests.length);
for(BuildRequest request : requests){
write.b(request.breaking ? (byte)1 : 0);
write.i(Pos.get(request.x, request.y));
write.i(Point2.pack(request.x, request.y));
if(!request.breaking){
write.s(request.block.id);
write.b((byte)request.rotation);
@ -128,13 +137,13 @@ public class TypeIO{
}
if(type == 1){ //remove
currentRequest = new BuildRequest(Pos.x(position), Pos.y(position));
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position));
}else{ //place
short block = read.s();
byte rotation = read.b();
boolean hasConfig = read.b() == 1;
Object config = readObject(read);
currentRequest = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.block(block));
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position), rotation, content.block(block));
if(hasConfig){
currentRequest.configure(config);
}

View File

@ -378,7 +378,7 @@ public abstract class BasicGenerator implements WorldGenerator{
arr.add(start.pos());
while(!arr.isEmpty()){
int i = arr.pop();
int x = Pos.x(i), y = Pos.y(i);
int x = Point2.x(i), y = Point2.y(i);
tiles.getn(x, y).cost = 2;
for(Point2 point : Geometry.d4){
int newx = x + point.x, newy = y + point.y;

View File

@ -476,14 +476,20 @@ public class Block extends BlockStorage{
/** Called when arbitrary configuration is applied to a tile. */
public void configured(Tile tile, @Nullable Playerc player, @Nullable Object value){
if(value == null){
//TODO
//tapped(tile, player);
}else if(configurations.containsKey(value.getClass())){
configurations.get(value.getClass()).configured(tile, 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).configured(tile, value);
}
}
/** Configure when a null value is passed.*/
public void configClear(Cons<Tile> cons){
configurations.put(void.class, (tile, value) -> cons.get(tile));
}
/** Listen for a config by class type. */
public <T> void config(Class<T> type, ConfigHandler<T> config){
configurations.put(type, config);
}
@ -743,7 +749,7 @@ public class Block extends BlockStorage{
}
public void drawRequestConfigCenter(BuildRequest req, Content content, String region){
public void drawRequestConfigCenter(BuildRequest req, Object content, String region){
Color color = content instanceof Item ? ((Item)content).color : content instanceof Liquid ? ((Liquid)content).color : null;
if(color == null) return;

View File

@ -1,21 +0,0 @@
package mindustry.world;
/** Methods for a packed position 'struct', contained in an int. */
public class Pos{
public static final int invalid = get(-1, -1);
/** Returns packed position from an x/y position. The values must be within short limits. */
public static int get(int x, int y){
return (((short)x) << 16) | (((short)y) & 0xFFFF);
}
/** Returns the x component of a position. */
public static short x(int pos){
return (short)(pos >>> 16);
}
/** Returns the y component of a position. */
public static short y(int pos){
return (short)(pos & 0xFFFF);
}
}

View File

@ -50,9 +50,9 @@ public class Tile implements Position{
this(x, y, content.block(floor), content.block(overlay), content.block(wall));
}
/** Returns this tile's position as a {@link Pos}. */
/** Returns this tile's position as a packed point. */
public int pos(){
return Pos.get(x, y);
return Point2.pack(x, y);
}
public byte relativeTo(Tile tile){

View File

@ -1,6 +1,7 @@
package mindustry.world;
import arc.func.*;
import arc.math.geom.*;
import arc.util.ArcAnnotate.*;
import java.util.*;
@ -61,7 +62,7 @@ public class Tiles implements Iterable<Tile>{
/** @return a tile at an int position (not equivalent to geti) */
public @Nullable Tile getp(int pos){
return get(Pos.x(pos), Pos.y(pos));
return get(Point2.x(pos), Point2.y(pos));
}
@Override

View File

@ -3,6 +3,7 @@ package mindustry.world.blocks;
import arc.Core;
import arc.graphics.g2d.*;
import arc.math.Mathf;
import arc.math.geom.*;
import mindustry.graphics.CacheLayer;
import mindustry.world.*;
@ -25,7 +26,7 @@ public class StaticWall extends Rock{
int rx = tile.x / 2 * 2;
int ry = tile.y / 2 * 2;
if(Core.atlas.isFound(large) && eq(rx, ry) && Mathf.randomSeed(Pos.get(rx, ry)) < 0.5){
if(Core.atlas.isFound(large) && eq(rx, ry) && Mathf.randomSeed(Point2.pack(rx, ry)) < 0.5){
Draw.rect(split[tile.x % 2][1 - tile.y % 2], tile.worldx(), tile.worldy());
}else if(variants > 0){
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());

View File

@ -1,20 +1,17 @@
package mindustry.world.blocks.defense;
import arc.*;
import arc.util.io.*;
import mindustry.annotations.Annotations.*;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.g2d.*;
import arc.math.geom.*;
import arc.util.io.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
import static mindustry.Vars.pathfinder;
public class Door extends Wall{
protected final static Rect rect = new Rect();
@ -31,23 +28,19 @@ public class Door extends Wall{
solidifes = true;
consumesTap = true;
entityType = DoorEntity::new;
}
@Remote(called = Loc.server)
public static void onDoorToggle(Playerc player, Tile tile, boolean open){
DoorEntity entity = tile.ent();
if(entity != null){
config(Boolean.class, (tile, open) -> {
DoorEntity entity = tile.ent();
entity.open = open;
Door door = (Door)tile.block();
pathfinder.updateTile(tile);
if(!entity.open){
door.openfx.at(tile.drawx(), tile.drawy());
openfx.at(tile.drawx(), tile.drawy());
}else{
door.closefx.at(tile.drawx(), tile.drawy());
closefx.at(tile.drawx(), tile.drawy());
}
Sounds.door.at(tile);
}
});
}
@Override
@ -86,12 +79,17 @@ public class Door extends Wall{
return;
}
Call.onDoorToggle(null, tile, !entity.open);
tile.configure(!entity.open);
}
public class DoorEntity extends TileEntity{
public boolean open = false;
@Override
public Boolean config(){
return open;
}
@Override
public void write(Writes write){
super.write(write);

View File

@ -1,23 +1,21 @@
package mindustry.world.blocks.distribution;
import arc.*;
import arc.struct.*;
import arc.struct.IntSet.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.struct.IntSet.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.meta.*;
import java.io.*;
import static mindustry.Vars.*;
public class ItemBridge extends Block{
@ -27,7 +25,7 @@ public class ItemBridge extends Block{
public TextureRegion endRegion, bridgeRegion, arrowRegion;
private static BuildRequest otherReq;
private static int lastPlaced = Pos.invalid;
private static int lastPlaced = -1;
public ItemBridge(String name){
super(name);
@ -43,6 +41,7 @@ public class ItemBridge extends Block{
group = BlockGroup.transportation;
entityType = ItemBridgeEntity::new;
config(Point2.class, (tile, i) -> tile.<ItemBridgeEntity>ent().link = i.pack());
config(Integer.class, (tile, i) -> tile.<ItemBridgeEntity>ent().link = i);
}
@ -59,7 +58,7 @@ public class ItemBridge extends Block{
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
otherReq = null;
list.each(other -> {
if(other.block == this && req.config == Pos.get(other.x, other.y)){
if(other.block == this && req.config instanceof Point2 && ((Point2)req.config).equals(other.x, other.y)){
otherReq = other;
}
});
@ -87,7 +86,7 @@ public class ItemBridge extends Block{
}
public Tile findLink(int x, int y){
if(world.tile(x, y) != null && linkValid(world.tile(x, y), world.tile(lastPlaced)) && lastPlaced != Pos.get(x, y)){
if(world.tile(x, y) != null && linkValid(world.tile(x, y), world.tile(lastPlaced)) && lastPlaced != Point2.pack(x, y)){
return world.tile(lastPlaced);
}
return null;
@ -152,7 +151,7 @@ public class ItemBridge extends Block{
if(linkValid(tile, other)){
if(entity.link == other.pos()){
tile.configure(Pos.invalid);
tile.configure(-1);
}else{
tile.configure(other.pos());
}
@ -283,7 +282,7 @@ public class ItemBridge extends Block{
while(it.hasNext){
int v = it.next();
if(tile.absoluteRelativeTo(Pos.x(v), Pos.y(v)) == i){
if(tile.absoluteRelativeTo(Point2.x(v), Point2.y(v)) == i){
return false;
}
}
@ -328,7 +327,7 @@ public class ItemBridge extends Block{
while(it.hasNext){
int v = it.next();
if(tile.absoluteRelativeTo(Pos.x(v), Pos.y(v)) == i){
if(tile.absoluteRelativeTo(Point2.x(v), Point2.y(v)) == i){
return false;
}
}
@ -359,7 +358,7 @@ public class ItemBridge extends Block{
}
public static class ItemBridgeEntity extends TileEntity{
public int link = Pos.invalid;
public int link = -1;
public IntSet incoming = new IntSet();
public float uptime;
public float time;
@ -367,8 +366,8 @@ public class ItemBridge extends Block{
public float cycleSpeed = 1f;
@Override
public Object config(){
return link;
public Point2 config(){
return Point2.unpack(link);
}
@Override

View File

@ -1,9 +1,10 @@
package mindustry.world.blocks.distribution;
import arc.*;
import arc.struct.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import arc.util.pooling.Pool.*;
@ -15,8 +16,6 @@ import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
public class MassDriver extends Block{
@ -42,11 +41,9 @@ public class MassDriver extends Block{
hasPower = true;
outlineIcon = true;
entityType = MassDriverEntity::new;
}
@Override
public void configured(Tile tile, Playerc player, Object value){
tile.<MassDriverEntity>ent().link = value;
config(Point2.class, (tile, point) -> tile.<MassDriverEntity>ent().link = point.pack());
config(Integer.class, (tile, point) -> tile.<MassDriverEntity>ent().link = point);
}
@Override
@ -327,8 +324,8 @@ public class MassDriver extends Block{
}
@Override
public int config(){
return link;
public Point2 config(){
return Point2.unpack(link);
}
@Override

View File

@ -136,7 +136,7 @@ public class OverflowGate extends Block{
@Override
public void write(Writes write){
write.i(lastInput == null ? Pos.invalid : lastInput.pos());
write.i(lastInput == null ? -1 : lastInput.pos());
}
@Override

View File

@ -6,15 +6,13 @@ import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.meta.*;
import java.io.*;
import static mindustry.Vars.*;
public class Sorter extends Block{
@ -32,6 +30,7 @@ public class Sorter extends Block{
entityType = SorterEntity::new;
config(Item.class, (tile, item) -> tile.<SorterEntity>ent().sortItem = item);
configClear(tile -> tile.<SorterEntity>ent().sortItem = null);
}
@Override
@ -48,7 +47,8 @@ public class Sorter extends Block{
@Override
public void configured(Tile tile, Playerc player, Object value){
tile.<SorterEntity>ent().sortItem = (Item)value;
super.configured(tile, player, value);
if(!headless){
renderer.minimap.update(tile);
}
@ -139,25 +139,17 @@ public class Sorter extends Block{
@Override
public void buildConfiguration(Tile tile, Table table){
SorterEntity entity = tile.ent();
ItemSelection.buildTable(table, content.items(), () -> entity.sortItem, item -> {
lastItem = item;
tile.configure(item == null ? -1 : item.id);
});
ItemSelection.buildTable(table, content.items(), () -> entity.sortItem, item -> tile.configure(lastItem = item));
}
public class SorterEntity extends TileEntity{
@Nullable Item sortItem;
@Override
public Object config(){
public Item config(){
return sortItem;
}
@Override
public void setConfig(Object config){
sortItem = (Item)config;
}
@Override
public byte version(){
return 2;

View File

@ -10,8 +10,6 @@ import arc.scene.ui.layout.*;
import arc.util.*;
import arc.util.io.*;
import arc.util.pooling.*;
import mindustry.annotations.Annotations.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.net.*;
import mindustry.ui.*;
@ -21,8 +19,9 @@ import mindustry.world.*;
import static mindustry.Vars.*;
public class MessageBlock extends Block{
protected static int maxTextLength = 220;
protected static int maxNewlines = 24;
//don't change this too much unless you want to run into issues with packet sizes
public int maxTextLength = 220;
public int maxNewlines = 24;
public MessageBlock(String name){
super(name);
@ -30,40 +29,32 @@ public class MessageBlock extends Block{
solid = true;
destructible = true;
entityType = MessageBlockEntity::new;
}
@Remote(targets = Loc.both, called = Loc.both, forward = true)
public static void setMessageBlockText(Playerc player, Tile tile, String text){
if(!Units.canInteract(player, tile)) return;
if(net.server() && text.length() > maxTextLength){
throw new ValidateException(player, "Player has gone above text limit.");
}
//can be broken while a player is typing
if(!(tile.block() instanceof MessageBlock)){
return;
}
StringBuilder result = new StringBuilder(text.length());
text = text.trim();
int count = 0;
for(int i = 0; i < text.length(); i++){
char c = text.charAt(i);
if(c == '\n' || c == '\r'){
count ++;
if(count <= maxNewlines){
result.append('\n');
}
}else{
result.append(c);
config(String.class, (tile, text) -> {
if(net.server() && text.length() > maxTextLength){
throw new ValidateException(player, "Player has gone above text limit.");
}
MessageBlockEntity entity = tile.ent();
StringBuilder result = new StringBuilder(text.length());
text = text.trim();
int count = 0;
for(int i = 0; i < text.length(); i++){
char c = text.charAt(i);
if(c == '\n' || c == '\r'){
count ++;
if(count <= maxNewlines){
result.append('\n');
}
}else{
result.append(c);
}
}
}
MessageBlockEntity entity = tile.ent();
if(entity != null){
entity.message = result.toString();
entity.lines = entity.message.split("\n");
}
});
}
@Override
@ -102,9 +93,7 @@ public class MessageBlock extends Block{
text = entity.message;
multiline = true;
maxLength = maxTextLength;
accepted = out -> {
Call.setMessageBlockText(player, tile, out);
};
accepted = tile::configure;
}});
}else{
FloatingDialog dialog = new FloatingDialog("$editmessage");
@ -124,11 +113,11 @@ public class MessageBlock extends Block{
});
a.setMaxLength(maxTextLength);
dialog.buttons.addButton("$ok", () -> {
Call.setMessageBlockText(player, tile, a.getText());
tile.configure(a.getText());
dialog.hide();
}).size(130f, 60f);
dialog.update(() -> {
if(!entity.isValid()){
if(tile.block() != this){
dialog.hide();
}
});
@ -148,6 +137,11 @@ public class MessageBlock extends Block{
public String message = "";
public String[] lines = {""};
@Override
public String config(){
return message;
}
@Override
public void write(Writes write){
super.write(write);

View File

@ -9,8 +9,6 @@ import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
public class LightBlock extends Block{
@ -27,6 +25,8 @@ public class LightBlock extends Block{
topRegion = reg("-top");
configurable = true;
entityType = LightEntity::new;
config(Integer.class, (tile, value) -> tile.<LightEntity>ent().color = value);
}
@Override
@ -61,11 +61,6 @@ public class LightBlock extends Block{
}).size(40f);
}
@Override
public void configured(Tile tile, Playerc player, Object value){
tile.<LightEntity>ent().color = value;
}
@Override
public void drawLight(Tile tile){
LightEntity entity = tile.ent();
@ -76,7 +71,7 @@ public class LightBlock extends Block{
public int color = Pal.accent.rgba();
@Override
public int config(){
public Integer config(){
return color;
}

View File

@ -35,45 +35,52 @@ public class PowerNode extends PowerBlock{
configurable = true;
consumesPower = false;
outputsPower = false;
}
entityType = PowerNodeEntity::new;
@Override
public void configured(Tile tile, Playerc player, Object value){
Tilec entity = tile.entity;
Tile other = world.tile(value);
boolean contains = entity.power().links.contains(value), valid = other != null && other.entity != null && other.entity.power() != null;
config(Integer.class, (tile, value) -> {
Tilec entity = tile.entity;
Tile other = world.tile(value);
boolean contains = entity.power().links.contains(value), valid = other != null && other.entity != null && other.entity.power() != null;
if(contains){
//unlink
entity.power().links.removeValue(value);
if(valid) other.entity.power().links.removeValue(tile.pos());
if(contains){
//unlink
entity.power().links.removeValue(value);
if(valid) other.entity.power().links.removeValue(tile.pos());
PowerGraph newgraph = new PowerGraph();
PowerGraph newgraph = new PowerGraph();
//reflow from this point, covering all tiles on this side
newgraph.reflow(tile);
//reflow from this point, covering all tiles on this side
newgraph.reflow(tile);
if(valid && other.entity.power().graph != newgraph){
//create new graph for other end
PowerGraph og = new PowerGraph();
//reflow from other end
og.reflow(other);
}
}else if(linkValid(tile, other) && valid && entity.power().links.size < maxNodes){
if(!entity.power().links.contains(other.pos())){
entity.power().links.add(other.pos());
}
if(other.getTeamID() == tile.getTeamID()){
if(!other.entity.power().links.contains(tile.pos())){
other.entity.power().links.add(tile.pos());
if(valid && other.entity.power().graph != newgraph){
//create new graph for other end
PowerGraph og = new PowerGraph();
//reflow from other end
og.reflow(other);
}
}
}else if(linkValid(tile, other) && valid && entity.power().links.size < maxNodes){
entity.power().graph.add(other.entity.power().graph);
}
if(!entity.power().links.contains(other.pos())){
entity.power().links.add(other.pos());
}
if(other.getTeamID() == tile.getTeamID()){
if(!other.entity.power().links.contains(tile.pos())){
other.entity.power().links.add(tile.pos());
}
}
entity.power().graph.add(other.entity.power().graph);
}
});
config(Point2[].class, (tile, value) -> {
tile.entity.power().links.clear();
for(Point2 p : value){
tile.entity.power().links.add(p.pack());
}
});
}
@Override
@ -360,4 +367,16 @@ public class PowerNode extends PowerBlock{
return false;
});
}
public class PowerNodeEntity extends TileEntity{
@Override
public Point2[] config(){
Point2[] out = new Point2[power.links.size];
for(int i = 0; i < out.length; i++){
out[i] = Point2.unpack(power.links.get(i));
}
return out;
}
}
}

View File

@ -5,15 +5,13 @@ import arc.graphics.g2d.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.meta.*;
import java.io.*;
import static mindustry.Vars.content;
public class ItemSource extends Block{
@ -27,17 +25,15 @@ public class ItemSource extends Block{
group = BlockGroup.transportation;
configurable = true;
entityType = ItemSourceEntity::new;
}
@Override
public void configured(Tile tile, Playerc player, Object value){
tile.<ItemSourceEntity>ent().outputItem = content.item(value);
config(Item.class, (tile, item) -> tile.<ItemSourceEntity>ent().outputItem = item);
configClear(tile -> tile.<ItemSourceEntity>ent().outputItem = null);
}
@Override
public void playerPlaced(Tile tile){
if(lastItem != null){
Core.app.post(() -> tile.configure(lastItem.id));
Core.app.post(() -> tile.configure(lastItem));
}
}
@ -49,7 +45,7 @@ public class ItemSource extends Block{
@Override
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
drawRequestConfigCenter(req, content.item(req.config), "center");
drawRequestConfigCenter(req, req.config, "center");
}
@Override
@ -82,10 +78,7 @@ public class ItemSource extends Block{
@Override
public void buildConfiguration(Tile tile, Table table){
ItemSourceEntity entity = tile.ent();
ItemSelection.buildTable(table, content.items(), () -> entity.outputItem, item -> {
lastItem = item;
tile.configure(item == null ? -1 : item.id);
});
ItemSelection.buildTable(table, content.items(), () -> entity.outputItem, item -> tile.configure(lastItem = item));
}
@Override
@ -97,8 +90,8 @@ public class ItemSource extends Block{
Item outputItem;
@Override
public int config(){
return outputItem == null ? -1 : outputItem.id;
public Item config(){
return outputItem;
}
@Override

View File

@ -6,14 +6,13 @@ import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.ctype.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import java.io.*;
import static mindustry.Vars.content;
public class LiquidSource extends Block{
@ -29,13 +28,14 @@ public class LiquidSource extends Block{
outputsLiquid = true;
entityType = LiquidSourceEntity::new;
config();
config(Liquid.class, (tile, l) -> tile.<LiquidSourceEntity>ent().source = l);
configClear(tile -> tile.<LiquidSourceEntity>ent().source = null);
}
@Override
public void playerPlaced(Tile tile){
if(lastLiquid != null){
Core.app.post(() -> tile.configure(lastLiquid.id));
Core.app.post(() -> tile.configure(lastLiquid));
}
}
@ -60,7 +60,7 @@ public class LiquidSource extends Block{
@Override
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
drawRequestConfigCenter(req, content.liquid(req.config), "center");
drawRequestConfigCenter(req, (Content)req.config, "center");
}
@Override
@ -80,22 +80,14 @@ public class LiquidSource extends Block{
public void buildConfiguration(Tile tile, Table table){
LiquidSourceEntity entity = tile.ent();
ItemSelection.buildTable(table, content.liquids(), () -> entity.source, liquid -> {
lastLiquid = liquid;
tile.configure(liquid == null ? -1 : liquid.id);
});
}
@Override
public void configured(Tile tile, Playerc player, Object value){
tile.<LiquidSourceEntity>ent().source = value == -1 ? null : content.liquid(value);
ItemSelection.buildTable(table, content.liquids(), () -> entity.source, liquid -> tile.configure(lastLiquid = liquid));
}
class LiquidSourceEntity extends TileEntity{
public @Nullable Liquid source = null;
@Override
public Object config(){
public Liquid config(){
return source;
}

View File

@ -5,14 +5,12 @@ import arc.graphics.g2d.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import java.io.*;
import static mindustry.Vars.content;
public class Unloader extends Block{
@ -29,11 +27,18 @@ public class Unloader extends Block{
hasItems = true;
configurable = true;
entityType = UnloaderEntity::new;
config(Item.class, (tile, item) -> {
tile.entity.items().clear();
tile.<UnloaderEntity>ent().sortItem = item;
});
configClear(tile -> tile.<UnloaderEntity>ent().sortItem = null);
}
@Override
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
drawRequestConfigCenter(req, content.item(req.config), "unloader-center");
drawRequestConfigCenter(req, (Item)req.config, "unloader-center");
}
@Override
@ -50,16 +55,10 @@ public class Unloader extends Block{
@Override
public void playerPlaced(Tile tile){
if(lastItem != null){
tile.configure(lastItem.id);
tile.configure(lastItem);
}
}
@Override
public void configured(Tile tile, Playerc player, Object value){
tile.entity.items().clear();
tile.<UnloaderEntity>ent().sortItem = content.item(value);
}
@Override
public void update(Tile tile){
UnloaderEntity entity = tile.ent();
@ -123,19 +122,15 @@ public class Unloader extends Block{
@Override
public void buildConfiguration(Tile tile, Table table){
UnloaderEntity entity = tile.ent();
ItemSelection.buildTable(table, content.items(), () -> entity.sortItem, item -> {
lastItem = item;
tile.configure(item == null ? -1 : item.id);
});
ItemSelection.buildTable(table, content.items(), () -> tile.<UnloaderEntity>ent().sortItem, item -> tile.configure(lastItem = item));
}
public static class UnloaderEntity extends TileEntity{
public Item sortItem = null;
@Override
public int config(){
return sortItem == null ? -1 : sortItem.id;
public Item config(){
return sortItem;
}
@Override

View File

@ -11,16 +11,14 @@ import arc.util.*;
import arc.util.io.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.meta.*;
import java.io.*;
import static mindustry.Vars.*;
public class CommandCenter extends Block{
@ -37,6 +35,21 @@ public class CommandCenter extends Block{
solid = true;
configurable = true;
entityType = CommandCenterEntity::new;
config(Integer.class, (tile, value) -> {
UnitCommand command = UnitCommand.all[value];
((CommandCenter)tile.block()).effect.at(tile);
for(Tile center : indexer.getAllied(tile.team(), BlockFlag.comandCenter)){
if(center.block() instanceof CommandCenter){
CommandCenterEntity entity = center.ent();
entity.command = command;
}
}
Groups.unit.each(t -> t.team() == tile.team(), u -> u.controller().command(command));
Events.fire(new CommandIssueEvent(tile, command));
});
}
@Override
@ -102,27 +115,11 @@ public class CommandCenter extends Block{
table.label(() -> entity.command.localized()).style(Styles.outlineLabel).center().growX().get().setAlignment(Align.center);
}
@Override
public void configured(Tile tile, Playerc player, Object value){
UnitCommand command = UnitCommand.all[value];
((CommandCenter)tile.block()).effect.at(tile);
for(Tile center : indexer.getAllied(tile.team(), BlockFlag.comandCenter)){
if(center.block() instanceof CommandCenter){
CommandCenterEntity entity = center.ent();
entity.command = command;
}
}
Groups.unit.each(t -> t.team() == tile.team(), u -> u.controller().command(command));
Events.fire(new CommandIssueEvent(tile, command));
}
public class CommandCenterEntity extends TileEntity{
public UnitCommand command = UnitCommand.attack;
@Override
public int config(){
public Integer config(){
return command.ordinal();
}