Generate tool bugfixes / Map edits / New blocks

This commit is contained in:
Anuken
2019-03-17 18:30:33 -04:00
parent 6dcf889ffe
commit 783f453da3
21 changed files with 1176 additions and 1056 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -250,6 +250,7 @@ filter.rivernoise = River Noise
filter.scatter = Scatter
filter.terrain = Terrain
filter.option.scale = Scale
filter.option.chance = Chance
filter.option.mag = Magnitude
filter.option.threshold = Threshold
filter.option.circle-scale = Circle Scale
@ -258,6 +259,8 @@ filter.option.falloff = Falloff
filter.option.floor = Floor
filter.option.wall = Wall
filter.option.ore = Ore
filter.option.floor2 = Secondary Floor
filter.option.threshold2 = Secondary Threshold
width = Width:
height = Height:
menu = Menu
@ -340,6 +343,7 @@ blocks.poweroutput = Power Output: {0}
blocks.powercapacity = Power Capacity
blocks.powershot = Power/Shot
blocks.targetsair = Targets Air
blocks.targetsground = Targets Ground
blocks.items = Items: {0}
blocks.itemsmoved = Move Speed
blocks.shootrange = Range
@ -563,6 +567,8 @@ block.grass.name = Grass
block.salt.name = Salt
block.sandrocks.name = Sand Rocks
block.spore-pine.name = Spore Pine
block.sporerocks.name = Spore Rocks
block.rock.name = Rock
block.shale.name = Shale
block.shale-boulder.name = Shale Boulder
block.moss.name = Moss

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 500 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 195 KiB

View File

