Changes to save importing, player sync fix, autosave on death fix

This commit is contained in:
Anuken
2018-01-09 13:19:36 -05:00
parent 4c16011480
commit 8e676494e3
19 changed files with 77 additions and 53 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 253 B

View File

@@ -3,7 +3,7 @@ text.discord=Join the mindustry discord!
text.gameover=The core was destroyed. text.gameover=The core was destroyed.
text.highscore=[YELLOW]New highscore! text.highscore=[YELLOW]New highscore!
text.lasted=You lasted until wave text.lasted=You lasted until wave
text.level.highscore=High Score: [accent] {0} text.level.highscore=High Score: [accent]{0}
text.level.delete.title=Confirm Delete text.level.delete.title=Confirm Delete
text.level.delete=Are you sure you want to delete\nthe map "[orange]{0}"? text.level.delete=Are you sure you want to delete\nthe map "[orange]{0}"?
text.level.select=Level Select text.level.select=Level Select

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -22,6 +22,7 @@ import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.ProductionBlocks;
import io.anuke.ucore.UCore; import io.anuke.ucore.UCore;
import io.anuke.ucore.core.*; import io.anuke.ucore.core.*;
import io.anuke.ucore.core.Inputs.Axis; import io.anuke.ucore.core.Inputs.Axis;
@@ -407,6 +408,10 @@ public class Control extends Module{
Timers.run(60, ()-> ui.restart.show()); Timers.run(60, ()-> ui.restart.show());
} }
public boolean isGameOver(){
return core.block() != ProductionBlocks.core;
}
float waveSpacing(){ float waveSpacing(){
int scale = Settings.getInt("difficulty"); int scale = Settings.getInt("difficulty");
float out = (scale == 0 ? 2f : scale == 1f ? 1f : 0.5f); float out = (scale == 0 ? 2f : scale == 1f ? 1f : 0.5f);

View File

@@ -20,6 +20,6 @@ public class GameState{
} }
public enum State{ public enum State{
paused, playing, menu, dead paused, playing, menu
} }
} }

View File

