Fixes for invisible players and improper respawning
This commit is contained in:
@@ -1,16 +1,14 @@
|
|||||||
package io.anuke.mindustry;
|
package io.anuke.mindustry;
|
||||||
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.text.InputFilter;
|
import android.text.InputFilter;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager.LayoutParams;
|
import android.view.WindowManager.LayoutParams;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
|
||||||
public class AndroidTextFieldDialog{
|
public class AndroidTextFieldDialog{
|
||||||
private Activity activity;
|
private Activity activity;
|
||||||
@@ -26,51 +24,43 @@ public class AndroidTextFieldDialog{
|
|||||||
|
|
||||||
public AndroidTextFieldDialog show() {
|
public AndroidTextFieldDialog show() {
|
||||||
|
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> {
|
||||||
@Override
|
Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown.");
|
||||||
public void run() {
|
AlertDialog dialog = builder.create();
|
||||||
Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown.");
|
|
||||||
AlertDialog dialog = builder.create();
|
dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||||
|
|
||||||
dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
dialog.show();
|
||||||
|
|
||||||
dialog.show();
|
});
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AndroidTextFieldDialog load() {
|
private AndroidTextFieldDialog load() {
|
||||||
|
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> {
|
||||||
|
|
||||||
@Override
|
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
|
||||||
public void run() {
|
LayoutInflater li = LayoutInflater.from(activity);
|
||||||
|
|
||||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
|
View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null);
|
||||||
LayoutInflater li = LayoutInflater.from(activity);
|
|
||||||
|
|
||||||
View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null);
|
alertDialogBuilder.setView(promptsView);
|
||||||
|
|
||||||
alertDialogBuilder.setView(promptsView);
|
|
||||||
|
|
||||||
userInput = (EditText) promptsView.findViewById(getResourceId("gdxDialogsEditTextInput", "id"));
|
userInput = (EditText) promptsView.findViewById(getResourceId("gdxDialogsEditTextInput", "id"));
|
||||||
|
|
||||||
alertDialogBuilder.setCancelable(false);
|
alertDialogBuilder.setCancelable(false);
|
||||||
builder = alertDialogBuilder;
|
builder = alertDialogBuilder;
|
||||||
|
|
||||||
isBuild = true;
|
isBuild = true;
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Wait till TextPrompt is built.
|
// Wait till TextPrompt is built.
|
||||||
while (!isBuild) {
|
while (!isBuild) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) { }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@@ -93,23 +83,17 @@ public class AndroidTextFieldDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) {
|
public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) {
|
||||||
builder.setNegativeButton(label, new DialogInterface.OnClickListener() {
|
builder.setNegativeButton(label, (dialog, id) -> dialog.cancel());
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
dialog.cancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) {
|
public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) {
|
||||||
builder.setPositiveButton(label, new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(label, (dialog, id) -> {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
if (listener != null && !userInput.getText().toString().isEmpty()) {
|
||||||
if (listener != null && !userInput.getText().toString().isEmpty()) {
|
listener.confirm(userInput.getText().toString());
|
||||||
listener.confirm(userInput.getText().toString());
|
}
|
||||||
}
|
|
||||||
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,8 +112,8 @@ public class AndroidTextFieldDialog{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface TextPromptListener{
|
public interface TextPromptListener{
|
||||||
public void confirm(String text);
|
void confirm(String text);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
package io.anuke.mindustry;
|
package io.anuke.mindustry;
|
||||||
|
|
||||||
|
|
||||||
|
import android.text.InputType;
|
||||||
import com.badlogic.gdx.Application.ApplicationType;
|
import com.badlogic.gdx.Application.ApplicationType;
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import io.anuke.ucore.scene.event.ChangeListener;
|
||||||
import android.text.InputType;
|
import io.anuke.ucore.scene.event.ClickListener;
|
||||||
import io.anuke.mindustry.AndroidTextFieldDialog.TextPromptListener;
|
|
||||||
import io.anuke.ucore.scene.event.InputEvent;
|
import io.anuke.ucore.scene.event.InputEvent;
|
||||||
import io.anuke.ucore.scene.event.InputListener;
|
import io.anuke.ucore.scene.event.InputListener;
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
import io.anuke.ucore.scene.ui.TextField;
|
||||||
import io.anuke.ucore.scene.event.ChangeListener;
|
|
||||||
import io.anuke.ucore.scene.event.ClickListener;
|
|
||||||
|
|
||||||
public class TextFieldDialogListener extends ClickListener{
|
public class TextFieldDialogListener extends ClickListener{
|
||||||
private TextField field;
|
private TextField field;
|
||||||
@@ -44,14 +42,12 @@ public class TextFieldDialogListener extends ClickListener{
|
|||||||
|
|
||||||
AndroidTextFieldDialog dialog = new AndroidTextFieldDialog();
|
AndroidTextFieldDialog dialog = new AndroidTextFieldDialog();
|
||||||
|
|
||||||
dialog.setTextPromptListener(new TextPromptListener(){
|
dialog.setTextPromptListener(text -> {
|
||||||
public void confirm(String text){
|
field.clearText();
|
||||||
field.clearText();
|
field.appendText(text);
|
||||||
field.appendText(text);
|
field.fire(new ChangeListener.ChangeEvent());
|
||||||
field.fire(new ChangeListener.ChangeEvent());
|
Gdx.graphics.requestRendering();
|
||||||
Gdx.graphics.requestRendering();
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(type == 0){
|
if(type == 0){
|
||||||
dialog.setInputType(InputType.TYPE_CLASS_TEXT);
|
dialog.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ public class NetClient extends Module {
|
|||||||
boolean connecting = false;
|
boolean connecting = false;
|
||||||
boolean gotData = false;
|
boolean gotData = false;
|
||||||
boolean kicked = false;
|
boolean kicked = false;
|
||||||
IntSet requests = new IntSet();
|
|
||||||
IntSet recieved = new IntSet();
|
IntSet recieved = new IntSet();
|
||||||
float playerSyncTime = 2;
|
float playerSyncTime = 2;
|
||||||
float dataTimeout = 60*18; //18 seconds timeout
|
float dataTimeout = 60*18; //18 seconds timeout
|
||||||
@@ -55,7 +54,6 @@ public class NetClient extends Module {
|
|||||||
|
|
||||||
Net.handle(Connect.class, packet -> {
|
Net.handle(Connect.class, packet -> {
|
||||||
Net.setClientLoaded(false);
|
Net.setClientLoaded(false);
|
||||||
requests.clear();
|
|
||||||
recieved.clear();
|
recieved.clear();
|
||||||
connecting = true;
|
connecting = true;
|
||||||
gotData = false;
|
gotData = false;
|
||||||
@@ -121,12 +119,11 @@ public class NetClient extends Module {
|
|||||||
SyncEntity entity = (SyncEntity) group.getByID(id);
|
SyncEntity entity = (SyncEntity) group.getByID(id);
|
||||||
|
|
||||||
if (entity == null || id == Vars.player.id) {
|
if (entity == null || id == Vars.player.id) {
|
||||||
if (!requests.contains(id) && id != Vars.player.id) {
|
if (id != Vars.player.id) {
|
||||||
UCore.log("Requesting entity " + id, "group " + group.getType());
|
UCore.log("Requesting entity " + id, "group " + group.getType());
|
||||||
requests.add(id);
|
|
||||||
EntityRequestPacket req = new EntityRequestPacket();
|
EntityRequestPacket req = new EntityRequestPacket();
|
||||||
req.id = id;
|
req.id = id;
|
||||||
Net.send(req, SendMode.tcp);
|
Net.send(req, SendMode.udp);
|
||||||
}
|
}
|
||||||
data.position(data.position() + SyncEntity.getWriteSize((Class<? extends SyncEntity>) group.getType()));
|
data.position(data.position() + SyncEntity.getWriteSize((Class<? extends SyncEntity>) group.getType()));
|
||||||
} else {
|
} else {
|
||||||
@@ -311,6 +308,13 @@ public class NetClient extends Module {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Net.handle(FriendlyFireChangePacket.class, packet -> Vars.control.setFriendlyFire(packet.enabled));
|
Net.handle(FriendlyFireChangePacket.class, packet -> Vars.control.setFriendlyFire(packet.enabled));
|
||||||
|
|
||||||
|
Net.handle(PlayerDeathPacket.class, packet -> {
|
||||||
|
Player player = Vars.control.playerGroup.getByID(packet.id);
|
||||||
|
if(player == null) return;
|
||||||
|
|
||||||
|
player.doRespawn();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -337,6 +341,12 @@ public class NetClient extends Module {
|
|||||||
return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name;
|
return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handlePlayerDeath(){
|
||||||
|
PlayerDeathPacket packet = new PlayerDeathPacket();
|
||||||
|
packet.id = Vars.player.id;
|
||||||
|
Net.send(packet, SendMode.tcp);
|
||||||
|
}
|
||||||
|
|
||||||
public void handleBlockConfig(Tile tile, byte data){
|
public void handleBlockConfig(Tile tile, byte data){
|
||||||
BlockConfigPacket packet = new BlockConfigPacket();
|
BlockConfigPacket packet = new BlockConfigPacket();
|
||||||
packet.data = data;
|
packet.data = data;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.utils.*;
|
import com.badlogic.gdx.utils.*;
|
||||||
|
import io.anuke.mindustry.Mindustry;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
@@ -66,6 +67,8 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
Net.sendStream(id, data);
|
Net.sendStream(id, data);
|
||||||
|
|
||||||
|
Mindustry.platforms.updateRPC();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> {
|
Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> {
|
||||||
@@ -184,7 +187,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
Net.handleServer(EntityRequestPacket.class, (cid, packet) -> {
|
Net.handleServer(EntityRequestPacket.class, (cid, packet) -> {
|
||||||
int id = packet.id;
|
int id = packet.id;
|
||||||
int dest = id;
|
int dest = cid;
|
||||||
if (Vars.control.playerGroup.getByID(id) != null) {
|
if (Vars.control.playerGroup.getByID(id) != null) {
|
||||||
Player player = Vars.control.playerGroup.getByID(id);
|
Player player = Vars.control.playerGroup.getByID(id);
|
||||||
PlayerSpawnPacket p = new PlayerSpawnPacket();
|
PlayerSpawnPacket p = new PlayerSpawnPacket();
|
||||||
@@ -195,6 +198,7 @@ public class NetServer extends Module{
|
|||||||
p.weaponleft = player.weaponLeft.id;
|
p.weaponleft = player.weaponLeft.id;
|
||||||
p.weaponright = player.weaponRight.id;
|
p.weaponright = player.weaponRight.id;
|
||||||
p.android = player.isAndroid;
|
p.android = player.isAndroid;
|
||||||
|
|
||||||
Net.sendTo(dest, p, SendMode.tcp);
|
Net.sendTo(dest, p, SendMode.tcp);
|
||||||
Gdx.app.error("Mindustry", "Replying to entity request (" + id + "): player, " + id);
|
Gdx.app.error("Mindustry", "Replying to entity request (" + id + "): player, " + id);
|
||||||
} else if (Vars.control.enemyGroup.getByID(id) != null) {
|
} else if (Vars.control.enemyGroup.getByID(id) != null) {
|
||||||
@@ -213,6 +217,16 @@ public class NetServer extends Module{
|
|||||||
Gdx.app.error("Mindustry", "Entity request target not found!");
|
Gdx.app.error("Mindustry", "Entity request target not found!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Net.handleServer(PlayerDeathPacket.class, (id, packet) -> {
|
||||||
|
Player player = connections.get(id);
|
||||||
|
if(player == null) return;
|
||||||
|
|
||||||
|
packet.id = player.id;
|
||||||
|
|
||||||
|
player.doRespawn();
|
||||||
|
Net.sendExcept(id, packet, SendMode.tcp);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(String message){
|
public void sendMessage(String message){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities;
|
|||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.resource.Mech;
|
import io.anuke.mindustry.resource.Mech;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
@@ -61,27 +62,37 @@ public class Player extends SyncEntity{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(){
|
public void onDeath(){
|
||||||
Effects.effect(Fx.explosion, this);
|
|
||||||
Effects.shake(4f, 5f, this);
|
|
||||||
Effects.sound("die", this);
|
|
||||||
|
|
||||||
if(isLocal){
|
if(isLocal){
|
||||||
remove();
|
remove();
|
||||||
}else{
|
if(Net.active()){
|
||||||
set(-9999, -9999);
|
Vars.netClient.handlePlayerDeath();
|
||||||
|
}
|
||||||
|
|
||||||
|
Effects.effect(Fx.explosion, this);
|
||||||
|
Effects.shake(4f, 5f, this);
|
||||||
|
Effects.sound("die", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO respawning doesn't work properly for multiplayer at all
|
//TODO respawning doesn't work properly for multiplayer at all
|
||||||
if(isLocal) {
|
if(isLocal) {
|
||||||
Vars.control.setRespawnTime(respawnduration);
|
Vars.control.setRespawnTime(respawnduration);
|
||||||
ui.hudfrag.fadeRespawn(true);
|
ui.hudfrag.fadeRespawn(true);
|
||||||
}else{
|
|
||||||
Timers.run(respawnduration, () -> {
|
|
||||||
heal();
|
|
||||||
set(Vars.control.getCore().worldx(), Vars.control.getCore().worldy());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, () -> {
|
||||||
|
heal();
|
||||||
|
set(Vars.control.getCore().worldx(), Vars.control.getCore().worldy());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
|
|||||||
@@ -496,4 +496,18 @@ public class Packets {
|
|||||||
enabled = buffer.get() == 1;
|
enabled = buffer.get() == 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class PlayerDeathPacket implements Packet{
|
||||||
|
public int id;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuffer buffer) {
|
||||||
|
buffer.putInt(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(ByteBuffer buffer) {
|
||||||
|
id = buffer.getInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class Registrator {
|
|||||||
ConnectConfirmPacket.class,
|
ConnectConfirmPacket.class,
|
||||||
GameOverPacket.class,
|
GameOverPacket.class,
|
||||||
FriendlyFireChangePacket.class,
|
FriendlyFireChangePacket.class,
|
||||||
|
PlayerDeathPacket.class,
|
||||||
};
|
};
|
||||||
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
|
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public class KryoServer implements ServerProvider {
|
|||||||
c.addressTCP = connection.getRemoteAddressTCP().toString();
|
c.addressTCP = connection.getRemoteAddressTCP().toString();
|
||||||
|
|
||||||
connections.add(kn);
|
connections.add(kn);
|
||||||
|
UCore.log("Adding connection #" + kn.id + " to list.");
|
||||||
Gdx.app.postRunnable(() -> Net.handleServerReceived(kn.id, c));
|
Gdx.app.postRunnable(() -> Net.handleServerReceived(kn.id, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +130,7 @@ public class KryoServer implements ServerProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void host(int port) throws IOException {
|
public void host(int port) throws IOException {
|
||||||
lastconnection = 0;
|
lastconnection = 0;
|
||||||
|
connections.clear();
|
||||||
server.bind(port, port);
|
server.bind(port, port);
|
||||||
webServer = new SocketServer(Vars.webPort);
|
webServer = new SocketServer(Vars.webPort);
|
||||||
webServer.start();
|
webServer.start();
|
||||||
@@ -147,6 +149,8 @@ public class KryoServer implements ServerProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
UCore.setPrivate(server, "shutdown", true);
|
UCore.setPrivate(server, "shutdown", true);
|
||||||
|
connections.clear();
|
||||||
|
lastconnection = 0;
|
||||||
|
|
||||||
Thread thread = new Thread(() ->{
|
Thread thread = new Thread(() ->{
|
||||||
try {
|
try {
|
||||||
@@ -226,6 +230,7 @@ public class KryoServer implements ServerProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void sendTo(int id, Object object, SendMode mode) {
|
public void sendTo(int id, Object object, SendMode mode) {
|
||||||
NetConnection conn = getByID(id);
|
NetConnection conn = getByID(id);
|
||||||
|
if(conn == null) throw new RuntimeException("Unable to find connection with ID " + id + "!");
|
||||||
conn.send(object, mode);
|
conn.send(object, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user