Merge remote-tracking branch 'anuken/master'

This commit is contained in:
Miguel de Dios Matias
2019-10-03 11:28:03 +02:00
90 changed files with 11393 additions and 8118 deletions
@@ -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;
}
}
+7 -4
View File
@@ -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
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();
+5 -6
View File
@@ -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;
+1 -2
View File
@@ -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();
+14 -3
View File
@@ -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);
}
}
+4 -3
View File
@@ -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;
+16
View File
@@ -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();
+5 -5
View File
@@ -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() + ")");
+119 -34
View File
@@ -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;
+6 -19
View File
@@ -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{" +
+1 -7
View File
@@ -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);
+17 -38
View File
@@ -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
View File
@@ -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);
+6 -8
View File
@@ -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;
/**
+25 -29
View File
@@ -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());
}
}
});