Improved floodfill / Fixed resource use bug / Fixed editor turret draw

This commit is contained in:
Anuken
2018-07-17 23:20:05 -04:00
parent d4b2cad94e
commit be9ea33aa4
8 changed files with 105 additions and 22 deletions

View File

@ -53,10 +53,10 @@ public class Logic extends Module{
for(TeamData team : state.teams.getTeams()){ for(TeamData team : state.teams.getTeams()){
for(Tile tile : team.cores){ for(Tile tile : team.cores){
if(debug){ if(true){
for(Item item : Item.all()){ for(Item item : Item.all()){
if(item.type == ItemType.material){ if(item.type == ItemType.material){
tile.entity.items.add(item, 1000); tile.entity.items.set(item, 1000);
} }
} }
}else{ }else{

View File

@ -1,12 +1,13 @@
package io.anuke.mindustry.editor; package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.IntArray; import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.content.blocks.Blocks; 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.DataPosition;
import io.anuke.mindustry.maps.MapTileData.TileDataMarker; import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.ucore.function.IntPositionConsumer;
import io.anuke.ucore.util.Bits; import io.anuke.ucore.util.Bits;
import static io.anuke.mindustry.Vars.ui; import static io.anuke.mindustry.Vars.ui;
@ -73,6 +74,12 @@ public enum EditorTool{
edit = true; edit = true;
} }
IntArray stack = new IntArray();
int width;
byte be, dest;
boolean floor;
MapTileData data;
public void touched(MapEditor editor, int x, int y){ public void touched(MapEditor editor, int x, int y){
if(editor.getDrawBlock().isMultiblock()){ if(editor.getDrawBlock().isMultiblock()){
//don't fill multiblocks, thanks //don't fill multiblocks, thanks
@ -80,20 +87,75 @@ public enum EditorTool{
return; return;
} }
boolean floor = editor.getDrawBlock() instanceof Floor; data = editor.getMap();
byte bf = editor.getMap().read(x, y, DataPosition.floor); floor = editor.getDrawBlock() instanceof Floor;
byte bw = editor.getMap().read(x, y, DataPosition.wall);
byte be = editor.getMap().read(x, y, DataPosition.elevation); 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(); boolean synth = editor.getDrawBlock().synthetic();
byte brt = Bits.packByte((byte) editor.getDrawRotation(), (byte) editor.getDrawTeam().ordinal()); 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; byte draw = (byte) editor.getDrawBlock().id;
int width = editor.getMap().width(); width = editor.getMap().width();
int height = editor.getMap().height(); 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(); IntSet set = new IntSet();
IntArray points = new IntArray(); IntArray points = new IntArray();
points.add(asInt(x, y, editor.getMap().width())); points.add(asInt(x, y, editor.getMap().width()));
@ -129,9 +191,18 @@ public enum EditorTool{
editor.onWrite(px, py, prev); 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; return x + y * width;
} }
}, },

View File

@ -111,9 +111,6 @@ public class MapRenderer implements Disposable{
Block floor = Block.getByID(bf); Block floor = Block.getByID(bf);
Block wall = Block.getByID(bw); Block wall = Block.getByID(bw);
int offsetx = -(wall.size - 1) / 2;
int offsety = -(wall.size - 1) / 2;
TextureRegion region; TextureRegion region;
if(bw != 0){ if(bw != 0){
@ -121,11 +118,12 @@ public class MapRenderer implements Disposable{
if(wall.rotate){ if(wall.rotate){
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, 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); region.getRegionWidth(), region.getRegionHeight(), rotation * 90 - 90);
}else{ }else{
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, 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()); region.getRegionWidth(), region.getRegionHeight());
} }
}else{ }else{
@ -149,7 +147,7 @@ public class MapRenderer implements Disposable{
} }
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize, region, 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()); region.getRegionWidth(), region.getRegionHeight());
mesh.setColor(Color.WHITE); mesh.setColor(Color.WHITE);
} }

View File

@ -19,6 +19,8 @@ public class Sector{
public transient Texture texture; public transient Texture texture;
/**Goal of this sector-- what needs to be accomplished to unlock it.*/ /**Goal of this sector-- what needs to be accomplished to unlock it.*/
public transient Goal goal = new WaveGoal(30); 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(){ public SaveSlot getSave(){
return control.getSaves().getByID(saveID); return control.getSaves().getByID(saveID);

View File

@ -16,6 +16,7 @@ import static io.anuke.mindustry.Vars.*;
public class Sectors{ public class Sectors{
private static final int sectorImageSize = 16; private static final int sectorImageSize = 16;
private static final float sectorLargeChance = 0.1f;
private GridMap<Sector> grid = new GridMap<>(); private GridMap<Sector> grid = new GridMap<>();

View File

@ -3,6 +3,7 @@ package io.anuke.mindustry.ui.dialogs;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.maps.Sector; import io.anuke.mindustry.maps.Sector;
import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Graphics;
@ -54,7 +55,7 @@ public class SectorsDialog extends FloatingDialog{
world.sectors().save(); world.sectors().save();
}else{ }else{
control.getSaves().getByID(selected.saveID).load(); control.getSaves().getByID(selected.saveID).load();
logic.play(); state.set(State.playing);
} }
}); });
}).size(230f, 64f).name("deploy-button").disabled(b -> selected == null); }).size(230f, 64f).name("deploy-button").disabled(b -> selected == null);

