Scale waves based on difficulty; improve map editor

This commit is contained in:
Anuken
2017-12-18 17:37:14 -05:00
parent 1ae875ebf4
commit 7953a21073
34 changed files with 857 additions and 714 deletions

View File

@@ -79,7 +79,7 @@ project(":core") {
apply plugin: "java" apply plugin: "java"
dependencies { dependencies {
compile 'com.github.anuken:ucore:283ecacfef' compile 'com.github.anuken:ucore:9c523c4'
compile "com.badlogicgames.gdx:gdx:$gdxVersion" compile "com.badlogicgames.gdx:gdx:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-ai:1.8.1" compile "com.badlogicgames.gdx:gdx-ai:1.8.1"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -16,8 +16,8 @@ import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.effect.Fx; import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.mindustry.entities.effect.Shield; import io.anuke.mindustry.entities.effect.Shield;
import io.anuke.mindustry.entities.enemies.BlastEnemy;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.entities.enemies.FortressEnemy;
import io.anuke.mindustry.entities.enemies.HealerEnemy; import io.anuke.mindustry.entities.enemies.HealerEnemy;
import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.DesktopInput; import io.anuke.mindustry.input.DesktopInput;
@@ -471,7 +471,7 @@ public class Control extends Module{
new HealerEnemy().set(player.x, player.y).add(); new HealerEnemy().set(player.x, player.y).add();
}else{ }else{
float px = player.x, py = player.y; float px = player.x, py = player.y;
Timers.run(30f, ()-> new BlastEnemy().set(px, py).add()); Timers.run(30f, ()-> new FortressEnemy().set(px, py).add());
} }
} }
} }

View File

@@ -546,7 +546,7 @@ public class Renderer extends RendererModule{
Draw.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace); Draw.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
} }
}else if(player.breakMode.delete && control.input.drawPlace()){ }else if(player.breakMode.delete && control.input.drawPlace() && player.recipe == null){ //TODO test!
player.breakMode.draw(control.input.getBlockX(), control.input.getBlockY(), player.breakMode.draw(control.input.getBlockX(), control.input.getBlockY(),
control.input.getBlockEndX(), control.input.getBlockEndY()); control.input.getBlockEndX(), control.input.getBlockEndY());
} }

View File

@@ -449,6 +449,14 @@ public class UI extends SceneModule{
editorDialog.show(); editorDialog.show();
} }
public MapEditorDialog getEditor(){
return editorDialog;
}
public boolean isEditing(){
return editorDialog.getScene() != null;
}
public void updateItems(){ public void updateItems(){
((HudFragment)hudfrag).updateItems(); ((HudFragment)hudfrag).updateItems();
} }

View File

@@ -1,15 +0,0 @@
package io.anuke.mindustry.editor;
import io.anuke.ucore.modules.ModuleCore;
public class Editor extends ModuleCore{
public static EditorControl control;
public static EditorUI ui;
@Override
public void init(){
module(control = new EditorControl());
module(ui = new EditorUI());
}
}

View File

