diff --git a/core/assets/scripts/base.js b/core/assets/scripts/base.js index a83a66c728..6ce3070968 100755 --- a/core/assets/scripts/base.js +++ b/core/assets/scripts/base.js @@ -16,5 +16,5 @@ const boolp = method => new Boolp(){get: method} const cons = method => new Cons(){get: method} const prov = method => new Prov(){get: method} const newEffect = (lifetime, renderer) => new Effects.Effect(lifetime, new Effects.EffectRenderer({render: renderer})) -Call = Packages.io.anuke.mindustry.gen.Call +Call = Packages.mindustry.gen.Call const Calls = Call //backwards compat \ No newline at end of file diff --git a/core/assets/scripts/global.js b/core/assets/scripts/global.js index 9ba7fc5e4c..22d746b420 100755 --- a/core/assets/scripts/global.js +++ b/core/assets/scripts/global.js @@ -18,7 +18,7 @@ const boolp = method => new Boolp(){get: method} const cons = method => new Cons(){get: method} const prov = method => new Prov(){get: method} const newEffect = (lifetime, renderer) => new Effects.Effect(lifetime, new Effects.EffectRenderer({render: renderer})) -Call = Packages.io.anuke.mindustry.gen.Call +Call = Packages.mindustry.gen.Call const Calls = Call //backwards compat importPackage(Packages.arc) importPackage(Packages.arc.func) diff --git a/core/src/mindustry/core/UI.java b/core/src/mindustry/core/UI.java index 1ce41f6e24..58cb23d802 100644 --- a/core/src/mindustry/core/UI.java +++ b/core/src/mindustry/core/UI.java @@ -43,6 +43,7 @@ public class UI implements ApplicationListener, Loadable{ public HudFragment hudfrag; public ChatFragment chatfrag; public ScriptConsoleFragment scriptfrag; + public MinimapFragment minimapfrag; public PlayerListFragment listfrag; public LoadingFragment loadfrag; @@ -68,7 +69,7 @@ public class UI implements ApplicationListener, Loadable{ public ContentInfoDialog content; public DeployDialog deploy; public TechTreeDialog tech; - public MinimapDialog minimap; + //public MinimapDialog minimap; public SchematicsDialog schematics; public ModsDialog mods; public ColorPicker picker; @@ -210,6 +211,7 @@ public class UI implements ApplicationListener, Loadable{ menufrag = new MenuFragment(); hudfrag = new HudFragment(); chatfrag = new ChatFragment(); + minimapfrag = new MinimapFragment(); listfrag = new PlayerListFragment(); loadfrag = new LoadingFragment(); scriptfrag = new ScriptConsoleFragment(); @@ -235,7 +237,6 @@ public class UI implements ApplicationListener, Loadable{ content = new ContentInfoDialog(); deploy = new DeployDialog(); tech = new TechTreeDialog(); - minimap = new MinimapDialog(); mods = new ModsDialog(); schematics = new SchematicsDialog(); @@ -254,6 +255,7 @@ public class UI implements ApplicationListener, Loadable{ hudfrag.build(hudGroup); menufrag.build(menuGroup); chatfrag.container().build(hudGroup); + minimapfrag.build(hudGroup); listfrag.build(hudGroup); scriptfrag.container().build(hudGroup); loadfrag.build(group); diff --git a/core/src/mindustry/entities/type/Player.java b/core/src/mindustry/entities/type/Player.java index af5165fc60..8366c01cc6 100644 --- a/core/src/mindustry/entities/type/Player.java +++ b/core/src/mindustry/entities/type/Player.java @@ -568,6 +568,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ protected void updateKeyboard(){ Tile tile = world.tileWorld(x, y); + boolean canMove = !Core.scene.hasKeyboard() || ui.minimapfrag.shown(); isBoosting = Core.input.keyDown(Binding.dash) && !mech.flying; @@ -594,8 +595,8 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ } if(Core.input.keyDown(Binding.mouse_move)){ - movement.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2) * 0.005f, -1, 1) * speed; - movement.y += Mathf.clamp((Core.input.mouseY() - Core.graphics.getHeight() / 2) * 0.005f, -1, 1) * speed; + movement.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2f) * 0.005f, -1, 1) * speed; + movement.y += Mathf.clamp((Core.input.mouseY() - Core.graphics.getHeight() / 2f) * 0.005f, -1, 1) * speed; } Vec2 vec = Core.input.mouseWorld(control.input.getMouseX(), control.input.getMouseY()); @@ -605,7 +606,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ movement.limit(speed).scl(Time.delta()); - if(!Core.scene.hasKeyboard()){ + if(canMove){ velocity.add(movement.x, movement.y); }else{ isShooting = false; @@ -614,7 +615,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ updateVelocityStatus(); moved = dst(prex, prey) > 0.001f; - if(!Core.scene.hasKeyboard()){ + if(canMove){ float baseLerp = mech.getRotationAlpha(this); if(!isShooting() || !mech.turnCursor){ if(!movement.isZero()){ diff --git a/core/src/mindustry/game/Team.java b/core/src/mindustry/game/Team.java index a6e9d1e20a..e6c05eb6e0 100644 --- a/core/src/mindustry/game/Team.java +++ b/core/src/mindustry/game/Team.java @@ -30,7 +30,7 @@ public class Team implements Comparable{ blue = new Team(5, "blue", Color.royal.cpy()); static{ - Mathf.random.setSeed(7); + Mathf.random.setSeed(8); //create the whole 256 placeholder teams for(int i = 6; i < all.length; i++){ new Team(i, "team#" + i, Color.HSVtoRGB(360f * Mathf.random(), 100f * Mathf.random(0.6f, 1f), 100f * Mathf.random(0.8f, 1f), 1f)); diff --git a/core/src/mindustry/graphics/MinimapRenderer.java b/core/src/mindustry/graphics/MinimapRenderer.java index 5d8af45304..36b8707490 100644 --- a/core/src/mindustry/graphics/MinimapRenderer.java +++ b/core/src/mindustry/graphics/MinimapRenderer.java @@ -9,6 +9,7 @@ import arc.math.*; import arc.math.geom.*; import arc.scene.ui.layout.*; import arc.util.*; +import arc.util.ArcAnnotate.*; import arc.util.pooling.*; import mindustry.entities.*; import mindustry.entities.type.*; @@ -42,7 +43,7 @@ public class MinimapRenderer implements Disposable{ return pixmap; } - public Texture getTexture(){ + public @Nullable Texture getTexture(){ return texture; } @@ -70,8 +71,13 @@ public class MinimapRenderer implements Disposable{ region = new TextureRegion(texture); } - public void drawEntities(float x, float y, float w, float h, boolean withLabels){ - updateUnitArray(); + public void drawEntities(float x, float y, float w, float h, float scaling, boolean withLabels){ + if(!withLabels){ + updateUnitArray(); + }else{ + units.clear(); + Units.all(units::add); + } float sz = baseSize * zoom; float dx = (Core.camera.position.x / tilesize); @@ -83,8 +89,8 @@ public class MinimapRenderer implements Disposable{ for(Unit unit : units){ if(unit.isDead()) continue; - float rx = (unit.x - rect.x) / rect.width * w; - float ry = (unit.y - rect.y) / rect.width * h; + float rx = !withLabels ? (unit.x - rect.x) / rect.width * w : unit.x / (world.width() * tilesize) * w; + float ry = !withLabels ? (unit.y - rect.y) / rect.width * h : unit.y / (world.height() * tilesize) * h; if(withLabels && unit instanceof Player){ Player pl = (Player) unit; @@ -94,18 +100,19 @@ public class MinimapRenderer implements Disposable{ } } - Draw.color(unit.getTeam().color); - Fill.rect(x + rx, y + ry, Scl.scl(baseSize / 2f), Scl.scl(baseSize / 2f)); + Draw.mixcol(unit.getTeam().color, 1f); + float scale = Scl.scl(1f) / 2f * scaling; + Draw.rect(unit.getIconRegion(), x + rx, y + ry, unit.getIconRegion().getWidth() * scale, unit.getIconRegion().getHeight() * scale, unit.rotation - 90); } - Draw.color(); + Draw.reset(); } public void drawEntities(float x, float y, float w, float h){ - drawEntities(x, y, w, h, true); + drawEntities(x, y, w, h, 1f, true); } - public TextureRegion getRegion(){ + public @Nullable TextureRegion getRegion(){ if(texture == null) return null; float sz = Mathf.clamp(baseSize * zoom, baseSize, Math.min(world.width(), world.height())); diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index c0cd917952..da8a808962 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -96,7 +96,7 @@ public class OverlayRenderer{ if(buildFadeTime > 0.005f){ state.teams.eachEnemyCore(player.getTeam(), core -> { float dst = core.dst(player); - if(dst < state.rules.enemyCoreBuildRadius * 1.5f){ + if(dst < state.rules.enemyCoreBuildRadius * 2.2f){ Draw.color(Color.darkGray); Lines.circle(core.x, core.y - 2, state.rules.enemyCoreBuildRadius); Draw.color(Pal.accent, core.getTeam().color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f)); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index e2efcac160..c485b49ff2 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -140,18 +140,19 @@ public class DesktopInput extends InputHandler{ //move camera around float camSpeed = !Core.input.keyDown(Binding.dash) ? 3f : 8f; Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed)); + + if(Core.input.keyDown(Binding.mouse_move)){ + Core.camera.position.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2f) * 0.005f, -1, 1) * camSpeed; + Core.camera.position.y += Mathf.clamp((Core.input.mouseY() - Core.graphics.getHeight() / 2f) * 0.005f, -1, 1) * camSpeed; + } } if(Core.input.keyRelease(Binding.select)){ player.isShooting = false; } - if(!state.is(State.menu) && Core.input.keyTap(Binding.minimap) && (scene.getKeyboardFocus() == ui.minimap || !scene.hasDialog()) && !Core.scene.hasKeyboard() && !(scene.getKeyboardFocus() instanceof TextField)){ - if(!ui.minimap.isShown()){ - ui.minimap.show(); - }else{ - ui.minimap.hide(); - } + if(!state.is(State.menu) && Core.input.keyTap(Binding.minimap) && !scene.hasDialog() && !(scene.getKeyboardFocus() instanceof TextField)){ + ui.minimapfrag.toggle(); } if(state.is(State.menu) || Core.scene.hasDialog()) return; diff --git a/core/src/mindustry/ui/Minimap.java b/core/src/mindustry/ui/Minimap.java index b724f4dd39..bbb81a7f00 100644 --- a/core/src/mindustry/ui/Minimap.java +++ b/core/src/mindustry/ui/Minimap.java @@ -36,7 +36,7 @@ public class Minimap extends Table{ Draw.rect(renderer.minimap.getRegion(), x + width / 2f, y + height / 2f, width, height); if(renderer.minimap.getTexture() != null){ - renderer.minimap.drawEntities(x, y, width, height, false); + renderer.minimap.drawEntities(x, y, width, height, 0.75f, false); } } }).size(140f); @@ -83,7 +83,7 @@ public class Minimap extends Table{ @Override public void clicked(InputEvent event, float x, float y){ - ui.minimap.show(); + ui.minimapfrag.toggle(); } }); diff --git a/core/src/mindustry/ui/fragments/MinimapFragment.java b/core/src/mindustry/ui/fragments/MinimapFragment.java new file mode 100644 index 0000000000..4a938b341a --- /dev/null +++ b/core/src/mindustry/ui/fragments/MinimapFragment.java @@ -0,0 +1,115 @@ +package mindustry.ui.fragments; + +import arc.*; +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.input.*; +import arc.math.*; +import arc.scene.*; +import arc.scene.event.*; +import arc.scene.ui.layout.*; +import mindustry.gen.*; +import mindustry.ui.*; + +import static mindustry.Vars.*; + +public class MinimapFragment extends Fragment{ + private boolean shown; + private float panx, pany, zoom = 1f, lastZoom = -1; + private float baseSize = Scl.scl(1000f); + private Element elem; + + @Override + public void build(Group parent){ + elem = parent.fill((x, y, w, h) -> { + w = Core.graphics.getWidth(); + h = Core.graphics.getHeight(); + float size = baseSize * zoom; + + Draw.color(Color.black); + Fill.crect(x, y, w, h); + + if(renderer.minimap.getTexture() != null){ + Draw.color(); + TextureRegion reg = Draw.wrap(renderer.minimap.getTexture()); + Draw.rect(reg, w/2f + panx*zoom, h/2f + pany*zoom, size, size); + renderer.minimap.drawEntities(w/2f + panx*zoom - size/2f, h/2f + pany*zoom - size/2f, size, size, zoom, true); + } + + Draw.reset(); + }); + + elem.visible(() -> shown); + elem.update(() -> { + elem.requestKeyboard(); + elem.requestScroll(); + elem.setFillParent(true); + elem.setBounds(0, 0, Core.graphics.getWidth(), Core.graphics.getHeight()); + + if(Core.input.keyTap(KeyCode.ESCAPE) || Core.input.keyTap(KeyCode.BACK)){ + shown = false; + } + }); + elem.touchable(Touchable.enabled); + + elem.addListener(new ElementGestureListener(){ + + @Override + public void zoom(InputEvent event, float initialDistance, float distance){ + if(lastZoom < 0){ + lastZoom = zoom; + } + + zoom = Mathf.clamp(distance / initialDistance * lastZoom, 0.25f, 10f); + } + + @Override + public void pan(InputEvent event, float x, float y, float deltaX, float deltaY){ + panx += deltaX / zoom; + pany += deltaY / zoom; + } + + @Override + public void touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ + super.touchDown(event, x, y, pointer, button); + } + + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, KeyCode button){ + lastZoom = zoom; + } + }); + + elem.addListener(new InputListener(){ + + @Override + public boolean scrolled(InputEvent event, float x, float y, float amountX, float amountY){ + zoom = Mathf.clamp(zoom - amountY / 10f * zoom, 0.25f, 10f); + return true; + } + }); + + parent.fill(t -> { + t.setFillParent(true); + t.visible(() -> shown); + t.update(() -> t.setBounds(0, 0, Core.graphics.getWidth(), Core.graphics.getHeight())); + + t.add("$minimap").style(Styles.outlineLabel).pad(10f); + t.row(); + t.add().growY(); + t.row(); + + if(mobile){ + t.addImageTextButton("$back", Icon.backSmall, () -> shown = false).size(220f, 60f).pad(12f); + } + }); + } + + public boolean shown(){ + return shown; + } + + public void toggle(){ + shown = !shown; + } +} diff --git a/core/src/mindustry/world/blocks/distribution/OverflowGate.java b/core/src/mindustry/world/blocks/distribution/OverflowGate.java index 185fdf7834..b07ae8c7be 100644 --- a/core/src/mindustry/world/blocks/distribution/OverflowGate.java +++ b/core/src/mindustry/world/blocks/distribution/OverflowGate.java @@ -81,11 +81,11 @@ public class OverflowGate extends Block{ if(to == null) return null; Tile edge = Edges.getFacingEdge(tile, to); - if(!to.block().acceptItem(item, to, edge) || (to.block() instanceof OverflowGate)){ + if(!to.block().acceptItem(item, to, edge) || to.getTeam() != tile.getTeam() || (to.block() instanceof OverflowGate)){ Tile a = tile.getNearby(Mathf.mod(from - 1, 4)); Tile b = tile.getNearby(Mathf.mod(from + 1, 4)); - boolean ac = a != null && a.block().acceptItem(item, a, edge) && !(a.block() instanceof OverflowGate); - boolean bc = b != null && b.block().acceptItem(item, b, edge) && !(b.block() instanceof OverflowGate); + boolean ac = a != null && a.block().acceptItem(item, a, edge) && !(a.block() instanceof OverflowGate) && a.getTeam() == tile.getTeam(); + boolean bc = b != null && b.block().acceptItem(item, b, edge) && !(b.block() instanceof OverflowGate) && b.getTeam() == tile.getTeam(); if(!ac && !bc){ return null; diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index f9a5cf6c9b..4a8f500d77 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -151,7 +151,7 @@ public class CoreBlock extends StorageBlock{ @Override public void removed(Tile tile){ CoreEntity entity = tile.ent(); - int total = tile.entity.proximity().count(e -> e.entity.items == tile.entity.items); + int total = tile.entity.proximity().count(e -> e.entity != null && e.entity.items != null && e.entity.items == tile.entity.items); float fract = 1f / total / state.teams.cores(tile.getTeam()).size; tile.entity.proximity().each(e -> isContainer(e) && e.entity.items == tile.entity.items, t -> { diff --git a/server/src/mindustry/server/ServerControl.java b/server/src/mindustry/server/ServerControl.java index d834ecd907..f78f6fbab9 100644 --- a/server/src/mindustry/server/ServerControl.java +++ b/server/src/mindustry/server/ServerControl.java @@ -292,7 +292,7 @@ public class ServerControl implements ApplicationListener{ info("&ly {0} seconds until next wave.", (int)(state.wavetime / 60)); } - info(" &ly{0} FPS, {1} MB used.", (int)(60f / Time.delta()), Core.app.getJavaHeap() / 1024 / 1024); + info(" &ly{0} FPS, {1} MB used.", Core.graphics.getFramesPerSecond(), Core.app.getJavaHeap() / 1024 / 1024); if(playerGroup.size() > 0){ info(" &lyPlayers: {0}", playerGroup.size());