Initial implementation of Anuken/Mindustry-Suggestions/issues/327
This commit is contained in:
138
core/src/mindustry/editor/WaveGraph.java
Normal file
138
core/src/mindustry/editor/WaveGraph.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package mindustry.editor;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.pooling.*;
|
||||
import mindustry.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
|
||||
public class WaveGraph extends Table{
|
||||
public Seq<SpawnGroup> groups = new Seq<>();
|
||||
public int from, to = 20;
|
||||
|
||||
private int[][] values;
|
||||
private OrderedSet<UnitType> used = new OrderedSet<>();
|
||||
private int max;
|
||||
private Table colors;
|
||||
private ObjectSet<UnitType> hidden = new ObjectSet<>();
|
||||
|
||||
public WaveGraph(){
|
||||
background(Tex.pane);
|
||||
|
||||
rect((x, y, width, height) -> {
|
||||
Lines.stroke(Scl.scl(3f));
|
||||
Lines.precise(true);
|
||||
|
||||
float offsetX = Scl.scl(30f), offsetY = Scl.scl(20f);
|
||||
|
||||
float graphX = x + offsetX, graphY = y + offsetY, graphW = width - offsetX, graphH = height - offsetY;
|
||||
float spacing = graphW / (values.length - 1);
|
||||
|
||||
for(UnitType type : used){
|
||||
Draw.color(color(type));
|
||||
Draw.alpha(parentAlpha);
|
||||
Lines.beginLine();
|
||||
for(int i = 0; i < values.length; i++){
|
||||
int val = values[i][type.id];
|
||||
|
||||
float cx = graphX + i*spacing, cy = 2f + graphY + val * (graphH - 4f) / max;
|
||||
Lines.linePoint(cx, cy);
|
||||
}
|
||||
Lines.endLine();
|
||||
}
|
||||
|
||||
GlyphLayout lay = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
|
||||
BitmapFont font = Fonts.outline;
|
||||
|
||||
lay.setText(font, "1");
|
||||
|
||||
//how many numbers can fit here
|
||||
float totalMarks = (height - offsetY - getMarginBottom() *2f - 1f) / (lay.height * 2);
|
||||
|
||||
int markSpace = Math.max(1, Mathf.ceil(max / totalMarks));
|
||||
|
||||
Draw.color(Color.lightGray);
|
||||
for(int i = 0; i < max; i += markSpace){
|
||||
float cy = 2f + y + i * (height - 4f) / max + offsetY, cx = x + offsetX;
|
||||
//Lines.line(cx, cy, cx + len, cy);
|
||||
|
||||
lay.setText(font, "" + i);
|
||||
|
||||
font.draw("" + i, cx, cy + lay.height/2f - Scl.scl(3f), Align.right);
|
||||
}
|
||||
|
||||
float len = 4f;
|
||||
|
||||
for(int i = 0; i < values.length; i++){
|
||||
float cy = y, cx = x + graphW / (values.length - 1) * i + offsetX;
|
||||
|
||||
Lines.line(cx, cy, cx, cy + len);
|
||||
}
|
||||
|
||||
Pools.free(lay);
|
||||
|
||||
Lines.precise(false);
|
||||
Draw.reset();
|
||||
}).pad(4).padBottom(10).grow();
|
||||
|
||||
row();
|
||||
|
||||
table(t -> colors = t).growX();
|
||||
}
|
||||
|
||||
public void rebuild(){
|
||||
values = new int[to - from + 1][Vars.content.units().size];
|
||||
used.clear();
|
||||
max = 1;
|
||||
|
||||
for(int i = from; i <= to; i++){
|
||||
int index = i - from;
|
||||
|
||||
for(SpawnGroup spawn : groups){
|
||||
int spawned = spawn.getUnitsSpawned(i);
|
||||
values[index][spawn.type.id] += spawned;
|
||||
if(spawned > 0){
|
||||
used.add(spawn.type);
|
||||
}
|
||||
max = Math.max(max, values[index][spawn.type.id]);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectSet<UnitType> usedCopy = new ObjectSet<>(used);
|
||||
|
||||
colors.clear();
|
||||
colors.left();
|
||||
for(UnitType type : used){
|
||||
colors.button(b -> {
|
||||
Color tcolor = color(type).cpy();
|
||||
b.image().size(32f).update(i -> i.setColor(b.isChecked() ? Tmp.c1.set(tcolor).mul(0.5f) : tcolor)).get().act(1);
|
||||
b.image(type.icon(Cicon.medium)).padRight(20).update(i -> i.setColor(b.isChecked() ? Color.gray : Color.white)).get().act(1);
|
||||
b.margin(0f);
|
||||
}, Styles.fullTogglet, () -> {
|
||||
if(!hidden.add(type)){
|
||||
hidden.remove(type);
|
||||
}
|
||||
|
||||
used.clear();
|
||||
used.addAll(usedCopy);
|
||||
for(UnitType o : hidden) used.remove(o);
|
||||
}).update(b -> b.setChecked(hidden.contains(type)));
|
||||
}
|
||||
|
||||
for(UnitType type : hidden){
|
||||
used.remove(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Color color(UnitType type){
|
||||
return Tmp.c1.fromHsv(type.id / (float)Vars.content.units().size * 360f, 0.7f, 1f);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,35 @@
|
||||
package mindustry.editor;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.*;
|
||||
import arc.graphics.*;
|
||||
import arc.input.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.event.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.TextField.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.ctype.ContentType;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.io.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.Cicon;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.ui.dialogs.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.game.SpawnGroup.never;
|
||||
import static mindustry.game.SpawnGroup.*;
|
||||
|
||||
public class WaveInfoDialog extends BaseDialog{
|
||||
private static final int displayed = 20;
|
||||
private Seq<SpawnGroup> groups = new Seq<>();
|
||||
|
||||
private Table table, preview;
|
||||
private Table table;
|
||||
private int start = 0;
|
||||
private UnitType lastType = UnitTypes.dagger;
|
||||
private float updateTimer, updatePeriod = 1f;
|
||||
private WaveGraph graph = new WaveGraph();
|
||||
|
||||
public WaveInfoDialog(MapEditor editor){
|
||||
super("$waves.title");
|
||||
@@ -47,7 +45,31 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
}
|
||||
});
|
||||
|
||||
onResize(this::setup);
|
||||
addCloseButton();
|
||||
buttons.button("<<", () -> {
|
||||
}).update(t -> {
|
||||
if(t.getClickListener().isPressed()){
|
||||
updateTimer += Time.delta;
|
||||
if(updateTimer >= updatePeriod){
|
||||
start = Math.max(start - 1, 0);
|
||||
updateTimer = 0f;
|
||||
updateWaves();
|
||||
}
|
||||
}
|
||||
});
|
||||
buttons.button(">>", () -> {
|
||||
}).update(t -> {
|
||||
if(t.getClickListener().isPressed()){
|
||||
updateTimer += Time.delta;
|
||||
if(updateTimer >= updatePeriod){
|
||||
start++;
|
||||
updateTimer = 0f;
|
||||
updateWaves();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
buttons.button("$waves.edit", () -> {
|
||||
BaseDialog dialog = new BaseDialog("$waves.edit");
|
||||
dialog.addCloseButton();
|
||||
@@ -98,35 +120,7 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
setAlignment(Align.center, Align.center);
|
||||
}}).width(390f).growY();
|
||||
|
||||
cont.table(Tex.clear, m -> {
|
||||
m.add("$waves.preview").color(Color.lightGray).wrap().growX().center().get().setAlignment(Align.center, Align.center);
|
||||
m.row();
|
||||
m.button("-", () -> {
|
||||
}).update(t -> {
|
||||
if(t.getClickListener().isPressed()){
|
||||
updateTimer += Time.delta;
|
||||
if(updateTimer >= updatePeriod){
|
||||
start = Math.max(start - 1, 0);
|
||||
updateTimer = 0f;
|
||||
updateWaves();
|
||||
}
|
||||
}
|
||||
}).growX().height(70f);
|
||||
m.row();
|
||||
m.pane(t -> preview = t).grow().get().setScrollingDisabled(true, true);
|
||||
m.row();
|
||||
m.button("+", () -> {
|
||||
}).update(t -> {
|
||||
if(t.getClickListener().isPressed()){
|
||||
updateTimer += Time.delta;
|
||||
if(updateTimer >= updatePeriod){
|
||||
start++;
|
||||
updateTimer = 0f;
|
||||
updateWaves();
|
||||
}
|
||||
}
|
||||
}).growX().height(70f);
|
||||
}).growY().width(180f).growY();
|
||||
cont.add(graph).grow();
|
||||
|
||||
buildGroups();
|
||||
}
|
||||
@@ -137,6 +131,7 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
table.margin(10f);
|
||||
|
||||
if(groups != null){
|
||||
|
||||
for(SpawnGroup group : groups){
|
||||
table.table(Tex.button, t -> {
|
||||
t.margin(0).defaults().pad(3).padLeft(5f).growX().left();
|
||||
@@ -225,6 +220,7 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
updateWaves();
|
||||
}).growX().pad(-6f).padTop(5);
|
||||
}).width(340f).pad(16);
|
||||
|
||||
table.row();
|
||||
}
|
||||
}else{
|
||||
@@ -243,7 +239,7 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
if(type.isHidden()) continue;
|
||||
p.button(t -> {
|
||||
t.left();
|
||||
t.image(type.icon(mindustry.ui.Cicon.medium)).size(40f).padRight(2f);
|
||||
t.image(type.icon(Cicon.medium)).size(40f).padRight(2f);
|
||||
t.add(type.localizedName);
|
||||
}, () -> {
|
||||
lastType = type;
|
||||
@@ -258,36 +254,9 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
}
|
||||
|
||||
void updateWaves(){
|
||||
preview.clear();
|
||||
preview.top();
|
||||
|
||||
for(int i = start; i < displayed + start; i++){
|
||||
int wave = i;
|
||||
preview.table(Tex.underline, table -> {
|
||||
table.add((wave + 1) + "").color(Pal.accent).center().colspan(2).get().setAlignment(Align.center, Align.center);
|
||||
table.row();
|
||||
|
||||
int[] spawned = new int[Vars.content.getBy(ContentType.unit).size];
|
||||
|
||||
for(SpawnGroup spawn : groups){
|
||||
spawned[spawn.type.id] += spawn.getUnitsSpawned(wave);
|
||||
}
|
||||
|
||||
for(int j = 0; j < spawned.length; j++){
|
||||
if(spawned[j] > 0){
|
||||
UnitType type = content.getByID(ContentType.unit, j);
|
||||
table.image(type.icon(Cicon.medium)).size(8f * 4f).padRight(4);
|
||||
table.add(spawned[j] + "x").color(Color.lightGray).padRight(6);
|
||||
table.row();
|
||||
}
|
||||
}
|
||||
|
||||
if(table.getChildren().size == 1){
|
||||
table.add("$none").color(Pal.remove);
|
||||
}
|
||||
}).width(110f).pad(2f);
|
||||
|
||||
preview.row();
|
||||
}
|
||||
graph.groups = groups;
|
||||
graph.from = start;
|
||||
graph.to = start + displayed;
|
||||
graph.rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user