Loadout selection + custom loadout schematics
This commit is contained in:
@@ -36,6 +36,8 @@ public class Vars implements Loadable{
|
|||||||
public static boolean loadLocales = true;
|
public static boolean loadLocales = true;
|
||||||
/** Whether the logger is loaded. */
|
/** Whether the logger is loaded. */
|
||||||
public static boolean loadedLogger = false, loadedFileLogger = false;
|
public static boolean loadedLogger = false, loadedFileLogger = false;
|
||||||
|
/** Maximum extra padding around deployment schematics. */
|
||||||
|
public static final int maxLoadoutSchematicPad = 4;
|
||||||
/** Maximum schematic size.*/
|
/** Maximum schematic size.*/
|
||||||
public static final int maxSchematicSize = 32;
|
public static final int maxSchematicSize = 32;
|
||||||
/** All schematic base64 starts with this string.*/
|
/** All schematic base64 starts with this string.*/
|
||||||
|
|||||||
@@ -6,14 +6,12 @@ import mindustry.game.*;
|
|||||||
public class Loadouts implements ContentList{
|
public class Loadouts implements ContentList{
|
||||||
public static Schematic
|
public static Schematic
|
||||||
basicShard,
|
basicShard,
|
||||||
advancedShard,
|
|
||||||
basicFoundation,
|
basicFoundation,
|
||||||
basicNucleus;
|
basicNucleus;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
basicShard = Schematics.readBase64("bXNjaAB4nD2K2wqAIBiD5ymibnoRn6YnEP1BwUMoBL19FuJ2sbFvUFgYZDaJsLeQrkinN9UJHImsNzlYE7WrIUastuSbnlKx2VJJt+8IQGGKdfO/8J5yrGJSMegLg+YUIA==");
|
basicShard = Schematics.readBase64("bXNjaAB4nD2K2wqAIBiD5ymibnoRn6YnEP1BwUMoBL19FuJ2sbFvUFgYZDaJsLeQrkinN9UJHImsNzlYE7WrIUastuSbnlKx2VJJt+8IQGGKdfO/8J5yrGJSMegLg+YUIA==");
|
||||||
advancedShard = Schematics.readBase64("bXNjaAB4nD2LjQqAIAyET7OMIOhFfJqeYMxBgSkYCL199gu33fFtB4tOwUTaBCP5QpHFzwtl32DahBeKK1NwPq8hoOcUixwpY+CUxe3XIwBbB/pa6tadVCUP02hgHvp5vZq/0b7pBHPYFOQ=");
|
|
||||||
basicFoundation = Schematics.readBase64("bXNjaAB4nD1OSQ6DMBBzFhVu8BG+0X8MQyoiJTNSukj8nlCi2Adbtg/GA4OBF8oB00rvyE/9ykafqOIw58A7SWRKy1ZiShhZ5RcOLZhYS1hefQ1gRIeptH9jq/qW2lvc1d2tgWsOfVX/tOwE86AYBA==");
|
basicFoundation = Schematics.readBase64("bXNjaAB4nD1OSQ6DMBBzFhVu8BG+0X8MQyoiJTNSukj8nlCi2Adbtg/GA4OBF8oB00rvyE/9ykafqOIw58A7SWRKy1ZiShhZ5RcOLZhYS1hefQ1gRIeptH9jq/qW2lvc1d2tgWsOfVX/tOwE86AYBA==");
|
||||||
basicNucleus = Schematics.readBase64("bXNjaAB4nD2MUQqAIBBEJy0s6qOLdJXuYNtCgikYBd2+LNmdj308hkGHtkId7M4YFns4mk/yfB4a48602eDI+mlNznu0FMPFd0wYKCaewl8F0EOueqM+yKSLVfJrNKWnSw/FZGzEGXFG9sy/px4gEBW1");
|
basicNucleus = Schematics.readBase64("bXNjaAB4nD2MUQqAIBBEJy0s6qOLdJXuYNtCgikYBd2+LNmdj308hkGHtkId7M4YFns4mk/yfB4a48602eDI+mlNznu0FMPFd0wYKCaewl8F0EOueqM+yKSLVfJrNKWnSw/FZGzEGXFG9sy/px4gEBW1");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import static mindustry.Vars.*;
|
|||||||
*/
|
*/
|
||||||
public class Control implements ApplicationListener, Loadable{
|
public class Control implements ApplicationListener, Loadable{
|
||||||
public Saves saves;
|
public Saves saves;
|
||||||
public mindustry.audio.MusicControl music;
|
public MusicControl music;
|
||||||
public Tutorial tutorial;
|
public Tutorial tutorial;
|
||||||
public InputHandler input;
|
public InputHandler input;
|
||||||
|
|
||||||
@@ -265,6 +265,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
|
|
||||||
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
||||||
|
//TODO this is broken?
|
||||||
if(state.rules.defaultTeam.cores().isEmpty()){
|
if(state.rules.defaultTeam.cores().isEmpty()){
|
||||||
|
|
||||||
//kill all friendly units, since they should be dead anwyay
|
//kill all friendly units, since they should be dead anwyay
|
||||||
@@ -276,7 +277,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
Tile spawn = world.tile(sector.getSpawnPosition());
|
Tile spawn = world.tile(sector.getSpawnPosition());
|
||||||
//TODO PLACE CORRECT LOADOUT
|
//TODO PLACE CORRECT LOADOUT
|
||||||
Schematics.placeLoadout(Loadouts.advancedShard, spawn.x, spawn.y);
|
Schematics.placeLoadout(universe.getLastLoadout(), spawn.x, spawn.y);
|
||||||
|
|
||||||
//set up camera/player locations
|
//set up camera/player locations
|
||||||
player.set(spawn.x * tilesize, spawn.y * tilesize);
|
player.set(spawn.x * tilesize, spawn.y * tilesize);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ public class Schematics implements Loadable{
|
|||||||
private Seq<Schematic> all = new Seq<>();
|
private Seq<Schematic> all = new Seq<>();
|
||||||
private OrderedMap<Schematic, FrameBuffer> previews = new OrderedMap<>();
|
private OrderedMap<Schematic, FrameBuffer> previews = new OrderedMap<>();
|
||||||
private ObjectSet<Schematic> errored = new ObjectSet<>();
|
private ObjectSet<Schematic> errored = new ObjectSet<>();
|
||||||
|
private ObjectMap<CoreBlock, Seq<Schematic>> loadouts = new ObjectMap<>();
|
||||||
private FrameBuffer shadowBuffer;
|
private FrameBuffer shadowBuffer;
|
||||||
private Texture errorTexture;
|
private Texture errorTexture;
|
||||||
private long lastClearTime;
|
private long lastClearTime;
|
||||||
@@ -85,6 +86,8 @@ public class Schematics implements Loadable{
|
|||||||
public void load(){
|
public void load(){
|
||||||
all.clear();
|
all.clear();
|
||||||
|
|
||||||
|
loadLoadouts();
|
||||||
|
|
||||||
for(Fi file : schematicDirectory.list()){
|
for(Fi file : schematicDirectory.list()){
|
||||||
loadFile(file);
|
loadFile(file);
|
||||||
}
|
}
|
||||||
@@ -109,6 +112,10 @@ public class Schematics implements Loadable{
|
|||||||
bases.load();
|
bases.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadLoadouts(){
|
||||||
|
Seq.with(Loadouts.basicShard, Loadouts.basicFoundation, Loadouts.basicNucleus).each(s -> checkLoadout(s,false));
|
||||||
|
}
|
||||||
|
|
||||||
public void overwrite(Schematic target, Schematic newSchematic){
|
public void overwrite(Schematic target, Schematic newSchematic){
|
||||||
if(previews.containsKey(target)){
|
if(previews.containsKey(target)){
|
||||||
previews.get(target).dispose();
|
previews.get(target).dispose();
|
||||||
@@ -136,6 +143,7 @@ public class Schematics implements Loadable{
|
|||||||
try{
|
try{
|
||||||
Schematic s = read(file);
|
Schematic s = read(file);
|
||||||
all.add(s);
|
all.add(s);
|
||||||
|
checkLoadout(s, true);
|
||||||
|
|
||||||
//external file from workshop
|
//external file from workshop
|
||||||
if(!s.file.parent().equals(schematicDirectory)){
|
if(!s.file.parent().equals(schematicDirectory)){
|
||||||
@@ -275,6 +283,22 @@ public class Schematics implements Loadable{
|
|||||||
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedNow());
|
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedNow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return all the valid loadouts for a specific core type. */
|
||||||
|
public Seq<Schematic> getLoadouts(CoreBlock block){
|
||||||
|
return loadouts.get(block, Seq::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks a schematic for deployment validity and adds it to the cache. */
|
||||||
|
private void checkLoadout(Schematic s, boolean validate){
|
||||||
|
Stile core = s.tiles.find(t -> t.block instanceof CoreBlock);
|
||||||
|
|
||||||
|
//make sure a core exists, and that the schematic is small enough.
|
||||||
|
if(core == null || (validate && (s.width > core.block.size + maxLoadoutSchematicPad *2 || s.height > core.block.size + maxLoadoutSchematicPad *2))) return;
|
||||||
|
|
||||||
|
//place in the cache
|
||||||
|
loadouts.get((CoreBlock)core.block, Seq::new).add(s);
|
||||||
|
}
|
||||||
|
|
||||||
/** Adds a schematic to the list, also copying it into the files.*/
|
/** Adds a schematic to the list, also copying it into the files.*/
|
||||||
public void add(Schematic schematic){
|
public void add(Schematic schematic){
|
||||||
all.add(schematic);
|
all.add(schematic);
|
||||||
@@ -286,11 +310,14 @@ public class Schematics implements Loadable{
|
|||||||
ui.showException(e);
|
ui.showException(e);
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkLoadout(schematic, true);
|
||||||
all.sort();
|
all.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(Schematic s){
|
public void remove(Schematic s){
|
||||||
all.remove(s);
|
all.remove(s);
|
||||||
|
loadouts.each((block, seq) -> seq.remove(s));
|
||||||
if(s.file != null){
|
if(s.file != null){
|
||||||
s.file.delete();
|
s.file.delete();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import mindustry.game.EventType.*;
|
|||||||
import mindustry.game.SectorInfo.*;
|
import mindustry.game.SectorInfo.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ public class Universe{
|
|||||||
private float secondCounter;
|
private float secondCounter;
|
||||||
private int turn;
|
private int turn;
|
||||||
private float turnCounter;
|
private float turnCounter;
|
||||||
|
private Schematic lastLoadout = Loadouts.basicShard;
|
||||||
|
|
||||||
public Universe(){
|
public Universe(){
|
||||||
load();
|
load();
|
||||||
@@ -73,6 +75,31 @@ public class Universe{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Updates selected loadout for future deployment. */
|
||||||
|
public void updateLoadout(CoreBlock block, Schematic schem){
|
||||||
|
Core.settings.put("lastloadout-" + block.name, schem.file == null ? "" : schem.file.nameWithoutExtension());
|
||||||
|
lastLoadout = schem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Schematic getLastLoadout(){
|
||||||
|
return lastLoadout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return the last selected loadout for this specific core type. */
|
||||||
|
public Schematic getLoadout(CoreBlock core){
|
||||||
|
//for tools - schem
|
||||||
|
if(schematics == null) return Loadouts.basicShard;
|
||||||
|
|
||||||
|
//find last used loadout file name
|
||||||
|
String file = Core.settings.getString("lastloadout-" + core.name, "");
|
||||||
|
|
||||||
|
//use default (first) schematic if not found
|
||||||
|
Seq<Schematic> all = schematics.getLoadouts(core);
|
||||||
|
Schematic schem = all.find(s -> s.file != null && s.file.nameWithoutExtension().equals(file));
|
||||||
|
|
||||||
|
return schem == null ? all.first() : schem;
|
||||||
|
}
|
||||||
|
|
||||||
public int[] getTotalExports(){
|
public int[] getTotalExports(){
|
||||||
int[] exports = new int[Vars.content.items().size];
|
int[] exports = new int[Vars.content.items().size];
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ public class FileMapGenerator implements WorldGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(tile.isCenter() && tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam && !anyCores){
|
if(tile.isCenter() && tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam && !anyCores){
|
||||||
//TODO PLACE THE (CORRECT) LOADOUT
|
Schematics.placeLoadout(universe.getLastLoadout(), tile.x, tile.y);
|
||||||
Schematics.placeLoadout(Loadouts.basicShard, tile.x, tile.y);
|
|
||||||
anyCores = true;
|
anyCores = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -279,8 +279,7 @@ public class TODOPlanetGenerator extends PlanetGenerator{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO PLACE CORRECT LOADOUT
|
Schematics.placeLoadout(universe.getLastLoadout(), spawn.x, spawn.y);
|
||||||
Schematics.placeLoadout(Loadouts.advancedShard, spawn.x, spawn.y);
|
|
||||||
|
|
||||||
if(sector.hasEnemyBase()){
|
if(sector.hasEnemyBase()){
|
||||||
basegen.generate(tiles, enemies.map(r -> tiles.getn(r.x, r.y)), tiles.get(spawn.x, spawn.y), state.rules.waveTeam, sector);
|
basegen.generate(tiles, enemies.map(r -> tiles.getn(r.x, r.y)), tiles.get(spawn.x, spawn.y), state.rules.waveTeam, sector);
|
||||||
|
|||||||
56
core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java
Normal file
56
core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.scene.ui.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
|
import mindustry.game.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
|
import mindustry.ui.dialogs.SchematicsDialog.*;
|
||||||
|
import mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
/** Dialog for selecting loadout at sector launch. */
|
||||||
|
public class LaunchLoadoutDialog extends BaseDialog{
|
||||||
|
Schematic selected;
|
||||||
|
|
||||||
|
public LaunchLoadoutDialog(){
|
||||||
|
super("$configure");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(CoreBlock core, Building build, Runnable confirm){
|
||||||
|
cont.clear();
|
||||||
|
buttons.clear();
|
||||||
|
|
||||||
|
addCloseButton();
|
||||||
|
buttons.button("$ok", () -> {
|
||||||
|
universe.updateLoadout(core, selected);
|
||||||
|
confirm.run();
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
int cols = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1);
|
||||||
|
ButtonGroup<Button> group = new ButtonGroup<>();
|
||||||
|
selected = universe.getLoadout(core);
|
||||||
|
|
||||||
|
cont.pane(t -> {
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for(Schematic s : schematics.getLoadouts(core)){
|
||||||
|
|
||||||
|
t.button(b -> b.add(new SchematicImage(s)), Styles.togglet, () -> selected = s)
|
||||||
|
.group(group).pad(4).disabled(!build.items.has(s.requirements())).checked(s == selected).size(200f);
|
||||||
|
|
||||||
|
if(++i % cols == 0){
|
||||||
|
t.row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).growX().get().setScrollingDisabled(true, false);
|
||||||
|
|
||||||
|
//TODO configure items to launch with
|
||||||
|
|
||||||
|
show();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ import static mindustry.ui.dialogs.PlanetDialog.Mode.*;
|
|||||||
public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||||
private final FrameBuffer buffer = new FrameBuffer(2, 2, true);
|
private final FrameBuffer buffer = new FrameBuffer(2, 2, true);
|
||||||
private final PlanetRenderer planets = renderer.planets;
|
private final PlanetRenderer planets = renderer.planets;
|
||||||
|
private final LaunchLoadoutDialog loadouts = new LaunchLoadoutDialog();
|
||||||
private final Table stable = new Table().background(Styles.black3);
|
private final Table stable = new Table().background(Styles.black3);
|
||||||
|
|
||||||
private int launchRange;
|
private int launchRange;
|
||||||
@@ -331,7 +332,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hide();
|
boolean shouldHide = true;
|
||||||
|
|
||||||
//save before launch.
|
//save before launch.
|
||||||
if(control.saves.getCurrent() != null && state.isGame()){
|
if(control.saves.getCurrent() != null && state.isGame()){
|
||||||
@@ -344,14 +345,19 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(mode == launch){
|
if(mode == launch){
|
||||||
control.handleLaunch(launcher);
|
shouldHide = false;
|
||||||
zoom = 0.5f;
|
loadouts.show((CoreBlock)launcher.block, launcher, () -> {
|
||||||
|
control.handleLaunch(launcher);
|
||||||
|
zoom = 0.5f;
|
||||||
|
|
||||||
ui.hudfrag.showLaunchDirect();
|
ui.hudfrag.showLaunchDirect();
|
||||||
Time.runTask(launchDuration, () -> control.playSector(sector));
|
Time.runTask(launchDuration, () -> control.playSector(sector));
|
||||||
|
});
|
||||||
}else{
|
}else{
|
||||||
control.playSector(sector);
|
control.playSector(sector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(shouldHide) hide();
|
||||||
}).growX().padTop(2f).height(50f).minWidth(170f);
|
}).growX().padTop(2f).height(50f).minWidth(170f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class SchematicsDialog extends BaseDialog{
|
|||||||
});
|
});
|
||||||
|
|
||||||
rebuildPane[0] = () -> {
|
rebuildPane[0] = () -> {
|
||||||
int maxwidth = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1);
|
int cols = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1);
|
||||||
|
|
||||||
t.clear();
|
t.clear();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -153,7 +153,7 @@ public class SchematicsDialog extends BaseDialog{
|
|||||||
|
|
||||||
sel[0].getStyle().up = Tex.pane;
|
sel[0].getStyle().up = Tex.pane;
|
||||||
|
|
||||||
if(++i % maxwidth == 0){
|
if(++i % cols == 0){
|
||||||
t.row();
|
t.row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,13 @@ public class ItemModule extends BlockModule{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean has(Iterable<ItemStack> stacks){
|
||||||
|
for(ItemStack stack : stacks){
|
||||||
|
if(!has(stack.item, stack.amount)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean has(ItemStack[] stacks, float multiplier){
|
public boolean has(ItemStack[] stacks, float multiplier){
|
||||||
for(ItemStack stack : stacks){
|
for(ItemStack stack : stacks){
|
||||||
if(!has(stack.item, Math.round(stack.amount * multiplier))) return false;
|
if(!has(stack.item, Math.round(stack.amount * multiplier))) return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user