@ -66,6 +66,8 @@ public class Vars{
public static final float finalWorldBounds = worldBounds + 500;
/**ticks spent out of bound until self destruct.*/
public static final float boundsCountdown = 60*7;
/**for map generator dialog*/
public static boolean updateEditorOnChange = false;
/**size of tiles in units*/
public static final int tilesize = 8;
/**all choosable player colors in join/host dialog*/

View File

@ -36,9 +36,9 @@ public class Blocks implements ContentList{
//environment
air, part, spawn, deepwater, water, tar, stone, craters, charr, sand, ice, snow,
holostone, rocks, icerocks, cliffs, sporePine, pine, whiteTree, whiteTreeDead, sporeCluster,
holostone, rocks, sporerocks, icerocks, cliffs, sporePine, pine, whiteTree, whiteTreeDead, sporeCluster,
iceSnow, sandWater, duneRocks, sandRocks, moss, sporeMoss, shale, shaleRocks, shaleBoulder, grass, salt,
metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, ignarock, magmarock, hotrock, snowrocks,
metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, ignarock, magmarock, hotrock, snowrocks, rock,
//ores
oreCopper, oreLead, oreScrap, oreCoal, oreTitanium, oreThorium,
@ -214,6 +214,14 @@ public class Blocks implements ContentList{
variants = 2;
}};
sporerocks = new StaticWall("sporerocks"){{
variants = 2;
}};
rock = new Rock("rock"){{
variants = 2;
}};
icerocks = new StaticWall("icerocks"){{
variants = 2;
}};
@ -694,7 +702,7 @@ public class Blocks implements ContentList{
}};
junction = new Junction("junction"){{
requirements(Category.distribution, ItemStack.with(Items.copper, 3));
requirements(Category.distribution, ItemStack.with(Items.copper, 3), true);
speed = 26;
capacity = 32;
health = 25;
@ -1067,20 +1075,21 @@ public class Blocks implements ContentList{
}};
scatter = new BurstTurret("scatter"){{
requirements(Category.turret, ItemStack.with(Items.copper, 170, Items.lead, 90), true);
requirements(Category.turret, ItemStack.with(Items.copper, 170, Items.lead, 90));
ammo(
Items.scrap, Bullets.flakScrap,
Items.lead, Bullets.flakLead
);
reload = 45f;
reload = 43f;
range = 160f;
size = 2;
burstSpacing = 5f;
shots = 2;
targetGround = false;
recoil = 2f;
rotatespeed = 10f;
inaccuracy = 18f;
inaccuracy = 17f;
shootCone = 35f;
health = 220*size*size;

View File

@ -6,10 +6,12 @@ import io.anuke.arc.function.Supplier;
import io.anuke.arc.graphics.Pixmap;
import io.anuke.arc.graphics.Pixmap.Format;
import io.anuke.arc.graphics.Texture;
import io.anuke.arc.scene.ui.Image;
import io.anuke.arc.scene.ui.layout.Stack;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Scaling;
import io.anuke.arc.util.async.AsyncExecutor;
import io.anuke.arc.util.async.AsyncResult;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.editor.generation.*;
import io.anuke.mindustry.editor.generation.GenerateFilter.GenerateInput;
import io.anuke.mindustry.game.Team;
@ -21,7 +23,7 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import static io.anuke.mindustry.Vars.mobile;
import static io.anuke.mindustry.Vars.*;
@SuppressWarnings("unchecked")
public class MapGenerateDialog extends FloatingDialog{
@ -48,8 +50,10 @@ public class MapGenerateDialog extends FloatingDialog{
shown(this::setup);
addCloseButton();
buttons.addButton("$editor.apply", () -> {
apply();
hide();
ui.loadAnd(() -> {
apply();
hide();
});
}).size(160f, 64f);
buttons.addButton("$editor.randomize", () -> {
for(GenerateFilter filter : filters){
@ -75,15 +79,20 @@ public class MapGenerateDialog extends FloatingDialog{
cont.clear();
cont.table("flat", t -> {
t.margin(8f);
t.add(new BorderImage(texture)).size(400f).padRight(6);
t.stack(new BorderImage(texture), new Stack(){{
add(new Image("loadDim"));
add(new Image("icon-refresh"){{
setScaling(Scaling.none);
}});
visible(() -> generating);
}}).size(mobile ? 300f : 400f).padRight(6);
t.pane(p -> filterTable = p).width(300f).get().setScrollingDisabled(true, false);
}).grow();
update();
buffer1 = create();
buffer2 = create();
update();
rebuildFilters();
}
@ -186,6 +195,16 @@ public class MapGenerateDialog extends FloatingDialog{
result.get();
}
buffer1 = null;
buffer2 = null;
generating = false;
if(pixmap != null){
pixmap.dispose();
texture.dispose();
pixmap = null;
texture = null;
}
//writeback buffer
DummyTile[][] writeTiles = new DummyTile[editor.width()][editor.height()];
@ -196,7 +215,7 @@ public class MapGenerateDialog extends FloatingDialog{
}
for(GenerateFilter filter : filters){
input.setFilter(filter, (x, y) -> dset(editor.tile(x, y)));
input.setFilter(filter, editor.width(), editor.height(), 1, (x, y) -> dset(editor.tile(x, y)));
//write to buffer
for(int x = 0; x < editor.width(); x++){
for(int y = 0; y < editor.height(); y++){
@ -215,10 +234,10 @@ public class MapGenerateDialog extends FloatingDialog{
DummyTile write = writeTiles[x][y];
tile.setRotation((byte)write.rotation);
tile.setFloor((Floor)write.floor);
tile.setBlock(write.block);
tile.setTeam(write.team);
tile.setOre(write.ore);
tile.setFloor((Floor)content.block(write.floor));
tile.setBlock(content.block(write.block));
tile.setTeam(Team.all[write.team]);
tile.setOre(content.block(write.ore));
}
}
});
@ -239,74 +258,81 @@ public class MapGenerateDialog extends FloatingDialog{
Array<GenerateFilter> copy = new Array<>(filters);
result = executor.submit(() -> {
generating = true;
try{
generating = true;
if(!filters.isEmpty()){
//write to buffer1 for reading
for(int px = 0; px < pixmap.getWidth(); px++){
for(int py = 0; py < pixmap.getHeight(); py++){
buffer1[px][py].set(editor.tile(px * scaling, py * scaling));
}
}
}
for(GenerateFilter filter : copy){
input.setFilter(filter, pixmap.getWidth(), pixmap.getHeight(), scaling, (x, y) -> buffer1[x][y]);
//read from buffer1 and write to buffer2
for(int px = 0; px < pixmap.getWidth(); px++){
for(int py = 0; py < pixmap.getHeight(); py++){
int x = px * scaling, y = py * scaling;
DummyTile tile = buffer1[px][py];
input.begin(editor, x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
filter.apply(input);
buffer2[px][py].set(input.floor, input.block, input.ore, Team.all[tile.team], tile.rotation);
}
}
for(int px = 0; px < pixmap.getWidth(); px++){
for(int py = 0; py < pixmap.getHeight(); py++){
buffer1[px][py].set(buffer2[px][py]);
}
}
}
if(!filters.isEmpty()){
//write to buffer1 for reading
for(int px = 0; px < pixmap.getWidth(); px++){
for(int py = 0; py < pixmap.getHeight(); py++){
buffer1[px][py].set(editor.tile(px * scaling, py * scaling));
int color;
//get result from buffer1 if there's filters left, otherwise get from editor directly
if(filters.isEmpty()){
Tile tile = editor.tile(px * scaling, py * scaling);
color = MapIO.colorFor(tile.floor(), tile.block(), tile.ore(), Team.none);
}else{
DummyTile tile = buffer1[px][py];
color = MapIO.colorFor(content.block(tile.floor), content.block(tile.block), content.block(tile.ore), Team.none);
}
pixmap.drawPixel(px, pixmap.getHeight() - 1 - py, color);
}
}
}
for(GenerateFilter filter : copy){
input.setFilter(filter, (x, y) -> buffer1[x][y]);
//read from buffer1 and write to buffer2
for(int px = 0; px < pixmap.getWidth(); px++){
for(int py = 0; py < pixmap.getHeight(); py++){
int x = px*scaling, y = py*scaling;
DummyTile tile = buffer1[px][py];
input.begin(editor, x, y, tile.floor, tile.block, tile.ore);
filter.apply(input);
buffer2[px][py].set(input.floor, input.block, input.ore, tile.team, tile.rotation);
}
}
for(int px = 0; px < pixmap.getWidth(); px++){
for(int py = 0; py < pixmap.getHeight(); py++){
buffer1[px][py].set(buffer2[px][py]);
}
}
}
for(int px = 0; px < pixmap.getWidth(); px++){
for(int py = 0; py < pixmap.getHeight(); py++){
int color;
//get result from buffer1 if there's filters left, otherwise get from editor directly
if(filters.isEmpty()){
Tile tile = editor.tile(px * scaling, py * scaling);
color = MapIO.colorFor(tile.floor(), tile.block(), tile.ore(), Team.none);
}else{
DummyTile tile = buffer1[px][py];
color = MapIO.colorFor(tile.floor, tile.block, tile.ore, Team.none);
}
pixmap.drawPixel(px, pixmap.getHeight() - 1 - py, color);
}
}
Core.app.post(() -> {
texture.draw(pixmap, 0, 0);
Core.app.post(() -> {
texture.draw(pixmap, 0, 0);
generating = false;
});
}catch(Exception e){
generating = false;
});
e.printStackTrace();
}
return null;
});
}
public static class DummyTile{
public Block block = Blocks.air, ore = Blocks.air, floor = Blocks.air;
public Team team = Team.none;
public int rotation;
public byte block, floor, ore, team, rotation;
void set(Block floor, Block wall, Block ore, Team team, int rotation){
this.floor = floor;
this.block = wall;
this.ore = ore;
this.team = team;
this.rotation = rotation;
this.floor = floor.id;
this.block = wall.id;
this.ore = ore.id;
this.team = (byte)team.ordinal();
this.rotation = (byte)rotation;
}
void set(DummyTile other){
set(other.floor, other.block, other.ore, other.team, other.rotation);
this.floor = other.floor;
this.block = other.block;
this.ore = other.ore;
this.team = other.team;
this.rotation = other.rotation;
}
void set(Tile other){

View File

@ -267,7 +267,9 @@ public class MapView extends Element implements GestureListener{
Draw.color(Pal.remove);
Lines.stroke(2f);
Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2);
editor.renderer().draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight);
if(Core.scene.getKeyboardFocus() != null && isDescendantOf(Core.scene.getKeyboardFocus())){
editor.renderer().draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight);
}
Draw.reset();
if(!ScissorStack.pushScissors(rect.set(x, y, width, height))){

View File

@ -4,6 +4,8 @@ import io.anuke.mindustry.editor.MapGenerateDialog.DummyTile;
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
import io.anuke.mindustry.world.blocks.Floor;
import static io.anuke.mindustry.Vars.content;
public class DistortFilter extends GenerateFilter{
float scl = 40, mag = 5;
@ -16,10 +18,10 @@ public class DistortFilter extends GenerateFilter{
@Override
public void apply(){
DummyTile tile = in.tile(in.x + noise(in.x, in.y, scl, mag)-mag/2f, in.y + noise(in.x, in.y+o, scl, mag)-mag/2f);
DummyTile tile = in.tile(in.x / (in.scaling) + (noise(in.x, in.y, scl, mag)-mag/2f)/in.scaling, in.y / (in.scaling) + (noise(in.x, in.y+o, scl, mag)-mag/2f)/in.scaling);
in.floor = tile.floor;
if(!tile.block.synthetic() && !in.block.synthetic()) in.block = tile.block;
if(!((Floor)in.floor).isLiquid) in.ore = tile.ore;
in.floor = content.block(tile.floor);
if(!content.block(tile.block).synthetic() && !in.block.synthetic()) in.block = content.block(tile.block);
if(!((Floor)in.floor).isLiquid) in.ore = content.block(tile.ore);
}
}

View File

@ -12,6 +12,8 @@ import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.OreBlock;
import static io.anuke.mindustry.Vars.updateEditorOnChange;
public abstract class FilterOption{
public static final Predicate<Block> floorsOnly = b -> (b instanceof Floor && !(b instanceof OreBlock)) && Core.atlas.isFound(b.icon(Icon.full));
public static final Predicate<Block> wallsOnly = b -> (!b.synthetic() && !(b instanceof Floor)) && Core.atlas.isFound(b.icon(Icon.full));
@ -40,7 +42,11 @@ public abstract class FilterOption{
table.row();
Slider slider = table.addSlider(min, max, (max-min)/200f, setter).growX().get();
slider.setValue(getter.get());
slider.changed(changed);
if(updateEditorOnChange){
slider.changed(changed);
}else{
slider.released(changed);
}
}
}

View File

@ -56,7 +56,7 @@ public abstract class GenerateFilter{
public Floor srcfloor;
public Block srcblock;
public Block srcore;
public int x, y;
public int x, y, width, height, scaling;
public MapEditor editor;
public Block floor, block, ore;
@ -74,14 +74,17 @@ public abstract class GenerateFilter{
this.y = y;
}
public void setFilter(GenerateFilter filter, TileProvider buffer){
public void setFilter(GenerateFilter filter, int width, int height, int scaling, TileProvider buffer){
this.buffer = buffer;
this.width = width;
this.height = height;
this.scaling = scaling;
noise.setSeed(filter.seed);
pnoise.setSeed((int)(filter.seed + 1));
}
DummyTile tile(float x, float y){
return buffer.get(Mathf.clamp((int)x, 0, editor.width() - 1), Mathf.clamp((int)y, 0, editor.height() - 1));
return buffer.get(Mathf.clamp((int)x, 0, width - 1), Mathf.clamp((int)y, 0, height - 1));
}
public interface TileProvider{

View File

@ -32,20 +32,18 @@ public abstract class FlyingUnit extends BaseUnit{
target = null;
}
if(target == null){
retarget(() -> {
targetClosest();
retarget(() -> {
targetClosest();
if(target == null) targetClosestEnemyFlag(BlockFlag.producer);
if(target == null) targetClosestEnemyFlag(BlockFlag.turret);
if(target == null) targetClosestEnemyFlag(BlockFlag.producer);
if(target == null) targetClosestEnemyFlag(BlockFlag.turret);
if(target == null){
setState(patrol);
}
});
if(target == null){
setState(patrol);
}
});
}else{
if(target != null){
attack(type.attackLength);
if((Angles.near(angleTo(target), rotation, type.shootCone) || getWeapon().ignoreRotation) //bombers and such don't care about rotation

View File

@ -58,6 +58,7 @@ public abstract class Turret extends Block{
protected float shootShake = 0f;
protected float xRand = 0f;
protected boolean targetAir = true;
protected boolean targetGround = true;
protected Vector2 tr = new Vector2();
protected Vector2 tr2 = new Vector2();
@ -108,6 +109,7 @@ public abstract class Turret extends Block{
stats.add(BlockStat.reload, 60f / reload, StatUnit.none);
stats.add(BlockStat.shots, shots, StatUnit.none);
stats.add(BlockStat.targetsAir, targetAir);
stats.add(BlockStat.targetsGround, targetGround);
}
@Override
@ -201,7 +203,7 @@ public abstract class Turret extends Block{
TurretEntity entity = tile.entity();
entity.target = Units.getClosestTarget(tile.getTeam(),
tile.drawx(), tile.drawy(), range, e -> !e.isDead() && (!e.isFlying() || targetAir));
tile.drawx(), tile.drawy(), range, e -> !e.isDead() && (!e.isFlying() || targetAir) && (e.isFlying() || targetGround));
}
protected void turnToTarget(Tile tile, float targetRot){

View File

@ -47,6 +47,7 @@ public enum BlockStat{
reload(StatCategory.shooting),
powerShot(StatCategory.shooting),
targetsAir(StatCategory.shooting),
targetsGround(StatCategory.shooting),
boostItem(StatCategory.optional),
boostLiquid(StatCategory.optional),;