diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index 380fd84442..006f322b24 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -173,7 +173,7 @@ public abstract class UnlockableContent extends MappableContent{ if(!makeNew || !packer.has(name + "-outline")){ String regName = name + (makeNew ? "-outline" : ""); if(packer.registerOutlined(regName)){ - PixmapRegion base = Core.atlas.getPixmap(region); + PixmapRegion base = packer.get(region); var result = Pixmaps.outline(base, outlineColor, outlineRadius); Drawf.checkBleed(result); packer.add(page, regName, result); @@ -185,7 +185,7 @@ public abstract class UnlockableContent extends MappableContent{ protected void makeOutline(MultiPacker packer, TextureRegion region, String name, Color outlineColor, int outlineRadius){ if(region.found() && packer.registerOutlined(name)){ - PixmapRegion base = Core.atlas.getPixmap(region); + PixmapRegion base = packer.get(region); var result = Pixmaps.outline(base, outlineColor, outlineRadius); Drawf.checkBleed(result); packer.add(PageType.main, name, result); diff --git a/core/src/mindustry/editor/data/MapAssetsDialog.java b/core/src/mindustry/editor/data/MapAssetsDialog.java index 5f20093411..04a994e4ec 100644 --- a/core/src/mindustry/editor/data/MapAssetsDialog.java +++ b/core/src/mindustry/editor/data/MapAssetsDialog.java @@ -116,6 +116,7 @@ public class MapAssetsDialog extends BaseDialog{ //make sure new assets appear correctly when switching to the content view if(type == DataAssetType.content){ state.data.reloadContent(false); + state.data.regenerateContentSprites(false); } rebuild(); @@ -153,6 +154,9 @@ public class MapAssetsDialog extends BaseDialog{ Seq results = new Seq<>(); Fi zipped = new ZipFi(targetFile); Seq errors = new Seq<>(); + //force regen + state.data.clearGeneratedImages(); + for(var type : DataAssetType.all){ Fi folder = zipped.child(type.folder); @@ -208,6 +212,10 @@ public class MapAssetsDialog extends BaseDialog{ prev.addAll(results); prev.sort(); state.data.load(prev); + if(state.data.getContent().size > 0){ + //TODO: packs twice (bad) + state.data.regenerateContentSprites(false); + } rebuild(); } @@ -219,7 +227,7 @@ public class MapAssetsDialog extends BaseDialog{ ep.add(Seq.with(errors).toString("\n", s -> "[gray]- []" + s)).labelAlign(Align.left, Align.left).grow(); }); }else if(results.size == 0){ - idiag.cont.add("@asset.image.none"); + idiag.cont.add("@asset.import.none"); } idiag.buttons.button("@ok", Icon.ok, idiag::hide).size(200f, 64f); idiag.show(); diff --git a/core/src/mindustry/editor/data/MapContentView.java b/core/src/mindustry/editor/data/MapContentView.java index e56311d35c..e05535436f 100644 --- a/core/src/mindustry/editor/data/MapContentView.java +++ b/core/src/mindustry/editor/data/MapContentView.java @@ -102,8 +102,11 @@ public class MapContentView implements AssetView{ list.button(Icon.refresh, Styles.graySquarei, Vars.iconMed, () -> { Cons handler = str -> { content.data = str; - state.data.reloadContent(false); - diag.rebuild(); + ui.loadAnd(() -> { + state.data.reloadContent(false); + state.data.regenerateContentSprites(false); + diag.rebuild(); + }); }; BaseDialog dialog = new BaseDialog("@editor.import"); @@ -176,10 +179,14 @@ public class MapContentView implements AssetView{ buttons.button("@add", Icon.add, () -> showImport(diag)).size(190f, 64f); } - void addContent(ContentType type, String path, String data){ - ContentAsset asset = new ContentAsset(path, type, data); - state.data.getContent().add(asset); - state.data.reloadContent(false); + void addContent(MapAssetsDialog diag, ContentType type, String path, String data){ + ui.loadAnd(() -> { + ContentAsset asset = new ContentAsset(path, type, data); + state.data.getContent().add(asset); + state.data.reloadContent(false); + state.data.regenerateContentSprites(false); + diag.rebuild(); + }); } void showImport(MapAssetsDialog diag){ @@ -220,7 +227,7 @@ public class MapContentView implements AssetView{ choose.buttons.button("@asset.content.import.file", Icon.fileText, () -> FileChooser.open("json", "json5", "hjson").submit(file -> { choose.hide(); - addContent(selected[0], nameField.getText() + ".json", file.readString()); + addContent(diag, selected[0], nameField.getText() + ".json", file.readString()); diag.rebuild(); })).size(200f, 64f).disabled(b -> nameField.getText().isEmpty() || invalid[0]); @@ -229,8 +236,7 @@ public class MapContentView implements AssetView{ if(text == null) return; choose.hide(); - addContent(selected[0], nameField.getText() + ".json", text); - diag.rebuild(); + addContent(diag, selected[0], nameField.getText() + ".json", text); }).size(200f, 64f).disabled(b -> nameField.getText().isEmpty() || invalid[0] || Core.app.getClipboardText() == null); choose.show(); } diff --git a/core/src/mindustry/editor/data/MapImagesView.java b/core/src/mindustry/editor/data/MapImagesView.java index bbf9cf560e..4bedecb0eb 100644 --- a/core/src/mindustry/editor/data/MapImagesView.java +++ b/core/src/mindustry/editor/data/MapImagesView.java @@ -32,6 +32,7 @@ public class MapImagesView implements AssetView{ buttons.button("@add", Icon.add, () -> { FileChooser.open("png", "jpeg", "jpg").submitMulti(results -> { var images = getImages(); + state.data.clearGeneratedImages(); for(var result : results){ try{ @@ -49,14 +50,13 @@ public class MapImagesView implements AssetView{ String name = result.nameWithoutExtension(); String path = result.name(); - var other = images.find(p -> (p.path.equalsIgnoreCase(path) || p.name.equalsIgnoreCase(name))); + var other = images.find(p -> p.path.equalsIgnoreCase(path) || p.name.equalsIgnoreCase(name)); if(other != null){ ui.showErrorMessage(Core.bundle.format("asset.image.exists", other.name + " (" + other.path + ")")); return; } byte[] hash = assetCache.add(bytes); - images.add(new ImageAsset(path, hash)); }catch(Exception e){ ui.showException(e); @@ -64,7 +64,7 @@ public class MapImagesView implements AssetView{ } images.sort(); - state.data.reloadImages(images); + state.data.regenerateContentSprites(true); diag.rebuild(); }); }).size(190f, 64f); @@ -132,6 +132,8 @@ public class MapImagesView implements AssetView{ zipped.delete(); //closes the zip file int imported = 0; + state.data.clearGeneratedImages(); + for(var future : images){ var image = (Result)future.get(); if(image != null){ @@ -141,11 +143,12 @@ public class MapImagesView implements AssetView{ } String path = image.path.pathWithoutExtension(), name = image.path.nameWithoutExtension(); - var other = getImages().find(op -> (op.path.equalsIgnoreCase(path) || op.name.equalsIgnoreCase(name))); + var other = getImages().find(op -> !op.isGenerated() && (op.path.equalsIgnoreCase(path) || op.name.equalsIgnoreCase(name))); if(other != null){ errors.add("[accent]" + image.path + "[white]: " + Core.bundle.format("asset.image.exists", other.name + " (" + other.path + ")").replace("\n", " ")); continue; } + getImages().removeAll(i -> i.isGenerated() && i.name.equals(name)); getImages().add(new ImageAsset(path, image.hash)); imported ++; } @@ -154,6 +157,7 @@ public class MapImagesView implements AssetView{ getImages().sort(); state.data.reloadImages(getImages()); + state.data.regenerateContentSprites(true); diag.rebuild(); var idiag = new BaseDialog("@asset.image.imports"); @@ -211,7 +215,10 @@ public class MapImagesView implements AssetView{ int cols = (int)Math.max(1, Core.graphics.getWidth() / Scl.scl(size + 12f)); int i = 0; for(var image : getImages()){ + //showing generated images is confusing, so don't. + if(image.isGenerated()) continue; if(diag.searchString != null && !image.path.toLowerCase().contains(diag.searchString)) continue; + TextureRegion region = Core.atlas.find(regionPrefix + image.name, "nomap"); boolean found = Core.atlas.has(regionPrefix + image.name); @Nullable Fi cacheFile = image.getCacheFile(); @@ -254,10 +261,12 @@ public class MapImagesView implements AssetView{ var istyle = Styles.emptyi; b.button(Icon.pencil, istyle, () -> { ui.showTextInput("@save.rename", "@patch.path", image.path, res -> { + if(!res.endsWith(".png")) res = res + ".png"; + Fi fi = new Fi(res); String name = fi.nameWithoutExtension(); String path = fi.pathWithoutExtension(); - var other = getImages().find(p -> p != image && (p.path.equalsIgnoreCase(path) || p.name.equalsIgnoreCase(name))); + var other = getImages().find(p -> p != image && !p.isGenerated() && (p.path.equalsIgnoreCase(path) || p.name.equalsIgnoreCase(name))); if(other != null){ ui.showErrorMessage(Core.bundle.format("asset.image.exists", other.name + " (" + other.path + ")")); }else{ @@ -269,7 +278,7 @@ public class MapImagesView implements AssetView{ at.name = regionPrefix + name; } - image.setPath(path); + image.setPath(fi.path()); image.name = name; diag.rebuild(); } diff --git a/core/src/mindustry/graphics/MultiPacker.java b/core/src/mindustry/graphics/MultiPacker.java index f3ebb3b5b5..0d40a489e3 100644 --- a/core/src/mindustry/graphics/MultiPacker.java +++ b/core/src/mindustry/graphics/MultiPacker.java @@ -1,5 +1,6 @@ package mindustry.graphics; +import arc.*; import arc.graphics.*; import arc.graphics.Texture.*; import arc.graphics.g2d.*; @@ -9,17 +10,31 @@ import arc.util.Log.*; import mindustry.*; public class MultiPacker implements Disposable{ - private PixmapPacker[] packers = new PixmapPacker[PageType.all.length]; + private PixmapPacker[] packers; private ObjectSet outlined = new ObjectSet<>(); public MultiPacker(){ - for(int i = 0; i < packers.length; i++){ - packers[i] = new PixmapPacker(Math.min(Vars.maxTextureSize, PageType.all[i].width), Math.min(Vars.maxTextureSize, PageType.all[i].height), 2, true); + this(true); + } + + public MultiPacker(boolean initialize){ + if(initialize){ + packers = new PixmapPacker[PageType.all.length]; + for(int i = 0; i < packers.length; i++){ + packers[i] = new PixmapPacker(Math.min(Vars.maxTextureSize, PageType.all[i].width), Math.min(Vars.maxTextureSize, PageType.all[i].height), 2, true); + } } } - @Nullable - public PixmapRegion get(String name){ + public PixmapRegion get(TextureRegion region){ + return Core.atlas.getPixmap(region); + } + + public PixmapRegion get(String region){ + return Core.atlas.getPixmap(region); + } + + public @Nullable PixmapRegion getPacked(String name){ for(var packer : packers){ var region = packer.getRegion(name); if(region != null){ @@ -59,10 +74,6 @@ public class MultiPacker implements Disposable{ return outlined.contains(name); } - public PixmapPacker getPacker(PageType type){ - return packers[type.ordinal()]; - } - public boolean has(String name){ for(var page : PageType.all){ if(packers[page.ordinal()].getRect(name) != null){ @@ -97,6 +108,7 @@ public class MultiPacker implements Disposable{ @Override public void dispose(){ + if(packers == null) return; for(int i = 0; i < PageType.all.length; i ++){ var packer = packers[i]; //the UI packer's image is later used when merging with the font, don't dispose it diff --git a/core/src/mindustry/mod/DataImagePacker.java b/core/src/mindustry/mod/DataImagePacker.java index 10b3e0f90e..0640d3649b 100644 --- a/core/src/mindustry/mod/DataImagePacker.java +++ b/core/src/mindustry/mod/DataImagePacker.java @@ -70,8 +70,27 @@ public class DataImagePacker{ TextureRegion envReserveRegion = Core.atlas.find("data-patch-reserved-env"); PixmapPacker envPacker = anyEnv ? new PixmapPacker(envReserveRegion.width, envReserveRegion.height, 2, true) : null; - var tasks = new Seq>(); + Seq toPack = new Seq<>(), pending = new Seq<>(); + ObjectSet generatedNames = new ObjectSet<>(); + + //this makes sure that generated images are prioritized for(var image : images){ + if(image.isGenerated()){ + generatedNames.add(image.name); + toPack.add(image); + }else{ + pending.add(image); + } + } + + for(var image : pending){ + if(!generatedNames.contains(image.name)){ + toPack.add(image); + } + } + + var tasks = new Seq>(); + for(var image : toPack){ tasks.add(Vars.mainExecutor.submit(() -> { Fi cacheFile = image.getCacheFile(); //logged elsewhere @@ -131,7 +150,7 @@ public class DataImagePacker{ printStats(packer, envPacker); - packer.dispose(); + packer.forceDispose(); //textures are never updated, so force disposal if(envPacker != null) envPacker.forceDispose(); diff --git a/core/src/mindustry/mod/DataManager.java b/core/src/mindustry/mod/DataManager.java index eca7687d0b..76998eca6a 100644 --- a/core/src/mindustry/mod/DataManager.java +++ b/core/src/mindustry/mod/DataManager.java @@ -1,7 +1,14 @@ package mindustry.mod; +import arc.files.*; +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.graphics.g2d.TextureAtlas.*; import arc.struct.*; +import arc.util.*; import mindustry.*; +import mindustry.ctype.*; +import mindustry.graphics.*; import mindustry.mod.data.*; public class DataManager{ @@ -22,6 +29,139 @@ public class DataManager{ rebuildOrderedAssets(); } + public void regenerateContentSprites(boolean forcePack){ + var allContent = patcher.getAddedContent(); + + //TODO: what to do when headless (server?) + if(allContent.isEmpty()){ + if(forcePack) reloadImages(); + return; + } + + Seq contentToPack = allContent.select(c -> c instanceof UnlockableContent && c.minfo.asset != null).as(); + ObjectSet existingContentHashes = new ObjectSet<>(); + ObjectSet imagesWithHashes = new ObjectSet<>(); + ObjectMap hashes = new ObjectMap<>(); + + //store hashes based on JSON contents + for(var content : contentToPack){ + String hash = content.minfo.asset.hashData(); + hashes.put(content, hash); + existingContentHashes.add(hash); + } + + var images = getImages(); + images.removeAll(i -> { + if(i.isGenerated()){ + Fi file = new Fi(i.path); + String imageToContentHash = file.parent().name(); + imagesWithHashes.add(imageToContentHash); + //don't remove images that correspond to content that exists with that hash + return !existingContentHashes.contains(imageToContentHash); + } + return false; + }); + + //remove content that doesn't need to be packed + contentToPack.removeAll(u -> imagesWithHashes.contains(hashes.get(u))); + + ObjectMap imageMap = new ObjectMap<>(); + for(var image : images){ + imageMap.put(DataImagePacker.regionPrefix + image.name, image); + } + int[] packed = {0}; + ObjectMap imagePixmaps = new ObjectMap<>(); + PixmapRegion error = new PixmapRegion(Pixmaps.blankPixmap()); + UnlockableContent[] currentContent = {null}; + String[] currentHash = {null}; + + MultiPacker saver = new MultiPacker(false){ + @Override + public void add(PageType type, String name, PixmapRegion region, int[] splits, int[] pads){ + try{ + if(region.pixmap.width > 2000) throw new IllegalArgumentException("Max image size exceeded"); + + //strip duplicate prefix + if(name.startsWith(DataImagePacker.regionPrefix)) name = name.substring(DataImagePacker.regionPrefix.length()); + String path = "generated/" + currentHash[0] + "/" + name + ".png"; + ImageAsset newImage = new ImageAsset(); + newImage.setPath(path); + //it would be nice to do this async, but the pixmap typically gets disposed right after add() exist + byte[] bytes = PixmapIO.writePngBytes(region.pixmap); + newImage.updateData(bytes); + + images.add(newImage); + packed[0] ++; + }catch(Exception e){ + Log.err("Failed to pack image " + name, e); + } + } + + @Override + public boolean has(String name){ + return imageMap.containsKey(name); + } + + @Override + public boolean has(PageType type, String name){ + return has(name); + } + + @Override + public @Nullable PixmapRegion get(TextureRegion region){ + return get(((AtlasRegion)region).name); + } + + @Override + public PixmapRegion get(String name){ + var pix = imagePixmaps.get(name); + if(pix != null) return pix; + + var image = imageMap.get(name); + if(image == null) return error; + + try{ + var result = new PixmapRegion(new Pixmap(image.getCacheFileNoNull())); + imagePixmaps.put(name, result); + return result; + }catch(Exception e){ + Log.err("Failed loading image: " + image.path, e); + imagePixmaps.put(name, error); + return error; + } + } + }; + + for(var content : contentToPack){ + currentContent[0] = content; + currentHash[0] = hashes.get(content); + + try{ + content.createIcons(saver); + }catch(Throwable e){ + Log.err(e); + } + } + + imagePixmaps.each((key, val) -> val.pixmap.dispose()); + error.pixmap.dispose(); + + if(packed[0] > 0 || forcePack){ + reloadImages(); + + if(!Vars.headless){ + for(var cont : contentToPack){ + try{ + cont.loadIcon(); + cont.load(); + }catch(Exception e){ + Log.err("Failed to load icons for " + cont, e); + } + } + } + } + } + public void reloadPatches(Seq patches){ if(patches != getPatches()) getPatches().set(patches); @@ -31,13 +171,17 @@ public class DataManager{ rebuildOrderedAssets(); } + public void reloadImages(){ + packer.unload(); + packer.pack(getImages()); + + rebuildOrderedAssets(); + } + public void reloadImages(Seq images){ if(images != getImages()) getImages().set(images); - packer.unload(); - packer.pack(images); - - rebuildOrderedAssets(); + reloadImages(); } public void reloadAudio(){ @@ -134,6 +278,10 @@ public class DataManager{ return assets.get(type, Seq::new).as(); } + public void clearGeneratedImages(){ + getImages().removeAll(ImageAsset::isGenerated); + } + public Seq getImages(){ return getAssets(DataAssetType.image); } diff --git a/core/src/mindustry/mod/DataPatcher.java b/core/src/mindustry/mod/DataPatcher.java index 1f92de356e..2ac173fc97 100644 --- a/core/src/mindustry/mod/DataPatcher.java +++ b/core/src/mindustry/mod/DataPatcher.java @@ -48,6 +48,7 @@ public class DataPatcher{ private Seq resetters = new Seq<>(); private Seq afterCallbacks = new Seq<>(); private Seq visitStack = new Seq<>(); + private Seq addedContent = new Seq<>(); private @Nullable PatchAsset currentlyApplyingPatch; private @Nullable ContentAsset currentlyApplyingContent; private Seq addedVars = new Seq<>(); @@ -203,7 +204,9 @@ public class DataPatcher{ Vars.content.remove(errored); } - Seq all = new Seq<>(); + addedContent.clear(); + Seq all = addedContent; + for(var arr : Vars.content.getContentMap()){ all.addAll(arr.select(c -> c.minfo.mod == dpMod)); } @@ -287,10 +290,15 @@ public class DataPatcher{ afterCallbacks.each(Runnable::run); afterCallbacks.clear(); usedpatches.clear(); + addedContent.clear(); if(reloadContentWorld) fixContentArrays(); } + public Seq getAddedContent(){ + return addedContent; + } + void callContentRemove(){ for(var arr : Vars.content.getContentMap()){ for(var value : arr){ diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 30e7b67b85..eb0683a037 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -263,7 +263,7 @@ public class Mods implements Loadable{ @Override public AtlasRegion find(String name){ - var base = packer.get(name); + var base = packer.getPacked(name); if(base != null){ var reg = new AtlasRegion(shadow.find(name).texture, base.x, base.y, base.width, base.height); @@ -287,15 +287,15 @@ public class Mods implements Loadable{ @Override public boolean has(String s){ - return shadow.has(s) || packer.get(s) != null; + return shadow.has(s) || packer.getPacked(s) != null; } //return the *actual* pixmap regions, not the disposed ones. @Override public PixmapRegion getPixmap(AtlasRegion region){ - PixmapRegion out = packer.get(region.name); + PixmapRegion out = packer.getPacked(region.name); //this should not happen in normal situations - if(out == null) return packer.get("error"); + if(out == null) return packer.getPacked("error"); return out; } }; diff --git a/core/src/mindustry/mod/data/ContentAsset.java b/core/src/mindustry/mod/data/ContentAsset.java index 701c58fc07..e200c0a5af 100644 --- a/core/src/mindustry/mod/data/ContentAsset.java +++ b/core/src/mindustry/mod/data/ContentAsset.java @@ -4,6 +4,7 @@ import arc.files.*; import arc.struct.*; import arc.util.*; import mindustry.ctype.*; +import mindustry.mod.*; import java.io.*; @@ -31,6 +32,10 @@ public class ContentAsset extends DataAsset{ public ContentAsset(){ } + public String hashData(){ + return type.name() + "_" + DataAssetCache.encodeHash(Strings.sha256(data)); + } + public void readOverride(String path, Fi file, ContentType type) throws IOException{ this.type = type; setPath(path); diff --git a/core/src/mindustry/mod/data/ImageAsset.java b/core/src/mindustry/mod/data/ImageAsset.java index 45876d049f..cb1aed92e1 100644 --- a/core/src/mindustry/mod/data/ImageAsset.java +++ b/core/src/mindustry/mod/data/ImageAsset.java @@ -9,6 +9,10 @@ public class ImageAsset extends DataAsset{ setHash(hash); } + public boolean isGenerated(){ + return path.startsWith("generated/"); + } + @Override public DataAssetType getType(){ return DataAssetType.image; diff --git a/core/src/mindustry/type/Item.java b/core/src/mindustry/type/Item.java index 3ba4dc9de5..97a0f71a0d 100644 --- a/core/src/mindustry/type/Item.java +++ b/core/src/mindustry/type/Item.java @@ -129,7 +129,7 @@ public class Item extends UnlockableContent implements Senseable{ var pixmaps = new PixmapRegion[frames]; for(int i = 0; i < frames; i++){ - pixmaps[i] = Core.atlas.getPixmap(name + (i + 1)); + pixmaps[i] = packer.get(name + (i + 1)); } for(int i = 0; i < frames; i++){ diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 99d0e08cb0..db3a4ebd6b 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -1232,7 +1232,7 @@ public class UnitType extends UnlockableContent implements Senseable{ for(var region : toOutline){ if(region instanceof AtlasRegion atlas && !Core.atlas.has(atlas.name + "-outline")){ String regionName = atlas.name; - Pixmap outlined = Pixmaps.outline(Core.atlas.getPixmap(region), outlineColor, outlineRadius); + Pixmap outlined = Pixmaps.outline(packer.get(region), outlineColor, outlineRadius); Drawf.checkBleed(outlined); @@ -1268,7 +1268,7 @@ public class UnitType extends UnlockableContent implements Senseable{ } if(sample instanceof Tankc){ - PixmapRegion pix = Core.atlas.getPixmap(treadRegion); + PixmapRegion pix = packer.get(treadRegion); for(int r = 0; r < treadRects.length; r++){ Rect treadRect = treadRects[r]; diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 131e8d997d..c5cf127a41 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -1538,7 +1538,7 @@ public class Block extends UnlockableContent implements Senseable{ super.createIcons(packer); if(!synthetic()){ - PixmapRegion image = Core.atlas.getPixmap(fullIcon); + PixmapRegion image = packer.get(fullIcon); mapColor.set(image.get(image.width/2, image.height/2)); } @@ -1549,7 +1549,7 @@ public class Block extends UnlockableContent implements Senseable{ for(Team team : Team.all){ //if there's an override, don't generate anything if(team.hasPalette && !Core.atlas.has(name + "-team-" + team.name)){ - var base = Core.atlas.getPixmap(teamRegion); + var base = packer.get(teamRegion); Pixmap out = new Pixmap(base.width, base.height); for(int x = 0; x < base.width; x++){ @@ -1584,7 +1584,7 @@ public class Block extends UnlockableContent implements Senseable{ if(outlineIcon){ AtlasRegion atlasRegion = (AtlasRegion)gen[outlinedIcon >= 0 ? Math.min(outlinedIcon, gen.length - 1) : gen.length -1]; - PixmapRegion region = Core.atlas.getPixmap(atlasRegion); + PixmapRegion region = packer.get(atlasRegion); Pixmap out = last = Pixmaps.outline(region, outlineColor, outlineRadius); Drawf.checkBleed(out); packer.add(PageType.main, atlasRegion.name, out); @@ -1597,7 +1597,7 @@ public class Block extends UnlockableContent implements Senseable{ for(var region : toOutline){ if(region instanceof AtlasRegion atlas){ String regionName = atlas.name; - Pixmap outlined = Pixmaps.outline(Core.atlas.getPixmap(region), outlineColor, outlineRadius); + Pixmap outlined = Pixmaps.outline(packer.get(region), outlineColor, outlineRadius); Drawf.checkBleed(outlined); @@ -1607,19 +1607,19 @@ public class Block extends UnlockableContent implements Senseable{ } if(gen.length > 1){ - Pixmap base = Core.atlas.getPixmap(gen[0]).crop(); + Pixmap base = packer.get(gen[0]).crop(); for(int i = 1; i < gen.length; i++){ if(i == gen.length - 1 && last != null){ base.draw(last, 0, 0, true); }else{ - base.draw(Core.atlas.getPixmap(gen[i]), true); + base.draw(packer.get(gen[i]), true); } } packer.add(PageType.main, "block-" + name + "-full", base); toDispose.add(base); }else{ - if(gen[0] != null) packer.add(PageType.main, "block-" + name + "-full", Core.atlas.getPixmap(gen[0])); + if(gen[0] != null) packer.add(PageType.main, "block-" + name + "-full", packer.get(gen[0])); } toDispose.each(Pixmap::dispose); diff --git a/core/src/mindustry/world/blocks/environment/Floor.java b/core/src/mindustry/world/blocks/environment/Floor.java index 12ba8c78d1..ab4b3366ae 100644 --- a/core/src/mindustry/world/blocks/environment/Floor.java +++ b/core/src/mindustry/world/blocks/environment/Floor.java @@ -220,8 +220,8 @@ public class Floor extends Block{ if(Core.atlas.has(name + "-edge")) return; - var image = Core.atlas.getPixmap(icons()[0]); - var edge = Core.atlas.getPixmap(Core.atlas.find(name + "-edge-stencil", "edge-stencil")); + var image = packer.get(icons()[0]); + var edge = packer.get(Core.atlas.find(name + "-edge-stencil", "edge-stencil")); Pixmap result = new Pixmap(edge.width, edge.height); for(int x = 0; x < edge.width; x++){ diff --git a/core/src/mindustry/world/blocks/environment/OreBlock.java b/core/src/mindustry/world/blocks/environment/OreBlock.java index ec79b82e42..ed7db5f32d 100644 --- a/core/src/mindustry/world/blocks/environment/OreBlock.java +++ b/core/src/mindustry/world/blocks/environment/OreBlock.java @@ -46,8 +46,8 @@ public class OreBlock extends OverlayFloor{ for(int i = 0; i < variants; i++){ //use name (e.g. "ore-copper1"), fallback to "copper1" as per the old naming system PixmapRegion shadow = Core.atlas.has(name + (i + 1)) ? - Core.atlas.getPixmap(name + (i + 1)) : - Core.atlas.getPixmap(itemDrop.name + (i + 1)); + packer.get(name + (i + 1)) : + packer.get(itemDrop.name + (i + 1)); Pixmap image = shadow.crop(); diff --git a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java index 87b10a8dd6..76a119fe69 100644 --- a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java +++ b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java @@ -1,6 +1,5 @@ package mindustry.world.blocks.environment; -import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.util.*; @@ -37,10 +36,10 @@ public class ShallowLiquid extends Floor{ //super.createIcons(packer); if(liquidBase != null && floorBase != null){ - var overlay = Core.atlas.getPixmap(liquidBase.region); + var overlay = packer.get(liquidBase.region); int index = 0; for(TextureRegion region : floorBase.variantRegions()){ - var res = Core.atlas.getPixmap(region).crop(); + var res = packer.get(region).crop(); for(int x = 0; x < res.width; x++){ for(int y = 0; y < res.height; y++){ res.setRaw(x, y, Pixmap.blend((overlay.getRaw(x, y) & 0xffffff00) | (int)(liquidOpacity * 255), res.getRaw(x, y))); diff --git a/gradle.properties b/gradle.properties index 9c6ef94aec..bb00ef7c95 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,4 @@ org.gradle.caching=true org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 android.enableR8.fullMode=false -archash=6e3c0bbc30 +archash=2b0a95e325