a bit less broken but still broken
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Tile> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()){
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ public enum EditorTool{
|
||||
}
|
||||
|
||||
if(draw.rotate){
|
||||
write.setRotation((byte)editor.rotation);
|
||||
write.rotation((byte)editor.rotation);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ public class MapEditor{
|
||||
tile.setTeam(drawTeam);
|
||||
}
|
||||
if(drawBlock.rotate){
|
||||
tile.setRotation((byte)rotation);
|
||||
tile.rotation((byte)rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String, Block> 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<String, String> 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{
|
||||
|
||||
@@ -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<String, String> fallback = ObjectMap.of(
|
||||
"alpha-dart-mech-pad", "dart-mech-pad"
|
||||
);
|
||||
private final Region[] regions;
|
||||
private final ObjectMap<String, String> 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<DataOutput> 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<DataInput> 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<DataInput> 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<String, String> map) throws IOException{
|
||||
public void writeMeta(DataOutput stream, ObjectMap<String, String> map) throws IOException{
|
||||
stream.writeShort(map.size);
|
||||
for(Entry<String, String> 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<T>{
|
||||
/** 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<DataOutput> writer;
|
||||
final IORunner<DataInput> reader;
|
||||
final String name;
|
||||
|
||||
public Region(IORunner<DataOutput> writer, IORunner<DataInput> reader, String name){
|
||||
this.writer = writer;
|
||||
this.reader = reader;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
protected interface IORunner<T>{
|
||||
void accept(T stream) throws IOException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SaveFileVersion> versions = new IntMap<>();
|
||||
public static final Array<SaveFileVersion> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -105,7 +105,7 @@ public abstract class BlockStorage extends UnlockableContent{
|
||||
|
||||
public void tryDumpLiquid(Tile tile, Liquid liquid){
|
||||
Array<Tile> 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<Tile> 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<Tile> 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;
|
||||
}
|
||||
|
||||
@@ -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.<BuildEntity>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.<BuildEntity>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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Tile> getLinkedTiles(Array<Tile> tmpArray){
|
||||
Block block = block();
|
||||
tmpArray.clear();
|
||||
public void getLinkedTiles(Consumer<Tile> 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<Tile> getLinkedTiles(Array<Tile> 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) + "]" : "");
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.<ConveyorEntity>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.<ConveyorEntity>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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,11 +58,11 @@ public class Router extends Block{
|
||||
|
||||
Tile getTileTarget(Tile tile, Item item, Tile from, boolean set){
|
||||
Array<Tile> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user