Added mirror tool for attack/PvP maps
This commit is contained in:
@@ -277,6 +277,7 @@ filter.option.threshold = Threshold
|
|||||||
filter.option.circle-scale = Circle Scale
|
filter.option.circle-scale = Circle Scale
|
||||||
filter.option.octaves = Octaves
|
filter.option.octaves = Octaves
|
||||||
filter.option.falloff = Falloff
|
filter.option.falloff = Falloff
|
||||||
|
filter.option.angle = Angle
|
||||||
filter.option.block = Block
|
filter.option.block = Block
|
||||||
filter.option.floor = Floor
|
filter.option.floor = Floor
|
||||||
filter.option.flooronto = Target Floor
|
filter.option.flooronto = Target Floor
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -30,7 +30,8 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
public class MapGenerateDialog extends FloatingDialog{
|
public class MapGenerateDialog extends FloatingDialog{
|
||||||
private final Supplier<GenerateFilter>[] filterTypes = new Supplier[]{
|
private final Supplier<GenerateFilter>[] filterTypes = new Supplier[]{
|
||||||
NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new,
|
NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new,
|
||||||
RiverNoiseFilter::new, OreFilter::new, MedianFilter::new, BlendFilter::new
|
RiverNoiseFilter::new, OreFilter::new, MedianFilter::new, BlendFilter::new,
|
||||||
|
MirrorFilter::new
|
||||||
};
|
};
|
||||||
private final MapEditor editor;
|
private final MapEditor editor;
|
||||||
|
|
||||||
@@ -84,9 +85,19 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
cont.clear();
|
cont.clear();
|
||||||
cont.table(t -> {
|
cont.table(t -> {
|
||||||
t.margin(8f);
|
t.margin(8f);
|
||||||
t.stack(new BorderImage(texture){{
|
t.stack(new BorderImage(texture){
|
||||||
setScaling(Scaling.fit);
|
{
|
||||||
}}, new Stack(){{
|
setScaling(Scaling.fit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(){
|
||||||
|
super.draw();
|
||||||
|
for(GenerateFilter filter : filters){
|
||||||
|
filter.draw(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, new Stack(){{
|
||||||
add(new Image("loadDim"));
|
add(new Image("loadDim"));
|
||||||
add(new Image("icon-refresh"){{
|
add(new Image("icon-refresh"){{
|
||||||
setScaling(Scaling.none);
|
setScaling(Scaling.none);
|
||||||
|
|||||||
@@ -24,28 +24,32 @@ public abstract class FilterOption{
|
|||||||
|
|
||||||
public abstract void build(Table table);
|
public abstract void build(Table table);
|
||||||
|
|
||||||
public Runnable changed = () -> {
|
public Runnable changed = () -> {};
|
||||||
};
|
|
||||||
|
|
||||||
static class SliderOption extends FilterOption{
|
static class SliderOption extends FilterOption{
|
||||||
final String name;
|
final String name;
|
||||||
final FloatProvider getter;
|
final FloatProvider getter;
|
||||||
final FloatConsumer setter;
|
final FloatConsumer setter;
|
||||||
final float min, max;
|
final float min, max, step;
|
||||||
|
|
||||||
SliderOption(String name, FloatProvider getter, FloatConsumer setter, float min, float max){
|
SliderOption(String name, FloatProvider getter, FloatConsumer setter, float min, float max){
|
||||||
|
this(name, getter, setter, min, max, (max - min) / 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
SliderOption(String name, FloatProvider getter, FloatConsumer setter, float min, float max, float step){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.getter = getter;
|
this.getter = getter;
|
||||||
this.setter = setter;
|
this.setter = setter;
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
|
this.step = step;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(Table table){
|
public void build(Table table){
|
||||||
table.add("$filter.option." + name);
|
table.add("$filter.option." + name);
|
||||||
table.row();
|
table.row();
|
||||||
Slider slider = table.addSlider(min, max, (max - min) / 200f, setter).growX().get();
|
Slider slider = table.addSlider(min, max, step, setter).growX().get();
|
||||||
slider.setValue(getter.get());
|
slider.setValue(getter.get());
|
||||||
if(updateEditorOnChange){
|
if(updateEditorOnChange){
|
||||||
slider.changed(changed);
|
slider.changed(changed);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.editor.generation;
|
|||||||
|
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.Core;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
|
import io.anuke.arc.scene.ui.*;
|
||||||
import io.anuke.arc.util.Pack;
|
import io.anuke.arc.util.Pack;
|
||||||
import io.anuke.arc.util.noise.RidgedPerlin;
|
import io.anuke.arc.util.noise.RidgedPerlin;
|
||||||
import io.anuke.arc.util.noise.Simplex;
|
import io.anuke.arc.util.noise.Simplex;
|
||||||
@@ -20,6 +21,9 @@ public abstract class GenerateFilter{
|
|||||||
|
|
||||||
protected abstract void apply();
|
protected abstract void apply();
|
||||||
|
|
||||||
|
//draw any additional guides
|
||||||
|
public void draw(Image image){}
|
||||||
|
|
||||||
protected float noise(float x, float y, float scl, float mag){
|
protected float noise(float x, float y, float scl, float mag){
|
||||||
return (float)in.noise.octaveNoise2D(1f, 0f, 1f / scl, x + o, y + o) * mag;
|
return (float)in.noise.octaveNoise2D(1f, 0f, 1f / scl, x + o, y + o) * mag;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package io.anuke.mindustry.editor.generation;
|
||||||
|
|
||||||
|
import io.anuke.arc.function.*;
|
||||||
|
import io.anuke.arc.graphics.g2d.*;
|
||||||
|
import io.anuke.arc.math.geom.*;
|
||||||
|
import io.anuke.arc.scene.ui.*;
|
||||||
|
import io.anuke.arc.scene.ui.layout.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
|
import io.anuke.mindustry.editor.MapGenerateDialog.*;
|
||||||
|
import io.anuke.mindustry.editor.generation.FilterOption.*;
|
||||||
|
import io.anuke.mindustry.graphics.*;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.content;
|
||||||
|
|
||||||
|
public class MirrorFilter extends GenerateFilter{
|
||||||
|
private final Vector2 v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2();
|
||||||
|
|
||||||
|
float angle = 45;
|
||||||
|
|
||||||
|
{
|
||||||
|
options(new SliderOption("angle", () -> angle, f -> angle = f, 0, 360, 45));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void apply(){
|
||||||
|
v1.trns(angle - 90, 1f);
|
||||||
|
v2.set(v1).scl(-1f);
|
||||||
|
|
||||||
|
v1.add(in.width/2f, in.height/2f);
|
||||||
|
v2.add(in.width/2f, in.height/2f);
|
||||||
|
|
||||||
|
v3.set(in.x / in.scaling, in.y / in.scaling);
|
||||||
|
|
||||||
|
if(!left(v1, v2, v3)){
|
||||||
|
mirror(v3, v1.x, v1.y, v2.x, v2.y);
|
||||||
|
GenTile tile = in.tile(v3.x, v3.y);
|
||||||
|
in.floor = content.block(tile.floor);
|
||||||
|
in.block = content.block(tile.block);
|
||||||
|
in.ore = content.block(tile.ore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Image image){
|
||||||
|
super.draw(image);
|
||||||
|
float size = Math.max(image.getWidth() *2, image.getHeight()*2);
|
||||||
|
Consumer<Vector2> clamper = v -> v.clamp(image.getX(), image.getX() + image.getWidth(), image.getY(), image.getY() + image.getHeight());
|
||||||
|
clamper.accept(Tmp.v1.trns(angle - 90, size).add(image.getWidth()/2f + image.getX(), image.getHeight()/2f + image.getY()));
|
||||||
|
clamper.accept(Tmp.v2.set(Tmp.v1).sub(image.getWidth()/2f + image.getX(), image.getHeight()/2f + image.getY()).rotate(180f).add(image.getWidth()/2f + image.getX(), image.getHeight()/2f + image.getY()));
|
||||||
|
|
||||||
|
Lines.stroke(Unit.dp.scl(3f), Pal.accent);
|
||||||
|
Lines.line(Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y);
|
||||||
|
Draw.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mirror(Vector2 p, float x0, float y0, float x1, float y1){
|
||||||
|
float dx = x1 - x0;
|
||||||
|
float dy = y1 - y0;
|
||||||
|
|
||||||
|
float a = (dx * dx - dy * dy) / (dx * dx + dy*dy);
|
||||||
|
float b = 2 * dx * dy / (dx*dx + dy*dy);
|
||||||
|
|
||||||
|
p.set((a * (p.x - x0) + b*(p.y - y0) + x0), (b * (p.x - x0) - a*(p.y - y0) + y0));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean left(Vector2 a, Vector2 b, Vector2 c){
|
||||||
|
return ((b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x)) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
package io.anuke.mindustry.type;
|
package io.anuke.mindustry.type;
|
||||||
|
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.collection.IntMap;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.game.*;
|
||||||
import io.anuke.mindustry.game.Content;
|
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
import io.anuke.mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.defaultTeam;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
|
||||||
|
|
||||||
public class Loadout extends Content{
|
public class Loadout extends Content{
|
||||||
private final Array<Tile> outArray = new Array<>();
|
private final Array<Tile> outArray = new Array<>();
|
||||||
@@ -70,6 +68,8 @@ public class Loadout extends Content{
|
|||||||
int rx = Pos.x(entry.key);
|
int rx = Pos.x(entry.key);
|
||||||
int ry = Pos.y(entry.key);
|
int ry = Pos.y(entry.key);
|
||||||
Tile tile = world.tile(x + rx, y + ry);
|
Tile tile = world.tile(x + rx, y + ry);
|
||||||
|
if(tile == null) continue;
|
||||||
|
|
||||||
world.setBlock(tile, entry.value.block, defaultTeam);
|
world.setBlock(tile, entry.value.block, defaultTeam);
|
||||||
tile.rotation((byte)entry.value.rotation);
|
tile.rotation((byte)entry.value.rotation);
|
||||||
if(entry.value.ore != null){
|
if(entry.value.ore != null){
|
||||||
|
|||||||
Reference in New Issue
Block a user