Changes to save importing, player sync fix, autosave on death fix
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 253 B |
@@ -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 |
@@ -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;
|
||||||
@@ -406,6 +407,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");
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ public class GameState{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum State{
|
public enum State{
|
||||||
paused, playing, menu, dead
|
paused, playing, menu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -185,8 +185,7 @@ public class World extends Module{
|
|||||||
Generator.generate(map.pixmap, tiles);
|
Generator.generate(map.pixmap, tiles);
|
||||||
|
|
||||||
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")){
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -119,8 +120,10 @@ public class Player extends DestructibleEntity implements Syncable{
|
|||||||
if(!isDead() && !isLocal) inter.update(this);
|
if(!isDead() && !isLocal) inter.update(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dashing = Inputs.keyDown("dash");
|
||||||
|
|
||||||
float speed = Inputs.keyDown("dash") ? Player.dashSpeed : Player.speed;
|
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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -65,6 +65,11 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
if(i % maxwidth == 0){
|
if(i % maxwidth == 0){
|
||||||
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);
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user