More multiplayer setup, possible android support

This commit is contained in:
Anuken
2017-12-31 22:06:18 -05:00
parent 701c7f6e78
commit 62ae6dc159
13 changed files with 354 additions and 206 deletions

View File

@@ -221,9 +221,8 @@ public class Control extends Module{
wavetime = waveSpacing();
Entities.clear();
enemies = 0;
if(!android)
player.add();
player.add();
player.heal();
clearItems();

View File

@@ -100,8 +100,12 @@ public class NetClient extends Module {
entity = Vars.control.playerGroup.getByID(id);
}
Syncable sync = ((Syncable)entity);
if(sync == null) continue;
//augh
((Interpolator)((Syncable)entity).getInterpolator()).type.read(entity, packet.data[i]);
((Interpolator)sync.getInterpolator()).type.read(entity, packet.data[i]);
}
}
});
@@ -151,8 +155,10 @@ public class NetClient extends Module {
});
Net.handle(EnemyDeathPacket.class, spawn -> {
Enemy enemy = Vars.control.enemyGroup.getByID(spawn.id);
if(enemy != null) enemy.onDeath();
Gdx.app.postRunnable(() -> {
Enemy enemy = Vars.control.enemyGroup.getByID(spawn.id);
if (enemy != null) enemy.onDeath();
});
});
Net.handle(PathPacket.class, packet -> {
@@ -170,6 +176,24 @@ public class NetClient extends Module {
Entity owner = Vars.control.enemyGroup.getByID(packet.owner);
Bullet bullet = new Bullet(type, owner, packet.x, packet.y, packet.angle).add();
});
Net.handle(BlockDestroyPacket.class, packet -> {
Tile tile = Vars.world.tile(packet.position % Vars.world.width(), packet.position / Vars.world.width());
if(tile.entity != null){
tile.entity.onDeath(true);
}
});
Net.handle(BlockUpdatePacket.class, packet -> {
Tile tile = Vars.world.tile(packet.position % Vars.world.width(), packet.position / Vars.world.width());
if(tile.entity != null){
tile.entity.health = packet.health;
}
});
Net.handle(BlockSyncPacket.class, packet -> {
//TODO implementation, load data...
});
}
public void update(){

View File

@@ -2,11 +2,13 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.IntMap;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.io.NetworkIO;
import io.anuke.mindustry.net.Net;
@@ -22,10 +24,12 @@ import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Mathf;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class NetServer extends Module{
@@ -66,7 +70,6 @@ public class NetServer extends Module{
UCore.log("Sending entities: " + Arrays.toString(dp.players));
//TODO send pathfind positions
//TODO new denser format
//TODO save enemy nodes
Net.sendTo(packet.id, dp, SendMode.tcp);
@@ -166,6 +169,19 @@ public class NetServer extends Module{
Net.send(packet, SendMode.tcp);
}
public void handleBlockDestroyed(TileEntity entity){
BlockDestroyPacket packet = new BlockDestroyPacket();
packet.position = entity.tile.packedPosition();
Net.send(packet, SendMode.tcp);
}
public void handleBlockDamaged(TileEntity entity){
BlockUpdatePacket packet = new BlockUpdatePacket();
packet.health = entity.health;
packet.position = entity.tile.packedPosition();
Net.send(packet, SendMode.udp);
}
public void update(){
if(!Net.server()) return;
@@ -220,18 +236,59 @@ public class NetServer extends Module{
if(Timers.get("serverBlockSync", blockSyncTime)){
BlockSyncPacket packet = new BlockSyncPacket();
//TODO
IntArray connections = Net.getConnections();
for(int i = 0; i < connections.size; i ++){
int id = connections.get(i);
Player player = this.connections.get(i);
int x = Mathf.scl2(player.x, Vars.tilesize);
int y = Mathf.scl2(player.y, Vars.tilesize);
}
//TODO sync to each player entity
}
}
public void sendBlockSync(int client){
public void sendBlockSync(int client, int x, int y, int viewx, int viewy){
BlockSyncPacket packet = new BlockSyncPacket();
ByteArrayOutputStream bs = new ByteArrayOutputStream();
DataOutputStream stream = new DataOutputStream(bs);
//TODO
try {
DataOutputStream stream = new DataOutputStream(bs);
for (int rx = -viewx / 2; rx <= viewx / 2; rx++) {
for (int ry = -viewy / 2; ry <= viewy / 2; ry++) {
Tile tile = Vars.world.tile(x + rx, y + ry);
if (tile == null || tile.entity == null) continue;
stream.writeInt(tile.packedPosition());
byte times = 0;
for(; times < tile.entity.timer.getTimes().length; times ++){
if(tile.entity.timer.getTimes()[times] > 0){
break;
}
}
stream.writeByte(times);
for(int i = 0; i < times; i ++){
stream.writeFloat(tile.entity.timer.getTimes()[times]);
}
tile.entity.write(stream);
}
}
}catch (IOException e){
throw new RuntimeException(e);
}
//TODO finish
packet.stream = new ByteArrayInputStream(bs.toByteArray());
Net.sendStream(client, packet);
}
}

View File

@@ -79,20 +79,22 @@ public class Player extends DestructibleEntity implements Syncable{
@Override
public void draw(){
if(Vars.debug && (!Vars.showPlayer || !Vars.showUI)) return;
if((Vars.debug && (!Vars.showPlayer || !Vars.showUI)) || (Vars.android && isLocal)) return;
String part = Vars.android ? "ship" : "mech";
if(Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){
Draw.rect("mech-"+mech.name(), (int)x, (int)y, angle-90);
Draw.rect(part+"-"+mech.name(), (int)x, (int)y, angle-90);
}else{
Draw.rect("mech-"+mech.name(), x, y, angle-90);
Draw.rect(part+"-"+mech.name(), x, y, angle-90);
}
}
@Override
public void update(){
if(!isLocal){
if(!isDead()) inter.update(this);
if(!isLocal || android){
if(!isDead() && !isLocal) inter.update(this);
return;
}

View File

@@ -1,12 +1,9 @@
package io.anuke.mindustry.entities;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
@@ -18,6 +15,10 @@ import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class TileEntity extends Entity{
public Tile tile;
public int[] items = new int[Item.getAllItems().size];
@@ -54,19 +55,28 @@ public class TileEntity extends Entity{
}
public void onDeath(){
if(tile.block() == ProductionBlocks.core){
Vars.control.coreDestroyed();
onDeath(false);
}
public void onDeath(boolean force){
if(Net.active() && Net.server()){
Vars.netServer.handleBlockDestroyed(this);
}
if(!dead) {
dead = true;
Block block = tile.block();
if(!Net.active() || Net.server() || force){
if(tile.block() == ProductionBlocks.core){
Vars.control.coreDestroyed();
}
block.onDestroyed(tile);
if(!dead) {
dead = true;
Block block = tile.block();
Vars.world.removeBlock(tile);
remove();
block.onDestroyed(tile);
Vars.world.removeBlock(tile);
remove();
}
}
}
@@ -80,6 +90,10 @@ public class TileEntity extends Entity{
int amount = tile.block().handleDamage(tile, damage);
health -= amount;
if(health <= 0) onDeath();
if(Net.active() && Net.server()){
Vars.netServer.handleBlockDamaged(this);
}
}
public boolean collide(Bullet other){

View File

@@ -1,15 +1,15 @@
package io.anuke.mindustry.input;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.input.GestureDetector.GestureAdapter;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*;
public class GestureHandler extends GestureAdapter{
AndroidInput input;
@@ -49,8 +49,10 @@ public class GestureHandler extends GestureAdapter{
if(!Vars.control.showCursor() && !(player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && player.placeMode.lockCamera) &&
!(player.recipe == null && player.breakMode.lockCamera)){
player.x -= deltaX*Core.camera.zoom/Core.cameraScale;
player.y += deltaY*Core.camera.zoom/Core.cameraScale;
float dx = deltaX*Core.camera.zoom/Core.cameraScale, dy = deltaY*Core.camera.zoom/Core.cameraScale;
player.x -= dx;
player.y += dy;
player.angle = Mathf.lerpAngDelta(player.angle, Mathf.atan2(dx, dy), 0.5f);
}else if(player.placeMode.lockCamera && (player.placeMode.pan && player.recipe != null)){
input.mousex += deltaX;
input.mousey += deltaY;

View File

@@ -1,6 +1,7 @@
package io.anuke.mindustry.net;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.net.Streamable.StreamBegin;
@@ -48,6 +49,11 @@ public class Net{
server = false;
active = false;
}
/**Returns a list of all connections IDs.*/
public static IntArray getConnections(){
return serverProvider.getConnections();
}
/**Send an object to all connected clients, or to the server if this is a client.*/
public static void send(Object object, SendMode mode){
@@ -182,6 +188,8 @@ public class Net{
public void sendExcept(int id, Object object, SendMode mode);
/**Close the server connection.*/
public void close();
/**Return all connected users.*/
public IntArray getConnections();
/**Register classes to be sent.*/
public void register(Class<?>... types);
}

View File

@@ -96,6 +96,6 @@ public class Packets {
}
public static class BlockUpdatePacket{
public int health;
public int health, position;
}
}

View File

@@ -29,6 +29,8 @@ public class Registrator {
PathPacket.class,
BulletPacket.class,
EnemyDeathPacket.class,
BlockUpdatePacket.class,
BlockDestroyPacket.class,
Class.class,
byte[].class,

View File

@@ -1,9 +1,14 @@
package io.anuke.mindustry.net;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
//TODO clean up this giant mess
@@ -36,6 +41,11 @@ public interface Syncable {
entity.set(i.target.x, i.target.y);
}
if(Vars.android && i.target.dst(entity.x, entity.y) > 2f && Timers.get(entity, "dashfx", 3)){
Angles.translation(entity.angle + 180, 3f);
Effects.effect(Fx.dashsmoke, entity.x + Angles.x(), entity.y + Angles.y());
}
entity.x = Mathf.lerpDelta(entity.x, i.target.x, 0.4f);
entity.y = Mathf.lerpDelta(entity.y, i.target.y, 0.4f);
entity.angle = Mathf.lerpAngDelta(entity.angle, i.targetrot, 0.6f);