From be9ea33aa4177abc8b048e25df5ee847d096316a Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 17 Jul 2018 23:20:05 -0400 Subject: [PATCH] Improved floodfill / Fixed resource use bug / Fixed editor turret draw --- core/src/io/anuke/mindustry/core/Logic.java | 4 +- .../io/anuke/mindustry/editor/EditorTool.java | 87 +++++++++++++++++-- .../anuke/mindustry/editor/MapRenderer.java | 10 +-- core/src/io/anuke/mindustry/maps/Sector.java | 2 + core/src/io/anuke/mindustry/maps/Sectors.java | 1 + .../mindustry/ui/dialogs/SectorsDialog.java | 3 +- .../mindustry/world/blocks/BuildBlock.java | 18 +++- .../world/blocks/storage/CoreBlock.java | 2 +- 8 files changed, 105 insertions(+), 22 deletions(-) diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 2e07b0a2e6..1cf980dbe9 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -53,10 +53,10 @@ public class Logic extends Module{ for(TeamData team : state.teams.getTeams()){ for(Tile tile : team.cores){ - if(debug){ + if(true){ for(Item item : Item.all()){ if(item.type == ItemType.material){ - tile.entity.items.add(item, 1000); + tile.entity.items.set(item, 1000); } } }else{ diff --git a/core/src/io/anuke/mindustry/editor/EditorTool.java b/core/src/io/anuke/mindustry/editor/EditorTool.java index d2ced70c5e..6e98c481ca 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTool.java +++ b/core/src/io/anuke/mindustry/editor/EditorTool.java @@ -1,12 +1,13 @@ package io.anuke.mindustry.editor; import com.badlogic.gdx.utils.IntArray; -import com.badlogic.gdx.utils.IntSet; import io.anuke.mindustry.content.blocks.Blocks; +import io.anuke.mindustry.maps.MapTileData; import io.anuke.mindustry.maps.MapTileData.DataPosition; import io.anuke.mindustry.maps.MapTileData.TileDataMarker; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.Floor; +import io.anuke.ucore.function.IntPositionConsumer; import io.anuke.ucore.util.Bits; import static io.anuke.mindustry.Vars.ui; @@ -73,6 +74,12 @@ public enum EditorTool{ edit = true; } + IntArray stack = new IntArray(); + int width; + byte be, dest; + boolean floor; + MapTileData data; + public void touched(MapEditor editor, int x, int y){ if(editor.getDrawBlock().isMultiblock()){ //don't fill multiblocks, thanks @@ -80,20 +87,75 @@ public enum EditorTool{ return; } - boolean floor = editor.getDrawBlock() instanceof Floor; + data = editor.getMap(); - byte bf = editor.getMap().read(x, y, DataPosition.floor); - byte bw = editor.getMap().read(x, y, DataPosition.wall); - byte be = editor.getMap().read(x, y, DataPosition.elevation); + floor = editor.getDrawBlock() instanceof Floor; + + byte bf = data.read(x, y, DataPosition.floor); + byte bw = data.read(x, y, DataPosition.wall); + be = data.read(x, y, DataPosition.elevation); boolean synth = editor.getDrawBlock().synthetic(); byte brt = Bits.packByte((byte) editor.getDrawRotation(), (byte) editor.getDrawTeam().ordinal()); - byte dest = floor ? bf : bw; + dest = floor ? bf : bw; byte draw = (byte) editor.getDrawBlock().id; - int width = editor.getMap().width(); + width = editor.getMap().width(); int height = editor.getMap().height(); + int x1; + boolean spanAbove, spanBelow; + + stack.clear(); + + stack.add(asi(x, y)); + + IntPositionConsumer writer = (px, py) -> { + TileDataMarker prev = editor.getPrev(px, py, false); + + if(floor){ + data.write(px, py, DataPosition.floor, draw); + }else{ + data.write(px, py, DataPosition.wall, draw); + } + + if(synth){ + data.write(px, py, DataPosition.rotationTeam, brt); + } + + editor.onWrite(px, py, prev); + }; + + while(stack.size > 0){ + int popped = stack.pop(); + x = popped % width; + y = popped / width; + + x1 = x; + while(x1 >= 0 && eq(x1, y)) x1--; + x1++; + spanAbove = spanBelow = false; + while(x1 < width && eq(x1, y)){ + writer.accept(x1, y); + + if(!spanAbove && y > 0 && eq(x1, y - 1)){ + stack.add(asi(x1, y - 1)); + spanAbove = true; + }else if(spanAbove && y > 0 && eq(x1, y - 1)){ + spanAbove = false; + } + + if(!spanBelow && y < height - 1 && eq(x1, y + 1)){ + stack.add(asi(x1, y + 1)); + spanBelow = true; + }else if(spanBelow && y < height - 1 && eq(x1, y + 1)){ + spanBelow = false; + } + x1++; + } + } + + /* IntSet set = new IntSet(); IntArray points = new IntArray(); points.add(asInt(x, y, editor.getMap().width())); @@ -129,9 +191,18 @@ public enum EditorTool{ editor.onWrite(px, py, prev); } } + */ } - int asInt(int x, int y, int width){ + boolean eq(int px, int py){ + byte nbf = data.read(px, py, DataPosition.floor); + byte nbw = data.read(px, py, DataPosition.wall); + byte nbe = data.read(px, py, DataPosition.elevation); + + return (floor ? nbf : nbw) == dest && nbe == be; + } + + int asi(int x, int y){ return x + y * width; } }, diff --git a/core/src/io/anuke/mindustry/editor/MapRenderer.java b/core/src/io/anuke/mindustry/editor/MapRenderer.java index 48ad02cf68..7b61726c90 100644 --- a/core/src/io/anuke/mindustry/editor/MapRenderer.java +++ b/core/src/io/anuke/mindustry/editor/MapRenderer.java @@ -111,9 +111,6 @@ public class MapRenderer implements Disposable{ Block floor = Block.getByID(bf); Block wall = Block.getByID(bw); - int offsetx = -(wall.size - 1) / 2; - int offsety = -(wall.size - 1) / 2; - TextureRegion region; if(bw != 0){ @@ -121,11 +118,12 @@ public class MapRenderer implements Disposable{ if(wall.rotate){ mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, - wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize, + wx * tilesize + wall.offset(), wy * tilesize + wall.offset(), region.getRegionWidth(), region.getRegionHeight(), rotation * 90 - 90); }else{ mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, - wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize, + wx * tilesize + wall.offset() + (tilesize - region.getRegionWidth())/2f, + wy * tilesize + wall.offset() + (tilesize - region.getRegionHeight())/2f, region.getRegionWidth(), region.getRegionHeight()); } }else{ @@ -149,7 +147,7 @@ public class MapRenderer implements Disposable{ } mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize, region, - wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize, + wx * tilesize - (wall.size/3) * tilesize, wy * tilesize - (wall.size/3) * tilesize, region.getRegionWidth(), region.getRegionHeight()); mesh.setColor(Color.WHITE); } diff --git a/core/src/io/anuke/mindustry/maps/Sector.java b/core/src/io/anuke/mindustry/maps/Sector.java index 4fda353884..3eb20a7285 100644 --- a/core/src/io/anuke/mindustry/maps/Sector.java +++ b/core/src/io/anuke/mindustry/maps/Sector.java @@ -19,6 +19,8 @@ public class Sector{ public transient Texture texture; /**Goal of this sector-- what needs to be accomplished to unlock it.*/ public transient Goal goal = new WaveGoal(30); + /**Sector size; if more than 1, the coordinates are the bottom left corner.*/ + public int size = 1; public SaveSlot getSave(){ return control.getSaves().getByID(saveID); diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index 39bf308e07..a6cb3ed5a5 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -16,6 +16,7 @@ import static io.anuke.mindustry.Vars.*; public class Sectors{ private static final int sectorImageSize = 16; + private static final float sectorLargeChance = 0.1f; private GridMap grid = new GridMap<>(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index 14126249f4..ea72f70cac 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.ui.dialogs; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; +import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.maps.Sector; import io.anuke.ucore.core.Graphics; @@ -54,7 +55,7 @@ public class SectorsDialog extends FloatingDialog{ world.sectors().save(); }else{ control.getSaves().getByID(selected.saveID).load(); - logic.play(); + state.set(State.playing); } }); }).size(230f, 64f).name("deploy-button").disabled(b -> selected == null); diff --git a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index 9c085a3c06..ce90c42233 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -191,12 +191,14 @@ public class BuildBlock extends Block{ public int builderID = -1; private float[] accumulator; + private float[] totalAccumulator; public void construct(Unit builder, TileEntity core, float amount){ float maxProgress = checkRequired(core.items, amount, false); for(int i = 0; i < recipe.requirements.length; i++){ - accumulator[i] += recipe.requirements[i].amount * maxProgress; //add min amount progressed to the accumulator + accumulator[i] += Math.min(recipe.requirements[i].amount * maxProgress, recipe.requirements[i].amount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator + totalAccumulator[i] = Math.min(totalAccumulator[i] + recipe.requirements[i].amount * maxProgress, recipe.requirements[i].amount); } maxProgress = checkRequired(core.items, maxProgress, true); @@ -219,7 +221,9 @@ public class BuildBlock extends Block{ ItemStack[] requirements = recipe.requirements; for(int i = 0; i < requirements.length; i++){ - accumulator[i] += requirements[i].amount * amount / 2f; //add scaled amount progressed to the accumulator + accumulator[i] += Math.min(requirements[i].amount * amount / 2f, requirements[i].amount/2f - totalAccumulator[i]); //add scaled amount progressed to the accumulator + totalAccumulator[i] = Math.min(totalAccumulator[i] + requirements[i].amount * amount / 2f, requirements[i].amount); + int accumulated = (int) (accumulator[i]); //get amount if(amount > 0){ //if it's positive, add it to the core @@ -255,6 +259,7 @@ public class BuildBlock extends Block{ //move max progress down if this fraction is less than 1 maxProgress = Math.min(maxProgress, maxProgress * fraction); + //TODO uncomment? accumulator[i] -= maxUse; //remove stuff that is actually used @@ -276,6 +281,7 @@ public class BuildBlock extends Block{ this.recipe = recipe; this.previous = previous; this.accumulator = new float[recipe.requirements.length]; + this.totalAccumulator = new float[recipe.requirements.length]; this.buildCost = recipe.cost; } @@ -285,6 +291,7 @@ public class BuildBlock extends Block{ if(Recipe.getByResult(previous) != null){ this.recipe = Recipe.getByResult(previous); this.accumulator = new float[Recipe.getByResult(previous).requirements.length]; + this.totalAccumulator = new float[Recipe.getByResult(previous).requirements.length]; this.buildCost = Recipe.getByResult(previous).cost; }else{ this.buildCost = 20f; //default no-recipe build cost is 20 @@ -301,8 +308,9 @@ public class BuildBlock extends Block{ stream.writeByte(-1); }else{ stream.writeByte(accumulator.length); - for(float d : accumulator){ - stream.writeFloat(d); + for(int i = 0; i < accumulator.length; i++){ + stream.writeFloat(accumulator[i]); + stream.writeFloat(totalAccumulator[i]); } } } @@ -316,8 +324,10 @@ public class BuildBlock extends Block{ if(acsize != -1){ accumulator = new float[acsize]; + totalAccumulator = new float[acsize]; for(int i = 0; i < acsize; i++){ accumulator[i] = stream.readFloat(); + totalAccumulator[i] = stream.readFloat(); } } 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 9d921ccc5a..028d0651ce 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -199,7 +199,7 @@ public class CoreBlock extends StorageBlock{ if(entity.currentUnit != null){ entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f); entity.time += Timers.delta(); - entity.progress += 1f / (entity.currentUnit instanceof Player ? respawnduration : droneRespawnDuration); + entity.progress += 1f / (entity.currentUnit instanceof Player ? respawnduration : droneRespawnDuration) * Timers.delta(); //instant build for fast testing. if(debug){