From cc70ff97323521624bfb4f6b123aa36e911502f1 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 16 Sep 2018 22:05:29 -0400 Subject: [PATCH 01/22] Branch created --- core/src/io/anuke/mindustry/Vars.java | 2 +- core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 6376266c97..7f978345c3 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -48,7 +48,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 = 300; + public static final int sectorSize = 150; 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/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index dd532199b8..de958c89d4 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -60,6 +60,10 @@ public class SectorsDialog extends FloatingDialog{ selected = sector; } + public Sector getSelected(){ + return selected; + } + class SectorView extends Element{ float lastX, lastY; float sectorSize = Unit.dp.scl(32*4); From 4ba46bff69cdbeb523530550d6a647db2898b040 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 16 Sep 2018 22:28:42 -0400 Subject: [PATCH 02/22] Smoother map preview --- .../io/anuke/mindustry/entities/bullet/Bullet.java | 12 ++++++++---- .../mindustry/maps/generation/WorldGenerator.java | 4 ++-- .../blocks/defense/turrets/ArtilleryTurret.java | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java index 152429f1c1..09a37e1960 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java @@ -16,6 +16,7 @@ import io.anuke.ucore.entities.impl.BulletEntity; import io.anuke.ucore.entities.trait.Entity; import io.anuke.ucore.entities.trait.SolidTrait; import io.anuke.ucore.entities.trait.VelocityTrait; +import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Pooling; import io.anuke.ucore.util.Timer; @@ -23,13 +24,12 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import static io.anuke.mindustry.Vars.bulletGroup; -import static io.anuke.mindustry.Vars.content; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; public class Bullet extends BulletEntity implements TeamTrait, SyncTrait, AbsorbTrait{ private static Vector2 vector = new Vector2(); public Timer timer = new Timer(3); + private float lifeScl; private Team team; private Object data; private boolean supressCollision, supressOnce, initialized; @@ -68,7 +68,7 @@ public class Bullet extends BulletEntity implements TeamTrait, SyncT bullet.team = team; bullet.type = type; - bullet.time(type.lifetime() * (1f - lifetimeScl)); + bullet.lifeScl = lifetimeScl; //translate bullets backwards, purely for visual reasons float backDelta = Timers.delta(); @@ -227,6 +227,9 @@ public class Bullet extends BulletEntity implements TeamTrait, SyncT @Override protected void updateLife(){ + time += Timers.delta() * 1f/(lifeScl); + time = Mathf.clamp(time, 0, type.lifetime()); + if(time >= type.lifetime){ if(!supressCollision) type.despawned(this); remove(); @@ -237,6 +240,7 @@ public class Bullet extends BulletEntity implements TeamTrait, SyncT public void reset(){ super.reset(); timer.clear(); + lifeScl = 1f; team = null; data = null; supressCollision = false; diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index 1fd7c30ead..a8df8cf115 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -255,7 +255,7 @@ public class WorldGenerator{ double ridge = rid.getValue(x, y, 1f / 400f); double iceridge = rid.getValue(x+99999, y, 1f / 300f) + sim3.octaveNoise2D(2, 1f, 1f/14f, x, y)/11f; double elevation = elevationOf(x, y, detailed); - double temp = vn.noise(x, y, 1f / 300f) * sim3.octaveNoise2D(detailed ? 2 : 1, 1, 1f / 13f, x, y)/13f + double temp = + sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x, y); int lerpDst = 20; @@ -321,7 +321,7 @@ public class WorldGenerator{ double elevationOf(int x, int y, boolean detailed){ double ridge = rid.getValue(x, y, 1f / 400f); - return sim.octaveNoise2D(detailed ? 7 : 4, 0.62, 1f / 800, x, y) * 6.1 - 1 - ridge; + return sim.octaveNoise2D(detailed ? 7 : 5, 0.62, 1f / 800, x, y) * 6.1 - 1 - ridge; } public static class GenResult{ diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java index ec2b56e27d..21bfb9c100 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java @@ -38,7 +38,7 @@ public class ArtilleryTurret extends ItemTurret{ for(int i = 0; i < shots; i++){ Bullet.create(ammo.bullet, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, - entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), Mathf.clamp(dst / maxTraveled)); + entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled)); } effects(tile); From 98fff9b81db0781e05516e223ba642576337cf98 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 18 Sep 2018 11:54:08 -0400 Subject: [PATCH 03/22] Sector width/height --- core/src/io/anuke/mindustry/maps/Sector.java | 2 +- core/src/io/anuke/mindustry/maps/Sectors.java | 29 ++++++------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/core/src/io/anuke/mindustry/maps/Sector.java b/core/src/io/anuke/mindustry/maps/Sector.java index 4299cb5497..cad7bc5101 100644 --- a/core/src/io/anuke/mindustry/maps/Sector.java +++ b/core/src/io/anuke/mindustry/maps/Sector.java @@ -22,7 +22,7 @@ public class Sector{ /**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 size = 1; + public int width = 1, height = 1; /**Num of missions in this sector that have been completed so far.*/ public int completedMissions; /**Display texture. Needs to be disposed.*/ diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 965bbccc1a..745f4fb285 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -75,19 +75,14 @@ public class Sectors{ Sector sector = get(x, y); sector.complete = true; - for(GridPoint2 point : Edges.getEdges(sector.size)){ + //TODO work for unique width + height? + for(GridPoint2 point : Edges.getEdges(sector.width)){ createSector(sector.x + point.x, sector.y + point.y); } } /**Creates a sector at a location if it is not present, but does not unlock it.*/ public void createSector(int x, int y){ - boolean isLarge = Mathf.randomSeed(3+Bits.packInt((short)round2(x), (short)round2(y))) < sectorLargeChance; - - if(isLarge){ - x = round2(x); - y = round2(y); - } if(grid.containsKey(x, y)) return; @@ -95,11 +90,11 @@ public class Sectors{ sector.x = (short)x; sector.y = (short)y; sector.complete = false; - sector.size = isLarge ? 2 : 1; + sector.width = sector.height = 1; initSector(sector); - for(int cx = 0; cx < sector.size; cx++){ - for(int cy = 0; cy < sector.size; cy++){ + for(int cx = 0; cx < sector.width; cx++){ + for(int cy = 0; cy < sector.height; cy++){ grid.put(x + cx, y + cy, sector); } } @@ -118,8 +113,8 @@ public class Sectors{ for(Sector sector : out){ createTexture(sector); initSector(sector); - for(int cx = 0; cx < sector.size; cx++){ - for(int cy = 0; cy < sector.size; cy++){ + 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); } } @@ -155,8 +150,7 @@ public class Sectors{ sector.spawns = sector.missions.first().getWaves(sector); - //add all ores for now since material differences aren't well handled yet - sector.ores.addAll(Items.copper, Items.coal, Items.lead, Items.thorium, Items.titanium); + sector.ores.addAll(Items.copper); //set starter items if(sector.difficulty > 12){ //now with titanium @@ -174,15 +168,10 @@ public class Sectors{ } } - private int round2(int i){ - if(i < 0) i --; - return i/2*2; - } - private void createTexture(Sector sector){ if(headless) return; //obviously not created or needed on server - Pixmap pixmap = new Pixmap(sectorImageSize * sector.size, sectorImageSize * sector.size, Format.RGBA8888); + Pixmap pixmap = new Pixmap(sectorImageSize * sector.width, sectorImageSize * sector.height, Format.RGBA8888); for(int x = 0; x < pixmap.getWidth(); x++){ for(int y = 0; y < pixmap.getHeight(); y++){ From f61f3df7322bd4cc9ff09d57d6fbcd0940f58c90 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 20 Sep 2018 12:32:12 -0400 Subject: [PATCH 04/22] Build fix --- core/src/io/anuke/mindustry/core/World.java | 2 +- .../io/anuke/mindustry/maps/generation/FortressGenerator.java | 2 +- core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 16fd6f710e..5aa3e7ea01 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -232,7 +232,7 @@ public class World extends Module{ beginMapLoad(); - int width = sectorSize * sector.size, height = sectorSize * sector.size; + int width = sectorSize * sector.width, height = sectorSize * sector.height; Tile[][] tiles = createTiles(width, height); diff --git a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java index ade08e36b0..1176e781e3 100644 --- a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java @@ -70,7 +70,7 @@ public class FortressGenerator{ gen.setBlock(enemyX, enemyY, StorageBlocks.core, team); float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(1f/2f), 0f, 0.9999f); - int coreDst = FortressGenerator.coreDst*gen.sector.size; + int coreDst = FortressGenerator.coreDst*gen.sector.width; Array turrets = find(b -> b instanceof ItemTurret); Array powerTurrets = find(b -> b instanceof PowerTurret); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index de958c89d4..71df2edd8f 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -130,7 +130,7 @@ public class SectorsDialog extends FloatingDialog{ float drawY = y + height/2f + sectorY * padSectorSize - offsetY * padSectorSize - panY % padSectorSize; Sector sector = world.sectors().get(sectorX, sectorY); - int size = (sector == null ? 1 : sector.size); + int size = (sector == null ? 1 : sector.width); float padding = (size-1) * sectorPadding; if(sector != null && (sector.x != sectorX || sector.y != sectorY)){ From 950f4a9f1a7dbd4952a6d18780d63da67ee7789c Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 08:47:37 -0400 Subject: [PATCH 05/22] Added expandSector method --- core/src/io/anuke/mindustry/io/SaveIO.java | 2 +- core/src/io/anuke/mindustry/maps/Sectors.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index cbd9a3a803..ccef23d108 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -16,7 +16,7 @@ import java.util.zip.InflaterInputStream; import static io.anuke.mindustry.Vars.*; public class SaveIO{ - public static final IntArray breakingVersions = IntArray.with(47, 48, 49, 50, 51, 52); + public static final IntArray breakingVersions = IntArray.with(47, 48, 49, 50, 51, 52, 53, 54, 55, 56); public static final IntMap versions = new IntMap<>(); public static final Array versionArray = Array.with( new Save16() diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 965bbccc1a..d82989aa01 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -69,6 +69,16 @@ 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. + * 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){ + + return false; + } + /**Unlocks a sector. This shows nearby sectors.*/ public void completeSector(int x, int y){ createSector(x, y); From 569afb55352bf9bee0dee86f0b2b8affda245137 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 08:49:35 -0400 Subject: [PATCH 06/22] expandSector implementation --- core/src/io/anuke/mindustry/maps/Sectors.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index f5743b92eb..8e5e511ad9 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -75,6 +75,23 @@ public class Sectors{ * @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){ + sector.width += expandX; + sector.height += expandY; + + 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, null); + } + } + + if(expandX < 0) sector.x += expandX; + if(expandY < 0) sector.y += expandY; + + 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); + } + } return false; } From fd8f2438fac357444bed4e5c4918e140d76e977e Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 13:50:39 -0400 Subject: [PATCH 07/22] New world generation methods --- core/src/io/anuke/mindustry/core/World.java | 6 ++ core/src/io/anuke/mindustry/maps/Sectors.java | 71 ++++++++++++++++++- .../maps/generation/WorldGenerator.java | 31 +++++--- .../world/blocks/storage/CoreBlock.java | 8 +++ 4 files changed, 105 insertions(+), 11 deletions(-) diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 5aa3e7ea01..e149c2e7ab 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -195,6 +195,12 @@ public class World extends Module{ generating = true; } + /**Call to signal the beginning of loading the map with a custom set of tiles.*/ + public void beginMapLoad(Tile[][] tiles){ + this.tiles = tiles; + generating = true; + } + /** * Call to signify the end of map loading. Updates tile occlusions and sets up physics for the world. * A WorldLoadEvent will be fire. diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 8e5e511ad9..4b0c82eda8 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -15,7 +15,11 @@ import io.anuke.mindustry.maps.missions.WaveMission; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.Edges; +import io.anuke.mindustry.world.Tile; 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.Bits; import io.anuke.ucore.util.GridMap; import io.anuke.ucore.util.Log; @@ -25,6 +29,7 @@ import static io.anuke.mindustry.Vars.*; public class Sectors{ private static final int sectorImageSize = 32; + private static final boolean checkExpansion = false; private static final float sectorLargeChance = 0.24f; private GridMap grid = new GridMap<>(); @@ -78,6 +83,7 @@ public class Sectors{ sector.width += expandX; sector.height += expandY; + //remove old sector data to clear things up 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, null); @@ -87,13 +93,76 @@ public class Sectors{ 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).complete) { + //if a completed sector is hit, expansion failed + if (expandX < 0) sector.x -= expandX; + if (expandY < 0) sector.y -= expandY; + sector.width -= Math.abs(expandX); + sector.height -= Math.abs(expandY); + return false; + } + } + } + } + + //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); } } - return false; + //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); + } + } + + //create *new* tile array + Tile[][] newTiles = new Tile[sector.width * sectorSize][sector.height * sectorSize]; + + world.beginMapLoad(newTiles); + + //shift existing tiles to new array + for (int x = 0; x < (sector.width - Math.abs(expandX)); x++) { + for (int y = 0; y < (sector.height - Math.abs(expandY)); y++) { + Tile tile = world.rawTile(x, y); + tile.x = (short)(x + shiftX); + tile.y = (short)(y + shiftY); + newTiles[x + shiftX][y + shiftY] = tile; + } + } + + //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){ + //gen tiles in sector + for (int x = 0; x < sectorSize; x++) { + for (int y = 0; y < sectorSize; y++) { + GenResult result = world.generator().generateTile(sx + sector.x, sy + sector.y, x, y); + newTiles[sx * sectorSize + x][sy * sectorSize + y] = new Tile(x + sx * tilesize, y + sy*tilesize, result.floor.id, result.wall.id, (byte)0, (byte)0, result.elevation); + } + } + } + } + } + + //end loading of map + world.endMapLoad(); + + return true; } /**Unlocks a sector. This shows nearby sectors.*/ diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index a8df8cf115..97a4638c8c 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -8,7 +8,6 @@ import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.content.blocks.OreBlocks; -import io.anuke.mindustry.content.blocks.StorageBlocks; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.maps.MapTileData; import io.anuke.mindustry.maps.MapTileData.TileDataMarker; @@ -26,7 +25,8 @@ import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.SeedRandom; -import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.Vars.sectorSize; +import static io.anuke.mindustry.Vars.world; public class WorldGenerator{ @@ -73,6 +73,11 @@ public class WorldGenerator{ generateOres(tiles, seed, genOres, null); } + /**'Prepares' a tile array by:
+ * - setting up multiblocks
+ * - updating cliff data
+ * - removing ores on cliffs
+ * Usually used before placing structures on a tile array.*/ public void prepareTiles(Tile[][] tiles){ //find multiblocks @@ -82,14 +87,8 @@ public class WorldGenerator{ for(int y = 0; y < tiles[0].length; y++){ Tile tile = tiles[x][y]; - Team team = tile.getTeam(); - - if(tile.block() == StorageBlocks.core){ - state.teams.get(team).cores.add(tile); - } - - if(tiles[x][y].block().isMultiblock()){ - multiblocks.add(tiles[x][y].packedPosition()); + if(tile.block().isMultiblock()){ + multiblocks.add(tile.packedPosition()); } } } @@ -134,6 +133,7 @@ public class WorldGenerator{ tile.setBlock(Blocks.air); } + //remove ore veins on cliffs if(tile.floor() instanceof OreBlock && tile.hasCliffs()){ tile.setFloor(((OreBlock)tile.floor()).base); } @@ -245,6 +245,17 @@ public class WorldGenerator{ return generateTile(result, sectorX, sectorY, localX, localY, detailed, null); } + /** + * Gets the generation result from a specific sector at specific coordinates. + * @param result where to put the generation results + * @param sectorX X of the sector in terms of sector coordinates + * @param sectorY Y of the sector in terms of sector coordinates + * @param localX X in terms of local sector tile coordinates + * @param localY Y in terms of local sector tile coordinates + * @param detailed whether the tile result is 'detailed' (e.g. previews should not be detailed) + * @param spawnpoints list of player spawnpoints, can be null + * @return the GenResult passed in with its values modified + */ public GenResult generateTile(GenResult result, int sectorX, int sectorY, int localX, int localY, boolean detailed, Array spawnpoints){ int x = sectorX * sectorSize + localX + Short.MAX_VALUE; int y = sectorY * sectorSize + localY + Short.MAX_VALUE; diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index 09e3046723..958994594f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -79,6 +79,14 @@ public class CoreBlock extends StorageBlock{ if(entity != null) entity.solid = solid; } + @Override + public void onProximityUpdate(Tile tile) { + //add cores + if(!state.teams.get(tile.getTeam()).cores.contains(tile, true)){ + state.teams.get(tile.getTeam()).cores.add(tile); + } + } + @Override public boolean canBreak(Tile tile){ return state.teams.get(tile.getTeam()).cores.size > 1; From bee83a3a3ed9b5249b3a9d8af6bf706cf1f5e41c Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 14:01:00 -0400 Subject: [PATCH 08/22] Sector expansion functional --- core/src/io/anuke/mindustry/maps/Sectors.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 4b0c82eda8..373a6bba59 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -80,8 +80,6 @@ public class Sectors{ * @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){ - sector.width += expandX; - sector.height += expandY; //remove old sector data to clear things up for(int x = sector.x; x < sector.x+sector.width; x++){ @@ -131,11 +129,9 @@ public class Sectors{ //create *new* tile array Tile[][] newTiles = new Tile[sector.width * sectorSize][sector.height * sectorSize]; - world.beginMapLoad(newTiles); - //shift existing tiles to new array - for (int x = 0; x < (sector.width - Math.abs(expandX)); x++) { - for (int y = 0; y < (sector.height - Math.abs(expandY)); y++) { + 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); @@ -143,6 +139,8 @@ public class Sectors{ } } + world.beginMapLoad(newTiles); + //create new tiles for (int sx = 0; sx < sector.width; sx++) { for (int sy = 0; sy < sector.height; sy++) { From 90691de457e3651f61bfb185fc7d74e61529f979 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 16:11:40 -0400 Subject: [PATCH 09/22] Fog persistence in sector expansion --- .../anuke/mindustry/graphics/FogRenderer.java | 29 ++++++++++++++++++- core/src/io/anuke/mindustry/maps/Sectors.java | 6 +++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/core/src/io/anuke/mindustry/graphics/FogRenderer.java b/core/src/io/anuke/mindustry/graphics/FogRenderer.java index 5f65bbbbae..031abfe8c1 100644 --- a/core/src/io/anuke/mindustry/graphics/FogRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FogRenderer.java @@ -40,21 +40,40 @@ public class FogRenderer implements Disposable{ private Rectangle rect = new Rectangle(); private boolean dirty; + private boolean isOffseted; + private int offsettedX, offsettedY; + public FogRenderer(){ Events.on(WorldLoadGraphicsEvent.class, event -> { - dispose(); + if(!isOffseted){ + dispose(); + } padding = world.getSector() != null ? mapPadding + extraPadding : 0; shadowPadding = world.getSector() != null ? fshadowPadding : -1; + FrameBuffer lastBuffer = buffer; + buffer = new FrameBuffer(Format.RGBA8888, world.width() + padding*2, world.height() + padding*2, false); changeQueue.clear(); //clear buffer to black buffer.begin(); Graphics.clear(0, 0, 0, 1f); + + if(isOffseted){ + Core.batch.getProjectionMatrix().setToOrtho2D(-padding, -padding, buffer.getWidth(), buffer.getHeight()); + Core.batch.begin(); + Core.batch.draw(lastBuffer.getColorBufferTexture(), offsettedX, offsettedY + lastBuffer.getColorBufferTexture().getHeight(), + lastBuffer.getColorBufferTexture().getWidth(), -lastBuffer.getColorBufferTexture().getHeight()); + Core.batch.end(); + } buffer.end(); + if(isOffseted){ + lastBuffer.dispose(); + } + for(int x = 0; x < world.width(); x++){ for(int y = 0; y < world.height(); y++){ Tile tile = world.tile(x, y); @@ -66,6 +85,8 @@ public class FogRenderer implements Disposable{ pixelBuffer = ByteBuffer.allocateDirect(world.width() * world.height() * 4); dirty = true; + + isOffseted = false; }); Events.on(TileChangeEvent.class, event -> threads.runGraphics(() -> { @@ -75,6 +96,12 @@ public class FogRenderer implements Disposable{ })); } + public void setLoadingOffset(int x, int y){ + isOffseted = true; + offsettedX = x; + offsettedY = y; + } + public void writeFog(){ if(buffer == null) return; diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 373a6bba59..f5d5083cf4 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -126,6 +126,10 @@ public class Sectors{ } } + if(!headless){ + renderer.fog().setLoadingOffset(shiftX, shiftY); + } + //create *new* tile array Tile[][] newTiles = new Tile[sector.width * sectorSize][sector.height * sectorSize]; @@ -150,7 +154,7 @@ public class Sectors{ for (int x = 0; x < sectorSize; x++) { for (int y = 0; y < sectorSize; y++) { GenResult result = world.generator().generateTile(sx + sector.x, sy + sector.y, x, y); - newTiles[sx * sectorSize + x][sy * sectorSize + y] = new Tile(x + sx * tilesize, y + sy*tilesize, result.floor.id, result.wall.id, (byte)0, (byte)0, result.elevation); + 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); } } } From b124d540552679064aa67d4c253ec9eec3bbf690 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 16:32:38 -0400 Subject: [PATCH 10/22] Merge --- core/src/io/anuke/mindustry/maps/Sectors.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 8e5e511ad9..6e772854c6 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -70,11 +70,16 @@ public class Sectors{ } /**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!"); + } + sector.width += expandX; sector.height += expandY; From d067bbfa65a78df45f541c496a138e40f673d554 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 19:36:19 -0400 Subject: [PATCH 11/22] New mission classes --- core/assets/bundles/bundle.properties | 3 +- .../mindustry/content/blocks/DebugBlocks.java | 1 - core/src/io/anuke/mindustry/core/Control.java | 3 ++ core/src/io/anuke/mindustry/core/UI.java | 6 +-- .../mindustry/editor/MapEditorDialog.java | 14 +++--- .../src/io/anuke/mindustry/game/GameMode.java | 6 +++ core/src/io/anuke/mindustry/maps/Sector.java | 5 +- .../maps/generation/WorldGenerator.java | 4 -- .../maps/missions/ActionMission.java | 34 +++++++++++++ .../maps/missions/BattleMission.java | 5 -- .../mindustry/maps/missions/BlockMission.java | 49 +++++++++++++++++++ .../maps/missions/ExpandMission.java | 17 +++++++ .../mindustry/maps/missions/Mission.java | 5 +- .../maps/missions/ResourceMission.java | 17 ++++--- .../maps/missions/VictoryMission.java | 26 ++++++++++ .../mindustry/maps/missions/WaveMission.java | 11 ++--- .../mindustry/ui/dialogs/SaveDialog.java | 2 +- .../mindustry/ui/fragments/MenuFragment.java | 4 +- 18 files changed, 172 insertions(+), 40 deletions(-) create mode 100644 core/src/io/anuke/mindustry/maps/missions/ActionMission.java create mode 100644 core/src/io/anuke/mindustry/maps/missions/BlockMission.java create mode 100644 core/src/io/anuke/mindustry/maps/missions/ExpandMission.java create mode 100644 core/src/io/anuke/mindustry/maps/missions/VictoryMission.java diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index adfa391de8..eb5e1d1143 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -63,6 +63,7 @@ text.mission.complete.body=Sector {0},{1} has been conquered. text.mission.wave=Survive [accent]{0}[] waves. text.mission.battle=Destroy the enemy base. text.mission.resource=Obtain {0} x{1} +text.mission.block=Create '{0}' structure text.none= text.close=Close text.quit=Quit @@ -617,7 +618,7 @@ block.rotary-pump.name=Rotary Pump block.thorium-reactor.name=Thorium Reactor block.command-center.name=Command Center block.mass-driver.name=Mass Driver -block.blast-drill.name=Blast Drill +block.blast-drill.name=Airblast Drill block.thermal-pump.name=Thermal Pump block.thermal-generator.name=Thermal Generator block.alloy-smelter.name=Alloy Smelter diff --git a/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java index abaaaf2a0c..7839c41d06 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java @@ -129,7 +129,6 @@ public class DebugBlocks extends BlockList implements ContentList{ Table cont = new Table(); for(int i = 0; i < items.size; i++){ - if(i == 0) continue; final int f = i; ImageButton button = cont.addImageButton("liquid-icon-" + items.get(i).name, "toggle", 24, () -> { Call.setLiquidSourceLiquid(null, tile, items.get(f)); diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 61246c4245..6727b8bf20 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -13,6 +13,7 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.ContentDatabase; import io.anuke.mindustry.game.EventType.*; +import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.Saves; import io.anuke.mindustry.input.DefaultKeybinds; import io.anuke.mindustry.input.DesktopInput; @@ -378,11 +379,13 @@ public class Control extends Module{ if(world.getSector() != null && !world.getSector().complete){ //all assigned missions are complete if(world.getSector().completedMissions >= world.getSector().missions.size){ + state.mode = GameMode.victory; world.sectors().completeSector(world.getSector().x, world.getSector().y); world.sectors().save(); ui.missions.show(world.getSector()); }else if(world.getSector().currentMission().isComplete()){ + state.mode = world.getSector().currentMission().getMode(); //increment completed missions, check next index next frame world.getSector().completedMissions ++; } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 6ed35d773f..835a603c7c 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -210,11 +210,11 @@ public class UI extends SceneModule{ } } - public void loadAnd(Runnable call){ - loadAnd("$text.loading", call); + public void loadGraphics(Runnable call){ + loadGraphics("$text.loading", call); } - public void loadAnd(String text, Runnable call){ + public void loadGraphics(String text, Runnable call){ loadfrag.show(text); Timers.runTask(7f, () -> { call.run(); diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 472167176d..552ba7f57e 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -95,7 +95,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ "$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Runnable) loadDialog::show, "$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () -> { Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> { - ui.loadAnd(() -> { + ui.loadGraphics(() -> { try{ DataInputStream stream = new DataInputStream(file.read()); @@ -116,7 +116,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ ui.showError("$text.web.unsupported"); }else { Platform.instance.showFileChooser("$text.loadimage", "Image Files", file -> { - ui.loadAnd(() -> { + ui.loadGraphics(() -> { try{ MapTileData data = MapIO.readPixmap(new Pixmap(file)); @@ -137,7 +137,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> { file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension); FileHandle result = file; - ui.loadAnd(() -> { + ui.loadGraphics(() -> { try{ if(!editor.getTags().containsKey("name")){ @@ -168,7 +168,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ Platform.instance.showFileChooser("$text.saveimage", "Image Files", file -> { file = file.parent().child(file.nameWithoutExtension() + ".png"); FileHandle result = file; - ui.loadAnd(() -> { + ui.loadGraphics(() -> { try{ Pixmaps.write(MapIO.generatePixmap(editor.getMap()), result); }catch (Exception e){ @@ -194,7 +194,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ resizeDialog = new MapResizeDialog(editor, (x, y) -> { if(!(editor.getMap().width() == x && editor.getMap().height() == y)){ - ui.loadAnd(() -> { + ui.loadGraphics(() -> { editor.resize(x, y); view.clearStack(); }); @@ -203,7 +203,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ loadDialog = new MapLoadDialog(map -> { - ui.loadAnd(() -> { + ui.loadGraphics(() -> { try(DataInputStream stream = new DataInputStream(map.stream.get())){ MapMeta meta = MapIO.readMapMeta(stream); MapTileData data = MapIO.readTileData(stream, meta, false); @@ -338,7 +338,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ } public void beginEditMap(InputStream is){ - ui.loadAnd(() -> { + ui.loadGraphics(() -> { try{ shownWithMap = true; DataInputStream stream = new DataInputStream(is); diff --git a/core/src/io/anuke/mindustry/game/GameMode.java b/core/src/io/anuke/mindustry/game/GameMode.java index 7d0de33ad9..4c21688166 100644 --- a/core/src/io/anuke/mindustry/game/GameMode.java +++ b/core/src/io/anuke/mindustry/game/GameMode.java @@ -17,6 +17,12 @@ public enum GameMode{ enemyCheat = true; showPads = true; }}, + victory{{ + disableWaves = true; + hidden = true; + enemyCheat = false; + showPads = true; + }}, pvp{{ showPads = true; disableWaves = true; diff --git a/core/src/io/anuke/mindustry/maps/Sector.java b/core/src/io/anuke/mindustry/maps/Sector.java index cad7bc5101..fc1b32db65 100644 --- a/core/src/io/anuke/mindustry/maps/Sector.java +++ b/core/src/io/anuke/mindustry/maps/Sector.java @@ -7,6 +7,7 @@ import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.Saves.SaveSlot; import io.anuke.mindustry.game.SpawnGroup; import io.anuke.mindustry.maps.missions.Mission; +import io.anuke.mindustry.maps.missions.VictoryMission; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.ucore.util.Bits; @@ -15,6 +16,8 @@ import static io.anuke.mindustry.Vars.control; @Serialize public class Sector{ + private static final Mission victoryMission = new VictoryMission(); + /**Position on the map, can be positive or negative.*/ public short x, y; /**Whether this sector has already been completed.*/ @@ -52,7 +55,7 @@ public class Sector{ } public Mission currentMission(){ - return missions.get(Math.min(completedMissions, missions.size - 1)); + return completedMissions >= missions.size ? victoryMission : missions.get(completedMissions); } public int getSeed(){ diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index 97a4638c8c..a1c9b9760c 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -20,7 +20,6 @@ import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.OreBlock; import io.anuke.ucore.noise.RidgedPerlin; import io.anuke.ucore.noise.Simplex; -import io.anuke.ucore.noise.VoronoiNoise; import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.SeedRandom; @@ -37,15 +36,12 @@ public class WorldGenerator{ private Simplex sim2 = new Simplex(baseSeed + 1); private Simplex sim3 = new Simplex(baseSeed + 2); private RidgedPerlin rid = new RidgedPerlin(baseSeed + 4, 1); - private VoronoiNoise vn = new VoronoiNoise(baseSeed + 2, (short)0); private SeedRandom random = new SeedRandom(baseSeed + 3); private GenResult result = new GenResult(); private ObjectMap decoration; public WorldGenerator(){ - vn.setUseDistance(true); - decoration = Mathf.map( Blocks.grass, Blocks.shrub, Blocks.stone, Blocks.rock, diff --git a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java new file mode 100644 index 0000000000..da93050101 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java @@ -0,0 +1,34 @@ +package io.anuke.mindustry.maps.missions; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.game.GameMode; + +import static io.anuke.mindustry.Vars.threads; + +/**A mission which simply runs a single action and is completed instantly.*/ +public abstract class ActionMission implements Mission{ + private Runnable runner; + + public ActionMission(Runnable runner){ + this.runner = runner; + } + + @Override + public boolean isComplete(){ + if(runner != null){ + threads.run(runner); + runner = null; + } + return true; + } + + @Override + public String displayString(){ + return ""; + } + + @Override + public GameMode getMode(){ + return Vars.state.mode; + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java index 97230888e5..cdfc10d28b 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java @@ -7,15 +7,10 @@ import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.maps.generation.FortressGenerator; import io.anuke.mindustry.maps.generation.Generation; -import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; public class BattleMission implements Mission{ private final static int coreX = 60, coreY = 60; - @Override - public void display(Table table){ - table.add("$text.mission.battle"); - } @Override public GameMode getMode(){ diff --git a/core/src/io/anuke/mindustry/maps/missions/BlockMission.java b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java new file mode 100644 index 0000000000..2c522208a1 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java @@ -0,0 +1,49 @@ +package io.anuke.mindustry.maps.missions; + +import io.anuke.mindustry.game.EventType.BlockBuildEvent; +import io.anuke.mindustry.game.GameMode; +import io.anuke.mindustry.world.Block; +import io.anuke.ucore.core.Events; +import io.anuke.ucore.util.Bundles; + +import static io.anuke.mindustry.Vars.defaultTeam; +import static io.anuke.mindustry.Vars.world; + +/**A mission in which the player must place a block.*/ +public class BlockMission implements Mission{ + private final Block block; + private boolean complete; + + static{ + Events.on(BlockBuildEvent.class, event -> { + if(world.getSector() != null && event.team == defaultTeam){ + Mission mission = world.getSector().currentMission(); + if(mission instanceof BlockMission){ + BlockMission block = (BlockMission)world.getSector().currentMission(); + if(block.block == event.tile.block()){ + block.complete = true; + } + } + } + }); + } + + public BlockMission(Block block){ + this.block = block; + } + + @Override + public boolean isComplete(){ + return complete; + } + + @Override + public String displayString(){ + return Bundles.format("text.mission.block", block.formalName); + } + + @Override + public GameMode getMode(){ + return GameMode.noWaves; + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java b/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java new file mode 100644 index 0000000000..33999eab73 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java @@ -0,0 +1,17 @@ +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{ + + public ExpandMission(int expandX, int expandY){ + super(() -> { + if(headless){ + world.sectors().expandSector(world.getSector(), expandX, expandY); + }else{ + ui.loadLogic(() -> world.sectors().expandSector(world.getSector(), expandX, expandY)); + } + }); + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index 5c20056d27..351d7daf4a 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -14,7 +14,10 @@ public interface Mission{ boolean isComplete(); String displayString(); GameMode getMode(); - void display(Table table); + + default void display(Table table){ + table.add(displayString()); + } default Array getWaves(Sector sector){ return new Array<>(); diff --git a/core/src/io/anuke/mindustry/maps/missions/ResourceMission.java b/core/src/io/anuke/mindustry/maps/missions/ResourceMission.java index d2a21f2975..dd59c89386 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ResourceMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ResourceMission.java @@ -3,9 +3,12 @@ package io.anuke.mindustry.maps.missions; import io.anuke.mindustry.Vars; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.type.Item; -import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.mindustry.world.Tile; import io.anuke.ucore.util.Bundles; +import static io.anuke.mindustry.Vars.state; + +/**A mission that is completed when the player obtains items in their core.*/ public class ResourceMission implements Mission{ private final Item item; private final int amount; @@ -15,11 +18,6 @@ public class ResourceMission implements Mission{ this.amount = amount; } - @Override - public void display(Table table){ - - } - @Override public GameMode getMode(){ return GameMode.waves; @@ -27,7 +25,12 @@ public class ResourceMission implements Mission{ @Override public boolean isComplete(){ - return Vars.state.teams.get(Vars.defaultTeam).cores.first().entity.items.has(item, amount); + for(Tile tile : state.teams.get(Vars.defaultTeam).cores){ + if(tile.entity.items.has(item, amount)){ + return true; + } + } + return false; } @Override diff --git a/core/src/io/anuke/mindustry/maps/missions/VictoryMission.java b/core/src/io/anuke/mindustry/maps/missions/VictoryMission.java new file mode 100644 index 0000000000..fd3e912170 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/VictoryMission.java @@ -0,0 +1,26 @@ +package io.anuke.mindustry.maps.missions; + +import io.anuke.mindustry.game.GameMode; +import io.anuke.ucore.scene.ui.layout.Table; + +public class VictoryMission implements Mission{ + @Override + public boolean isComplete(){ + return false; + } + + @Override + public String displayString(){ + return "none"; + } + + @Override + public GameMode getMode(){ + return GameMode.victory; + } + + @Override + public void display(Table table){ + + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index f75450125e..2a1fc27ea7 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -2,10 +2,12 @@ package io.anuke.mindustry.maps.missions; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; -import io.anuke.mindustry.game.*; +import io.anuke.mindustry.game.GameMode; +import io.anuke.mindustry.game.SpawnGroup; +import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.game.Waves; import io.anuke.mindustry.maps.Sector; import io.anuke.mindustry.maps.generation.Generation; -import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.state; @@ -28,11 +30,6 @@ public class WaveMission implements Mission{ generateCoreAt(gen, coreX, coreY, Team.blue); } - @Override - public void display(Table table){ - table.add(Bundles.format("text.mission.wave", target)); - } - @Override public GameMode getMode(){ return GameMode.waves; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java index 4b97bb82f8..c501f796f5 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java @@ -24,7 +24,7 @@ public class SaveDialog extends LoadDialog{ slots.row(); slots.addImageTextButton("$text.save.new", "icon-add", "clear", 14 * 3, () -> ui.showTextInput("$text.save", "$text.save.newslot", "", text -> { - ui.loadAnd("$text.saving", () -> { + ui.loadGraphics("$text.saving", () -> { control.getSaves().addSave(text); threads.runGraphics(() -> threads.run(() -> threads.runGraphics(this::setup))); }); diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index 9cf67392bd..703a8a6fb9 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -59,7 +59,7 @@ public class MenuFragment extends Fragment{ maps = new MobileButton("icon-map", isize, "$text.maps", ui.maps::show), load = new MobileButton("icon-load", isize, "$text.load", ui.load::show), join = new MobileButton("icon-add", isize, "$text.joingame", ui.join::show), - editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadAnd(ui.editor::show)), + editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadGraphics(ui.editor::show)), tools = new MobileButton("icon-tools", isize, "$text.settings", ui.settings::show), unlocks = new MobileButton("icon-unlocks", isize, "$text.unlocks", ui.unlocks::show), donate = new MobileButton("icon-donate", isize, "$text.donate", Platform.instance::openDonations); @@ -114,7 +114,7 @@ public class MenuFragment extends Fragment{ out.row(); - out.add(new MenuButton("icon-editor", "$text.editor", () -> ui.loadAnd(ui.editor::show))); + out.add(new MenuButton("icon-editor", "$text.editor", () -> ui.loadGraphics(ui.editor::show))); out.add(new MenuButton("icon-map", "$text.maps", ui.maps::show)); From a1a6a3ab8166047b5d1062d321f6a229dc17747d Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 23:14:26 -0400 Subject: [PATCH 12/22] Tutorial sector prototype / New mission display --- core/assets/bundles/bundle.properties | 5 +- core/src/io/anuke/mindustry/Vars.java | 2 +- core/src/io/anuke/mindustry/core/Control.java | 4 +- .../io/anuke/mindustry/game/EventType.java | 4 +- .../src/io/anuke/mindustry/game/GameMode.java | 3 +- core/src/io/anuke/mindustry/maps/Sectors.java | 46 +++++++++++++++---- .../maps/generation/WorldGenerator.java | 1 + .../maps/missions/ActionMission.java | 9 ++-- ...{ResourceMission.java => ItemMission.java} | 4 +- .../mindustry/maps/missions/Mission.java | 12 ++++- .../mindustry/maps/missions/UnitMission.java | 35 ++++++++++++++ .../mindustry/maps/missions/WaveMission.java | 2 +- .../mindustry/ui/fragments/HudFragment.java | 12 +---- .../anuke/mindustry/server/ServerControl.java | 1 + 14 files changed, 104 insertions(+), 36 deletions(-) rename core/src/io/anuke/mindustry/maps/missions/{ResourceMission.java => ItemMission.java} (90%) create mode 100644 core/src/io/anuke/mindustry/maps/missions/UnitMission.java diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index eb5e1d1143..57806fe23c 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -60,10 +60,11 @@ text.sector.unexplored=[accent][[Unexplored] text.mission=Mission:[LIGHT_GRAY] {0} text.mission.complete=Mission complete! text.mission.complete.body=Sector {0},{1} has been conquered. -text.mission.wave=Survive [accent]{0}[] waves. +text.mission.wave=Survive [accent]{0} []waves. text.mission.battle=Destroy the enemy base. text.mission.resource=Obtain {0} x{1} -text.mission.block=Create '{0}' structure +text.mission.block=Create {0} +text.mission.unit=Create {0} Unit text.none= text.close=Close text.quit=Quit diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 7f978345c3..f7f3c0dd74 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -48,7 +48,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 = 150; + public static final int sectorSize = 140; 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 6727b8bf20..488f2b3bf6 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -375,6 +375,7 @@ public class Control extends Module{ Platform.instance.updateRPC(); } + //TODO move sector code into logic class //check unlocked sectors if(world.getSector() != null && !world.getSector().complete){ //all assigned missions are complete @@ -385,9 +386,10 @@ public class Control extends Module{ world.sectors().save(); ui.missions.show(world.getSector()); }else if(world.getSector().currentMission().isComplete()){ - state.mode = world.getSector().currentMission().getMode(); + world.getSector().currentMission().onComplete(); //increment completed missions, check next index next frame world.getSector().completedMissions ++; + state.mode = world.getSector().currentMission().getMode(); } } diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java index c6ed9f37fe..150e942fd9 100644 --- a/core/src/io/anuke/mindustry/game/EventType.java +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -42,9 +42,7 @@ public class EventType{ } - /** - * Called from the logic thread. Do not access graphics here! - */ + /**Called from the logic thread. Do not access graphics here!*/ public static class TileChangeEvent implements Event{ public final Tile tile; diff --git a/core/src/io/anuke/mindustry/game/GameMode.java b/core/src/io/anuke/mindustry/game/GameMode.java index 4c21688166..13fa56e6a2 100644 --- a/core/src/io/anuke/mindustry/game/GameMode.java +++ b/core/src/io/anuke/mindustry/game/GameMode.java @@ -22,6 +22,7 @@ public enum GameMode{ hidden = true; enemyCheat = false; showPads = true; + showMission = false; }}, pvp{{ showPads = true; @@ -32,7 +33,7 @@ public enum GameMode{ respawnTime = 60 * 10; }}; - public boolean infiniteResources, disableWaveTimer, disableWaves, hidden, enemyCheat, isPvp, showPads; + public boolean infiniteResources, disableWaveTimer, disableWaves, showMission = true, hidden, enemyCheat, isPvp, showPads; public float enemyCoreBuildRadius = 400f; public float respawnTime = 60 * 4; diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index db9dffacbd..664e50d1b3 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -3,18 +3,17 @@ package io.anuke.mindustry.maps; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.Items; +import io.anuke.mindustry.content.UnitTypes; +import io.anuke.mindustry.content.blocks.*; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; -import io.anuke.mindustry.maps.missions.BattleMission; -import io.anuke.mindustry.maps.missions.WaveMission; +import io.anuke.mindustry.maps.missions.*; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.ColorMapper; -import io.anuke.mindustry.world.Edges; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Settings; import io.anuke.ucore.entities.Entities; @@ -177,9 +176,16 @@ public class Sectors{ Sector sector = get(x, y); sector.complete = true; - //TODO work for unique width + height? - for(GridPoint2 point : Edges.getEdges(sector.width)){ - createSector(sector.x + point.x, sector.y + point.y); + 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); + } + } } } @@ -244,7 +250,27 @@ public class Sectors{ sector.difficulty = (int)(Mathf.dst(sector.x, sector.y)); if(sector.difficulty == 0){ - sector.missions.add(new WaveMission(10)); + //TODO make specfic expansion sector have specific ores + sector.missions.addAll(Array.with( + new ItemMission(Items.copper, 30), + new BlockMission(ProductionBlocks.mechanicalDrill), + new BlockMission(DistributionBlocks.conveyor), + new ItemMission(Items.copper, 40), + new BlockMission(TurretBlocks.duo), + new WaveMission(5), + new ExpandMission(1, 0), + new ItemMission(Items.lead, 30), + new BlockMission(CraftingBlocks.smelter), + new ItemMission(Items.densealloy, 30), + new BlockMission(PowerBlocks.combustionGenerator), + new BlockMission(PowerBlocks.powerNode), + new BlockMission(CraftingBlocks.siliconsmelter), + new ItemMission(Items.silicon, 30), + new BlockMission(UnitBlocks.daggerFactory), + new UnitMission(UnitTypes.dagger), + new ExpandMission(0, 1), + new BattleMission() + )); }else{ sector.missions.add(Mathf.randomSeed(sector.getSeed() + 1) < waveChance ? new WaveMission(Math.min(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 0, 3)*5, 100)) : new BattleMission()); @@ -265,8 +291,8 @@ public class Sectors{ sector.startingItems = Array.with(new ItemStack(Items.copper, 700), new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 130)); }else if(sector.difficulty > 1){ //more starter items for faster start sector.startingItems = Array.with(new ItemStack(Items.copper, 400), new ItemStack(Items.lead, 100)); - }else{ //base starting items to prevent grinding much - sector.startingItems = Array.with(new ItemStack(Items.copper, 130)); + }else{ //empty default + sector.startingItems = Array.with(); } } diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index a1c9b9760c..a5e21c0c5c 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -241,6 +241,7 @@ public class WorldGenerator{ return generateTile(result, sectorX, sectorY, localX, localY, detailed, null); } + //TODO include tile in result /** * Gets the generation result from a specific sector at specific coordinates. * @param result where to put the generation results diff --git a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java index da93050101..7c8ee53b0f 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java @@ -13,12 +13,13 @@ public abstract class ActionMission implements Mission{ this.runner = runner; } + @Override + public void onComplete(){ + threads.run(runner); + } + @Override public boolean isComplete(){ - if(runner != null){ - threads.run(runner); - runner = null; - } return true; } diff --git a/core/src/io/anuke/mindustry/maps/missions/ResourceMission.java b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java similarity index 90% rename from core/src/io/anuke/mindustry/maps/missions/ResourceMission.java rename to core/src/io/anuke/mindustry/maps/missions/ItemMission.java index dd59c89386..63b6b14ffd 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ResourceMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java @@ -9,11 +9,11 @@ import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.state; /**A mission that is completed when the player obtains items in their core.*/ -public class ResourceMission implements Mission{ +public class ItemMission implements Mission{ private final Item item; private final int amount; - public ResourceMission(Item item, int amount){ + public ItemMission(Item item, int amount){ this.item = item; this.amount = amount; } diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index 351d7daf4a..fc3b0d2fc1 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.maps.missions; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.blocks.StorageBlocks; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.SpawnGroup; @@ -13,7 +14,16 @@ import io.anuke.ucore.scene.ui.layout.Table; public interface Mission{ boolean isComplete(); String displayString(); - GameMode getMode(); + + default GameMode getMode(){ + return GameMode.noWaves; + } + + default void onComplete(){ + if(!Vars.headless){ + //TODO show 'mission complete' message somewhere + } + } default void display(Table table){ table.add(displayString()); diff --git a/core/src/io/anuke/mindustry/maps/missions/UnitMission.java b/core/src/io/anuke/mindustry/maps/missions/UnitMission.java new file mode 100644 index 0000000000..841ad39c89 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/UnitMission.java @@ -0,0 +1,35 @@ +package io.anuke.mindustry.maps.missions; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.entities.units.BaseUnit; +import io.anuke.mindustry.entities.units.UnitType; +import io.anuke.mindustry.game.GameMode; +import io.anuke.ucore.util.Bundles; + +public class UnitMission implements Mission{ + private final UnitType type; + + public UnitMission(UnitType type){ + this.type = type; + } + + @Override + public boolean isComplete(){ + for(BaseUnit unit : Vars.unitGroups[Vars.defaultTeam.ordinal()].all()){ + if(unit.getType() == type){ + return true; + } + } + return false; + } + + @Override + public String displayString(){ + return Bundles.format("text.mission.unit", type.localizedName()); + } + + @Override + public GameMode getMode(){ + return GameMode.noWaves; + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index 2a1fc27ea7..bae5ad832c 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -37,7 +37,7 @@ public class WaveMission implements Mission{ @Override public String displayString(){ - return Bundles.format("text.mission.wave", target); + return Bundles.format("text.mission.wave", state.wave); } @Override diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index d8639ddb13..80f216cf9a 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -320,17 +320,9 @@ public class HudFragment extends Fragment{ IntFormat timef = new IntFormat("text.wave.waiting"); table.background("button"); - table.left().table(text -> { - text.left(); - text.label(() -> wavef.get(state.wave)).left().get().setFontScale(fontScale * 1.5f); - text.row(); - text.label(() -> unitGroups[Team.red.ordinal()].size() > 0 && state.mode.disableWaveTimer ? - getEnemiesRemaining() : (state.mode.disableWaveTimer) ? "$text.waiting" : - timef.get((int) (state.wavetime / 60f))).minWidth(126).left(); - }); + table.left().labelWrap(() -> world.getSector() == null ? wavef.get(state.wave) : world.getSector().currentMission().displayString()).left().growX(); - table.add().growX(); - table.visible(() -> !state.mode.disableWaves); + table.visible(() -> !((world.getSector() == null && state.mode.disableWaves) || !state.mode.showMission)); playButton(uheight); } diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index e94f0227b2..d5eafdbc08 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -913,6 +913,7 @@ public class ServerControl extends Module{ playSectorMap(); }else if(world.getSector().currentMission().isComplete()){ + world.getSector().currentMission().onComplete(); //increment completed missions, check next index next frame world.getSector().completedMissions ++; } From 999dd5eb6fc8ee4519d8120058f0961f9d4a399a Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Sep 2018 23:29:17 -0400 Subject: [PATCH 13/22] Better mission display / Improved tutorial item amounts --- core/assets/bundles/bundle.properties | 6 ++++-- core/src/io/anuke/mindustry/Vars.java | 2 +- core/src/io/anuke/mindustry/maps/Sectors.java | 3 ++- core/src/io/anuke/mindustry/maps/missions/Mission.java | 7 +++++++ core/src/io/anuke/mindustry/maps/missions/WaveMission.java | 7 ++++++- core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java | 2 +- core/src/io/anuke/mindustry/ui/fragments/HudFragment.java | 5 ++++- 7 files changed, 25 insertions(+), 7 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 57806fe23c..27e78ebd55 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -60,11 +60,13 @@ text.sector.unexplored=[accent][[Unexplored] text.mission=Mission:[LIGHT_GRAY] {0} text.mission.complete=Mission complete! text.mission.complete.body=Sector {0},{1} has been conquered. -text.mission.wave=Survive [accent]{0} []waves. -text.mission.battle=Destroy the enemy base. +text.mission.wave=Survive [accent]{0}/{1} []waves +text.mission.wave.menu=Survive [accent]{0} []waves +text.mission.battle=Destroy the enemy core text.mission.resource=Obtain {0} x{1} text.mission.block=Create {0} text.mission.unit=Create {0} Unit +text.mission.display=[accent]Mission:[LIGHT_GRAY] {0} text.none= text.close=Close text.quit=Quit diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index f7f3c0dd74..a140eaec45 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -48,7 +48,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 = 140; + public static final int sectorSize = 130; 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/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 664e50d1b3..90ae02349a 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -260,6 +260,7 @@ public class Sectors{ new WaveMission(5), new ExpandMission(1, 0), new ItemMission(Items.lead, 30), + new ItemMission(Items.copper, 150), new BlockMission(CraftingBlocks.smelter), new ItemMission(Items.densealloy, 30), new BlockMission(PowerBlocks.combustionGenerator), @@ -268,7 +269,7 @@ public class Sectors{ new ItemMission(Items.silicon, 30), new BlockMission(UnitBlocks.daggerFactory), new UnitMission(UnitTypes.dagger), - new ExpandMission(0, 1), + new ExpandMission(-1, 0), new BattleMission() )); }else{ diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index fc3b0d2fc1..0283a752fd 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -13,8 +13,15 @@ import io.anuke.ucore.scene.ui.layout.Table; public interface Mission{ boolean isComplete(); + + /**Returns the string that is displayed in-game near the menu.*/ String displayString(); + /**Returns the info string displayed in the sector dialog (menu)*/ + default String menuDisplayString(){ + return displayString(); + } + default GameMode getMode(){ return GameMode.noWaves; } diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index bae5ad832c..5438cf4b90 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -37,7 +37,12 @@ public class WaveMission implements Mission{ @Override public String displayString(){ - return Bundles.format("text.mission.wave", state.wave); + return Bundles.format("text.mission.wave", state.wave, target); + } + + @Override + public String menuDisplayString(){ + return Bundles.format("text.mission.wave.menu", target); } @Override diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index 71df2edd8f..1f04b05294 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -43,7 +43,7 @@ public class SectorsDialog extends FloatingDialog{ (selected.hasSave() ? " [accent]/[white] " + Bundles.format("text.sector.time", selected.getSave().getPlayTime()) : "")))); content().row(); content().label(() -> Bundles.format("text.mission", selected == null || selected.completedMissions >= selected.missions.size - ? Bundles.get("text.none") : selected.missions.get(selected.completedMissions).displayString()) + ? Bundles.get("text.none") : selected.missions.get(selected.completedMissions).menuDisplayString()) + "[WHITE] " + (selected == null ? "" : Bundles.format("text.save.difficulty", "[LIGHT_GRAY]" + selected.getDifficulty().toString()))); content().row(); content().add(new SectorView()).grow(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 80f216cf9a..c50f396e5f 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Scaling; import io.anuke.mindustry.core.GameState.State; @@ -320,7 +321,9 @@ public class HudFragment extends Fragment{ IntFormat timef = new IntFormat("text.wave.waiting"); table.background("button"); - table.left().labelWrap(() -> world.getSector() == null ? wavef.get(state.wave) : world.getSector().currentMission().displayString()).left().growX(); + table.labelWrap(() -> world.getSector() == null ? wavef.get(state.wave) : + Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX() + .get().setAlignment(Align.center, Align.center); table.visible(() -> !((world.getSector() == null && state.mode.disableWaves) || !state.mode.showMission)); From b77caed0ba766071305f641d0bdeacebc5392412 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 22 Sep 2018 12:20:04 -0400 Subject: [PATCH 14/22] Added sample tutorial text / Refactoring --- core/assets/bundles/bundle.properties | 13 +++-- core/src/io/anuke/mindustry/core/Control.java | 42 ++++++++------ core/src/io/anuke/mindustry/maps/Sectors.java | 27 +-------- .../anuke/mindustry/maps/TutorialSector.java | 35 ++++++++++++ .../maps/generation/WorldGenerator.java | 4 +- .../maps/missions/ActionMission.java | 2 +- .../maps/missions/BattleMission.java | 2 +- .../mindustry/maps/missions/BlockMission.java | 2 +- .../mindustry/maps/missions/ItemMission.java | 2 +- .../maps/missions/MessageMission.java | 15 +++++ .../mindustry/maps/missions/Mission.java | 54 +++++++++++++----- .../mindustry/maps/missions/UnitMission.java | 2 +- .../maps/missions/VictoryMission.java | 2 +- .../mindustry/maps/missions/WaveMission.java | 4 +- .../mindustry/ui/dialogs/SectorsDialog.java | 30 +++++----- .../mindustry/ui/fragments/HudFragment.java | 56 ++++++++++++++++--- 16 files changed, 199 insertions(+), 93 deletions(-) create mode 100644 core/src/io/anuke/mindustry/maps/TutorialSector.java create mode 100644 core/src/io/anuke/mindustry/maps/missions/MessageMission.java diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 27e78ebd55..72d6cf1f24 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -58,15 +58,16 @@ text.sector.resume=Resume text.sector.locked=[scarlet][[Incomplete] text.sector.unexplored=[accent][[Unexplored] text.mission=Mission:[LIGHT_GRAY] {0} -text.mission.complete=Mission complete! +text.mission.info=Mission Info +text.mission.complete=[accent]Mission complete! text.mission.complete.body=Sector {0},{1} has been conquered. -text.mission.wave=Survive [accent]{0}/{1} []waves -text.mission.wave.menu=Survive [accent]{0} []waves +text.mission.wave=Survive[accent] {0}/{1} []waves\nWave in {2} +text.mission.wave.menu=Survive[accent] {0} []waves text.mission.battle=Destroy the enemy core text.mission.resource=Obtain {0} x{1} text.mission.block=Create {0} text.mission.unit=Create {0} Unit -text.mission.display=[accent]Mission:[LIGHT_GRAY] {0} +text.mission.display=[accent]Mission:\n[LIGHT_GRAY]{0} text.none= text.close=Close text.quit=Quit @@ -654,4 +655,6 @@ unit.wraith.description=A fast, hit-and-run interceptor unit. unit.fortress.name=Fortress unit.fortress.description=A heavy artillery ground unit. unit.revenant.name=Revenant -unit.revenant.description=A heavy laser platform. \ No newline at end of file +unit.revenant.description=A heavy laser platform. + +tutorial.begin=Starting tutorial text \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 488f2b3bf6..e8da63b7b6 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -338,7 +338,6 @@ public class Control extends Module{ dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f); dialog.content().add("You might have noticed that 4.0 does not have any sound.\nThis is [orange]intentional![] Sound will be added in a later update.\n\n[LIGHT_GRAY](now stop reporting this as a bug)").wrap().width(400f); dialog.show(); - }); } } @@ -350,6 +349,29 @@ public class Control extends Module{ } } + private void updateSectors(){ + if(world.getSector() == null) return; + + //TODO move sector code into logic class + //check unlocked sectors + while(!world.getSector().complete && world.getSector().currentMission().isComplete()){ + world.getSector().currentMission().onComplete(); + world.getSector().completedMissions ++; + + state.mode = world.getSector().currentMission().getMode(); + world.getSector().currentMission().onBegin(); + } + + //check if all assigned missions are complete + if(!world.getSector().complete && world.getSector().completedMissions >= world.getSector().missions.size){ + state.mode = GameMode.victory; + + world.sectors().completeSector(world.getSector().x, world.getSector().y); + world.sectors().save(); + ui.missions.show(world.getSector()); + } + } + @Override public void update(){ @@ -375,23 +397,7 @@ public class Control extends Module{ Platform.instance.updateRPC(); } - //TODO move sector code into logic class - //check unlocked sectors - if(world.getSector() != null && !world.getSector().complete){ - //all assigned missions are complete - if(world.getSector().completedMissions >= world.getSector().missions.size){ - state.mode = GameMode.victory; - - world.sectors().completeSector(world.getSector().x, world.getSector().y); - world.sectors().save(); - ui.missions.show(world.getSector()); - }else if(world.getSector().currentMission().isComplete()){ - world.getSector().currentMission().onComplete(); - //increment completed missions, check next index next frame - world.getSector().completedMissions ++; - state.mode = world.getSector().currentMission().getMode(); - } - } + updateSectors(); //check unlocks every 2 seconds if(world.getSector() != null && Timers.get("timerCheckUnlock", 120)){ diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 90ae02349a..3afa08012c 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -5,13 +5,12 @@ import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.UnitTypes; -import io.anuke.mindustry.content.blocks.*; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.SaveIO; 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.WaveMission; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.Tile; @@ -251,27 +250,7 @@ public class Sectors{ if(sector.difficulty == 0){ //TODO make specfic expansion sector have specific ores - sector.missions.addAll(Array.with( - new ItemMission(Items.copper, 30), - new BlockMission(ProductionBlocks.mechanicalDrill), - new BlockMission(DistributionBlocks.conveyor), - new ItemMission(Items.copper, 40), - new BlockMission(TurretBlocks.duo), - new WaveMission(5), - new ExpandMission(1, 0), - new ItemMission(Items.lead, 30), - new ItemMission(Items.copper, 150), - new BlockMission(CraftingBlocks.smelter), - new ItemMission(Items.densealloy, 30), - new BlockMission(PowerBlocks.combustionGenerator), - new BlockMission(PowerBlocks.powerNode), - new BlockMission(CraftingBlocks.siliconsmelter), - new ItemMission(Items.silicon, 30), - new BlockMission(UnitBlocks.daggerFactory), - new UnitMission(UnitTypes.dagger), - new ExpandMission(-1, 0), - new BattleMission() - )); + sector.missions.addAll(TutorialSector.getMissions()); }else{ sector.missions.add(Mathf.randomSeed(sector.getSeed() + 1) < waveChance ? new WaveMission(Math.min(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 0, 3)*5, 100)) : new BattleMission()); diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java new file mode 100644 index 0000000000..477080a450 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -0,0 +1,35 @@ +package io.anuke.mindustry.maps; + +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.content.Items; +import io.anuke.mindustry.content.UnitTypes; +import io.anuke.mindustry.content.blocks.*; +import io.anuke.mindustry.maps.missions.*; + +/**Just a class for returning the list of tutorial missions.*/ +public class TutorialSector{ + + public static Array getMissions(){ + return Array.with( + new ItemMission(Items.copper, 30).setMessage("$tutorial.begin"), + new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.begin"), + new BlockMission(DistributionBlocks.conveyor), + new ItemMission(Items.copper, 40), + new BlockMission(TurretBlocks.duo), + new WaveMission(5), + new ExpandMission(1, 0), + new ItemMission(Items.lead, 30), + new ItemMission(Items.copper, 150), + new BlockMission(CraftingBlocks.smelter), + new ItemMission(Items.densealloy, 30), + new BlockMission(PowerBlocks.combustionGenerator), + new BlockMission(PowerBlocks.powerNode), + new BlockMission(CraftingBlocks.siliconsmelter), + new ItemMission(Items.silicon, 30), + new BlockMission(UnitBlocks.daggerFactory), + new UnitMission(UnitTypes.dagger), + new ExpandMission(-1, 0), + new BattleMission() + ); + } +} diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index a5e21c0c5c..78e9936df0 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -190,7 +190,7 @@ public class WorldGenerator{ for(int x = 0; x < width; x++){ for(int y = 0; y < height; y++){ GenResult result = generateTile(this.result, sector.x, sector.y, x, y, true, spawnpoints); - Tile tile = new Tile(x, y, (byte)result.floor.id, (byte)result.wall.id, (byte)0, (byte)0, result.elevation); + Tile tile = new Tile(x, y, result.floor.id, result.wall.id, (byte)0, (byte)0, result.elevation); tiles[x][y] = tile; } } @@ -241,7 +241,7 @@ public class WorldGenerator{ return generateTile(result, sectorX, sectorY, localX, localY, detailed, null); } - //TODO include tile in result + //TODO include ore in result /** * Gets the generation result from a specific sector at specific coordinates. * @param result where to put the generation results diff --git a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java index 7c8ee53b0f..c73a6e40b9 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java @@ -6,7 +6,7 @@ import io.anuke.mindustry.game.GameMode; import static io.anuke.mindustry.Vars.threads; /**A mission which simply runs a single action and is completed instantly.*/ -public abstract class ActionMission implements Mission{ +public abstract class ActionMission extends Mission{ private Runnable runner; public ActionMission(Runnable runner){ diff --git a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java index cdfc10d28b..822d8225e3 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BattleMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BattleMission.java @@ -9,7 +9,7 @@ import io.anuke.mindustry.maps.generation.FortressGenerator; import io.anuke.mindustry.maps.generation.Generation; import io.anuke.ucore.util.Bundles; -public class BattleMission implements Mission{ +public class BattleMission extends Mission{ private final static int coreX = 60, coreY = 60; @Override diff --git a/core/src/io/anuke/mindustry/maps/missions/BlockMission.java b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java index 2c522208a1..fbd9149ef4 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BlockMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java @@ -10,7 +10,7 @@ import static io.anuke.mindustry.Vars.defaultTeam; import static io.anuke.mindustry.Vars.world; /**A mission in which the player must place a block.*/ -public class BlockMission implements Mission{ +public class BlockMission extends Mission{ private final Block block; private boolean complete; diff --git a/core/src/io/anuke/mindustry/maps/missions/ItemMission.java b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java index 63b6b14ffd..fbf24430a9 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ItemMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java @@ -9,7 +9,7 @@ import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.state; /**A mission that is completed when the player obtains items in their core.*/ -public class ItemMission implements Mission{ +public class ItemMission extends Mission{ private final Item item; private final int amount; diff --git a/core/src/io/anuke/mindustry/maps/missions/MessageMission.java b/core/src/io/anuke/mindustry/maps/missions/MessageMission.java new file mode 100644 index 0000000000..920f2cc111 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/MessageMission.java @@ -0,0 +1,15 @@ +package io.anuke.mindustry.maps.missions; + +import io.anuke.mindustry.Vars; + +/**A mission that just displays some text.*/ +public class MessageMission extends ActionMission{ + + public MessageMission(String text){ + super(() -> { + if(!Vars.headless){ + Vars.ui.showInfo(text); + } + }); + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index 0283a752fd..77a88084f2 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.maps.missions; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; -import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.blocks.StorageBlocks; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.SpawnGroup; @@ -10,43 +9,70 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.maps.Sector; import io.anuke.mindustry.maps.generation.Generation; import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.util.Bundles; -public interface Mission{ - boolean isComplete(); +import static io.anuke.mindustry.Vars.headless; +import static io.anuke.mindustry.Vars.ui; + +public abstract class Mission{ + private String extraMessage; + + public abstract boolean isComplete(); /**Returns the string that is displayed in-game near the menu.*/ - String displayString(); + public abstract String displayString(); /**Returns the info string displayed in the sector dialog (menu)*/ - default String menuDisplayString(){ + public String menuDisplayString(){ return displayString(); } - default GameMode getMode(){ + public GameMode getMode(){ return GameMode.noWaves; } - default void onComplete(){ - if(!Vars.headless){ - //TODO show 'mission complete' message somewhere + /**Sets the message displayed on mission begin. Returns this mission for chaining.*/ + public Mission setMessage(String message){ + this.extraMessage = message; + return this; + } + + /**Shows the unique sector message.*/ + public void showMessage(){ + if(!headless && extraMessage != null){ + ui.hudfrag.showTextDialog(extraMessage); } } - default void display(Table table){ + public boolean hasMessage(){ + return extraMessage != null; + } + + public void onBegin(){ + showMessage(); + } + + public void onComplete(){ + if(!headless){ + ui.hudfrag.showText("[LIGHT_GRAY]"+menuDisplayString() + ":\n" + Bundles.get("text.mission.complete")); + } + } + + public void display(Table table){ table.add(displayString()); } - default Array getWaves(Sector sector){ + public Array getWaves(Sector sector){ return new Array<>(); } - default Array getSpawnPoints(Generation gen){ + public Array getSpawnPoints(Generation gen){ return Array.with(); } - default void generate(Generation gen){} + public void generate(Generation gen){} - default void generateCoreAt(Generation gen, int coreX, int coreY, Team team){ + public void generateCoreAt(Generation gen, int coreX, int coreY, Team team){ gen.tiles[coreX][coreY].setBlock(StorageBlocks.core); gen.tiles[coreX][coreY].setTeam(team); } diff --git a/core/src/io/anuke/mindustry/maps/missions/UnitMission.java b/core/src/io/anuke/mindustry/maps/missions/UnitMission.java index 841ad39c89..36a10ece7c 100644 --- a/core/src/io/anuke/mindustry/maps/missions/UnitMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/UnitMission.java @@ -6,7 +6,7 @@ import io.anuke.mindustry.entities.units.UnitType; import io.anuke.mindustry.game.GameMode; import io.anuke.ucore.util.Bundles; -public class UnitMission implements Mission{ +public class UnitMission extends Mission{ private final UnitType type; public UnitMission(UnitType type){ diff --git a/core/src/io/anuke/mindustry/maps/missions/VictoryMission.java b/core/src/io/anuke/mindustry/maps/missions/VictoryMission.java index fd3e912170..46b6153dff 100644 --- a/core/src/io/anuke/mindustry/maps/missions/VictoryMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/VictoryMission.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.maps.missions; import io.anuke.mindustry.game.GameMode; import io.anuke.ucore.scene.ui.layout.Table; -public class VictoryMission implements Mission{ +public class VictoryMission extends Mission{ @Override public boolean isComplete(){ return false; diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index 5438cf4b90..0ba837fe11 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -12,7 +12,7 @@ import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.state; -public class WaveMission implements Mission{ +public class WaveMission extends Mission{ private final int target; public WaveMission(int target){ @@ -37,7 +37,7 @@ public class WaveMission implements Mission{ @Override public String displayString(){ - return Bundles.format("text.mission.wave", state.wave, target); + return Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60)); } @Override diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index 1f04b05294..1f414c043b 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -110,9 +110,9 @@ public class SectorsDialog extends FloatingDialog{ float padSectorSize = sectorSize + sectorPadding; - float clipSize = Math.min(width, height); - int shownSectors = (int)(clipSize/padSectorSize); - clip.setSize(clipSize).setCenter(x + width/2f, y + height/2f); + int shownSectorsX = (int)(width/padSectorSize); + int shownSectorsY = (int)(height/padSectorSize); + clip.setSize(width, height).setCenter(x + width/2f, y + height/2f); Graphics.flush(); boolean clipped = ScissorStack.pushScissors(clip); @@ -121,8 +121,8 @@ public class SectorsDialog extends FloatingDialog{ Vector2 mouse = Graphics.mouse(); - for(int x = -shownSectors; x <= shownSectors; x++){ - for(int y = -shownSectors; y <= shownSectors; y++){ + for(int x = -shownSectorsX; x <= shownSectorsX; x++){ + for(int y = -shownSectorsY; y <= shownSectorsY; y++){ int sectorX = offsetX + x; int sectorY = offsetY + y; @@ -130,19 +130,21 @@ public class SectorsDialog extends FloatingDialog{ float drawY = y + height/2f + sectorY * padSectorSize - offsetY * padSectorSize - panY % padSectorSize; Sector sector = world.sectors().get(sectorX, sectorY); - int size = (sector == null ? 1 : sector.width); - float padding = (size-1) * sectorPadding; + int width = (sector == null ? 1 : sector.width); + int height = (sector == null ? 1 : sector.height); + float paddingx = (width-1) * sectorPadding; + float paddingy = (height-1) * sectorPadding; if(sector != null && (sector.x != sectorX || sector.y != sectorY)){ continue; } - drawX += (size-1)/2f*padSectorSize; - drawY += (size-1)/2f*padSectorSize; + drawX += (width-1)/2f*padSectorSize; + drawY += (height-1)/2f*padSectorSize; if(sector != null && sector.texture != null){ Draw.color(Color.WHITE); - Draw.rect(sector.texture, drawX, drawY, sectorSize * size + padding, sectorSize * size + padding); + Draw.rect(sector.texture, drawX, drawY, sectorSize * width + paddingx, sectorSize * height + paddingy); } float stroke = 4f; @@ -152,8 +154,8 @@ public class SectorsDialog extends FloatingDialog{ }else if(sector == selected){ Draw.color(Palette.place); stroke = 6f; - }else if(Mathf.inRect(mouse.x, mouse.y, drawX - padSectorSize/2f * size, drawY - padSectorSize/2f * size, - drawX + padSectorSize/2f * size, drawY + padSectorSize/2f * size)){ + }else if(Mathf.inRect(mouse.x, mouse.y, drawX - padSectorSize/2f * width, drawY - padSectorSize/2f * height, + drawX + padSectorSize/2f * width, drawY + padSectorSize/2f * height)){ if(clicked){ selectSector(sector); } @@ -165,13 +167,13 @@ public class SectorsDialog extends FloatingDialog{ } Lines.stroke(Unit.dp.scl(stroke)); - Lines.crect(drawX, drawY, sectorSize * size + padding, sectorSize * size + padding, (int)stroke); + Lines.crect(drawX, drawY, sectorSize * width + paddingx, sectorSize * height + paddingy, (int)stroke); } } Draw.color(Palette.accent); Lines.stroke(Unit.dp.scl(4f)); - Lines.crect(x + width/2f, y + height/2f, clipSize, clipSize); + Lines.crect(x + width/2f, y + height/2f, width, height); Draw.reset(); Graphics.flush(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index c50f396e5f..6d4fd42381 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -16,15 +16,14 @@ import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.IntFormat; import io.anuke.mindustry.ui.Minimap; +import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.ucore.core.*; import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.scene.Element; import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.actions.Actions; import io.anuke.ucore.scene.event.Touchable; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.ImageButton; -import io.anuke.ucore.scene.ui.Label; +import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.layout.Stack; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; @@ -104,7 +103,8 @@ public class HudFragment extends Fragment{ cont.row(); - Table waves = cont.table(this::addWaveTable).touchable(Touchable.enabled).fillX().height(66f).get(); + TextButton waves = cont.addButton("", ()->{}).fillX().height(66f).get(); + addWaveTable(waves); cont.row(); @@ -183,6 +183,27 @@ public class HudFragment extends Fragment{ blockfrag.build(Core.scene.getRoot()); } + public void showText(String text){ + Table table = new Table("button"); + table.update(() -> { + if(state.is(State.menu)){ + table.remove(); + } + }); + table.margin(12); + table.addImage("icon-check").size(16*2).pad(3); + table.add(text).wrap().width(280f).get().setAlignment(Align.center, Align.center); + table.pack(); + + //create container table which will align and move + Table container = Core.scene.table(); + container.top().add(table); + container.setTranslation(0, table.getPrefHeight()); + container.actions(Actions.translateBy(0, -table.getPrefHeight(), 1f, Interpolation.fade), Actions.delay(4f), + //nesting actions() calls is necessary so the right prefHeight() is used + Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.removeActor()))); + } + /** * Show unlock notification for a new recipe. */ @@ -282,6 +303,16 @@ public class HudFragment extends Fragment{ } } + public void showTextDialog(String str){ + new FloatingDialog("$text.mission.info"){{ + shouldPause = true; + setFillParent(false); + getCell(content()).growX(); + content().margin(15).add(str).width(600f).wrap().get().setAlignment(Align.left, Align.left); + buttons().addButton("$text.continue", this::hide).size(140, 60).pad(4); + }}.show(); + } + private void toggleMenus(){ wavetable.clearActions(); infolabel.clearActions(); @@ -313,21 +344,30 @@ public class HudFragment extends Fragment{ } } - private void addWaveTable(Table table){ + private void addWaveTable(TextButton table){ wavetable = table; float uheight = 66f; IntFormat wavef = new IntFormat("text.wave"); IntFormat timef = new IntFormat("text.wave.waiting"); + table.clearChildren(); + table.setTouchable(Touchable.enabled); + table.background("button"); table.labelWrap(() -> world.getSector() == null ? wavef.get(state.wave) : - Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX() - .get().setAlignment(Align.center, Align.center); + Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX(); + table.clicked(() -> { + if(world.getSector() != null && world.getSector().currentMission().hasMessage()){ + world.getSector().currentMission().showMessage(); + } + }); + + table.setDisabled(() -> !(world.getSector() != null && world.getSector().currentMission().hasMessage())); table.visible(() -> !((world.getSector() == null && state.mode.disableWaves) || !state.mode.showMission)); - playButton(uheight); + //playButton(uheight); } private void playButton(float uheight){ From 8d20c462287b802e2ae93c6798af00f424dcab28 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 22 Sep 2018 16:41:55 -0400 Subject: [PATCH 15/22] Basic tutorial text --- core/assets/bundles/bundle.properties | 26 ++++++++++++--- core/src/io/anuke/mindustry/maps/Sectors.java | 1 + .../anuke/mindustry/maps/TutorialSector.java | 33 ++++++++++--------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 72d6cf1f24..931debd6b4 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -59,7 +59,7 @@ text.sector.locked=[scarlet][[Incomplete] text.sector.unexplored=[accent][[Unexplored] text.mission=Mission:[LIGHT_GRAY] {0} text.mission.info=Mission Info -text.mission.complete=[accent]Mission complete! +text.mission.complete=Mission complete! text.mission.complete.body=Sector {0},{1} has been conquered. text.mission.wave=Survive[accent] {0}/{1} []waves\nWave in {2} text.mission.wave.menu=Survive[accent] {0} []waves @@ -607,9 +607,9 @@ block.spirit-factory.name=Spirit Drone Factory block.phantom-factory.name=Phantom Drone Factory block.wraith-factory.name=Wraith Fighter Factory block.ghoul-factory.name=Ghoul Bomber Factory -block.dagger-factory.name=Dagger Factory -block.titan-factory.name=Titan Factory -block.revenant-factory.name=Revenant Factory +block.dagger-factory.name=Dagger Mech Factory +block.titan-factory.name=Titan Mech Factory +block.revenant-factory.name=Revenant Fighter Factory block.repair-point.name=Repair Point block.resupply-point.name=Resupply Point block.pulse-conduit.name=Pulse Conduit @@ -657,4 +657,20 @@ unit.fortress.description=A heavy artillery ground unit. unit.revenant.name=Revenant unit.revenant.description=A heavy laser platform. -tutorial.begin=Starting tutorial text \ No newline at end of file +tutorial.begin=Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by [accent]mining copper[] units. Tap a copper ore vein near your core to do this. +tutorial.drill=Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. +tutorial.conveyor=[accent]Conveyors []are used to transport items to the core.\nMake a line of conveyors from the drill to the core. +tutorial.morecopper=More copper is required. Use drills to mine it. +tutorial.turret=Defensive structures must be built to repel the [LIGHT_GRAY]enemy[].\nBuild a duo turret near your base. +tutorial.drillturret=Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret. +tutorial.waves=The[LIGHT_GRAY] enemy[] approaches.\n\nDefend your core for 5 waves. Build more turrets. +tutorial.lead=More ores are available. Explore to your right and mine[accent] lead[].\n\nDrag from your unit to the core to transfer resources. +tutorial.smelter=Copper and lead are weak metals.\nSuperior[accent] Dense Alloy[] can be created in a smelter.\n\nBuild one. +tutorial.densealloy=Create conveyors leading copper, lead and coal from drills into the smelter.\nCreate an additional output conveyor leading to the core.\n\nUse this to create 30 dense alloy. +tutorial.siliconsmelter=Advanced weapons require[accent] silicon.\nMake a silicon smelter. +tutorial.generator=This technology requires power.\nCreate a[accent] combustion generator[] for it. +tutorial.node=Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power.\nTo link power, tap the node.\n\nLink the generator to the silicon smelter. +tutorial.silicon=Fuel the combustion generator with coal from drills.\nInput sand and coal from drills into the silicon smelter\nThis will produce silicon.\n\nMake some silicon and move it into your base. +tutorial.daggerfactory=Construct a[accent] dagger mech factory.[]\n\nThis will be used to create attack mechs. +tutorial.dagger=Supply silicon, copper and power to the factory.\nOnce requirements are met, a mech will be created.\n\nCreate more drills, generators and conveyors as necessary. +tutorial.battle=The[LIGHT_GRAY] enemy[] has revealed their core.\nDestroy it with your unit and dagger mechs. \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 3afa08012c..2343362921 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -44,6 +44,7 @@ public class Sectors{ sector.saveID = control.getSaves().addSave("sector-" + sector.packedPosition()).index; world.sectors().save(); world.setSector(sector); + sector.currentMission().onBegin(); }else if(SaveIO.breakingVersions.contains(sector.getSave().getBuild())){ ui.showInfo("$text.save.old"); }else try{ diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index 477080a450..45b73dd53d 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -12,24 +12,25 @@ public class TutorialSector{ public static Array getMissions(){ return Array.with( new ItemMission(Items.copper, 30).setMessage("$tutorial.begin"), - new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.begin"), - new BlockMission(DistributionBlocks.conveyor), - new ItemMission(Items.copper, 40), - new BlockMission(TurretBlocks.duo), - new WaveMission(5), + new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drill"), + new BlockMission(DistributionBlocks.conveyor).setMessage("$tutorial.conveyor"), + new ItemMission(Items.copper, 50).setMessage("$tutorial.morecopper"), + new BlockMission(TurretBlocks.duo).setMessage("$tutorial.turret"), + new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drillturret"), + new WaveMission(5).setMessage("$tutorial.waves"), new ExpandMission(1, 0), - new ItemMission(Items.lead, 30), - new ItemMission(Items.copper, 150), - new BlockMission(CraftingBlocks.smelter), - new ItemMission(Items.densealloy, 30), - new BlockMission(PowerBlocks.combustionGenerator), - new BlockMission(PowerBlocks.powerNode), - new BlockMission(CraftingBlocks.siliconsmelter), - new ItemMission(Items.silicon, 30), - new BlockMission(UnitBlocks.daggerFactory), - new UnitMission(UnitTypes.dagger), + new ItemMission(Items.lead, 30).setMessage("$tutorial.lead"), + new ItemMission(Items.copper, 150).setMessage("$tutorial.morecopper"), + new BlockMission(CraftingBlocks.smelter).setMessage("$tutorial.smelter"), + new ItemMission(Items.densealloy, 30).setMessage("$tutorial.densealloy"), + new BlockMission(CraftingBlocks.siliconsmelter).setMessage("$tutorial.siliconsmelter"), + new BlockMission(PowerBlocks.combustionGenerator).setMessage("$tutorial.generator"), + new BlockMission(PowerBlocks.powerNode).setMessage("$tutorial.node"), + new ItemMission(Items.silicon, 30).setMessage("$tutorial.silicon"), + new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"), + new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), new ExpandMission(-1, 0), - new BattleMission() + new BattleMission().setMessage("$tutorial.battle") ); } } From 4eab89d73ed8b872ef0a94a51c005eab3841cf51 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 23 Sep 2018 10:10:05 -0400 Subject: [PATCH 16/22] Per-sector ore gen --- core/src/io/anuke/mindustry/Vars.java | 2 +- core/src/io/anuke/mindustry/maps/Sector.java | 3 +- core/src/io/anuke/mindustry/maps/Sectors.java | 16 +++++++-- .../anuke/mindustry/maps/TutorialSector.java | 29 ++++++++++++++- .../maps/generation/WorldGenerator.java | 22 +++++++++--- .../maps/missions/ActionMission.java | 5 ++- .../maps/missions/BlockLocMission.java | 35 +++++++++++++++++++ .../mindustry/maps/missions/BlockMission.java | 6 ++++ .../maps/missions/ExpandMission.java | 26 ++++++++++++-- .../mindustry/ui/dialogs/GenViewDialog.java | 2 +- 10 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index a140eaec45..449318f9bd 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -48,7 +48,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 = 130; + public static final int sectorSize = 120; 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/maps/Sector.java b/core/src/io/anuke/mindustry/maps/Sector.java index fc1b32db65..6265188c76 100644 --- a/core/src/io/anuke/mindustry/maps/Sector.java +++ b/core/src/io/anuke/mindustry/maps/Sector.java @@ -8,7 +8,6 @@ import io.anuke.mindustry.game.Saves.SaveSlot; import io.anuke.mindustry.game.SpawnGroup; import io.anuke.mindustry.maps.missions.Mission; import io.anuke.mindustry.maps.missions.VictoryMission; -import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.ucore.util.Bits; @@ -35,7 +34,7 @@ public class Sector{ /**Enemies spawned at this sector.*/ public transient Array spawns; /**Ores that appear in this sector.*/ - public transient Array ores = new Array<>(); + //public transient Array ores = new Array<>(); /**Difficulty of the sector, measured by calculating distance from origin and applying scaling.*/ public transient int difficulty; /**Items the player starts with on this sector.*/ diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 2343362921..e2b616bfc2 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -11,6 +11,7 @@ import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; import io.anuke.mindustry.maps.missions.BattleMission; import io.anuke.mindustry.maps.missions.WaveMission; +import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.Tile; @@ -153,10 +154,12 @@ public class Sectors{ 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++) { - GenResult result = world.generator().generateTile(sx + sector.x, sy + sector.y, x, 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); } } @@ -170,6 +173,15 @@ public class Sectors{ return true; } + public Array getOres(int x, int y){ + if(x == 0 && y == 0){ + return Array.with(Items.copper); + }else if(x == 1 && y == 0){ + return Array.with(Items.copper, Items.lead, Items.coal); + } + return Array.with(Items.copper); + } + /**Unlocks a sector. This shows nearby sectors.*/ public void completeSector(int x, int y){ createSector(x, y); @@ -259,7 +271,7 @@ public class Sectors{ sector.spawns = sector.missions.first().getWaves(sector); - sector.ores.addAll(Items.copper); + //sector.ores.addAll(Items.copper); //set starter items if(sector.difficulty > 12){ //now with titanium diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index 45b73dd53d..4bb7c4314b 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -4,8 +4,11 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.UnitTypes; import io.anuke.mindustry.content.blocks.*; +import io.anuke.mindustry.maps.generation.Generation; import io.anuke.mindustry.maps.missions.*; +import static io.anuke.mindustry.Vars.*; + /**Just a class for returning the list of tutorial missions.*/ public class TutorialSector{ @@ -30,7 +33,31 @@ public class TutorialSector{ new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"), new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), new ExpandMission(-1, 0), - new BattleMission().setMessage("$tutorial.battle") + new BattleMission(){ + public void generate(Generation gen){} + + @Override + public boolean isComplete(){ + return false; + } + + public void onBegin(){ + super.onBegin(); + generateBase(); + } + }.setMessage("$tutorial.battle") ); } + + private static void generateBase(){ + int x = sectorSize/2, y = sectorSize/2; + world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam); + world.setBlock(world.tile(x + 1, y + 2), TurretBlocks.duo, waveTeam); + world.setBlock(world.tile(x + 1, y - 2), TurretBlocks.duo, waveTeam); + world.setBlock(world.tile(x - 1, y + 2), UnitBlocks.daggerFactory, waveTeam); + world.setBlock(world.tile(x - 1, y - 3), UnitBlocks.daggerFactory, waveTeam); + + //since placed() is not called here, add core manually + state.teams.get(waveTeam).cores.add(world.tile(x, y)); + } } diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index 78e9936df0..845898590d 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -186,10 +186,11 @@ public class WorldGenerator{ SeedRandom rnd = new SeedRandom(sector.getSeed()); Generation gena = new Generation(sector, tiles, tiles.length, tiles[0].length, rnd); Array spawnpoints = sector.currentMission().getSpawnPoints(gena); + Array ores = world.sectors().getOres(sector.x, sector.y); for(int x = 0; x < width; x++){ for(int y = 0; y < height; y++){ - GenResult result = generateTile(this.result, sector.x, sector.y, x, y, true, spawnpoints); + GenResult result = generateTile(this.result, sector.x, sector.y, x, y, true, spawnpoints, ores); Tile tile = new Tile(x, y, result.floor.id, result.wall.id, (byte)0, (byte)0, result.elevation); tiles[x][y] = tile; } @@ -214,7 +215,7 @@ public class WorldGenerator{ } } - generateOres(tiles, sector.getSeed(), true, sector.ores); + //generateOres(tiles, sector.getSeed(), true, ores); for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ @@ -238,7 +239,7 @@ public class WorldGenerator{ } public GenResult generateTile(int sectorX, int sectorY, int localX, int localY, boolean detailed){ - return generateTile(result, sectorX, sectorY, localX, localY, detailed, null); + return generateTile(result, sectorX, sectorY, localX, localY, detailed, null, null); } //TODO include ore in result @@ -253,7 +254,7 @@ public class WorldGenerator{ * @param spawnpoints list of player spawnpoints, can be null * @return the GenResult passed in with its values modified */ - public GenResult generateTile(GenResult result, int sectorX, int sectorY, int localX, int localY, boolean detailed, Array spawnpoints){ + public GenResult generateTile(GenResult result, int sectorX, int sectorY, int localX, int localY, boolean detailed, Array spawnpoints, Array ores){ int x = sectorX * sectorSize + localX + Short.MAX_VALUE; int y = sectorY * sectorSize + localY + Short.MAX_VALUE; @@ -321,6 +322,19 @@ public class WorldGenerator{ wall = decoration.get(floor); } + if(ores != null && ((Floor) floor).hasOres && wall == Blocks.air){ + int offsetX = 10 + x, offsetY = 10 + y; + for(int i = ores.size - 1; i >= 0; i--){ + Item entry = ores.get(i); + if(sim.octaveNoise2D(1, 0.7, 1f / (10 + i * 3), offsetX, offsetY) / 4f + + Math.abs(0.5f - sim.octaveNoise2D(2, 0.7, 1f / (50 + i * 2), offsetX, offsetY)) > 0.35f && + Math.abs(0.5f - sim2.octaveNoise2D(1, 1, 1f / (55 + i * 4), offsetX, offsetY)) > 0.33f){ + floor = OreBlocks.get(floor, entry); + break; + } + } + } + result.wall = wall; result.floor = floor; result.elevation = (byte) Math.max(elevation, 0); diff --git a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java index c73a6e40b9..99a0cc5a8f 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java @@ -7,12 +7,15 @@ import static io.anuke.mindustry.Vars.threads; /**A mission which simply runs a single action and is completed instantly.*/ public abstract class ActionMission extends Mission{ - private Runnable runner; + protected Runnable runner; public ActionMission(Runnable runner){ this.runner = runner; } + public ActionMission(){ + } + @Override public void onComplete(){ threads.run(runner); diff --git a/core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java b/core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java new file mode 100644 index 0000000000..a3c003b3c8 --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java @@ -0,0 +1,35 @@ +package io.anuke.mindustry.maps.missions; + +import io.anuke.mindustry.world.Block; +import io.anuke.ucore.util.Bundles; + +import static io.anuke.mindustry.Vars.world; + +public class BlockLocMission extends Mission{ + private final Block block; + private final int x, y, rotation; + + public BlockLocMission(Block block, int x, int y, int rotation){ + this.block = block; + this.x = x; + this.y = y; + this.rotation = rotation; + } + + public BlockLocMission(Block block, int x, int y){ + this.block = block; + this.x = x; + this.y = y; + this.rotation = 0; + } + + @Override + public boolean isComplete(){ + return world.tile(x, y).block() == block && (!block.rotate || world.tile(x,y).getRotation() == rotation); + } + + @Override + public String displayString(){ + return Bundles.format("text.mission.block", block.formalName); + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/BlockMission.java b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java index fbd9149ef4..6ec0457c8d 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BlockMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java @@ -32,6 +32,12 @@ public class BlockMission extends Mission{ this.block = block; } + @Override + public void onComplete(){ + super.onComplete(); + complete = false; + } + @Override public boolean isComplete(){ return complete; diff --git a/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java b/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java index 33999eab73..660064ff4c 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ExpandMission.java @@ -4,14 +4,34 @@ import static io.anuke.mindustry.Vars.*; /**An action mission which simply expands the sector.*/ public class ExpandMission extends ActionMission{ + private boolean done = false; public ExpandMission(int expandX, int expandY){ - super(() -> { + runner = () -> { if(headless){ world.sectors().expandSector(world.getSector(), expandX, expandY); + done = true; }else{ - ui.loadLogic(() -> world.sectors().expandSector(world.getSector(), expandX, expandY)); + ui.loadLogic(() -> { + world.sectors().expandSector(world.getSector(), expandX, expandY); + done = true; + }); } - }); + }; + } + + @Override + public void onBegin(){ + runner.run(); + } + + @Override + public boolean isComplete(){ + return done; + } + + @Override + public void onComplete(){ + done = false; } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java index 622f22f646..20eb89e5e8 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java @@ -81,7 +81,7 @@ public class GenViewDialog extends FloatingDialog{ Pixmap pixmap = new Pixmap(sectorSize, sectorSize, Format.RGBA8888); for(int i = 0; i < sectorSize; i++){ for(int j = 0; j < sectorSize; j++){ - world.generator().generateTile(result, wx, wy, i, j, true, null); + world.generator().generateTile(result, wx, wy, i, j, true, null, null); pixmap.drawPixel(i, sectorSize - 1 - j, ColorMapper.colorFor(result.floor, result.wall, Team.none, result.elevation, (byte)0)); } } From 6bab6c57f25d24fcf0d826a1539695ec6f1b8112 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 23 Sep 2018 12:45:22 -0400 Subject: [PATCH 17/22] Fixed waves not appearing / Fixed ore tile blending --- core/src/io/anuke/mindustry/core/Logic.java | 2 +- core/src/io/anuke/mindustry/game/SpawnGroup.java | 1 - core/src/io/anuke/mindustry/maps/Sector.java | 2 -- core/src/io/anuke/mindustry/maps/Sectors.java | 5 ++++- core/src/io/anuke/mindustry/world/blocks/OreBlock.java | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index c04577612f..9441767bf5 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -132,7 +132,7 @@ public class Logic extends Module{ Entities.update(fireGroup); Entities.update(playerGroup); - //effect group only contains item drops in the headless version, update it! + //effect group only contains item transfers in the headless version, update it! if(headless){ Entities.update(effectGroup); } diff --git a/core/src/io/anuke/mindustry/game/SpawnGroup.java b/core/src/io/anuke/mindustry/game/SpawnGroup.java index 63faefda7d..93cbc2a30d 100644 --- a/core/src/io/anuke/mindustry/game/SpawnGroup.java +++ b/core/src/io/anuke/mindustry/game/SpawnGroup.java @@ -85,7 +85,6 @@ public class SpawnGroup{ if(wave < begin || wave > end || (wave - begin) % spacing != 0){ return 0; } - float scaling = this.groupScaling; return Math.min(groupAmount - 1 + Math.max((int) ((wave / spacing) / groupScaling), 1), max); } diff --git a/core/src/io/anuke/mindustry/maps/Sector.java b/core/src/io/anuke/mindustry/maps/Sector.java index 6265188c76..e1ce211748 100644 --- a/core/src/io/anuke/mindustry/maps/Sector.java +++ b/core/src/io/anuke/mindustry/maps/Sector.java @@ -33,8 +33,6 @@ public class Sector{ public transient Array missions = new Array<>(); /**Enemies spawned at this sector.*/ public transient Array spawns; - /**Ores that appear in this sector.*/ - //public transient Array ores = new Array<>(); /**Difficulty of the sector, measured by calculating distance from origin and applying scaling.*/ public transient int difficulty; /**Items the player starts with on this sector.*/ diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index e2b616bfc2..9578973571 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -10,6 +10,7 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; import io.anuke.mindustry.maps.missions.BattleMission; +import io.anuke.mindustry.maps.missions.Mission; import io.anuke.mindustry.maps.missions.WaveMission; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; @@ -269,7 +270,9 @@ public class Sectors{ : new BattleMission()); } - sector.spawns = sector.missions.first().getWaves(sector); + for(Mission mission : sector.missions){ + sector.spawns.addAll(mission.getWaves(sector)); + } //sector.ores.addAll(Items.copper); diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java index 79c09df684..7333c7dcd2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java @@ -19,7 +19,7 @@ public class OreBlock extends Floor{ this.base = base; this.variants = 3; this.minimapColor = ore.color; - this.blends = block -> block instanceof OreBlock && ((OreBlock) block).base != base; + this.blends = block -> (block instanceof OreBlock && ((OreBlock) block).base != base) || (!(block instanceof OreBlock) && block != base); this.tileBlends = (tile, other) -> tile.getElevation() < other.getElevation(); this.edge = base.name; } From 06763b34c3b513bb3b99210b6b0ab257fdaa7355 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 23 Sep 2018 18:41:08 -0400 Subject: [PATCH 18/22] Bugfixes / Better topological map --- core/src/io/anuke/mindustry/ai/Pathfinder.java | 4 ++++ core/src/io/anuke/mindustry/game/Waves.java | 2 +- core/src/io/anuke/mindustry/maps/Sectors.java | 6 +++++- core/src/io/anuke/mindustry/maps/TutorialSector.java | 4 ++++ .../mindustry/maps/generation/WorldGenerator.java | 10 +++++----- .../io/anuke/mindustry/maps/missions/WaveMission.java | 9 +++++++++ .../io/anuke/mindustry/ui/dialogs/GenViewDialog.java | 6 +++++- core/src/io/anuke/mindustry/world/ColorMapper.java | 5 ++--- .../mindustry/world/blocks/storage/CoreBlock.java | 3 ++- 9 files changed, 37 insertions(+), 12 deletions(-) diff --git a/core/src/io/anuke/mindustry/ai/Pathfinder.java b/core/src/io/anuke/mindustry/ai/Pathfinder.java index 0e141cca5d..a00a7e756d 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfinder.java +++ b/core/src/io/anuke/mindustry/ai/Pathfinder.java @@ -40,6 +40,10 @@ public class Pathfinder{ }); } + public void activateTeamPath(Team team){ + createFor(team); + } + public void update(){ if(Net.client()) return; diff --git a/core/src/io/anuke/mindustry/game/Waves.java b/core/src/io/anuke/mindustry/game/Waves.java index 6917ed4f1e..4da4c37701 100644 --- a/core/src/io/anuke/mindustry/game/Waves.java +++ b/core/src/io/anuke/mindustry/game/Waves.java @@ -13,7 +13,7 @@ public class Waves{ return Array.with( new SpawnGroup(UnitTypes.dagger){{ end = 8; - unitScaling = 1; + unitScaling = 3; }}, new SpawnGroup(UnitTypes.wraith){{ diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 9578973571..2c0d3a2fa4 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -270,6 +270,8 @@ public class Sectors{ : new BattleMission()); } + sector.spawns = new Array<>(); + for(Mission mission : sector.missions){ sector.spawns.addAll(mission.getWaves(sector)); } @@ -296,6 +298,7 @@ public class Sectors{ if(headless) return; //obviously not created or needed on server Pixmap pixmap = new Pixmap(sectorImageSize * sector.width, sectorImageSize * sector.height, Format.RGBA8888); + GenResult secResult = new GenResult(); for(int x = 0; x < pixmap.getWidth(); x++){ for(int y = 0; y < pixmap.getHeight(); y++){ @@ -303,8 +306,9 @@ public class Sectors{ int toY = y * sectorSize / sectorImageSize; GenResult result = world.generator().generateTile(sector.x, sector.y, toX, toY, false); + world.generator().generateTile(secResult, sector.x, sector.y, toX, toY + sectorSize / sectorImageSize, false, null, null); - int color = ColorMapper.colorFor(result.floor, result.wall, Team.none, result.elevation, (byte)0); + int color = ColorMapper.colorFor(result.floor, result.wall, Team.none, result.elevation, secResult.elevation > result.elevation ? (byte)(1 << 6) : (byte)0); pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color); } } diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index 4bb7c4314b..516a6ef3b4 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -49,6 +49,10 @@ public class TutorialSector{ ); } + public static boolean supressDrone(){ + return world.getSector() != null && world.getSector().x == 0 && world.getSector().y == 0; + } + private static void generateBase(){ int x = sectorSize/2, y = sectorSize/2; world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam); diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index 845898590d..bd76d1a5fe 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -322,13 +322,13 @@ public class WorldGenerator{ wall = decoration.get(floor); } - if(ores != null && ((Floor) floor).hasOres && wall == Blocks.air){ - int offsetX = 10 + x, offsetY = 10 + y; + if(ores != null && ((Floor) floor).hasOres){ + int offsetX = x + 1, offsetY = y + 15; for(int i = ores.size - 1; i >= 0; i--){ Item entry = ores.get(i); - if(sim.octaveNoise2D(1, 0.7, 1f / (10 + i * 3), offsetX, offsetY) / 4f + - Math.abs(0.5f - sim.octaveNoise2D(2, 0.7, 1f / (50 + i * 2), offsetX, offsetY)) > 0.35f && - Math.abs(0.5f - sim2.octaveNoise2D(1, 1, 1f / (55 + i * 4), offsetX, offsetY)) > 0.33f){ + 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/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index 0ba837fe11..a0b06fc351 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -11,6 +11,8 @@ import io.anuke.mindustry.maps.generation.Generation; import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.state; +import static io.anuke.mindustry.Vars.waveTeam; +import static io.anuke.mindustry.Vars.world; public class WaveMission extends Mission{ private final int target; @@ -30,6 +32,13 @@ public class WaveMission extends Mission{ generateCoreAt(gen, coreX, coreY, Team.blue); } + @Override + public void onBegin(){ + super.onBegin(); + + world.pathfinder().activateTeamPath(waveTeam); + } + @Override public GameMode getMode(){ return GameMode.waves; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java index 20eb89e5e8..e966a00693 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/GenViewDialog.java @@ -4,9 +4,12 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.async.AsyncExecutor; +import io.anuke.mindustry.content.Items; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; +import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.ColorMapper; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.scene.Element; @@ -20,6 +23,7 @@ import static io.anuke.mindustry.Vars.sectorSize; import static io.anuke.mindustry.Vars.world; public class GenViewDialog extends FloatingDialog{ + Array ores = Array.with(Items.copper, Items.lead, Items.coal); public GenViewDialog(){ super("generate view"); @@ -81,7 +85,7 @@ public class GenViewDialog extends FloatingDialog{ Pixmap pixmap = new Pixmap(sectorSize, sectorSize, Format.RGBA8888); for(int i = 0; i < sectorSize; i++){ for(int j = 0; j < sectorSize; j++){ - world.generator().generateTile(result, wx, wy, i, j, true, null, null); + world.generator().generateTile(result, wx, wy, i, j, true, null, ores); pixmap.drawPixel(i, sectorSize - 1 - j, ColorMapper.colorFor(result.floor, result.wall, Team.none, result.elevation, (byte)0)); } } diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java index 00f64f10e4..14561e95dc 100644 --- a/core/src/io/anuke/mindustry/world/ColorMapper.java +++ b/core/src/io/anuke/mindustry/world/ColorMapper.java @@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.ObjectIntMap; import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.type.ContentType; -import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.content; @@ -34,8 +33,8 @@ public class ColorMapper implements ContentList{ Color tmpColor = tmpColors.get(); tmpColor.set(color); float maxMult = 1f/Math.max(Math.max(tmpColor.r, tmpColor.g), tmpColor.b) ; - float mul = Math.min(1.1f + elevation / 4f, maxMult); - if((cliffs & Mathf.pow2(6)) != 0){ + float mul = Math.min(0.7f + elevation / 5f, maxMult); + if((cliffs & ((1 << 6))) != 0){ mul -= 0.5f; } tmpColor.mul(mul, mul, mul, 1f); diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index 958994594f..f1410621e9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -16,6 +16,7 @@ import io.anuke.mindustry.entities.units.UnitType; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shaders; +import io.anuke.mindustry.maps.TutorialSector; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemType; @@ -225,7 +226,7 @@ public class CoreBlock extends StorageBlock{ } } - if(!found){ + if(!found && !TutorialSector.supressDrone()){ BaseUnit unit = droneType.create(tile.getTeam()); unit.setSpawner(tile); unit.setDead(true); From 20732f04ff77c6818433bb291f4def550bfad812 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 23 Sep 2018 23:45:35 -0400 Subject: [PATCH 19/22] Block position starting missions --- core/assets/bundles/bundle.properties | 2 +- core/src/io/anuke/mindustry/core/World.java | 12 ++++-- .../mindustry/graphics/OverlayRenderer.java | 4 ++ .../anuke/mindustry/maps/TutorialSector.java | 29 ++++++++++++--- .../maps/generation/WorldGenerator.java | 2 +- .../maps/missions/BlockLocMission.java | 37 +++++++++++++++++++ .../mindustry/maps/missions/Mission.java | 16 +++++++- 7 files changed, 89 insertions(+), 13 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 931debd6b4..8bff5f3db0 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -657,7 +657,7 @@ unit.fortress.description=A heavy artillery ground unit. unit.revenant.name=Revenant unit.revenant.description=A heavy laser platform. -tutorial.begin=Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by [accent]mining copper[] units. Tap a copper ore vein near your core to do this. +tutorial.begin=Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by [accent]mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill=Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. tutorial.conveyor=[accent]Conveyors []are used to transport items to the core.\nMake a line of conveyors from the drill to the core. tutorial.morecopper=More copper is required. Use drills to mine it. diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index e149c2e7ab..9562fc3658 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -15,6 +15,7 @@ import io.anuke.mindustry.maps.*; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.maps.generation.WorldGenerator; +import io.anuke.mindustry.world.blocks.OreBlock; import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.EntityPhysics; @@ -208,10 +209,15 @@ public class World extends Module{ public void endMapLoad(){ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ - tiles[x][y].updateOcclusion(); + Tile tile = tiles[x][y]; + tile.updateOcclusion(); - if(tiles[x][y].entity != null){ - tiles[x][y].entity.updateProximity(); + if(tile.floor() instanceof OreBlock && tile.hasCliffs()){ + tile.setFloor(((OreBlock) tile.floor()).base); + } + + if(tile.entity != null){ + tile.entity.updateProximity(); } } } diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index bd57cb5c0e..242d7ce543 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -28,6 +28,10 @@ public class OverlayRenderer{ for(Player player : players){ InputHandler input = control.input(player.playerIndex); + if(world.getSector() != null){ + world.getSector().currentMission().drawOverlay(); + } + if(!input.isDrawing() || player.isDead()) continue; Shaders.outline.color.set(Palette.accent); diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index 516a6ef3b4..ec9f59e778 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -13,23 +13,36 @@ import static io.anuke.mindustry.Vars.*; public class TutorialSector{ public static Array getMissions(){ + int x = sectorSize/2, y = sectorSize/2; + return Array.with( new ItemMission(Items.copper, 30).setMessage("$tutorial.begin"), - new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drill"), - new BlockMission(DistributionBlocks.conveyor).setMessage("$tutorial.conveyor"), + + new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 62).setMessage("$tutorial.drill"), + + new BlockLocMission(DistributionBlocks.conveyor, 57, 62, 0).setShowComplete(false).setMessage("$tutorial.conveyor"), + new BlockLocMission(DistributionBlocks.conveyor, 58, 62, 0).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 59, 62, 0).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 60, 62, 3).setShowComplete(false), + new ItemMission(Items.copper, 50).setMessage("$tutorial.morecopper"), - new BlockMission(TurretBlocks.duo).setMessage("$tutorial.turret"), - new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drillturret"), + + new BlockLocMission(TurretBlocks.duo, 56, 59).setMessage("$tutorial.turret"), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 60).setMessage("$tutorial.drillturret"), + new WaveMission(5).setMessage("$tutorial.waves"), new ExpandMission(1, 0), new ItemMission(Items.lead, 30).setMessage("$tutorial.lead"), new ItemMission(Items.copper, 150).setMessage("$tutorial.morecopper"), + new BlockMission(CraftingBlocks.smelter).setMessage("$tutorial.smelter"), new ItemMission(Items.densealloy, 30).setMessage("$tutorial.densealloy"), new BlockMission(CraftingBlocks.siliconsmelter).setMessage("$tutorial.siliconsmelter"), new BlockMission(PowerBlocks.combustionGenerator).setMessage("$tutorial.generator"), new BlockMission(PowerBlocks.powerNode).setMessage("$tutorial.node"), + new ItemMission(Items.silicon, 30).setMessage("$tutorial.silicon"), + new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"), new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), new ExpandMission(-1, 0), @@ -56,11 +69,15 @@ public class TutorialSector{ private static void generateBase(){ int x = sectorSize/2, y = sectorSize/2; world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam); - world.setBlock(world.tile(x + 1, y + 2), TurretBlocks.duo, waveTeam); - world.setBlock(world.tile(x + 1, y - 2), TurretBlocks.duo, waveTeam); + // world.setBlock(world.tile(x + 1, y + 2), TurretBlocks.duo, waveTeam); + //world.setBlock(world.tile(x + 1, y - 2), TurretBlocks.duo, waveTeam); world.setBlock(world.tile(x - 1, y + 2), UnitBlocks.daggerFactory, waveTeam); world.setBlock(world.tile(x - 1, y - 3), UnitBlocks.daggerFactory, waveTeam); + //fill turret ammo + //world.tile(x + 1, y + 2).block().handleStack(Items.copper, 1, world.tile(x + 1, y + 2), null); + //world.tile(x + 1, y - 2).block().handleStack(Items.copper, 1, world.tile(x + 1, y - 2), null); + //since placed() is not called here, add core manually state.teams.get(waveTeam).cores.add(world.tile(x, y)); } diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index bd76d1a5fe..5fd0c11ba7 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -323,7 +323,7 @@ public class WorldGenerator{ } if(ores != null && ((Floor) floor).hasOres){ - int offsetX = x + 1, offsetY = y + 15; + int offsetX = x - 4, offsetY = y + 23; for(int i = ores.size - 1; i >= 0; i--){ Item entry = ores.get(i); if( diff --git a/core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java b/core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java index a3c003b3c8..412cb2ecac 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BlockLocMission.java @@ -1,8 +1,16 @@ package io.anuke.mindustry.maps.missions; +import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.world.Block; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.graphics.Lines; +import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Bundles; +import io.anuke.ucore.util.Mathf; +import static io.anuke.mindustry.Vars.players; +import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; public class BlockLocMission extends Mission{ @@ -23,6 +31,35 @@ public class BlockLocMission extends Mission{ this.rotation = 0; } + @Override + public void drawOverlay(){ + Lines.stroke(2f); + + Draw.color(Palette.accent.r * 0.8f,Palette.accent.g * 0.8f,Palette.accent.b * 0.8f); + Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1f, block.size * tilesize/2f + 1f+ Mathf.absin(Timers.time(), 6f, 2f)); + + Draw.color(Palette.accent); + Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset(), block.size * tilesize/2f + 1f+ Mathf.absin(Timers.time(), 6f, 2f)); + + + if(block.rotate){ + Draw.colorl(0.4f); + Draw.rect("icon-arrow", x * tilesize + block.offset(), y * tilesize + block.offset() - 1f, rotation*90); + Draw.colorl(0.6f); + Draw.rect("icon-arrow", x * tilesize + block.offset(), y * tilesize + block.offset(), rotation*90); + } + + float rot = players[0].angleTo(x * tilesize + block.offset(), y * tilesize + block.offset()); + float len = 12f; + + Draw.color(Palette.accent.r * 0.8f,Palette.accent.g * 0.8f,Palette.accent.b * 0.8f); + Draw.rect("icon-arrow", players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len), rot); + Draw.color(Palette.accent); + Draw.rect("icon-arrow", players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len) + 1f, rot); + + Draw.reset(); + } + @Override public boolean isComplete(){ return world.tile(x, y).block() == block && (!block.rotate || world.tile(x,y).getRotation() == rotation); diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index 77a88084f2..63d58091bc 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -8,6 +8,7 @@ import io.anuke.mindustry.game.SpawnGroup; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.maps.Sector; import io.anuke.mindustry.maps.generation.Generation; +import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; @@ -16,6 +17,7 @@ import static io.anuke.mindustry.Vars.ui; public abstract class Mission{ private String extraMessage; + private boolean showComplete =true; public abstract boolean isComplete(); @@ -37,6 +39,16 @@ public abstract class Mission{ return this; } + public Mission setShowComplete(boolean complete){ + this.showComplete = complete; + return this; + } + + /**Draw mission overlay.*/ + public void drawOverlay(){ + + } + /**Shows the unique sector message.*/ public void showMessage(){ if(!headless && extraMessage != null){ @@ -49,11 +61,11 @@ public abstract class Mission{ } public void onBegin(){ - showMessage(); + Timers.runTask(60f, this::showMessage); } public void onComplete(){ - if(!headless){ + if(showComplete && !headless){ ui.hudfrag.showText("[LIGHT_GRAY]"+menuDisplayString() + ":\n" + Bundles.get("text.mission.complete")); } } From 32c59b66f6c959c693b3d1528c49f58e7114d156 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 24 Sep 2018 10:19:27 -0400 Subject: [PATCH 20/22] Changed tutorial ore gen --- .../src/io/anuke/annotations/Annotations.java | 4 - .../anuke/mindustry/maps/TutorialSector.java | 96 ++++++++++++------- .../maps/missions/ActionMission.java | 2 +- 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/annotations/src/io/anuke/annotations/Annotations.java b/annotations/src/io/anuke/annotations/Annotations.java index 4f8381d177..feb4dc0ec9 100644 --- a/annotations/src/io/anuke/annotations/Annotations.java +++ b/annotations/src/io/anuke/annotations/Annotations.java @@ -5,10 +5,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** - * Goal: To create a system to send events to the server from the client and vice versa, without creating a new packet type each time.
- * These events may optionally also trigger on the caller client/server as well.
- */ public class Annotations{ /** Marks a class as serializable.*/ diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index ec9f59e778..6206865b6c 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -4,8 +4,14 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.UnitTypes; import io.anuke.mindustry.content.blocks.*; +import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.maps.generation.Generation; +import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; import io.anuke.mindustry.maps.missions.*; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.Floor; +import io.anuke.ucore.core.Events; import static io.anuke.mindustry.Vars.*; @@ -13,52 +19,68 @@ import static io.anuke.mindustry.Vars.*; public class TutorialSector{ public static Array getMissions(){ - int x = sectorSize/2, y = sectorSize/2; + //int x = sectorSize/2, y = sectorSize/2; return Array.with( - new ItemMission(Items.copper, 30).setMessage("$tutorial.begin"), + new ItemMission(Items.copper, 30).setMessage("$tutorial.begin"), - new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 62).setMessage("$tutorial.drill"), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 62).setMessage("$tutorial.drill"), - new BlockLocMission(DistributionBlocks.conveyor, 57, 62, 0).setShowComplete(false).setMessage("$tutorial.conveyor"), - new BlockLocMission(DistributionBlocks.conveyor, 58, 62, 0).setShowComplete(false), - new BlockLocMission(DistributionBlocks.conveyor, 59, 62, 0).setShowComplete(false), - new BlockLocMission(DistributionBlocks.conveyor, 60, 62, 3).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 57, 62, 0).setShowComplete(false).setMessage("$tutorial.conveyor"), + new BlockLocMission(DistributionBlocks.conveyor, 58, 62, 0).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 59, 62, 0).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 60, 62, 3).setShowComplete(false), - new ItemMission(Items.copper, 50).setMessage("$tutorial.morecopper"), + new ItemMission(Items.copper, 50).setMessage("$tutorial.morecopper"), - new BlockLocMission(TurretBlocks.duo, 56, 59).setMessage("$tutorial.turret"), - new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 60).setMessage("$tutorial.drillturret"), + new BlockLocMission(TurretBlocks.duo, 56, 59).setMessage("$tutorial.turret"), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 60).setMessage("$tutorial.drillturret"), - new WaveMission(5).setMessage("$tutorial.waves"), - new ExpandMission(1, 0), - new ItemMission(Items.lead, 30).setMessage("$tutorial.lead"), - new ItemMission(Items.copper, 150).setMessage("$tutorial.morecopper"), + new WaveMission(5).setMessage("$tutorial.waves"), - new BlockMission(CraftingBlocks.smelter).setMessage("$tutorial.smelter"), - new ItemMission(Items.densealloy, 30).setMessage("$tutorial.densealloy"), - new BlockMission(CraftingBlocks.siliconsmelter).setMessage("$tutorial.siliconsmelter"), - new BlockMission(PowerBlocks.combustionGenerator).setMessage("$tutorial.generator"), - new BlockMission(PowerBlocks.powerNode).setMessage("$tutorial.node"), - - new ItemMission(Items.silicon, 30).setMessage("$tutorial.silicon"), - - new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"), - new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), - new ExpandMission(-1, 0), - new BattleMission(){ - public void generate(Generation gen){} - - @Override - public boolean isComplete(){ - return false; + new ActionMission(() -> { + Array ores = Array.with(Items.copper, Items.coal, Items.lead); + GenResult res = new GenResult(); + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ + Tile tile = world.tile(x, y); + world.generator().generateTile(res, 0, 0, x, y, true, null, ores); + if(!tile.hasCliffs()){ + tile.setFloor((Floor) res.floor); + } } + } + Events.fire(new WorldLoadEvent()); + }), - public void onBegin(){ - super.onBegin(); - generateBase(); - } - }.setMessage("$tutorial.battle") + new ItemMission(Items.lead, 30).setMessage("$tutorial.lead"), + new ItemMission(Items.copper, 150).setMessage("$tutorial.morecopper"), + + new BlockMission(CraftingBlocks.smelter).setMessage("$tutorial.smelter"), + new ItemMission(Items.densealloy, 30).setMessage("$tutorial.densealloy"), + new BlockMission(CraftingBlocks.siliconsmelter).setMessage("$tutorial.siliconsmelter"), + new BlockMission(PowerBlocks.combustionGenerator).setMessage("$tutorial.generator"), + new BlockMission(PowerBlocks.powerNode).setMessage("$tutorial.node"), + + new ItemMission(Items.silicon, 30).setMessage("$tutorial.silicon"), + + new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"), + new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), + new ExpandMission(1, 0), + new BattleMission(){ + public void generate(Generation gen){ + } + + @Override + public boolean isComplete(){ + return false; + } + + public void onBegin(){ + super.onBegin(); + generateBase(); + } + }.setMessage("$tutorial.battle") ); } @@ -67,7 +89,7 @@ public class TutorialSector{ } private static void generateBase(){ - int x = sectorSize/2, y = sectorSize/2; + int x = sectorSize/2, y = sectorSize + sectorSize/2; world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam); // world.setBlock(world.tile(x + 1, y + 2), TurretBlocks.duo, waveTeam); //world.setBlock(world.tile(x + 1, y - 2), TurretBlocks.duo, waveTeam); diff --git a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java index 99a0cc5a8f..5f45a4e3d5 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java @@ -6,7 +6,7 @@ import io.anuke.mindustry.game.GameMode; import static io.anuke.mindustry.Vars.threads; /**A mission which simply runs a single action and is completed instantly.*/ -public abstract class ActionMission extends Mission{ +public class ActionMission extends Mission{ protected Runnable runner; public ActionMission(Runnable runner){ From 5354e02b6f57b479f9f101a68fc626114724328d Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 24 Sep 2018 20:24:51 -0400 Subject: [PATCH 21/22] Finally a somewhat functional tutorial / Many bugfixes --- core/assets/bundles/bundle.properties | 35 ++-- core/assets/ui/uiskin.json | 3 +- core/src/io/anuke/mindustry/Vars.java | 4 +- .../io/anuke/mindustry/content/Recipes.java | 24 +-- .../io/anuke/mindustry/content/UnitTypes.java | 6 +- .../content/blocks/StorageBlocks.java | 2 +- .../mindustry/content/blocks/UnitBlocks.java | 2 +- core/src/io/anuke/mindustry/core/Control.java | 31 ++- core/src/io/anuke/mindustry/core/World.java | 9 + .../entities/traits/BuilderTrait.java | 3 - .../anuke/mindustry/game/ContentDatabase.java | 2 +- core/src/io/anuke/mindustry/game/Saves.java | 2 +- core/src/io/anuke/mindustry/maps/Sector.java | 4 +- core/src/io/anuke/mindustry/maps/Sectors.java | 11 ++ .../anuke/mindustry/maps/TutorialSector.java | 179 ++++++++++++------ .../maps/generation/WorldGenerator.java | 5 +- .../maps/missions/ActionMission.java | 3 +- .../mindustry/maps/missions/BlockMission.java | 4 +- .../maps/missions/ConditionMission.java | 23 +++ .../mindustry/maps/missions/ItemMission.java | 10 +- .../maps/missions/LineBlockMission.java | 46 +++++ .../mindustry/maps/missions/Mission.java | 8 + .../mindustry/maps/missions/WaveMission.java | 14 +- core/src/io/anuke/mindustry/type/Recipe.java | 20 +- .../mindustry/ui/dialogs/SectorsDialog.java | 2 +- .../ui/fragments/BlocksFragment.java | 8 +- .../mindustry/ui/fragments/HudFragment.java | 2 +- core/src/io/anuke/mindustry/world/Block.java | 14 ++ .../world/blocks/distribution/ItemBridge.java | 8 + .../world/blocks/distribution/MassDriver.java | 8 + .../world/blocks/units/Reconstructor.java | 8 + 31 files changed, 365 insertions(+), 135 deletions(-) create mode 100644 core/src/io/anuke/mindustry/maps/missions/ConditionMission.java create mode 100644 core/src/io/anuke/mindustry/maps/missions/LineBlockMission.java diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 8bff5f3db0..9632a05ca9 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -21,7 +21,7 @@ text.level.delete.title=Confirm Delete text.map.delete=Are you sure you want to delete the map "[orange]{0}[]"? text.level.select=Level Select text.level.mode=Gamemode: -text.construction.desktop=Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use space[]. +text.construction.desktop=To deselect a block or stop building, [accent]use space[]. text.construction.title=Block Construction Guide text.construction=\ You've just selected [accent]block construction mode[].\n\n\ @@ -62,11 +62,14 @@ text.mission.info=Mission Info text.mission.complete=Mission complete! text.mission.complete.body=Sector {0},{1} has been conquered. text.mission.wave=Survive[accent] {0}/{1} []waves\nWave in {2} +text.mission.wave.enemies=Survive[accent] {0}/{1} []waves\n{2} Enemies text.mission.wave.menu=Survive[accent] {0} []waves text.mission.battle=Destroy the enemy core -text.mission.resource=Obtain {0} x{1} +text.mission.resource.menu=Obtain {0} x{1} +text.mission.resource=Obtain {0}:\n[accent]{1}/{2}[] text.mission.block=Create {0} text.mission.unit=Create {0} Unit +text.mission.linknode=Link Power Node text.mission.display=[accent]Mission:\n[LIGHT_GRAY]{0} text.none= text.close=Close @@ -657,20 +660,24 @@ unit.fortress.description=A heavy artillery ground unit. unit.revenant.name=Revenant unit.revenant.description=A heavy laser platform. -tutorial.begin=Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by [accent]mining copper[]. Tap a copper ore vein near your core to do this. +tutorial.begin=Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill=Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. -tutorial.conveyor=[accent]Conveyors []are used to transport items to the core.\nMake a line of conveyors from the drill to the core. -tutorial.morecopper=More copper is required. Use drills to mine it. -tutorial.turret=Defensive structures must be built to repel the [LIGHT_GRAY]enemy[].\nBuild a duo turret near your base. -tutorial.drillturret=Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret. -tutorial.waves=The[LIGHT_GRAY] enemy[] approaches.\n\nDefend your core for 5 waves. Build more turrets. -tutorial.lead=More ores are available. Explore to your right and mine[accent] lead[].\n\nDrag from your unit to the core to transfer resources. +tutorial.conveyor=[accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core. +tutorial.morecopper=More copper is required.\n\nEither mine it manually, or place more drills. +tutorial.turret=Defensive structures must be built to repel the[LIGHT_GRAY] enemy[].\nBuild a duo turret near your base. +tutorial.drillturret=Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret to supply it with mined copper. +tutorial.waves=The[LIGHT_GRAY] enemy[] approaches.\n\nDefend your core for 2 waves. Build more turrets. +tutorial.lead=More ores are available. Explore and mine[accent] lead[].\n\nDrag from your unit to the core to transfer resources. tutorial.smelter=Copper and lead are weak metals.\nSuperior[accent] Dense Alloy[] can be created in a smelter.\n\nBuild one. -tutorial.densealloy=Create conveyors leading copper, lead and coal from drills into the smelter.\nCreate an additional output conveyor leading to the core.\n\nUse this to create 30 dense alloy. -tutorial.siliconsmelter=Advanced weapons require[accent] silicon.\nMake a silicon smelter. +tutorial.densealloy=The smelter will now produce alloy.\nGet some.\nImprove the production if necessary. +tutorial.siliconsmelter=The core will now create a[accent] spirit drone[] for mining and repairing blocks.\n\nFactories for other units can be created with [accent] silicon.\nMake a silicon smelter. +tutorial.silicondrill=Silicon requires[accent] coal[] and[accent] sand[].\nStart by making drills. tutorial.generator=This technology requires power.\nCreate a[accent] combustion generator[] for it. -tutorial.node=Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power.\nTo link power, tap the node.\n\nLink the generator to the silicon smelter. -tutorial.silicon=Fuel the combustion generator with coal from drills.\nInput sand and coal from drills into the silicon smelter\nThis will produce silicon.\n\nMake some silicon and move it into your base. +tutorial.generatordrill=Combustion generators need fuel.\nFuel it with coal from a drill. +tutorial.node=Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power. +tutorial.nodelink=Power can be transferred through contacting power blocks and generators, or by linked power nodes.\n\nLink power by tapping the node and selecting the generator and silicon smelter. +tutorial.silicon=Silicon is being produced. Get some.\n\nImproving the production system is advised. tutorial.daggerfactory=Construct a[accent] dagger mech factory.[]\n\nThis will be used to create attack mechs. -tutorial.dagger=Supply silicon, copper and power to the factory.\nOnce requirements are met, a mech will be created.\n\nCreate more drills, generators and conveyors as necessary. +tutorial.router=Factories need resources to function.\nCreate a router to split conveyor resources. +tutorial.dagger=Link power nodes to the factory.\nOnce requirements are met, a mech will be created.\n\nCreate more drills, generators and conveyors as necessary. tutorial.battle=The[LIGHT_GRAY] enemy[] has revealed their core.\nDestroy it with your unit and dagger mechs. \ No newline at end of file diff --git a/core/assets/ui/uiskin.json b/core/assets/ui/uiskin.json index 2b3645775a..aadef91b12 100644 --- a/core/assets/ui/uiskin.json +++ b/core/assets/ui/uiskin.json @@ -41,6 +41,7 @@ TintedDrawable: { loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} }, chatfield: {name: white, color: {r: 0, g: 0, b: 0, a: 0.2}}, clear: {name: white, color: {r: 0.1, g: 0.1, b: 0.1, a: 0.75}}, + none: {name: white, color: {r: 0, g: 0, b: 0, a: 0}}, clear-over: {name: white, color: {r: 1, g: 1, b: 1, a: 0.2} }, clear-down: {name: white, color: {r: 1, g: 1, b: 1, a: 0.4} } }, @@ -64,7 +65,7 @@ ImageButtonStyle: { static: {up: button }, static-down: {up: button-down }, toggle: {checked: button-down, down: button-down, up: button, imageDisabledColor: gray, imageUpColor: white }, - select: {checked: button-select, up: clear }, + select: {checked: button-select, up: none }, clear: {down: clear-down, up: clear, over: clear-over}, }, ScrollPaneStyle: { diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 449318f9bd..642686e1f4 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -36,14 +36,14 @@ public class Vars{ //time between waves in frames (on normal mode) public static final float wavespace = 60 * 60 * 1.5f; - public static final float mineTransferRange = 310f; + public static final float mineTransferRange = 250f; //set ridiculously high for now public static final float coreBuildRange = 999999f; //team of the player by default public static final Team defaultTeam = Team.blue; //team of the enemy in waves public static final Team waveTeam = Team.red; - public static final float unlockResourceScaling = 1.5f; + public static final float unlockResourceScaling = 1f; public static final int maxTextLength = 150; public static final int maxNameLength = 40; public static final float itemSize = 5f; diff --git a/core/src/io/anuke/mindustry/content/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java index 9719c26bc0..cedd512d39 100644 --- a/core/src/io/anuke/mindustry/content/Recipes.java +++ b/core/src/io/anuke/mindustry/content/Recipes.java @@ -14,17 +14,17 @@ public class Recipes implements ContentList{ @Override public void load(){ //DEBUG - new Recipe(distribution, DebugBlocks.itemSource).setMode(GameMode.sandbox).setHidden(true); - new Recipe(distribution, DebugBlocks.itemVoid).setMode(GameMode.sandbox).setHidden(true); - new Recipe(liquid, DebugBlocks.liquidSource).setMode(GameMode.sandbox).setHidden(true); - new Recipe(power, DebugBlocks.powerVoid).setMode(GameMode.sandbox).setHidden(true); - new Recipe(power, DebugBlocks.powerInfinite).setMode(GameMode.sandbox).setHidden(true); + new Recipe(distribution, DebugBlocks.itemSource).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true); + new Recipe(distribution, DebugBlocks.itemVoid).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true); + new Recipe(liquid, DebugBlocks.liquidSource).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true); + new Recipe(power, DebugBlocks.powerVoid).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true); + new Recipe(power, DebugBlocks.powerInfinite).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true); //DEFENSE //walls - new Recipe(defense, DefenseBlocks.copperWall, new ItemStack(Items.copper, 12)); - new Recipe(defense, DefenseBlocks.copperWallLarge, new ItemStack(Items.copper, 12 * 4)); + new Recipe(defense, DefenseBlocks.copperWall, new ItemStack(Items.copper, 12)).setAlwaysUnlocked(true); + new Recipe(defense, DefenseBlocks.copperWallLarge, new ItemStack(Items.copper, 12 * 4)).setAlwaysUnlocked(true); new Recipe(defense, DefenseBlocks.denseAlloyWall, new ItemStack(Items.densealloy, 12)); new Recipe(defense, DefenseBlocks.denseAlloyWallLarge, new ItemStack(Items.densealloy, 12 * 4)); @@ -51,7 +51,7 @@ public class Recipes implements ContentList{ .setDependencies(Items.blastCompound); //TURRETS - new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.copper, 40)); + new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.copper, 40)).setAlwaysUnlocked(true); new Recipe(weapon, TurretBlocks.arc, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 30), new ItemStack(Items.silicon, 20)); new Recipe(weapon, TurretBlocks.hail, new ItemStack(Items.copper, 60), new ItemStack(Items.densealloy, 35)); new Recipe(weapon, TurretBlocks.lancer, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 90)); @@ -65,13 +65,13 @@ public class Recipes implements ContentList{ new Recipe(weapon, TurretBlocks.meltdown, new ItemStack(Items.copper, 500), new ItemStack(Items.lead, 700), new ItemStack(Items.densealloy, 600), new ItemStack(Items.surgealloy, 650), new ItemStack(Items.silicon, 650)); //DISTRIBUTION - new Recipe(distribution, DistributionBlocks.conveyor, new ItemStack(Items.copper, 1)); + new Recipe(distribution, DistributionBlocks.conveyor, new ItemStack(Items.copper, 1)).setAlwaysUnlocked(true); new Recipe(distribution, DistributionBlocks.titaniumconveyor, new ItemStack(Items.copper, 2), new ItemStack(Items.titanium, 1)); new Recipe(distribution, DistributionBlocks.phaseConveyor, new ItemStack(Items.phasematter, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.densealloy, 20)); //starter lead transportation - new Recipe(distribution, DistributionBlocks.junction, new ItemStack(Items.copper, 2)); - new Recipe(distribution, DistributionBlocks.router, new ItemStack(Items.copper, 6)); + new Recipe(distribution, DistributionBlocks.junction, new ItemStack(Items.copper, 2)).setAlwaysUnlocked(true); + new Recipe(distribution, DistributionBlocks.router, new ItemStack(Items.copper, 6)).setAlwaysUnlocked(true); //advanced densealloy transporation new Recipe(distribution, DistributionBlocks.distributor, new ItemStack(Items.densealloy, 8), new ItemStack(Items.copper, 8)); @@ -140,7 +140,7 @@ public class Recipes implements ContentList{ ); //DRILLS, PRODUCERS - new Recipe(production, ProductionBlocks.mechanicalDrill, new ItemStack(Items.copper, 50)); + new Recipe(production, ProductionBlocks.mechanicalDrill, new ItemStack(Items.copper, 45)).setAlwaysUnlocked(true); new Recipe(production, ProductionBlocks.pneumaticDrill, new ItemStack(Items.copper, 60), new ItemStack(Items.densealloy, 50)); new Recipe(production, ProductionBlocks.laserdrill, new ItemStack(Items.copper, 70), new ItemStack(Items.densealloy, 90), new ItemStack(Items.silicon, 60), new ItemStack(Items.titanium, 50)); new Recipe(production, ProductionBlocks.blastdrill, new ItemStack(Items.copper, 130), new ItemStack(Items.densealloy, 180), new ItemStack(Items.silicon, 120), new ItemStack(Items.titanium, 100), new ItemStack(Items.thorium, 60)); diff --git a/core/src/io/anuke/mindustry/content/UnitTypes.java b/core/src/io/anuke/mindustry/content/UnitTypes.java index b7c79e7860..2d981f7597 100644 --- a/core/src/io/anuke/mindustry/content/UnitTypes.java +++ b/core/src/io/anuke/mindustry/content/UnitTypes.java @@ -40,7 +40,7 @@ public class UnitTypes implements ContentList{ speed = 0.2f; maxVelocity = 0.8f; range = 50f; - healSpeed = 0.25f; + healSpeed = 0.22f; health = 60; }}; @@ -50,7 +50,7 @@ public class UnitTypes implements ContentList{ drag = 0.4f; range = 40f; weapon = Weapons.chainBlaster; - health = 150; + health = 130; }}; titan = new UnitType("titan", Titan.class, Titan::new){{ @@ -108,7 +108,7 @@ public class UnitTypes implements ContentList{ health = 220; buildPower = 0.9f; minePower = 1.1f; - healSpeed = 0.55f; + healSpeed = 0.5f; toMine = ObjectSet.with(Items.lead, Items.copper, Items.titanium); }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java index dee532688d..acf1f63d30 100644 --- a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java @@ -12,7 +12,7 @@ public class StorageBlocks extends BlockList implements ContentList{ @Override public void load(){ core = new CoreBlock("core"){{ - health = 1400; + health = 1100; }}; vault = new Vault("vault"){{ diff --git a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java index 708b045bff..31e06841b8 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java @@ -63,7 +63,7 @@ public class UnitBlocks extends BlockList implements ContentList{ produceTime = 1700; size = 2; consumes.power(0.05f); - consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10), new ItemStack(Items.copper, 10)}); + consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10)}); }}; titanFactory = new UnitFactory("titan-factory"){{ diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index e8da63b7b6..0720fc4c24 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -316,27 +316,19 @@ public class Control extends Module{ Platform.instance.updateRPC(); - if(!Settings.has("4.0-warning")){ - Settings.putBool("4.0-warning", true); + if(!Settings.getBool("4.0-warning-2", false)){ Timers.run(5f, () -> { FloatingDialog dialog = new FloatingDialog("[orange]WARNING![]"); - dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f); - dialog.content().add("The beta version you are about to play should be considered very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " + - "A large portion of content is still unimplemented. \nAll current art and UI is temporary, and will be re-drawn before release. " + - "\n\n[accent]Saves and maps may be corrupted without warning between updates.[] You have been warned!").wrap().width(400f); - dialog.show(); - - }); - } - - if(!Settings.has("4.0-no-sound")){ - Settings.putBool("4.0-no-sound", true); - - Timers.run(4f, () -> { - FloatingDialog dialog = new FloatingDialog("[orange]Attention![]"); - dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f); - dialog.content().add("You might have noticed that 4.0 does not have any sound.\nThis is [orange]intentional![] Sound will be added in a later update.\n\n[LIGHT_GRAY](now stop reporting this as a bug)").wrap().width(400f); + dialog.buttons().addButton("$text.ok", () -> { + dialog.hide(); + Settings.putBool("4.0-warning-2", true); + Settings.save(); + }).size(100f, 60f); + dialog.content().add("Reminder: The beta version you are about to play is very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " + + "\nThere is currently[scarlet] no sound implemented[]; this is intentional.\n" + + "All current art and UI is temporary, and will be re-drawn before release. " + + "\n\n[accent]Saves and maps may be corrupted without warning between updates.").wrap().width(400f); dialog.show(); }); } @@ -352,6 +344,8 @@ public class Control extends Module{ private void updateSectors(){ if(world.getSector() == null) return; + world.getSector().currentMission().update(); + //TODO move sector code into logic class //check unlocked sectors while(!world.getSector().complete && world.getSector().currentMission().isComplete()){ @@ -360,6 +354,7 @@ public class Control extends Module{ state.mode = world.getSector().currentMission().getMode(); world.getSector().currentMission().onBegin(); + world.sectors().save(); } //check if all assigned missions are complete diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 9562fc3658..bf3f3002b3 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -334,6 +334,15 @@ public class World extends Module{ } } + public int transform(int packed, int oldWidth, int oldHeight, int newWidth, int shiftX, int shiftY){ + int x = packed % oldWidth; + int y = packed / oldWidth; + if(!Mathf.inBounds(x, y, oldWidth, oldHeight)) return -1; + x += shiftX; + y += shiftY; + return y*newWidth + x; + } + /** * Raycast, but with world coordinates. */ diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index 1edf7165b6..c49dca1a6a 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -311,9 +311,6 @@ public interface BuilderTrait extends Entity{ Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f)); - Fill.tri(px, py, x2, y2, x1, y1); - Fill.tri(px, py, x2, y2, x3, y3); - Draw.alpha(1f); Lines.line(px, py, x1, y1); diff --git a/core/src/io/anuke/mindustry/game/ContentDatabase.java b/core/src/io/anuke/mindustry/game/ContentDatabase.java index 8ec95cfdbc..97c825964a 100644 --- a/core/src/io/anuke/mindustry/game/ContentDatabase.java +++ b/core/src/io/anuke/mindustry/game/ContentDatabase.java @@ -40,7 +40,7 @@ public class ContentDatabase{ * @return whether or not this content was newly unlocked. */ public boolean unlockContent(UnlockableContent content){ - if(!content.canBeUnlocked()) return false; + if(!content.canBeUnlocked() || content.alwaysUnlocked()) return false; if(!unlocked.containsKey(content.getContentType())){ unlocked.put(content.getContentType(), new ObjectSet<>()); diff --git a/core/src/io/anuke/mindustry/game/Saves.java b/core/src/io/anuke/mindustry/game/Saves.java index dfe6c11fee..398a72b2ae 100644 --- a/core/src/io/anuke/mindustry/game/Saves.java +++ b/core/src/io/anuke/mindustry/game/Saves.java @@ -79,7 +79,7 @@ public class Saves{ if(time > Settings.getInt("saveinterval") * 60){ saving = true; - Timers.run(2f, () -> { + Timers.runTask(2f, () -> { try{ current.save(); }catch(Exception e){ diff --git a/core/src/io/anuke/mindustry/maps/Sector.java b/core/src/io/anuke/mindustry/maps/Sector.java index e1ce211748..1c07912dfc 100644 --- a/core/src/io/anuke/mindustry/maps/Sector.java +++ b/core/src/io/anuke/mindustry/maps/Sector.java @@ -41,7 +41,9 @@ public class Sector{ /**Returns scaled difficulty. This is not just the difficulty ordinal.*/ public Difficulty getDifficulty(){ if(difficulty == 0){ - return Difficulty.easy; + //yes, this means insane tutorial difficulty + //(((have fun))) + return Difficulty.hard; }else if(difficulty < 4){ return Difficulty.normal; }else if(difficulty < 9){ diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 2c0d3a2fa4..2846297699 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -41,6 +41,9 @@ public class Sectors{ } if(!sector.hasSave()){ + for(Mission mission : sector.missions){ + mission.reset(); + } world.loadSector(sector); logic.play(); sector.saveID = control.getSaves().addSave("sector-" + sector.packedPosition()).index; @@ -53,6 +56,7 @@ public class Sectors{ sector.getSave().load(); world.setSector(sector); state.set(State.playing); + sector.currentMission().onBegin(); }catch(Exception e){ Log.err(e); sector.getSave().delete(); @@ -145,6 +149,7 @@ public class Sectors{ 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); } } @@ -171,6 +176,8 @@ public class Sectors{ //end loading of map world.endMapLoad(); + threads.runGraphics(() -> createTexture(sector)); + return true; } @@ -297,6 +304,10 @@ public class Sectors{ private void createTexture(Sector sector){ if(headless) return; //obviously not created or needed on server + if(sector.texture != null){ + sector.texture.dispose(); + } + Pixmap pixmap = new Pixmap(sectorImageSize * sector.width, sectorImageSize * sector.height, Format.RGBA8888); GenResult secResult = new GenResult(); diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index 6206865b6c..be1e8f6990 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -5,91 +5,150 @@ import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.UnitTypes; import io.anuke.mindustry.content.blocks.*; import io.anuke.mindustry.game.EventType.WorldLoadEvent; -import io.anuke.mindustry.maps.generation.Generation; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; import io.anuke.mindustry.maps.missions.*; import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; import io.anuke.ucore.core.Events; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.*; /**Just a class for returning the list of tutorial missions.*/ public class TutorialSector{ + private static int droneIndex; public static Array getMissions(){ //int x = sectorSize/2, y = sectorSize/2; - return Array.with( - new ItemMission(Items.copper, 30).setMessage("$tutorial.begin"), + Array missions = Array.with( + new ItemMission(Items.copper, 60).setMessage("$tutorial.begin"), - new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 62).setMessage("$tutorial.drill"), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 62).setMessage("$tutorial.drill"), - new BlockLocMission(DistributionBlocks.conveyor, 57, 62, 0).setShowComplete(false).setMessage("$tutorial.conveyor"), - new BlockLocMission(DistributionBlocks.conveyor, 58, 62, 0).setShowComplete(false), - new BlockLocMission(DistributionBlocks.conveyor, 59, 62, 0).setShowComplete(false), - new BlockLocMission(DistributionBlocks.conveyor, 60, 62, 3).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 57, 62, 0).setShowComplete(false).setMessage("$tutorial.conveyor"), + new BlockLocMission(DistributionBlocks.conveyor, 58, 62, 0).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 59, 62, 0).setShowComplete(false), + new BlockLocMission(DistributionBlocks.conveyor, 60, 62, 3).setShowComplete(false), - new ItemMission(Items.copper, 50).setMessage("$tutorial.morecopper"), + new ItemMission(Items.copper, 100).setMessage("$tutorial.morecopper"), - new BlockLocMission(TurretBlocks.duo, 56, 59).setMessage("$tutorial.turret"), - new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 60).setMessage("$tutorial.drillturret"), + new BlockLocMission(TurretBlocks.duo, 56, 59).setMessage("$tutorial.turret"), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 60).setMessage("$tutorial.drillturret"), - new WaveMission(5).setMessage("$tutorial.waves"), + new WaveMission(2).setMessage("$tutorial.waves"), - new ActionMission(() -> { - Array ores = Array.with(Items.copper, Items.coal, Items.lead); - GenResult res = new GenResult(); - for(int x = 0; x < world.width(); x++){ - for(int y = 0; y < world.height(); y++){ - Tile tile = world.tile(x, y); - world.generator().generateTile(res, 0, 0, x, y, true, null, ores); - if(!tile.hasCliffs()){ - tile.setFloor((Floor) res.floor); + new ActionMission(() -> { + Timers.runTask(30f, () -> { + Runnable r = () -> { + Array ores = Array.with(Items.copper, Items.coal, Items.lead); + GenResult res = new GenResult(); + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ + Tile tile = world.tile(x, y); + world.generator().generateTile(res, 0, 0, x, y, true, null, ores); + if(!tile.hasCliffs()){ + tile.setFloor((Floor) res.floor); + } + } + } + Events.fire(new WorldLoadEvent()); + }; + + if(headless){ + ui.loadLogic(r); + }else{ + threads.run(r); } + }); + }), + + new ItemMission(Items.lead, 90).setMessage("$tutorial.lead"), + new ItemMission(Items.copper, 250).setMessage("$tutorial.morecopper"), + + new BlockLocMission(CraftingBlocks.smelter, 58, 69).setMessage("$tutorial.smelter"), + + //drills for smelter + new BlockLocMission(ProductionBlocks.mechanicalDrill, 62, 86), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 58, 89), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 54, 68), + + //conveyors for smelter + new LineBlockMission(DistributionBlocks.conveyor, 58, 88, 58, 70, 3), + new LineBlockMission(DistributionBlocks.conveyor, 61, 86, 61, 70, 3), + new LineBlockMission(DistributionBlocks.conveyor, 61, 69, 59, 69, 2), + new LineBlockMission(DistributionBlocks.conveyor, 56, 69, 57, 69, 0), + new LineBlockMission(DistributionBlocks.conveyor, 58, 68, 58, 63, 3), + new BlockLocMission(DistributionBlocks.junction, 58, 62, 0), + new BlockLocMission(DistributionBlocks.conveyor, 58, 61, 0), + + new ItemMission(Items.densealloy, 20).setMessage("$tutorial.densealloy"), + + new MarkerBlockMission(CraftingBlocks.siliconsmelter, 54, 52).setMessage("$tutorial.siliconsmelter"), + + //coal line + new BlockLocMission(ProductionBlocks.mechanicalDrill, 47, 52).setMessage("$tutorial.silicondrill"), + new LineBlockMission(DistributionBlocks.conveyor, 49, 52, 53, 52, 0), + + //sand line + new BlockLocMission(ProductionBlocks.mechanicalDrill, 53, 49), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 56, 49), + new LineBlockMission(DistributionBlocks.conveyor, 55, 50, 55, 51, 1), + + //silicon line + new LineBlockMission(DistributionBlocks.conveyor, 56, 53, 59, 53, 0), + new LineBlockMission(DistributionBlocks.conveyor, 60, 53, 60, 58, 1), + + new BlockLocMission(PowerBlocks.combustionGenerator, 49, 54).setMessage("$tutorial.generator"), + new BlockLocMission(ProductionBlocks.mechanicalDrill, 47, 54).setMessage("$tutorial.generatordrill"), + new BlockLocMission(PowerBlocks.powerNode, 52, 54).setMessage("$tutorial.node"), + new ConditionMission(Bundles.get("text.mission.linknode"), () -> world.tile(54, 52).entity != null && world.tile(54, 52).entity.power != null && world.tile(54, 52).entity.power.amount >= 0.01f) + .setMessage("$tutorial.nodelink"), + + new ItemMission(Items.silicon, 70).setMessage("$tutorial.silicon"), + + new BlockLocMission(UnitBlocks.daggerFactory, 64, 59).setMessage("$tutorial.daggerfactory"), + + //silicon lines for dagger factory + new BlockLocMission(DistributionBlocks.router, 60, 57).setMessage("$tutorial.router"), + new LineBlockMission(DistributionBlocks.conveyor, 61, 57, 63, 57, 0), + new LineBlockMission(DistributionBlocks.conveyor, 64, 57, 64, 58, 1), + + //power for dagger factory + new BlockLocMission(PowerBlocks.powerNode, 57, 54), + new BlockLocMission(PowerBlocks.powerNode, 62, 54), + + new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), + new ExpandMission(1, 0){ + @Override + public void onComplete(){ + super.onComplete(); + generateBase(); } - } - Events.fire(new WorldLoadEvent()); - }), - - new ItemMission(Items.lead, 30).setMessage("$tutorial.lead"), - new ItemMission(Items.copper, 150).setMessage("$tutorial.morecopper"), - - new BlockMission(CraftingBlocks.smelter).setMessage("$tutorial.smelter"), - new ItemMission(Items.densealloy, 30).setMessage("$tutorial.densealloy"), - new BlockMission(CraftingBlocks.siliconsmelter).setMessage("$tutorial.siliconsmelter"), - new BlockMission(PowerBlocks.combustionGenerator).setMessage("$tutorial.generator"), - new BlockMission(PowerBlocks.powerNode).setMessage("$tutorial.node"), - - new ItemMission(Items.silicon, 30).setMessage("$tutorial.silicon"), - - new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"), - new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"), - new ExpandMission(1, 0), - new BattleMission(){ - public void generate(Generation gen){ - } - - @Override - public boolean isComplete(){ - return false; - } - - public void onBegin(){ - super.onBegin(); - generateBase(); - } - }.setMessage("$tutorial.battle") + }, + new BattleMission().setMessage("$tutorial.battle") ); + + //find drone marker mission + for(int i = 0; i < missions.size; i++){ + if(missions.get(i) instanceof MarkerBlockMission){ + droneIndex = i; + break; + } + } + + return missions; } public static boolean supressDrone(){ - return world.getSector() != null && world.getSector().x == 0 && world.getSector().y == 0; + return world.getSector() != null && world.getSector().x == 0 && world.getSector().y == 0 && world.getSector().completedMissions < droneIndex; } private static void generateBase(){ - int x = sectorSize/2, y = sectorSize + sectorSize/2; + int x = sectorSize/2 + sectorSize, y = sectorSize/2; world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam); // world.setBlock(world.tile(x + 1, y + 2), TurretBlocks.duo, waveTeam); //world.setBlock(world.tile(x + 1, y - 2), TurretBlocks.duo, waveTeam); @@ -101,6 +160,14 @@ public class TutorialSector{ //world.tile(x + 1, y - 2).block().handleStack(Items.copper, 1, world.tile(x + 1, y - 2), null); //since placed() is not called here, add core manually - state.teams.get(waveTeam).cores.add(world.tile(x, y)); + if(!state.teams.get(waveTeam).cores.contains(world.tile(x, y), true)){ + state.teams.get(waveTeam).cores.add(world.tile(x, y)); + } + } + + private static class MarkerBlockMission extends BlockLocMission{ + public MarkerBlockMission(Block block, int x, int y){ + super(block, x, y); + } } } diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java index 5fd0c11ba7..eaa7ede832 100644 --- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java @@ -215,8 +215,6 @@ public class WorldGenerator{ } } - //generateOres(tiles, sector.getSeed(), true, ores); - for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ Tile tile = tiles[x][y]; @@ -242,7 +240,6 @@ public class WorldGenerator{ return generateTile(result, sectorX, sectorY, localX, localY, detailed, null, null); } - //TODO include ore in result /** * Gets the generation result from a specific sector at specific coordinates. * @param result where to put the generation results @@ -265,7 +262,7 @@ public class WorldGenerator{ double iceridge = rid.getValue(x+99999, y, 1f / 300f) + sim3.octaveNoise2D(2, 1f, 1f/14f, x, y)/11f; double elevation = elevationOf(x, y, detailed); double temp = - + sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x, y); + + sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x - 120, y); int lerpDst = 20; lerpDst *= lerpDst; diff --git a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java index 5f45a4e3d5..5852bd337c 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.maps.missions; import io.anuke.mindustry.Vars; import io.anuke.mindustry.game.GameMode; +import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.threads; @@ -28,7 +29,7 @@ public class ActionMission extends Mission{ @Override public String displayString(){ - return ""; + return Bundles.get("text.loading"); } @Override diff --git a/core/src/io/anuke/mindustry/maps/missions/BlockMission.java b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java index 6ec0457c8d..beff68c6d4 100644 --- a/core/src/io/anuke/mindustry/maps/missions/BlockMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/BlockMission.java @@ -10,6 +10,7 @@ import static io.anuke.mindustry.Vars.defaultTeam; import static io.anuke.mindustry.Vars.world; /**A mission in which the player must place a block.*/ +@Deprecated public class BlockMission extends Mission{ private final Block block; private boolean complete; @@ -33,8 +34,7 @@ public class BlockMission extends Mission{ } @Override - public void onComplete(){ - super.onComplete(); + public void reset(){ complete = false; } diff --git a/core/src/io/anuke/mindustry/maps/missions/ConditionMission.java b/core/src/io/anuke/mindustry/maps/missions/ConditionMission.java new file mode 100644 index 0000000000..68e141633b --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/ConditionMission.java @@ -0,0 +1,23 @@ +package io.anuke.mindustry.maps.missions; + +import io.anuke.ucore.function.BooleanProvider; + +public class ConditionMission extends Mission{ + private final BooleanProvider complete; + private final String display; + + public ConditionMission(String display, BooleanProvider complete){ + this.complete = complete; + this.display = display; + } + + @Override + public boolean isComplete(){ + return complete.get(); + } + + @Override + public String displayString(){ + return display; + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/ItemMission.java b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java index fbf24430a9..45ba039a3f 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ItemMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.maps.missions; import io.anuke.mindustry.Vars; +import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; @@ -35,6 +36,13 @@ public class ItemMission extends Mission{ @Override public String displayString(){ - return Bundles.format("text.mission.resource", item.localizedName(), amount); + TileEntity core = Vars.players[0].getClosestCore(); + if(core == null) return "imminent doom"; + return Bundles.format("text.mission.resource", item.localizedName(), core.items.get(item), amount); + } + + @Override + public String menuDisplayString(){ + return Bundles.format("text.mission.resource.menu", item.localizedName(), amount); } } diff --git a/core/src/io/anuke/mindustry/maps/missions/LineBlockMission.java b/core/src/io/anuke/mindustry/maps/missions/LineBlockMission.java new file mode 100644 index 0000000000..918788b55c --- /dev/null +++ b/core/src/io/anuke/mindustry/maps/missions/LineBlockMission.java @@ -0,0 +1,46 @@ +package io.anuke.mindustry.maps.missions; + +import com.badlogic.gdx.math.Bresenham2; +import com.badlogic.gdx.math.GridPoint2; +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.world.Block; + +public class LineBlockMission extends Mission{ + private Array points = new Array<>(); + private int completeIndex; + + public LineBlockMission(Block block, int x1, int y1, int x2, int y2, int rotation){ + Array points = new Bresenham2().line(x1, y1, x2, y2); + for(GridPoint2 point : points){ + this.points.add(new BlockLocMission(block, point.x, point.y, rotation)); + } + } + + @Override + public boolean isComplete(){ + while(completeIndex < points.size && points.get(completeIndex).isComplete()){ + completeIndex ++; + } + return completeIndex >= points.size; + } + + @Override + public void drawOverlay(){ + if(completeIndex < points.size){ + points.get(completeIndex).drawOverlay(); + } + } + + @Override + public void reset(){ + completeIndex = 0; + } + + @Override + public String displayString(){ + if(completeIndex < points.size){ + return points.get(completeIndex).displayString(); + } + return points.first().displayString(); + } +} diff --git a/core/src/io/anuke/mindustry/maps/missions/Mission.java b/core/src/io/anuke/mindustry/maps/missions/Mission.java index 63d58091bc..61994587e9 100644 --- a/core/src/io/anuke/mindustry/maps/missions/Mission.java +++ b/core/src/io/anuke/mindustry/maps/missions/Mission.java @@ -49,6 +49,14 @@ public abstract class Mission{ } + public void update(){ + + } + + public void reset(){ + + } + /**Shows the unique sector message.*/ public void showMessage(){ if(!headless && extraMessage != null){ diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index a0b06fc351..43c3e24b59 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.maps.missions; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.SpawnGroup; import io.anuke.mindustry.game.Team; @@ -46,7 +47,9 @@ public class WaveMission extends Mission{ @Override public String displayString(){ - return Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60)); + return state.wave > target ? + Bundles.format("text.mission.wave.enemies", state.wave, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) : + Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60)); } @Override @@ -54,9 +57,16 @@ public class WaveMission extends Mission{ return Bundles.format("text.mission.wave.menu", target); } + @Override + public void update(){ + if(state.wave > target){ + state.mode = GameMode.noWaves; + } + } + @Override public boolean isComplete(){ - return state.wave >= target; + return state.wave > target && Vars.unitGroups[Vars.waveTeam.ordinal()].size() == 0; } @Override diff --git a/core/src/io/anuke/mindustry/type/Recipe.java b/core/src/io/anuke/mindustry/type/Recipe.java index 1d484bc25e..ff81d31414 100644 --- a/core/src/io/anuke/mindustry/type/Recipe.java +++ b/core/src/io/anuke/mindustry/type/Recipe.java @@ -33,6 +33,7 @@ public class Recipe extends UnlockableContent{ public GameMode mode; public boolean isPad; public boolean hidden; + public boolean alwaysUnlocked; private UnlockableContent[] dependencies; private Block[] blockDependencies; @@ -58,15 +59,16 @@ public class Recipe extends UnlockableContent{ * Returns unlocked recipes in a category. * Do not call on the server backend, as unlocking does not exist! */ - public static void getUnlockedByCategory(Category category, Array r){ + public static void getUnlockedByCategory(Category category, Array arr){ if(headless){ throw new RuntimeException("Not implemented on the headless backend!"); } - r.clear(); - for(Recipe recipe : content.recipes()){ - if(recipe.category == category && (control.database().isUnlocked(recipe))){ - r.add(recipe); + arr.clear(); + for(Recipe r : content.recipes()){ + if(r.category == category && (control.database().isUnlocked(r)) && + !((r.mode != null && r.mode != state.mode) || (r.desktopOnly && mobile) || (r.isPad && !state.mode.showPads))){ + arr.add(r); } } } @@ -107,9 +109,15 @@ public class Recipe extends UnlockableContent{ return this; } + public Recipe setAlwaysUnlocked(boolean unlocked){ + this.alwaysUnlocked = unlocked; + return this; + } + + @Override public boolean alwaysUnlocked(){ - return hidden; + return alwaysUnlocked; } @Override diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index 1f414c043b..fafdc596c8 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -44,7 +44,7 @@ public class SectorsDialog extends FloatingDialog{ content().row(); content().label(() -> Bundles.format("text.mission", selected == null || selected.completedMissions >= selected.missions.size ? Bundles.get("text.none") : selected.missions.get(selected.completedMissions).menuDisplayString()) - + "[WHITE] " + (selected == null ? "" : Bundles.format("text.save.difficulty", "[LIGHT_GRAY]" + selected.getDifficulty().toString()))); + + "[WHITE] " /*+ (selected == null ? "" : Bundles.format("text.save.difficulty", "[LIGHT_GRAY]" + selected.getDifficulty().toString()))*/); content().row(); content().add(new SectorView()).grow(); content().row(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index 1a4f6107c9..2728a52a58 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -81,14 +81,16 @@ public class BlocksFragment extends Fragment{ } }); - container.add(descTable).fillX().uniformX(); + float w = 246f; - container.row(); + main.add(descTable).width(w); + + main.row(); //now add the block selection menu selectTable = main.table("pane", select -> {}) .margin(10f).marginLeft(0f).marginRight(0f).marginTop(-5) - .touchable(Touchable.enabled).right().bottom().get(); + .touchable(Touchable.enabled).right().bottom().width(w).get(); }).bottom().right().get(); }); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 6d4fd42381..11f0b9a411 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -308,7 +308,7 @@ public class HudFragment extends Fragment{ shouldPause = true; setFillParent(false); getCell(content()).growX(); - content().margin(15).add(str).width(600f).wrap().get().setAlignment(Align.left, Align.left); + content().margin(15).add(str).width(400f).wrap().get().setAlignment(Align.left, Align.left); buttons().addButton("$text.continue", this::hide).size(140, 60).pad(4); }}.show(); } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 9c3b25ad37..5c949ae312 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.world; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.IntArray; import io.anuke.mindustry.entities.Damage; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; @@ -252,6 +253,19 @@ public class Block extends BaseBlock { region = Draw.region(name); } + /**Called when the world is resized. + * Call super!*/ + public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ + if(tile.entity != null && tile.entity.power != null){ + IntArray links = tile.entity.power.links; + IntArray out = new IntArray(); + for(int i = 0; i < links.size; i++){ + out.add(world.transform(links.get(i), oldWidth, oldHeight, newWidth, shiftX, shiftY)); + } + tile.entity.power.links = out; + } + } + /** Called when the block is tapped. */ public void tapped(Tile tile, Player player){ diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index 5eee09e958..ed3b5c3ebe 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -286,6 +286,14 @@ public class ItemBridge extends Block{ return rel != rel2; } + @Override + public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ + super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY); + + ItemBridgeEntity entity = tile.entity(); + entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY); + } + @Override public TileEntity newEntity(){ return new ItemBridgeEntity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index d336911253..1fe8301645 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -233,6 +233,14 @@ public class MassDriver extends Block{ return tile.entity.items.total() < itemCapacity; } + @Override + public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ + super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY); + + MassDriverEntity entity = tile.entity(); + entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY); + } + @Override public TileEntity newEntity(){ return new MassDriverEntity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java index 304dba3185..b55fe56774 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java @@ -298,6 +298,14 @@ public class Reconstructor extends Block{ Call.reconstructPlayer(player, tile); } + @Override + public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ + super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY); + + ReconstructorEntity entity = tile.entity(); + entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY); + } + @Override public TileEntity newEntity(){ return new ReconstructorEntity(); From af86564adcedde27dccdcba4f248ee3e6f1bffa9 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 24 Sep 2018 22:56:48 -0400 Subject: [PATCH 22/22] Final tutorial fixes --- core/assets/bundles/bundle.properties | 3 ++- core/src/io/anuke/mindustry/Vars.java | 2 +- core/src/io/anuke/mindustry/entities/units/BaseUnit.java | 4 ++++ core/src/io/anuke/mindustry/input/DesktopInput.java | 4 ++++ core/src/io/anuke/mindustry/maps/Sectors.java | 8 ++++++++ core/src/io/anuke/mindustry/maps/TutorialSector.java | 7 +++++-- .../io/anuke/mindustry/maps/missions/ActionMission.java | 7 ------- .../src/io/anuke/mindustry/maps/missions/ItemMission.java | 6 ------ .../src/io/anuke/mindustry/maps/missions/UnitMission.java | 6 ------ .../src/io/anuke/mindustry/maps/missions/WaveMission.java | 5 ++++- .../mindustry/world/blocks/defense/MendProjector.java | 5 +++-- 11 files changed, 31 insertions(+), 26 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 9632a05ca9..5f9e18f77b 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -63,6 +63,7 @@ text.mission.complete=Mission complete! text.mission.complete.body=Sector {0},{1} has been conquered. text.mission.wave=Survive[accent] {0}/{1} []waves\nWave in {2} text.mission.wave.enemies=Survive[accent] {0}/{1} []waves\n{2} Enemies +text.mission.wave.enemy=Survive[accent] {0}/{1} []waves\n{2} Enemy text.mission.wave.menu=Survive[accent] {0} []waves text.mission.battle=Destroy the enemy core text.mission.resource.menu=Obtain {0} x{1} @@ -284,7 +285,7 @@ text.settings.clearall=Clear All text.paused=Paused text.yes=Yes text.no=No -text.info.title=[accent]Info +text.info.title=Info text.error.title=[crimson]An error has occured text.error.crashtitle=An error has occured text.blocks.blockinfo=Block Info diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 642686e1f4..30bb9cece1 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -36,7 +36,7 @@ public class Vars{ //time between waves in frames (on normal mode) public static final float wavespace = 60 * 60 * 1.5f; - public static final float mineTransferRange = 250f; + public static final float mineTransferRange = 220f; //set ridiculously high for now public static final float coreBuildRange = 999999f; //team of the player by default diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java index cbe63c5118..7aac45600c 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java @@ -121,6 +121,10 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ this.spawner = tile.packedPosition(); } + public void setIntSpawner(int pos){ + this.spawner = pos; + } + /**Sets this to a 'wave' unit, which means it has slightly different AI and will not run out of ammo.*/ public void setWave(){ isWave = true; diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 1806ae81e2..d85f94db96 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -206,6 +206,10 @@ public class DesktopInput extends InputHandler{ return; } + if(Inputs.keyTap(section, "deselect")){ + player.setMineTile(null); + } + if(!ui.hasMouse()){ if(Inputs.keyTap(section, "select")){ if(isPlacing()){ diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 2846297699..153d8681cf 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.Texture; 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.Team; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; @@ -132,6 +133,13 @@ public class Sectors{ 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)); + } } } diff --git a/core/src/io/anuke/mindustry/maps/TutorialSector.java b/core/src/io/anuke/mindustry/maps/TutorialSector.java index be1e8f6990..9fd4f49d6b 100644 --- a/core/src/io/anuke/mindustry/maps/TutorialSector.java +++ b/core/src/io/anuke/mindustry/maps/TutorialSector.java @@ -5,6 +5,7 @@ import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.UnitTypes; import io.anuke.mindustry.content.blocks.*; import io.anuke.mindustry.game.EventType.WorldLoadEvent; +import io.anuke.mindustry.maps.generation.Generation; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; import io.anuke.mindustry.maps.missions.*; import io.anuke.mindustry.type.Item; @@ -66,7 +67,7 @@ public class TutorialSector{ }); }), - new ItemMission(Items.lead, 90).setMessage("$tutorial.lead"), + new ItemMission(Items.lead, 150).setMessage("$tutorial.lead"), new ItemMission(Items.copper, 250).setMessage("$tutorial.morecopper"), new BlockLocMission(CraftingBlocks.smelter, 58, 69).setMessage("$tutorial.smelter"), @@ -129,7 +130,9 @@ public class TutorialSector{ generateBase(); } }, - new BattleMission().setMessage("$tutorial.battle") + new BattleMission(){ + public void generate(Generation gen){} //no + }.setMessage("$tutorial.battle") ); //find drone marker mission diff --git a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java index 5852bd337c..55710aa1ff 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ActionMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ActionMission.java @@ -1,7 +1,5 @@ package io.anuke.mindustry.maps.missions; -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.game.GameMode; import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.threads; @@ -31,9 +29,4 @@ public class ActionMission extends Mission{ public String displayString(){ return Bundles.get("text.loading"); } - - @Override - public GameMode getMode(){ - return Vars.state.mode; - } } diff --git a/core/src/io/anuke/mindustry/maps/missions/ItemMission.java b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java index 45ba039a3f..a65eb4bc31 100644 --- a/core/src/io/anuke/mindustry/maps/missions/ItemMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/ItemMission.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.maps.missions; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.util.Bundles; @@ -19,11 +18,6 @@ public class ItemMission extends Mission{ this.amount = amount; } - @Override - public GameMode getMode(){ - return GameMode.waves; - } - @Override public boolean isComplete(){ for(Tile tile : state.teams.get(Vars.defaultTeam).cores){ diff --git a/core/src/io/anuke/mindustry/maps/missions/UnitMission.java b/core/src/io/anuke/mindustry/maps/missions/UnitMission.java index 36a10ece7c..efe097a687 100644 --- a/core/src/io/anuke/mindustry/maps/missions/UnitMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/UnitMission.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.maps.missions; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.UnitType; -import io.anuke.mindustry.game.GameMode; import io.anuke.ucore.util.Bundles; public class UnitMission extends Mission{ @@ -27,9 +26,4 @@ public class UnitMission extends Mission{ public String displayString(){ return Bundles.format("text.mission.unit", type.localizedName()); } - - @Override - public GameMode getMode(){ - return GameMode.noWaves; - } } diff --git a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java index 43c3e24b59..6e65f6c71b 100644 --- a/core/src/io/anuke/mindustry/maps/missions/WaveMission.java +++ b/core/src/io/anuke/mindustry/maps/missions/WaveMission.java @@ -48,7 +48,10 @@ public class WaveMission extends Mission{ @Override public String displayString(){ return state.wave > target ? - Bundles.format("text.mission.wave.enemies", state.wave, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) : + Bundles.format( + Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 ? + "text.mission.wave.enemies" : + "text.mission.wave.enemy", target, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) : Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60)); } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java index 2ca61d9aeb..fa9559e101 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java @@ -34,7 +34,8 @@ public class MendProjector extends Block{ protected float reload = 250f; protected float range = 50f; protected float healPercent = 6f; - protected float phaseBoost = 10f; + protected float phaseBoost = 12f; + protected float phaseRangeBoost = 40f; protected float useTime = 300f; public MendProjector(String name){ @@ -65,7 +66,7 @@ public class MendProjector extends Block{ } if(entity.charge >= reload){ - float realRange = range + entity.phaseHeat * 20f; + float realRange = range + entity.phaseHeat * phaseRangeBoost; Effects.effect(BlockFx.healWaveMend, Hue.mix(color, phase, entity.phaseHeat), tile.drawx(), tile.drawy(), realRange); entity.charge = 0f;