From 6f146c6cade13d6a1332572538decb19c52a7d91 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 5 Dec 2019 21:15:28 -0500 Subject: [PATCH] Added support for mod map/schematic packs --- core/assets/bundles/bundle.properties | 1 + core/src/io/anuke/mindustry/game/Schematic.java | 5 ++++- core/src/io/anuke/mindustry/game/Schematics.java | 16 ++++++++++++++-- core/src/io/anuke/mindustry/maps/Map.java | 4 ++++ core/src/io/anuke/mindustry/maps/Maps.java | 11 +++++++++++ core/src/io/anuke/mindustry/mod/Mods.java | 12 ++++++++++++ .../anuke/mindustry/ui/dialogs/MapsDialog.java | 2 +- .../mindustry/ui/dialogs/SchematicsDialog.java | 12 ++++++++---- 8 files changed, 55 insertions(+), 8 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 26d75701c6..69ed270b04 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -107,6 +107,7 @@ mod.requiresrestart = The game will now close to apply the mod changes. mod.reloadrequired = [scarlet]Reload Required mod.import = Import Mod mod.import.github = Import GitHub Mod +mod.item.remove = This item is part of the[accent] '{0}'[] mod. To remove it, uninstall that mod. mod.remove.confirm = This mod will be deleted. mod.author = [LIGHT_GRAY]Author:[] {0} mod.missing = This save contains mods that you have recently updated or no longer have installed. Save corruption may occur. Are you sure you want to load it?\n[lightgray]Mods:\n{0} diff --git a/core/src/io/anuke/mindustry/game/Schematic.java b/core/src/io/anuke/mindustry/game/Schematic.java index 1ff6efd77c..4c83623602 100644 --- a/core/src/io/anuke/mindustry/game/Schematic.java +++ b/core/src/io/anuke/mindustry/game/Schematic.java @@ -5,6 +5,7 @@ import io.anuke.arc.collection.IntIntMap.*; import io.anuke.arc.files.*; import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.mindustry.*; +import io.anuke.mindustry.mod.Mods.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.blocks.storage.*; @@ -16,8 +17,10 @@ public class Schematic implements Publishable, Comparable{ public StringMap tags; public int width, height; public @Nullable FileHandle file; + /** Associated mod. If null, no mod is associated with this schematic. */ + public @Nullable LoadedMod mod; - public Schematic(Array tiles, StringMap tags, int width, int height){ + public Schematic(Array tiles, @NonNull StringMap tags, int width, int height){ this.tiles = tiles; this.tags = tags; this.width = width; diff --git a/core/src/io/anuke/mindustry/game/Schematics.java b/core/src/io/anuke/mindustry/game/Schematics.java index f6086b8b2e..078300bc52 100644 --- a/core/src/io/anuke/mindustry/game/Schematics.java +++ b/core/src/io/anuke/mindustry/game/Schematics.java @@ -8,6 +8,7 @@ import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.graphics.glutils.*; import io.anuke.arc.util.*; +import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.io.Streams.*; import io.anuke.arc.util.serialization.*; import io.anuke.mindustry.*; @@ -74,6 +75,14 @@ public class Schematics implements Loadable{ platform.getWorkshopContent(Schematic.class).each(this::loadFile); + //mod-specific schematics, cannot be removed + mods.listFiles("schematics", (mod, file) -> { + Schematic s = loadFile(file); + if(s != null){ + s.mod = mod; + } + }); + all.sort(); if(shadowBuffer == null){ @@ -102,8 +111,8 @@ public class Schematics implements Loadable{ } } - private void loadFile(FileHandle file){ - if(!file.extension().equals(schematicExtension)) return; + private @Nullable Schematic loadFile(FileHandle file){ + if(!file.extension().equals(schematicExtension)) return null; try{ Schematic s = read(file); @@ -113,9 +122,12 @@ public class Schematics implements Loadable{ if(!s.file.parent().equals(schematicDirectory)){ s.tags.put("steamid", s.file.parent().name()); } + + return s; }catch(IOException e){ Log.err(e); } + return null; } public Array all(){ diff --git a/core/src/io/anuke/mindustry/maps/Map.java b/core/src/io/anuke/mindustry/maps/Map.java index 4fb42f0a33..3bd66784c4 100644 --- a/core/src/io/anuke/mindustry/maps/Map.java +++ b/core/src/io/anuke/mindustry/maps/Map.java @@ -5,11 +5,13 @@ import io.anuke.arc.collection.*; import io.anuke.arc.files.*; import io.anuke.arc.graphics.*; import io.anuke.arc.util.*; +import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.mindustry.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.*; import io.anuke.mindustry.io.*; import io.anuke.mindustry.maps.filters.*; +import io.anuke.mindustry.mod.Mods.*; import io.anuke.mindustry.type.*; import static io.anuke.mindustry.Vars.*; @@ -35,6 +37,8 @@ public class Map implements Comparable, Publishable{ public IntSet teams = new IntSet(); /** Number of enemy spawns on this map.*/ public int spawns = 0; + /** Associated mod. If null, no mod is associated. */ + public @Nullable LoadedMod mod; public Map(FileHandle file, int width, int height, StringMap tags, boolean custom, int version, int build){ this.custom = custom; diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index b9f14a19ac..500932d6b6 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -138,6 +138,17 @@ public class Maps{ Log.err(e); } } + + //mod + mods.listFiles("maps", (mod, file) -> { + try{ + Map map = loadMap(file, false); + map.mod = mod; + }catch(Exception e){ + Log.err("Failed to load mod map file '{0}'!", file); + Log.err(e); + } + }); } public void reload(){ diff --git a/core/src/io/anuke/mindustry/mod/Mods.java b/core/src/io/anuke/mindustry/mod/Mods.java index 6188d5c954..2d1a731272 100644 --- a/core/src/io/anuke/mindustry/mod/Mods.java +++ b/core/src/io/anuke/mindustry/mod/Mods.java @@ -50,6 +50,18 @@ public class Mods implements Loadable{ return modDirectory.child(load.name).child("config.json"); } + /** Returns a list of files per mod subdirectory. */ + public void listFiles(String directory, Cons2 cons){ + for(LoadedMod mod : loaded){ + FileHandle file = mod.root.child(directory); + if(file.exists()){ + for(FileHandle child : file.list()){ + cons.get(mod, child); + } + } + } + } + /** @return the loaded mod found by class, or null if not found. */ public @Nullable LoadedMod getMod(Class type){ return loaded.find(l -> l.mod != null && l.mod.getClass() == type); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java index a2fb508fcb..0ae118d5d2 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java @@ -143,7 +143,7 @@ public class MapsDialog extends FloatingDialog{ button.row(); button.stack(new Image(map.safeTexture()).setScaling(Scaling.fit), new BorderImage(map.safeTexture()).setScaling(Scaling.fit)).size(mapsize - 20f); button.row(); - button.add(map.custom ? "$custom" : map.workshop ? "$workshop" : "$builtin").color(Color.gray).padTop(3); + button.add(map.custom ? "$custom" : map.workshop ? "$workshop" : map.mod != null ? "[lightgray]" + map.mod.meta.name : "$builtin").color(Color.gray).padTop(3); i++; } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java index e9c6cc18de..52f236fa81 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SchematicsDialog.java @@ -99,10 +99,14 @@ public class SchematicsDialog extends FloatingDialog{ buttons.addImageButton(Icon.linkSmall, style, () -> platform.viewListing(s)); }else{ buttons.addImageButton(Icon.trash16Small, style, () -> { - ui.showConfirm("$confirm", "$schematic.delete.confirm", () -> { - schematics.remove(s); - rebuildPane[0].run(); - }); + if(s.mod != null){ + ui.showInfo(Core.bundle.format("mod.item.remove", s.mod.meta.name)); + }else{ + ui.showConfirm("$confirm", "$schematic.delete.confirm", () -> { + schematics.remove(s); + rebuildPane[0].run(); + }); + } }); }