Merge + update

This commit is contained in:
Anuken
2019-06-30 14:13:13 -04:00
214 changed files with 11773 additions and 8613 deletions

View File

@@ -1,6 +1,10 @@
package io.anuke.mindustry;
import io.anuke.arc.*;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Texture;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.SpriteBatch;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Time;
@@ -8,6 +12,7 @@ import io.anuke.mindustry.core.*;
import io.anuke.mindustry.game.EventType.GameLoadEvent;
import io.anuke.mindustry.io.BundleLoader;
import static io.anuke.arc.Core.batch;
import static io.anuke.mindustry.Vars.*;
public class Mindustry extends ApplicationCore{
@@ -21,28 +26,38 @@ public class Mindustry extends ApplicationCore{
Time.mark();
Vars.init();
batch = new SpriteBatch();
Log.setUseColors(false);
BundleLoader.load();
content.load();
content.loadColors();
Core.app.post(() -> Core.app.post(() -> {
drawLoading();
Core.app.post(() -> Core.app.post(() -> {
Vars.init();
Log.setUseColors(false);
BundleLoader.load();
content.load();
content.loadColors();
add(logic = new Logic());
add(world = new World());
add(control = new Control());
add(renderer = new Renderer());
add(ui = new UI());
add(netServer = new NetServer());
add(netClient = new NetClient());
add(logic = new Logic());
add(world = new World());
add(control = new Control());
add(renderer = new Renderer());
add(ui = new UI());
add(netServer = new NetServer());
add(netClient = new NetClient());
for(ApplicationListener listener : modules){
listener.init();
}
Log.info("Time to load [total]: {0}", Time.elapsed());
Events.fire(new GameLoadEvent());
}));
}));
}
@Override
public void init(){
super.init();
Log.info("Time to load [total]: {0}", Time.elapsed());
Events.fire(new GameLoadEvent());
setup();
}
@Override
@@ -66,4 +81,16 @@ public class Mindustry extends ApplicationCore{
}
}
void drawLoading(){
Core.graphics.clear(Color.BLACK);
Draw.proj().setOrtho(0, 0, Core.graphics.getWidth(), Core.graphics.getHeight());
Texture icon = new Texture("sprites/logotext.png");
float width = Math.min(Core.graphics.getWidth() - 10f, icon.getWidth());
Draw.rect(Draw.wrap(icon), Core.graphics.getWidth()/2f, Core.graphics.getHeight()/2f, width, (float)icon.getHeight() / icon.getWidth() * width);
Draw.flush();
icon.dispose();
}
}

View File