View File

@ -191,12 +191,14 @@ public class BuildBlock extends Block{
public int builderID = -1; public int builderID = -1;
private float[] accumulator; private float[] accumulator;
private float[] totalAccumulator;
public void construct(Unit builder, TileEntity core, float amount){ public void construct(Unit builder, TileEntity core, float amount){
float maxProgress = checkRequired(core.items, amount, false); float maxProgress = checkRequired(core.items, amount, false);
for(int i = 0; i < recipe.requirements.length; i++){ 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); maxProgress = checkRequired(core.items, maxProgress, true);
@ -219,7 +221,9 @@ public class BuildBlock extends Block{
ItemStack[] requirements = recipe.requirements; ItemStack[] requirements = recipe.requirements;
for(int i = 0; i < requirements.length; i++){ 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 int accumulated = (int) (accumulator[i]); //get amount
if(amount > 0){ //if it's positive, add it to the core 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 //move max progress down if this fraction is less than 1
maxProgress = Math.min(maxProgress, maxProgress * fraction); maxProgress = Math.min(maxProgress, maxProgress * fraction);
//TODO uncomment?
accumulator[i] -= maxUse; accumulator[i] -= maxUse;
//remove stuff that is actually used //remove stuff that is actually used
@ -276,6 +281,7 @@ public class BuildBlock extends Block{
this.recipe = recipe; this.recipe = recipe;
this.previous = previous; this.previous = previous;
this.accumulator = new float[recipe.requirements.length]; this.accumulator = new float[recipe.requirements.length];
this.totalAccumulator = new float[recipe.requirements.length];
this.buildCost = recipe.cost; this.buildCost = recipe.cost;
} }
@ -285,6 +291,7 @@ public class BuildBlock extends Block{
if(Recipe.getByResult(previous) != null){ if(Recipe.getByResult(previous) != null){
this.recipe = Recipe.getByResult(previous); this.recipe = Recipe.getByResult(previous);
this.accumulator = new float[Recipe.getByResult(previous).requirements.length]; this.accumulator = new float[Recipe.getByResult(previous).requirements.length];
this.totalAccumulator = new float[Recipe.getByResult(previous).requirements.length];
this.buildCost = Recipe.getByResult(previous).cost; this.buildCost = Recipe.getByResult(previous).cost;
}else{ }else{
this.buildCost = 20f; //default no-recipe build cost is 20 this.buildCost = 20f; //default no-recipe build cost is 20
@ -301,8 +308,9 @@ public class BuildBlock extends Block{
stream.writeByte(-1); stream.writeByte(-1);
}else{ }else{
stream.writeByte(accumulator.length); stream.writeByte(accumulator.length);
for(float d : accumulator){ for(int i = 0; i < accumulator.length; i++){
stream.writeFloat(d); stream.writeFloat(accumulator[i]);
stream.writeFloat(totalAccumulator[i]);
} }
} }
} }
@ -316,8 +324,10 @@ public class BuildBlock extends Block{
if(acsize != -1){ if(acsize != -1){
accumulator = new float[acsize]; accumulator = new float[acsize];
totalAccumulator = new float[acsize];
for(int i = 0; i < acsize; i++){ for(int i = 0; i < acsize; i++){
accumulator[i] = stream.readFloat(); accumulator[i] = stream.readFloat();
totalAccumulator[i] = stream.readFloat();
} }
} }

View File

@ -199,7 +199,7 @@ public class CoreBlock extends StorageBlock{
if(entity.currentUnit != null){ if(entity.currentUnit != null){
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f); entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f);
entity.time += Timers.delta(); 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. //instant build for fast testing.
if(debug){ if(debug){