diff --git a/core/src/io/anuke/mindustry/ai/BlockIndexer.java b/core/src/io/anuke/mindustry/ai/BlockIndexer.java index f3cba3a173..bcaca39b7f 100644 --- a/core/src/io/anuke/mindustry/ai/BlockIndexer.java +++ b/core/src/io/anuke/mindustry/ai/BlockIndexer.java @@ -171,12 +171,10 @@ public class BlockIndexer{ for(int tx = rx * structQuadrantSize; tx < (rx + 1) * structQuadrantSize && tx < world.width(); tx++){ for(int ty = ry * structQuadrantSize; ty < (ry + 1) * structQuadrantSize && ty < world.height(); ty++){ - Tile other = world.tile(tx, ty); + Tile other = world.ltile(tx, ty); if(other == null) continue; - other = other.target(); - if(other.entity == null || other.getTeam() != team || !pred.test(other) || !other.block().targetable) continue; @@ -293,7 +291,7 @@ public class BlockIndexer{ outer: for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){ for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){ - Tile result = world.tile(x, y).target(); + Tile result = world.ltile(x, y); //when a targetable block is found, mark this quadrant as occupied and stop searching if(result.entity != null && result.getTeam() == data.team){ structQuadrants[data.team.ordinal()].set(index); diff --git a/core/src/io/anuke/mindustry/ai/Pathfinder.java b/core/src/io/anuke/mindustry/ai/Pathfinder.java index 8ee044e32b..85890bba56 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfinder.java +++ b/core/src/io/anuke/mindustry/ai/Pathfinder.java @@ -83,7 +83,7 @@ public class Pathfinder{ } private boolean passable(Tile tile, Team team){ - return (!tile.solid()) || (tile.breakable() && (tile.target().getTeam() != team)); + return (!tile.solid()) || (tile.breakable() && (tile.getTeam() != team)); } /** diff --git a/core/src/io/anuke/mindustry/content/Blocks.java b/core/src/io/anuke/mindustry/content/Blocks.java index dc287849be..bb200f9c6f 100644 --- a/core/src/io/anuke/mindustry/content/Blocks.java +++ b/core/src/io/anuke/mindustry/content/Blocks.java @@ -112,16 +112,19 @@ public class Blocks implements ContentList{ //create special blockpart variants for(int dx = 0; dx < BlockPart.maxSize; dx++){ for(int dy = 0; dy < BlockPart.maxSize; dy++){ - new BlockPart(dx - BlockPart.maxSize/2, dy - BlockPart.maxSize/2); + int fx = dx - BlockPart.maxSize/2, fy = dy - BlockPart.maxSize/2; + if(fx != 0 || fy != 0){ + new BlockPart(fx, fy); + } } } spawn = new Block("spawn"); - //Registers build blocks from size 1-6 + //Registers build blocks //no reference is needed here since they can be looked up by name later - for(int i = 1; i <= 6; i++){ - new BuildBlock("build" + i); + for(int i = 1; i <= BuildBlock.maxSize; i++){ + new BuildBlock(i); } deepwater = new Floor("deepwater"){{ @@ -561,7 +564,7 @@ public class Blocks implements ContentList{ drawer = tile -> { LiquidModule mod = tile.entity.liquids; - int rotation = rotate ? tile.getRotation() * 90 : 0; + int rotation = rotate ? tile.rotation() * 90 : 0; Draw.rect(reg(bottomRegion), tile.drawx(), tile.drawy(), rotation); diff --git a/core/src/io/anuke/mindustry/content/Bullets.java b/core/src/io/anuke/mindustry/content/Bullets.java index 864e49460c..fb6ca467fe 100644 --- a/core/src/io/anuke/mindustry/content/Bullets.java +++ b/core/src/io/anuke/mindustry/content/Bullets.java @@ -398,9 +398,9 @@ public class Bullets implements ContentList{ @Override public void hitTile(Bullet b, Tile tile){ super.hit(b); - tile = tile.target(); + tile = tile.link(); - if(tile != null && tile.getTeam() == b.getTeam() && !(tile.block() instanceof BuildBlock)){ + if(tile.getTeam() == b.getTeam() && !(tile.block() instanceof BuildBlock)){ Effects.effect(Fx.healBlockFull, Pal.heal, tile.drawx(), tile.drawy(), tile.block().size); tile.entity.healBy(healPercent / 100f * tile.entity.maxHealth()); } diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index c4ef5ee932..b641b1dcb2 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -120,7 +120,7 @@ public class Control implements ApplicationListener{ Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); //the restart dialog can show info for any number of scenarios Call.onGameOver(event.winner); - if(state.rules.zone != -1){ + if(state.rules.zone != null){ //remove zone save on game over if(saves.getZoneSlot() != null){ saves.getZoneSlot().delete(); diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 605dce9128..ea02ae0c01 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -289,7 +289,7 @@ public class NetServer implements ApplicationListener{ //auto-skip done requests if(req.breaking && tile.block() == Blocks.air){ continue; - }else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || tile.getRotation() == req.rotation)){ + }else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || tile.rotation() == req.rotation)){ continue; } player.getPlaceQueue().addLast(req); diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index d309942f80..ef2cdeef30 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -20,6 +20,7 @@ import io.anuke.mindustry.maps.*; import io.anuke.mindustry.maps.generators.Generator; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.blocks.BlockPart; import static io.anuke.mindustry.Vars.*; @@ -111,6 +112,10 @@ public class World implements ApplicationListener{ return tile(Math.round(x / tilesize), Math.round(y / tilesize)); } + public @Nullable Tile ltileWorld(float x, float y){ + return ltile(Math.round(x / tilesize), Math.round(y / tilesize)); + } + public int toTile(float coord){ return Math.round(coord / tilesize); } @@ -194,14 +199,14 @@ public class World implements ApplicationListener{ } public Zone getZone(){ - return content.getByID(ContentType.zone, state.rules.zone); + return state.rules.zone; } public void playZone(Zone zone){ ui.loadAnd(() -> { logic.reset(); state.rules = zone.rules.get(); - state.rules.zone = zone.id; + state.rules.zone = zone; loadGenerator(zone.generator); for(Tile core : state.teams.get(defaultTeam).cores){ for(ItemStack stack : zone.getStartingItems()){ @@ -295,16 +300,7 @@ public class World implements ApplicationListener{ } public void removeBlock(Tile tile){ - if(!tile.block().isMultiblock() && !tile.isLinked()){ - tile.setBlock(Blocks.air); - }else{ - Tile target = tile.target(); - Array removals = target.getLinkedTiles(tempTiles); - for(Tile toremove : removals){ - //note that setting a new block automatically unlinks it - if(toremove != null) toremove.setBlock(Blocks.air); - } - } + tile.link().getLinkedTiles(other -> other.setBlock(Blocks.air)); } public void setBlock(Tile tile, Block block, Team team){ @@ -324,8 +320,7 @@ public class World implements ApplicationListener{ if(!(worldx == tile.x && worldy == tile.y)){ Tile toplace = world.tile(worldx, worldy); if(toplace != null){ - toplace.setLinked((byte)(dx + offsetx), (byte)(dy + offsety)); - toplace.setTeam(team); + toplace.setBlock(BlockPart.get(dx + offsetx, dy + offsety), team); } } } @@ -333,15 +328,6 @@ public class World implements ApplicationListener{ } } - public int transform(int packed, int oldWidth, int oldHeight, int newWidth, int shiftX, int shiftY){ - int x = packed % oldWidth; - int y = packed / oldWidth; - if(!Structs.inBounds(x, y, oldWidth, oldHeight)) return -1; - x += shiftX; - y += shiftY; - return y * newWidth + x; - } - /** * Raycast, but with world coordinates. */ @@ -462,7 +448,7 @@ public class World implements ApplicationListener{ for(int y = 0; y < tiles[0].length; y++){ Tile tile = tiles[x][y]; if(tile.block().solid && !tile.block().synthetic()){ - tiles[x][y].setRotation(dark[x][y]); + tiles[x][y].rotation(dark[x][y]); } } } @@ -509,8 +495,7 @@ public class World implements ApplicationListener{ if(!(worldx == x && worldy == y)){ Tile toplace = world.tile(worldx, worldy); if(toplace != null){ - toplace.setLinked((byte)(dx + offsetx), (byte)(dy + offsety)); - toplace.setTeam(team); + toplace.setBlock(BlockPart.get(dx + offsetx, dy + offsety), team); } } } diff --git a/core/src/io/anuke/mindustry/editor/DrawOperation.java b/core/src/io/anuke/mindustry/editor/DrawOperation.java index ea26df6ea4..62dd831fa1 100755 --- a/core/src/io/anuke/mindustry/editor/DrawOperation.java +++ b/core/src/io/anuke/mindustry/editor/DrawOperation.java @@ -46,7 +46,7 @@ public class DrawOperation{ editor.updateLinks(block, tile.x, tile.y); } }else if(type == OpType.rotation.ordinal()){ - tile.setRotation(to); + tile.rotation(to); }else if(type == OpType.team.ordinal()){ tile.setTeam(Team.all[to]); }else if(type == OpType.ore.ordinal()){ diff --git a/core/src/io/anuke/mindustry/editor/EditorTile.java b/core/src/io/anuke/mindustry/editor/EditorTile.java index 021664ce06..75a35f8e8a 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTile.java +++ b/core/src/io/anuke/mindustry/editor/EditorTile.java @@ -67,10 +67,10 @@ public class EditorTile extends Tile{ } @Override - public void setRotation(byte rotation){ - byte previous = getRotation(); + public void rotation(byte rotation){ + byte previous = rotation(); if(previous == rotation) return; - super.setRotation(rotation); + super.rotation(rotation); op(TileOp.get(x, y, (byte)OpType.rotation.ordinal(), previous, rotation)); } diff --git a/core/src/io/anuke/mindustry/editor/EditorTool.java b/core/src/io/anuke/mindustry/editor/EditorTool.java index b4cb882ce2..b92d1ac3d0 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTool.java +++ b/core/src/io/anuke/mindustry/editor/EditorTool.java @@ -116,7 +116,7 @@ public enum EditorTool{ } if(draw.rotate){ - write.setRotation((byte)editor.rotation); + write.rotation((byte)editor.rotation); } }; diff --git a/core/src/io/anuke/mindustry/editor/MapEditor.java b/core/src/io/anuke/mindustry/editor/MapEditor.java index e74128be2b..c1253509aa 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditor.java +++ b/core/src/io/anuke/mindustry/editor/MapEditor.java @@ -246,7 +246,7 @@ public class MapEditor{ tile.setTeam(drawTeam); } if(drawBlock.rotate){ - tile.setRotation((byte)rotation); + tile.rotation((byte)rotation); } } } diff --git a/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java b/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java index e34a139e9e..0e1f81affb 100644 --- a/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java @@ -224,7 +224,7 @@ public class MapGenerateDialog extends FloatingDialog{ Tile tile = editor.tile(x, y); input.begin(editor, x, y, tile.floor(), tile.block(), tile.overlay()); filter.apply(input); - writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.getRotation()); + writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.rotation()); } } @@ -235,7 +235,7 @@ public class MapGenerateDialog extends FloatingDialog{ Tile tile = editor.tile(x, y); DummyTile write = writeTiles[x][y]; - tile.setRotation(write.rotation); + tile.rotation(write.rotation); tile.setFloor((Floor)content.block(write.floor)); tile.setBlock(content.block(write.block)); tile.setTeam(Team.all[write.team]); @@ -341,7 +341,7 @@ public class MapGenerateDialog extends FloatingDialog{ } void set(Tile other){ - set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.getRotation()); + set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.rotation()); } } diff --git a/core/src/io/anuke/mindustry/editor/MapRenderer.java b/core/src/io/anuke/mindustry/editor/MapRenderer.java index 1488f8e0c6..f26b7f83f5 100644 --- a/core/src/io/anuke/mindustry/editor/MapRenderer.java +++ b/core/src/io/anuke/mindustry/editor/MapRenderer.java @@ -116,7 +116,7 @@ public class MapRenderer implements Disposable{ if(wall.rotate){ mesh.draw(idxWall, region, wx * tilesize + wall.offset(), wy * tilesize + wall.offset(), - region.getWidth() * Draw.scl, region.getHeight() * Draw.scl, tile.getRotation() * 90 - 90); + region.getWidth() * Draw.scl, region.getHeight() * Draw.scl, tile.rotation() * 90 - 90); }else{ mesh.draw(idxWall, region, wx * tilesize + wall.offset() + (tilesize - region.getWidth() * Draw.scl) / 2f, diff --git a/core/src/io/anuke/mindustry/entities/Damage.java b/core/src/io/anuke/mindustry/entities/Damage.java index 9f7ea0ca44..7acfae0783 100644 --- a/core/src/io/anuke/mindustry/entities/Damage.java +++ b/core/src/io/anuke/mindustry/entities/Damage.java @@ -85,9 +85,8 @@ public class Damage{ public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length){ tr.trns(angle, length); world.raycastEachWorld(x, y, x + tr.x, y + tr.y, (cx, cy) -> { - Tile tile = world.tile(cx, cy); - if(tile != null) tile = tile.target(); - if(tile != null && tile.entity != null && tile.target().getTeamID() != team.ordinal() && tile.entity.collide(hitter)){ + Tile tile = world.ltile(cx, cy); + if(tile != null && tile.entity != null && tile.getTeamID() != team.ordinal() && tile.entity.collide(hitter)){ tile.entity.collision(hitter); hitter.getBulletType().hit(hitter, tile.worldx(), tile.worldy()); } @@ -216,12 +215,10 @@ public class Damage{ int scaledDamage = (int)(damage * (1f - (float)dst / radius)); bits.set(bitOffset + x, bitOffset + y); - Tile tile = world.tile(startx + x, starty + y); + Tile tile = world.ltile(startx + x, starty + y); if(scaledDamage <= 0 || tile == null) continue; - tile = tile.target(); - //apply damage to entity if needed if(tile.entity != null && tile.getTeam() != team){ int health = (int)tile.entity.health; diff --git a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java index 590e3b1635..2ff39fcc6f 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java @@ -225,9 +225,8 @@ public class Bullet extends SolidEntity implements DamageTrait, ScaleTrait, Pool if(type.hitTiles && collidesTiles() && !supressCollision && initialized){ world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> { - Tile tile = world.tile(x, y); + Tile tile = world.ltile(x, y); if(tile == null) return false; - tile = tile.target(); if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.isDead() && (type.collidesTeam || tile.getTeam() != team)){ if(tile.getTeam() != team){ diff --git a/core/src/io/anuke/mindustry/entities/effect/Fire.java b/core/src/io/anuke/mindustry/entities/effect/Fire.java index fe447c1dcd..99dcc91a93 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Fire.java +++ b/core/src/io/anuke/mindustry/entities/effect/Fire.java @@ -98,7 +98,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{ return; } - TileEntity entity = tile.target().entity; + TileEntity entity = tile.link().entity; boolean damage = entity != null; float flammability = baseFlammability + puddleFlammability; diff --git a/core/src/io/anuke/mindustry/entities/effect/Puddle.java b/core/src/io/anuke/mindustry/entities/effect/Puddle.java index 76816d077e..09eaad2494 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Puddle.java +++ b/core/src/io/anuke/mindustry/entities/effect/Puddle.java @@ -201,7 +201,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai } }); - if(liquid.temperature > 0.7f && (tile.target().entity != null) && Mathf.chance(0.3 * Time.delta())){ + if(liquid.temperature > 0.7f && (tile.link().entity != null) && Mathf.chance(0.3 * Time.delta())){ Fire.create(tile); } diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index ec745b67c3..c8cf5c9164 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -164,7 +164,7 @@ public interface BuilderTrait extends Entity, TeamTrait{ for(BuildRequest request : removal){ if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) || - (!request.breaking && (world.tile(request.x, request.y).getRotation() == request.rotation || !request.block.rotate) + (!request.breaking && (world.tile(request.x, request.y).rotation() == request.rotation || !request.block.rotate) && world.tile(request.x, request.y).block() == request.block))){ getPlaceQueue().addLast(request); } diff --git a/core/src/io/anuke/mindustry/entities/type/Player.java b/core/src/io/anuke/mindustry/entities/type/Player.java index 6a4e40125b..35a8b058bf 100644 --- a/core/src/io/anuke/mindustry/entities/type/Player.java +++ b/core/src/io/anuke/mindustry/entities/type/Player.java @@ -432,7 +432,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{ if(getCurrentRequest() == request && request.progress > 0.001f) continue; if(request.breaking){ - Block block = world.tile(request.x, request.y).target().block(); + Block block = world.ltile(request.x, request.y).block(); //draw removal request Lines.stroke(2f, Pal.removeBack); diff --git a/core/src/io/anuke/mindustry/entities/type/TileEntity.java b/core/src/io/anuke/mindustry/entities/type/TileEntity.java index 313307c777..36636d9468 100644 --- a/core/src/io/anuke/mindustry/entities/type/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/type/TileEntity.java @@ -116,7 +116,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ @CallSuper public void write(DataOutput stream) throws IOException{ stream.writeShort((short)health); - stream.writeByte(Pack.byteByte(tile.getTeamID(), tile.getRotation())); //team + rotation + stream.writeByte(Pack.byteByte(tile.getTeamID(), tile.rotation())); //team + rotation if(items != null) items.write(stream); if(power != null) power.write(stream); if(liquids != null) liquids.write(stream); @@ -131,7 +131,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ byte rotation = Pack.rightByte(tr); tile.setTeam(Team.all[team]); - tile.setRotation(rotation); + tile.rotation(rotation); if(items != null) items.read(stream); if(power != null) power.read(stream); @@ -180,14 +180,14 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ Point2[] nearby = Edges.getEdges(block.size); for(Point2 point : nearby){ - Tile other = world.tile(tile.x + point.x, tile.y + point.y); + Tile other = world.ltile(tile.x + point.x, tile.y + point.y); //remove this tile from all nearby tile's proximities if(other != null){ - other = other.target(); other.block().onProximityUpdate(other); - } - if(other != null && other.entity != null){ - other.entity.proximity.removeValue(tile, true); + + if(other.entity != null){ + other.entity.proximity.removeValue(tile, true); + } } } } @@ -198,10 +198,9 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ Point2[] nearby = Edges.getEdges(block.size); for(Point2 point : nearby){ - Tile other = world.tile(tile.x + point.x, tile.y + point.y); + Tile other = world.ltile(tile.x + point.x, tile.y + point.y); if(other == null) continue; - other = other.target(); if(other.entity == null || !(other.interactable(tile.getTeam()))) continue; other.block().onProximityUpdate(other); diff --git a/core/src/io/anuke/mindustry/entities/type/base/Drone.java b/core/src/io/anuke/mindustry/entities/type/base/Drone.java index 5d6fe4c1e1..3531e22d39 100644 --- a/core/src/io/anuke/mindustry/entities/type/base/Drone.java +++ b/core/src/io/anuke/mindustry/entities/type/base/Drone.java @@ -58,7 +58,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{ if(isBreaking){ getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y)); }else{ - getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.cblock)); + getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.rotation(), entity.cblock)); } } diff --git a/core/src/io/anuke/mindustry/game/Saves.java b/core/src/io/anuke/mindustry/game/Saves.java index 718d3a7df4..46d66c5d0a 100644 --- a/core/src/io/anuke/mindustry/game/Saves.java +++ b/core/src/io/anuke/mindustry/game/Saves.java @@ -12,14 +12,14 @@ import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.io.SaveIO.SaveException; import io.anuke.mindustry.io.SaveMeta; import io.anuke.mindustry.maps.Map; -import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Zone; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; -import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.Vars.saveExtension; +import static io.anuke.mindustry.Vars.state; public class Saves{ private int nextSlot; @@ -224,7 +224,7 @@ public class Saves{ } public Zone getZone(){ - return meta == null || meta.rules == null ? null : content.getByID(ContentType.zone, meta.rules.zone); + return meta == null || meta.rules == null ? null : meta.rules.zone; } public int getBuild(){ diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 6d62314e23..50d904682d 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -78,7 +78,7 @@ public class BlockRenderer implements Disposable{ for(int y = 0; y < world.height(); y++){ Tile tile = world.rawTile(x, y); int edgeBlend = 2; - float rot = tile.getRotation(); + float rot = tile.rotation(); boolean fillable = (tile.block().solid && tile.block().fillsTile && !tile.block().synthetic()); int edgeDst = Math.min(x, Math.min(y, Math.min(Math.abs(x - (world.width() - 1)), Math.abs(y - (world.height() - 1))))); if(edgeDst <= edgeBlend){ diff --git a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java index 612af596eb..12390c6558 100644 --- a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java @@ -129,7 +129,7 @@ public class MinimapRenderer implements Disposable{ } private int colorFor(Tile tile){ - tile = tile.target(); + tile = tile.link(); return MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()); } diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index bea762d8be..494099befb 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -97,11 +97,10 @@ public class OverlayRenderer{ //draw selected block bars and info if(input.block == null && !Core.scene.hasMouse()){ Vector2 vec = Core.input.mouseWorld(input.getMouseX(), input.getMouseY()); - Tile tile = world.tileWorld(vec.x, vec.y); + Tile tile = world.ltileWorld(vec.x, vec.y); - if(tile != null && tile.block() != Blocks.air && tile.target().getTeam() == player.getTeam()){ - Tile target = tile.target(); - target.block().drawSelect(target); + if(tile != null && tile.block() != Blocks.air && tile.getTeam() == player.getTeam()){ + tile.block().drawSelect(tile); } } @@ -113,8 +112,7 @@ public class OverlayRenderer{ Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f)); Draw.reset(); - Tile tile = world.tileWorld(v.x, v.y); - if(tile != null) tile = tile.target(); + Tile tile = world.ltileWorld(v.x, v.y); if(tile != null && tile.interactable(player.getTeam()) && tile.block().acceptStack(player.item().item, player.item().amount, tile, player) > 0){ Draw.color(Pal.place); Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 1 + Mathf.absin(Time.time(), 5f, 1f)); diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 0327108f1d..2198f002ef 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -96,9 +96,8 @@ public class DesktopInput extends InputHandler{ for(int x = dresult.x; x <= dresult.x2; x++){ for(int y = dresult.y; y <= dresult.y2; y++){ - Tile tile = world.tile(x, y); + Tile tile = world.ltile(x, y); if(tile == null || !validBreak(tile.x, tile.y)) continue; - tile = tile.target(); Draw.color(Pal.removeBack); Lines.square(tile.drawx(), tile.drawy() - 1, tile.block().size * tilesize / 2f - 1); @@ -175,7 +174,7 @@ public class DesktopInput extends InputHandler{ Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY()); if(cursor != null){ - cursor = cursor.target(); + cursor = cursor.link(); cursorType = cursor.block().getCursor(cursor); @@ -257,7 +256,7 @@ public class DesktopInput extends InputHandler{ } if(selected != null){ - tryDropItems(selected.target(), Core.input.mouseWorld().x, Core.input.mouseWorld().y); + tryDropItems(selected.link(), Core.input.mouseWorld().x, Core.input.mouseWorld().y); } mode = none; diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 8a073e1f4b..9d553bdbfc 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -154,7 +154,7 @@ public abstract class InputHandler implements InputProcessor{ /** Handles tile tap events that are not platform specific. */ boolean tileTapped(Tile tile){ - tile = tile.target(); + tile = tile.link(); boolean consumed = false, showedInventory = false; @@ -331,7 +331,7 @@ public abstract class InputHandler implements InputProcessor{ } public void breakBlock(int x, int y){ - Tile tile = world.tile(x, y).target(); + Tile tile = world.ltile(x, y); player.addBuildRequest(new BuildRequest(tile.x, tile.y)); } diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index 7b7f53b098..1a6ef3a1d4 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -87,8 +87,7 @@ public class MobileInput extends InputHandler implements GestureListener{ player.setMineTile(null); player.target = unit; }else{ - Tile tile = world.tileWorld(x, y); - if(tile != null) tile = tile.target(); + Tile tile = world.ltileWorld(x, y); if(tile != null && tile.synthetic() && state.teams.areEnemies(player.getTeam(), tile.getTeam())){ TileEntity entity = tile.entity; @@ -408,9 +407,8 @@ public class MobileInput extends InputHandler implements GestureListener{ for(int x = dresult.x; x <= dresult.x2; x++){ for(int y = dresult.y; y <= dresult.y2; y++){ - Tile other = world.tile(x, y); + Tile other = world.ltile(x, y); if(other == null || !validBreak(other.x, other.y)) continue; - other = other.target(); Draw.color(Pal.removeBack); Lines.square(other.drawx(), other.drawy() - 1, other.block().size * tilesize / 2f - 1); @@ -506,12 +504,10 @@ public class MobileInput extends InputHandler implements GestureListener{ int wx = lineStartX + x * Mathf.sign(tileX - lineStartX); int wy = lineStartY + y * Mathf.sign(tileY - lineStartY); - Tile tar = world.tile(wx, wy); + Tile tar = world.ltile(wx, wy); if(tar == null) continue; - tar = tar.target(); - if(!hasRequest(world.tile(tar.x, tar.y)) && validBreak(tar.x, tar.y)){ PlaceRequest request = new PlaceRequest(tar.x, tar.y); request.scale = 1f; @@ -527,7 +523,7 @@ public class MobileInput extends InputHandler implements GestureListener{ if(tile == null) return false; - tryDropItems(tile.target(), Core.input.mouseWorld(screenX, screenY).x, Core.input.mouseWorld(screenX, screenY).y); + tryDropItems(tile.link(), Core.input.mouseWorld(screenX, screenY).x, Core.input.mouseWorld(screenX, screenY).y); } return false; } @@ -577,11 +573,11 @@ public class MobileInput extends InputHandler implements GestureListener{ }else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, block, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, block)){ //add to selection queue if it's a valid place position selection.add(lastPlaced = new PlaceRequest(cursor.x, cursor.y, block, rotation)); - }else if(mode == breaking && validBreak(cursor.target().x, cursor.target().y) && !hasRequest(cursor.target())){ + }else if(mode == breaking && validBreak(cursor.link().x, cursor.link().y) && !hasRequest(cursor.link())){ //add to selection queue if it's a valid BREAK position - cursor = cursor.target(); + cursor = cursor.link(); selection.add(new PlaceRequest(cursor.x, cursor.y)); - }else if(!canTapPlayer(worldx, worldy) && !tileTapped(cursor.target())){ + }else if(!canTapPlayer(worldx, worldy) && !tileTapped(cursor.link())){ tryBeginMine(cursor); } diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index ccd7381c8d..78cbb4200b 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -1,26 +1,21 @@ package io.anuke.mindustry.io; -import io.anuke.arc.collection.IntIntMap; import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.collection.ObjectMap.Entry; import io.anuke.arc.files.FileHandle; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.Pixmap; import io.anuke.arc.graphics.Pixmap.Format; -import io.anuke.arc.math.Mathf; import io.anuke.arc.util.*; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.game.*; import io.anuke.mindustry.maps.Map; -import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.LegacyColorMapper.LegacyBlock; import io.anuke.mindustry.world.blocks.BlockPart; import io.anuke.mindustry.world.blocks.Floor; import java.io.*; -import java.util.Arrays; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; @@ -30,24 +25,7 @@ import static io.anuke.mindustry.Vars.content; /** Reads and writes map files. */ public class MapIO{ public static final int version = 1; - private static final int[] pngHeader = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; - private static ObjectMap missingBlocks; - - private static void initBlocks(){ - if(missingBlocks != null) return; - - //only for legacy maps - missingBlocks = ObjectMap.of( - "stained-stone", Blocks.shale, - "stained-stone-red", Blocks.shale, - "stained-stone-yellow", Blocks.shale, - "stained-rocks", Blocks.shaleRocks, - "stained-boulder", Blocks.shaleBoulder, - "stained-rocks-red", Blocks.shaleRocks, - "stained-rocks-yellow", Blocks.shaleRocks - ); - } public static boolean isImage(FileHandle file){ try(InputStream stream = file.read(32)){ @@ -169,7 +147,7 @@ public class MapIO{ if(tile.block() instanceof BlockPart){ stream.writeByte(tile.getLinkByte()); }else if(tile.entity != null){ - stream.writeByte(Pack.byteByte(tile.getTeamID(), tile.getRotation())); //team + rotation + stream.writeByte(Pack.byteByte(tile.getTeamID(), tile.rotation())); //team + rotation stream.writeShort(/*(short)tile.entity.health*/tile.block().health); //health if(tile.block() == Blocks.liquidSource || tile.block() == Blocks.unloader || tile.block() == Blocks.sorter){ stream.writeByte(-1); //write an meaningless byte here, just a fallback thing @@ -294,9 +272,7 @@ public class MapIO{ Tile tile = tiles.get(x, y); tile.setBlock(block); - if(block == Blocks.part){ - tile.setLinkByte(stream.readByte()); - }else if(tile.entity != null){ + if(tile.entity != null){ byte tr = stream.readByte(); short health = stream.readShort(); @@ -305,7 +281,7 @@ public class MapIO{ tile.setTeam(Team.all[team]); tile.entity.health = /*health*/tile.block().health; - tile.setRotation(rotation); + tile.rotation(rotation); if(tile.block() == Blocks.liquidSource || tile.block() == Blocks.unloader || tile.block() == Blocks.sorter){ stream.readByte(); //these blocks have an extra config byte, read it @@ -353,9 +329,8 @@ public class MapIO{ //multiblock parts if(Structs.inBounds(worldx, worldy, pixmap.getWidth(), pixmap.getHeight())){ Tile write = tiles[worldx][worldy]; - write.setBlock(Blocks.part); + write.setBlock(BlockPart.get(dx - 1, dy - 1)); write.setTeam(Team.blue); - write.setLinkByte(Pack.byteByte((byte)(dx - 1 + 8), (byte)(dy - 1 + 8))); } } } @@ -368,112 +343,6 @@ public class MapIO{ } } - /** Reads a pixmap in the old 4.0 .mmap format. */ - private static void readLegacyMmapTiles(FileHandle file, Tile[][] tiles) throws IOException{ - readLegacyMmapTiles(file, (x, y) -> tiles[x][y]); - } - - /** Reads a mmap in the old 4.0 .mmap format. */ - private static void readLegacyMmapTiles(FileHandle file, TileProvider tiles) throws IOException{ - try(DataInputStream stream = new DataInputStream(file.read(bufferSize))){ - stream.readInt(); //version - byte tagAmount = stream.readByte(); - - for(int i = 0; i < tagAmount; i++){ - stream.readUTF(); //key - stream.readUTF(); //val - } - - initBlocks(); - - //block id -> real id map - IntIntMap map = new IntIntMap(); - IntIntMap oreMap = new IntIntMap(); - - short blocks = stream.readShort(); - for(int i = 0; i < blocks; i++){ - short id = stream.readShort(); - String name = stream.readUTF(); - Block block = content.getByName(ContentType.block, name); - if(block == null){ - //substitute for replacement in missingBlocks if possible - if(missingBlocks.containsKey(name)){ - block = missingBlocks.get(name); - }else if(name.startsWith("ore-")){ //an ore floor combination - String[] split = name.split("-"); - String itemName = split[1], floorName = Strings.join("-", Arrays.copyOfRange(split, 2, split.length)); - Item item = content.getByName(ContentType.item, itemName); - Block oreBlock = item == null ? null : content.getByName(ContentType.block, "ore-" + item.name); - Block floor = missingBlocks.get(floorName, content.getByName(ContentType.block, floorName)); - if(oreBlock != null && floor != null){ - oreMap.put(id, oreBlock.id); - block = floor; - }else{ - block = Blocks.air; - } - }else{ - block = Blocks.air; - } - - } - map.put(id, block.id); - } - short width = stream.readShort(), height = stream.readShort(); - - for(int y = 0; y < height; y++){ - for(int x = 0; x < width; x++){ - Tile tile = tiles.get(x, y); - byte floorb = stream.readByte(); - byte blockb = stream.readByte(); - byte link = stream.readByte(); - byte rotTeamb = stream.readByte(); - stream.readByte();//unused stuff - - tile.setFloor((Floor)content.block(map.get(floorb, 0))); - tile.setBlock(content.block(map.get(blockb, 0))); - tile.setRotation(Pack.leftByte(rotTeamb)); - if(tile.block().synthetic()){ - tile.setTeam(Team.all[Mathf.clamp(Pack.rightByte(rotTeamb), 0, Team.all.length)]); - } - - if(tile.block() == Blocks.part){ - tile.setLinkByte(link); - } - - if(oreMap.containsKey(floorb)){ - tile.setOverlay(content.block(oreMap.get(floorb, 0))); - } - } - } - } - } - - private static Map readLegacyMap(FileHandle file, boolean custom) throws IOException{ - try(DataInputStream stream = new DataInputStream(file.read(bufferSize))){ - ObjectMap tags = new ObjectMap<>(); - - int version = stream.readInt(); - if(version != 0) throw new IOException("Attempted to read non-legacy map in legacy method!"); - byte tagAmount = stream.readByte(); - - for(int i = 0; i < tagAmount; i++){ - String name = stream.readUTF(); - String value = stream.readUTF(); - tags.put(name, value); - } - - short blocks = stream.readShort(); - for(int i = 0; i < blocks; i++){ - stream.readShort(); - stream.readUTF(); - } - short width = stream.readShort(), height = stream.readShort(); - - //note that build 64 is the default build of all maps <65; while this can be inaccurate it's better than nothing - return new Map(file, width, height, tags, custom, 0, 64); - } - } - //endregion interface TileProvider{ diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index 1ccb52ba17..aedbb453bc 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -2,12 +2,13 @@ package io.anuke.mindustry.io; import io.anuke.arc.collection.*; import io.anuke.arc.collection.ObjectMap.Entry; +import io.anuke.arc.util.io.CounterInputStream; import io.anuke.arc.util.io.ReusableByteOutStream; import io.anuke.mindustry.entities.Entities; import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.traits.*; -import io.anuke.mindustry.game.*; -import io.anuke.mindustry.gen.Serialization; +import io.anuke.mindustry.game.Content; +import io.anuke.mindustry.game.MappableContent; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -19,25 +20,25 @@ import static io.anuke.mindustry.Vars.world; /** * Format: - * - * Everything is compressed. Use a DeflaterStream to begin reading. - * * 1. version of format / int - * 2. meta tags - * - length / short - * - continues with (string, string) pairs indicating key, value + * (begin deflating) + * 2. regions */ public abstract class SaveFileVersion{ public final int version; private final ReusableByteOutStream byteOutput = new ReusableByteOutStream(); private final DataOutputStream dataBytes = new DataOutputStream(byteOutput); - private final ObjectMap fallback = ObjectMap.of( - "alpha-dart-mech-pad", "dart-mech-pad" - ); + private final Region[] regions; + private final ObjectMap fallback = ObjectMap.of("alpha-dart-mech-pad", "dart-mech-pad"); - public SaveFileVersion(int version){ + public SaveFileVersion(int version, Region... regions){ this.version = version; + this.regions = regions; + } + + public void writeChunk(DataOutput output, IORunner runner) throws IOException{ + writeChunk(output, false, runner); } /** Write a chunk of input to the stream. An integer of some length is written first, followed by the data. */ @@ -59,6 +60,10 @@ public abstract class SaveFileVersion{ output.write(byteOutput.getBytes(), 0, length); } + public int readChunk(DataInput input, IORunner runner) throws IOException{ + return readChunk(input, false, runner); + } + /** Reads a chunk of some length. Use the runner for reading to catch more descriptive errors. */ public int readChunk(DataInput input, boolean isByte, IORunner runner) throws IOException{ int length = isByte ? input.readUnsignedByte() : input.readInt(); @@ -76,18 +81,7 @@ public abstract class SaveFileVersion{ } } - public SaveMeta getData(DataInputStream stream) throws IOException{ - long time = stream.readLong(); - long playtime = stream.readLong(); - int build = stream.readInt(); - - Rules rules = Serialization.readRulesStreamJson(stream); - String map = stream.readUTF(); - int wave = stream.readInt(); - return new SaveMeta(version, time, playtime, build, map, wave, rules); - } - - public void writeMeta(DataOutputStream stream, ObjectMap map) throws IOException{ + public void writeMeta(DataOutput stream, ObjectMap map) throws IOException{ stream.writeShort(map.size); for(Entry entry : map.entries()){ stream.writeUTF(entry.key); @@ -95,7 +89,7 @@ public abstract class SaveFileVersion{ } } - public StringMap readMeta(DataInputStream stream) throws IOException{ + public StringMap readMeta(DataInput stream) throws IOException{ StringMap map = new StringMap(); short size = stream.readShort(); for(int i = 0; i < size; i++){ @@ -104,7 +98,7 @@ public abstract class SaveFileVersion{ return map; } - public void writeMap(DataOutputStream stream) throws IOException{ + public void writeMap(DataOutput stream) throws IOException{ //write world size stream.writeShort(world.width()); stream.writeShort(world.height()); @@ -185,7 +179,7 @@ public abstract class SaveFileVersion{ //read blocks for(int i = 0; i < width * height; i++){ int x = i % width, y = i / width; - Block block = content.block(stream.readByte()); + Block block = content.block(stream.readShort()); Tile tile = tiles[x][y]; tile.setBlock(block); @@ -208,6 +202,7 @@ public abstract class SaveFileVersion{ } public void writeEntities(DataOutputStream stream) throws IOException{ + //write entity chunk int groups = 0; for(EntityGroup group : Entities.getAllGroups()){ @@ -222,8 +217,11 @@ public abstract class SaveFileVersion{ if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ stream.writeInt(group.size()); for(Entity entity : group.all()){ - stream.writeByte(((SaveTrait)entity).getTypeID()); - ((SaveTrait)entity).writeSave(stream); + //each entity is a separate chunk. + writeChunk(stream, true, out -> { + stream.writeByte(((SaveTrait)entity).getTypeID()); + ((SaveTrait)entity).writeSave(out); + }); } } } @@ -284,11 +282,45 @@ public abstract class SaveFileVersion{ } } - public abstract void read(DataInputStream stream) throws IOException; + public final void read(DataInputStream stream, CounterInputStream counter) throws IOException{ + for(Region region : regions){ + counter.resetCount(); + try{ + int length = readChunk(stream, region.reader); + if(length != counter.count() + 4){ + throw new IOException("Error reading region \"" + region.name + "\": read length mismatch. Expected: " + length + "; Actual: " + (counter.count() + 4)); + } + }catch(Throwable e){ + throw new IOException("Error reading region \"" + region.name + "\".", e); + } + } + } - public abstract void write(DataOutputStream stream) throws IOException; + public final void write(DataOutputStream stream) throws IOException{ + for(Region region : regions){ + try{ + writeChunk(stream, region.writer); + }catch(Throwable e){ + throw new IOException("Error writing region \"" + region.name + "\".", e); + } + } + } - public interface IORunner{ + /** A region of a save file that holds a specific category of information. + * Uses: simplify code reuse, provide better error messages, skip unnecessary data.*/ + protected final class Region{ + final IORunner writer; + final IORunner reader; + final String name; + + public Region(IORunner writer, IORunner reader, String name){ + this.writer = writer; + this.reader = reader; + this.name = name; + } + } + + protected interface IORunner{ void accept(T stream) throws IOException; } } diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index 8be9291446..fbba038e5a 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.io; import io.anuke.arc.collection.*; import io.anuke.arc.files.FileHandle; +import io.anuke.arc.util.io.CounterInputStream; import io.anuke.mindustry.Vars; import io.anuke.mindustry.io.versions.Save1; @@ -12,6 +13,8 @@ import java.util.zip.InflaterInputStream; import static io.anuke.mindustry.Vars.*; public class SaveIO{ + /** Format header. This is the string 'MSAV' in ASCII. */ + public static final byte[] header = {77, 83, 65, 86}; public static final IntMap versions = new IntMap<>(); public static final Array versionArray = Array.with(new Save1()); @@ -130,15 +133,16 @@ public class SaveIO{ } public static void load(InputStream is) throws SaveException{ - try(DataInputStream stream = new DataInputStream(is)){ + try(CounterInputStream counter = new CounterInputStream(is); DataInputStream stream = new DataInputStream(counter)){ logic.reset(); int version = stream.readInt(); SaveFileVersion ver = versions.get(version); - ver.read(stream); + ver.read(stream, counter); }catch(Exception e){ - content.setTemporaryMapper(null); throw new SaveException(e); + }finally{ + content.setTemporaryMapper(null); } } diff --git a/core/src/io/anuke/mindustry/io/TypeIO.java b/core/src/io/anuke/mindustry/io/TypeIO.java index d785cbb1b3..41a097bc51 100644 --- a/core/src/io/anuke/mindustry/io/TypeIO.java +++ b/core/src/io/anuke/mindustry/io/TypeIO.java @@ -108,12 +108,12 @@ public class TypeIO{ @WriteClass(Block.class) public static void writeBlock(ByteBuffer buffer, Block block){ - buffer.put(block.id); + buffer.putShort(block.id); } @ReadClass(Block.class) public static Block readBlock(ByteBuffer buffer){ - return content.block(buffer.get()); + return content.block(buffer.getShort()); } @WriteClass(BuildRequest[].class) @@ -123,7 +123,7 @@ public class TypeIO{ buffer.put(request.breaking ? (byte)1 : 0); buffer.putInt(Pos.get(request.x, request.y)); if(!request.breaking){ - buffer.put(request.block.id); + buffer.putShort(request.block.id); buffer.put((byte)request.rotation); } } @@ -141,7 +141,7 @@ public class TypeIO{ if(type == 1){ //remove currentRequest = new BuildRequest(Pos.x(position), Pos.y(position)); }else{ //place - byte block = buffer.get(); + short block = buffer.getShort(); byte rotation = buffer.get(); currentRequest = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.block(block)); } @@ -204,7 +204,7 @@ public class TypeIO{ @WriteClass(Mech.class) public static void writeMech(ByteBuffer buffer, Mech mech){ - buffer.put(mech.id); + buffer.put((byte)mech.id); } @ReadClass(Mech.class) @@ -214,33 +214,33 @@ public class TypeIO{ @WriteClass(Liquid.class) public static void writeLiquid(ByteBuffer buffer, Liquid liquid){ - buffer.put(liquid == null ? -1 : liquid.id); + buffer.putShort(liquid == null ? -1 : liquid.id); } @ReadClass(Liquid.class) public static Liquid readLiquid(ByteBuffer buffer){ - byte id = buffer.get(); - return id == -1 ? null : content.liquid(buffer.get()); + short id = buffer.getShort(); + return id == -1 ? null : content.liquid(buffer.getShort()); } @WriteClass(BulletType.class) public static void writeBulletType(ByteBuffer buffer, BulletType type){ - buffer.put(type.id); + buffer.putShort(type.id); } @ReadClass(BulletType.class) public static BulletType readBulletType(ByteBuffer buffer){ - return content.getByID(ContentType.bullet, buffer.get()); + return content.getByID(ContentType.bullet, buffer.getShort()); } @WriteClass(Item.class) public static void writeItem(ByteBuffer buffer, Item item){ - buffer.put(item == null ? -1 : item.id); + buffer.putShort(item == null ? -1 : item.id); } @ReadClass(Item.class) public static Item readItem(ByteBuffer buffer){ - byte id = buffer.get(); + short id = buffer.getShort(); return id == -1 ? null : content.item(id); } diff --git a/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java b/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java index 920596c020..cf6f3cc750 100644 --- a/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java @@ -200,7 +200,7 @@ public abstract class BasicGenerator extends RandomGenerator{ Tile child = tiles[newx][newy]; if(!closed.get(child.x, child.y)){ closed.set(child.x, child.y); - child.setRotation(child.relativeTo(next.x, next.y)); + child.rotation(child.relativeTo(next.x, next.y)); costs.put(child.pos(), th.cost(child) + baseCost); queue.add(child); } @@ -215,7 +215,7 @@ public abstract class BasicGenerator extends RandomGenerator{ Tile current = end; while(current != start){ out.add(current); - Point2 p = Geometry.d4(current.getRotation()); + Point2 p = Geometry.d4(current.rotation()); current = tiles[current.x + p.x][current.y + p.y]; } diff --git a/core/src/io/anuke/mindustry/type/Loadout.java b/core/src/io/anuke/mindustry/type/Loadout.java index c322488fc4..aebdaf03bc 100644 --- a/core/src/io/anuke/mindustry/type/Loadout.java +++ b/core/src/io/anuke/mindustry/type/Loadout.java @@ -71,7 +71,7 @@ public class Loadout extends Content{ int ry = Pos.y(entry.key); Tile tile = world.tile(x + rx, y + ry); world.setBlock(tile, entry.value.block, defaultTeam); - tile.setRotation((byte)entry.value.rotation); + tile.rotation((byte)entry.value.rotation); if(entry.value.ore != null){ for(Tile t : tile.getLinkedTiles(outArray)){ t.setOverlay(entry.value.ore); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java index 71a633707b..d0a86d0f3c 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java @@ -59,11 +59,11 @@ public class BlockInventoryFragment extends Fragment{ } public void showFor(Tile t){ - if(this.tile == t.target()){ + if(this.tile == t){ hide(); return; } - this.tile = t.target(); + this.tile = t; if(tile == null || tile.entity == null || !tile.block().isAccessible() || tile.entity.items.total() == 0) return; rebuild(true); diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java index 6a01e36a88..c8c0013a23 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -78,7 +78,7 @@ public class PlacementFragment extends Fragment{ Tile tile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); if(tile != null){ - tile = tile.target(); + tile = tile.link(); Block tryRecipe = tile.block(); if(tryRecipe.isVisible() && unlocked(tryRecipe)){ input.block = tryRecipe; @@ -313,7 +313,7 @@ public class PlacementFragment extends Fragment{ if(!Core.scene.hasMouse() && topTable.hit(v.x, v.y, false) == null){ Tile tile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); if(tile != null){ - hoverTile = tile.target(); + hoverTile = tile.link(); }else{ hoverTile = null; } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 2a39935fd2..672c50d8b0 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -240,7 +240,7 @@ public class Block extends BlockStorage{ } public void draw(Tile tile){ - Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.getRotation() * 90 : 0); + Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.rotation() * 90 : 0); } public void drawTeam(Tile tile){ diff --git a/core/src/io/anuke/mindustry/world/BlockStorage.java b/core/src/io/anuke/mindustry/world/BlockStorage.java index 0484676931..1ce213f382 100644 --- a/core/src/io/anuke/mindustry/world/BlockStorage.java +++ b/core/src/io/anuke/mindustry/world/BlockStorage.java @@ -105,7 +105,7 @@ public abstract class BlockStorage extends UnlockableContent{ public void tryDumpLiquid(Tile tile, Liquid liquid){ Array proximity = tile.entity.proximity(); - int dump = tile.getDump(); + int dump = tile.rotation(); for(int i = 0; i < proximity.size; i++){ incrementDump(tile, proximity.size); @@ -138,7 +138,7 @@ public abstract class BlockStorage extends UnlockableContent{ public float tryMoveLiquid(Tile tile, Tile next, boolean leak, Liquid liquid){ if(next == null) return 0; - next = next.target(); + next = next.link(); if(next.getTeam() == tile.getTeam() && next.block().hasLiquids && tile.entity.liquids.get(liquid) > 0f){ @@ -182,7 +182,7 @@ public abstract class BlockStorage extends UnlockableContent{ */ public void offloadNear(Tile tile, Item item){ Array proximity = tile.entity.proximity(); - int dump = tile.getDump(); + int dump = tile.rotation(); for(int i = 0; i < proximity.size; i++){ incrementDump(tile, proximity.size); @@ -212,7 +212,7 @@ public abstract class BlockStorage extends UnlockableContent{ return false; Array proximity = entity.proximity(); - int dump = tile.getDump(); + int dump = tile.rotation(); if(proximity.size == 0) return false; @@ -249,7 +249,7 @@ public abstract class BlockStorage extends UnlockableContent{ } protected void incrementDump(Tile tile, int prox){ - tile.setDump((byte)((tile.getDump() + 1) % prox)); + tile.rotation((byte)((tile.rotation() + 1) % prox)); } /** Used for dumping items. */ @@ -259,8 +259,8 @@ public abstract class BlockStorage extends UnlockableContent{ /** Try offloading an item to a nearby container in its facing direction. Returns true if success. */ public boolean offloadDir(Tile tile, Item item){ - Tile other = tile.getNearby(tile.getRotation()); - if(other != null && other.target().getTeamID() == tile.getTeamID() && other.block().acceptItem(item, other, tile)){ + Tile other = tile.getNearby(tile.rotation()); + if(other != null && other.getTeam() == tile.getTeam() && other.block().acceptItem(item, other, tile)){ other.block().handleItem(item, other, tile); return true; } diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index f301dd3e42..bb08372000 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -10,7 +10,7 @@ import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.game.EventType.BlockBuildBeginEvent; import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.type.ContentType; +import io.anuke.mindustry.world.blocks.BuildBlock; import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity; import static io.anuke.mindustry.Vars.*; @@ -25,7 +25,7 @@ public class Build{ return; } - Tile tile = world.tile(x, y); + Tile tile = world.ltile(x, y); float prevPercent = 1f; //just in case @@ -35,38 +35,15 @@ public class Build{ prevPercent = tile.entity.healthf(); } - tile = tile.target(); - + int rotation = tile.rotation(); Block previous = tile.block(); + Block sub = BuildBlock.get(previous.size); - Block sub = content.getByName(ContentType.block, "build" + previous.size); - - tile.setBlock(sub); + world.setBlock(tile, sub, team, rotation); tile.entity().setDeconstruct(previous); - tile.setTeam(team); tile.entity.health = tile.entity.maxHealth() * prevPercent; - if(previous.isMultiblock()){ - int offsetx = -(previous.size - 1) / 2; - int offsety = -(previous.size - 1) / 2; - - for(int dx = 0; dx < previous.size; dx++){ - for(int dy = 0; dy < previous.size; dy++){ - int worldx = dx + offsetx + tile.x; - int worldy = dy + offsety + tile.y; - if(!(worldx == tile.x && worldy == tile.y)){ - Tile toplace = world.tile(worldx, worldy); - if(toplace != null){ - toplace.setLinked((byte)(dx + offsetx), (byte)(dy + offsety)); - toplace.setTeam(team); - } - } - } - } - } - - Tile ftile = tile; - Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(ftile, team, true))); + Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, true))); } /** Places a BuildBlock at this location. */ @@ -82,31 +59,10 @@ public class Build{ if(tile == null) return; Block previous = tile.block(); + Block sub = BuildBlock.get(result.size); - Block sub = content.getByName(ContentType.block, "build" + result.size); - - tile.setBlock(sub, rotation); + world.setBlock(tile, sub, team, rotation); tile.entity().setConstruct(previous, result); - tile.setTeam(team); - - if(result.isMultiblock()){ - int offsetx = -(result.size - 1) / 2; - int offsety = -(result.size - 1) / 2; - - for(int dx = 0; dx < result.size; dx++){ - for(int dy = 0; dy < result.size; dy++){ - int worldx = dx + offsetx + x; - int worldy = dy + offsety + y; - if(!(worldx == x && worldy == y)){ - Tile toplace = world.tile(worldx, worldy); - if(toplace != null){ - toplace.setLinked((byte)(dx + offsetx), (byte)(dy + offsety)); - toplace.setTeam(team); - } - } - } - } - } Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, false))); } @@ -166,7 +122,7 @@ public class Build{ && (!tile.floor().isDeep() || type.floating) && tile.floor().placeableOn && ((type.canReplace(tile.block()) - && !(type == tile.block() && rotation == tile.getRotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air) + && !(type == tile.block() && rotation == tile.rotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air) && tile.block().isMultiblock() == type.isMultiblock() && type.canPlaceOn(tile); } } @@ -195,9 +151,7 @@ public class Build{ /** Returns whether the tile at this position is breakable by this team */ public static boolean validBreak(Team team, int x, int y){ - Tile tile = world.tile(x, y); - if(tile != null) tile = tile.target(); - + Tile tile = world.ltile(x, y); return tile != null && tile.block().canBreak(tile) && tile.breakable() && tile.interactable(team); } } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index b1f8bc861e..147bfffd03 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.world; import io.anuke.arc.collection.Array; +import io.anuke.arc.function.Consumer; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.*; import io.anuke.mindustry.content.Blocks; @@ -120,7 +121,7 @@ public class Tile implements Position, TargetTrait{ @Override public Team getTeam(){ - return Team.all[target().team]; + return Team.all[link().team]; } public void setTeam(Team team){ @@ -169,20 +170,12 @@ public class Tile implements Position, TargetTrait{ this.overlay = 0; } - public byte getRotation(){ + public byte rotation(){ return rotation; } - public void setRotation(byte rotation){ - this.rotation = rotation; - } - - public byte getDump(){ - return rotation; - } - - public void setDump(byte dump){ - this.rotation = dump; + public void rotation(int rotation){ + this.rotation = (byte)rotation; } public short overlayID(){ @@ -210,31 +203,24 @@ public class Tile implements Position, TargetTrait{ } public boolean passable(){ - Block block = block(); - Block floor = floor(); return isLinked() || !((floor.solid && (block == Blocks.air || block.solidifes)) || (block.solid && (!block.destructible && !block.update))); } /** Whether this block was placed by a player/unit. */ public boolean synthetic(){ - Block block = block(); return block.update || block.destructible; } public boolean solid(){ - Block block = block(); - Block floor = floor(); - return block.solid || (floor.solid && (block == Blocks.air || block.solidifes)) || block.isSolidFor(this) - || (isLinked() && getLinked().block().isSolidFor(getLinked())); + return block.solid || block.isSolidFor(this) || (isLinked() && link().solid()); } public boolean breakable(){ - Block block = block(); - if(!isLinked()){ - return (block.destructible || block.breakable || block.update); - }else{ - return getLinked() != this && getLinked().getLinked() == null && getLinked().breakable(); - } + return !isLinked() ? (block.destructible || block.breakable || block.update) : link().breakable(); + } + + public Tile link(){ + return block.linked(this); } public boolean isEnemyCheat(){ @@ -249,21 +235,28 @@ public class Tile implements Position, TargetTrait{ * Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock. * This array contains all linked tiles, including this tile itself. */ - public Array getLinkedTiles(Array tmpArray){ - Block block = block(); - tmpArray.clear(); + public void getLinkedTiles(Consumer cons){ if(block.isMultiblock()){ int offsetx = -(block.size - 1) / 2; int offsety = -(block.size - 1) / 2; for(int dx = 0; dx < block.size; dx++){ for(int dy = 0; dy < block.size; dy++){ Tile other = world.tile(x + dx + offsetx, y + dy + offsety); - if(other != null) tmpArray.add(other); + if(other != null) cons.accept(other); } } }else{ - tmpArray.add(this); + cons.accept(this); } + } + + /** + * Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock. + * This array contains all linked tiles, including this tile itself. + */ + public Array getLinkedTiles(Array tmpArray){ + tmpArray.clear(); + getLinkedTiles(tmpArray::add); return tmpArray; } @@ -355,8 +348,8 @@ public class Tile implements Position, TargetTrait{ //+26 - if(target().synthetic()){ - cost += Mathf.clamp(target().block().health / 10f, 0, 20); + if(link().synthetic()){ + cost += Mathf.clamp(link().block.health / 10f, 0, 20); } //+46 @@ -410,9 +403,8 @@ public class Tile implements Position, TargetTrait{ }else if(!(block instanceof BlockPart) && !world.isGenerating()){ //since the entity won't update proximity for us, update proximity for all nearby tiles manually for(Point2 p : Geometry.d4){ - Tile tile = world.tile(x + p.x, y + p.y); + Tile tile = world.ltile(x + p.x, y + p.y); if(tile != null){ - tile = tile.target(); tile.block().onProximityUpdate(tile); } } @@ -455,9 +447,6 @@ public class Tile implements Position, TargetTrait{ @Override public String toString(){ - Block block = block(); - Block floor = floor(); - return floor.name + ":" + block.name + ":" + content.block(overlay) + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) + (isLinked() ? " link=[" + linkX(rotation) + ", " + linkY(rotation) + "]" : ""); } diff --git a/core/src/io/anuke/mindustry/world/blocks/BlockPart.java b/core/src/io/anuke/mindustry/world/blocks/BlockPart.java index 325f451175..ab163259d4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BlockPart.java +++ b/core/src/io/anuke/mindustry/world/blocks/BlockPart.java @@ -24,6 +24,7 @@ public class BlockPart extends Block{ } public static BlockPart get(int dx, int dy){ + if(dx == -maxSize/2 && dy == -maxSize/2) throw new IllegalArgumentException("Why are you getting a [0,0] blockpart? Stop it."); return parts[dx + maxSize/2][dy + maxSize/2]; } diff --git a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index f9e373e2f1..bfe29bed54 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -28,15 +28,25 @@ import java.io.*; import static io.anuke.mindustry.Vars.*; public class BuildBlock extends Block{ + public static final int maxSize = 9; + private static final BuildBlock[] buildBlocks = new BuildBlock[maxSize]; - public BuildBlock(String name){ - super(name); + public BuildBlock(int size){ + super("build" + size); + this.size = size; update = true; - size = Integer.parseInt(name.charAt(name.length() - 1) + ""); health = 20; layer = Layer.placement; consumesTap = true; solidifes = true; + + buildBlocks[size - 1] = this; + } + + /** Returns a BuildBlock by size. */ + public static BuildBlock get(int size){ + if(size > maxSize) throw new IllegalArgumentException("No. Don't place BuildBlocks of size greater than " + maxSize); + return buildBlocks[size - 1]; } @Remote(called = Loc.server) @@ -102,7 +112,7 @@ public class BuildBlock extends Block{ //if the target is constructible, begin constructing if(entity.cblock != null){ player.clearBuilding(); - player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.getRotation(), entity.cblock)); + player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.rotation(), entity.cblock)); } } @@ -127,7 +137,7 @@ public class BuildBlock extends Block{ if(entity.previous == null) return; if(Core.atlas.isFound(entity.previous.icon(Icon.full))){ - Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0); + Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.rotation() * 90 : 0); } } @@ -146,7 +156,7 @@ public class BuildBlock extends Block{ Shaders.blockbuild.region = region; Shaders.blockbuild.progress = entity.progress; - Draw.rect(region, tile.drawx(), tile.drawy(), target.rotate ? tile.getRotation() * 90 : 0); + Draw.rect(region, tile.drawx(), tile.drawy(), target.rotate ? tile.rotation() * 90 : 0); Draw.flush(); } } @@ -198,7 +208,7 @@ public class BuildBlock extends Block{ } if(progress >= 1f || state.rules.infiniteResources){ - Call.onConstructFinish(tile, cblock, builderID, tile.getRotation(), builder.getTeam()); + Call.onConstructFinish(tile, cblock, builderID, tile.rotation(), builder.getTeam()); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java b/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java index f20db17790..f7b4b9566c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java @@ -38,7 +38,7 @@ public class LiquidBlock extends Block{ public void draw(Tile tile){ LiquidModule mod = tile.entity.liquids; - int rotation = rotate ? tile.getRotation() * 90 : 0; + int rotation = rotate ? tile.rotation() * 90 : 0; Draw.rect(bottomRegion, tile.drawx(), tile.drawy(), rotation); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java index defe6d698e..22e45e65cb 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java @@ -85,10 +85,9 @@ public class MendProjector extends Block{ for(int y = -tileRange + tile.y; y <= tileRange + tile.y; y++){ if(Mathf.dst(x, y, tile.x, tile.y) > tileRange) continue; - Tile other = world.tile(x, y); + Tile other = world.ltile(x, y); if(other == null) continue; - other = other.target(); if(other.getTeamID() == tile.getTeamID() && !healed.contains(other.pos()) && other.entity != null && other.entity.health < other.entity.maxHealth()){ other.entity.healBy(other.entity.maxHealth() * (healPercent + entity.phaseHeat * phaseBoost) / 100f * entity.power.satisfaction); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java index 7f5cd03c5c..6b0efc6450 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java @@ -92,10 +92,9 @@ public class OverdriveProjector extends Block{ for(int y = -tileRange + tile.y; y <= tileRange + tile.y; y++){ if(Mathf.dst(x, y, tile.x, tile.y) > tileRange) continue; - Tile other = world.tile(x, y); + Tile other = world.ltile(x, y); if(other == null) continue; - other = other.target(); if(other.getTeamID() == tile.getTeamID() && !healed.contains(other.pos()) && other.entity != null){ other.entity.timeScaleDuration = Math.max(other.entity.timeScaleDuration, reload + 1f); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java index e1b2055236..e4b4bc1950 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java @@ -60,17 +60,17 @@ public class Conduit extends LiquidBlock{ } private boolean blends(Tile tile, int direction){ - Tile other = tile.getNearby(Mathf.mod(tile.getRotation() - direction, 4)); - if(other != null) other = other.target(); + Tile other = tile.getNearby(Mathf.mod(tile.rotation() - direction, 4)); + if(other != null) other = other.link(); - return other != null && other.block().hasLiquids && other.block().outputsLiquid && ((tile.getNearby(tile.getRotation()) == other) || (!other.block().rotate || other.getNearby(other.getRotation()) == tile)); + return other != null && other.block().hasLiquids && other.block().outputsLiquid && ((tile.getNearby(tile.rotation()) == other) || (!other.block().rotate || other.getNearby(other.rotation()) == tile)); } @Override public void draw(Tile tile){ ConduitEntity entity = tile.entity(); LiquidModule mod = tile.entity.liquids; - int rotation = tile.getRotation() * 90; + int rotation = tile.rotation() * 90; Draw.colorl(0.34f); Draw.rect(botRegions[entity.blendbits], tile.drawx(), tile.drawy(), rotation); @@ -89,7 +89,7 @@ public class Conduit extends LiquidBlock{ entity.smoothLiquid = Mathf.lerpDelta(entity.smoothLiquid, entity.liquids.total() / liquidCapacity, 0.05f); if(tile.entity.liquids.total() > 0.001f && tile.entity.timer.get(timerFlow, 1)){ - tryMoveLiquid(tile, tile.getNearby(tile.getRotation()), true, tile.entity.liquids.current()); + tryMoveLiquid(tile, tile.getNearby(tile.rotation()), true, tile.entity.liquids.current()); entity.noSleep(); }else{ entity.sleep(); @@ -104,7 +104,7 @@ public class Conduit extends LiquidBlock{ @Override public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ tile.entity.noSleep(); - return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f) && ((2 + source.relativeTo(tile.x, tile.y)) % 4 != tile.getRotation()); + return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f) && ((2 + source.relativeTo(tile.x, tile.y)) % 4 != tile.rotation()); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index 023eb8fb72..25fb795702 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -69,7 +69,7 @@ public class Conveyor extends Block{ @Override public void draw(Tile tile){ ConveyorEntity entity = tile.entity(); - byte rotation = tile.getRotation(); + byte rotation = tile.rotation(); int frame = entity.clogHeat <= 0.5f ? (int)(((Time.time() * speed * 8f * entity.timeScale)) % 4) : 0; Draw.rect(regions[Mathf.clamp(entity.blendbits, 0, regions.length - 1)][Mathf.clamp(frame, 0, regions[0].length - 1)], tile.drawx(), tile.drawy(), @@ -125,11 +125,11 @@ public class Conveyor extends Block{ } private boolean blends(Tile tile, int direction){ - Tile other = tile.getNearby(Mathf.mod(tile.getRotation() - direction, 4)); - if(other != null) other = other.target(); + Tile other = tile.getNearby(Mathf.mod(tile.rotation() - direction, 4)); + if(other != null) other = other.link(); return other != null && other.block().outputsItems() - && ((tile.getNearby(tile.getRotation()) == other) || (!other.block().rotate || other.getNearby(other.getRotation()) == tile)); + && ((tile.getNearby(tile.rotation()) == other) || (!other.block().rotate || other.getNearby(other.rotation()) == tile)); } @Override @@ -141,7 +141,7 @@ public class Conveyor extends Block{ public void drawLayer(Tile tile){ ConveyorEntity entity = tile.entity(); - byte rotation = tile.getRotation(); + byte rotation = tile.rotation(); try{ @@ -176,7 +176,7 @@ public class Conveyor extends Block{ float speed = this.speed * tilesize / 2.4f; float centerSpeed = 0.1f; float centerDstScl = 3f; - float tx = Geometry.d4[tile.getRotation()].x, ty = Geometry.d4[tile.getRotation()].y; + float tx = Geometry.d4[tile.rotation()].x, ty = Geometry.d4[tile.rotation()].y; float centerx = 0f, centery = 0f; @@ -197,7 +197,7 @@ public class Conveyor extends Block{ public void update(Tile tile){ ConveyorEntity entity = tile.entity(); entity.minitem = 1f; - Tile next = tile.getNearby(tile.getRotation()); + Tile next = tile.getNearby(tile.rotation()); float nextMax = next != null && next.block() instanceof Conveyor ? 1f - Math.max(itemSpace - next.entity().minitem, 0) : 1f; int minremove = Integer.MAX_VALUE; @@ -231,7 +231,7 @@ public class Conveyor extends Block{ ItemPos ni = pos2.set(othere.convey.get(othere.lastInserted), ItemPos.updateShorts); - if(next.getRotation() == tile.getRotation()){ + if(next.rotation() == tile.rotation()){ ni.x = pos.x; } othere.convey.set(othere.lastInserted, ni.pack()); @@ -290,7 +290,7 @@ public class Conveyor extends Block{ @Override public void getStackOffset(Item item, Tile tile, Vector2 trns){ - trns.trns(tile.getRotation() * 90 + 180f, tilesize / 2f); + trns.trns(tile.rotation() * 90 + 180f, tilesize / 2f); } @Override @@ -314,15 +314,15 @@ public class Conveyor extends Block{ @Override public boolean acceptItem(Item item, Tile tile, Tile source){ - int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.getRotation()); + int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.rotation()); float minitem = tile.entity().minitem; return (((direction == 0) && minitem > itemSpace) || - ((direction % 2 == 1) && minitem > 0.52f)) && (source == null || !(source.block().rotate && (source.getRotation() + 2) % 4 == tile.getRotation())); + ((direction % 2 == 1) && minitem > 0.52f)) && (source == null || !(source.block().rotate && (source.rotation() + 2) % 4 == tile.rotation())); } @Override public void handleItem(Item item, Tile tile, Tile source){ - byte rotation = tile.getRotation(); + byte rotation = tile.rotation(); int ch = Math.abs(source.relativeTo(tile.x, tile.y) - rotation); int ang = ((source.relativeTo(tile.x, tile.y) - rotation)); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index 213418b72e..d49f665f16 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -252,7 +252,7 @@ public class ItemBridge extends Block{ @Override public boolean acceptItem(Item item, Tile tile, Tile source){ - if(tile.getTeam() != source.target().getTeam()) return false; + if(tile.getTeam() != source.getTeam()) return false; ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java index 6330409029..87c8c71aa7 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java @@ -74,7 +74,7 @@ public class Junction extends Block{ if(entity == null || relative == -1 || entity.buffers[relative].full()) return false; Tile to = tile.getNearby(relative); - return to != null && to.target().entity != null; + return to != null && to.link().entity != null; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java index 1999136d89..cf3c96cdab 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java @@ -59,7 +59,7 @@ public class LiquidBridge extends ItemBridge{ @Override public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - if(tile.getTeam() != source.target().getTeam()) return false; + if(tile.getTeam() != source.getTeam()) return false; ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java index a160348107..c2942cb797 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java @@ -41,7 +41,7 @@ public class LiquidJunction extends LiquidBlock{ public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ int dir = source.relativeTo(tile.x, tile.y); dir = (dir + 4) % 4; - Tile to = tile.getNearby(dir).target(); + Tile to = tile.getNearby(dir).link(); if(to.block().hasLiquids && to.block().acceptLiquid(to, tile, liquid, amount)){ to.block().handleLiquid(to, tile, liquid, amount); @@ -54,7 +54,7 @@ public class LiquidJunction extends LiquidBlock{ dir = (dir + 4) % 4; Tile to = dest.getNearby(dir); if(to == null) return false; - to = to.target(); + to = to.link(); return to != null && to.entity != null && to.block().hasLiquids && to.block().acceptLiquid(to, dest, liquid, amount); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java b/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java index 6ba2d1496b..de9532a56c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java @@ -58,12 +58,12 @@ public class OverflowGate extends Router{ }else if(bc && !ac){ to = b; }else{ - if(tile.getDump() == 0){ + if(tile.rotation() == 0){ to = a; - if(flip) tile.setDump((byte)1); + if(flip) tile.rotation((byte)1); }else{ to = b; - if(flip) tile.setDump((byte)0); + if(flip) tile.rotation((byte)0); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java index a272f1011e..21a7baf18c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java @@ -58,11 +58,11 @@ public class Router extends Block{ Tile getTileTarget(Tile tile, Item item, Tile from, boolean set){ Array proximity = tile.entity.proximity(); - int counter = tile.getDump(); + int counter = tile.rotation(); for(int i = 0; i < proximity.size; i++){ Tile other = proximity.get((i + counter) % proximity.size); if(tile == from) continue; - if(set) tile.setDump((byte)((tile.getDump() + 1) % proximity.size)); + if(set) tile.rotation((byte)((tile.rotation() + 1) % proximity.size)); if(other.block().acceptItem(item, other, Edges.getFacingEdge(tile, other))){ return other; } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java index 89068a1a06..e9bd6df167 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java @@ -99,14 +99,14 @@ public class Sorter extends Block{ }else if(!bc){ return null; }else{ - if(dest.getDump() == 0){ + if(dest.rotation() == 0){ to = a; if(flip) - dest.setDump((byte)1); + dest.rotation((byte)1); }else{ to = b; if(flip) - dest.setDump((byte)0); + dest.rotation((byte)0); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java index 3915f563eb..af73a01302 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -101,7 +101,7 @@ public class PowerNode extends PowerBlock{ Tile before = world.tile(lastPlaced); if(linkValid(tile, before) && before.block() instanceof PowerNode){ for(Tile near : before.entity.proximity()){ - if(near.target() == tile){ + if(near == tile){ lastPlaced = tile.pos(); return; } @@ -127,7 +127,7 @@ public class PowerNode extends PowerBlock{ @Override public boolean onConfigureTileTapped(Tile tile, Tile other){ TileEntity entity = tile.entity(); - other = other.target(); + other = other.link(); Tile result = other; @@ -167,8 +167,7 @@ public class PowerNode extends PowerBlock{ for(int x = (int)(tile.x - laserRange - 1); x <= tile.x + laserRange + 1; x++){ for(int y = (int)(tile.y - laserRange - 1); y <= tile.y + laserRange + 1; y++){ - Tile link = world.tile(x, y); - if(link != null) link = link.target(); + Tile link = world.ltile(x, y); if(link != tile && linkValid(tile, link, false)){ boolean linked = linked(tile, link); diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java index 12026eef43..33494a8db5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java @@ -35,8 +35,7 @@ public class Unloader extends Block{ @Override public boolean canDump(Tile tile, Tile to, Item item){ - Block block = to.target().block(); - return !(block instanceof StorageBlock); + return !(to.block() instanceof StorageBlock); } @Override diff --git a/tests/src/test/java/WorldTests.java b/tests/src/test/java/WorldTests.java index 2b4f480bfa..bd1cf2af54 100644 --- a/tests/src/test/java/WorldTests.java +++ b/tests/src/test/java/WorldTests.java @@ -31,7 +31,7 @@ public class WorldTests{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ - assertEquals(4, tiles[x][y].getRotation()); + assertEquals(4, tiles[x][y].rotation()); } } } @@ -43,7 +43,7 @@ public class WorldTests{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ - assertEquals(0, tiles[x][y].getRotation()); + assertEquals(0, tiles[x][y].rotation()); } } } @@ -55,7 +55,7 @@ public class WorldTests{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ - assertEquals(0, tiles[x][y].getRotation()); + assertEquals(0, tiles[x][y].rotation()); } } } @@ -67,7 +67,7 @@ public class WorldTests{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ - assertEquals(0, tiles[x][y].getRotation()); + assertEquals(0, tiles[x][y].rotation()); } } } @@ -80,7 +80,7 @@ public class WorldTests{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ - byte darkness = tiles[x][y].getRotation(); + byte darkness = tiles[x][y].rotation(); int distance = Math.abs(x - 5) + Math.abs(y - 5); assertEquals(Math.min(Math.max(distance - 1, 0), 4), darkness); } @@ -95,7 +95,7 @@ public class WorldTests{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ - byte darkness = tiles[x][y].getRotation(); + byte darkness = tiles[x][y].rotation(); int distance = Math.abs(x - 7) + Math.abs(y - 7); assertEquals(Math.min(Math.max(distance - 1, 0), 4), darkness); }