Sector refactoring, invasions and cleanup

This commit is contained in:
Anuken
2020-10-16 11:02:24 -04:00
parent 5ee4101ba4
commit 2f54edf34f
27 changed files with 319 additions and 376 deletions

View File

@@ -18,6 +18,7 @@ public class Universe{
private int netSeconds;
private float secondCounter;
private int turn;
private float turnCounter;
private Schematic lastLoadout;
private ItemSeq lastLaunchResources = new ItemSeq();
@@ -54,17 +55,19 @@ public class Universe{
}
}
/** @return sectors attacked on the current planet, minus the ones that are being played on right now. */
public Seq<Sector> getAttacked(Planet planet){
return planet.sectors.select(s -> s.isUnderAttack() && s.hasBase() && !s.isBeingPlayed() && s.getWavesPassed() > 0);
}
/** Update planet rotations, global time and relevant state. */
public void update(){
//only update time when not in multiplayer
if(!net.client()){
secondCounter += Time.delta / 60f;
turnCounter += Time.delta;
//auto-run turns
if(turnCounter >= turnDuration){
turnCounter = 0;
runTurn();
}
if(secondCounter >= 1){
seconds += (int)secondCounter;
@@ -133,59 +136,84 @@ public class Universe{
//update relevant sectors
for(Planet planet : content.planets()){
for(Sector sector : planet.sectors){
if(sector.hasSave()){
int spent = (int)(sector.getTimeSpent() / 60);
int actuallyPassed = Math.max(newSecondsPassed - spent, 0);
if(sector.hasSave() && sector.hasBase()){
//increment seconds passed for this sector by the time that just passed with this turn
if(!sector.isBeingPlayed()){
int secPassed = sector.getSecondsPassed() + actuallyPassed;
//increment time
sector.info.secondsPassed += turnDuration/60f;
sector.setSecondsPassed(secPassed);
boolean attacked = sector.isUnderAttack();
int wavesPassed = (int)(secPassed*60f / sector.save.meta.rules.waveSpacing);
float damage = attacked ? SectorDamage.getDamage(sector.save.meta.secinfo, sector.save.meta.rules.waveSpacing, sector.save.meta.wave, wavesPassed) : 0f;
int wavesPassed = (int)(sector.info.secondsPassed*60f / sector.info.waveSpacing);
boolean attacked = sector.info.waves;
if(attacked){
sector.setWavesPassed(wavesPassed);
sector.info.wavesPassed = wavesPassed;
}
sector.setDamage(damage);
float damage = attacked ? SectorDamage.getDamage(sector.info) : 0f;
//damage never goes down until the player visits the sector, so use max
sector.info.damage = Math.max(sector.info.damage, damage);
//check if the sector has been attacked too many times...
if(attacked && damage >= 0.999f){
//fire event for losing the sector
Events.fire(new SectorLoseEvent(sector));
//if so, just delete the save for now. it's lost.
//TODO don't delete it later maybe
sector.setExtraItems(new ItemSeq());
sector.setDamage(1.01f);
}else if(attacked && wavesPassed > 0 && sector.save.meta.wave + wavesPassed >= sector.save.meta.rules.winWave && !sector.hasEnemyBase()){
//sector is dead.
sector.info.items.clear();
sector.info.damage = 1f;
sector.info.hasCore = false;
sector.info.production.clear();
}else if(attacked && wavesPassed > 0 && sector.info.wave + wavesPassed >= sector.info.winWave && !sector.hasEnemyBase()){
//autocapture the sector
sector.setUnderAttack(false);
sector.info.waves = false;
//fire the event
Events.fire(new SectorCaptureEvent(sector));
}
float scl = sector.getProductionScale();
//export to another sector
if(sector.info.destination != null){
Sector to = sector.info.destination;
if(to.hasBase()){
ItemSeq items = new ItemSeq();
//calculated exported items to this sector
sector.info.export.each((item, stat) -> items.add(item, (int)(stat.mean * newSecondsPassed * scl)));
to.addItems(items);
}
}
//add production, making sure that it's capped
sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * seconds * scl), sector.info.storageCapacity - sector.info.items.get(item))));
sector.saveInfo();
}
//export to another sector
if(sector.save != null && sector.save.meta != null && sector.save.meta.secinfo != null && sector.save.meta.secinfo.destination != null){
Sector to = sector.save.meta.secinfo.destination;
if(to.save != null){
float scl = Math.max(1f - sector.getDamage(), 0);
ItemSeq items = new ItemSeq();
//calculated exported items to this sector
sector.save.meta.secinfo.export.each((item, stat) -> items.add(item, (int)(stat.mean * newSecondsPassed * scl)));
to.addItems(items);
//queue random invasions
if(!sector.isAttacked() && turn > invasionGracePeriod){
//TODO use factors like difficulty for better invasion chance
if(sector.near().contains(Sector::hasEnemyBase) && Mathf.chance(baseInvasionChance)){
int waveMax = Math.max(sector.info.winWave, sector.isBeingPlayed() ? state.wave : 0) + Mathf.random(2, 4) * 5;
float waveSpace = Math.max(sector.info.waveSpacing - Mathf.random(1, 4) * 5 * 60, 40 * 60);
//assign invasion-related things
if(sector.isBeingPlayed()){
state.rules.winWave = waveMax;
state.rules.waves = true;
state.rules.waveSpacing = waveSpace;
}else{
sector.info.winWave = waveMax;
sector.info.waves = true;
sector.info.waveSpacing = waveSpace;
sector.saveInfo();
}
Events.fire(new SectorInvasionEvent(sector));
}
}
//reset time spent to 0
sector.setTimeSpent(0f);
}
}
}
@@ -202,7 +230,7 @@ public class Universe{
for(Planet planet : content.planets()){
for(Sector sector : planet.sectors){
if(sector.hasSave()){
count.add(sector.calculateItems());
count.add(sector.items());
}
}
}