diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index cd8891e462..a51431a503 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -49,7 +49,7 @@ public class Vars{ public static final int maxNameLength = 40; public static final float itemSize = 5f; public static final int tilesize = 8; - public static final int sectorSize = 120; + public static final int sectorSize = 250; public static final int mapPadding = 3; public static final int invalidSector = Integer.MAX_VALUE; public static Locale[] locales; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 886cd28599..dca67baded 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -348,7 +348,6 @@ public class Control extends Module{ @Override public void update(){ - if(error != null){ throw new RuntimeException(error); } diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 097082035f..9f383cfbab 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -112,7 +112,6 @@ public class Logic extends Module{ world.getSector().completedMissions ++; state.mode = world.getSector().currentMission().getMode(); - world.getSector().currentMission().onFirstBegin(); world.getSector().currentMission().onBegin(); world.sectors.save(); } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 19957469f7..750f34b0e4 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -111,8 +111,8 @@ public class UI extends SceneModule{ Structs.each(font -> { font.setUseIntegerPositions(false); font.getData().setScale(Vars.fontScale); - font.getData().down += Unit.dp.scl(4f); - font.getData().lineHeight -= Unit.dp.scl(4f); + font.getData().down += Unit.dp.scl(3f); + font.getData().lineHeight -= Unit.dp.scl(3f); }, skin.font(), skin.getFont("default-font-chat"), skin.getFont("trad-chinese"), skin.getFont("simp-chinese")); } diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 24191adbc7..e337a94d1f 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -217,7 +217,7 @@ public class World extends Module{ beginMapLoad(); - int width = sectorSize * sector.width, height = sectorSize * sector.height; + int width = sectorSize, height = sectorSize; Tile[][] tiles = createTiles(width, height); diff --git a/core/src/io/anuke/mindustry/editor/MapEditor.java b/core/src/io/anuke/mindustry/editor/MapEditor.java index e997a0e272..532e720622 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditor.java +++ b/core/src/io/anuke/mindustry/editor/MapEditor.java @@ -15,7 +15,6 @@ import io.anuke.ucore.util.Bits; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.content; public class MapEditor{ - public static final int minMapSize = 128, maxMapSize = 512; public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15}; private MapTileData map; @@ -28,10 +27,6 @@ public class MapEditor{ private Block drawBlock = Blocks.stone; private Team drawTeam = Team.blue; - public MapEditor(){ - - } - public MapTileData getMap(){ return map; } diff --git a/core/src/io/anuke/mindustry/game/Team.java b/core/src/io/anuke/mindustry/game/Team.java index 1fd94ae2d1..2bace764e2 100644 --- a/core/src/io/anuke/mindustry/game/Team.java +++ b/core/src/io/anuke/mindustry/game/Team.java @@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color; import io.anuke.ucore.util.Bundles; public enum Team{ - none(Color.DARK_GRAY), + none(Color.valueOf("4d4e58")), blue(Color.ROYAL), red(Color.valueOf("e84737")), green(Color.valueOf("1dc645")), diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index b338fdaf4d..5f3d005030 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -1,16 +1,28 @@ package io.anuke.mindustry.io; import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.content.blocks.Blocks; +import io.anuke.mindustry.content.blocks.StorageBlocks; +import io.anuke.mindustry.entities.traits.SaveTrait; +import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.MappableContent; +import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.type.ContentType; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.BlockPart; +import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.entities.EntityGroup; +import io.anuke.ucore.entities.trait.Entity; +import io.anuke.ucore.util.Bits; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.*; public abstract class SaveFileVersion{ public final int version; @@ -31,6 +43,187 @@ public abstract class SaveFileVersion{ return new SaveMeta(version, time, playtime, build, sector, mode, map, wave, Difficulty.values()[difficulty]); } + public void writeMap(DataOutputStream stream) throws IOException{ + + //write world size + stream.writeShort(world.width()); + stream.writeShort(world.height()); + + for(int i = 0; i < world.width() * world.height(); i++){ + Tile tile = world.tile(i); + + stream.writeByte(tile.getFloorID()); + stream.writeByte(tile.getBlockID()); + stream.writeByte(tile.getElevation()); + + if(tile.block() instanceof BlockPart){ + stream.writeByte(tile.link); + }else if(tile.entity != null){ + stream.writeByte(Bits.packByte(tile.getTeamID(), tile.getRotation())); //team + rotation + stream.writeShort((short) tile.entity.health); //health + + if(tile.entity.items != null) tile.entity.items.write(stream); + if(tile.entity.power != null) tile.entity.power.write(stream); + if(tile.entity.liquids != null) tile.entity.liquids.write(stream); + if(tile.entity.cons != null) tile.entity.cons.write(stream); + + tile.entity.write(stream); + }else if(tile.block() == Blocks.air){ + int consecutives = 0; + + for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){ + Tile nextTile = world.tile(j); + + if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getElevation() != tile.getElevation()){ + break; + } + + consecutives++; + } + + stream.writeByte(consecutives); + i += consecutives; + } + } + + //write visibility, length-run encoded + for(int i = 0; i < world.width() * world.height(); i++){ + Tile tile = world.tile(i); + boolean discovered = tile.discovered(); + + int consecutives = 0; + + for(int j = i + 1; j < world.width() * world.height() && consecutives < 32767*2-1; j++){ + Tile nextTile = world.tile(j); + + if(nextTile.discovered() != discovered){ + break; + } + + consecutives++; + } + + stream.writeBoolean(discovered); + stream.writeShort(consecutives); + i += consecutives; + } + } + + public void readMap(DataInputStream stream) throws IOException{ + short width = stream.readShort(); + short height = stream.readShort(); + + if(world.getSector() != null){ + world.setMap(new Map("Sector " + world.getSector().x + ", " + world.getSector().y, width, height)); + }else if(world.getMap() == null){ + world.setMap(new Map("unknown", width, height)); + } + + world.beginMapLoad(); + + Tile[][] tiles = world.createTiles(width, height); + + for(int i = 0; i < width * height; i++){ + int x = i % width, y = i / width; + byte floorid = stream.readByte(); + byte wallid = stream.readByte(); + byte elevation = stream.readByte(); + + Tile tile = new Tile(x, y, floorid, wallid); + tile.setElevation(elevation); + + if(wallid == Blocks.blockpart.id){ + tile.link = stream.readByte(); + }else if(tile.entity != null){ + byte tr = stream.readByte(); + short health = stream.readShort(); + + byte team = Bits.getLeftByte(tr); + byte rotation = Bits.getRightByte(tr); + + Team t = Team.all[team]; + + tile.setTeam(Team.all[team]); + tile.entity.health = health; + tile.setRotation(rotation); + + if(tile.entity.items != null) tile.entity.items.read(stream); + if(tile.entity.power != null) tile.entity.power.read(stream); + if(tile.entity.liquids != null) tile.entity.liquids.read(stream); + if(tile.entity.cons != null) tile.entity.cons.read(stream); + + tile.entity.read(stream); + + if(tile.block() == StorageBlocks.core){ + state.teams.get(t).cores.add(tile); + } + }else if(wallid == 0){ + int consecutives = stream.readUnsignedByte(); + + for(int j = i + 1; j < i + 1 + consecutives; j++){ + int newx = j % width, newy = j / width; + Tile newTile = new Tile(newx, newy, floorid, wallid); + newTile.setElevation(elevation); + tiles[newx][newy] = newTile; + } + + i += consecutives; + } + + tiles[x][y] = tile; + } + + for(int i = 0; i < width * height; i++){ + boolean discovered = stream.readBoolean(); + int consecutives = stream.readUnsignedShort(); + if(discovered){ + for(int j = i + 1; j < i + 1 + consecutives; j++){ + int newx = j % width, newy = j / width; + tiles[newx][newy].setVisibility((byte) 1); + } + } + i += consecutives; + } + + content.setTemporaryMapper(null); + world.endMapLoad(); + } + + public void writeEntities(DataOutputStream stream) throws IOException{ + int groups = 0; + + for(EntityGroup group : Entities.getAllGroups()){ + if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ + groups++; + } + } + + stream.writeByte(groups); + + for(EntityGroup group : Entities.getAllGroups()){ + 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); + } + } + } + } + + public void readEntities(DataInputStream stream) throws IOException{ + byte groups = stream.readByte(); + + for(int i = 0; i < groups; i++){ + int amount = stream.readInt(); + for(int j = 0; j < amount; j++){ + byte typeid = stream.readByte(); + SaveTrait trait = (SaveTrait) TypeTrait.getTypeByID(typeid).get(); + trait.readSave(stream); + } + } + } + public MappableContent[][] readContentHeader(DataInputStream stream) throws IOException{ byte mapped = stream.readByte(); diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index ccef23d108..51120ce987 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -28,6 +28,10 @@ public class SaveIO{ } } + public static SaveFileVersion getSaveWriter(){ + return versionArray.peek(); + } + public static void saveToSlot(int slot){ if(gwt){ ByteArrayOutputStream stream = new ByteArrayOutputStream(); diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 52e859635c..3431873465 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -1,23 +1,11 @@ package io.anuke.mindustry.io.versions; import com.badlogic.gdx.utils.TimeUtils; -import io.anuke.mindustry.content.blocks.Blocks; -import io.anuke.mindustry.content.blocks.StorageBlocks; -import io.anuke.mindustry.entities.traits.SaveTrait; -import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; -import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Version; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.maps.Map; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.BlockPart; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.entities.EntityGroup; -import io.anuke.ucore.entities.trait.Entity; -import io.anuke.ucore.util.Bits; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -39,7 +27,6 @@ public class Save16 extends SaveFileVersion{ int sector = stream.readInt(); //sector ID //general state - byte mode = stream.readByte(); String mapname = stream.readUTF(); Map map = world.maps.getByName(mapname); @@ -60,98 +47,9 @@ public class Save16 extends SaveFileVersion{ state.spawner.read(stream); - //entities + readEntities(stream); - byte groups = stream.readByte(); - - for(int i = 0; i < groups; i++){ - int amount = stream.readInt(); - for(int j = 0; j < amount; j++){ - byte typeid = stream.readByte(); - SaveTrait trait = (SaveTrait) TypeTrait.getTypeByID(typeid).get(); - trait.readSave(stream); - } - } - - //map - - short width = stream.readShort(); - short height = stream.readShort(); - - if(world.getSector() != null){ - world.setMap(new Map("Sector " + world.getSector().x + ", " + world.getSector().y, width, height)); - }else if(map == null){ - world.setMap(new Map("unknown", width, height)); - } - - world.beginMapLoad(); - - Tile[][] tiles = world.createTiles(width, height); - - for(int i = 0; i < width * height; i++){ - int x = i % width, y = i / width; - byte floorid = stream.readByte(); - byte wallid = stream.readByte(); - byte elevation = stream.readByte(); - - Tile tile = new Tile(x, y, floorid, wallid); - tile.setElevation(elevation); - - if(wallid == Blocks.blockpart.id){ - tile.link = stream.readByte(); - }else if(tile.entity != null){ - byte tr = stream.readByte(); - short health = stream.readShort(); - - byte team = Bits.getLeftByte(tr); - byte rotation = Bits.getRightByte(tr); - - Team t = Team.all[team]; - - tile.setTeam(Team.all[team]); - tile.entity.health = health; - tile.setRotation(rotation); - - if(tile.entity.items != null) tile.entity.items.read(stream); - if(tile.entity.power != null) tile.entity.power.read(stream); - if(tile.entity.liquids != null) tile.entity.liquids.read(stream); - if(tile.entity.cons != null) tile.entity.cons.read(stream); - - tile.entity.read(stream); - - if(tile.block() == StorageBlocks.core){ - state.teams.get(t).cores.add(tile); - } - }else if(wallid == 0){ - int consecutives = stream.readUnsignedByte(); - - for(int j = i + 1; j < i + 1 + consecutives; j++){ - int newx = j % width, newy = j / width; - Tile newTile = new Tile(newx, newy, floorid, wallid); - newTile.setElevation(elevation); - tiles[newx][newy] = newTile; - } - - i += consecutives; - } - - tiles[x][y] = tile; - } - - for(int i = 0; i < width * height; i++){ - boolean discovered = stream.readBoolean(); - int consecutives = stream.readUnsignedShort(); - if(discovered){ - for(int j = i + 1; j < i + 1 + consecutives; j++){ - int newx = j % width, newy = j / width; - tiles[newx][newy].setVisibility((byte) 1); - } - } - i += consecutives; - } - - content.setTemporaryMapper(null); - world.endMapLoad(); + readMap(stream); } @Override @@ -177,91 +75,8 @@ public class Save16 extends SaveFileVersion{ //--ENTITIES-- - int groups = 0; + writeEntities(stream); - for(EntityGroup group : Entities.getAllGroups()){ - if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ - groups++; - } - } - - stream.writeByte(groups); - - for(EntityGroup group : Entities.getAllGroups()){ - 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); - } - } - } - - //--MAP DATA-- - - Timers.mark(); - - //write world size - stream.writeShort(world.width()); - stream.writeShort(world.height()); - - for(int i = 0; i < world.width() * world.height(); i++){ - Tile tile = world.tile(i); - - stream.writeByte(tile.getFloorID()); - stream.writeByte(tile.getBlockID()); - stream.writeByte(tile.getElevation()); - - if(tile.block() instanceof BlockPart){ - stream.writeByte(tile.link); - }else if(tile.entity != null){ - stream.writeByte(Bits.packByte(tile.getTeamID(), tile.getRotation())); //team + rotation - stream.writeShort((short) tile.entity.health); //health - - if(tile.entity.items != null) tile.entity.items.write(stream); - if(tile.entity.power != null) tile.entity.power.write(stream); - if(tile.entity.liquids != null) tile.entity.liquids.write(stream); - if(tile.entity.cons != null) tile.entity.cons.write(stream); - - tile.entity.write(stream); - }else if(tile.block() == Blocks.air){ - int consecutives = 0; - - for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){ - Tile nextTile = world.tile(j); - - if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getElevation() != tile.getElevation()){ - break; - } - - consecutives++; - } - - stream.writeByte(consecutives); - i += consecutives; - } - } - - //write visibility, length-run encoded - for(int i = 0; i < world.width() * world.height(); i++){ - Tile tile = world.tile(i); - boolean discovered = tile.discovered(); - - int consecutives = 0; - - for(int j = i + 1; j < world.width() * world.height() && consecutives < 32767*2-1; j++){ - Tile nextTile = world.tile(j); - - if(nextTile.discovered() != discovered){ - break; - } - - consecutives++; - } - - stream.writeBoolean(discovered); - stream.writeShort(consecutives); - i += consecutives; - } + writeMap(stream); } } diff --git a/core/src/io/anuke/mindustry/maps/Sector.java b/core/src/io/anuke/mindustry/maps/Sector.java index c228151b7d..bba6876781 100644 --- a/core/src/io/anuke/mindustry/maps/Sector.java +++ b/core/src/io/anuke/mindustry/maps/Sector.java @@ -22,8 +22,6 @@ public class Sector{ public boolean complete; /**Slot ID of this sector's save. -1 means no save has been created.*/ public int saveID = -1; - /**Sector size; if more than 1, the coordinates are the bottom left corner.*/ - public int width = 1, height = 1; /**Num of missions in this sector that have been completed so far.*/ public int completedMissions; @@ -37,8 +35,6 @@ public class Sector{ public transient int difficulty; /**Items the player starts with on this sector.*/ public transient Array startingItems; - /**Last expansion parameters.*/ - public transient int lastExpandX, lastExpandY; public Mission getDominantMission(){ for(Mission mission : missions){ diff --git a/core/src/io/anuke/mindustry/maps/SectorPresets.java b/core/src/io/anuke/mindustry/maps/SectorPresets.java index 6fbe532ff2..29540e1d5b 100644 --- a/core/src/io/anuke/mindustry/maps/SectorPresets.java +++ b/core/src/io/anuke/mindustry/maps/SectorPresets.java @@ -26,8 +26,7 @@ public class SectorPresets{ //base tutorial mission add(new SectorPreset(0, 0, TutorialSector.getMissions(), - Array.with(Items.copper, Items.coal, Items.lead), - 1)); + Array.with(Items.copper, Items.coal, Items.lead))); //command center mission add(new SectorPreset(0, 1, @@ -39,8 +38,7 @@ public class SectorPresets{ new CommandMission(UnitCommand.attack), new BattleMission() ), - Array.with(Items.copper, Items.lead, Items.coal), - 2)); + Array.with(Items.copper, Items.lead, Items.coal))); //pad mission add(new SectorPreset(0, -2, @@ -49,8 +47,7 @@ public class SectorPresets{ new MechMission(mobile ? Mechs.alpha : Mechs.dart), new WaveMission(15) ), - Array.with(Items.copper, Items.lead, Items.coal, Items.titanium), - 2)); + Array.with(Items.copper, Items.lead, Items.coal, Items.titanium))); //oil mission add(new SectorPreset(-2, 0, @@ -61,8 +58,7 @@ public class SectorPresets{ Missions.blockRecipe(CraftingBlocks.biomatterCompressor), new ContentMission(Liquids.oil) ), - Array.with(Items.copper, Items.lead, Items.coal, Items.titanium), - 2)); + Array.with(Items.copper, Items.lead, Items.coal, Items.titanium))); } public Array getOres(int x, int y){ @@ -74,29 +70,20 @@ public class SectorPresets{ } private void add(SectorPreset preset){ - for(int x = 0; x < preset.size; x++){ - for(int y = 0; y < preset.size; y++){ - presets.put(x + preset.x, y + preset.y, preset); - orePresets.put(x + preset.x, y + preset.y, preset.ores); - } - } + presets.put(preset.x, preset.y, preset); + orePresets.put(preset.x, preset.y, preset.ores); } public static class SectorPreset{ public final Array missions; public final Array ores; - public final int size, x, y; + public final int x, y; - public SectorPreset(int x, int y, Array missions, Array ores, int size){ + public SectorPreset(int x, int y, Array missions, Array ores){ this.missions = missions; - this.size = size; this.x = x; this.y = y; this.ores = ores; } - - void generate(Sector sector){ - - } } } diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 4e0ba5d483..8f968ded65 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -7,30 +7,28 @@ import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.Items; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.SectorPresets.SectorPreset; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; -import io.anuke.mindustry.maps.missions.*; +import io.anuke.mindustry.maps.missions.BattleMission; +import io.anuke.mindustry.maps.missions.Mission; +import io.anuke.mindustry.maps.missions.Missions; +import io.anuke.mindustry.maps.missions.WaveMission; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Recipe; +import io.anuke.mindustry.type.Recipe.RecipeVisibility; import io.anuke.mindustry.world.ColorMapper; -import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.defense.Wall; import io.anuke.ucore.core.Settings; -import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.entities.EntityGroup; -import io.anuke.ucore.entities.trait.Entity; import io.anuke.ucore.util.*; import static io.anuke.mindustry.Vars.*; public class Sectors{ private static final int sectorImageSize = 32; - private static final boolean checkExpansion = true; private final GridMap grid = new GridMap<>(); private final SectorPresets presets = new SectorPresets(); @@ -82,124 +80,6 @@ public class Sectors{ return grid.get(Bits.getLeftShort(position), Bits.getRightShort(position)); } - /**Tries to a sector in a specific direciton, specified by expandX and expandY. - * The player *must* currently be playing in this sector. - * If a sector is in that direction, this method will return false (failure) - * @param sector the sector to expand - * @param expandX spaces in X coordinate to expand, can be negative - * @param expandY spaces in Y coordinate to expand, can be negative*/ - public boolean expandSector(Sector sector, int expandX, int expandY){ - if(world.getSector() != sector){ - throw new IllegalArgumentException("Sector is not being played in!"); - } - - if(expandX < 0) sector.x += expandX; - if(expandY < 0) sector.y += expandY; - - sector.width += Math.abs(expandX); - sector.height += Math.abs(expandY); - - if(checkExpansion) { - for (int x = sector.x; x < sector.x + sector.width; x++) { - for (int y = sector.y; y < sector.y + sector.height; y++) { - if (grid.get(x, y) != null && grid.get(x,y) != sector && grid.get(x, y).hasSave() /*|| !canMerge(sector, grid.get(x, y))*/) { - //if a completed sector is hit, expansion failed - //put back the values of the sector - if (expandX < 0) sector.x -= expandX; - if (expandY < 0) sector.y -= expandY; - sector.width -= Math.abs(expandX); - sector.height -= Math.abs(expandY); - return false; - } - } - } - } - - sector.lastExpandX = expandX; - sector.lastExpandY = expandY; - - //add new sector spaces - for(int x = sector.x; x < sector.x+sector.width; x++){ - for(int y = sector.y; y < sector.y+sector.height; y++){ - grid.put(x, y, sector); - } - } - - //sector map data should now be shifted and generated - int shiftX = expandX < 0 ? -expandX*sectorSize : 0; - int shiftY = expandY < 0 ? -expandY*sectorSize : 0; - - for(EntityGroup group : Entities.getAllGroups()){ - for(Entity entity : group.all()){ - entity.set(entity.getX() + shiftX * tilesize, entity.getY() + shiftY * tilesize); - - if(entity instanceof BaseUnit){ - Tile spawner = ((BaseUnit) entity).getSpawner(); - if(spawner == null) continue; - int i = spawner.packedPosition(); - ((BaseUnit) entity).setIntSpawner(world.transform(i, world.width(), world.height(), sector.width*sectorSize, shiftX, shiftY)); - } - } - } - - if(!headless){ - renderer.fog.setLoadingOffset(shiftX, shiftY); - } - - //create *new* tile array - Tile[][] newTiles = new Tile[sector.width * sectorSize][sector.height * sectorSize]; - - //shift existing tiles to new array - for (int x = 0; x < (sector.width - Math.abs(expandX))*sectorSize; x++) { - for (int y = 0; y < (sector.height - Math.abs(expandY))*sectorSize; y++) { - Tile tile = world.rawTile(x, y); - tile.x = (short)(x + shiftX); - tile.y = (short)(y + shiftY); - newTiles[x + shiftX][y + shiftY] = tile; - tile.block().transformLinks(tile, world.width(), world.height(), sector.width*sectorSize, sector.height*sectorSize, shiftX, shiftY); - } - } - - world.beginMapLoad(newTiles); - - //create new tiles - for (int sx = 0; sx < sector.width; sx++) { - for (int sy = 0; sy < sector.height; sy++) { - //if this sector is a 'new sector (not part of the current save data...) - if(sx < -expandX || sy < -expandY || sx >= sector.width - expandX || sy >= sector.height - expandY){ - GenResult result = new GenResult(); - Array ores = getOres(sx + sector.x, sy + sector.y); - //gen tiles in sector - for (int x = 0; x < sectorSize; x++) { - for (int y = 0; y < sectorSize; y++) { - world.generator.generateTile(result, sx + sector.x, sy + sector.y, x, y, true, null, ores); - newTiles[sx * sectorSize + x][sy * sectorSize + y] = new Tile(x + sx * sectorSize, y + sy*sectorSize, result.floor.id, result.wall.id, (byte)0, (byte)0, result.elevation); - } - } - } - } - } - - //end loading of map - world.endMapLoad(); - - threads.runGraphics(() -> createTexture(sector)); - - return true; - } - - /**Returns whether a sector of this size and position can be fit here.*/ - public boolean canFit(int x, int y, int width, int height){ - for(int cx = x; cx < x + width; cx++){ - for(int cy = y; cy < y + height; cy++){ - if(grid.get(cx, cy) != null){ - return false; - } - } - } - return true; - } - public Difficulty getDifficulty(Sector sector){ if(sector.difficulty == 0){ //yes, this means hard tutorial difficulty @@ -224,20 +104,12 @@ public class Sectors{ Sector sector = get(x, y); sector.complete = true; - for(int sx = 0; sx < sector.width + 2; sx++){ - for(int sy = 0; sy < sector.height + 2; sy++){ - if((sx == 0 || sy == 0 || sx == sector.width + 1 || sy == sector.height + 1) && - !((sx == 0 && sy == 0) - || (sx == 0 && sy == sector.height+1) - || (sx == sector.width+1 && sy == 0) - || (sx == sector.width+1 && sy == sector.height+1))){ - createSector(sector.x + sx - 1, sector.y + sy - 1); - } - } + for(GridPoint2 g : Geometry.d4){ + createSector(x + g.x, y + g.y); } } - /**Creates a sector at a location if it is not present, but does not unlock it.*/ + /**Creates a sector at a location if it is not present, but does not complete it.*/ public void createSector(int x, int y){ if(grid.containsKey(x, y)) return; @@ -246,14 +118,9 @@ public class Sectors{ sector.x = (short)x; sector.y = (short)y; sector.complete = false; - sector.width = sector.height = 1; initSector(sector); - for(int cx = 0; cx < sector.width; cx++){ - for(int cy = 0; cy < sector.height; cy++){ - grid.put(sector.x + cx, sector.y + cy, sector); - } - } + grid.put(sector.x, sector.y, sector); if(sector.texture == null){ threads.runGraphics(() -> createTexture(sector)); @@ -261,11 +128,6 @@ public class Sectors{ } public void abandonSector(Sector sector){ - for(int x = sector.x; x < sector.width + sector.x; x++){ - for(int y = sector.y; y < sector.y + sector.height; y++){ - grid.put(x, y, null); - } - } if(sector.hasSave()){ sector.getSave().delete(); } @@ -273,11 +135,7 @@ public class Sectors{ sector.complete = false; initSector(sector); - for(int x = sector.x; x < sector.width + sector.x; x++){ - for(int y = sector.y; y < sector.y + sector.height; y++){ - grid.put(x, y, sector); - } - } + grid.put(sector.x, sector.y, sector); threads.runGraphics(() -> createTexture(sector)); @@ -290,27 +148,13 @@ public class Sectors{ } grid.clear(); - Array out = Settings.getObject("sectors", Array.class, Array::new); + Array out = Settings.getObject("sector-data", Array.class, Array::new); for(Sector sector : out){ - short x = sector.x; - short y = sector.y; - int w = sector.width; - int h = sector.height; createTexture(sector); initSector(sector); - - sector.x = x; - sector.y = y; - sector.width = w; - sector.height = h; - - for(int cx = 0; cx < sector.width; cx++){ - for(int cy = 0; cy < sector.height; cy++){ - grid.put(sector.x + cx, sector.y + cy, sector); - } - } + grid.put(sector.x, sector.y, sector); } if(out.size == 0){ @@ -318,6 +162,12 @@ public class Sectors{ } } + public void clear(){ + grid.clear(); + save(); + createSector(0, 0); + } + public void save(){ Array out = new Array<>(); @@ -327,17 +177,16 @@ public class Sectors{ } } - Settings.putObject("sectors", out); + Settings.putObject("sector-data", out); Settings.save(); } private void initSector(Sector sector){ - sector.difficulty = (int)(Mathf.dst(sector.x, sector.y) / 2); + sector.difficulty = (int)(Mathf.dst(sector.x, sector.y)); if(presets.get(sector.x, sector.y) != null){ SectorPreset p = presets.get(sector.x, sector.y); sector.missions.addAll(p.missions); - sector.width = sector.height = p.size; sector.x = (short)p.x; sector.y = (short)p.y; }else{ @@ -366,81 +215,43 @@ public class Sectors{ } } + /**Generates a mission for a sector. This is deterministic and the same for each client.*/ private void generate(Sector sector){ - int width = Mathf.randomSeed(sector.getSeed()+1, 1, 3); - int height = Mathf.randomSeed(sector.getSeed()+2, 1, 3); - int finalWidth = 1, finalHeight = 1; - int finalX = sector.x, finalY = sector.y; - - for(int x = 1; x <= width; x++){ - for(int y = 1; y <= height; y++){ - for(GridPoint2 point : Geometry.d8edge){ - int shiftx = (int)(-x/2f + (point.x * (x - 1))/2f), shifty = (int)(-y/2f + (point.y * (y - 1))/2f); - if(canFit(sector.x + shiftx, sector.y + shifty, x, y)){ - finalWidth = x; - finalHeight = y; - finalX = sector.x + shiftx; - finalY = sector.y + shifty; - } - } - } - } - - sector.width = finalWidth; - sector.height = finalHeight; - sector.x = (short)finalX; - sector.y = (short)finalY; - - //recipe mission - addRecipeMission(sector, 3); - - //expand - addExpandMission(sector, 16); - - if((sector.width + sector.height) <= 3){ - sector.difficulty = Math.max(sector.difficulty - 3, 0); - } //50% chance to get a wave mission - if(Mathf.randomSeed(sector.getSeed() + 6) < 0.5 || (sector.width + sector.height) <= 3){ + if(Mathf.randomSeed(sector.getSeed() + 6) < 0.5){ + //recipe mission (maybe) + addRecipeMission(sector, 3); sector.missions.add(new WaveMission(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 1, 4)*5)); }else{ + //battle missions don't get recipes + sector.missions.add(new BattleMission()); + } + + //possibly another battle mission + if(Mathf.randomSeed(sector.getSeed() + 3) < 0.3){ sector.missions.add(new BattleMission()); } //possibly add another recipe mission addRecipeMission(sector, 11); - - //possibly another battle mission - if(Mathf.randomSeed(sector.getSeed() + 3) < 0.3){ - addExpandMission(sector, 20); - sector.missions.add(new BattleMission()); - } - } - - private void addExpandMission(Sector sector, int offset){ - //add 0-1 expansion mission - if(sector.missions.size > 0){ - int ex = sector.width >= 3 ? 0 : Mathf.randomSeed(sector.getSeed() + 6 + offset, -2, 2); - int ey = sector.height >= 3 ? 0 : Mathf.randomSeed(sector.getSeed() + 7 + offset, -2, 2); - if(ex != 0 || ey != 0){ - sector.missions.add(new ExpandMission(ex, ey)); - } - } } private void addRecipeMission(Sector sector, int offset){ //build list of locked recipes to add mission for obtaining it - if(!headless && Mathf.randomSeed(sector.getSeed() + offset) < 0.5){ + if(Mathf.randomSeed(sector.getSeed() + offset) < 0.5){ Array recipes = new Array<>(); for(Recipe r : content.recipes()){ - //..wall missions don't happen - if(r.result instanceof Wall || control.unlocks.isUnlocked(r)) continue; + if(r.result instanceof Wall || (r.visibility != RecipeVisibility.all) || r.cost < 10f) continue; recipes.add(r); } + float maxdiff = 8f; + recipes.sort((r1, r2) -> Float.compare(r1.cost, r2.cost)); + int end = (int)(Mathf.clamp(sector.difficulty / maxdiff + 0.25f) * (recipes.size - 1)); + int start = (int)(Mathf.clamp(sector.difficulty / maxdiff) * (recipes.size / 2f)); - if(recipes.size > 0){ - Recipe recipe = recipes.get(Mathf.randomSeed(sector.getSeed() + 10, 0, recipes.size-1)); + if(recipes.size > 0 && end > start){ + Recipe recipe = recipes.get(Mathf.randomSeed(sector.getSeed() + 10, start, end)); sector.missions.addAll(Missions.blockRecipe(recipe.result)); } } @@ -453,7 +264,7 @@ public class Sectors{ sector.texture.dispose(); } - Pixmap pixmap = new Pixmap(sectorImageSize * sector.width, sectorImageSize * sector.height, Format.RGBA8888); + Pixmap pixmap = new Pixmap(sectorImageSize, sectorImageSize, Format.RGBA8888); GenResult secResult = new GenResult(); for(int x = 0; x < pixmap.getWidth(); x++){ diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index 0053e17ae5..91db10fa26 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -90,16 +90,9 @@ public class TutorialSector{ new BlockLocMission(PowerBlocks.powerNode, 62, 54), new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), - new ExpandMission(1, 0){ - @Override - public void onComplete(){ - super.onComplete(); - generateBase(); - } - }, + new ActionMission(TutorialSector::generateBase), new BattleMission(){ public void generate(Generation gen){} //no - public void onFirstBegin(){} //also no }.setMessage("$tutorial.battle") ); @@ -119,7 +112,7 @@ public class TutorialSector{ } private static void generateBase(){ - int x = sectorSize/2 + sectorSize, y = sectorSize/2; + int x = sectorSize - 50, y = sectorSize - 50; world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam); world.setBlock(world.tile(x - 1, y + 2), UnitBlocks.daggerFactory, waveTeam); world.setBlock(world.tile(x - 1, y - 3), UnitBlocks.daggerFactory, waveTeam); diff --git a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java index 7451978534..ef58381653 100644 --- a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java @@ -60,7 +60,6 @@ public class FortressGenerator{ float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(0.25f), 0f, 0.9999f); float dscl2 = Mathf.clamp(0.5f + gen.sector.difficulty / 20f + gen.random.range(0.1f), 0f, 1.5f); - int coreDst = FortressGenerator.coreDst*Math.min(gen.sector.width, gen.sector.height); Array turrets = find(b -> b instanceof ItemTurret); Array powerTurrets = find(b -> b instanceof PowerTurret); diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index 2d9426984e..9f95d9cb2d 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -369,8 +369,7 @@ public class WorldGenerator{ int offsetX = x - 4, offsetY = y + 23; for(int i = ores.size - 1; i >= 0; i--){ Item entry = ores.get(i); - if( - Math.abs(0.5f - sim.octaveNoise2D(2, 0.7, 1f / (50 + i * 2), offsetX, offsetY)) > 0.23f && + if(Math.abs(0.5f - sim.octaveNoise2D(2, 0.7, 1f / (50 + i * 2), offsetX, offsetY)) > 0.23f && Math.abs(0.5f - sim2.octaveNoise2D(1, 1, 1f / (40 + i * 4), offsetX, offsetY)) > 0.32f){ floor = OreBlocks.get(floor, entry); break; diff --git a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java index 6fda8f0aab..8bbfb29622 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java @@ -7,12 +7,11 @@ import io.anuke.mindustry.maps.generation.FortressGenerator; import io.anuke.mindustry.maps.generation.Generation; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.util.Bundles; -import io.anuke.ucore.util.SeedRandom; import static io.anuke.mindustry.Vars.*; public class BattleMission extends Mission{ - final int spacing = 20; + final int spacing = 30; @Override public GameMode getMode(){ @@ -25,20 +24,16 @@ public class BattleMission extends Mission{ } @Override - public void onFirstBegin(){ + public void generate(Generation gen){ + super.generate(gen); + if(state.teams.get(defaultTeam).cores.size == 0){ return; } + Tile core = state.teams.get(defaultTeam).cores.first(); - Generation gen = new Generation(world.getSector(), world.getTiles(), world.width(), world.height(), new SeedRandom(world.getSector().getSeed()-1)); - int ex = world.getSector().lastExpandX; - int ey = world.getSector().lastExpandY; int enx = world.width() - 1 - spacing; int eny = world.height() - 1 - spacing; - if(ex < 0) enx = spacing*gen.sector.width; - if(ex > 0) enx = world.width() - 1 - spacing*gen.sector.width; - if(ey < 0) eny = spacing*gen.sector.height; - if(ey > 0) eny = world.height() - 1 - spacing*gen.sector.height; new FortressGenerator().generate(gen, Team.red, core.x, core.y, enx, eny); } diff --git a/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java b/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java deleted file mode 100644 index 8e28be3a6a..0000000000 --- a/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.anuke.mindustry.maps.missions; - -import static io.anuke.mindustry.Vars.*; - -/**An action mission which simply expands the sector.*/ -public class ExpandMission extends ActionMission{ - private boolean done = false; - private final int expandX, expandY; - - public ExpandMission(int expandX, int expandY){ - this.expandX = expandX; - this.expandY = expandY; - - runner = () -> { - if(headless){ - world.sectors.expandSector(world.getSector(), expandX, expandY); - done = true; - }else{ - ui.loadLogic(() -> { - world.sectors.expandSector(world.getSector(), expandX, expandY); - done = true; - }); - } - }; - } - - @Override - public void onFirstBegin(){ - runner.run(); - } - - @Override - public boolean isComplete(){ - return done; - } - - @Override - public void onComplete(){ - done = false; - } - - public int getExpandX(){ - return expandX; - } - - public int getExpandY(){ - return expandY; - } -} diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index d024e02fa7..4c0b880040 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -62,10 +62,6 @@ public abstract class Mission{ } - public void onFirstBegin(){ - - } - /**Shows the unique sector message.*/ public void showMessage(){ if(!headless && extraMessage != null){ @@ -100,11 +96,12 @@ public abstract class Mission{ } public void generate(Generation gen){ - generateCoreAt(gen, gen.width/2, gen.height/2, defaultTeam); + generateCoreAt(gen, 50, 50, defaultTeam); } public void generateCoreAt(Generation gen, int coreX, int coreY, Team team){ gen.tiles[coreX][coreY].setBlock(StorageBlocks.core); gen.tiles[coreX][coreY].setTeam(team); + state.teams.get(team).cores.add(gen.tiles[coreX][coreY]); } } diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index 9ab41aa0cf..f256557b6c 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -192,7 +192,6 @@ public class NetworkIO{ int width = stream.readShort(); int height = stream.readShort(); - //TODO send advanced map meta such as author, etc Map currentMap = new Map(map, new MapMeta(0, new ObjectMap<>(), width, height, null), true, () -> null); currentMap.meta.tags.clear(); currentMap.meta.tags.putAll(tags); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index a1de283c9a..0009263d47 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -71,7 +71,7 @@ public class SectorsDialog extends FloatingDialog{ class SectorView extends Element{ float lastX, lastY; - float sectorSize = Unit.dp.scl(32*4); + float sectorSize = Unit.dp.scl(32*5); float sectorPadding = Unit.dp.scl(14f); boolean clicked = false; float panX = -sectorPadding/2f, panY = -sectorSize/2f; @@ -133,8 +133,8 @@ public class SectorsDialog extends FloatingDialog{ float drawY = y + height/2f + sectorY * padSectorSize - offsetY * padSectorSize - panY % padSectorSize; Sector sector = world.sectors.get(sectorX, sectorY); - int width = (sector == null ? 1 : sector.width); - int height = (sector == null ? 1 : sector.height); + int width = 1; + int height = 1; float paddingx = (width-1) * sectorPadding; float paddingy = (height-1) * sectorPadding; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index bccb2816ad..b94cc4eea0 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -151,9 +151,7 @@ public class SettingsMenuDialog extends SettingsDialog{ dialog.addCloseButton(); dialog.content().addButton("$text.settings.clearsectors", "clear", () -> { ui.showConfirm("$text.confirm", "$text.settings.clear.confirm", () -> { - Settings.clearBytes("sectors"); - Settings.save(); - world.sectors.load(); + world.sectors.clear(); dialog.hide(); }); }); @@ -161,7 +159,6 @@ public class SettingsMenuDialog extends SettingsDialog{ dialog.content().addButton("$text.settings.clearunlocks", "clear", () -> { ui.showConfirm("$text.confirm", "$text.settings.clear.confirm", () -> { control.unlocks.reset(); - Settings.save(); dialog.hide(); }); }); diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java index 8c76090929..e8a5205267 100644 --- a/core/src/io/anuke/mindustry/world/ColorMapper.java +++ b/core/src/io/anuke/mindustry/world/ColorMapper.java @@ -35,7 +35,7 @@ public class ColorMapper implements ContentList{ float maxMult = 1f/Math.max(Math.max(tmpColor.r, tmpColor.g), tmpColor.b) ; float mul = Math.min(0.7f + elevation / 5f, maxMult); if((cliffs & ((1 << 6))) != 0){ - mul -= 0.5f; + mul -= 0.35f; } tmpColor.mul(mul, mul, mul, 1f); color = Color.rgba8888(tmpColor);