@@ -107,7 +107,6 @@ public class Renderer extends RendererModule{
} }
if(control.core.block() == ProductionBlocks.core){ if(control.core.block() == ProductionBlocks.core){
if(!smoothcam){ if(!smoothcam){
setCamera(player.x, player.y); setCamera(player.x, player.y);
}else{ }else{

View File

@@ -186,7 +186,6 @@ public class World extends Module{
if(control.getCore() == null) return; if(control.getCore() == null) return;
//TODO multiblock core
control.getInput().placeBlock(control.getCore().x, control.getCore().y, ProductionBlocks.core, 0, false, false); control.getInput().placeBlock(control.getCore().x, control.getCore().y, ProductionBlocks.core, 0, false, false);
if(!map.name.equals("tutorial")){ if(!map.name.equals("tutorial")){

View File

@@ -29,6 +29,7 @@ public class Player extends DestructibleEntity implements Syncable{
public float angle; public float angle;
public transient float targetAngle = 0f; public transient float targetAngle = 0f;
public transient boolean dashing = false;
public transient int clientid; public transient int clientid;
public transient boolean isLocal = false; public transient boolean isLocal = false;
@@ -70,7 +71,7 @@ public class Player extends DestructibleEntity implements Syncable{
Effects.shake(4f, 5f, this); Effects.shake(4f, 5f, this);
Effects.sound("die", this); Effects.sound("die", this);
//TODO respawning doesn't work for multiplayer //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);
@@ -120,7 +121,9 @@ public class Player extends DestructibleEntity implements Syncable{
return; return;
} }
float speed = Inputs.keyDown("dash") ? Player.dashSpeed : Player.speed; dashing = Inputs.keyDown("dash");
float speed = dashing ? Player.dashSpeed : Player.speed;
if(health < maxhealth && Timers.get(this, "regen", 50)) if(health < maxhealth && Timers.get(this, "regen", 50))
health ++; health ++;
@@ -148,7 +151,7 @@ public class Player extends DestructibleEntity implements Syncable{
weaponRight.update(player, false); weaponRight.update(player, false);
} }
if(Inputs.keyDown("dash") && Timers.get(this, "dashfx", 3) && vector.len() > 0){ if(dashing && Timers.get(this, "dashfx", 3) && vector.len() > 0){
Angles.translation(angle + 180, 3f); Angles.translation(angle + 180, 3f);
Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y()); Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y());
} }

View File

@@ -68,7 +68,7 @@ public class Shield extends Entity{
@Override @Override
public void draw(){ public void draw(){
if(!(tile.block() instanceof ShieldBlock)){ if(!(tile.block() instanceof ShieldBlock) || radius <= 1f){
return; return;
} }

View File

@@ -228,6 +228,8 @@ public class NetworkIO {
Vars.world.loadMap(Vars.world.maps().getMap(mapid), seed); Vars.world.loadMap(Vars.world.maps().getMap(mapid), seed);
Vars.renderer.clearTiles(); Vars.renderer.clearTiles();
Vars.player.set(Vars.control.getCore().worldx(), Vars.control.getCore().worldy());
for(int x = 0; x < Vars.world.width(); x ++){ for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){ for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y); Tile tile = Vars.world.tile(x, y);

View File

@@ -45,7 +45,7 @@ public class Saves {
} }
public void update(){ public void update(){
if(!GameState.is(State.menu) && !GameState.is(State.dead) && current != null && current.isAutosave()){ if(!GameState.is(State.menu) && !Vars.control.isGameOver() && current != null && current.isAutosave()){
time += Timers.delta(); time += Timers.delta();
if(time > Settings.getInt("saveinterval")*60) { if(time > Settings.getInt("saveinterval")*60) {
saving = true; saving = true;
@@ -85,6 +85,16 @@ public class Saves {
current = slot; current = slot;
} }
public void importSave(FileHandle file) throws IOException{
SaveSlot slot = new SaveSlot(nextSlot);
slot.importFile(file);
nextSlot ++;
slot.setName(file.nameWithoutExtension());
saves.add(slot);
slot.meta = SaveIO.getData(slot.index);
current = slot;
}
public Array<SaveSlot> getSaveSlots(){ public Array<SaveSlot> getSaveSlots(){
return saves; return saves;
} }

View File

@@ -24,7 +24,7 @@ public interface Syncable {
public static final SyncType<Player> player = new SyncType<Player>() { public static final SyncType<Player> player = new SyncType<Player>() {
@Override @Override
public float[] write(Player entity) { public float[] write(Player entity) {
return new float[]{entity.x, entity.y, entity.angle, entity.health}; return new float[]{entity.x, entity.y, entity.angle, entity.health, entity.dashing ? 1f : -1f};
} }
@Override @Override
@@ -32,6 +32,7 @@ public interface Syncable {
entity.getInterpolator().target.set(data[0], data[1]); entity.getInterpolator().target.set(data[0], data[1]);
entity.getInterpolator().targetrot = data[2]; entity.getInterpolator().targetrot = data[2];
entity.health = (int)data[3]; entity.health = (int)data[3];
entity.dashing = data[4] > 0;
} }
@Override @Override
@@ -46,6 +47,11 @@ public interface Syncable {
Effects.effect(Fx.dashsmoke, entity.x + Angles.x(), entity.y + Angles.y()); Effects.effect(Fx.dashsmoke, entity.x + Angles.x(), entity.y + Angles.y());
} }
if(entity.dashing && 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.x = Mathf.lerpDelta(entity.x, i.target.x, 0.4f);
entity.y = Mathf.lerpDelta(entity.y, i.target.y, 0.4f); entity.y = Mathf.lerpDelta(entity.y, i.target.y, 0.4f);
entity.angle = Mathf.lerpAngDelta(entity.angle, i.targetrot, 0.6f); entity.angle = Mathf.lerpAngDelta(entity.angle, i.targetrot, 0.6f);

View File

@@ -66,6 +66,11 @@ public class LevelDialog extends FloatingDialog{
maps.row(); maps.row();
} }
//TODO this is a hack
if(!Settings.has("hiscore" + map.name)){
Settings.defaults("hiscore" + map.name, 1);
}
Table inset = new Table("pane-button"); Table inset = new Table("pane-button");
inset.add("[accent]" + Bundles.get("map."+map.name+".name", map.name)).pad(3f); inset.add("[accent]" + Bundles.get("map."+map.name+".name", map.name)).pad(3f);
inset.row(); inset.row();

View File

@@ -89,24 +89,6 @@ public class LoadDialog extends FloatingDialog{
dialog.content().row(); dialog.content().row();
dialog.content().addImageTextButton("$text.save.import", "icon-save", 14*3, () -> {
new FileChooser("$text.save.import", f -> f.extension().equals("mins"), true, file -> {
if(SaveIO.isSaveValid(file)){
try{
slot.importFile(file);
setup();
}catch (IOException e){
Vars.ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false)));
}
}else{
Vars.ui.showError("$text.save.import.invalid");
}
dialog.hide();
}).show();
});
dialog.content().row();
dialog.content().addImageTextButton("$text.save.export", "icon-load", 14*3, () -> { dialog.content().addImageTextButton("$text.save.export", "icon-load", 14*3, () -> {
new FileChooser("$text.save.export", false, file -> { new FileChooser("$text.save.export", false, file -> {
try{ try{
@@ -151,11 +133,29 @@ public class LoadDialog extends FloatingDialog{
} }
public void addSetup(){ public void addSetup(){
if(Vars.control.getSaves().getSaveSlots().size != 0) return; if(Vars.control.getSaves().getSaveSlots().size == 0) {
slots.row();
slots.addButton("$text.save.none", "clear", () -> {
}).disabled(true).fillX().margin(20f).minWidth(340f).height(80f).pad(4f);
}
slots.row(); slots.row();
slots.addButton("$text.save.none", "clear", ()->{})
.disabled(true).fillX().margin(20f).minWidth(340f).height(80f).pad(4f); slots.addImageTextButton("$text.save.import", "icon-add", "clear", 14*3, () -> {
new FileChooser("$text.save.import", f -> f.extension().equals("mins"), true, file -> {
if(SaveIO.isSaveValid(file)){
try{
Vars.control.getSaves().importSave(file);
setup();
}catch (IOException e){
Vars.ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false)));
}
}else{
Vars.ui.showError("$text.save.import.invalid");
}
}).show();
}).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4);
} }
public void modifyButton(TextButton button, SaveSlot slot){ public void modifyButton(TextButton button, SaveSlot slot){

View File

@@ -11,14 +11,14 @@ public class RestartDialog extends Dialog {
public RestartDialog(){ public RestartDialog(){
super("$text.gameover", "dialog"); super("$text.gameover", "dialog");
shown(()->{ shown(() -> {
content().clearChildren(); content().clearChildren();
if(control.isHighScore()){ if(control.isHighScore()){
content().add("$text.highscore").pad(6); content().add("$text.highscore").pad(6);
content().row(); content().row();
} }
content().add("$text.lasted").pad(12).get(); content().add("$text.lasted").pad(12).get();
content().add("[GREEN]" + control.getWave()); content().add("[accent]" + control.getWave());
pack(); pack();
}); });
@@ -26,6 +26,6 @@ public class RestartDialog extends Dialog {
hide(); hide();
GameState.set(State.menu); GameState.set(State.menu);
control.reset(); control.reset();
}); }).size(130f, 60f);
} }
} }

View File

@@ -26,7 +26,7 @@ public class Generator{
/**Returns world size.*/ /**Returns world size.*/
public static void generate(Pixmap pixmap, Tile[][] tiles){ public static void generate(Pixmap pixmap, Tile[][] tiles){
boolean hasenemies = true, hascore = false;; boolean hasenemies = true, hascore = false;
Noise.setSeed(Vars.world.getSeed()); Noise.setSeed(Vars.world.getSeed());

View File

@@ -19,7 +19,7 @@ public class CoreBlock extends Block {
@Override @Override
public int handleDamage(Tile tile, int amount){ public int handleDamage(Tile tile, int amount){
return Vars.debug ? 0 : amount; return Vars.debug ? amount : amount;
} }
@Override @Override

View File

@@ -29,7 +29,7 @@ public class Smelter extends Block{
protected float burnDuration = 60f; //by default, the fuel will burn 60 frames, so that's 2 items/fuel at most protected float burnDuration = 60f; //by default, the fuel will burn 60 frames, so that's 2 items/fuel at most
protected Effect craftEffect = Fx.smelt, burnEffect = Fx.fuelburn; protected Effect craftEffect = Fx.smelt, burnEffect = Fx.fuelburn;
protected int capacity = 30; protected int capacity = 20;
public Smelter(String name) { public Smelter(String name) {
super(name); super(name);
@@ -92,15 +92,16 @@ public class Smelter extends Block{
@Override @Override
public boolean acceptItem(Item item, Tile tile, Tile source){ public boolean acceptItem(Item item, Tile tile, Tile source){
int amount = 0;
boolean isInput = false; boolean isInput = false;
for(Item req : inputs){ for(Item req : inputs){
if(req == item) isInput = true; if(req == item){
amount += tile.entity.getItem(req); isInput = true;
break;
}
} }
return (isInput && amount < capacity) || (item == fuel && tile.entity.getItem(fuel) < capacity); return (isInput && tile.entity.getItem(item) < capacity) || (item == fuel && tile.entity.getItem(fuel) < capacity);
} }
@Override @Override
@@ -120,17 +121,12 @@ public class Smelter extends Block{
@Override @Override
public void drawSelect(Tile tile){ public void drawSelect(Tile tile){
//all required items are put into one big capacity buffer //draw a separate bar for each requirement
int totalCapacity = capacity; for(int i = 0; i < inputs.length; i ++){
int amount = 0; float fract = ((float)tile.entity.getItem(inputs[i]))/capacity;
for(Item item : inputs){ Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 6 + i*4, fract);
amount += tile.entity.getItem(item);
} }
float fract = ((float)amount)/totalCapacity;
Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 6, fract);
} }
@Override @Override

View File

@@ -136,6 +136,7 @@ public class KryoServer implements ServerProvider {
@Override @Override
public void sendStream(int id, Streamable stream) { public void sendStream(int id, Streamable stream) {
Connection connection = getByID(id); Connection connection = getByID(id);
UCore.log("Sending stream: " + stream.getClass().getSimpleName() + " / " + stream.stream.available());
connection.addListener(new InputStreamSender(stream.stream, 512) { connection.addListener(new InputStreamSender(stream.stream, 512) {
int id; int id;
@@ -147,14 +148,12 @@ public class KryoServer implements ServerProvider {
begin.type = stream.getClass(); begin.type = stream.getClass();
connection.sendTCP(begin); connection.sendTCP(begin);
id = begin.id; id = begin.id;
UCore.log("Sending begin packet: " + begin);
} }
protected Object next (byte[] bytes) { protected Object next (byte[] bytes) {
StreamChunk chunk = new StreamChunk(); StreamChunk chunk = new StreamChunk();
chunk.id = id; chunk.id = id;
chunk.data = bytes; chunk.data = bytes;
UCore.log("Sending chunk of size " + chunk.data.length);
return chunk; //wrap the byte[] with an object so the receiving side knows how to handle it. return chunk; //wrap the byte[] with an object so the receiving side knows how to handle it.
} }
}); });