diff --git a/build.gradle b/build.gradle
index a98d53020a..56ace01894 100644
--- a/build.gradle
+++ b/build.gradle
@@ -22,7 +22,7 @@ allprojects {
appName = "Mindustry"
gdxVersion = '1.9.8'
aiVersion = '1.8.1'
- uCoreVersion = '82c0091'
+ uCoreVersion = 'fe2f2dd'
}
repositories {
diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml
index 68c562e7dd..724be5ba0b 100644
--- a/core/src/Mindustry.gwt.xml
+++ b/core/src/Mindustry.gwt.xml
@@ -3,6 +3,8 @@
+
+
diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java
index 5a1e39f8d5..1b5b3d3e6b 100644
--- a/core/src/io/anuke/mindustry/core/NetClient.java
+++ b/core/src/io/anuke/mindustry/core/NetClient.java
@@ -9,18 +9,13 @@ import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.entities.enemies.Enemy;
-import io.anuke.mindustry.entities.enemies.EnemyType;
-import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.NetworkIO;
import io.anuke.mindustry.net.Packets.*;
-import io.anuke.mindustry.resource.Upgrade;
-import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.Tile;
-import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.BaseBulletType;
import io.anuke.ucore.entities.Entities;
@@ -131,6 +126,7 @@ public class NetClient extends Module {
if (id != player.id) {
EntityRequestPacket req = new EntityRequestPacket();
req.id = id;
+ req.group = groupid;
Net.send(req, SendMode.udp);
}
data.position(data.position() + SyncEntity.getWriteSize((Class extends SyncEntity>) group.getType()));
@@ -157,25 +153,18 @@ public class NetClient extends Module {
ui.hudfrag.updateItems();
});
- Net.handleClient(EnemySpawnPacket.class, spawn -> {
+ Net.handleClient(EntitySpawnPacket.class, packet -> {
+ EntityGroup group = packet.group;
+
//duplicates.
- if (enemyGroup.getByID(spawn.id) != null ||
- recieved.contains(spawn.id) || dead.contains(spawn.id)) return;
+ if (group.getByID(packet.entity.id) != null ||
+ recieved.contains(packet.entity.id) || dead.contains(packet.entity.id)) return;
- recieved.add(spawn.id);
+ recieved.add(packet.entity.id);
- Enemy enemy = new Enemy(EnemyType.getByID(spawn.type));
- enemy.interpolator.target.set(spawn.x, spawn.y);
- enemy.set(spawn.x, spawn.y);
- enemy.tier = spawn.tier;
- enemy.lane = spawn.lane;
- enemy.id = spawn.id;
- enemy.health = spawn.health;
- enemy.add();
+ packet.entity.add();
- Effects.effect(Fx.spawn, enemy);
-
- Log.info("Recieved enemy {0}", spawn.id);
+ Log.info("Recieved entity {0}", packet.entity.id);
});
Net.handleClient(EnemyDeathPacket.class, spawn -> {
@@ -252,31 +241,6 @@ public class NetClient extends Module {
Platform.instance.updateRPC();
});
- Net.handleClient(PlayerSpawnPacket.class, packet -> {
- //duplicates.
- if (enemyGroup.getByID(packet.id) != null ||
- recieved.contains(packet.id)) return;
-
- recieved.add(packet.id);
-
- Player player = new Player();
- player.x = packet.x;
- player.y = packet.y;
- player.isAndroid = packet.android;
- player.name = packet.name;
- player.id = packet.id;
- player.weaponLeft = (Weapon) Upgrade.getByID(packet.weaponleft);
- player.weaponRight = (Weapon) Upgrade.getByID(packet.weaponright);
-
- player.interpolator.last.set(player.x, player.y);
- player.interpolator.target.set(player.x, player.y);
- player.add();
-
- Log.info("Recieved player {0}", packet.id);
-
- Platform.instance.updateRPC();
- });
-
Net.handleClient(KickPacket.class, packet -> {
kicked = true;
Net.disconnect();
diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java
index 7cb22ce63b..0546d85e56 100644
--- a/core/src/io/anuke/mindustry/core/NetServer.java
+++ b/core/src/io/anuke/mindustry/core/NetServer.java
@@ -1,11 +1,9 @@
package io.anuke.mindustry.core;
-import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.*;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
-import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode;
@@ -20,7 +18,6 @@ import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.modules.Module;
-import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Mathf;
@@ -95,18 +92,18 @@ public class NetServer extends Module{
if (player == null) return;
player.add();
- netCommon.sendMessage("[accent]" + Bundles.format("text.server.connected", player.name));
+ netCommon.sendMessage("[accent]" + player.name + " has connected.");
});
Net.handleServer(Disconnect.class, (id, packet) -> {
Player player = connections.get(packet.id);
if (player == null) {
- Gdx.app.error("Mindustry", "Unknown client has disconnected (ID=" + id + ")");
+ Log.err("Unknown client has disconnected (ID={0})", id);
return;
}
- netCommon.sendMessage("[accent]" + Bundles.format("text.server.disconnected", player.name));
+ netCommon.sendMessage("[accent]" + player.name + " has disconnected.");
player.remove();
DisconnectPacket dc = new DisconnectPacket();
@@ -171,29 +168,12 @@ public class NetServer extends Module{
Net.handleServer(EntityRequestPacket.class, (cid, packet) -> {
int id = packet.id;
int dest = cid;
- if (playerGroup.getByID(id) != null) {
- Player player = playerGroup.getByID(id);
- PlayerSpawnPacket p = new PlayerSpawnPacket();
- p.x = player.x;
- p.y = player.y;
- p.id = player.id;
- p.name = player.name;
- p.weaponleft = player.weaponLeft.id;
- p.weaponright = player.weaponRight.id;
- p.android = player.isAndroid;
-
+ EntityGroup group = Entities.getGroup(packet.group);
+ if(group.getByID(id) != null){
+ EntitySpawnPacket p = new EntitySpawnPacket();
+ p.entity = (SyncEntity)group.getByID(id);
Net.sendTo(dest, p, SendMode.tcp);
- } else if (enemyGroup.getByID(id) != null) {
- Enemy enemy = enemyGroup.getByID(id);
- EnemySpawnPacket e = new EnemySpawnPacket();
- e.x = enemy.x;
- e.y = enemy.y;
- e.id = enemy.id;
- e.tier = (byte) enemy.tier;
- e.lane = (byte) enemy.lane;
- e.type = enemy.type.id;
- e.health = (short) enemy.health;
- Net.sendTo(dest, e, SendMode.tcp);
+ return;
}
});
diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java
index bc90107ee6..328dfee9de 100644
--- a/core/src/io/anuke/mindustry/entities/Player.java
+++ b/core/src/io/anuke/mindustry/entities/Player.java
@@ -7,6 +7,7 @@ import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.Mech;
+import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Blocks;
@@ -66,33 +67,29 @@ public class Player extends SyncEntity{
@Override
public void onDeath(){
+ if(!isLocal) return;
- if(isLocal){
- remove();
- if(Net.active()){
- NetEvents.handlePlayerDeath();
- }
-
- Effects.effect(Fx.explosion, this);
- Effects.shake(4f, 5f, this);
- Effects.sound("die", this);
+ remove();
+ if(Net.active()){
+ NetEvents.handlePlayerDeath();
}
- //TODO respawning doesn't work properly for multiplayer at all
- if(isLocal) {
- control.setRespawnTime(respawnduration);
- ui.hudfrag.fadeRespawn(true);
- }
+ Effects.effect(Fx.explosion, this);
+ Effects.shake(4f, 5f, this);
+ Effects.sound("die", this);
+
+ control.setRespawnTime(respawnduration);
+ ui.hudfrag.fadeRespawn(true);
}
+ /**called when a remote player death event is recieved*/
public void doRespawn(){
dead = true;
Effects.effect(Fx.explosion, this);
Effects.shake(4f, 5f, this);
Effects.sound("die", this);
- set(-9999, -9999);
- Timers.run(respawnduration, () -> {
+ Timers.run(respawnduration + 5f, () -> {
heal();
set(world.getSpawnX(), world.getSpawnY());
});
@@ -104,7 +101,7 @@ public class Player extends SyncEntity{
angle = Mathf.lerpAngDelta(angle, targetAngle, 0.2f);
}
- if((debug && (!showPlayer || !showUI)) || (isAndroid && isLocal) ) return;
+ if((debug && (!showPlayer || !showUI)) || (isAndroid && isLocal) || dead) return;
boolean snap = snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate") && isLocal;
String part = isAndroid ? "ship" : "mech";
@@ -140,7 +137,7 @@ public class Player extends SyncEntity{
@Override
public void update(){
if(!isLocal || isAndroid || ui.chatfrag.chatOpen()){
- if(!isDead() && !isLocal) interpolate();
+ if(!isLocal) interpolate();
return;
}
@@ -214,6 +211,30 @@ public class Player extends SyncEntity{
return "Player{" + id + ", android=" + isAndroid + ", local=" + isLocal + ", " + x + ", " + y + "}\n";
}
+ @Override
+ public void writeSpawn(ByteBuffer buffer) {
+ buffer.put((byte)name.getBytes().length);
+ buffer.put(name.getBytes());
+ buffer.put(weaponLeft.id);
+ buffer.put(weaponRight.id);
+ buffer.put(isAndroid ? 1 : (byte)0);
+ buffer.putFloat(x);
+ buffer.putFloat(y);
+ }
+
+ @Override
+ public void readSpawn(ByteBuffer buffer) {
+ byte nlength = buffer.get();
+ byte[] n = new byte[nlength];
+ buffer.get(n);
+ name = new String(n);
+ weaponLeft = (Weapon) Upgrade.getByID(buffer.get());
+ weaponRight = (Weapon) Upgrade.getByID(buffer.get());
+ isAndroid = buffer.get() == 1;
+ x = buffer.getFloat();
+ y = buffer.getFloat();
+ }
+
@Override
public void write(ByteBuffer data) {
data.putFloat(x);
diff --git a/core/src/io/anuke/mindustry/entities/SyncEntity.java b/core/src/io/anuke/mindustry/entities/SyncEntity.java
index 580c9c11ee..3d8bddb678 100644
--- a/core/src/io/anuke/mindustry/entities/SyncEntity.java
+++ b/core/src/io/anuke/mindustry/entities/SyncEntity.java
@@ -17,10 +17,11 @@ public abstract class SyncEntity extends DestructibleEntity{
setWriteSize(Player.class, 4 + 4 + 4 + 2 + 1);
}
+ public abstract void writeSpawn(ByteBuffer data);
+ public abstract void readSpawn(ByteBuffer data);
+
public abstract void write(ByteBuffer data);
-
public abstract void read(ByteBuffer data);
-
public abstract void interpolate();
public int getWriteSize(){
diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java
index 88cd9559ce..ace3028e68 100644
--- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java
+++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java
@@ -17,7 +17,7 @@ import java.nio.ByteBuffer;
import static io.anuke.mindustry.Vars.enemyGroup;
public class Enemy extends SyncEntity {
- public final EnemyType type;
+ public EnemyType type;
public Timer timer = new Timer(5);
public float idletime = 0f;
@@ -38,6 +38,9 @@ public class Enemy extends SyncEntity {
this.type = type;
}
+ /**internal constructor used for deserialization, DO NOT USE*/
+ public Enemy(){}
+
@Override
public void update(){
type.update(this);
@@ -93,6 +96,26 @@ public class Enemy extends SyncEntity {
return add(enemyGroup);
}
+ @Override
+ public void writeSpawn(ByteBuffer buffer) {
+ buffer.put(type.id);
+ buffer.put((byte)lane);
+ buffer.put((byte)tier);
+ buffer.putFloat(x);
+ buffer.putFloat(y);
+ buffer.putShort((short)health);
+ }
+
+ @Override
+ public void readSpawn(ByteBuffer buffer) {
+ type = EnemyType.getByID(buffer.get());
+ lane = buffer.get();
+ tier = buffer.get();
+ x = buffer.getFloat();
+ y = buffer.getFloat();
+ health = buffer.getShort();
+ }
+
@Override
public void write(ByteBuffer data) {
data.putFloat(x);
diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditor.java b/core/src/io/anuke/mindustry/mapeditor/MapEditor.java
index bf424a81b8..3e50e435cd 100644
--- a/core/src/io/anuke/mindustry/mapeditor/MapEditor.java
+++ b/core/src/io/anuke/mindustry/mapeditor/MapEditor.java
@@ -11,6 +11,7 @@ import io.anuke.mindustry.world.ColorMapper;
import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.graphics.Pixmaps;
+import io.anuke.ucore.util.Log;
public class MapEditor{
public static final int[] validMapSizes = {128, 256, 512};
@@ -103,6 +104,7 @@ public class MapEditor{
}
public void setDrawBlock(Block block){
+ Log.info("Setting draw block {0}", block);
this.drawBlock = block;
pixmap.setColor(ColorMapper.getColor(block));
}
diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java
index 029fc79a67..d00ef09d1c 100644
--- a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java
+++ b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java
@@ -1,5 +1,6 @@
package io.anuke.mindustry.mapeditor;
+import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
@@ -13,9 +14,12 @@ import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.mindustry.world.blocks.SpecialBlocks;
import io.anuke.ucore.core.Core;
+import io.anuke.ucore.core.Graphics;
+import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Pixmaps;
+import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.builders.build;
import io.anuke.ucore.scene.builders.imagebutton;
import io.anuke.ucore.scene.builders.label;
@@ -37,6 +41,7 @@ public class MapEditorDialog extends Dialog{
private MapLoadDialog loadDialog;
private MapSaveDialog saveDialog;
private MapResizeDialog resizeDialog;
+ private ScrollPane pane;
private FileChooser openFile, saveFile;
private boolean saved = false;
@@ -138,6 +143,17 @@ public class MapEditorDialog extends Dialog{
build.begin(this);
build();
build.end();
+
+ tapped(() -> {
+ Element e = getScene().hit(Graphics.mouse().x, Graphics.mouse().y, true);
+ if(e == null || !e.isDescendantOf(pane)) getScene().setScrollFocus(null);
+ });
+
+ update(() -> {
+ if(getScene().getKeyboardFocus() == this){
+ doInput();
+ }
+ });
shown(() -> {
saved = true;
@@ -146,9 +162,7 @@ public class MapEditorDialog extends Dialog{
Core.scene.setScrollFocus(view);
view.clearStack();
- Timers.runTask(3f, () -> {
- Platform.instance.updateRPC();
- });
+ Timers.runTask(10f, Platform.instance::updateRPC);
});
hidden(() -> Platform.instance.updateRPC());
@@ -173,6 +187,10 @@ public class MapEditorDialog extends Dialog{
i++;
}
}
+
+ public boolean hasPane(){
+ return getScene().getScrollFocus() == pane;
+ }
public void build(){
@@ -247,18 +265,20 @@ public class MapEditorDialog extends Dialog{
ImageButton undo = tools.addImageButton("icon-undo", 16*2f, () -> view.undo()).get();
ImageButton redo = tools.addImageButton("icon-redo", 16*2f, () -> view.redo()).get();
- tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get();
+ ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get();
undo.setDisabled(() -> !view.getStack().canUndo());
redo.setDisabled(() -> !view.getStack().canRedo());
undo.update(() -> undo.getImage().setColor(undo.isDisabled() ? Color.GRAY : Color.WHITE));
redo.update(() -> redo.getImage().setColor(redo.isDisabled() ? Color.GRAY : Color.WHITE));
+ grid.update(() -> grid.setChecked(view.isGrid()));
for(EditorTool tool : EditorTool.values()){
ImageButton button = new ImageButton("icon-" + tool.name(), "toggle");
button.clicked(() -> view.setTool(tool));
button.resizeImage(16*2f);
+ button.update(() -> button.setChecked(view.getTool() == tool));
group.add(button);
if (tool == EditorTool.pencil)
button.setChecked(true);
@@ -283,9 +303,8 @@ public class MapEditorDialog extends Dialog{
row();
new table("button"){{
- get().addCheck("$text.oregen", b -> {
- editor.getMap().oreGen = b;
- }).update(c -> c.setChecked(editor.getMap().oreGen)).padTop(3).padBottom(3);
+ get().addCheck("$text.oregen", b -> editor.getMap().oreGen = b)
+ .update(c -> c.setChecked(editor.getMap().oreGen)).padTop(3).padBottom(3);
}}.growX().padBottom(-6).end();
row();
@@ -297,6 +316,36 @@ public class MapEditorDialog extends Dialog{
}}.right().growY().end();
}}.grow().end();
}
+
+ private void doInput(){
+ //tool select
+ for(int i = 0; i < EditorTool.values().length; i ++){
+ int code = i == 0 ? 5 : i;
+ if(Inputs.keyTap("weapon_" + code)){
+ view.setTool(EditorTool.values()[i]);
+ break;
+ }
+ }
+
+ //ctrl keys (undo, redo, save)
+ if(Inputs.keyDown(Keys.CONTROL_LEFT)){
+ if(Inputs.keyTap(Keys.Z)){
+ view.undo();
+ }
+
+ if(Inputs.keyTap(Keys.Y)){
+ view.redo();
+ }
+
+ if(Inputs.keyTap(Keys.S)){
+ saveDialog.save();
+ }
+
+ if(Inputs.keyTap(Keys.G)){
+ view.setGrid(!view.isGrid());
+ }
+ }
+ }
private boolean verifySize(Pixmap pix){
boolean w = false, h = false;
@@ -344,7 +393,7 @@ public class MapEditorDialog extends Dialog{
private void addBlockSelection(Table table){
Table content = new Table();
- ScrollPane pane = new ScrollPane(content, "volume");
+ pane = new ScrollPane(content, "volume");
pane.setScrollingDisabled(true, false);
pane.setFadeScrollBars(false);
pane.setOverscroll(true, false);
diff --git a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java
index 967917e5d7..3090325975 100644
--- a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java
+++ b/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java
@@ -1,6 +1,5 @@
package io.anuke.mindustry.mapeditor;
-import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Map;
@@ -8,12 +7,16 @@ import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.TextField;
+import static io.anuke.mindustry.Vars.*;
+
public class MapSaveDialog extends FloatingDialog{
private TextField field;
+ private Consumer listener;
public MapSaveDialog(Consumer cons){
super("$text.editor.savemap");
field = new TextField();
+ listener = cons;
Platform.instance.addDialog(field);
@@ -48,11 +51,18 @@ public class MapSaveDialog extends FloatingDialog{
button.setDisabled(this::invalid);
buttons().add(button);
}
+
+ public void save(){
+ if(!invalid()){
+ listener.accept(field.getText());
+ }else{
+ ui.showError("$text.editor.failoverwrite");
+ }
+ }
public void setFieldText(String text){
field.setText(text);
}
-
private boolean invalid(){
if(field.getText().isEmpty()){
diff --git a/core/src/io/anuke/mindustry/mapeditor/MapView.java b/core/src/io/anuke/mindustry/mapeditor/MapView.java
index 14e065d2d0..8bb018b4e3 100644
--- a/core/src/io/anuke/mindustry/mapeditor/MapView.java
+++ b/core/src/io/anuke/mindustry/mapeditor/MapView.java
@@ -11,13 +11,12 @@ import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
import com.badlogic.gdx.utils.Array;
-import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.ui.GridImage;
import io.anuke.mindustry.world.ColorMapper;
import io.anuke.ucore.core.Core;
-import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
+import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Pixmaps;
import io.anuke.ucore.scene.Element;
@@ -28,6 +27,8 @@ import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp;
+import static io.anuke.mindustry.Vars.ui;
+
public class MapView extends Element implements GestureListener{
private MapEditor editor;
private EditorTool tool = EditorTool.pencil;
@@ -49,6 +50,10 @@ public class MapView extends Element implements GestureListener{
this.tool = tool;
}
+ public EditorTool getTool() {
+ return tool;
+ }
+
public void clearStack(){
stack.clear();
current = null;
@@ -85,7 +90,6 @@ public class MapView extends Element implements GestureListener{
stack.redo();
editor.updateTexture();
}
-
}
public MapView(MapEditor editor){
@@ -171,19 +175,20 @@ public class MapView extends Element implements GestureListener{
@Override
public void act(float delta){
super.act(delta);
-
- float size = Math.min(width, height);
- offsetx = Mathf.clamp(offsetx, -size, size);
- offsety = Mathf.clamp(offsety, -size, size);
-
- if(tool != EditorTool.zoom) return;
+
+ float ax = Inputs.getAxis("move_x");
+ float ay = Inputs.getAxis("move_y");
+ offsetx -= ax * 15f / zoom;
+ offsety -= ay * 15f / zoom;
+
+ if(ui.editor.hasPane()) return;
zoom += Inputs.scroll()/10f * zoom;
clampZoom();
}
private void clampZoom(){
- zoom = Mathf.clamp(zoom, 0.4f, 6f);
+ zoom = Mathf.clamp(zoom, 0.4f, 8f);
}
private GridPoint2 project(float x, float y){
diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java
index 079d34ba9e..7c5f8e7223 100644
--- a/core/src/io/anuke/mindustry/net/Packets.java
+++ b/core/src/io/anuke/mindustry/net/Packets.java
@@ -1,9 +1,13 @@
package io.anuke.mindustry.net;
+import com.badlogic.gdx.utils.reflect.ClassReflection;
+import com.badlogic.gdx.utils.reflect.ReflectionException;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.net.Packet.ImportantPacket;
import io.anuke.mindustry.resource.Item;
+import io.anuke.ucore.entities.Entities;
+import io.anuke.ucore.entities.EntityGroup;
import java.nio.ByteBuffer;
@@ -241,66 +245,29 @@ public class Packets {
}
}
- public static class EnemySpawnPacket implements Packet{
- public byte type, lane, tier;
- public float x, y;
- public short health;
- public int id;
+ public static class EntitySpawnPacket implements Packet{
+ public SyncEntity entity;
+ public EntityGroup> group;
@Override
- public void write(ByteBuffer buffer) {
- buffer.put(type);
- buffer.put(lane);
- buffer.put(tier);
- buffer.putFloat(x);
- buffer.putFloat(y);
- buffer.putShort(health);
- buffer.putInt(id);
+ public void write(ByteBuffer buffer){
+ buffer.put((byte)entity.getGroup().getID());
+ buffer.putInt(entity.id);
+ entity.writeSpawn(buffer);
}
@Override
public void read(ByteBuffer buffer) {
- type = buffer.get();
- lane = buffer.get();
- tier = buffer.get();
- x = buffer.getFloat();
- y = buffer.getFloat();
- health = buffer.getShort();
- id = buffer.getInt();
- }
- }
-
- public static class PlayerSpawnPacket implements Packet{
- public byte weaponleft, weaponright;
- public boolean android;
- public String name;
- public float x, y;
- public int id;
-
- @Override
- public void write(ByteBuffer buffer) {
- buffer.put((byte)name.getBytes().length);
- buffer.put(name.getBytes());
- buffer.put(weaponleft);
- buffer.put(weaponright);
- buffer.put(android ? 1 : (byte)0);
- buffer.putFloat(x);
- buffer.putFloat(y);
- buffer.putInt(id);
- }
-
- @Override
- public void read(ByteBuffer buffer) {
- byte nlength = buffer.get();
- byte[] n = new byte[nlength];
- buffer.get(n);
- name = new String(n);
- weaponleft = buffer.get();
- weaponright = buffer.get();
- android = buffer.get() == 1;
- x = buffer.getFloat();
- y = buffer.getFloat();
- id = buffer.getInt();
+ byte groupid = buffer.get();
+ int id = buffer.getInt();
+ group = Entities.getGroup(groupid);
+ try {
+ entity = (SyncEntity) ClassReflection.newInstance(group.getType());
+ entity.id = id;
+ entity.readSpawn(buffer);
+ }catch (ReflectionException e){
+ throw new RuntimeException(e);
+ }
}
}
@@ -467,15 +434,18 @@ public class Packets {
public static class EntityRequestPacket implements Packet{
public int id;
+ public byte group;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(id);
+ buffer.put(group);
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.getInt();
+ group = buffer.get();
}
}
diff --git a/core/src/io/anuke/mindustry/net/Registrator.java b/core/src/io/anuke/mindustry/net/Registrator.java
index 3697588e7a..9f4d197bb1 100644
--- a/core/src/io/anuke/mindustry/net/Registrator.java
+++ b/core/src/io/anuke/mindustry/net/Registrator.java
@@ -18,8 +18,6 @@ public class Registrator {
BreakPacket.class,
StateSyncPacket.class,
BlockSyncPacket.class,
- EnemySpawnPacket.class,
- PlayerSpawnPacket.class,
BulletPacket.class,
EnemyDeathPacket.class,
BlockUpdatePacket.class,
@@ -38,7 +36,8 @@ public class Registrator {
FriendlyFireChangePacket.class,
PlayerDeathPacket.class,
CustomMapPacket.class,
- MapAckPacket.class
+ MapAckPacket.class,
+ EntitySpawnPacket.class,
};
private static ObjectIntMap> ids = new ObjectIntMap<>();
diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java
index ee6d92dcbd..e1c66283ef 100644
--- a/core/src/io/anuke/mindustry/world/Block.java
+++ b/core/src/io/anuke/mindustry/world/Block.java
@@ -281,4 +281,9 @@ public class Block{
public static Block getByID(int id){
return blocks.get(id);
}
+
+ @Override
+ public String toString(){
+ return name;
+ }
}
diff --git a/kryonet/src/io/anuke/kryonet/JavaWebsocketClient.java b/kryonet/src/io/anuke/kryonet/JavaWebsocketClient.java
deleted file mode 100644
index cafb859967..0000000000
--- a/kryonet/src/io/anuke/kryonet/JavaWebsocketClient.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package io.anuke.kryonet;
-
-import com.badlogic.gdx.utils.Array;
-import com.badlogic.gdx.utils.Base64Coder;
-import com.badlogic.gdx.utils.reflect.ClassReflection;
-import io.anuke.mindustry.Vars;
-import io.anuke.mindustry.net.Host;
-import io.anuke.mindustry.net.Net;
-import io.anuke.mindustry.net.Net.ClientProvider;
-import io.anuke.mindustry.net.Net.SendMode;
-import io.anuke.mindustry.net.Packet;
-import io.anuke.mindustry.net.Packets.Connect;
-import io.anuke.mindustry.net.Packets.Disconnect;
-import io.anuke.mindustry.net.Registrator;
-import io.anuke.ucore.function.Consumer;
-import io.anuke.ucore.util.Log;
-import org.java_websocket.client.WebSocketClient;
-import org.java_websocket.drafts.Draft_6455;
-import org.java_websocket.handshake.ServerHandshake;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.ByteBuffer;
-
-public class JavaWebsocketClient implements ClientProvider {
- WebSocketClient socket;
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- boolean debug = false;
-
- @Override
- public void connect(String ip, int port) throws IOException {
- try {
- URI i = new URI("ws://" + ip + ":" + Vars.webPort);
- Log.info("Connecting: {0}", i);
- socket = new WebSocketClient(i, new Draft_6455(), null, 5000) {
- Thread thread;
-
- @Override
- public void connect() {
- if(thread != null )
- throw new IllegalStateException( "WebSocketClient objects are not reuseable" );
- thread = new Thread(this);
- thread.setDaemon(true);
- thread.start();
- }
-
- @Override
- public void onOpen(ServerHandshake handshakedata) {
- Log.info("Connected!");
- Connect connect = new Connect();
- Net.handleClientReceived(connect);
- }
-
- @Override
- public void onMessage(String message) {
- try {
- byte[] bytes = Base64Coder.decode(message);
- ByteBuffer buffer = ByteBuffer.wrap(bytes);
- byte id = buffer.get();
- if (id == -2) {
- //this is a framework message... do nothing yet?
- } else {
- Class> type = Registrator.getByID(id);
- Packet packet = (Packet) ClassReflection.newInstance(type);
- packet.read(buffer);
- Net.handleClientReceived(packet);
- }
- } catch (Exception e) {
- e.printStackTrace();
- //throw new RuntimeException(e);
- }
- }
-
- @Override
- public void onClose(int code, String reason, boolean remote) {
- Disconnect disconnect = new Disconnect();
- Net.handleClientReceived(disconnect);
- }
-
- @Override
- public void onError(Exception ex) {
- onClose(0, null, true);
- ex.printStackTrace();
- }
- };
- socket.connect();
- }catch (URISyntaxException e){
- throw new IOException(e);
- }
- }
-
- @Override
- public void send(Object object, SendMode mode) {
- if(!(object instanceof Packet)) throw new RuntimeException("All sent objects must be packets!");
- Packet p = (Packet)object;
- buffer.position(0);
- buffer.put(Registrator.getID(object.getClass()));
- p.write(buffer);
- int pos = buffer.position();
- buffer.position(0);
- byte[] out = new byte[pos];
- buffer.get(out);
- String string = new String(Base64Coder.encode(out));
- socket.send(string);
- }
-
- @Override
- public void updatePing() {
-
- }
-
- @Override
- public int getPing() {
- return 0;
- }
-
- @Override
- public void disconnect() {
- socket.close();
- }
-
- @Override
- public void discover(Consumer> callback){
- callback.accept(new Array<>());
- }
-
- @Override
- public void pingHost(String address, int port, Consumer valid, Consumer failed) {
- failed.accept(new IOException());
- }
-
- @Override
- public void dispose() {
- if(socket != null) socket.close();
- for(Thread thread : Thread.getAllStackTraces().keySet()){
- if(thread.getName().equals("WebsocketWriteThread")) thread.interrupt();
- }
- }
-}
diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java
index 3592e7d1c8..e1bdfe1ab8 100644
--- a/kryonet/src/io/anuke/kryonet/KryoServer.java
+++ b/kryonet/src/io/anuke/kryonet/KryoServer.java
@@ -135,7 +135,7 @@ public class KryoServer implements ServerProvider {
serverThread = new Thread(() -> {
try{
server.run();
- }catch (Exception e){
+ }catch (Throwable e){
if(!(e instanceof ClosedSelectorException)) handleException(e);
}
}, "Kryonet Server");
@@ -273,7 +273,7 @@ public class KryoServer implements ServerProvider {
Log.info("Disposed server.");
}
- private void handleException(Exception e){
+ private void handleException(Throwable e){
Gdx.app.postRunnable(() -> { throw new RuntimeException(e);});
}
@@ -435,9 +435,7 @@ public class KryoServer implements ServerProvider {
}
@Override
- public void onStart() {
- Log.info("Web server started.");
- }
+ public void onStart() {}
}
}