Sector save remapping

This commit is contained in:
Anuken
2025-05-22 18:46:29 -04:00
parent 6d8096ded4
commit 268a87a6c0
5 changed files with 86 additions and 15 deletions

View File

@@ -412,7 +412,8 @@ public class Control implements ApplicationListener, Loadable{
try{
boolean hadNoCore = !sector.info.hasCore;
reloader.begin();
slot.load();
//pass in a sector context to make absolutely sure the correct sector is written; it may differ from what's in the meta due to remapping.
slot.load(world.makeSectorContext(sector));
slot.setAutosave(true);
state.rules.sector = sector;
state.rules.cloudColor = sector.planet.landCloudColor;

View File

@@ -579,10 +579,19 @@ public class World{
}
}
public WorldContext makeSectorContext(Sector sector){
return new Context(sector);
}
private class Context implements WorldContext{
private Sector sector;
Context(){}
Context(Sector sector){
this.sector = sector;
}
@Override
public Tile tile(int index){
return tiles.geti(index);
@@ -614,6 +623,12 @@ public class World{
public void end(){
endMapLoad();
}
@Nullable
@Override
public Sector getSector(){
return sector;
}
}
/** World context that applies filters after generation end. */

View File

@@ -13,6 +13,7 @@ import mindustry.io.*;
import mindustry.io.SaveIO.*;
import mindustry.maps.Map;
import mindustry.type.*;
import mindustry.world.*;
import java.io.*;
import java.text.*;
@@ -69,27 +70,72 @@ public class Saves{
}
}
//clear saves from build <130 that had the new naval sectors.
saves.removeAll(s -> {
if(s.getSector() != null && (s.getSector().id == 108 || s.getSector().id == 216) && s.meta.build <= 130 && s.meta.build > 0){
s.getSector().clearInfo();
s.file.delete();
return true;
}
return false;
});
lastSectorSave = saves.find(s -> s.isSector() && s.getName().equals(Core.settings.getString("last-sector-save", "<none>")));
ObjectSet<Sector> infoToClear = new ObjectSet<>(), remapped = new ObjectSet<>();
//automatically assign sector save slots
for(SaveSlot slot : saves){
if(slot.getSector() != null){
if(slot.getSector().save != null){
Log.warn("Sector @ has two corresponding saves: @ and @", slot.getSector(), slot.getSector().save.file, slot.file);
Sector sector = slot.getSector();
String name = slot.meta.tags.get("sectorPreset");
Sector remapTarget = null;
if(name != null){
if(!name.isEmpty()){ //if this save had a preset defined...
SectorPreset preset = content.sector(name);
//...place it in the right sector according to its preset
if(preset != null && preset.sector != sector){
remapTarget = preset.sector;
}
}
}else{ //there was no sector preset in the meta at all, which means this is a legacy save that may need mapping
SectorPreset target = content.sectors().find(s -> s.planet == sector.planet && s.originalPosition == sector.id);
if(target != null && target.sector != sector){ //there is indeed a sector preset that used to have this ID, and it needs remapping!
remapTarget = target.sector;
}
}
if(remapTarget != null){
//if the file name matches the destination of the remap, assume it has already been remapped, and skip the file movement procedure
if(!slot.file.equals(getSectorFile(remapTarget))){
Log.info("Remapping sectors: @: @ -> @", sector.id, remapTarget.id);
//overwrite the target sector's info with the save's info
Core.settings.putJson(remapTarget.planet.name + "-s-" + remapTarget.id + "-info", sector.info);
remapTarget.loadInfo();
//queue a clear of the sector that had its data moved
infoToClear.add(sector);
//add to the remapped list (if it was remapped, don't clear it!)
remapped.add(remapTarget);
remapTarget.save = slot;
try{
//move over save file
slot.file.moveTo(getSectorFile(remapTarget));
}catch(Exception e){
Log.err("Failed to move sector files when remapping: " + sector.id + " -> " + remapTarget.id, e);
}
}
remapTarget.save = slot;
slot.meta.rules.sector = remapTarget;
}else{
if(sector.save != null){
Log.warn("Sector @ has two corresponding saves: @ and @", sector, sector.save.file, slot.file);
}
sector.save = slot;
}
slot.getSector().save = slot;
}
}
for(var sector : infoToClear){
if(!remapped.contains(sector)){
sector.clearInfo();
}
}
}
public @Nullable SaveSlot getLastSector(){
@@ -207,8 +253,12 @@ public class Saves{
}
public void load() throws SaveException{
load(world.context);
}
public void load(WorldContext context) throws SaveException{
try{
SaveIO.load(file);
SaveIO.load(file, context);
meta = SaveIO.getMeta(file);
current = this;
totalPlaytime = meta.timePlayed;
@@ -313,6 +363,7 @@ public class Saves{
}
public @Nullable Sector getSector(){
//TODO remap sectors
return meta == null || meta.rules == null ? null : meta.rules.sector;
}

View File

@@ -140,6 +140,7 @@ public abstract class SaveVersion extends SaveFileReader{
"wavetime", state.wavetime,
"stats", JsonIO.write(state.stats),
"rules", JsonIO.write(state.rules),
"sectorPreset", state.rules.sector != null && state.rules.sector.preset != null ? state.rules.sector.preset.name : "", //empty string is a placeholder for null (null is possible but may be finicky)
"locales", JsonIO.write(state.mapLocales),
"mods", JsonIO.write(mods.getModStrings().toArray(String.class)),
"controlGroups", headless || control == null ? "null" : JsonIO.write(control.input.controlGroups),

View File

@@ -34,6 +34,8 @@ public class SectorPreset extends UnlockableContent{
public boolean allowLaunchLoadout = false;
/** If true, switches to attack mode after waves end. */
public boolean attackAfterWaves = false;
/** The original position of this sector; used for migration. Internal use for vanilla campaign only! */
public int originalPosition;
public SectorPreset(String name, Planet planet, int sector){
this(name, null, planet, sector);
@@ -61,6 +63,7 @@ public class SectorPreset extends UnlockableContent{
public void initialize(Planet planet, int sector){
this.planet = planet;
this.originalPosition = sector;
//auto remap based on data
var data = planet.getData();
if(data != null){