mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-04-21 04:50:59 -07:00
Fixed MapIO not reading map stream fully
This commit is contained in:
parent
6f9b712230
commit
5b65c2e27e
19 changed files with 141 additions and 50 deletions
BIN
core/assets/cursors/drill.png
Normal file
BIN
core/assets/cursors/drill.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 207 B |
|
|
@ -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){{
|
||||
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()){
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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<BuildRequest> 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);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public class Player extends Unit implements BlockBuilder {
|
|||
private boolean respawning;
|
||||
private float walktime;
|
||||
private Queue<BuildRequest> 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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(){
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.*/
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<Block> 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);
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ public class DesktopLauncher {
|
|||
|
||||
if(OS.isMac) {
|
||||
Application.getApplication().setOpenFileHandler(e -> {
|
||||
List<File> 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());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue