mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-26 23:57:39 +07:00
WIP objective editor progress
This commit is contained in:
BIN
core/assets-raw/sprites/effects/point-laser-center.png
Normal file
BIN
core/assets-raw/sprites/effects/point-laser-center.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 496 B |
BIN
core/assets-raw/sprites/effects/point-laser-end.png
Normal file
BIN
core/assets-raw/sprites/effects/point-laser-end.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 539 B |
BIN
core/assets-raw/sprites/effects/point-laser.png
Normal file
BIN
core/assets-raw/sprites/effects/point-laser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 131 B |
@ -4196,14 +4196,14 @@ public class Blocks{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
lustre = new ContinuousTurret("lustre"){{
|
lustre = new ContinuousTurret("lustre"){{
|
||||||
requirements(Category.turret, with(Items.beryllium, 150, Items.silicon, 200, Items.graphite, 200, Items.carbide, 50));
|
requirements(Category.turret, with(Items.silicon, 250, Items.graphite, 200, Items.oxide, 50, Items.carbide, 90));
|
||||||
|
|
||||||
range = 100f;
|
range = 100f;
|
||||||
|
|
||||||
shootType = new PointLaserBulletType(){{
|
shootType = new PointLaserBulletType(){{
|
||||||
damage = 150f;
|
damage = 150f;
|
||||||
buildingDamageMultiplier = 0.3f;
|
buildingDamageMultiplier = 0.3f;
|
||||||
hitColor = Color.valueOf("fd9e81");
|
hitColor = Color.valueOf("fda981");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
drawer = new DrawTurret("reinforced-"){{
|
drawer = new DrawTurret("reinforced-"){{
|
||||||
|
@ -1,22 +1,36 @@
|
|||||||
package mindustry.editor;
|
package mindustry.editor;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.func.*;
|
||||||
|
import arc.scene.event.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.game.MapObjectives.*;
|
import mindustry.game.MapObjectives.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class MapObjectivesDialog extends BaseDialog{
|
public class MapObjectivesDialog extends BaseDialog{
|
||||||
private Seq<MapObjective> objectives = new Seq<>();
|
private Seq<MapObjective> objectives = new Seq<>();
|
||||||
|
private @Nullable MapObjective selectedObjective;
|
||||||
|
private Table list = new Table();
|
||||||
|
|
||||||
public MapObjectivesDialog(){
|
public MapObjectivesDialog(){
|
||||||
super("@editor.objectives");
|
super("@editor.objectives");
|
||||||
|
|
||||||
buttons.defaults().size(180f, 64f).pad(2f);
|
buttons.defaults().size(170f, 64f).pad(2f);
|
||||||
buttons.button("@back", Icon.left, this::hide);
|
buttons.button("@back", Icon.left, this::hide);
|
||||||
|
|
||||||
buttons.button("@edit", Icon.edit, () -> {
|
buttons.button("@edit", Icon.edit, () -> {
|
||||||
@ -54,17 +68,247 @@ public class MapObjectivesDialog extends BaseDialog{
|
|||||||
dialog.addCloseButton();
|
dialog.addCloseButton();
|
||||||
dialog.show();
|
dialog.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
buttons.button("@add", Icon.add, () -> {
|
||||||
|
var selection = new BaseDialog("@add");
|
||||||
|
selection.cont.pane(p -> {
|
||||||
|
p.background(Tex.button);
|
||||||
|
p.marginRight(14);
|
||||||
|
p.defaults().size(195f, 56f);
|
||||||
|
int i = 0;
|
||||||
|
for(var gen : MapObjectives.allObjectiveTypes){
|
||||||
|
var objective = gen.get();
|
||||||
|
|
||||||
|
p.button(objective.typeName(), Styles.flatt, () -> {
|
||||||
|
objectives.add(objective);
|
||||||
|
setup();
|
||||||
|
selection.hide();
|
||||||
|
}).with(Table::left).get().getLabelCell().growX().left().padLeft(5).labelAlign(Align.left);
|
||||||
|
|
||||||
|
if(++i % 3 == 0) p.row();
|
||||||
|
}
|
||||||
|
}).scrollX(false);
|
||||||
|
|
||||||
|
selection.addCloseButton();
|
||||||
|
selection.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
cont.clear();
|
||||||
|
cont.pane(t -> {
|
||||||
|
list = t;
|
||||||
|
list.top();
|
||||||
|
}).grow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(Seq<MapObjective> objectives){
|
public void show(Seq<MapObjective> objectives){
|
||||||
super.show();
|
super.show();
|
||||||
|
selectedObjective = null;
|
||||||
|
|
||||||
this.objectives = objectives;
|
this.objectives = objectives;
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
cont.clear();
|
list.clear();
|
||||||
cont.add("This editor doesn't work yet. Come back later.");
|
|
||||||
|
for(var objective : objectives){
|
||||||
|
list.table(Tex.button, t -> {
|
||||||
|
t.margin(0);
|
||||||
|
|
||||||
|
t.button(b -> {
|
||||||
|
b.left();
|
||||||
|
b.add(objective.typeName()).color(Pal.accent);
|
||||||
|
|
||||||
|
b.add().growX();
|
||||||
|
|
||||||
|
b.button(Icon.upOpen, Styles.emptyi, () -> {
|
||||||
|
int index = objectives.indexOf(objective);
|
||||||
|
if(index > 0){
|
||||||
|
objectives.swap(index, index - 1);
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
}).pad(-6).size(46f);
|
||||||
|
|
||||||
|
b.button(Icon.downOpen, Styles.emptyi, () -> {
|
||||||
|
int index = objectives.indexOf(objective);
|
||||||
|
if(index < objectives.size - 1){
|
||||||
|
objectives.swap(index, index + 1);
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
}).pad(-6).size(46f);
|
||||||
|
|
||||||
|
b.button(Icon.cancel, Styles.emptyi, () -> {
|
||||||
|
objectives.remove(objective);
|
||||||
|
list.getCell(t).pad(0f);
|
||||||
|
|
||||||
|
t.remove();
|
||||||
|
setup();
|
||||||
|
}).pad(-6).size(46f).padRight(-12f);
|
||||||
|
}, () -> {
|
||||||
|
if(selectedObjective != objective){
|
||||||
|
selectedObjective = objective;
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
}).growX().height(46f).pad(-6f).padBottom(0f).row();
|
||||||
|
|
||||||
|
if(selectedObjective == objective){
|
||||||
|
t.table(f -> {
|
||||||
|
f.left();
|
||||||
|
f.margin(10f);
|
||||||
|
|
||||||
|
f.defaults().minHeight(40f).left();
|
||||||
|
|
||||||
|
var fields = objective.getClass().getFields();
|
||||||
|
|
||||||
|
for(var field : fields){
|
||||||
|
if((field.getModifiers() & Modifier.PUBLIC) == 0) continue;
|
||||||
|
|
||||||
|
f.add(field.getName() + ": ");
|
||||||
|
|
||||||
|
var type = field.getType();
|
||||||
|
|
||||||
|
if(type == String.class){
|
||||||
|
f.field(Reflect.get(objective, field), text -> {
|
||||||
|
Reflect.set(objective, field, text);
|
||||||
|
});
|
||||||
|
}else if(type == int.class){
|
||||||
|
f.field(Reflect.<Integer>get(objective, field) + "", text -> {
|
||||||
|
if(Strings.canParseInt(text)){
|
||||||
|
Reflect.set(objective, field, Strings.parseInt(text));
|
||||||
|
}
|
||||||
|
}).valid(Strings::canParseInt);
|
||||||
|
}else if(type == float.class){
|
||||||
|
f.field(Reflect.<Float>get(objective, field) + "", text -> {
|
||||||
|
if(Strings.canParsePositiveFloat(text)){
|
||||||
|
Reflect.set(objective, field, Strings.parseFloat(text));
|
||||||
|
}
|
||||||
|
}).valid(Strings::canParseFloat);
|
||||||
|
}else if(type == UnlockableContent.class){
|
||||||
|
|
||||||
|
f.button(b -> b.image(Reflect.<UnlockableContent>get(objective, field).uiIcon).size(iconSmall), () -> {
|
||||||
|
showContentSelect(null, result -> {
|
||||||
|
Reflect.set(objective, field, result);
|
||||||
|
setup();
|
||||||
|
}, b -> b.techNode != null);
|
||||||
|
}).pad(4);
|
||||||
|
|
||||||
|
}else if(type == Block.class){
|
||||||
|
f.button(b -> b.image(Reflect.<Block>get(objective, field).uiIcon).size(iconSmall), () -> {
|
||||||
|
showContentSelect(ContentType.block, result -> {
|
||||||
|
Reflect.set(objective, field, result);
|
||||||
|
setup();
|
||||||
|
}, b -> ((Block)b).synthetic());
|
||||||
|
}).pad(4);
|
||||||
|
}else if(type == Team.class){ //TODO list of flags
|
||||||
|
f.button(b -> b.image(Tex.whiteui).color(Reflect.<Team>get(objective, field).color).size(iconSmall), () -> {
|
||||||
|
showTeamSelect(result -> {
|
||||||
|
Reflect.set(objective, field, result);
|
||||||
|
setup();
|
||||||
|
});
|
||||||
|
}).pad(4);
|
||||||
|
}else if(type == String[].class){ //TODO list of flags
|
||||||
|
|
||||||
|
Table strings = new Table();
|
||||||
|
strings.marginLeft(20f);
|
||||||
|
Runnable[] rebuild = {null};
|
||||||
|
|
||||||
|
strings.left();
|
||||||
|
|
||||||
|
float h = 40f;
|
||||||
|
|
||||||
|
rebuild[0] = () -> {
|
||||||
|
strings.clear();
|
||||||
|
strings.left().defaults().padBottom(3f).padTop(3f);
|
||||||
|
String[] array = Reflect.get(objective, field);
|
||||||
|
|
||||||
|
for(int i = 0; i < array.length; i ++){
|
||||||
|
int fi = i;
|
||||||
|
var str = array[i];
|
||||||
|
strings.field(str, result -> {
|
||||||
|
array[fi] = result;
|
||||||
|
}).maxTextLength(20).height(h);
|
||||||
|
|
||||||
|
strings.button(Icon.cancel, Styles.squarei, () -> {
|
||||||
|
|
||||||
|
String[] next = new String[array.length - 1];
|
||||||
|
System.arraycopy(array, 0, next, 0, fi);
|
||||||
|
if(fi < array.length - 1){
|
||||||
|
System.arraycopy(array, fi + 1, next, fi, array.length - 1 - fi);
|
||||||
|
}
|
||||||
|
Reflect.set(objective, field, next);
|
||||||
|
|
||||||
|
rebuild[0].run();
|
||||||
|
}).padLeft(4).size(h);
|
||||||
|
|
||||||
|
strings.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
strings.button("+ Add", () -> {
|
||||||
|
String[] next = new String[array.length + 1];
|
||||||
|
next[array.length] = "";
|
||||||
|
System.arraycopy(array, 0, next, 0, array.length);
|
||||||
|
Reflect.set(objective, field, next);
|
||||||
|
|
||||||
|
rebuild[0].run();
|
||||||
|
}).height(h).width(140f).padLeft(-20f).left().row();
|
||||||
|
};
|
||||||
|
|
||||||
|
rebuild[0].run();
|
||||||
|
|
||||||
|
f.row();
|
||||||
|
f.add(strings).colspan(2).fill();
|
||||||
|
|
||||||
|
}else{
|
||||||
|
f.add("[red]UNFINISHED");
|
||||||
|
}
|
||||||
|
|
||||||
|
f.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).grow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).width(340f).pad(8f).row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showContentSelect(@Nullable ContentType type, Cons<UnlockableContent> cons, Boolf<UnlockableContent> check){
|
||||||
|
BaseDialog dialog = new BaseDialog("");
|
||||||
|
dialog.cont.pane(p -> {
|
||||||
|
int i = 0;
|
||||||
|
for(var block : (type == null ? Vars.content.blocks().copy().<UnlockableContent>as()
|
||||||
|
.add(Vars.content.items())
|
||||||
|
.add(Vars.content.liquids())
|
||||||
|
.add(Vars.content.units()) :
|
||||||
|
Vars.content.getBy(type).<UnlockableContent>as())){
|
||||||
|
|
||||||
|
if(!check.get(block)) continue;
|
||||||
|
|
||||||
|
p.image(block == Blocks.air ? Icon.none.getRegion() : block.uiIcon).size(iconMed).pad(3).with(b -> b.addListener(new HandCursorListener()))
|
||||||
|
.tooltip(block.localizedName).get().clicked(() -> {
|
||||||
|
cons.get(block);
|
||||||
|
dialog.hide();
|
||||||
|
});
|
||||||
|
if(++i % 10 == 0) p.row();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.closeOnBack();
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showTeamSelect(Cons<Team> cons){
|
||||||
|
BaseDialog dialog = new BaseDialog("");
|
||||||
|
for(var team : Team.baseTeams){
|
||||||
|
|
||||||
|
dialog.cont.image(Tex.whiteui).size(iconMed).color(team.color).pad(4).with(i -> i.addListener(new HandCursorListener()))
|
||||||
|
.tooltip(team.localized()).get().clicked(() -> {
|
||||||
|
cons.get(team);
|
||||||
|
dialog.hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.closeOnBack();
|
||||||
|
dialog.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import mindustry.graphics.*;
|
|||||||
|
|
||||||
/** A continuous bullet type that only damages in a point. */
|
/** A continuous bullet type that only damages in a point. */
|
||||||
public class PointLaserBulletType extends BulletType{
|
public class PointLaserBulletType extends BulletType{
|
||||||
public String sprite = "drill-laser";
|
public String sprite = "point-laser";
|
||||||
public TextureRegion laser, laserEnd;
|
public TextureRegion laser, laserEnd;
|
||||||
|
|
||||||
public Color color = Color.white;
|
public Color color = Color.white;
|
||||||
|
@ -365,10 +365,15 @@ public class MapObjectives{
|
|||||||
|
|
||||||
/** Base abstract class for any in-map objective. */
|
/** Base abstract class for any in-map objective. */
|
||||||
public static abstract class MapObjective{
|
public static abstract class MapObjective{
|
||||||
|
public @Nullable String details;
|
||||||
public String[] flagsAdded = {};
|
public String[] flagsAdded = {};
|
||||||
public String[] flagsRemoved = {};
|
public String[] flagsRemoved = {};
|
||||||
public ObjectiveMarker[] markers = {};
|
public ObjectiveMarker[] markers = {};
|
||||||
public @Nullable String details;
|
|
||||||
|
//TODO localize
|
||||||
|
public String typeName(){
|
||||||
|
return getClass().getSimpleName().replace("Objective", "");
|
||||||
|
}
|
||||||
|
|
||||||
public MapObjective withFlags(String... flags){
|
public MapObjective withFlags(String... flags){
|
||||||
this.flagsAdded = flags;
|
this.flagsAdded = flags;
|
||||||
|
Reference in New Issue
Block a user