diff --git a/core/src/io/anuke/mindustry/content/Items.java b/core/src/io/anuke/mindustry/content/Items.java index 547d4ecb24..2822651db3 100644 --- a/core/src/io/anuke/mindustry/content/Items.java +++ b/core/src/io/anuke/mindustry/content/Items.java @@ -15,7 +15,7 @@ public class Items implements ContentList{ public void load() { stone = new Item("stone", Color.valueOf("777777")) {{ - hardness = 3; + hardness = 2; }}; tungsten = new Item("tungsten", Color.valueOf("a0b0c8")) {{ diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index b5136c3caf..9169157bbd 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -16,7 +16,7 @@ public class Mechs implements ContentList { public void load() { alpha = new Mech("alpha-mech", false){{ - drillPower = 2; + drillPower = 1; speed = 0.5f; }}; diff --git a/core/src/io/anuke/mindustry/content/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java index 4d39947fca..1b65008cb9 100644 --- a/core/src/io/anuke/mindustry/content/Recipes.java +++ b/core/src/io/anuke/mindustry/content/Recipes.java @@ -95,6 +95,14 @@ public class Recipes implements ContentList{ //new Recipe(liquid, LiquidBlocks.laserconduit, new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 2), new ItemStack(Items.phasematter, 10)); new Recipe(liquid, LiquidBlocks.mechanicalPump, new ItemStack(Items.tungsten, 30), new ItemStack(Items.lead, 20)); + + //DEBUG + new Recipe(units, DebugBlocks.itemSource, new ItemStack(Items.carbide, 10)).setDebug(); + new Recipe(units, DebugBlocks.itemVoid, new ItemStack(Items.carbide, 10)).setDebug(); + new Recipe(units, DebugBlocks.liquidSource, new ItemStack(Items.carbide, 10)).setDebug(); + new Recipe(units, DebugBlocks.powerVoid, new ItemStack(Items.carbide, 10)).setDebug(); + new Recipe(units, DebugBlocks.powerInfinite, new ItemStack(Items.carbide, 10), new ItemStack(Items.surgealloy, 5)).setDebug(); + //new Recipe(liquid, LiquidBlocks.rotaryPump, new ItemStack(Items.carbide, 10), new ItemStack(Items.surgealloy, 5)); //new Recipe(liquid, LiquidBlocks.thermalPump, new ItemStack(Items.carbide, 10), new ItemStack(Items.surgealloy, 5)); diff --git a/core/src/io/anuke/mindustry/content/blocks/Blocks.java b/core/src/io/anuke/mindustry/content/blocks/Blocks.java index c6a0007a09..b4c8709f12 100644 --- a/core/src/io/anuke/mindustry/content/blocks/Blocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/Blocks.java @@ -103,11 +103,13 @@ public class Blocks extends BlockList implements ContentList{ drops = new ItemStack(Items.stone, 1); blends = block -> block != this && !(block instanceof Ore); minimapColor = Color.valueOf("323232"); + playerUnmineable = true; }}; blackstone = new Floor("blackstone") {{ drops = new ItemStack(Items.stone, 1); minimapColor = Color.valueOf("252525"); + playerUnmineable = true; }}; dirt = new Floor("dirt"){{ @@ -118,6 +120,7 @@ public class Blocks extends BlockList implements ContentList{ drops = new ItemStack(Items.sand, 1); minimapColor = Color.valueOf("988a67"); hasOres = true; + playerUnmineable = true; }}; ice = new Floor("ice") {{ diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 7104ef873f..fdb301885a 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -264,7 +264,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f); } - boostHeat = Mathf.lerpDelta(boostHeat, isBoosting ? 1f : 0f, 0.08f); + boostHeat = Mathf.lerpDelta(boostHeat, isBoosting && !movement.isZero() && moved ? 1f : 0f, 0.08f); boolean snap = snapCamera && isLocal; @@ -415,6 +415,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { hitTime = Math.max(0f, hitTime - Timers.delta()); if(isDead()){ + isBoosting = false; CoreEntity entity = (CoreEntity)getClosestCore(); if (!respawning && entity != null) { diff --git a/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java b/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java index af1f01a6db..9788aa2d7f 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java +++ b/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java @@ -207,6 +207,7 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT y = data.readFloat(); item = Item.getByID(data.readByte()); amount = data.readShort(); + add(); } @Override diff --git a/core/src/io/anuke/mindustry/entities/effect/Puddle.java b/core/src/io/anuke/mindustry/entities/effect/Puddle.java index 229b26522c..4496176cb6 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Puddle.java +++ b/core/src/io/anuke/mindustry/entities/effect/Puddle.java @@ -164,9 +164,9 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Timers.delta(); for (GridPoint2 point : Geometry.d4) { Tile other = world.tile(tile.x + point.x, tile.y + point.y); - if (other.block() == Blocks.air) { + if (other.block() == Blocks.air && other.cliffs == 0) { deposit(other, tile, liquid, deposited, generation + 1); - amount -= deposited / 4f; + amount -= deposited / 2f; //tweak to speed up/slow down puddle propagation } } } diff --git a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java index 8ee8300121..a93bde5a6f 100644 --- a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java @@ -226,6 +226,8 @@ public class FloorRenderer { Log.info("Time to create: {0}", Timers.elapsed()); + Timers.mark(); + for (int x = 0; x < chunksx; x++) { for (int y = 0; y < chunksy; y++) { cache[x][y] = new Chunk(); diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index f47cdea035..bfb163f124 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -156,7 +156,9 @@ public class DesktopInput extends InputHandler{ Tile cursor = tileAt(control.gdxInput().getX(), control.gdxInput().getY()); - if(cursor != null){ + if(player.isDead()){ + cursorType = normal; + }else if(cursor != null){ cursor = cursor.target(); cursorType = cursor.block().getCursor(cursor); @@ -197,7 +199,7 @@ public class DesktopInput extends InputHandler{ mode = placing; } else { //only begin shooting if there's no cursor event - if(!tileTapped(cursor) && player.getPlaceQueue().size == 0 && !tryTapPlayer(worldx, worldy) && !droppingItem && + if(!tileTapped(cursor) && !tryTapPlayer(worldx, worldy) && player.getPlaceQueue().size == 0 && !droppingItem && !tryBeginMine(cursor) && player.getMineTile() == null){ CallEntity.setShooting(true); } diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 0a8384af3c..db1bd9cf4a 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -162,6 +162,7 @@ public abstract class InputHandler extends InputAdapter{ boolean canMine(Tile tile){ return tile.floor().drops != null && tile.floor().drops.item.hardness <= player.mech.drillPower + && !tile.floor().playerUnmineable && player.inventory.canAcceptItem(tile.floor().drops.item) && tile.block() == Blocks.air && player.distanceTo(tile.worldx(), tile.worldy()) <= Player.mineDistance; } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java index 33eeeac887..711a883f2d 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java @@ -20,6 +20,7 @@ import io.anuke.ucore.scene.ui.layout.Stack; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.utils.Elements; import io.anuke.ucore.util.Bundles; +import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; @@ -129,6 +130,7 @@ public class LevelDialog extends FloatingDialog{ Timers.run(5f, () -> { threads.run(() -> { + Timers.mark(); MapTileData data = WorldGenerator.generate(); Map map = new Map("generated-map", new MapMeta(0, new ObjectMap<>(), data.width(), data.height(), null), true, () -> null); @@ -147,6 +149,8 @@ public class LevelDialog extends FloatingDialog{ world.endMapLoad(); + Log.info("Time to generate: {0}", Timers.elapsed()); + logic.play(); Gdx.app.postRunnable(ui.loadfrag::hide); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index 12f5e35863..2bf7378791 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -24,6 +24,7 @@ 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.Mathf; +import io.anuke.ucore.util.Strings; import static io.anuke.mindustry.Vars.*; @@ -183,12 +184,12 @@ public class BlocksFragment implements Fragment{ TextureRegion[] regions = r.result.getCompactIcon(); Stack istack = new Stack(); for(TextureRegion region : regions){ - istack.add(new Image(region)); + Image u = new Image(region); + u.update(() -> u.setColor(image.isDisabled() ? Color.GRAY : Color.WHITE)); + istack.add(u); } image.getImageCell().setActor(istack).size(size); - image.getStyle().imageUpColor = Color.WHITE; - image.getStyle().imageDisabledColor = Color.GRAY; image.addChild(istack); image.setTouchable(Touchable.enabled); image.getImage().remove(); @@ -246,7 +247,6 @@ public class BlocksFragment implements Fragment{ recipeTable.add(image).size(size + 8); image.update(() -> { - image.getImage().setColor(image.isDisabled() ? Color.GRAY : Color.WHITE); for(Player player : players){ if(control.input(player.playerIndex).recipe == r){ image.setChecked(true); @@ -325,7 +325,15 @@ public class BlocksFragment implements Fragment{ for(ItemStack stack : recipe.requirements){ requirements.addImage(stack.item.region).size(8*3); - Label reqlabel = new Label(() -> Mathf.clamp(stack.amount, 0, stack.amount) + "/" + stack.amount); + Label reqlabel = new Label(() ->{ + TileEntity core = players[0].getClosestCore(); + if(core == null) return "*/*"; + + int amount = core.items.getItem(stack.item); + String color = (amount < stack.amount/2f ? "[red]" : amount < stack.amount ? "[orange]" : "[white]"); + + return color + format(amount) + "[white]/" + stack.amount; + }); requirements.add(reqlabel).left(); requirements.row(); @@ -333,4 +341,16 @@ public class BlocksFragment implements Fragment{ descTable.row(); } + + String format(int number){ + if(number > 1000000) { + return Strings.toFixed(number/1000000f, 1) + "[gray]mil[]"; + }else if(number > 10000){ + return number/1000 + "[gray]k[]"; + }else if(number > 1000){ + return Strings.toFixed(number/1000f, 1) + "[gray]k[]"; + }else{ + return number + ""; + } + } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 8009e0b98a..ae8bcc6966 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -351,9 +351,9 @@ public class Tile implements PosTrait, TargetTrait { //010 //check for corner bitmasking: doesn't even get checked so it doesn't matter - if(te != null && tex != null && tey != null && te.elevation == -1 && elevation > 0){ + /*if(te != null && tex != null && tey != null && te.elevation == -1 && elevation > 0){ cliffs |= (1 << (((i+1)%4)*2)); - } + }*/ } if(occluded){ cost += 1; diff --git a/core/src/io/anuke/mindustry/world/blocks/BreakBlock.java b/core/src/io/anuke/mindustry/world/blocks/BreakBlock.java index 3f417e825a..4cf01fe6c8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BreakBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BreakBlock.java @@ -34,7 +34,7 @@ public class BreakBlock extends Block { public BreakBlock(String name) { super(name); - solid = true; + solidifes = true; update = true; size = Integer.parseInt(name.charAt(name.length()-1) + ""); health = 1; @@ -42,6 +42,12 @@ public class BreakBlock extends Block { consumesTap = true; } + @Override + public boolean isSolidFor(Tile tile) { + BreakEntity entity = tile.entity(); + return entity.previous.solid; + } + @Override public CursorType getCursor(Tile tile) { return CursorType.hand; diff --git a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index 7b08d3d48c..484fa347ee 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -37,12 +37,18 @@ public class BuildBlock extends Block { public BuildBlock(String name) { super(name); - solid = true; update = true; size = Integer.parseInt(name.charAt(name.length()-1) + ""); health = 1; layer = Layer.placement; consumesTap = true; + solidifes = true; + } + + @Override + public boolean isSolidFor(Tile tile) { + BuildEntity entity = tile.entity(); + return entity.recipe.result.solid || entity.previous.solid; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index 1e8c699ac7..65889a6199 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -61,6 +61,8 @@ public class Floor extends Block{ public boolean hasOres = false; /**whether this block can be drowned in*/ public boolean isLiquid; + /**if true, this block cannot be mined by players. useful for annoying things like stone.*/ + public boolean playerUnmineable = false; public Floor(String name) { super(name); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java index 5764f60641..46bf59f58c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java @@ -114,7 +114,7 @@ public class PowerSmelter extends PowerBlock { return; } - boolean consumeInputs = false; + boolean consumeInputs = true; if(useFlux){ //remove flux materials if present 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 dbc8f55b6c..1da2754a89 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -169,7 +169,7 @@ public class CoreBlock extends StorageBlock { }else{ entity.warmup += Timers.delta(); - if(entity.solid && entity.warmup > 10f && unitGroups[tile.getTeamID()].getByID(entity.droneID) == null && !Net.client()){ + if(entity.solid && entity.warmup > 60f && unitGroups[tile.getTeamID()].getByID(entity.droneID) == null && !Net.client()){ boolean found = false; for(BaseUnit unit : unitGroups[tile.getTeamID()].all()){ diff --git a/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java b/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java index 1b18345c4d..976bb426f6 100644 --- a/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java @@ -1,5 +1,6 @@ package io.anuke.mindustry.world.mapgen; +import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.IntArray; @@ -18,6 +19,7 @@ import io.anuke.mindustry.world.Tile; import io.anuke.ucore.noise.RidgedPerlin; import io.anuke.ucore.noise.Simplex; import io.anuke.ucore.util.Bits; +import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.SeedRandom; @@ -99,11 +101,13 @@ public class WorldGenerator { //update cliffs, occlusion data for(int x = 0; x < data.width(); x ++){ for(int y = 0; y < data.height(); y ++) { - tiles[x][y].updateOcclusion(); + Tile tile = tiles[x][y]; + + tile.updateOcclusion(); //fix things on cliffs that shouldn't be - if(tiles[x][y].block() != Blocks.air && tiles[x][y].cliffs != 0){ - tiles[x][y].setBlock(Blocks.air); + if(tile.block() != Blocks.air && tile.cliffs != 0){ + tile.setBlock(Blocks.air); } } } @@ -151,8 +155,6 @@ public class WorldGenerator { decoration.put(Blocks.snow, Blocks.icerock); decoration.put(Blocks.blackstone, Blocks.blackrock); - //TODO implement improved, more interesting generation - for (int x = 0; x < data.width(); x++) { for (int y = 0; y < data.height(); y++) { marker.floor = (byte)Blocks.stone.id; @@ -163,7 +165,7 @@ public class WorldGenerator { double r = sim2.octaveNoise2D(1, 0.6, 1f/70, x, y); double edgeDist = Math.max(data.width()/2, data.height()/2) - Math.max(Math.abs(x - data.width()/2), Math.abs(y - data.height()/2)); double dst = Vector2.dst(data.width()/2, data.height()/2, x, y); - double elevDip = 20; + double elevDip = 30; double border = 14; @@ -175,7 +177,7 @@ public class WorldGenerator { marker.floor = (byte)Blocks.snow.id; }else if(temp < 0.45){ marker.floor = (byte)Blocks.stone.id; - }else if(temp < 0.7){ + }else if(temp < 0.65){ marker.floor = (byte)Blocks.grass.id; }else if(temp < 0.8){ marker.floor = (byte)Blocks.sand.id; @@ -187,7 +189,7 @@ public class WorldGenerator { } if(dst < elevDip){ - elevation -= (elevDip - dst)/elevDip * 4.0; + elevation -= (elevDip - dst)/elevDip * 3.0; }else if(r > 0.9){ marker.floor = (byte)Blocks.water.id; elevation = 0; @@ -208,6 +210,24 @@ public class WorldGenerator { marker.wall = 0; } } + + for (int x = 0; x < data.width(); x++) { + for (int y = 0; y < data.height(); y++) { + byte elevation = data.read(x, y, DataPosition.elevation); + + for(GridPoint2 point : Geometry.d4){ + if(!Mathf.inBounds(x + point.x, y + point.y, data.width(), data.height())) continue; + if(data.read(x + point.x, y + point.y, DataPosition.elevation) < elevation){ + + if(Mathf.chance(0.05)){ + data.write(x, y, DataPosition.elevation, (byte)-1); + } + break; + } + } + } + } + data.write(data.width()/2, data.height()/2, DataPosition.wall, (byte)StorageBlocks.core.id); data.write(data.width()/2, data.height()/2, DataPosition.rotationTeam, Bits.packByte((byte)0, (byte)Team.blue.ordinal())); return data;