Implemented automatic co-op sector change sync
This commit is contained in:
@@ -17,7 +17,9 @@ linkfail = Failed to open link!\nThe URL has been copied to your clipboard.
|
|||||||
screenshot = Screenshot saved to {0}
|
screenshot = Screenshot saved to {0}
|
||||||
screenshot.invalid = Map too large, potentially not enough memory for screenshot.
|
screenshot.invalid = Map too large, potentially not enough memory for screenshot.
|
||||||
gameover = Game Over
|
gameover = Game Over
|
||||||
|
gameover.disconnect = Disconnect
|
||||||
gameover.pvp = The[accent] {0}[] team is victorious!
|
gameover.pvp = The[accent] {0}[] team is victorious!
|
||||||
|
gameover.waiting = [accent]Waiting for next map...
|
||||||
highscore = [accent]New highscore!
|
highscore = [accent]New highscore!
|
||||||
copied = Copied.
|
copied = Copied.
|
||||||
indev.popup = [accent]v6[] is currently in [accent]beta[].\n[lightgray]This means:[]\n[scarlet]- The campaign is unfinished[]\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[].
|
indev.popup = [accent]v6[] is currently in [accent]beta[].\n[lightgray]This means:[]\n[scarlet]- The campaign is unfinished[]\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[].
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import mindustry.type.*;
|
|||||||
public class Planets implements ContentList{
|
public class Planets implements ContentList{
|
||||||
public static Planet
|
public static Planet
|
||||||
sun,
|
sun,
|
||||||
|
//tantros,
|
||||||
serpulo;
|
serpulo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -32,6 +33,17 @@ public class Planets implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
/*tantros = new Planet("tantros", sun, 2, 0.8f){{
|
||||||
|
generator = new TantrosPlanetGenerator();
|
||||||
|
meshLoader = () -> new HexMesh(this, 4);
|
||||||
|
atmosphereColor = Color.valueOf("3db899");
|
||||||
|
startSector = 10;
|
||||||
|
atmosphereRadIn = -0.01f;
|
||||||
|
atmosphereRadOut = 0.3f;
|
||||||
|
accessible = false;
|
||||||
|
visible = false;
|
||||||
|
}};*/
|
||||||
|
|
||||||
serpulo = new Planet("serpulo", sun, 3, 1){{
|
serpulo = new Planet("serpulo", sun, 3, 1){{
|
||||||
generator = new SerpuloPlanetGenerator();
|
generator = new SerpuloPlanetGenerator();
|
||||||
meshLoader = () -> new HexMesh(this, 6);
|
meshLoader = () -> new HexMesh(this, 6);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import mindustry.input.*;
|
|||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.io.SaveIO.*;
|
import mindustry.io.SaveIO.*;
|
||||||
import mindustry.maps.Map;
|
import mindustry.maps.Map;
|
||||||
|
import mindustry.net.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -162,7 +163,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
Events.on(GameOverEvent.class, e -> {
|
Events.on(GameOverEvent.class, e -> {
|
||||||
if(state.isCampaign() && !net.client() && !headless){
|
if(state.isCampaign() && !net.client() && !headless){
|
||||||
|
|
||||||
//delete the save, it is gone.
|
//save gameover sate immediately
|
||||||
if(saves.getCurrent() != null && !state.rules.tutorial){
|
if(saves.getCurrent() != null && !state.rules.tutorial){
|
||||||
saves.getCurrent().save();
|
saves.getCurrent().save();
|
||||||
}
|
}
|
||||||
@@ -279,6 +280,10 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void playSector(@Nullable Sector origin, Sector sector){
|
public void playSector(@Nullable Sector origin, Sector sector){
|
||||||
|
playSector(origin, sector, new WorldReloader());
|
||||||
|
}
|
||||||
|
|
||||||
|
void playSector(@Nullable Sector origin, Sector sector, WorldReloader reloader){
|
||||||
ui.loadAnd(() -> {
|
ui.loadAnd(() -> {
|
||||||
if(saves.getCurrent() != null && state.isGame()){
|
if(saves.getCurrent() != null && state.isGame()){
|
||||||
control.saves.getCurrent().save();
|
control.saves.getCurrent().save();
|
||||||
@@ -291,7 +296,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
if(slot != null && !clearSectors){
|
if(slot != null && !clearSectors){
|
||||||
|
|
||||||
try{
|
try{
|
||||||
net.reset();
|
reloader.begin();
|
||||||
slot.load();
|
slot.load();
|
||||||
slot.setAutosave(true);
|
slot.setAutosave(true);
|
||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
@@ -305,7 +310,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
sector.save = null;
|
sector.save = null;
|
||||||
slot.delete();
|
slot.delete();
|
||||||
//play again
|
//play again
|
||||||
playSector(origin, sector);
|
playSector(origin, sector, reloader);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,6 +336,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.set(State.playing);
|
state.set(State.playing);
|
||||||
|
reloader.end();
|
||||||
|
|
||||||
}catch(SaveException e){
|
}catch(SaveException e){
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
@@ -341,8 +347,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
}
|
}
|
||||||
ui.planet.hide();
|
ui.planet.hide();
|
||||||
}else{
|
}else{
|
||||||
net.reset();
|
reloader.begin();
|
||||||
logic.reset();
|
|
||||||
world.loadSector(sector);
|
world.loadSector(sector);
|
||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
//assign origin when launching
|
//assign origin when launching
|
||||||
@@ -352,6 +357,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
control.saves.saveSector(sector);
|
control.saves.saveSector(sector);
|
||||||
Events.fire(new SectorLaunchEvent(sector));
|
Events.fire(new SectorLaunchEvent(sector));
|
||||||
Events.fire(Trigger.newGame);
|
Events.fire(Trigger.newGame);
|
||||||
|
reloader.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public class PlanetRenderer implements Disposable{
|
|||||||
|
|
||||||
Vec3 center = planet.parent.position;
|
Vec3 center = planet.parent.position;
|
||||||
float radius = planet.orbitRadius;
|
float radius = planet.orbitRadius;
|
||||||
int points = (int)(radius * 50);
|
int points = (int)(radius * 10);
|
||||||
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray));
|
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray));
|
||||||
batch.flush(Gl.lineLoop);
|
batch.flush(Gl.lineLoop);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package mindustry.maps.planet;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import mindustry.maps.generators.*;
|
||||||
|
|
||||||
|
public class TantrosPlanetGenerator extends PlanetGenerator{
|
||||||
|
Color c1 = Color.valueOf("5057a6"), c2 = Color.valueOf("272766"), out = new Color();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getHeight(Vec3 position){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getColor(Vec3 position){
|
||||||
|
float depth = (float)noise.octaveNoise3D(2, 0.56, 1.7f, position.x, position.y, position.z) / 1.7f;
|
||||||
|
return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(0.6f);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package mindustry.net;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.struct.Seq.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
/** Handles player state for sending to every connected player*/
|
||||||
|
public class WorldReloader{
|
||||||
|
Seq<Player> players = new Seq<>();
|
||||||
|
boolean wasServer = false;
|
||||||
|
boolean began = false;
|
||||||
|
|
||||||
|
/** Begins reloading the world. Sends world begin packets to each user and stores player state.
|
||||||
|
* If the current client is not a server, this resets state and disconnects. */
|
||||||
|
public void begin(){
|
||||||
|
//don't begin twice
|
||||||
|
if(began) return;
|
||||||
|
|
||||||
|
if(wasServer = net.server()){
|
||||||
|
players.clear();
|
||||||
|
|
||||||
|
for(Player p : Groups.player){
|
||||||
|
if(p.isLocal()) continue;
|
||||||
|
|
||||||
|
players.add(p);
|
||||||
|
p.clearUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
logic.reset();
|
||||||
|
|
||||||
|
Call.worldDataBegin();
|
||||||
|
}else{
|
||||||
|
net.reset();
|
||||||
|
logic.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
began = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Ends reloading the world. Sends world data to each player.
|
||||||
|
* If the current client was not a server, does nothing.*/
|
||||||
|
public void end(){
|
||||||
|
if(wasServer){
|
||||||
|
for(Player p : players){
|
||||||
|
if(p.con == null) continue;
|
||||||
|
|
||||||
|
boolean wasAdmin = p.admin;
|
||||||
|
p.reset();
|
||||||
|
p.admin = wasAdmin;
|
||||||
|
if(state.rules.pvp){
|
||||||
|
p.team(netServer.assignTeam(p, new SeqIterable<>(players)));
|
||||||
|
}
|
||||||
|
netServer.sendWorldData(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,6 +53,8 @@ public class Planet extends UnlockableContent{
|
|||||||
public int startSector = 0;
|
public int startSector = 0;
|
||||||
/** Whether the bloom render effect is enabled. */
|
/** Whether the bloom render effect is enabled. */
|
||||||
public boolean bloom = false;
|
public boolean bloom = false;
|
||||||
|
/** Whether this planet is displayed. */
|
||||||
|
public boolean visible = true;
|
||||||
/** For suns, this is the color that shines on other planets. Does nothing for children. */
|
/** For suns, this is the color that shines on other planets. Does nothing for children. */
|
||||||
public Color lightColor = Color.white.cpy();
|
public Color lightColor = Color.white.cpy();
|
||||||
/** Atmosphere tint for landable planets. */
|
/** Atmosphere tint for landable planets. */
|
||||||
@@ -266,7 +268,7 @@ public class Planet extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean visible(){
|
public boolean visible(){
|
||||||
return true;
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(Mat3D projection, Mat3D transform){
|
public void draw(Mat3D projection, Mat3D transform){
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.ui.dialogs;
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
@@ -15,6 +16,8 @@ public class GameOverDialog extends BaseDialog{
|
|||||||
super("@gameover");
|
super("@gameover");
|
||||||
setFillParent(true);
|
setFillParent(true);
|
||||||
shown(this::rebuild);
|
shown(this::rebuild);
|
||||||
|
|
||||||
|
Events.on(ResetEvent.class, e -> hide());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(Team winner){
|
public void show(Team winner){
|
||||||
@@ -49,47 +52,51 @@ public class GameOverDialog extends BaseDialog{
|
|||||||
cont.pane(t -> {
|
cont.pane(t -> {
|
||||||
t.margin(13f);
|
t.margin(13f);
|
||||||
t.left().defaults().left();
|
t.left().defaults().left();
|
||||||
t.add(Core.bundle.format("stat.wave", state.stats.wavesLasted));
|
t.add(Core.bundle.format("stat.wave", state.stats.wavesLasted)).row();
|
||||||
t.row();
|
t.add(Core.bundle.format("stat.enemiesDestroyed", state.stats.enemyUnitsDestroyed)).row();
|
||||||
t.add(Core.bundle.format("stat.enemiesDestroyed", state.stats.enemyUnitsDestroyed));
|
t.add(Core.bundle.format("stat.built", state.stats.buildingsBuilt)).row();
|
||||||
t.row();
|
t.add(Core.bundle.format("stat.destroyed", state.stats.buildingsDestroyed)).row();
|
||||||
t.add(Core.bundle.format("stat.built", state.stats.buildingsBuilt));
|
t.add(Core.bundle.format("stat.deconstructed", state.stats.buildingsDeconstructed)).row();
|
||||||
t.row();
|
|
||||||
t.add(Core.bundle.format("stat.destroyed", state.stats.buildingsDestroyed));
|
|
||||||
t.row();
|
|
||||||
t.add(Core.bundle.format("stat.deconstructed", state.stats.buildingsDeconstructed));
|
|
||||||
t.row();
|
|
||||||
if(control.saves.getCurrent() != null){
|
if(control.saves.getCurrent() != null){
|
||||||
t.add(Core.bundle.format("stat.playtime", control.saves.getCurrent().getPlayTime()));
|
t.add(Core.bundle.format("stat.playtime", control.saves.getCurrent().getPlayTime())).row();
|
||||||
t.row();
|
|
||||||
}
|
}
|
||||||
if(state.isCampaign() && !state.stats.itemsDelivered.isEmpty()){
|
if(state.isCampaign() && !state.stats.itemsDelivered.isEmpty()){
|
||||||
t.add("@stat.delivered");
|
t.add("@stat.delivered").row();
|
||||||
t.row();
|
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
if(state.stats.itemsDelivered.get(item, 0) > 0){
|
if(state.stats.itemsDelivered.get(item, 0) > 0){
|
||||||
t.table(items -> {
|
t.table(items -> {
|
||||||
items.add(" [lightgray]" + state.stats.itemsDelivered.get(item, 0));
|
items.add(" [lightgray]" + state.stats.itemsDelivered.get(item, 0));
|
||||||
items.image(item.icon(Cicon.small)).size(8 * 3).pad(4);
|
items.image(item.icon(Cicon.small)).size(8 * 3).pad(4);
|
||||||
}).left();
|
}).left().row();
|
||||||
t.row();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(state.isCampaign() && net.client()){
|
||||||
|
t.add("@gameover.waiting").padTop(20f).row();
|
||||||
|
}
|
||||||
|
|
||||||
}).pad(12);
|
}).pad(12);
|
||||||
|
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
buttons.button("@continue", () -> {
|
if(net.client()){
|
||||||
hide();
|
buttons.button("@gameover.disconnect", () -> {
|
||||||
logic.reset();
|
logic.reset();
|
||||||
ui.planet.show();
|
net.reset();
|
||||||
}).size(130f, 60f);
|
hide();
|
||||||
|
state.set(State.menu);
|
||||||
|
}).size(170f, 60f);
|
||||||
|
}else{
|
||||||
|
buttons.button("@continue", () -> {
|
||||||
|
hide();
|
||||||
|
ui.planet.show();
|
||||||
|
}).size(170f, 60f);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
buttons.button("@menu", () -> {
|
buttons.button("@menu", () -> {
|
||||||
hide();
|
hide();
|
||||||
logic.reset();
|
logic.reset();
|
||||||
}).size(130f, 60f);
|
}).size(140f, 60f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
- Fixed file chooser crash [Android]
|
||||||
|
- Fixed time stopping after sector capture
|
||||||
|
- Moved Ruinous Shores map to more approppriate location
|
||||||
@@ -3,7 +3,6 @@ package mindustry.server;
|
|||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.struct.Seq.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.Timer;
|
import arc.util.Timer;
|
||||||
import arc.util.CommandHandler.*;
|
import arc.util.CommandHandler.*;
|
||||||
@@ -22,6 +21,7 @@ import mindustry.maps.Maps.*;
|
|||||||
import mindustry.mod.Mods.*;
|
import mindustry.mod.Mods.*;
|
||||||
import mindustry.net.Administration.*;
|
import mindustry.net.Administration.*;
|
||||||
import mindustry.net.Packets.*;
|
import mindustry.net.Packets.*;
|
||||||
|
import mindustry.net.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@@ -964,30 +964,16 @@ public class ServerControl implements ApplicationListener{
|
|||||||
private void play(boolean wait, Runnable run){
|
private void play(boolean wait, Runnable run){
|
||||||
inExtraRound = true;
|
inExtraRound = true;
|
||||||
Runnable r = () -> {
|
Runnable r = () -> {
|
||||||
Seq<Player> players = new Seq<>();
|
var reloader = new WorldReloader();
|
||||||
for(Player p : Groups.player){
|
|
||||||
players.add(p);
|
|
||||||
p.clearUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
logic.reset();
|
reloader.begin();
|
||||||
|
|
||||||
Call.worldDataBegin();
|
|
||||||
run.run();
|
run.run();
|
||||||
|
|
||||||
state.rules = state.map.applyRules(lastMode);
|
state.rules = state.map.applyRules(lastMode);
|
||||||
logic.play();
|
logic.play();
|
||||||
|
|
||||||
for(Player p : players){
|
reloader.end();
|
||||||
if(p.con == null) continue;
|
|
||||||
|
|
||||||
boolean wasAdmin = p.admin;
|
|
||||||
p.reset();
|
|
||||||
p.admin = wasAdmin;
|
|
||||||
if(state.rules.pvp){
|
|
||||||
p.team(netServer.assignTeam(p, new SeqIterable<>(players)));
|
|
||||||
}
|
|
||||||
netServer.sendWorldData(p);
|
|
||||||
}
|
|
||||||
inExtraRound = false;
|
inExtraRound = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user