Merge remote-tracking branch 'anuken/master'
This commit is contained in:
@@ -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"));
|
||||
|
||||
dispose.addStatement(name + ".dispose()");
|
||||
dispose.addStatement("io.anuke.arc.Core.assets.unload(" + filename + ")");
|
||||
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());
|
||||
});
|
||||
|
||||
@@ -1,32 +1,29 @@
|
||||
package io.anuke.annotations;
|
||||
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.source.util.Trees;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
|
||||
import io.anuke.annotations.Annotations.OverrideCallSuper;
|
||||
import com.sun.source.util.*;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.lang.model.*;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.tools.Diagnostic.*;
|
||||
import java.util.*;
|
||||
|
||||
@SupportedAnnotationTypes("java.lang.Override")
|
||||
@SupportedAnnotationTypes({"java.lang.Override"})
|
||||
public class CallSuperAnnotationProcessor extends AbstractProcessor{
|
||||
private Trees trees;
|
||||
|
||||
@Override
|
||||
public void init (ProcessingEnvironment pe) {
|
||||
public void init(ProcessingEnvironment pe){
|
||||
super.init(pe);
|
||||
trees = Trees.instance(pe);
|
||||
}
|
||||
|
||||
public boolean process (Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
for (Element e : roundEnv.getElementsAnnotatedWith(Override.class)) {
|
||||
if (e.getAnnotation(OverrideCallSuper.class) != null) return false;
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||
for(Element e : roundEnv.getElementsAnnotatedWith(Override.class)){
|
||||
if(e.getAnnotation(OverrideCallSuper.class) != null) return false;
|
||||
|
||||
CodeAnalyzerTreeScanner codeScanner = new CodeAnalyzerTreeScanner();
|
||||
codeScanner.setMethodName(e.getSimpleName().toString());
|
||||
@@ -34,10 +31,10 @@ public class CallSuperAnnotationProcessor extends AbstractProcessor{
|
||||
TreePath tp = trees.getPath(e.getEnclosingElement());
|
||||
codeScanner.scan(tp, trees);
|
||||
|
||||
if (codeScanner.isCallSuperUsed()) {
|
||||
if(codeScanner.isCallSuperUsed()){
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -46,12 +43,12 @@ public class CallSuperAnnotationProcessor extends AbstractProcessor{
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean doesCallSuper (List list, String methodName) {
|
||||
for (Object object : list) {
|
||||
if (object instanceof JCTree.JCExpressionStatement) {
|
||||
JCTree.JCExpressionStatement expr = (JCExpressionStatement) object;
|
||||
private boolean doesCallSuper(List list, String methodName){
|
||||
for(Object object : list){
|
||||
if(object instanceof JCTree.JCExpressionStatement){
|
||||
JCTree.JCExpressionStatement expr = (JCExpressionStatement)object;
|
||||
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
|
||||
public SourceVersion getSupportedSourceVersion () {
|
||||
public SourceVersion getSupportedSourceVersion(){
|
||||
return SourceVersion.RELEASE_8;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,15 +67,19 @@ committingchanges = Comitting Changes
|
||||
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.alpha = [scarlet](Alpha)
|
||||
mods.alpha = [accent](Alpha)
|
||||
mods = Mods
|
||||
mods.none = [LIGHT_GRAY]No mods found!
|
||||
mod.enabled = [lightgray]Enabled
|
||||
mod.disabled = [scarlet]Disabled
|
||||
mod.disable = Disable
|
||||
mod.enable = Enable
|
||||
mod.requiresrestart = The game will now close to apply the mod changes.
|
||||
mod.reloadrequired = [scarlet]Reload Required
|
||||
mod.import = Import Mod
|
||||
mod.remove.confirm = This mod will be deleted.
|
||||
mod.author = [LIGHT_GRAY]Author:[] {0}
|
||||
mod.missing = This save contains mods that you have recently updated or no longer have installed. Save corruption may occur. Are you sure you want to load it?\n[lightgray]Mods:\n{0}
|
||||
|
||||
about.button = About
|
||||
name = Name:
|
||||
@@ -177,7 +181,7 @@ save.rename.text = New name:
|
||||
selectslot = Select a save.
|
||||
slot = [accent]Slot {0}
|
||||
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>
|
||||
on = On
|
||||
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.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...
|
||||
reloading = [accent]Reloading Mods...
|
||||
saving = [accent]Saving...
|
||||
wave = [accent]Wave {0}
|
||||
wave.waiting = [lightgray]Wave in {0}
|
||||
@@ -459,8 +464,6 @@ settings.graphics = Graphics
|
||||
settings.cleardata = Clear Game Data...
|
||||
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.clearunlocks = Clear Unlocks
|
||||
settings.clearall = Clear All
|
||||
paused = [accent]< Paused >
|
||||
yes = Yes
|
||||
no = No
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+10215
-7275
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 |
@@ -2,6 +2,8 @@ package io.anuke.mindustry;
|
||||
|
||||
import io.anuke.arc.*;
|
||||
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.g2d.*;
|
||||
import io.anuke.arc.math.*;
|
||||
@@ -41,10 +43,15 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
||||
batch = new SpriteBatch();
|
||||
assets = new AssetManager();
|
||||
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);
|
||||
atlas = TextureAtlas.blankAtlas();
|
||||
Vars.net = new Net(platform.getNet());
|
||||
Vars.mods = new Mods();
|
||||
mods = new Mods();
|
||||
|
||||
UI.loadSystemCursors();
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import static io.anuke.arc.Core.*;
|
||||
public class Vars implements Loadable{
|
||||
/** Whether to load locales.*/
|
||||
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;
|
||||
/** IO buffer size. */
|
||||
public static final int bufferSize = 8192;
|
||||
@@ -196,10 +196,9 @@ public class Vars implements Loadable{
|
||||
|
||||
Version.init();
|
||||
|
||||
tree = new FileTree();
|
||||
if(mods == null){
|
||||
mods = new Mods();
|
||||
}
|
||||
if(tree == null) tree = new FileTree();
|
||||
if(mods == null) mods = new Mods();
|
||||
|
||||
content = new ContentLoader();
|
||||
loops = new LoopControl();
|
||||
defaultWaves = new DefaultWaves();
|
||||
@@ -258,7 +257,7 @@ public class Vars implements Loadable{
|
||||
public static void loadSettings(){
|
||||
Core.settings.setAppName(appName);
|
||||
|
||||
if(steam){
|
||||
if(steam || "steam".equals(Version.modifier)){
|
||||
Core.settings.setDataDirectory(Core.files.local("saves/"));
|
||||
}
|
||||
|
||||
|
||||
@@ -781,7 +781,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
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;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -792,7 +792,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
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;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -803,7 +803,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
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;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -814,7 +814,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
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;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -825,7 +825,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
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;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -836,7 +836,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
doorLarge = new Door("door-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(door.buildRequirements, 4));
|
||||
requirements(Category.defense, ItemStack.mult(door.requirements, 4));
|
||||
openfx = Fx.dooropenlarge;
|
||||
closefx = Fx.doorcloselarge;
|
||||
health = 100 * 4 * wallHealthMultiplier;
|
||||
@@ -1315,7 +1315,8 @@ public class Blocks implements ContentList{
|
||||
requirements(Category.turret, ItemStack.with(Items.copper, 85, Items.lead, 45));
|
||||
ammo(
|
||||
Items.scrap, Bullets.flakScrap,
|
||||
Items.lead, Bullets.flakLead
|
||||
Items.lead, Bullets.flakLead,
|
||||
Items.metaglass, Bullets.flakGlass
|
||||
);
|
||||
reload = 18f;
|
||||
range = 170f;
|
||||
@@ -1558,6 +1559,7 @@ public class Blocks implements ContentList{
|
||||
cyclone = new ItemTurret("cyclone"){{
|
||||
requirements(Category.turret, ItemStack.with(Items.copper, 200, Items.titanium, 125, Items.plastanium, 80));
|
||||
ammo(
|
||||
Items.metaglass, Bullets.flakGlass,
|
||||
Items.blastCompound, Bullets.flakExplosive,
|
||||
Items.plastanium, Bullets.flakPlastic,
|
||||
Items.surgealloy, Bullets.flakSurge
|
||||
|
||||
@@ -21,7 +21,7 @@ public class Bullets implements ContentList{
|
||||
artilleryDense, arilleryPlastic, artilleryPlasticFrag, artilleryHoming, artlleryIncendiary, artilleryExplosive, artilleryUnit,
|
||||
|
||||
//flak
|
||||
flakScrap, flakLead, flakPlastic, flakExplosive, flakSurge,
|
||||
flakScrap, flakLead, flakPlastic, flakExplosive, flakSurge, flakGlass, glassFrag,
|
||||
|
||||
//missiles
|
||||
missileExplosive, missileIncendiary, missileSurge, missileJavelin, missileSwarm, missileRevenant,
|
||||
@@ -55,7 +55,7 @@ public class Bullets implements ContentList{
|
||||
splashDamage = 33f;
|
||||
}};
|
||||
|
||||
artilleryPlasticFrag = new BasicBulletType(2.5f, 7, "bullet"){{
|
||||
artilleryPlasticFrag = new BasicBulletType(2.5f, 10, "bullet"){{
|
||||
bulletWidth = 10f;
|
||||
bulletHeight = 12f;
|
||||
bulletShrink = 1f;
|
||||
@@ -132,6 +132,16 @@ public class Bullets implements ContentList{
|
||||
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){{
|
||||
lifetime = 60f;
|
||||
ammoMultiplier = 4f;
|
||||
@@ -155,8 +165,23 @@ public class Bullets implements ContentList{
|
||||
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){{
|
||||
splashDamageRadius = 50f;
|
||||
splashDamage = 25f;
|
||||
fragBullet = artilleryPlasticFrag;
|
||||
fragBullets = 6;
|
||||
hitEffect = Fx.plasticExplosion;
|
||||
|
||||
@@ -11,7 +11,6 @@ import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.type.Item.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
|
||||
@@ -552,7 +551,7 @@ public class Fx implements ContentList{
|
||||
float length = 20f * e.finpow();
|
||||
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);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ public class TechTree implements ContentList{
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
TechNode.context = null;
|
||||
all = new Array<>();
|
||||
|
||||
root = node(coreShard, () -> {
|
||||
@@ -302,19 +303,24 @@ public class TechTree implements ContentList{
|
||||
});
|
||||
}
|
||||
|
||||
private TechNode node(Block block, Runnable children){
|
||||
ItemStack[] requirements = new ItemStack[block.buildRequirements.length];
|
||||
private static TechNode node(Block block, Runnable children){
|
||||
ItemStack[] requirements = new ItemStack[block.requirements.length];
|
||||
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);
|
||||
}
|
||||
|
||||
private TechNode node(Block block){
|
||||
private static TechNode node(Block 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{
|
||||
static TechNode context;
|
||||
|
||||
@@ -322,19 +328,22 @@ public class TechTree implements ContentList{
|
||||
public final ItemStack[] requirements;
|
||||
public final Array<TechNode> children = new Array<>();
|
||||
|
||||
TechNode(Block block, ItemStack[] requirements, Runnable children){
|
||||
if(context != null){
|
||||
context.children.add(this);
|
||||
TechNode(TechNode ccontext, Block block, ItemStack[] requirements, Runnable children){
|
||||
if(ccontext != null){
|
||||
ccontext.children.add(this);
|
||||
}
|
||||
|
||||
this.block = block;
|
||||
this.requirements = requirements;
|
||||
|
||||
TechNode last = context;
|
||||
context = this;
|
||||
children.run();
|
||||
context = last;
|
||||
context = ccontext;
|
||||
all.add(this);
|
||||
}
|
||||
|
||||
TechNode(Block block, ItemStack[] requirements, Runnable children){
|
||||
this(context, block, requirements, children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,14 @@ public class ContentLoader{
|
||||
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. */
|
||||
public void createContent(){
|
||||
if(loaded){
|
||||
@@ -58,37 +66,11 @@ public class ContentLoader{
|
||||
list.load();
|
||||
}
|
||||
|
||||
setupMapping();
|
||||
|
||||
if(mods != null){
|
||||
mods.loadContent();
|
||||
}
|
||||
|
||||
setupMapping();
|
||||
|
||||
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
|
||||
//check up ID mapping, make sure it's linear
|
||||
for(Array<Content> arr : contentMap){
|
||||
for(int i = 0; i < arr.size; i++){
|
||||
int id = arr.get(i).id;
|
||||
@@ -97,6 +79,8 @@ public class ContentLoader{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
/** Logs content statistics.*/
|
||||
@@ -125,6 +109,7 @@ public class ContentLoader{
|
||||
|
||||
for(ContentType type : ContentType.values()){
|
||||
for(Content content : contentMap[type.ordinal()]){
|
||||
//TODO catch error and display it per mod
|
||||
callable.accept(content);
|
||||
}
|
||||
}
|
||||
@@ -154,6 +139,14 @@ public class ContentLoader{
|
||||
|
||||
public void handleContent(Content 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){
|
||||
|
||||
@@ -91,6 +91,7 @@ public class Control implements ApplicationListener, Loadable{
|
||||
hiscore = true;
|
||||
world.getMap().setHighScore(state.wave);
|
||||
}
|
||||
|
||||
Sounds.wave.play();
|
||||
});
|
||||
|
||||
@@ -388,7 +389,10 @@ public class Control implements ApplicationListener, Loadable{
|
||||
saves.update();
|
||||
|
||||
//update and load any requested assets
|
||||
assets.update();
|
||||
try{
|
||||
assets.update();
|
||||
}catch(Exception ignored){
|
||||
}
|
||||
|
||||
input.updateState();
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package io.anuke.mindustry.core;
|
||||
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.assets.loaders.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.files.*;
|
||||
|
||||
/** Handles files in a modded context. */
|
||||
public class FileTree{
|
||||
public class FileTree implements FileHandleResolver{
|
||||
private ObjectMap<String, FileHandle> files = new ObjectMap<>();
|
||||
|
||||
public void addFile(FileHandle f){
|
||||
files.put(f.path(), f);
|
||||
public void addFile(String path, FileHandle f){
|
||||
files.put(path, f);
|
||||
}
|
||||
|
||||
/** Gets an asset file.*/
|
||||
@@ -20,4 +21,14 @@ public class FileTree{
|
||||
return Core.files.internal(path);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears all mod files.*/
|
||||
public void clear(){
|
||||
files.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileHandle resolve(String fileName){
|
||||
return get(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,13 @@ public class Logic implements ApplicationListener{
|
||||
|
||||
public Logic(){
|
||||
Events.on(WaveEvent.class, event -> {
|
||||
if(world.isZone()){
|
||||
world.getZone().updateWave(state.wave);
|
||||
}
|
||||
for(Player p : playerGroup.all()){
|
||||
p.respawns = state.rules.respawns;
|
||||
}
|
||||
|
||||
if(world.isZone()){
|
||||
world.getZone().updateWave(state.wave);
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(BlockDestroyEvent.class, event -> {
|
||||
|
||||
@@ -18,12 +18,10 @@ import io.anuke.mindustry.entities.effect.*;
|
||||
import io.anuke.mindustry.entities.effect.GroundEffectEntity.*;
|
||||
import io.anuke.mindustry.entities.traits.*;
|
||||
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.EventType.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.input.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.defense.ForceProjector.*;
|
||||
|
||||
import static io.anuke.arc.Core.*;
|
||||
@@ -310,7 +308,7 @@ public class Renderer implements ApplicationListener{
|
||||
float fract = landTime / Fx.coreLand.lifetime;
|
||||
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 s = reg.getWidth() * Draw.scl * scl * 4f * fract;
|
||||
|
||||
|
||||
@@ -417,6 +417,22 @@ public class UI implements ApplicationListener, Loadable{
|
||||
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){
|
||||
FloatingDialog dialog = new FloatingDialog(title);
|
||||
dialog.cont.add(text).width(500f).wrap().pad(4f).get().setAlignment(Align.center, Align.center);
|
||||
|
||||
@@ -702,7 +702,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
||||
});
|
||||
|
||||
for(Block block : blocksOut){
|
||||
TextureRegion region = block.icon(Block.Icon.medium);
|
||||
TextureRegion region = block.icon(Cicon.medium);
|
||||
|
||||
if(!Core.atlas.isFound(region)) continue;
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
||||
GenTile tile = buffer1[px][py];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ public class WaveInfoDialog extends FloatingDialog{
|
||||
t.margin(0).defaults().pad(3).padLeft(5f).growX().left();
|
||||
t.addButton(b -> {
|
||||
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);
|
||||
}, () -> showUpdate(group)).pad(-6f).padBottom(0f);
|
||||
|
||||
@@ -221,7 +221,7 @@ public class WaveInfoDialog extends FloatingDialog{
|
||||
for(UnitType type : content.units()){
|
||||
dialog.cont.addButton(t -> {
|
||||
t.left();
|
||||
t.addImage(type.iconRegion).size(40f).padRight(2f);
|
||||
t.addImage(type.icon(Cicon.medium)).size(40f).padRight(2f);
|
||||
t.add(type.localizedName);
|
||||
}, () -> {
|
||||
lastType = type;
|
||||
@@ -253,7 +253,7 @@ public class WaveInfoDialog extends FloatingDialog{
|
||||
for(int j = 0; j < spawned.length; j++){
|
||||
if(spawned[j] > 0){
|
||||
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.row();
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
|
||||
@Override
|
||||
public TextureRegion getIconRegion(){
|
||||
return type.iconRegion;
|
||||
return type.icon(Cicon.full);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -160,7 +160,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
||||
|
||||
@Override
|
||||
public TextureRegion getIconRegion(){
|
||||
return mech.iconRegion;
|
||||
return mech.icon(Cicon.full);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -281,7 +281,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
||||
public void drawShadow(float offsetX, float offsetY){
|
||||
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
|
||||
|
||||
@@ -216,10 +216,14 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
float cx = x - fsize/2f, cy = y - fsize/2f;
|
||||
|
||||
for(Team team : Team.all){
|
||||
avoid(unitGroups[team.ordinal()].intersect(cx, cy, fsize, fsize));
|
||||
if(team != getTeam() || !(this instanceof Player)){
|
||||
avoid(unitGroups[team.ordinal()].intersect(cx, cy, fsize, fsize));
|
||||
}
|
||||
}
|
||||
|
||||
avoid(playerGroup.intersect(cx, cy, fsize, fsize));
|
||||
if(!(this instanceof Player)){
|
||||
avoid(playerGroup.intersect(cx, cy, fsize, fsize));
|
||||
}
|
||||
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;
|
||||
|
||||
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 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));
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable
|
||||
TileEntity getClosestCore(){
|
||||
public @Nullable TileEntity getClosestCore(){
|
||||
TeamData data = state.teams.get(team);
|
||||
|
||||
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;
|
||||
|
||||
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),
|
||||
y + Angles.trnsy(rotation + 180f, backTrns),
|
||||
size, size, rotation);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.mod.Mods.*;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
|
||||
|
||||
/** Base class for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}. */
|
||||
public abstract class Content{
|
||||
public final short id;
|
||||
/** The mod that loaded this piece of content. */
|
||||
public @Nullable LoadedMod mod;
|
||||
|
||||
public Content(){
|
||||
this.id = (short)Vars.content.getBy(getContentType()).size;
|
||||
|
||||
@@ -83,6 +83,10 @@ public class EventType{
|
||||
|
||||
}
|
||||
|
||||
public static class ContentReloadEvent{
|
||||
|
||||
}
|
||||
|
||||
public static class DisposeEvent{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.mindustry.*;
|
||||
|
||||
public abstract class MappableContent extends Content{
|
||||
public final String name;
|
||||
|
||||
public MappableContent(String name){
|
||||
this.name = name;
|
||||
Vars.content.handleMappableContent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.anuke.arc.files.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.async.*;
|
||||
import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.core.GameState.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.io.*;
|
||||
@@ -253,6 +254,17 @@ public class Saves{
|
||||
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(){
|
||||
return Core.settings.getString("save-" + index + "-name", "untitled");
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.*;
|
||||
|
||||
/** Base interface for an unlockable content type. */
|
||||
public abstract class UnlockableContent extends MappableContent{
|
||||
@@ -11,6 +12,8 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
public String localizedName;
|
||||
/** Localized description. May be null. */
|
||||
public String description;
|
||||
/** Icons by Cicon ID.*/
|
||||
protected TextureRegion[] cicons = new TextureRegion[Cicon.all.length];
|
||||
|
||||
public UnlockableContent(String name){
|
||||
super(name);
|
||||
@@ -19,10 +22,24 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
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. */
|
||||
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. */
|
||||
public abstract void displayInfo(Table table);
|
||||
|
||||
@@ -132,7 +132,7 @@ public class BlockRenderer implements Disposable{
|
||||
|
||||
Draw.alpha(0.5f);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import io.anuke.arc.util.noise.RidgedPerlin;
|
||||
import io.anuke.arc.util.noise.Simplex;
|
||||
import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.content.UnitTypes;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.UnitType;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.Floor;
|
||||
@@ -252,7 +253,9 @@ public class MenuRenderer implements Disposable{
|
||||
private void drawFlyers(){
|
||||
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) -> {
|
||||
Draw.rect(flyerType.region, x - 12f, y - 13f, flyerRot - 90);
|
||||
|
||||
@@ -106,7 +106,7 @@ public class MinimapRenderer implements Disposable{
|
||||
public void updateAll(){
|
||||
for(int x = 0; x < world.width(); x++){
|
||||
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);
|
||||
@@ -114,7 +114,7 @@ public class MinimapRenderer implements Disposable{
|
||||
|
||||
public void update(Tile tile){
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
package io.anuke.mindustry.graphics;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.arc.util.Tmp;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.input.*;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -125,7 +122,7 @@ public class OverlayRenderer{
|
||||
if(input.isDroppingItem()){
|
||||
Vector2 v = Core.input.mouseWorld(input.getMouseX(), input.getMouseY());
|
||||
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);
|
||||
Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f));
|
||||
Draw.reset();
|
||||
|
||||
@@ -81,8 +81,8 @@ public class MapIO{
|
||||
super.setBlock(type);
|
||||
int c = colorFor(Blocks.air, block(), Blocks.air, getTeam());
|
||||
if(c != black){
|
||||
walls.drawPixel(x, floors.getHeight() - 1 - y, c);
|
||||
floors.drawPixel(x, floors.getHeight() - 1 - y + 1, shade);
|
||||
walls.draw(x, floors.getHeight() - 1 - y, c);
|
||||
floors.draw(x, floors.getHeight() - 1 - y + 1, shade);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,9 +112,9 @@ public class MapIO{
|
||||
@Override
|
||||
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
||||
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{
|
||||
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){
|
||||
map.spawns ++;
|
||||
@@ -136,7 +136,7 @@ public class MapIO{
|
||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||
for(int y = 0; y < pixmap.getHeight(); 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;
|
||||
|
||||
@@ -66,7 +66,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
||||
"wavetime", state.wavetime,
|
||||
"stats", JsonIO.write(state.stats),
|
||||
"rules", JsonIO.write(state.rules),
|
||||
"mods", JsonIO.write(mods.getModNames().toArray(String.class)),
|
||||
"mods", JsonIO.write(mods.getModStrings().toArray(String.class)),
|
||||
"width", world.width(),
|
||||
"height", world.height()
|
||||
).merge(tags));
|
||||
|
||||
@@ -8,20 +8,20 @@ import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.ui.dialogs.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.Block.*;
|
||||
import io.anuke.mindustry.world.blocks.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.updateEditorOnChange;
|
||||
|
||||
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> wallsOnly = b -> (!b.synthetic() && !(b instanceof Floor)) && 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(Icon.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> 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> oresOnly = b -> 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(Cicon.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(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(Cicon.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 abstract void build(Table table);
|
||||
@@ -76,15 +76,15 @@ public abstract class FilterOption{
|
||||
|
||||
@Override
|
||||
public void build(Table table){
|
||||
table.addButton(b -> b.addImage(supplier.get().icon(Icon.small)).update(i -> ((TextureRegionDrawable)i.getDrawable())
|
||||
.setRegion(supplier.get() == Blocks.air ? Core.atlas.find("icon-none") : supplier.get().icon(Icon.small))).size(8 * 3), () -> {
|
||||
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(Cicon.small))).size(8 * 3), () -> {
|
||||
FloatingDialog dialog = new FloatingDialog("");
|
||||
dialog.setFillParent(false);
|
||||
int i = 0;
|
||||
for(Block block : Vars.content.blocks()){
|
||||
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);
|
||||
dialog.hide();
|
||||
changed.run();
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package io.anuke.mindustry.mod;
|
||||
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.audio.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.function.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.arc.util.*;
|
||||
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.type.*;
|
||||
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.world.*;
|
||||
|
||||
@@ -23,7 +28,30 @@ public class ContentParser{
|
||||
private ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<Class<?>, FieldParser>(){{
|
||||
put(BulletType.class, (type, data) -> field(Bullets.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(){
|
||||
public <T> T readValue(Class<T> type, Class elementType, JsonValue jsonData){
|
||||
@@ -33,7 +61,11 @@ public class ContentParser{
|
||||
}
|
||||
|
||||
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(
|
||||
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");
|
||||
Block block = type.getDeclaredConstructor(String.class).newInstance(mod + "-" + name);
|
||||
readFields(block, value, true);
|
||||
//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"
|
||||
);
|
||||
|
||||
//make block visible
|
||||
if(block.buildRequirements != null){
|
||||
block.buildVisibility = () -> true;
|
||||
}
|
||||
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);
|
||||
|
||||
//add research tech node
|
||||
if(value.has("research")){
|
||||
TechTree.create(Vars.content.getByName(ContentType.block, value.get("research").asString()), block);
|
||||
}
|
||||
|
||||
//make block visible
|
||||
if(value.has("requirements")){
|
||||
block.buildVisibility = () -> true;
|
||||
}
|
||||
});
|
||||
|
||||
return block;
|
||||
},
|
||||
ContentType.unit, (TypeParser<UnitType>)(mod, name, value) -> {
|
||||
Class<BaseUnit> type = resolve(value.getString("type"), "io.anuke.mindustry.entities.type.base");
|
||||
UnitType unit = new UnitType(mod + "-" + name, supply(type));
|
||||
readFields(unit, value, true);
|
||||
read(() -> readFields(unit, value, true));
|
||||
|
||||
return unit;
|
||||
},
|
||||
@@ -75,11 +153,20 @@ public class ContentParser{
|
||||
}else{
|
||||
item = constructor.get(mod + "-" + name);
|
||||
}
|
||||
readFields(item, value);
|
||||
read(() -> readFields(item, value));
|
||||
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(){
|
||||
for(ContentType type : ContentType.all){
|
||||
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.
|
||||
* @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
|
||||
* @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()){
|
||||
init();
|
||||
}
|
||||
@@ -112,7 +204,9 @@ public class ContentParser{
|
||||
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);
|
||||
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.
|
||||
* Throws an exception if any are null.*/
|
||||
private void checkNulls(Object object){
|
||||
@@ -187,7 +291,9 @@ public class ContentParser{
|
||||
FieldMetadata metadata = fields.get(child.name().replace(" ", "_"));
|
||||
if(metadata == null){
|
||||
if(ignoreUnknownFields){
|
||||
Log.err("{0}: Ignoring unknown field: " + child.name + " (" + type.getName() + ")", object);
|
||||
if(!child.name.equals("research")){
|
||||
Log.err("{0}: Ignoring unknown field: " + child.name + " (" + type.getName() + ")", object);
|
||||
}
|
||||
continue;
|
||||
}else{
|
||||
SerializationException ex = new SerializationException("Field not found: " + child.name + " (" + type.getName() + ")");
|
||||
|
||||
@@ -9,13 +9,16 @@ import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.Pixmap.*;
|
||||
import io.anuke.arc.graphics.Texture.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.graphics.g2d.TextureAtlas.*;
|
||||
import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.io.*;
|
||||
import io.anuke.arc.util.serialization.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.plugin.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
@@ -32,8 +35,9 @@ public class Mods implements Loadable{
|
||||
private PixmapPacker packer;
|
||||
|
||||
private Array<LoadedMod> loaded = new Array<>();
|
||||
private Array<LoadedMod> disabled = new Array<>();
|
||||
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.
|
||||
* Call this in init(). */
|
||||
@@ -59,7 +63,7 @@ public class Mods implements Loadable{
|
||||
file.copyTo(dest);
|
||||
try{
|
||||
loaded.add(loadMod(file));
|
||||
requiresRestart = true;
|
||||
requiresReload = true;
|
||||
}catch(IOException e){
|
||||
dest.delete();
|
||||
throw e;
|
||||
@@ -75,27 +79,31 @@ public class Mods implements Loadable{
|
||||
if(loaded.isEmpty()) return;
|
||||
|
||||
packer = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true);
|
||||
|
||||
for(LoadedMod mod : loaded){
|
||||
try{
|
||||
int packed = 0;
|
||||
for(FileHandle file : mod.root.child("sprites").list()){
|
||||
if(file.extension().equals("png")){
|
||||
try(InputStream stream = file.read()){
|
||||
byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512));
|
||||
Pixmap pixmap = new Pixmap(bytes, 0, bytes.length);
|
||||
packer.pack(mod.name + "-" + file.nameWithoutExtension(), pixmap);
|
||||
pixmap.dispose();
|
||||
packed ++;
|
||||
totalSprites ++;
|
||||
}
|
||||
int[] packed = {0};
|
||||
boolean[] failed = {false};
|
||||
mod.root.child("sprites").walk(file -> {
|
||||
if(failed[0]) return;
|
||||
if(file.extension().equals("png")){
|
||||
try(InputStream stream = file.read()){
|
||||
byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512));
|
||||
Pixmap pixmap = new Pixmap(bytes, 0, bytes.length);
|
||||
packer.pack(mod.name + "-" + file.nameWithoutExtension(), pixmap);
|
||||
pixmap.dispose();
|
||||
packed[0] ++;
|
||||
totalSprites ++;
|
||||
}catch(IOException e){
|
||||
failed[0] = true;
|
||||
Core.app.post(() -> {
|
||||
Log.err("Error packing images for mod: {0}", mod.meta.name);
|
||||
e.printStackTrace();
|
||||
if(!headless) ui.showException(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
Log.info("Packed {0} images for mod '{1}'.", packed, mod.meta.name);
|
||||
}catch(IOException e){
|
||||
Log.err("Error packing images for mod: {0}", mod.meta.name);
|
||||
e.printStackTrace();
|
||||
if(!headless) ui.showException(e);
|
||||
}
|
||||
});
|
||||
Log.info("Packed {0} images for mod '{1}'.", packed[0], mod.meta.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,14 +111,36 @@ public class Mods implements Loadable{
|
||||
public void loadSync(){
|
||||
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
|
||||
if(totalSprites > 0){
|
||||
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 = null;
|
||||
}
|
||||
|
||||
/** Removes a mod file and marks it for requiring a restart. */
|
||||
@@ -121,11 +151,11 @@ public class Mods implements Loadable{
|
||||
mod.file.delete();
|
||||
}
|
||||
loaded.remove(mod);
|
||||
requiresRestart = true;
|
||||
requiresReload = true;
|
||||
}
|
||||
|
||||
public boolean requiresRestart(){
|
||||
return requiresRestart;
|
||||
public boolean requiresReload(){
|
||||
return requiresReload;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
|
||||
try{
|
||||
loaded.add(loadMod(file));
|
||||
LoadedMod mod = loadMod(file);
|
||||
if(mod.enabled()){
|
||||
loaded.add(mod);
|
||||
}else{
|
||||
disabled.add(mod);
|
||||
}
|
||||
}catch(IllegalArgumentException ignored){
|
||||
}catch(Exception e){
|
||||
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
|
||||
if(file.isDirectory() && !specialFolders.contains(file.name())){
|
||||
//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. */
|
||||
public void loadContent(){
|
||||
for(LoadedMod mod : loaded){
|
||||
@@ -197,7 +257,8 @@ public class Mods implements Loadable{
|
||||
for(FileHandle file : folder.list()){
|
||||
if(file.extension().equals("json")){
|
||||
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);
|
||||
}catch(Exception 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);
|
||||
}
|
||||
|
||||
@@ -217,6 +281,11 @@ public class Mods implements Loadable{
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/** @return all disabled mods. */
|
||||
public Array<LoadedMod> disabled(){
|
||||
return disabled;
|
||||
}
|
||||
|
||||
/** @return a list of mod names only, without versions. */
|
||||
public Array<String> getModNames(){
|
||||
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);
|
||||
}
|
||||
|
||||
/** 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.
|
||||
* 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){
|
||||
Array<String> mods = getModStrings();
|
||||
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
|
||||
if(mainFile.exists()){
|
||||
//other platforms don't have standard java class loaders
|
||||
if(mobile){
|
||||
throw new IllegalArgumentException("This mod is not compatible with " + (ios ? "iOS" : "Android") + ".");
|
||||
if(!headless && Version.build != -1){
|
||||
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());
|
||||
@@ -305,9 +389,6 @@ public class Mods implements Loadable{
|
||||
/** This mod's metadata. */
|
||||
public final ModMeta meta;
|
||||
|
||||
//TODO implement
|
||||
protected boolean enabled;
|
||||
|
||||
public LoadedMod(FileHandle file, FileHandle root, Mod mod, ModMeta meta){
|
||||
this.root = root;
|
||||
this.file = file;
|
||||
@@ -315,6 +396,10 @@ public class Mods implements Loadable{
|
||||
this.meta = meta;
|
||||
this.name = meta.name.toLowerCase().replace(" ", "-");
|
||||
}
|
||||
|
||||
public boolean enabled(){
|
||||
return Core.settings.getBool(name + "-enabled", true);
|
||||
}
|
||||
}
|
||||
|
||||
/** Plugin metadata information.*/
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.anuke.mindustry.type;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
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 final Color color;
|
||||
private TextureRegion[] regions;
|
||||
|
||||
/** type of the item; used for tabs and core acceptance. default value is {@link 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));
|
||||
}
|
||||
|
||||
@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
|
||||
public boolean alwaysUnlocked(){
|
||||
return alwaysUnlocked;
|
||||
@@ -71,11 +56,6 @@ public class Item extends UnlockableContent implements Comparable<Item>{
|
||||
return Core.bundle.get("item." + this.name + ".name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return icon(Icon.large);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return localizedName();
|
||||
@@ -91,20 +71,6 @@ public class Item extends UnlockableContent implements Comparable<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. */
|
||||
public static Array<Item> getAllOres(){
|
||||
return content.blocks().select(b -> b instanceof OreBlock).map(b -> ((Floor)b).itemDrop);
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.anuke.mindustry.content.Items;
|
||||
|
||||
public class ItemStack implements Comparable<ItemStack>{
|
||||
public Item item;
|
||||
public int amount;
|
||||
public int amount = 1;
|
||||
|
||||
public ItemStack(Item item, int amount){
|
||||
if(item == null) item = Items.copper;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package io.anuke.mindustry.type;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.content.StatusEffects;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.ui.ContentDisplay;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
|
||||
public class Liquid extends UnlockableContent{
|
||||
public final Color color;
|
||||
@@ -25,8 +24,6 @@ public class Liquid extends UnlockableContent{
|
||||
public Color flameColor = Color.valueOf("ffb763");
|
||||
/** The associated status effect. */
|
||||
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){
|
||||
super(name);
|
||||
@@ -43,11 +40,6 @@ public class Liquid extends UnlockableContent{
|
||||
return flammability < 0.1f && temperature <= 0.5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
iconRegion = Core.atlas.find("liquid-" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayInfo(Table table){
|
||||
ContentDisplay.displayLiquid(table, this);
|
||||
@@ -58,11 +50,6 @@ public class Liquid extends UnlockableContent{
|
||||
return Core.bundle.get("liquid." + this.name + ".name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return iconRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return localizedName();
|
||||
|
||||
@@ -9,6 +9,11 @@ public class LiquidStack{
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
/** serialization only*/
|
||||
protected LiquidStack(){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "LiquidStack{" +
|
||||
|
||||
@@ -33,7 +33,7 @@ public class Mech extends UnlockableContent{
|
||||
public float weaponOffsetX, weaponOffsetY, engineOffset = 5f, engineSize = 2.5f;
|
||||
public Weapon weapon;
|
||||
|
||||
public TextureRegion baseRegion, legRegion, region, iconRegion;
|
||||
public TextureRegion baseRegion, legRegion, region;
|
||||
|
||||
public Mech(String name, boolean flying){
|
||||
super(name);
|
||||
@@ -94,11 +94,6 @@ public class Mech extends UnlockableContent{
|
||||
ContentDisplay.displayMech(table, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return iconRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getContentType(){
|
||||
return ContentType.mech;
|
||||
@@ -113,7 +108,6 @@ public class Mech extends UnlockableContent{
|
||||
}
|
||||
|
||||
region = Core.atlas.find(name);
|
||||
iconRegion = Core.atlas.find("mech-icon-" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,7 +40,7 @@ public class UnitType extends UnlockableContent{
|
||||
public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
|
||||
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){
|
||||
this(name);
|
||||
@@ -68,15 +68,9 @@ public class UnitType extends UnlockableContent{
|
||||
return Core.bundle.get("unit." + name + ".name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return iconRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
weapon.load();
|
||||
iconRegion = Core.atlas.find("unit-icon-" + name, Core.atlas.find(name));
|
||||
region = Core.atlas.find(name);
|
||||
legRegion = Core.atlas.find(name + "-leg");
|
||||
baseRegion = Core.atlas.find(name + "-base");
|
||||
|
||||
@@ -198,11 +198,6 @@ public class Zone extends UnlockableContent{
|
||||
public void displayInfo(Table table){
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String localizedName(){
|
||||
return Core.bundle.get("zone." + name + ".name");
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.OrderedMap;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Strings;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.meta.*;
|
||||
|
||||
public class ContentDisplay{
|
||||
@@ -19,7 +18,7 @@ public class ContentDisplay{
|
||||
table.table(title -> {
|
||||
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);
|
||||
});
|
||||
|
||||
@@ -67,7 +66,7 @@ public class ContentDisplay{
|
||||
public static void displayItem(Table table, Item item){
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
@@ -98,7 +97,7 @@ public class ContentDisplay{
|
||||
public static void displayLiquid(Table table, Liquid liquid){
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
@@ -132,7 +131,7 @@ public class ContentDisplay{
|
||||
|
||||
public static void displayMech(Table table, Mech mech){
|
||||
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);
|
||||
});
|
||||
table.left().defaults().left();
|
||||
@@ -180,7 +179,7 @@ public class ContentDisplay{
|
||||
|
||||
public static void displayUnit(Table table, UnitType unit){
|
||||
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);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.layout.Stack;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
|
||||
public class ItemImage extends Stack{
|
||||
|
||||
@@ -25,7 +24,7 @@ public class ItemImage extends 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){
|
||||
Table t = new Table().left().bottom();
|
||||
|
||||
@@ -3,18 +3,14 @@ package io.anuke.mindustry.ui;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.core.GameState.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
/** Displays a list of items, e.g. launched items.*/
|
||||
public class ItemsDisplay extends Table{
|
||||
private static final NumberFormat format = NumberFormat.getNumberInstance(Locale.getDefault());
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
|
||||
public ItemsDisplay(){
|
||||
@@ -33,7 +29,7 @@ public class ItemsDisplay extends Table{
|
||||
for(Item item : content.items()){
|
||||
if(item.type == ItemType.material && data.isUnlocked(item)){
|
||||
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.row();
|
||||
}
|
||||
@@ -44,7 +40,7 @@ public class ItemsDisplay extends Table{
|
||||
private String format(Item item){
|
||||
builder.setLength(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(ui.formatAmount(state.teams.get(player.getTeam()).cores.first().entity.items.get(item)));
|
||||
}
|
||||
|
||||
@@ -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.Table;
|
||||
import io.anuke.arc.util.Strings;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.world.meta.StatUnit;
|
||||
|
||||
@@ -20,7 +21,7 @@ public class LiquidDisplay extends Table{
|
||||
this.perSecond = perSecond;
|
||||
|
||||
add(new Stack(){{
|
||||
add(new Image(liquid.getContentIcon()));
|
||||
add(new Image(liquid.icon(Cicon.medium)));
|
||||
|
||||
if(amount != 0){
|
||||
Table t = new Table().left().bottom();
|
||||
|
||||
@@ -10,8 +10,7 @@ import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.Content;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
@@ -56,7 +55,7 @@ public class DatabaseDialog extends FloatingDialog{
|
||||
for(int i = 0; i < array.size; 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);
|
||||
ClickListener listener = new ClickListener();
|
||||
image.addListener(listener);
|
||||
|
||||
@@ -103,19 +103,21 @@ public class DeployDialog extends FloatingDialog{
|
||||
}
|
||||
|
||||
TextButton button = Elements.newButton(Core.bundle.format("resume", slot.getZone().localizedName()), Styles.squaret, () -> {
|
||||
hide();
|
||||
ui.loadAnd(() -> {
|
||||
logic.reset();
|
||||
net.reset();
|
||||
try{
|
||||
control.saves.getZoneSlot().load();
|
||||
state.set(State.playing);
|
||||
}catch(SaveException e){ //make sure to handle any save load errors!
|
||||
e.printStackTrace();
|
||||
if(control.saves.getZoneSlot() != null) control.saves.getZoneSlot().delete();
|
||||
Core.app.post(() -> ui.showInfo("$save.corrupted"));
|
||||
show();
|
||||
}
|
||||
control.saves.getZoneSlot().cautiousLoad(() -> {
|
||||
hide();
|
||||
ui.loadAnd(() -> {
|
||||
logic.reset();
|
||||
net.reset();
|
||||
try{
|
||||
slot.load();
|
||||
state.set(State.playing);
|
||||
}catch(SaveException e){ //make sure to handle any save load errors!
|
||||
e.printStackTrace();
|
||||
if(control.saves.getZoneSlot() != null) control.saves.getZoneSlot().delete();
|
||||
Core.app.post(() -> ui.showInfo("$save.corrupted"));
|
||||
show();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -2,11 +2,10 @@ package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.mindustry.core.GameState.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.game.Stats.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.type.Item.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -69,7 +68,7 @@ public class GameOverDialog extends FloatingDialog{
|
||||
if(state.stats.itemsDelivered.get(item, 0) > 0){
|
||||
t.table(items -> {
|
||||
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();
|
||||
t.row();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class HostDialog extends FloatingDialog{
|
||||
|
||||
if(steam){
|
||||
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);
|
||||
platform.updateLobby();
|
||||
});
|
||||
|
||||
@@ -186,22 +186,23 @@ public class LoadDialog extends FloatingDialog{
|
||||
}
|
||||
|
||||
public void runLoadSave(SaveSlot slot){
|
||||
hide();
|
||||
ui.paused.hide();
|
||||
|
||||
ui.loadAnd(() -> {
|
||||
try{
|
||||
net.reset();
|
||||
slot.load();
|
||||
state.rules.editor = false;
|
||||
state.rules.zone = null;
|
||||
state.set(State.playing);
|
||||
}catch(SaveException e){
|
||||
Log.err(e);
|
||||
state.set(State.menu);
|
||||
logic.reset();
|
||||
ui.showErrorMessage("$save.corrupted");
|
||||
}
|
||||
slot.cautiousLoad(() -> {
|
||||
ui.loadAnd(() -> {
|
||||
hide();
|
||||
ui.paused.hide();
|
||||
try{
|
||||
net.reset();
|
||||
slot.load();
|
||||
state.rules.editor = false;
|
||||
state.rules.zone = null;
|
||||
state.set(State.playing);
|
||||
}catch(SaveException e){
|
||||
Log.err(e);
|
||||
state.set(State.menu);
|
||||
logic.reset();
|
||||
ui.showErrorMessage("$save.corrupted");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.anuke.arc.input.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
@@ -55,7 +56,7 @@ public class LoadoutDialog extends FloatingDialog{
|
||||
}).size(300f, 36f).get();
|
||||
button.clearChildren();
|
||||
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);
|
||||
dialog.cont.row();
|
||||
}
|
||||
@@ -118,7 +119,7 @@ public class LoadoutDialog extends FloatingDialog{
|
||||
ui.showInfo(Core.bundle.format("configure.invalid", capacity));
|
||||
})).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.row();
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.mod.Mods.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
|
||||
@@ -17,9 +20,9 @@ public class ModsDialog extends FloatingDialog{
|
||||
shown(this::setup);
|
||||
|
||||
hidden(() -> {
|
||||
if(mods.requiresRestart()){
|
||||
ui.showOkText("$mods", "$mod.requiresrestart", () -> {
|
||||
Core.app.exit();
|
||||
if(mods.requiresReload()){
|
||||
ui.loadAnd("$reloading", () -> {
|
||||
mods.reloadContent();
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -34,18 +37,34 @@ public class ModsDialog extends FloatingDialog{
|
||||
void setup(){
|
||||
cont.clear();
|
||||
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 -> {
|
||||
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 -> {
|
||||
t.defaults().pad(2).left().top();
|
||||
t.margin(14f).left();
|
||||
t.table(title -> {
|
||||
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.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", () -> {
|
||||
mods.removeMod(mod);
|
||||
setup();
|
||||
|
||||
@@ -317,6 +317,10 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
tex.setFilter(filter, filter);
|
||||
}
|
||||
}
|
||||
|
||||
if(!mobile){
|
||||
Core.settings.put("swapdiagonal", false);
|
||||
}
|
||||
}
|
||||
|
||||
private void back(){
|
||||
|
||||
@@ -4,7 +4,6 @@ import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.input.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.scene.*;
|
||||
@@ -16,14 +15,13 @@ import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.content.TechTree.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
import io.anuke.mindustry.ui.Styles;
|
||||
import io.anuke.mindustry.ui.TreeLayout.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -145,7 +143,7 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
infoTable.touchable(Touchable.enabled);
|
||||
|
||||
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.clicked(() -> {
|
||||
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.getStyle().up = !locked(node.node) ? Tex.buttonOver : !data.hasItems(node.node.requirements) ? Tex.buttonRed : Tex.button;
|
||||
((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);
|
||||
});
|
||||
addChild(button);
|
||||
@@ -278,7 +276,7 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
for(ItemStack req : node.requirements){
|
||||
t.table(list -> {
|
||||
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.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));
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ZoneInfoDialog extends FloatingDialog{
|
||||
if(i++ % 2 == 0){
|
||||
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);
|
||||
}
|
||||
};
|
||||
@@ -82,7 +82,7 @@ public class ZoneInfoDialog extends FloatingDialog{
|
||||
r.add("$research.list").colspan(2).left();
|
||||
r.row();
|
||||
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.addImage(data.isUnlocked(block) ? Icon.checkSmall : Icon.cancelSmall, data.isUnlocked(block) ? Color.lightGray : Color.scarlet).padLeft(3);
|
||||
r.row();
|
||||
@@ -111,7 +111,7 @@ public class ZoneInfoDialog extends FloatingDialog{
|
||||
t.left();
|
||||
int i = 0;
|
||||
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){
|
||||
r.row();
|
||||
}
|
||||
|
||||
@@ -1,32 +1,27 @@
|
||||
package io.anuke.mindustry.ui.fragments;
|
||||
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.IntSet;
|
||||
import io.anuke.arc.function.BooleanProvider;
|
||||
import io.anuke.arc.function.Supplier;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.input.KeyCode;
|
||||
import io.anuke.arc.math.Interpolation;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.scene.Element;
|
||||
import io.anuke.arc.scene.Group;
|
||||
import io.anuke.arc.scene.actions.Actions;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.function.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.input.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.scene.*;
|
||||
import io.anuke.arc.scene.actions.*;
|
||||
import io.anuke.arc.scene.event.*;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.layout.Stack;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
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.type.Player;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -140,7 +135,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
HandCursorListener l = new HandCursorListener();
|
||||
l.setEnabled(canPick);
|
||||
|
||||
Element image = itemImage(item.icon(Icon.xlarge), () -> {
|
||||
Element image = itemImage(item.icon(Cicon.xlarge), () -> {
|
||||
if(tile == null || tile.entity == null){
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -187,10 +187,10 @@ public class HudFragment extends Fragment{
|
||||
FloatingDialog dialog = new FloatingDialog("$editor.spawn");
|
||||
int i = 0;
|
||||
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);
|
||||
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();
|
||||
}
|
||||
dialog.addCloseButton();
|
||||
@@ -421,7 +421,7 @@ public class HudFragment extends Fragment{
|
||||
public void showUnlock(UnlockableContent content){
|
||||
//some content may not have icons... yet
|
||||
//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();
|
||||
|
||||
@@ -441,10 +441,10 @@ public class HudFragment extends Fragment{
|
||||
Table in = new Table();
|
||||
|
||||
//create texture stack for displaying
|
||||
Image image = new Image(content.getContentIcon());
|
||||
Image image = new Image(content.icon(Cicon.xlarge));
|
||||
image.setScaling(Scaling.fit);
|
||||
|
||||
in.add(image).size(48f).pad(2);
|
||||
in.add(image).size(8 * 6).pad(2);
|
||||
|
||||
//add to table
|
||||
table.add(in).padRight(8);
|
||||
@@ -495,7 +495,7 @@ public class HudFragment extends Fragment{
|
||||
//if there's space, add it
|
||||
if(esize < cap){
|
||||
|
||||
Image image = new Image(content.getContentIcon());
|
||||
Image image = new Image(content.icon(Cicon.medium));
|
||||
image.setScaling(Scaling.fit);
|
||||
|
||||
lastUnlockLayout.add(image);
|
||||
|
||||
@@ -11,6 +11,7 @@ import io.anuke.arc.scene.style.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
@@ -80,7 +81,7 @@ public class PlacementFragment extends Fragment{
|
||||
Block tryRecipe = tile.block();
|
||||
if(tryRecipe.isVisible() && unlocked(tryRecipe)){
|
||||
input.block = tryRecipe;
|
||||
currentCategory = input.block.buildCategory;
|
||||
currentCategory = input.block.category;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -92,7 +93,7 @@ public class PlacementFragment extends Fragment{
|
||||
for(KeyCode key : inputCatGrid){
|
||||
if(Core.input.keyDown(key)){
|
||||
input.block = getByCategory(Category.all[i]).first();
|
||||
currentCategory = input.block.buildCategory;
|
||||
currentCategory = input.block.category;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -143,11 +144,11 @@ public class PlacementFragment extends Fragment{
|
||||
}
|
||||
}).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
|
||||
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.setChecked(control.input.block == block);
|
||||
});
|
||||
@@ -189,7 +190,7 @@ public class PlacementFragment extends Fragment{
|
||||
|
||||
topTable.table(header -> {
|
||||
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)
|
||||
.left().width(190f).padLeft(5);
|
||||
header.add().growX();
|
||||
@@ -205,10 +206,10 @@ public class PlacementFragment extends Fragment{
|
||||
topTable.table(req -> {
|
||||
req.top().left();
|
||||
|
||||
for(ItemStack stack : lastDisplay.buildRequirements){
|
||||
for(ItemStack stack : lastDisplay.requirements){
|
||||
req.table(line -> {
|
||||
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.labelWrap(() -> {
|
||||
TileEntity core = player.getClosestCore();
|
||||
@@ -296,7 +297,7 @@ public class PlacementFragment extends Fragment{
|
||||
Array<Block> getByCategory(Category cat){
|
||||
returnArray.clear();
|
||||
for(Block block : content.blocks()){
|
||||
if(block.buildCategory == cat && block.isVisible()){
|
||||
if(block.category == cat && block.isVisible()){
|
||||
returnArray.add(block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class PlayerListFragment extends Fragment{
|
||||
}
|
||||
};
|
||||
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.labelWrap("[#" + user.color.toString().toUpperCase() + "]" + user.name).width(170f).pad(10);
|
||||
|
||||
@@ -114,9 +114,9 @@ public class Block extends BlockStorage{
|
||||
public float idleSoundVolume = 0.5f;
|
||||
|
||||
/** Cost of constructing this block. */
|
||||
public ItemStack[] buildRequirements = new ItemStack[]{};
|
||||
public ItemStack[] requirements = new ItemStack[]{};
|
||||
/** Category in place menu. */
|
||||
public Category buildCategory = Category.distribution;
|
||||
public Category category = Category.distribution;
|
||||
/** Cost of building this block; do not modify directly! */
|
||||
public float buildCost;
|
||||
/** 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<Tile> tempTiles = new Array<>();
|
||||
protected TextureRegion[] icons = new TextureRegion[Icon.values().length];
|
||||
protected TextureRegion[] generatedIcons;
|
||||
protected TextureRegion[] variantRegions, editorVariantRegions;
|
||||
protected TextureRegion region, editorIcon;
|
||||
@@ -362,11 +361,6 @@ public class Block extends BlockStorage{
|
||||
return localizedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return icon(Icon.medium);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayInfo(Table table){
|
||||
ContentDisplay.displayBlock(table, this);
|
||||
@@ -387,7 +381,7 @@ public class Block extends BlockStorage{
|
||||
}
|
||||
|
||||
buildCost = 0f;
|
||||
for(ItemStack stack : buildRequirements){
|
||||
for(ItemStack stack : requirements){
|
||||
buildCost += stack.amount * stack.item.cost;
|
||||
}
|
||||
|
||||
@@ -493,7 +487,7 @@ public class Block extends BlockStorage{
|
||||
stats.add(BlockStat.health, health, StatUnit.none);
|
||||
if(isBuildable()){
|
||||
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);
|
||||
@@ -631,7 +625,7 @@ public class Block extends BlockStorage{
|
||||
}
|
||||
|
||||
public TextureRegion getDisplayIcon(Tile tile){
|
||||
return icon(Icon.medium);
|
||||
return icon(Cicon.medium);
|
||||
}
|
||||
|
||||
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){
|
||||
draw.region = icon(Icon.full);
|
||||
draw.region = icon(Cicon.full);
|
||||
draw.scalex = draw.scaley = 1;
|
||||
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! */
|
||||
public TextureRegion editorIcon(){
|
||||
if(editorIcon == null) editorIcon = Core.atlas.find(name + "-icon-editor");
|
||||
@@ -713,7 +706,7 @@ public class Block extends BlockStorage{
|
||||
|
||||
public TextureRegion[] variantRegions(){
|
||||
if(variantRegions == null){
|
||||
variantRegions = new TextureRegion[]{icon(Icon.full)};
|
||||
variantRegions = new TextureRegion[]{icon(Cicon.full)};
|
||||
}
|
||||
return variantRegions;
|
||||
}
|
||||
@@ -772,25 +765,11 @@ public class Block extends BlockStorage{
|
||||
|
||||
/** Sets up requirements. Use only this method to set up requirements. */
|
||||
protected void requirements(Category cat, BooleanProvider visible, ItemStack[] stacks){
|
||||
this.buildCategory = cat;
|
||||
this.buildRequirements = stacks;
|
||||
this.category = cat;
|
||||
this.requirements = stacks;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +91,11 @@ public abstract class BlockStorage extends UnlockableContent{
|
||||
}
|
||||
|
||||
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){
|
||||
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){
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
package io.anuke.mindustry.world.blocks;
|
||||
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.Graphics.Cursor;
|
||||
import io.anuke.arc.Graphics.Cursor.SystemCursor;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.Graphics.*;
|
||||
import io.anuke.arc.Graphics.Cursor.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.mindustry.content.Fx;
|
||||
import io.anuke.mindustry.entities.Effects;
|
||||
import io.anuke.mindustry.entities.effect.RubbleDecal;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
import io.anuke.mindustry.entities.effect.*;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.EventType.BlockBuildEndEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.modules.ItemModule;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.modules.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@@ -93,7 +90,7 @@ public class BuildBlock extends Block{
|
||||
@Override
|
||||
public TextureRegion getDisplayIcon(Tile tile){
|
||||
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
|
||||
@@ -138,8 +135,8 @@ public class BuildBlock extends Block{
|
||||
|
||||
if(entity.previous == null) return;
|
||||
|
||||
if(Core.atlas.isFound(entity.previous.icon(Icon.full))){
|
||||
Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.rotation() * 90 : 0);
|
||||
if(Core.atlas.isFound(entity.previous.icon(Cicon.full))){
|
||||
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);
|
||||
|
||||
for(int i = 0; i < cblock.buildRequirements.length; i++){
|
||||
int reqamount = Math.round(state.rules.buildCostMultiplier * cblock.buildRequirements[i].amount);
|
||||
for(int i = 0; i < cblock.requirements.length; i++){
|
||||
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
|
||||
totalAccumulator[i] = Math.min(totalAccumulator[i] + reqamount * maxProgress, reqamount);
|
||||
}
|
||||
@@ -221,7 +218,7 @@ public class BuildBlock extends Block{
|
||||
float deconstructMultiplier = 0.5f;
|
||||
|
||||
if(cblock != null){
|
||||
ItemStack[] requirements = cblock.buildRequirements;
|
||||
ItemStack[] requirements = cblock.requirements;
|
||||
if(requirements.length != accumulator.length || totalAccumulator.length != requirements.length){
|
||||
setDeconstruct(previous);
|
||||
}
|
||||
@@ -258,15 +255,15 @@ public class BuildBlock extends Block{
|
||||
private float checkRequired(ItemModule inventory, float amount, boolean remove){
|
||||
float maxProgress = amount;
|
||||
|
||||
for(int i = 0; i < cblock.buildRequirements.length; i++){
|
||||
int sclamount = Math.round(state.rules.buildCostMultiplier * cblock.buildRequirements[i].amount);
|
||||
for(int i = 0; i < cblock.requirements.length; i++){
|
||||
int sclamount = Math.round(state.rules.buildCostMultiplier * cblock.requirements[i].amount);
|
||||
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;
|
||||
}else if(required > 0){ //if this amount is positive...
|
||||
//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
|
||||
float fraction = maxUse / (float)required;
|
||||
|
||||
@@ -277,7 +274,7 @@ public class BuildBlock extends Block{
|
||||
|
||||
//remove stuff that is actually used
|
||||
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
|
||||
@@ -293,8 +290,8 @@ public class BuildBlock extends Block{
|
||||
public void setConstruct(Block previous, Block block){
|
||||
this.cblock = block;
|
||||
this.previous = previous;
|
||||
this.accumulator = new float[block.buildRequirements.length];
|
||||
this.totalAccumulator = new float[block.buildRequirements.length];
|
||||
this.accumulator = new float[block.requirements.length];
|
||||
this.totalAccumulator = new float[block.requirements.length];
|
||||
this.buildCost = block.buildCost * state.rules.buildCostMultiplier;
|
||||
}
|
||||
|
||||
@@ -303,8 +300,8 @@ public class BuildBlock extends Block{
|
||||
this.progress = 1f;
|
||||
if(previous.buildCost >= 0.01f){
|
||||
this.cblock = previous;
|
||||
this.accumulator = new float[previous.buildRequirements.length];
|
||||
this.totalAccumulator = new float[previous.buildRequirements.length];
|
||||
this.accumulator = new float[previous.requirements.length];
|
||||
this.totalAccumulator = new float[previous.requirements.length];
|
||||
this.buildCost = previous.buildCost * state.rules.buildCostMultiplier;
|
||||
}else{
|
||||
this.buildCost = 20f; //default no-requirement build cost is 20
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
package io.anuke.mindustry.world.blocks;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.IntSet;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Geometry;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
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.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
|
||||
|
||||
@@ -5,9 +5,10 @@ import io.anuke.arc.function.*;
|
||||
import io.anuke.arc.scene.style.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.Styles;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
|
||||
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();
|
||||
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));
|
||||
|
||||
if(i++ % 4 == 3){
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
package io.anuke.mindustry.world.blocks;
|
||||
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
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.*/
|
||||
public class OreBlock extends OverlayFloor{
|
||||
@@ -14,9 +20,60 @@ public class OreBlock extends OverlayFloor{
|
||||
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
|
||||
public void init(){
|
||||
super.init();
|
||||
|
||||
if(itemDrop != null){
|
||||
setup(itemDrop);
|
||||
}else{
|
||||
throw new IllegalArgumentException(name + " must have an item drop!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,7 @@ public class RespawnBlock{
|
||||
|
||||
Draw.reset();
|
||||
if(player != null){
|
||||
TextureRegion region = to.iconRegion;
|
||||
TextureRegion region = player.getIconRegion();
|
||||
|
||||
Draw.color(0f, 0f, 0f, 0.4f * progress);
|
||||
Draw.rect("circle-shadow", tile.drawx(), tile.drawy(), region.getWidth() / 3f, region.getWidth() / 3f);
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.entities.bullet.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
@@ -44,7 +45,7 @@ public class ItemTurret extends CooledTurret{
|
||||
@Override
|
||||
public void build(Tile tile, Table table){
|
||||
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)));
|
||||
|
||||
table.add(image).size(8 * 4);
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.input.InputHandler.*;
|
||||
@@ -161,7 +162,7 @@ public class Conveyor extends Block{
|
||||
tr1.trns(rotation * 90, tilesize, 0);
|
||||
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.y * tilesize + tr1.y * pos.y + tr2.y), itemSize, itemSize);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
import io.anuke.mindustry.entities.Effects.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
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 dx = x * tilesize + offset() - width/2f - 4f, dy = y * tilesize + offset() + size * tilesize / 2f + 5;
|
||||
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.rect(returnItem.icon(Item.Icon.large), dx, dy);
|
||||
Draw.rect(returnItem.icon(Cicon.small), dx, dy);
|
||||
}else{
|
||||
Tile to = tile.getLinkedTilesAs(this, tempTiles).find(t -> t.drop() != null && t.drop().hardness > tier);
|
||||
Item item = to == null ? null : to.drop();
|
||||
@@ -162,9 +163,9 @@ public class Drill extends Block{
|
||||
if(entity.dominantItem != null){
|
||||
float dx = tile.drawx() - size * tilesize/2f, dy = tile.drawy() + size * tilesize/2f;
|
||||
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.rect(entity.dominantItem.icon(Item.Icon.medium), dx, dy);
|
||||
Draw.rect(entity.dominantItem.icon(Cicon.small), dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
@@ -87,7 +88,7 @@ public class LiquidSource extends Block{
|
||||
control.input.frag.config.hideConfig();
|
||||
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));
|
||||
|
||||
if(i % 4 == 3){
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.Fx;
|
||||
import io.anuke.mindustry.entities.Effects;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
@@ -121,7 +122,7 @@ public class UnitFactory extends Block{
|
||||
@Override
|
||||
public void draw(Tile tile){
|
||||
UnitFactoryEntity entity = tile.entity();
|
||||
TextureRegion region = type.iconRegion;
|
||||
TextureRegion region = type.icon(Cicon.full);
|
||||
|
||||
Draw.rect(name, tile.drawx(), tile.drawy());
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.world.consumers;
|
||||
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.entities.type.TileEntity;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@@ -17,7 +18,7 @@ public abstract class Consume{
|
||||
* Apply a filter to items accepted.
|
||||
* 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.
|
||||
* This should set all liquid IDs that are present in the filter to true.
|
||||
*/
|
||||
public void applyLiquidFilter(boolean[] filter){
|
||||
public void applyLiquidFilter(Bits filter){
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package io.anuke.mindustry.world.consumers;
|
||||
|
||||
import io.anuke.arc.function.Predicate;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.entities.type.TileEntity;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.function.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.meta.BlockStat;
|
||||
import io.anuke.mindustry.world.meta.BlockStats;
|
||||
import io.anuke.mindustry.world.meta.values.ItemFilterValue;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.meta.*;
|
||||
import io.anuke.mindustry.world.meta.values.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -21,8 +21,8 @@ public class ConsumeItemFilter extends Consume{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyItemFilter(boolean[] arr){
|
||||
content.items().each(filter, item -> arr[item.id] = true);
|
||||
public void applyItemFilter(Bits arr){
|
||||
content.items().each(filter, item -> arr.set(item.id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,7 +33,7 @@ public class ConsumeItemFilter extends Consume{
|
||||
@Override
|
||||
public void build(Tile tile, Table table){
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package io.anuke.mindustry.world.consumers;
|
||||
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.entities.type.TileEntity;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.ui.ItemImage;
|
||||
import io.anuke.mindustry.ui.ReqImage;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.meta.BlockStat;
|
||||
import io.anuke.mindustry.world.meta.BlockStats;
|
||||
import io.anuke.mindustry.world.meta.values.ItemListValue;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.meta.*;
|
||||
import io.anuke.mindustry.world.meta.values.*;
|
||||
|
||||
public class ConsumeItems extends Consume{
|
||||
public final ItemStack[] items;
|
||||
@@ -19,9 +18,9 @@ public class ConsumeItems extends Consume{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyItemFilter(boolean[] filter){
|
||||
public void applyItemFilter(Bits filter){
|
||||
for(ItemStack stack : items){
|
||||
filter[stack.item.id] = true;
|
||||
filter.set(stack.item.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +32,7 @@ public class ConsumeItems extends Consume{
|
||||
@Override
|
||||
public void build(Tile tile, Table table){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package io.anuke.mindustry.world.consumers;
|
||||
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.entities.type.TileEntity;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.ui.ReqImage;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@@ -17,13 +19,13 @@ public class ConsumeLiquid extends ConsumeLiquidBase{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyLiquidFilter(boolean[] filter){
|
||||
filter[liquid.id] = true;
|
||||
public void applyLiquidFilter(Bits filter){
|
||||
filter.set(liquid.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
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.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.entities.type.TileEntity;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.ui.MultiReqImage;
|
||||
import io.anuke.mindustry.ui.ReqImage;
|
||||
@@ -23,15 +24,15 @@ public class ConsumeLiquidFilter extends ConsumeLiquidBase{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyLiquidFilter(boolean[] arr){
|
||||
content.liquids().each(filter, item -> arr[item.id] = true);
|
||||
public void applyLiquidFilter(Bits arr){
|
||||
content.liquids().each(filter, item -> arr.set(item.id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Tile tile, Table table){
|
||||
Array<Liquid> list = content.liquids().select(l -> !l.isHidden() && filter.test(l));
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.world.consumers;
|
||||
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.function.Predicate;
|
||||
import io.anuke.arc.util.Structs;
|
||||
import io.anuke.mindustry.Vars;
|
||||
@@ -12,8 +13,8 @@ public class Consumers{
|
||||
private Consume[] map = new Consume[ConsumeType.values().length];
|
||||
private Consume[] results, optionalResults;
|
||||
|
||||
public final boolean[] itemFilters = new boolean[Vars.content.items().size];
|
||||
public final boolean[] liquidfilters = new boolean[Vars.content.liquids().size];
|
||||
public final Bits itemFilters = new Bits(Vars.content.items().size);
|
||||
public final Bits liquidfilters = new Bits(Vars.content.liquids().size);
|
||||
|
||||
public void init(){
|
||||
results = Structs.filter(Consume.class, map, m -> m != null);
|
||||
|
||||
@@ -10,8 +10,6 @@ import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.entities.bullet.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.mindustry.world.meta.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
@@ -85,9 +83,6 @@ public class AmmoListValue<T extends UnlockableContent> implements StatValue{
|
||||
}
|
||||
|
||||
TextureRegion icon(T t){
|
||||
if(t instanceof Item){
|
||||
return ((Item)t).icon(Icon.medium);
|
||||
}
|
||||
return t.getContentIcon();
|
||||
return t.icon(Cicon.medium);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ import io.anuke.mindustry.net.*;
|
||||
import io.anuke.mindustry.net.Net.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.*;
|
||||
|
||||
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");
|
||||
|
||||
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){
|
||||
try{
|
||||
new SdlApplication(new DesktopLauncher(arg), new SdlConfig(){{
|
||||
@@ -131,7 +139,7 @@ public class DesktopLauncher extends ClientLauncher{
|
||||
}catch(Throwable e){
|
||||
steam = false;
|
||||
Log.err("Failed to load Steam native libraries.");
|
||||
e.printStackTrace();
|
||||
Log.err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||
archash=840b75daba69d93a5c493e740a573463e03f9ada
|
||||
archash=e17b152d4f597837640fe4d659ca5a820e8a2b15
|
||||
|
||||
@@ -45,6 +45,7 @@ public class ApplicationTests{
|
||||
public void setup(){
|
||||
headless = true;
|
||||
net = new Net(null);
|
||||
tree = new FileTree();
|
||||
Vars.init();
|
||||
content.createContent();
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.core.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.*;
|
||||
import io.anuke.mindustry.world.blocks.power.*;
|
||||
@@ -26,7 +27,12 @@ public class PowerTestFixture{
|
||||
@BeforeAll
|
||||
static void initializeDependencies(){
|
||||
Core.graphics = new FakeGraphics();
|
||||
Vars.content = new ContentLoader();
|
||||
Vars.content = new ContentLoader(){
|
||||
@Override
|
||||
public void handleMappableContent(MappableContent content){
|
||||
|
||||
}
|
||||
};
|
||||
content.createContent();
|
||||
Log.setUseColors(false);
|
||||
Time.setDeltaProvider(() -> 0.5f);
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package power;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.power.PowerGenerator;
|
||||
import io.anuke.mindustry.world.blocks.power.PowerGraph;
|
||||
import io.anuke.mindustry.world.consumers.ConsumePower;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.power.*;
|
||||
import io.anuke.mindustry.world.consumers.*;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.util.Log;
|
||||
import io.anuke.arc.util.noise.RidgedPerlin;
|
||||
import io.anuke.mindustry.ImagePacker.GenRegion;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.noise.*;
|
||||
import io.anuke.mindustry.ImagePacker.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.content;
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
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");
|
||||
|
||||
for(Icon icon : Icon.values()){
|
||||
if(icon.size == 0) continue;
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
Image scaled = new Image(icon.size, icon.size);
|
||||
scaled.drawScaled(image);
|
||||
scaled.save("../ui/" + block.name + "-icon-" + icon.name());
|
||||
scaled.save("../ui/block-" + block.name + "-" + icon.name());
|
||||
}
|
||||
|
||||
Color average = new Color();
|
||||
@@ -182,13 +179,13 @@ public class Generators{
|
||||
});
|
||||
|
||||
ImagePacker.generate("item-icons", () -> {
|
||||
for(Item item : content.items()){
|
||||
Image base = ImagePacker.get("item-" + item.name);
|
||||
for(Item.Icon icon : Item.Icon.values()){
|
||||
if(icon.size == base.width) continue;
|
||||
for(UnlockableContent item : (Array<? extends UnlockableContent>)(Array)Array.withArrays(content.items(), content.liquids())){
|
||||
Image base = ImagePacker.get(item.getContentType().name() + "-" + item.name);
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
//if(icon.size == base.width) continue;
|
||||
Image image = new Image(icon.size, icon.size);
|
||||
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.save("mech-icon-" + mech.name);
|
||||
image.save("mech-" + mech.name + "-full");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -236,7 +233,7 @@ public class Generators{
|
||||
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));
|
||||
|
||||
//save icons
|
||||
image.save(ore.name + "-icon-full");
|
||||
for(Icon icon : Icon.values()){
|
||||
if(icon.size == 0) continue;
|
||||
image.save("block-" + ore.name + "-full");
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
Image scaled = new Image(icon.size, icon.size);
|
||||
scaled.drawScaled(image);
|
||||
scaled.save(ore.name + "-icon-" + icon.name());
|
||||
scaled.save("block-" + ore.name + "-" + icon.name());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user