Fixed #10806 / Fixed crash

This commit is contained in:
Anuken
2025-05-14 12:06:35 -04:00
parent 8951a2698e
commit e1e5bd5b3f
5 changed files with 33 additions and 30 deletions

View File

@@ -1242,6 +1242,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
@Override @Override
public void setTexture(String textureName){ public void setTexture(String textureName){
this.textureName = textureName; this.textureName = textureName;
if(headless) return;
boolean firstUpdate = fetchedRegion == null; boolean firstUpdate = fetchedRegion == null;

View File

@@ -196,7 +196,7 @@ public class SectorInfo{
} }
/** Prepare data for writing to a save. */ /** Prepare data for writing to a save. */
public void prepare(){ public void prepare(Sector sector){
//update core items //update core items
items.clear(); items.clear();
@@ -237,12 +237,10 @@ public class SectorInfo{
export.clear(); export.clear();
} }
if(state.rules.sector != null){ sector.saveInfo();
state.rules.sector.saveInfo();
}
if(state.rules.sector != null && state.rules.sector.planet.allowWaveSimulation){ if(sector.planet.allowWaveSimulation){
SectorDamage.writeParameters(this); SectorDamage.writeParameters(sector);
} }
} }

View File

@@ -226,7 +226,7 @@ public class Universe{
sector.info.wavesPassed = wavesPassed; sector.info.wavesPassed = wavesPassed;
} }
float damage = attacked ? SectorDamage.getDamage(sector.info) : 0f; float damage = attacked ? SectorDamage.getDamage(sector) : 0f;
//damage never goes down until the player visits the sector, so use max //damage never goes down until the player visits the sector, so use max
sector.info.damage = Math.max(sector.info.damage, damage); sector.info.damage = Math.max(sector.info.damage, damage);

View File

