Merge remote-tracking branch 'anuken/master'

This commit is contained in:
Miguel de Dios Matias
2019-10-03 11:28:03 +02:00
90 changed files with 11393 additions and 8118 deletions

View File

@@ -139,7 +139,7 @@ public class AssetsAnnotationProcessor extends AbstractProcessor{
loadBegin.addStatement("io.anuke.arc.Core.assets.load("+filename +", "+rtype+".class).loaded = a -> " + name + " = ("+rtype+")a", filepath, filepath.replace(".ogg", ".mp3")); loadBegin.addStatement("io.anuke.arc.Core.assets.load("+filename +", "+rtype+".class).loaded = a -> " + name + " = ("+rtype+")a", filepath, filepath.replace(".ogg", ".mp3"));
dispose.addStatement(name + ".dispose()"); dispose.addStatement("io.anuke.arc.Core.assets.unload(" + filename + ")");
dispose.addStatement(name + " = null"); dispose.addStatement(name + " = null");
type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), name, Modifier.STATIC, Modifier.PUBLIC).initializer("new io.anuke.arc.audio.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1)+ "()").build()); type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), name, Modifier.STATIC, Modifier.PUBLIC).initializer("new io.anuke.arc.audio.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1)+ "()").build());
}); });

View File

@@ -1,32 +1,29 @@
package io.anuke.annotations; package io.anuke.annotations;
import com.sun.source.util.TreePath; import com.sun.source.util.*;
import com.sun.source.util.Trees; import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; import io.anuke.annotations.Annotations.*;
import io.anuke.annotations.Annotations.OverrideCallSuper;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.SourceVersion; import javax.lang.model.*;
import javax.lang.model.element.Element; import javax.lang.model.element.*;
import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic.*;
import javax.tools.Diagnostic.Kind; import java.util.*;
import java.util.List;
import java.util.Set;
@SupportedAnnotationTypes("java.lang.Override") @SupportedAnnotationTypes({"java.lang.Override"})
public class CallSuperAnnotationProcessor extends AbstractProcessor{ public class CallSuperAnnotationProcessor extends AbstractProcessor{
private Trees trees; private Trees trees;
@Override @Override
public void init (ProcessingEnvironment pe) { public void init(ProcessingEnvironment pe){
super.init(pe); super.init(pe);
trees = Trees.instance(pe); trees = Trees.instance(pe);
} }
public boolean process (Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
for (Element e : roundEnv.getElementsAnnotatedWith(Override.class)) { for(Element e : roundEnv.getElementsAnnotatedWith(Override.class)){
if (e.getAnnotation(OverrideCallSuper.class) != null) return false; if(e.getAnnotation(OverrideCallSuper.class) != null) return false;
CodeAnalyzerTreeScanner codeScanner = new CodeAnalyzerTreeScanner(); CodeAnalyzerTreeScanner codeScanner = new CodeAnalyzerTreeScanner();
codeScanner.setMethodName(e.getSimpleName().toString()); codeScanner.setMethodName(e.getSimpleName().toString());
@@ -34,10 +31,10 @@ public class CallSuperAnnotationProcessor extends AbstractProcessor{
TreePath tp = trees.getPath(e.getEnclosingElement()); TreePath tp = trees.getPath(e.getEnclosingElement());
codeScanner.scan(tp, trees); codeScanner.scan(tp, trees);
if (codeScanner.isCallSuperUsed()) { if(codeScanner.isCallSuperUsed()){
List list = codeScanner.getMethod().getBody().getStatements(); List list = codeScanner.getMethod().getBody().getStatements();
if (!doesCallSuper(list, codeScanner.getMethodName())) { if(!doesCallSuper(list, codeScanner.getMethodName())){
processingEnv.getMessager().printMessage(Kind.ERROR, "Overriding method '" + codeScanner.getMethodName() + "' must explicitly call super method from its parent class.", e); processingEnv.getMessager().printMessage(Kind.ERROR, "Overriding method '" + codeScanner.getMethodName() + "' must explicitly call super method from its parent class.", e);
} }
} }
@@ -46,12 +43,12 @@ public class CallSuperAnnotationProcessor extends AbstractProcessor{
return false; return false;
} }
private boolean doesCallSuper (List list, String methodName) { private boolean doesCallSuper(List list, String methodName){
for (Object object : list) { for(Object object : list){
if (object instanceof JCTree.JCExpressionStatement) { if(object instanceof JCTree.JCExpressionStatement){
JCTree.JCExpressionStatement expr = (JCExpressionStatement) object; JCTree.JCExpressionStatement expr = (JCExpressionStatement)object;
String exprString = expr.toString(); String exprString = expr.toString();
if (exprString.startsWith("super." + methodName) && exprString.endsWith(");")) return true; if(exprString.startsWith("super." + methodName) && exprString.endsWith(");")) return true;
} }
} }
@@ -59,7 +56,7 @@ public class CallSuperAnnotationProcessor extends AbstractProcessor{
} }
@Override @Override
public SourceVersion getSupportedSourceVersion () { public SourceVersion getSupportedSourceVersion(){
return SourceVersion.RELEASE_8; return SourceVersion.RELEASE_8;
} }
} }

View File

@@ -67,15 +67,19 @@ committingchanges = Comitting Changes
done = Done done = Done
mods.alphainfo = Keep in mind that mods are in alpha, and[scarlet] may be very buggy[].\nReport any issues you find to the Mindustry Github or Discord. mods.alphainfo = Keep in mind that mods are in alpha, and[scarlet] may be very buggy[].\nReport any issues you find to the Mindustry Github or Discord.
mods.alpha = [scarlet](Alpha) mods.alpha = [accent](Alpha)
mods = Mods mods = Mods
mods.none = [LIGHT_GRAY]No mods found! mods.none = [LIGHT_GRAY]No mods found!
mod.enabled = [lightgray]Enabled mod.enabled = [lightgray]Enabled
mod.disabled = [scarlet]Disabled mod.disabled = [scarlet]Disabled
mod.disable = Disable
mod.enable = Enable
mod.requiresrestart = The game will now close to apply the mod changes. mod.requiresrestart = The game will now close to apply the mod changes.
mod.reloadrequired = [scarlet]Reload Required
mod.import = Import Mod mod.import = Import Mod
mod.remove.confirm = This mod will be deleted. mod.remove.confirm = This mod will be deleted.
mod.author = [LIGHT_GRAY]Author:[] {0} 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}
about.button = About about.button = About
name = Name: name = Name:
@@ -177,7 +181,7 @@ save.rename.text = New name:
selectslot = Select a save. selectslot = Select a save.
slot = [accent]Slot {0} slot = [accent]Slot {0}
editmessage = Edit Message editmessage = Edit Message
save.corrupted = [accent]Save file corrupted or invalid!\nIf you have just updated your game, this is probably a change in the save format and [scarlet]not[] a bug. save.corrupted = Save file corrupted or invalid!
empty = <empty> empty = <empty>
on = On on = On
off = Off off = Off
@@ -209,6 +213,7 @@ classic.export.text = [accent]Mindustry[] has just had a major update.\nClassic
quit.confirm = Are you sure you want to quit? quit.confirm = Are you sure you want to quit?
quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[] quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[]
loading = [accent]Loading... loading = [accent]Loading...
reloading = [accent]Reloading Mods...
saving = [accent]Saving... saving = [accent]Saving...
wave = [accent]Wave {0} wave = [accent]Wave {0}
wave.waiting = [lightgray]Wave in {0} wave.waiting = [lightgray]Wave in {0}
@@ -459,8 +464,6 @@ settings.graphics = Graphics
settings.cleardata = Clear Game Data... settings.cleardata = Clear Game Data...
settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone!
settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit.
settings.clearunlocks = Clear Unlocks
settings.clearall = Clear All
paused = [accent]< Paused > paused = [accent]< Paused >
yes = Yes yes = Yes
no = No no = No

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 KiB

After

Width:  |  Height:  |  Size: 712 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 721 KiB

View File

@@ -2,6 +2,8 @@ package io.anuke.mindustry;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.assets.*; import io.anuke.arc.assets.*;
import io.anuke.arc.assets.loaders.*;
import io.anuke.arc.audio.*;
import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.*; import io.anuke.arc.math.*;
@@ -41,10 +43,15 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
batch = new SpriteBatch(); batch = new SpriteBatch();
assets = new AssetManager(); assets = new AssetManager();
assets.setLoader(Texture.class, "." + mapExtension, new MapPreviewLoader()); assets.setLoader(Texture.class, "." + mapExtension, new MapPreviewLoader());
tree = new FileTree();
assets.setLoader(Sound.class, new SoundLoader(tree));
assets.setLoader(Music.class, new MusicLoader(tree));
assets.load("sprites/error.png", Texture.class); assets.load("sprites/error.png", Texture.class);
atlas = TextureAtlas.blankAtlas(); atlas = TextureAtlas.blankAtlas();
Vars.net = new Net(platform.getNet()); Vars.net = new Net(platform.getNet());
Vars.mods = new Mods(); mods = new Mods();
UI.loadSystemCursors(); UI.loadSystemCursors();

View File

@@ -31,7 +31,7 @@ import static io.anuke.arc.Core.*;
public class Vars implements Loadable{ public class Vars implements Loadable{
/** Whether to load locales.*/ /** Whether to load locales.*/
public static boolean loadLocales = true; public static boolean loadLocales = true;
/** Maximum number of broken blocks.*/ /** Maximum number of broken blocks. TODO implement or remove.*/
public static final int maxBrokenBlocks = 256; public static final int maxBrokenBlocks = 256;
/** IO buffer size. */ /** IO buffer size. */
public static final int bufferSize = 8192; public static final int bufferSize = 8192;
@@ -196,10 +196,9 @@ public class Vars implements Loadable{
Version.init(); Version.init();
tree = new FileTree(); if(tree == null) tree = new FileTree();
if(mods == null){ if(mods == null) mods = new Mods();
mods = new Mods();
}
content = new ContentLoader(); content = new ContentLoader();
loops = new LoopControl(); loops = new LoopControl();
defaultWaves = new DefaultWaves(); defaultWaves = new DefaultWaves();
@@ -258,7 +257,7 @@ public class Vars implements Loadable{
public static void loadSettings(){ public static void loadSettings(){
Core.settings.setAppName(appName); Core.settings.setAppName(appName);
if(steam){ if(steam || "steam".equals(Version.modifier)){
Core.settings.setDataDirectory(Core.files.local("saves/")); Core.settings.setDataDirectory(Core.files.local("saves/"));
} }

View File

@@ -781,7 +781,7 @@ public class Blocks implements ContentList{
}}; }};
copperWallLarge = new Wall("copper-wall-large"){{ copperWallLarge = new Wall("copper-wall-large"){{
requirements(Category.defense, ItemStack.mult(copperWall.buildRequirements, 4)); requirements(Category.defense, ItemStack.mult(copperWall.requirements, 4));
health = 80 * 4 * wallHealthMultiplier; health = 80 * 4 * wallHealthMultiplier;
size = 2; size = 2;
}}; }};
@@ -792,7 +792,7 @@ public class Blocks implements ContentList{
}}; }};
titaniumWallLarge = new Wall("titanium-wall-large"){{ titaniumWallLarge = new Wall("titanium-wall-large"){{
requirements(Category.defense, ItemStack.mult(titaniumWall.buildRequirements, 4)); requirements(Category.defense, ItemStack.mult(titaniumWall.requirements, 4));
health = 110 * wallHealthMultiplier * 4; health = 110 * wallHealthMultiplier * 4;
size = 2; size = 2;
}}; }};
@@ -803,7 +803,7 @@ public class Blocks implements ContentList{
}}; }};
thoriumWallLarge = new Wall("thorium-wall-large"){{ thoriumWallLarge = new Wall("thorium-wall-large"){{
requirements(Category.defense, ItemStack.mult(thoriumWall.buildRequirements, 4)); requirements(Category.defense, ItemStack.mult(thoriumWall.requirements, 4));
health = 200 * wallHealthMultiplier * 4; health = 200 * wallHealthMultiplier * 4;
size = 2; size = 2;
}}; }};
@@ -814,7 +814,7 @@ public class Blocks implements ContentList{
}}; }};
phaseWallLarge = new DeflectorWall("phase-wall-large"){{ phaseWallLarge = new DeflectorWall("phase-wall-large"){{
requirements(Category.defense, ItemStack.mult(phaseWall.buildRequirements, 4)); requirements(Category.defense, ItemStack.mult(phaseWall.requirements, 4));
health = 150 * 4 * wallHealthMultiplier; health = 150 * 4 * wallHealthMultiplier;
size = 2; size = 2;
}}; }};
@@ -825,7 +825,7 @@ public class Blocks implements ContentList{
}}; }};
surgeWallLarge = new SurgeWall("surge-wall-large"){{ surgeWallLarge = new SurgeWall("surge-wall-large"){{
requirements(Category.defense, ItemStack.mult(surgeWall.buildRequirements, 4)); requirements(Category.defense, ItemStack.mult(surgeWall.requirements, 4));
health = 230 * 4 * wallHealthMultiplier; health = 230 * 4 * wallHealthMultiplier;
size = 2; size = 2;
}}; }};
@@ -836,7 +836,7 @@ public class Blocks implements ContentList{
}}; }};
doorLarge = new Door("door-large"){{ doorLarge = new Door("door-large"){{
requirements(Category.defense, ItemStack.mult(door.buildRequirements, 4)); requirements(Category.defense, ItemStack.mult(door.requirements, 4));
openfx = Fx.dooropenlarge; openfx = Fx.dooropenlarge;
closefx = Fx.doorcloselarge; closefx = Fx.doorcloselarge;
health = 100 * 4 * wallHealthMultiplier; health = 100 * 4 * wallHealthMultiplier;
@@ -1315,7 +1315,8 @@ public class Blocks implements ContentList{
requirements(Category.turret, ItemStack.with(Items.copper, 85, Items.lead, 45)); requirements(Category.turret, ItemStack.with(Items.copper, 85, Items.lead, 45));
ammo( ammo(
Items.scrap, Bullets.flakScrap, Items.scrap, Bullets.flakScrap,
Items.lead, Bullets.flakLead Items.lead, Bullets.flakLead,
Items.metaglass, Bullets.flakGlass
); );
reload = 18f; reload = 18f;
range = 170f; range = 170f;
@@ -1558,6 +1559,7 @@ public class Blocks implements ContentList{
cyclone = new ItemTurret("cyclone"){{ cyclone = new ItemTurret("cyclone"){{
requirements(Category.turret, ItemStack.with(Items.copper, 200, Items.titanium, 125, Items.plastanium, 80)); requirements(Category.turret, ItemStack.with(Items.copper, 200, Items.titanium, 125, Items.plastanium, 80));
ammo( ammo(
Items.metaglass, Bullets.flakGlass,
Items.blastCompound, Bullets.flakExplosive, Items.blastCompound, Bullets.flakExplosive,
Items.plastanium, Bullets.flakPlastic, Items.plastanium, Bullets.flakPlastic,
Items.surgealloy, Bullets.flakSurge Items.surgealloy, Bullets.flakSurge

View File

@@ -21,7 +21,7 @@ public class Bullets implements ContentList{
artilleryDense, arilleryPlastic, artilleryPlasticFrag, artilleryHoming, artlleryIncendiary, artilleryExplosive, artilleryUnit, artilleryDense, arilleryPlastic, artilleryPlasticFrag, artilleryHoming, artlleryIncendiary, artilleryExplosive, artilleryUnit,
//flak //flak
flakScrap, flakLead, flakPlastic, flakExplosive, flakSurge, flakScrap, flakLead, flakPlastic, flakExplosive, flakSurge, flakGlass, glassFrag,
//missiles //missiles
missileExplosive, missileIncendiary, missileSurge, missileJavelin, missileSwarm, missileRevenant, missileExplosive, missileIncendiary, missileSurge, missileJavelin, missileSwarm, missileRevenant,
@@ -55,7 +55,7 @@ public class Bullets implements ContentList{
splashDamage = 33f; splashDamage = 33f;
}}; }};
artilleryPlasticFrag = new BasicBulletType(2.5f, 7, "bullet"){{ artilleryPlasticFrag = new BasicBulletType(2.5f, 10, "bullet"){{
bulletWidth = 10f; bulletWidth = 10f;
bulletHeight = 12f; bulletHeight = 12f;
bulletShrink = 1f; bulletShrink = 1f;
@@ -132,6 +132,16 @@ public class Bullets implements ContentList{
frontColor = Pal.bulletYellow; frontColor = Pal.bulletYellow;
}}; }};
glassFrag = new BasicBulletType(3f, 6, "bullet"){{
bulletWidth = 5f;
bulletHeight = 12f;
bulletShrink = 1f;
lifetime = 20f;
backColor = Pal.gray;
frontColor = Color.white;
despawnEffect = Fx.none;
}};
flakLead = new FlakBulletType(4.2f, 3){{ flakLead = new FlakBulletType(4.2f, 3){{
lifetime = 60f; lifetime = 60f;
ammoMultiplier = 4f; ammoMultiplier = 4f;
@@ -155,8 +165,23 @@ public class Bullets implements ContentList{
splashDamageRadius = 24f; splashDamageRadius = 24f;
}}; }};
flakGlass = new FlakBulletType(4f, 3){{
lifetime = 70f;
ammoMultiplier = 5f;
shootEffect = Fx.shootSmall;
reloadMultiplier = 0.8f;
bulletWidth = 6f;
bulletHeight = 8f;
hitEffect = Fx.flakExplosion;
splashDamage = 30f;
splashDamageRadius = 26f;
fragBullet = glassFrag;
fragBullets = 6;
}};
flakPlastic = new FlakBulletType(4f, 6){{ flakPlastic = new FlakBulletType(4f, 6){{
splashDamageRadius = 50f; splashDamageRadius = 50f;
splashDamage = 25f;
fragBullet = artilleryPlasticFrag; fragBullet = artilleryPlasticFrag;
fragBullets = 6; fragBullets = 6;
hitEffect = Fx.plasticExplosion; hitEffect = Fx.plasticExplosion;

View File

@@ -11,7 +11,6 @@ import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Item.*;
import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.tilesize;
@@ -552,7 +551,7 @@ public class Fx implements ContentList{
float length = 20f * e.finpow(); float length = 20f * e.finpow();
float size = 7f * e.fout(); float size = 7f * e.fout();
Draw.rect(((Item)e.data).icon(Icon.large), e.x + Angles.trnsx(e.rotation, length), e.y + Angles.trnsy(e.rotation, length), size, size); Draw.rect(((Item)e.data).icon(Cicon.medium), e.x + Angles.trnsx(e.rotation, length), e.y + Angles.trnsy(e.rotation, length), size, size);
}); });

View File

@@ -13,6 +13,7 @@ public class TechTree implements ContentList{
@Override @Override
public void load(){ public void load(){
TechNode.context = null;
all = new Array<>(); all = new Array<>();
root = node(coreShard, () -> { root = node(coreShard, () -> {
@@ -302,19 +303,24 @@ public class TechTree implements ContentList{
}); });
} }
private TechNode node(Block block, Runnable children){ private static TechNode node(Block block, Runnable children){
ItemStack[] requirements = new ItemStack[block.buildRequirements.length]; ItemStack[] requirements = new ItemStack[block.requirements.length];
for(int i = 0; i < requirements.length; i++){ for(int i = 0; i < requirements.length; i++){
requirements[i] = new ItemStack(block.buildRequirements[i].item, 30 + block.buildRequirements[i].amount * 6); requirements[i] = new ItemStack(block.requirements[i].item, 30 + block.requirements[i].amount * 6);
} }
return new TechNode(block, requirements, children); return new TechNode(block, requirements, children);
} }
private TechNode node(Block block){ private static TechNode node(Block block){
return node(block, () -> {}); return node(block, () -> {});
} }
public static void create(Block parent, Block block){
TechNode.context = all.find(t -> t.block == parent);
node(block, () -> {});
}
public static class TechNode{ public static class TechNode{
static TechNode context; static TechNode context;
@@ -322,19 +328,22 @@ public class TechTree implements ContentList{
public final ItemStack[] requirements; public final ItemStack[] requirements;
public final Array<TechNode> children = new Array<>(); public final Array<TechNode> children = new Array<>();
TechNode(Block block, ItemStack[] requirements, Runnable children){ TechNode(TechNode ccontext, Block block, ItemStack[] requirements, Runnable children){
if(context != null){ if(ccontext != null){
context.children.add(this); ccontext.children.add(this);
} }
this.block = block; this.block = block;
this.requirements = requirements; this.requirements = requirements;
TechNode last = context;
context = this; context = this;
children.run(); children.run();
context = last; context = ccontext;
all.add(this); all.add(this);
} }
TechNode(Block block, ItemStack[] requirements, Runnable children){
this(context, block, requirements, children);
}
} }
} }

View File

@@ -42,6 +42,14 @@ public class ContentLoader{
new LegacyColorMapper(), new LegacyColorMapper(),
}; };
/** Clears all initialized content.*/
public void clear(){
contentNameMap = new ObjectMap[ContentType.values().length];
contentMap = new Array[ContentType.values().length];
initialization = new ObjectSet<>();
loaded = false;
}
/** Creates all content types. */ /** Creates all content types. */
public void createContent(){ public void createContent(){
if(loaded){ if(loaded){
@@ -58,37 +66,11 @@ public class ContentLoader{
list.load(); list.load();
} }
setupMapping();
if(mods != null){ if(mods != null){
mods.loadContent(); mods.loadContent();
} }
setupMapping(); //check up ID mapping, make sure it's linear
loaded = true;
}
private void setupMapping(){
for(ContentType type : ContentType.values()){
contentNameMap[type.ordinal()].clear();
}
for(ContentType type : ContentType.values()){
for(Content c : contentMap[type.ordinal()]){
if(c instanceof MappableContent){
String name = ((MappableContent)c).name;
if(contentNameMap[type.ordinal()].containsKey(name)){
throw new IllegalArgumentException("Two content objects cannot have the same name! (issue: '" + name + "')");
}
contentNameMap[type.ordinal()].put(name, (MappableContent)c);
}
}
}
//set up ID mapping
for(Array<Content> arr : contentMap){ for(Array<Content> arr : contentMap){
for(int i = 0; i < arr.size; i++){ for(int i = 0; i < arr.size; i++){
int id = arr.get(i).id; int id = arr.get(i).id;
@@ -97,6 +79,8 @@ public class ContentLoader{
} }
} }
} }
loaded = true;
} }
/** Logs content statistics.*/ /** Logs content statistics.*/
@@ -125,6 +109,7 @@ public class ContentLoader{
for(ContentType type : ContentType.values()){ for(ContentType type : ContentType.values()){
for(Content content : contentMap[type.ordinal()]){ for(Content content : contentMap[type.ordinal()]){
//TODO catch error and display it per mod
callable.accept(content); callable.accept(content);
} }
} }
@@ -154,6 +139,14 @@ public class ContentLoader{
public void handleContent(Content content){ public void handleContent(Content content){
contentMap[content.getContentType().ordinal()].add(content); contentMap[content.getContentType().ordinal()].add(content);
}
public void handleMappableContent(MappableContent content){
if(contentNameMap[content.getContentType().ordinal()].containsKey(content.name)){
throw new IllegalArgumentException("Two content objects cannot have the same name! (issue: '" + content.name + "')");
}
contentNameMap[content.getContentType().ordinal()].put(content.name, content);
} }
public void setTemporaryMapper(MappableContent[][] temporaryMapper){ public void setTemporaryMapper(MappableContent[][] temporaryMapper){

View File

@@ -91,6 +91,7 @@ public class Control implements ApplicationListener, Loadable{
hiscore = true; hiscore = true;
world.getMap().setHighScore(state.wave); world.getMap().setHighScore(state.wave);
} }
Sounds.wave.play(); Sounds.wave.play();
}); });
@@ -388,7 +389,10 @@ public class Control implements ApplicationListener, Loadable{
saves.update(); saves.update();
//update and load any requested assets //update and load any requested assets
try{
assets.update(); assets.update();
}catch(Exception ignored){
}
input.updateState(); input.updateState();

View File

@@ -1,15 +1,16 @@
package io.anuke.mindustry.core; package io.anuke.mindustry.core;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.assets.loaders.*;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.*;
import io.anuke.arc.files.*; import io.anuke.arc.files.*;
/** Handles files in a modded context. */ /** Handles files in a modded context. */
public class FileTree{ public class FileTree implements FileHandleResolver{
private ObjectMap<String, FileHandle> files = new ObjectMap<>(); private ObjectMap<String, FileHandle> files = new ObjectMap<>();
public void addFile(FileHandle f){ public void addFile(String path, FileHandle f){
files.put(f.path(), f); files.put(path, f);
} }
/** Gets an asset file.*/ /** Gets an asset file.*/
@@ -20,4 +21,14 @@ public class FileTree{
return Core.files.internal(path); return Core.files.internal(path);
} }
} }
/** Clears all mod files.*/
public void clear(){
files.clear();
}
@Override
public FileHandle resolve(String fileName){
return get(fileName);
}
} }

View File

@@ -32,12 +32,13 @@ public class Logic implements ApplicationListener{
public Logic(){ public Logic(){
Events.on(WaveEvent.class, event -> { Events.on(WaveEvent.class, event -> {
if(world.isZone()){
world.getZone().updateWave(state.wave);
}
for(Player p : playerGroup.all()){ for(Player p : playerGroup.all()){
p.respawns = state.rules.respawns; p.respawns = state.rules.respawns;
} }
if(world.isZone()){
world.getZone().updateWave(state.wave);
}
}); });
Events.on(BlockDestroyEvent.class, event -> { Events.on(BlockDestroyEvent.class, event -> {

View File

@@ -18,12 +18,10 @@ import io.anuke.mindustry.entities.effect.*;
import io.anuke.mindustry.entities.effect.GroundEffectEntity.*; import io.anuke.mindustry.entities.effect.GroundEffectEntity.*;
import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.entities.type.EffectEntity;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.input.*; import io.anuke.mindustry.input.*;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.defense.ForceProjector.*; import io.anuke.mindustry.world.blocks.defense.ForceProjector.*;
import static io.anuke.arc.Core.*; import static io.anuke.arc.Core.*;
@@ -310,7 +308,7 @@ public class Renderer implements ApplicationListener{
float fract = landTime / Fx.coreLand.lifetime; float fract = landTime / Fx.coreLand.lifetime;
TileEntity entity = player.getClosestCore(); TileEntity entity = player.getClosestCore();
TextureRegion reg = entity.block.icon(Block.Icon.full); TextureRegion reg = entity.block.icon(Cicon.full);
float scl = Scl.scl(4f) / camerascale; float scl = Scl.scl(4f) / camerascale;
float s = reg.getWidth() * Draw.scl * scl * 4f * fract; float s = reg.getWidth() * Draw.scl * scl * 4f * fract;

View File

@@ -417,6 +417,22 @@ public class UI implements ApplicationListener, Loadable{
dialog.show(); dialog.show();
} }
public void showCustomConfirm(String title, String text, String yes, String no, Runnable confirmed){
FloatingDialog dialog = new FloatingDialog(title);
dialog.cont.add(text).width(500f).wrap().pad(4f).get().setAlignment(Align.center, Align.center);
dialog.buttons.defaults().size(200f, 54f).pad(2f);
dialog.setFillParent(false);
dialog.buttons.addButton(no, dialog::hide);
dialog.buttons.addButton(yes, () -> {
dialog.hide();
confirmed.run();
});
dialog.keyDown(KeyCode.ESCAPE, dialog::hide);
dialog.keyDown(KeyCode.BACK, dialog::hide);
dialog.show();
}
public void showOkText(String title, String text, Runnable confirmed){ public void showOkText(String title, String text, Runnable confirmed){
FloatingDialog dialog = new FloatingDialog(title); FloatingDialog dialog = new FloatingDialog(title);
dialog.cont.add(text).width(500f).wrap().pad(4f).get().setAlignment(Align.center, Align.center); dialog.cont.add(text).width(500f).wrap().pad(4f).get().setAlignment(Align.center, Align.center);

View File

@@ -702,7 +702,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}); });
for(Block block : blocksOut){ for(Block block : blocksOut){
TextureRegion region = block.icon(Block.Icon.medium); TextureRegion region = block.icon(Cicon.medium);
if(!Core.atlas.isFound(region)) continue; if(!Core.atlas.isFound(region)) continue;

View File

@@ -388,7 +388,7 @@ public class MapGenerateDialog extends FloatingDialog{
GenTile tile = buffer1[px][py]; GenTile tile = buffer1[px][py];
color = MapIO.colorFor(content.block(tile.floor), content.block(tile.block), content.block(tile.ore), Team.derelict); color = MapIO.colorFor(content.block(tile.floor), content.block(tile.block), content.block(tile.ore), Team.derelict);
} }
pixmap.drawPixel(px, pixmap.getHeight() - 1 - py, color); pixmap.draw(px, pixmap.getHeight() - 1 - py, color);
} }
} }

View File

@@ -140,7 +140,7 @@ public class WaveInfoDialog extends FloatingDialog{
t.margin(0).defaults().pad(3).padLeft(5f).growX().left(); t.margin(0).defaults().pad(3).padLeft(5f).growX().left();
t.addButton(b -> { t.addButton(b -> {
b.left(); b.left();
b.addImage(group.type.iconRegion).size(30f).padRight(3); b.addImage(group.type.icon(Cicon.medium)).size(32f).padRight(3);
b.add(group.type.localizedName).color(Pal.accent); b.add(group.type.localizedName).color(Pal.accent);
}, () -> showUpdate(group)).pad(-6f).padBottom(0f); }, () -> showUpdate(group)).pad(-6f).padBottom(0f);
@@ -221,7 +221,7 @@ public class WaveInfoDialog extends FloatingDialog{
for(UnitType type : content.units()){ for(UnitType type : content.units()){
dialog.cont.addButton(t -> { dialog.cont.addButton(t -> {
t.left(); t.left();
t.addImage(type.iconRegion).size(40f).padRight(2f); t.addImage(type.icon(Cicon.medium)).size(40f).padRight(2f);
t.add(type.localizedName); t.add(type.localizedName);
}, () -> { }, () -> {
lastType = type; lastType = type;
@@ -253,7 +253,7 @@ public class WaveInfoDialog extends FloatingDialog{
for(int j = 0; j < spawned.length; j++){ for(int j = 0; j < spawned.length; j++){
if(spawned[j] > 0){ if(spawned[j] > 0){
UnitType type = content.getByID(ContentType.unit, j); UnitType type = content.getByID(ContentType.unit, j);
table.addImage(type.iconRegion).size(30f).padRight(4); table.addImage(type.icon(Cicon.medium)).size(8f * 4f).padRight(4);
table.add(spawned[j] + "x").color(Color.lightGray).padRight(6); table.add(spawned[j] + "x").color(Color.lightGray).padRight(6);
table.row(); table.row();
} }

View File

@@ -236,7 +236,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
@Override @Override
public TextureRegion getIconRegion(){ public TextureRegion getIconRegion(){
return type.iconRegion; return type.icon(Cicon.full);
} }
@Override @Override

View File

@@ -160,7 +160,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
@Override @Override
public TextureRegion getIconRegion(){ public TextureRegion getIconRegion(){
return mech.iconRegion; return mech.icon(Cicon.full);
} }
@Override @Override
@@ -281,7 +281,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
public void drawShadow(float offsetX, float offsetY){ public void drawShadow(float offsetX, float offsetY){
float scl = mech.flying ? 1f : boostHeat / 2f; float scl = mech.flying ? 1f : boostHeat / 2f;
Draw.rect(mech.iconRegion, x + offsetX * scl, y + offsetY * scl, rotation - 90); Draw.rect(getIconRegion(), x + offsetX * scl, y + offsetY * scl, rotation - 90);
} }
@Override @Override

View File

@@ -216,10 +216,14 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
float cx = x - fsize/2f, cy = y - fsize/2f; float cx = x - fsize/2f, cy = y - fsize/2f;
for(Team team : Team.all){ for(Team team : Team.all){
if(team != getTeam() || !(this instanceof Player)){
avoid(unitGroups[team.ordinal()].intersect(cx, cy, fsize, fsize)); avoid(unitGroups[team.ordinal()].intersect(cx, cy, fsize, fsize));
} }
}
if(!(this instanceof Player)){
avoid(playerGroup.intersect(cx, cy, fsize, fsize)); avoid(playerGroup.intersect(cx, cy, fsize, fsize));
}
velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta()); velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta());
} }
@@ -227,15 +231,14 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
float radScl = 1.5f; float radScl = 1.5f;
for(Unit en : arr){ for(Unit en : arr){
if(en.isFlying() != isFlying()) continue; if(en.isFlying() != isFlying() || (en instanceof Player && en.getTeam() != getTeam())) continue;
float dst = dst(en); float dst = dst(en);
float scl = Mathf.clamp(1f - dst / (getSize()/(radScl*2f) + en.getSize()/(radScl*2f))); float scl = Mathf.clamp(1f - dst / (getSize()/(radScl*2f) + en.getSize()/(radScl*2f)));
moveVector.add(Tmp.v1.set((x - en.x) * scl, (y - en.y) * scl).limit(0.4f)); moveVector.add(Tmp.v1.set((x - en.x) * scl, (y - en.y) * scl).limit(0.4f));
} }
} }
public @Nullable public @Nullable TileEntity getClosestCore(){
TileEntity getClosestCore(){
TeamData data = state.teams.get(team); TeamData data = state.teams.get(team);
Tile tile = Geometry.findClosest(x, y, data.cores); Tile tile = Geometry.findClosest(x, y, data.cores);
@@ -404,7 +407,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
float size = (itemSize + Mathf.absin(Time.time(), 5f, 1f)) * itemtime; float size = (itemSize + Mathf.absin(Time.time(), 5f, 1f)) * itemtime;
Draw.mixcol(Pal.accent, Mathf.absin(Time.time(), 5f, 0.5f)); Draw.mixcol(Pal.accent, Mathf.absin(Time.time(), 5f, 0.5f));
Draw.rect(item.item.icon(Item.Icon.large), Draw.rect(item.item.icon(Cicon.medium),
x + Angles.trnsx(rotation + 180f, backTrns), x + Angles.trnsx(rotation + 180f, backTrns),
y + Angles.trnsy(rotation + 180f, backTrns), y + Angles.trnsy(rotation + 180f, backTrns),
size, size, rotation); size, size, rotation);

View File

@@ -0,0 +1,23 @@
package io.anuke.mindustry.game;
import java.util.*;
/** Defines sizes of a content's preview icon. */
public enum Cicon{
/** Full size. */
full(0),
tiny(8 * 2),
small(8 * 3),
medium(8 * 4),
large(8 * 5),
xlarge(8 * 6);
public static final Cicon[] all = values();
public static final Cicon[] scaled = Arrays.copyOfRange(all, 1, all.length);
public final int size;
Cicon(int size){
this.size = size;
}
}

View File

@@ -1,12 +1,16 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.ContentType;
/** Base class for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}. */ /** Base class for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}. */
public abstract class Content{ public abstract class Content{
public final short id; public final short id;
/** The mod that loaded this piece of content. */
public @Nullable LoadedMod mod;
public Content(){ public Content(){
this.id = (short)Vars.content.getBy(getContentType()).size; this.id = (short)Vars.content.getBy(getContentType()).size;

View File

@@ -83,6 +83,10 @@ public class EventType{
} }
public static class ContentReloadEvent{
}
public static class DisposeEvent{ public static class DisposeEvent{
} }

View File

@@ -1,10 +1,13 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.mindustry.*;
public abstract class MappableContent extends Content{ public abstract class MappableContent extends Content{
public final String name; public final String name;
public MappableContent(String name){ public MappableContent(String name){
this.name = name; this.name = name;
Vars.content.handleMappableContent(this);
} }
@Override @Override

View File

@@ -7,6 +7,7 @@ import io.anuke.arc.files.*;
import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.arc.util.async.*; import io.anuke.arc.util.async.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.core.GameState.*; import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.io.*; import io.anuke.mindustry.io.*;
@@ -253,6 +254,17 @@ public class Saves{
return meta.map; return meta.map;
} }
public void cautiousLoad(Runnable run){
Array<String> mods = Array.with(getMods());
mods.removeAll(Vars.mods.getModStrings());
if(!mods.isEmpty()){
ui.showConfirm("$warning", Core.bundle.format("mod.missing", mods.toString("\n")), run);
}else{
run.run();
}
}
public String getName(){ public String getName(){
return Core.settings.getString("save-" + index + "-name", "untitled"); return Core.settings.getString("save-" + index + "-name", "untitled");
} }

View File

@@ -1,9 +1,10 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.arc.Core; import io.anuke.annotations.Annotations.*;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.graphics.g2d.*;
import io.anuke.mindustry.Vars; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.*;
/** Base interface for an unlockable content type. */ /** Base interface for an unlockable content type. */
public abstract class UnlockableContent extends MappableContent{ public abstract class UnlockableContent extends MappableContent{
@@ -11,6 +12,8 @@ public abstract class UnlockableContent extends MappableContent{
public String localizedName; public String localizedName;
/** Localized description. May be null. */ /** Localized description. May be null. */
public String description; public String description;
/** Icons by Cicon ID.*/
protected TextureRegion[] cicons = new TextureRegion[Cicon.all.length];
public UnlockableContent(String name){ public UnlockableContent(String name){
super(name); super(name);
@@ -19,10 +22,24 @@ public abstract class UnlockableContent extends MappableContent{
this.description = Core.bundle.getOrNull(getContentType() + "." + name + ".description"); this.description = Core.bundle.getOrNull(getContentType() + "." + name + ".description");
} }
/** Generate any special icons for this content. Called asynchronously.*/
@CallSuper
public void createIcons(PixmapPacker out, PixmapPacker editor){
}
/** Returns a specific content icon, or the region {contentType}-{name} if not found.*/
public TextureRegion icon(Cicon icon){
if(cicons[icon.ordinal()] == null){
cicons[icon.ordinal()] = Core.atlas.find(getContentType().name() + "-" + name + "-" + icon.name(), Core.atlas.find(getContentType().name() + "-" + name + "-full", Core.atlas.find(getContentType().name() + "-" + name, Core.atlas.find(name))));
}
return cicons[icon.ordinal()];
}
/** Returns the localized name of this content. */ /** Returns the localized name of this content. */
public abstract String localizedName(); public abstract String localizedName();
public abstract TextureRegion getContentIcon(); //public abstract TextureRegion getContentIcon();
/** This should show all necessary info about this content in the specified table. */ /** This should show all necessary info about this content in the specified table. */
public abstract void displayInfo(Table table); public abstract void displayInfo(Table table);

View File

@@ -132,7 +132,7 @@ public class BlockRenderer implements Disposable{
Draw.alpha(0.5f); Draw.alpha(0.5f);
Draw.mixcol(Pal.accent, 0.2f + Mathf.absin(5f, 0.2f)); Draw.mixcol(Pal.accent, 0.2f + Mathf.absin(5f, 0.2f));
Draw.rect(b.icon(Icon.full), block.x * tilesize + b.offset(), block.y * tilesize + b.offset(), b.rotate ? block.rotation * 90 : 0f); Draw.rect(b.icon(Cicon.full), block.x * tilesize + b.offset(), block.y * tilesize + b.offset(), b.rotate ? block.rotation * 90 : 0f);
} }
Draw.reset(); Draw.reset();
} }

View File

@@ -14,6 +14,7 @@ import io.anuke.arc.util.noise.RidgedPerlin;
import io.anuke.arc.util.noise.Simplex; import io.anuke.arc.util.noise.Simplex;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.content.UnitTypes; import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.UnitType; import io.anuke.mindustry.type.UnitType;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.Floor;
@@ -252,7 +253,9 @@ public class MenuRenderer implements Disposable{
private void drawFlyers(){ private void drawFlyers(){
Draw.color(0f, 0f, 0f, 0.4f); Draw.color(0f, 0f, 0f, 0.4f);
float size = Math.max(flyerType.iconRegion.getWidth(), flyerType.iconRegion.getHeight()) * Draw.scl * 1.6f; TextureRegion icon = flyerType.icon(Cicon.full);
float size = Math.max(icon.getWidth(), icon.getHeight()) * Draw.scl * 1.6f;
flyers((x, y) -> { flyers((x, y) -> {
Draw.rect(flyerType.region, x - 12f, y - 13f, flyerRot - 90); Draw.rect(flyerType.region, x - 12f, y - 13f, flyerRot - 90);

View File

@@ -106,7 +106,7 @@ public class MinimapRenderer implements Disposable{
public void updateAll(){ public void updateAll(){
for(int x = 0; x < world.width(); x++){ for(int x = 0; x < world.width(); x++){
for(int y = 0; y < world.height(); y++){ for(int y = 0; y < world.height(); y++){
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(world.tile(x, y))); pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(world.tile(x, y)));
} }
} }
texture.draw(pixmap, 0, 0); texture.draw(pixmap, 0, 0);
@@ -114,7 +114,7 @@ public class MinimapRenderer implements Disposable{
public void update(Tile tile){ public void update(Tile tile){
int color = colorFor(world.tile(tile.x, tile.y)); int color = colorFor(world.tile(tile.x, tile.y));
pixmap.drawPixel(tile.x, pixmap.getHeight() - 1 - tile.y, color); pixmap.draw(tile.x, pixmap.getHeight() - 1 - tile.y, color);
Pixmaps.drawPixel(texture, tile.x, pixmap.getHeight() - 1 - tile.y, color); Pixmaps.drawPixel(texture, tile.x, pixmap.getHeight() - 1 - tile.y, color);
} }

View File

@@ -1,21 +1,18 @@
package io.anuke.mindustry.graphics; package io.anuke.mindustry.graphics;
import io.anuke.arc.Core; import io.anuke.arc.*;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.*;
import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.*;
import io.anuke.arc.util.Time; import io.anuke.mindustry.*;
import io.anuke.arc.util.Tmp; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.input.*; import io.anuke.mindustry.input.*;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -125,7 +122,7 @@ public class OverlayRenderer{
if(input.isDroppingItem()){ if(input.isDroppingItem()){
Vector2 v = Core.input.mouseWorld(input.getMouseX(), input.getMouseY()); Vector2 v = Core.input.mouseWorld(input.getMouseX(), input.getMouseY());
float size = 8; float size = 8;
Draw.rect(player.item().item.icon(Item.Icon.large), v.x, v.y, size, size); Draw.rect(player.item().item.icon(Cicon.medium), v.x, v.y, size, size);
Draw.color(Pal.accent); Draw.color(Pal.accent);
Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f)); Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f));
Draw.reset(); Draw.reset();

View File

@@ -81,8 +81,8 @@ public class MapIO{
super.setBlock(type); super.setBlock(type);
int c = colorFor(Blocks.air, block(), Blocks.air, getTeam()); int c = colorFor(Blocks.air, block(), Blocks.air, getTeam());
if(c != black){ if(c != black){
walls.drawPixel(x, floors.getHeight() - 1 - y, c); walls.draw(x, floors.getHeight() - 1 - y, c);
floors.drawPixel(x, floors.getHeight() - 1 - y + 1, shade); floors.draw(x, floors.getHeight() - 1 - y + 1, shade);
} }
} }
@@ -112,9 +112,9 @@ public class MapIO{
@Override @Override
public Tile create(int x, int y, int floorID, int overlayID, int wallID){ public Tile create(int x, int y, int floorID, int overlayID, int wallID){
if(overlayID != 0){ if(overlayID != 0){
floors.drawPixel(x, floors.getHeight() - 1 - y, colorFor(Blocks.air, Blocks.air, content.block(overlayID), Team.derelict)); floors.draw(x, floors.getHeight() - 1 - y, colorFor(Blocks.air, Blocks.air, content.block(overlayID), Team.derelict));
}else{ }else{
floors.drawPixel(x, floors.getHeight() - 1 - y, colorFor(content.block(floorID), Blocks.air, Blocks.air, Team.derelict)); floors.draw(x, floors.getHeight() - 1 - y, colorFor(content.block(floorID), Blocks.air, Blocks.air, Team.derelict));
} }
if(content.block(overlayID) == Blocks.spawn){ if(content.block(overlayID) == Blocks.spawn){
map.spawns ++; map.spawns ++;
@@ -136,7 +136,7 @@ public class MapIO{
for(int x = 0; x < pixmap.getWidth(); x++){ for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){ for(int y = 0; y < pixmap.getHeight(); y++){
Tile tile = tiles[x][y]; Tile tile = tiles[x][y];
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam())); pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
} }
} }
return pixmap; return pixmap;

View File

@@ -66,7 +66,7 @@ public abstract class SaveVersion extends SaveFileReader{
"wavetime", state.wavetime, "wavetime", state.wavetime,
"stats", JsonIO.write(state.stats), "stats", JsonIO.write(state.stats),
"rules", JsonIO.write(state.rules), "rules", JsonIO.write(state.rules),
"mods", JsonIO.write(mods.getModNames().toArray(String.class)), "mods", JsonIO.write(mods.getModStrings().toArray(String.class)),
"width", world.width(), "width", world.width(),
"height", world.height() "height", world.height()
).merge(tags)); ).merge(tags));

View File

@@ -8,20 +8,20 @@ import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.*; import io.anuke.mindustry.*;
import io.anuke.mindustry.content.*; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.ui.dialogs.*; import io.anuke.mindustry.ui.dialogs.*;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Block.*;
import io.anuke.mindustry.world.blocks.*; import io.anuke.mindustry.world.blocks.*;
import static io.anuke.mindustry.Vars.updateEditorOnChange; import static io.anuke.mindustry.Vars.updateEditorOnChange;
public abstract class FilterOption{ public abstract class FilterOption{
public static final Predicate<Block> floorsOnly = b -> (b instanceof Floor && !(b instanceof OverlayFloor)) && Core.atlas.isFound(b.icon(Icon.full)); public static final Predicate<Block> floorsOnly = b -> (b instanceof Floor && !(b instanceof OverlayFloor)) && Core.atlas.isFound(b.icon(Cicon.full));
public static final Predicate<Block> wallsOnly = b -> (!b.synthetic() && !(b instanceof Floor)) && Core.atlas.isFound(b.icon(Icon.full)); public static final Predicate<Block> wallsOnly = b -> (!b.synthetic() && !(b instanceof Floor)) && Core.atlas.isFound(b.icon(Cicon.full));
public static final Predicate<Block> floorsOptional = b -> b == Blocks.air || ((b instanceof Floor && !(b instanceof OverlayFloor)) && Core.atlas.isFound(b.icon(Icon.full))); public static final Predicate<Block> floorsOptional = b -> b == Blocks.air || ((b instanceof Floor && !(b instanceof OverlayFloor)) && Core.atlas.isFound(b.icon(Cicon.full)));
public static final Predicate<Block> wallsOptional = b -> b == Blocks.air || ((!b.synthetic() && !(b instanceof Floor)) && Core.atlas.isFound(b.icon(Icon.full))); public static final Predicate<Block> wallsOptional = b -> b == Blocks.air || ((!b.synthetic() && !(b instanceof Floor)) && Core.atlas.isFound(b.icon(Cicon.full)));
public static final Predicate<Block> wallsOresOptional = b -> b == Blocks.air || (((!b.synthetic() && !(b instanceof Floor)) || (b instanceof OverlayFloor)) && Core.atlas.isFound(b.icon(Icon.full))); public static final Predicate<Block> wallsOresOptional = b -> b == Blocks.air || (((!b.synthetic() && !(b instanceof Floor)) || (b instanceof OverlayFloor)) && Core.atlas.isFound(b.icon(Cicon.full)));
public static final Predicate<Block> oresOnly = b -> b instanceof OverlayFloor && Core.atlas.isFound(b.icon(Icon.full)); public static final Predicate<Block> oresOnly = b -> b instanceof OverlayFloor && Core.atlas.isFound(b.icon(Cicon.full));
public static final Predicate<Block> anyOptional = b -> floorsOnly.test(b) || wallsOnly.test(b) || oresOnly.test(b) || b == Blocks.air; public static final Predicate<Block> anyOptional = b -> floorsOnly.test(b) || wallsOnly.test(b) || oresOnly.test(b) || b == Blocks.air;
public abstract void build(Table table); public abstract void build(Table table);
@@ -76,15 +76,15 @@ public abstract class FilterOption{
@Override @Override
public void build(Table table){ public void build(Table table){
table.addButton(b -> b.addImage(supplier.get().icon(Icon.small)).update(i -> ((TextureRegionDrawable)i.getDrawable()) table.addButton(b -> b.addImage(supplier.get().icon(Cicon.small)).update(i -> ((TextureRegionDrawable)i.getDrawable())
.setRegion(supplier.get() == Blocks.air ? Core.atlas.find("icon-none") : supplier.get().icon(Icon.small))).size(8 * 3), () -> { .setRegion(supplier.get() == Blocks.air ? Core.atlas.find("icon-none") : supplier.get().icon(Cicon.small))).size(8 * 3), () -> {
FloatingDialog dialog = new FloatingDialog(""); FloatingDialog dialog = new FloatingDialog("");
dialog.setFillParent(false); dialog.setFillParent(false);
int i = 0; int i = 0;
for(Block block : Vars.content.blocks()){ for(Block block : Vars.content.blocks()){
if(!filter.test(block)) continue; if(!filter.test(block)) continue;
dialog.cont.addImage(block == Blocks.air ? Core.atlas.find("icon-none-small") : block.icon(Icon.medium)).size(8 * 4).pad(3).get().clicked(() -> { dialog.cont.addImage(block == Blocks.air ? Core.atlas.find("icon-none-small") : block.icon(Cicon.medium)).size(8 * 4).pad(3).get().clicked(() -> {
consumer.accept(block); consumer.accept(block);
dialog.hide(); dialog.hide();
changed.run(); changed.run();

View File

@@ -1,7 +1,10 @@
package io.anuke.mindustry.mod; package io.anuke.mindustry.mod;
import io.anuke.arc.*;
import io.anuke.arc.audio.*;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.*;
import io.anuke.arc.function.*; import io.anuke.arc.function.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.arc.util.reflect.*; import io.anuke.arc.util.reflect.*;
@@ -13,6 +16,8 @@ import io.anuke.mindustry.entities.Effects.*;
import io.anuke.mindustry.entities.bullet.*; import io.anuke.mindustry.entities.bullet.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.*;
@@ -23,7 +28,30 @@ public class ContentParser{
private ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<Class<?>, FieldParser>(){{ private ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<Class<?>, FieldParser>(){{
put(BulletType.class, (type, data) -> field(Bullets.class, data)); put(BulletType.class, (type, data) -> field(Bullets.class, data));
put(Effect.class, (type, data) -> field(Fx.class, data)); put(Effect.class, (type, data) -> field(Fx.class, data));
put(StatusEffect.class, (type, data) -> field(StatusEffects.class, data));
put(Color.class, (type, data) -> Color.valueOf(data.asString()));
put(Music.class, (type, data) -> {
if(fieldOpt(Musics.class, data) != null) return fieldOpt(Musics.class, data);
String path = "music/" + data.asString() + (Vars.ios ? ".mp3" : ".ogg");
Core.assets.load(path, Music.class);
Core.assets.finishLoadingAsset(path);
return Core.assets.get(path);
});
put(Sound.class, (type, data) -> {
if(fieldOpt(Sounds.class, data) != null) return fieldOpt(Sounds.class, data);
String path = "sounds/" + data.asString() + (Vars.ios ? ".mp3" : ".ogg");
Core.assets.load(path, Sound.class);
Core.assets.finishLoadingAsset(path);
Log.info(Core.assets.get(path));
return Core.assets.get(path);
});
}}; }};
/** Stores things that need to be parsed fully, e.g. reading fields of content.
* This is done to accomodate binding of content names first.*/
private Array<Runnable> reads = new Array<>();
private LoadedMod currentMod;
private Json parser = new Json(){ private Json parser = new Json(){
public <T> T readValue(Class<T> type, Class elementType, JsonValue jsonData){ public <T> T readValue(Class<T> type, Class elementType, JsonValue jsonData){
@@ -33,7 +61,11 @@ public class ContentParser{
} }
if(Content.class.isAssignableFrom(type)){ if(Content.class.isAssignableFrom(type)){
return (T)Vars.content.getByName(contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName())), jsonData.asString()); ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName()));
String prefix = currentMod != null ? currentMod.name + "-" : "";
T one = (T)Vars.content.getByName(ctype, prefix + jsonData.asString());
if(one != null) return one;
return (T)Vars.content.getByName(ctype, jsonData.asString());
} }
} }
@@ -43,21 +75,67 @@ public class ContentParser{
private ObjectMap<ContentType, TypeParser<?>> parsers = ObjectMap.of( private ObjectMap<ContentType, TypeParser<?>> parsers = ObjectMap.of(
ContentType.block, (TypeParser<Block>)(mod, name, value) -> { ContentType.block, (TypeParser<Block>)(mod, name, value) -> {
Class<Block> type = resolve(value.getString("type"), "io.anuke.mindustry.world", "io.anuke.mindustry.world.blocks", "io.anuke.mindustry.world.blocks.defense"); //TODO generate dynamically instead of doing.. this
Class<? extends Block> type = resolve(value.getString("type"),
"io.anuke.mindustry.world",
"io.anuke.mindustry.world.blocks",
"io.anuke.mindustry.world.blocks.defense",
"io.anuke.mindustry.world.blocks.defense.turrets",
"io.anuke.mindustry.world.blocks.distribution",
"io.anuke.mindustry.world.blocks.logic",
"io.anuke.mindustry.world.blocks.power",
"io.anuke.mindustry.world.blocks.production",
"io.anuke.mindustry.world.blocks.sandbox",
"io.anuke.mindustry.world.blocks.storage",
"io.anuke.mindustry.world.blocks.units"
);
Block block = type.getDeclaredConstructor(String.class).newInstance(mod + "-" + name); Block block = type.getDeclaredConstructor(String.class).newInstance(mod + "-" + name);
read(() -> {
if(value.has("consumes")){
for(JsonValue child : value.get("consumes")){
if(child.name.equals("item")){
if(child.isString()){
block.consumes.item(Vars.content.getByName(ContentType.item, child.asString()));
}else{
ItemStack stack = parser.readValue(ItemStack.class, child);
block.consumes.item(stack.item, stack.amount);
}
}else if(child.name.equals("items")){
block.consumes.items(parser.readValue(ItemStack[].class, child));
}else if(child.name.equals("liquid")){
LiquidStack stack = parser.readValue(LiquidStack.class, child);
block.consumes.liquid(stack.liquid, stack.amount);
}else if(child.name.equals("power")){
block.consumes.power(child.asFloat());
}else if(child.name.equals("powerBuffered")){
block.consumes.powerBuffered(child.asFloat());
}else{
throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'.");
}
}
value.remove("consumes");
}
readFields(block, value, true); readFields(block, value, true);
//add research tech node
if(value.has("research")){
TechTree.create(Vars.content.getByName(ContentType.block, value.get("research").asString()), block);
}
//make block visible //make block visible
if(block.buildRequirements != null){ if(value.has("requirements")){
block.buildVisibility = () -> true; block.buildVisibility = () -> true;
} }
});
return block; return block;
}, },
ContentType.unit, (TypeParser<UnitType>)(mod, name, value) -> { ContentType.unit, (TypeParser<UnitType>)(mod, name, value) -> {
Class<BaseUnit> type = resolve(value.getString("type"), "io.anuke.mindustry.entities.type.base"); Class<BaseUnit> type = resolve(value.getString("type"), "io.anuke.mindustry.entities.type.base");
UnitType unit = new UnitType(mod + "-" + name, supply(type)); UnitType unit = new UnitType(mod + "-" + name, supply(type));
readFields(unit, value, true); read(() -> readFields(unit, value, true));
return unit; return unit;
}, },
@@ -75,11 +153,20 @@ public class ContentParser{
}else{ }else{
item = constructor.get(mod + "-" + name); item = constructor.get(mod + "-" + name);
} }
readFields(item, value); read(() -> readFields(item, value));
return item; return item;
}; };
} }
/** Call to read a content's extra info later.*/
private void read(Runnable run){
LoadedMod mod = currentMod;
reads.add(() -> {
this.currentMod = mod;
run.run();
});
}
private void init(){ private void init(){
for(ContentType type : ContentType.all){ for(ContentType type : ContentType.all){
Array<Content> arr = Vars.content.getBy(type); Array<Content> arr = Vars.content.getBy(type);
@@ -95,6 +182,11 @@ public class ContentParser{
} }
} }
public void finishParsing(){
reads.each(Runnable::run);
reads.clear();
}
/** /**
* Parses content from a json file. * Parses content from a json file.
* @param name the name of the file without its extension * @param name the name of the file without its extension
@@ -102,7 +194,7 @@ public class ContentParser{
* @param type the type of content this is * @param type the type of content this is
* @return the content that was parsed * @return the content that was parsed
*/ */
public Content parse(String mod, String name, String json, ContentType type) throws Exception{ public Content parse(LoadedMod mod, String name, String json, ContentType type) throws Exception{
if(contentTypes.isEmpty()){ if(contentTypes.isEmpty()){
init(); init();
} }
@@ -112,7 +204,9 @@ public class ContentParser{
throw new SerializationException("No parsers for content type '" + type + "'"); throw new SerializationException("No parsers for content type '" + type + "'");
} }
Content c = parsers.get(type).parse(mod, name, value); currentMod = mod;
Content c = parsers.get(type).parse(mod.name, name, value);
c.mod = mod;
checkNulls(c); checkNulls(c);
return c; return c;
} }
@@ -147,6 +241,16 @@ public class ContentParser{
} }
} }
private Object fieldOpt(Class<?> type, JsonValue value){
try{
Object b = type.getField(value.asString()).get(null);
if(b == null) return null;
return b;
}catch(Exception e){
return null;
}
}
/** Checks all @NonNull fields in this object, recursively. /** Checks all @NonNull fields in this object, recursively.
* Throws an exception if any are null.*/ * Throws an exception if any are null.*/
private void checkNulls(Object object){ private void checkNulls(Object object){
@@ -187,7 +291,9 @@ public class ContentParser{
FieldMetadata metadata = fields.get(child.name().replace(" ", "_")); FieldMetadata metadata = fields.get(child.name().replace(" ", "_"));
if(metadata == null){ if(metadata == null){
if(ignoreUnknownFields){ if(ignoreUnknownFields){
if(!child.name.equals("research")){
Log.err("{0}: Ignoring unknown field: " + child.name + " (" + type.getName() + ")", object); Log.err("{0}: Ignoring unknown field: " + child.name + " (" + type.getName() + ")", object);
}
continue; continue;
}else{ }else{
SerializationException ex = new SerializationException("Field not found: " + child.name + " (" + type.getName() + ")"); SerializationException ex = new SerializationException("Field not found: " + child.name + " (" + type.getName() + ")");

View File

@@ -9,13 +9,16 @@ import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.Pixmap.*; import io.anuke.arc.graphics.Pixmap.*;
import io.anuke.arc.graphics.Texture.*; import io.anuke.arc.graphics.Texture.*;
import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.graphics.g2d.TextureAtlas.*;
import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.arc.util.io.*; import io.anuke.arc.util.io.*;
import io.anuke.arc.util.serialization.*; import io.anuke.arc.util.serialization.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.plugin.*; import io.anuke.mindustry.plugin.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
@@ -32,8 +35,9 @@ public class Mods implements Loadable{
private PixmapPacker packer; private PixmapPacker packer;
private Array<LoadedMod> loaded = new Array<>(); private Array<LoadedMod> loaded = new Array<>();
private Array<LoadedMod> disabled = new Array<>();
private ObjectMap<Class<?>, ModMeta> metas = new ObjectMap<>(); private ObjectMap<Class<?>, ModMeta> metas = new ObjectMap<>();
private boolean requiresRestart; private boolean requiresReload;
/** Returns a file named 'config.json' in a special folder for the specified plugin. /** Returns a file named 'config.json' in a special folder for the specified plugin.
* Call this in init(). */ * Call this in init(). */
@@ -59,7 +63,7 @@ public class Mods implements Loadable{
file.copyTo(dest); file.copyTo(dest);
try{ try{
loaded.add(loadMod(file)); loaded.add(loadMod(file));
requiresRestart = true; requiresReload = true;
}catch(IOException e){ }catch(IOException e){
dest.delete(); dest.delete();
throw e; throw e;
@@ -75,42 +79,68 @@ public class Mods implements Loadable{
if(loaded.isEmpty()) return; if(loaded.isEmpty()) return;
packer = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true); packer = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true);
for(LoadedMod mod : loaded){ for(LoadedMod mod : loaded){
try{ int[] packed = {0};
int packed = 0; boolean[] failed = {false};
for(FileHandle file : mod.root.child("sprites").list()){ mod.root.child("sprites").walk(file -> {
if(failed[0]) return;
if(file.extension().equals("png")){ if(file.extension().equals("png")){
try(InputStream stream = file.read()){ try(InputStream stream = file.read()){
byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512)); byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512));
Pixmap pixmap = new Pixmap(bytes, 0, bytes.length); Pixmap pixmap = new Pixmap(bytes, 0, bytes.length);
packer.pack(mod.name + "-" + file.nameWithoutExtension(), pixmap); packer.pack(mod.name + "-" + file.nameWithoutExtension(), pixmap);
pixmap.dispose(); pixmap.dispose();
packed ++; packed[0] ++;
totalSprites ++; totalSprites ++;
}
}
}
Log.info("Packed {0} images for mod '{1}'.", packed, mod.meta.name);
}catch(IOException e){ }catch(IOException e){
failed[0] = true;
Core.app.post(() -> {
Log.err("Error packing images for mod: {0}", mod.meta.name); Log.err("Error packing images for mod: {0}", mod.meta.name);
e.printStackTrace(); e.printStackTrace();
if(!headless) ui.showException(e); if(!headless) ui.showException(e);
});
} }
} }
});
Log.info("Packed {0} images for mod '{1}'.", packed[0], mod.meta.name);
}
} }
@Override @Override
public void loadSync(){ public void loadSync(){
if(packer == null) return; if(packer == null) return;
Texture editor = Core.atlas.find("clear-editor").getTexture();
PixmapPacker editorPacker = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true);
for(AtlasRegion region : Core.atlas.getRegions()){
if(region.getTexture() == editor){
editorPacker.pack(region.name, Core.atlas.getPixmap(region).crop());
}
}
//get textures packed //get textures packed
if(totalSprites > 0){ if(totalSprites > 0){
TextureFilter filter = Core.settings.getBool("linear") ? TextureFilter.Linear : TextureFilter.Nearest; TextureFilter filter = Core.settings.getBool("linear") ? TextureFilter.Linear : TextureFilter.Nearest;
packer.getPages().each(page -> page.updateTexture(filter, filter, false));
packer.getPages().each(page -> page.getRects().each((name, rect) -> Core.atlas.addRegion(name, page.getTexture(), (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height))); packer.updateTextureAtlas(Core.atlas, filter, filter, false);
//generate new icons
for(Array<Content> arr : content.getContentMap()){
arr.each(c -> {
if(c instanceof UnlockableContent && c.mod != null){
UnlockableContent u = (UnlockableContent)c;
u.createIcons(packer, editorPacker);
}
});
}
editorPacker.updateTextureAtlas(Core.atlas, filter, filter, false);
packer.updateTextureAtlas(Core.atlas, filter, filter, false);
} }
packer.dispose(); packer.dispose();
packer = null;
} }
/** Removes a mod file and marks it for requiring a restart. */ /** Removes a mod file and marks it for requiring a restart. */
@@ -121,11 +151,11 @@ public class Mods implements Loadable{
mod.file.delete(); mod.file.delete();
} }
loaded.remove(mod); loaded.remove(mod);
requiresRestart = true; requiresReload = true;
} }
public boolean requiresRestart(){ public boolean requiresReload(){
return requiresRestart; return requiresReload;
} }
/** Loads all mods from the folder, but does call any methods on them.*/ /** Loads all mods from the folder, but does call any methods on them.*/
@@ -134,7 +164,12 @@ public class Mods implements Loadable{
if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && file.child("mod.json").exists())) continue; if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && file.child("mod.json").exists())) continue;
try{ try{
loaded.add(loadMod(file)); LoadedMod mod = loadMod(file);
if(mod.enabled()){
loaded.add(mod);
}else{
disabled.add(mod);
}
}catch(IllegalArgumentException ignored){ }catch(IllegalArgumentException ignored){
}catch(Exception e){ }catch(Exception e){
Log.err("Failed to load plugin file {0}. Skipping.", file); Log.err("Failed to load plugin file {0}. Skipping.", file);
@@ -154,7 +189,7 @@ public class Mods implements Loadable{
//ignore special folders like bundles or sprites //ignore special folders like bundles or sprites
if(file.isDirectory() && !specialFolders.contains(file.name())){ if(file.isDirectory() && !specialFolders.contains(file.name())){
//TODO calling child/parent on these files will give you gibberish; create wrapper class. //TODO calling child/parent on these files will give you gibberish; create wrapper class.
file.walk(f -> tree.addFile(f)); file.walk(f -> tree.addFile(mod.file.isDirectory() ? f.path().substring(1 + mod.file.path().length()) : f.path(), f));
} }
} }
@@ -186,6 +221,31 @@ public class Mods implements Loadable{
} }
} }
/** Reloads all mod content. How does this even work? I refuse to believe that it functions correctly.*/
public void reloadContent(){
//epic memory leak
Core.atlas = new TextureAtlas(Core.files.internal("sprites/sprites.atlas"));
Tex.load();
Tex.loadStyles();
Styles.load();
loaded.clear();
disabled.clear();
load();
buildFiles();
Musics.dispose();
Sounds.dispose();
Musics.load();
Sounds.load();
Core.assets.finishLoading();
content.clear();
content.createContent();
loadAsync();
loadSync();
content.init();
content.load();
content.loadColors();
}
/** Creates all the content found in mod files. */ /** Creates all the content found in mod files. */
public void loadContent(){ public void loadContent(){
for(LoadedMod mod : loaded){ for(LoadedMod mod : loaded){
@@ -197,7 +257,8 @@ public class Mods implements Loadable{
for(FileHandle file : folder.list()){ for(FileHandle file : folder.list()){
if(file.extension().equals("json")){ if(file.extension().equals("json")){
try{ try{
Content loaded = parser.parse(mod.name, file.nameWithoutExtension(), file.readString(), type); //this binds the content but does not load it entirely
Content loaded = parser.parse(mod, file.nameWithoutExtension(), file.readString(), type);
Log.info("[{0}] Loaded '{1}'.", mod.meta.name, loaded); Log.info("[{0}] Loaded '{1}'.", mod.meta.name, loaded);
}catch(Exception e){ }catch(Exception e){
throw new RuntimeException("Failed to parse content file '" + file + "' for mod '" + mod.meta.name + "'.", e); throw new RuntimeException("Failed to parse content file '" + file + "' for mod '" + mod.meta.name + "'.", e);
@@ -209,6 +270,9 @@ public class Mods implements Loadable{
} }
} }
//this finishes parsing content fields
parser.finishParsing();
each(Mod::loadContent); each(Mod::loadContent);
} }
@@ -217,6 +281,11 @@ public class Mods implements Loadable{
return loaded; return loaded;
} }
/** @return all disabled mods. */
public Array<LoadedMod> disabled(){
return disabled;
}
/** @return a list of mod names only, without versions. */ /** @return a list of mod names only, without versions. */
public Array<String> getModNames(){ public Array<String> getModNames(){
return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version); return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version);
@@ -227,8 +296,23 @@ public class Mods implements Loadable{
return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version); return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version);
} }
/** Makes a mod enabled or disabled. shifts it.*/
public void setEnabled(LoadedMod mod, boolean enabled){
if(mod.enabled() != enabled){
Core.settings.putSave(mod.name + "-enabled", enabled);
requiresReload = true;
if(!enabled){
loaded.remove(mod);
disabled.add(mod);
}else{
loaded.add(mod);
disabled.remove(mod);
}
}
}
/** @return the mods that the client is missing. /** @return the mods that the client is missing.
* The inputted array is changed to contain the extra mods that the client has but the server does.*/ * The inputted array is changed to contain the extra mods that the client has but the server doesn't.*/
public Array<String> getIncompatibility(Array<String> out){ public Array<String> getIncompatibility(Array<String> out){
Array<String> mods = getModStrings(); Array<String> mods = getModStrings();
Array<String> result = mods.copy(); Array<String> result = mods.copy();
@@ -272,8 +356,8 @@ public class Mods implements Loadable{
//make sure the main class exists before loading it; if it doesn't just don't put it there //make sure the main class exists before loading it; if it doesn't just don't put it there
if(mainFile.exists()){ if(mainFile.exists()){
//other platforms don't have standard java class loaders //other platforms don't have standard java class loaders
if(mobile){ if(!headless && Version.build != -1){
throw new IllegalArgumentException("This mod is not compatible with " + (ios ? "iOS" : "Android") + "."); throw new IllegalArgumentException("Java class mods are currently unsupported outside of custom builds.");
} }
URLClassLoader classLoader = new URLClassLoader(new URL[]{sourceFile.file().toURI().toURL()}, ClassLoader.getSystemClassLoader()); URLClassLoader classLoader = new URLClassLoader(new URL[]{sourceFile.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
@@ -305,9 +389,6 @@ public class Mods implements Loadable{
/** This mod's metadata. */ /** This mod's metadata. */
public final ModMeta meta; public final ModMeta meta;
//TODO implement
protected boolean enabled;
public LoadedMod(FileHandle file, FileHandle root, Mod mod, ModMeta meta){ public LoadedMod(FileHandle file, FileHandle root, Mod mod, ModMeta meta){
this.root = root; this.root = root;
this.file = file; this.file = file;
@@ -315,6 +396,10 @@ public class Mods implements Loadable{
this.meta = meta; this.meta = meta;
this.name = meta.name.toLowerCase().replace(" ", "-"); this.name = meta.name.toLowerCase().replace(" ", "-");
} }
public boolean enabled(){
return Core.settings.getBool(name + "-enabled", true);
}
} }
/** Plugin metadata information.*/ /** Plugin metadata information.*/

View File

@@ -3,7 +3,6 @@ package io.anuke.mindustry.type;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.*;
import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
@@ -13,7 +12,6 @@ import static io.anuke.mindustry.Vars.content;
public class Item extends UnlockableContent implements Comparable<Item>{ public class Item extends UnlockableContent implements Comparable<Item>{
public final Color color; public final Color color;
private TextureRegion[] regions;
/** type of the item; used for tabs and core acceptance. default value is {@link ItemType#resource}. */ /** type of the item; used for tabs and core acceptance. default value is {@link ItemType#resource}. */
public ItemType type = ItemType.resource; public ItemType type = ItemType.resource;
@@ -43,19 +41,6 @@ public class Item extends UnlockableContent implements Comparable<Item>{
this(name, new Color(Color.black)); this(name, new Color(Color.black));
} }
@Override
public void load(){
regions = new TextureRegion[Icon.values().length];
for(int i = 0; i < regions.length; i++){
Icon icon = Icon.values()[i];
regions[i] = Core.atlas.find(icon == Icon.large ? "item-" + name : "item-" + name + "-" + icon.name());
}
}
public TextureRegion icon(Icon icon){
return regions[icon.ordinal()];
}
@Override @Override
public boolean alwaysUnlocked(){ public boolean alwaysUnlocked(){
return alwaysUnlocked; return alwaysUnlocked;
@@ -71,11 +56,6 @@ public class Item extends UnlockableContent implements Comparable<Item>{
return Core.bundle.get("item." + this.name + ".name"); return Core.bundle.get("item." + this.name + ".name");
} }
@Override
public TextureRegion getContentIcon(){
return icon(Icon.large);
}
@Override @Override
public String toString(){ public String toString(){
return localizedName(); return localizedName();
@@ -91,20 +71,6 @@ public class Item extends UnlockableContent implements Comparable<Item>{
return ContentType.item; return ContentType.item;
} }
public enum Icon{
small(8 * 2),
medium(8 * 3),
large(8 * 4),
xlarge(8 * 5),
xxlarge(8 * 6);
public final int size;
Icon(int size){
this.size = size;
}
}
/** Allocates a new array containing all items that generate ores. */ /** Allocates a new array containing all items that generate ores. */
public static Array<Item> getAllOres(){ public static Array<Item> getAllOres(){
return content.blocks().select(b -> b instanceof OreBlock).map(b -> ((Floor)b).itemDrop); return content.blocks().select(b -> b instanceof OreBlock).map(b -> ((Floor)b).itemDrop);

View File

@@ -5,7 +5,7 @@ import io.anuke.mindustry.content.Items;
public class ItemStack implements Comparable<ItemStack>{ public class ItemStack implements Comparable<ItemStack>{
public Item item; public Item item;
public int amount; public int amount = 1;
public ItemStack(Item item, int amount){ public ItemStack(Item item, int amount){
if(item == null) item = Items.copper; if(item == null) item = Items.copper;

View File

@@ -1,12 +1,11 @@
package io.anuke.mindustry.type; package io.anuke.mindustry.type;
import io.anuke.arc.Core; import io.anuke.arc.*;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.ui.ContentDisplay;
public class Liquid extends UnlockableContent{ public class Liquid extends UnlockableContent{
public final Color color; public final Color color;
@@ -25,8 +24,6 @@ public class Liquid extends UnlockableContent{
public Color flameColor = Color.valueOf("ffb763"); public Color flameColor = Color.valueOf("ffb763");
/** The associated status effect. */ /** The associated status effect. */
public StatusEffect effect = StatusEffects.none; public StatusEffect effect = StatusEffects.none;
/** Displayed icon. TODO fix it by removing autogen, draw icons manually */
public TextureRegion iconRegion;
public Liquid(String name, Color color){ public Liquid(String name, Color color){
super(name); super(name);
@@ -43,11 +40,6 @@ public class Liquid extends UnlockableContent{
return flammability < 0.1f && temperature <= 0.5f; return flammability < 0.1f && temperature <= 0.5f;
} }
@Override
public void load(){
iconRegion = Core.atlas.find("liquid-" + name);
}
@Override @Override
public void displayInfo(Table table){ public void displayInfo(Table table){
ContentDisplay.displayLiquid(table, this); ContentDisplay.displayLiquid(table, this);
@@ -58,11 +50,6 @@ public class Liquid extends UnlockableContent{
return Core.bundle.get("liquid." + this.name + ".name"); return Core.bundle.get("liquid." + this.name + ".name");
} }
@Override
public TextureRegion getContentIcon(){
return iconRegion;
}
@Override @Override
public String toString(){ public String toString(){
return localizedName(); return localizedName();

View File

@@ -9,6 +9,11 @@ public class LiquidStack{
this.amount = amount; this.amount = amount;
} }
/** serialization only*/
protected LiquidStack(){
}
@Override @Override
public String toString(){ public String toString(){
return "LiquidStack{" + return "LiquidStack{" +

View File

@@ -33,7 +33,7 @@ public class Mech extends UnlockableContent{
public float weaponOffsetX, weaponOffsetY, engineOffset = 5f, engineSize = 2.5f; public float weaponOffsetX, weaponOffsetY, engineOffset = 5f, engineSize = 2.5f;
public Weapon weapon; public Weapon weapon;
public TextureRegion baseRegion, legRegion, region, iconRegion; public TextureRegion baseRegion, legRegion, region;
public Mech(String name, boolean flying){ public Mech(String name, boolean flying){
super(name); super(name);
@@ -94,11 +94,6 @@ public class Mech extends UnlockableContent{
ContentDisplay.displayMech(table, this); ContentDisplay.displayMech(table, this);
} }
@Override
public TextureRegion getContentIcon(){
return iconRegion;
}
@Override @Override
public ContentType getContentType(){ public ContentType getContentType(){
return ContentType.mech; return ContentType.mech;
@@ -113,7 +108,6 @@ public class Mech extends UnlockableContent{
} }
region = Core.atlas.find(name); region = Core.atlas.find(name);
iconRegion = Core.atlas.find("mech-icon-" + name);
} }
@Override @Override

View File

@@ -40,7 +40,7 @@ public class UnitType extends UnlockableContent{
public ObjectSet<StatusEffect> immunities = new ObjectSet<>(); public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
public Sound deathSound = Sounds.bang; public Sound deathSound = Sounds.bang;
public TextureRegion iconRegion, legRegion, baseRegion, region; public TextureRegion legRegion, baseRegion, region;
public <T extends BaseUnit> UnitType(String name, Supplier<T> mainConstructor){ public <T extends BaseUnit> UnitType(String name, Supplier<T> mainConstructor){
this(name); this(name);
@@ -68,15 +68,9 @@ public class UnitType extends UnlockableContent{
return Core.bundle.get("unit." + name + ".name"); return Core.bundle.get("unit." + name + ".name");
} }
@Override
public TextureRegion getContentIcon(){
return iconRegion;
}
@Override @Override
public void load(){ public void load(){
weapon.load(); weapon.load();
iconRegion = Core.atlas.find("unit-icon-" + name, Core.atlas.find(name));
region = Core.atlas.find(name); region = Core.atlas.find(name);
legRegion = Core.atlas.find(name + "-leg"); legRegion = Core.atlas.find(name + "-leg");
baseRegion = Core.atlas.find(name + "-base"); baseRegion = Core.atlas.find(name + "-base");

View File

@@ -198,11 +198,6 @@ public class Zone extends UnlockableContent{
public void displayInfo(Table table){ public void displayInfo(Table table){
} }
@Override
public TextureRegion getContentIcon(){
return null;
}
@Override @Override
public String localizedName(){ public String localizedName(){
return Core.bundle.get("zone." + name + ".name"); return Core.bundle.get("zone." + name + ".name");

View File

@@ -1,15 +1,14 @@
package io.anuke.mindustry.ui; package io.anuke.mindustry.ui;
import io.anuke.arc.Core; import io.anuke.arc.*;
import io.anuke.arc.collection.Array; import io.anuke.arc.collection.*;
import io.anuke.arc.collection.OrderedMap; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.Color; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.*;
import io.anuke.arc.util.Strings; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.meta.*; import io.anuke.mindustry.world.meta.*;
public class ContentDisplay{ public class ContentDisplay{
@@ -19,7 +18,7 @@ public class ContentDisplay{
table.table(title -> { table.table(title -> {
int size = 8 * 6; int size = 8 * 6;
title.addImage(block.icon(Icon.large)).size(size); title.addImage(block.icon(Cicon.xlarge)).size(size);
title.add("[accent]" + block.localizedName).padLeft(5); title.add("[accent]" + block.localizedName).padLeft(5);
}); });
@@ -67,7 +66,7 @@ public class ContentDisplay{
public static void displayItem(Table table, Item item){ public static void displayItem(Table table, Item item){
table.table(title -> { table.table(title -> {
title.addImage(item.getContentIcon()).size(8 * 6); title.addImage(item.icon(Cicon.xlarge)).size(8 * 6);
title.add("[accent]" + item.localizedName()).padLeft(5); title.add("[accent]" + item.localizedName()).padLeft(5);
}); });
@@ -98,7 +97,7 @@ public class ContentDisplay{
public static void displayLiquid(Table table, Liquid liquid){ public static void displayLiquid(Table table, Liquid liquid){
table.table(title -> { table.table(title -> {
title.addImage(liquid.getContentIcon()).size(8 * 6); title.addImage(liquid.icon(Cicon.xlarge)).size(8 * 6);
title.add("[accent]" + liquid.localizedName()).padLeft(5); title.add("[accent]" + liquid.localizedName()).padLeft(5);
}); });
@@ -132,7 +131,7 @@ public class ContentDisplay{
public static void displayMech(Table table, Mech mech){ public static void displayMech(Table table, Mech mech){
table.table(title -> { table.table(title -> {
title.addImage(mech.getContentIcon()).size(8 * 6); title.addImage(mech.icon(Cicon.xlarge)).size(8 * 6);
title.add("[accent]" + mech.localizedName()).padLeft(5); title.add("[accent]" + mech.localizedName()).padLeft(5);
}); });
table.left().defaults().left(); table.left().defaults().left();
@@ -180,7 +179,7 @@ public class ContentDisplay{
public static void displayUnit(Table table, UnitType unit){ public static void displayUnit(Table table, UnitType unit){
table.table(title -> { table.table(title -> {
title.addImage(unit.getContentIcon()).size(8 * 6); title.addImage(unit.icon(Cicon.xlarge)).size(8 * 6);
title.add("[accent]" + unit.localizedName()).padLeft(5); title.add("[accent]" + unit.localizedName()).padLeft(5);
}); });

View File

@@ -1,11 +1,10 @@
package io.anuke.mindustry.ui; package io.anuke.mindustry.ui;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.scene.ui.Image; import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.Stack; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.Item.Icon; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.ItemStack;
public class ItemImage extends Stack{ public class ItemImage extends Stack{
@@ -25,7 +24,7 @@ public class ItemImage extends Stack{
} }
public ItemImage(ItemStack stack){ public ItemImage(ItemStack stack){
add(new Image(stack.item.icon(Icon.large))); add(new Image(stack.item.icon(Cicon.medium)));
if(stack.amount != 0){ if(stack.amount != 0){
Table t = new Table().left().bottom(); Table t = new Table().left().bottom();

View File

@@ -3,18 +3,14 @@ package io.anuke.mindustry.ui;
import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.core.GameState.*; import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Item.Icon;
import java.text.*;
import java.util.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
/** Displays a list of items, e.g. launched items.*/ /** Displays a list of items, e.g. launched items.*/
public class ItemsDisplay extends Table{ public class ItemsDisplay extends Table{
private static final NumberFormat format = NumberFormat.getNumberInstance(Locale.getDefault());
private StringBuilder builder = new StringBuilder(); private StringBuilder builder = new StringBuilder();
public ItemsDisplay(){ public ItemsDisplay(){
@@ -33,7 +29,7 @@ public class ItemsDisplay extends Table{
for(Item item : content.items()){ for(Item item : content.items()){
if(item.type == ItemType.material && data.isUnlocked(item)){ if(item.type == ItemType.material && data.isUnlocked(item)){
t.label(() -> format(item)).left(); t.label(() -> format(item)).left();
t.addImage(item.icon(Icon.medium)).size(8 * 3).padLeft(4).padRight(4); t.addImage(item.icon(Cicon.small)).size(8 * 3).padLeft(4).padRight(4);
t.add(item.localizedName()).color(Color.lightGray).left(); t.add(item.localizedName()).color(Color.lightGray).left();
t.row(); t.row();
} }
@@ -44,7 +40,7 @@ public class ItemsDisplay extends Table{
private String format(Item item){ private String format(Item item){
builder.setLength(0); builder.setLength(0);
builder.append(ui.formatAmount(data.items().get(item, 0))); builder.append(ui.formatAmount(data.items().get(item, 0)));
if(!state.teams.get(player.getTeam()).cores.isEmpty() && state.teams.get(player.getTeam()).cores.first().entity != null){ if(!state.is(State.menu) && !state.teams.get(player.getTeam()).cores.isEmpty() && state.teams.get(player.getTeam()).cores.first().entity != null && state.teams.get(player.getTeam()).cores.first().entity.items.get(item) > 0){
builder.append(" [unlaunched]+ "); builder.append(" [unlaunched]+ ");
builder.append(ui.formatAmount(state.teams.get(player.getTeam()).cores.first().entity.items.get(item))); builder.append(ui.formatAmount(state.teams.get(player.getTeam()).cores.first().entity.items.get(item)));
} }

View File

@@ -5,6 +5,7 @@ import io.anuke.arc.scene.ui.Image;
import io.anuke.arc.scene.ui.layout.Stack; import io.anuke.arc.scene.ui.layout.Stack;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Strings; import io.anuke.arc.util.Strings;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.mindustry.world.meta.StatUnit;
@@ -20,7 +21,7 @@ public class LiquidDisplay extends Table{
this.perSecond = perSecond; this.perSecond = perSecond;
add(new Stack(){{ add(new Stack(){{
add(new Image(liquid.getContentIcon())); add(new Image(liquid.icon(Cicon.medium)));
if(amount != 0){ if(amount != 0){
Table t = new Table().left().bottom(); Table t = new Table().left().bottom();

View File

@@ -10,8 +10,7 @@ import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.ContentType;
@@ -56,7 +55,7 @@ public class DatabaseDialog extends FloatingDialog{
for(int i = 0; i < array.size; i++){ for(int i = 0; i < array.size; i++){
UnlockableContent unlock = (UnlockableContent)array.get(i); UnlockableContent unlock = (UnlockableContent)array.get(i);
Image image = unlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image(Icon.lockedSmall, Pal.gray); Image image = unlocked(unlock) ? new Image(unlock.icon(Cicon.medium)) : new Image(Icon.lockedSmall, Pal.gray);
list.add(image).size(8*4).pad(3); list.add(image).size(8*4).pad(3);
ClickListener listener = new ClickListener(); ClickListener listener = new ClickListener();
image.addListener(listener); image.addListener(listener);

View File

@@ -103,12 +103,13 @@ public class DeployDialog extends FloatingDialog{
} }
TextButton button = Elements.newButton(Core.bundle.format("resume", slot.getZone().localizedName()), Styles.squaret, () -> { TextButton button = Elements.newButton(Core.bundle.format("resume", slot.getZone().localizedName()), Styles.squaret, () -> {
control.saves.getZoneSlot().cautiousLoad(() -> {
hide(); hide();
ui.loadAnd(() -> { ui.loadAnd(() -> {
logic.reset(); logic.reset();
net.reset(); net.reset();
try{ try{
control.saves.getZoneSlot().load(); slot.load();
state.set(State.playing); state.set(State.playing);
}catch(SaveException e){ //make sure to handle any save load errors! }catch(SaveException e){ //make sure to handle any save load errors!
e.printStackTrace(); e.printStackTrace();
@@ -118,6 +119,7 @@ public class DeployDialog extends FloatingDialog{
} }
}); });
}); });
});
sub.add(button); sub.add(button);

View File

@@ -2,11 +2,10 @@ package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.mindustry.core.GameState.*; import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.Stats.*; import io.anuke.mindustry.game.Stats.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Item.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -69,7 +68,7 @@ public class GameOverDialog extends FloatingDialog{
if(state.stats.itemsDelivered.get(item, 0) > 0){ if(state.stats.itemsDelivered.get(item, 0) > 0){
t.table(items -> { t.table(items -> {
items.add(" [LIGHT_GRAY]" + state.stats.itemsDelivered.get(item, 0)); items.add(" [LIGHT_GRAY]" + state.stats.itemsDelivered.get(item, 0));
items.addImage(item.icon(Icon.medium)).size(8 * 3).pad(4); items.addImage(item.icon(Cicon.small)).size(8 * 3).pad(4);
}).left(); }).left();
t.row(); t.row();
} }

View File

@@ -70,7 +70,7 @@ public class HostDialog extends FloatingDialog{
if(steam){ if(steam){
Core.app.post(() -> Core.settings.getBoolOnce("steampublic", () -> { Core.app.post(() -> Core.settings.getBoolOnce("steampublic", () -> {
ui.showConfirm("$setting.publichost.name", "$public.confirm", () -> { ui.showCustomConfirm("$setting.publichost.name", "$public.confirm", "$yes", "$no", () -> {
Core.settings.putSave("publichost", true); Core.settings.putSave("publichost", true);
platform.updateLobby(); platform.updateLobby();
}); });

View File

@@ -186,10 +186,10 @@ public class LoadDialog extends FloatingDialog{
} }
public void runLoadSave(SaveSlot slot){ public void runLoadSave(SaveSlot slot){
slot.cautiousLoad(() -> {
ui.loadAnd(() -> {
hide(); hide();
ui.paused.hide(); ui.paused.hide();
ui.loadAnd(() -> {
try{ try{
net.reset(); net.reset();
slot.load(); slot.load();
@@ -203,6 +203,7 @@ public class LoadDialog extends FloatingDialog{
ui.showErrorMessage("$save.corrupted"); ui.showErrorMessage("$save.corrupted");
} }
}); });
});
} }
public void modifyButton(TextButton button, SaveSlot slot){ public void modifyButton(TextButton button, SaveSlot slot){

View File

@@ -7,6 +7,7 @@ import io.anuke.arc.input.*;
import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
@@ -55,7 +56,7 @@ public class LoadoutDialog extends FloatingDialog{
}).size(300f, 36f).get(); }).size(300f, 36f).get();
button.clearChildren(); button.clearChildren();
button.left(); button.left();
button.addImage(item.icon(Item.Icon.medium)).size(8 * 3).pad(4); button.addImage(item.icon(Cicon.small)).size(8 * 3).pad(4);
button.add(item.localizedName); button.add(item.localizedName);
dialog.cont.row(); dialog.cont.row();
} }
@@ -118,7 +119,7 @@ public class LoadoutDialog extends FloatingDialog{
ui.showInfo(Core.bundle.format("configure.invalid", capacity)); ui.showInfo(Core.bundle.format("configure.invalid", capacity));
})).size(bsize); })).size(bsize);
items.addImage(stack.item.icon(Item.Icon.medium)).size(8 * 3).padRight(4).padLeft(4); items.addImage(stack.item.icon(Cicon.small)).size(8 * 3).padRight(4).padLeft(4);
items.label(() -> stack.amount + "").left(); items.label(() -> stack.amount + "").left();
items.row(); items.row();

View File

@@ -1,7 +1,10 @@
package io.anuke.mindustry.ui.dialogs; package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.util.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.mod.Mods.*; import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
@@ -17,9 +20,9 @@ public class ModsDialog extends FloatingDialog{
shown(this::setup); shown(this::setup);
hidden(() -> { hidden(() -> {
if(mods.requiresRestart()){ if(mods.requiresReload()){
ui.showOkText("$mods", "$mod.requiresrestart", () -> { ui.loadAnd("$reloading", () -> {
Core.app.exit(); mods.reloadContent();
}); });
} }
}); });
@@ -34,18 +37,34 @@ public class ModsDialog extends FloatingDialog{
void setup(){ void setup(){
cont.clear(); cont.clear();
cont.defaults().width(520f).pad(4); cont.defaults().width(520f).pad(4);
if(!mods.all().isEmpty()){ cont.add("$mod.reloadrequired").visible(mods::requiresReload).center().get().setAlignment(Align.center);
cont.row();
if(!(mods.all().isEmpty() && mods.disabled().isEmpty())){
cont.pane(table -> { cont.pane(table -> {
table.margin(10f).top(); table.margin(10f).top();
for(LoadedMod mod : mods.all()){ Array<LoadedMod> all = Array.withArrays(mods.all(), mods.disabled());
boolean anyDisabled = false;
for(LoadedMod mod : all){
if(!mod.enabled() && !anyDisabled && mods.all().size > 0){
anyDisabled = true;
table.row();
table.addImage().growX().height(4f).pad(6f).color(Pal.gray);
}
table.table(Styles.black6, t -> { table.table(Styles.black6, t -> {
t.defaults().pad(2).left().top(); t.defaults().pad(2).left().top();
t.margin(14f).left(); t.margin(14f).left();
t.table(title -> { t.table(title -> {
title.left(); title.left();
title.add("[accent]" + mod.meta.name + "[lightgray] v" + mod.meta.version); title.add("[accent]" + mod.meta.name + "[lightgray] v" + mod.meta.version + (" | " + Core.bundle.get(mod.enabled() ? "mod.enabled" : "mod.disabled")));
title.add().growX(); title.add().growX();
title.addButton(mod.enabled() ? "$mod.disable" : "$mod.enable", Styles.cleart, () -> {
mods.setEnabled(mod, !mod.enabled());
setup();
}).height(50f).margin(8f).width(100f);
title.addImageButton(Icon.trash16Small, Styles.cleari, () -> ui.showConfirm("$confirm", "$mod.remove.confirm", () -> { title.addImageButton(Icon.trash16Small, Styles.cleari, () -> ui.showConfirm("$confirm", "$mod.remove.confirm", () -> {
mods.removeMod(mod); mods.removeMod(mod);
setup(); setup();

View File

@@ -317,6 +317,10 @@ public class SettingsMenuDialog extends SettingsDialog{
tex.setFilter(filter, filter); tex.setFilter(filter, filter);
} }
} }
if(!mobile){
Core.settings.put("swapdiagonal", false);
}
} }
private void back(){ private void back(){

View File

@@ -4,7 +4,6 @@ import io.anuke.arc.*;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.*;
import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.input.*;
import io.anuke.arc.math.*; import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.*; import io.anuke.arc.math.geom.*;
import io.anuke.arc.scene.*; import io.anuke.arc.scene.*;
@@ -16,14 +15,13 @@ import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.mindustry.content.*; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.TechTree.*; import io.anuke.mindustry.content.TechTree.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.ui.Styles;
import io.anuke.mindustry.ui.TreeLayout.*; import io.anuke.mindustry.ui.TreeLayout.*;
import io.anuke.mindustry.world.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -145,7 +143,7 @@ public class TechTreeDialog extends FloatingDialog{
infoTable.touchable(Touchable.enabled); infoTable.touchable(Touchable.enabled);
for(TechTreeNode node : nodes){ for(TechTreeNode node : nodes){
ImageButton button = new ImageButton(node.node.block.icon(Block.Icon.medium), Styles.nodei); ImageButton button = new ImageButton(node.node.block.icon(Cicon.medium), Styles.nodei);
button.visible(() -> node.visible); button.visible(() -> node.visible);
button.clicked(() -> { button.clicked(() -> {
if(mobile){ if(mobile){
@@ -191,7 +189,7 @@ public class TechTreeDialog extends FloatingDialog{
button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center); button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center);
button.getStyle().up = !locked(node.node) ? Tex.buttonOver : !data.hasItems(node.node.requirements) ? Tex.buttonRed : Tex.button; button.getStyle().up = !locked(node.node) ? Tex.buttonOver : !data.hasItems(node.node.requirements) ? Tex.buttonRed : Tex.button;
((TextureRegionDrawable)button.getStyle().imageUp) ((TextureRegionDrawable)button.getStyle().imageUp)
.setRegion(node.visible ? node.node.block.icon(Block.Icon.medium) : Core.atlas.find("icon-locked")); .setRegion(node.visible ? node.node.block.icon(Cicon.medium) : Core.atlas.find("icon-locked"));
button.getImage().setColor(!locked(node.node) ? Color.white : Color.gray); button.getImage().setColor(!locked(node.node) ? Color.white : Color.gray);
}); });
addChild(button); addChild(button);
@@ -278,7 +276,7 @@ public class TechTreeDialog extends FloatingDialog{
for(ItemStack req : node.requirements){ for(ItemStack req : node.requirements){
t.table(list -> { t.table(list -> {
list.left(); list.left();
list.addImage(req.item.icon(Item.Icon.medium)).size(8 * 3).padRight(3); list.addImage(req.item.icon(Cicon.small)).size(8 * 3).padRight(3);
list.add(req.item.localizedName()).color(Color.lightGray); list.add(req.item.localizedName()).color(Color.lightGray);
list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount) list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount)
.update(l -> l.setColor(data.has(req.item, req.amount) ? Color.lightGray : Color.scarlet)); .update(l -> l.setColor(data.has(req.item, req.amount) ? Color.lightGray : Color.scarlet));

View File

@@ -45,7 +45,7 @@ public class ZoneInfoDialog extends FloatingDialog{
if(i++ % 2 == 0){ if(i++ % 2 == 0){
iteminfo.row(); iteminfo.row();
} }
iteminfo.addImage(stack.item.icon(Item.Icon.medium)).size(8 * 3).padRight(1); iteminfo.addImage(stack.item.icon(Cicon.small)).size(8 * 3).padRight(1);
iteminfo.add(stack.amount + "").color(Color.lightGray).padRight(5); iteminfo.add(stack.amount + "").color(Color.lightGray).padRight(5);
} }
}; };
@@ -82,7 +82,7 @@ public class ZoneInfoDialog extends FloatingDialog{
r.add("$research.list").colspan(2).left(); r.add("$research.list").colspan(2).left();
r.row(); r.row();
for(Block block : zone.blockRequirements){ for(Block block : zone.blockRequirements){
r.addImage(block.icon(Block.Icon.small)).size(8 * 3).padRight(4); r.addImage(block.icon(Cicon.small)).size(8 * 3).padRight(4);
r.add(block.localizedName).color(Color.lightGray); r.add(block.localizedName).color(Color.lightGray);
r.addImage(data.isUnlocked(block) ? Icon.checkSmall : Icon.cancelSmall, data.isUnlocked(block) ? Color.lightGray : Color.scarlet).padLeft(3); r.addImage(data.isUnlocked(block) ? Icon.checkSmall : Icon.cancelSmall, data.isUnlocked(block) ? Color.lightGray : Color.scarlet).padLeft(3);
r.row(); r.row();
@@ -111,7 +111,7 @@ public class ZoneInfoDialog extends FloatingDialog{
t.left(); t.left();
int i = 0; int i = 0;
for(Item item : zone.resources){ for(Item item : zone.resources){
r.addImage(item.icon(Item.Icon.medium)).size(8 * 3); r.addImage(item.icon(Cicon.small)).size(8 * 3);
if(++i % 4 == 0){ if(++i % 4 == 0){
r.row(); r.row();
} }

View File

@@ -1,32 +1,27 @@
package io.anuke.mindustry.ui.fragments; package io.anuke.mindustry.ui.fragments;
import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.*;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.collection.IntSet; import io.anuke.arc.collection.*;
import io.anuke.arc.function.BooleanProvider; import io.anuke.arc.function.*;
import io.anuke.arc.function.Supplier; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.input.*;
import io.anuke.arc.input.KeyCode; import io.anuke.arc.math.*;
import io.anuke.arc.math.Interpolation; import io.anuke.arc.math.geom.*;
import io.anuke.arc.math.Mathf; import io.anuke.arc.scene.*;
import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.scene.actions.*;
import io.anuke.arc.scene.Element;
import io.anuke.arc.scene.Group;
import io.anuke.arc.scene.actions.Actions;
import io.anuke.arc.scene.event.*; import io.anuke.arc.scene.event.*;
import io.anuke.arc.scene.ui.Image; import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.Stack; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Item.Icon; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -140,7 +135,7 @@ public class BlockInventoryFragment extends Fragment{
HandCursorListener l = new HandCursorListener(); HandCursorListener l = new HandCursorListener();
l.setEnabled(canPick); l.setEnabled(canPick);
Element image = itemImage(item.icon(Icon.xlarge), () -> { Element image = itemImage(item.icon(Cicon.xlarge), () -> {
if(tile == null || tile.entity == null){ if(tile == null || tile.entity == null){
return ""; return "";
} }

View File

@@ -187,10 +187,10 @@ public class HudFragment extends Fragment{
FloatingDialog dialog = new FloatingDialog("$editor.spawn"); FloatingDialog dialog = new FloatingDialog("$editor.spawn");
int i = 0; int i = 0;
for(UnitType type : content.<UnitType>getBy(ContentType.unit)){ for(UnitType type : content.<UnitType>getBy(ContentType.unit)){
dialog.cont.addImageButton(Tex.whiteui, 48, () -> { dialog.cont.addImageButton(Tex.whiteui, 8 * 6f, () -> {
Call.spawnUnitEditor(player, type); Call.spawnUnitEditor(player, type);
dialog.hide(); dialog.hide();
}).get().getStyle().imageUp = new TextureRegionDrawable(type.iconRegion); }).get().getStyle().imageUp = new TextureRegionDrawable(type.icon(Cicon.xlarge));
if(++i % 4 == 0) dialog.cont.row(); if(++i % 4 == 0) dialog.cont.row();
} }
dialog.addCloseButton(); dialog.addCloseButton();
@@ -421,7 +421,7 @@ public class HudFragment extends Fragment{
public void showUnlock(UnlockableContent content){ public void showUnlock(UnlockableContent content){
//some content may not have icons... yet //some content may not have icons... yet
//also don't play in the tutorial to prevent confusion //also don't play in the tutorial to prevent confusion
if(content.getContentIcon() == null || state.is(State.menu) || state.rules.tutorial) return; if(state.is(State.menu) || state.rules.tutorial) return;
Sounds.message.play(); Sounds.message.play();
@@ -441,10 +441,10 @@ public class HudFragment extends Fragment{
Table in = new Table(); Table in = new Table();
//create texture stack for displaying //create texture stack for displaying
Image image = new Image(content.getContentIcon()); Image image = new Image(content.icon(Cicon.xlarge));
image.setScaling(Scaling.fit); image.setScaling(Scaling.fit);
in.add(image).size(48f).pad(2); in.add(image).size(8 * 6).pad(2);
//add to table //add to table
table.add(in).padRight(8); table.add(in).padRight(8);
@@ -495,7 +495,7 @@ public class HudFragment extends Fragment{
//if there's space, add it //if there's space, add it
if(esize < cap){ if(esize < cap){
Image image = new Image(content.getContentIcon()); Image image = new Image(content.icon(Cicon.medium));
image.setScaling(Scaling.fit); image.setScaling(Scaling.fit);
lastUnlockLayout.add(image); lastUnlockLayout.add(image);

View File

@@ -11,6 +11,7 @@ import io.anuke.arc.scene.style.*;
import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
@@ -80,7 +81,7 @@ public class PlacementFragment extends Fragment{
Block tryRecipe = tile.block(); Block tryRecipe = tile.block();
if(tryRecipe.isVisible() && unlocked(tryRecipe)){ if(tryRecipe.isVisible() && unlocked(tryRecipe)){
input.block = tryRecipe; input.block = tryRecipe;
currentCategory = input.block.buildCategory; currentCategory = input.block.category;
return true; return true;
} }
} }
@@ -92,7 +93,7 @@ public class PlacementFragment extends Fragment{
for(KeyCode key : inputCatGrid){ for(KeyCode key : inputCatGrid){
if(Core.input.keyDown(key)){ if(Core.input.keyDown(key)){
input.block = getByCategory(Category.all[i]).first(); input.block = getByCategory(Category.all[i]).first();
currentCategory = input.block.buildCategory; currentCategory = input.block.category;
} }
i++; i++;
} }
@@ -143,11 +144,11 @@ public class PlacementFragment extends Fragment{
} }
}).size(46f).group(group).name("block-" + block.name).get(); }).size(46f).group(group).name("block-" + block.name).get();
button.getStyle().imageUp = new TextureRegionDrawable(block.icon(Block.Icon.medium)); button.getStyle().imageUp = new TextureRegionDrawable(block.icon(Cicon.medium));
button.update(() -> { //color unplacable things gray button.update(() -> { //color unplacable things gray
TileEntity core = player.getClosestCore(); TileEntity core = player.getClosestCore();
Color color = state.rules.infiniteResources || (core != null && (core.items.has(block.buildRequirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources)) ? Color.white : Color.gray; Color color = state.rules.infiniteResources || (core != null && (core.items.has(block.requirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources)) ? Color.white : Color.gray;
button.forEach(elem -> elem.setColor(color)); button.forEach(elem -> elem.setColor(color));
button.setChecked(control.input.block == block); button.setChecked(control.input.block == block);
}); });
@@ -189,7 +190,7 @@ public class PlacementFragment extends Fragment{
topTable.table(header -> { topTable.table(header -> {
header.left(); header.left();
header.add(new Image(lastDisplay.icon(Block.Icon.medium))).size(8 * 4); header.add(new Image(lastDisplay.icon(Cicon.medium))).size(8 * 4);
header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("block.unknown") : lastDisplay.localizedName) header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("block.unknown") : lastDisplay.localizedName)
.left().width(190f).padLeft(5); .left().width(190f).padLeft(5);
header.add().growX(); header.add().growX();
@@ -205,10 +206,10 @@ public class PlacementFragment extends Fragment{
topTable.table(req -> { topTable.table(req -> {
req.top().left(); req.top().left();
for(ItemStack stack : lastDisplay.buildRequirements){ for(ItemStack stack : lastDisplay.requirements){
req.table(line -> { req.table(line -> {
line.left(); line.left();
line.addImage(stack.item.icon(Item.Icon.small)).size(8 * 2); line.addImage(stack.item.icon(Cicon.small)).size(8 * 2);
line.add(stack.item.localizedName()).color(Color.lightGray).padLeft(2).left(); line.add(stack.item.localizedName()).color(Color.lightGray).padLeft(2).left();
line.labelWrap(() -> { line.labelWrap(() -> {
TileEntity core = player.getClosestCore(); TileEntity core = player.getClosestCore();
@@ -296,7 +297,7 @@ public class PlacementFragment extends Fragment{
Array<Block> getByCategory(Category cat){ Array<Block> getByCategory(Category cat){
returnArray.clear(); returnArray.clear();
for(Block block : content.blocks()){ for(Block block : content.blocks()){
if(block.buildCategory == cat && block.isVisible()){ if(block.category == cat && block.isVisible()){
returnArray.add(block); returnArray.add(block);
} }
} }

View File

@@ -87,7 +87,7 @@ public class PlayerListFragment extends Fragment{
} }
}; };
table.margin(8); table.margin(8);
table.add(new Image(user.mech.getContentIcon()).setScaling(Scaling.none)).grow(); table.add(new Image(user.getIconRegion()).setScaling(Scaling.none)).grow();
button.add(table).size(h); button.add(table).size(h);
button.labelWrap("[#" + user.color.toString().toUpperCase() + "]" + user.name).width(170f).pad(10); button.labelWrap("[#" + user.color.toString().toUpperCase() + "]" + user.name).width(170f).pad(10);

View File

@@ -114,9 +114,9 @@ public class Block extends BlockStorage{
public float idleSoundVolume = 0.5f; public float idleSoundVolume = 0.5f;
/** Cost of constructing this block. */ /** Cost of constructing this block. */
public ItemStack[] buildRequirements = new ItemStack[]{}; public ItemStack[] requirements = new ItemStack[]{};
/** Category in place menu. */ /** Category in place menu. */
public Category buildCategory = Category.distribution; public Category category = Category.distribution;
/** Cost of building this block; do not modify directly! */ /** Cost of building this block; do not modify directly! */
public float buildCost; public float buildCost;
/** Whether this block is visible and can currently be built. */ /** Whether this block is visible and can currently be built. */
@@ -129,7 +129,6 @@ public class Block extends BlockStorage{
protected Array<String> cacheRegionStrings = new Array<>(); protected Array<String> cacheRegionStrings = new Array<>();
protected Array<Tile> tempTiles = new Array<>(); protected Array<Tile> tempTiles = new Array<>();
protected TextureRegion[] icons = new TextureRegion[Icon.values().length];
protected TextureRegion[] generatedIcons; protected TextureRegion[] generatedIcons;
protected TextureRegion[] variantRegions, editorVariantRegions; protected TextureRegion[] variantRegions, editorVariantRegions;
protected TextureRegion region, editorIcon; protected TextureRegion region, editorIcon;
@@ -362,11 +361,6 @@ public class Block extends BlockStorage{
return localizedName; return localizedName;
} }
@Override
public TextureRegion getContentIcon(){
return icon(Icon.medium);
}
@Override @Override
public void displayInfo(Table table){ public void displayInfo(Table table){
ContentDisplay.displayBlock(table, this); ContentDisplay.displayBlock(table, this);
@@ -387,7 +381,7 @@ public class Block extends BlockStorage{
} }
buildCost = 0f; buildCost = 0f;
for(ItemStack stack : buildRequirements){ for(ItemStack stack : requirements){
buildCost += stack.amount * stack.item.cost; buildCost += stack.amount * stack.item.cost;
} }
@@ -493,7 +487,7 @@ public class Block extends BlockStorage{
stats.add(BlockStat.health, health, StatUnit.none); stats.add(BlockStat.health, health, StatUnit.none);
if(isBuildable()){ if(isBuildable()){
stats.add(BlockStat.buildTime, buildCost / 60, StatUnit.seconds); stats.add(BlockStat.buildTime, buildCost / 60, StatUnit.seconds);
stats.add(BlockStat.buildCost, new ItemListValue(false, buildRequirements)); stats.add(BlockStat.buildCost, new ItemListValue(false, requirements));
} }
consumes.display(stats); consumes.display(stats);
@@ -631,7 +625,7 @@ public class Block extends BlockStorage{
} }
public TextureRegion getDisplayIcon(Tile tile){ public TextureRegion getDisplayIcon(Tile tile){
return icon(Icon.medium); return icon(Cicon.medium);
} }
public void display(Tile tile, Table table){ public void display(Tile tile, Table table){
@@ -667,20 +661,19 @@ public class Block extends BlockStorage{
} }
} }
public TextureRegion icon(Icon icon){
if(icons[icon.ordinal()] == null){
icons[icon.ordinal()] = Core.atlas.find(name + "-icon-" + icon.name(), icon == Icon.full ?
getGeneratedIcons()[0] : Core.atlas.find(name + "-icon-full", getGeneratedIcons()[0]));
}
return icons[icon.ordinal()];
}
public void getPlaceDraw(PlaceDraw draw, int rotation, int prevX, int prevY, int prevRotation){ public void getPlaceDraw(PlaceDraw draw, int rotation, int prevX, int prevY, int prevRotation){
draw.region = icon(Icon.full); draw.region = icon(Cicon.full);
draw.scalex = draw.scaley = 1; draw.scalex = draw.scaley = 1;
draw.rotation = rotation; draw.rotation = rotation;
} }
@Override
public void createIcons(PixmapPacker out, PixmapPacker editor){
super.createIcons(out, editor);
editor.pack(name + "-icon-editor", Core.atlas.getPixmap((AtlasRegion)icon(Cicon.full)).crop());
}
/** Never use outside of the editor! */ /** Never use outside of the editor! */
public TextureRegion editorIcon(){ public TextureRegion editorIcon(){
if(editorIcon == null) editorIcon = Core.atlas.find(name + "-icon-editor"); if(editorIcon == null) editorIcon = Core.atlas.find(name + "-icon-editor");
@@ -713,7 +706,7 @@ public class Block extends BlockStorage{
public TextureRegion[] variantRegions(){ public TextureRegion[] variantRegions(){
if(variantRegions == null){ if(variantRegions == null){
variantRegions = new TextureRegion[]{icon(Icon.full)}; variantRegions = new TextureRegion[]{icon(Cicon.full)};
} }
return variantRegions; return variantRegions;
} }
@@ -772,25 +765,11 @@ public class Block extends BlockStorage{
/** Sets up requirements. Use only this method to set up requirements. */ /** Sets up requirements. Use only this method to set up requirements. */
protected void requirements(Category cat, BooleanProvider visible, ItemStack[] stacks){ protected void requirements(Category cat, BooleanProvider visible, ItemStack[] stacks){
this.buildCategory = cat; this.category = cat;
this.buildRequirements = stacks; this.requirements = stacks;
this.buildVisibility = visible; this.buildVisibility = visible;
Arrays.sort(buildRequirements, (a, b) -> Integer.compare(a.item.id, b.item.id)); Arrays.sort(requirements, (a, b) -> Integer.compare(a.item.id, b.item.id));
} }
public enum Icon{
//these are stored in the UI atlases
small(8 * 3),
medium(8 * 4),
large(8 * 6),
/** uses whatever the size of the block is. this is always stored in the main game atlas! */
full(0);
public final int size;
Icon(int size){
this.size = size;
}
}
} }

View File

@@ -91,11 +91,11 @@ public abstract class BlockStorage extends UnlockableContent{
} }
public boolean acceptItem(Item item, Tile tile, Tile source){ public boolean acceptItem(Item item, Tile tile, Tile source){
return consumes.itemFilters[item.id] && tile.entity.items.get(item) < getMaximumAccepted(tile, item); return consumes.itemFilters.get(item.id) && tile.entity.items.get(item) < getMaximumAccepted(tile, item);
} }
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return hasLiquids && tile.entity.liquids.get(liquid) + amount < liquidCapacity && consumes.liquidfilters[liquid.id]; return hasLiquids && tile.entity.liquids.get(liquid) + amount < liquidCapacity && consumes.liquidfilters.get(liquid.id);
} }
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){

View File

@@ -1,27 +1,24 @@
package io.anuke.mindustry.world.blocks; package io.anuke.mindustry.world.blocks;
import io.anuke.annotations.Annotations.*; import io.anuke.annotations.Annotations.*;
import io.anuke.arc.Core; import io.anuke.arc.*;
import io.anuke.arc.Events; import io.anuke.arc.Graphics.*;
import io.anuke.arc.Graphics.Cursor; import io.anuke.arc.Graphics.Cursor.*;
import io.anuke.arc.Graphics.Cursor.SystemCursor; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.math.*;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.effect.RubbleDecal; import io.anuke.mindustry.entities.effect.*;
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.BuilderTrait.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.EventType.BlockBuildEndEvent; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.modules.*;
import io.anuke.mindustry.world.modules.ItemModule;
import java.io.*; import java.io.*;
@@ -93,7 +90,7 @@ public class BuildBlock extends Block{
@Override @Override
public TextureRegion getDisplayIcon(Tile tile){ public TextureRegion getDisplayIcon(Tile tile){
BuildEntity entity = tile.entity(); BuildEntity entity = tile.entity();
return (entity.cblock == null ? entity.previous : entity.cblock).icon(Icon.full); return (entity.cblock == null ? entity.previous : entity.cblock).icon(Cicon.full);
} }
@Override @Override
@@ -138,8 +135,8 @@ public class BuildBlock extends Block{
if(entity.previous == null) return; if(entity.previous == null) return;
if(Core.atlas.isFound(entity.previous.icon(Icon.full))){ if(Core.atlas.isFound(entity.previous.icon(Cicon.full))){
Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.rotation() * 90 : 0); Draw.rect(entity.previous.icon(Cicon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.rotation() * 90 : 0);
} }
} }
@@ -196,8 +193,8 @@ public class BuildBlock extends Block{
float maxProgress = core == null ? amount : checkRequired(core.items, amount, false); float maxProgress = core == null ? amount : checkRequired(core.items, amount, false);
for(int i = 0; i < cblock.buildRequirements.length; i++){ for(int i = 0; i < cblock.requirements.length; i++){
int reqamount = Math.round(state.rules.buildCostMultiplier * cblock.buildRequirements[i].amount); int reqamount = Math.round(state.rules.buildCostMultiplier * cblock.requirements[i].amount);
accumulator[i] += Math.min(reqamount * maxProgress, reqamount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator accumulator[i] += Math.min(reqamount * maxProgress, reqamount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator
totalAccumulator[i] = Math.min(totalAccumulator[i] + reqamount * maxProgress, reqamount); totalAccumulator[i] = Math.min(totalAccumulator[i] + reqamount * maxProgress, reqamount);
} }
@@ -221,7 +218,7 @@ public class BuildBlock extends Block{
float deconstructMultiplier = 0.5f; float deconstructMultiplier = 0.5f;
if(cblock != null){ if(cblock != null){
ItemStack[] requirements = cblock.buildRequirements; ItemStack[] requirements = cblock.requirements;
if(requirements.length != accumulator.length || totalAccumulator.length != requirements.length){ if(requirements.length != accumulator.length || totalAccumulator.length != requirements.length){
setDeconstruct(previous); setDeconstruct(previous);
} }
@@ -258,15 +255,15 @@ public class BuildBlock extends Block{
private float checkRequired(ItemModule inventory, float amount, boolean remove){ private float checkRequired(ItemModule inventory, float amount, boolean remove){
float maxProgress = amount; float maxProgress = amount;
for(int i = 0; i < cblock.buildRequirements.length; i++){ for(int i = 0; i < cblock.requirements.length; i++){
int sclamount = Math.round(state.rules.buildCostMultiplier * cblock.buildRequirements[i].amount); int sclamount = Math.round(state.rules.buildCostMultiplier * cblock.requirements[i].amount);
int required = (int)(accumulator[i]); //calculate items that are required now int required = (int)(accumulator[i]); //calculate items that are required now
if(inventory.get(cblock.buildRequirements[i].item) == 0 && sclamount != 0){ if(inventory.get(cblock.requirements[i].item) == 0 && sclamount != 0){
maxProgress = 0f; maxProgress = 0f;
}else if(required > 0){ //if this amount is positive... }else if(required > 0){ //if this amount is positive...
//calculate how many items it can actually use //calculate how many items it can actually use
int maxUse = Math.min(required, inventory.get(cblock.buildRequirements[i].item)); int maxUse = Math.min(required, inventory.get(cblock.requirements[i].item));
//get this as a fraction //get this as a fraction
float fraction = maxUse / (float)required; float fraction = maxUse / (float)required;
@@ -277,7 +274,7 @@ public class BuildBlock extends Block{
//remove stuff that is actually used //remove stuff that is actually used
if(remove){ if(remove){
inventory.remove(cblock.buildRequirements[i].item, maxUse); inventory.remove(cblock.requirements[i].item, maxUse);
} }
} }
//else, no items are required yet, so just keep going //else, no items are required yet, so just keep going
@@ -293,8 +290,8 @@ public class BuildBlock extends Block{
public void setConstruct(Block previous, Block block){ public void setConstruct(Block previous, Block block){
this.cblock = block; this.cblock = block;
this.previous = previous; this.previous = previous;
this.accumulator = new float[block.buildRequirements.length]; this.accumulator = new float[block.requirements.length];
this.totalAccumulator = new float[block.buildRequirements.length]; this.totalAccumulator = new float[block.requirements.length];
this.buildCost = block.buildCost * state.rules.buildCostMultiplier; this.buildCost = block.buildCost * state.rules.buildCostMultiplier;
} }
@@ -303,8 +300,8 @@ public class BuildBlock extends Block{
this.progress = 1f; this.progress = 1f;
if(previous.buildCost >= 0.01f){ if(previous.buildCost >= 0.01f){
this.cblock = previous; this.cblock = previous;
this.accumulator = new float[previous.buildRequirements.length]; this.accumulator = new float[previous.requirements.length];
this.totalAccumulator = new float[previous.buildRequirements.length]; this.totalAccumulator = new float[previous.requirements.length];
this.buildCost = previous.buildCost * state.rules.buildCostMultiplier; this.buildCost = previous.buildCost * state.rules.buildCostMultiplier;
}else{ }else{
this.buildCost = 20f; //default no-requirement build cost is 20 this.buildCost = 20f; //default no-requirement build cost is 20

View File

@@ -1,19 +1,15 @@
package io.anuke.mindustry.world.blocks; package io.anuke.mindustry.world.blocks;
import io.anuke.arc.Core; import io.anuke.arc.*;
import io.anuke.arc.collection.Array; import io.anuke.arc.collection.*;
import io.anuke.arc.collection.IntSet; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.math.*;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.geom.*;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.mindustry.content.*; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.mindustry.entities.Effects.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.tilesize;

View File

@@ -5,9 +5,10 @@ import io.anuke.arc.function.*;
import io.anuke.arc.scene.style.*; import io.anuke.arc.scene.style.*;
import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.Styles; import io.anuke.mindustry.ui.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -29,7 +30,7 @@ public class ItemSelection{
ImageButton button = cont.addImageButton(Tex.whiteui, Styles.clearToggleTransi, 24, () -> control.input.frag.config.hideConfig()).group(group).get(); ImageButton button = cont.addImageButton(Tex.whiteui, Styles.clearToggleTransi, 24, () -> control.input.frag.config.hideConfig()).group(group).get();
button.changed(() -> consumer.accept(button.isChecked() ? item : null)); button.changed(() -> consumer.accept(button.isChecked() ? item : null));
button.getStyle().imageUp = new TextureRegionDrawable(item.icon(Item.Icon.medium)); button.getStyle().imageUp = new TextureRegionDrawable(item.icon(Cicon.small));
button.update(() -> button.setChecked(holder.get() == item)); button.update(() -> button.setChecked(holder.get() == item));
if(i++ % 4 == 3){ if(i++ % 4 == 3){

View File

@@ -1,7 +1,13 @@
package io.anuke.mindustry.world.blocks; package io.anuke.mindustry.world.blocks;
import io.anuke.mindustry.type.Item; import io.anuke.annotations.Annotations.*;
import io.anuke.mindustry.world.Tile; import io.anuke.arc.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.*;
import static io.anuke.mindustry.Vars.tilesize;
/**An overlay ore for a specific item type.*/ /**An overlay ore for a specific item type.*/
public class OreBlock extends OverlayFloor{ public class OreBlock extends OverlayFloor{
@@ -14,9 +20,60 @@ public class OreBlock extends OverlayFloor{
this.color.set(ore.color); this.color.set(ore.color);
} }
/** For mod use only!*/
public OreBlock(String name){
super(name);
}
public void setup(Item ore){
this.localizedName = ore.localizedName();
this.itemDrop = ore;
this.variants = 3;
this.color.set(ore.color);
}
@Override
@OverrideCallSuper
public void createIcons(PixmapPacker out, PixmapPacker editor){
for(int i = 0; i < 3; i++){
Pixmap image = new Pixmap(32, 32);
PixmapRegion shadow = Core.atlas.getPixmap(itemDrop.name + (i + 1));
int offset = image.getWidth() / tilesize - 1;
Color color = new Color();
for(int x = 0; x < image.getWidth(); x++){
for(int y = offset; y < image.getHeight(); y++){
shadow.getPixel(x, y - offset, color);
if(color.a > 0.001f){
color.set(0, 0, 0, 0.3f);
image.draw(x, y, color);
}
}
}
image.draw(shadow);
out.pack(name + (i + 1), image);
editor.pack("editor-" + name + (i + 1), image);
if(i == 0){
editor.pack("editor-block-" + name + "-full", image);
out.pack("block-" + name + "-full", image);
}
}
}
@Override @Override
public void init(){ public void init(){
super.init(); super.init();
if(itemDrop != null){
setup(itemDrop);
}else{
throw new IllegalArgumentException(name + " must have an item drop!");
}
} }
@Override @Override

View File

@@ -20,7 +20,7 @@ public class RespawnBlock{
Draw.reset(); Draw.reset();
if(player != null){ if(player != null){
TextureRegion region = to.iconRegion; TextureRegion region = player.getIconRegion();
Draw.color(0f, 0f, 0f, 0.4f * progress); Draw.color(0f, 0f, 0f, 0.4f * progress);
Draw.rect("circle-shadow", tile.drawx(), tile.drawy(), region.getWidth() / 3f, region.getWidth() / 3f); Draw.rect("circle-shadow", tile.drawx(), tile.drawy(), region.getWidth() / 3f, region.getWidth() / 3f);

View File

@@ -7,6 +7,7 @@ import io.anuke.mindustry.*;
import io.anuke.mindustry.content.*; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.bullet.*; import io.anuke.mindustry.entities.bullet.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
@@ -44,7 +45,7 @@ public class ItemTurret extends CooledTurret{
@Override @Override
public void build(Tile tile, Table table){ public void build(Tile tile, Table table){
MultiReqImage image = new MultiReqImage(); MultiReqImage image = new MultiReqImage();
content.items().each(i -> filter.test(i) && (!world.isZone() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Item.Icon.large)), content.items().each(i -> filter.test(i) && (!world.isZone() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium)),
() -> tile.entity != null && !((ItemTurretEntity)tile.entity).ammo.isEmpty() && ((ItemEntry)tile.<ItemTurretEntity>entity().ammo.peek()).item == item))); () -> tile.entity != null && !((ItemTurretEntity)tile.entity).ammo.isEmpty() && ((ItemEntry)tile.<ItemTurretEntity>entity().ammo.peek()).item == item)));
table.add(image).size(8 * 4); table.add(image).size(8 * 4);

View File

@@ -7,6 +7,7 @@ import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.*; import io.anuke.arc.math.geom.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.input.InputHandler.*; import io.anuke.mindustry.input.InputHandler.*;
@@ -161,7 +162,7 @@ public class Conveyor extends Block{
tr1.trns(rotation * 90, tilesize, 0); tr1.trns(rotation * 90, tilesize, 0);
tr2.trns(rotation * 90, -tilesize / 2f, pos.x * tilesize / 2f); tr2.trns(rotation * 90, -tilesize / 2f, pos.x * tilesize / 2f);
Draw.rect(pos.item.icon(Item.Icon.medium), Draw.rect(pos.item.icon(Cicon.medium),
(tile.x * tilesize + tr1.x * pos.y + tr2.x), (tile.x * tilesize + tr1.x * pos.y + tr2.x),
(tile.y * tilesize + tr1.y * pos.y + tr2.y), itemSize, itemSize); (tile.y * tilesize + tr1.y * pos.y + tr2.y), itemSize, itemSize);
} }

View File

@@ -10,6 +10,7 @@ import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.Effects.*; import io.anuke.mindustry.entities.Effects.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
@@ -143,9 +144,9 @@ public class Drill extends Block{
float width = drawPlaceText(Core.bundle.formatFloat("bar.drillspeed", 60f / (drillTime + hardnessDrillMultiplier * returnItem.hardness) * returnCount, 2), x, y, valid); float width = drawPlaceText(Core.bundle.formatFloat("bar.drillspeed", 60f / (drillTime + hardnessDrillMultiplier * returnItem.hardness) * returnCount, 2), x, y, valid);
float dx = x * tilesize + offset() - width/2f - 4f, dy = y * tilesize + offset() + size * tilesize / 2f + 5; float dx = x * tilesize + offset() - width/2f - 4f, dy = y * tilesize + offset() + size * tilesize / 2f + 5;
Draw.mixcol(Color.darkGray, 1f); Draw.mixcol(Color.darkGray, 1f);
Draw.rect(returnItem.icon(Item.Icon.large), dx, dy - 1); Draw.rect(returnItem.icon(Cicon.small), dx, dy - 1);
Draw.reset(); Draw.reset();
Draw.rect(returnItem.icon(Item.Icon.large), dx, dy); Draw.rect(returnItem.icon(Cicon.small), dx, dy);
}else{ }else{
Tile to = tile.getLinkedTilesAs(this, tempTiles).find(t -> t.drop() != null && t.drop().hardness > tier); Tile to = tile.getLinkedTilesAs(this, tempTiles).find(t -> t.drop() != null && t.drop().hardness > tier);
Item item = to == null ? null : to.drop(); Item item = to == null ? null : to.drop();
@@ -162,9 +163,9 @@ public class Drill extends Block{
if(entity.dominantItem != null){ if(entity.dominantItem != null){
float dx = tile.drawx() - size * tilesize/2f, dy = tile.drawy() + size * tilesize/2f; float dx = tile.drawx() - size * tilesize/2f, dy = tile.drawy() + size * tilesize/2f;
Draw.mixcol(Color.darkGray, 1f); Draw.mixcol(Color.darkGray, 1f);
Draw.rect(entity.dominantItem.icon(Item.Icon.large), dx, dy); Draw.rect(entity.dominantItem.icon(Cicon.small), dx, dy - 1);
Draw.reset(); Draw.reset();
Draw.rect(entity.dominantItem.icon(Item.Icon.medium), dx, dy); Draw.rect(entity.dominantItem.icon(Cicon.small), dx, dy);
} }
} }

View File

@@ -8,6 +8,7 @@ import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
@@ -87,7 +88,7 @@ public class LiquidSource extends Block{
control.input.frag.config.hideConfig(); control.input.frag.config.hideConfig();
lastLiquid = items.get(f); lastLiquid = items.get(f);
}); });
button.getStyle().imageUp = new TextureRegionDrawable(items.get(i).iconRegion); button.getStyle().imageUp = new TextureRegionDrawable(items.get(i).icon(Cicon.medium));
button.setChecked(entity.source == items.get(i)); button.setChecked(entity.source == items.get(i));
if(i % 4 == 3){ if(i % 4 == 3){

View File

@@ -10,6 +10,7 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Pal;
@@ -121,7 +122,7 @@ public class UnitFactory extends Block{
@Override @Override
public void draw(Tile tile){ public void draw(Tile tile){
UnitFactoryEntity entity = tile.entity(); UnitFactoryEntity entity = tile.entity();
TextureRegion region = type.iconRegion; TextureRegion region = type.icon(Cicon.full);
Draw.rect(name, tile.drawx(), tile.drawy()); Draw.rect(name, tile.drawx(), tile.drawy());

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.world.consumers; package io.anuke.mindustry.world.consumers;
import io.anuke.arc.collection.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -17,7 +18,7 @@ public abstract class Consume{
* Apply a filter to items accepted. * Apply a filter to items accepted.
* This should set all item IDs that are present in the filter to true. * This should set all item IDs that are present in the filter to true.
*/ */
public void applyItemFilter(boolean[] filter){ public void applyItemFilter(Bits filter){
} }
@@ -25,7 +26,7 @@ public abstract class Consume{
* Apply a filter to liquids accepted. * Apply a filter to liquids accepted.
* This should set all liquid IDs that are present in the filter to true. * This should set all liquid IDs that are present in the filter to true.
*/ */
public void applyLiquidFilter(boolean[] filter){ public void applyLiquidFilter(Bits filter){
} }

View File

@@ -1,15 +1,15 @@
package io.anuke.mindustry.world.consumers; package io.anuke.mindustry.world.consumers;
import io.anuke.arc.function.Predicate; import io.anuke.arc.collection.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.function.*;
import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.type.Item.Icon; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.*;
import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.mindustry.world.meta.values.*;
import io.anuke.mindustry.world.meta.values.ItemFilterValue;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -21,8 +21,8 @@ public class ConsumeItemFilter extends Consume{
} }
@Override @Override
public void applyItemFilter(boolean[] arr){ public void applyItemFilter(Bits arr){
content.items().each(filter, item -> arr[item.id] = true); content.items().each(filter, item -> arr.set(item.id));
} }
@Override @Override
@@ -33,7 +33,7 @@ public class ConsumeItemFilter extends Consume{
@Override @Override
public void build(Tile tile, Table table){ public void build(Tile tile, Table table){
MultiReqImage image = new MultiReqImage(); MultiReqImage image = new MultiReqImage();
content.items().each(i -> filter.test(i) && (!world.isZone() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Icon.large), 1), () -> tile.entity != null && tile.entity.items != null && tile.entity.items.has(item)))); content.items().each(i -> filter.test(i) && (!world.isZone() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium), 1), () -> tile.entity != null && tile.entity.items != null && tile.entity.items.has(item))));
table.add(image).size(8 * 4); table.add(image).size(8 * 4);
} }

View File

@@ -1,15 +1,14 @@
package io.anuke.mindustry.world.consumers; package io.anuke.mindustry.world.consumers;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.collection.*;
import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.type.Item.Icon; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.ui.ItemImage; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.ReqImage; import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.*;
import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.mindustry.world.meta.values.*;
import io.anuke.mindustry.world.meta.values.ItemListValue;
public class ConsumeItems extends Consume{ public class ConsumeItems extends Consume{
public final ItemStack[] items; public final ItemStack[] items;
@@ -19,9 +18,9 @@ public class ConsumeItems extends Consume{
} }
@Override @Override
public void applyItemFilter(boolean[] filter){ public void applyItemFilter(Bits filter){
for(ItemStack stack : items){ for(ItemStack stack : items){
filter[stack.item.id] = true; filter.set(stack.item.id);
} }
} }
@@ -33,7 +32,7 @@ public class ConsumeItems extends Consume{
@Override @Override
public void build(Tile tile, Table table){ public void build(Tile tile, Table table){
for(ItemStack stack : items){ for(ItemStack stack : items){
table.add(new ReqImage(new ItemImage(stack.item.icon(Icon.large), stack.amount), () -> tile.entity != null && tile.entity.items != null && tile.entity.items.has(stack.item, stack.amount))).size(8 * 4).padRight(5); table.add(new ReqImage(new ItemImage(stack.item.icon(Cicon.medium), stack.amount), () -> tile.entity != null && tile.entity.items != null && tile.entity.items.has(stack.item, stack.amount))).size(8 * 4).padRight(5);
} }
} }

View File

@@ -1,7 +1,9 @@
package io.anuke.mindustry.world.consumers; package io.anuke.mindustry.world.consumers;
import io.anuke.arc.collection.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.ui.ReqImage; import io.anuke.mindustry.ui.ReqImage;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -17,13 +19,13 @@ public class ConsumeLiquid extends ConsumeLiquidBase{
} }
@Override @Override
public void applyLiquidFilter(boolean[] filter){ public void applyLiquidFilter(Bits filter){
filter[liquid.id] = true; filter.set(liquid.id);
} }
@Override @Override
public void build(Tile tile, Table table){ public void build(Tile tile, Table table){
table.add(new ReqImage(liquid.getContentIcon(), () -> valid(tile.entity))).size(8 * 4); table.add(new ReqImage(liquid.icon(Cicon.medium), () -> valid(tile.entity))).size(8 * 4);
} }
@Override @Override

View File

@@ -1,9 +1,10 @@
package io.anuke.mindustry.world.consumers; package io.anuke.mindustry.world.consumers;
import io.anuke.arc.collection.Array; import io.anuke.arc.collection.*;
import io.anuke.arc.function.Predicate; import io.anuke.arc.function.Predicate;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.ui.MultiReqImage; import io.anuke.mindustry.ui.MultiReqImage;
import io.anuke.mindustry.ui.ReqImage; import io.anuke.mindustry.ui.ReqImage;
@@ -23,15 +24,15 @@ public class ConsumeLiquidFilter extends ConsumeLiquidBase{
} }
@Override @Override
public void applyLiquidFilter(boolean[] arr){ public void applyLiquidFilter(Bits arr){
content.liquids().each(filter, item -> arr[item.id] = true); content.liquids().each(filter, item -> arr.set(item.id));
} }
@Override @Override
public void build(Tile tile, Table table){ public void build(Tile tile, Table table){
Array<Liquid> list = content.liquids().select(l -> !l.isHidden() && filter.test(l)); Array<Liquid> list = content.liquids().select(l -> !l.isHidden() && filter.test(l));
MultiReqImage image = new MultiReqImage(); MultiReqImage image = new MultiReqImage();
list.each(liquid -> image.add(new ReqImage(liquid.getContentIcon(), () -> tile.entity != null && tile.entity.liquids != null && tile.entity.liquids.get(liquid) >= use(tile.entity)))); list.each(liquid -> image.add(new ReqImage(liquid.icon(Cicon.medium), () -> tile.entity != null && tile.entity.liquids != null && tile.entity.liquids.get(liquid) >= use(tile.entity))));
table.add(image).size(8 * 4); table.add(image).size(8 * 4);
} }

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.world.consumers; package io.anuke.mindustry.world.consumers;
import io.anuke.arc.collection.*;
import io.anuke.arc.function.Predicate; import io.anuke.arc.function.Predicate;
import io.anuke.arc.util.Structs; import io.anuke.arc.util.Structs;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
@@ -12,8 +13,8 @@ public class Consumers{
private Consume[] map = new Consume[ConsumeType.values().length]; private Consume[] map = new Consume[ConsumeType.values().length];
private Consume[] results, optionalResults; private Consume[] results, optionalResults;
public final boolean[] itemFilters = new boolean[Vars.content.items().size]; public final Bits itemFilters = new Bits(Vars.content.items().size);
public final boolean[] liquidfilters = new boolean[Vars.content.liquids().size]; public final Bits liquidfilters = new Bits(Vars.content.liquids().size);
public void init(){ public void init(){
results = Structs.filter(Consume.class, map, m -> m != null); results = Structs.filter(Consume.class, map, m -> m != null);

View File

@@ -10,8 +10,6 @@ import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.bullet.*; import io.anuke.mindustry.entities.bullet.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Item.Icon;
import io.anuke.mindustry.world.meta.*; import io.anuke.mindustry.world.meta.*;
import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.tilesize;
@@ -85,9 +83,6 @@ public class AmmoListValue<T extends UnlockableContent> implements StatValue{
} }
TextureRegion icon(T t){ TextureRegion icon(T t){
if(t instanceof Item){ return t.icon(Cicon.medium);
return ((Item)t).icon(Icon.medium);
}
return t.getContentIcon();
} }
} }

View File

@@ -26,7 +26,9 @@ import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Net.*; import io.anuke.mindustry.net.Net.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
import java.io.*;
import java.net.*; import java.net.*;
import java.nio.charset.*;
import java.util.*; import java.util.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -37,6 +39,12 @@ public class DesktopLauncher extends ClientLauncher{
boolean useDiscord = OS.is64Bit, showConsole = OS.getPropertyNotNull("user.name").equals("anuke"); boolean useDiscord = OS.is64Bit, showConsole = OS.getPropertyNotNull("user.name").equals("anuke");
static{
if(!Charset.forName("US-ASCII").newEncoder().canEncode(System.getProperty("user.name", ""))){
System.setProperty("com.codedisaster.steamworks.SharedLibraryExtractPath", new File("").getAbsolutePath());
}
}
public static void main(String[] arg){ public static void main(String[] arg){
try{ try{
new SdlApplication(new DesktopLauncher(arg), new SdlConfig(){{ new SdlApplication(new DesktopLauncher(arg), new SdlConfig(){{
@@ -131,7 +139,7 @@ public class DesktopLauncher extends ClientLauncher{
}catch(Throwable e){ }catch(Throwable e){
steam = false; steam = false;
Log.err("Failed to load Steam native libraries."); Log.err("Failed to load Steam native libraries.");
e.printStackTrace(); Log.err(e);
} }
} }
} }

View File

@@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=840b75daba69d93a5c493e740a573463e03f9ada archash=e17b152d4f597837640fe4d659ca5a820e8a2b15

View File

@@ -45,6 +45,7 @@ public class ApplicationTests{
public void setup(){ public void setup(){
headless = true; headless = true;
net = new Net(null); net = new Net(null);
tree = new FileTree();
Vars.init(); Vars.init();
content.createContent(); content.createContent();

View File

@@ -5,6 +5,7 @@ import io.anuke.arc.util.*;
import io.anuke.mindustry.*; import io.anuke.mindustry.*;
import io.anuke.mindustry.content.*; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.core.*; import io.anuke.mindustry.core.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.*; import io.anuke.mindustry.world.blocks.*;
import io.anuke.mindustry.world.blocks.power.*; import io.anuke.mindustry.world.blocks.power.*;
@@ -26,7 +27,12 @@ public class PowerTestFixture{
@BeforeAll @BeforeAll
static void initializeDependencies(){ static void initializeDependencies(){
Core.graphics = new FakeGraphics(); Core.graphics = new FakeGraphics();
Vars.content = new ContentLoader(); Vars.content = new ContentLoader(){
@Override
public void handleMappableContent(MappableContent content){
}
};
content.createContent(); content.createContent();
Log.setUseColors(false); Log.setUseColors(false);
Time.setDeltaProvider(() -> 0.5f); Time.setDeltaProvider(() -> 0.5f);

View File

@@ -1,16 +1,14 @@
package power; package power;
import io.anuke.arc.Core; import io.anuke.arc.*;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.power.PowerGenerator; import io.anuke.mindustry.world.blocks.power.*;
import io.anuke.mindustry.world.blocks.power.PowerGraph; import io.anuke.mindustry.world.consumers.*;
import io.anuke.mindustry.world.consumers.ConsumePower;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.junit.jupiter.api.DynamicTest.dynamicTest;
/** /**

View File

@@ -1,23 +1,21 @@
package io.anuke.mindustry; package io.anuke.mindustry;
import io.anuke.arc.graphics.Color; import io.anuke.arc.collection.*;
import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.*;
import io.anuke.arc.util.Log; import io.anuke.arc.util.*;
import io.anuke.arc.util.noise.RidgedPerlin; import io.anuke.arc.util.noise.*;
import io.anuke.mindustry.ImagePacker.GenRegion; import io.anuke.mindustry.ImagePacker.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.blocks.*; import io.anuke.mindustry.world.blocks.*;
import java.io.IOException; import java.io.*;
import java.nio.file.Files; import java.nio.file.*;
import java.nio.file.Paths;
import static io.anuke.mindustry.Vars.content; import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.tilesize;
public class Generators{ public class Generators{
@@ -143,15 +141,14 @@ public class Generators{
} }
} }
image.save(block.name + "-icon-full"); image.save("block-" + block.name + "-full");
image.save("../editor/" + block.name + "-icon-editor"); image.save("../editor/" + block.name + "-icon-editor");
for(Icon icon : Icon.values()){ for(Cicon icon : Cicon.scaled){
if(icon.size == 0) continue;
Image scaled = new Image(icon.size, icon.size); Image scaled = new Image(icon.size, icon.size);
scaled.drawScaled(image); scaled.drawScaled(image);
scaled.save("../ui/" + block.name + "-icon-" + icon.name()); scaled.save("../ui/block-" + block.name + "-" + icon.name());
} }
Color average = new Color(); Color average = new Color();
@@ -182,13 +179,13 @@ public class Generators{
}); });
ImagePacker.generate("item-icons", () -> { ImagePacker.generate("item-icons", () -> {
for(Item item : content.items()){ for(UnlockableContent item : (Array<? extends UnlockableContent>)(Array)Array.withArrays(content.items(), content.liquids())){
Image base = ImagePacker.get("item-" + item.name); Image base = ImagePacker.get(item.getContentType().name() + "-" + item.name);
for(Item.Icon icon : Item.Icon.values()){ for(Cicon icon : Cicon.scaled){
if(icon.size == base.width) continue; //if(icon.size == base.width) continue;
Image image = new Image(icon.size, icon.size); Image image = new Image(icon.size, icon.size);
image.drawScaled(base); image.drawScaled(base);
image.save("item-" + item.name + "-" + icon.name(), false); image.save(item.getContentType().name() + "-" + item.name + "-" + icon.name(), false);
} }
} }
}); });
@@ -213,7 +210,7 @@ public class Generators{
image.draw(mech.weapon.region, i * (int)mech.weaponOffsetX*4 + off, -(int)mech.weaponOffsetY*4 + off, i > 0, false); image.draw(mech.weapon.region, i * (int)mech.weaponOffsetX*4 + off, -(int)mech.weaponOffsetY*4 + off, i > 0, false);
} }
image.save("mech-icon-" + mech.name); image.save("mech-" + mech.name + "-full");
} }
}); });
@@ -236,7 +233,7 @@ public class Generators{
b, false); b, false);
} }
image.save("unit-icon-" + type.name); image.save("unit-" + type.name + "-full");
}); });
}); });
@@ -268,12 +265,11 @@ public class Generators{
image.save("../editor/editor-ore-" + item.name + (i + 1)); image.save("../editor/editor-ore-" + item.name + (i + 1));
//save icons //save icons
image.save(ore.name + "-icon-full"); image.save("block-" + ore.name + "-full");
for(Icon icon : Icon.values()){ for(Cicon icon : Cicon.scaled){
if(icon.size == 0) continue;
Image scaled = new Image(icon.size, icon.size); Image scaled = new Image(icon.size, icon.size);
scaled.drawScaled(image); scaled.drawScaled(image);
scaled.save(ore.name + "-icon-" + icon.name()); scaled.save("block-" + ore.name + "-" + icon.name());
} }
} }
}); });