From bd274f804a95e1576689f1e58a5e3d98bb456edf Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 27 Jun 2020 23:04:38 -0400 Subject: [PATCH] Loadout selection + custom loadout schematics --- core/src/mindustry/Vars.java | 2 + core/src/mindustry/content/Loadouts.java | 2 - core/src/mindustry/core/Control.java | 5 +- core/src/mindustry/game/Schematics.java | 27 +++++++++ core/src/mindustry/game/Universe.java | 27 +++++++++ .../maps/generators/FileMapGenerator.java | 3 +- .../maps/planet/TODOPlanetGenerator.java | 3 +- .../ui/dialogs/LaunchLoadoutDialog.java | 56 +++++++++++++++++++ .../mindustry/ui/dialogs/PlanetDialog.java | 16 ++++-- .../ui/dialogs/SchematicsDialog.java | 4 +- .../mindustry/world/modules/ItemModule.java | 7 +++ 11 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index 24c444c0cb..39691d48d6 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -36,6 +36,8 @@ public class Vars implements Loadable{ public static boolean loadLocales = true; /** Whether the logger is loaded. */ public static boolean loadedLogger = false, loadedFileLogger = false; + /** Maximum extra padding around deployment schematics. */ + public static final int maxLoadoutSchematicPad = 4; /** Maximum schematic size.*/ public static final int maxSchematicSize = 32; /** All schematic base64 starts with this string.*/ diff --git a/core/src/mindustry/content/Loadouts.java b/core/src/mindustry/content/Loadouts.java index 145da6120e..2a7c4435db 100644 --- a/core/src/mindustry/content/Loadouts.java +++ b/core/src/mindustry/content/Loadouts.java @@ -6,14 +6,12 @@ import mindustry.game.*; public class Loadouts implements ContentList{ public static Schematic basicShard, - advancedShard, basicFoundation, basicNucleus; @Override public void load(){ basicShard = Schematics.readBase64("bXNjaAB4nD2K2wqAIBiD5ymibnoRn6YnEP1BwUMoBL19FuJ2sbFvUFgYZDaJsLeQrkinN9UJHImsNzlYE7WrIUastuSbnlKx2VJJt+8IQGGKdfO/8J5yrGJSMegLg+YUIA=="); - advancedShard = Schematics.readBase64("bXNjaAB4nD2LjQqAIAyET7OMIOhFfJqeYMxBgSkYCL199gu33fFtB4tOwUTaBCP5QpHFzwtl32DahBeKK1NwPq8hoOcUixwpY+CUxe3XIwBbB/pa6tadVCUP02hgHvp5vZq/0b7pBHPYFOQ="); basicFoundation = Schematics.readBase64("bXNjaAB4nD1OSQ6DMBBzFhVu8BG+0X8MQyoiJTNSukj8nlCi2Adbtg/GA4OBF8oB00rvyE/9ykafqOIw58A7SWRKy1ZiShhZ5RcOLZhYS1hefQ1gRIeptH9jq/qW2lvc1d2tgWsOfVX/tOwE86AYBA=="); basicNucleus = Schematics.readBase64("bXNjaAB4nD2MUQqAIBBEJy0s6qOLdJXuYNtCgikYBd2+LNmdj308hkGHtkId7M4YFns4mk/yfB4a48602eDI+mlNznu0FMPFd0wYKCaewl8F0EOueqM+yKSLVfJrNKWnSw/FZGzEGXFG9sy/px4gEBW1"); } diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index cc9937f670..c85b6f1e85 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -43,7 +43,7 @@ import static mindustry.Vars.*; */ public class Control implements ApplicationListener, Loadable{ public Saves saves; - public mindustry.audio.MusicControl music; + public MusicControl music; public Tutorial tutorial; public InputHandler input; @@ -265,6 +265,7 @@ public class Control implements ApplicationListener, Loadable{ state.rules.sector = sector; //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()){ //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()); //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 player.set(spawn.x * tilesize, spawn.y * tilesize); diff --git a/core/src/mindustry/game/Schematics.java b/core/src/mindustry/game/Schematics.java index c79792728a..400e01a3c7 100644 --- a/core/src/mindustry/game/Schematics.java +++ b/core/src/mindustry/game/Schematics.java @@ -55,6 +55,7 @@ public class Schematics implements Loadable{ private Seq all = new Seq<>(); private OrderedMap previews = new OrderedMap<>(); private ObjectSet errored = new ObjectSet<>(); + private ObjectMap> loadouts = new ObjectMap<>(); private FrameBuffer shadowBuffer; private Texture errorTexture; private long lastClearTime; @@ -85,6 +86,8 @@ public class Schematics implements Loadable{ public void load(){ all.clear(); + loadLoadouts(); + for(Fi file : schematicDirectory.list()){ loadFile(file); } @@ -109,6 +112,10 @@ public class Schematics implements Loadable{ 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){ if(previews.containsKey(target)){ previews.get(target).dispose(); @@ -136,6 +143,7 @@ public class Schematics implements Loadable{ try{ Schematic s = read(file); all.add(s); + checkLoadout(s, true); //external file from workshop if(!s.file.parent().equals(schematicDirectory)){ @@ -275,6 +283,22 @@ public class Schematics implements Loadable{ .removeAll(s -> !s.block.isVisible() || !s.block.unlockedNow()); } + /** @return all the valid loadouts for a specific core type. */ + public Seq 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.*/ public void add(Schematic schematic){ all.add(schematic); @@ -286,11 +310,14 @@ public class Schematics implements Loadable{ ui.showException(e); Log.err(e); } + + checkLoadout(schematic, true); all.sort(); } public void remove(Schematic s){ all.remove(s); + loadouts.each((block, seq) -> seq.remove(s)); if(s.file != null){ s.file.delete(); } diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index 7cf7786382..8a6c11b310 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -10,6 +10,7 @@ import mindustry.game.EventType.*; import mindustry.game.SectorInfo.*; import mindustry.io.*; import mindustry.type.*; +import mindustry.world.blocks.storage.*; import static mindustry.Vars.*; @@ -19,6 +20,7 @@ public class Universe{ private float secondCounter; private int turn; private float turnCounter; + private Schematic lastLoadout = Loadouts.basicShard; public Universe(){ 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 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(){ int[] exports = new int[Vars.content.items().size]; diff --git a/core/src/mindustry/maps/generators/FileMapGenerator.java b/core/src/mindustry/maps/generators/FileMapGenerator.java index 72daf1aec5..395f8130e5 100644 --- a/core/src/mindustry/maps/generators/FileMapGenerator.java +++ b/core/src/mindustry/maps/generators/FileMapGenerator.java @@ -54,8 +54,7 @@ public class FileMapGenerator implements WorldGenerator{ } if(tile.isCenter() && tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam && !anyCores){ - //TODO PLACE THE (CORRECT) LOADOUT - Schematics.placeLoadout(Loadouts.basicShard, tile.x, tile.y); + Schematics.placeLoadout(universe.getLastLoadout(), tile.x, tile.y); anyCores = true; } diff --git a/core/src/mindustry/maps/planet/TODOPlanetGenerator.java b/core/src/mindustry/maps/planet/TODOPlanetGenerator.java index 35cdb3cc88..f1b5c47f81 100644 --- a/core/src/mindustry/maps/planet/TODOPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/TODOPlanetGenerator.java @@ -279,8 +279,7 @@ public class TODOPlanetGenerator extends PlanetGenerator{ } }); - //TODO PLACE CORRECT LOADOUT - Schematics.placeLoadout(Loadouts.advancedShard, spawn.x, spawn.y); + Schematics.placeLoadout(universe.getLastLoadout(), spawn.x, spawn.y); 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); diff --git a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java new file mode 100644 index 0000000000..859b8a00ca --- /dev/null +++ b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java @@ -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