mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-08 23:07:33 +07:00
Many editor improvements, lang bugfixes, Syncable entity change
This commit is contained in:
@ -22,7 +22,7 @@ allprojects {
|
||||
appName = "Mindustry"
|
||||
gdxVersion = '1.9.8'
|
||||
aiVersion = '1.8.1'
|
||||
uCoreVersion = '82c0091'
|
||||
uCoreVersion = 'fe2f2dd'
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -3,6 +3,8 @@
|
||||
<source path="io/anuke/mindustry" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.Player" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.types.Enemy" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.EnemySpawn" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion" />
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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(){
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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<String> listener;
|
||||
|
||||
public MapSaveDialog(Consumer<String> 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()){
|
||||
|
@ -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){
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Class<?>> ids = new ObjectIntMap<>();
|
||||
|
||||
|
@ -281,4 +281,9 @@ public class Block{
|
||||
public static Block getByID(int id){
|
||||
return blocks.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
@ -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<Array<Host>> callback){
|
||||
callback.accept(new Array<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pingHost(String address, int port, Consumer<Host> valid, Consumer<IOException> 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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() {}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user