This commit is contained in:
NgLamVN
2020-11-28 11:30:35 +07:00
committed by GitHub
29 changed files with 97 additions and 23 deletions

View File

@@ -1460,7 +1460,7 @@ unit.reign.description = Fires a barrage of massive piercing bullets at all near
unit.nova.description = Fires laser bolts that damage enemies and repair allied structures. Capable of flight. unit.nova.description = Fires laser bolts that damage enemies and repair allied structures. Capable of flight.
unit.pulsar.description = Fires arcs of electricity that damage enemies and repair allied structures. Capable of flight. unit.pulsar.description = Fires arcs of electricity that damage enemies and repair allied structures. Capable of flight.
unit.quasar.description = Fires piercing laser beams that damage enemies and repair allied structures. Capable of flight. Shielded. unit.quasar.description = Fires piercing laser beams that damage enemies and repair allied structures. Capable of flight. Shielded.
unit.vela.description = Fires a massive continuous laser beam that damages enemies, causes fires and repair allied structures. Capable of flight. unit.vela.description = Fires a massive continuous laser beam that damages enemies, causes fires and repairs allied structures. Capable of flight.
unit.corvus.description = Fires a massive laser blast that damages enemies and repairs allied structures. Can step over most terrain. unit.corvus.description = Fires a massive laser blast that damages enemies and repairs allied structures. Can step over most terrain.
unit.crawler.description = Runs toward enemies and self-destructs, causing a large explosion. unit.crawler.description = Runs toward enemies and self-destructs, causing a large explosion.
unit.atrax.description = Fires debilitating orbs of slag at ground targets. Can step over most terrain. unit.atrax.description = Fires debilitating orbs of slag at ground targets. Can step over most terrain.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

