Fixed sector damage calculations / Campaign balance

This commit is contained in:
Anuken 2020-11-23 18:09:20 -05:00
parent 06929ee8f3
commit 2282cb89b1
6 changed files with 21 additions and 16 deletions

View file

@ -88,7 +88,7 @@ public class Vars implements Loadable{
/** duration of time between turns in ticks */
public static final float turnDuration = 2 * Time.toMinutes;
/** chance of an invasion per turn, 1 = 100% */
public static final float baseInvasionChance = 1f / 55f;
public static final float baseInvasionChance = 1f / 60f;
/** how many turns have to pass before invasions start */
public static final int invasionGracePeriod = 20;
/** min armor fraction damage; e.g. 0.05 = at least 5% damage */

View file

@ -484,6 +484,7 @@ public class TechTree implements ContentList{
new Research(bryde),
new Research(spectre),
new Research(launchPad),
new Research(massDriver),
new Research(impactReactor),
new Research(additiveReconstructor),
new Research(exponentialReconstructor)

View file

@ -1413,12 +1413,12 @@ public class UnitTypes implements ContentList{
ejectEffect = Fx.casing1;
shootSound = Sounds.missile;
bullet = new MissileBulletType(2.7f, 12, "missile"){{
keepVelocity = true;
width = 8f;
height = 8f;
shrinkY = 0f;
drag = -0.003f;
homingRange = 60f;
keepVelocity = false;
splashDamageRadius = 25f;
splashDamage = 10f;
lifetime = 80f;

View file

@ -277,7 +277,7 @@ public class Waves{
int cap = 150;
float shieldStart = 30, shieldsPerWave = 20 + difficulty*30f;
float[] scaling = {1, 1.2f, 1.5f, 3f, 4f};
float[] scaling = {1, 1.2f, 2f, 3f, 4f};
Intc createProgression = start -> {
//main sequence

View file

@ -111,23 +111,26 @@ public class SectorDamage{
float damage = getDamage(state.rules.sector.info);
//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.6f);
float scaled = Mathf.pow(damage, 1.2f);
//apply damage to units
float unitDamage = damage * state.rules.sector.info.sumHealth;
Tile spawn = spawner.getFirstSpawn();
//damage only units near the spawn point
if(spawn != null){
Seq<Unit> allies = new Seq<>();
float sumUnitHealth = 0f;
for(Unit ally : Groups.unit){
if(ally.team == state.rules.defaultTeam && ally.within(spawn, state.rules.dropZoneRadius * 2.5f)){
allies.add(ally);
sumUnitHealth += ally.health;
}
}
allies.sort(u -> u.dst2(spawn));
//apply damage to units
float unitDamage = damage * sumUnitHealth;
//damage units one by one, not uniformly
for(var u : allies){
if(u.health < unitDamage){
@ -335,9 +338,9 @@ public class SectorDamage{
info.waveDpsSlope = reg.slope;
//enemy units like to aim for a lot of non-essential things, so increase resulting health slightly
info.sumHealth = sumHealth * 1.18f;
info.sumHealth = sumHealth * 1.2f;
//players tend to have longer range units/turrets, so assume DPS is higher
info.sumDps = sumDps * 1.18f;
info.sumDps = sumDps * 1.2f;
info.sumRps = sumRps;
info.wavesSurvived = getWavesSurvived(info);
@ -348,13 +351,12 @@ public class SectorDamage{
Queue<Tile> frontier = new Queue<>();
float[][] values = new float[tiles.width][tiles.height];
float damage = fraction*80; //arbitrary damage value
//phase one: find all spawnpoints
for(Tile tile : tiles){
if((tile.block() instanceof CoreBlock && tile.team() == state.rules.waveTeam) || tile.overlay() == Blocks.spawn){
frontier.add(tile);
values[tile.x][tile.y] = damage;
values[tile.x][tile.y] = fraction * 80;
}
}
@ -368,14 +370,16 @@ public class SectorDamage{
int radius = 3;
//only penetrate a certain % by health, not by distance
float totalHealth = damage >= 1f ? 1f : path.sumf(t -> {
float totalHealth = fraction >= 1f ? 1f : path.sumf(t -> {
float s = 0;
for(int dx = -radius; dx <= radius; dx++){
for(int dy = -radius; dy <= radius; dy++){
int wx = dx + t.x, wy = dy + t.y;
if(wx >= 0 && wy >= 0 && wx < world.width() && wy < world.height() && Mathf.within(dx, dy, radius)){
Tile other = world.rawTile(wx, wy);
s += other.team() == state.rules.defaultTeam ? other.build.health / other.block().size : 0f;
if(!(other.block() instanceof CoreBlock)){
s += other.team() == state.rules.defaultTeam ? other.build.health / other.block().size : 0f;
}
}
}
}
@ -385,7 +389,7 @@ public class SectorDamage{
float healthCount = 0;
out:
for(int i = 0; i < path.size && (healthCount < targetHealth || damage >= 1f); i++){
for(int i = 0; i < path.size && (healthCount < targetHealth || fraction >= 1f); i++){
Tile t = path.get(i);
for(int dx = -radius; dx <= radius; dx++){
@ -405,7 +409,7 @@ public class SectorDamage{
removal.add(other.build);
if(healthCount >= targetHealth && damage < 0.999f){
if(healthCount >= targetHealth && fraction < 0.999f){
break out;
}
}
@ -430,10 +434,10 @@ public class SectorDamage{
}
}
float falloff = (damage) / (Math.max(tiles.width, tiles.height) * Mathf.sqrt2);
float falloff = (fraction) / (Math.max(tiles.width, tiles.height) * Mathf.sqrt2);
int peak = 0;
if(damage > 0.1f){
if(fraction > 0.1f){
//phase two: propagate the damage
while(!frontier.isEmpty()){
peak = Math.max(peak, frontier.size);