@@ -1,267 +0,0 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.*;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Generator;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.graphics.Pixmaps;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.noise.RidgedPerlin;
import io.anuke.ucore.noise.Simplex;
import io.anuke.ucore.util.Mathf;
public class EditorControl extends Module{
private ObjectIntMap<Block> colors = new ObjectIntMap<>();
Pixmap pixmap;
Texture texture;
Simplex sim = new Simplex();
RidgedPerlin rid = new RidgedPerlin(1, 10, 20f);
RidgedPerlin rid2 = new RidgedPerlin(1, 6, 1f);
RidgedPerlin rid3 = new RidgedPerlin(1, 6, 1f);
String map = "fortress";
ObjectMap<String, Boolean> prefs = new OrderedMap<String, Boolean>(){
{
put("replace", true);
put("terrain", false);
put("circle", false);
put("distort", false);
put("sand", false);
put("grass", false);
put("stone", false);
put("allgrass", false);
put("allsnow", false);
put("allsand", false);
put("lavarock", false);
put("water", false);
put("oil", false);
put("lavariver", false);
put("slavariver", false);
put("river", false);
put("iceriver", false);
put("oilriver", false);
}
};
public EditorControl() {
IntMap.Keys keys = Generator.colors.keys();
for(int key = keys.next(); keys.hasNext; key = keys.next()){
colors.put(Generator.colors.get(key), key);
}
loadMap(map);
}
@Override
public void update(){
clearScreen();
if(Inputs.keyUp(Keys.ESCAPE)){
Gdx.app.exit();
}
if(Core.scene.getKeyboardFocus() == null){
if(Inputs.keyUp(Keys.R)){
randomize();
loadMap(map);
}
if(Inputs.keyUp(Keys.E)){
try{
ClassReflection.getMethod(ClassReflection.forName("com.badlogic.gdx.graphics.PixmapIO"), "writePNG", FileHandle.class, Pixmap.class)
.invoke(Gdx.files.absolute("/home/anuke/Pictures/maps/out-" + TimeUtils.millis() + ".png"), pixmap);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
}
public void randomize(){
sim.setSeed(Mathf.random(999999));
rid.setSeed(Mathf.random(999999));
rid2.setSeed(Mathf.random(999999));
rid3.setSeed(Mathf.random(999999));
}
public void reload(){
loadMap(map);
}
public void loadMap(String name){
if(pixmap != null)
pixmap.dispose();
pixmap = new Pixmap(Gdx.files.internal("maps/" + name + ".png"));
process();
}
public void process(){
if(prefs.get("terrain")){
for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){
float dist = Vector2.dst((float) x / pixmap.getWidth(), (float) y / pixmap.getHeight(), 0.5f, 0.5f) * 2f;
double noise = sim.octaveNoise2D(6, 0.6, 1 / 180.0, x, y + 9999) / (prefs.get("circle") ? 1.7 : 1f) + dist / 10f;
if(dist > 0.8){
noise += 2 * (dist - 0.8);
}
Block block = noise > 0.6 ? Blocks.stoneblock : Blocks.stone;
pixmap.drawPixel(x, y, colors.get(block, 0));
}
}
}
Pixmap src = Pixmaps.copy(pixmap);
for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){
int dx = 0, dy = 0;
if(prefs.get("distort")){
double intensity = 12;
double scale = 80;
double octaves = 4;
double falloff = 0.6;
double nx = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y) - 0.5f) * intensity;
double ny = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y + 99999) - 0.5f) * intensity;
dx = (int) nx;
dy = (int) ny;
}
int pix = src.getPixel(x + dx, y + dy);
Block block = Generator.colors.get(pix);
if(block == null)
continue;
boolean floor = block instanceof Floor;
double noise = sim.octaveNoise2D(4, 0.6, 1 / 170.0, x, y) + sim.octaveNoise2D(1, 1.0, 1 / 5.0, x, y) / 18.0;
double nwater = sim.octaveNoise2D(1, 1.0, 1 / 130.0, x, y);
noise += nwater / 5.0;
double noil = sim.octaveNoise2D(1, 1.0, 1 / 150.0, x + 9999, y) + sim.octaveNoise2D(1, 1.0, 1 / 2.0, x, y) / 290.0;
if(!floor || prefs.get("replace")){
if(prefs.get("allgrass")){
block = floor ? Blocks.grass : Blocks.grassblock;
}else if(prefs.get("allsnow")){
block = floor ? Blocks.snow : Blocks.snowblock;
}else if(prefs.get("allsand")){
block = floor ? Blocks.sand : Blocks.sandblock;
}else if(prefs.get("replace")){
block = floor ? Blocks.stone : Blocks.stoneblock;
}
if(noise > 0.7 && prefs.get("grass")){
block = floor ? Blocks.grass : Blocks.grassblock;
}
if(noise > 0.7 && prefs.get("lavarock")){
block = floor ? Blocks.blackstone : Blocks.blackstoneblock;
}
if(noise > 0.7 && prefs.get("sand")){
block = floor ? Blocks.sand : Blocks.sandblock;
}
if(noise > 0.8 && prefs.get("stone")){
block = floor ? Blocks.stone : Blocks.stoneblock;
}
}
if(floor){
if(nwater > 0.93 && prefs.get("water")){
block = Blocks.water;
if(nwater > 0.943){
block = Blocks.deepwater;
}
}
if(noil > 0.95 && prefs.get("oil")){
block = Blocks.dirt;
if(noil > 0.955){
block = Blocks.oil;
}
}
}
if(floor && prefs.get("lavariver")){
double lava = rid.getValue(x, y, 1 / 100f);
double t = 0.6;
if(lava > t){
block = Blocks.lava;
}else if(lava > t - 0.2){
block = Blocks.blackstone;
}
}
if(floor && prefs.get("slavariver")){
double lava = rid.getValue(x, y, 1 / 40f);
double t = 0.7;
if(lava > t){
block = Blocks.lava;
}else if(lava > t - 0.3){
block = Blocks.blackstone;
}
}
if(floor && prefs.get("oilriver")){
double lava = rid3.getValue(x, y, 1 / 100f);
double t = 0.9;
if(lava > t){
block = Blocks.oil;
}else if(lava > t - 0.2){
block = Blocks.dirt;
}
}
if(floor && prefs.get("river")){
double riv = rid2.getValue(x, y, 1 / 140f);
double t = 0.4;
if(riv > t + 0.1){
block = Blocks.deepwater;
}else if(riv > t){
block = Blocks.water;
}else if(riv > t - 0.2){
block = Blocks.grass;
}
}
if(floor && prefs.get("iceriver")){
double riv = rid2.getValue(x, y, 1 / 140f);
double t = 0.4;
if(riv > t + 0.1){
block = Blocks.ice;
}else if(riv > t){
block = Blocks.ice;
}else if(riv > t - 0.2){
block = Blocks.snow;
}
}
pixmap.drawPixel(x, y, colors.get(block, 0));
}
}
src.dispose();
if(texture != null){
texture.dispose();
}
texture = new Texture(pixmap);
}
}

View File

@@ -1,65 +0,0 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Scaling;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.graphics.Atlas;
import io.anuke.ucore.modules.SceneModule;
import io.anuke.ucore.scene.Skin;
import io.anuke.ucore.scene.builders.*;
import io.anuke.ucore.scene.style.TextureRegionDrawable;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.TextField;
public class EditorUI extends SceneModule{
@Override
public void init(){
build.begin();
new table(){{
Image image = new Image();
image.update(()-> image.setDrawable(new TextureRegionDrawable(new TextureRegion(Editor.control.texture))));
image.setScaling(Scaling.fit);
add(image).size(256 * 3);
new table("button"){{
new field(Editor.control.map, text->{
if(Gdx.files.internal("maps/" + text + ".png").exists()){
Editor.control.map = text;
Editor.control.reload();
}
});
row();
for(String key : Editor.control.prefs.keys()){
new checkbox(key, Editor.control.prefs.get(key), b->{
Editor.control.prefs.put(key, b);
Editor.control.reload();
}).left();
row();
}
margin(16);
}}.end();
}}.end();
build.end();
}
@Override
public void update(){
super.update();
if(Inputs.buttonUp(Buttons.LEFT)){
if(!hasMouse() || !(scene.hit(Graphics.mouse().x, Graphics.mouse().y, true) instanceof TextField)){
scene.setKeyboardFocus(null);
}
}
}
@Override
protected void loadSkin(){
skin = new Skin(Gdx.files.internal("ui/uiskin.json"), new Atlas(Gdx.files.internal("sprites/sprites.atlas")));
}
}

View File

