Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry;
|
package io.anuke.mindustry;
|
||||||
|
|
||||||
|
import android.*;
|
||||||
import android.app.*;
|
import android.app.*;
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
import android.content.pm.*;
|
import android.content.pm.*;
|
||||||
@@ -21,6 +22,7 @@ import io.anuke.mindustry.ui.dialogs.*;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.System;
|
import java.lang.System;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -68,14 +70,16 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showFileChooser(boolean open, String extension, Consumer<FileHandle> cons){
|
public void showFileChooser(boolean open, String extension, Consumer<FileHandle> cons){
|
||||||
if(VERSION.SDK_INT >= 19){
|
if(VERSION.SDK_INT >= VERSION_CODES.Q){
|
||||||
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
|
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
intent.setType("*/*");
|
intent.setType(extension.equals("zip") ? "application/zip" : "*/*");
|
||||||
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
|
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
|
||||||
if(code == Activity.RESULT_OK && in != null && in.getData() != null){
|
if(code == Activity.RESULT_OK && in != null && in.getData() != null){
|
||||||
Uri uri = in.getData();
|
Uri uri = in.getData();
|
||||||
|
|
||||||
|
if(uri.getPath().contains("(invalid)")) return;
|
||||||
|
|
||||||
Core.app.post(() -> Core.app.post(() -> cons.accept(new FileHandle(uri.getPath()){
|
Core.app.post(() -> Core.app.post(() -> cons.accept(new FileHandle(uri.getPath()){
|
||||||
@Override
|
@Override
|
||||||
public InputStream read(){
|
public InputStream read(){
|
||||||
@@ -97,6 +101,24 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}else if(VERSION.SDK_INT >= VERSION_CODES.M && !(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
|
||||||
|
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){
|
||||||
|
chooser = new FileChooser(open ? "$open" : "$save", file -> file.extension().equalsIgnoreCase(extension), open, file -> {
|
||||||
|
if(!open){
|
||||||
|
cons.accept(file.parent().child(file.nameWithoutExtension() + "." + extension));
|
||||||
|
}else{
|
||||||
|
cons.accept(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ArrayList<String> perms = new ArrayList<>();
|
||||||
|
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
|
||||||
|
perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
|
}
|
||||||
|
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
|
||||||
|
perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
|
}
|
||||||
|
requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE);
|
||||||
}else{
|
}else{
|
||||||
super.showFileChooser(open, extension, cons);
|
super.showFileChooser(open, extension, cons);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ save.playtime = Playtime: {0}
|
|||||||
warning = Warning.
|
warning = Warning.
|
||||||
confirm = Confirm
|
confirm = Confirm
|
||||||
delete = Delete
|
delete = Delete
|
||||||
|
view.workshop = View In Workshop
|
||||||
ok = OK
|
ok = OK
|
||||||
open = Open
|
open = Open
|
||||||
customize = Customize Rules
|
customize = Customize Rules
|
||||||
@@ -222,6 +223,7 @@ editor.oregen.info = Ore Generation:
|
|||||||
editor.mapinfo = Map Info
|
editor.mapinfo = Map Info
|
||||||
editor.author = Author:
|
editor.author = Author:
|
||||||
editor.description = Description:
|
editor.description = Description:
|
||||||
|
editor.nodescription = A map must have a description of at least 4 characters before being published.
|
||||||
editor.waves = Waves:
|
editor.waves = Waves:
|
||||||
editor.rules = Rules:
|
editor.rules = Rules:
|
||||||
editor.generation = Generation:
|
editor.generation = Generation:
|
||||||
@@ -288,6 +290,7 @@ editor.resizemap = Resize Map
|
|||||||
editor.mapname = Map Name:
|
editor.mapname = Map Name:
|
||||||
editor.overwrite = [accent]Warning!\nThis overwrites an existing map.
|
editor.overwrite = [accent]Warning!\nThis overwrites an existing map.
|
||||||
editor.overwrite.confirm = [scarlet]Warning![] A map with this name already exists. Are you sure you want to overwrite it?
|
editor.overwrite.confirm = [scarlet]Warning![] A map with this name already exists. Are you sure you want to overwrite it?
|
||||||
|
editor.exists = A map with this name already exists.
|
||||||
editor.selectmap = Select a map to load:
|
editor.selectmap = Select a map to load:
|
||||||
|
|
||||||
toolmode.replace = Replace
|
toolmode.replace = Replace
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||||||
batch = new SpriteBatch();
|
batch = new SpriteBatch();
|
||||||
assets = new AssetManager();
|
assets = new AssetManager();
|
||||||
assets.setLoader(Texture.class, "." + mapExtension, new MapPreviewLoader());
|
assets.setLoader(Texture.class, "." + mapExtension, new MapPreviewLoader());
|
||||||
|
assets.load("sprites/error.png", Texture.class);
|
||||||
atlas = TextureAtlas.blankAtlas();
|
atlas = TextureAtlas.blankAtlas();
|
||||||
Vars.net = new Net(platform.getNet());
|
Vars.net = new Net(platform.getNet());
|
||||||
|
|
||||||
|
|||||||
@@ -122,8 +122,6 @@ public class Vars implements Loadable{
|
|||||||
public static FileHandle saveDirectory;
|
public static FileHandle saveDirectory;
|
||||||
/** data subdirectory used for plugins */
|
/** data subdirectory used for plugins */
|
||||||
public static FileHandle pluginDirectory;
|
public static FileHandle pluginDirectory;
|
||||||
/** old map file extension, for conversion */
|
|
||||||
public static final String oldMapExtension = "mmap";
|
|
||||||
/** map file extension */
|
/** map file extension */
|
||||||
public static final String mapExtension = "msav";
|
public static final String mapExtension = "msav";
|
||||||
/** save file extension */
|
/** save file extension */
|
||||||
@@ -139,7 +137,7 @@ public class Vars implements Loadable{
|
|||||||
public static EntityCollisions collisions;
|
public static EntityCollisions collisions;
|
||||||
public static DefaultWaves defaultWaves;
|
public static DefaultWaves defaultWaves;
|
||||||
public static LoopControl loops;
|
public static LoopControl loops;
|
||||||
public static Platform platform;
|
public static Platform platform = new Platform(){};
|
||||||
public static Plugins plugins;
|
public static Plugins plugins;
|
||||||
|
|
||||||
public static World world;
|
public static World world;
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class StatusEffects implements ContentList{
|
|||||||
if(unit.getTeam() == waveTeam){
|
if(unit.getTeam() == waveTeam){
|
||||||
Events.fire(Trigger.shock);
|
Events.fire(Trigger.shock);
|
||||||
}
|
}
|
||||||
|
result.set(this, time);
|
||||||
}));
|
}));
|
||||||
opposite(() -> burning);
|
opposite(() -> burning);
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -371,11 +371,13 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
|
//TODO find out why this happens on Android
|
||||||
|
if(assets == null) return;
|
||||||
|
|
||||||
saves.update();
|
saves.update();
|
||||||
|
|
||||||
//update and load any requested assets
|
//update and load any requested assets
|
||||||
if(assets != null){
|
|
||||||
assets.update();
|
assets.update();
|
||||||
}
|
|
||||||
|
|
||||||
input.updateController();
|
input.updateController();
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
|
|||||||
|
|
||||||
import io.anuke.arc.*;
|
import io.anuke.arc.*;
|
||||||
import io.anuke.arc.Input.*;
|
import io.anuke.arc.Input.*;
|
||||||
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.files.*;
|
import io.anuke.arc.files.*;
|
||||||
import io.anuke.arc.function.*;
|
import io.anuke.arc.function.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
@@ -25,6 +26,14 @@ public interface Platform{
|
|||||||
/** Steam: Share a map on the workshop.*/
|
/** Steam: Share a map on the workshop.*/
|
||||||
default void publishMap(Map map){}
|
default void publishMap(Map map){}
|
||||||
|
|
||||||
|
/** Steam: Return external workshop maps to be loaded.*/
|
||||||
|
default Array<FileHandle> getExternalMaps(){
|
||||||
|
return Array.with();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Steam: View a map listing on the workshop.*/
|
||||||
|
default void viewMapListing(Map map){}
|
||||||
|
|
||||||
/** Steam: Open workshop for maps.*/
|
/** Steam: Open workshop for maps.*/
|
||||||
default void openWorkshop(){}
|
default void openWorkshop(){}
|
||||||
|
|
||||||
|
|||||||
@@ -325,8 +325,9 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
cont.row();
|
cont.row();
|
||||||
cont.addImage().width(300f).pad(2).height(4f).color(Color.scarlet);
|
cont.addImage().width(300f).pad(2).height(4f).color(Color.scarlet);
|
||||||
cont.row();
|
cont.row();
|
||||||
cont.add(text).pad(2f).growX().wrap();
|
cont.add(text).pad(2f).growX().wrap().get().setAlignment(Align.center);
|
||||||
buttons.addButton("$ok", this::hide).size(120, 50).pad(4);
|
cont.row();
|
||||||
|
cont.addButton("$ok", this::hide).size(120, 50).pad(4);
|
||||||
}}.show();
|
}}.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,10 +154,21 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
if(steam){
|
if(steam){
|
||||||
menu.cont.addImageTextButton("$editor.publish.workshop", Icon.linkSmall, () -> {
|
menu.cont.addImageTextButton("$editor.publish.workshop", Icon.linkSmall, () -> {
|
||||||
Map map = save();
|
Map map = save();
|
||||||
if(map != null){
|
|
||||||
platform.publishMap(map);
|
if(map == null) return;
|
||||||
|
|
||||||
|
if(map.tags.get("description", "").length() < 4){
|
||||||
|
ui.showErrorMessage("$editor.nodescription");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}).padTop(-3).size(swidth * 2f + 10, 60f);
|
|
||||||
|
if(!Gamemode.survival.valid(map)){
|
||||||
|
ui.showErrorMessage("$map.nospawn");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform.publishMap(map);
|
||||||
|
}).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.getTags().containsKey("steamid") ? "$view.workshop" : "$editor.publish.workshop"));
|
||||||
|
|
||||||
menu.cont.row();
|
menu.cont.row();
|
||||||
}
|
}
|
||||||
@@ -276,7 +287,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map save(){
|
public Map save(){
|
||||||
String name = editor.getTags().get("name", "").trim();
|
String name = editor.getTags().get("name", "").trim();
|
||||||
editor.getTags().put("rules", JsonIO.write(state.rules));
|
editor.getTags().put("rules", JsonIO.write(state.rules));
|
||||||
editor.getTags().remove("width");
|
editor.getTags().remove("width");
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class MapLoadDialog extends FloatingDialog{
|
|||||||
for(Map map : maps.all()){
|
for(Map map : maps.all()){
|
||||||
|
|
||||||
TextButton button = new TextButton(map.name(), Styles.togglet);
|
TextButton button = new TextButton(map.name(), Styles.togglet);
|
||||||
button.add(new BorderImage(map.texture, 2f).setScaling(Scaling.fit)).size(16 * 4f);
|
button.add(new BorderImage(map.safeTexture(), 2f).setScaling(Scaling.fit)).size(16 * 4f);
|
||||||
button.getCells().reverse();
|
button.getCells().reverse();
|
||||||
button.clicked(() -> selected = map);
|
button.clicked(() -> selected = map);
|
||||||
button.getLabelCell().grow().left().padLeft(5f);
|
button.getLabelCell().grow().left().padLeft(5f);
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public class EntityGroup<T extends Entity>{
|
|||||||
private final Array<T> entityArray = new Array<>(false, 32);
|
private final Array<T> entityArray = new Array<>(false, 32);
|
||||||
private final Array<T> entitiesToRemove = new Array<>(false, 32);
|
private final Array<T> entitiesToRemove = new Array<>(false, 32);
|
||||||
private final Array<T> entitiesToAdd = new Array<>(false, 32);
|
private final Array<T> entitiesToAdd = new Array<>(false, 32);
|
||||||
|
private final Array<T> intersectArray = new Array<>();
|
||||||
|
private final Rectangle intersectRect = new Rectangle();
|
||||||
private IntMap<T> map;
|
private IntMap<T> map;
|
||||||
private QuadTree tree;
|
private QuadTree tree;
|
||||||
private Consumer<T> removeListener;
|
private Consumer<T> removeListener;
|
||||||
@@ -161,6 +163,15 @@ public class EntityGroup<T extends Entity>{
|
|||||||
tree().getIntersect(out, x, y, width, height);
|
tree().getIntersect(out, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Array<T> intersect(float x, float y, float width, float height){
|
||||||
|
intersectArray.clear();
|
||||||
|
//don't waste time for empty groups
|
||||||
|
if(isEmpty()) return intersectArray;
|
||||||
|
tree().getIntersect(intersectArray, intersectRect.set(x, y, width, height));
|
||||||
|
return intersectArray;
|
||||||
|
}
|
||||||
|
|
||||||
public QuadTree tree(){
|
public QuadTree tree(){
|
||||||
if(!useTree) throw new RuntimeException("This group does not support quadtrees! Enable quadtrees when creating it.");
|
if(!useTree) throw new RuntimeException("This group does not support quadtrees! Enable quadtrees when creating it.");
|
||||||
return tree;
|
return tree;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class Lightning extends TimedEntity implements DrawTrait, TimeTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Do not invoke! */
|
/** Do not invoke! */
|
||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server, unreliable = true)
|
||||||
public static void createLighting(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
|
public static void createLighting(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
|
||||||
|
|
||||||
Lightning l = Pools.obtain(Lightning.class, Lightning::new);
|
Lightning l = Pools.obtain(Lightning.class, Lightning::new);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import io.anuke.mindustry.game.*;
|
|||||||
import io.anuke.mindustry.gen.*;
|
import io.anuke.mindustry.gen.*;
|
||||||
import io.anuke.mindustry.type.*;
|
import io.anuke.mindustry.type.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
|
import io.anuke.mindustry.world.blocks.*;
|
||||||
import io.anuke.mindustry.world.blocks.defense.DeflectorWall.*;
|
import io.anuke.mindustry.world.blocks.defense.DeflectorWall.*;
|
||||||
import io.anuke.mindustry.world.blocks.units.CommandCenter.*;
|
import io.anuke.mindustry.world.blocks.units.CommandCenter.*;
|
||||||
import io.anuke.mindustry.world.blocks.units.UnitFactory.*;
|
import io.anuke.mindustry.world.blocks.units.UnitFactory.*;
|
||||||
@@ -273,7 +274,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isFlying() && (world.tileWorld(x, y) != null && world.tileWorld(x, y).solid())){
|
if(!isFlying() && (world.tileWorld(x, y) != null && !(world.tileWorld(x, y).block() instanceof BuildBlock) && world.tileWorld(x, y).solid())){
|
||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities.type;
|
|||||||
|
|
||||||
import io.anuke.annotations.Annotations.*;
|
import io.anuke.annotations.Annotations.*;
|
||||||
import io.anuke.arc.*;
|
import io.anuke.arc.*;
|
||||||
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.graphics.*;
|
import io.anuke.arc.graphics.*;
|
||||||
import io.anuke.arc.graphics.g2d.*;
|
import io.anuke.arc.graphics.g2d.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
@@ -212,15 +213,25 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
float radScl = 1.5f;
|
float radScl = 1.5f;
|
||||||
float fsize = getSize() / radScl;
|
float fsize = getSize() / radScl;
|
||||||
moveVector.setZero();
|
moveVector.setZero();
|
||||||
|
float cx = x - fsize/2f, cy = y - fsize/2f;
|
||||||
|
|
||||||
Units.nearby(x - fsize/2f, y - fsize/2f, fsize, fsize, en -> {
|
for(Team team : Team.all){
|
||||||
if(en == this || en.isFlying() != isFlying()) return;
|
avoid(unitGroups[team.ordinal()].intersect(cx, cy, fsize, fsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
avoid(playerGroup.intersect(cx, cy, fsize, fsize));
|
||||||
|
velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void avoid(Array<? extends Unit> arr){
|
||||||
|
float radScl = 1.5f;
|
||||||
|
|
||||||
|
for(Unit en : arr){
|
||||||
|
if(en.isFlying() != isFlying()) continue;
|
||||||
float dst = dst(en);
|
float dst = dst(en);
|
||||||
float scl = Mathf.clamp(1f - dst / (getSize()/(radScl*2f) + en.getSize()/(radScl*2f)));
|
float scl = Mathf.clamp(1f - dst / (getSize()/(radScl*2f) + en.getSize()/(radScl*2f)));
|
||||||
moveVector.add(Tmp.v1.set((x - en.x) * scl, (y - en.y) * scl).limit(0.4f));
|
moveVector.add(Tmp.v1.set((x - en.x) * scl, (y - en.y) * scl).limit(0.4f));
|
||||||
});
|
}
|
||||||
|
|
||||||
velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable TileEntity getClosestCore(){
|
public @Nullable TileEntity getClosestCore(){
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ public class Statuses implements Saveable{
|
|||||||
if(statuses.size > 0){
|
if(statuses.size > 0){
|
||||||
//check for opposite effects
|
//check for opposite effects
|
||||||
for(StatusEntry entry : statuses){
|
for(StatusEntry entry : statuses){
|
||||||
if(entry.effect == null) continue;
|
|
||||||
//extend effect
|
//extend effect
|
||||||
if(entry.effect == effect){
|
if(entry.effect == effect){
|
||||||
entry.time = Math.max(entry.time, duration);
|
entry.time = Math.max(entry.time, duration);
|
||||||
return;
|
return;
|
||||||
}else if(entry.effect.reactsWith(effect)){ //find opposite
|
}else if(entry.effect.reactsWith(effect)){ //find opposite
|
||||||
|
globalResult.effect = entry.effect;
|
||||||
entry.effect.getTransition(unit, effect, entry.time, duration, globalResult);
|
entry.effect.getTransition(unit, effect, entry.time, duration, globalResult);
|
||||||
entry.time = globalResult.time;
|
entry.time = globalResult.time;
|
||||||
|
|
||||||
@@ -84,10 +84,6 @@ public class Statuses implements Saveable{
|
|||||||
removals.clear();
|
removals.clear();
|
||||||
|
|
||||||
for(StatusEntry entry : statuses){
|
for(StatusEntry entry : statuses){
|
||||||
if(entry.effect == null){
|
|
||||||
removals.add(entry);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
entry.time = Math.max(entry.time - Time.delta(), 0);
|
entry.time = Math.max(entry.time - Time.delta(), 0);
|
||||||
applied.set(entry.effect.id);
|
applied.set(entry.effect.id);
|
||||||
|
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ public class Tutorial{
|
|||||||
}
|
}
|
||||||
},;
|
},;
|
||||||
|
|
||||||
protected final String line = Core.bundle.has("tutorial." + name() + ".mobile") && mobile ? "tutorial." + name() + ".mobile" : "tutorial." + name();
|
protected String line = "";
|
||||||
protected final Function<String, String> text;
|
protected final Function<String, String> text;
|
||||||
protected Array<String> sentences;
|
protected Array<String> sentences;
|
||||||
protected final BooleanProvider done;
|
protected final BooleanProvider done;
|
||||||
@@ -203,7 +203,10 @@ public class Tutorial{
|
|||||||
|
|
||||||
/** displayed tutorial stage text.*/
|
/** displayed tutorial stage text.*/
|
||||||
public String text(){
|
public String text(){
|
||||||
if(sentences == null) this.sentences = Array.select(Core.bundle.get(line).split("\n"), s -> !s.isEmpty());
|
if(sentences == null){
|
||||||
|
this.line = Core.bundle.has("tutorial." + name() + ".mobile") && mobile ? "tutorial." + name() + ".mobile" : "tutorial." + name();
|
||||||
|
this.sentences = Array.select(Core.bundle.get(line).split("\n"), s -> !s.isEmpty());
|
||||||
|
}
|
||||||
String line = sentences.get(control.tutorial.sentence);
|
String line = sentences.get(control.tutorial.sentence);
|
||||||
return line.contains("{") ? text.get(line) : line;
|
return line.contains("{") ? text.get(line) : line;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public abstract class InputHandler implements InputProcessor{
|
|||||||
|
|
||||||
@Remote(targets = Loc.both, forward = true, called = Loc.server)
|
@Remote(targets = Loc.both, forward = true, called = Loc.server)
|
||||||
public static void transferInventory(Player player, Tile tile){
|
public static void transferInventory(Player player, Tile tile){
|
||||||
if(!player.timer.get(Player.timerTransfer, 40)) return;
|
if(player == null || player.timer == null || !player.timer.get(Player.timerTransfer, 40)) return;
|
||||||
if(net.server() && (player.item().amount <= 0 || player.isTransferring|| !tile.interactable(player.getTeam()))){
|
if(net.server() && (player.item().amount <= 0 || player.isTransferring|| !tile.interactable(player.getTeam()))){
|
||||||
throw new ValidateException(player, "Player cannot transfer an item.");
|
throw new ValidateException(player, "Player cannot transfer an item.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,33 +67,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
public MobileInput(){
|
public MobileInput(){
|
||||||
Events.on(ClientLoadEvent.class, e -> {
|
Events.on(ClientLoadEvent.class, e -> {
|
||||||
GestureDetector dec = new GestureDetector(20, 0.5f, 0.4f, 0.15f, this){
|
Core.input.getInputProcessors().add(new GestureDetector(20, 0.5f, 0.4f, 0.15f, this));
|
||||||
boolean clearMouse = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean touchDown(int x, int y, int pointer, KeyCode button){
|
|
||||||
if(Core.scene.hasMouse(x, y)){
|
|
||||||
clearMouse = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return super.touchDown(x, y, pointer, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean touchDragged(int x, int y, int pointer){
|
|
||||||
if(!clearMouse){
|
|
||||||
return super.touchDragged(x, y, pointer);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean touchUp(int x, int y, int pointer, KeyCode button){
|
|
||||||
clearMouse = false;
|
|
||||||
return super.touchUp(x, y, pointer, button);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Core.input.getInputProcessors().insert(0, dec);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ public class Map implements Comparable<Map>{
|
|||||||
public final FileHandle file;
|
public final FileHandle file;
|
||||||
/** Format version. */
|
/** Format version. */
|
||||||
public final int version;
|
public final int version;
|
||||||
|
/** Whether this map is managed, e.g. downloaded from the Steam workshop.*/
|
||||||
|
public boolean workshop;
|
||||||
/** Map width/height, shorts. */
|
/** Map width/height, shorts. */
|
||||||
public int width, height;
|
public int width, height;
|
||||||
/** Preview texture. */
|
/** Preview texture. */
|
||||||
@@ -57,8 +59,12 @@ public class Map implements Comparable<Map>{
|
|||||||
return Core.settings.getInt("hiscore" + file.nameWithoutExtension(), 0);
|
return Core.settings.getInt("hiscore" + file.nameWithoutExtension(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Texture safeTexture(){
|
||||||
|
return texture == null ? Core.assets.get("sprites/error.png") : texture;
|
||||||
|
}
|
||||||
|
|
||||||
public FileHandle previewFile(){
|
public FileHandle previewFile(){
|
||||||
return Vars.mapPreviewDirectory.child(file.nameWithoutExtension() + ".png");
|
return Vars.mapPreviewDirectory.child((workshop ? file.parent().name() : file.nameWithoutExtension()) + ".png");
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileHandle cacheFile(){
|
public FileHandle cacheFile(){
|
||||||
@@ -127,6 +133,8 @@ public class Map implements Comparable<Map>{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Map map){
|
public int compareTo(Map map){
|
||||||
|
int work = -Boolean.compare(workshop, map.workshop);
|
||||||
|
if(work != 0) return work;
|
||||||
int type = -Boolean.compare(custom, map.custom);
|
int type = -Boolean.compare(custom, map.custom);
|
||||||
if(type != 0) return type;
|
if(type != 0) return type;
|
||||||
int modes = Boolean.compare(Gamemode.pvp.valid(this), Gamemode.pvp.valid(map));
|
int modes = Boolean.compare(Gamemode.pvp.valid(this), Gamemode.pvp.valid(map));
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.anuke.arc.assets.loaders.resolvers.*;
|
|||||||
import io.anuke.arc.collection.*;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.files.*;
|
import io.anuke.arc.files.*;
|
||||||
import io.anuke.arc.graphics.*;
|
import io.anuke.arc.graphics.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.*;
|
import io.anuke.mindustry.*;
|
||||||
import io.anuke.mindustry.game.*;
|
import io.anuke.mindustry.game.*;
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ public class MapPreviewLoader extends TextureLoader{
|
|||||||
try{
|
try{
|
||||||
super.loadAsync(manager, fileName, file.sibling(file.nameWithoutExtension()), parameter);
|
super.loadAsync(manager, fileName, file.sibling(file.nameWithoutExtension()), parameter);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
Log.err(e);
|
||||||
MapPreviewParameter param = (MapPreviewParameter)parameter;
|
MapPreviewParameter param = (MapPreviewParameter)parameter;
|
||||||
Vars.maps.queueNewPreview(param.map);
|
Vars.maps.queueNewPreview(param.map);
|
||||||
}
|
}
|
||||||
@@ -31,11 +32,11 @@ public class MapPreviewLoader extends TextureLoader{
|
|||||||
try{
|
try{
|
||||||
return super.loadSync(manager, fileName, file, parameter);
|
return super.loadSync(manager, fileName, file, parameter);
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
e.printStackTrace();
|
Log.err(e);
|
||||||
try{
|
try{
|
||||||
return new Texture(file);
|
return new Texture(file);
|
||||||
}catch(Throwable e2){
|
}catch(Throwable e2){
|
||||||
e2.printStackTrace();
|
Log.err(e2);
|
||||||
return new Texture("sprites/error.png");
|
return new Texture("sprites/error.png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public class Maps{
|
|||||||
|
|
||||||
/** Load all maps. Should be called at application start. */
|
/** Load all maps. Should be called at application start. */
|
||||||
public void load(){
|
public void load(){
|
||||||
|
//defaults; must work
|
||||||
try{
|
try{
|
||||||
for(String name : defaultMapNames){
|
for(String name : defaultMapNames){
|
||||||
FileHandle file = Core.files.internal("maps/" + name + "." + mapExtension);
|
FileHandle file = Core.files.internal("maps/" + name + "." + mapExtension);
|
||||||
@@ -90,7 +91,27 @@ public class Maps{
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCustomMaps();
|
//custom
|
||||||
|
for(FileHandle file : customMapDirectory.list()){
|
||||||
|
try{
|
||||||
|
if(file.extension().equalsIgnoreCase(mapExtension)){
|
||||||
|
loadMap(file, true);
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
Log.err("Failed to load custom map file '{0}'!", file);
|
||||||
|
Log.err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//workshop
|
||||||
|
for(FileHandle file : platform.getExternalMaps()){
|
||||||
|
try{
|
||||||
|
loadMap(file, false).workshop = true;
|
||||||
|
}catch(Exception e){
|
||||||
|
Log.err("Failed to load workshop map file '{0}'!", file);
|
||||||
|
Log.err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reload(){
|
public void reload(){
|
||||||
@@ -174,14 +195,6 @@ public class Maps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a legacy map by converting it to a non-legacy map and pasting it in a temp directory.
|
|
||||||
* Should be followed up by {@link #importMap(FileHandle)} .*/
|
|
||||||
public Map makeLegacyMap(FileHandle file) throws IOException{
|
|
||||||
FileHandle dst = tmpDirectory.child("conversion_map." + mapExtension);
|
|
||||||
LegacyMapIO.convertMap(file, dst);
|
|
||||||
return MapIO.createMap(dst, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Import a map, then save it. This updates all values and stored data necessary. */
|
/** Import a map, then save it. This updates all values and stored data necessary. */
|
||||||
public void importMap(FileHandle file) throws IOException{
|
public void importMap(FileHandle file) throws IOException{
|
||||||
FileHandle dest = findFile();
|
FileHandle dest = findFile();
|
||||||
@@ -203,7 +216,6 @@ public class Maps{
|
|||||||
if(error[0] != null){
|
if(error[0] != null){
|
||||||
throw new IOException(error[0]);
|
throw new IOException(error[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attempts to run the following code;
|
/** Attempts to run the following code;
|
||||||
@@ -314,7 +326,7 @@ public class Maps{
|
|||||||
for(Map map : maps){
|
for(Map map : maps){
|
||||||
//try to load preview
|
//try to load preview
|
||||||
if(map.previewFile().exists()){
|
if(map.previewFile().exists()){
|
||||||
//this may fail, but calls createNewPreview
|
//this may fail, but calls queueNewPreview
|
||||||
Core.assets.load(new AssetDescriptor<>(map.previewFile().path() + "." + mapExtension, Texture.class, new MapPreviewParameter(map))).loaded = t -> map.texture = (Texture)t;
|
Core.assets.load(new AssetDescriptor<>(map.previewFile().path() + "." + mapExtension, Texture.class, new MapPreviewParameter(map))).loaded = t -> map.texture = (Texture)t;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
@@ -332,7 +344,7 @@ public class Maps{
|
|||||||
private void createAllPreviews(){
|
private void createAllPreviews(){
|
||||||
Core.app.post(() -> {
|
Core.app.post(() -> {
|
||||||
for(Map map : previewList){
|
for(Map map : previewList){
|
||||||
createNewPreview(map, e -> Core.app.post(() -> map.texture = new Texture("sprites/error.png")));
|
createNewPreview(map, e -> Core.app.post(() -> map.texture = Core.assets.get("sprites/error.png")));
|
||||||
}
|
}
|
||||||
previewList.clear();
|
previewList.clear();
|
||||||
});
|
});
|
||||||
@@ -407,16 +419,4 @@ public class Maps{
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCustomMaps(){
|
|
||||||
for(FileHandle file : customMapDirectory.list()){
|
|
||||||
try{
|
|
||||||
if(file.extension().equalsIgnoreCase(mapExtension)){
|
|
||||||
loadMap(file, true);
|
|
||||||
}
|
|
||||||
}catch(Exception e){
|
|
||||||
Log.err("Failed to load custom map file '{0}'!", file);
|
|
||||||
Log.err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -25,8 +25,8 @@ public class CrashSender{
|
|||||||
try{
|
try{
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
|
|
||||||
//don't create crash logs for me (anuke) or custom builds, as it's expected
|
//don't create crash logs for custom builds, as it's expected
|
||||||
if(System.getProperty("user.name").equals("anuke") || Version.build == -1) return;
|
if(Version.build == -1) return;
|
||||||
|
|
||||||
//attempt to load version regardless
|
//attempt to load version regardless
|
||||||
if(Version.number == 0){
|
if(Version.number == 0){
|
||||||
|
|||||||
@@ -46,7 +46,9 @@ public class Net{
|
|||||||
t = t.getCause();
|
t = t.getCause();
|
||||||
}
|
}
|
||||||
|
|
||||||
String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase();
|
String baseError = Strings.getFinalMesage(e);
|
||||||
|
|
||||||
|
String error = baseError == null ? "" : baseError.toLowerCase();
|
||||||
String type = t.getClass().toString().toLowerCase();
|
String type = t.getClass().toString().toLowerCase();
|
||||||
boolean isError = false;
|
boolean isError = false;
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class Plugins{
|
|||||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
||||||
Class<?> main = classLoader.loadClass(meta.main);
|
Class<?> main = classLoader.loadClass(meta.main);
|
||||||
metas.put(main, meta);
|
metas.put(main, meta);
|
||||||
return new LoadedPlugin(jar, zip, (Plugin)main.newInstance(), meta);
|
return new LoadedPlugin(jar, zip, (Plugin)main.getDeclaredConstructor().newInstance(), meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Represents a plugin that has been loaded from a jar file.*/
|
/** Represents a plugin that has been loaded from a jar file.*/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import io.anuke.arc.collection.ObjectMap;
|
|||||||
import io.anuke.arc.function.Supplier;
|
import io.anuke.arc.function.Supplier;
|
||||||
import io.anuke.arc.graphics.Color;
|
import io.anuke.arc.graphics.Color;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.content.Fx;
|
import io.anuke.mindustry.content.Fx;
|
||||||
import io.anuke.mindustry.entities.Effects;
|
import io.anuke.mindustry.entities.Effects;
|
||||||
import io.anuke.mindustry.entities.Effects.Effect;
|
import io.anuke.mindustry.entities.Effects.Effect;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class CustomGameDialog extends FloatingDialog{
|
|||||||
maps.row();
|
maps.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButton image = new ImageButton(new TextureRegion(map.texture), Styles.cleari);
|
ImageButton image = new ImageButton(new TextureRegion(map.safeTexture()), Styles.cleari);
|
||||||
image.margin(5);
|
image.margin(5);
|
||||||
image.top();
|
image.top();
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ public class CustomGameDialog extends FloatingDialog{
|
|||||||
image.add(img).size(images);
|
image.add(img).size(images);
|
||||||
|
|
||||||
|
|
||||||
BorderImage border = new BorderImage(map.texture, 3f);
|
BorderImage border = new BorderImage(map.safeTexture(), 3f);
|
||||||
border.setScaling(Scaling.fit);
|
border.setScaling(Scaling.fit);
|
||||||
image.replaceImage(border);
|
image.replaceImage(border);
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class MapPlayDialog extends FloatingDialog{
|
|||||||
cont.row();
|
cont.row();
|
||||||
cont.addImageTextButton("$customize", Icon.toolsSmall, () -> dialog.show(rules, () -> rules = map.applyRules(selectedGamemode))).width(230);
|
cont.addImageTextButton("$customize", Icon.toolsSmall, () -> dialog.show(rules, () -> rules = map.applyRules(selectedGamemode))).width(230);
|
||||||
cont.row();
|
cont.row();
|
||||||
cont.add(new BorderImage(map.texture, 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit);
|
cont.add(new BorderImage(map.safeTexture(), 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit);
|
||||||
//only maps with survival are valid for high scores
|
//only maps with survival are valid for high scores
|
||||||
if(Gamemode.survival.valid(map)){
|
if(Gamemode.survival.valid(map)){
|
||||||
cont.row();
|
cont.row();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import io.anuke.arc.*;
|
|||||||
import io.anuke.arc.graphics.*;
|
import io.anuke.arc.graphics.*;
|
||||||
import io.anuke.arc.input.*;
|
import io.anuke.arc.input.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.scene.event.*;
|
|
||||||
import io.anuke.arc.scene.ui.*;
|
import io.anuke.arc.scene.ui.*;
|
||||||
import io.anuke.arc.scene.ui.layout.*;
|
import io.anuke.arc.scene.ui.layout.*;
|
||||||
import io.anuke.arc.util.*;
|
import io.anuke.arc.util.*;
|
||||||
@@ -53,12 +52,18 @@ public class MapsDialog extends FloatingDialog{
|
|||||||
|
|
||||||
buttons.addImageTextButton("$editor.newmap", Icon.add, () -> {
|
buttons.addImageTextButton("$editor.newmap", Icon.add, () -> {
|
||||||
ui.showTextInput("$editor.newmap", "$name", "", text -> {
|
ui.showTextInput("$editor.newmap", "$name", "", text -> {
|
||||||
ui.loadAnd(() -> {
|
Runnable show = () -> ui.loadAnd(() -> {
|
||||||
hide();
|
hide();
|
||||||
ui.editor.show();
|
ui.editor.show();
|
||||||
ui.editor.editor.getTags().put("name", text);
|
ui.editor.editor.getTags().put("name", text);
|
||||||
Events.fire(new MapMakeEvent());
|
Events.fire(new MapMakeEvent());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(maps.byName(text) != null){
|
||||||
|
ui.showErrorMessage("$editor.exists");
|
||||||
|
}else{
|
||||||
|
show.run();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}).size(210f, 64f);
|
}).size(210f, 64f);
|
||||||
|
|
||||||
@@ -137,9 +142,9 @@ public class MapsDialog extends FloatingDialog{
|
|||||||
button.row();
|
button.row();
|
||||||
button.addImage().growX().pad(4).color(Pal.gray);
|
button.addImage().growX().pad(4).color(Pal.gray);
|
||||||
button.row();
|
button.row();
|
||||||
button.stack(new Image(map.texture).setScaling(Scaling.fit), new BorderImage(map.texture).setScaling(Scaling.fit)).size(mapsize - 20f);
|
button.stack(new Image(map.safeTexture()).setScaling(Scaling.fit), new BorderImage(map.safeTexture()).setScaling(Scaling.fit)).size(mapsize - 20f);
|
||||||
button.row();
|
button.row();
|
||||||
button.add(map.custom ? "$custom" : "$builtin").color(Color.gray).padTop(3);
|
button.add(map.custom ? "$custom" : map.workshop ? "$workshop" : "$builtin").color(Color.gray).padTop(3);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -160,7 +165,7 @@ public class MapsDialog extends FloatingDialog{
|
|||||||
float mapsize = Core.graphics.isPortrait() ? 160f : 300f;
|
float mapsize = Core.graphics.isPortrait() ? 160f : 300f;
|
||||||
Table table = dialog.cont;
|
Table table = dialog.cont;
|
||||||
|
|
||||||
table.stack(new Image(map.texture).setScaling(Scaling.fit), new BorderImage(map.texture).setScaling(Scaling.fit)).size(mapsize);
|
table.stack(new Image(map.safeTexture()).setScaling(Scaling.fit), new BorderImage(map.safeTexture()).setScaling(Scaling.fit)).size(mapsize);
|
||||||
|
|
||||||
table.table(Styles.black, desc -> {
|
table.table(Styles.black, desc -> {
|
||||||
desc.top();
|
desc.top();
|
||||||
@@ -199,13 +204,17 @@ public class MapsDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
}).fillX().height(54f).marginLeft(10);
|
}).fillX().height(54f).marginLeft(10);
|
||||||
|
|
||||||
table.addImageTextButton("$delete", Icon.trash16Small, () -> {
|
table.addImageTextButton(map.workshop ? "$view.workshop" : "$delete", map.workshop ? Icon.linkSmall : Icon.trash16Small, () -> {
|
||||||
|
if(map.workshop){
|
||||||
|
platform.viewMapListing(map);
|
||||||
|
}else{
|
||||||
ui.showConfirm("$confirm", Core.bundle.format("map.delete", map.name()), () -> {
|
ui.showConfirm("$confirm", Core.bundle.format("map.delete", map.name()), () -> {
|
||||||
maps.removeMap(map);
|
maps.removeMap(map);
|
||||||
dialog.hide();
|
dialog.hide();
|
||||||
setup();
|
setup();
|
||||||
});
|
});
|
||||||
}).fillX().height(54f).marginLeft(10).disabled(!map.custom).touchable(map.custom ? Touchable.enabled : Touchable.disabled);
|
}
|
||||||
|
}).fillX().height(54f).marginLeft(10).disabled(!map.workshop && !map.custom);
|
||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
public class BlockInventoryFragment extends Fragment{
|
public class BlockInventoryFragment extends Fragment{
|
||||||
private final static float holdWithdraw = 20f;
|
private final static float holdWithdraw = 20f;
|
||||||
|
|
||||||
private Table table;
|
private Table table = new Table();
|
||||||
private Tile tile;
|
private Tile tile;
|
||||||
private float holdTime = 0f;
|
private float holdTime = 0f;
|
||||||
private boolean holding;
|
private boolean holding;
|
||||||
@@ -52,7 +52,6 @@ public class BlockInventoryFragment extends Fragment{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(Group parent){
|
public void build(Group parent){
|
||||||
table = new Table();
|
|
||||||
table.setName("inventory");
|
table.setName("inventory");
|
||||||
table.setTransform(true);
|
table.setTransform(true);
|
||||||
parent.setTransform(true);
|
parent.setTransform(true);
|
||||||
|
|||||||
@@ -572,9 +572,6 @@ public class HudFragment extends Fragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
shown = !shown;
|
shown = !shown;
|
||||||
if(flip != null){
|
|
||||||
flip.getParent().act(Core.graphics.getDeltaTime());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addWaveTable(Button table){
|
private void addWaveTable(Button table){
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class CooledTurret extends Turret{
|
|||||||
Liquid liquid = entity.liquids.current();
|
Liquid liquid = entity.liquids.current();
|
||||||
|
|
||||||
float used = Math.min(Math.min(entity.liquids.get(liquid), maxUsed * Time.delta()), Math.max(0, ((reload - entity.reload) / coolantMultiplier) / liquid.heatCapacity)) * baseReloadSpeed(tile);
|
float used = Math.min(Math.min(entity.liquids.get(liquid), maxUsed * Time.delta()), Math.max(0, ((reload - entity.reload) / coolantMultiplier) / liquid.heatCapacity)) * baseReloadSpeed(tile);
|
||||||
entity.reload += (used * liquid.heatCapacity) / liquid.heatCapacity;
|
entity.reload += used * liquid.heatCapacity * coolantMultiplier;
|
||||||
entity.liquids.remove(liquid, used);
|
entity.liquids.remove(liquid, used);
|
||||||
|
|
||||||
if(Mathf.chance(0.06 * used)){
|
if(Mathf.chance(0.06 * used)){
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public abstract class Turret extends Block{
|
|||||||
|
|
||||||
stats.add(BlockStat.shootRange, range / tilesize, StatUnit.blocks);
|
stats.add(BlockStat.shootRange, range / tilesize, StatUnit.blocks);
|
||||||
stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees);
|
stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees);
|
||||||
stats.add(BlockStat.reload, 60f / reload * shots, StatUnit.none);
|
stats.add(BlockStat.reload, 60f / reload, StatUnit.none);
|
||||||
stats.add(BlockStat.shots, shots, StatUnit.none);
|
stats.add(BlockStat.shots, shots, StatUnit.none);
|
||||||
stats.add(BlockStat.targetsAir, targetAir);
|
stats.add(BlockStat.targetsAir, targetAir);
|
||||||
stats.add(BlockStat.targetsGround, targetGround);
|
stats.add(BlockStat.targetsGround, targetGround);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ public class ItemBridge extends Block{
|
|||||||
protected int timerTransport = timers++;
|
protected int timerTransport = timers++;
|
||||||
protected int range;
|
protected int range;
|
||||||
protected float transportTime = 2f;
|
protected float transportTime = 2f;
|
||||||
protected IntArray removals = new IntArray();
|
|
||||||
protected TextureRegion endRegion, bridgeRegion, arrowRegion;
|
protected TextureRegion endRegion, bridgeRegion, arrowRegion;
|
||||||
|
|
||||||
private static int lastPlaced = Pos.invalid;
|
private static int lastPlaced = Pos.invalid;
|
||||||
@@ -162,21 +161,15 @@ public class ItemBridge extends Block{
|
|||||||
entity.time += entity.cycleSpeed * entity.delta();
|
entity.time += entity.cycleSpeed * entity.delta();
|
||||||
entity.time2 += (entity.cycleSpeed - 1f) * entity.delta();
|
entity.time2 += (entity.cycleSpeed - 1f) * entity.delta();
|
||||||
|
|
||||||
removals.clear();
|
|
||||||
|
|
||||||
IntSetIterator it = entity.incoming.iterator();
|
IntSetIterator it = entity.incoming.iterator();
|
||||||
|
|
||||||
while(it.hasNext){
|
while(it.hasNext){
|
||||||
int i = it.next();
|
int i = it.next();
|
||||||
Tile other = world.tile(i);
|
Tile other = world.tile(i);
|
||||||
if(!linkValid(tile, other, false)){
|
if(!linkValid(tile, other, false)){
|
||||||
removals.add(i);
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int j = 0; j < removals.size; j++)
|
|
||||||
entity.incoming.remove(removals.get(j));
|
|
||||||
|
|
||||||
Tile other = world.tile(entity.link);
|
Tile other = world.tile(entity.link);
|
||||||
if(!linkValid(tile, other)){
|
if(!linkValid(tile, other)){
|
||||||
entity.link = Pos.invalid;
|
entity.link = Pos.invalid;
|
||||||
@@ -184,7 +177,7 @@ public class ItemBridge extends Block{
|
|||||||
entity.uptime = 0f;
|
entity.uptime = 0f;
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
if(entity.cons.valid()){
|
if(entity.cons.valid() && (!hasPower || Mathf.isZero(1f - entity.power.satisfaction))){
|
||||||
entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f);
|
entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f);
|
||||||
}else{
|
}else{
|
||||||
entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f);
|
entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import io.anuke.mindustry.content.*;
|
|||||||
import io.anuke.mindustry.entities.*;
|
import io.anuke.mindustry.entities.*;
|
||||||
import io.anuke.mindustry.entities.Effects.*;
|
import io.anuke.mindustry.entities.Effects.*;
|
||||||
import io.anuke.mindustry.entities.type.*;
|
import io.anuke.mindustry.entities.type.*;
|
||||||
import io.anuke.mindustry.entities.type.Bullet;
|
|
||||||
import io.anuke.mindustry.gen.*;
|
import io.anuke.mindustry.gen.*;
|
||||||
import io.anuke.mindustry.graphics.*;
|
import io.anuke.mindustry.graphics.*;
|
||||||
import io.anuke.mindustry.type.*;
|
import io.anuke.mindustry.type.*;
|
||||||
@@ -120,12 +119,13 @@ public class MassDriver extends Block{
|
|||||||
|
|
||||||
if(
|
if(
|
||||||
tile.entity.items.total() >= minDistribute && //must shoot minimum amount of items
|
tile.entity.items.total() >= minDistribute && //must shoot minimum amount of items
|
||||||
link.block().itemCapacity - link.entity.items.total() >= minDistribute && //must have minimum amount of space
|
link.block().itemCapacity - link.entity.items.total() >= minDistribute //must have minimum amount of space
|
||||||
entity.reload <= 0.0001f //must have reloaded
|
|
||||||
){
|
){
|
||||||
MassDriverEntity other = link.entity();
|
MassDriverEntity other = link.entity();
|
||||||
other.waitingShooters.add(tile);
|
other.waitingShooters.add(tile);
|
||||||
|
|
||||||
|
if(entity.reload <= 0.0001f){
|
||||||
|
|
||||||
//align to target location
|
//align to target location
|
||||||
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRotation, rotateSpeed * entity.power.satisfaction);
|
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRotation, rotateSpeed * entity.power.satisfaction);
|
||||||
|
|
||||||
@@ -144,6 +144,7 @@ public class MassDriver extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Tile tile){
|
public void draw(Tile tile){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.world.blocks.distribution;
|
|||||||
|
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.Array;
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.Time;
|
||||||
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.entities.type.TileEntity;
|
import io.anuke.mindustry.entities.type.TileEntity;
|
||||||
import io.anuke.mindustry.type.Item;
|
import io.anuke.mindustry.type.Item;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
@@ -63,7 +64,7 @@ public class Router extends Block{
|
|||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
Tile other = proximity.get((i + counter) % proximity.size);
|
Tile other = proximity.get((i + counter) % proximity.size);
|
||||||
if(set) tile.rotation((byte)((tile.rotation() + 1) % proximity.size));
|
if(set) tile.rotation((byte)((tile.rotation() + 1) % proximity.size));
|
||||||
if(other == from) continue;
|
if(other == from && from.block() == Blocks.overflowGate) continue;
|
||||||
if(other.block().acceptItem(item, other, Edges.getFacingEdge(tile, other))){
|
if(other.block().acceptItem(item, other, Edges.getFacingEdge(tile, other))){
|
||||||
return other;
|
return other;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,13 @@ public class GenericCrafter extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean outputsItems(){
|
||||||
|
return outputItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canProduce(Tile tile){
|
public boolean canProduce(Tile tile){
|
||||||
if(outputItem != null && tile.entity.items.get(outputItem.item) >= itemCapacity){
|
if(outputItem != null && tile.entity.items.get(outputItem.item) >= itemCapacity){
|
||||||
|
|||||||
@@ -97,9 +97,11 @@ public class CoreBlock extends StorageBlock{
|
|||||||
entity.storageCapacity += other.block().itemCapacity + other.entity.proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
|
entity.storageCapacity += other.block().itemCapacity + other.entity.proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!world.isGenerating()){
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
entity.items.set(item, Math.min(entity.items.get(item), entity.storageCapacity));
|
entity.items.set(item, Math.min(entity.items.get(item), entity.storageCapacity));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(Tile other : state.teams.get(tile.getTeam()).cores){
|
for(Tile other : state.teams.get(tile.getTeam()).cores){
|
||||||
CoreEntity oe = other.entity();
|
CoreEntity oe = other.entity();
|
||||||
|
|||||||
@@ -77,8 +77,9 @@ public class LaunchPad extends StorageBlock{
|
|||||||
for(Item item : Vars.content.items()){
|
for(Item item : Vars.content.items()){
|
||||||
Events.fire(Trigger.itemLaunch);
|
Events.fire(Trigger.itemLaunch);
|
||||||
Effects.effect(Fx.padlaunch, tile);
|
Effects.effect(Fx.padlaunch, tile);
|
||||||
data.addItem(item, entity.items.get(item));
|
int used = Math.min(entity.items.get(item), itemCapacity);
|
||||||
entity.items.set(item, 0);
|
data.addItem(item, used);
|
||||||
|
entity.items.remove(item, used);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import io.anuke.arc.Files.*;
|
|||||||
import io.anuke.arc.backends.sdl.*;
|
import io.anuke.arc.backends.sdl.*;
|
||||||
import io.anuke.arc.backends.sdl.jni.*;
|
import io.anuke.arc.backends.sdl.jni.*;
|
||||||
import io.anuke.arc.collection.*;
|
import io.anuke.arc.collection.*;
|
||||||
|
import io.anuke.arc.files.*;
|
||||||
import io.anuke.arc.function.*;
|
import io.anuke.arc.function.*;
|
||||||
import io.anuke.arc.input.*;
|
import io.anuke.arc.input.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
@@ -48,11 +49,12 @@ public class DesktopLauncher extends ClientLauncher{
|
|||||||
setWindowIcon(FileType.Internal, "icons/icon_64.png");
|
setWindowIcon(FileType.Internal, "icons/icon_64.png");
|
||||||
}});
|
}});
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
DesktopLauncher.handleCrash(e);
|
handleCrash(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DesktopLauncher(String[] args){
|
public DesktopLauncher(String[] args){
|
||||||
|
Log.setUseColors(false);
|
||||||
Version.init();
|
Version.init();
|
||||||
boolean useSteam = Version.modifier.equals("steam");
|
boolean useSteam = Version.modifier.equals("steam");
|
||||||
testMobile = Array.with(args).contains("-testMobile");
|
testMobile = Array.with(args).contains("-testMobile");
|
||||||
@@ -72,6 +74,16 @@ public class DesktopLauncher extends ClientLauncher{
|
|||||||
|
|
||||||
if(useSteam){
|
if(useSteam){
|
||||||
if(showConsole){
|
if(showConsole){
|
||||||
|
StringBuilder base = new StringBuilder();
|
||||||
|
Log.setLogger(new LogHandler(){
|
||||||
|
@Override
|
||||||
|
public void print(String text, Object... args){
|
||||||
|
String out = Log.format(text, false, args);
|
||||||
|
|
||||||
|
base.append(out).append("\n");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Events.on(ClientLoadEvent.class, event -> {
|
Events.on(ClientLoadEvent.class, event -> {
|
||||||
Label[] label = {null};
|
Label[] label = {null};
|
||||||
boolean[] visible = {false};
|
boolean[] visible = {false};
|
||||||
@@ -86,6 +98,7 @@ public class DesktopLauncher extends ClientLauncher{
|
|||||||
t.toFront();
|
t.toFront();
|
||||||
});
|
});
|
||||||
t.table(Styles.black3, f -> label[0] = f.add("").get()).visible(() -> visible[0]);
|
t.table(Styles.black3, f -> label[0] = f.add("").get()).visible(() -> visible[0]);
|
||||||
|
label[0].getText().append(base);
|
||||||
});
|
});
|
||||||
|
|
||||||
Log.setLogger(new LogHandler(){
|
Log.setLogger(new LogHandler(){
|
||||||
@@ -177,12 +190,23 @@ public class DesktopLauncher extends ClientLauncher{
|
|||||||
boolean fbgp = badGPU;
|
boolean fbgp = badGPU;
|
||||||
|
|
||||||
CrashSender.send(e, file -> {
|
CrashSender.send(e, file -> {
|
||||||
|
Throwable cause = Strings.getFinalCause(e);
|
||||||
if(!fbgp){
|
if(!fbgp){
|
||||||
dialog.accept(() -> message("A crash has occured. It has been saved in:\n" + file.getAbsolutePath() + "\n" + (e.getMessage() == null ? "" : "\n" + e.getMessage())));
|
dialog.accept(() -> message("A crash has occured. It has been saved in:\n" + file.getAbsolutePath() + "\n" + cause.getClass().getSimpleName().replace("Exception", "") + (cause.getMessage() == null ? "" : ":\n" + cause.getMessage())));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Array<FileHandle> getExternalMaps(){
|
||||||
|
return !steam ? super.getExternalMaps() : SVars.workshop.getMapFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void viewMapListing(Map map){
|
||||||
|
SVars.net.friends.activateGameOverlayToWebPage("steam://url/CommunityFilePage/" + map.file.parent().name());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetProvider getNet(){
|
public NetProvider getNet(){
|
||||||
return steam ? SVars.net : new ArcNetImpl();
|
return steam ? SVars.net : new ArcNetImpl();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.codedisaster.steamworks.*;
|
|||||||
import com.codedisaster.steamworks.SteamRemoteStorage.*;
|
import com.codedisaster.steamworks.SteamRemoteStorage.*;
|
||||||
import com.codedisaster.steamworks.SteamUGC.*;
|
import com.codedisaster.steamworks.SteamUGC.*;
|
||||||
import io.anuke.arc.*;
|
import io.anuke.arc.*;
|
||||||
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.files.*;
|
import io.anuke.arc.files.*;
|
||||||
import io.anuke.arc.util.*;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.game.EventType.*;
|
import io.anuke.mindustry.game.EventType.*;
|
||||||
@@ -18,8 +19,35 @@ public class SWorkshop implements SteamUGCCallback{
|
|||||||
public final SteamUGC ugc = new SteamUGC(this);
|
public final SteamUGC ugc = new SteamUGC(this);
|
||||||
|
|
||||||
private Map lastMap;
|
private Map lastMap;
|
||||||
|
private Array<FileHandle> mapFiles;
|
||||||
|
|
||||||
|
public SWorkshop(){
|
||||||
|
int items = ugc.getNumSubscribedItems();
|
||||||
|
SteamPublishedFileID[] ids = new SteamPublishedFileID[items];
|
||||||
|
ItemInstallInfo info = new ItemInstallInfo();
|
||||||
|
ugc.getSubscribedItems(ids);
|
||||||
|
mapFiles = Array.with(ids).map(f -> {
|
||||||
|
ugc.getItemInstallInfo(f, info);
|
||||||
|
return new FileHandle(info.getFolder());
|
||||||
|
}).select(f -> f.list().length > 0).map(f -> f.list()[0]);
|
||||||
|
|
||||||
|
Log.info("Fetching {0} subscribed maps.", items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array<FileHandle> getMapFiles(){
|
||||||
|
return mapFiles;
|
||||||
|
}
|
||||||
|
|
||||||
public void publishMap(Map map){
|
public void publishMap(Map map){
|
||||||
|
if(map.tags.containsKey("steamid")){
|
||||||
|
Log.info("Map already published, redirecting to ID.");
|
||||||
|
SVars.net.friends.activateGameOverlayToWebPage("steam://url/CommunityFilePage/" + map.tags.get("steamid"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//update author name when publishing
|
||||||
|
map.tags.put("author", SVars.net.friends.getPersonaName());
|
||||||
|
|
||||||
FloatingDialog dialog = new FloatingDialog("$confirm");
|
FloatingDialog dialog = new FloatingDialog("$confirm");
|
||||||
dialog.setFillParent(false);
|
dialog.setFillParent(false);
|
||||||
dialog.cont.add("$map.publish.confirm").width(600f).wrap();
|
dialog.cont.add("$map.publish.confirm").width(600f).wrap();
|
||||||
@@ -122,6 +150,12 @@ public class SWorkshop implements SteamUGCCallback{
|
|||||||
if(needsToAcceptWLA){
|
if(needsToAcceptWLA){
|
||||||
SVars.net.friends.activateGameOverlayToWebPage("https://steamcommunity.com/sharedfiles/workshoplegalagreement");
|
SVars.net.friends.activateGameOverlayToWebPage("https://steamcommunity.com/sharedfiles/workshoplegalagreement");
|
||||||
}
|
}
|
||||||
|
ui.editor.editor.getTags().put("steamid", SteamNativeHandle.getNativeHandle(publishedFileID) + "");
|
||||||
|
try{
|
||||||
|
ui.editor.save();
|
||||||
|
}catch(Exception e){
|
||||||
|
Log.err(e);
|
||||||
|
}
|
||||||
Events.fire(new MapPublishEvent());
|
Events.fire(new MapPublishEvent());
|
||||||
}else{
|
}else{
|
||||||
ui.showErrorMessage(Core.bundle.format("map.publish.error ", result.name()));
|
ui.showErrorMessage(Core.bundle.format("map.publish.error ", result.name()));
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=1fda7fc4ed52e00fdbd6b9a5fab9af6add78dc63
|
archash=818e26ff093403031fcf31d3424dacb9c646d4b6
|
||||||
|
|||||||
Reference in New Issue
Block a user