diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml
index 724be5ba0b..1dcf056855 100644
--- a/core/src/Mindustry.gwt.xml
+++ b/core/src/Mindustry.gwt.xml
@@ -4,9 +4,11 @@
-
+
+
+
diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java
index 60a2feab52..ab73d1c800 100644
--- a/core/src/io/anuke/mindustry/Vars.java
+++ b/core/src/io/anuke/mindustry/Vars.java
@@ -3,6 +3,7 @@ package io.anuke.mindustry;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
+import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.Player;
@@ -80,6 +81,25 @@ public class Vars{
public static final int tilesize = 8;
+ public static final Color[] playerColors = {
+ Color.valueOf("82759a"),
+ Color.valueOf("c0c1c5"),
+ Color.valueOf("fff0e7"),
+ Color.valueOf("7d2953"),
+ Color.valueOf("ff074e"),
+ Color.valueOf("ff072a"),
+ Color.valueOf("ff76a6"),
+ Color.valueOf("a95238"),
+ Color.valueOf("ffa108"),
+ Color.valueOf("feeb2c"),
+ Color.valueOf("ffcaa8"),
+ Color.valueOf("008551"),
+ Color.valueOf("00e339"),
+ Color.valueOf("222e53"),
+ Color.valueOf("4b5ef1"),
+ Color.valueOf("2cabfe"),
+ };
+
//server port
public static final int port = 6567;
public static final int webPort = 6568;
diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java
index 53f22810fd..371668960b 100644
--- a/core/src/io/anuke/mindustry/core/Control.java
+++ b/core/src/io/anuke/mindustry/core/Control.java
@@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons;
+import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.input.DefaultKeybinds;
@@ -111,7 +112,8 @@ public class Control extends Module{
"ip", "localhost",
"port", port+"",
"name", android || gwt ? "player" : UCore.getProperty("user.name"),
- "servers", ""
+ "servers", "",
+ "color", Color.rgba8888(playerColors[9])
);
KeyBinds.load();
@@ -123,6 +125,7 @@ public class Control extends Module{
player = new Player();
player.name = Settings.getString("name");
player.isAndroid = android;
+ player.color.set(Settings.getInt("color"));
player.isLocal = true;
saves.load();
diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java
index 1b5b3d3e6b..ebc092b18e 100644
--- a/core/src/io/anuke/mindustry/core/NetClient.java
+++ b/core/src/io/anuke/mindustry/core/NetClient.java
@@ -1,6 +1,7 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.core.GameState.State;
@@ -57,6 +58,7 @@ public class NetClient extends Module {
ConnectPacket c = new ConnectPacket();
c.name = player.name;
c.android = android;
+ c.color = Color.rgba8888(player.color);
Net.send(c, SendMode.tcp);
Timers.runTask(dataTimeout, () -> {
diff --git a/core/src/io/anuke/mindustry/core/NetCommon.java b/core/src/io/anuke/mindustry/core/NetCommon.java
index 4e2142e74a..b2326211cd 100644
--- a/core/src/io/anuke/mindustry/core/NetCommon.java
+++ b/core/src/io/anuke/mindustry/core/NetCommon.java
@@ -1,6 +1,5 @@
package io.anuke.mindustry.core;
-import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode;
@@ -16,9 +15,6 @@ import io.anuke.ucore.modules.Module;
import static io.anuke.mindustry.Vars.*;
public class NetCommon extends Module {
- public static final Color[] colorArray = {Color.ORANGE, Color.SCARLET, Color.LIME, Color.PURPLE,
- Color.GOLD, Color.PINK, Color.SKY, Color.GOLD, Color.VIOLET,
- Color.GREEN, Color.CORAL, Color.CYAN, Color.CHARTREUSE};
public NetCommon(){
@@ -86,6 +82,8 @@ public class NetCommon extends Module {
}
public String colorizeName(int id, String name){
- return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name;
+ Player player = playerGroup.getByID(id);
+ if(name == null || player == null) return null;
+ return "[#" + player.color.toString().toUpperCase() + "]" + name;
}
}
diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java
index 0546d85e56..10c08d0e83 100644
--- a/core/src/io/anuke/mindustry/core/NetServer.java
+++ b/core/src/io/anuke/mindustry/core/NetServer.java
@@ -56,6 +56,7 @@ public class NetServer extends Module{
player.set(world.getSpawnX(), world.getSpawnY());
player.interpolator.last.set(player.x, player.y);
player.interpolator.target.set(player.x, player.y);
+ player.color.set(packet.color);
connections.put(id, player);
if(world.getMap().custom){
diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java
index ef88cebdb7..e1a9582368 100644
--- a/core/src/io/anuke/mindustry/core/Renderer.java
+++ b/core/src/io/anuke/mindustry/core/Renderer.java
@@ -243,9 +243,9 @@ public class Renderer extends RendererModule{
void drawEnemyMarkers(){
Graphics.surface(indicatorSurface);
Draw.color(Color.RED);
- for(Enemy enemy : enemyGroup.all()){
+ for(Enemy enemy : enemyGroup.all()) {
- if(Tmp.r1.setSize(camera.viewportWidth, camera.viewportHeight).setCenter(camera.position.x, camera.position.y).overlaps(enemy.hitbox.getRect(enemy.x, enemy.y))){
+ if (Tmp.r1.setSize(camera.viewportWidth, camera.viewportHeight).setCenter(camera.position.x, camera.position.y).overlaps(enemy.hitbox.getRect(enemy.x, enemy.y))) {
continue;
}
@@ -253,6 +253,7 @@ public class Renderer extends RendererModule{
Angles.translation(angle, Unit.dp.scl(20f));
Draw.rect("enemyarrow", camera.position.x + Angles.x(), camera.position.y + Angles.y(), angle);
}
+
Draw.color();
Draw.alpha(0.4f);
Graphics.flushSurface();
@@ -374,6 +375,9 @@ public class Renderer extends RendererModule{
for(SpawnPoint spawn : world.getSpawns()){
Lines.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
}
+
+ Draw.color(Color.LIME);
+ Lines.poly(world.getSpawnX(), world.getSpawnY(), 4, 6f, Timers.time()*2f);
if(input.breakMode == PlaceMode.holdDelete)
input.breakMode.draw(tilex, tiley, 0, 0);
diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java
index d542db35e5..7d024a49f5 100644
--- a/core/src/io/anuke/mindustry/entities/Player.java
+++ b/core/src/io/anuke/mindustry/entities/Player.java
@@ -1,7 +1,6 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
-import io.anuke.mindustry.core.NetCommon;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.net.Net;
@@ -27,18 +26,18 @@ public class Player extends SyncEntity{
public String name = "name";
public boolean isAndroid;
+ public Color color = new Color();
- //TODO send these.
- public transient Weapon weaponLeft = Weapon.blaster;
- public transient Weapon weaponRight = Weapon.blaster;
- public transient Mech mech = Mech.standard;
+ public Weapon weaponLeft = Weapon.blaster;
+ public Weapon weaponRight = Weapon.blaster;
+ public Mech mech = Mech.standard;
public float angle;
- public transient float targetAngle = 0f;
- public transient boolean dashing = false;
+ public float targetAngle = 0f;
+ public boolean dashing = false;
- public transient int clientid;
- public transient boolean isLocal = false;
+ public int clientid;
+ public boolean isLocal = false;
public Player(){
hitbox.setSize(5);
@@ -137,11 +136,20 @@ public class Player extends SyncEntity{
@Override
public void update(){
- if(!isLocal || isAndroid || ui.chatfrag.chatOpen()){
+ if(!isLocal || isAndroid){
if(!isLocal) interpolate();
return;
}
+ Tile tile = world.tileWorld(x, y);
+
+ //if player is in solid block
+ if(tile != null && ((tile.floor().liquid && tile.block() == Blocks.air) || tile.solid())){
+ damage(health+1); //die instantly
+ }
+
+ if(ui.chatfrag.chatOpen()) return;
+
dashing = Inputs.keyDown("dash");
float speed = dashing ? (debug ? Player.dashSpeed * 5f : Player.dashSpeed) : Player.speed;
@@ -150,13 +158,6 @@ public class Player extends SyncEntity{
health ++;
health = Mathf.clamp(health, -1, maxhealth);
-
- Tile tile = world.tileWorld(x, y);
-
- //if player is in solid block
- if(tile != null && ((tile.floor().liquid && tile.block() == Blocks.air) || tile.solid())){
- damage(health+1); //die instantly
- }
vector.set(0, 0);
@@ -219,6 +220,7 @@ public class Player extends SyncEntity{
buffer.put(weaponLeft.id);
buffer.put(weaponRight.id);
buffer.put(isAndroid ? 1 : (byte)0);
+ buffer.putInt(Color.rgba8888(color));
buffer.putFloat(x);
buffer.putFloat(y);
}
@@ -232,6 +234,7 @@ public class Player extends SyncEntity{
weaponLeft = (Weapon) Upgrade.getByID(buffer.get());
weaponRight = (Weapon) Upgrade.getByID(buffer.get());
isAndroid = buffer.get() == 1;
+ color.set(buffer.getInt());
x = buffer.getFloat();
y = buffer.getFloat();
}
@@ -282,6 +285,6 @@ public class Player extends SyncEntity{
}
public Color getColor(){
- return NetCommon.colorArray[id % NetCommon.colorArray.length];
+ return color;
}
}
diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java
index a21104a25c..fa1bf5f0d3 100644
--- a/core/src/io/anuke/mindustry/input/InputHandler.java
+++ b/core/src/io/anuke/mindustry/input/InputHandler.java
@@ -119,7 +119,7 @@ public abstract class InputHandler extends InputAdapter{
Tile tile = world.tile(x, y);
- if(tile == null) return false;
+ if(tile == null || (isSpawnPoint(tile) && (type.solidifes || type.solid))) return false;
if(!type.isMultiblock() && control.tutorial().active() &&
control.tutorial().showBlock()){
@@ -142,7 +142,7 @@ public abstract class InputHandler extends InputAdapter{
for(int dx = 0; dx < type.width; dx ++){
for(int dy = 0; dy < type.height; dy ++){
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
- if(other == null || other.block() != Blocks.air){
+ if(other == null || other.block() != Blocks.air || isSpawnPoint(other)){
return false;
}
}
@@ -152,9 +152,13 @@ public abstract class InputHandler extends InputAdapter{
if(tile.block() != type && type.canReplace(tile.block()) && tile.block().isMultiblock() == type.isMultiblock()){
return true;
}
- return tile != null && tile.block() == Blocks.air;
+ return tile.block() == Blocks.air;
}
}
+
+ public boolean isSpawnPoint(Tile tile){
+ return tile != null && tile.x == world.getCore().x && tile.y == world.getCore().y - 2;
+ }
public boolean validBreak(int x, int y){
Tile tile = world.tile(x, y);
diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java
index 8cb50dc70b..9f409ca57e 100644
--- a/core/src/io/anuke/mindustry/net/Net.java
+++ b/core/src/io/anuke/mindustry/net/Net.java
@@ -21,7 +21,7 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class Net{
- public static final int version = 14;
+ public static final int version = 15;
private static boolean server;
private static boolean active;
@@ -94,6 +94,11 @@ public class Net{
public static Array getConnections(){
return (Array)serverProvider.getConnections();
}
+
+ /**Returns a connection by ID*/
+ public static NetConnection getConnection(int id){
+ return serverProvider.getByID(id);
+ }
/**Send an object to all connected clients, or to the server if this is a client.*/
public static void send(Object object, SendMode mode){
@@ -261,6 +266,8 @@ public class Net{
void close();
/**Return all connected users.*/
Array extends NetConnection> getConnections();
+ /**Returns a connection by ID.*/
+ NetConnection getByID(int id);
/**Kick a certain connection.*/
void kick(int connection, KickReason reason);
/**Returns the ping for a certain connection.*/
diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java
index 4a817d21af..92ca7cb9a9 100644
--- a/core/src/io/anuke/mindustry/net/Packets.java
+++ b/core/src/io/anuke/mindustry/net/Packets.java
@@ -52,6 +52,7 @@ public class Packets {
public int version;
public String name;
public boolean android;
+ public int color;
@Override
public void write(ByteBuffer buffer) {
@@ -59,6 +60,7 @@ public class Packets {
buffer.put((byte)name.getBytes().length);
buffer.put(name.getBytes());
buffer.put(android ? (byte)1 : 0);
+ buffer.putInt(color);
}
@Override
@@ -69,6 +71,7 @@ public class Packets {
buffer.get(bytes);
name = new String(bytes);
android = buffer.get() == 1;
+ color = buffer.getInt();
}
}
diff --git a/core/src/io/anuke/mindustry/net/ServerDebug.java b/core/src/io/anuke/mindustry/net/ServerDebug.java
index 96687c58ed..fc9709a0b9 100644
--- a/core/src/io/anuke/mindustry/net/ServerDebug.java
+++ b/core/src/io/anuke/mindustry/net/ServerDebug.java
@@ -29,6 +29,8 @@ public class ServerDebug {
build.append(player.clientid);
build.append(" / player '");
build.append(player.name);
+ build.append(" android: ");
+ build.append(player.isAndroid);
build.append("'\n");
for(Class> type : map.orderedKeys()){
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java
new file mode 100644
index 0000000000..244dc944ea
--- /dev/null
+++ b/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java
@@ -0,0 +1,44 @@
+package io.anuke.mindustry.ui.dialogs;
+
+import com.badlogic.gdx.graphics.Color;
+import io.anuke.ucore.function.Consumer;
+import io.anuke.ucore.scene.ui.Dialog;
+import io.anuke.ucore.scene.ui.ImageButton;
+import io.anuke.ucore.scene.ui.layout.Table;
+
+import static io.anuke.mindustry.Vars.player;
+import static io.anuke.mindustry.Vars.playerColors;
+
+public class ColorPickDialog extends Dialog{
+ private Consumer cons;
+
+ public ColorPickDialog(){
+ super("", "dialog");
+ build();
+ }
+
+ private void build(){
+ Table table = new Table();
+ content().add(table);
+
+ for(int i = 0; i < playerColors.length; i ++){
+ Color color = playerColors[i];
+
+ ImageButton button = table.addImageButton("white", "toggle", 34, () -> {
+ cons.accept(color);
+ hide();
+ }).size(44, 48).pad(0).padBottom(-5.1f).get();
+ button.setChecked(player.getColor().equals(color));
+ button.getStyle().imageUpColor = color;
+
+ if(i%4 == 3){
+ table.row();
+ }
+ }
+ }
+
+ public void show(Consumer cons){
+ this.cons = cons;
+ show();
+ }
+}
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java
index d49f6a8300..d4991027bf 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java
@@ -1,14 +1,17 @@
package io.anuke.mindustry.ui.dialogs;
+import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
+import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Strings;
import java.io.IOException;
+import static io.anuke.mindustry.Vars.player;
import static io.anuke.mindustry.Vars.ui;
//TODO add port specification
@@ -29,6 +32,15 @@ public class HostDialog extends FloatingDialog{
Settings.save();
ui.listfrag.rebuild();
}).grow().pad(8);
+
+ ImageButton button = t.addImageButton("white", 40, () -> {
+ new ColorPickDialog().show(color -> {
+ player.color.set(color);
+ Settings.putInt("color", Color.rgba8888(color));
+ Settings.save();;
+ });
+ }).size(50f, 54f).get();
+ button.update(() -> button.getStyle().imageUpColor = player.getColor());
}).width(w).height(70f).pad(4);
content().row();
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java
index 196d05e231..8a5234ee0d 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java
@@ -1,5 +1,6 @@
package io.anuke.mindustry.ui.dialogs;
+import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.io.Platform;
@@ -9,6 +10,7 @@ import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.style.Drawable;
import io.anuke.ucore.scene.ui.Dialog;
+import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.layout.Table;
@@ -16,6 +18,7 @@ import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Strings;
+import static io.anuke.mindustry.Vars.player;
import static io.anuke.mindustry.Vars.ui;
public class JoinDialog extends FloatingDialog {
@@ -40,7 +43,7 @@ public class JoinDialog extends FloatingDialog {
Platform.instance.addDialog(add.content().addField(Settings.getString("ip"), text ->{
Settings.putString("ip", text);
Settings.save();
- }).size(340f, 54f).get(), 100);
+ }).size(320f, 54f).get(), 100);
add.content().row();
add.buttons().defaults().size(140f, 60f).pad(4f);
@@ -173,6 +176,16 @@ public class JoinDialog extends FloatingDialog {
Settings.put("name", text);
Settings.save();
}).grow().pad(8);
+
+ ImageButton button = t.addImageButton("white", 40, () -> {
+ new ColorPickDialog().show(color -> {
+ player.color.set(color);
+ Settings.putInt("color", Color.rgba8888(color));
+ Settings.save();
+ });
+ }).size(50f, 54f).get();
+ button.update(() -> button.getStyle().imageUpColor = player.getColor());
+
}).width(w).height(70f).pad(4);
content().row();
content().add(pane).width(w).pad(0);
diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java
index e1bdfe1ab8..0ef768cc41 100644
--- a/kryonet/src/io/anuke/kryonet/KryoServer.java
+++ b/kryonet/src/io/anuke/kryonet/KryoServer.java
@@ -114,9 +114,25 @@ public class KryoServer implements ServerProvider {
return array;
}
+ @Override
+ public KryoConnection getByID(int id){
+ for(int i = 0; i < connections.size(); i ++){
+ KryoConnection con = connections.get(i);
+ if(con.id == id){
+ return con;
+ }
+ }
+
+ return null;
+ }
+
@Override
public void kick(int connection, KickReason reason) {
KryoConnection con = getByID(connection);
+ if(con == null){
+ Log.err("Cannot kick unknown player!");
+ return;
+ }
KickPacket p = new KickPacket();
p.reason = reason;
@@ -277,17 +293,6 @@ public class KryoServer implements ServerProvider {
Gdx.app.postRunnable(() -> { throw new RuntimeException(e);});
}
- KryoConnection getByID(int id){
- for(int i = 0; i < connections.size(); i ++){
- KryoConnection con = connections.get(i);
- if(con.id == id){
- return con;
- }
- }
-
- return null;
- }
-
KryoConnection getByKryoID(int id){
for(int i = 0; i < connections.size(); i ++){
KryoConnection con = connections.get(i);
@@ -407,7 +412,7 @@ public class KryoServer implements ServerProvider {
if (k == null) return;
if(message.equals("_ping_")){
- conn.send("---" + connections.size() + "|" + Vars.player.name);
+ conn.send("---" + Vars.playerGroup.size() + "|" + (Vars.headless ? "Server" : Vars.player.name));
connections.remove(k);
}else {
diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java
index 72877de894..0ca6a3f29b 100644
--- a/server/src/io/anuke/mindustry/server/ServerControl.java
+++ b/server/src/io/anuke/mindustry/server/ServerControl.java
@@ -73,7 +73,7 @@ public class ServerControl extends Module {
if(shuffle) {
Map previous = world.getMap();
Map map = previous;
- while(map == previous) map = world.maps().getDefaultMaps().random();
+ while(map == previous || !map.visible) map = world.maps().getDefaultMaps().random();
info("Selected next map to be {0}.", map.name);
state.set(State.playing);
@@ -172,7 +172,7 @@ public class ServerControl extends Module {
return;
}
- netCommon.sendMessage("[pink][[Server]:[] " + arg[0]);
+ netCommon.sendMessage("[DARK_GRAY][[Server]:[] " + arg[0]);
info("&lyServer: &lb{0}", arg[0]);
}).mergeArgs();