@@ -1,9 +1,12 @@
package io.anuke.mindustry.entities; package io.anuke.mindustry.entities;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class EnemySpawn{ public class EnemySpawn{
private static float[] scalings = {2f, 1.5f, 1f};
/**The enemy type spawned*/ /**The enemy type spawned*/
public final Class<? extends Enemy> type; public final Class<? extends Enemy> type;
/**When this spawns should end*/ /**When this spawns should end*/
@@ -33,6 +36,8 @@ public class EnemySpawn{
if(wave < after || wave > before || (wave - after) % spacing != 0){ if(wave < after || wave > before || (wave - after) % spacing != 0){
return 0; return 0;
} }
float scaling = this.scaling * scalings[(Settings.getInt("difficulty"))];
return Math.min(amount-1 + 1 * Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max); return Math.min(amount-1 + 1 * Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max);
} }

View File

@@ -331,6 +331,15 @@ public class Fx{
Draw.reset(); Draw.reset();
}), }),
shieldhit = new Effect(9, e -> {
Draw.thickness(1f);
Draw.color(Color.WHITE, Color.SKY, e.ifract());
Draw.spikes(e.x, e.y, e.ifract() * 5f, 2, 6);
Draw.thickness(4f*e.fract());
Draw.circle(e.x, e.y, e.ifract()*14f);
Draw.reset();
}),
shoot = new Effect(8, e -> { shoot = new Effect(8, e -> {
Draw.thickness(1f); Draw.thickness(1f);
Draw.color(Color.WHITE, Color.GOLD, e.ifract()); Draw.color(Color.WHITE, Color.GOLD, e.ifract());

View File

@@ -78,7 +78,7 @@ public class AndroidInput extends InputHandler{
if(!GameState.is(State.menu)){ if(!GameState.is(State.menu)){
Tile cursor = world.tile(Mathf.scl2(Graphics.mouseWorld().x, tilesize), Mathf.scl2(Graphics.mouseWorld().y, tilesize)); Tile cursor = world.tile(Mathf.scl2(Graphics.mouseWorld().x, tilesize), Mathf.scl2(Graphics.mouseWorld().y, tilesize));
if(cursor != null && !ui.hasMouse()){ if(cursor != null && !ui.hasMouse(screenX, screenY)){
Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor; Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor;
if(linked != null && linked.block() instanceof Configurable){ if(linked != null && linked.block() instanceof Configurable){
ui.showConfig(linked); ui.showConfig(linked);
@@ -155,7 +155,7 @@ public class AndroidInput extends InputHandler{
} }
@Override @Override
public void tryPlaceBlock(int x, int y, boolean sound){ public boolean tryPlaceBlock(int x, int y, boolean sound){
if(player.recipe != null && if(player.recipe != null &&
validPlace(x, y, player.recipe.result) && cursorNear() && validPlace(x, y, player.recipe.result) && cursorNear() &&
Vars.control.hasItems(player.recipe.requirements)){ Vars.control.hasItems(player.recipe.requirements)){
@@ -169,6 +169,8 @@ public class AndroidInput extends InputHandler{
if(!Vars.control.hasItems(player.recipe.requirements)){ if(!Vars.control.hasItems(player.recipe.requirements)){
Cursors.restoreCursor(); Cursors.restoreCursor();
} }
return true;
} }
return false;
} }
} }

View File

@@ -94,7 +94,7 @@ public class DesktopInput extends InputHandler{
Tile cursor = world.tile(tilex(), tiley()); Tile cursor = world.tile(tilex(), tiley());
if(Inputs.buttonUp(Buttons.LEFT) && cursor != null){ if(Inputs.buttonUp(Buttons.LEFT) && cursor != null && !ui.hasMouse()){
Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor; Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor;
if(linked != null && linked.block() instanceof Configurable){ if(linked != null && linked.block() instanceof Configurable){
ui.showConfig(linked); ui.showConfig(linked);

View File

@@ -49,7 +49,7 @@ public abstract class InputHandler extends InputAdapter{
return Vector2.dst(player.x, player.y, getBlockX() * tilesize, getBlockY() * tilesize) <= placerange; return Vector2.dst(player.x, player.y, getBlockX() * tilesize, getBlockY() * tilesize) <= placerange;
} }
public void tryPlaceBlock(int x, int y, boolean sound){ public boolean tryPlaceBlock(int x, int y, boolean sound){
if(player.recipe != null && if(player.recipe != null &&
validPlace(x, y, player.recipe.result) && !ui.hasMouse() && cursorNear() && validPlace(x, y, player.recipe.result) && !ui.hasMouse() && cursorNear() &&
Vars.control.hasItems(player.recipe.requirements)){ Vars.control.hasItems(player.recipe.requirements)){
@@ -63,7 +63,9 @@ public abstract class InputHandler extends InputAdapter{
if(!Vars.control.hasItems(player.recipe.requirements)){ if(!Vars.control.hasItems(player.recipe.requirements)){
Cursors.restoreCursor(); Cursors.restoreCursor();
} }
return true;
} }
return false;
} }
public boolean tryDeleteBlock(int x, int y, boolean sound){ public boolean tryDeleteBlock(int x, int y, boolean sound){

View File

@@ -306,10 +306,12 @@ public enum PlaceMode{
boolean first = true; boolean first = true;
for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){ for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){
for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){ for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){
control.getInput().tryPlaceBlock( if(control.getInput().tryPlaceBlock(
tilex + x * Mathf.sign(endx - tilex), tilex + x * Mathf.sign(endx - tilex),
tiley + y * Mathf.sign(endy - tiley), first); tiley + y * Mathf.sign(endy - tiley), first)){
first = false; first = false;
}
} }
} }
} }

View File

@@ -0,0 +1,70 @@
package io.anuke.mindustry.mapeditor;
import java.util.Stack;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.ColorMapper;
public enum EditorTool{
pencil{
public void touched(MapEditor editor, int x, int y){
editor.draw(x, y);
}
},
fill{
public void touched(MapEditor editor, int x, int y){
Pixmap pix = editor.pixmap();
int dest = pix.getPixel(x, y);
int width = pix.getWidth();
IntSet set = new IntSet();
Stack<GridPoint2> points = new Stack<GridPoint2>();
points.add(new GridPoint2(x, y));
while( !points.isEmpty()){
GridPoint2 pos = points.pop();
set.add(asInt(pos.x, pos.y, width));
int pcolor = pix.getPixel(pos.x, pos.y);
if(colorEquals(pcolor, dest)){
pix.drawPixel(pos.x, pos.y);
if(pos.x > 0 && !set.contains(asInt(pos.x - 1, pos.y, width))) points.add(new GridPoint2(pos).cpy().add( -1, 0));
if(pos.y > 0 && !set.contains(asInt(pos.x, pos.y - 1, width))) points.add(new GridPoint2(pos).cpy().add(0, -1));
if(pos.x < pix.getWidth() - 1 && !set.contains(asInt(pos.x + 1, pos.y, width))) points.add(new GridPoint2(pos).cpy().add(1, 0));
if(pos.y < pix.getHeight() - 1 && !set.contains(asInt(pos.x, pos.y + 1, width))) points.add(new GridPoint2(pos).cpy().add(0, 1));
}
}
editor.updateTexture();
}
int asInt(int x, int y, int width){
return x+y*width;
}
boolean colorEquals(int a, int b){
return a == b;
}
},
pick{
public void touched(MapEditor editor, int x, int y){
Block block = ColorMapper.get(editor.pixmap().getPixel(x, y)).dominant();
editor.setDrawBlock(block);
Vars.ui.getEditor().updateSelectedBlock();
}
},
zoom;
public void touched(MapEditor editor, int x, int y){
}
}

View File

@@ -19,6 +19,11 @@ public class MapEditor{
private Pixmap[] brushPixmaps = new Pixmap[brushSizes.length]; private Pixmap[] brushPixmaps = new Pixmap[brushSizes.length];
private Map map; private Map map;
private MapFilter filter = new MapFilter();
private Pixmap filterPixmap;
private Texture filterTexture;
private Pixmap pixmap; private Pixmap pixmap;
private Texture texture; private Texture texture;
private int brushSize = 1; private int brushSize = 1;
@@ -31,6 +36,44 @@ public class MapEditor{
} }
} }
public void updateTexture(){
texture.draw(pixmap, 0, 0);
}
public MapFilter getFilter(){
return filter;
}
public void applyFilterPreview(){
if(filterPixmap != null && (filterPixmap.getWidth() != pixmap.getWidth()
|| filterPixmap.getHeight() != pixmap.getHeight())){
filterPixmap.dispose();
filterTexture.dispose();
filterPixmap = null;
filterTexture = null;
}
if(filterPixmap == null){
filterPixmap = Pixmaps.copy(pixmap);
filter.process(filterPixmap);
filterTexture = new Texture(filterPixmap);
}else{
filterPixmap.drawPixmap(pixmap, 0, 0);
filter.process(filterPixmap);
filterTexture.draw(filterPixmap, 0, 0);
}
}
public Texture getFilterTexture(){
return filterTexture;
}
public void applyFilter(){
filter.process(pixmap);
texture.draw(pixmap, 0, 0);
}
public void beginEdit(Map map){ public void beginEdit(Map map){
this.map = map; this.map = map;
this.brushSize = 1; this.brushSize = 1;
@@ -87,7 +130,7 @@ public class MapEditor{
y = 0; y = 0;
} }
pixmap.fillCircle(dx, dy, brushSize); pixmap.fillCircle(dx, dy, brushSize-1);
Pixmap dst = brush(brushSize); Pixmap dst = brush(brushSize);
dst.drawPixmap(pixmap, x, y, dstWidth, dstHeight, 0, 0, dstWidth, dstHeight); dst.drawPixmap(pixmap, x, y, dstWidth, dstHeight, 0, 0, dstWidth, dstHeight);
@@ -109,6 +152,10 @@ public class MapEditor{
return texture; return texture;
} }
public Pixmap pixmap(){
return pixmap;
}
public void resize(int mapSize){ public void resize(int mapSize){
Pixmap out = Pixmaps.resize(pixmap, mapSize, mapSize); Pixmap out = Pixmaps.resize(pixmap, mapSize, mapSize);
pixmap.dispose(); pixmap.dispose();

View File

@@ -5,6 +5,7 @@ import io.anuke.mindustry.world.ColorMapper;
import io.anuke.mindustry.world.ColorMapper.BlockPair; import io.anuke.mindustry.world.ColorMapper.BlockPair;
import io.anuke.mindustry.world.Map; import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
import io.anuke.ucore.scene.builders.*; import io.anuke.ucore.scene.builders.*;
import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.*;
@@ -14,10 +15,13 @@ import io.anuke.ucore.scene.ui.layout.Unit;
public class MapEditorDialog extends Dialog{ public class MapEditorDialog extends Dialog{
private MapEditor editor; private MapEditor editor;
private MapView view; private MapView view;
private MapGenerateDialog dialog;
private ButtonGroup<ImageButton> blockgroup;
public MapEditorDialog(MapEditor editor){ public MapEditorDialog(MapEditor editor){
super("Map Editor", "dialog"); super("Map Editor", "dialog");
this.editor = editor; this.editor = editor;
dialog = new MapGenerateDialog(editor);
view = new MapView(editor); view = new MapView(editor);
setFillParent(true); setFillParent(true);
@@ -30,9 +34,23 @@ public class MapEditorDialog extends Dialog{
shown(() -> { shown(() -> {
editor.beginEdit(new Map()); editor.beginEdit(new Map());
Core.scene.setScrollFocus(view);
}); });
} }
public void updateSelectedBlock(){
Block block = editor.getDrawBlock();
int i = 0;
for(BlockPair pair : ColorMapper.getPairs()){
if(pair.wall == block || (pair.wall == Blocks.air && pair.floor == block)){
blockgroup.getButtons().get(i).setChecked(true);
break;
}
i++;
}
}
public void build(){ public void build(){
new table(){{ new table(){{
@@ -40,8 +58,15 @@ public class MapEditorDialog extends Dialog{
aleft(); aleft();
new table(){{ new table(){{
defaults().growY().width(130f).units(Unit.dp).padBottom(-6); defaults().growY().width(130f).units(Unit.dp).padBottom(-6);
new imagebutton("icon-terrain", isize, () -> {
dialog.show();
}).text("generate").units(Unit.dp);
row();
new imagebutton("icon-load", isize, () -> { new imagebutton("icon-load", isize, () -> {
}).text("load map"); }).text("load map");
@@ -73,7 +98,7 @@ public class MapEditorDialog extends Dialog{
row(); row();
new imagebutton("icon-arrow-left", isize, () -> { new imagebutton("icon-arrow-left", isize, () -> {
hide();
}).padBottom(0).text("back"); }).padBottom(0).text("back");
}}.left().growY().end(); }}.left().growY().end();
@@ -83,9 +108,24 @@ public class MapEditorDialog extends Dialog{
}}.grow().end(); }}.grow().end();
new table(){{ new table(){{
new imagebutton("icon-terrain", isize, () -> { Table tools = new Table("button");
tools.top();
tools.padTop(0).padBottom(6);
}).margin(12f).text("generate...").width(148f).units(Unit.dp); ButtonGroup<ImageButton> group = new ButtonGroup<>();
int i = 0;
for(EditorTool tool : EditorTool.values()){
ImageButton button = new ImageButton("icon-" + tool.name(), "toggle");
button.clicked(() -> view.setTool(tool));
button.resizeImage(Unit.dp.inPixels(16*2f));
group.add(button);
tools.add(button).size(80f, 85f).padBottom(-6f).units(Unit.dp);
if(i++ % 2 == 1) tools.row();
}
add(tools).units(Unit.dp).width(160f).padBottom(-6);
row(); row();
@@ -116,6 +156,7 @@ public class MapEditorDialog extends Dialog{
pane.setFadeScrollBars(false); pane.setFadeScrollBars(false);
pane.setOverscroll(true, false); pane.setOverscroll(true, false);
ButtonGroup<ImageButton> group = new ButtonGroup<>(); ButtonGroup<ImageButton> group = new ButtonGroup<>();
blockgroup = group;
int i = 0; int i = 0;

View File

@@ -16,33 +16,37 @@ import io.anuke.ucore.noise.Simplex;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class MapFilter{ public class MapFilter{
private ObjectMap<String, Boolean> prefs = new OrderedMap<String, Boolean>(){ private ObjectMap<String, GenPref> prefs = map(
{ pref("replace", "whether to replace blocks"),
put("replace", true); pref("terrain", "generate new terrain"),
put("terrain", false); pref("circle", "generate terrain in a circle"),
put("circle", false); pref("distort", "distort the map image"),
put("distort", false); pref("sand", "add patches of sand"),
put("sand", false); pref("grass", "add patches of grass"),
put("grass", false); pref("stone", "add patches of stone"),
put("stone", false); pref("blackstone", "add patches of black stone"),
put("allgrass", false); pref("allgrass", "fill map with grass"),
put("allsnow", false); pref("allsnow", "fill map with snow"),
put("allsand", false); pref("allsand", "fill map with sand"),
put("lavarock", false); pref("water", "add lakes"),
put("water", false); pref("oil", "add oil lakes"),
put("oil", false); pref("lavariver", "add lava rivers"),
put("lavariver", false); pref("slavariver", "ad small lava rivers"),
put("slavariver", false); pref("river", "add rivers"),
put("river", false); pref("iceriver", "add frozen rivers"),
put("iceriver", false); pref("oilriver", "add oil rivers")
put("oilriver", false); );
}
};
private Simplex sim = new Simplex(); private Simplex sim = new Simplex();
private RidgedPerlin rid = new RidgedPerlin(1, 10, 20f); private RidgedPerlin rid = new RidgedPerlin(1, 10, 20f);
private RidgedPerlin rid2 = new RidgedPerlin(1, 6, 1f); private RidgedPerlin rid2 = new RidgedPerlin(1, 6, 1f);
private RidgedPerlin rid3 = new RidgedPerlin(1, 6, 1f); private RidgedPerlin rid3 = new RidgedPerlin(1, 6, 1f);
public MapFilter(){
prefs.get("replace").enabled = true;
prefs.get("terrain").enabled = true;
}
public void randomize(){ public void randomize(){
sim.setSeed(Mathf.random(999999)); sim.setSeed(Mathf.random(999999));
rid.setSeed(Mathf.random(999999)); rid.setSeed(Mathf.random(999999));
@@ -50,16 +54,16 @@ public class MapFilter{
rid3.setSeed(Mathf.random(999999)); rid3.setSeed(Mathf.random(999999));
} }
public ObjectMap<String, Boolean> getPrefs(){ public ObjectMap<String, GenPref> getPrefs(){
return prefs; return prefs;
} }
public Pixmap process(Pixmap pixmap){ public Pixmap process(Pixmap pixmap){
if(prefs.get("terrain")){ if(prefs.get("terrain").enabled){
for(int x = 0; x < pixmap.getWidth(); x++){ for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){ for(int y = 0; y < pixmap.getHeight(); y++){
float dist = Vector2.dst((float) x / pixmap.getWidth(), (float) y / pixmap.getHeight(), 0.5f, 0.5f) * 2f; float dist = Vector2.dst((float) x / pixmap.getWidth(), (float) y / pixmap.getHeight(), 0.5f, 0.5f) * 2f;
double noise = sim.octaveNoise2D(6, 0.6, 1 / 180.0, x, y + 9999) / (prefs.get("circle") ? 1.7 : 1f) + dist / 10f; double noise = sim.octaveNoise2D(6, 0.6, 1 / 180.0, x, y + 9999) / (prefs.get("circle").enabled ? 1.7 : 1f) + dist / 10f;
if(dist > 0.8){ if(dist > 0.8){
noise += 2 * (dist - 0.8); noise += 2 * (dist - 0.8);
@@ -78,7 +82,7 @@ public class MapFilter{
for(int y = 0; y < pixmap.getHeight(); y++){ for(int y = 0; y < pixmap.getHeight(); y++){
int dx = 0, dy = 0; int dx = 0, dy = 0;
if(prefs.get("distort")){ if(prefs.get("distort").enabled){
double intensity = 12; double intensity = 12;
double scale = 80; double scale = 80;
double octaves = 4; double octaves = 4;
@@ -105,41 +109,41 @@ public class MapFilter{
double noil = sim.octaveNoise2D(1, 1.0, 1 / 150.0, x + 9999, y) + sim.octaveNoise2D(1, 1.0, 1 / 2.0, x, y) / 290.0; double noil = sim.octaveNoise2D(1, 1.0, 1 / 150.0, x + 9999, y) + sim.octaveNoise2D(1, 1.0, 1 / 2.0, x, y) / 290.0;
if(!floor || prefs.get("replace")){ if(!floor || prefs.get("replace").enabled){
if(prefs.get("allgrass")){ if(prefs.get("allgrass").enabled){
block = floor ? Blocks.grass : Blocks.grassblock; block = floor ? Blocks.grass : Blocks.grassblock;
}else if(prefs.get("allsnow")){ }else if(prefs.get("allsnow").enabled){
block = floor ? Blocks.snow : Blocks.snowblock; block = floor ? Blocks.snow : Blocks.snowblock;
}else if(prefs.get("allsand")){ }else if(prefs.get("allsand").enabled){
block = floor ? Blocks.sand : Blocks.sandblock; block = floor ? Blocks.sand : Blocks.sandblock;
}else if(prefs.get("replace")){ }else if(prefs.get("replace").enabled){
block = floor ? Blocks.stone : Blocks.stoneblock; block = floor ? Blocks.stone : Blocks.stoneblock;
} }
if(noise > 0.7 && prefs.get("grass")){ if(noise > 0.7 && prefs.get("grass").enabled){
block = floor ? Blocks.grass : Blocks.grassblock; block = floor ? Blocks.grass : Blocks.grassblock;
} }
if(noise > 0.7 && prefs.get("lavarock")){ if(noise > 0.7 && prefs.get("blackstone").enabled){
block = floor ? Blocks.blackstone : Blocks.blackstoneblock; block = floor ? Blocks.blackstone : Blocks.blackstoneblock;
} }
if(noise > 0.7 && prefs.get("sand")){ if(noise > 0.7 && prefs.get("sand").enabled){
block = floor ? Blocks.sand : Blocks.sandblock; block = floor ? Blocks.sand : Blocks.sandblock;
} }
if(noise > 0.8 && prefs.get("stone")){ if(noise > 0.8 && prefs.get("stone").enabled){
block = floor ? Blocks.stone : Blocks.stoneblock; block = floor ? Blocks.stone : Blocks.stoneblock;
} }
} }
if(floor){ if(floor){
if(nwater > 0.93 && prefs.get("water")){ if(nwater > 0.93 && prefs.get("water").enabled){
block = Blocks.water; block = Blocks.water;
if(nwater > 0.943){ if(nwater > 0.943){
block = Blocks.deepwater; block = Blocks.deepwater;
} }
} }
if(noil > 0.95 && prefs.get("oil")){ if(noil > 0.95 && prefs.get("oil").enabled){
block = Blocks.dirt; block = Blocks.dirt;
if(noil > 0.955){ if(noil > 0.955){
block = Blocks.oil; block = Blocks.oil;
@@ -147,7 +151,7 @@ public class MapFilter{
} }
} }
if(floor && prefs.get("lavariver")){ if(floor && prefs.get("lavariver").enabled){
double lava = rid.getValue(x, y, 1 / 100f); double lava = rid.getValue(x, y, 1 / 100f);
double t = 0.6; double t = 0.6;
if(lava > t){ if(lava > t){
@@ -157,7 +161,7 @@ public class MapFilter{
} }
} }
if(floor && prefs.get("slavariver")){ if(floor && prefs.get("slavariver").enabled){
double lava = rid.getValue(x, y, 1 / 40f); double lava = rid.getValue(x, y, 1 / 40f);
double t = 0.7; double t = 0.7;
if(lava > t){ if(lava > t){
@@ -167,7 +171,7 @@ public class MapFilter{
} }
} }
if(floor && prefs.get("oilriver")){ if(floor && prefs.get("oilriver").enabled){
double lava = rid3.getValue(x, y, 1 / 100f); double lava = rid3.getValue(x, y, 1 / 100f);
double t = 0.9; double t = 0.9;
if(lava > t){ if(lava > t){
@@ -177,7 +181,7 @@ public class MapFilter{
} }
} }
if(floor && prefs.get("river")){ if(floor && prefs.get("river").enabled){
double riv = rid2.getValue(x, y, 1 / 140f); double riv = rid2.getValue(x, y, 1 / 140f);
double t = 0.4; double t = 0.4;
@@ -190,7 +194,7 @@ public class MapFilter{
} }
} }
if(floor && prefs.get("iceriver")){ if(floor && prefs.get("iceriver").enabled){
double riv = rid2.getValue(x, y, 1 / 140f); double riv = rid2.getValue(x, y, 1 / 140f);
double t = 0.4; double t = 0.4;
@@ -211,4 +215,29 @@ public class MapFilter{
return pixmap; return pixmap;
} }
private static OrderedMap<String, GenPref> map(GenPref...objects){
OrderedMap<String, GenPref> prefs = new OrderedMap<>();
for(int i = 0; i < objects.length; i ++){
GenPref pref = (GenPref)objects[i];
prefs.put(pref.name, pref);
}
return prefs;
}
private GenPref pref(String name, String desc){
return new GenPref(name, desc);
}
class GenPref{
public final String name;
public final String description;
public boolean enabled;
GenPref(String name, String description){
this.name = name;
this.description = description;
}
}
} }

View File

@@ -1,5 +1,97 @@
package io.anuke.mindustry.mapeditor; package io.anuke.mindustry.mapeditor;
public class MapGenerateDialog{ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Scaling;
import io.anuke.mindustry.mapeditor.MapFilter.GenPref;
import io.anuke.mindustry.ui.BorderImage;
import io.anuke.mindustry.ui.FloatingDialog;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.style.TextureRegionDrawable;
import io.anuke.ucore.scene.ui.CheckBox;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.layout.Stack;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit;
public class MapGenerateDialog extends FloatingDialog{
private MapEditor editor;
private Image image;
private boolean loading;
public MapGenerateDialog(MapEditor editor) {
super("generate");
this.editor = editor;
Stack stack = new Stack();
stack.add(image = new BorderImage());
Image loadImage = new Image("icon-loading");
loadImage.setScaling(Scaling.none);
loadImage.setScale(3f);
loadImage.update(() -> loadImage.setOrigin(Align.center));
loadImage.setVisible(() -> loading);
Image next = new Image("white");
next.setScaling(Scaling.fit);
next.setColor(0, 0, 0, 0.6f);
next.setVisible(() -> loading);
stack.add(next);
stack.add(loadImage);
content().add(stack).grow();
image.setScaling(Scaling.fit);
Table preft = new Table();
preft.left();
preft.pad(Unit.dp.inPixels(4f)).padRight(Unit.dp.inPixels(25f));
for(GenPref pref : editor.getFilter().getPrefs().values()){
CheckBox box = new CheckBox(pref.name);
box.setChecked(pref.enabled);
box.changed(() -> pref.enabled = box.isChecked());
preft.add(box).pad(4f).units(Unit.dp).left();
preft.row();
}
ScrollPane pane = new ScrollPane(preft, "volume");
pane.setFadeScrollBars(false);
pane.setScrollingDisabled(true, false);
content().add(pane).fillY();
buttons().defaults().size(170f, 50f).units(Unit.dp).pad(4f);
buttons().addButton("Back", () -> hide());
buttons().addButton("Randomize", () ->{
editor.getFilter().randomize();
apply();
});
buttons().addButton("Update", () ->{
apply();
});
buttons().addButton("Apply", () ->{
editor.applyFilter();
hide();
});
shown(() ->{
loading = true;
Timers.run(30f, () -> {
editor.applyFilterPreview();
image.setDrawable(new TextureRegionDrawable(new TextureRegion(editor.getFilterTexture())));
loading = false;
});
});
}
private void apply(){
loading = true;
Timers.run(3f, ()->{
editor.applyFilterPreview();
loading = false;
});
}
} }

View File

@@ -1,21 +1,42 @@
package io.anuke.mindustry.mapeditor; package io.anuke.mindustry.mapeditor;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.input.GestureDetector.GestureListener;
import com.badlogic.gdx.math.Bresenham2; import com.badlogic.gdx.math.Bresenham2;
import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.scene.Element; import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.event.InputEvent; import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.event.InputListener; import io.anuke.ucore.scene.event.InputListener;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp; import io.anuke.ucore.util.Tmp;
public class MapView extends Element{ public class MapView extends Element implements GestureListener{
private MapEditor editor; private MapEditor editor;
private EditorTool tool = EditorTool.pencil;
private Bresenham2 br = new Bresenham2(); private Bresenham2 br = new Bresenham2();
private float offsetx, offsety;
private float zoom = 1f;
public void setTool(EditorTool tool){
this.tool = tool;
}
public MapView(MapEditor editor){ public MapView(MapEditor editor){
this.editor = editor; this.editor = editor;
Inputs.addProcessor(0, new GestureDetector(20, 0.5f, 2, 0.15f, this));
addListener(new InputListener(){ addListener(new InputListener(){
int lastx, lasty; int lastx, lasty;
boolean drawing; boolean drawing;
@@ -25,7 +46,9 @@ public class MapView extends Element{
GridPoint2 p = project(x, y); GridPoint2 p = project(x, y);
lastx = p.x; lastx = p.x;
lasty = p.y; lasty = p.y;
editor.draw(p.x, p.y); tool.touched(editor, p.x, p.y);
drawing = true;
return true; return true;
} }
@@ -38,29 +61,131 @@ public class MapView extends Element{
public void touchDragged (InputEvent event, float x, float y, int pointer) { public void touchDragged (InputEvent event, float x, float y, int pointer) {
GridPoint2 p = project(x, y); GridPoint2 p = project(x, y);
if(drawing){ if(drawing && tool == EditorTool.pencil){
Array<GridPoint2> points = br.line(lastx, lasty, p.x, p.y); Array<GridPoint2> points = br.line(lastx, lasty, p.x, p.y);
for(GridPoint2 point : points){ for(GridPoint2 point : points){
editor.draw(point.x, point.y); editor.draw(point.x, point.y);
} }
} }
drawing = true;
lastx = p.x; lastx = p.x;
lasty = p.y; lasty = p.y;
} }
}); });
addListener(new InputListener(){
@Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
return tool == EditorTool.zoom;
}
@Override
public void touchDragged (InputEvent event, float x, float y, int pointer) {
//offsetx += Gdx.input.getDeltaX(pointer) / zoom;
//offsety -= Gdx.input.getDeltaY(pointer) / zoom;
}
});
}
@Override
public void act(float delta){
super.act(delta);
float size = Math.min(width, height);
offsetx = Mathf.clamp(offsetx, -size, size);
offsety = Mathf.clamp(offsety, -size, size);
if(tool != EditorTool.zoom) return;
zoom += Inputs.scroll()/10f * zoom;
clampZoom();
}
private void clampZoom(){
zoom = Mathf.clamp(zoom, 0.4f, 6f);
} }
private GridPoint2 project(float x, float y){ private GridPoint2 project(float x, float y){
float size = Math.min(width, height); float size = Math.min(width, height)*zoom;
x = (x - getWidth()/2 + size/2) / size * editor.texture().getWidth(); x = (x - getWidth()/2 + size/2 - offsetx*zoom) / size * editor.texture().getWidth();
y = (y - getHeight()/2 + size/2) / size * editor.texture().getHeight(); y = (y - getHeight()/2 + size/2 - offsety*zoom) / size * editor.texture().getHeight();
return Tmp.g1.set((int)x, editor.texture().getHeight() - 1 - (int)y); return Tmp.g1.set((int)x, editor.texture().getHeight() - 1 - (int)y);
} }
@Override @Override
public void draw(Batch batch, float alpha){ public void draw(Batch batch, float alpha){
float size = Math.min(width, height); float size = Math.min(width, height);
batch.draw(editor.texture(), x + width/2 - size/2, y + height/2 - size/2, size, size); float sclsize = size * zoom;
float centerx = x + width/2 + offsetx * zoom;
float centery = y + height/2 + offsety * zoom;
batch.flush();
ScissorStack.pushScissors(Tmp.r1.set(x + width/2 - size/2, y + height/2 - size/2, size, size));
batch.draw(editor.texture(), centerx - sclsize/2, centery - sclsize/2, sclsize, sclsize);
batch.flush();
ScissorStack.popScissors();
Draw.color(Colors.get("accent"));
Draw.thick(Unit.dp.inPixels(3f));
Draw.linerect(x + width/2 - size/2, y + height/2 - size/2, size, size);
Draw.reset();
}
private boolean active(){
return Core.scene.getKeyboardFocus().isDescendantOf(Vars.ui.getEditor()) && Vars.ui.isEditing() && tool == EditorTool.zoom;
}
@Override
public boolean touchDown(float x, float y, int pointer, int button){
return false;
}
@Override
public boolean tap(float x, float y, int count, int button){
return false;
}
@Override
public boolean longPress(float x, float y){
return false;
}
@Override
public boolean fling(float velocityX, float velocityY, int button){
return false;
}
@Override
public boolean pan(float x, float y, float deltaX, float deltaY){
if(!active()) return false;
offsetx += deltaX / zoom;
offsety -= deltaY / zoom;
return false;
}
@Override
public boolean panStop(float x, float y, int pointer, int button){
return false;
}
@Override
public boolean zoom(float initialDistance, float distance){
if(!active()) return false;
float nzoom = distance - initialDistance;
zoom += nzoom / 2000f / Unit.dp.inPixels(1f) * zoom;
clampZoom();
return false;
}
@Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2){
return false;
}
@Override
public void pinchStop(){
} }
} }

View File

@@ -0,0 +1,24 @@
package io.anuke.mindustry.ui;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.Batch;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.layout.Unit;
public class BorderImage extends Image{
@Override
public void draw(Batch batch, float alpha){
super.draw(batch, alpha);
float scaleX = getScaleX();
float scaleY = getScaleY();
Draw.color(Colors.get("accent"));
Draw.thick(Unit.dp.inPixels(3f));
Draw.linerect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY);
Draw.reset();
}
}

View File

@@ -69,6 +69,10 @@ public class ColorMapper{
public static class BlockPair{ public static class BlockPair{
public final Block floor, wall; public final Block floor, wall;
public Block dominant(){
return wall == Blocks.air ? floor : wall;
}
private BlockPair(Block floor, Block wall){ private BlockPair(Block floor, Block wall){
this.floor = floor; this.floor = floor;
this.wall = wall; this.wall = wall;

View File

@@ -55,7 +55,7 @@ public class ProductionBlocks{
requirements = new Item[]{Item.coal, Item.iron}; requirements = new Item[]{Item.coal, Item.iron};
result = Item.steel; result = Item.steel;
description = "Converts coal + iron to steel."; description = "Converts coal + iron to steel.";
fullDescription = "The essential crafting block. When inputted 1x iron and 1x iron, outputs one steel."; fullDescription = "The essential crafting block. When inputted 1x iron and 1x coal, outputs one steel.";
} }
}, },

View File

@@ -75,7 +75,7 @@ public class ShieldBlock extends PowerBlock{
} }
bullet.remove(); bullet.remove();
Effects.effect(Fx.laserhit, bullet); Effects.effect(bullet.damage > 5 ? Fx.shieldhit : Fx.laserhit, bullet);
Vars.renderer.addShieldHit(bullet.x, bullet.y); Vars.renderer.addShieldHit(bullet.x, bullet.y);
entity.power -= bullet.getDamage() * powerPerDamage; entity.power -= bullet.getDamage() * powerPerDamage;

View File

@@ -31,7 +31,6 @@ public class TunnelConveyor extends Block{
if(to == null || to.entity == null) return; if(to == null || to.entity == null) return;
to.block().handleItem(item, to, tunnel); to.block().handleItem(item, to, tunnel);
}); });
} }
@Override @Override

View File

@@ -1,18 +0,0 @@
package io.anuke.mindustry.desktop;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import io.anuke.mindustry.editor.Editor;
public class EditorLauncher{
public static void main (String[] arg) {
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setTitle("Mindustry Editor");
config.setMaximized(true);
config.setWindowedMode(800, 600);
config.setWindowIcon("sprites/icon.png");
new Lwjgl3Application(new Editor(), config);
}
}