From c9f0a5933921fa6d2f41a77df33d28cbcc24321a Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 8 Sep 2019 15:08:55 -0400 Subject: [PATCH] time for a crusade against dialogs --- core/assets-raw/sprites/ui/window-empty.9.png | Bin 168 -> 2315 bytes core/assets/bundles/bundle.properties | 7 +- core/assets/sprites/sprites.atlas | 2 +- .../io/anuke/mindustry/content/Bullets.java | 2 +- .../mindustry/content/StatusEffects.java | 4 +- core/src/io/anuke/mindustry/core/Control.java | 2 +- .../io/anuke/mindustry/core/NetClient.java | 6 +- .../src/io/anuke/mindustry/core/Platform.java | 19 +++-- .../src/io/anuke/mindustry/core/Renderer.java | 2 +- core/src/io/anuke/mindustry/core/UI.java | 45 +++++++--- core/src/io/anuke/mindustry/core/World.java | 8 +- .../mindustry/editor/MapEditorDialog.java | 19 ++--- .../anuke/mindustry/editor/MapSaveDialog.java | 2 +- .../mindustry/editor/WaveInfoDialog.java | 2 +- .../entities/effect/ItemTransfer.java | 2 +- .../src/io/anuke/mindustry/game/Gamemode.java | 1 - .../anuke/mindustry/input/InputHandler.java | 5 +- core/src/io/anuke/mindustry/maps/Maps.java | 6 +- core/src/io/anuke/mindustry/net/Net.java | 4 +- .../io/anuke/mindustry/plugin/Plugins.java | 1 - .../mindustry/ui/dialogs/AboutDialog.java | 2 +- .../mindustry/ui/dialogs/DeployDialog.java | 5 -- .../mindustry/ui/dialogs/DiscordDialog.java | 2 +- .../mindustry/ui/dialogs/FileChooser.java | 36 +++----- .../mindustry/ui/dialogs/HostDialog.java | 2 +- .../mindustry/ui/dialogs/LoadDialog.java | 10 +-- .../mindustry/ui/dialogs/MapsDialog.java | 6 +- .../mindustry/ui/dialogs/MinimapDialog.java | 4 - .../mindustry/ui/dialogs/PausedDialog.java | 9 +- .../mindustry/ui/dialogs/SaveDialog.java | 2 +- .../ui/dialogs/SettingsMenuDialog.java | 19 +++-- .../mindustry/ui/dialogs/TechTreeDialog.java | 5 -- .../mindustry/ui/dialogs/ZoneInfoDialog.java | 5 -- .../ui/fragments/BlockInventoryFragment.java | 2 +- .../world/blocks/distribution/ItemBridge.java | 79 +++++++++++++----- .../blocks/distribution/LiquidBridge.java | 55 +----------- .../distribution/LiquidExtendingBridge.java | 43 ++-------- .../mindustry/desktop/DesktopLauncher.java | 58 ++++++++----- .../mindustry/desktop/steam/SAchievement.java | 35 ++++++++ .../{SteamCoreNetImpl.java => SNet.java} | 8 +- .../anuke/mindustry/desktop/steam/SStat.java | 22 +++++ .../anuke/mindustry/desktop/steam/SStats.java | 67 +++++++++++++++ .../anuke/mindustry/desktop/steam/SVars.java | 9 ++ .../{WorkshopImpl.java => SWorkshop.java} | 13 ++- 44 files changed, 375 insertions(+), 262 deletions(-) create mode 100644 desktop/src/io/anuke/mindustry/desktop/steam/SAchievement.java rename desktop/src/io/anuke/mindustry/desktop/steam/{SteamCoreNetImpl.java => SNet.java} (98%) create mode 100644 desktop/src/io/anuke/mindustry/desktop/steam/SStat.java create mode 100644 desktop/src/io/anuke/mindustry/desktop/steam/SStats.java create mode 100644 desktop/src/io/anuke/mindustry/desktop/steam/SVars.java rename desktop/src/io/anuke/mindustry/desktop/steam/{WorkshopImpl.java => SWorkshop.java} (85%) diff --git a/core/assets-raw/sprites/ui/window-empty.9.png b/core/assets-raw/sprites/ui/window-empty.9.png index cbc2915f6051571fa98d7375f3501f8578d776d1..fe790ac23a0b00312ef037404a8532f0e2f5be78 100644 GIT binary patch delta 2304 zcmZ3%*ex_cxt=YlDkP#LD6w3jpeR2rGbdG{q_QAYA+;hije()!*4v24G97iEzv-fp zOimsLiX_gTRCxdV^uoQ1(|0~D-OC|h7-bh<8uwTGNs;`7N2>Mt=ZmKQTB;u3^LXr z897_6yW#(TRGzpWrM%wMzog!@$zAo8=oNR3-<-12mrhpCc;xj%+-7;LXpCf4lHK2Y_qsi zvoLr23|ooQ8*DginH?n!>h|4P{osC_f7dmmS;9YSKCwg{SfB8xNxE&$-HY4}^%r&( zX<6@o;`cb-o=u0@@n+^Zjt#%cLQED~Z?AZKCQfFTTm3WcrG=UfT?x?-cnk$Tc*qAbg|AvvyE?ok>A0@iGC_z7mR6D#g&dU#wF4f<@hjCM6$DE|rEpu}x3fe3)ZP&?@Fjf`K zlsL`Nb=u2Buq^WQ^EuZNUN^OJB&V;htYpv37dF?3StVK@H)YQ9PqPeCWwU1;u-$Ci zuT=e^+w4UV?@12H+iCAFv_GW7P`Y4AnO)(zA27TRL&p3-T?Rcwmmux1GIF^%2J+ZZAE3 z&XnPm`pNbAChng@wkkH9%w<}6^K#BbL(!vb+^8arnPPLHkLM$HRt4i)CN8IJ2Tdwv!?R7T+xXO+obP{ z?s&|UgbwVtn@n*zGhzApBnk=)kQnvH$VRU zq~O1*(dW0yW=~!mNn=?5_Okh+-;QtDx5{6s3xF}CO@Ca>DErY{EIDUBv-w7$dQaO` zMIuSL{8}rV82e-^0(LCaaCY2#qjcZZl_9q~9?84CHQXIlE!Em}w(YIsx7`bPi~mVq z+n0PMcCnI{i>mA`rlo5VugG1Ueo>j{x#Ckn>vzR-MeZBFu?v#fdg>XQtMig`zI#~@ z6xg_4>{f0FVV0UXB~p2>Q(qs zX|{r%^)_*9j$hYaeOq*!QKh+zNqXyd!8hWKY0H1NEbg6_Xzy~{>!F?8zn!fox2U%j zemuOagj=?zEIUc;{FdrlTu=Y8rJ8uHP7^fW#=yYXlIiSRAK>Zi46Aw=7%Jw}PPFwn z>>zVAK6t5CD7$rsMal|4F&9^vtz51v1hQJgWPSAhHmUJ?c6Bd)5LNIYdE=`GkJhYi zUai1U*RW%UmF6yw&i~$Ax=A(`?~d=T?%!SB5TI{-_LT&?$z8MH&K)yOuIpMDUZUJ# zkaj`c`1FkW$xBpfj$gNBs@dE9QRjbgeP5hux}k!C(0QZ7TRP1Wn4wARQ~*e}jM#l*bb;ry)Y(Z%x1`5k8M^18>s z-hLpXantqMdv~wiyS+cXe%9Z=3_%q|v&0Qb_!t-%*pj^6T^N2cEM_>K6lq(@z`(#+ z;1OBOz@VoL!i*J5?aLS#7}!fZeO=ifb8-lYSc@z_P|Lu;Fw4`$F(l&f+Z%g18w>>6 z9$FWQZ`>ft?JmI0zE!|{qrmYKEE|P`ViaeweB7%gaKd@tACcuk(<-M|EIpVYq3#*_ z+Q?f`a#e@S%Fa{z7cR}R`1bbWqtLrG3CmZ_lKXn^{}Uz4=M~Erpo7T3&6QWnY(F;L z+wGCRm>?2 zz4o2t{rPOy{KQ7NwpCd>Yy*tBk5}0T3Uab@p@1kyV~rQvUReE~qHLUDeCzR +details = Details... edit = Edit... editor.name = Name: editor.spawn = Spawn Unit editor.removeunit = Remove Unit editor.teams = Teams -editor.errorload = Error loading file:\n[accent]{0} -editor.errorsave = Error saving file:\n[accent]{0} +editor.errorload = Error loading file. +editor.errorsave = Error saving file. editor.errorimage = That's an image, not a map.\n\nIf you want to import a 3.5/build 40 map, use the 'Import Legacy Map' button in the editor. editor.errorlegacy = This map is too old, and uses a legacy map format that is no longer supported. editor.errornot = This is not a map file. diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 2b65c73d7f..e1e8ef5e28 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -15156,7 +15156,7 @@ window-empty rotate: false xy: 1308, 494 size: 27, 61 - split: 8, 8, 44, 11 + split: 2, 2, 2, 2 orig: 27, 61 offset: 0, 0 index: -1 diff --git a/core/src/io/anuke/mindustry/content/Bullets.java b/core/src/io/anuke/mindustry/content/Bullets.java index 11fc118902..a290d91b27 100644 --- a/core/src/io/anuke/mindustry/content/Bullets.java +++ b/core/src/io/anuke/mindustry/content/Bullets.java @@ -636,7 +636,7 @@ public class Bullets implements ContentList{ } }; - arc = new BulletType(0.001f, 25){ + arc = new BulletType(0.001f, 21){ { lifetime = 1; despawnEffect = Fx.none; diff --git a/core/src/io/anuke/mindustry/content/StatusEffects.java b/core/src/io/anuke/mindustry/content/StatusEffects.java index a869b0cbe9..6250336233 100644 --- a/core/src/io/anuke/mindustry/content/StatusEffects.java +++ b/core/src/io/anuke/mindustry/content/StatusEffects.java @@ -37,8 +37,8 @@ public class StatusEffects implements ContentList{ speedMultiplier = 0.9f; effect = Fx.wet; - trans(() -> shocked, ((unit, time, newTime, result) -> unit.damage(15f))); - opposite(() -> burning, () -> shocked); + trans(() -> shocked, ((unit, time, newTime, result) -> unit.damage(20f))); + opposite(() -> burning); }}; melting = new StatusEffect(){{ diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index e425f2778b..b9ac0c6e4d 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -114,7 +114,7 @@ public class Control implements ApplicationListener, Loadable{ net.host(port); player.isAdmin = true; }catch(IOException e){ - ui.showError(Core.bundle.format("server.error", Strings.parseException(e, true))); + ui.showException("$server.error", e); Core.app.post(() -> state.set(State.menu)); } } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index ee3d4e18a7..747d2ab2f4 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -87,7 +87,7 @@ public class NetClient implements ApplicationListener{ c.uuid = platform.getUUID(); if(c.uuid == null){ - ui.showError("$invalidid"); + ui.showErrorMessage("$invalidid"); ui.loadfrag.hide(); disconnectQuietly(); return; @@ -117,7 +117,7 @@ public class NetClient implements ApplicationListener{ ui.showSmall("$disconnect", "$disconnect.error"); } }else{ - ui.showError("$disconnect"); + ui.showErrorMessage("$disconnect"); } }); @@ -360,7 +360,7 @@ public class NetClient implements ApplicationListener{ Log.err("Failed to load data!"); ui.loadfrag.hide(); quiet = true; - ui.showError("$disconnect.data"); + ui.showErrorMessage("$disconnect.data"); net.disconnect(); timeoutTime = 0f; } diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java index 71ac3ba836..52e017268d 100644 --- a/core/src/io/anuke/mindustry/core/Platform.java +++ b/core/src/io/anuke/mindustry/core/Platform.java @@ -7,6 +7,7 @@ import io.anuke.arc.function.*; import io.anuke.arc.math.*; import io.anuke.arc.scene.ui.*; import io.anuke.arc.util.serialization.*; +import io.anuke.mindustry.maps.*; import io.anuke.mindustry.net.*; import io.anuke.mindustry.net.Net.*; import io.anuke.mindustry.ui.dialogs.*; @@ -15,16 +16,20 @@ import static io.anuke.mindustry.Vars.mobile; public interface Platform{ + /** Steam: Update lobby visibility.*/ + default void updateLobby(){} + + /** Steam: Show multiplayer friend invite dialog.*/ + default void inviteFriends(){} + + /** Steam: Share a map on the workshop.*/ + default void publishMap(Map map){} + /** Get the networking implementation.*/ default NetProvider getNet(){ return new ArcNetImpl(); } - /** Steam: Update lobby visibility.*/ - default void updateLobby(){ - - } - /** Add a text input dialog that should show up after the field is tapped. */ default void addDialog(TextField field){ addDialog(field, 16); @@ -95,11 +100,11 @@ public interface Platform{ default void hide(){ } - /** Forces the app into landscape mode. Currently Android only. */ + /** Forces the app into landscape mode.*/ default void beginForceLandscape(){ } - /** Stops forcing the app into landscape orientation. Currently Android only. */ + /** Stops forcing the app into landscape orientation.*/ default void endForceLandscape(){ } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index b23e46dc91..a8830fefe6 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -162,7 +162,7 @@ public class Renderer implements ApplicationListener{ e.printStackTrace(); settings.put("bloom", false); settings.save(); - ui.showError("$error.bloom"); + ui.showErrorMessage("$error.bloom"); } } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 7a3281d1e1..ca99eb151a 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -107,7 +107,7 @@ public class UI implements ApplicationListener, Loadable{ Core.settings.setErrorHandler(e -> { e.printStackTrace(); - Core.app.post(() -> showError("Failed to access local storage.\nSettings will not be saved.")); + Core.app.post(() -> showErrorMessage("Failed to access local storage.\nSettings will not be saved.")); }); ClickListener.clicked = () -> Sounds.press.play(); @@ -330,19 +330,42 @@ public class UI implements ApplicationListener, Loadable{ }}.show(); } - public void showError(String text){ + public void showErrorMessage(String text){ new Dialog("", "dialog"){{ - setFillParent(true); + setFillParent(false); + cont.margin(15f); cont.add("$error.title"); cont.row(); - cont.margin(15).pane(t -> { - Label l = t.add(text).pad(14f).get(); - l.setAlignment(Align.center, Align.left); - if(mobile){ - t.getCell(l).wrap().width(400f); - } - }); - buttons.addButton("$ok", this::hide).size(90, 50).pad(4); + cont.addImage("whiteui").fillX().pad(2).height(4f).color(Color.SCARLET); + cont.row(); + cont.add(text).pad(2f); + buttons.addButton("$ok", this::hide).size(120, 50).pad(4); + }}.show(); + } + + public void showException(Throwable t){ + showException("", t); + } + + public void showException(String text, Throwable exc){ + new Dialog("", "dialog"){{ + String message = Strings.getFinalMesage(exc); + + setFillParent(true); + cont.margin(15); + cont.add("$error.title").colspan(2); + cont.row(); + cont.addImage("whiteui").fillX().pad(2).colspan(2).height(4f).color(Color.SCARLET); + cont.row(); + cont.add((text.startsWith("$") ? Core.bundle.get(text.substring(1)) : text) + (message == null ? "" : "\n[lightgray](" + message + ")")).colspan(2).center().get().setAlignment(Align.center); + cont.row(); + + Collapser col = new Collapser(base -> base.pane(t -> t.margin(14f).add(Strings.parseException(exc, true)).color(Color.LIGHT_GRAY).left()), true); + + cont.addButton("$details", "toggle", col::toggle).size(180f, 50f).checked(b -> !col.isCollapsed()).fillX().right(); + cont.addButton("$ok", this::hide).size(100, 50).fillX().left(); + cont.row(); + cont.add(col).colspan(2).pad(2); }}.show(); } diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 5f47708369..26e0441e8a 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -215,7 +215,7 @@ public class World{ }catch(Exception e){ Log.err(e); if(!headless){ - ui.showError("$map.invalid"); + ui.showErrorMessage("$map.invalid"); Core.app.post(() -> state.set(State.menu)); invalidMap = true; } @@ -229,7 +229,7 @@ public class World{ if(!headless){ if(state.teams.get(defaultTeam).cores.size == 0 && !checkRules.pvp){ - ui.showError("$map.nospawn"); + ui.showErrorMessage("$map.nospawn"); invalidMap = true; }else if(checkRules.pvp){ //pvp maps need two cores to be valid int teams = 0; @@ -240,12 +240,12 @@ public class World{ } if(teams < 2){ invalidMap = true; - ui.showError("$map.nospawn.pvp"); + ui.showErrorMessage("$map.nospawn.pvp"); } }else if(checkRules.attackMode){ //attack maps need two cores to be valid invalidMap = state.teams.get(waveTeam).cores.isEmpty(); if(invalidMap){ - ui.showError("$map.nospawn.attack"); + ui.showErrorMessage("$map.nospawn.attack"); } } }else{ diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 4ec5d34037..86ae323fdd 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -109,7 +109,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ editor.beginEdit(pixmap); pixmap.dispose(); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); + ui.showException("$editor.errorload", e); Log.err(e); } }))) @@ -126,7 +126,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ } MapIO.writeMap(file, editor.createMap(file)); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, true))); + ui.showException("$editor.errorsave", e); Log.err(e); } }); @@ -138,7 +138,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ MapIO.writeMap(result, editor.createMap(result)); platform.shareFile(result); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, true))); + ui.showException("$editor.errorsave", e); Log.err(e); } }); @@ -173,7 +173,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ try{ editor.beginEdit(map); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); + ui.showException("$editor.errorload", e); Log.err(e); } })); @@ -227,11 +227,6 @@ public class MapEditorDialog extends Dialog implements Disposable{ shown(this::build); } - @Override - protected void drawBackground(float x, float y){ - drawDefaultBackground(x, y); - } - public void resumeEditing(){ state.set(State.menu); shownWithMap = true; @@ -280,7 +275,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ if(name.isEmpty()){ infoDialog.show(); - Core.app.post(() -> ui.showError("$editor.save.noname")); + Core.app.post(() -> ui.showErrorMessage("$editor.save.noname")); }else{ Map map = maps.all().find(m -> m.name().equals(name)); if(map != null && !map.custom){ @@ -297,7 +292,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ /** Called when a built-in map save is attempted.*/ protected void handleSaveBuiltin(Map map){ - ui.showError("$editor.save.overwrite"); + ui.showErrorMessage("$editor.save.overwrite"); } /** @@ -366,7 +361,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ show(); }catch(Exception e){ Log.err(e); - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); + ui.showException("$editor.errorload", e); } }); } diff --git a/core/src/io/anuke/mindustry/editor/MapSaveDialog.java b/core/src/io/anuke/mindustry/editor/MapSaveDialog.java index 18360445a1..d0f8ce77ae 100644 --- a/core/src/io/anuke/mindustry/editor/MapSaveDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapSaveDialog.java @@ -55,7 +55,7 @@ public class MapSaveDialog extends FloatingDialog{ if(!invalid()){ listener.accept(field.getText()); }else{ - ui.showError("$editor.failoverwrite"); + ui.showErrorMessage("$editor.failoverwrite"); } } diff --git a/core/src/io/anuke/mindustry/editor/WaveInfoDialog.java b/core/src/io/anuke/mindustry/editor/WaveInfoDialog.java index ad5dccb5d8..3785a2a968 100644 --- a/core/src/io/anuke/mindustry/editor/WaveInfoDialog.java +++ b/core/src/io/anuke/mindustry/editor/WaveInfoDialog.java @@ -61,7 +61,7 @@ public class WaveInfoDialog extends FloatingDialog{ groups = maps.readWaves(Core.app.getClipboardText()); buildGroups(); }catch(Exception e){ - ui.showError("$waves.invalid"); + ui.showErrorMessage("$waves.invalid"); } dialog.hide(); }).disabled(b -> Core.app.getClipboardText() == null || Core.app.getClipboardText().isEmpty()); diff --git a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java index 2cb7f567e1..aea1fe903f 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java +++ b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java @@ -17,7 +17,7 @@ import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; -import static io.anuke.mindustry.Vars.effectGroup; +import static io.anuke.mindustry.Vars.*; public class ItemTransfer extends TimedEntity implements DrawTrait{ private Vector2 from = new Vector2(); diff --git a/core/src/io/anuke/mindustry/game/Gamemode.java b/core/src/io/anuke/mindustry/game/Gamemode.java index 2dd0c31348..79fa228305 100644 --- a/core/src/io/anuke/mindustry/game/Gamemode.java +++ b/core/src/io/anuke/mindustry/game/Gamemode.java @@ -22,7 +22,6 @@ public enum Gamemode{ attack(rules -> { rules.unitDrops = true; rules.attackMode = true; - rules.waves = true; }, map -> map.teams.contains(waveTeam.ordinal())), pvp(rules -> { rules.pvp = true; diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index c64da21582..21b269207e 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -19,7 +19,6 @@ import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.gen.*; import io.anuke.mindustry.graphics.*; -import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.ui.fragments.*; @@ -60,11 +59,11 @@ public abstract class InputHandler implements InputProcessor{ @Remote(targets = Loc.both, forward = true, called = Loc.server) public static void transferInventory(Player player, Tile tile){ if(!player.timer.get(Player.timerTransfer, 40)) return; - if(net.server() && (player.item().amount <= 0 || player.isTransferring)){ + if(net.server() && (player.item().amount <= 0 || player.isTransferring|| !tile.interactable(player.getTeam()))){ throw new ValidateException(player, "Player cannot transfer an item."); } - if(player == null || tile.entity == null) return; + if(tile.entity == null) return; player.isTransferring = true; diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index d751f5fc7d..8852603efa 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -207,11 +207,11 @@ public class Maps{ Log.err(e); if("Outdated legacy map format".equals(e.getMessage())){ - ui.showError("$editor.errornot"); + ui.showErrorMessage("$editor.errornot"); }else if(e.getMessage() != null && e.getMessage().contains("Incorrect header!")){ - ui.showError("$editor.errorheader"); + ui.showErrorMessage("$editor.errorheader"); }else{ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); + ui.showException("$editor.errorload", e); } } } diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index b4d9ec152c..d4cb7dccd9 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -61,12 +61,12 @@ public class Net{ }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); + error = Core.bundle.get("error.any"); isError = true; } if(isError){ - ui.showError(Core.bundle.format("connectfail", error)); + ui.showException("$error.any", e); }else{ ui.showText("", Core.bundle.format("connectfail", error)); } diff --git a/core/src/io/anuke/mindustry/plugin/Plugins.java b/core/src/io/anuke/mindustry/plugin/Plugins.java index 803ed277c5..bd97013f6b 100644 --- a/core/src/io/anuke/mindustry/plugin/Plugins.java +++ b/core/src/io/anuke/mindustry/plugin/Plugins.java @@ -49,7 +49,6 @@ public class Plugins{ PluginMeta meta = JsonIO.read(PluginMeta.class, metaf.readString()); - URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, ClassLoader.getSystemClassLoader()); Class main = classLoader.loadClass(meta.main); return new LoadedPlugin(jar, zip, (Plugin)main.newInstance(), meta); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java index f77707749e..123e2a9d28 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java @@ -68,7 +68,7 @@ public class AboutDialog extends FloatingDialog{ table.addImageButton("icon-link", iconsize, () -> { if(!Core.net.openURI(link.link)){ - ui.showError("$linkfail"); + ui.showErrorMessage("$linkfail"); Core.app.setClipboardText(link.link); } }).size(h - 5, h); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java index a6bf5a1fdb..ae2976bb03 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java @@ -168,11 +168,6 @@ public class DeployDialog extends FloatingDialog{ return false; } - @Override - protected void drawBackground(float x, float y){ - drawDefaultBackground(x, y); - } - void buildButton(Zone zone, Button button){ button.setDisabled(() -> hidden(zone)); button.clicked(() -> info.show(zone)); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java index c7c343c6c6..cc7dfbfb2b 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java @@ -43,7 +43,7 @@ public class DiscordDialog extends Dialog{ }); buttons.addButton("$openlink", () -> { if(!Core.net.openURI(discordURL)){ - ui.showError("$linkfail"); + ui.showErrorMessage("$linkfail"); Core.app.setClipboardText(discordURL); } }); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java index 75d5a4c352..f33e924bab 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java @@ -1,19 +1,17 @@ package io.anuke.mindustry.ui.dialogs; -import io.anuke.arc.Core; -import io.anuke.arc.collection.Array; -import io.anuke.arc.files.FileHandle; -import io.anuke.arc.function.Consumer; -import io.anuke.arc.function.Predicate; -import io.anuke.arc.graphics.g2d.GlyphLayout; -import io.anuke.arc.scene.event.Touchable; +import io.anuke.arc.*; +import io.anuke.arc.collection.*; +import io.anuke.arc.files.*; +import io.anuke.arc.function.*; +import io.anuke.arc.graphics.g2d.*; +import io.anuke.arc.scene.event.*; import io.anuke.arc.scene.ui.*; -import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.arc.scene.ui.layout.UnitScl; +import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.util.*; -import io.anuke.arc.util.pooling.Pools; +import io.anuke.arc.util.pooling.*; -import java.util.Arrays; +import java.util.*; import static io.anuke.mindustry.Vars.*; @@ -31,13 +29,9 @@ public class FileChooser extends FloatingDialog{ private Consumer selectListener; private boolean open; - public static final Predicate pngFiles = str -> str.equals("png"); - public static final Predicate anyMapFiles = str -> str.equals(oldMapExtension) || str.equals(mapExtension); - public static final Predicate mapFiles = str -> str.equals(mapExtension); - public static final Predicate saveFiles = str -> str.equals(saveExtension); - public FileChooser(String title, Predicate filter, boolean open, Consumer result){ super(title); + setFillParent(true); this.open = open; this.filter = filter; this.selectListener = result; @@ -88,11 +82,7 @@ public class FileChooser extends FloatingDialog{ files.marginRight(10); files.marginLeft(3); - pane = new ScrollPane(files){ - public float getPrefHeight(){ - return Core.graphics.getHeight(); - } - }; + pane = new ScrollPane(files); pane.setOverscroll(false, false); pane.setFadeScrollBars(false); @@ -152,7 +142,7 @@ public class FileChooser extends FloatingDialog{ content.add(icontable).expandX().fillX(); content.row(); - content.center().add(pane).width(Core.graphics.isPortrait() ? Core.graphics.getWidth() / UnitScl.dp.scl(1) : Core.graphics.getWidth() / UnitScl.dp.scl(2)).colspan(3).grow(); + content.center().add(pane).colspan(3).grow(); content.row(); if(!open){ @@ -162,7 +152,7 @@ public class FileChooser extends FloatingDialog{ content.add(buttons).growX(); - cont.add(content); + cont.add(content).grow(); } private void updateFileFieldStatus(){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index 4ecd9e72c3..afaa94e617 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -66,7 +66,7 @@ public class HostDialog extends FloatingDialog{ net.host(Vars.port); player.isAdmin = true; }catch(IOException e){ - ui.showError(Core.bundle.format("server.error", Strings.parseException(e, true))); + ui.showException("$server.error", e); } ui.loadfrag.hide(); hide(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java index e9ae270de6..0b41389fce 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java @@ -94,7 +94,7 @@ public class LoadDialog extends FloatingDialog{ slot.exportFile(file); setup(); }catch(IOException e){ - ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, true))); + ui.showException("save.export.fail", e); } }); }else{ @@ -103,7 +103,7 @@ public class LoadDialog extends FloatingDialog{ slot.exportFile(file); platform.shareFile(file); }catch(Exception e){ - ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, true))); + ui.showException("save.export.fail", e); } } }).size(iconsize).right(); @@ -177,10 +177,10 @@ public class LoadDialog extends FloatingDialog{ setup(); }catch(IOException e){ e.printStackTrace(); - ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, true))); + ui.showException("save.import.fail", e); } }else{ - ui.showError("$save.import.invalid"); + ui.showErrorMessage("$save.import.invalid"); } }); }).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4); @@ -199,7 +199,7 @@ public class LoadDialog extends FloatingDialog{ Log.err(e); state.set(State.menu); logic.reset(); - ui.showError("$save.corrupted"); + ui.showErrorMessage("$save.corrupted"); } }); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java index 0ec1195aa4..6073130c89 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java @@ -65,7 +65,7 @@ public class MapsDialog extends FloatingDialog{ ui.loadAnd(() -> { maps.tryCatchMapError(() -> { if(MapIO.isImage(file)){ - ui.showError("$editor.errorimage"); + ui.showErrorMessage("$editor.errorimage"); return; } @@ -82,7 +82,7 @@ public class MapsDialog extends FloatingDialog{ //this will never actually get called, but it remains just in case if(name == null){ - ui.showError("$editor.errorname"); + ui.showErrorMessage("$editor.errorname"); return; } @@ -192,7 +192,7 @@ public class MapsDialog extends FloatingDialog{ hide(); }catch(Exception e){ e.printStackTrace(); - ui.showError("$error.mapnotfound"); + ui.showErrorMessage("$error.mapnotfound"); } }).fillX().height(54f).marginLeft(10); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java index 88002c6627..0d90c9e517 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java @@ -23,10 +23,6 @@ public class MinimapDialog extends FloatingDialog{ onResize(this::setup); } - public void drawBackground(float x, float y){ - drawDefaultBackground(x, y); - } - void setup(){ cont.clearChildren(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index 538c97fb4c..d3e138d436 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -1,9 +1,8 @@ package io.anuke.mindustry.ui.dialogs; -import io.anuke.arc.Core; -import io.anuke.arc.input.KeyCode; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.net.Net; +import io.anuke.arc.*; +import io.anuke.arc.input.*; +import io.anuke.mindustry.core.GameState.*; import static io.anuke.mindustry.Vars.*; @@ -123,7 +122,7 @@ public class PausedDialog extends FloatingDialog{ control.saves.getCurrent().save(); }catch(Throwable e){ e.printStackTrace(); - ui.showError("[accent]" + Core.bundle.get("savefail")); + ui.showException("[accent]" + Core.bundle.get("savefail"), e); } state.set(State.menu); logic.reset(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java index 1a3966b4d1..8f91999b6e 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java @@ -53,7 +53,7 @@ public class SaveDialog extends LoadDialog{ }catch(Throwable e){ e.printStackTrace(); - ui.showError("[accent]" + Core.bundle.get("savefail")); + ui.showException("[accent]" + Core.bundle.get("savefail"), e); } }); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 40db1ed6c0..abff329f77 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -15,7 +15,6 @@ import io.anuke.arc.util.*; import io.anuke.mindustry.core.GameState.*; import io.anuke.mindustry.gen.*; import io.anuke.mindustry.graphics.*; -import io.anuke.mindustry.net.Net; import static io.anuke.arc.Core.bundle; import static io.anuke.mindustry.Vars.*; @@ -108,7 +107,7 @@ public class SettingsMenuDialog extends SettingsDialog{ try{ data.exportData(file); }catch(Exception e){ - ui.showError(Strings.parseException(e, true)); + ui.showException(e); } platform.shareFile(file); }else{ @@ -118,7 +117,7 @@ public class SettingsMenuDialog extends SettingsDialog{ ui.showInfo("$data.exported"); }catch(Exception e){ e.printStackTrace(); - ui.showError(Strings.parseException(e, true)); + ui.showException(e); } }); } @@ -133,13 +132,13 @@ public class SettingsMenuDialog extends SettingsDialog{ data.importData(file); Core.app.exit(); }catch(IllegalArgumentException e){ - ui.showError("$data.invalid"); + ui.showErrorMessage("$data.invalid"); }catch(Exception e){ e.printStackTrace(); if(e.getMessage() == null || !e.getMessage().contains("too short")){ - ui.showError(Strings.parseException(e, true)); + ui.showException(e); }else{ - ui.showError("$data.invalid"); + ui.showErrorMessage("$data.invalid"); } } }))); @@ -215,9 +214,11 @@ public class SettingsMenuDialog extends SettingsDialog{ game.checkPref("savecreate", true); - game.checkPref("publichost", false, i -> { - platform.updateLobby(); - }); + if(steam){ + game.checkPref("publichost", false, i -> { + platform.updateLobby(); + }); + } game.pref(new Setting(){ @Override diff --git a/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java index 4af3810a1f..268c3aa8db 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java @@ -53,11 +53,6 @@ public class TechTreeDialog extends FloatingDialog{ }).size(210f, 64f); } - @Override - protected void drawBackground(float x, float y){ - drawDefaultBackground(x, y); - } - void treeLayout(){ TreeLayout layout = new TreeLayout(); layout.gapBetweenLevels = UnitScl.dp.scl(60f); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java index 55de763cc2..3c5f9a6d18 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java @@ -24,11 +24,6 @@ public class ZoneInfoDialog extends FloatingDialog{ addCloseButton(); } - @Override - protected void drawBackground(float x, float y){ - drawDefaultBackground(x, y); - } - public void show(Zone zone){ setup(zone); show(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java index a1853ee300..d4bdd0c0cd 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java @@ -40,7 +40,7 @@ public class BlockInventoryFragment extends Fragment{ @Remote(called = Loc.server, targets = Loc.both, forward = true) public static void requestItem(Player player, Tile tile, Item item, int amount){ - if(player == null || tile == null || !player.timer.get(Player.timerTransfer, 20)) return; + if(player == null || tile == null || !player.timer.get(Player.timerTransfer, 20) || !tile.interactable(player.getTeam())) return; int removed = tile.block().removeStack(tile, item, amount); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index f5a86d0d1d..30047db909 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -1,29 +1,24 @@ package io.anuke.mindustry.world.blocks.distribution; -import io.anuke.annotations.Annotations.Loc; -import io.anuke.annotations.Annotations.Remote; -import io.anuke.arc.Core; -import io.anuke.arc.collection.IntArray; -import io.anuke.arc.collection.IntSet; -import io.anuke.arc.collection.IntSet.IntSetIterator; -import io.anuke.arc.graphics.Color; +import io.anuke.annotations.Annotations.*; +import io.anuke.arc.*; +import io.anuke.arc.collection.*; +import io.anuke.arc.collection.IntSet.*; +import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.math.geom.Geometry; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.type.Player; -import io.anuke.mindustry.entities.type.TileEntity; -import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Pal; -import io.anuke.mindustry.type.Item; +import io.anuke.arc.math.*; +import io.anuke.arc.math.geom.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.entities.type.*; +import io.anuke.mindustry.gen.*; +import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; -import io.anuke.mindustry.world.meta.BlockGroup; +import io.anuke.mindustry.world.meta.*; import java.io.*; -import static io.anuke.mindustry.Vars.tilesize; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; public class ItemBridge extends Block{ protected int timerTransport = timers++; @@ -270,6 +265,52 @@ public class ItemBridge extends Block{ return tile.entity.items.total() < itemCapacity; } + + @Override + public boolean canDumpLiquid(Tile tile, Tile to, Liquid liquid){ + ItemBridgeEntity entity = tile.entity(); + + Tile other = world.tile(entity.link); + if(!linkValid(tile, other)){ + Tile edge = Edges.getFacingEdge(to, tile); + int i = tile.absoluteRelativeTo(edge.x, edge.y); + + IntSetIterator it = entity.incoming.iterator(); + + while(it.hasNext){ + int v = it.next(); + if(tile.absoluteRelativeTo(Pos.x(v), Pos.y(v)) == i){ + return false; + } + } + return true; + } + + int rel = tile.absoluteRelativeTo(other.x, other.y); + int rel2 = tile.relativeTo(to.x, to.y); + + return rel != rel2; + } + + @Override + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + if(tile.getTeam() != source.getTeam()) return false; + + ItemBridgeEntity entity = tile.entity(); + Tile other = world.tile(entity.link); + + if(linkValid(tile, other)){ + int rel = tile.absoluteRelativeTo(other.x, other.y); + int rel2 = tile.relativeTo(source.x, source.y); + + if(rel == rel2) return false; + }else if(!(source.block() instanceof ItemBridge && source.entity().link == tile.pos())){ + return false; + } + + return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f); + } + @Override public boolean canDump(Tile tile, Tile to, Item item){ ItemBridgeEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java index cf3c96cdab..d282321114 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java @@ -1,12 +1,10 @@ package io.anuke.mindustry.world.blocks.distribution; -import io.anuke.arc.collection.IntSet.IntSetIterator; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Liquid; +import io.anuke.arc.math.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; -import io.anuke.mindustry.world.meta.BlockGroup; +import io.anuke.mindustry.world.meta.*; import static io.anuke.mindustry.Vars.world; @@ -56,49 +54,4 @@ public class LiquidBridge extends ItemBridge{ public boolean acceptItem(Item item, Tile tile, Tile source){ return false; } - - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - if(tile.getTeam() != source.getTeam()) return false; - - ItemBridgeEntity entity = tile.entity(); - Tile other = world.tile(entity.link); - - if(linkValid(tile, other)){ - int rel = tile.absoluteRelativeTo(other.x, other.y); - int rel2 = tile.relativeTo(source.x, source.y); - - if(rel == rel2) return false; - }else if(!(source.block() instanceof ItemBridge && source.entity().link == tile.pos())){ - return false; - } - - return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f); - } - - @Override - public boolean canDumpLiquid(Tile tile, Tile to, Liquid liquid){ - ItemBridgeEntity entity = tile.entity(); - - Tile other = world.tile(entity.link); - if(!linkValid(tile, other)){ - Tile edge = Edges.getFacingEdge(to, tile); - int i = tile.absoluteRelativeTo(edge.x, edge.y); - - IntSetIterator it = entity.incoming.iterator(); - - while(it.hasNext){ - int v = it.next(); - if(tile.absoluteRelativeTo(Pos.x(v), Pos.y(v)) == i){ - return false; - } - } - return true; - } - - int rel = tile.absoluteRelativeTo(other.x, other.y); - int rel2 = tile.relativeTo(to.x, to.y); - - return rel != rel2; - } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java index 9d75b6f849..53abc6d128 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java @@ -1,13 +1,10 @@ package io.anuke.mindustry.world.blocks.distribution; -import io.anuke.arc.collection.IntSet.IntSetIterator; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.world.Pos; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.meta.BlockGroup; +import io.anuke.arc.math.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.type.*; +import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.meta.*; import static io.anuke.mindustry.Vars.world; @@ -53,34 +50,4 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{ public boolean acceptItem(Item item, Tile tile, Tile source){ return false; } - - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f); - } - - @Override - public boolean canDumpLiquid(Tile tile, Tile to, Liquid liquid){ - ItemBridgeEntity entity = tile.entity(); - - Tile other = world.tile(entity.link); - if(!linkValid(tile, other)){ - int i = tile.absoluteRelativeTo(to.x, to.y); - - IntSetIterator it = entity.incoming.iterator(); - - while(it.hasNext){ - int v = it.next(); - if(tile.absoluteRelativeTo(Pos.x(v), Pos.y(v)) == i){ - return false; - } - } - return true; - } - - int rel = tile.absoluteRelativeTo(other.x, other.y); - int rel2 = tile.relativeTo(to.x, to.y); - - return rel != rel2; - } } diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index 4e561de942..98b4f0b59f 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -19,6 +19,7 @@ import io.anuke.mindustry.core.GameState.*; import io.anuke.mindustry.desktop.steam.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.Version; +import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.net.*; import io.anuke.mindustry.net.Net.*; @@ -29,10 +30,9 @@ import static io.anuke.mindustry.Vars.*; public class DesktopLauncher extends ClientLauncher{ - private final static String applicationId = "610508934456934412"; + public final static String discordID = "610508934456934412"; boolean useDiscord = OS.is64Bit, showConsole = true; - SteamCoreNetImpl steamCore; public static void main(String[] arg){ try{ @@ -58,7 +58,7 @@ public class DesktopLauncher extends ClientLauncher{ if(useDiscord){ try{ DiscordEventHandlers handlers = new DiscordEventHandlers(); - DiscordRPC.INSTANCE.Discord_Initialize(applicationId, handlers, true, "1127400"); + DiscordRPC.INSTANCE.Discord_Initialize(discordID, handlers, true, "1127400"); Log.info("Initialized Discord rich presence."); Runtime.getRuntime().addShutdownHook(new Thread(DiscordRPC.INSTANCE::Discord_Shutdown)); @@ -111,21 +111,8 @@ public class DesktopLauncher extends ClientLauncher{ Log.err("Steam client not running."); }else{ Vars.steam = true; - steamCore = new SteamCoreNetImpl(new ArcNetImpl()); - Events.on(ClientLoadEvent.class, event -> { - Core.settings.defaults("name", steamCore.friends.getPersonaName()); - //update callbacks - Core.app.addListener(new ApplicationListener(){ - @Override - public void update(){ - if(SteamAPI.isSteamRunning()){ - SteamAPI.runCallbacks(); - } - } - }); - }); - //steam shutdown hook - Runtime.getRuntime().addShutdownHook(new Thread(SteamAPI::shutdown)); + initSteam(); + } }catch(Exception e){ Log.err("Failed to load Steam native libraries."); @@ -134,6 +121,27 @@ public class DesktopLauncher extends ClientLauncher{ } } + void initSteam(){ + SVars.net = new SNet(new ArcNetImpl()); + SVars.stats = new SStats(); + SVars.workshop = new SWorkshop(); + + Events.on(ClientLoadEvent.class, event -> { + Core.settings.defaults("name", SVars.net.friends.getPersonaName()); + //update callbacks + Core.app.addListener(new ApplicationListener(){ + @Override + public void update(){ + if(SteamAPI.isSteamRunning()){ + SteamAPI.runCallbacks(); + } + } + }); + }); + //steam shutdown hook + Runtime.getRuntime().addShutdownHook(new Thread(SteamAPI::shutdown)); + } + static void handleCrash(Throwable e){ Consumer dialog = Runnable::run; boolean badGPU = false; @@ -159,12 +167,22 @@ public class DesktopLauncher extends ClientLauncher{ @Override public NetProvider getNet(){ - return steam ? steamCore : new ArcNetImpl(); + return steam ? SVars.net : new ArcNetImpl(); + } + + @Override + public void publishMap(Map map){ + SVars.workshop.publishMap(map); + } + + @Override + public void inviteFriends(){ + SVars.net.showFriendInvites(); } @Override public void updateLobby(){ - steamCore.updateLobby(); + SVars.net.updateLobby(); } @Override diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SAchievement.java b/desktop/src/io/anuke/mindustry/desktop/steam/SAchievement.java new file mode 100644 index 0000000000..113ddddb8b --- /dev/null +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SAchievement.java @@ -0,0 +1,35 @@ +package io.anuke.mindustry.desktop.steam; + +import io.anuke.arc.function.*; + +public enum SAchievement{ + ; + + private final BooleanProvider completed; + + public static final SAchievement[] all = values(); + + SAchievement(BooleanProvider completed){ + this.completed = completed; + } + + /** Creates an achievement that is triggered when this stat reaches a number.*/ + SAchievement(SStat stat, int required){ + this(() -> stat.get() >= required); + } + + public void checkCompletion(){ + if(!achieved() && conditionsMet()){ + SVars.stats.stats.setAchievement(name()); + SVars.stats.stats.storeStats(); + } + } + + public boolean achieved(){ + return SVars.stats.stats.isAchieved(name(), false); + } + + public boolean conditionsMet(){ + return completed.get(); + } +} diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SteamCoreNetImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/SNet.java similarity index 98% rename from desktop/src/io/anuke/mindustry/desktop/steam/SteamCoreNetImpl.java rename to desktop/src/io/anuke/mindustry/desktop/steam/SNet.java index 05453c7635..a713640083 100644 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SteamCoreNetImpl.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SNet.java @@ -23,7 +23,7 @@ import java.util.concurrent.*; import static io.anuke.mindustry.Vars.*; -public class SteamCoreNetImpl implements SteamNetworkingCallback, SteamMatchmakingCallback, SteamFriendsCallback, NetProvider{ +public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback, SteamFriendsCallback, NetProvider{ public final SteamNetworking snet = new SteamNetworking(this); public final SteamMatchmaking smat = new SteamMatchmaking(this); public final SteamFriends friends = new SteamFriends(this); @@ -43,7 +43,7 @@ public class SteamCoreNetImpl implements SteamNetworkingCallback, SteamMatchmaki Consumer lobbyCallback; Runnable lobbyDoneCallback, joinCallback; - public SteamCoreNetImpl(NetProvider provider){ + public SNet(NetProvider provider){ this.provider = provider; Events.on(ClientLoadEvent.class, e -> Core.app.addListener(new ApplicationListener(){ @@ -324,7 +324,11 @@ public class SteamCoreNetImpl implements SteamNetworkingCallback, SteamMatchmaki smat.setLobbyData(steamID, "versionType", Version.type); smat.setLobbyData(steamID, "wave", state.wave + ""); smat.setLobbyData(steamID, "gamemode", Gamemode.bestFit(state.rules) + ""); + } + } + public void showFriendInvites(){ + if(currentLobby != null){ friends.activateGameOverlayInviteDialog(currentLobby); Log.info("Activating overlay dialog"); } diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SStat.java b/desktop/src/io/anuke/mindustry/desktop/steam/SStat.java new file mode 100644 index 0000000000..692350b26e --- /dev/null +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SStat.java @@ -0,0 +1,22 @@ +package io.anuke.mindustry.desktop.steam; + +public enum SStat{ + unitsDestroyed; + + public int get(){ + return SVars.stats.stats.getStatI(name(), 0); + } + + public void add(int amount){ + SVars.stats.stats.setStatI(name(), get() + amount); + SVars.stats.onUpdate(); + + for(SAchievement a : SAchievement.all){ + a.checkCompletion(); + } + } + + public void add(){ + add(1); + } +} diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SStats.java b/desktop/src/io/anuke/mindustry/desktop/steam/SStats.java new file mode 100644 index 0000000000..02ce2af331 --- /dev/null +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SStats.java @@ -0,0 +1,67 @@ +package io.anuke.mindustry.desktop.steam; + +import com.codedisaster.steamworks.*; +import io.anuke.arc.util.*; + +public class SStats implements SteamUserStatsCallback{ + public final SteamUserStats stats = new SteamUserStats(this); + + //todo store stats periodically + private boolean updated = false; + + public SStats(){ + stats.requestCurrentStats(); + } + + public void onUpdate(){ + this.updated = true; + } + + private void registerEvents(){ + + } + + @Override + public void onUserStatsReceived(long gameID, SteamID steamID, SteamResult result){ + if(result == SteamResult.OK){ + registerEvents(); + }else{ + Log.err("Failed to recieve steam stats: {0}", result); + } + } + + @Override + public void onUserStatsStored(long l, SteamResult steamResult){ + + } + + @Override + public void onUserStatsUnloaded(SteamID steamID){ + + } + + @Override + public void onUserAchievementStored(long l, boolean b, String s, int i, int i1){ + + } + + @Override + public void onLeaderboardFindResult(SteamLeaderboardHandle steamLeaderboardHandle, boolean b){ + + } + + @Override + public void onLeaderboardScoresDownloaded(SteamLeaderboardHandle steamLeaderboardHandle, SteamLeaderboardEntriesHandle steamLeaderboardEntriesHandle, int i){ + + } + + @Override + public void onLeaderboardScoreUploaded(boolean b, SteamLeaderboardHandle steamLeaderboardHandle, int i, boolean b1, int i1, int i2){ + + } + + @Override + public void onGlobalStatsReceived(long l, SteamResult steamResult){ + + } +} diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SVars.java b/desktop/src/io/anuke/mindustry/desktop/steam/SVars.java new file mode 100644 index 0000000000..a8b8eb8f2a --- /dev/null +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SVars.java @@ -0,0 +1,9 @@ +package io.anuke.mindustry.desktop.steam; + +public class SVars{ + public final static int steamID = 1127400; + + public static SNet net; + public static SStats stats; + public static SWorkshop workshop; +} diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/WorkshopImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java similarity index 85% rename from desktop/src/io/anuke/mindustry/desktop/steam/WorkshopImpl.java rename to desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java index e106cf97ad..cb8adb38ed 100644 --- a/desktop/src/io/anuke/mindustry/desktop/steam/WorkshopImpl.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java @@ -4,16 +4,15 @@ import com.codedisaster.steamworks.*; import com.codedisaster.steamworks.SteamRemoteStorage.*; import io.anuke.mindustry.maps.*; -public class WorkshopImpl implements SteamUGCCallback{ - private SteamUGC ugc = new SteamUGC(this); +public class SWorkshop implements SteamUGCCallback{ + public final SteamUGC ugc = new SteamUGC(this); public void publishMap(Map map){ - ugc.createItem(1127400, WorkshopFileType.GameManagedItem); + ugc.createItem(SVars.steamID, WorkshopFileType.GameManagedItem); } @Override public void onUGCQueryCompleted(SteamUGCQuery query, int numResultsReturned, int totalMatchingResults, boolean isCachedData, SteamResult result){ - //ugc.submitItemUpdate() } @@ -35,6 +34,12 @@ public class WorkshopImpl implements SteamUGCCallback{ @Override public void onCreateItem(SteamPublishedFileID publishedFileID, boolean needsToAcceptWLA, SteamResult result){ //TODO + if(result == SteamResult.OK){ + + }else{ + //TODO show "failed to create" dialog + //ui.showError(""); + } } @Override