@@ -57,6 +57,12 @@ public class Vars{
public static final float itemSize = 5f;
/** extra padding around the world; units outside this bound will begin to self-destruct. */
public static final float worldBounds = 100f;
/** default size of UI icons.*/
public static final int iconsize = 48;
/** size of UI icons (small)*/
public static final int iconsizesmall = 32;
/** size of UI icons (medium)*/
public static final int iconsizemed = 30;
/** units outside of this bound will simply die instantly */
public static final float finalWorldBounds = worldBounds + 500;
/** ticks spent out of bound until self destruct. */

View File

@@ -384,7 +384,7 @@ public class Blocks implements ContentList{
darkMetal = new StaticWall("dark-metal");
pebbles = new OverlayFloor("pebbles");
pebbles = new DoubleOverlayFloor("pebbles");
tendrils = new OverlayFloor("tendrils");
@@ -1433,15 +1433,15 @@ public class Blocks implements ContentList{
);
size = 2;
range = 120f;
reload = 35f;
range = 150f;
reload = 30f;
restitution = 0.03f;
ammoEjectBack = 3f;
cooldown = 0.03f;
recoil = 3f;
shootShake = 2f;
burstSpacing = 4;
shots = 3;
burstSpacing = 3f;
shots = 4;
ammoUseEffect = Fx.shellEjectBig;
health = 360;
}};
@@ -1687,7 +1687,7 @@ public class Blocks implements ContentList{
repairPoint = new RepairPoint("repair-point"){{
requirements(Category.units, ItemStack.with(Items.lead, 30, Items.copper, 30, Items.silicon, 30));
repairSpeed = 0.1f;
repairSpeed = 0.3f;
powerUse = 1f;
}};

View File

@@ -280,6 +280,7 @@ public class Bullets implements ContentList{
standardCopper = new BasicBulletType(2.5f, 9, "bullet"){{
bulletWidth = 7f;
bulletHeight = 9f;
lifetime = 60f;
shootEffect = Fx.shootSmall;
smokeEffect = Fx.shootSmallSmoke;
ammoMultiplier = 1;
@@ -290,6 +291,7 @@ public class Bullets implements ContentList{
bulletHeight = 12f;
reloadMultiplier = 0.6f;
ammoMultiplier = 2;
lifetime = 60f;
}};
standardThorium = new BasicBulletType(4f, 29, "bullet"){{
@@ -298,6 +300,7 @@ public class Bullets implements ContentList{
shootEffect = Fx.shootBig;
smokeEffect = Fx.shootBigSmoke;
ammoMultiplier = 2;
lifetime = 60f;
}};
standardHoming = new BasicBulletType(3f, 9, "bullet"){{
@@ -306,6 +309,7 @@ public class Bullets implements ContentList{
homingPower = 5f;
reloadMultiplier = 1.4f;
ammoMultiplier = 3;
lifetime = 60f;
}};
standardIncendiary = new BasicBulletType(3.2f, 11, "bullet"){{
@@ -317,6 +321,7 @@ public class Bullets implements ContentList{
incendAmount = 1;
incendChance = 0.3f;
inaccuracy = 3f;
lifetime = 60f;
}};
standardGlaive = new BasicBulletType(4f, 7.5f, "bullet"){{
@@ -327,6 +332,7 @@ public class Bullets implements ContentList{
incendSpread = 3f;
incendAmount = 1;
incendChance = 0.3f;
lifetime = 60f;
}};
standardMechSmall = new BasicBulletType(4f, 9, "bullet"){{
@@ -399,7 +405,7 @@ public class Bullets implements ContentList{
super.hit(b);
tile = tile.link();
if(tile.getTeam() == b.getTeam() && !(tile.block() instanceof BuildBlock)){
if(tile.entity != null && tile.getTeam() == b.getTeam() && !(tile.block() instanceof BuildBlock)){
Effects.effect(Fx.healBlockFull, Pal.heal, tile.drawx(), tile.drawy(), tile.block().size);
tile.entity.healBy(healPercent / 100f * tile.entity.maxHealth());
}

View File

@@ -261,7 +261,7 @@ public class TechTree implements ContentList{
});
node(wraithFactory, () -> {
node(spiritFactory, () -> {
node(ghoulFactory, () -> {
node(revenantFactory, () -> {
});

View File

@@ -19,7 +19,7 @@ public class Zones implements ContentList{
@Override
public void load(){
groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1).decor(new Decoration(Blocks.snow, Blocks.snowrock, 0.01))){{
groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1)){{
baseLaunchCost = ItemStack.with(Items.copper, -100);
startingItems = ItemStack.list(Items.copper, 100);
alwaysUnlocked = true;

View File

@@ -6,9 +6,9 @@ import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Pixmap;
import io.anuke.arc.util.Log;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.bullet.BulletType;
import io.anuke.mindustry.entities.effect.*;
import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.effect.Puddle;
import io.anuke.mindustry.entities.traits.TypeTrait;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.game.*;
@@ -241,7 +241,5 @@ public class ContentLoader{
TypeTrait.registerType(Player.class, Player::new);
TypeTrait.registerType(Fire.class, Fire::new);
TypeTrait.registerType(Puddle.class, Puddle::new);
TypeTrait.registerType(Bullet.class, Bullet::new);
TypeTrait.registerType(Lightning.class, Lightning::new);
}
}

View File

@@ -321,7 +321,7 @@ public class Control implements ApplicationListener{
Time.update();
}
if(!scene.hasDialog() && !(scene.root.getChildren().peek() instanceof Dialog) && Core.input.keyTap(KeyCode.BACK)){
if(!scene.hasDialog() && !scene.root.getChildren().isEmpty() && !(scene.root.getChildren().peek() instanceof Dialog) && Core.input.keyTap(KeyCode.BACK)){
Platform.instance.hide();
}
}

View File

@@ -15,6 +15,7 @@ import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.Teams.TeamData;
import io.anuke.mindustry.gen.BrokenBlock;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
@@ -130,8 +131,13 @@ public class Logic implements ApplicationListener{
}
if(alive != null && !state.gameOver){
if(world.isZone() && alive == defaultTeam){
//in attack maps, a victorious game over is equivalent to a launch
Call.launchZone();
}else{
Events.fire(new GameOverEvent(alive));
}
state.gameOver = true;
Events.fire(new GameOverEvent(alive));
}
}
}
@@ -154,6 +160,9 @@ public class Logic implements ApplicationListener{
world.removeBlock(tile);
}
state.launched = true;
state.gameOver = true;
//manually fire game over event now
Events.fire(new GameOverEvent(defaultTeam));
});
}

View File

@@ -251,7 +251,7 @@ public class NetClient implements ApplicationListener{
//read the entity
entity.read(input);
if(created){
if(created && entity.getInterpolator() != null && entity.getInterpolator().target != null){
//set initial starting position
entity.setNet(entity.getInterpolator().target.x, entity.getInterpolator().target.y);
if(entity instanceof Unit && entity.getInterpolator().targets.length > 0){

View File

@@ -274,7 +274,7 @@ public class NetServer implements ApplicationListener{
long elapsed = Time.timeSinceMillis(connection.lastRecievedClientTime);
float maxSpeed = boosting && !player.mech.flying ? player.mech.boostSpeed : player.mech.speed;
float maxMove = elapsed / 1000f * 60f * Math.min(compound(maxSpeed, player.mech.drag) * 1.25f, player.mech.maxSpeed * 1.1f);
float maxMove = elapsed / 1000f * 60f * Math.min(compound(maxSpeed, player.mech.drag) * 1.25f, player.mech.maxSpeed * 1.2f);
player.pointerX = pointerX;
player.pointerY = pointerY;
@@ -284,6 +284,7 @@ public class NetServer implements ApplicationListener{
player.isShooting = shooting;
player.buildQueue().clear();
for(BuildRequest req : requests){
if(req == null) continue;
Tile tile = world.tile(req.x, req.y);
if(tile == null) continue;
//auto-skip done requests
@@ -296,7 +297,7 @@ public class NetServer implements ApplicationListener{
}
vector.set(x - player.getInterpolator().target.x, y - player.getInterpolator().target.y);
//vector.limit(maxMove);
vector.limit(maxMove);
float prevx = player.x, prevy = player.y;
player.set(player.getInterpolator().target.x, player.getInterpolator().target.y);

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.core;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Core;
import io.anuke.arc.*;
import io.anuke.arc.files.FileHandle;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.function.Predicate;
@@ -21,6 +20,7 @@ import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
import io.anuke.mindustry.entities.impl.EffectEntity;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.EventType.DisposeEvent;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.world.blocks.defense.ForceProjector.ShieldEntity;
@@ -42,7 +42,6 @@ public class Renderer implements ApplicationListener{
private float shakeIntensity, shaketime;
public Renderer(){
batch = new SpriteBatch(4096);
camera = new Camera();
Lines.setCircleVertices(20);
Shaders.init();
@@ -113,7 +112,7 @@ public class Renderer implements ApplicationListener{
}else{
camera.position.lerpDelta(position, 0.08f);
}
}else if(!mobile){
}else if(!mobile || settings.getBool("keyboard")){
camera.position.lerpDelta(position, 0.08f);
}
@@ -131,6 +130,7 @@ public class Renderer implements ApplicationListener{
minimap.dispose();
shieldBuffer.dispose();
blocks.dispose();
Events.fire(new DisposeEvent());
}
void updateShake(float scale){

View File

@@ -207,12 +207,12 @@ public class UI implements ApplicationListener{
});
}
public void showTextInput(String titleText, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){
public void showTextInput(String titleText, String text, int textLength, String def, TextFieldFilter filter, Consumer<String> confirmed){
new Dialog(titleText, "dialog"){{
cont.margin(30).add(text).padRight(6f);
TextField field = cont.addField(def, t -> {
}).size(170f, 50f).get();
field.setFilter((f, c) -> field.getText().length() < 12 && filter.acceptChar(f, c));
field.setFilter((f, c) -> field.getText().length() < textLength && filter.acceptChar(f, c));
Platform.instance.addDialog(field);
buttons.defaults().size(120, 54).pad(4);
buttons.addButton("$ok", () -> {
@@ -224,7 +224,11 @@ public class UI implements ApplicationListener{
}
public void showTextInput(String title, String text, String def, Consumer<String> confirmed){
showTextInput(title, text, def, (field, c) -> true, confirmed);
showTextInput(title, text, 12, def, (field, c) -> true, confirmed);
}
public void showTextInput(String title, String text, int textLength, String def, Consumer<String> confirmed){
showTextInput(title, text, textLength < 0 ? 12 : textLength, def, (field, c) -> true, confirmed);
}
public void showInfoFade(String info){

View File

@@ -65,7 +65,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
menu = new FloatingDialog("$menu");
menu.addCloseButton();
float isize = 16 * 2f;
float isize = iconsize;
float swidth = 180f;
menu.cont.table(t -> {
@@ -314,7 +314,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}).left().margin(0).get();
button.clearChildren();
button.addImage(iconname).size(16 * 3).padLeft(10);
button.addImage(iconname).size(iconsize).padLeft(10);
button.table(t -> {
t.add(name).growX().wrap();
t.row();
@@ -385,14 +385,14 @@ public class MapEditorDialog extends Dialog implements Disposable{
Consumer<EditorTool> addTool = tool -> {
Table[] lastTable = {null};
ImageButton button = new ImageButton("icon-" + tool.name(), "clear-toggle");
ImageButton button = new ImageButton("icon-" + tool.name() + "-small", "clear-toggle");
button.clicked(() -> {
view.setTool(tool);
if(lastTable[0] != null){
lastTable[0].remove();
}
});
button.resizeImage(16 * 2f);
button.resizeImage(iconsizesmall);
button.update(() -> button.setChecked(view.getTool() == tool));
group.add(button);
@@ -436,12 +436,16 @@ public class MapEditorDialog extends Dialog implements Disposable{
table.update(() -> {
Vector2 v = button.localToStageCoordinates(Tmp.v1.setZero());
table.setPosition(v.x, v.y, Align.topLeft);
if(!isShown()){
table.remove();
lastTable[0] = null;
}
});
table.pack();
table.act(Core.graphics.getDeltaTime());
Core.scene.add(table);
addChild(table);
lastTable[0] = table;
});
}
@@ -458,16 +462,16 @@ public class MapEditorDialog extends Dialog implements Disposable{
tools.defaults().size(size, size);
tools.addImageButton("icon-menu-large", "clear", 16 * 2f, menu::show);
tools.addImageButton("icon-menu-large-small", "clear", iconsizesmall, menu::show);
ImageButton grid = tools.addImageButton("icon-grid", "clear-toggle", 16 * 2f, () -> view.setGrid(!view.isGrid())).get();
ImageButton grid = tools.addImageButton("icon-grid-small", "clear-toggle", iconsizesmall, () -> view.setGrid(!view.isGrid())).get();
addTool.accept(EditorTool.zoom);
tools.row();
ImageButton undo = tools.addImageButton("icon-undo", "clear", 16 * 2f, editor::undo).get();
ImageButton redo = tools.addImageButton("icon-redo", "clear", 16 * 2f, editor::redo).get();
ImageButton undo = tools.addImageButton("icon-undo-small", "clear", iconsizesmall, editor::undo).get();
ImageButton redo = tools.addImageButton("icon-redo-small", "clear", iconsizesmall, editor::redo).get();
addTool.accept(EditorTool.pick);
@@ -489,7 +493,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
addTool.accept(EditorTool.fill);
addTool.accept(EditorTool.spray);
ImageButton rotate = tools.addImageButton("icon-arrow-16", "clear", 16 * 2f, () -> editor.rotation = (editor.rotation + 1) % 4).get();
ImageButton rotate = tools.addImageButton("icon-arrow-16-small", "clear", iconsizesmall, () -> editor.rotation = (editor.rotation + 1) % 4).get();
rotate.getImage().update(() -> {
rotate.getImage().setRotation(editor.rotation * 90);
rotate.getImage().setOrigin(Align.center);

View File

@@ -12,6 +12,7 @@ import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Scaling;
import io.anuke.arc.util.async.AsyncExecutor;
import io.anuke.arc.util.async.AsyncResult;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.editor.generation.*;
import io.anuke.mindustry.editor.generation.GenerateFilter.GenerateInput;
import io.anuke.mindustry.game.Team;
@@ -27,7 +28,10 @@ import static io.anuke.mindustry.Vars.*;
@SuppressWarnings("unchecked")
public class MapGenerateDialog extends FloatingDialog{
private final Supplier<GenerateFilter>[] filterTypes = new Supplier[]{NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new, RiverNoiseFilter::new, OreFilter::new, MedianFilter::new};
private final Supplier<GenerateFilter>[] filterTypes = new Supplier[]{
NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new,
RiverNoiseFilter::new, OreFilter::new, MedianFilter::new, BlendFilter::new
};
private final MapEditor editor;
private Pixmap pixmap;
@@ -63,7 +67,7 @@ public class MapGenerateDialog extends FloatingDialog{
update();
}).size(160f, 64f);
buttons.addImageTextButton("$add", "icon-add", 14 * 2, this::showAdd).height(64f).width(140f);
buttons.addImageTextButton("$add", "icon-add", iconsize, this::showAdd).height(64f).width(140f);
}
void setup(){
@@ -123,24 +127,24 @@ public class MapGenerateDialog extends FloatingDialog{
t.table(b -> {
b.left();
b.defaults().size(50f);
b.addImageButton("icon-refresh", 14 * 2, () -> {
b.addImageButton("icon-refresh-small", iconsizesmall, () -> {
filter.randomize();
update();
});
b.addImageButton("icon-arrow-up", 10 * 2, () -> {
b.addImageButton("icon-arrow-up-small", iconsizesmall, () -> {
int idx = filters.indexOf(filter);
filters.swap(idx, Math.max(0, idx - 1));
rebuildFilters();
update();
});
b.addImageButton("icon-arrow-down", 10 * 2, () -> {
b.addImageButton("icon-arrow-down-small", iconsizesmall, () -> {
int idx = filters.indexOf(filter);
filters.swap(idx, Math.min(filters.size - 1, idx + 1));
rebuildFilters();
update();
});
b.addImageButton("icon-trash", 14 * 2, () -> {
b.addImageButton("icon-trash-small", iconsizesmall, () -> {
filters.remove(filter);
rebuildFilters();
update();
@@ -184,6 +188,20 @@ public class MapGenerateDialog extends FloatingDialog{
if(++i % 2 == 0) selection.cont.row();
}
selection.cont.addButton("Default Ores", () -> {
int index = 0;
for(Block block : new Block[]{Blocks.oreCopper, Blocks.oreCoal, Blocks.oreLead, Blocks.oreTitanium, Blocks.oreThorium}){
OreFilter filter = new OreFilter();
filter.threshold += index ++ * 0.02f;
filter.ore = block;
filters.add(filter);
}
rebuildFilters();
update();
selection.hide();
});
selection.addCloseButton();
selection.show();
}

View File

@@ -0,0 +1,46 @@
package io.anuke.mindustry.editor.generation;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.editor.generation.FilterOption.BlockOption;
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
import io.anuke.mindustry.world.Block;
import static io.anuke.mindustry.editor.generation.FilterOption.floorsOnly;
public class BlendFilter extends GenerateFilter{
float radius = 2f;
Block flooronto = Blocks.stone, floor = Blocks.ice;
{
options(
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 10f),
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOnly),
new BlockOption("floor", () -> floor, b -> floor = b, floorsOnly)
);
}
@Override
public void apply(){
if(in.floor == flooronto) return;
int rad = (int)radius;
boolean found = false;
outer:
for(int x = -rad; x <= rad; x++){
for(int y = -rad; y <= rad; y++){
if(Mathf.dst2(x, y) > rad*rad) continue;
if(in.tile(in.x + x, in.y + y).floor == flooronto.id){
found = true;
break outer;
}
}
}
if(found){
in.floor = floor;
}
}
}

View File

@@ -6,6 +6,7 @@ import io.anuke.arc.scene.style.TextureRegionDrawable;
import io.anuke.arc.scene.ui.Slider;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
@@ -16,6 +17,9 @@ 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 abstract void build(Table table);
@@ -66,14 +70,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().icon(Icon.small))).size(8 * 3), () -> {
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), () -> {
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.icon(Icon.medium)).size(8 * 4).pad(3).get().clicked(() -> {
dialog.cont.addImage(block == Blocks.air ? Core.atlas.find("icon-none-small") : block.icon(Icon.medium)).size(8 * 4).pad(3).get().clicked(() -> {
consumer.accept(block);
dialog.hide();
changed.run();

View File

@@ -8,8 +8,8 @@ import static io.anuke.mindustry.editor.generation.FilterOption.BlockOption;
import static io.anuke.mindustry.editor.generation.FilterOption.oresOnly;
public class OreFilter extends GenerateFilter{
float scl = 40, threshold = 0.8f, octaves = 3f, falloff = 0.5f;
Block ore = Blocks.oreCopper;
public float scl = 50, threshold = 0.72f, octaves = 3f, falloff = 0.4f;
public Block ore = Blocks.oreCopper;
{
options(

View File

@@ -5,26 +5,34 @@ import io.anuke.mindustry.editor.generation.FilterOption.BlockOption;
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
import io.anuke.mindustry.world.Block;
import static io.anuke.mindustry.editor.generation.FilterOption.floorsOnly;
import static io.anuke.mindustry.editor.generation.FilterOption.wallsOnly;
import static io.anuke.mindustry.editor.generation.FilterOption.*;
public class ScatterFilter extends GenerateFilter{
float chance = 0.1f;
Block floor = Blocks.ice, block = Blocks.icerocks;
Block flooronto = Blocks.air, floor = Blocks.air, block = Blocks.air;
{
options(
new SliderOption("chance", () -> chance, f -> chance = f, 0f, 1f),
new BlockOption("floor", () -> floor, b -> floor = b, floorsOnly),
new BlockOption("block", () -> block, b -> block = b, wallsOnly)
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOptional),
new BlockOption("floor", () -> floor, b -> floor = b, floorsOptional),
new BlockOption("block", () -> block, b -> block = b, wallsOresOptional)
);
}
@Override
public void apply(){
if(in.srcfloor == floor && in.srcblock == Blocks.air && chance() <= chance){
in.block = block;
if(block != Blocks.air && (in.srcfloor == flooronto || flooronto == Blocks.air) && in.srcblock == Blocks.air && chance() <= chance){
if(!block.isOverlay()){
in.block = block;
}else{
in.ore = block;
}
}
if(floor != Blocks.air && (in.srcfloor == flooronto || flooronto == Blocks.air) && chance() <= chance){
in.floor = floor;
}
}
}

View File

@@ -16,11 +16,10 @@ import io.anuke.mindustry.entities.type.Unit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import java.io.*;
import static io.anuke.mindustry.Vars.bulletGroup;
import static io.anuke.mindustry.Vars.world;
import static io.anuke.mindustry.Vars.*;
public class Bullet extends SolidEntity implements DamageTrait, ScaleTrait, Poolable, DrawTrait, VelocityTrait, TimeTrait, TeamTrait, SyncTrait, AbsorbTrait{
public class Bullet extends SolidEntity implements DamageTrait, ScaleTrait, Poolable, DrawTrait, VelocityTrait, TimeTrait, TeamTrait, AbsorbTrait{
public Interval timer = new Interval(3);
private float lifeScl;
@@ -153,31 +152,6 @@ public class Bullet extends SolidEntity implements DamageTrait, ScaleTrait, Pool
return type.damage * damageMultiplier();
}
@Override
public boolean isSyncing(){
return type.syncable;
}
@Override
public void write(DataOutput data) throws IOException{
data.writeFloat(x);
data.writeFloat(y);
data.writeFloat(velocity.x);
data.writeFloat(velocity.y);
data.writeByte(team.ordinal());
data.writeByte(type.id);
}
@Override
public void read(DataInput data) throws IOException{
x = data.readFloat();
y = data.readFloat();
velocity.x = data.readFloat();
velocity.y = data.readFloat();
team = Team.all[data.readByte()];
type = content.bullet(data.readByte());
}
@Override
public Team getTeam(){
return team;

View File

@@ -46,8 +46,6 @@ public abstract class BulletType extends Content{
public StatusEffect status = StatusEffects.none;
/** Intensity of applied status effect in terms of duration. */
public float statusDuration = 60 * 1f;
/** Whether to sync this bullet to clients. */
public boolean syncable;
/** Whether this bullet type collides with tiles. */
public boolean collidesTiles = true;
/** Whether this bullet type collides with tiles that are of the same team. */

View File

@@ -14,18 +14,16 @@ import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.impl.TimedEntity;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.entities.traits.DrawTrait;
import io.anuke.mindustry.entities.traits.TimeTrait;
import io.anuke.mindustry.entities.type.Unit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Pal;
import java.io.DataInput;
import java.io.DataOutput;
import static io.anuke.mindustry.Vars.bulletGroup;
public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, TimeTrait{
public class Lightning extends TimedEntity implements DrawTrait, TimeTrait{
public static final float lifetime = 10f;
private static final RandomXS128 random = new RandomXS128();
@@ -91,19 +89,6 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
}
}
@Override
public boolean isSyncing(){
return false;
}
@Override
public void write(DataOutput data){
}
@Override
public void read(DataInput data){
}
@Override
public float lifetime(){
return lifetime;

View File

@@ -8,22 +8,14 @@ import io.anuke.arc.math.Mathf;
import static io.anuke.mindustry.Vars.headless;
public class RubbleDecal extends Decal{
private static final TextureRegion[][] regions = new TextureRegion[16][0];
private TextureRegion region;
/** Creates a rubble effect at a position. Provide a block size to use. */
public static void create(float x, float y, int size){
if(headless) return;
if(regions[size].length == 0 || regions[size][0].getTexture().isDisposed()){
regions[size] = new TextureRegion[2];
for(int j = 0; j < 2; j++){
regions[size][j] = Core.atlas.find("rubble-" + size + "-" + j);
}
}
RubbleDecal decal = new RubbleDecal();
decal.region = regions[size][Mathf.clamp(Mathf.randomSeed(decal.id, 0, 1), 0, regions[size].length - 1)];
decal.region = Core.atlas.find("rubble-" + size + "-" + Mathf.randomSeed(decal.id, 0, 1));
if(!Core.atlas.isFound(decal.region)){
return;

View File

@@ -1,14 +1,18 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.*;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.entities.type.Unit;
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Pal;
@@ -21,7 +25,8 @@ import java.io.*;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.entities.traits.BuilderTrait.BuildDataStatic.*;
import static io.anuke.mindustry.entities.traits.BuilderTrait.BuildDataStatic.removal;
import static io.anuke.mindustry.entities.traits.BuilderTrait.BuildDataStatic.tmptr;
/** Interface for units that build things.*/
public interface BuilderTrait extends Entity, TeamTrait{
@@ -66,9 +71,9 @@ public interface BuilderTrait extends Entity, TeamTrait{
}
if(!(tile.block() instanceof BuildBlock)){
if(canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
if(!current.initialized && canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
Call.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
}else if(canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
}else if(!current.initialized && canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
Call.beginBreak(getTeam(), current.x, current.y);
}else{
buildQueue().removeFirst();
@@ -78,6 +83,11 @@ public interface BuilderTrait extends Entity, TeamTrait{
TileEntity core = unit.getClosestCore();
if(tile.entity instanceof BuildEntity && !current.initialized){
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
current.initialized = true;
}
//if there is no core to build with or no build entity, stop building!
if((core == null && !state.rules.infiniteResources) || !(tile.entity instanceof BuildEntity)){
return;
@@ -107,11 +117,6 @@ public interface BuilderTrait extends Entity, TeamTrait{
}else{
entity.progress = current.progress;
}
if(!current.initialized){
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
current.initialized = true;
}
}
/** Returns the queue for storing build requests. */

View File

@@ -105,7 +105,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
}
public boolean targetHasFlag(BlockFlag flag){
return target instanceof TileEntity && ((TileEntity)target).tile.block().flags.contains(flag);
return (target instanceof TileEntity && ((TileEntity)target).tile.block().flags.contains(flag)) ||
(target instanceof Tile && ((Tile)target).block().flags.contains(flag));
}
public void setState(UnitState state){

View File

@@ -564,10 +564,10 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
data.unlockContent(mech);
}
if(mobile){
updateFlying();
if(mobile && !Core.settings.getBool("keyboard")){
updateTouch();
}else{
updateMech();
updateKeyboard();
}
isTyping = ui.chatfrag.chatOpen();
@@ -579,7 +579,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
}
}
protected void updateMech(){
protected void updateKeyboard(){
Tile tile = world.tileWorld(x, y);
isBoosting = Core.input.keyDown(Binding.dash) && !mech.flying;
@@ -646,7 +646,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
}
}
protected void updateFlying(){
protected void updateTouch(){
if(Units.invalidateTarget(target, this) && !(target instanceof TileEntity && ((TileEntity)target).damaged() && target.isValid() && target.getTeam() == team && mech.canHeal && dst(target) < getWeapon().bullet.range())){
target = null;
}
@@ -657,6 +657,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
float targetX = Core.camera.position.x, targetY = Core.camera.position.y;
float attractDst = 15f;
float speed = isBoosting && !mech.flying ? mech.boostSpeed : mech.speed;
if(moveTarget != null && !moveTarget.isDead()){
targetX = moveTarget.getX();
@@ -680,7 +681,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
moveTarget = null;
}
movement.set((targetX - x) / Time.delta(), (targetY - y) / Time.delta()).limit(isBoosting && !mech.flying ? mech.boostSpeed : mech.speed);
movement.set((targetX - x) / Time.delta(), (targetY - y) / Time.delta()).limit(speed);
movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f));
if(dst(targetX, targetY) < attractDst){

View File

@@ -17,7 +17,7 @@ public abstract class BaseDrone extends FlyingUnit{
public void update(){
if(health >= maxHealth()){
state.set(attack);
state.set(getStartState());
}else if(!targetHasFlag(BlockFlag.repair)){
if(retarget()){
Tile repairPoint = Geometry.findClosest(x, y, world.indexer.getAllied(team, BlockFlag.repair));
@@ -44,7 +44,7 @@ public abstract class BaseDrone extends FlyingUnit{
@Override
public void behavior(){
if(health <= health * type.retreatPercent){
if(health <= maxHealth() * type.retreatPercent && !state.is(retreat) && Geometry.findClosest(x, y, world.indexer.getAllied(team, BlockFlag.repair)) != null){
setState(retreat);
}
}

View File

@@ -67,6 +67,8 @@ public class BuilderDrone extends BaseDrone implements BuilderTrait{
circle(placeDistance * 0.7f);
velocity.scl(0.74f);
}else{ //else, building isn't valid, follow a player
target = null;
if(playerTarget == null || playerTarget.getTeam() != team || !playerTarget.isValid()){
playerTarget = null;

View File

@@ -33,32 +33,21 @@ public class MinerDrone extends BaseDrone implements MinerTrait{
if(entity == null) return;
if(targetItem == null){
findItem();
}
findItem();
//core full
//core full of the target item, do nothing
if(targetItem != null && entity.block.acceptStack(targetItem, 1, entity.tile, MinerDrone.this) == 0){
MinerDrone.this.clearItem();
return;
}
//if inventory is full, drop it off.
if(item.amount >= getItemCapacity()){
if(item.amount >= getItemCapacity() || (targetItem != null && !acceptsItem(targetItem))){
setState(drop);
}else{
if(targetItem != null && !acceptsItem(targetItem)){
setState(drop);
return;
}
if(retarget()){
findItem();
if(targetItem == null) return;
if(retarget() && targetItem != null){
target = world.indexer.findClosestOre(x, y, targetItem);
};
}
if(target instanceof Tile){
moveTo(type.range / 1.5f);
@@ -92,13 +81,7 @@ public class MinerDrone extends BaseDrone implements MinerTrait{
}
public void update(){
if(item.amount == 0){
setState(mine);
return;
}
if(item.item.type != ItemType.material){
item.amount = 0;
if(item.amount == 0 || item.item.type != ItemType.material){
setState(mine);
return;
}

View File

@@ -32,6 +32,10 @@ public class EventType{
}
public static class DisposeEvent{
}
public static class PlayEvent{
}

View File

@@ -40,7 +40,7 @@ public class Rules{
/** No-build zone around enemy core radius. */
public float enemyCoreBuildRadius = 400f;
/** Radius around enemy wave drop zones.*/
public float dropZoneRadius = 380f;
public float dropZoneRadius = 300f;
/** Player respawn time in ticks. */
public float respawnTime = 60 * 4;
/** Time between waves in ticks. */

View File

@@ -22,6 +22,7 @@ import static io.anuke.mindustry.Vars.*;
public class OverlayRenderer{
private static final float indicatorLength = 14f;
private static final float spawnerMargin = tilesize*11f;
private static final Rectangle rect = new Rectangle();
private float buildFadeTime;
@@ -92,6 +93,16 @@ public class OverlayRenderer{
}
}
Lines.stroke(2f);
Draw.color(Color.GRAY, Color.LIGHT_GRAY, Mathf.absin(Time.time(), 8f, 1f));
for(Tile tile : world.spawner.getGroundSpawns()){
if(tile.withinDst(player.x, player.y, state.rules.dropZoneRadius + spawnerMargin)){
Draw.alpha(Mathf.clamp(1f - (player.dst(tile) - state.rules.dropZoneRadius) / spawnerMargin));
Lines.dashCircle(tile.worldx(), tile.worldy(), state.rules.dropZoneRadius);
}
}
Draw.reset();
//draw selected block bars and info

View File

@@ -141,7 +141,7 @@ public class DesktopInput extends InputHandler{
if(state.is(State.menu) || Core.scene.hasDialog()) return;
//zoom and rotate things
//zoom things
if(Math.abs(Core.input.axisTap(Binding.zoom)) > 0 && (Core.input.keyDown(Binding.zoom_hold))){
renderer.scaleCamera(Core.input.axisTap(Binding.zoom));
}

View File

@@ -265,7 +265,7 @@ public class MobileInput extends InputHandler implements GestureListener{
table.row();
table.left().margin(0f).defaults().size(48f);
table.addImageButton("icon-break", "clear-toggle-partial", 16 * 2f, () -> {
table.addImageButton("icon-break-small", "clear-toggle-partial", iconsizesmall, () -> {
mode = mode == breaking ? block == null ? none : placing : breaking;
lastBlock = block;
if(mode == breaking){
@@ -274,17 +274,17 @@ public class MobileInput extends InputHandler implements GestureListener{
}).update(l -> l.setChecked(mode == breaking));
//diagonal swap button
table.addImageButton("icon-diagonal", "clear-toggle-partial", 16 * 2f, () -> {
table.addImageButton("icon-diagonal-small", "clear-toggle-partial", iconsizesmall, () -> {
Core.settings.put("swapdiagonal", !Core.settings.getBool("swapdiagonal"));
Core.settings.save();
}).update(l -> l.setChecked(Core.settings.getBool("swapdiagonal")));
//rotate button
table.addImageButton("icon-arrow", "clear-partial", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4))
table.addImageButton("icon-arrow-small", "clear-partial", iconsizesmall, () -> rotation = Mathf.mod(rotation + 1, 4))
.update(i -> i.getImage().setRotationOrigin(rotation * 90, Align.center)).visible(() -> block != null && block.rotate);
//confirm button
table.addImageButton("icon-check", "clear-partial", 16 * 2f, () -> {
table.addImageButton("icon-check-small", "clear-partial", iconsizesmall, () -> {
for(PlaceRequest request : selection){
Tile tile = request.tile();
@@ -475,7 +475,10 @@ public class MobileInput extends InputHandler implements GestureListener{
//call tap events
if(pointer == 0 && !selecting && mode == none){
tryTapPlayer(worldx, worldy);
if(!tryTapPlayer(worldx, worldy) && Core.settings.getBool("keyboard")){
//shoot on touch down when in keyboard mode
player.isShooting = true;
}
}
return false;
@@ -598,6 +601,27 @@ public class MobileInput extends InputHandler implements GestureListener{
mode = none;
}
//zoom things
if(Math.abs(Core.input.axisTap(Binding.zoom)) > 0 && (Core.input.keyDown(Binding.zoom_hold))){
renderer.scaleCamera(Core.input.axisTap(Binding.zoom));
}
if(!Core.settings.getBool("keyboard")){
//move camera around
float camSpeed = 6f;
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed));
}
if(Core.settings.getBool("keyboard")){
if(Core.input.keyRelease(Binding.select)){
player.isShooting = false;
}
if(player.isShooting && !canShoot()){
player.isShooting = false;
}
}
//reset state when not placing
if(mode == none){
selecting = false;
@@ -678,7 +702,7 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public boolean pan(float x, float y, float deltaX, float deltaY){
if(Core.scene.hasDialog()) return false;
if(Core.scene.hasDialog() || Core.settings.getBool("keyboard")) return false;
float scale = Core.camera.width / Core.graphics.getWidth();
deltaX *= scale;
@@ -723,6 +747,7 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public boolean zoom(float initialDistance, float distance){
if(Core.settings.getBool("keyboard")) return false;
if(lastDistance == -1) lastDistance = initialDistance;
float amount = (Mathf.sign(distance > lastDistance) * 0.04f) * Time.delta();

View File

@@ -7,7 +7,6 @@ import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.Teams.TeamData;
import io.anuke.mindustry.gen.BrokenBlock;
import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.type.ContentType;
@@ -65,7 +64,6 @@ public abstract class SaveVersion extends SaveFileReader{
"wavetime", state.wavetime,
"stats", JsonIO.write(state.stats),
"rules", JsonIO.write(state.rules),
"teamdata", JsonIO.write(state.teams.getActive().toArray(TeamData.class)),
"width", world.width(),
"height", world.height()
).merge(tags));
@@ -80,12 +78,6 @@ public abstract class SaveVersion extends SaveFileReader{
state.rules = JsonIO.read(Rules.class, map.get("rules", "{}"));
if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get();
//only broken blocks are transferred over right now; nothing else
TeamData[] teams = JsonIO.read(TeamData[].class, map.get("teamdata", "[]"));
for(TeamData data : teams){
state.teams.get(data.team).brokenBlocks = data.brokenBlocks;
}
Map worldmap = world.maps.byName(map.get("mapname", "\\\\\\"));
world.setMap(worldmap == null ? new Map(StringMap.of(
"name", map.get("mapname", "Unknown"),

View File

@@ -139,6 +139,10 @@ public class TypeIO{
int position = buffer.getInt();
BuildRequest currentRequest;
if(world.tile(position) == null){
continue;
}
if(type == 1){ //remove
currentRequest = new BuildRequest(Pos.x(position), Pos.y(position));
}else{ //place

View File

@@ -18,7 +18,7 @@ import static io.anuke.mindustry.Vars.*;
public class Maps implements Disposable{
/** List of all built-in maps. Filenames only. */
private static String[] defaultMapNames = {"fortress", "labyrinth", "islands"};
private static String[] defaultMapNames = {"fortress", "labyrinth", "islands", "tendrils", "caldera"};
/** All maps stored in an ordered array. */
private Array<Map> maps = new Array<>();
/** Serializer for meta. */

View File

@@ -58,6 +58,10 @@ public class MapGenerator extends Generator{
return this;
}
{
decor(new Decoration(Blocks.snow, Blocks.snowrock, 0.01), new Decoration(Blocks.ignarock, Blocks.pebbles, 0.03f));
}
@Override
public void init(Loadout loadout){
this.loadout = loadout;
@@ -126,7 +130,9 @@ public class MapGenerator extends Generator{
if(tile.block() == Blocks.air && !(decor.wall instanceof Floor) && tile.floor() == decor.floor && Mathf.chance(decor.chance)){
tile.setBlock(decor.wall);
}else if(tile.floor() == decor.floor && decor.wall instanceof Floor && Mathf.chance(decor.chance)){
}else if(tile.floor() == decor.floor && decor.wall.isOverlay() && Mathf.chance(decor.chance)){
tile.setOverlay(decor.wall);
}else if(tile.floor() == decor.floor && decor.wall.isFloor() && !decor.wall.isOverlay() && Mathf.chance(decor.chance)){
tile.setFloor((Floor)decor.wall);
}
}

View File

@@ -3,11 +3,8 @@ package io.anuke.mindustry.net;
import io.anuke.arc.Core;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.OS;
import io.anuke.arc.util.Strings;
import io.anuke.arc.util.*;
import io.anuke.arc.util.io.PropertiesUtils;
import io.anuke.arc.util.io.Streams;
import io.anuke.arc.util.serialization.JsonValue;
import io.anuke.arc.util.serialization.JsonValue.ValueType;
import io.anuke.arc.util.serialization.JsonWriter.OutputType;
@@ -53,7 +50,7 @@ public class CrashSender{
try{
File file = new File(OS.getAppDataDirectoryString(Vars.appName), "crashes/crash-report-" + DateTimeFormatter.ofPattern("MM_dd_yyyy_HH_mm_ss").format(LocalDateTime.now()) + ".txt");
new File(OS.getAppDataDirectoryString(Vars.appName)).mkdir();
new BufferedOutputStream(new FileOutputStream(file), Streams.DEFAULT_BUFFER_SIZE).write(parseException(exception).getBytes());
Files.write(file.toPath(), parseException(exception).getBytes());
Files.createDirectories(Paths.get(OS.getAppDataDirectoryString(Vars.appName), "crashes"));
writeListener.accept(file);

View File

@@ -53,7 +53,7 @@ public class Net{
error = Core.bundle.get("error.unreachable");
}else if(type.contains("timeout")){
error = Core.bundle.get("error.timedout");
}else if(error.equals("alreadyconnected")){
}else if(error.equals("alreadyconnected") || error.contains("connection is closed")){
error = Core.bundle.get("error.alreadyconnected");
}else if(!error.isEmpty()){
error = Core.bundle.get("error.any") + "\n" + Strings.parseException(e, true);

View File

@@ -69,7 +69,7 @@ public class Item extends UnlockableContent implements Comparable<Item>{
@Override
public TextureRegion getContentIcon(){
return icon(Icon.xlarge);
return icon(Icon.xxlarge);
}
@Override
@@ -91,7 +91,8 @@ public class Item extends UnlockableContent implements Comparable<Item>{
small(8 * 2),
medium(8 * 3),
large(8 * 4),
xlarge(8 * 5);
xlarge(8 * 5),
xxlarge(8 * 6);
public final int size;

View File

@@ -121,7 +121,8 @@ public class Zone extends UnlockableContent{
/** Whether this zone has met its condition; if true, the player can leave. */
public boolean metCondition(){
return state.wave >= conditionWave;
//players can't leave in attack mode.
return state.wave >= conditionWave && !state.rules.attackMode;
}
public boolean canConfigure(){

View File

@@ -4,6 +4,8 @@ import io.anuke.arc.graphics.Color;
import io.anuke.arc.scene.ui.TextButton;
import io.anuke.arc.util.Align;
import static io.anuke.mindustry.Vars.iconsize;
public class MenuButton extends TextButton{
public MenuButton(String icon, String text, Runnable clicked){
@@ -19,7 +21,7 @@ public class MenuButton extends TextButton{
margin(0);
table(t -> {
t.addImage(icon).size(14 * 3).padLeft(6);
t.addImage(icon).size(iconsize).padLeft(6);
t.add(text).wrap().growX().get().setAlignment(Align.center, Align.left);
if(description != null){

View File

@@ -53,7 +53,7 @@ public class AboutDialog extends FloatingDialog{
table.table(i -> {
i.background("button-edge-3");
i.addImage("icon-" + link.name).size(14 * 3f);
i.addImage("icon-" + link.name).size(iconsize);
}).size(h - 5, h);
table.table(inset -> {
@@ -62,7 +62,7 @@ public class AboutDialog extends FloatingDialog{
inset.labelWrap(link.description).width(w - 100f).color(Color.LIGHT_GRAY).growX();
}).padLeft(8);
table.addImageButton("icon-link", 14 * 3, () -> {
table.addImageButton("icon-link", iconsize, () -> {
if(!Core.net.openURI(link.link)){
ui.showError("$linkfail");
Core.app.getClipboard().setContents(link.link);

View File

@@ -37,7 +37,7 @@ public class AdminsDialog extends FloatingDialog{
res.labelWrap("[LIGHT_GRAY]" + info.lastName).width(w - h - 24f);
res.add().growX();
res.addImageButton("icon-cancel", 14 * 3, () -> {
res.addImageButton("icon-cancel", iconsize, () -> {
ui.showConfirm("$confirm", "$confirmunadmin", () -> {
netServer.admins.unAdminPlayer(info.id);
playerGroup.all().each(player -> {

View File

@@ -4,8 +4,7 @@ import io.anuke.arc.scene.ui.ScrollPane;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.net.Administration.PlayerInfo;
import static io.anuke.mindustry.Vars.netServer;
import static io.anuke.mindustry.Vars.ui;
import static io.anuke.mindustry.Vars.*;
public class BansDialog extends FloatingDialog{
@@ -39,7 +38,7 @@ public class BansDialog extends FloatingDialog{
res.labelWrap("IP: [LIGHT_GRAY]" + info.lastIP + "\n[]Name: [LIGHT_GRAY]" + info.lastName).width(w - h - 24f);
res.add().growX();
res.addImageButton("icon-cancel", 14 * 3, () -> {
res.addImageButton("icon-cancel", iconsize, () -> {
ui.showConfirm("$confirm", "$confirmunban", () -> {
netServer.admins.unbanPlayerID(info.id);
setup();

View File

@@ -46,20 +46,20 @@ public class DatabaseDialog extends FloatingDialog{
list.left();
int maxWidth = Core.graphics.isPortrait() ? 7 : 13;
int size = 8 * 5;
float size = Vars.iconsize;
int count = 0;
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-tree-locked");
Image image = unlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-locked");
image.addListener(new HandCursorListener());
list.add(image).size(size).pad(3);
if(unlocked(unlock)){
image.clicked(() -> Vars.ui.content.show(unlock));
image.addListener(new Tooltip(t -> t.add(unlock.localizedName())));
image.addListener(new Tooltip(t -> t.background("button").add(unlock.localizedName())));
}
if((++count) % maxWidth == 0){

View File

@@ -40,7 +40,7 @@ public class DeployDialog extends FloatingDialog{
layout.layout(root);
addCloseButton();
buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f);
buttons.addImageTextButton("$techtree", "icon-tree", iconsize, () -> ui.tech.show()).size(230f, 64f);
shown(this::setup);
}
@@ -131,10 +131,10 @@ public class DeployDialog extends FloatingDialog{
button.clicked(() -> info.show(zone));
if(zone.unlocked()){
button.addImage("icon-zone").padRight(3);
button.addImage("icon-terrain").size(iconsize).padRight(3);
button.labelWrap(zone.localizedName()).width(140).growX();
}else{
button.addImage("icon-zone-locked");
button.addImage("icon-locked");
button.row();
button.add("$locked");
}

View File

@@ -5,8 +5,7 @@ import io.anuke.arc.graphics.Color;
import io.anuke.arc.scene.ui.Dialog;
import io.anuke.mindustry.graphics.Pal;
import static io.anuke.mindustry.Vars.discordURL;
import static io.anuke.mindustry.Vars.ui;
import static io.anuke.mindustry.Vars.*;
public class DiscordDialog extends Dialog{
@@ -30,7 +29,7 @@ public class DiscordDialog extends Dialog{
t.table(i -> {
i.background("button");
i.addImage("icon-discord").size(14 * 3);
i.addImage("icon-discord").size(iconsize);
}).size(h).left();
t.add("$discord").color(Pal.accent).growX().padLeft(10f);

View File

@@ -17,6 +17,8 @@ import io.anuke.mindustry.core.Platform;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.iconsize;
public class FileChooser extends FloatingDialog{
private static final FileHandle homeDirectory = Core.files.absolute(OS.isMac ? OS.getProperty("user.home") + "/Downloads/" : Core.files.getExternalStoragePath());
private static FileHandle lastDirectory = homeDirectory;
@@ -99,7 +101,7 @@ public class FileChooser extends FloatingDialog{
Table icontable = new Table();
float isize = 14 * 2;
float isize = iconsize;
ImageButton up = new ImageButton("icon-folder-parent");
up.resizeImage(isize);
@@ -131,7 +133,7 @@ public class FileChooser extends FloatingDialog{
updateFiles(true);
});
icontable.defaults().height(50).growX().padTop(5).uniform();
icontable.defaults().height(60).growX().padTop(5).uniform();
icontable.add(home);
icontable.add(back);
icontable.add(forward);
@@ -142,7 +144,7 @@ public class FileChooser extends FloatingDialog{
fieldcontent.add(filefield).height(40f).fillX().expandX().padLeft(10f);
Table buttons = new Table();
buttons.defaults().growX().height(50);
buttons.defaults().growX().height(60);
buttons.add(cancel);
buttons.add(ok);
@@ -213,7 +215,7 @@ public class FileChooser extends FloatingDialog{
updateFiles(true);
});
upbutton.left().add(upimage).padRight(4f).size(14 * 2);
upbutton.left().add(upimage).padRight(4f).size(iconsize);
upbutton.getLabel().setAlignment(Align.left);
upbutton.getCells().reverse();
@@ -249,7 +251,7 @@ public class FileChooser extends FloatingDialog{
Image image = new Image(file.isDirectory() ? "icon-folder" : "icon-file-text");
button.add(image).padRight(4f).size(14 * 2f);
button.add(image).padRight(4f).size(iconsize);
button.getCells().reverse();
files.top().left().add(button).align(Align.topLeft).fillX().expandX()
.height(50).pad(2).padTop(0).padBottom(0).colspan(2);

View File

@@ -11,6 +11,7 @@ import io.anuke.mindustry.game.EventType.ResizeEvent;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.net.Net;
import static io.anuke.mindustry.Vars.iconsize;
import static io.anuke.mindustry.Vars.state;
public class FloatingDialog extends Dialog{
@@ -63,7 +64,7 @@ public class FloatingDialog extends Dialog{
@Override
public void addCloseButton(){
buttons.addImageTextButton("$back", "icon-arrow-left", 30f, this::hide).size(210f, 64f);
buttons.addImageTextButton("$back", "icon-arrow-left", iconsize, this::hide).size(210f, 64f);
keyDown(key -> {
if(key == KeyCode.ESCAPE || key == KeyCode.BACK){

View File

@@ -97,7 +97,7 @@ public class JoinDialog extends FloatingDialog{
if(!buttons[0].childrenPressed()){
connect(server.ip, server.port);
}
}).width(targetWidth()).height(155f).pad(4f).get();
}).width(targetWidth()).height(130f).pad(4f).get();
button.getLabel().setWrap(true);
@@ -107,16 +107,35 @@ public class JoinDialog extends FloatingDialog{
inner.add(button.getLabel()).growX();
inner.addImageButton("icon-loading", "empty", 16 * 2, () -> {
inner.addImageButton("icon-arrow-up-small", "empty", iconsizesmall, () -> {
int index = servers.indexOf(server);
if(index > 0){
servers.remove(index);
servers.insert(0, server);
saveServers();
setupRemote();
for(Server other : servers){
if(other.lastHost != null){
setupServer(other, other.lastHost);
}else{
refreshServer(other);
}
}
}
}).margin(3f).padTop(6f).top().right();
inner.addImageButton("icon-loading-small", "empty", iconsizesmall, () -> {
refreshServer(server);
}).margin(3f).padTop(6f).top().right();
inner.addImageButton("icon-pencil", "empty", 16 * 2, () -> {
inner.addImageButton("icon-pencil-small", "empty", iconsizesmall, () -> {
renaming = server;
add.show();
}).margin(3f).padTop(6f).top().right();
inner.addImageButton("icon-trash-16", "empty", 16 * 2, () -> {
inner.addImageButton("icon-trash-16-small", "empty", iconsizesmall, () -> {
ui.showConfirm("$confirm", "$server.delete", () -> {
servers.removeValue(server, true);
saveServers();
@@ -144,42 +163,41 @@ public class JoinDialog extends FloatingDialog{
server.content.clear();
server.content.label(() -> Core.bundle.get("server.refreshing") + Strings.animated(Time.time(), 4, 11, "."));
Net.pingHost(server.ip, server.port, host -> {
String versionString;
if(host.version == -1){
versionString = Core.bundle.format("server.version", Core.bundle.get("server.custombuild"), "");
}else if(host.version == 0){
versionString = Core.bundle.get("server.outdated");
}else if(host.version < Version.build && Version.build != -1){
versionString = Core.bundle.get("server.outdated") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else if(host.version > Version.build && Version.build != -1){
versionString = Core.bundle.get("server.outdated.client") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else{
versionString = Core.bundle.format("server.version", host.version, host.versionType);
}
server.content.clear();
server.content.table(t -> {
t.add("[lightgray]" + host.name).width(targetWidth() - 10f).left().get().setEllipsis(true);
t.row();
t.add(versionString).left();
t.row();
t.add("[lightgray]" + (host.players != 1 ? Core.bundle.format("players", host.players) :
Core.bundle.format("players.single", host.players))).left();
t.row();
t.add("[lightgray]" + Core.bundle.format("save.map", host.mapname) + "[] / " + Core.bundle.format("save.wave", host.wave)).width(targetWidth() - 10f).left().get().setEllipsis(true);
}).expand().left().bottom().padLeft(12f).padBottom(8);
}, e -> {
Net.pingHost(server.ip, server.port, host -> setupServer(server, host), e -> {
server.content.clear();
server.content.add("$host.invalid");
});
}
void setupServer(Server server, Host host){
server.lastHost = host;
String versionString;
if(host.version == -1){
versionString = Core.bundle.format("server.version", Core.bundle.get("server.custombuild"), "");
}else if(host.version == 0){
versionString = Core.bundle.get("server.outdated");
}else if(host.version < Version.build && Version.build != -1){
versionString = Core.bundle.get("server.outdated") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else if(host.version > Version.build && Version.build != -1){
versionString = Core.bundle.get("server.outdated.client") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else{
versionString = Core.bundle.format("server.version", host.version, host.versionType);
}
server.content.clear();
server.content.table(t -> {
t.add("[lightgray]" + host.name + " " + versionString).width(targetWidth() - 10f).left().get().setEllipsis(true);
t.row();
t.add("[lightgray]" + (host.players != 1 ? Core.bundle.format("players", host.players == 0 ? host.players : "[accent]" + host.players + "[lightgray]") : Core.bundle.format("players.single", "[accent]" + host.players + "[lightgray]"))).left();
t.row();
t.add("[lightgray]" + Core.bundle.format("save.map", host.mapname) + "[lightgray] / " + Core.bundle.format("save.wave", host.wave)).width(targetWidth() - 10f).left().get().setEllipsis(true);
}).expand().left().bottom().padLeft(12f).padBottom(8);
}
void setup(){
float w = targetWidth();
@@ -217,7 +235,7 @@ public class JoinDialog extends FloatingDialog{
cont.row();
cont.add(pane).width(w + 38).pad(0);
cont.row();
cont.addCenteredImageTextButton("$server.add", "icon-add", 14 * 3, () -> {
cont.addCenteredImageTextButton("$server.add", "icon-add", iconsize, () -> {
renaming = null;
add.show();
}).marginLeft(6).width(w).height(80f).update(button -> {
@@ -253,7 +271,7 @@ public class JoinDialog extends FloatingDialog{
local.background("button");
local.add("$hosts.none").pad(10f);
local.add().growX();
local.addImageButton("icon-loading", 16 * 2f, this::refreshLocal).pad(-12f).padLeft(0).size(70f);
local.addImageButton("icon-loading", iconsize, this::refreshLocal).pad(-12f).padLeft(0).size(70f);
}else{
local.background((Drawable)null);
}
@@ -320,6 +338,7 @@ public class JoinDialog extends FloatingDialog{
public int port;
transient Table content;
transient Host lastHost;
void setIP(String ip){

View File

@@ -65,25 +65,25 @@ public class LoadDialog extends FloatingDialog{
button.table(t -> {
t.right();
t.addImageButton("icon-floppy", "emptytoggle", 14 * 3, () -> {
t.addImageButton("icon-floppy", "emptytoggle", iconsize, () -> {
slot.setAutosave(!slot.isAutosave());
}).checked(slot.isAutosave()).right();
t.addImageButton("icon-trash", "empty", 14 * 3, () -> {
t.addImageButton("icon-trash", "empty", iconsize, () -> {
ui.showConfirm("$confirm", "$save.delete.confirm", () -> {
slot.delete();
setup();
});
}).size(14 * 3).right();
}).size(iconsize).right();
t.addImageButton("icon-pencil-small", "empty", 14 * 3, () -> {
t.addImageButton("icon-pencil", "empty", iconsize, () -> {
ui.showTextInput("$save.rename", "$save.rename.text", slot.getName(), text -> {
slot.setName(text);
setup();
});
}).size(14 * 3).right();
}).size(iconsize).right();
t.addImageButton("icon-save", "empty", 14 * 3, () -> {
t.addImageButton("icon-save", "empty", iconsize, () -> {
if(!ios){
Platform.instance.showFileChooser(Core.bundle.get("save.export"), "Mindustry Save", file -> {
try{
@@ -102,7 +102,7 @@ public class LoadDialog extends FloatingDialog{
ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, true)));
}
}
}).size(14 * 3).right();
}).size(iconsize).right();
}).padRight(-10).growX();
@@ -147,7 +147,7 @@ public class LoadDialog extends FloatingDialog{
if(ios) return;
slots.addImageTextButton("$save.import", "icon-add", 14 * 3, () -> {
slots.addImageTextButton("$save.import", "icon-add", iconsize, () -> {
Platform.instance.showFileChooser(Core.bundle.get("save.import"), "Mindustry Save", file -> {
if(SaveIO.isSaveValid(file)){
try{

View File

@@ -57,14 +57,14 @@ public class MapPlayDialog extends FloatingDialog{
cont.add(selmode);
cont.row();
cont.addImageTextButton("$customize", "icon-tools", 14*2, () -> dialog.show(rules, () -> rules = (selectedGamemode == null ? map.rules() : selectedGamemode.apply(map.rules())))).width(230);
cont.addImageTextButton("$customize", "icon-tools-small", iconsizesmall, () -> dialog.show(rules, () -> rules = (selectedGamemode == null ? map.rules() : selectedGamemode.apply(map.rules())))).width(230);
cont.row();
cont.add(new BorderImage(map.texture, 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit);
buttons.clearChildren();
addCloseButton();
buttons.addImageTextButton("$play", "icon-play", 8*3, () -> {
buttons.addImageTextButton("$play", "icon-play", iconsize, () -> {
control.playMap(map, rules);
hide();
ui.custom.hide();

View File

@@ -21,7 +21,7 @@ public class MapsDialog extends FloatingDialog{
super("$maps");
addCloseButton();
buttons.addImageTextButton("$editor.importmap", "icon-add", 14 * 2, () -> {
buttons.addImageTextButton("$editor.importmap", "icon-add", iconsize, () -> {
Platform.instance.showFileChooser("$editor.importmap", "Map File", file -> {
world.maps.tryCatchMapError(() -> {
if(MapIO.isImage(file)){
@@ -145,7 +145,7 @@ public class MapsDialog extends FloatingDialog{
table.row();
table.addImageTextButton("$editor.openin", "icon-load-map", 16 * 2, () -> {
table.addImageTextButton("$editor.openin", "icon-load-map", iconsize, () -> {
try{
Vars.ui.editor.beginEditMap(map.file);
dialog.hide();
@@ -156,7 +156,7 @@ public class MapsDialog extends FloatingDialog{
}
}).fillX().height(54f).marginLeft(10);
table.addImageTextButton("$delete", "icon-trash-16", 16 * 2, () -> {
table.addImageTextButton("$delete", "icon-trash-16", iconsize, () -> {
ui.showConfirm("$confirm", Core.bundle.format("map.delete", map.name()), () -> {
world.maps.removeMap(map);
dialog.hide();

View File

@@ -70,7 +70,7 @@ public class PausedDialog extends FloatingDialog{
}else{
cont.defaults().size(120f).pad(5);
float isize = 14f * 4;
float isize = iconsize;
cont.addRowImageTextButton("$back", "icon-play-2", isize, this::hide);
cont.addRowImageTextButton("$settings", "icon-tools", isize, ui.settings::show);

View File

@@ -23,7 +23,7 @@ public class SaveDialog extends LoadDialog{
public void addSetup(){
slots.row();
slots.addImageTextButton("$save.new", "icon-add", 14 * 3, () ->
ui.showTextInput("$save", "$save.newslot", "", text -> {
ui.showTextInput("$save", "$save.newslot", 30, "", text -> {
ui.loadAnd("$saving", () -> {
control.saves.addSave(text);
Core.app.post(() -> Core.app.post(this::setup));

View File

@@ -12,7 +12,6 @@ import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.SettingsDialog.SettingsTable.Setting;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Align;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.graphics.Pal;
@@ -59,7 +58,7 @@ public class SettingsMenuDialog extends SettingsDialog{
Consumer<SettingsTable> s = table -> {
table.row();
table.addImageTextButton("$back", "icon-arrow-left", 10 * 3, this::back).size(240f, 60f).colspan(2).padTop(15f);
table.addImageTextButton("$back", "icon-arrow-left", iconsize, this::back).size(240f, 60f).colspan(2).padTop(15f);
};
game = new SettingsTable(s);
@@ -76,12 +75,10 @@ public class SettingsMenuDialog extends SettingsDialog{
menu.addButton("$settings.graphics", () -> visible(1));
menu.row();
menu.addButton("$settings.sound", () -> visible(2));
if(!Vars.mobile){
menu.row();
menu.addButton("$settings.controls", ui.controls::show);
}
menu.row();
menu.addButton("$settings.language", ui.language::show);
menu.row();
menu.addButton("$settings.controls", ui.controls::show).visible(() -> !mobile || Core.settings.getBool("keyboard"));
prefs.clearChildren();
prefs.add(menu);
@@ -125,6 +122,7 @@ public class SettingsMenuDialog extends SettingsDialog{
game.screenshakePref();
if(mobile){
game.checkPref("autotarget", true);
game.checkPref("keyboard", false);
}
game.sliderPref("saveinterval", 60, 10, 5 * 120, i -> Core.bundle.format("setting.seconds", i));
@@ -191,11 +189,11 @@ public class SettingsMenuDialog extends SettingsDialog{
Core.graphics.setVSync(Core.settings.getBool("vsync"));
if(Core.settings.getBool("fullscreen")){
Core.graphics.setFullscreenMode(Core.graphics.getDisplayMode());
Core.app.post(() -> Core.graphics.setFullscreenMode(Core.graphics.getDisplayMode()));
}
if(Core.settings.getBool("borderlesswindow")){
Core.graphics.setUndecorated(true);
Core.app.post(() -> Core.graphics.setUndecorated(true));
}
}else{
graphics.checkPref("landscape", false, b -> {

View File

@@ -50,7 +50,7 @@ public class TechTreeDialog extends FloatingDialog{
addCloseButton();
buttons.addImageTextButton("$database", "icon-database", 14 * 2, () -> {
buttons.addImageTextButton("$database", "icon-database", iconsize, () -> {
hide();
ui.database.show();
}).size(210f, 64f);
@@ -194,7 +194,7 @@ public class TechTreeDialog extends FloatingDialog{
button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center);
button.getStyle().up = Core.scene.skin.getDrawable(!locked(node.node) ? "content-background" : !data.hasItems(node.node.requirements) ? "content-background-noitems" : "content-background-locked");
((TextureRegionDrawable)button.getStyle().imageUp)
.setRegion(node.visible ? node.node.block.icon(Icon.medium) : Core.atlas.find("icon-tree-locked"));
.setRegion(node.visible ? node.node.block.icon(Icon.medium) : Core.atlas.find("icon-locked"));
button.getImage().setColor(!locked(node.node) ? Color.WHITE : Color.GRAY);
});
addChild(button);
@@ -253,7 +253,7 @@ public class TechTreeDialog extends FloatingDialog{
infoTable.table("content-background", b -> {
b.margin(0).left().defaults().left();
b.addImageButton("icon-info", "node", 14 * 2, () -> ui.content.show(node.block)).growY().width(50f);
b.addImageButton("icon-info", "node", iconsize, () -> ui.content.show(node.block)).growY().width(50f);
b.add().grow();
b.table(desc -> {
desc.left().defaults().left();
@@ -280,7 +280,7 @@ public class TechTreeDialog extends FloatingDialog{
if(mobile && locked(node)){
b.row();
b.addImageTextButton("$research", "icon-check", "node", 16 * 2, () -> unlock(node))
b.addImageTextButton("$research", "icon-check", "node", iconsize, () -> unlock(node))
.disabled(i -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
}
});

View File

@@ -58,7 +58,7 @@ public class ZoneInfoDialog extends FloatingDialog{
cont.table(cont -> {
if(zone.locked()){
cont.addImage("icon-zone-locked");
cont.addImage("icon-locked");
cont.row();
cont.add("$locked").padBottom(6);
cont.row();
@@ -71,9 +71,9 @@ public class ZoneInfoDialog extends FloatingDialog{
r.add("$complete").colspan(2).left();
r.row();
for(ZoneRequirement other : zone.zoneRequirements){
r.addImage("icon-zone").padRight(4);
r.addImage("icon-terrain").padRight(4);
r.add(Core.bundle.format("zone.requirement", other.wave, other.zone.localizedName())).color(Color.LIGHT_GRAY);
r.addImage(other.zone.bestWave() >= other.wave ? "icon-check-2" : "icon-cancel-2")
r.addImage(other.zone.bestWave() >= other.wave ? "icon-check" : "icon-cancel")
.color(other.zone.bestWave() >= other.wave ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
r.row();
}
@@ -89,7 +89,7 @@ public class ZoneInfoDialog extends FloatingDialog{
for(Block block : zone.blockRequirements){
r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4);
r.add(block.localizedName).color(Color.LIGHT_GRAY);
r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2")
r.addImage(data.isUnlocked(block) ? "icon-check" : "icon-cancel")
.color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
r.row();
}

View File

@@ -48,7 +48,6 @@ public class HudFragment extends Fragment{
private Table lastUnlockLayout;
private boolean shown = true;
private float dsize = 59;
private float isize = 40;
private float coreAttackTime;
private float lastCoreHP;
@@ -70,10 +69,10 @@ public class HudFragment extends Fragment{
select.left();
select.defaults().size(dsize).left();
select.addImageButton("icon-menu", "clear", isize, ui.paused::show);
flip = select.addImageButton("icon-arrow-up", "clear", isize, this::toggleMenus).get();
select.addImageButton("icon-menu-large", "clear", iconsize, ui.paused::show);
flip = select.addImageButton("icon-arrow-up", "clear", iconsize, this::toggleMenus).get();
select.addImageButton("icon-pause", "clear", isize, () -> {
select.addImageButton("icon-pause", "clear", iconsize, () -> {
if(Net.active()){
ui.listfrag.toggle();
}else{
@@ -88,7 +87,7 @@ public class HudFragment extends Fragment{
}
}).get();
select.addImageButton("icon-settings", "clear", isize, () -> {
select.addImageButton("icon-settings", "clear", iconsize, () -> {
if(Net.active() && mobile){
if(ui.chatfrag.chatOpen()){
ui.chatfrag.hide();
@@ -104,7 +103,7 @@ public class HudFragment extends Fragment{
if(Net.active() && mobile){
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-chat");
}else{
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-database-small");
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-database");
}
}).get();
@@ -197,7 +196,7 @@ public class HudFragment extends Fragment{
if(enableUnitEditing){
t.row();
t.addImageTextButton("$editor.spawn", "icon-add", 8 * 3, () -> {
t.addImageTextButton("$editor.spawn", "icon-add", iconsize, () -> {
FloatingDialog dialog = new FloatingDialog("$editor.spawn");
int i = 0;
for(UnitType type : content.<UnitType>getBy(ContentType.unit)){
@@ -216,7 +215,7 @@ public class HudFragment extends Fragment{
float[] position = {0, 0};
t.row();
t.addImageTextButton("$editor.removeunit", "icon-quit", "toggle", 8 * 3, () -> {
t.addImageTextButton("$editor.removeunit", "icon-quit", "toggle", iconsize, () -> {
}).fillX().update(b -> {
boolean[] found = {false};
@@ -360,10 +359,10 @@ public class HudFragment extends Fragment{
button.getStyle().disabledFontColor = Color.WHITE;
button.margin(16f);
button.visible(() ->
world.isZone() &&
world.getZone().metCondition() &&
!Net.client() &&
state.wave % world.getZone().launchPeriod == 0 && !world.spawner.isSpawning());
world.isZone() &&
world.getZone().metCondition() &&
!Net.client() &&
state.wave % world.getZone().launchPeriod == 0 && !world.spawner.isSpawning());
button.update(() -> {
if(world.getZone() == null){
@@ -430,7 +429,7 @@ public class HudFragment extends Fragment{
}
});
table.margin(12);
table.addImage("icon-check").size(16 * 2).pad(3);
table.addImage("icon-check").size(iconsize).pad(3);
table.add(text).wrap().width(280f).get().setAlignment(Align.center, Align.center);
table.pack();

View File

@@ -53,7 +53,7 @@ public class MenuFragment extends Fragment{
container.setSize(Core.graphics.getWidth(), Core.graphics.getHeight());
float size = 120f;
float isize = 14f * 4;
float isize = iconsize;
container.defaults().size(size).pad(5).padTop(4f);
MobileButton

View File

@@ -274,7 +274,7 @@ public class PlacementFragment extends Fragment{
continue;
}
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16 * 2, () -> {
categories.addImageButton("icon-" + cat.name() + "-med", "clear-toggle", iconsizemed, () -> {
currentCategory = cat;
rebuildCategory.run();
}).group(group).update(i -> i.setChecked(currentCategory == cat));

View File

@@ -95,7 +95,7 @@ public class PlayerListFragment extends Fragment{
button.labelWrap("[#" + user.color.toString().toUpperCase() + "]" + user.name).width(170f).pad(10);
button.add().grow();
button.addImage("icon-admin").size(14 * 2).visible(() -> user.isAdmin && !(!user.isLocal && Net.server())).padRight(5).get().updateVisibility();
button.addImage("icon-admin").size(iconsize).visible(() -> user.isAdmin && !(!user.isLocal && Net.server())).padRight(5).get().updateVisibility();
if((Net.server() || player.isAdmin) && !user.isLocal && (!user.isAdmin || Net.server())){
button.add().growY();
@@ -105,14 +105,14 @@ public class PlayerListFragment extends Fragment{
button.table(t -> {
t.defaults().size(bs);
t.addImageButton("icon-ban", "clear-partial", 14 * 2,
t.addImageButton("icon-ban-small", "clear-partial", iconsizesmall,
() -> ui.showConfirm("$confirm", "$confirmban", () -> Call.onAdminRequest(user, AdminAction.ban)));
t.addImageButton("icon-cancel", "clear-partial", 16 * 2,
t.addImageButton("icon-cancel-small", "clear-partial", iconsizesmall,
() -> ui.showConfirm("$confirm", "$confirmkick", () -> Call.onAdminRequest(user, AdminAction.kick)));
t.row();
t.addImageButton("icon-admin", "clear-toggle-partial", 14 * 2, () -> {
t.addImageButton("icon-admin-small", "clear-toggle-partial", iconsizesmall, () -> {
if(Net.client()) return;
String id = user.uuid;
@@ -128,7 +128,7 @@ public class PlayerListFragment extends Fragment{
.touchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled)
.checked(user.isAdmin);
t.addImageButton("icon-zoom-small", "clear-partial", 14 * 2, () -> Call.onAdminRequest(user, AdminAction.trace));
t.addImageButton("icon-zoom-small", "clear-partial", iconsizesmall, () -> Call.onAdminRequest(user, AdminAction.trace));
}).padRight(12).size(bs + 10f, bs);
}

View File

@@ -0,0 +1,20 @@
package io.anuke.mindustry.world.blocks;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.world.Tile;
public class DoubleOverlayFloor extends OverlayFloor{
public DoubleOverlayFloor(String name){
super(name);
}
@Override
public void draw(Tile tile){
Draw.colorl(0.4f);
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy() - 0.75f);
Draw.color();
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
}
}

View File

@@ -40,7 +40,7 @@ public class Conduit extends LiquidBlock{
ConduitEntity entity = tile.entity();
entity.blendbits = 0;
entity.blendshadowrot = -1;
entity.blendrot = 0;
if(blends(tile, 2) && blends(tile, 1) && blends(tile, 3)){
entity.blendbits = 3;
@@ -52,10 +52,8 @@ public class Conduit extends LiquidBlock{
entity.blendbits = 4;
}else if(blends(tile, 1)){
entity.blendbits = 5;
entity.blendshadowrot = 0;
}else if(blends(tile, 3)){
entity.blendbits = 1;
entity.blendshadowrot = 1;
}
}
@@ -116,6 +114,6 @@ public class Conduit extends LiquidBlock{
public float smoothLiquid;
byte blendbits;
int blendshadowrot;
int blendrot;
}
}

View File

@@ -204,7 +204,7 @@ public class MassDriver extends Block{
if(entity.link == other.pos()){
Call.linkMassDriver(null, tile, -1);
return false;
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range){
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.getTeam() == tile.getTeam()){
Call.linkMassDriver(null, tile, other.pos());
return false;
}

View File

@@ -40,6 +40,7 @@ public class PowerGraph{
public float getPowerProduced(){
float powerProduced = 0f;
for(Tile producer : producers){
if(producer.entity == null) continue;
powerProduced += producer.block().getPowerProduction(producer) * producer.entity.delta();
}
return powerProduced;

View File

@@ -28,7 +28,7 @@ public class ConsumeLiquid extends ConsumeLiquidBase{
@Override
public String getIcon(){
return "icon-liquid-small";
return "icon-liquid-consume";
}
@Override

View File

@@ -38,7 +38,7 @@ public class ConsumeLiquidFilter extends ConsumeLiquidBase{
@Override
public String getIcon(){
return "icon-liquid-small";
return "icon-liquid-consume";
}
@Override

View File

@@ -32,7 +32,7 @@ public class ConsumePower extends Consume{
@Override
public String getIcon(){
return "icon-power-small";
return "icon-power";
}
@Override