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