@@ -55,11 +55,12 @@ public class BaseAI{
public void update(){ public void update(){
if(data.team.rules().aiCoreSpawn && timer.get(timerSpawn, 60 * 2.5f) && data.hasCore()){ if(data.team.rules().aiCoreSpawn && timer.get(timerSpawn, 60 * 2.5f) && data.hasCore()){
CoreBlock block = (CoreBlock)data.core().block; CoreBlock block = (CoreBlock)data.core().block;
int coreUnits = Groups.unit.count(u -> u.team == data.team && u.type == block.unitType);
//create AI core unit //create AI core unit(s)
if(!state.isEditor() && !Groups.unit.contains(u -> u.team() == data.team && u.type == block.unitType)){ if(!state.isEditor() && coreUnits < data.cores.size){
Unit unit = block.unitType.create(data.team); Unit unit = block.unitType.create(data.team);
unit.set(data.core()); unit.set(data.cores.random());
unit.add(); unit.add();
Fx.spawn.at(unit); Fx.spawn.at(unit);
} }

View File

@@ -83,7 +83,7 @@ public class SectorPresets implements ContentList{
}}; }};
desolateRift = new SectorPreset("desolateRift", serpulo, 123){{ desolateRift = new SectorPreset("desolateRift", serpulo, 123){{
captureWave = 30; captureWave = 18;
difficulty = 8; difficulty = 8;
}}; }};

View File

@@ -471,7 +471,8 @@ public class TechTree implements ContentList{
node(desolateRift, Seq.with( node(desolateRift, Seq.with(
new SectorComplete(impact0078), new SectorComplete(impact0078),
new Research(thermalGenerator), new Research(thermalGenerator),
new Research(thoriumReactor) new Research(thoriumReactor),
new Research(coreNucleus)
), () -> { ), () -> {
node(planetaryTerminal, Seq.with( node(planetaryTerminal, Seq.with(
new SectorComplete(desolateRift), new SectorComplete(desolateRift),

View File

@@ -620,7 +620,7 @@ public class UnitTypes implements ContentList{
drag = 0.4f; drag = 0.4f;
hitSize = 12f; hitSize = 12f;
rotateSpeed = 3f; rotateSpeed = 3f;
health = 800; health = 900;
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting); immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
legCount = 6; legCount = 6;
legLength = 13f; legLength = 13f;
@@ -651,7 +651,7 @@ public class UnitTypes implements ContentList{
bullet = new SapBulletType(){{ bullet = new SapBulletType(){{
sapStrength = 0.4f; sapStrength = 0.4f;
length = 75f; length = 75f;
damage = 18; damage = 20;
shootEffect = Fx.shootSmall; shootEffect = Fx.shootSmall;
hitColor = color = Color.valueOf("bf92f9"); hitColor = color = Color.valueOf("bf92f9");
despawnEffect = Fx.none; despawnEffect = Fx.none;
@@ -671,7 +671,7 @@ public class UnitTypes implements ContentList{
bullet = new SapBulletType(){{ bullet = new SapBulletType(){{
sapStrength = 0.8f; sapStrength = 0.8f;
length = 40f; length = 40f;
damage = 15; damage = 16;
shootEffect = Fx.shootSmall; shootEffect = Fx.shootSmall;
hitColor = color = Color.valueOf("bf92f9"); hitColor = color = Color.valueOf("bf92f9");
despawnEffect = Fx.none; despawnEffect = Fx.none;
@@ -1252,8 +1252,8 @@ public class UnitTypes implements ContentList{
mineTier = 3; mineTier = 3;
mineSpeed = 4f; mineSpeed = 4f;
health = 500; health = 460;
armor = 5f; armor = 3f;
speed = 2.5f; speed = 2.5f;
accel = 0.06f; accel = 0.06f;
drag = 0.017f; drag = 0.017f;

View File

@@ -53,7 +53,7 @@ public class Weathers implements ContentList{
baseSpeed = 5.4f; baseSpeed = 5.4f;
attrs.set(Attribute.light, -0.1f); attrs.set(Attribute.light, -0.1f);
attrs.set(Attribute.water, -0.1f); attrs.set(Attribute.water, -0.1f);
opacityMultiplier = 0.4f; opacityMultiplier = 0.35f;
force = 0.1f; force = 0.1f;
sound = Sounds.wind; sound = Sounds.wind;
soundVol = 0.8f; soundVol = 0.8f;

View File

@@ -336,6 +336,8 @@ public class Control implements ApplicationListener, Loadable{
state.wavetime = state.rules.waveSpacing * 2f; state.wavetime = state.rules.waveSpacing * 2f;
//reset captured state //reset captured state
sector.info.wasCaptured = false; sector.info.wasCaptured = false;
//re-enable waves
state.rules.waves = true;
//reset win wave?? //reset win wave??
state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : 40; state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : 40;

View File

@@ -311,7 +311,7 @@ public class World{
//TODO bad code //TODO bad code
boolean hasSnow = floors[0].name.contains("ice") || floors[0].name.contains("snow"); boolean hasSnow = floors[0].name.contains("ice") || floors[0].name.contains("snow");
boolean hasRain = !hasSnow && content.contains(Liquids.water) && !floors[0].name.contains("sand"); boolean hasRain = !hasSnow && content.contains(Liquids.water) && !floors[0].name.contains("sand");
boolean hasDesert = !hasSnow && !hasRain && floors[0].name.contains("sand"); boolean hasDesert = !hasSnow && !hasRain && floors[0] == Blocks.sand;
boolean hasSpores = floors[0].name.contains("spore") || floors[0].name.contains("moss") || floors[0].name.contains("tainted"); boolean hasSpores = floors[0].name.contains("spore") || floors[0].name.contains("moss") || floors[0].name.contains("tainted");
if(hasSnow){ if(hasSnow){

View File

@@ -17,7 +17,7 @@ import mindustry.ui.*;
public class WaveGraph extends Table{ public class WaveGraph extends Table{
public Seq<SpawnGroup> groups = new Seq<>(); public Seq<SpawnGroup> groups = new Seq<>();
public int from, to = 20; public int from = 0, to = 20;
private Mode mode = Mode.counts; private Mode mode = Mode.counts;
private int[][] values; private int[][] values;
@@ -114,7 +114,7 @@ public class WaveGraph extends Table{
Lines.line(cx, cy, cx, cy + len); Lines.line(cx, cy, cx, cy + len);
if(i == values.length/2){ if(i == values.length/2){
font.draw("" + (i + from), cx, cy - 2f, Align.center); font.draw("" + (i + from + 1), cx, cy - 2f, Align.center);
} }
} }
font.setColor(Color.white); font.setColor(Color.white);

View File

@@ -71,7 +71,9 @@ public class SectorInfo{
public boolean shown = false; public boolean shown = false;
/** Special variables for simulation. */ /** Special variables for simulation. */
public float sumHealth, sumRps, sumDps, waveHealthBase, waveHealthSlope, waveDpsBase, waveDpsSlope; public float sumHealth, sumRps, sumDps, waveHealthBase, waveHealthSlope, waveDpsBase, waveDpsSlope, bossHealth, bossDps;
/** Wave where first boss shows up. */
public int bossWave = -1;
/** Counter refresh state. */ /** Counter refresh state. */
private transient Interval time = new Interval(); private transient Interval time = new Interval();

View File

@@ -6,6 +6,7 @@ import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.SectorInfo.*;
import mindustry.maps.*; import mindustry.maps.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.blocks.storage.*; import mindustry.world.blocks.storage.*;
@@ -199,6 +200,13 @@ public class Universe{
} }
} }
sector.info.export.each((item, amount) -> {
if(sector.info.items.get(item) <= 0 && sector.info.production.get(item, ExportStat::new).mean <= 0){
//disable export when production is negative.
sector.info.export.get(item).mean = 0f;
}
});
//add production, making sure that it's capped //add production, making sure that it's capped
sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * newSecondsPassed * scl), sector.info.storageCapacity - sector.info.items.get(item)))); sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * newSecondsPassed * scl), sector.info.storageCapacity - sector.info.items.get(item))));
//prevent negative values with unloaders //prevent negative values with unloaders

View File

@@ -68,6 +68,11 @@ public class SectorDamage{
float enemyDps = info.waveDpsBase + info.waveDpsSlope * (i); float enemyDps = info.waveDpsBase + info.waveDpsSlope * (i);
float enemyHealth = info.waveHealthBase + info.waveHealthSlope * (i); float enemyHealth = info.waveHealthBase + info.waveHealthSlope * (i);
if(info.bossWave == i){
enemyDps += info.bossDps;
enemyHealth += info.bossHealth;
}
//happens due to certain regressions //happens due to certain regressions
if(enemyHealth < 0 || enemyDps < 0) continue; if(enemyHealth < 0 || enemyDps < 0) continue;
@@ -305,6 +310,7 @@ public class SectorDamage{
//calculate DPS and health for the next few waves and store in list //calculate DPS and health for the next few waves and store in list
var reg = new LinearRegression(); var reg = new LinearRegression();
SpawnGroup bossGroup = null;
Seq<Vec2> waveDps = new Seq<>(), waveHealth = new Seq<>(); Seq<Vec2> waveDps = new Seq<>(), waveHealth = new Seq<>();
for(int wave = state.wave; wave < state.wave + 10; wave ++){ for(int wave = state.wave; wave < state.wave + 10; wave ++){
@@ -320,6 +326,11 @@ public class SectorDamage{
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(wave); int spawned = group.getSpawned(wave);
//save the boss group
if(group.effect == StatusEffects.boss){
bossGroup = group;
continue;
}
if(spawned <= 0) continue; if(spawned <= 0) continue;
sumWaveHealth += spawned * (group.getShield(wave) + group.type.health * effect.healthMultiplier * healthMult); sumWaveHealth += spawned * (group.getShield(wave) + group.type.health * effect.healthMultiplier * healthMult);
sumWaveDps += spawned * group.type.dpsEstimate * effect.damageMultiplier; sumWaveDps += spawned * group.type.dpsEstimate * effect.damageMultiplier;
@@ -328,6 +339,21 @@ public class SectorDamage{
waveHealth.add(new Vec2(wave, sumWaveHealth)); waveHealth.add(new Vec2(wave, sumWaveHealth));
} }
if(bossGroup != null){
float bossMult = 1.1f;
//calculate first boss appearaance
for(int wave = state.wave; wave < state.wave + 60; wave++){
int spawned = bossGroup.getSpawned(wave - 1);
if(spawned > 0){
//set up relevant stats
info.bossWave = wave;
info.bossDps = spawned * bossGroup.type.dpsEstimate * StatusEffects.boss.damageMultiplier * bossMult;
info.bossHealth = spawned * (bossGroup.getShield(wave) + bossGroup.type.health * StatusEffects.boss.healthMultiplier * (1f + Mathf.clamp(bossGroup.type.armor / 20f))) * bossMult;
break;
}
}
}
//calculate linear regression of the wave data and store it //calculate linear regression of the wave data and store it
reg.calculate(waveHealth); reg.calculate(waveHealth);
info.waveHealthBase = reg.intercept; info.waveHealthBase = reg.intercept;
@@ -356,7 +382,7 @@ public class SectorDamage{
for(Tile tile : tiles){ for(Tile tile : tiles){
if((tile.block() instanceof CoreBlock && tile.team() == state.rules.waveTeam) || tile.overlay() == Blocks.spawn){ if((tile.block() instanceof CoreBlock && tile.team() == state.rules.waveTeam) || tile.overlay() == Blocks.spawn){
frontier.add(tile); frontier.add(tile);
values[tile.x][tile.y] = fraction * 26; values[tile.x][tile.y] = fraction * 24;
} }
} }

View File

@@ -3,6 +3,8 @@ package mindustry.maps.planet;
import arc.graphics.*; import arc.graphics.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import mindustry.content.*;
import mindustry.game.*;
import mindustry.maps.generators.*; import mindustry.maps.generators.*;
public class TantrosPlanetGenerator extends PlanetGenerator{ public class TantrosPlanetGenerator extends PlanetGenerator{
@@ -18,4 +20,13 @@ public class TantrosPlanetGenerator extends PlanetGenerator{
float depth = (float)noise.octaveNoise3D(2, 0.56, 1.7f, position.x, position.y, position.z) / 2f; float depth = (float)noise.octaveNoise3D(2, 0.56, 1.7f, position.x, position.y, position.z) / 2f;
return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(0.6f); return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(0.6f);
} }
@Override
protected void generate(){
pass((x, y) -> {
floor = Blocks.deepwater;
});
Schematics.placeLaunchLoadout(width / 2, height / 2);
}
} }

View File

@@ -262,7 +262,7 @@ public abstract class Weather extends UnlockableContent{
/** Creates a weather entry with some approximate weather values. */ /** Creates a weather entry with some approximate weather values. */
public WeatherEntry(Weather weather){ public WeatherEntry(Weather weather){
this(weather, weather.duration * 3f, weather.duration * 6f, weather.duration / 2f, weather.duration * 1.5f); this(weather, weather.duration * 2f, weather.duration * 6f, weather.duration / 2f, weather.duration * 1.5f);
} }
public WeatherEntry(Weather weather, float minFrequency, float maxFrequency, float minDuration, float maxDuration){ public WeatherEntry(Weather weather, float minFrequency, float maxFrequency, float minDuration, float maxDuration){

View File

@@ -78,6 +78,9 @@ public class Bar extends Element{
lastValue = computed; lastValue = computed;
} }
if(Float.isNaN(computed)) computed = 0;
if(Float.isInfinite(computed)) computed = 1f;
blink = Mathf.lerpDelta(blink, 0f, 0.2f); blink = Mathf.lerpDelta(blink, 0f, 0.2f);
value = Mathf.lerpDelta(value, computed, 0.15f); value = Mathf.lerpDelta(value, computed, 0.15f);

View File

@@ -311,7 +311,7 @@ public class Conveyor extends Block implements Autotiler{
if(len >= capacity) return false; if(len >= capacity) return false;
Tile facing = Edges.getFacingEdge(source.tile, tile); Tile facing = Edges.getFacingEdge(source.tile, tile);
int direction = Math.abs(facing.relativeTo(tile.x, tile.y) - rotation); int direction = Math.abs(facing.relativeTo(tile.x, tile.y) - rotation);
return (((direction == 0) && minitem >= itemSpace) || ((direction % 2 == 1) && minitem > 0.7f)) && !(source.block.rotate && (source.rotation + 2) % 4 == rotation); return (((direction == 0) && minitem >= itemSpace) || ((direction % 2 == 1) && minitem > 0.7f)) && !(source.block.rotate && next == source);
} }
@Override @Override

View File

@@ -93,7 +93,7 @@ public class ItemBridge extends Block{
Draw.reset(); Draw.reset();
Draw.color(Pal.placing); Draw.color(Pal.placing);
Lines.stroke(1f); Lines.stroke(1f);
if(link != null){ if(link != null && Math.abs(link.x - x) + Math.abs(link.y - y) > 1){
int rot = link.absoluteRelativeTo(x, y); int rot = link.absoluteRelativeTo(x, y);
float w = (link.x == x ? tilesize : Math.abs(link.x - x) * tilesize - tilesize); float w = (link.x == x ? tilesize : Math.abs(link.x - x) * tilesize - tilesize);
float h = (link.y == y ? tilesize : Math.abs(link.y - y) * tilesize - tilesize); float h = (link.y == y ? tilesize : Math.abs(link.y - y) * tilesize - tilesize);
@@ -145,7 +145,7 @@ public class ItemBridge extends Block{
if(config != null) return; if(config != null) return;
Tile link = findLink(tile.x, tile.y); Tile link = findLink(tile.x, tile.y);
if(linkValid(tile, link)){ if(linkValid(tile, link) && !proximity.contains(link.build)){
link.build.configure(tile.pos()); link.build.configure(tile.pos());
} }

View File

@@ -10,6 +10,8 @@ import mindustry.world.*;
import mindustry.world.blocks.storage.CoreBlock.*; import mindustry.world.blocks.storage.CoreBlock.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static mindustry.Vars.*;
public class StorageBlock extends Block{ public class StorageBlock extends Block{
public StorageBlock(String name){ public StorageBlock(String name){
@@ -57,6 +59,24 @@ public class StorageBlock extends Block{
} }
} }
@Override
public void itemTaken(Item item){
if(linkedCore != null){
linkedCore.itemTaken(item);
}
}
@Override
public int removeStack(Item item, int amount){
int result = super.removeStack(item, amount);
if(linkedCore != null && team == state.rules.defaultTeam && state.isCampaign()){
state.rules.sector.info.handleCoreItem(item, -result);
}
return result;
}
@Override @Override
public int getMaximumAccepted(Item item){ public int getMaximumAccepted(Item item){
return itemCapacity; return itemCapacity;

View File

@@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=7a2a357f6cfdc3725ce581093a0ced91f4474222 archash=2d451f0c342755ef84e609c951a8fca654ef41b5