@@ -118,7 +118,7 @@ public abstract class SaveVersion extends SaveFileReader{
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{ public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
//prepare campaign data for writing //prepare campaign data for writing
if(state.isCampaign()){ if(state.isCampaign()){
state.rules.sector.info.prepare(); state.rules.sector.info.prepare(state.rules.sector);
state.rules.sector.saveInfo(); state.rules.sector.saveInfo();
} }

View File

@@ -27,23 +27,24 @@ public class SectorDamage{
private static final boolean rubble = true; private static final boolean rubble = true;
/** @return calculated capture progress of the enemy */ /** @return calculated capture progress of the enemy */
public static float getDamage(SectorInfo info){ public static float getDamage(Sector sector){
return getDamage(info, info.wavesPassed); return getDamage(sector, sector.info.wavesPassed);
} }
/** @return calculated capture progress of the enemy */ /** @return calculated capture progress of the enemy */
public static float getDamage(SectorInfo info, int wavesPassed){ public static float getDamage(Sector sector, int wavesPassed){
return getDamage(info, wavesPassed, false); return getDamage(sector, wavesPassed, false);
} }
/** @return maximum waves survived, up to maxRetWave. */ /** @return maximum waves survived, up to maxRetWave. */
public static int getWavesSurvived(SectorInfo info){ public static int getWavesSurvived(Sector sector){
return (int)getDamage(info, maxRetWave, true); return (int)getDamage(sector, maxRetWave, true);
} }
/** @return calculated capture progress of the enemy if retWave is false, otherwise return the maximum waves survived as int. /** @return calculated capture progress of the enemy if retWave is false, otherwise return the maximum waves survived as int.
* if it survives all the waves, returns maxRetWave. */ * if it survives all the waves, returns maxRetWave. */
public static float getDamage(SectorInfo info, int wavesPassed, boolean retWave){ public static float getDamage(Sector sector, int wavesPassed, boolean retWave){
var info = sector.info;
float health = info.sumHealth; float health = info.sumHealth;
int wave = info.wave; int wave = info.wave;
float waveSpace = info.waveSpacing; float waveSpace = info.waveSpacing;
@@ -64,18 +65,20 @@ public class SectorDamage{
for(int i = waveBegin; i <= waveEnd; i++){ for(int i = waveBegin; i <= waveEnd; i++){
float enemyDps = 0f, enemyHealth = 0f; float enemyDps = 0f, enemyHealth = 0f;
for(SpawnGroup group : state.rules.spawns){ if(sector.save != null || sector.isBeingPlayed()){
//calculate the amount of spawn points used for(SpawnGroup group : (sector.isBeingPlayed() ? state.rules.spawns : sector.save.meta.rules.spawns)){
//if there's a spawn position override, there is only one potential place they spawn //calculate the amount of spawn points used
//assume that all overridden positions are valid, should always be true in properly designed campaign maps //if there's a spawn position override, there is only one potential place they spawn
int spawnCount = group.spawn != -1 ? 1 : group.type.flying ? airSpawns : groundSpawns; //assume that all overridden positions are valid, should always be true in properly designed campaign maps
int spawnCount = group.spawn != -1 ? 1 : group.type.flying ? airSpawns : groundSpawns;
float healthMult = 1f + Mathf.clamp(group.type.armor / 20f); float healthMult = 1f + Mathf.clamp(group.type.armor / 20f);
StatusEffect effect = (group.effect == null ? StatusEffects.none : group.effect); StatusEffect effect = (group.effect == null ? StatusEffects.none : group.effect);
int spawned = group.getSpawned(i) * spawnCount; int spawned = group.getSpawned(i) * spawnCount;
if(spawned <= 0) continue; if(spawned <= 0) continue;
enemyHealth += spawned * (group.getShield(i) + group.type.health * effect.healthMultiplier * healthMult); enemyHealth += spawned * (group.getShield(i) + group.type.health * effect.healthMultiplier * healthMult);
enemyDps += spawned * group.type.dpsEstimate * effect.damageMultiplier; enemyDps += spawned * group.type.dpsEstimate * effect.damageMultiplier;
}
} }
float efficiency = health / info.sumHealth; float efficiency = health / info.sumHealth;
@@ -106,7 +109,7 @@ public class SectorDamage{
if(timeDestroyEnemy > timeDestroyBase){ if(timeDestroyEnemy > timeDestroyBase){
health = 0f; health = 0f;
//return current wave if simulating //return current wave if simulating
if(retWave) return i - waveBegin; if(retWave) return Math.max(i - waveBegin - 1, waveBegin);
break; break;
} }
@@ -132,7 +135,7 @@ public class SectorDamage{
/** Applies wave damage based on sector parameters. */ /** Applies wave damage based on sector parameters. */
public static void applyCalculatedDamage(){ public static void applyCalculatedDamage(){
//calculate base damage fraction //calculate base damage fraction
float damage = getDamage(state.rules.sector.info); float damage = getDamage(state.rules.sector);
//scaled damage has a power component to make it seem a little more realistic (as systems fail, enemy capturing gets easier and easier) //scaled damage has a power component to make it seem a little more realistic (as systems fail, enemy capturing gets easier and easier)
float scaled = Mathf.pow(damage, 1.2f); float scaled = Mathf.pow(damage, 1.2f);
@@ -187,7 +190,8 @@ public class SectorDamage{
} }
/** Calculates damage simulation parameters before a game is saved. */ /** Calculates damage simulation parameters before a game is saved. */
public static void writeParameters(SectorInfo info){ public static void writeParameters(Sector sector){
var info = sector.info;
Building core = state.rules.defaultTeam.core(); Building core = state.rules.defaultTeam.core();
Seq<Tile> spawns = new Seq<>(); Seq<Tile> spawns = new Seq<>();
spawner.eachGroundSpawn((x, y) -> spawns.add(world.tile(x, y))); spawner.eachGroundSpawn((x, y) -> spawns.add(world.tile(x, y)));
@@ -370,7 +374,7 @@ public class SectorDamage{
info.curEnemyDps = curEnemyDps*cmult; info.curEnemyDps = curEnemyDps*cmult;
info.curEnemyHealth = curEnemyHealth*cmult; info.curEnemyHealth = curEnemyHealth*cmult;
info.wavesSurvived = getWavesSurvived(info); info.wavesSurvived = getWavesSurvived(sector);
} }
public static void apply(float fraction){ public static void apply(float fraction){