From 5b65c2e27eac1a221fd533aa80f1fb56bc01e3ee Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 2 Jun 2018 00:19:31 -0400 Subject: [PATCH] Fixed MapIO not reading map stream fully --- core/assets/cursors/drill.png | Bin 0 -> 207 bytes .../src/io/anuke/mindustry/content/Mechs.java | 9 +++- .../mindustry/content/blocks/Blocks.java | 5 +- .../src/io/anuke/mindustry/core/Renderer.java | 1 + .../io/anuke/mindustry/editor/MapEditor.java | 9 ++++ .../mindustry/editor/MapEditorDialog.java | 8 +-- .../anuke/mindustry/editor/MapRenderer.java | 5 ++ .../mindustry/entities/BlockBuilder.java | 24 +++++++-- .../io/anuke/mindustry/entities/Player.java | 12 +++++ .../anuke/mindustry/input/DesktopInput.java | 47 ++++++++++++++---- .../anuke/mindustry/input/InputHandler.java | 13 ++++- core/src/io/anuke/mindustry/io/MapIO.java | 29 ++++------- .../io/anuke/mindustry/io/MapTileData.java | 3 ++ core/src/io/anuke/mindustry/io/Maps.java | 1 + core/src/io/anuke/mindustry/type/Mech.java | 1 + core/src/io/anuke/mindustry/world/Block.java | 2 - .../anuke/mindustry/world/WorldGenerator.java | 2 + .../mindustry/world/blocks/types/Floor.java | 12 +++++ .../mindustry/desktop/DesktopLauncher.java | 8 +-- 19 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 core/assets/cursors/drill.png diff --git a/core/assets/cursors/drill.png b/core/assets/cursors/drill.png new file mode 100644 index 0000000000000000000000000000000000000000..e524b82762eb015fbc641393aaa84cbb681870a0 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#5gQYu74M7FPd@^M@;qG}Lo80eofOD-K!L-#^7OkWf9)+pzi-S;n{#5*eN#gr zrGTijbvy;-#otTnx}|K7W{Ss0}xtC69 z{MPHb+mmah)y~CCIiAjKkF4fQpSDW7?S1@z25BebSvl7~Ujy3A;OXk;vd$@?2>^Am BOR@j} literal 0 HcmV?d00001 diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index 4e32490a6b..6f59a2d588 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -9,7 +9,12 @@ public class Mechs implements ContentList { @Override public void load() { - standard = new Mech("standard-mech", false); - standardShip = new Mech("standard-ship", true); + standard = new Mech("standard-mech", false){{ + drillPower = 1; + }}; + + standardShip = new Mech("standard-ship", true){{ + + }}; } } diff --git a/core/src/io/anuke/mindustry/content/blocks/Blocks.java b/core/src/io/anuke/mindustry/content/blocks/Blocks.java index 2e681dd7b2..d4d274cd23 100644 --- a/core/src/io/anuke/mindustry/content/blocks/Blocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/Blocks.java @@ -16,14 +16,11 @@ public class Blocks implements ContentList{ @Override public void load() { - air = new Block("air") { + air = new Floor("air") { //don't draw public void draw(Tile tile) {} }; - //player/enemy spawnpoint? - spawn = new Block("spawn"); - blockpart = new BlockPart(); build1 = new BuildBlock("build1"); diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index e3fc72a0c5..c4ef8bbd7c 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -102,6 +102,7 @@ public class Renderer extends RendererModule{ Cursors.arrow = Cursors.loadCursor("cursor"); Cursors.hand = Cursors.loadCursor("hand"); Cursors.ibeam = Cursors.loadCursor("ibar"); + Cursors.tool1 = Cursors.loadCursor("drill"); clearColor = Hue.lightness(0.4f); clearColor.a = 1f; diff --git a/core/src/io/anuke/mindustry/editor/MapEditor.java b/core/src/io/anuke/mindustry/editor/MapEditor.java index cfbd5a7fc7..a484d28647 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditor.java +++ b/core/src/io/anuke/mindustry/editor/MapEditor.java @@ -154,6 +154,10 @@ public class MapEditor{ continue; } + byte b1 = map.readAt(x + rx, y + ry, 1); + byte b2 = map.readAt(x + rx, y + ry, 2); + byte b3 = map.readAt(x + rx, y + ry, 3); + if(!isfloor) { byte link = map.readAt(x + rx, y + ry, 2); @@ -162,6 +166,11 @@ public class MapEditor{ } } + writer.wall = b1; + writer.link = b2; + writer.rotation = Bits.getLeftByte(b3); + writer.team = Bits.getRightByte(b3); + write(x + rx, y + ry, writer, true); renderer.updatePoint(x + rx, y + ry); } diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 0faa1c60a3..b2a2dea648 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -228,11 +228,11 @@ public class MapEditorDialog extends Dialog implements Disposable{ build(); build.end(); - tapped(() -> { - - }); - update(() -> { + if(Core.scene.getKeyboardFocus() instanceof Dialog && Core.scene.getKeyboardFocus() != this) { + return; + } + Vector2 v = pane.stageToLocalCoordinates(Graphics.mouse()); if(v.x >= 0 && v.y >= 0 && v.x <= pane.getWidth() && v.y <= pane.getHeight()){ diff --git a/core/src/io/anuke/mindustry/editor/MapRenderer.java b/core/src/io/anuke/mindustry/editor/MapRenderer.java index a12554dec2..9125ca5b65 100644 --- a/core/src/io/anuke/mindustry/editor/MapRenderer.java +++ b/core/src/io/anuke/mindustry/editor/MapRenderer.java @@ -169,6 +169,11 @@ public class MapRenderer implements Disposable{ int offsety = -(wall.size-1)/2; TextureRegion region = blockIcons.get(floor, regions.get("clear")); + + if(data.link != 0 || wall.solid){ + region = regions.get("clear"); + } + mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, 8, 8); region = blockIcons.get(wall, regions.get("clear")); diff --git a/core/src/io/anuke/mindustry/entities/BlockBuilder.java b/core/src/io/anuke/mindustry/entities/BlockBuilder.java index e234b139c0..d7ffdf9984 100644 --- a/core/src/io/anuke/mindustry/entities/BlockBuilder.java +++ b/core/src/io/anuke/mindustry/entities/BlockBuilder.java @@ -21,7 +21,7 @@ import java.util.Arrays; import static io.anuke.mindustry.Vars.world; -/**Interface for units that build thing.*/ +/**Interface for units that build, break or mine things.*/ public interface BlockBuilder { //temporary static final values Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()}; @@ -30,6 +30,12 @@ public interface BlockBuilder { /**Returns the queue for storing build requests.*/ Queue getPlaceQueue(); + /**Returns the tile this builder is currently mining.*/ + Tile getMineTile(); + + /**Sets the tile this builder is currently mining.*/ + void setMineTile(Tile tile); + /**Return whether this builder's place queue contains items.*/ default boolean isBuilding(){ return getPlaceQueue().size != 0; @@ -70,11 +76,18 @@ public interface BlockBuilder { return getPlaceQueue().size == 0 ? null : getPlaceQueue().first(); } - /**Update building mechanism for this unit.*/ + /**Update building mechanism for this unit. + * This includes mining.*/ default void updateBuilding(Unit unit){ BuildRequest current = getCurrentRequest(); - if(current == null) return; //nothing to do here + //update mining here + if(current == null){ + if(getMineTile() != null){ + updateMining(unit); + } + return; + } Tile tile = world.tile(current.x, current.y); @@ -138,6 +151,11 @@ public interface BlockBuilder { } } + /**Do not call directly.*/ + default void updateMining(Unit unit){ + + } + /**Draw placement effects for an entity.*/ default void drawBuilding(Unit unit){ Tile tile = world.tile(getCurrentRequest().x, getCurrentRequest().y); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index b450e454e6..5625cedb5e 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -63,6 +63,7 @@ public class Player extends Unit implements BlockBuilder { private boolean respawning; private float walktime; private Queue placeQueue = new Queue<>(); + private Tile mining; private Trail trail = new Trail(16); public Player(){ @@ -77,6 +78,17 @@ public class Player extends Unit implements BlockBuilder { //region unit and event overrides, utility methods + + @Override + public Tile getMineTile() { + return mining; + } + + @Override + public void setMineTile(Tile tile) { + this.mining = tile; + } + @Override public float getArmor() { return 0f; diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 5b244565c8..af4cbc32bb 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -15,6 +15,7 @@ import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Inputs.DeviceType; import io.anuke.ucore.core.KeyBinds; import io.anuke.ucore.core.Settings; +import io.anuke.ucore.function.Callable; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.scene.ui.layout.Unit; @@ -22,14 +23,17 @@ import io.anuke.ucore.scene.utils.Cursors; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.input.DesktopInput.CursorType.drill; +import static io.anuke.mindustry.input.DesktopInput.CursorType.hand; +import static io.anuke.mindustry.input.DesktopInput.CursorType.normal; import static io.anuke.mindustry.input.PlaceMode.*; public class DesktopInput extends InputHandler{ //controller info private float controlx, controly; private boolean controlling; - private boolean handCursor; private final String section; + private CursorType cursorType = normal; /**Position where the player started dragging a line.*/ private int selectX, selectY; @@ -132,7 +136,7 @@ public class DesktopInput extends InputHandler{ } if(isPlacing()){ - handCursor = true; + cursorType = hand; selectScale = Mathf.lerpDelta(selectScale, 1f, 0.2f); }else{ selectScale = 0f; @@ -150,19 +154,24 @@ public class DesktopInput extends InputHandler{ Tile cursor = tileAt(control.gdxInput().getX(), control.gdxInput().getY()); - if(cursor != null && cursor.target().block().isCursor(cursor.target())){ - handCursor = true; + if(cursor != null){ + cursor = cursor.target(); + + if(cursor.block().isCursor(cursor)) { + cursorType = hand; + } + + if(cursor.floor().drops != null && cursor.floor().drops.item.hardness <= player.mech.drillPower + && cursor.block() == Blocks.air){ + cursorType = drill; + } } if(!ui.hasMouse()) { - if (handCursor) { - Cursors.setHand(); - }else { - Cursors.restoreCursor(); - } + cursorType.set(); } - handCursor = false; + cursorType = normal; } @Override @@ -179,7 +188,7 @@ public class DesktopInput extends InputHandler{ mode = placing; } else { //only begin shooting if there's no cursor event - if(!tileTapped(cursor) && player.getPlaceQueue().size == 0){ + if(!tileTapped(cursor) && player.getPlaceQueue().size == 0 && !tryBeginMine(cursor)){ shooting = true; } } @@ -299,4 +308,20 @@ public class DesktopInput extends InputHandler{ controly = control.gdxInput().getY(); } } + + enum CursorType{ + normal(Cursors::restoreCursor), + hand(Cursors::setHand), + drill(Cursors::setTool1); + + private final Callable call; + + CursorType(Callable call){ + this.call = call; + } + + void set(){ + call.run(); + } + } } diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index b0c29cca0d..90b7508ad1 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -2,9 +2,10 @@ package io.anuke.mindustry.input; import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.math.Vector2; +import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.entities.BlockBuilder.BuildRequest; -import io.anuke.mindustry.entities.effect.ItemTransfer; import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.effect.ItemTransfer; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.fragments.OverlayFragment; @@ -119,6 +120,16 @@ public abstract class InputHandler extends InputAdapter{ //utility methods + /**Tries to begin mining a tile, returns true if successful.*/ + boolean tryBeginMine(Tile tile){ + if(tile.floor().drops != null && tile.floor().drops.item.hardness <= player.mech.drillPower + && tile.block() == Blocks.air){ + player.setMineTile(tile); + return true; + } + return false; + } + /**Returns the tile at the specified MOUSE coordinates.*/ Tile tileAt(float x, float y){ Vector2 vec = Graphics.world(x, y); diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index 676abfad5d..87d2d58dc6 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.io; -import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; @@ -14,10 +13,10 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.ColorMapper.BlockPair; -import java.io.*; - -import static io.anuke.mindustry.Vars.customMapDirectory; -import static io.anuke.mindustry.Vars.mapExtension; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; /**Reads and writes map files.*/ //TODO GWT support @@ -48,6 +47,8 @@ public class MapIO { } } + data.position(0, 0); + return pixmap; } @@ -93,28 +94,18 @@ public class MapIO { return readTileData(stream, meta, readOnly); } + /**Does not skip meta. Call after reading meta.*/ public static MapTileData readTileData(DataInputStream stream, MapMeta meta, boolean readOnly) throws IOException { byte[] bytes = new byte[stream.available()]; - stream.read(bytes); + stream.readFully(bytes); return new MapTileData(bytes, meta.width, meta.height, meta.blockMap, readOnly); } /**Reads tile data, skipping meta tags.*/ public static MapTileData readTileData(Map map, boolean readOnly){ - try { - InputStream stream; - - if (!map.custom) { - stream = Gdx.files.internal("maps/" + map.name + "." + mapExtension).read(); - } else { - stream = customMapDirectory.child(map.name + "." + mapExtension).read(); - } - - DataInputStream ds = new DataInputStream(stream); - MapTileData data = MapIO.readTileData(ds, readOnly); - ds.close(); - return data; + try (DataInputStream ds = new DataInputStream(map.stream.get())){ + return MapIO.readTileData(ds, readOnly); }catch (IOException e){ throw new RuntimeException(e); } diff --git a/core/src/io/anuke/mindustry/io/MapTileData.java b/core/src/io/anuke/mindustry/io/MapTileData.java index 078e14c6c7..2b2e878477 100644 --- a/core/src/io/anuke/mindustry/io/MapTileData.java +++ b/core/src/io/anuke/mindustry/io/MapTileData.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.io; import com.badlogic.gdx.utils.IntIntMap; import io.anuke.ucore.util.Bits; +import io.anuke.ucore.util.Log; import java.nio.ByteBuffer; @@ -44,6 +45,8 @@ public class MapTileData { buffer.position(0); this.map = null; } + + read(); } public byte[] toArray(){ diff --git a/core/src/io/anuke/mindustry/io/Maps.java b/core/src/io/anuke/mindustry/io/Maps.java index 807fef2eea..352c477c22 100644 --- a/core/src/io/anuke/mindustry/io/Maps.java +++ b/core/src/io/anuke/mindustry/io/Maps.java @@ -134,6 +134,7 @@ public class Maps implements Disposable{ try(DataInputStream ds = new DataInputStream(supplier.get())) { MapMeta meta = MapIO.readMapMeta(ds); Map map = new Map(name, meta, custom, supplier); + if (!headless){ map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true))); } diff --git a/core/src/io/anuke/mindustry/type/Mech.java b/core/src/io/anuke/mindustry/type/Mech.java index 16d6b95331..0fd6a8e91f 100644 --- a/core/src/io/anuke/mindustry/type/Mech.java +++ b/core/src/io/anuke/mindustry/type/Mech.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.type; public class Mech extends Upgrade { public boolean flying; public float mass = 1f; + public int drillPower = -1; public Mech(String name, boolean flying){ super(name); diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 1cd5c761aa..449b6c043f 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -82,8 +82,6 @@ public class Block extends BaseBlock implements Content{ public int variants = 0; /**stuff that drops when broken*/ public ItemStack drops = null; - /**liquids that drop from this block, used for pumps*/ - public Liquid liquidDrop = null; /**multiblock size*/ public int size = 1; /**Detailed description of the block. Can be as long as necesary.*/ diff --git a/core/src/io/anuke/mindustry/world/WorldGenerator.java b/core/src/io/anuke/mindustry/world/WorldGenerator.java index 3006329b0f..6a449d9b45 100644 --- a/core/src/io/anuke/mindustry/world/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/world/WorldGenerator.java @@ -20,6 +20,8 @@ public class WorldGenerator { IntArray multiblocks = new IntArray(); + data.position(0, 0); + for(int y = 0; y < data.height(); y ++){ for(int x = 0; x < data.width(); x ++){ TileDataMarker tile = data.read(); diff --git a/core/src/io/anuke/mindustry/world/blocks/types/Floor.java b/core/src/io/anuke/mindustry/world/blocks/types/Floor.java index 102b3ad756..24d1b48412 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/Floor.java @@ -7,6 +7,7 @@ import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.entities.StatusEffect; +import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Effects.Effect; @@ -24,15 +25,26 @@ public class Floor extends Block{ protected Predicate blends = block -> block != this; protected boolean blend = true; + /**Multiplies unit velocity by this when walked on.*/ public float speedMultiplier = 1f; + /**Multiplies unit drag by this when walked on.*/ public float dragMultiplier = 1f; + /**Damage taken per tick on this tile.*/ public float damageTaken = 0f; + /**How many ticks it takes to drown on this.*/ public float drownTime = 0f; + /**Effect when walking on this floor.*/ public Effect walkEffect = BlockFx.ripple; + /**Effect displayed when drowning on this floor.*/ public Effect drownUpdateEffect = BlockFx.bubble; + /**Status effect applied when walking on.*/ public StatusEffect status = StatusEffects.none; + /**Intensity of applied status effect.*/ public float statusIntensity = 0.6f; + /**Color of this floor's liquid. Used for tinting sprites.*/ public Color liquidColor; + /**liquids that drop from this block, used for pumps*/ + public Liquid liquidDrop = null; public Floor(String name) { super(name); diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index b67ceccc2f..2d41d4bb37 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -35,9 +35,9 @@ public class DesktopLauncher { if(OS.isMac) { Application.getApplication().setOpenFileHandler(e -> { - List list = e.getFiles(); + List list = e.getFiles(); - File target = list.get(0); + File target = (File)list.get(0); Gdx.app.postRunnable(() -> { FileHandle file = OS.getAppDataDirectory("Mindustry").child("tmp").child(target.getName()); @@ -68,10 +68,10 @@ public class DesktopLauncher { } }); }); - - config.setPreferencesConfig(OS.getAppDataDirectoryString("Mindustry"), FileType.Absolute); } + config.setPreferencesConfig(OS.getAppDataDirectoryString("Mindustry"), FileType.Absolute); + Platform.instance = new DesktopPlatform(arg); Net.setClientProvider(new KryoClient());